#
# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.17.13
+# Wed Oct 18 17:15:54 2006
#
+CONFIG_X86_32=y
+CONFIG_SEMAPHORE_SLEEPERS=y
CONFIG_X86=y
CONFIG_MMU=y
-CONFIG_UID16=y
CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMI=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=17
-CONFIG_HOTPLUG=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
# CONFIG_IKCONFIG is not set
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_VM86=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=m
#
# Loadable module support
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
#
# Processor type and features
#
-# CONFIG_X86_PC is not set
+# CONFIG_SMP is not set
+CONFIG_X86_PC=y
+# CONFIG_X86_XEN is not set
# CONFIG_X86_ELAN is not set
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_NUMAQ is not set
# CONFIG_X86_SUMMIT is not set
# CONFIG_X86_BIGSMP is not set
# CONFIG_X86_VISWS is not set
-CONFIG_X86_GENERICARCH=y
+# CONFIG_X86_GENERICARCH is not set
# CONFIG_X86_ES7000 is not set
-CONFIG_X86_CYCLONE_TIMER=y
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
+# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP2 is not set
# CONFIG_MWINCHIP3D is not set
+# CONFIG_MGEODEGX1 is not set
+# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
CONFIG_X86_GENERIC=y
CONFIG_X86_XADD=y
CONFIG_X86_L1_CACHE_SHIFT=7
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_X86_PPRO_FENCE=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
+CONFIG_X86_CMPXCHG64=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
-CONFIG_X86_4G=y
-CONFIG_X86_SWITCH_PAGETABLES=y
-CONFIG_X86_4G_VM_LAYOUT=y
-CONFIG_X86_UACCESS_INDIRECT=y
-CONFIG_X86_HIGH_ENTRY=y
+CONFIG_X86_TSC=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=32
-CONFIG_SCHED_SMT=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
+CONFIG_X86_UP_APIC=y
+CONFIG_X86_UP_IOAPIC=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
-CONFIG_X86_TSC=y
CONFIG_X86_MCE=y
# CONFIG_X86_MCE_NONFATAL is not set
CONFIG_X86_MCE_P4THERMAL=y
CONFIG_TOSHIBA=m
CONFIG_I8K=m
+# CONFIG_X86_REBOOTFIXUPS is not set
CONFIG_MICROCODE=m
CONFIG_X86_MSR=m
CONFIG_X86_CPUID=m
+# CONFIG_SWIOTLB is not set
#
# Firmware Drivers
#
CONFIG_EDD=m
+CONFIG_EFI_VARS=y
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
# CONFIG_NOHIGHMEM is not set
-# CONFIG_HIGHMEM4G is not set
-CONFIG_HIGHMEM64G=y
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_HIGHMEM=y
-CONFIG_X86_PAE=y
-# CONFIG_NUMA is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
CONFIG_HIGHPTE=y
# CONFIG_MATH_EMULATION is not set
CONFIG_MTRR=y
-# CONFIG_EFI is not set
-# CONFIG_IRQBALANCE is not set
-CONFIG_HAVE_DEC_LOCK=y
+CONFIG_EFI=y
+CONFIG_BOOT_IOREMAP=y
CONFIG_REGPARM=y
+# CONFIG_SECCOMP is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x400000
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
#
# Power management options (ACPI, APM)
#
CONFIG_PM=y
-# CONFIG_SOFTWARE_SUSPEND is not set
-# CONFIG_PM_DISK is not set
+CONFIG_PM_LEGACY=y
+CONFIG_PM_DEBUG=y
+CONFIG_SOFTWARE_SUSPEND=y
+CONFIG_PM_STD_PARTITION=""
#
# ACPI (Advanced Configuration and Power Interface) Support
#
CONFIG_ACPI=y
-CONFIG_ACPI_BOOT=y
-CONFIG_ACPI_INTERPRETER=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_SLEEP_PROC_FS=y
+# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set
CONFIG_ACPI_AC=m
CONFIG_ACPI_BATTERY=m
CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
+# CONFIG_ACPI_HOTKEY is not set
CONFIG_ACPI_FAN=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_THERMAL=y
CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_IBM=m
+CONFIG_ACPI_IBM_DOCK=y
CONFIG_ACPI_TOSHIBA=m
+CONFIG_ACPI_BLACKLIST_YEAR=1999
# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_BUS=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
-CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
CONFIG_X86_PM_TIMER=y
+# CONFIG_ACPI_CONTAINER is not set
#
# APM (Advanced Power Management) BIOS Support
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
-# CONFIG_CPU_FREQ_PROC_INTF is not set
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=y
-# CONFIG_CPU_FREQ_24_API is not set
-CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
#
# CPUFreq processor drivers
#
CONFIG_X86_ACPI_CPUFREQ=m
-# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
-CONFIG_X86_POWERNOW_K6=m
+# CONFIG_X86_POWERNOW_K6 is not set
CONFIG_X86_POWERNOW_K7=y
-CONFIG_X86_POWERNOW_K8=m
+CONFIG_X86_POWERNOW_K7_ACPI=y
+CONFIG_X86_POWERNOW_K8=y
+CONFIG_X86_POWERNOW_K8_ACPI=y
# CONFIG_X86_GX_SUSPMOD is not set
CONFIG_X86_SPEEDSTEP_CENTRINO=y
-CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
CONFIG_X86_SPEEDSTEP_ICH=y
-CONFIG_X86_SPEEDSTEP_SMI=m
+CONFIG_X86_SPEEDSTEP_SMI=y
CONFIG_X86_P4_CLOCKMOD=m
+# CONFIG_X86_CPUFREQ_NFORCE2 is not set
+CONFIG_X86_LONGRUN=y
+
+#
+# shared options
+#
+# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
CONFIG_X86_SPEEDSTEP_LIB=y
# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set
-CONFIG_X86_LONGRUN=y
-# CONFIG_X86_LONGHAUL is not set
#
# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GOMMCONFIG is not set
# CONFIG_PCI_GODIRECT is not set
+# CONFIG_PCI_GOXEN_FE is not set
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
-CONFIG_PCI_USE_VECTOR=y
-CONFIG_PCI_LEGACY_PROC=y
-# CONFIG_PCI_NAMES is not set
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=m
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+CONFIG_ISA_DMA_API=y
CONFIG_ISA=y
# CONFIG_EISA is not set
# CONFIG_MCA is not set
# CONFIG_SCx200 is not set
#
-# PCMCIA/CardBus support
+# PCCARD (PCMCIA/CardBus) support
#
-CONFIG_PCMCIA=m
+CONFIG_PCCARD=y
# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_YENTA=m
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
CONFIG_I82092=m
-CONFIG_I82365=m
-CONFIG_TCIC=m
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
#
# PCI Hotplug Support
#
CONFIG_HOTPLUG_PCI=y
-# CONFIG_HOTPLUG_PCI_FAKE is not set
+CONFIG_HOTPLUG_PCI_FAKE=m
CONFIG_HOTPLUG_PCI_COMPAQ=m
# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
CONFIG_HOTPLUG_PCI_IBM=m
-# CONFIG_HOTPLUG_PCI_ACPI is not set
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
# CONFIG_HOTPLUG_PCI_CPCI is not set
-CONFIG_HOTPLUG_PCI_PCIE=m
-CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE=y
-CONFIG_HOTPLUG_PCI_SHPC=m
-CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y
+# CONFIG_HOTPLUG_PCI_SHPC is not set
#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_MISC=m
+CONFIG_BINFMT_MISC=y
#
-# Device Drivers
+# Networking
#
+CONFIG_NET=y
#
-# Generic Driver Options
+# Networking options
#
-CONFIG_FW_LOADER=y
-# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
+CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
#
-# Memory Technology Devices (MTD)
+# IP: Virtual Server Configuration
#
-CONFIG_MTD=m
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=m
-CONFIG_MTD_CONCAT=m
-CONFIG_MTD_REDBOOT_PARTS=m
-CONFIG_MTD_CMDLINE_PARTS=m
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
#
-# User Modules And Translation Layers
+# IPVS transport protocol load balancing support
#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=m
-CONFIG_MTD_BLOCK_RO=m
-CONFIG_FTL=m
-CONFIG_NFTL=m
-CONFIG_NFTL_RW=y
-CONFIG_INFTL=m
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
#
-# RAM/ROM/Flash chip drivers
+# IPVS scheduler
#
-CONFIG_MTD_CFI=m
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_GEN_PROBE=m
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_CFI_INTELEXT=m
-CONFIG_MTD_CFI_AMDSTD=m
-CONFIG_MTD_CFI_STAA=m
-CONFIG_MTD_RAM=m
-CONFIG_MTD_ROM=m
-CONFIG_MTD_ABSENT=m
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
#
-# Mapping drivers for chip access
+# IPVS application helper
#
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_PNC2000 is not set
-CONFIG_MTD_SC520CDP=m
-CONFIG_MTD_NETSC520=m
-CONFIG_MTD_SBC_GXX=m
-CONFIG_MTD_ELAN_104NC=m
-CONFIG_MTD_SCx200_DOCFLASH=m
-CONFIG_MTD_AMD76XROM=m
-CONFIG_MTD_ICH2ROM=m
-CONFIG_MTD_SCB2_FLASH=m
-# CONFIG_MTD_NETtel is not set
-# CONFIG_MTD_DILNETPC is not set
-CONFIG_MTD_L440GX=m
-CONFIG_MTD_PCI=m
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
#
-# Self-contained MTD device drivers
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+
#
-CONFIG_MTD_PMC551=m
-# CONFIG_MTD_PMC551_BUGFIX is not set
-# CONFIG_MTD_PMC551_DEBUG is not set
-# CONFIG_MTD_SLRAM is not set
-CONFIG_MTD_MTDRAM=m
-CONFIG_MTDRAM_TOTAL_SIZE=4096
-CONFIG_MTDRAM_ERASE_SIZE=128
-# CONFIG_MTD_BLKMTD is not set
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_NETBIOS_NS=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_PPTP=m
+CONFIG_IP_NF_H323=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_PPTP=m
+CONFIG_IP_NF_NAT_H323=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
#
-# Disk-On-Chip Device Drivers
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
-CONFIG_MTD_DOC2000=m
-# CONFIG_MTD_DOC2001 is not set
-CONFIG_MTD_DOC2001PLUS=m
-CONFIG_MTD_DOCPROBE=m
-# CONFIG_MTD_DOCPROBE_ADVANCED is not set
-CONFIG_MTD_DOCPROBE_ADDRESS=0
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_RAW=m
#
-# NAND Flash Device Drivers
+# DECnet: Netfilter Configuration
#
-CONFIG_MTD_NAND=m
-# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-CONFIG_MTD_NAND_IDS=m
+# CONFIG_DECNET_NF_GRABULATOR is not set
#
-# Parallel port support
+# Bridge: Netfilter Configuration
#
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
-CONFIG_PARPORT_SERIAL=m
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
-CONFIG_PARPORT_PC_PCMCIA=m
-# CONFIG_PARPORT_OTHER is not set
-CONFIG_PARPORT_1284=y
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
#
-# Plug and Play support
+# DCCP Configuration (EXPERIMENTAL)
#
-CONFIG_PNP=y
-# CONFIG_PNP_DEBUG is not set
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
#
-# Protocols
+# DCCP CCIDs Configuration (EXPERIMENTAL)
#
-CONFIG_ISAPNP=y
-# CONFIG_PNPBIOS is not set
+CONFIG_IP_DCCP_CCID2=m
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
#
-# Block devices
+# DCCP Kernel Hacking
#
-CONFIG_BLK_DEV_FD=m
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-CONFIG_BLK_CPQ_DA=m
-CONFIG_BLK_CPQ_CISS_DA=m
-CONFIG_CISS_SCSI_TAPE=y
-CONFIG_BLK_DEV_DAC960=m
-CONFIG_BLK_DEV_UMEM=m
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_CARMEL=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_LBD=y
+# CONFIG_IP_DCCP_DEBUG is not set
#
-# ATA/ATAPI/MFM/RLL support
+# SCTP Configuration (EXPERIMENTAL)
#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
#
-# Please see Documentation/ide.txt for help/info on IDE drives
+# TIPC Configuration (EXPERIMENTAL)
#
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_IDEDISK_STROKE is not set
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=y
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDE_TASKFILE_IO is not set
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=y
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+CONFIG_NET_DIVERT=y
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
#
-# IDE chipset support/bugfixes
+# QoS and/or fair queueing
#
-CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_CMD640 is not set
-CONFIG_BLK_DEV_IDEPNP=y
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_SHARE_IRQ=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_RZ1000=y
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_ADMA=y
-CONFIG_BLK_DEV_AEC62XX=y
-CONFIG_BLK_DEV_ALI15X3=y
-# CONFIG_WDC_ALI15X3 is not set
-CONFIG_BLK_DEV_AMD74XX=y
-CONFIG_BLK_DEV_ATIIXP=y
-CONFIG_BLK_DEV_CMD64X=y
-CONFIG_BLK_DEV_TRIFLEX=y
-CONFIG_BLK_DEV_CY82C693=y
-CONFIG_BLK_DEV_CS5520=y
-CONFIG_BLK_DEV_CS5530=y
-CONFIG_BLK_DEV_HPT34X=y
-# CONFIG_HPT34X_AUTODMA is not set
-CONFIG_BLK_DEV_HPT366=y
-# CONFIG_BLK_DEV_SC1200 is not set
-CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_NS87415 is not set
-CONFIG_BLK_DEV_PDC202XX_OLD=y
-# CONFIG_PDC202XX_BURST is not set
-CONFIG_BLK_DEV_PDC202XX_NEW=y
-CONFIG_PDC202XX_FORCE=y
-CONFIG_BLK_DEV_SVWKS=y
-CONFIG_BLK_DEV_SIIMAGE=y
-CONFIG_BLK_DEV_SIS5513=y
-CONFIG_BLK_DEV_SLC90E66=y
-# CONFIG_BLK_DEV_TRM290 is not set
-CONFIG_BLK_DEV_VIA82CXXX=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_IDE_CHIPSETS is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_BLK_DEV_HD is not set
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
#
-# SCSI device support
+# Queueing/Scheduling
#
-CONFIG_SCSI=m
-CONFIG_SCSI_PROC_FS=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
#
-# SCSI support type (disk, tape, CD-ROM)
+# Classification
#
-CONFIG_BLK_DEV_SD=m
-CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+# Network testing
#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
#
-# SCSI Transport Attributes
+# IrDA protocols
#
-CONFIG_SCSI_SPI_ATTRS=m
-CONFIG_SCSI_FC_ATTRS=m
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
#
-# SCSI low-level drivers
+# IrDA options
#
-CONFIG_BLK_DEV_3W_XXXX_RAID=m
-# CONFIG_SCSI_7000FASST is not set
-CONFIG_SCSI_ACARD=m
-CONFIG_SCSI_AHA152X=m
-CONFIG_SCSI_AHA1542=m
-CONFIG_SCSI_AACRAID=m
-CONFIG_SCSI_AIC7XXX=m
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
-CONFIG_AIC7XXX_RESET_DELAY_MS=15000
-# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
-# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
-CONFIG_AIC7XXX_DEBUG_MASK=0
-# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
-CONFIG_SCSI_AIC7XXX_OLD=m
-CONFIG_SCSI_AIC79XX=m
-CONFIG_AIC79XX_CMDS_PER_DEVICE=4
-CONFIG_AIC79XX_RESET_DELAY_MS=15000
-# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
-# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
-# CONFIG_AIC79XX_DEBUG_ENABLE is not set
-CONFIG_AIC79XX_DEBUG_MASK=0
-# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
-# CONFIG_SCSI_DPT_I2O is not set
-CONFIG_SCSI_ADVANSYS=m
-CONFIG_SCSI_IN2000=m
-CONFIG_SCSI_MEGARAID=m
-CONFIG_SCSI_SATA=y
-CONFIG_SCSI_SATA_SVW=m
-CONFIG_SCSI_ATA_PIIX=m
-CONFIG_SCSI_SATA_PROMISE=m
-CONFIG_SCSI_SATA_SX4=m
-CONFIG_SCSI_SATA_SIL=m
-CONFIG_SCSI_SATA_SIS=m
-CONFIG_SCSI_SATA_VIA=m
-CONFIG_SCSI_SATA_VITESSE=m
-CONFIG_SCSI_BUSLOGIC=m
-# CONFIG_SCSI_OMIT_FLASHPOINT is not set
-# CONFIG_SCSI_CPQFCTS is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-CONFIG_SCSI_FUTURE_DOMAIN=m
-CONFIG_SCSI_GDTH=m
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
-CONFIG_SCSI_IPS=m
-CONFIG_SCSI_INIA100=m
-CONFIG_SCSI_PPA=m
-CONFIG_SCSI_IMM=m
-# CONFIG_SCSI_IZIP_EPP16 is not set
-# CONFIG_SCSI_IZIP_SLOW_CTR is not set
-# CONFIG_SCSI_NCR53C406A is not set
-CONFIG_SCSI_SYM53C8XX_2=m
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PSI240I is not set
-CONFIG_SCSI_QLOGIC_FAS=m
-CONFIG_SCSI_QLOGIC_ISP=m
-# CONFIG_SCSI_QLOGIC_FC is not set
-CONFIG_SCSI_QLOGIC_1280=m
-CONFIG_SCSI_QLA2XXX=m
-CONFIG_SCSI_QLA21XX=m
-CONFIG_SCSI_QLA22XX=m
-CONFIG_SCSI_QLA2300=m
-CONFIG_SCSI_QLA2322=m
-CONFIG_SCSI_QLA6312=m
-CONFIG_SCSI_QLA6322=m
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC395x is not set
-CONFIG_SCSI_DC390T=m
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
#
-# PCMCIA SCSI adapter support
+# Infrared-port device drivers
#
-CONFIG_PCMCIA_AHA152X=m
-CONFIG_PCMCIA_FDOMAIN=m
-CONFIG_PCMCIA_NINJA_SCSI=m
-CONFIG_PCMCIA_QLOGIC=m
-CONFIG_PCMCIA_SYM53C500=m
#
-# Old CD-ROM drivers (not SCSI, not IDE)
+# SIR device drivers
#
-# CONFIG_CD_NO_IDESCSI is not set
+CONFIG_IRTTY_SIR=m
#
-# Multi-device support (RAID and LVM)
+# Dongle support
#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID5=m
-CONFIG_MD_RAID6=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_TOIM3232_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
#
-# Fusion MPT device support
+# Old SIR device drivers
#
-CONFIG_FUSION=m
-CONFIG_FUSION_MAX_SGE=40
-# CONFIG_FUSION_ISENSE is not set
-CONFIG_FUSION_CTL=m
-CONFIG_FUSION_LAN=m
+CONFIG_IRPORT_SIR=m
#
-# IEEE 1394 (FireWire) support
+# Old Serial dongle support
#
-CONFIG_IEEE1394=m
+# CONFIG_DONGLE_OLD is not set
#
-# Subsystem Options
+# FIR device drivers
#
-# CONFIG_IEEE1394_VERBOSEDEBUG is not set
-CONFIG_IEEE1394_OUI_DB=y
-# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_CMTP=m
+CONFIG_BT_HIDP=m
#
-# Device Drivers
+# Bluetooth device drivers
#
-# CONFIG_IEEE1394_PCILYNX is not set
-CONFIG_IEEE1394_OHCI1394=m
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_TUX=m
#
-# Protocol Drivers
+# TUX options
#
-CONFIG_IEEE1394_VIDEO1394=m
-CONFIG_IEEE1394_SBP2=m
-# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
-# CONFIG_IEEE1394_ETH1394 is not set
-CONFIG_IEEE1394_DV1394=m
-CONFIG_IEEE1394_RAWIO=m
-CONFIG_IEEE1394_CMP=m
-CONFIG_IEEE1394_AMDTP=m
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
#
-# I2O device support
+# Device Drivers
#
-CONFIG_I2O=m
-CONFIG_I2O_CONFIG=m
-CONFIG_I2O_BLOCK=m
-CONFIG_I2O_SCSI=m
-CONFIG_I2O_PROC=m
#
-# Networking support
+# Generic Driver Options
#
-CONFIG_NET=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
#
-# Networking options
+# Connector - unified userspace <-> kernelspace linker
#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_FWMARK=y
-CONFIG_IP_ROUTE_NAT=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_TOS=y
-CONFIG_IP_ROUTE_VERBOSE=y
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
+CONFIG_CONNECTOR=m
#
-# IP: Virtual Server Configuration
+# Memory Technology Devices (MTD)
#
-CONFIG_IP_VS=m
-# CONFIG_IP_VS_DEBUG is not set
-CONFIG_IP_VS_TAB_BITS=12
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
#
-# IPVS transport protocol load balancing support
+# User Modules And Translation Layers
#
-CONFIG_IP_VS_PROTO_TCP=y
-CONFIG_IP_VS_PROTO_UDP=y
-CONFIG_IP_VS_PROTO_ESP=y
-CONFIG_IP_VS_PROTO_AH=y
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
#
-# IPVS scheduler
+# RAM/ROM/Flash chip drivers
#
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
-# IPVS application helper
+# Mapping drivers for chip access
#
-CONFIG_IP_VS_FTP=m
-CONFIG_IPV6=m
-CONFIG_IPV6_PRIVACY=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_BRIDGE_NETFILTER=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PNC2000 is not set
+CONFIG_MTD_SC520CDP=m
+CONFIG_MTD_NETSC520=m
+CONFIG_MTD_TS5500=m
+# CONFIG_MTD_SBC_GXX is not set
+# CONFIG_MTD_AMD76XROM is not set
+# CONFIG_MTD_ICHXROM is not set
+CONFIG_MTD_SCB2_FLASH=m
+# CONFIG_MTD_NETtel is not set
+# CONFIG_MTD_DILNETPC is not set
+# CONFIG_MTD_L440GX is not set
+CONFIG_MTD_PCI=m
+# CONFIG_MTD_PLATRAM is not set
#
-# IP: Netfilter Configuration
+# Self-contained MTD device drivers
#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_PHYSDEV=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_LOCAL=y
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_RAW=m
+CONFIG_MTD_PMC551=m
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
#
-# IPv6: Netfilter Configuration
+# Disk-On-Chip Device Drivers
#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_FRAG=m
-CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-CONFIG_IP6_NF_RAW=m
+CONFIG_MTD_DOC2000=m
+# CONFIG_MTD_DOC2001 is not set
+CONFIG_MTD_DOC2001PLUS=m
+CONFIG_MTD_DOCPROBE=m
+CONFIG_MTD_DOCECC=m
+# CONFIG_MTD_DOCPROBE_ADVANCED is not set
+CONFIG_MTD_DOCPROBE_ADDRESS=0
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=m
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_NANDSIM=m
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_PCMCIA=m
+CONFIG_PARPORT_NOT_PC=y
+# CONFIG_PARPORT_GSC is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+# CONFIG_PNPBIOS is not set
+CONFIG_PNPACPI=y
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_CPQ_DA=m
+CONFIG_BLK_CPQ_CISS_DA=m
+CONFIG_CISS_SCSI_TAPE=y
+CONFIG_BLK_DEV_DAC960=m
+CONFIG_BLK_DEV_UMEM=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_CMD640=y
+CONFIG_BLK_DEV_CMD640_ENHANCED=y
+CONFIG_BLK_DEV_IDEPNP=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_RZ1000=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+CONFIG_BLK_DEV_ALI15X3=y
+# CONFIG_WDC_ALI15X3 is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_BLK_DEV_ATIIXP=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_TRIFLEX=y
+CONFIG_BLK_DEV_CY82C693=y
+CONFIG_BLK_DEV_CS5520=y
+CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_CS5535=y
+CONFIG_BLK_DEV_HPT34X=y
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT821X=y
+# CONFIG_BLK_DEV_NS87415 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+CONFIG_BLK_DEV_SVWKS=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_BLK_DEV_SIS5513=y
+CONFIG_BLK_DEV_SLC90E66=y
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
#
-# Bridge: Netfilter Configuration
+# SCSI device support
#
-CONFIG_BRIDGE_NF_EBTABLES=m
-CONFIG_BRIDGE_EBT_BROUTE=m
-CONFIG_BRIDGE_EBT_T_FILTER=m
-CONFIG_BRIDGE_EBT_T_NAT=m
-CONFIG_BRIDGE_EBT_802_3=m
-CONFIG_BRIDGE_EBT_AMONG=m
-CONFIG_BRIDGE_EBT_ARP=m
-CONFIG_BRIDGE_EBT_IP=m
-CONFIG_BRIDGE_EBT_LIMIT=m
-CONFIG_BRIDGE_EBT_MARK=m
-CONFIG_BRIDGE_EBT_PKTTYPE=m
-CONFIG_BRIDGE_EBT_STP=m
-CONFIG_BRIDGE_EBT_VLAN=m
-CONFIG_BRIDGE_EBT_ARPREPLY=m
-CONFIG_BRIDGE_EBT_DNAT=m
-CONFIG_BRIDGE_EBT_MARK_T=m
-CONFIG_BRIDGE_EBT_REDIRECT=m
-CONFIG_BRIDGE_EBT_SNAT=m
-CONFIG_BRIDGE_EBT_LOG=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
#
-# SCTP Configuration (EXPERIMENTAL)
+# SCSI support type (disk, tape, CD-ROM)
#
-CONFIG_IP_SCTP=m
-# CONFIG_SCTP_DBG_MSG is not set
-# CONFIG_SCTP_DBG_OBJCNT is not set
-# CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
-# CONFIG_ATM is not set
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-# CONFIG_DECNET is not set
-CONFIG_LLC=m
-# CONFIG_LLC2 is not set
-CONFIG_IPX=m
-# CONFIG_IPX_INTERN is not set
-CONFIG_ATALK=m
-CONFIG_DEV_APPLETALK=y
-CONFIG_LTPC=m
-CONFIG_COPS=m
-CONFIG_COPS_DAYNA=y
-CONFIG_COPS_TANGENT=y
-CONFIG_IPDDP=m
-CONFIG_IPDDP_ENCAP=y
-CONFIG_IPDDP_DECAP=y
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-CONFIG_NET_DIVERT=y
-# CONFIG_ECONET is not set
-CONFIG_WAN_ROUTER=m
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
#
-# QoS and/or fair queueing
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_CSZ=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_DELAY=m
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_CLS_POLICE=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
#
-# Network testing
+# SCSI Transport Attributes
#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_NETPOLL=y
-# CONFIG_NETPOLL_RX is not set
-# CONFIG_NETPOLL_TRAP is not set
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_HAMRADIO is not set
-CONFIG_IRDA=m
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
#
-# IrDA protocols
+# SCSI low-level drivers
#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-# CONFIG_IRDA_ULTRA is not set
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+# CONFIG_SCSI_7000FASST is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=4
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_ADVANSYS=m
+# CONFIG_SCSI_IN2000 is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
+CONFIG_SCSI_SATA=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+CONFIG_SCSI_ATA_PIIX=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_PDC_ADMA=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+CONFIG_SCSI_IPS=m
+CONFIG_SCSI_INITIO=m
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+CONFIG_SCSI_SYM53C8XX_2=m
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+CONFIG_SCSI_SYM53C8XX_MMIO=y
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE=y
+CONFIG_SCSI_QLA21XX=m
+CONFIG_SCSI_QLA22XX=m
+CONFIG_SCSI_QLA2300=m
+CONFIG_SCSI_QLA2322=m
+CONFIG_SCSI_QLA24XX=m
+CONFIG_SCSI_LPFC=m
+# CONFIG_SCSI_SYM53C416 is not set
+CONFIG_SCSI_DC395x=m
+CONFIG_SCSI_DC390T=m
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
#
-# IrDA options
+# PCMCIA SCSI adapter support
#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-# CONFIG_IRDA_DEBUG is not set
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
#
-# Infrared-port device drivers
+# Old CD-ROM drivers (not SCSI, not IDE)
#
+# CONFIG_CD_NO_IDESCSI is not set
#
-# SIR device drivers
+# Multi-device support (RAID and LVM)
#
-CONFIG_IRTTY_SIR=m
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
#
-# Dongle support
+# Fusion MPT device support
#
-CONFIG_DONGLE=y
-CONFIG_ESI_DONGLE=m
-CONFIG_ACTISYS_DONGLE=m
-CONFIG_TEKRAM_DONGLE=m
-CONFIG_LITELINK_DONGLE=m
-CONFIG_MA600_DONGLE=m
-CONFIG_GIRBIL_DONGLE=m
-CONFIG_MCP2120_DONGLE=m
-CONFIG_OLD_BELKIN_DONGLE=m
-CONFIG_ACT200L_DONGLE=m
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=m
+CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_LAN=m
#
-# Old SIR device drivers
+# IEEE 1394 (FireWire) support
#
+CONFIG_IEEE1394=m
#
-# Old Serial dongle support
+# Subsystem Options
#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
#
-# FIR device drivers
+# Device Drivers
#
-CONFIG_USB_IRDA=m
-CONFIG_SIGMATEL_FIR=m
-CONFIG_NSC_FIR=m
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-# CONFIG_VIA_FIR is not set
-CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
-CONFIG_BT_RFCOMM=m
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=m
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_CMTP=m
+CONFIG_IEEE1394_PCILYNX=m
+CONFIG_IEEE1394_OHCI1394=m
#
-# Bluetooth device drivers
+# Protocol Drivers
#
-CONFIG_BT_HCIUSB=m
-CONFIG_BT_HCIUSB_SCO=y
-CONFIG_BT_HCIUART=m
-CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_BCSP_TXCRC=y
-CONFIG_BT_HCIBCM203X=m
-CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIDTL1=m
-CONFIG_BT_HCIBT3C=m
-CONFIG_BT_HCIBLUECARD=m
-CONFIG_BT_HCIBTUART=m
-CONFIG_BT_HCIVHCI=m
-CONFIG_TUX=m
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
#
-# TUX options
+# I2O device support
+#
+CONFIG_I2O=m
+# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
+CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_CONFIG=m
+CONFIG_I2O_CONFIG_OLD_IOCTL=y
+CONFIG_I2O_BUS=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+
+#
+# Network device support
#
-CONFIG_TUX_EXTCGI=y
-# CONFIG_TUX_EXTENDED_LOG is not set
-# CONFIG_TUX_DEBUG is not set
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-CONFIG_ETHERTAP=m
CONFIG_NET_SB1000=m
#
#
# 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)
#
CONFIG_MII=m
CONFIG_HAPPYMEAL=m
CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
CONFIG_NET_VENDOR_3COM=y
-CONFIG_EL1=m
-CONFIG_EL2=m
-CONFIG_ELPLUS=m
-CONFIG_EL16=m
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
CONFIG_EL3=m
-CONFIG_3C515=m
+# CONFIG_3C515 is not set
CONFIG_VORTEX=m
CONFIG_TYPHOON=m
-CONFIG_LANCE=m
+# CONFIG_LANCE is not set
CONFIG_NET_VENDOR_SMC=y
-CONFIG_WD80x3=m
+# CONFIG_WD80x3 is not set
CONFIG_ULTRA=m
-CONFIG_SMC9194=m
-CONFIG_NET_VENDOR_RACAL=y
-CONFIG_NI52=m
-CONFIG_NI65=m
+# CONFIG_SMC9194 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
#
# Tulip family network device support
CONFIG_DE4X5=m
CONFIG_WINBOND_840=m
CONFIG_DM9102=m
+CONFIG_ULI526X=m
CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_PCMCIA_XIRTULIP is not set
# CONFIG_AT1700 is not set
-CONFIG_DEPCA=m
+# CONFIG_DEPCA is not set
CONFIG_HP100=m
-# CONFIG_NET_ISA is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+CONFIG_EWRK3=m
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
CONFIG_NE2000=m
+# CONFIG_ZNET is not set
+# CONFIG_SEEQ8005 is not set
CONFIG_NET_PCI=y
CONFIG_PCNET32=m
CONFIG_AMD8111_ETH=m
CONFIG_AMD8111E_NAPI=y
CONFIG_ADAPTEC_STARFIRE=m
CONFIG_ADAPTEC_STARFIRE_NAPI=y
-CONFIG_AC3200=m
-CONFIG_APRICOT=m
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
CONFIG_B44=m
CONFIG_FORCEDETH=m
-CONFIG_CS89x0=m
+# CONFIG_CS89x0 is not set
CONFIG_DGRS=m
-CONFIG_EEPRO100=m
-# CONFIG_EEPRO100_PIO is not set
+# CONFIG_EEPRO100 is not set
CONFIG_E100=m
-CONFIG_E100_NAPI=y
CONFIG_FEALNX=m
CONFIG_NATSEMI=m
CONFIG_NE2K_PCI=m
CONFIG_8139CP=m
CONFIG_8139TOO=m
-CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_PIO is not set
# CONFIG_8139TOO_TUNE_TWISTER is not set
CONFIG_8139TOO_8129=y
# CONFIG_8139_OLD_RX_RESET is not set
CONFIG_DE620=m
#
-# Gigabit Ethernet (1000/10000 Mbit)
+# Ethernet (1000 Mbit)
#
-CONFIG_NET_GIGE=y
CONFIG_ACENIC=m
# CONFIG_ACENIC_OMIT_TIGON_I is not set
CONFIG_DL2K=m
CONFIG_E1000=m
CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
CONFIG_NS83820=m
CONFIG_HAMACHI=m
CONFIG_YELLOWFIN=m
CONFIG_R8169=m
-CONFIG_SK98LIN=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+# CONFIG_SK98LIN is not set
+CONFIG_VIA_VELOCITY=m
CONFIG_TIGON3=m
+CONFIG_BNX2=m
+
+#
+# Ethernet (10000 Mbit)
+#
+CONFIG_CHELSIO_T1=m
CONFIG_IXGB=m
CONFIG_IXGB_NAPI=y
CONFIG_S2IO=m
#
# Token Ring devices
#
-# CONFIG_TR is not set
+CONFIG_TR=y
+# CONFIG_IBMTR is not set
+CONFIG_IBMOL=m
+CONFIG_IBMLS=m
+CONFIG_3C359=m
+# CONFIG_TMS380TR is not set
+# CONFIG_SMCTR is not set
#
# Wireless LAN (non-hamradio)
#
CONFIG_NET_RADIO=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
#
# Obsolete Wireless cards support (pre-802.11)
#
# CONFIG_STRIP is not set
# CONFIG_ARLAN is not set
-CONFIG_WAVELAN=m
+# CONFIG_WAVELAN is not set
CONFIG_PCMCIA_WAVELAN=m
CONFIG_PCMCIA_NETWAVE=m
#
# Wireless 802.11b ISA/PCI cards support
#
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100_DEBUG is not set
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW_QOS=y
+# CONFIG_IPW2200_DEBUG is not set
CONFIG_AIRO=m
CONFIG_HERMES=m
CONFIG_PLX_HERMES=m
CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
CONFIG_PCI_HERMES=m
CONFIG_ATMEL=m
CONFIG_PCI_ATMEL=m
# 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
# 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_PCMCIA_SMC91C92=m
CONFIG_PCMCIA_XIRC2PS=m
CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_IBMTR=m
#
# Wan interfaces
#
# CONFIG_WAN is not set
+
+#
+# ATM drivers
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+# CONFIG_ATM_IA is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
CONFIG_FDDI=y
# CONFIG_DEFXX is not set
CONFIG_SKFP=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_PPP_DEFLATE=m
# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
CONFIG_PPPOE=m
-# CONFIG_SLIP is not set
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
CONFIG_NET_FC=y
# CONFIG_SHAPER is not set
CONFIG_NETCONSOLE=m
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
#
# ISDN subsystem
#
# ISDN feature submodules
#
+CONFIG_ISDN_DRV_LOOP=m
+CONFIG_ISDN_DIVERSION=m
#
# ISDN4Linux hardware drivers
#
# HiSax supported cards
#
-CONFIG_HISAX_16_0=y
+# CONFIG_HISAX_16_0 is not set
CONFIG_HISAX_16_3=y
CONFIG_HISAX_TELESPCI=y
CONFIG_HISAX_S0BOX=y
-CONFIG_HISAX_AVM_A1=y
+# CONFIG_HISAX_AVM_A1 is not set
CONFIG_HISAX_FRITZPCI=y
CONFIG_HISAX_AVM_A1_PCMCIA=y
CONFIG_HISAX_ELSA=y
-CONFIG_HISAX_IX1MICROR2=y
+# CONFIG_HISAX_IX1MICROR2 is not set
CONFIG_HISAX_DIEHLDIVA=y
-CONFIG_HISAX_ASUSCOM=y
-CONFIG_HISAX_TELEINT=y
-CONFIG_HISAX_HFCS=y
+# CONFIG_HISAX_ASUSCOM is not set
+# CONFIG_HISAX_TELEINT is not set
+# CONFIG_HISAX_HFCS is not set
CONFIG_HISAX_SEDLBAUER=y
-CONFIG_HISAX_SPORTSTER=y
-CONFIG_HISAX_MIC=y
+# CONFIG_HISAX_SPORTSTER is not set
+# CONFIG_HISAX_MIC is not set
CONFIG_HISAX_NETJET=y
CONFIG_HISAX_NETJET_U=y
CONFIG_HISAX_NICCY=y
-CONFIG_HISAX_ISURF=y
-CONFIG_HISAX_HSTSAPHIR=y
+# CONFIG_HISAX_ISURF is not set
+# CONFIG_HISAX_HSTSAPHIR is not set
CONFIG_HISAX_BKM_A4T=y
CONFIG_HISAX_SCT_QUADRO=y
CONFIG_HISAX_GAZEL=y
# HiSax sub driver modules
#
CONFIG_HISAX_ST5481=m
-CONFIG_HISAX_HFCUSB=m
+# CONFIG_HISAX_HFCUSB is not set
+CONFIG_HISAX_HFC4S8S=m
CONFIG_HISAX_FRITZ_PCIPNP=m
CONFIG_HISAX_HDLC=y
#
# Active cards
#
-CONFIG_ISDN_DRV_ICN=m
-CONFIG_ISDN_DRV_PCBIT=m
-CONFIG_ISDN_DRV_SC=m
-CONFIG_ISDN_DRV_ACT2000=m
-CONFIG_ISDN_DRV_TPAM=m
+# CONFIG_ISDN_DRV_ICN is not set
+# CONFIG_ISDN_DRV_PCBIT is not set
+# CONFIG_ISDN_DRV_SC is not set
+# CONFIG_ISDN_DRV_ACT2000 is not set
+CONFIG_HYSDN=m
+CONFIG_HYSDN_CAPI=y
+
+#
+# Siemens Gigaset
+#
+CONFIG_ISDN_DRV_GIGASET=m
+CONFIG_GIGASET_BASE=m
+CONFIG_GIGASET_M105=m
+# CONFIG_GIGASET_DEBUG is not set
+# CONFIG_GIGASET_UNDOCREQ is not set
#
# CAPI subsystem
# 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
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
#
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_JOYSTICK_SPACEORB=m
CONFIG_JOYSTICK_SPACEBALL=m
CONFIG_JOYSTICK_STINGER=m
-CONFIG_JOYSTICK_TWIDDLER=m
+CONFIG_JOYSTICK_TWIDJOY=m
CONFIG_JOYSTICK_DB9=m
CONFIG_JOYSTICK_GAMECON=m
CONFIG_JOYSTICK_TURBOGRAFX=m
-# CONFIG_INPUT_JOYDUMP is not set
+CONFIG_JOYSTICK_JOYDUMP=m
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PCSPKR=m
-# CONFIG_INPUT_UINPUT is not set
+CONFIG_INPUT_WISTRON_BTNS=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
#
# Character devices
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
CONFIG_ROCKETPORT=m
# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
CONFIG_SYNCLINK=m
CONFIG_SYNCLINKMP=m
+# CONFIG_SYNCLINK_GT is not set
CONFIG_N_HDLC=m
-CONFIG_STALDRV=y
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
CONFIG_SERIAL_8250_CS=m
-# CONFIG_SERIAL_8250_ACPI is not set
-CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_MULTIPORT=y
CONFIG_SERIAL_8250_RSA=y
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_CRASH=m
CONFIG_LP_CONSOLE=y
CONFIG_PPDEV=m
CONFIG_TIPAR=m
-# CONFIG_QIC02_TAPE is not set
#
# IPMI
CONFIG_IPMI_DEVICE_INTERFACE=m
CONFIG_IPMI_SI=m
CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
#
# Watchdog Cards
# Watchdog Device Drivers
#
CONFIG_SOFT_WATCHDOG=m
-CONFIG_ACQUIRE_WDT=m
-CONFIG_ADVANTECH_WDT=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
CONFIG_ALIM1535_WDT=m
CONFIG_ALIM7101_WDT=m
-CONFIG_SC520_WDT=m
-CONFIG_EUROTECH_WDT=m
-CONFIG_IB700_WDT=m
-CONFIG_WAFER_WDT=m
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+CONFIG_IBMASR=m
+# CONFIG_WAFER_WDT is not set
+CONFIG_I6300ESB_WDT=m
CONFIG_I8XX_TCO=m
-CONFIG_SC1200_WDT=m
-# CONFIG_SCx200_WDT is not set
+# CONFIG_SC1200_WDT is not set
# CONFIG_60XX_WDT is not set
-CONFIG_CPU5_WDT=m
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
CONFIG_W83627HF_WDT=m
CONFIG_W83877F_WDT=m
+CONFIG_W83977F_WDT=m
CONFIG_MACHZ_WDT=m
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
#
# ISA-based Watchdog Cards
#
-CONFIG_PCWATCHDOG=m
+# CONFIG_PCWATCHDOG is not set
# CONFIG_MIXCOMWD is not set
-CONFIG_WDT=m
-# CONFIG_WDT_501 is not set
+# CONFIG_WDT is not set
#
# PCI-based Watchdog Cards
#
CONFIG_USBPCWATCHDOG=m
CONFIG_HW_RANDOM=m
-CONFIG_NVRAM=m
+CONFIG_NVRAM=y
CONFIG_RTC=y
CONFIG_DTLK=m
CONFIG_R3964=m
#
# Ftape, the floppy tape device driver
#
+# CONFIG_FTAPE is not set
CONFIG_AGP=y
CONFIG_AGP_ALI=y
CONFIG_AGP_ATI=y
CONFIG_AGP_AMD=y
CONFIG_AGP_AMD64=y
CONFIG_AGP_INTEL=y
-CONFIG_AGP_INTEL_MCH=y
CONFIG_AGP_NVIDIA=y
CONFIG_AGP_SIS=y
CONFIG_AGP_SWORKS=y
CONFIG_AGP_VIA=y
CONFIG_AGP_EFFICEON=y
-CONFIG_DRM=y
+CONFIG_DRM=m
CONFIG_DRM_TDFX=m
-CONFIG_DRM_GAMMA=m
CONFIG_DRM_R128=m
CONFIG_DRM_RADEON=m
CONFIG_DRM_I810=m
CONFIG_DRM_I830=m
+CONFIG_DRM_I915=m
CONFIG_DRM_MGA=m
CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
#
# PCMCIA character devices
#
CONFIG_SYNCLINK_CS=m
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
CONFIG_MWAVE=m
+CONFIG_CS5535_GPIO=m
# CONFIG_RAW_DRIVER is not set
+CONFIG_HPET=y
+# CONFIG_HPET_RTC_IRQ is not set
+# CONFIG_HPET_MMAP is not set
CONFIG_HANGCHECK_TIMER=m
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
#
# I2C support
#
#
CONFIG_I2C_ALGOBIT=m
CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
#
# I2C Hardware Bus support
CONFIG_I2C_ALI1563=m
CONFIG_I2C_ALI15X3=m
CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
CONFIG_I2C_AMD8111=m
+# CONFIG_I2C_ELEKTOR is not set
CONFIG_I2C_I801=m
CONFIG_I2C_I810=m
+CONFIG_I2C_PIIX4=m
CONFIG_I2C_ISA=m
CONFIG_I2C_NFORCE2=m
-# CONFIG_I2C_PARPORT is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-CONFIG_I2C_PIIX4=m
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
CONFIG_I2C_PROSAVAGE=m
CONFIG_I2C_SAVAGE4=m
# CONFIG_SCx200_ACB is not set
CONFIG_I2C_SIS5595=m
CONFIG_I2C_SIS630=m
CONFIG_I2C_SIS96X=m
+CONFIG_I2C_STUB=m
CONFIG_I2C_VIA=m
CONFIG_I2C_VIAPRO=m
CONFIG_I2C_VOODOO3=m
+CONFIG_I2C_PCA_ISA=m
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+
+#
+# 1-wire Bus Masters
+#
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS9490=m
+CONFIG_W1_MASTER_DS9490_BRIDGE=m
+CONFIG_W1_MASTER_DS2482=m
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
#
-# Hardware Sensors Chip support
+# Hardware Monitoring support
#
-CONFIG_I2C_SENSOR=m
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_ATXP1=m
CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
CONFIG_SENSORS_LM78=m
CONFIG_SENSORS_LM80=m
CONFIG_SENSORS_LM83=m
CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47B397=m
CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83792D=m
CONFIG_SENSORS_W83L785TS=m
CONFIG_SENSORS_W83627HF=m
-
-#
-# Other I2C Chip support
-#
-CONFIG_SENSORS_EEPROM=m
-CONFIG_SENSORS_PCF8574=m
-CONFIG_SENSORS_PCF8591=m
-CONFIG_SENSORS_RTC8564=m
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_HDAPS=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
# Multimedia devices
#
CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=m
#
-# Video For Linux
+# Video Capture Adapters
#
#
-# Video Adapters
+# Video Capture Adapters
#
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_VIVI is not set
CONFIG_VIDEO_BT848=m
-CONFIG_VIDEO_PMS=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+# CONFIG_VIDEO_PMS is not set
CONFIG_VIDEO_BWQCAM=m
CONFIG_VIDEO_CQCAM=m
CONFIG_VIDEO_W9966=m
CONFIG_VIDEO_CPIA=m
CONFIG_VIDEO_CPIA_PP=m
CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
CONFIG_VIDEO_SAA5246A=m
CONFIG_VIDEO_SAA5249=m
CONFIG_TUNER_3036=m
CONFIG_VIDEO_ZORAN_DC30=m
CONFIG_VIDEO_ZORAN_LML33=m
CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_MEYE=m
CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
CONFIG_VIDEO_MXB=m
CONFIG_VIDEO_DPC=m
CONFIG_VIDEO_HEXIUM_ORION=m
CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88_VP3054=m
CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_OVCAMCHIP=m
+
+#
+# Encoders and Decoders
+#
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+
+#
+# V4L USB devices
+#
+CONFIG_VIDEO_EM28XX=m
+CONFIG_USB_DSBR=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_ET61X251=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
#
# Radio Adapters
#
-CONFIG_RADIO_CADET=m
-CONFIG_RADIO_RTRACK=m
-CONFIG_RADIO_RTRACK2=m
-CONFIG_RADIO_AZTECH=m
-CONFIG_RADIO_GEMTEK=m
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
CONFIG_RADIO_GEMTEK_PCI=m
CONFIG_RADIO_MAXIRADIO=m
CONFIG_RADIO_MAESTRO=m
-CONFIG_RADIO_SF16FMI=m
-CONFIG_RADIO_SF16FMR2=m
-CONFIG_RADIO_TERRATEC=m
-CONFIG_RADIO_TRUST=m
-CONFIG_RADIO_TYPHOON=m
-CONFIG_RADIO_TYPHOON_PROC_FS=y
-CONFIG_RADIO_ZOLTRIX=m
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
#
# Digital Video Broadcasting Devices
#
-# CONFIG_DVB is not set
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_S5H1420=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terresterial DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
CONFIG_VIDEO_SAA7146=m
CONFIG_VIDEO_SAA7146_VV=m
CONFIG_VIDEO_VIDEOBUF=m
CONFIG_VIDEO_TUNER=m
CONFIG_VIDEO_BUF=m
+CONFIG_VIDEO_BUF_DVB=m
CONFIG_VIDEO_BTCX=m
CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_USB_DABUSB=m
#
# Graphics support
#
CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_FIRMWARE_EDID is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ARC is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
CONFIG_FB_VGA16=m
CONFIG_FB_VESA=y
CONFIG_VIDEO_SELECT=y
-CONFIG_FB_HGA=m
-CONFIG_FB_HGA_ACCEL=y
+# CONFIG_FB_HGA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
CONFIG_FB_I810=m
CONFIG_FB_I810_GTF=y
+CONFIG_FB_I810_I2C=y
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
CONFIG_FB_MATROX=m
CONFIG_FB_MATROX_MILLENIUM=y
CONFIG_FB_MATROX_MYSTIQUE=y
-CONFIG_FB_MATROX_G450=y
-CONFIG_FB_MATROX_G100=y
+CONFIG_FB_MATROX_G=y
CONFIG_FB_MATROX_I2C=m
CONFIG_FB_MATROX_MAVEN=m
CONFIG_FB_MATROX_MULTIHEAD=y
-# CONFIG_FB_RADEON_OLD is not set
CONFIG_FB_RADEON=m
CONFIG_FB_RADEON_I2C=y
# CONFIG_FB_RADEON_DEBUG is not set
CONFIG_FB_ATY128=m
CONFIG_FB_ATY=m
CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
CONFIG_FB_ATY_GX=y
-# CONFIG_FB_ATY_XL_INIT is not set
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
# CONFIG_FB_SIS is not set
CONFIG_FB_NEOMAGIC=m
CONFIG_FB_KYRO=m
CONFIG_FB_3DFX=m
CONFIG_FB_3DFX_ACCEL=y
CONFIG_FB_VOODOO1=m
+CONFIG_FB_CYBLA=m
CONFIG_FB_TRIDENT=m
CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_GEODE is not set
# CONFIG_FB_VIRTUAL is not set
#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
-CONFIG_MDA_CONSOLE=m
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_PCI_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
# 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
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SEQUENCER_OSS=y
CONFIG_SND_RTCTIMER=m
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
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
#
# ISA devices
#
-CONFIG_SND_AD1816A=m
-CONFIG_SND_AD1848=m
-CONFIG_SND_CS4231=m
-CONFIG_SND_CS4232=m
+CONFIG_SND_CS4231_LIB=m
+CONFIG_SND_ADLIB=m
+# CONFIG_SND_AD1816A is not set
+# CONFIG_SND_AD1848 is not set
+# CONFIG_SND_ALS100 is not set
+# CONFIG_SND_AZT2320 is not set
+# CONFIG_SND_CMI8330 is not set
+# CONFIG_SND_CS4231 is not set
+# CONFIG_SND_CS4232 is not set
CONFIG_SND_CS4236=m
-CONFIG_SND_ES968=m
-CONFIG_SND_ES1688=m
+# CONFIG_SND_DT019X is not set
+# CONFIG_SND_ES968 is not set
+# CONFIG_SND_ES1688 is not set
CONFIG_SND_ES18XX=m
-CONFIG_SND_GUSCLASSIC=m
-CONFIG_SND_GUSEXTREME=m
-CONFIG_SND_GUSMAX=m
-CONFIG_SND_INTERWAVE=m
-CONFIG_SND_INTERWAVE_STB=m
-CONFIG_SND_OPTI92X_AD1848=m
-CONFIG_SND_OPTI92X_CS4231=m
-CONFIG_SND_OPTI93X=m
-CONFIG_SND_SB8=m
+# CONFIG_SND_GUSCLASSIC is not set
+# CONFIG_SND_GUSEXTREME is not set
+# CONFIG_SND_GUSMAX is not set
+# CONFIG_SND_INTERWAVE is not set
+# CONFIG_SND_INTERWAVE_STB is not set
+CONFIG_SND_OPL3SA2=m
+# CONFIG_SND_OPTI92X_AD1848 is not set
+# CONFIG_SND_OPTI92X_CS4231 is not set
+# CONFIG_SND_OPTI93X is not set
+CONFIG_SND_MIRO=m
+# CONFIG_SND_SB8 is not set
CONFIG_SND_SB16=m
CONFIG_SND_SBAWE=m
-CONFIG_SND_SB16_CSP=y
+# CONFIG_SND_SB16_CSP is not set
+# CONFIG_SND_SGALAXY is not set
+# CONFIG_SND_SSCAPE is not set
# CONFIG_SND_WAVEFRONT is not set
-CONFIG_SND_ALS100=m
-CONFIG_SND_AZT2320=m
-CONFIG_SND_CMI8330=m
-CONFIG_SND_DT019X=m
-CONFIG_SND_OPL3SA2=m
-CONFIG_SND_SGALAXY=m
-CONFIG_SND_SSCAPE=m
#
# PCI devices
#
-CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
CONFIG_SND_ALI5451=m
CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
CONFIG_SND_AU8810=m
CONFIG_SND_AU8820=m
CONFIG_SND_AU8830=m
CONFIG_SND_AZT3328=m
CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
CONFIG_SND_CS46XX=m
CONFIG_SND_CS46XX_NEW_DSP=y
-CONFIG_SND_CS4281=m
+CONFIG_SND_CS5535AUDIO=m
CONFIG_SND_EMU10K1=m
-CONFIG_SND_KORG1212=m
-CONFIG_SND_MIXART=m
-CONFIG_SND_NM256=m
-CONFIG_SND_RME32=m
-CONFIG_SND_RME96=m
-CONFIG_SND_RME9652=m
-CONFIG_SND_HDSP=m
-CONFIG_SND_TRIDENT=m
-CONFIG_SND_YMFPCI=m
-CONFIG_SND_ALS4000=m
-CONFIG_SND_CMIPCI=m
+CONFIG_SND_EMU10K1X=m
CONFIG_SND_ENS1370=m
CONFIG_SND_ENS1371=m
CONFIG_SND_ES1938=m
CONFIG_SND_ES1968=m
-CONFIG_SND_MAESTRO3=m
CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
CONFIG_SND_ICE1712=m
CONFIG_SND_ICE1724=m
CONFIG_SND_INTEL8X0=m
CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
#
-# ALSA USB devices
+# USB devices
#
CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
#
# PCMCIA devices
#
# CONFIG_SND_VXPOCKET is not set
-# CONFIG_SND_VXP440 is not set
-CONFIG_SND_PDAUDIOCF=m
+# CONFIG_SND_PDAUDIOCF is not set
#
# Open Sound System
#
# 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_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
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_EHCI_SPLIT_ISO=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_ISP116X_HCD=m
CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
#
# USB Device Class drivers
#
-CONFIG_USB_AUDIO=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
#
-# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
#
-CONFIG_USB_MIDI=m
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_ISD200=y
CONFIG_USB_STORAGE_DPCM=y
-CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_USBAT=y
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
#
-# USB Human Interface Devices (HID)
+# USB Input Devices
#
CONFIG_USB_HID=y
CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
CONFIG_HID_FF=y
CONFIG_HID_PID=y
CONFIG_LOGITECH_FF=y
CONFIG_USB_HIDDEV=y
CONFIG_USB_AIPTEK=m
CONFIG_USB_WACOM=m
+CONFIG_USB_ACECAD=m
CONFIG_USB_KBTAB=m
CONFIG_USB_POWERMATE=m
-CONFIG_USB_MTOUCH=m
-CONFIG_USB_EGALAX=m
+CONFIG_USB_TOUCHSCREEN=m
+CONFIG_USB_TOUCHSCREEN_EGALAX=y
+CONFIG_USB_TOUCHSCREEN_PANJIT=y
+CONFIG_USB_TOUCHSCREEN_3M=y
+CONFIG_USB_TOUCHSCREEN_ITM=y
+# CONFIG_USB_YEALINK is not set
CONFIG_USB_XPAD=m
CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_APPLETOUCH=m
#
# USB Imaging devices
#
CONFIG_USB_MDC800=m
CONFIG_USB_MICROTEK=m
-CONFIG_USB_HPUSBSCSI=m
-
-#
-# USB Multimedia devices
-#
-CONFIG_USB_DABUSB=m
-CONFIG_USB_VICAM=m
-CONFIG_USB_DSBR=m
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_KONICAWC=m
-CONFIG_USB_OV511=m
-CONFIG_USB_SE401=m
-CONFIG_USB_STV680=m
-CONFIG_USB_W9968CF=m
#
-# USB Network adaptors
+# USB Network Adapters
#
CONFIG_USB_CATC=m
CONFIG_USB_KAWETH=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_USBNET=m
-
-#
-# USB Host-to-Host Cables
-#
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
CONFIG_USB_BELKIN=y
-CONFIG_USB_GENESYS=y
-CONFIG_USB_NET1080=y
-CONFIG_USB_PL2301=y
-
-#
-# Intelligent USB Devices/Gadgets
-#
CONFIG_USB_ARMLINUX=y
CONFIG_USB_EPSON2888=y
-CONFIG_USB_ZAURUS=y
-CONFIG_USB_CDCETHER=y
-
-#
-# USB Network Adapters
-#
-CONFIG_USB_AX8817X=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_USB_ZD1201=m
+CONFIG_USB_MON=y
#
# USB port drivers
#
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ANYDATA=m
+CONFIG_USB_SERIAL_ARK3116=m
CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
CONFIG_USB_SERIAL_VISOR=m
CONFIG_USB_SERIAL_IPAQ=m
CONFIG_USB_SERIAL_IR=m
CONFIG_USB_SERIAL_EDGEPORT=m
CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
CONFIG_USB_SERIAL_KEYSPAN_PDA=m
CONFIG_USB_SERIAL_KEYSPAN=m
CONFIG_USB_SERIAL_KEYSPAN_MPR=y
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_HP4X=m
CONFIG_USB_SERIAL_SAFE=m
CONFIG_USB_SERIAL_SAFE_PADDED=y
+CONFIG_USB_SERIAL_TI=m
CONFIG_USB_SERIAL_CYBERJACK=m
CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_SERIAL_OMNINET=m
CONFIG_USB_EZUSB=y
# USB Miscellaneous drivers
#
CONFIG_USB_EMI62=m
-# CONFIG_USB_EMI26 is not set
-CONFIG_USB_TIGL=m
+CONFIG_USB_EMI26=m
CONFIG_USB_AUERSWALD=m
CONFIG_USB_RIO500=m
CONFIG_USB_LEGOTOWER=m
CONFIG_USB_LCD=m
CONFIG_USB_LED=m
# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGETKIT=m
CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
CONFIG_USB_TEST=m
+#
+# USB DSL modem support
+#
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+
#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_WBSD=m
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_MTHCA=m
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_AMD76X=m
+CONFIG_EDAC_E7XXX=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_I82875P=m
+CONFIG_EDAC_I82860=m
+CONFIG_EDAC_R82600=m
+CONFIG_EDAC_POLL=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+
#
# File systems
#
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_REISERFS_FS_SECURITY=y
CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
+CONFIG_XFS_EXPORT=y
CONFIG_XFS_QUOTA=y
CONFIG_XFS_SECURITY=y
CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+CONFIG_OCFS2_FS=m
CONFIG_MINIX_FS=m
CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
CONFIG_QUOTA=y
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=y
CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
#
# CD-ROM/DVD Filesystems
CONFIG_ZISOFS=y
CONFIG_ZISOFS_FS=y
CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
#
# DOS/FAT/NT Filesystems
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_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
#
# Miscellaneous filesystems
# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=m
CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_NAND=y
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_SQUASHFS_VMALLOC is not set
CONFIG_VXFS_FS=m
# CONFIG_HPFS_FS is not set
CONFIG_QNX4FS_FS=m
-# CONFIG_QNX4FS_RW is not set
CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
-# CONFIG_UFS_FS_WRITE is not set
#
# Network File Systems
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_DIRECTIO=y
CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
CONFIG_CIFS=m
# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_EXPERIMENTAL is not set
CONFIG_NCP_FS=m
CONFIG_NCPFS_PACKET_SIGNING=y
CONFIG_NCPFS_IOCTL_LOCKING=y
CONFIG_NCPFS_SMALLDOS=y
CONFIG_NCPFS_NLS=y
CONFIG_NCPFS_EXTRAS=y
-# CONFIG_CODA_FS is not set
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
#
# Partition Types
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_SOLARIS_X86_PARTITION=y
CONFIG_UNIXWARE_DISKLABEL=y
# CONFIG_LDM_PARTITION is not set
-# CONFIG_NEC98_PARTITION is not set
CONFIG_SGI_PARTITION=y
# CONFIG_ULTRIX_PARTITION is not set
CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
CONFIG_EFI_PARTITION=y
#
#
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_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_UTF8=m
#
-# Profiling support
+# Instrumentation Support
#
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_DEBUG_STACKOVERFLOW=y
-# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHEDSTATS=y
# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_DEBUG_HIGHMEM is not set
-CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_VM=y
# CONFIG_FRAME_POINTER is not set
+CONFIG_UNWIND_INFO=y
+# CONFIG_FORCED_INLINING is not set
+CONFIG_BOOT_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_STACK_BACKTRACE_COLS=2
+
+#
+# Page alloc debug is incompatible with Software Suspend on i386
+#
+CONFIG_DEBUG_RODATA=y
+CONFIG_4KSTACKS=y
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y
+CONFIG_DOUBLEFAULT=y
#
# Security options
#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_NETWORK_XFRM=y
CONFIG_SECURITY_CAPABILITIES=y
# CONFIG_SECURITY_ROOTPLUG is not set
+# CONFIG_SECURITY_SECLVL is not set
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_SECURITY_SELINUX_DEVELOP=y
-# CONFIG_SECURITY_SELINUX_MLS is not set
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
#
# Cryptographic options
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_AES_586=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_TEST is not set
+CONFIG_CRYPTO_SIGNATURE=y
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+
+#
+# Hardware crypto devices
+#
+CONFIG_CRYPTO_DEV_PADLOCK=m
+CONFIG_CRYPTO_DEV_PADLOCK_AES=y
#
# Library routines
#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
-CONFIG_X86_SMP=y
-CONFIG_X86_HT=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_X86_BIOS_REBOOT=y
-CONFIG_X86_TRAMPOLINE=y
-CONFIG_X86_STD_RESOURCES=y
-CONFIG_PC=y
+CONFIG_KTIME_SCALAR=y
+# i386
#
# Automatically generated make config: don't edit
#
CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_SMP=y
-# CONFIG_HOTPLUG_CPU is not set
-CONFIG_SCHED_SMT=y
-
+# CONFIG_SMP is not set
+CONFIG_HOTPLUG_CPU=y
+CONFIG_LOCALVERSION=""
+# CONFIG_CRASH_DUMP is not set
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_STANDALONE=y
-
+CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# General setup
#
+# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
CONFIG_LOG_BUF_SHIFT=17
# CONFIG_IKCONFIG is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
-# CONFIG_NUMA is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_IRQBALANCE is not set
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_CFQ=y
CONFIG_POSIX_MQUEUE=y
-CONFIG_EDD=m
-# CONFIG_SMBIOS is not set
-CONFIG_IRQSTACKS=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
#
# Loadable module support
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_KMOD=y
-
-#
-# Power management options (ACPI, APM)
-#
-CONFIG_PM=y
-# CONFIG_SOFTWARE_SUSPEND is not set
-# CONFIG_PM_DISK is not set
-
-#
-# ACPI (Advanced Configuration and Power Interface) Support
-#
-CONFIG_ACPI=y
-CONFIG_ACPI_BOOT=y
-CONFIG_ACPI_INTERPRETER=y
-CONFIG_ACPI_SLEEP=y
-CONFIG_ACPI_AC=m
-CONFIG_ACPI_BATTERY=m
-CONFIG_ACPI_BUTTON=m
-CONFIG_ACPI_FAN=y
-CONFIG_ACPI_PROCESSOR=y
-CONFIG_ACPI_THERMAL=y
-CONFIG_ACPI_ASUS=m
-CONFIG_ACPI_TOSHIBA=m
-# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_BUS=y
-CONFIG_ACPI_EC=y
-CONFIG_ACPI_POWER=y
-CONFIG_ACPI_PCI=y
-CONFIG_ACPI_SYSTEM=y
-CONFIG_ACPI_NUMA=y
-
-#
-# CPU Frequency scaling
-#
-CONFIG_CPU_FREQ=y
-# CONFIG_CPU_FREQ_PROC_INTF is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=m
-CONFIG_CPU_FREQ_GOV_USERSPACE=m
-# CONFIG_CPU_FREQ_24_API is not set
-CONFIG_CPU_FREQ_TABLE=y
-
+CONFIG_MODULE_SIG=y
+# CONFIG_MODULE_SIG_FORCE is not set
#
# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
#
CONFIG_PCI=y
-# CONFIG_PCI_GOBIOS is not set
-# CONFIG_PCI_GOMMCONFIG is not set
-# CONFIG_PCI_GODIRECT is not set
-CONFIG_PCI_GOANY=y
-CONFIG_PCI_BIOS=y
-CONFIG_PCI_DIRECT=y
-CONFIG_PCI_MMCONFIG=y
+# CONFIG_PCI_DEBUG is not set
+CONFIG_PCI_MSI=y
CONFIG_PCI_LEGACY_PROC=y
-# CONFIG_PCI_NAMES is not set
-CONFIG_PCI_USE_VECTOR=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=m
+CONFIG_HOTPLUG_PCI_FAKE=m
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
CONFIG_ISA=y
# CONFIG_EISA is not set
# CONFIG_MCA is not set
# CONFIG_SCx200 is not set
CONFIG_HOTPLUG=y
+# CONFIG_DEBUG_KOBJECT is not set
#
# PCMCIA/CardBus support
#
-CONFIG_PCMCIA=m
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_YENTA=y
CONFIG_CARDBUS=y
CONFIG_I82092=m
-CONFIG_I82365=m
-CONFIG_TCIC=m
-CONFIG_PCMCIA_PROBE=y
-
-#
-# PCI Hotplug Support
-#
-CONFIG_HOTPLUG_PCI=y
-# CONFIG_HOTPLUG_PCI_FAKE is not set
-CONFIG_HOTPLUG_PCI_COMPAQ=m
-# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
-CONFIG_HOTPLUG_PCI_IBM=m
-# CONFIG_HOTPLUG_PCI_ACPI is not set
-# CONFIG_HOTPLUG_PCI_CPCI is not set
-CONFIG_HOTPLUG_PCI_PCIE=m
-CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE=y
-CONFIG_HOTPLUG_PCI_SHPC=m
-CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE=y
-# CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY is not set
+CONFIG_PD6729=m
+CONFIG_PCMCIA_IOCTL=y
+
+CONFIG_PCCARD=y
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_WBSD=y
+CONFIG_MMC_SDHCI=m
+
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_MTHCA=m
+# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
+CONFIG_INFINIBAND_SRP=m
+CONFIG_INFINIBAND_USER_MAD=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_IPATH_CORE=m
+CONFIG_INFINIBAND_IPATH=m
#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_MISC=m
+CONFIG_BINFMT_MISC=y
#
# Device Drivers
#
CONFIG_FW_LOADER=y
+# CONFIG_SPI is not set
+
#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=m
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=m
+CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CONCAT=m
-CONFIG_MTD_REDBOOT_PARTS=m
-CONFIG_MTD_CMDLINE_PARTS=m
-
+CONFIG_MTD_CMDLINE_PARTS=y
#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=m
CONFIG_MTD_BLOCK=m
CONFIG_MTD_BLOCK_RO=m
+CONFIG_MTD_BLOCK2MTD=m
CONFIG_FTL=m
CONFIG_NFTL=m
CONFIG_NFTL_RW=y
CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
#
# RAM/ROM/Flash chip drivers
# CONFIG_MTD_PNC2000 is not set
CONFIG_MTD_SC520CDP=m
CONFIG_MTD_NETSC520=m
-CONFIG_MTD_SBC_GXX=m
-CONFIG_MTD_ELAN_104NC=m
+# CONFIG_MTD_SBC_GXX is not set
CONFIG_MTD_SCx200_DOCFLASH=m
-CONFIG_MTD_AMD76XROM=m
-CONFIG_MTD_ICH2ROM=m
+# CONFIG_MTD_AMD76XROM is not set
CONFIG_MTD_SCB2_FLASH=m
# CONFIG_MTD_NETtel is not set
# CONFIG_MTD_DILNETPC is not set
-CONFIG_MTD_L440GX=m
+# CONFIG_MTD_L440GX is not set
CONFIG_MTD_PCI=m
+CONFIG_MTD_TS5500=m
#
# Self-contained MTD device drivers
CONFIG_MTD_NAND=m
# CONFIG_MTD_NAND_VERIFY_WRITE is not set
CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_NANDSIM=m
+# CONFIG_MTD_ONENAND is not set
+
+CONFIG_MTD_REDBOOT_PARTS=m
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+CONFIG_MTD_CFI_AMDSTD_RETRY=3
+# CONFIG_MTD_XIP is not set
+# CONFIG_MTD_ICHXROM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_PLATRAM is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
#
# Parallel port support
#
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
CONFIG_PARPORT_SERIAL=m
# CONFIG_PARPORT_PC_FIFO is not set
# CONFIG_PARPORT_PC_SUPERIO is not set
CONFIG_PARPORT_PC_PCMCIA=m
-# CONFIG_PARPORT_OTHER is not set
CONFIG_PARPORT_1284=y
#
#
CONFIG_ISAPNP=y
# CONFIG_PNPBIOS is not set
+# CONFIG_ACPI_CONTAINER is not set
+# CONFIG_ACPI_SLEEP_PROC_SLEEP is not set
+# CONFIG_ACPI_HOTKEY is not set
#
# Block devices
#
CONFIG_BLK_DEV_FD=m
# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPATC8=y
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
CONFIG_BLK_CPQ_DA=m
CONFIG_BLK_CPQ_CISS_DA=m
CONFIG_CISS_SCSI_TAPE=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=16384
CONFIG_BLK_DEV_INITRD=y
CONFIG_BLK_DEV_ATIIXP=y
CONFIG_LBD=y
-# CONFIG_DCSSBLK is not set
-
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
#
# ATA/ATAPI/MFM/RLL support
# CONFIG_BLK_DEV_HD_IDE is not set
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_IDEDISK_STROKE is not set
CONFIG_BLK_DEV_IDECS=m
CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_IDETAPE=m
+# CONFIG_BLK_DEV_IDETAPE is not set
CONFIG_BLK_DEV_IDEFLOPPY=y
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDE_TASKFILE_IO is not set
+CONFIG_BLK_DEV_IDESCSI=m
+CONFIG_IDE_TASK_IOCTL=y
+# CONFIG_BLK_DEV_IDE_SATA is not set
#
# IDE chipset support/bugfixes
#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+CONFIG_BLK_DEV_CMD640=y
+CONFIG_BLK_DEV_CMD640_ENHANCED=y
CONFIG_BLK_DEV_IDEPNP=y
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_RZ1000=y
CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDE_TCQ is not set
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_ADMA=y
CONFIG_BLK_DEV_AEC62XX=y
CONFIG_BLK_DEV_ALI15X3=y
# CONFIG_WDC_ALI15X3 is not set
CONFIG_BLK_DEV_CY82C693=y
CONFIG_BLK_DEV_CS5520=y
CONFIG_BLK_DEV_CS5530=y
+CONFIG_BLK_DEV_CS5535=y
CONFIG_BLK_DEV_HPT34X=y
CONFIG_BLK_DEV_HPT366=y
+CONFIG_BLK_DEV_IT821X=y
# CONFIG_BLK_DEV_SC1200 is not set
CONFIG_BLK_DEV_PIIX=y
# CONFIG_BLK_DEV_NS87415 is not set
CONFIG_BLK_DEV_PDC202XX_OLD=y
# CONFIG_PDC202XX_BURST is not set
CONFIG_BLK_DEV_PDC202XX_NEW=y
-CONFIG_PDC202XX_FORCE=y
CONFIG_BLK_DEV_SVWKS=y
CONFIG_BLK_DEV_SIIMAGE=y
CONFIG_BLK_DEV_SIS5513=y
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_SR=m
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_REPORT_LUNS=y
+CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_RAID_ATTRS=m
+
+CONFIG_ISCSI_TCP=m
#
# SCSI low-level drivers
#
CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
# CONFIG_SCSI_7000FASST is not set
CONFIG_SCSI_ACARD=m
-CONFIG_SCSI_AHA152X=m
-CONFIG_SCSI_AHA1542=m
CONFIG_SCSI_AACRAID=m
CONFIG_SCSI_AIC7XXX=m
CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
CONFIG_AIC79XX_DEBUG_MASK=0
# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
CONFIG_SCSI_ADVANSYS=m
-CONFIG_SCSI_IN2000=m
-CONFIG_SCSI_MEGARAID=m
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_MEGARAID_LEGACY=m
+CONFIG_MEGARAID_SAS=m
CONFIG_SCSI_SATA=y
CONFIG_SCSI_SATA_SVW=m
CONFIG_SCSI_ATA_PIIX=m
CONFIG_SCSI_SATA_PROMISE=m
CONFIG_SCSI_SATA_VIA=m
-CONFIG_BLK_DEV_CARMEL=m
+CONFIG_BLK_DEV_SX8=m
CONFIG_SCSI_SATA_VITESSE=m
CONFIG_SCSI_SATA_SIL=m
CONFIG_SCSI_SATA_SIS=m
CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_NV=m
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_QSTOR=m
+CONFIG_SCSI_SATA_MV=m
+CONFIG_SCSI_SATA_SIL24=m
+CONFIG_SCSI_PDC_ADMA=m
CONFIG_SCSI_BUSLOGIC=m
+CONFIG_SCSI_INITIO=m
# CONFIG_SCSI_OMIT_FLASHPOINT is not set
-# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_PIO is not set
CONFIG_SCSI_FUTURE_DOMAIN=m
CONFIG_SCSI_GDTH=m
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
CONFIG_SCSI_IPS=m
CONFIG_SCSI_INIA100=m
CONFIG_SCSI_PPA=m
CONFIG_SCSI_IMM=m
# CONFIG_SCSI_IZIP_EPP16 is not set
# CONFIG_SCSI_IZIP_SLOW_CTR is not set
-# CONFIG_SCSI_NCR53C406A is not set
CONFIG_SCSI_SYM53C8XX_2=m
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+CONFIG_SCSI_SYM53C8XX_MMIO=y
# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PSI240I is not set
-CONFIG_SCSI_QLOGIC_FAS=m
-CONFIG_SCSI_QLOGIC_ISP=m
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
CONFIG_SCSI_QLOGIC_1280=m
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
+CONFIG_SCSI_DC395x=m
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
CONFIG_SCSI_DC390T=m
-CONFIG_SCSI_QLA2XXX=m
+CONFIG_SCSI_QLA_FC=m
+# FIXME: Turn off for FC6 - Move to external firmware loader.
+CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE=y
CONFIG_SCSI_QLA21XX=m
CONFIG_SCSI_QLA22XX=m
CONFIG_SCSI_QLA2300=m
CONFIG_SCSI_QLA2322=m
+CONFIG_SCSI_QLA24XX=m
CONFIG_SCSI_QLA6312=m
-CONFIG_SCSI_QLA6322=m
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_DPT_I2O is not set
+CONFIG_SCSI_LPFC=m
#
# PCMCIA SCSI adapter support
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)
#
CONFIG_MD_RAID0=m
CONFIG_MD_RAID1=m
CONFIG_MD_RAID5=m
+CONFIG_MD_RAID5_RESHAPE=y
CONFIG_MD_RAID6=m
+CONFIG_MD_RAID10=m
CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
CONFIG_BLK_DEV_DM=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
CONFIG_DM_CRYPT=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
#
# Fusion MPT device support
#
-CONFIG_FUSION=m
+CONFIG_FUSION_SPI=m
+CONFIG_FUSION_FC=m
CONFIG_FUSION_MAX_SGE=40
-# CONFIG_FUSION_ISENSE is not set
CONFIG_FUSION_CTL=m
CONFIG_FUSION_LAN=m
+CONFIG_FUSION_SAS=m
#
# IEEE 1394 (FireWire) support (EXPERIMENTAL)
#
# Device Drivers
#
-# CONFIG_IEEE1394_PCILYNX is not set
+CONFIG_IEEE1394_PCILYNX=m
CONFIG_IEEE1394_OHCI1394=m
#
CONFIG_IEEE1394_VIDEO1394=m
CONFIG_IEEE1394_SBP2=m
# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
-# CONFIG_IEEE1394_ETH1394 is not set
+CONFIG_IEEE1394_ETH1394=m
CONFIG_IEEE1394_DV1394=m
CONFIG_IEEE1394_RAWIO=m
-CONFIG_IEEE1394_CMP=m
-CONFIG_IEEE1394_AMDTP=m
-# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
#
# I2O device support
#
CONFIG_I2O=m
-CONFIG_I2O_PCI=m
-CONFIG_I2O_BLOCK=m
-CONFIG_I2O_SCSI=m
-CONFIG_I2O_PROC=m
-CONFIG_I2O_CONFIG=y
+# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
#
# Networking support
#
CONFIG_NET=y
+# CONFIG_NETDEBUG is not set
+
+# CONFIG_TCP_CONG_ADVANCED is not set
#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
CONFIG_UNIX=y
CONFIG_NET_KEY=m
CONFIG_INET=y
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_DIAG=m
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_FWMARK=y
-CONFIG_IP_ROUTE_NAT=y
CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_TOS=y
CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
+CONFIG_IP_ROUTE_MULTIPATH_RR=m
+CONFIG_IP_ROUTE_MULTIPATH_RANDOM=m
+CONFIG_IP_ROUTE_MULTIPATH_WRANDOM=m
+CONFIG_IP_ROUTE_MULTIPATH_DRR=m
# CONFIG_IP_PNP is not set
CONFIG_NET_IPIP=m
CONFIG_NET_IPGRE=m
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
CONFIG_IP_VS_NQ=m
CONFIG_IP_VS_FTP=m
-
CONFIG_IPV6=m
CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
CONFIG_IPV6_TUNNEL=m
-# CONFIG_DECNET is not set
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+# CONFIG_DECNET_NF_GRABULATOR is not set
CONFIG_BRIDGE=m
CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
# IP: Netfilter Configuration
#
CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_POLICY=m
CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TOS=m
CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_PHYSDEV=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_NAT_LOCAL=y
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_NETBIOS_NS=m
+CONFIG_IP_NF_PPTP=m
+CONFIG_IP_NF_H323=m
#
# IPv6: Netfilter Configuration
#
-# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_FRAG=m
CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_POLICY=m
CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
CONFIG_IP6_NF_RAW=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_TARGET_HL=m
#
# Bridge: Netfilter Configuration
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_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_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_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
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_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_CLS_ROUTE=y
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
CONFIG_NET_CLS_POLICE=y
+# CONFIG_NET_ACT_POLICE is not set
+CONFIG_CLS_U32_PERF=y
+CONFIG_NET_CLS_IND=y
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
#
# Network testing
#
-# CONFIG_NET_PKTGEN is not set
+CONFIG_NET_PKTGEN=m
CONFIG_NETDEVICES=y
#
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
-CONFIG_ETHERTAP=m
CONFIG_NET_SB1000=m
+#
+# ATM
+#
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_CLIP=m
+CONFIG_ATM_LANE=m
+CONFIG_ATM_BR2684=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+CONFIG_ATM_FIRESTREAM=m
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_IDT77252=m
+CONFIG_ATM_AMBASSADOR=m
+CONFIG_ATM_HORIZON=m
+CONFIG_ATM_FORE200E_MAYBE=m
+CONFIG_ATM_HE=m
+CONFIG_PPPOATM=m
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_IA is not set
+
+
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+# CONFIG_ATM_MPOA is not set
+# CONFIG_ATM_BR2684_IPFILTER is not set
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+# CONFIG_ATM_ZATM_DEBUG is not set
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+# CONFIG_ATM_HORIZON_DEBUG is not set
+# CONFIG_ATM_FORE200E_PCA is not set
+# CONFIG_ATM_HE_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+# CONFIG_ATM_IA_DEBUG is not set
+
+
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
+CONFIG_PHYLIB=m
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
CONFIG_MII=m
CONFIG_HAPPYMEAL=m
CONFIG_SUNGEM=m
CONFIG_NET_VENDOR_3COM=y
-CONFIG_EL1=m
-CONFIG_EL2=m
-CONFIG_ELPLUS=m
-CONFIG_EL16=m
-CONFIG_EL3=m
-CONFIG_3C515=m
CONFIG_VORTEX=m
CONFIG_TYPHOON=m
-CONFIG_LANCE=m
-CONFIG_NET_VENDOR_SMC=y
-CONFIG_WD80x3=m
-CONFIG_ULTRA=m
-CONFIG_SMC9194=m
-CONFIG_NET_VENDOR_RACAL=y
-CONFIG_NI52=m
-CONFIG_NI65=m
#
# Tulip family network device support
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_WINBOND_840=m
CONFIG_DM9102=m
CONFIG_PCMCIA_XIRCOM=m
-# CONFIG_AT1700 is not set
-CONFIG_DEPCA=m
+CONFIG_ULI526X=m
CONFIG_HP100=m
-# CONFIG_NET_ISA is not set
-# CONFIG_EWRK3 is not set
-CONFIG_E2100=m
-CONFIG_EEXPRESS=m
-CONFIG_EEXPRESS_PRO=m
-CONFIG_HPLAN_PLUS=m
-CONFIG_HPLAN=m
-CONFIG_LP486E=m
-CONFIG_ETH16I=m
-CONFIG_NE2000=m
-CONFIG_ZNET=m
-CONFIG_SEEQ8005=m
CONFIG_LNE390=m
CONFIG_NE3210=m
CONFIG_ES3210=m
CONFIG_AMD8111E_NAPI=y
CONFIG_ADAPTEC_STARFIRE=m
CONFIG_ADAPTEC_STARFIRE_NAPI=y
-CONFIG_AC3200=m
-CONFIG_APRICOT=m
CONFIG_B44=m
-CONFIG_CS89x0=m
+CONFIG_BNX2=m
CONFIG_DGRS=m
-CONFIG_EEPRO100=m
-# CONFIG_EEPRO100_PIO is not set
+# CONFIG_EEPRO100 is not set
CONFIG_E100=m
-CONFIG_E100_NAPI=y
CONFIG_FEALNX=m
CONFIG_FORCEDETH=m
CONFIG_NATSEMI=m
CONFIG_NE2K_PCI=m
CONFIG_8139CP=m
CONFIG_8139TOO=m
-CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_PIO is not set
# CONFIG_8139TOO_TUNE_TWISTER is not set
CONFIG_8139TOO_8129=y
# CONFIG_8139_OLD_RX_RESET is not set
-CONFIG_8139_RXBUF_IDX=2
CONFIG_SIS900=m
+CONFIG_SIS190=m
CONFIG_EPIC100=m
CONFIG_SUNDANCE=m
# CONFIG_SUNDANCE_MMIO is not set
CONFIG_TLAN=m
CONFIG_VIA_RHINE=m
CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_VELOCITY=m
CONFIG_NET_POCKET=y
CONFIG_ATP=m
CONFIG_DE600=m
CONFIG_DE620=m
+CONFIG_CASSINI=m
+# CONFIG_FEC_8XX is not set
#
# Ethernet (1000 Mbit)
#
-CONFIG_NET_GIGE=y
CONFIG_ACENIC=m
# CONFIG_ACENIC_OMIT_TIGON_I is not set
CONFIG_DL2K=m
CONFIG_E1000=m
CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
CONFIG_NS83820=m
CONFIG_HAMACHI=m
CONFIG_YELLOWFIN=m
CONFIG_R8169=m
-CONFIG_SK98LIN=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+# CONFIG_SK98LIN is not set
+CONFIG_SKGE=m
CONFIG_TIGON3=m
+CONFIG_SKY2=m
#
# Ethernet (10000 Mbit)
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_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)
#
# CONFIG_STRIP is not set
# CONFIG_ARLAN is not set
-CONFIG_WAVELAN=m
CONFIG_PCMCIA_WAVELAN=m
CONFIG_PCMCIA_NETWAVE=m
#
# Wireless 802.11b ISA/PCI cards support
#
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IEEE80211_SOFTMAC=m
+CONFIG_IEEE80211_SOFTMAC_DEBUG=y
+CONFIG_IPW2100=m
+CONFIG_IPW2200=m
+# CONFIG_IPW2100_DEBUG is not set
+# CONFIG_IPW2200_DEBUG is not set
CONFIG_AIRO=m
CONFIG_HERMES=m
CONFIG_PLX_HERMES=m
CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
CONFIG_PCI_HERMES=m
CONFIG_ATMEL=m
CONFIG_PCI_ATMEL=m
CONFIG_PRISM54=m
+CONFIG_BCM43XX=m
+CONFIG_BCM43XX_DEBUG=y
#
# Wireless 802.11b Pcmcia/Cardbus cards support
#
CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
CONFIG_AIRO_CS=m
CONFIG_PCMCIA_ATMEL=m
CONFIG_PCMCIA_WL3501=m
CONFIG_NET_WIRELESS=y
+CONFIG_NET_WIRELESS_RTNETLINK=y
+
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_CS=m
#
# Token Ring devices
#
-# CONFIG_TR is not set
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_3C359=m
+# Broken with gcc4.1
+# CONFIG_TMS380TR is not set
+CONFIG_TMSPCI=m
+CONFIG_ABYSS=m
+CONFIG_IBMLS=m
+CONFIG_PCMCIA_IBMTR=m
+
CONFIG_NET_FC=y
-CONFIG_RCPCI=m
# CONFIG_SHAPER is not set
#
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_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
CONFIG_BT_BNEP=m
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
#
# Bluetooth device drivers
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_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
CONFIG_ISDN=m
CONFIG_ISDN_I4L=m
-CONFIG_ISDN_DRV_AVMB1_B1ISA=m
CONFIG_ISDN_DRV_AVMB1_B1PCI=m
-CONFIG_ISDN_DRV_AVMB1_T1ISA=m
CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
CONFIG_ISDN_DRV_AVMB1_T1PCI=m
CONFIG_ISDN_DRV_AVMB1_C4=m
CONFIG_ISDN_AUDIO=y
CONFIG_ISDN_DRV_HISAX=m
-CONFIG_ISDN_DRV_ICN=m
-CONFIG_ISDN_DRV_PCBIT=m
-CONFIG_ISDN_DRV_SC=m
-CONFIG_ISDN_DRV_ACT2000=m
-CONFIG_ISDN_DRV_TPAM=m
CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
CONFIG_ISDN_CAPI_CAPIDRV=m
+CONFIG_ISDN_DIVERSION=m
CONFIG_HISAX_EURO=y
CONFIG_HISAX_1TR6=y
CONFIG_HISAX_NI1=y
CONFIG_HISAX_MAX_CARDS=8
-CONFIG_HISAX_16_0=y
CONFIG_HISAX_16_3=y
CONFIG_HISAX_TELESPCI=y
CONFIG_HISAX_S0BOX=y
-CONFIG_HISAX_AVM_A1=y
CONFIG_HISAX_FRITZPCI=y
CONFIG_HISAX_AVM_A1_PCMCIA=y
CONFIG_HISAX_ELSA=y
-CONFIG_HISAX_IX1MICROR2=y
CONFIG_HISAX_DIEHLDIVA=y
-CONFIG_HISAX_ASUSCOM=y
-CONFIG_HISAX_TELEINT=y
-CONFIG_HISAX_HFCS=y
CONFIG_HISAX_SEDLBAUER=y
-CONFIG_HISAX_SPORTSTER=y
-CONFIG_HISAX_MIC=y
CONFIG_HISAX_NETJET=y
CONFIG_HISAX_NETJET_U=y
CONFIG_HISAX_NICCY=y
-CONFIG_HISAX_ISURF=y
-CONFIG_HISAX_HSTSAPHIR=y
CONFIG_HISAX_BKM_A4T=y
CONFIG_HISAX_SCT_QUADRO=y
CONFIG_HISAX_GAZEL=y
# 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_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_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
#
# Input I/O drivers
#
CONFIG_GAMEPORT=m
-CONFIG_SOUND_GAMEPORT=m
CONFIG_GAMEPORT_NS558=m
CONFIG_GAMEPORT_L4=m
CONFIG_GAMEPORT_EMU10K1=m
-CONFIG_GAMEPORT_VORTEX=m
CONFIG_GAMEPORT_FM801=m
-CONFIG_GAMEPORT_CS461x=m
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_RAW=m
+
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PARKBD is not set
# CONFIG_SERIO_PCIPS2 is not set
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_JOYSTICK_SPACEORB=m
CONFIG_JOYSTICK_SPACEBALL=m
CONFIG_JOYSTICK_STINGER=m
-CONFIG_JOYSTICK_TWIDDLER=m
CONFIG_JOYSTICK_DB9=m
CONFIG_JOYSTICK_GAMECON=m
CONFIG_JOYSTICK_TURBOGRAFX=m
-# CONFIG_INPUT_JOYDUMP is not set
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_JOYSTICK_TWIDJOY=m
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_MK712=m
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PCSPKR=m
-# CONFIG_INPUT_UINPUT is not set
+CONFIG_INPUT_UINPUT=m
+CONFIG_INPUT_WISTRON_BTNS=m
#
# Character devices
CONFIG_ROCKETPORT=m
CONFIG_SYNCLINK=m
CONFIG_SYNCLINKMP=m
+# CONFIG_SYNCLINK_GT is not set
CONFIG_N_HDLC=m
-CONFIG_STALDRV=y
+# CONFIG_STALDRV is not set
# CONFIG_FTAPE is not set
CONFIG_IBM_ASM=m
+# CONFIG_TCG_TPM is not set
+# CONFIG_TCG_NSC is not set
+# CONFIG_TCG_ATMEL is not set
+CONFIG_TCG_INFINEON=m
+# CONFIG_TELCLOCK is not set
#
# Serial drivers
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_CS=m
# CONFIG_SERIAL_8250_ACPI is not set
-CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_MULTIPORT=y
CONFIG_SERIAL_8250_RSA=y
# CONFIG_COMPUTONE is not set
# CONFIG_CYCLADES is not set
# CONFIG_DIGIEPCA is not set
-# CONFIG_DIGI is not set
# CONFIG_ESPSERIAL is not set
# CONFIG_MOXA_INTELLIO is not set
# CONFIG_MOXA_SMARTIO is not set
# 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
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
#
# I2C Hardware Bus support
#
+
+CONFIG_I2C_NFORCE2=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+CONFIG_I2C_VOODOO3=m
CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
CONFIG_I2C_ALI15X3=m
CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
CONFIG_I2C_AMD8111=m
CONFIG_I2C_I801=m
CONFIG_I2C_I810=m
-CONFIG_I2C_ISA=m
-CONFIG_I2C_NFORCE2=m
CONFIG_I2C_PIIX4=m
-CONFIG_I2C_PROSAVAGE=m
-CONFIG_I2C_SAVAGE4=m
# CONFIG_SCx200_ACB is not set
CONFIG_I2C_SIS5595=m
CONFIG_I2C_SIS630=m
CONFIG_I2C_SIS96X=m
CONFIG_I2C_VIA=m
CONFIG_I2C_VIAPRO=m
-CONFIG_I2C_VOODOO3=m
+
# CONFIG_I2C_ELEKTOR is not set
CONFIG_I2C_PARPORT=m
CONFIG_I2C_PARPORT_LIGHT=m
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_I2C_PARPORT is not set
-CONFIG_I2C_ALI1563=m
-# CONFIG_I2C_PARPORT_LIGHT is not set
-
-
+CONFIG_I2C_ALGOPCA=m
+CONFIG_I2C_PCA_ISA=m
+CONFIG_I2C_STUB=m
#
# I2C Hardware Sensors Chip support
#
-CONFIG_I2C_SENSOR=m
CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_FSCHER=m
+CONFIG_SENSORS_FSCPOS=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_HDAPS=m
CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
CONFIG_SENSORS_LM78=m
CONFIG_SENSORS_LM80=m
CONFIG_SENSORS_LM83=m
CONFIG_SENSORS_LM85=m
-CONFIG_SENSORS_VIA686A=m
-CONFIG_SENSORS_W83781D=m
-CONFIG_SENSORS_ASB100=m
+CONFIG_SENSORS_LM87=m
CONFIG_SENSORS_LM90=m
-CONFIG_SENSORS_W83L785TS=m
-CONFIG_SENSORS_FSCHER=m
-CONFIG_SENSORS_GL518SM=m
-CONFIG_SENSORS_DS1621=m
-CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_MAX6875=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_PCA9539=m
CONFIG_SENSORS_PCF8574=m
CONFIG_SENSORS_PCF8591=m
CONFIG_SENSORS_RTC8564=m
-CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_RTC_X1205_I2C=m
+
+CONFIG_W1=m
+CONFIG_W1_DS2433_CRC=y
+
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS9490=m
+CONFIG_W1_MASTER_DS9490_BRIDGE=m
+CONFIG_W1_MASTER_DS2482=m
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
#
# Mice
#
-CONFIG_BUSMOUSE=m
-# CONFIG_QIC02_TAPE is not set
-CONFIG_CRASH=m
#
# IPMI
CONFIG_IPMI_HANDLER=m
# CONFIG_IPMI_PANIC_EVENT is not set
CONFIG_IPMI_DEVICE_INTERFACE=m
-CONFIG_IPMI_KCS=m
CONFIG_IPMI_WATCHDOG=m
CONFIG_IPMI_SI=m
+CONFIG_IPMI_POWEROFF=m
#
# Watchdog Cards
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
CONFIG_SOFT_WATCHDOG=m
-CONFIG_WDT=m
# CONFIG_WDT_501 is not set
CONFIG_WDTPCI=m
CONFIG_WDT_501_PCI=y
-CONFIG_PCWATCHDOG=m
-CONFIG_ACQUIRE_WDT=m
-CONFIG_ADVANTECH_WDT=m
-CONFIG_EUROTECH_WDT=m
-CONFIG_IB700_WDT=m
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
CONFIG_I8XX_TCO=m
# CONFIG_MIXCOMWD is not set
# CONFIG_SCx200_WDT is not set
CONFIG_W83877F_WDT=m
CONFIG_W83627HF_WDT=m
CONFIG_MACHZ_WDT=m
-CONFIG_SC520_WDT=m
-CONFIG_AMD7XX_TCO=m
+# CONFIG_SC520_WDT is not set
CONFIG_ALIM7101_WDT=m
CONFIG_ALIM1535_WDT=m
-CONFIG_SC1200_WDT=m
-CONFIG_WAFER_WDT=m
-CONFIG_CPU5_WDT=m
+# CONFIG_SC1200_WDT is not set
+# CONFIG_WAFER_WDT is not set
+# CONFIG_CPU5_WDT is not set
+CONFIG_I6300ESB_WDT=m
+# CONFIG_SBC8360_WDT is not set
+CONFIG_W83977F_WDT=m
CONFIG_PCIPCWATCHDOG=m
CONFIG_USBPCWATCHDOG=m
-
+# CONFIG_SBC_EPX_C3_WATCHDOG is not set
CONFIG_HW_RANDOM=m
-CONFIG_NVRAM=m
+CONFIG_NVRAM=y
CONFIG_RTC=y
+CONFIG_RTC_CLASS=m
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_RS5C372=m
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_EP93XX is not set
+# CONFIG_RTC_DRV_SA1100 is not set
+# CONFIG_RTC_DRV_TEST is not set
CONFIG_DTLK=m
CONFIG_R3964=m
# CONFIG_APPLICOM is not set
CONFIG_AGP_AMD=y
CONFIG_AGP_AMD64=y
CONFIG_AGP_INTEL=y
-CONFIG_AGP_INTEL_MCH=y
CONFIG_AGP_NVIDIA=y
CONFIG_AGP_SIS=y
CONFIG_AGP_SWORKS=y
CONFIG_AGP_VIA=y
CONFIG_AGP_EFFICEON=y
-CONFIG_DRM=y
+CONFIG_DRM=m
CONFIG_DRM_TDFX=m
-CONFIG_DRM_GAMMA=m
CONFIG_DRM_R128=m
CONFIG_DRM_RADEON=m
CONFIG_DRM_I810=m
CONFIG_DRM_I830=m
CONFIG_DRM_MGA=m
CONFIG_DRM_SIS=m
-
+CONFIG_DRM_SAVAGE=m
+CONFIG_DRM_I915=m
+CONFIG_DRM_VIA=m
#
# PCMCIA character devices
#
CONFIG_SYNCLINK_CS=m
-
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
CONFIG_MWAVE=m
# CONFIG_RAW_DRIVER is not set
# 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 Adapters
#
+CONFIG_VIDEO_AUDIO_DECODER=m
CONFIG_VIDEO_BT848=m
-CONFIG_VIDEO_PMS=m
+CONFIG_VIDEO_BT848_DVB=y
CONFIG_VIDEO_BWQCAM=m
-CONFIG_VIDEO_CQCAM=m
-CONFIG_VIDEO_W9966=m
CONFIG_VIDEO_CPIA=m
CONFIG_VIDEO_CPIA_PP=m
CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_DECODER=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_MEYE=m
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_VIDEO_SAA5246A=m
CONFIG_VIDEO_SAA5249=m
-CONFIG_TUNER_3036=m
+CONFIG_VIDEO_SAA6588=m
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS=y
CONFIG_VIDEO_STRADIS=m
-CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
CONFIG_VIDEO_ZORAN=m
CONFIG_VIDEO_ZORAN_BUZ=m
CONFIG_VIDEO_ZORAN_DC10=m
CONFIG_VIDEO_ZORAN_DC30=m
CONFIG_VIDEO_ZORAN_LML33=m
CONFIG_VIDEO_ZORAN_LML33R10=m
-CONFIG_VIDEO_MEYE=m
-CONFIG_VIDEO_SAA7134=m
-CONFIG_VIDEO_MXB=m
-CONFIG_VIDEO_DPC=m
-CONFIG_VIDEO_HEXIUM_ORION=m
-CONFIG_VIDEO_HEXIUM_GEMINI=m
-CONFIG_VIDEO_CX88=m
-CONFIG_VIDEO_SAA5246A=m
+CONFIG_TUNER_3036=m
#
# Radio Adapters
#
-CONFIG_RADIO_CADET=m
-CONFIG_RADIO_RTRACK=m
-CONFIG_RADIO_RTRACK2=m
-CONFIG_RADIO_AZTECH=m
-CONFIG_RADIO_GEMTEK=m
CONFIG_RADIO_GEMTEK_PCI=m
CONFIG_RADIO_MAXIRADIO=m
CONFIG_RADIO_MAESTRO=m
CONFIG_RADIO_MIROPCM20=m
CONFIG_RADIO_MIROPCM20_RDS=m
-CONFIG_RADIO_SF16FMI=m
-CONFIG_RADIO_SF16FMR2=m
-CONFIG_RADIO_TERRATEC=m
-CONFIG_RADIO_TRUST=m
-CONFIG_RADIO_TYPHOON=m
-CONFIG_RADIO_TYPHOON_PROC_FS=y
-CONFIG_RADIO_ZOLTRIX=m
#
# Digital Video Broadcasting Devices
#
-# CONFIG_DVB is not set
+CONFIG_DVB=y
CONFIG_DVB_CORE=m
#
#
CONFIG_DVB_STV0299=m
# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_ALPS_TDLB7 is not set
-CONFIG_DVB_ALPS_TDMB7=m
-CONFIG_DVB_ATMEL_AT76C651=m
CONFIG_DVB_CX24110=m
-CONFIG_DVB_GRUNDIG_29504_491=m
-CONFIG_DVB_GRUNDIG_29504_401=m
CONFIG_DVB_MT312=m
CONFIG_DVB_VES1820=m
CONFIG_DVB_VES1X93=m
-CONFIG_DVB_TWINHAN_DST=m
CONFIG_DVB_TTUSB_DEC=m
CONFIG_DVB_BT8XX=m
-# CONFIG_DVB_TDA1004X is not set
+CONFIG_DVB_TDA1004X=m
CONFIG_DVB_NXT6000=m
#
#
# 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_FB_VGA16=m
CONFIG_FB_VESA=y
CONFIG_VIDEO_SELECT=y
-CONFIG_FB_HGA=m
+# CONFIG_FB_HGA is not set
CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_DEBUG is not set
+# CONFIG_FB_RIVA_I2C is not set
CONFIG_FB_I810=m
CONFIG_FB_I810_GTF=y
+CONFIG_FB_I810_I2C=y
CONFIG_FB_MATROX=m
CONFIG_FB_MATROX_MILLENIUM=y
CONFIG_FB_MATROX_MYSTIQUE=y
-CONFIG_FB_MATROX_G450=y
-CONFIG_FB_MATROX_G100=y
+CONFIG_FB_MATROX_G=y
CONFIG_FB_MATROX_I2C=m
CONFIG_FB_MATROX_MAVEN=m
CONFIG_FB_MATROX_MULTIHEAD=y
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_PM2 is not set
# CONFIG_FB_PM2_FIFO_DISCONNECT is not set
# CONFIG_FB_ASILIANT is not set
-CONFIG_FB_HGA_ACCEL=y
CONFIG_FB_3DFX_ACCEL=y
CONFIG_FB_TRIDENT_ACCEL=y
+CONFIG_FB_CIRRUS=m
+CONFIG_FB_TILEBLITTING=y
+# CONFIG_FB_ARC is not set
+CONFIG_FB_INTEL=m
+# CONFIG_FB_INTEL_DEBUG is not set
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# 2.6.12-rc1-bk2 = Nvidia fb crashes.
+# CONFIG_FB_NVIDIA is not set
+CONFIG_FB_NVIDIA_I2C=y
+# CONFIG_FB_GEODE is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_CYBLA=m
+# CONFIG_FB_FIRMWARE_EDID is not set
#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
-CONFIG_MDA_CONSOLE=m
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
# CONFIG_FONTS is not set
# Advanced Linux Sound Architecture
#
CONFIG_SND=m
+CONFIG_SND_VERBOSE_PROCFS=y
CONFIG_SND_SEQUENCER=m
CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
-CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_RTCTIMER=m
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
-CONFIG_SND_BIT32_EMUL=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
#
# Generic devices
#
# ISA devices
#
-CONFIG_SND_AD1816A=m
-CONFIG_SND_AD1848=m
-CONFIG_SND_CS4231=m
-CONFIG_SND_CS4232=m
-CONFIG_SND_CS4236=m
-CONFIG_SND_ES968=m
-CONFIG_SND_ES1688=m
-CONFIG_SND_ES18XX=m
-CONFIG_SND_GUSCLASSIC=m
-CONFIG_SND_GUSEXTREME=m
-CONFIG_SND_GUSMAX=m
-CONFIG_SND_INTERWAVE=m
-CONFIG_SND_INTERWAVE_STB=m
-CONFIG_SND_OPTI92X_AD1848=m
-CONFIG_SND_OPTI92X_CS4231=m
-CONFIG_SND_OPTI93X=m
-CONFIG_SND_SB8=m
-CONFIG_SND_SB16=m
-CONFIG_SND_SBAWE=m
-CONFIG_SND_SB16_CSP=y
+CONFIG_SND_AD1889=m
# CONFIG_SND_WAVEFRONT is not set
-CONFIG_SND_ALS100=m
-CONFIG_SND_AZT2320=m
-CONFIG_SND_CMI8330=m
-CONFIG_SND_DT019X=m
-CONFIG_SND_OPL3SA2=m
-CONFIG_SND_SGALAXY=m
-CONFIG_SND_SSCAPE=m
#
# PCI devices
CONFIG_SND_CS46XX=m
CONFIG_SND_CS46XX_NEW_DSP=y
CONFIG_SND_CS4281=m
+CONFIG_SND_CS5535AUDIO=m
CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_CA0106=m
CONFIG_SND_KORG1212=m
CONFIG_SND_NM256=m
CONFIG_SND_RME32=m
+CONFIG_SND_PCXHR=m
CONFIG_SND_RME96=m
CONFIG_SND_RME9652=m
CONFIG_SND_HDSP=m
CONFIG_SND_INTEL8X0=m
CONFIG_SND_SONICVIBES=m
CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
CONFIG_SND_VX222=m
CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
CONFIG_SND_AU8810=m
CONFIG_SND_AU8820=m
CONFIG_SND_AU8830=m
CONFIG_SND_MIXART=m
CONFIG_SND_FM801_TEA575X=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
CONFIG_SND_INTEL8X0M=m
-CONFIG_SND_PDAUDIOCF=m
-
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ADLIB=m
+CONFIG_SND_MIRO=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_RIPTIDE=m
#
# ALSA USB devices
#
CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
#
# PCMCIA devices
#
# CONFIG_SND_VXPOCKET is not set
-# CONFIG_SND_VXP440 is not set
#
# Open Sound System
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
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_OHCI_HCD=m
CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_SL811_CS=m
#
# USB Device Class drivers
#
-CONFIG_USB_AUDIO=m
+# CONFIG_USB_AUDIO is not set
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
#
# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
CONFIG_USB_MIDI=m
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m
+CONFIG_BLK_DEV_UB=m
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_ISD200=y
CONFIG_USB_STORAGE_DPCM=y
-CONFIG_USB_STORAGE_HP8200e=y
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_LIBUSUAL=y
#
# USB Human Interface Devices (HID)
CONFIG_LOGITECH_FF=y
CONFIG_THRUSTMASTER_FF=y
CONFIG_USB_HIDDEV=y
+CONFIG_USB_IDMOUSE=m
#
# USB HID Boot Protocol drivers
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set
CONFIG_USB_AIPTEK=m
+
CONFIG_USB_WACOM=m
+
CONFIG_USB_KBTAB=m
CONFIG_USB_POWERMATE=m
CONFIG_USB_XPAD=m
#
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_ET61X251=m
CONFIG_USB_IBMCAM=m
CONFIG_USB_KONICAWC=m
CONFIG_USB_OV511=m
-CONFIG_USB_PWC=m
CONFIG_USB_SE401=m
CONFIG_USB_STV680=m
+CONFIG_USB_SN9C102=m
#
# USB Network adaptors
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_USBNET=m
+CONFIG_USB_SPEEDTOUCH=m
+# Has dumb detection, which gets loaded for every hid device.
+# CONFIG_USB_YEALINK is not set
+CONFIG_USB_ZD1201=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_NET_ZAURUS=m
#
# USB Host-to-Host Cables
#
CONFIG_USB_AN2720=y
CONFIG_USB_BELKIN=y
-CONFIG_USB_GENESYS=y
-CONFIG_USB_NET1080=y
-CONFIG_USB_PL2301=y
#
# Intelligent USB Devices/Gadgets
#
CONFIG_USB_ARMLINUX=y
CONFIG_USB_EPSON2888=y
-CONFIG_USB_ZAURUS=y
-CONFIG_USB_CDCETHER=y
-
-#
-# USB Network Adapters
-#
-CONFIG_USB_AX8817X=y
#
# USB port drivers
#
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ANYDATA=m
+CONFIG_USB_SERIAL_ARK3116=m
CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_CYBERJACK=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
-CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_HP4X=m
CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IPW=m
CONFIG_USB_SERIAL_IR=m
-CONFIG_USB_SERIAL_EDGEPORT=m
-CONFIG_USB_SERIAL_EDGEPORT_TI=m
CONFIG_USB_SERIAL_KEYSPAN_PDA=m
CONFIG_USB_SERIAL_KEYSPAN=m
CONFIG_USB_SERIAL_KEYSPAN_MPR=y
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_NAVMAN=m
+CONFIG_USB_SERIAL_OPTION=y
+CONFIG_USB_SERIAL_OMNINET=m
CONFIG_USB_SERIAL_PL2303=m
CONFIG_USB_SERIAL_SAFE=m
CONFIG_USB_SERIAL_SAFE_PADDED=y
-CONFIG_USB_SERIAL_CYBERJACK=m
-CONFIG_USB_SERIAL_XIRCOM=m
-CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_VISOR=m
CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_XIRCOM=m
+
CONFIG_USB_EZUSB=y
CONFIG_USB_EMI62=m
CONFIG_USB_LED=m
#
# USB Miscellaneous drivers
#
-# CONFIG_USB_EMI26 is not set
-CONFIG_USB_TIGL=m
+CONFIG_USB_EMI26=m
CONFIG_USB_AUERSWALD=m
CONFIG_USB_RIO500=m
-CONFIG_USB_BRLVGER=m
CONFIG_USB_LCD=m
CONFIG_USB_TEST=m
# CONFIG_USB_GADGET is not set
# CONFIG_USB_GADGET_PXA2XX is not set
# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_SA1100 is not set
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
-CONFIG_USB_GADGETFS=m
+# CONFIG_USB_GADGETFS is not set
CONFIG_USB_W9968CF=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
CONFIG_USB_LEGOTOWER=m
CONFIG_USB_FILE_STORAGE=m
# CONFIG_USB_FILE_STORAGE_TEST is not set
-CONFIG_USB_MTOUCH=m
CONFIG_USB_ATI_REMOTE=m
+CONFIG_USB_ATI_REMOTE2=m
CONFIG_USB_ALI_M5632=y
# CONFIG_USB_CYTHERM is not set
-CONFIG_USB_EGALAX=m
CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_MON=y
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_ACECAD=m
+CONFIG_USB_ATM=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_XUSBATM=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_KEYSPAN_REMOTE=m
+CONFIG_USB_LD=m
+CONFIG_USB_APPLETOUCH=m
+
+CONFIG_USB_TOUCHSCREEN=m
+
#
# File systems
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_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_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_PROC_FS=y
CONFIG_PROC_KCORE=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
+CONFIG_DEBUG_FS=y
#
# Miscellaneous filesystems
# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=m
CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_NAND=y
CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
CONFIG_VXFS_FS=m
# CONFIG_HPFS_FS is not set
CONFIG_QNX4FS_FS=m
CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
# CONFIG_UFS_FS_WRITE is not set
+CONFIG_9P_FS=m
+CONFIG_FUSE_FS=m
#
# Network File Systems
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_DIRECTIO=y
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
-CONFIG_SMB_FS=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
# CONFIG_SMB_NLS_DEFAULT is not set
CONFIG_CIFS=m
# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
CONFIG_NCP_FS=m
CONFIG_NCPFS_PACKET_SIGNING=y
CONFIG_NCPFS_IOCTL_LOCKING=y
CONFIG_NCPFS_SMALLDOS=y
CONFIG_NCPFS_NLS=y
CONFIG_NCPFS_EXTRAS=y
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
# CONFIG_AFS_FS is not set
# CONFIG_RXRPC is not set
+CONFIG_OCFS2_FS=m
+CONFIG_CONFIGFS_FS=m
+
#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
CONFIG_OSF_PARTITION=y
-# CONFIG_AMIGA_PARTITION is not set
+CONFIG_AMIGA_PARTITION=y
# CONFIG_ATARI_PARTITION is not set
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
CONFIG_SOLARIS_X86_PARTITION=y
CONFIG_UNIXWARE_DISKLABEL=y
# CONFIG_LDM_PARTITION is not set
-# CONFIG_NEC98_PARTITION is not set
CONFIG_SGI_PARTITION=y
# CONFIG_ULTRIX_PARTITION is not set
CONFIG_SUN_PARTITION=y
CONFIG_EFI_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+
CONFIG_NLS=y
#
# Native Language Support
#
CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
CONFIG_NLS_CODEPAGE_850=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=m
+CONFIG_NLS_ASCII=y
#
# Profiling support
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
-#
-# Tux
-#
-CONFIG_TUX=m
-CONFIG_TUX_EXTCGI=y
-# CONFIG_TUX_EXTENDED_LOG is not set
-# CONFIG_TUX_DEBUG is not set
-
-
#
# Kernel hacking
#
CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_STACKOVERFLOW=y
-# CONFIG_DEBUG_SLAB is not set
CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_DEBUG_HIGHMEM is not set
CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_FRAME_POINTER is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# Turn off these debug options for production kernels.
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_VM=y
+
+# These debug options are deliberatly left on.
+# They aren't that much of a performance impact, and the value
+# from getting out-of-tree modules fixed is worth the trade-off.
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_BOOT_DELAY=y
+CONFIG_DEBUG_SLAB_LEAK=y
+
+CONFIG_KGDB=y
+# CONFIG_KGDB_CONSOLE is not set
+CONFIG_KGDBOE=m
+# CONFIG_KGDB_SIMPLE_SERIAL is not set
+CONFIG_KGDB_8250_CONF_STRING=""
#
# Security options
#
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_NETWORK_XFRM=y
CONFIG_SECURITY_CAPABILITIES=y
# CONFIG_SECURITY_ROOTPLUG is not set
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_SECURITY_SELINUX_DEVELOP=y
-# CONFIG_SECURITY_SELINUX_MLS is not set
-# CONFIG_AUDIT is not set
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SECLVL is not set
+CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
#
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_TEST is not set
CONFIG_LIBCRC32C=m
CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_SIGNATURE_DSA=y
+CONFIG_CRYPTO_MPILIB=y
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_TGR192=m
#
# Library routines
#
+CONFIG_CRC16=m
CONFIG_CRC32=m
+CONFIG_CRC_CCITT=m
+
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
-CONFIG_PC=y
+
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+CONFIG_ATA_OVER_ETH=m
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+CONFIG_NETDUMP=m
+CONFIG_DISKDUMP=m
+
+CONFIG_SCHEDSTATS=y
+
+CONFIG_TUX=m
+CONFIG_TUX_EXTCGI=y
+CONFIG_TUX_EXTENDED_LOG=y
+# CONFIG_TUX_DEBUG is not set
+
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+# CONFIG_SECCOMP is not set
+# CONFIG_PRINTK_TIME is not set
+
+CONFIG_DETECT_SOFTLOCKUP=y
+
+CONFIG_KEXEC=y
+
+CONFIG_HWMON=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+CONFIG_INOTIFY=y
+
+CONFIG_CONNECTOR=m
+
+CONFIG_IBMASR=m
+
+CONFIG_PM_LEGACY=y
+
+CONFIG_CRASH=m
+
+## BEGIN ISA Junk.
+
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_PROBE is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_CD_NO_IDESCSI is not set
+
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
+CONFIG_EL3=m
+# CONFIG_3C515 is not set
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+CONFIG_ULTRA=m
+# CONFIG_SMC9194 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NI52 is not set
+# CONFIG_NI65 is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+CONFIG_NET_ISA=y
+CONFIG_NE2000=m
+# CONFIG_E2100 is not set
+CONFIG_EWRK3=m
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
+# CONFIG_ZNET is not set
+# CONFIG_SEEQ8005 is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_IBMTR is not set
+# CONFIG_SKISA is not set
+# CONFIG_PROTEON is not set
+# CONFIG_SMCTR is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_HISAX_16_0 is not set
+# CONFIG_HISAX_AVM_A1 is not set
+# CONFIG_HISAX_IX1MICROR2 is not set
+# CONFIG_HISAX_ASUSCOM is not set
+# CONFIG_HISAX_TELEINT is not set
+# CONFIG_HISAX_HFCS is not set
+# CONFIG_HISAX_SPORTSTER is not set
+# CONFIG_HISAX_MIC is not set
+# CONFIG_HISAX_ISURF is not set
+# CONFIG_HISAX_HSTSAPHIR is not set
+# CONFIG_ISDN_DRV_ICN is not set
+# CONFIG_ISDN_DRV_PCBIT is not set
+# CONFIG_ISDN_DRV_SC is not set
+# CONFIG_ISDN_DRV_ACT2000 is not set
+# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set
+# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set
+
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_ATIXL is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_WDT is not set
+
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+
+# CONFIG_SND_OPL4_LIB is not set
+# CONFIG_SND_AD1848_LIB is not set
+# CONFIG_SND_AD1816A is not set
+# CONFIG_SND_AD1848 is not set
+# CONFIG_SND_CS4231 is not set
+# CONFIG_SND_CS4232 is not set
+CONFIG_SND_CS4231_LIB=m
+CONFIG_SND_CS4236=m
+# CONFIG_SND_ES968 is not set
+# CONFIG_SND_ES1688 is not set
+CONFIG_SND_ES18XX=m
+# CONFIG_SND_GUS_SYNTH is not set
+# CONFIG_SND_GUSCLASSIC is not set
+# CONFIG_SND_GUSEXTREME is not set
+# CONFIG_SND_GUSMAX is not set
+# CONFIG_SND_INTERWAVE is not set
+# CONFIG_SND_INTERWAVE_STB is not set
+# CONFIG_SND_OPTI92X_AD1848 is not set
+# CONFIG_SND_OPTI92X_CS4231 is not set
+# CONFIG_SND_OPTI93X is not set
+# CONFIG_SND_SB8 is not set
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+# CONFIG_SND_SB16_CSP is not set
+# CONFIG_SND_ALS100 is not set
+# CONFIG_SND_AZT2320 is not set
+# CONFIG_SND_CMI8330 is not set
+# CONFIG_SND_DT019X is not set
+CONFIG_SND_OPL3SA2=m
+# CONFIG_SND_SGALAXY is not set
+# CONFIG_SND_SSCAPE is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+## END of ISA options.
+
+# FIXME: This needs to be made to depend on PPC
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+
+CONFIG_UNWIND_INFO=y
+# CONFIG_FORCED_INLINING is not set
+
+CONFIG_MIGRATION=y
+# CONFIG_NEW_LEDS is not set
+
+CONFIG_UID16=y
# CONFIG_X86_PC is not set
+CONFIG_X86_GENERICARCH=y
# CONFIG_X86_ELAN is not set
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_NUMAQ is not set
# CONFIG_X86_SUMMIT is not set
# CONFIG_X86_BIGSMP is not set
# CONFIG_X86_VISWS is not set
-CONFIG_X86_GENERICARCH=y
# CONFIG_X86_ES7000 is not set
# CONFIG_M386 is not set
# CONFIG_M486 is not set
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_HPET=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
-CONFIG_NR_CPUS=32
+# CONFIG_HPET_RTC_IRQ is not set
+# CONFIG_HPET_MMAP is not set
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_TSC=y
CONFIG_X86_MSR=m
CONFIG_X86_CPUID=m
CONFIG_EDD=m
-# CONFIG_NOHIGHMEM is not set
-CONFIG_HIGHMEM4G=y
-CONFIG_HIGHMEM64G=y
-# CONFIG_HIGHMEM64G is not set
+# CONFIG_NUMA is not set
CONFIG_HIGHMEM=y
CONFIG_HIGHPTE=y
# CONFIG_MATH_EMULATION is not set
CONFIG_MTRR=y
-CONFIG_HAVE_DEC_LOCK=y
-# CONFIG_X86_UP_APIC is not set
+CONFIG_X86_UP_APIC=y
+CONFIG_X86_UP_IOAPIC=y
CONFIG_X86_PM_TIMER=y
-CONFIG_X86_4G=y
-# CONFIG_EFI is not set
+CONFIG_EFI=y
+CONFIG_EFI_VARS=y
+CONFIG_EFI_PCDP=y
+CONFIG_EFI_RTC=y
CONFIG_REGPARM=y
# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GODIRECT is not set
+# CONFIG_PCI_GOMMCONFIG is not set
CONFIG_PCI_GOANY=y
-CONFIG_MDA_CONSOLE=m
+CONFIG_ROCKETPORT=m
CONFIG_SYNCLINK_CS=m
CONFIG_SYNCLINK=m
CONFIG_SYNCLINKMP=m
CONFIG_HP100=m
CONFIG_PCMCIA_FDOMAIN=m
CONFIG_SCSI_FUTURE_DOMAIN=m
-CONFIG_CRASH=m
+CONFIG_SCSI_ADVANSYS=m
+CONFIG_CAPI_EICON=y
CONFIG_I2O=m
+CONFIG_I2O_BLOCK=m
+CONFIG_I2O_SCSI=m
+CONFIG_I2O_PROC=m
+CONFIG_I2O_CONFIG=y
+CONFIG_I2O_EXT_ADAPTEC=y
+CONFIG_I2O_EXT_ADAPTEC_DMA64=y
+CONFIG_I2O_CONFIG_OLD_IOCTL=y
+CONFIG_I2O_BUS=m
CONFIG_APM=y
# CONFIG_APM_IGNORE_USER_SUSPEND is not set
# CONFIG_APM_DO_ENABLE is not set
# CONFIG_APM_REAL_MODE_POWER_OFF is not set
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y
-CONFIG_4KSTACKS=y
+CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_AC=m
+CONFIG_ACPI_BATTERY=m
+CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_ASUS=m
+CONFIG_ACPI_TOSHIBA=m
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_EC=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+CONFIG_ACPI_NUMA=y
+CONFIG_ACPI_BLACKLIST_YEAR=1999
+CONFIG_ACPI_VIDEO=m
+CONFIG_ACPI_IBM=m
+CONFIG_PNPACPI=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEBUG=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
CONFIG_X86_ACPI_CPUFREQ=m
# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
-CONFIG_X86_POWERNOW_K6=m
+# CONFIG_X86_POWERNOW_K6 is not set
CONFIG_X86_POWERNOW_K7=y
-CONFIG_X86_POWERNOW_K8=m
+CONFIG_X86_POWERNOW_K8=y
# CONFIG_X86_GX_SUSPMOD is not set
CONFIG_X86_SPEEDSTEP_CENTRINO=y
CONFIG_X86_SPEEDSTEP_ICH=y
-CONFIG_X86_SPEEDSTEP_SMI=m
+CONFIG_X86_SPEEDSTEP_SMI=y
CONFIG_X86_SPEEDSTEP_LIB=y
CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
+CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y
# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set
CONFIG_X86_P4_CLOCKMOD=m
CONFIG_X86_LONGRUN=y
# CONFIG_X86_LONGHAUL is not set
+# CONFIG_X86_CPUFREQ_NFORCE2 is not set
CONFIG_X86_SMP=y
CONFIG_X86_HT=y
CONFIG_X86_BIOS_REBOOT=y
CONFIG_X86_TRAMPOLINE=y
-CONFIG_TUX=m
-CONFIG_NVRAM=m
+CONFIG_NVRAM=y
CONFIG_IBM_ASM=m
-CONFIG_M686=y
-# CONFIG_NOHIGHMEM is not set
-CONFIG_HIGHMEM64G=y
+CONFIG_CRYPTO_AES_586=m
+CONFIG_CRYPTO_DEV_PADLOCK=m
+CONFIG_CRYPTO_DEV_PADLOCK_AES=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_SCHED_SMT=y
+# CONFIG_IRQBALANCE is not set
+CONFIG_SOFTWARE_SUSPEND=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_STD_PARTITION=""
+CONFIG_DEBUG_RODATA=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_STACK_BACKTRACE_COLS=2
+CONFIG_4KSTACKS=y
+CONFIG_KPROBES=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_MMCONFIG=y
+CONFIG_PCI_BIOS=y
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_COMPAQ=m
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
CONFIG_HOTPLUG_PCI_IBM=m
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI_ACPI_IBM=m
+CONFIG_ACPI_IBM_DOCK=y
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+CONFIG_HOTPLUG_PCI_PCIE=m
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY is not set
+CONFIG_PM=y
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW_QOS=y
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD756_S4882=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+CONFIG_I2C_I810=m
+CONFIG_I2C_ISA=m
+CONFIG_I2C_NFORCE2=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_PROSAVAGE=m
+CONFIG_I2C_SAVAGE4=m
+# CONFIG_SCx200_ACB is not set
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_VOODOO3=m
+# CONFIG_X86_REBOOTFIXUPS is not set
+CONFIG_PHYSICAL_START=0x400000
+CONFIG_DELL_RBU=m
+CONFIG_DCDBAS=m
+CONFIG_CS5535_GPIO=m
+CONFIG_EDAC=y
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_EDAC_AMD76X=m
+CONFIG_EDAC_E7XXX=m
+CONFIG_EDAC_E752X=m
+CONFIG_EDAC_I82875P=m
+CONFIG_EDAC_I82860=m
+CONFIG_EDAC_R82600=m
+CONFIG_SCHED_MC=y
+CONFIG_SND_ES18XX=m
+CONFIG_TCG_INFINEON=m
+CONFIG_M686=y
+# CONFIG_SMP is not set
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
# CONFIG_HIGHMEM64G is not set
-# CONFIG_EWRK3 is not set
-CONFIG_NR_CPUS=32
-# CONFIG_X86_PC is not set
-CONFIG_X86_GENERICARCH=y
Context: nominally process, but don't sleep inside an rwlock
dev->hard_start_xmit:
- Synchronization: dev->xmit_lock spinlock.
+ Synchronization: netif_tx_lock spinlock.
When the driver sets NETIF_F_LLTX in dev->features this will be
- called without holding xmit_lock. In this case the driver
+ called without holding netif_tx_lock. In this case the driver
has to lock by itself when needed. It is recommended to use a try lock
for this and return -1 when the spin lock fails.
The locking there should also properly protect against
Only valid when NETIF_F_LLTX is set.
dev->tx_timeout:
- Synchronization: dev->xmit_lock spinlock.
+ Synchronization: netif_tx_lock spinlock.
Context: BHs disabled
Notes: netif_queue_stopped() is guaranteed true
dev->set_multicast_list:
- Synchronization: dev->xmit_lock spinlock.
+ Synchronization: netif_tx_lock spinlock.
Context: BHs disabled
dev->poll:
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
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 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.
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
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
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
config X86_LOCAL_APIC
bool
- depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER)
+ depends on X86_UP_APIC || ((X86_VISWS || SMP) && !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST))
default y
config X86_IO_APIC
bool
- depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER))
+ depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER || XEN_UNPRIVILEGED_GUEST))
default y
config X86_VISWS_APIC
depends on X86_VISWS
default y
+config X86_TSC
+ bool
+ depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ && !X86_XEN
+ default y
+
config X86_MCE
bool "Machine Check Exception"
- depends on !X86_VOYAGER
+ depends on !(X86_VOYAGER || X86_XEN)
---help---
Machine Check Exception support allows the processor to notify the
kernel if it detects a problem (e.g. overheating, component failure).
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
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
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
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
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
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
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
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.
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
endmenu
+config ARCH_ENABLE_MEMORY_HOTPLUG
+ def_bool y
+ depends on HIGHMEM
menu "Power management options (ACPI, APM)"
- depends on !X86_VOYAGER
+ depends on !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST)
+if !X86_XEN
source kernel/power/Kconfig
+endif
source "drivers/acpi/Kconfig"
menu "APM (Advanced Power Management) BIOS Support"
-depends on PM && !X86_VISWS
+depends on PM && !(X86_VISWS || X86_XEN)
config APM
tristate "APM (Advanced Power Management) BIOS support"
- depends on PM
+ depends on PM && PM_LEGACY
---help---
APM is a BIOS specification for saving power using several different
techniques. This is mostly useful for battery powered laptops with
config PCI_GOBIOS
bool "BIOS"
+ depends on !X86_XEN
config PCI_GOMMCONFIG
bool "MMConfig"
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_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
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"
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
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
source "crypto/Kconfig"
+source "drivers/xen/Kconfig"
+
source "lib/Kconfig"
#
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
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 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
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
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
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
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
install:
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
+endif
archclean:
$(Q)$(MAKE) $(clean)=arch/i386/boot
CLEAN_FILES += arch/$(ARCH)/boot/fdimage \
arch/$(ARCH)/boot/image.iso \
arch/$(ARCH)/boot/mtools.conf
+CLEAN_FILES += vmlinuz vmlinux-stripped
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
$(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
SYSCFLAGS_vsyscall-syms.o = -r
$(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
- $(obj)/vsyscall-sysenter.o $(obj)/vsyscall-note.o FORCE
+ $(obj)/vsyscall-sysenter.o $(obj)/$(vsyscall_note) FORCE
$(call if_changed,syscall)
+
+ifdef CONFIG_XEN
+include $(srctree)/scripts/Makefile.xen
+
+obj-y += fixup.o
+microcode-$(subst m,y,$(CONFIG_MICROCODE)) := microcode-xen.o
+n-obj-xen := i8259.o timers/ reboot.o smpboot.o trampoline.o
+
+obj-y := $(call filterxen, $(obj-y), $(n-obj-xen))
+obj-y := $(call cherrypickxen, $(obj-y))
+extra-y := $(call cherrypickxen, $(extra-y))
+endif
obj-y += cstate.o processor.o
endif
+ifdef CONFIG_XEN
+include $(srctree)/scripts/Makefile.xen
+obj-y := $(call cherrypickxen, $(obj-y), $(src))
+endif
#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))
OFFSET(pbe_orig_address, pbe, orig_address);
OFFSET(pbe_next, pbe, next);
+#ifndef CONFIG_X86_NO_TSS
/* Offset from the sysenter stack to tss.esp0 */
- DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, esp0) -
+ DEFINE(SYSENTER_stack_esp0, offsetof(struct tss_struct, esp0) -
sizeof(struct tss_struct));
+#else
+ /* sysenter stack points directly to esp0 */
+ DEFINE(SYSENTER_stack_esp0, 0);
+#endif
DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
- DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
}
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
rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
- /* recalibrate cpu_khz */
recalibrate_cpu_khz();
fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
* 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;
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
# 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)
ENTRY(irq_entries_start)
.rept NR_IRQS
ALIGN
-1: pushl $vector-256
+1: pushl $~(vector)
jmp common_interrupt
.data
.long 1b
#define BUILD_INTERRUPT(name, nr) \
ENTRY(name) \
- pushl $nr-256; \
+ pushl $~(nr); \
SAVE_ALL \
movl %esp,%eax; \
call smp_/**/name; \
* 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.
*
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
*/
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;
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"),
- },
- },
{ }
};
#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 <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)
{
+#ifndef CONFIG_X86_NO_TSS
int cpu = get_cpu();
struct tss_struct *tss = &per_cpu(init_tss, cpu);
wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0);
wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0);
put_cpu();
+#endif
}
/*
*/
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)
sysenter_pages[0] = virt_to_page(page);
- if (!boot_cpu_has(X86_FEATURE_SEP)) {
+#ifdef CONFIG_XEN
+ if (boot_cpu_has(X86_FEATURE_SEP)) {
+ struct callback_register sysenter = {
+ .type = CALLBACKTYPE_sysenter,
+ .address = { __KERNEL_CS, (unsigned long)sysenter_entry },
+ };
+
+ if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) < 0)
+ clear_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability);
+ }
+#endif
+
+ if (boot_cpu_has(X86_FEATURE_SEP)) {
memcpy(page,
- &vsyscall_int80_start,
- &vsyscall_int80_end - &vsyscall_int80_start);
+ &vsyscall_sysenter_start,
+ &vsyscall_sysenter_end - &vsyscall_sysenter_start);
return 0;
}
memcpy(page,
- &vsyscall_sysenter_start,
- &vsyscall_sysenter_end - &vsyscall_sysenter_start);
+ &vsyscall_int80_start,
+ &vsyscall_int80_end - &vsyscall_int80_start);
return 0;
}
return err;
}
+#ifndef CONFIG_XEN
int in_gate_area_no_task(unsigned long addr)
{
return 0;
{
return NULL;
}
+#endif
static void io_check_error(unsigned char reason, struct pt_regs * regs)
{
- unsigned long i;
-
printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
show_registers(regs);
/* Re-enable the IOCK line, wait for a few seconds */
- reason = (reason & 0xf) | 8;
- outb(reason, 0x61);
- i = 2000;
- while (--i) udelay(1000);
- reason &= ~8;
- outb(reason, 0x61);
+ clear_io_check_error(reason);
}
static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
struct pt_regs * FASTCALL(save_v86_state(struct kernel_vm86_regs * regs));
struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs)
{
+#ifndef CONFIG_X86_NO_TSS
struct tss_struct *tss;
+#endif
struct pt_regs *ret;
unsigned long tmp;
do_exit(SIGSEGV);
}
+#ifndef CONFIG_X86_NO_TSS
tss = &per_cpu(init_tss, get_cpu());
+#endif
current->thread.esp0 = current->thread.saved_esp0;
current->thread.sysenter_cs = __KERNEL_CS;
load_esp0(tss, ¤t->thread);
current->thread.saved_esp0 = 0;
+#ifndef CONFIG_X86_NO_TSS
put_cpu();
+#endif
loadsegment(fs, current->thread.saved_fs);
loadsegment(gs, current->thread.saved_gs);
static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk)
{
+#ifndef CONFIG_X86_NO_TSS
struct tss_struct *tss;
+#endif
long eax;
/*
* make sure the vm86() system call doesn't try to do anything silly
savesegment(fs, tsk->thread.saved_fs);
savesegment(gs, tsk->thread.saved_gs);
+#ifndef CONFIG_X86_NO_TSS
tss = &per_cpu(init_tss, get_cpu());
+#endif
tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
if (cpu_has_sep)
tsk->thread.sysenter_cs = 0;
load_esp0(tss, &tsk->thread);
+#ifndef CONFIG_X86_NO_TSS
put_cpu();
+#endif
tsk->thread.screen_bitmap = info->screen_bitmap;
if (info->flags & VM86_SCREEN_BITMAP)
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
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);
#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/spinlock.h>
+#include <linux/module.h>
#include <asm/system.h>
#include <asm/pgtable.h>
__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);
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)
oprofilefs.o oprofile_stats.o \
timer_int.o )
+ifdef CONFIG_XEN
+oprofile-y := $(DRIVER_OBJS) xenoprof.o
+else
oprofile-y := $(DRIVER_OBJS) init.o backtrace.o
oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o \
op_model_ppro.o op_model_p4.o
oprofile-$(CONFIG_X86_IO_APIC) += nmi_timer_int.o
+endif
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-$(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
#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
return;
if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
- pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE,
+ pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
E820_RESERVED)) {
- printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n");
+ printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
+ pci_mmcfg_config[0].base_address);
printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
return;
}
-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
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
return retval;
}
+int ia64_map_check_rgn(unsigned long addr, unsigned long len,
+ unsigned long flags)
+{
+ unsigned long roff;
+
+ /*
+ * Don't permit mappings into unmapped space, the virtual page table
+ * of a region, or across a region boundary. Note: RGN_MAP_LIMIT is
+ * equal to 2^n-PAGE_SIZE (for some integer n <= 61) and len > 0.
+ */
+ roff = REGION_OFFSET(addr);
+ if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len)))
+ return -EINVAL;
+ return 0;
+}
+
static inline unsigned long
do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff)
{
- unsigned long roff;
struct file *file = NULL;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
goto out;
}
- /*
- * Don't permit mappings into unmapped space, the virtual page table of a region,
- * or across a region boundary. Note: RGN_MAP_LIMIT is equal to 2^n-PAGE_SIZE
- * (for some integer n <= 61) and len > 0.
- */
- roff = REGION_OFFSET(addr);
- if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len))) {
- addr = -EINVAL;
- goto out;
- }
-
down_write(¤t->mm->mmap_sem);
addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(¤t->mm->mmap_sem);
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 (xpc_sysctl) {
unregister_sysctl_table(xpc_sysctl);
}
+
+ kfree(xpc_remote_copy_buffer_base);
}
partid_t partid;
struct xpc_partition *part;
pid_t pid;
+ size_t buf_size;
if (!ia64_platform_is("sn2")) {
return -ENODEV;
}
- /*
- * xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng
- * various portions of a partition's reserved page. Its size is based
- * on the size of the reserved page header and part_nasids mask. So we
- * need to ensure that the other items will fit as well.
- */
- if (XPC_RP_VARS_SIZE > XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES) {
- dev_err(xpc_part, "xpc_remote_copy_buffer is not big enough\n");
- return -EPERM;
- }
- DBUG_ON((u64) xpc_remote_copy_buffer !=
- L1_CACHE_ALIGN((u64) xpc_remote_copy_buffer));
+
+ buf_size = max(XPC_RP_VARS_SIZE,
+ XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES);
+ xpc_remote_copy_buffer = xpc_kmalloc_cacheline_aligned(buf_size,
+ GFP_KERNEL, &xpc_remote_copy_buffer_base);
+ if (xpc_remote_copy_buffer == NULL)
+ return -ENOMEM;
snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part");
snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan");
if (xpc_sysctl) {
unregister_sysctl_table(xpc_sysctl);
}
+
+ kfree(xpc_remote_copy_buffer_base);
return -EBUSY;
}
if (xpc_sysctl) {
unregister_sysctl_table(xpc_sysctl);
}
+
+ kfree(xpc_remote_copy_buffer_base);
return -EBUSY;
}
if (xpc_sysctl) {
unregister_sysctl_table(xpc_sysctl);
}
+
+ kfree(xpc_remote_copy_buffer_base);
return -EBUSY;
}
* Generic buffer used to store a local copy of portions of a remote
* partition's reserved page (either its header and part_nasids mask,
* or its vars).
- *
- * xpc_discovery runs only once and is a seperate thread that is
- * very likely going to be processing in parallel with receiving
- * interrupts.
*/
-char ____cacheline_aligned xpc_remote_copy_buffer[XPC_RP_HEADER_SIZE +
- XP_NASID_MASK_BYTES];
+char *xpc_remote_copy_buffer;
+void *xpc_remote_copy_buffer_base;
/*
* Guarantee that the kmalloc'd memory is cacheline aligned.
*/
-static void *
+void *
xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
{
/* see if kmalloc will give us cachline aligned memory by default */
}
}
- 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);
/* 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) {
/* 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) {
return xpcVarsNotSet;
}
-
/* pull over the cross partition variables */
-
- bres = xp_bte_copy(remote_vars_pa, ia64_tpa((u64) remote_vars),
- XPC_RP_VARS_SIZE,
+ bres = xp_bte_copy(remote_vars_pa, (u64) remote_vars, XPC_RP_VARS_SIZE,
(BTE_NOTIFY | BTE_WACQUIRE), NULL);
if (bres != BTE_SUCCESS) {
return xpc_map_bte_errors(bres);
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);
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
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
#include <linux/elf.h>
#include <linux/elfcore.h>
#include <linux/init.h>
+#include <linux/irq.h>
#include <linux/types.h>
#include <asm/processor.h>
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.
*/
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);
ops->cppr_info(cpu, 0x00);
iosync();
+ /*
+ * Clear IPI
+ */
+ ops->qirr_info(cpu, 0xff);
+ /*
+ * we need to EOI the IPI if we got here from kexec down IPI
+ *
+ * probably need to check all the other interrupts too
+ * should we be flagging idle loop instead?
+ * or creating some task to be scheduled?
+ */
+ ops->xirr_info_set(cpu, XICS_IPI);
+
/*
* Some machines need to have at least one cpu in the GIQ,
* so leave the master cpu in the group.
*/
- if (secondary) {
- /*
- * we need to EOI the IPI if we got here from kexec down IPI
- *
- * probably need to check all the other interrupts too
- * should we be flagging idle loop instead?
- * or creating some task to be scheduled?
- */
- ops->xirr_info_set(cpu, XICS_IPI);
+ if (secondary)
rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
(1UL << interrupt_server_size) - 1 -
default_distrib_server, 0);
- }
+
}
#ifdef CONFIG_HOTPLUG_CPU
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,
goto out;
}
- retval = -EINVAL;
len = PAGE_ALIGN(len);
- if (ARCH_SUN4C_SUN4 &&
- (len > 0x20000000 ||
- ((flags & MAP_FIXED) &&
- addr < 0xe0000000 && addr + len > 0x20000000)))
- goto out_putf;
-
- /* See asm-sparc/uaccess.h */
- if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
- goto out_putf;
-
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
down_write(¤t->mm->mmap_sem);
retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(¤t->mm->mmap_sem);
-out_putf:
if (file)
fput(file);
out:
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,
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
len = PAGE_ALIGN(len);
- retval = -EINVAL;
-
- if (test_thread_flag(TIF_32BIT)) {
- if (len >= STACK_TOP32)
- goto out_putf;
-
- if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len)
- goto out_putf;
- } else {
- if (len >= VA_EXCLUDE_START)
- goto out_putf;
-
- if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len))
- goto out_putf;
- }
down_write(¤t->mm->mmap_sem);
retval = do_mmap(file, addr, len, prot, flags, off);
up_write(¤t->mm->mmap_sem);
-out_putf:
if (file)
fput(file);
out:
} 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);
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;
virt = __va(page_to_phys(page + i));
physmem_remove_mapping(virt);
}
+
+ return 0;
}
int is_remapped(void *virt)
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
#
config X86_TSC
bool
+ depends on !X86_64_XEN
default y
config X86_GOOD_APIC
config X86_HT
bool
- depends on SMP && !MK8
+ depends on SMP && !MK8 && !X86_64_XEN
default y
config MATH_EMULATION
config X86_IO_APIC
bool
+ depends !XEN_UNPRIVILEGED_GUEST
default y
+config X86_XEN_GENAPIC
+ bool
+ depends X86_64_XEN
+ default XEN_PRIVILEGED_GUEST || SMP
+
config X86_LOCAL_APIC
bool
+ depends !XEN_UNPRIVILEGED_GUEST
default y
config MTRR
bool "MTRR (Memory Type Range Register) support"
+ depends on !XEN_UNPRIVILEGED_GUEST
---help---
On Intel P6 family processors (Pentium Pro, Pentium II and later)
the Memory Type Range Registers (MTRRs) may be used to control
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
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
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
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
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
can be controlled through /sys/devices/system/cpu/cpu#.
Say N if you want to disable CPU hotplug.
+config ARCH_ENABLE_MEMORY_HOTPLUG
+ def_bool y
config HPET_TIMER
bool
+ depends on !X86_64_XEN
default y
help
Use the IA-PC HPET (High Precision Event Timer) to manage
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.
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.
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
default y
menu "Power management options"
+ depends on !XEN_UNPRIVILEGED_GUEST
+if !X86_64_XEN
source kernel/power/Kconfig
+endif
source "drivers/acpi/Kconfig"
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 "crypto/Kconfig"
+source "drivers/xen/Kconfig"
+
source "lib/Kconfig"
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
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
install:
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
+endif
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
-Wl,-soname=linux-gate.so.1 -o $@ \
-Wl,-T,$(filter-out FORCE,$^)
+$(obj)/vsyscall-int80.so \
$(obj)/vsyscall-sysenter.so $(obj)/vsyscall-syscall.so: \
$(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
$(call if_changed,syscall)
-AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32
-AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32
+AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32 -Iarch/i386/kernel
+AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32 -Iarch/i386/kernel
+
+ifdef CONFIG_XEN
+AFLAGS_vsyscall-int80.o = -m32 -Wa,-32 -Iarch/i386/kernel
+CFLAGS_syscall32-xen.o += -DUSE_INT80
+AFLAGS_syscall32_syscall-xen.o += -DUSE_INT80
+
+$(obj)/syscall32_syscall-xen.o: \
+ $(foreach F,int80 sysenter syscall,$(obj)/vsyscall-$F.so)
+
+targets := $(foreach F,int80 sysenter syscall,vsyscall-$F.o vsyscall-$F.so)
+
+include $(srctree)/scripts/Makefile.xen
+
+obj-y := $(call cherrypickxen, $(obj-y))
+endif
.align 4
.LENDFDE3:
-#include "../../i386/kernel/vsyscall-note.S"
+#include <vsyscall-note.S>
obj-$(CONFIG_X86_CPUID) += cpuid.o
obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
+obj-$(CONFIG_X86_XEN_GENAPIC) += genapic.o genapic_xen.o
obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o \
genapic.o genapic_cluster.o genapic_flat.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
-obj-$(CONFIG_PM) += suspend.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
+obj-$(CONFIG_ACPI_SLEEP) += suspend.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o
obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
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
obj-y += processor.o
endif
+boot-$(CONFIG_XEN) := ../../../i386/kernel/acpi/boot-xen.o
DEFINE(pbe_address, offsetof(struct pbe, address));
DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
DEFINE(pbe_next, offsetof(struct pbe, next));
+#ifndef CONFIG_X86_NO_TSS
BLANK();
DEFINE(TSS_ist, offsetof(struct tss_struct, ist));
+#endif
return 0;
}
*/
.macro apicinterrupt num,func
INTR_FRAME
- pushq $\num-256
+ pushq $~(\num)
CFI_ADJUST_CFA_OFFSET 8
interrupt \func
jmp ret_from_intr
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
* 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")))
*/
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();
delta = cyc2us((tick - last_pmtmr_tick) & ACPI_PM_MASK);
last_pmtmr_tick = tick;
+#ifndef CONFIG_XEN
monotonic_base += delta * NSEC_PER_USEC;
+#endif
delta += offset_delay;
.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)
{
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;
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:
cpu = smp_processor_id();
/*
- * orig_rax contains the interrupt vector - 256.
+ * orig_rax contains the negated interrupt vector.
* Use that to determine where the sender put the data.
*/
- sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START;
+ sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
f = &per_cpu(flush_state, sender);
if (!cpu_isset(cpu, f->flush_cpumask))
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
oprofilefs.o oprofile_stats.o \
timer_int.o )
+ifdef CONFIG_XEN
+OPROFILE-y := xenoprof.o
+else
OPROFILE-y := init.o backtrace.o
OPROFILE-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o op_model_p4.o \
op_model_ppro.o
OPROFILE-$(CONFIG_X86_IO_APIC) += nmi_timer_int.o
-
+endif
oprofile-y = $(DRIVER_OBJS) $(addprefix ../../i386/oprofile/, $(OPROFILE-y))
obj-$(CONFIG_NUMA) += k8-bus.o
+# pcifront should be after mmconfig.o and direct.o as it should only
+# take over if direct access to the PCI bus is unavailable
+obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += pcifront.o
+
direct-y += ../../i386/pci/direct.o
acpi-y += ../../i386/pci/acpi.o
+pcifront-y += ../../i386/pci/pcifront.o
legacy-y += ../../i386/pci/legacy.o
irq-y += ../../i386/pci/irq.o
common-y += ../../i386/pci/common.o
fixup-y += ../../i386/pci/fixup.o
i386-y += ../../i386/pci/i386.o
init-y += ../../i386/pci/init.o
+
+ifdef CONFIG_XEN
+irq-y := ../../i386/pci/irq-xen.o
+include $(srctree)/scripts/Makefile.xen
+
+obj-y := $(call cherrypickxen, $(obj-y))
+endif
#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
return;
if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
- pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE,
+ pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
E820_RESERVED)) {
- printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n");
+ printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
+ pci_mmcfg_config[0].base_address);
printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
return;
}
}
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);
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);
/* 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
+# i386
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17-prep
-# Thu Jul 27 16:52:11 2006
+# Linux kernel version: 2.6.17.13
+# Wed Oct 18 17:15:50 2006
#
CONFIG_X86_32=y
CONFIG_SEMAPHORE_SLEEPERS=y
#
# 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_MICROCODE is not set
CONFIG_X86_MSR=m
CONFIG_X86_CPUID=m
+# CONFIG_SWIOTLB is not set
#
# Firmware Drivers
CONFIG_EFI_VARS=y
# CONFIG_DELL_RBU is not set
# CONFIG_DCDBAS is not set
-CONFIG_NOHIGHMEM=y
-# CONFIG_HIGHMEM4G is not set
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
# CONFIG_HIGHMEM64G is not set
CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_HIGHMEM=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
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_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_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_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_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_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_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_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
+# i386
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17-prep
-# Thu Jul 27 16:52:13 2006
+# Linux kernel version: 2.6.17.13
+# Wed Oct 18 17:15:52 2006
#
CONFIG_X86_32=y
CONFIG_SEMAPHORE_SLEEPERS=y
#
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_MICROCODE=m
CONFIG_X86_MSR=m
CONFIG_X86_CPUID=m
+# CONFIG_SWIOTLB is not set
#
# Firmware Drivers
# 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)
# 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_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_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_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_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
+# i386
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17-prep
-# Thu Jul 27 16:52:12 2006
+# Linux kernel version: 2.6.17.13
+# Wed Oct 18 17:15:54 2006
#
CONFIG_X86_32=y
CONFIG_SEMAPHORE_SLEEPERS=y
#
# 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_MICROCODE=m
CONFIG_X86_MSR=m
CONFIG_X86_CPUID=m
+# CONFIG_SWIOTLB is not set
#
# Firmware Drivers
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_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_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_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_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_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
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/
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---
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,
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;
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;
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;
# 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.
}
#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.
*ppos += written;
return written;
}
+#endif
#ifndef __HAVE_PHYS_MEM_ACCESS_PROT
static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
#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,
.mmap = mmap_mem,
.open = open_mem,
};
+#else
+extern struct file_operations mem_fops;
+#endif
static struct file_operations kmem_fops = {
.llseek = memory_lseek,
iowrite32(interrupt,
chip->vendor.iobase +
TPM_INT_STATUS(chip->vendor.locality));
+ ioread32(chip->vendor.iobase + TPM_INT_STATUS(chip->vendor.locality));
return IRQ_HANDLED;
}
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 */
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.
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;
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;
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;
disc->receive_buf(tty, char_buf, flag_buf, count);
spin_lock_irqsave(&tty->buf.lock, flags);
}
- if (tbuf->active)
+ if (tbuf->active) {
+ tty->buf.head = head;
break;
- tty->buf.head = tbuf->next;
- if (tty->buf.head == NULL)
+ }
+ head = tbuf->next;
+ if (head == NULL)
tty->buf.tail = NULL;
tty_buffer_free(tty, tbuf);
}
#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)
class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
vty_init();
+ out_vt:
#endif
return 0;
}
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
break;
case state_read:
- /* Set ACK if receiving the last byte */
- if (iface->len == 1)
+ /* Set ACK if _next_ byte will be the last one */
+ if (iface->len == 2)
outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
else
outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
- *iface->ptr++ = inb(ACBSDA);
- --iface->len;
-
- if (iface->len == 0) {
+ if (iface->len == 1) {
iface->result = 0;
iface->state = state_idle;
outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
}
+ *iface->ptr++ = inb(ACBSDA);
+ --iface->len;
+
break;
case state_write:
buffer = (u8 *)&cur_word;
break;
- case I2C_SMBUS_BLOCK_DATA:
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ if (rw == I2C_SMBUS_READ)
+ data->block[0] = I2C_SMBUS_BLOCK_MAX; /* For now */
len = data->block[0];
+ if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
+ return -EINVAL;
buffer = &data->block[1];
break;
{
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) */
"parameter for adapter %d, "
"addr 0x%02x\n", adap_id,
address_data->ignore[j + 1]);
+ ignore = 1;
+ break;
}
- ignore = 1;
- break;
}
if (ignore)
continue;
{
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;
}
*
* vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
* vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a,
- * vt8235, vt8237
+ * vt8235, vt8237, vt8237a
*
* Copyright (c) 2000-2002 Vojtech Pavlik
*
{ "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 },
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;
}
#endif
- pci_save_state(pdev);
-
return 0;
}
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;
}
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)
}
}
+ 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) {
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 */
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.
}
}
+ 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;
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_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) {
struct dm_snapshot *snap; /* up pointer to my snapshot */
int version;
int valid;
- uint32_t chunk_size;
uint32_t exceptions_per_area;
/*
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
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);
}
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);
}
{
int r;
struct disk_header *dh;
+ chunk_t chunk_size;
r = chunk_io(ps, 0, READ);
if (r)
*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;
{
struct disk_header *dh;
- memset(ps->area, 0, ps->chunk_size << SECTOR_SHIFT);
+ memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
dh = (struct disk_header *) ps->area;
dh->magic = cpu_to_le32(SNAP_MAGIC);
dh->valid = cpu_to_le32(ps->valid);
dh->version = cpu_to_le32(ps->version);
- dh->chunk_size = cpu_to_le32(ps->chunk_size);
+ dh->chunk_size = cpu_to_le32(ps->snap->chunk_size);
return chunk_io(ps, 0, WRITE);
}
{
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);
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 ?
*/
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;
if (r)
goto bad;
- /*
- * Allocate space for all the callbacks.
- */
ps->callback_count = 0;
atomic_set(&ps->pending_count, 0);
- ps->callbacks = dm_vcalloc(ps->exceptions_per_area,
- sizeof(*ps->callbacks));
-
- if (!ps->callbacks) {
- r = -ENOMEM;
- goto bad;
- }
+ ps->callbacks = NULL;
store->destroy = persistent_destroy;
store->read_metadata = persistent_read_metadata;
unsigned int h = hash_str(str);
list_for_each_entry (hc, _name_buckets + h, name_list)
- if (!strcmp(hc->name, str))
+ if (!strcmp(hc->name, str)) {
+ dm_get(hc->md);
return hc;
+ }
return NULL;
}
unsigned int h = hash_str(str);
list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
- if (!strcmp(hc->uuid, str))
+ if (!strcmp(hc->uuid, str)) {
+ dm_get(hc->md);
return hc;
+ }
return NULL;
}
*/
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.
* Insert the cell into both hash tables.
*/
down_write(&_hash_lock);
- if (__get_name_cell(name))
+ hc = __get_name_cell(name);
+ if (hc) {
+ dm_put(hc->md);
goto bad;
+ }
list_add(&cell->name_list, _name_buckets + hash_str(name));
if (uuid) {
- if (__get_uuid_cell(uuid)) {
+ hc = __get_uuid_cell(uuid);
+ if (hc) {
list_del(&cell->name_list);
+ dm_put(hc->md);
goto bad;
}
list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
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;
dm_table_put(table);
}
+ dm_put(hc->md);
up_write(&_hash_lock);
kfree(old_name);
return 0;
return __get_name_cell(param->name);
md = dm_get_md(huge_decode_dev(param->dev));
- if (md) {
+ if (md)
mdptr = dm_get_mdptr(md);
- dm_put(md);
- }
return mdptr;
}
hc = __find_device_hash_cell(param);
if (hc) {
md = hc->md;
- dm_get(md);
/*
* Sneakily write in both the name and the uuid
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);
return -ENXIO;
}
+ md = hc->md;
+
__hash_remove(hc);
up_write(&_hash_lock);
+ dm_put(md);
param->data_size = 0;
return 0;
}
}
md = hc->md;
- dm_get(md);
new_map = hc->new_map;
hc->new_map = NULL;
{
int r;
struct hash_cell *hc;
+ struct mapped_device *md;
down_write(&_hash_lock);
param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
r = __dev_status(hc->md, param);
+ md = hc->md;
up_write(&_hash_lock);
+ dm_put(md);
return r;
}
return -EINVAL;
}
+ m->ti = ti;
+
r = parse_features(&as, m, ti);
if (r)
goto bad;
}
ti->private = m;
- m->ti = ti;
return 0;
struct bio_list delayed_bios;
};
+
+/*-----------------------------------------------------------------
+ * Mirror set structures.
+ *---------------------------------------------------------------*/
+struct mirror {
+ atomic_t error_count;
+ struct dm_dev *dev;
+ sector_t offset;
+};
+
+struct mirror_set {
+ struct dm_target *ti;
+ struct list_head list;
+ struct region_hash rh;
+ struct kcopyd_client *kcopyd_client;
+
+ spinlock_t lock; /* protects the next two lists */
+ struct bio_list reads;
+ struct bio_list writes;
+
+ /* recovery */
+ region_t nr_regions;
+ int in_sync;
+
+ struct mirror *default_mirror; /* Default mirror */
+
+ unsigned int nr_mirrors;
+ struct mirror mirror[0];
+};
+
/*
* Conversion fns
*/
static inline region_t bio_to_region(struct region_hash *rh, struct bio *bio)
{
- return bio->bi_sector >> rh->region_shift;
+ return (bio->bi_sector - rh->ms->ti->begin) >> rh->region_shift;
}
static inline sector_t region_to_sector(struct region_hash *rh, region_t region)
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;
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.
*/
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);
}
ti->private = s;
- ti->split_io = chunk_size;
+ ti->split_io = s->chunk_size;
return 0;
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,
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,
static unsigned int major = 0;
static unsigned int _major = 0;
+static DEFINE_SPINLOCK(_minor_lock);
/*
* One of these is allocated per bio.
*/
return NULL;
}
+#define MINOR_ALLOCED ((void *)-1)
+
/*
* Bits for the md->flags field.
*/
#define DMF_BLOCK_IO 0
#define DMF_SUSPENDED 1
#define DMF_FROZEN 2
+#define DMF_FREEING 3
struct mapped_device {
struct rw_semaphore io_lock;
{
struct mapped_device *md;
+ spin_lock(&_minor_lock);
+
md = inode->i_bdev->bd_disk->private_data;
+ if (!md)
+ goto out;
+
+ if (test_bit(DMF_FREEING, &md->flags)) {
+ md = NULL;
+ goto out;
+ }
+
dm_get(md);
- return 0;
+
+out:
+ spin_unlock(&_minor_lock);
+
+ return md ? 0 : -ENXIO;
}
static int dm_blk_close(struct inode *inode, struct file *file)
/*-----------------------------------------------------------------
* An IDR is used to keep track of allocated minor numbers.
*---------------------------------------------------------------*/
-static DEFINE_MUTEX(_minor_lock);
static DEFINE_IDR(_minor_idr);
static void free_minor(unsigned int minor)
{
- mutex_lock(&_minor_lock);
+ spin_lock(&_minor_lock);
idr_remove(&_minor_idr, minor);
- mutex_unlock(&_minor_lock);
+ spin_unlock(&_minor_lock);
}
/*
if (minor >= (1 << MINORBITS))
return -EINVAL;
- mutex_lock(&_minor_lock);
+ r = idr_pre_get(&_minor_idr, GFP_KERNEL);
+ if (!r)
+ return -ENOMEM;
+
+ spin_lock(&_minor_lock);
if (idr_find(&_minor_idr, minor)) {
r = -EBUSY;
goto out;
}
- r = idr_pre_get(&_minor_idr, GFP_KERNEL);
- if (!r) {
- r = -ENOMEM;
- goto out;
- }
-
- r = idr_get_new_above(&_minor_idr, md, minor, &m);
- if (r) {
+ r = idr_get_new_above(&_minor_idr, MINOR_ALLOCED, minor, &m);
+ if (r)
goto out;
- }
if (m != minor) {
idr_remove(&_minor_idr, m);
}
out:
- mutex_unlock(&_minor_lock);
+ spin_unlock(&_minor_lock);
return r;
}
int r;
unsigned int m;
- mutex_lock(&_minor_lock);
-
r = idr_pre_get(&_minor_idr, GFP_KERNEL);
- if (!r) {
- r = -ENOMEM;
- goto out;
- }
+ if (!r)
+ return -ENOMEM;
- r = idr_get_new(&_minor_idr, md, &m);
+ spin_lock(&_minor_lock);
+
+ r = idr_get_new(&_minor_idr, MINOR_ALLOCED, &m);
if (r) {
goto out;
}
*minor = m;
out:
- mutex_unlock(&_minor_lock);
+ spin_unlock(&_minor_lock);
return r;
}
{
int r;
struct mapped_device *md = kmalloc(sizeof(*md), GFP_KERNEL);
+ void *old_md;
if (!md) {
DMWARN("unable to allocate device, out of memory.");
return NULL;
}
+ if (!try_module_get(THIS_MODULE))
+ goto bad0;
+
/* get a minor number for the dev */
r = persistent ? specific_minor(md, minor) : next_free_minor(md, &minor);
if (r < 0)
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;
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;
blk_cleanup_queue(md->queue);
free_minor(minor);
bad1:
+ module_put(THIS_MODULE);
+ bad0:
kfree(md);
return NULL;
}
mempool_destroy(md->io_pool);
del_gendisk(md->disk);
free_minor(minor);
+
+ spin_lock(&_minor_lock);
+ md->disk->private_data = NULL;
+ spin_unlock(&_minor_lock);
+
put_disk(md->disk);
blk_cleanup_queue(md->queue);
+ module_put(THIS_MODULE);
kfree(md);
}
if (MAJOR(dev) != _major || minor >= (1 << MINORBITS))
return NULL;
- mutex_lock(&_minor_lock);
+ spin_lock(&_minor_lock);
md = idr_find(&_minor_idr, minor);
- if (!md || (dm_disk(md)->first_minor != minor))
+ if (md && (md == MINOR_ALLOCED ||
+ (dm_disk(md)->first_minor != minor) ||
+ test_bit(DMF_FREEING, &md->flags))) {
md = NULL;
+ goto out;
+ }
- mutex_unlock(&_minor_lock);
+out:
+ spin_unlock(&_minor_lock);
return md;
}
{
struct dm_table *map;
- if (atomic_dec_and_test(&md->holders)) {
+ BUG_ON(test_bit(DMF_FREEING, &md->flags));
+
+ if (atomic_dec_and_lock(&md->holders, &_minor_lock)) {
map = dm_get_table(md);
+ idr_replace(&_minor_idr, MINOR_ALLOCED, dm_disk(md)->first_minor);
+ set_bit(DMF_FREEING, &md->flags);
+ spin_unlock(&_minor_lock);
if (!dm_suspended(md)) {
dm_table_presuspend_targets(map);
dm_table_postsuspend_targets(map);
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,
s<<9, conf->tmppage, READ) == 0)
/* Well, this device is dead */
md_error(mddev, rdev);
+ else
+ atomic_add(s, &rdev->corrected_errors);
+
}
}
} else {
.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;
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;
#include "cx24110.h"
#include "or51211.h"
#include "lgdt330x.h"
+#include "zl10353.h"
struct dvb_bt8xx_card {
struct mutex lock;
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... */
return ret;
if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+ /* normal tune mode when opened R/W */
+ fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT;
+ fepriv->tone = -1;
+ fepriv->voltage = -1;
+
ret = dvb_frontend_start (fe);
if (ret)
dvb_generic_release (inode, file);
/* empty event queue */
fepriv->events.eventr = fepriv->events.eventw = 0;
-
- /* normal tune mode when opened R/W */
- fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT;
- fepriv->tone = -1;
- fepriv->voltage = -1;
}
return ret;
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);
}
}
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
dvb_net_feed_start(dev);
}
{ 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);
struct tasklet_struct ciintf_irq_tasklet;
int slot_status;
struct dvb_ca_en50221 ca;
+ u8 reinitialise_demod:1;
};
/* GPIO Connections:
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)
{
struct saa7146_dev * saa = budget_av->budget.dev;
struct dvb_frontend * fe = NULL;
+ /* Enable / PowerON Frontend */
+ saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
+
switch (saa->pci->subsystem_device) {
case SUBID_DVBS_KNC1_PLUS:
case SUBID_DVBC_KNC1_PLUS:
case SUBID_DVBT_KNC1_PLUS:
- // Enable / PowerON Frontend
- saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
break;
}
break;
case SUBID_DVBC_KNC1:
+ budget_av->reinitialise_demod = 1;
+ fe = tda10021_attach(&philips_cu1216_config,
+ &budget_av->budget.i2c_adap,
+ read_pwm(budget_av));
+ break;
+
case SUBID_DVBC_KNC1_PLUS:
+ budget_av->reinitialise_demod = 1;
fe = tda10021_attach(&philips_cu1216_config,
&budget_av->budget.i2c_adap,
read_pwm(budget_av));
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;
}
// 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))
source "drivers/media/video/cx25840/Kconfig"
config VIDEO_SAA711X
- tristate "Philips SAA7113/4/5 video decoders (OBSOLETED)"
- depends on VIDEO_V4L1 && I2C && EXPERIMENTAL
+ tristate "Philips SAA7113/4/5 video decoders"
+ depends on VIDEO_DEV && I2C && EXPERIMENTAL
---help---
- Old support for the Philips SAA7113/4 video decoders.
+ Support for the Philips SAA7113/4/5 video decoders.
To compile this driver as a module, choose M here: the
module will be called saa7115.
{ 0 }
};
-MODULE_DEVICE_TABLE(pci, stradis_pci_tbl);
static struct pci_driver stradis_driver = {
.name = "stradis",
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];
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 +
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
}
#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
(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;
}
#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
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;
/*
*/
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;
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;
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++;
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:
#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
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)
}
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;
* 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;
}
}
#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:
#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
* critical parts:
* - rx is (pseudo-) lockless: it relies on the single-threading provided
* by the arch code for interrupts.
- * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission
+ * - tx setup is lockless: it relies on netif_tx_lock. Actual submission
* needs dev->priv->lock :-(
- * - set_multicast_list: preparation lockless, relies on dev->xmit_lock.
+ * - set_multicast_list: preparation lockless, relies on netif_tx_lock.
*/
/* in dev: base, irq */
/*
* 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)
{
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);
/*
* 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)
{
* 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);
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;
}
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 */
/* 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);
}
/*
* 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)
{
{
struct sockaddr_ax25 *sa = addr;
- spin_lock_irq(&dev->xmit_lock);
+ netif_tx_lock_bh(dev);
memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
- spin_unlock_irq(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
return 0;
}
break;
}
- spin_lock_irq(&dev->xmit_lock);
+ netif_tx_lock_bh(dev);
memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
- spin_unlock_irq(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
err = 0;
break;
{
struct sockaddr_ax25 *sa = addr;
- spin_lock_irq(&dev->xmit_lock);
+ netif_tx_lock_bh(dev);
memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
- spin_unlock_irq(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
return 0;
}
break;
}
- spin_lock_irq(&dev->xmit_lock);
+ netif_tx_lock_bh(dev);
memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
- spin_unlock_irq(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
err = 0;
break;
dp->st_task_enter++;
if ((skb = skb_peek(&dp->tq)) == NULL) {
dp->st_txq_refl_try++;
- if (spin_trylock(&_dev->xmit_lock)) {
+ if (netif_tx_trylock(_dev)) {
dp->st_rxq_enter++;
while ((skb = skb_dequeue(&dp->rq)) != NULL) {
skb_queue_tail(&dp->tq, skb);
dp->st_rx2tx_tran++;
}
- spin_unlock(&_dev->xmit_lock);
+ netif_tx_unlock(_dev);
} else {
/* reschedule */
dp->st_rxq_notenter++;
}
}
- 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;
netif_wake_queue(_dev);
} else {
dp->st_rxq_rsch++;
- spin_unlock(&_dev->xmit_lock);
+ netif_tx_unlock(_dev);
goto resched;
}
- spin_unlock(&_dev->xmit_lock);
+ netif_tx_unlock(_dev);
} else {
resched:
dp->tasklet_pending = 1;
|| (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! */
}
}
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)
}
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,
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);
#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);
}
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);
The rx process only runs in the interrupt handler. Access from outside
the interrupt handler is only permitted after disable_irq().
-The rx process usually runs under the dev->xmit_lock. If np->intr_tx_reap
+The rx process usually runs under the netif_tx_lock. If np->intr_tx_reap
is set, then access is permitted under spin_lock_irq(&np->lock).
Thus configuration functions that want to access everything must call
disable_irq(dev->irq);
- spin_lock_bh(dev->xmit_lock);
+ netif_tx_lock_bh(dev);
spin_lock_irq(&np->lock);
IV. Notes
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);
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);
}
}
frg_len = skb->len - skb->data_len;
- if (skb_shinfo(skb)->ufo_size) {
+ if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) {
int ufo_size;
- ufo_size = skb_shinfo(skb)->ufo_size;
+ ufo_size = skb_shinfo(skb)->gso_size;
ufo_size &= ~7;
txdp->Control_1 |= TXD_UFO_EN;
txdp->Control_1 |= TXD_UFO_MSS(ufo_size);
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;
(sp->pdev, frag->page, frag->page_offset,
frag->size, PCI_DMA_TODEVICE);
txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size);
- if (skb_shinfo(skb)->ufo_size)
+ if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
txdp->Control_1 |= TXD_UFO_EN;
}
txdp->Control_1 |= TXD_GATHER_CODE_LAST;
- if (skb_shinfo(skb)->ufo_size)
+ if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
frg_cnt++; /* as Txd0 was used for inband header */
tx_fifo = mac_control->tx_FIFO_start[queue];
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);
#include "sky2.h"
#define DRV_NAME "sky2"
-#define DRV_VERSION "1.4"
+#define DRV_VERSION "1.6.1"
#define PFX DRV_NAME " "
/*
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);
sky2_pci_write32(hw, PCI_DEV_REG5, 0);
}
- sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
-
break;
case PCI_D3hot:
}
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;
ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
}
}
- gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
} else {
/* workaround for deviation #4.88 (CRC errors) */
/* disable Automatic Crossover */
ctrl &= ~PHY_M_PC_MDIX_MSK;
- gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+ }
- if (hw->chip_id == CHIP_ID_YUKON_XL) {
- /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
- ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
- ctrl &= ~PHY_M_MAC_MD_MSK;
- ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
- gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+ /* special setup for PHY 88E1112 Fiber */
+ if (hw->chip_id == CHIP_ID_YUKON_XL && !sky2_is_copper(hw)) {
+ pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+
+ /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */
+ gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
+ ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+ ctrl &= ~PHY_M_MAC_MD_MSK;
+ ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+ if (hw->pmd_type == 'P') {
/* select page 1 to access Fiber registers */
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 1);
+
+ /* for SFP-module set SIGDET polarity to low */
+ ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+ ctrl |= PHY_M_FIB_SIGD_POL;
+ gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
}
+
+ gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
}
ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
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)
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)
/*
* It appears the hardware has a bug in the FIFO logic that
* cause it to hang if the FIFO gets overrun and the receive buffer
- * is not aligned. ALso alloc_skb() won't align properly if slab
+ * is not aligned. Also dev_alloc_skb() won't align properly if slab
* debugging is enabled.
*/
static inline struct sk_buff *sky2_alloc_skb(unsigned int size, gfp_t gfp_mask)
{
struct sk_buff *skb;
- skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask);
+ skb = __dev_alloc_skb(size + RX_SKB_ALIGN, gfp_mask);
if (likely(skb)) {
unsigned long p = (unsigned long) skb->data;
skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
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)
}
/* 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) &&
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)
goto oversize;
if (length < copybreak) {
- skb = alloc_skb(length + 2, GFP_ATOMIC);
+ skb = dev_alloc_skb(length + 2);
if (!skb)
goto resubmit;
}
}
+ /* Fully processed status ring so clear irq */
+ sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
+
exit_loop:
return work_done;
}
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);
*budget -= work_done;
dev0->quota -= work_done;
- if (status & Y2_IS_STAT_BMU)
- sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
-
if (sky2_more_work(hw))
return 1;
-out:
+
netif_rx_complete(dev0);
sky2_read32(hw, B0_Y2_SP_LISR);
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);
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) {
static u32 sky2_supported_modes(const struct sky2_hw *hw)
{
- u32 modes;
- if (hw->copper) {
- modes = SUPPORTED_10baseT_Half
- | SUPPORTED_10baseT_Full
- | SUPPORTED_100baseT_Half
- | SUPPORTED_100baseT_Full
- | SUPPORTED_Autoneg | SUPPORTED_TP;
+ if (sky2_is_copper(hw)) {
+ u32 modes = SUPPORTED_10baseT_Half
+ | SUPPORTED_10baseT_Full
+ | SUPPORTED_100baseT_Half
+ | SUPPORTED_100baseT_Full
+ | SUPPORTED_Autoneg | SUPPORTED_TP;
if (hw->chip_id != CHIP_ID_YUKON_FE)
modes |= SUPPORTED_1000baseT_Half
- | SUPPORTED_1000baseT_Full;
+ | SUPPORTED_1000baseT_Full;
+ return modes;
} else
- modes = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE
- | SUPPORTED_Autoneg;
- return modes;
+ return SUPPORTED_1000baseT_Half
+ | SUPPORTED_1000baseT_Full
+ | SUPPORTED_Autoneg
+ | SUPPORTED_FIBRE;
}
static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
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
| SUPPORTED_1000baseT_Full
| SUPPORTED_Autoneg | SUPPORTED_TP;
ecmd->port = PORT_TP;
- } else
+ ecmd->speed = sky2->speed;
+ } else {
+ ecmd->speed = SPEED_1000;
ecmd->port = PORT_FIBRE;
+ }
ecmd->advertising = sky2->advertising;
ecmd->autoneg = sky2->autoneg;
- ecmd->speed = sky2->speed;
ecmd->duplex = sky2->duplex;
return 0;
}
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);
return err;
}
- init_waitqueue_head (&hw->msi_wait);
-
sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
- wmb();
+ sky2_read8(hw, B0_CTST);
wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10);
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 {
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,
};
int pm_cap;
u8 chip_id;
u8 chip_rev;
- u8 copper;
+ u8 pmd_type;
u8 ports;
struct sky2_status_le *st_le;
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)
{
#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
#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) &&
#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) &&
tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
}
- /* TSO is on by default on chips that support hardware TSO.
+ /* TSO is on by default on chips that support HW_TSO_2.
+ * Some HW_TSO_1 capable chips have bugs that can lead to
+ * tx timeouts in some cases when TSO is enabled.
* Firmware TSO on older chips gives lower performance, so it
* is off by default, but can be enabled using ethtool.
*/
- if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
+ if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 &&
+ tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2))
dev->features |= NETIF_F_TSO;
#endif
#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
* - get_stats:
* spin_lock_irq(np->lock), doesn't touch hw if not present
* - hard_start_xmit:
- * netif_stop_queue + spin_unlock_wait(&dev->xmit_lock);
+ * synchronize_irq + netif_tx_disable;
* - tx_timeout:
- * netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
+ * netif_device_detach + netif_tx_disable;
* - set_multicast_list
- * netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
+ * netif_device_detach + netif_tx_disable;
* - interrupt handler
* doesn't touch hw if not present, synchronize_irq waits for
* running instances of the interrupt handler.
netif_device_detach(dev);
update_csr6(dev, 0);
iowrite32(0, ioaddr + IntrEnable);
- netif_stop_queue(dev);
spin_unlock_irq(&np->lock);
- spin_unlock_wait(&dev->xmit_lock);
synchronize_irq(dev->irq);
+ netif_tx_disable(dev);
np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff;
#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
* 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
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++;
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);
if (ret < 0)
goto err_iounmap;
+ if (velocity_get_link(dev))
+ netif_carrier_off(dev);
+
velocity_print_info(vptr);
pci_set_drvdata(pdev, dev);
if (linked) {
vptr->mii_status &= ~VELOCITY_LINK_FAIL;
+ netif_carrier_on(vptr->dev);
} else {
vptr->mii_status |= VELOCITY_LINK_FAIL;
+ netif_carrier_off(vptr->dev);
}
velocity_print_link_status(vptr);
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];
*/
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);
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 =
/* 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;
}
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 */
*
* @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
last_cookie = INVALID_COOKIE;
}
-static void add_kernel_ctx_switch(unsigned int in_kernel)
+static void add_cpu_mode_switch(unsigned int cpu_mode)
{
add_event_entry(ESCAPE_CODE);
- if (in_kernel)
- add_event_entry(KERNEL_ENTER_SWITCH_CODE);
- else
- add_event_entry(KERNEL_EXIT_SWITCH_CODE);
+ switch (cpu_mode) {
+ case CPU_MODE_USER:
+ add_event_entry(USER_ENTER_SWITCH_CODE);
+ break;
+ case CPU_MODE_KERNEL:
+ add_event_entry(KERNEL_ENTER_SWITCH_CODE);
+ break;
+ case CPU_MODE_XEN:
+ add_event_entry(XEN_ENTER_SWITCH_CODE);
+ break;
+ default:
+ break;
+ }
}
-
+
+static void add_domain_switch(unsigned long domain_id)
+{
+ add_event_entry(ESCAPE_CODE);
+ add_event_entry(DOMAIN_SWITCH_CODE);
+ add_event_entry(domain_id);
+}
+
static void
add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
{
* 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) {
struct mm_struct *mm = NULL;
struct task_struct * new;
unsigned long cookie = 0;
- int in_kernel = 1;
+ int cpu_mode = 1;
unsigned int i;
sync_buffer_state state = sb_buffer_start;
unsigned long available;
+ int domain_switch = 0;
down(&buffer_sem);
for (i = 0; i < available; ++i) {
struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
- if (is_code(s->eip)) {
- if (s->event <= CPU_IS_KERNEL) {
- /* kernel/userspace switch */
- in_kernel = s->event;
+ if (is_code(s->eip) && !domain_switch) {
+ if (s->event <= CPU_MODE_XEN) {
+ /* xen/kernel/userspace switch */
+ cpu_mode = s->event;
if (state == sb_buffer_start)
state = sb_sample_start;
- add_kernel_ctx_switch(s->event);
+ add_cpu_mode_switch(s->event);
} else if (s->event == CPU_TRACE_BEGIN) {
state = sb_bt_start;
add_trace_begin();
+ } else if (s->event == CPU_DOMAIN_SWITCH) {
+ domain_switch = 1;
} else {
struct mm_struct * oldmm = mm;
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);
+ }
}
}
}
*
* @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
#define DEFAULT_TIMER_EXPIRE (HZ / 10)
static int work_enabled;
+static int32_t current_domain = COORDINATOR_DOMAIN;
+
void free_cpu_buffers(void)
{
int i;
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;
* 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;
}
* because of the head/tail separation of the writer and reader
* of the CPU buffer.
*
- * is_kernel is needed because on some architectures you cannot
+ * cpu_mode is needed because on some architectures you cannot
* tell if you are in kernel or user space simply by looking at
- * pc. We tag this in the buffer by generating kernel enter/exit
- * events whenever is_kernel changes
+ * pc. We tag this in the buffer by generating kernel/user (and xen)
+ * enter events whenever cpu_mode changes
*/
static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
- int is_kernel, unsigned long event)
+ int cpu_mode, unsigned long event)
{
struct task_struct * task;
return 0;
}
- is_kernel = !!is_kernel;
+ WARN_ON(cpu_mode > CPU_MODE_XEN);
task = current;
/* notice a switch from user->kernel or vice versa */
- if (cpu_buf->last_is_kernel != is_kernel) {
- cpu_buf->last_is_kernel = is_kernel;
- add_code(cpu_buf, is_kernel);
+ if (cpu_buf->last_cpu_mode != cpu_mode) {
+ cpu_buf->last_cpu_mode = cpu_mode;
+ add_code(cpu_buf, cpu_mode);
}
-
+
/* notice a task switch */
- if (cpu_buf->last_task != task) {
+ /* if not processing other domain samples */
+ if ((cpu_buf->last_task != task) &&
+ (current_domain == COORDINATOR_DOMAIN)) {
cpu_buf->last_task = task;
add_code(cpu_buf, (unsigned long)task);
}
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
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;
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 */
#define CPU_SWITCH_CODE 2
#define COOKIE_SWITCH_CODE 3
#define KERNEL_ENTER_SWITCH_CODE 4
-#define KERNEL_EXIT_SWITCH_CODE 5
+#define USER_ENTER_SWITCH_CODE 5
#define MODULE_LOADED_CODE 6
#define CTX_TGID_CODE 7
#define TRACE_BEGIN_CODE 8
#define TRACE_END_CODE 9
+#define XEN_ENTER_SWITCH_CODE 10
+#define DOMAIN_SWITCH_CODE 11
#define INVALID_COOKIE ~0UL
#define NO_COOKIE 0UL
+/* Constant used to refer to coordinator domain (Xen) */
+#define COORDINATOR_DOMAIN -1
+
/* add data to the event buffer */
void add_event_entry(unsigned long data);
* @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 "cpu_buffer.h"
#include "buffer_sync.h"
#include "oprofile_stats.h"
-
+
struct oprofile_operations oprofile_ops;
unsigned long oprofile_started;
*/
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;
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 */
* @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 <asm/uaccess.h>
+#include <linux/ctype.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 */
static struct file_operations dump_fops = {
.write = dump_write,
};
-
+
+#define TMPBUFSIZE 512
+
+#ifdef CONFIG_XEN
+static unsigned int adomains = 0;
+static int active_domains[MAX_OPROF_DOMAINS + 1];
+static DEFINE_MUTEX(adom_mutex);
+
+static ssize_t adomain_write(struct file * file, char const __user * buf,
+ size_t count, loff_t * offset)
+{
+ char *tmpbuf;
+ char *startp, *endp;
+ int i;
+ unsigned long val;
+ ssize_t retval = count;
+
+ if (*offset)
+ return -EINVAL;
+ if (count > TMPBUFSIZE - 1)
+ return -EINVAL;
+
+ if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
+ return -ENOMEM;
+
+ if (copy_from_user(tmpbuf, buf, count)) {
+ kfree(tmpbuf);
+ return -EFAULT;
+ }
+ tmpbuf[count] = 0;
+
+ mutex_lock(&adom_mutex);
+
+ startp = tmpbuf;
+ /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
+ for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
+ val = simple_strtoul(startp, &endp, 0);
+ if (endp == startp)
+ break;
+ while (ispunct(*endp) || isspace(*endp))
+ endp++;
+ active_domains[i] = val;
+ if (active_domains[i] != val)
+ /* Overflow, force error below */
+ i = MAX_OPROF_DOMAINS + 1;
+ startp = endp;
+ }
+ /* Force error on trailing junk */
+ adomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
+
+ kfree(tmpbuf);
+
+ if (adomains > MAX_OPROF_DOMAINS
+ || oprofile_set_active(active_domains, adomains)) {
+ adomains = 0;
+ retval = -EINVAL;
+ }
+
+ mutex_unlock(&adom_mutex);
+ return retval;
+}
+
+static ssize_t adomain_read(struct file * file, char __user * buf,
+ size_t count, loff_t * offset)
+{
+ char * tmpbuf;
+ size_t len;
+ int i;
+ ssize_t retval;
+
+ if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
+ return -ENOMEM;
+
+ mutex_lock(&adom_mutex);
+
+ len = 0;
+ for (i = 0; i < adomains; i++)
+ len += snprintf(tmpbuf + len,
+ len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
+ "%u ", active_domains[i]);
+ WARN_ON(len > TMPBUFSIZE);
+ if (len != 0 && len <= TMPBUFSIZE)
+ tmpbuf[len-1] = '\n';
+
+ mutex_unlock(&adom_mutex);
+
+ retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
+
+ kfree(tmpbuf);
+ return retval;
+}
+
+
+static struct file_operations active_domain_ops = {
+ .read = adomain_read,
+ .write = adomain_write,
+};
+
+static unsigned int pdomains = 0;
+static int passive_domains[MAX_OPROF_DOMAINS];
+static DEFINE_MUTEX(pdom_mutex);
+
+static ssize_t pdomain_write(struct file * file, char const __user * buf,
+ size_t count, loff_t * offset)
+{
+ char *tmpbuf;
+ char *startp, *endp;
+ int i;
+ unsigned long val;
+ ssize_t retval = count;
+
+ if (*offset)
+ return -EINVAL;
+ if (count > TMPBUFSIZE - 1)
+ return -EINVAL;
+
+ if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
+ return -ENOMEM;
+
+ if (copy_from_user(tmpbuf, buf, count)) {
+ kfree(tmpbuf);
+ return -EFAULT;
+ }
+ tmpbuf[count] = 0;
+
+ mutex_lock(&pdom_mutex);
+
+ startp = tmpbuf;
+ /* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
+ for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
+ val = simple_strtoul(startp, &endp, 0);
+ if (endp == startp)
+ break;
+ while (ispunct(*endp) || isspace(*endp))
+ endp++;
+ passive_domains[i] = val;
+ if (passive_domains[i] != val)
+ /* Overflow, force error below */
+ i = MAX_OPROF_DOMAINS + 1;
+ startp = endp;
+ }
+ /* Force error on trailing junk */
+ pdomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
+
+ kfree(tmpbuf);
+
+ if (pdomains > MAX_OPROF_DOMAINS
+ || oprofile_set_passive(passive_domains, pdomains)) {
+ pdomains = 0;
+ retval = -EINVAL;
+ }
+
+ mutex_unlock(&pdom_mutex);
+ return retval;
+}
+
+static ssize_t pdomain_read(struct file * file, char __user * buf,
+ size_t count, loff_t * offset)
+{
+ char * tmpbuf;
+ size_t len;
+ int i;
+ ssize_t retval;
+
+ if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
+ return -ENOMEM;
+
+ mutex_lock(&pdom_mutex);
+
+ len = 0;
+ for (i = 0; i < pdomains; i++)
+ len += snprintf(tmpbuf + len,
+ len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
+ "%u ", passive_domains[i]);
+ WARN_ON(len > TMPBUFSIZE);
+ if (len != 0 && len <= TMPBUFSIZE)
+ tmpbuf[len-1] = '\n';
+
+ mutex_unlock(&pdom_mutex);
+
+ retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
+
+ kfree(tmpbuf);
+ return retval;
+}
+
+static struct file_operations passive_domain_ops = {
+ .read = pdomain_read,
+ .write = pdomain_write,
+};
+#endif /* CONFIG_XEN */
+
void oprofile_create_files(struct super_block * sb, struct dentry * root)
{
oprofilefs_create_file(sb, root, "enable", &enable_fops);
oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
+#ifdef CONFIG_XEN
+ oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
+ oprofilefs_create_file(sb, root, "passive_domains", &passive_domain_ops);
+#endif
oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
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
pci_read_config_dword(dev, 0x48, ®ion);
quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES+1, "ICH6 GPIO");
}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi );
/*
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)
{
/* 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);
}
}
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){
QETH_DBF_TEXT(trace, 5, "eddpcanp");
/* can we put multiple skbs in one page? */
- skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len);
+ skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len);
if (skbs_per_page > 1){
- ctx->num_pages = (skb_shinfo(skb)->tso_segs + 1) /
+ ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) /
skbs_per_page + 1;
ctx->elements_per_skb = 1;
} else {
/* no -> how many elements per skb? */
- ctx->elements_per_skb = (skb_shinfo(skb)->tso_size + hdr_len +
+ ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len +
PAGE_SIZE) >> PAGE_SHIFT;
ctx->num_pages = ctx->elements_per_skb *
- (skb_shinfo(skb)->tso_segs + 1);
+ (skb_shinfo(skb)->gso_segs + 1);
}
ctx->num_elements = ctx->elements_per_skb *
- (skb_shinfo(skb)->tso_segs + 1);
+ (skb_shinfo(skb)->gso_segs + 1);
}
static inline struct qeth_eddp_context *
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");
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 */
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){
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));
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
*
* 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
#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"
-#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_VERSION(ISCSI_TCP_VERSION);
+MODULE_VERSION("0:4.445");
/* #define DEBUG_TCP */
+/* #define DEBUG_SCSI */
#define DEBUG_ASSERT
#ifdef DEBUG_TCP
-#define debug_tcp(fmt...) printk(KERN_INFO "tcp: " fmt)
+#define debug_tcp(fmt...) printk(KERN_DEBUG "tcp: " fmt)
#else
#define debug_tcp(fmt...)
#endif
+#ifdef DEBUG_SCSI
+#define debug_scsi(fmt...) printk(KERN_DEBUG "scsi: " fmt)
+#else
+#define debug_scsi(fmt...)
+#endif
+
#ifndef DEBUG_ASSERT
#ifdef BUG_ON
#undef BUG_ON
#define BUG_ON(expr)
#endif
+#define INVALID_SN_DELTA 0xffff
+
static unsigned int iscsi_max_lun = 512;
module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
+/* global data */
+static kmem_cache_t *taskcache;
+
+static inline void
+iscsi_buf_init_virt(struct iscsi_buf *ibuf, char *vbuf, int size)
+{
+ sg_init_one(&ibuf->sg, (u8 *)vbuf, size);
+ ibuf->sent = 0;
+ ibuf->use_sendmsg = 0;
+}
+
static inline void
iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
{
iscsi_hdr_digest(struct iscsi_conn *conn, struct iscsi_buf *buf,
u8* crc)
{
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
-
- crypto_digest_digest(tcp_conn->tx_tfm, &buf->sg, 1, crc);
+ crypto_digest_digest(conn->tx_tfm, &buf->sg, 1, crc);
buf->sg.length += sizeof(uint32_t);
}
+static void
+iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
+{
+ struct iscsi_session *session = conn->session;
+ unsigned long flags;
+
+ spin_lock_irqsave(&session->lock, flags);
+ if (session->conn_cnt == 1 || session->leadconn == conn)
+ session->state = ISCSI_STATE_FAILED;
+ spin_unlock_irqrestore(&session->lock, flags);
+ set_bit(SUSPEND_BIT, &conn->suspend_tx);
+ set_bit(SUSPEND_BIT, &conn->suspend_rx);
+ iscsi_conn_error(conn->cls_conn, err);
+}
+
static inline int
-iscsi_hdr_extract(struct iscsi_tcp_conn *tcp_conn)
+iscsi_check_assign_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr)
{
- struct sk_buff *skb = tcp_conn->in.skb;
+ uint32_t max_cmdsn = be32_to_cpu(hdr->max_cmdsn);
+ uint32_t exp_cmdsn = be32_to_cpu(hdr->exp_cmdsn);
+
+ if (max_cmdsn < exp_cmdsn -1 &&
+ max_cmdsn > exp_cmdsn - INVALID_SN_DELTA)
+ return ISCSI_ERR_MAX_CMDSN;
+ if (max_cmdsn > session->max_cmdsn ||
+ max_cmdsn < session->max_cmdsn - INVALID_SN_DELTA)
+ session->max_cmdsn = max_cmdsn;
+ if (exp_cmdsn > session->exp_cmdsn ||
+ exp_cmdsn < session->exp_cmdsn - INVALID_SN_DELTA)
+ session->exp_cmdsn = exp_cmdsn;
+
+ return 0;
+}
- tcp_conn->in.zero_copy_hdr = 0;
+static inline int
+iscsi_hdr_extract(struct iscsi_conn *conn)
+{
+ struct sk_buff *skb = conn->in.skb;
- if (tcp_conn->in.copy >= tcp_conn->hdr_size &&
- tcp_conn->in_progress == IN_PROGRESS_WAIT_HEADER) {
+ if (conn->in.copy >= conn->hdr_size &&
+ conn->in_progress == IN_PROGRESS_WAIT_HEADER) {
/*
* Zero-copy PDU Header: using connection context
* to store header pointer.
*/
if (skb_shinfo(skb)->frag_list == NULL &&
- !skb_shinfo(skb)->nr_frags) {
- tcp_conn->in.hdr = (struct iscsi_hdr *)
- ((char*)skb->data + tcp_conn->in.offset);
- tcp_conn->in.zero_copy_hdr = 1;
- } else {
+ !skb_shinfo(skb)->nr_frags)
+ conn->in.hdr = (struct iscsi_hdr *)
+ ((char*)skb->data + conn->in.offset);
+ else {
/* ignoring return code since we checked
* in.copy before */
- skb_copy_bits(skb, tcp_conn->in.offset,
- &tcp_conn->hdr, tcp_conn->hdr_size);
- tcp_conn->in.hdr = &tcp_conn->hdr;
+ skb_copy_bits(skb, conn->in.offset,
+ &conn->hdr, conn->hdr_size);
+ conn->in.hdr = &conn->hdr;
}
- tcp_conn->in.offset += tcp_conn->hdr_size;
- tcp_conn->in.copy -= tcp_conn->hdr_size;
+ conn->in.offset += conn->hdr_size;
+ conn->in.copy -= conn->hdr_size;
} else {
int hdr_remains;
int copylen;
* copying it... This'll happen quite rarely.
*/
- if (tcp_conn->in_progress == IN_PROGRESS_WAIT_HEADER)
- tcp_conn->in.hdr_offset = 0;
+ if (conn->in_progress == IN_PROGRESS_WAIT_HEADER)
+ conn->in.hdr_offset = 0;
- hdr_remains = tcp_conn->hdr_size - tcp_conn->in.hdr_offset;
+ hdr_remains = conn->hdr_size - conn->in.hdr_offset;
BUG_ON(hdr_remains <= 0);
- copylen = min(tcp_conn->in.copy, hdr_remains);
- skb_copy_bits(skb, tcp_conn->in.offset,
- (char*)&tcp_conn->hdr + tcp_conn->in.hdr_offset,
- copylen);
+ copylen = min(conn->in.copy, hdr_remains);
+ skb_copy_bits(skb, conn->in.offset,
+ (char*)&conn->hdr + conn->in.hdr_offset, copylen);
debug_tcp("PDU gather offset %d bytes %d in.offset %d "
- "in.copy %d\n", tcp_conn->in.hdr_offset, copylen,
- tcp_conn->in.offset, tcp_conn->in.copy);
+ "in.copy %d\n", conn->in.hdr_offset, copylen,
+ conn->in.offset, conn->in.copy);
- tcp_conn->in.offset += copylen;
- tcp_conn->in.copy -= copylen;
+ conn->in.offset += copylen;
+ conn->in.copy -= copylen;
if (copylen < hdr_remains) {
- tcp_conn->in_progress = IN_PROGRESS_HEADER_GATHER;
- tcp_conn->in.hdr_offset += copylen;
+ conn->in_progress = IN_PROGRESS_HEADER_GATHER;
+ conn->in.hdr_offset += copylen;
return -EAGAIN;
}
- tcp_conn->in.hdr = &tcp_conn->hdr;
- tcp_conn->discontiguous_hdr_cnt++;
- tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
+ conn->in.hdr = &conn->hdr;
+ conn->discontiguous_hdr_cnt++;
+ conn->in_progress = IN_PROGRESS_WAIT_HEADER;
}
return 0;
}
-/*
- * must be called with session lock
- */
-static void
-__iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+static inline void
+iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- struct scsi_cmnd *sc;
+ struct scsi_cmnd *sc = ctask->sc;
+ struct iscsi_session *session = conn->session;
- sc = ctask->sc;
- if (unlikely(!sc))
+ spin_lock(&session->lock);
+ if (unlikely(!sc)) {
+ spin_unlock(&session->lock);
return;
+ }
+ if (sc->sc_data_direction == DMA_TO_DEVICE) {
+ struct iscsi_data_task *dtask, *n;
+ /* WRITE: cleanup Data-Out's if any */
+ list_for_each_entry_safe(dtask, n, &ctask->dataqueue, item) {
+ list_del(&dtask->item);
+ mempool_free(dtask, ctask->datapool);
+ }
+ }
+ ctask->xmstate = XMSTATE_IDLE;
+ ctask->r2t = NULL;
+ ctask->sc = NULL;
+ __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*));
+ spin_unlock(&session->lock);
+}
+
+/**
+ * iscsi_cmd_rsp - SCSI Command Response processing
+ * @conn: iscsi connection
+ * @ctask: scsi command task
+ **/
+static int
+iscsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+{
+ int rc;
+ struct iscsi_cmd_rsp *rhdr = (struct iscsi_cmd_rsp *)conn->in.hdr;
+ struct iscsi_session *session = conn->session;
+ struct scsi_cmnd *sc = ctask->sc;
+
+ rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr);
+ if (rc) {
+ sc->result = (DID_ERROR << 16);
+ goto out;
+ }
+
+ conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
+
+ sc->result = (DID_OK << 16) | rhdr->cmd_status;
+
+ if (rhdr->response != ISCSI_STATUS_CMD_COMPLETED) {
+ sc->result = (DID_ERROR << 16);
+ goto out;
+ }
+
+ if (rhdr->cmd_status == SAM_STAT_CHECK_CONDITION && conn->senselen) {
+ int sensecopy = min(conn->senselen, SCSI_SENSE_BUFFERSIZE);
- tcp_ctask->xmstate = XMSTATE_IDLE;
- tcp_ctask->r2t = NULL;
+ memcpy(sc->sense_buffer, conn->data + 2, sensecopy);
+ debug_scsi("copied %d bytes of sense\n", sensecopy);
+ }
+
+ if (sc->sc_data_direction == DMA_TO_DEVICE)
+ goto out;
+
+ if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
+ int res_count = be32_to_cpu(rhdr->residual_count);
+
+ if (res_count > 0 && res_count <= sc->request_bufflen)
+ sc->resid = res_count;
+ else
+ sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
+ } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW)
+ sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
+ else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW)
+ sc->resid = be32_to_cpu(rhdr->residual_count);
+
+out:
+ debug_scsi("done [sc %lx res %d itt 0x%x]\n",
+ (long)sc, sc->result, ctask->itt);
+ conn->scsirsp_pdus_cnt++;
+ iscsi_ctask_cleanup(conn, ctask);
+ sc->scsi_done(sc);
+ return rc;
}
/**
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);
/*
* 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)
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) {
struct iscsi_r2t_info *r2t)
{
struct iscsi_data *hdr;
+ struct iscsi_data_task *dtask;
struct scsi_cmnd *sc = ctask->sc;
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- hdr = &r2t->dtask.hdr;
+ dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC);
+ BUG_ON(!dtask);
+ hdr = &dtask->hdr;
memset(hdr, 0, sizeof(struct iscsi_data));
hdr->ttt = r2t->ttt;
hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
r2t->solicit_datasn++;
hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
- memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
- hdr->itt = ctask->hdr->itt;
+ memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun));
+ hdr->itt = ctask->hdr.itt;
hdr->exp_statsn = r2t->exp_statsn;
hdr->offset = cpu_to_be32(r2t->data_offset);
if (r2t->data_length > conn->max_xmit_dlength) {
r2t->sent = 0;
- iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr,
+ iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr,
sizeof(struct iscsi_hdr));
+ r2t->dtask = dtask;
+
if (sc->use_sg) {
int i, sg_count = 0;
struct scatterlist *sg = sc->request_buffer;
}
BUG_ON(r2t->sg == NULL);
} else
- iscsi_buf_init_iov(&tcp_ctask->sendbuf,
+ iscsi_buf_init_iov(&ctask->sendbuf,
(char*)sc->request_buffer + r2t->data_offset,
r2t->data_count);
+
+ list_add(&dtask->item, &ctask->dataqueue);
}
/**
{
struct iscsi_r2t_info *r2t;
struct iscsi_session *session = conn->session;
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr;
+ struct iscsi_r2t_rsp *rhdr = (struct iscsi_r2t_rsp *)conn->in.hdr;
int r2tsn = be32_to_cpu(rhdr->r2tsn);
int rc;
- if (tcp_conn->in.datalen)
+ if (conn->in.ahslen)
+ return ISCSI_ERR_AHSLEN;
+
+ if (conn->in.datalen)
return ISCSI_ERR_DATALEN;
- if (tcp_ctask->exp_r2tsn && tcp_ctask->exp_r2tsn != r2tsn)
+ if (ctask->exp_r2tsn && ctask->exp_r2tsn != r2tsn)
return ISCSI_ERR_R2TSN;
rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)rhdr);
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;
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++;
}
static int
-iscsi_tcp_hdr_recv(struct iscsi_conn *conn)
+iscsi_hdr_recv(struct iscsi_conn *conn)
{
- int rc = 0, opcode, ahslen;
+ int rc = 0;
struct iscsi_hdr *hdr;
+ struct iscsi_cmd_task *ctask;
struct iscsi_session *session = conn->session;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- uint32_t cdgst, rdgst = 0, itt;
+ uint32_t cdgst, rdgst = 0;
- hdr = tcp_conn->in.hdr;
+ hdr = conn->in.hdr;
/* verify PDU length */
- tcp_conn->in.datalen = ntoh24(hdr->dlength);
- if (tcp_conn->in.datalen > conn->max_recv_dlength) {
+ conn->in.datalen = ntoh24(hdr->dlength);
+ if (conn->in.datalen > conn->max_recv_dlength) {
printk(KERN_ERR "iscsi_tcp: datalen %d > %d\n",
- tcp_conn->in.datalen, conn->max_recv_dlength);
+ conn->in.datalen, conn->max_recv_dlength);
return ISCSI_ERR_DATALEN;
}
- tcp_conn->data_copied = 0;
+ conn->data_copied = 0;
/* read AHS */
- ahslen = hdr->hlength << 2;
- tcp_conn->in.offset += ahslen;
- tcp_conn->in.copy -= ahslen;
- if (tcp_conn->in.copy < 0) {
+ conn->in.ahslen = hdr->hlength * 4;
+ conn->in.offset += conn->in.ahslen;
+ conn->in.copy -= conn->in.ahslen;
+ if (conn->in.copy < 0) {
printk(KERN_ERR "iscsi_tcp: can't handle AHS with length "
- "%d bytes\n", ahslen);
+ "%d bytes\n", conn->in.ahslen);
return ISCSI_ERR_AHSLEN;
}
/* calculate read padding */
- tcp_conn->in.padding = tcp_conn->in.datalen & (ISCSI_PAD_LEN-1);
- if (tcp_conn->in.padding) {
- tcp_conn->in.padding = ISCSI_PAD_LEN - tcp_conn->in.padding;
- debug_scsi("read padding %d bytes\n", tcp_conn->in.padding);
+ conn->in.padding = conn->in.datalen & (ISCSI_PAD_LEN-1);
+ if (conn->in.padding) {
+ conn->in.padding = ISCSI_PAD_LEN - conn->in.padding;
+ debug_scsi("read padding %d bytes\n", conn->in.padding);
}
if (conn->hdrdgst_en) {
struct scatterlist sg;
sg_init_one(&sg, (u8 *)hdr,
- sizeof(struct iscsi_hdr) + ahslen);
- crypto_digest_digest(tcp_conn->rx_tfm, &sg, 1, (u8 *)&cdgst);
+ sizeof(struct iscsi_hdr) + conn->in.ahslen);
+ crypto_digest_digest(conn->rx_tfm, &sg, 1, (u8 *)&cdgst);
rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) +
- ahslen);
+ conn->in.ahslen);
if (cdgst != rdgst) {
- printk(KERN_ERR "iscsi_tcp: hdrdgst error "
- "recv 0x%x calc 0x%x\n", rdgst, cdgst);
+ printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error "
+ "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst,
+ cdgst);
return ISCSI_ERR_HDR_DGST;
}
}
- opcode = hdr->opcode & ISCSI_OPCODE_MASK;
+ /* save opcode for later */
+ conn->in.opcode = hdr->opcode & ISCSI_OPCODE_MASK;
+
/* verify itt (itt encoding: age+cid+itt) */
- rc = iscsi_verify_itt(conn, hdr, &itt);
- if (rc == ISCSI_ERR_NO_SCSI_CMD) {
- tcp_conn->in.datalen = 0; /* force drop */
- return 0;
- } else if (rc)
- return rc;
+ if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) {
+ if ((hdr->itt & AGE_MASK) !=
+ (session->age << AGE_SHIFT)) {
+ printk(KERN_ERR "iscsi_tcp: received itt %x expected "
+ "session age (%x)\n", hdr->itt,
+ session->age & AGE_MASK);
+ return ISCSI_ERR_BAD_ITT;
+ }
+
+ if ((hdr->itt & CID_MASK) != (conn->id << CID_SHIFT)) {
+ printk(KERN_ERR "iscsi_tcp: received itt %x, expected "
+ "CID (%x)\n", hdr->itt, conn->id);
+ return ISCSI_ERR_BAD_ITT;
+ }
+ conn->in.itt = hdr->itt & ITT_MASK;
+ } else
+ conn->in.itt = hdr->itt;
debug_tcp("opcode 0x%x offset %d copy %d ahslen %d datalen %d\n",
- opcode, tcp_conn->in.offset, tcp_conn->in.copy,
- ahslen, tcp_conn->in.datalen);
+ hdr->opcode, conn->in.offset, conn->in.copy,
+ conn->in.ahslen, conn->in.datalen);
- switch(opcode) {
- case ISCSI_OP_SCSI_DATA_IN:
- tcp_conn->in.ctask = session->cmds[itt];
- rc = iscsi_data_rsp(conn, tcp_conn->in.ctask);
- /* fall through */
- case ISCSI_OP_SCSI_CMD_RSP:
- tcp_conn->in.ctask = session->cmds[itt];
- if (tcp_conn->in.datalen)
- goto copy_hdr;
-
- spin_lock(&session->lock);
- __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask);
- rc = __iscsi_complete_pdu(conn, hdr, NULL, 0);
- spin_unlock(&session->lock);
- break;
- case ISCSI_OP_R2T:
- tcp_conn->in.ctask = session->cmds[itt];
- if (ahslen)
- rc = ISCSI_ERR_AHSLEN;
- else if (tcp_conn->in.ctask->sc->sc_data_direction ==
- DMA_TO_DEVICE)
- rc = iscsi_r2t_rsp(conn, tcp_conn->in.ctask);
- else
- rc = ISCSI_ERR_PROTO;
- break;
- case ISCSI_OP_LOGIN_RSP:
- case ISCSI_OP_TEXT_RSP:
- case ISCSI_OP_LOGOUT_RSP:
- case ISCSI_OP_NOOP_IN:
- case ISCSI_OP_REJECT:
- case ISCSI_OP_ASYNC_EVENT:
- if (tcp_conn->in.datalen)
- goto copy_hdr;
- /* fall through */
- case ISCSI_OP_SCSI_TMFUNC_RSP:
- rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
- break;
- default:
- rc = ISCSI_ERR_BAD_OPCODE;
- break;
- }
+ if (conn->in.itt < session->cmds_max) {
+ ctask = (struct iscsi_cmd_task *)session->cmds[conn->in.itt];
- return rc;
+ if (!ctask->sc) {
+ printk(KERN_INFO "iscsi_tcp: dropping ctask with "
+ "itt 0x%x\n", ctask->itt);
+ conn->in.datalen = 0; /* force drop */
+ return 0;
+ }
-copy_hdr:
- /*
- * if we did zero copy for the header but we will need multiple
- * skbs to complete the command then we have to copy the header
- * for later use
- */
- if (tcp_conn->in.zero_copy_hdr && tcp_conn->in.copy <
- (tcp_conn->in.datalen + tcp_conn->in.padding +
- (conn->datadgst_en ? 4 : 0))) {
- debug_tcp("Copying header for later use. in.copy %d in.datalen"
- " %d\n", tcp_conn->in.copy, tcp_conn->in.datalen);
- memcpy(&tcp_conn->hdr, tcp_conn->in.hdr,
- sizeof(struct iscsi_hdr));
- tcp_conn->in.hdr = &tcp_conn->hdr;
- tcp_conn->in.zero_copy_hdr = 0;
- }
- return 0;
+ if (ctask->sc->SCp.phase != session->age) {
+ printk(KERN_ERR "iscsi_tcp: ctask's session age %d, "
+ "expected %d\n", ctask->sc->SCp.phase,
+ session->age);
+ return ISCSI_ERR_SESSION_FAILED;
+ }
+
+ conn->in.ctask = ctask;
+
+ debug_scsi("rsp [op 0x%x cid %d sc %lx itt 0x%x len %d]\n",
+ hdr->opcode, conn->id, (long)ctask->sc,
+ ctask->itt, conn->in.datalen);
+
+ switch(conn->in.opcode) {
+ case ISCSI_OP_SCSI_CMD_RSP:
+ BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
+ if (!conn->in.datalen)
+ rc = iscsi_cmd_rsp(conn, ctask);
+ else
+ /*
+ * got sense or response data; copying PDU
+ * Header to the connection's header
+ * placeholder
+ */
+ memcpy(&conn->hdr, hdr,
+ sizeof(struct iscsi_hdr));
+ break;
+ case ISCSI_OP_SCSI_DATA_IN:
+ BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
+ /* save flags for non-exceptional status */
+ conn->in.flags = hdr->flags;
+ /* save cmd_status for sense data */
+ conn->in.cmd_status =
+ ((struct iscsi_data_rsp*)hdr)->cmd_status;
+ rc = iscsi_data_rsp(conn, ctask);
+ break;
+ case ISCSI_OP_R2T:
+ BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
+ if (ctask->sc->sc_data_direction == DMA_TO_DEVICE)
+ rc = iscsi_r2t_rsp(conn, ctask);
+ else
+ rc = ISCSI_ERR_PROTO;
+ break;
+ default:
+ rc = ISCSI_ERR_BAD_OPCODE;
+ break;
+ }
+ } else if (conn->in.itt >= ISCSI_MGMT_ITT_OFFSET &&
+ conn->in.itt < ISCSI_MGMT_ITT_OFFSET +
+ session->mgmtpool_max) {
+ struct iscsi_mgmt_task *mtask = (struct iscsi_mgmt_task *)
+ session->mgmt_cmds[conn->in.itt -
+ ISCSI_MGMT_ITT_OFFSET];
+
+ debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n",
+ conn->in.opcode, conn->id, mtask->itt,
+ conn->in.datalen);
+
+ switch(conn->in.opcode) {
+ case ISCSI_OP_LOGIN_RSP:
+ case ISCSI_OP_TEXT_RSP:
+ case ISCSI_OP_LOGOUT_RSP:
+ rc = iscsi_check_assign_cmdsn(session,
+ (struct iscsi_nopin*)hdr);
+ if (rc)
+ break;
+
+ if (!conn->in.datalen) {
+ rc = iscsi_recv_pdu(conn->cls_conn, hdr,
+ NULL, 0);
+ if (conn->login_mtask != mtask) {
+ spin_lock(&session->lock);
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&mtask, sizeof(void*));
+ spin_unlock(&session->lock);
+ }
+ }
+ break;
+ case ISCSI_OP_SCSI_TMFUNC_RSP:
+ rc = iscsi_check_assign_cmdsn(session,
+ (struct iscsi_nopin*)hdr);
+ if (rc)
+ break;
+
+ if (conn->in.datalen || conn->in.ahslen) {
+ rc = ISCSI_ERR_PROTO;
+ break;
+ }
+ conn->tmfrsp_pdus_cnt++;
+ spin_lock(&session->lock);
+ if (conn->tmabort_state == TMABORT_INITIAL) {
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&mtask, sizeof(void*));
+ conn->tmabort_state =
+ ((struct iscsi_tm_rsp *)hdr)->
+ response == ISCSI_TMF_RSP_COMPLETE ?
+ TMABORT_SUCCESS:TMABORT_FAILED;
+ /* unblock eh_abort() */
+ wake_up(&conn->ehwait);
+ }
+ spin_unlock(&session->lock);
+ break;
+ case ISCSI_OP_NOOP_IN:
+ if (hdr->ttt != ISCSI_RESERVED_TAG) {
+ rc = ISCSI_ERR_PROTO;
+ break;
+ }
+ rc = iscsi_check_assign_cmdsn(session,
+ (struct iscsi_nopin*)hdr);
+ if (rc)
+ break;
+ conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
+
+ if (!conn->in.datalen) {
+ struct iscsi_mgmt_task *mtask;
+
+ rc = iscsi_recv_pdu(conn->cls_conn, hdr,
+ NULL, 0);
+ mtask = (struct iscsi_mgmt_task *)
+ session->mgmt_cmds[conn->in.itt -
+ ISCSI_MGMT_ITT_OFFSET];
+ if (conn->login_mtask != mtask) {
+ spin_lock(&session->lock);
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&mtask, sizeof(void*));
+ spin_unlock(&session->lock);
+ }
+ }
+ break;
+ default:
+ rc = ISCSI_ERR_BAD_OPCODE;
+ break;
+ }
+ } else if (conn->in.itt == ISCSI_RESERVED_TAG) {
+ switch(conn->in.opcode) {
+ case ISCSI_OP_NOOP_IN:
+ if (!conn->in.datalen) {
+ rc = iscsi_check_assign_cmdsn(session,
+ (struct iscsi_nopin*)hdr);
+ if (!rc && hdr->ttt != ISCSI_RESERVED_TAG)
+ rc = iscsi_recv_pdu(conn->cls_conn,
+ hdr, NULL, 0);
+ } else
+ rc = ISCSI_ERR_PROTO;
+ break;
+ case ISCSI_OP_REJECT:
+ /* we need sth like iscsi_reject_rsp()*/
+ case ISCSI_OP_ASYNC_EVENT:
+ /* we need sth like iscsi_async_event_rsp() */
+ rc = ISCSI_ERR_BAD_OPCODE;
+ break;
+ default:
+ rc = ISCSI_ERR_BAD_OPCODE;
+ break;
+ }
+ } else
+ rc = ISCSI_ERR_BAD_ITT;
+
+ return rc;
}
/**
* iscsi_ctask_copy - copy skb bits to the destanation cmd task
- * @conn: iscsi tcp connection
+ * @conn: iscsi connection
* @ctask: scsi command task
* @buf: buffer to copy to
* @buf_size: size of buffer
* buf_left left to copy from in progress buffer
**/
static inline int
-iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask,
+iscsi_ctask_copy(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
void *buf, int buf_size, int offset)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- int buf_left = buf_size - (tcp_conn->data_copied + offset);
- int size = min(tcp_conn->in.copy, buf_left);
+ int buf_left = buf_size - (conn->data_copied + offset);
+ int size = min(conn->in.copy, buf_left);
int rc;
size = min(size, ctask->data_count);
debug_tcp("ctask_copy %d bytes at offset %d copied %d\n",
- size, tcp_conn->in.offset, tcp_conn->in.copied);
+ size, conn->in.offset, conn->in.copied);
BUG_ON(size <= 0);
- BUG_ON(tcp_ctask->sent + size > ctask->total_length);
+ BUG_ON(ctask->sent + size > ctask->total_length);
- rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset,
- (char*)buf + (offset + tcp_conn->data_copied), size);
+ rc = skb_copy_bits(conn->in.skb, conn->in.offset,
+ (char*)buf + (offset + conn->data_copied), size);
/* must fit into skb->len */
BUG_ON(rc);
- tcp_conn->in.offset += size;
- tcp_conn->in.copy -= size;
- tcp_conn->in.copied += size;
- tcp_conn->data_copied += size;
- tcp_ctask->sent += size;
+ conn->in.offset += size;
+ conn->in.copy -= size;
+ conn->in.copied += size;
+ conn->data_copied += size;
+ ctask->sent += size;
ctask->data_count -= size;
- BUG_ON(tcp_conn->in.copy < 0);
+ BUG_ON(conn->in.copy < 0);
BUG_ON(ctask->data_count < 0);
- if (buf_size != (tcp_conn->data_copied + offset)) {
+ if (buf_size != (conn->data_copied + offset)) {
if (!ctask->data_count) {
- BUG_ON(buf_size - tcp_conn->data_copied < 0);
+ BUG_ON(buf_size - conn->data_copied < 0);
/* done with this PDU */
- return buf_size - tcp_conn->data_copied;
+ return buf_size - conn->data_copied;
}
return -EAGAIN;
}
/* done with this buffer or with both - PDU and buffer */
- tcp_conn->data_copied = 0;
+ conn->data_copied = 0;
return 0;
}
/**
* iscsi_tcp_copy - copy skb bits to the destanation buffer
- * @conn: iscsi tcp connection
+ * @conn: iscsi connection
+ * @buf: buffer to copy to
+ * @buf_size: number of bytes to copy
*
* Notes:
* The function calls skb_copy_bits() and updates per-connection
* byte counters.
**/
static inline int
-iscsi_tcp_copy(struct iscsi_tcp_conn *tcp_conn)
+iscsi_tcp_copy(struct iscsi_conn *conn, void *buf, int buf_size)
{
- void *buf = tcp_conn->data;
- int buf_size = tcp_conn->in.datalen;
- int buf_left = buf_size - tcp_conn->data_copied;
- int size = min(tcp_conn->in.copy, buf_left);
+ int buf_left = buf_size - conn->data_copied;
+ int size = min(conn->in.copy, buf_left);
int rc;
debug_tcp("tcp_copy %d bytes at offset %d copied %d\n",
- size, tcp_conn->in.offset, tcp_conn->data_copied);
+ size, conn->in.offset, conn->data_copied);
BUG_ON(size <= 0);
- rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset,
- (char*)buf + tcp_conn->data_copied, size);
+ rc = skb_copy_bits(conn->in.skb, conn->in.offset,
+ (char*)buf + conn->data_copied, size);
BUG_ON(rc);
- tcp_conn->in.offset += size;
- tcp_conn->in.copy -= size;
- tcp_conn->in.copied += size;
- tcp_conn->data_copied += size;
+ conn->in.offset += size;
+ conn->in.copy -= size;
+ conn->in.copied += size;
+ conn->data_copied += size;
- if (buf_size != tcp_conn->data_copied)
+ if (buf_size != conn->data_copied)
return -EAGAIN;
return 0;
}
static inline void
-partial_sg_digest_update(struct iscsi_tcp_conn *tcp_conn,
- struct scatterlist *sg, int offset, int length)
+partial_sg_digest_update(struct iscsi_conn *conn, struct scatterlist *sg,
+ int offset, int length)
{
struct scatterlist temp;
memcpy(&temp, sg, sizeof(struct scatterlist));
temp.offset = offset;
temp.length = length;
- crypto_digest_update(tcp_conn->data_rx_tfm, &temp, 1);
+ crypto_digest_update(conn->data_rx_tfm, &temp, 1);
}
static void
-iscsi_recv_digest_update(struct iscsi_tcp_conn *tcp_conn, char* buf, int len)
+iscsi_recv_digest_update(struct iscsi_conn *conn, char* buf, int len)
{
struct scatterlist tmp;
sg_init_one(&tmp, buf, len);
- crypto_digest_update(tcp_conn->data_rx_tfm, &tmp, 1);
+ crypto_digest_update(conn->data_rx_tfm, &tmp, 1);
}
static int iscsi_scsi_data_in(struct iscsi_conn *conn)
{
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- struct iscsi_cmd_task *ctask = tcp_conn->in.ctask;
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
+ struct iscsi_cmd_task *ctask = conn->in.ctask;
struct scsi_cmnd *sc = ctask->sc;
struct scatterlist *sg;
int i, offset, rc = 0;
*/
if (!sc->use_sg) {
i = ctask->data_count;
- rc = iscsi_ctask_copy(tcp_conn, ctask, sc->request_buffer,
- sc->request_bufflen,
- tcp_ctask->data_offset);
+ rc = iscsi_ctask_copy(conn, ctask, sc->request_buffer,
+ sc->request_bufflen, ctask->data_offset);
if (rc == -EAGAIN)
return rc;
if (conn->datadgst_en)
- iscsi_recv_digest_update(tcp_conn, sc->request_buffer,
- i);
+ iscsi_recv_digest_update(conn, sc->request_buffer, i);
rc = 0;
goto done;
}
- offset = tcp_ctask->data_offset;
+ offset = ctask->data_offset;
sg = sc->request_buffer;
- if (tcp_ctask->data_offset)
- for (i = 0; i < tcp_ctask->sg_count; i++)
+ if (ctask->data_offset)
+ for (i = 0; i < ctask->sg_count; i++)
offset -= sg[i].length;
/* we've passed through partial sg*/
if (offset < 0)
offset = 0;
- for (i = tcp_ctask->sg_count; i < sc->use_sg; i++) {
+ for (i = ctask->sg_count; i < sc->use_sg; i++) {
char *dest;
dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
- rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset,
+ rc = iscsi_ctask_copy(conn, ctask, dest + sg[i].offset,
sg[i].length, offset);
kunmap_atomic(dest, KM_SOFTIRQ0);
if (rc == -EAGAIN)
if (!rc) {
if (conn->datadgst_en) {
if (!offset)
- crypto_digest_update(
- tcp_conn->data_rx_tfm,
- &sg[i], 1);
+ crypto_digest_update(conn->data_rx_tfm,
+ &sg[i], 1);
else
- partial_sg_digest_update(tcp_conn,
- &sg[i],
+ partial_sg_digest_update(conn, &sg[i],
sg[i].offset + offset,
sg[i].length - offset);
}
offset = 0;
- tcp_ctask->sg_count++;
+ ctask->sg_count++;
}
if (!ctask->data_count) {
/*
* data-in is complete, but buffer not...
*/
- partial_sg_digest_update(tcp_conn, &sg[i],
+ partial_sg_digest_update(conn, &sg[i],
sg[i].offset, sg[i].length-rc);
rc = 0;
break;
}
- if (!tcp_conn->in.copy)
+ if (!conn->in.copy)
return -EAGAIN;
}
BUG_ON(ctask->data_count);
done:
/* check for non-exceptional status */
- if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) {
+ if (conn->in.flags & ISCSI_FLAG_DATA_STATUS) {
debug_scsi("done [sc %lx res %d itt 0x%x]\n",
(long)sc, sc->result, ctask->itt);
- spin_lock(&conn->session->lock);
- __iscsi_ctask_cleanup(conn, ctask);
- __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0);
- spin_unlock(&conn->session->lock);
+ conn->scsirsp_pdus_cnt++;
+ iscsi_ctask_cleanup(conn, ctask);
+ sc->scsi_done(sc);
}
return rc;
static int
iscsi_data_recv(struct iscsi_conn *conn)
{
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- int rc = 0, opcode;
+ struct iscsi_session *session = conn->session;
+ int rc = 0;
- opcode = tcp_conn->in.hdr->opcode & ISCSI_OPCODE_MASK;
- switch (opcode) {
+ switch(conn->in.opcode) {
case ISCSI_OP_SCSI_DATA_IN:
rc = iscsi_scsi_data_in(conn);
break;
- case ISCSI_OP_SCSI_CMD_RSP:
- spin_lock(&conn->session->lock);
- __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask);
- spin_unlock(&conn->session->lock);
+ case ISCSI_OP_SCSI_CMD_RSP: {
+ /*
+ * SCSI Sense Data:
+ * copying the entire Data Segment.
+ */
+ if (iscsi_tcp_copy(conn, conn->data, conn->in.datalen)) {
+ rc = -EAGAIN;
+ goto exit;
+ }
+
+ /*
+ * check for sense
+ */
+ conn->in.hdr = &conn->hdr;
+ conn->senselen = (conn->data[0] << 8) | conn->data[1];
+ rc = iscsi_cmd_rsp(conn, conn->in.ctask);
+ if (!rc && conn->datadgst_en)
+ iscsi_recv_digest_update(conn, conn->data,
+ conn->in.datalen);
+ }
+ break;
case ISCSI_OP_TEXT_RSP:
case ISCSI_OP_LOGIN_RSP:
- case ISCSI_OP_NOOP_IN:
- case ISCSI_OP_ASYNC_EVENT:
- case ISCSI_OP_REJECT:
+ case ISCSI_OP_NOOP_IN: {
+ struct iscsi_mgmt_task *mtask = NULL;
+
+ if (conn->in.itt != ISCSI_RESERVED_TAG)
+ mtask = (struct iscsi_mgmt_task *)
+ session->mgmt_cmds[conn->in.itt -
+ ISCSI_MGMT_ITT_OFFSET];
+
/*
* Collect data segment to the connection's data
* placeholder
*/
- if (iscsi_tcp_copy(tcp_conn)) {
+ if (iscsi_tcp_copy(conn, conn->data, conn->in.datalen)) {
rc = -EAGAIN;
goto exit;
}
- rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, tcp_conn->data,
- tcp_conn->in.datalen);
- if (!rc && conn->datadgst_en && opcode != ISCSI_OP_LOGIN_RSP)
- iscsi_recv_digest_update(tcp_conn, tcp_conn->data,
- tcp_conn->in.datalen);
- break;
+ rc = iscsi_recv_pdu(conn->cls_conn, conn->in.hdr,
+ conn->data, conn->in.datalen);
+
+ if (!rc && conn->datadgst_en &&
+ conn->in.opcode != ISCSI_OP_LOGIN_RSP)
+ iscsi_recv_digest_update(conn, conn->data,
+ conn->in.datalen);
+
+ if (mtask && conn->login_mtask != mtask) {
+ spin_lock(&session->lock);
+ __kfifo_put(session->mgmtpool.queue, (void*)&mtask,
+ sizeof(void*));
+ spin_unlock(&session->lock);
+ }
+ }
+ break;
+ case ISCSI_OP_ASYNC_EVENT:
+ case ISCSI_OP_REJECT:
default:
BUG_ON(1);
}
{
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;
* Save current SKB and its offset in the corresponding
* connection context.
*/
- tcp_conn->in.copy = skb->len - offset;
- tcp_conn->in.offset = offset;
- tcp_conn->in.skb = skb;
- tcp_conn->in.len = tcp_conn->in.copy;
- BUG_ON(tcp_conn->in.copy <= 0);
- debug_tcp("in %d bytes\n", tcp_conn->in.copy);
+ conn->in.copy = skb->len - offset;
+ conn->in.offset = offset;
+ conn->in.skb = skb;
+ conn->in.len = conn->in.copy;
+ BUG_ON(conn->in.copy <= 0);
+ debug_tcp("in %d bytes\n", conn->in.copy);
more:
- tcp_conn->in.copied = 0;
+ conn->in.copied = 0;
rc = 0;
if (unlikely(conn->suspend_rx)) {
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;
/*
* Verify and process incoming PDU header.
*/
- rc = iscsi_tcp_hdr_recv(conn);
- if (!rc && tcp_conn->in.datalen) {
+ rc = iscsi_hdr_recv(conn);
+ if (!rc && conn->in.datalen) {
if (conn->datadgst_en) {
- BUG_ON(!tcp_conn->data_rx_tfm);
- crypto_digest_init(tcp_conn->data_rx_tfm);
+ BUG_ON(!conn->data_rx_tfm);
+ crypto_digest_init(conn->data_rx_tfm);
}
- tcp_conn->in_progress = IN_PROGRESS_DATA_RECV;
+ conn->in_progress = IN_PROGRESS_DATA_RECV;
} else if (rc) {
iscsi_conn_failure(conn, rc);
return 0;
}
}
- if (tcp_conn->in_progress == IN_PROGRESS_DDIGEST_RECV) {
+ if (conn->in_progress == IN_PROGRESS_DDIGEST_RECV) {
uint32_t recv_digest;
-
debug_tcp("extra data_recv offset %d copy %d\n",
- tcp_conn->in.offset, tcp_conn->in.copy);
- skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset,
+ conn->in.offset, conn->in.copy);
+ skb_copy_bits(conn->in.skb, conn->in.offset,
&recv_digest, 4);
- tcp_conn->in.offset += 4;
- tcp_conn->in.copy -= 4;
- if (recv_digest != tcp_conn->in.datadgst) {
+ conn->in.offset += 4;
+ conn->in.copy -= 4;
+ if (recv_digest != conn->in.datadgst) {
debug_tcp("iscsi_tcp: data digest error!"
"0x%x != 0x%x\n", recv_digest,
- tcp_conn->in.datadgst);
+ conn->in.datadgst);
iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
return 0;
} else {
debug_tcp("iscsi_tcp: data digest match!"
"0x%x == 0x%x\n", recv_digest,
- tcp_conn->in.datadgst);
- tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
+ conn->in.datadgst);
+ conn->in_progress = IN_PROGRESS_WAIT_HEADER;
}
}
- if (tcp_conn->in_progress == IN_PROGRESS_DATA_RECV &&
- tcp_conn->in.copy) {
+ if (conn->in_progress == IN_PROGRESS_DATA_RECV && conn->in.copy) {
debug_tcp("data_recv offset %d copy %d\n",
- tcp_conn->in.offset, tcp_conn->in.copy);
+ conn->in.offset, conn->in.copy);
rc = iscsi_data_recv(conn);
if (rc) {
- if (rc == -EAGAIN)
+ if (rc == -EAGAIN) {
+ rd_desc->count = conn->in.datalen -
+ conn->in.ctask->data_count;
goto again;
+ }
iscsi_conn_failure(conn, rc);
return 0;
}
- tcp_conn->in.copy -= tcp_conn->in.padding;
- tcp_conn->in.offset += tcp_conn->in.padding;
+ conn->in.copy -= conn->in.padding;
+ conn->in.offset += conn->in.padding;
if (conn->datadgst_en) {
- if (tcp_conn->in.padding) {
- debug_tcp("padding -> %d\n",
- tcp_conn->in.padding);
- memset(pad, 0, tcp_conn->in.padding);
- sg_init_one(&sg, pad, tcp_conn->in.padding);
- crypto_digest_update(tcp_conn->data_rx_tfm,
- &sg, 1);
+ if (conn->in.padding) {
+ debug_tcp("padding -> %d\n", conn->in.padding);
+ memset(pad, 0, conn->in.padding);
+ sg_init_one(&sg, pad, conn->in.padding);
+ crypto_digest_update(conn->data_rx_tfm, &sg, 1);
}
- crypto_digest_final(tcp_conn->data_rx_tfm,
- (u8 *) & tcp_conn->in.datadgst);
- debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst);
- tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
+ crypto_digest_final(conn->data_rx_tfm,
+ (u8 *) & conn->in.datadgst);
+ debug_tcp("rx digest 0x%x\n", conn->in.datadgst);
+ conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
} else
- tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
+ conn->in_progress = IN_PROGRESS_WAIT_HEADER;
}
debug_tcp("f, processed %d from out of %d padding %d\n",
- tcp_conn->in.offset - offset, (int)len, tcp_conn->in.padding);
- BUG_ON(tcp_conn->in.offset - offset > len);
+ conn->in.offset - offset, (int)len, conn->in.padding);
+ BUG_ON(conn->in.offset - offset > len);
- if (tcp_conn->in.offset - offset != len) {
+ if (conn->in.offset - offset != len) {
debug_tcp("continue to process %d bytes\n",
- (int)len - (tcp_conn->in.offset - offset));
+ (int)len - (conn->in.offset - offset));
goto more;
}
nomore:
- processed = tcp_conn->in.offset - offset;
+ processed = conn->in.offset - offset;
BUG_ON(processed == 0);
return processed;
again:
- processed = tcp_conn->in.offset - offset;
+ processed = conn->in.offset - offset;
debug_tcp("c, processed %d from out of %d rd_desc_cnt %d\n",
processed, (int)len, (int)rd_desc->count);
BUG_ON(processed == 0);
read_lock(&sk->sk_callback_lock);
- /*
- * Use rd_desc to pass 'conn' to iscsi_tcp_data_recv.
- * We set count to 1 because we want the network layer to
- * hand us all the skbs that are available. iscsi_tcp_data_recv
- * handled pdus that cross buffers or pdus that still need data.
- */
+ /* use rd_desc to pass 'conn' to iscsi_tcp_data_recv */
rd_desc.arg.data = conn;
- rd_desc.count = 1;
+ rd_desc.count = 0;
tcp_read_sock(sk, &rd_desc, iscsi_tcp_data_recv);
read_unlock(&sk->sk_callback_lock);
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 *);
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);
iscsi_write_space(struct sock *sk)
{
struct iscsi_conn *conn = (struct iscsi_conn*)sk->sk_user_data;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
-
- tcp_conn->old_write_space(sk);
+ conn->old_write_space(sk);
debug_tcp("iscsi_write_space: cid %d\n", conn->id);
+ clear_bit(SUSPEND_BIT, &conn->suspend_tx);
scsi_queue_work(conn->session->host, &conn->xmitwork);
}
static void
iscsi_conn_set_callbacks(struct iscsi_conn *conn)
{
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- struct sock *sk = tcp_conn->sock->sk;
+ struct sock *sk = conn->sock->sk;
/* assign new callbacks */
write_lock_bh(&sk->sk_callback_lock);
sk->sk_user_data = conn;
- tcp_conn->old_data_ready = sk->sk_data_ready;
- tcp_conn->old_state_change = sk->sk_state_change;
- tcp_conn->old_write_space = sk->sk_write_space;
+ conn->old_data_ready = sk->sk_data_ready;
+ conn->old_state_change = sk->sk_state_change;
+ conn->old_write_space = sk->sk_write_space;
sk->sk_data_ready = iscsi_tcp_data_ready;
sk->sk_state_change = iscsi_tcp_state_change;
sk->sk_write_space = iscsi_write_space;
static void
iscsi_conn_restore_callbacks(struct iscsi_conn *conn)
{
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- struct sock *sk = tcp_conn->sock->sk;
+ struct sock *sk = conn->sock->sk;
/* restore socket callbacks, see also: iscsi_conn_set_callbacks() */
write_lock_bh(&sk->sk_callback_lock);
sk->sk_user_data = NULL;
- sk->sk_data_ready = tcp_conn->old_data_ready;
- sk->sk_state_change = tcp_conn->old_state_change;
- sk->sk_write_space = tcp_conn->old_write_space;
+ sk->sk_data_ready = conn->old_data_ready;
+ sk->sk_state_change = conn->old_state_change;
+ sk->sk_write_space = conn->old_write_space;
sk->sk_no_check = 0;
write_unlock_bh(&sk->sk_callback_lock);
}
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
* slab case.
*/
if (buf->use_sendmsg)
- res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
- else
- res = tcp_conn->sendpage(sk, buf->sg.page, offset, size, flags);
-
- if (res >= 0) {
- conn->txdata_octets += res;
- buf->sent += res;
- return res;
- }
-
- tcp_conn->sendpage_failures_cnt++;
- if (res == -EAGAIN)
- res = -ENOBUFS;
+ return sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
else
- iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
- return res;
+ return conn->sendpage(sk, buf->sg.page, offset, size, flags);
}
/**
res = iscsi_send(conn, buf, size, flags);
debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res);
if (res >= 0) {
+ conn->txdata_octets += res;
+ buf->sent += res;
if (size != res)
return -EAGAIN;
return 0;
- }
+ } else if (res == -EAGAIN) {
+ conn->sendpage_failures_cnt++;
+ set_bit(SUSPEND_BIT, &conn->suspend_tx);
+ } else if (res == -EPIPE)
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
return res;
}
debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n",
size, buf->sent, *count, *sent, res);
if (res >= 0) {
+ conn->txdata_octets += res;
+ buf->sent += res;
*count -= res;
*sent += res;
if (size != res)
return -EAGAIN;
return 0;
- }
+ } else if (res == -EAGAIN) {
+ conn->sendpage_failures_cnt++;
+ set_bit(SUSPEND_BIT, &conn->suspend_tx);
+ } else if (res == -EPIPE)
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
return res;
}
static inline void
-iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn,
- struct iscsi_cmd_task *ctask)
+iscsi_data_digest_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
-
- BUG_ON(!tcp_conn->data_tx_tfm);
- crypto_digest_init(tcp_conn->data_tx_tfm);
- tcp_ctask->digest_count = 4;
+ BUG_ON(!conn->data_tx_tfm);
+ crypto_digest_init(conn->data_tx_tfm);
+ ctask->digest_count = 4;
}
static int
iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
struct iscsi_buf *buf, uint32_t *digest, int final)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
int rc = 0;
int sent = 0;
if (final)
- crypto_digest_final(tcp_conn->data_tx_tfm, (u8*)digest);
+ crypto_digest_final(conn->data_tx_tfm, (u8*)digest);
- iscsi_buf_init_iov(buf, (char*)digest, 4);
- rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent);
+ iscsi_buf_init_virt(buf, (char*)digest, 4);
+ rc = iscsi_sendpage(conn, buf, &ctask->digest_count, &sent);
if (rc) {
- tcp_ctask->datadigest = *digest;
- tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST;
+ ctask->datadigest = *digest;
+ ctask->xmstate |= XMSTATE_DATA_DIGEST;
} else
- tcp_ctask->digest_count = 4;
+ ctask->digest_count = 4;
return rc;
}
iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
struct iscsi_r2t_info *r2t, int left)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
struct iscsi_data *hdr;
+ struct iscsi_data_task *dtask;
struct scsi_cmnd *sc = ctask->sc;
int new_offset;
- hdr = &r2t->dtask.hdr;
+ dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC);
+ BUG_ON(!dtask);
+ hdr = &dtask->hdr;
memset(hdr, 0, sizeof(struct iscsi_data));
hdr->ttt = r2t->ttt;
hdr->datasn = cpu_to_be32(r2t->solicit_datasn);
r2t->solicit_datasn++;
hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
- memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
- hdr->itt = ctask->hdr->itt;
+ memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun));
+ hdr->itt = ctask->hdr.itt;
hdr->exp_statsn = r2t->exp_statsn;
new_offset = r2t->data_offset + r2t->sent;
hdr->offset = cpu_to_be32(new_offset);
}
conn->dataout_pdus_cnt++;
- iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr,
+ iscsi_buf_init_virt(&r2t->headbuf, (char*)hdr,
sizeof(struct iscsi_hdr));
+ r2t->dtask = dtask;
+
if (sc->use_sg && !iscsi_buf_left(&r2t->sendbuf)) {
- BUG_ON(tcp_ctask->bad_sg == r2t->sg);
+ BUG_ON(ctask->bad_sg == r2t->sg);
iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg);
r2t->sg += 1;
} else
- iscsi_buf_init_iov(&tcp_ctask->sendbuf,
+ iscsi_buf_init_iov(&ctask->sendbuf,
(char*)sc->request_buffer + new_offset,
r2t->data_count);
+
+ list_add(&dtask->item, &ctask->dataqueue);
}
static void
iscsi_unsolicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
+ struct iscsi_data *hdr;
struct iscsi_data_task *dtask;
- dtask = tcp_ctask->dtask = &tcp_ctask->unsol_dtask;
- iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr,
- tcp_ctask->r2t_data_count);
- iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr,
+ dtask = mempool_alloc(ctask->datapool, GFP_ATOMIC);
+ BUG_ON(!dtask);
+ hdr = &dtask->hdr;
+ memset(hdr, 0, sizeof(struct iscsi_data));
+ hdr->ttt = cpu_to_be32(ISCSI_RESERVED_TAG);
+ hdr->datasn = cpu_to_be32(ctask->unsol_datasn);
+ ctask->unsol_datasn++;
+ hdr->opcode = ISCSI_OP_SCSI_DATA_OUT;
+ memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun));
+ hdr->itt = ctask->hdr.itt;
+ hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
+ hdr->offset = cpu_to_be32(ctask->total_length -
+ ctask->r2t_data_count -
+ ctask->unsol_count);
+ if (ctask->unsol_count > conn->max_xmit_dlength) {
+ hton24(hdr->dlength, conn->max_xmit_dlength);
+ ctask->data_count = conn->max_xmit_dlength;
+ hdr->flags = 0;
+ } else {
+ hton24(hdr->dlength, ctask->unsol_count);
+ ctask->data_count = ctask->unsol_count;
+ hdr->flags = ISCSI_FLAG_CMD_FINAL;
+ }
+
+ iscsi_buf_init_virt(&ctask->headbuf, (char*)hdr,
sizeof(struct iscsi_hdr));
+
+ list_add(&dtask->item, &ctask->dataqueue);
+
+ ctask->dtask = dtask;
}
/**
- * iscsi_tcp_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
+ * iscsi_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
* @conn: iscsi connection
* @ctask: scsi command task
* @sc: scsi command
**/
static void
-iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
+iscsi_cmd_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
+ struct scsi_cmnd *sc)
{
- struct scsi_cmnd *sc = ctask->sc;
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
+ struct iscsi_session *session = conn->session;
- BUG_ON(__kfifo_len(tcp_ctask->r2tqueue));
+ BUG_ON(__kfifo_len(ctask->r2tqueue));
- tcp_ctask->sent = 0;
- tcp_ctask->sg_count = 0;
+ ctask->sc = sc;
+ ctask->conn = conn;
+ ctask->hdr.opcode = ISCSI_OP_SCSI_CMD;
+ ctask->hdr.flags = ISCSI_ATTR_SIMPLE;
+ int_to_scsilun(sc->device->lun, (struct scsi_lun *)ctask->hdr.lun);
+ ctask->hdr.itt = ctask->itt | (conn->id << CID_SHIFT) |
+ (session->age << AGE_SHIFT);
+ ctask->hdr.data_length = cpu_to_be32(sc->request_bufflen);
+ ctask->hdr.cmdsn = cpu_to_be32(session->cmdsn); session->cmdsn++;
+ ctask->hdr.exp_statsn = cpu_to_be32(conn->exp_statsn);
+ memcpy(ctask->hdr.cdb, sc->cmnd, sc->cmd_len);
+ memset(&ctask->hdr.cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len);
+
+ ctask->mtask = NULL;
+ ctask->sent = 0;
+ ctask->sg_count = 0;
+
+ ctask->total_length = sc->request_bufflen;
if (sc->sc_data_direction == DMA_TO_DEVICE) {
- tcp_ctask->xmstate = XMSTATE_W_HDR;
- tcp_ctask->exp_r2tsn = 0;
+ ctask->exp_r2tsn = 0;
+ ctask->hdr.flags |= ISCSI_FLAG_CMD_WRITE;
BUG_ON(ctask->total_length == 0);
-
if (sc->use_sg) {
struct scatterlist *sg = sc->request_buffer;
- iscsi_buf_init_sg(&tcp_ctask->sendbuf,
- &sg[tcp_ctask->sg_count++]);
- tcp_ctask->sg = sg;
- tcp_ctask->bad_sg = sg + sc->use_sg;
- } else
- iscsi_buf_init_iov(&tcp_ctask->sendbuf,
- sc->request_buffer,
- sc->request_bufflen);
-
- if (ctask->imm_count)
- tcp_ctask->xmstate |= XMSTATE_IMM_DATA;
+ iscsi_buf_init_sg(&ctask->sendbuf,
+ &sg[ctask->sg_count++]);
+ ctask->sg = sg;
+ ctask->bad_sg = sg + sc->use_sg;
+ } else {
+ iscsi_buf_init_iov(&ctask->sendbuf, sc->request_buffer,
+ sc->request_bufflen);
+ }
- tcp_ctask->pad_count = ctask->total_length & (ISCSI_PAD_LEN-1);
- if (tcp_ctask->pad_count) {
- tcp_ctask->pad_count = ISCSI_PAD_LEN -
- tcp_ctask->pad_count;
+ /*
+ * Write counters:
+ *
+ * imm_count bytes to be sent right after
+ * SCSI PDU Header
+ *
+ * unsol_count bytes(as Data-Out) to be sent
+ * without R2T ack right after
+ * immediate data
+ *
+ * r2t_data_count bytes to be sent via R2T ack's
+ *
+ * pad_count bytes to be sent as zero-padding
+ */
+ ctask->imm_count = 0;
+ ctask->unsol_count = 0;
+ ctask->unsol_datasn = 0;
+ ctask->xmstate = XMSTATE_W_HDR;
+ /* calculate write padding */
+ ctask->pad_count = ctask->total_length & (ISCSI_PAD_LEN-1);
+ if (ctask->pad_count) {
+ ctask->pad_count = ISCSI_PAD_LEN - ctask->pad_count;
debug_scsi("write padding %d bytes\n",
- tcp_ctask->pad_count);
- tcp_ctask->xmstate |= XMSTATE_W_PAD;
+ ctask->pad_count);
+ ctask->xmstate |= XMSTATE_W_PAD;
}
+ if (session->imm_data_en) {
+ if (ctask->total_length >= session->first_burst)
+ ctask->imm_count = min(session->first_burst,
+ conn->max_xmit_dlength);
+ else
+ ctask->imm_count = min(ctask->total_length,
+ conn->max_xmit_dlength);
+ hton24(ctask->hdr.dlength, ctask->imm_count);
+ ctask->xmstate |= XMSTATE_IMM_DATA;
+ } else
+ zero_data(ctask->hdr.dlength);
+
+ if (!session->initial_r2t_en)
+ ctask->unsol_count = min(session->first_burst,
+ ctask->total_length) - ctask->imm_count;
+ if (!ctask->unsol_count)
+ /* No unsolicit Data-Out's */
+ ctask->hdr.flags |= ISCSI_FLAG_CMD_FINAL;
+ else
+ ctask->xmstate |= XMSTATE_UNS_HDR | XMSTATE_UNS_INIT;
- if (ctask->unsol_count)
- tcp_ctask->xmstate |= XMSTATE_UNS_HDR |
- XMSTATE_UNS_INIT;
- tcp_ctask->r2t_data_count = ctask->total_length -
+ ctask->r2t_data_count = ctask->total_length -
ctask->imm_count -
ctask->unsol_count;
debug_scsi("cmd [itt %x total %d imm %d imm_data %d "
"r2t_data %d]\n",
ctask->itt, ctask->total_length, ctask->imm_count,
- ctask->unsol_count, tcp_ctask->r2t_data_count);
- } else
- tcp_ctask->xmstate = XMSTATE_R_HDR;
+ ctask->unsol_count, ctask->r2t_data_count);
+ } else {
+ ctask->hdr.flags |= ISCSI_FLAG_CMD_FINAL;
+ if (sc->sc_data_direction == DMA_FROM_DEVICE)
+ ctask->hdr.flags |= ISCSI_FLAG_CMD_READ;
+ ctask->datasn = 0;
+ ctask->xmstate = XMSTATE_R_HDR;
+ zero_data(ctask->hdr.dlength);
+ }
- iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)ctask->hdr,
+ iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr,
sizeof(struct iscsi_hdr));
+ conn->scsicmd_pdus_cnt++;
}
/**
- * iscsi_tcp_mtask_xmit - xmit management(immediate) task
+ * iscsi_mtask_xmit - xmit management(immediate) task
* @conn: iscsi connection
* @mtask: task management task
*
* IN_PROGRESS_IMM_DATA - PDU Data xmit in progress
**/
static int
-iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
+iscsi_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
{
- struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
- int rc;
debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n",
- conn->id, tcp_mtask->xmstate, mtask->itt);
+ conn->id, mtask->xmstate, mtask->itt);
- if (tcp_mtask->xmstate & XMSTATE_IMM_HDR) {
- tcp_mtask->xmstate &= ~XMSTATE_IMM_HDR;
+ if (mtask->xmstate & XMSTATE_IMM_HDR) {
+ mtask->xmstate &= ~XMSTATE_IMM_HDR;
if (mtask->data_count)
- tcp_mtask->xmstate |= XMSTATE_IMM_DATA;
+ mtask->xmstate |= XMSTATE_IMM_DATA;
if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE &&
- conn->stop_stage != STOP_CONN_RECOVER &&
+ conn->stop_stage != STOP_CONN_RECOVER &&
conn->hdrdgst_en)
- iscsi_hdr_digest(conn, &tcp_mtask->headbuf,
- (u8*)tcp_mtask->hdrext);
- rc = iscsi_sendhdr(conn, &tcp_mtask->headbuf,
- mtask->data_count);
- if (rc) {
- tcp_mtask->xmstate |= XMSTATE_IMM_HDR;
+ iscsi_hdr_digest(conn, &mtask->headbuf,
+ (u8*)mtask->hdrext);
+ if (iscsi_sendhdr(conn, &mtask->headbuf, mtask->data_count)) {
+ mtask->xmstate |= XMSTATE_IMM_HDR;
if (mtask->data_count)
- tcp_mtask->xmstate &= ~XMSTATE_IMM_DATA;
- return rc;
+ mtask->xmstate &= ~XMSTATE_IMM_DATA;
+ return -EAGAIN;
}
}
- if (tcp_mtask->xmstate & XMSTATE_IMM_DATA) {
+ if (mtask->xmstate & XMSTATE_IMM_DATA) {
BUG_ON(!mtask->data_count);
- tcp_mtask->xmstate &= ~XMSTATE_IMM_DATA;
+ mtask->xmstate &= ~XMSTATE_IMM_DATA;
/* FIXME: implement.
* Virtual buffer could be spreaded across multiple pages...
*/
do {
- int rc;
-
- rc = iscsi_sendpage(conn, &tcp_mtask->sendbuf,
- &mtask->data_count, &tcp_mtask->sent);
- if (rc) {
- tcp_mtask->xmstate |= XMSTATE_IMM_DATA;
- return rc;
+ if (iscsi_sendpage(conn, &mtask->sendbuf,
+ &mtask->data_count, &mtask->sent)) {
+ mtask->xmstate |= XMSTATE_IMM_DATA;
+ return -EAGAIN;
}
} while (mtask->data_count);
}
- BUG_ON(tcp_mtask->xmstate != XMSTATE_IDLE);
- if (mtask->hdr->itt == cpu_to_be32(ISCSI_RESERVED_TAG)) {
- struct iscsi_session *session = conn->session;
-
- spin_lock_bh(&session->lock);
- list_del(&conn->mtask->running);
- __kfifo_put(session->mgmtpool.queue, (void*)&conn->mtask,
- sizeof(void*));
- spin_unlock_bh(&session->lock);
- }
+ BUG_ON(mtask->xmstate != XMSTATE_IDLE);
return 0;
}
static inline int
-handle_xmstate_r_hdr(struct iscsi_conn *conn,
- struct iscsi_tcp_cmd_task *tcp_ctask)
+handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
- int rc;
-
- tcp_ctask->xmstate &= ~XMSTATE_R_HDR;
+ ctask->xmstate &= ~XMSTATE_R_HDR;
if (conn->hdrdgst_en)
- iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
- (u8*)tcp_ctask->hdrext);
- rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, 0);
- if (!rc) {
- BUG_ON(tcp_ctask->xmstate != XMSTATE_IDLE);
+ iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
+ if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) {
+ BUG_ON(ctask->xmstate != XMSTATE_IDLE);
return 0; /* wait for Data-In */
}
- tcp_ctask->xmstate |= XMSTATE_R_HDR;
- return rc;
+ ctask->xmstate |= XMSTATE_R_HDR;
+ return -EAGAIN;
}
static inline int
-handle_xmstate_w_hdr(struct iscsi_conn *conn,
- struct iscsi_cmd_task *ctask)
+handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- int rc;
-
- tcp_ctask->xmstate &= ~XMSTATE_W_HDR;
+ ctask->xmstate &= ~XMSTATE_W_HDR;
if (conn->hdrdgst_en)
- iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
- (u8*)tcp_ctask->hdrext);
- rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count);
- if (rc)
- tcp_ctask->xmstate |= XMSTATE_W_HDR;
- return rc;
+ iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
+ if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) {
+ ctask->xmstate |= XMSTATE_W_HDR;
+ return -EAGAIN;
+ }
+ return 0;
}
static inline int
handle_xmstate_data_digest(struct iscsi_conn *conn,
struct iscsi_cmd_task *ctask)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- int rc;
-
- tcp_ctask->xmstate &= ~XMSTATE_DATA_DIGEST;
- debug_tcp("resent data digest 0x%x\n", tcp_ctask->datadigest);
- rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf,
- &tcp_ctask->datadigest, 0);
- if (rc) {
- tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST;
+ ctask->xmstate &= ~XMSTATE_DATA_DIGEST;
+ debug_tcp("resent data digest 0x%x\n", ctask->datadigest);
+ if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf,
+ &ctask->datadigest, 0)) {
+ ctask->xmstate |= XMSTATE_DATA_DIGEST;
debug_tcp("resent data digest 0x%x fail!\n",
- tcp_ctask->datadigest);
+ ctask->datadigest);
+ return -EAGAIN;
}
-
- return rc;
+ return 0;
}
static inline int
handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- int rc;
-
BUG_ON(!ctask->imm_count);
- tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA;
+ ctask->xmstate &= ~XMSTATE_IMM_DATA;
if (conn->datadgst_en) {
- iscsi_data_digest_init(tcp_conn, ctask);
- tcp_ctask->immdigest = 0;
+ iscsi_data_digest_init(conn, ctask);
+ ctask->immdigest = 0;
}
for (;;) {
- rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf,
- &ctask->imm_count, &tcp_ctask->sent);
- if (rc) {
- tcp_ctask->xmstate |= XMSTATE_IMM_DATA;
+ if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->imm_count,
+ &ctask->sent)) {
+ ctask->xmstate |= XMSTATE_IMM_DATA;
if (conn->datadgst_en) {
- crypto_digest_final(tcp_conn->data_tx_tfm,
- (u8*)&tcp_ctask->immdigest);
+ crypto_digest_final(conn->data_tx_tfm,
+ (u8*)&ctask->immdigest);
debug_tcp("tx imm sendpage fail 0x%x\n",
- tcp_ctask->datadigest);
+ ctask->datadigest);
}
- return rc;
+ return -EAGAIN;
}
if (conn->datadgst_en)
- crypto_digest_update(tcp_conn->data_tx_tfm,
- &tcp_ctask->sendbuf.sg, 1);
+ crypto_digest_update(conn->data_tx_tfm,
+ &ctask->sendbuf.sg, 1);
if (!ctask->imm_count)
break;
- iscsi_buf_init_sg(&tcp_ctask->sendbuf,
- &tcp_ctask->sg[tcp_ctask->sg_count++]);
+ iscsi_buf_init_sg(&ctask->sendbuf,
+ &ctask->sg[ctask->sg_count++]);
}
- if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) {
- rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf,
- &tcp_ctask->immdigest, 1);
- if (rc) {
+ if (conn->datadgst_en && !(ctask->xmstate & XMSTATE_W_PAD)) {
+ if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf,
+ &ctask->immdigest, 1)) {
debug_tcp("sending imm digest 0x%x fail!\n",
- tcp_ctask->immdigest);
- return rc;
+ ctask->immdigest);
+ return -EAGAIN;
}
- debug_tcp("sending imm digest 0x%x\n", tcp_ctask->immdigest);
+ debug_tcp("sending imm digest 0x%x\n", ctask->immdigest);
}
return 0;
static inline int
handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
struct iscsi_data_task *dtask;
- int rc;
- tcp_ctask->xmstate |= XMSTATE_UNS_DATA;
- if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) {
+ ctask->xmstate |= XMSTATE_UNS_DATA;
+ if (ctask->xmstate & XMSTATE_UNS_INIT) {
iscsi_unsolicit_data_init(conn, ctask);
- dtask = tcp_ctask->dtask;
+ BUG_ON(!ctask->dtask);
+ dtask = ctask->dtask;
if (conn->hdrdgst_en)
- iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
+ iscsi_hdr_digest(conn, &ctask->headbuf,
(u8*)dtask->hdrext);
- tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT;
+ ctask->xmstate &= ~XMSTATE_UNS_INIT;
}
-
- rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->data_count);
- if (rc) {
- tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA;
- tcp_ctask->xmstate |= XMSTATE_UNS_HDR;
- return rc;
+ if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->data_count)) {
+ ctask->xmstate &= ~XMSTATE_UNS_DATA;
+ ctask->xmstate |= XMSTATE_UNS_HDR;
+ return -EAGAIN;
}
debug_scsi("uns dout [itt 0x%x dlen %d sent %d]\n",
- ctask->itt, ctask->unsol_count, tcp_ctask->sent);
+ ctask->itt, ctask->unsol_count, ctask->sent);
return 0;
}
static inline int
handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- struct iscsi_data_task *dtask = tcp_ctask->dtask;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- int rc;
+ struct iscsi_data_task *dtask = ctask->dtask;
BUG_ON(!ctask->data_count);
- tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA;
+ ctask->xmstate &= ~XMSTATE_UNS_DATA;
if (conn->datadgst_en) {
- iscsi_data_digest_init(tcp_conn, ctask);
+ iscsi_data_digest_init(conn, ctask);
dtask->digest = 0;
}
for (;;) {
- int start = tcp_ctask->sent;
+ int start = ctask->sent;
- rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf,
- &ctask->data_count, &tcp_ctask->sent);
- if (rc) {
- ctask->unsol_count -= tcp_ctask->sent - start;
- tcp_ctask->xmstate |= XMSTATE_UNS_DATA;
+ if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->data_count,
+ &ctask->sent)) {
+ ctask->unsol_count -= ctask->sent - start;
+ ctask->xmstate |= XMSTATE_UNS_DATA;
/* will continue with this ctask later.. */
if (conn->datadgst_en) {
- crypto_digest_final(tcp_conn->data_tx_tfm,
+ crypto_digest_final(conn->data_tx_tfm,
(u8 *)&dtask->digest);
debug_tcp("tx uns data fail 0x%x\n",
dtask->digest);
}
- return rc;
+ return -EAGAIN;
}
- BUG_ON(tcp_ctask->sent > ctask->total_length);
- ctask->unsol_count -= tcp_ctask->sent - start;
+ BUG_ON(ctask->sent > ctask->total_length);
+ ctask->unsol_count -= ctask->sent - start;
/*
* XXX:we may run here with un-initial sendbuf.
* so pass it
*/
- if (conn->datadgst_en && tcp_ctask->sent - start > 0)
- crypto_digest_update(tcp_conn->data_tx_tfm,
- &tcp_ctask->sendbuf.sg, 1);
+ if (conn->datadgst_en && ctask->sent - start > 0)
+ crypto_digest_update(conn->data_tx_tfm,
+ &ctask->sendbuf.sg, 1);
if (!ctask->data_count)
break;
- iscsi_buf_init_sg(&tcp_ctask->sendbuf,
- &tcp_ctask->sg[tcp_ctask->sg_count++]);
+ iscsi_buf_init_sg(&ctask->sendbuf,
+ &ctask->sg[ctask->sg_count++]);
}
BUG_ON(ctask->unsol_count < 0);
*/
if (ctask->unsol_count) {
if (conn->datadgst_en) {
- rc = iscsi_digest_final_send(conn, ctask,
+ if (iscsi_digest_final_send(conn, ctask,
&dtask->digestbuf,
- &dtask->digest, 1);
- if (rc) {
+ &dtask->digest, 1)) {
debug_tcp("send uns digest 0x%x fail\n",
dtask->digest);
- return rc;
+ return -EAGAIN;
}
debug_tcp("sending uns digest 0x%x, more uns\n",
dtask->digest);
}
- tcp_ctask->xmstate |= XMSTATE_UNS_INIT;
+ ctask->xmstate |= XMSTATE_UNS_INIT;
return 1;
}
- if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) {
- rc = iscsi_digest_final_send(conn, ctask,
+ if (conn->datadgst_en && !(ctask->xmstate & XMSTATE_W_PAD)) {
+ if (iscsi_digest_final_send(conn, ctask,
&dtask->digestbuf,
- &dtask->digest, 1);
- if (rc) {
+ &dtask->digest, 1)) {
debug_tcp("send last uns digest 0x%x fail\n",
dtask->digest);
- return rc;
+ return -EAGAIN;
}
debug_tcp("sending uns digest 0x%x\n",dtask->digest);
}
handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
struct iscsi_session *session = conn->session;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- struct iscsi_r2t_info *r2t = tcp_ctask->r2t;
- struct iscsi_data_task *dtask = &r2t->dtask;
- int left, rc;
+ struct iscsi_r2t_info *r2t = ctask->r2t;
+ struct iscsi_data_task *dtask = r2t->dtask;
+ int left;
- tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
- tcp_ctask->dtask = dtask;
+ ctask->xmstate &= ~XMSTATE_SOL_DATA;
+ ctask->dtask = dtask;
if (conn->datadgst_en) {
- iscsi_data_digest_init(tcp_conn, ctask);
+ iscsi_data_digest_init(conn, ctask);
dtask->digest = 0;
}
solicit_again:
if (!r2t->data_count)
goto data_out_done;
- rc = iscsi_sendpage(conn, &r2t->sendbuf, &r2t->data_count, &r2t->sent);
- if (rc) {
- tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
+ if (iscsi_sendpage(conn, &r2t->sendbuf, &r2t->data_count, &r2t->sent)) {
+ ctask->xmstate |= XMSTATE_SOL_DATA;
/* will continue with this ctask later.. */
if (conn->datadgst_en) {
- crypto_digest_final(tcp_conn->data_tx_tfm,
+ crypto_digest_final(conn->data_tx_tfm,
(u8 *)&dtask->digest);
debug_tcp("r2t data send fail 0x%x\n", dtask->digest);
}
- return rc;
+ return -EAGAIN;
}
BUG_ON(r2t->data_count < 0);
if (conn->datadgst_en)
- crypto_digest_update(tcp_conn->data_tx_tfm, &r2t->sendbuf.sg,
- 1);
+ crypto_digest_update(conn->data_tx_tfm, &r2t->sendbuf.sg, 1);
if (r2t->data_count) {
BUG_ON(ctask->sc->use_sg == 0);
if (!iscsi_buf_left(&r2t->sendbuf)) {
- BUG_ON(tcp_ctask->bad_sg == r2t->sg);
+ BUG_ON(ctask->bad_sg == r2t->sg);
iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg);
r2t->sg += 1;
}
left = r2t->data_length - r2t->sent;
if (left) {
if (conn->datadgst_en) {
- rc = iscsi_digest_final_send(conn, ctask,
+ if (iscsi_digest_final_send(conn, ctask,
&dtask->digestbuf,
- &dtask->digest, 1);
- if (rc) {
+ &dtask->digest, 1)) {
debug_tcp("send r2t data digest 0x%x"
"fail\n", dtask->digest);
- return rc;
+ return -EAGAIN;
}
debug_tcp("r2t data send digest 0x%x\n",
dtask->digest);
}
iscsi_solicit_data_cont(conn, ctask, r2t, left);
- tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
- tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
+ ctask->xmstate |= XMSTATE_SOL_DATA;
+ ctask->xmstate &= ~XMSTATE_SOL_HDR;
return 1;
}
* Done with this R2T. Check if there are more
* outstanding R2Ts ready to be processed.
*/
- BUG_ON(tcp_ctask->r2t_data_count - r2t->data_length < 0);
+ BUG_ON(ctask->r2t_data_count - r2t->data_length < 0);
if (conn->datadgst_en) {
- rc = iscsi_digest_final_send(conn, ctask, &dtask->digestbuf,
- &dtask->digest, 1);
- if (rc) {
+ if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf,
+ &dtask->digest, 1)) {
debug_tcp("send last r2t data digest 0x%x"
"fail\n", dtask->digest);
- return rc;
+ return -EAGAIN;
}
debug_tcp("r2t done dout digest 0x%x\n", dtask->digest);
}
- tcp_ctask->r2t_data_count -= r2t->data_length;
- tcp_ctask->r2t = NULL;
+ ctask->r2t_data_count -= r2t->data_length;
+ ctask->r2t = NULL;
spin_lock_bh(&session->lock);
- __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*));
+ __kfifo_put(ctask->r2tpool.queue, (void*)&r2t, sizeof(void*));
spin_unlock_bh(&session->lock);
- if (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) {
- tcp_ctask->r2t = r2t;
- tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
- tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
+ if (__kfifo_get(ctask->r2tqueue, (void*)&r2t, sizeof(void*))) {
+ ctask->r2t = r2t;
+ ctask->xmstate |= XMSTATE_SOL_DATA;
+ ctask->xmstate &= ~XMSTATE_SOL_HDR;
return 1;
}
static inline int
handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- struct iscsi_data_task *dtask = tcp_ctask->dtask;
- int sent, rc;
-
- tcp_ctask->xmstate &= ~XMSTATE_W_PAD;
- iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad,
- tcp_ctask->pad_count);
- rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count,
- &sent);
- if (rc) {
- tcp_ctask->xmstate |= XMSTATE_W_PAD;
- return rc;
+ struct iscsi_data_task *dtask = ctask->dtask;
+ int sent;
+
+ ctask->xmstate &= ~XMSTATE_W_PAD;
+ iscsi_buf_init_virt(&ctask->sendbuf, (char*)&ctask->pad,
+ ctask->pad_count);
+ if (iscsi_sendpage(conn, &ctask->sendbuf, &ctask->pad_count, &sent)) {
+ ctask->xmstate |= XMSTATE_W_PAD;
+ return -EAGAIN;
}
if (conn->datadgst_en) {
- crypto_digest_update(tcp_conn->data_tx_tfm,
- &tcp_ctask->sendbuf.sg, 1);
+ crypto_digest_update(conn->data_tx_tfm, &ctask->sendbuf.sg, 1);
/* imm data? */
if (!dtask) {
- rc = iscsi_digest_final_send(conn, ctask,
- &tcp_ctask->immbuf,
- &tcp_ctask->immdigest, 1);
- if (rc) {
+ if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf,
+ &ctask->immdigest, 1)) {
debug_tcp("send padding digest 0x%x"
- "fail!\n", tcp_ctask->immdigest);
- return rc;
+ "fail!\n", ctask->immdigest);
+ return -EAGAIN;
}
debug_tcp("done with padding, digest 0x%x\n",
- tcp_ctask->datadigest);
+ ctask->datadigest);
} else {
- rc = iscsi_digest_final_send(conn, ctask,
+ if (iscsi_digest_final_send(conn, ctask,
&dtask->digestbuf,
- &dtask->digest, 1);
- if (rc) {
+ &dtask->digest, 1)) {
debug_tcp("send padding digest 0x%x"
"fail\n", dtask->digest);
- return rc;
+ return -EAGAIN;
}
debug_tcp("done with padding, digest 0x%x\n",
dtask->digest);
}
static int
-iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+iscsi_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
int rc = 0;
debug_scsi("ctask deq [cid %d xmstate %x itt 0x%x]\n",
- conn->id, tcp_ctask->xmstate, ctask->itt);
+ conn->id, ctask->xmstate, ctask->itt);
/*
* serialize with TMF AbortTask
if (ctask->mtask)
return rc;
- if (tcp_ctask->xmstate & XMSTATE_R_HDR)
- return handle_xmstate_r_hdr(conn, tcp_ctask);
+ if (ctask->xmstate & XMSTATE_R_HDR) {
+ rc = handle_xmstate_r_hdr(conn, ctask);
+ return rc;
+ }
- if (tcp_ctask->xmstate & XMSTATE_W_HDR) {
+ if (ctask->xmstate & XMSTATE_W_HDR) {
rc = handle_xmstate_w_hdr(conn, ctask);
if (rc)
return rc;
}
/* XXX: for data digest xmit recover */
- if (tcp_ctask->xmstate & XMSTATE_DATA_DIGEST) {
+ if (ctask->xmstate & XMSTATE_DATA_DIGEST) {
rc = handle_xmstate_data_digest(conn, ctask);
if (rc)
return rc;
}
- if (tcp_ctask->xmstate & XMSTATE_IMM_DATA) {
+ if (ctask->xmstate & XMSTATE_IMM_DATA) {
rc = handle_xmstate_imm_data(conn, ctask);
if (rc)
return rc;
}
- if (tcp_ctask->xmstate & XMSTATE_UNS_HDR) {
+ if (ctask->xmstate & XMSTATE_UNS_HDR) {
BUG_ON(!ctask->unsol_count);
- tcp_ctask->xmstate &= ~XMSTATE_UNS_HDR;
+ ctask->xmstate &= ~XMSTATE_UNS_HDR;
unsolicit_head_again:
rc = handle_xmstate_uns_hdr(conn, ctask);
if (rc)
return rc;
}
- if (tcp_ctask->xmstate & XMSTATE_UNS_DATA) {
+ if (ctask->xmstate & XMSTATE_UNS_DATA) {
rc = handle_xmstate_uns_data(conn, ctask);
if (rc == 1)
goto unsolicit_head_again;
goto done;
}
- if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
+ if (ctask->xmstate & XMSTATE_SOL_HDR) {
struct iscsi_r2t_info *r2t;
- tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
- tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
- if (!tcp_ctask->r2t)
- __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
+ ctask->xmstate &= ~XMSTATE_SOL_HDR;
+ ctask->xmstate |= XMSTATE_SOL_DATA;
+ if (!ctask->r2t)
+ __kfifo_get(ctask->r2tqueue, (void*)&ctask->r2t,
sizeof(void*));
solicit_head_again:
- r2t = tcp_ctask->r2t;
+ r2t = ctask->r2t;
if (conn->hdrdgst_en)
iscsi_hdr_digest(conn, &r2t->headbuf,
- (u8*)r2t->dtask.hdrext);
- rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count);
- if (rc) {
- tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
- tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
- return rc;
+ (u8*)r2t->dtask->hdrext);
+ if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) {
+ ctask->xmstate &= ~XMSTATE_SOL_DATA;
+ ctask->xmstate |= XMSTATE_SOL_HDR;
+ return -EAGAIN;
}
debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n",
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;
* Last thing to check is whether we need to send write
* padding. Note that we check for xmstate equality, not just the bit.
*/
- if (tcp_ctask->xmstate == XMSTATE_W_PAD)
+ if (ctask->xmstate == XMSTATE_W_PAD)
rc = handle_xmstate_w_pad(conn, ctask);
return rc;
}
+/**
+ * iscsi_data_xmit - xmit any command into the scheduled connection
+ * @conn: iscsi connection
+ *
+ * Notes:
+ * The function can return -EAGAIN in which case the caller must
+ * re-schedule it again later or recover. '0' return code means
+ * successful xmit.
+ **/
+static int
+iscsi_data_xmit(struct iscsi_conn *conn)
+{
+ if (unlikely(conn->suspend_tx)) {
+ debug_tcp("conn %d Tx suspended!\n", conn->id);
+ return 0;
+ }
+
+ /*
+ * Transmit in the following order:
+ *
+ * 1) un-finished xmit (ctask or mtask)
+ * 2) immediate control PDUs
+ * 3) write data
+ * 4) SCSI commands
+ * 5) non-immediate control PDUs
+ *
+ * No need to lock around __kfifo_get as long as
+ * there's one producer and one consumer.
+ */
+
+ BUG_ON(conn->ctask && conn->mtask);
+
+ if (conn->ctask) {
+ if (iscsi_ctask_xmit(conn, conn->ctask))
+ goto again;
+ /* done with this in-progress ctask */
+ conn->ctask = NULL;
+ }
+ if (conn->mtask) {
+ if (iscsi_mtask_xmit(conn, conn->mtask))
+ goto again;
+ /* done with this in-progress mtask */
+ conn->mtask = NULL;
+ }
+
+ /* process immediate first */
+ if (unlikely(__kfifo_len(conn->immqueue))) {
+ struct iscsi_session *session = conn->session;
+ while (__kfifo_get(conn->immqueue, (void*)&conn->mtask,
+ sizeof(void*))) {
+ if (iscsi_mtask_xmit(conn, conn->mtask))
+ goto again;
+
+ if (conn->mtask->hdr.itt ==
+ cpu_to_be32(ISCSI_RESERVED_TAG)) {
+ spin_lock_bh(&session->lock);
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&conn->mtask, sizeof(void*));
+ spin_unlock_bh(&session->lock);
+ }
+ }
+ /* done with this mtask */
+ conn->mtask = NULL;
+ }
+
+ /* process write queue */
+ while (__kfifo_get(conn->writequeue, (void*)&conn->ctask,
+ sizeof(void*))) {
+ if (iscsi_ctask_xmit(conn, conn->ctask))
+ goto again;
+ }
+
+ /* process command queue */
+ while (__kfifo_get(conn->xmitqueue, (void*)&conn->ctask,
+ sizeof(void*))) {
+ if (iscsi_ctask_xmit(conn, conn->ctask))
+ goto again;
+ }
+ /* done with this ctask */
+ conn->ctask = NULL;
+
+ /* process the rest control plane PDUs, if any */
+ if (unlikely(__kfifo_len(conn->mgmtqueue))) {
+ struct iscsi_session *session = conn->session;
+
+ while (__kfifo_get(conn->mgmtqueue, (void*)&conn->mtask,
+ sizeof(void*))) {
+ if (iscsi_mtask_xmit(conn, conn->mtask))
+ goto again;
+
+ if (conn->mtask->hdr.itt ==
+ cpu_to_be32(ISCSI_RESERVED_TAG)) {
+ spin_lock_bh(&session->lock);
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&conn->mtask,
+ sizeof(void*));
+ spin_unlock_bh(&session->lock);
+ }
+ }
+ /* done with this mtask */
+ conn->mtask = NULL;
+ }
+
+ return 0;
+
+again:
+ if (unlikely(conn->suspend_tx))
+ return 0;
+
+ return -EAGAIN;
+}
+
+static void
+iscsi_xmitworker(void *data)
+{
+ struct iscsi_conn *conn = data;
+
+ /*
+ * serialize Xmit worker on a per-connection basis.
+ */
+ mutex_lock(&conn->xmitmutex);
+ if (iscsi_data_xmit(conn))
+ scsi_queue_work(conn->session->host, &conn->xmitwork);
+ mutex_unlock(&conn->xmitmutex);
+}
+
+#define FAILURE_BAD_HOST 1
+#define FAILURE_SESSION_FAILED 2
+#define FAILURE_SESSION_FREED 3
+#define FAILURE_WINDOW_CLOSED 4
+#define FAILURE_SESSION_TERMINATE 5
+
+static int
+iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
+{
+ struct Scsi_Host *host;
+ int reason = 0;
+ struct iscsi_session *session;
+ struct iscsi_conn *conn = NULL;
+ struct iscsi_cmd_task *ctask = NULL;
+
+ sc->scsi_done = done;
+ sc->result = 0;
+
+ host = sc->device->host;
+ session = iscsi_hostdata(host->hostdata);
+ BUG_ON(host != session->host);
+
+ spin_lock(&session->lock);
+
+ if (session->state != ISCSI_STATE_LOGGED_IN) {
+ if (session->state == ISCSI_STATE_FAILED) {
+ reason = FAILURE_SESSION_FAILED;
+ goto reject;
+ } else if (session->state == ISCSI_STATE_TERMINATE) {
+ reason = FAILURE_SESSION_TERMINATE;
+ goto fault;
+ }
+ reason = FAILURE_SESSION_FREED;
+ goto fault;
+ }
+
+ /*
+ * Check for iSCSI window and take care of CmdSN wrap-around
+ */
+ if ((int)(session->max_cmdsn - session->cmdsn) < 0) {
+ reason = FAILURE_WINDOW_CLOSED;
+ goto reject;
+ }
+
+ conn = session->leadconn;
+
+ __kfifo_get(session->cmdpool.queue, (void*)&ctask, sizeof(void*));
+ BUG_ON(ctask->sc);
+
+ sc->SCp.phase = session->age;
+ sc->SCp.ptr = (char*)ctask;
+ iscsi_cmd_init(conn, ctask, sc);
+
+ __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*));
+ debug_scsi(
+ "ctask enq [%s cid %d sc %lx itt 0x%x len %d cmdsn %d win %d]\n",
+ sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
+ conn->id, (long)sc, ctask->itt, sc->request_bufflen,
+ session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
+ spin_unlock(&session->lock);
+
+ scsi_queue_work(host, &conn->xmitwork);
+ return 0;
+
+reject:
+ spin_unlock(&session->lock);
+ debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason);
+ return SCSI_MLQUEUE_HOST_BUSY;
+
+fault:
+ spin_unlock(&session->lock);
+ printk(KERN_ERR "iscsi_tcp: cmd 0x%x is not queued (%d)\n",
+ sc->cmnd[0], reason);
+ sc->sense_buffer[0] = 0x70;
+ sc->sense_buffer[2] = NOT_READY;
+ sc->sense_buffer[7] = 0x6;
+ sc->sense_buffer[12] = 0x08;
+ sc->sense_buffer[13] = 0x00;
+ sc->result = (DID_NO_CONNECT << 16);
+ sc->resid = sc->request_bufflen;
+ sc->scsi_done(sc);
+ return 0;
+}
+
+static int
+iscsi_change_queue_depth(struct scsi_device *sdev, int depth)
+{
+ if (depth > ISCSI_MAX_CMD_PER_LUN)
+ depth = ISCSI_MAX_CMD_PER_LUN;
+ scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+ return sdev->queue_depth;
+}
+
+static int
+iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size)
+{
+ int i;
+
+ *items = kmalloc(max * sizeof(void*), GFP_KERNEL);
+ if (*items == NULL)
+ return -ENOMEM;
+
+ q->max = max;
+ q->pool = kmalloc(max * sizeof(void*), GFP_KERNEL);
+ if (q->pool == NULL) {
+ kfree(*items);
+ return -ENOMEM;
+ }
+
+ q->queue = kfifo_init((void*)q->pool, max * sizeof(void*),
+ GFP_KERNEL, NULL);
+ if (q->queue == ERR_PTR(-ENOMEM)) {
+ kfree(q->pool);
+ kfree(*items);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < max; i++) {
+ q->pool[i] = kmalloc(item_size, GFP_KERNEL);
+ if (q->pool[i] == NULL) {
+ int j;
+
+ for (j = 0; j < i; j++)
+ kfree(q->pool[j]);
+
+ kfifo_free(q->queue);
+ kfree(q->pool);
+ kfree(*items);
+ return -ENOMEM;
+ }
+ memset(q->pool[i], 0, item_size);
+ (*items)[i] = q->pool[i];
+ __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*));
+ }
+ return 0;
+}
+
+static void
+iscsi_pool_free(struct iscsi_queue *q, void **items)
+{
+ int i;
+
+ for (i = 0; i < q->max; i++)
+ kfree(items[i]);
+ kfree(q->pool);
+ kfree(items);
+}
+
static struct iscsi_cls_conn *
-iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
+iscsi_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
{
+ struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+ struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
struct iscsi_conn *conn;
struct iscsi_cls_conn *cls_conn;
- struct iscsi_tcp_conn *tcp_conn;
- cls_conn = iscsi_conn_setup(cls_session, conn_idx);
+ cls_conn = iscsi_create_conn(cls_session, conn_idx);
if (!cls_conn)
return NULL;
conn = cls_conn->dd_data;
- /*
- * due to strange issues with iser these are not set
- * in iscsi_conn_setup
- */
- conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
+ memset(conn, 0, sizeof(*conn));
- tcp_conn = kzalloc(sizeof(*tcp_conn), GFP_KERNEL);
- if (!tcp_conn)
- goto tcp_conn_alloc_fail;
+ conn->cls_conn = cls_conn;
+ conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
+ conn->in_progress = IN_PROGRESS_WAIT_HEADER;
+ conn->id = conn_idx;
+ conn->exp_statsn = 0;
+ conn->tmabort_state = TMABORT_INITIAL;
- conn->dd_data = tcp_conn;
- tcp_conn->iscsi_conn = conn;
- tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
/* initial operational parameters */
- tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
- tcp_conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
+ conn->hdr_size = sizeof(struct iscsi_hdr);
+ conn->data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
+ conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
+
+ /* initialize general xmit PDU commands queue */
+ conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*),
+ GFP_KERNEL, NULL);
+ if (conn->xmitqueue == ERR_PTR(-ENOMEM))
+ goto xmitqueue_alloc_fail;
+
+ /* initialize write response PDU commands queue */
+ conn->writequeue = kfifo_alloc(session->cmds_max * sizeof(void*),
+ GFP_KERNEL, NULL);
+ if (conn->writequeue == ERR_PTR(-ENOMEM))
+ goto writequeue_alloc_fail;
+
+ /* initialize general immediate & non-immediate PDU commands queue */
+ conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*),
+ GFP_KERNEL, NULL);
+ if (conn->immqueue == ERR_PTR(-ENOMEM))
+ goto immqueue_alloc_fail;
+
+ conn->mgmtqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*),
+ GFP_KERNEL, NULL);
+ if (conn->mgmtqueue == ERR_PTR(-ENOMEM))
+ goto mgmtqueue_alloc_fail;
+
+ INIT_WORK(&conn->xmitwork, iscsi_xmitworker, conn);
+
+ /* allocate login_mtask used for the login/text sequences */
+ spin_lock_bh(&session->lock);
+ if (!__kfifo_get(session->mgmtpool.queue,
+ (void*)&conn->login_mtask,
+ sizeof(void*))) {
+ spin_unlock_bh(&session->lock);
+ goto login_mtask_alloc_fail;
+ }
+ spin_unlock_bh(&session->lock);
/* allocate initial PDU receive place holder */
- if (tcp_conn->data_size <= PAGE_SIZE)
- tcp_conn->data = kmalloc(tcp_conn->data_size, GFP_KERNEL);
+ if (conn->data_size <= PAGE_SIZE)
+ conn->data = kmalloc(conn->data_size, GFP_KERNEL);
else
- tcp_conn->data = (void*)__get_free_pages(GFP_KERNEL,
- get_order(tcp_conn->data_size));
- if (!tcp_conn->data)
+ conn->data = (void*)__get_free_pages(GFP_KERNEL,
+ get_order(conn->data_size));
+ if (!conn->data)
goto max_recv_dlenght_alloc_fail;
+ init_timer(&conn->tmabort_timer);
+ mutex_init(&conn->xmitmutex);
+ init_waitqueue_head(&conn->ehwait);
+
return cls_conn;
max_recv_dlenght_alloc_fail:
- kfree(tcp_conn);
-tcp_conn_alloc_fail:
- iscsi_conn_teardown(cls_conn);
+ spin_lock_bh(&session->lock);
+ __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
+ sizeof(void*));
+ spin_unlock_bh(&session->lock);
+login_mtask_alloc_fail:
+ kfifo_free(conn->mgmtqueue);
+mgmtqueue_alloc_fail:
+ kfifo_free(conn->immqueue);
+immqueue_alloc_fail:
+ kfifo_free(conn->writequeue);
+writequeue_alloc_fail:
+ kfifo_free(conn->xmitqueue);
+xmitqueue_alloc_fail:
+ iscsi_destroy_conn(cls_conn);
return NULL;
}
static void
-iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)
+iscsi_conn_destroy(struct iscsi_cls_conn *cls_conn)
{
struct iscsi_conn *conn = cls_conn->dd_data;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- int digest = 0;
+ struct iscsi_session *session = conn->session;
+ unsigned long flags;
+
+ mutex_lock(&conn->xmitmutex);
+ set_bit(SUSPEND_BIT, &conn->suspend_tx);
+ if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE && conn->sock) {
+ struct sock *sk = conn->sock->sk;
+
+ /*
+ * conn_start() has never been called!
+ * need to cleanup the socket.
+ */
+ write_lock_bh(&sk->sk_callback_lock);
+ set_bit(SUSPEND_BIT, &conn->suspend_rx);
+ write_unlock_bh(&sk->sk_callback_lock);
+
+ sock_hold(conn->sock->sk);
+ iscsi_conn_restore_callbacks(conn);
+ sock_put(conn->sock->sk);
+ sock_release(conn->sock);
+ conn->sock = NULL;
+ }
- if (conn->hdrdgst_en || conn->datadgst_en)
- digest = 1;
+ spin_lock_bh(&session->lock);
+ conn->c_stage = ISCSI_CONN_CLEANUP_WAIT;
+ if (session->leadconn == conn) {
+ /*
+ * leading connection? then give up on recovery.
+ */
+ session->state = ISCSI_STATE_TERMINATE;
+ wake_up(&conn->ehwait);
+ }
+ spin_unlock_bh(&session->lock);
+
+ mutex_unlock(&conn->xmitmutex);
- iscsi_conn_teardown(cls_conn);
+ /*
+ * Block until all in-progress commands for this connection
+ * time out or fail.
+ */
+ for (;;) {
+ spin_lock_irqsave(session->host->host_lock, flags);
+ if (!session->host->host_busy) { /* OK for ERL == 0 */
+ spin_unlock_irqrestore(session->host->host_lock, flags);
+ break;
+ }
+ spin_unlock_irqrestore(session->host->host_lock, flags);
+ msleep_interruptible(500);
+ printk("conn_destroy(): host_busy %d host_failed %d\n",
+ session->host->host_busy, session->host->host_failed);
+ /*
+ * force eh_abort() to unblock
+ */
+ wake_up(&conn->ehwait);
+ }
- /* now free tcp_conn */
- if (digest) {
- if (tcp_conn->tx_tfm)
- crypto_free_tfm(tcp_conn->tx_tfm);
- if (tcp_conn->rx_tfm)
- crypto_free_tfm(tcp_conn->rx_tfm);
- if (tcp_conn->data_tx_tfm)
- crypto_free_tfm(tcp_conn->data_tx_tfm);
- if (tcp_conn->data_rx_tfm)
- crypto_free_tfm(tcp_conn->data_rx_tfm);
+ /* now free crypto */
+ if (conn->hdrdgst_en || conn->datadgst_en) {
+ if (conn->tx_tfm)
+ crypto_free_tfm(conn->tx_tfm);
+ if (conn->rx_tfm)
+ crypto_free_tfm(conn->rx_tfm);
+ if (conn->data_tx_tfm)
+ crypto_free_tfm(conn->data_tx_tfm);
+ if (conn->data_rx_tfm)
+ crypto_free_tfm(conn->data_rx_tfm);
}
/* free conn->data, size = MaxRecvDataSegmentLength */
- if (tcp_conn->data_size <= PAGE_SIZE)
- kfree(tcp_conn->data);
+ if (conn->data_size <= PAGE_SIZE)
+ kfree(conn->data);
else
- free_pages((unsigned long)tcp_conn->data,
- get_order(tcp_conn->data_size));
- kfree(tcp_conn);
+ free_pages((unsigned long)conn->data,
+ get_order(conn->data_size));
+
+ spin_lock_bh(&session->lock);
+ __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
+ sizeof(void*));
+ list_del(&conn->item);
+ if (list_empty(&session->connections))
+ session->leadconn = NULL;
+ if (session->leadconn && session->leadconn == conn)
+ session->leadconn = container_of(session->connections.next,
+ struct iscsi_conn, item);
+
+ if (session->leadconn == NULL)
+ /* none connections exits.. reset sequencing */
+ session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1;
+ spin_unlock_bh(&session->lock);
+
+ kfifo_free(conn->xmitqueue);
+ kfifo_free(conn->writequeue);
+ kfifo_free(conn->immqueue);
+ kfifo_free(conn->mgmtqueue);
+
+ iscsi_destroy_conn(cls_conn);
}
static int
-iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
- struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
- int is_leading)
+iscsi_conn_bind(struct iscsi_cls_session *cls_session,
+ struct iscsi_cls_conn *cls_conn, uint32_t transport_fd,
+ int is_leading)
{
- struct iscsi_conn *conn = cls_conn->dd_data;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+ struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
+ struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data;
struct sock *sk;
struct socket *sock;
int err;
/* lookup for existing socket */
- sock = sockfd_lookup((int)transport_eph, &err);
+ sock = sockfd_lookup(transport_fd, &err);
if (!sock) {
printk(KERN_ERR "iscsi_tcp: sockfd_lookup failed %d\n", err);
return -EEXIST;
}
- err = iscsi_conn_bind(cls_session, cls_conn, is_leading);
- if (err)
- return err;
+ /* lookup for existing connection */
+ spin_lock_bh(&session->lock);
+ list_for_each_entry(tmp, &session->connections, item) {
+ if (tmp == conn) {
+ if (conn->c_stage != ISCSI_CONN_STOPPED ||
+ conn->stop_stage == STOP_CONN_TERM) {
+ printk(KERN_ERR "iscsi_tcp: can't bind "
+ "non-stopped connection (%d:%d)\n",
+ conn->c_stage, conn->stop_stage);
+ spin_unlock_bh(&session->lock);
+ return -EIO;
+ }
+ break;
+ }
+ }
+ if (tmp != conn) {
+ /* bind new iSCSI connection to session */
+ conn->session = session;
+
+ list_add(&conn->item, &session->connections);
+ }
+ spin_unlock_bh(&session->lock);
- /* bind iSCSI connection and socket */
- tcp_conn->sock = sock;
+ if (conn->stop_stage != STOP_CONN_SUSPEND) {
+ /* bind iSCSI connection and socket */
+ conn->sock = sock;
- /* setup Socket parameters */
- sk = sock->sk;
- sk->sk_reuse = 1;
- sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */
- sk->sk_allocation = GFP_ATOMIC;
+ /* setup Socket parameters */
+ sk = sock->sk;
+ sk->sk_reuse = 1;
+ sk->sk_sndtimeo = 15 * HZ; /* FIXME: make it configurable */
+ sk->sk_allocation = GFP_ATOMIC;
- /* FIXME: disable Nagle's algorithm */
+ /* FIXME: disable Nagle's algorithm */
+
+ /*
+ * Intercept TCP callbacks for sendfile like receive
+ * processing.
+ */
+ iscsi_conn_set_callbacks(conn);
+
+ conn->sendpage = conn->sock->ops->sendpage;
+
+ /*
+ * set receive state machine into initial state
+ */
+ conn->in_progress = IN_PROGRESS_WAIT_HEADER;
+ }
+
+ if (is_leading)
+ session->leadconn = conn;
/*
- * Intercept TCP callbacks for sendfile like receive
- * processing.
- */
- conn->recv_lock = &sk->sk_callback_lock;
- iscsi_conn_set_callbacks(conn);
- tcp_conn->sendpage = tcp_conn->sock->ops->sendpage;
- /*
- * set receive state machine into initial state
+ * Unblock xmitworker(), Login Phase will pass through.
*/
- tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
+ clear_bit(SUSPEND_BIT, &conn->suspend_rx);
+ clear_bit(SUSPEND_BIT, &conn->suspend_tx);
return 0;
}
-static void
-iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+static int
+iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
{
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
- struct iscsi_r2t_info *r2t;
+ struct iscsi_conn *conn = cls_conn->dd_data;
+ struct iscsi_session *session = conn->session;
+ struct sock *sk;
- /* flush ctask's r2t queues */
- while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)))
- __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
- sizeof(void*));
+ /* FF phase warming up... */
- __iscsi_ctask_cleanup(conn, ctask);
+ if (session == NULL) {
+ printk(KERN_ERR "iscsi_tcp: can't start unbound connection\n");
+ return -EPERM;
+ }
+
+ sk = conn->sock->sk;
+
+ write_lock_bh(&sk->sk_callback_lock);
+ spin_lock_bh(&session->lock);
+ conn->c_stage = ISCSI_CONN_STARTED;
+ session->state = ISCSI_STATE_LOGGED_IN;
+
+ switch(conn->stop_stage) {
+ case STOP_CONN_RECOVER:
+ /*
+ * unblock eh_abort() if it is blocked. re-try all
+ * commands after successful recovery
+ */
+ session->conn_cnt++;
+ conn->stop_stage = 0;
+ conn->tmabort_state = TMABORT_INITIAL;
+ session->age++;
+ wake_up(&conn->ehwait);
+ break;
+ case STOP_CONN_TERM:
+ session->conn_cnt++;
+ conn->stop_stage = 0;
+ break;
+ case STOP_CONN_SUSPEND:
+ conn->stop_stage = 0;
+ clear_bit(SUSPEND_BIT, &conn->suspend_rx);
+ clear_bit(SUSPEND_BIT, &conn->suspend_tx);
+ break;
+ default:
+ break;
+ }
+ spin_unlock_bh(&session->lock);
+ write_unlock_bh(&sk->sk_callback_lock);
+
+ return 0;
}
static void
-iscsi_tcp_suspend_conn_rx(struct iscsi_conn *conn)
+iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
{
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ struct iscsi_conn *conn = cls_conn->dd_data;
+ struct iscsi_session *session = conn->session;
struct sock *sk;
+ unsigned long flags;
- if (!tcp_conn->sock)
- return;
-
- sk = tcp_conn->sock->sk;
+ BUG_ON(!conn->sock);
+ sk = conn->sock->sk;
write_lock_bh(&sk->sk_callback_lock);
- set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
+ set_bit(SUSPEND_BIT, &conn->suspend_rx);
write_unlock_bh(&sk->sk_callback_lock);
+
+ mutex_lock(&conn->xmitmutex);
+
+ spin_lock_irqsave(session->host->host_lock, flags);
+ spin_lock(&session->lock);
+ conn->stop_stage = flag;
+ conn->c_stage = ISCSI_CONN_STOPPED;
+ set_bit(SUSPEND_BIT, &conn->suspend_tx);
+
+ if (flag != STOP_CONN_SUSPEND)
+ session->conn_cnt--;
+
+ if (session->conn_cnt == 0 || session->leadconn == conn)
+ session->state = ISCSI_STATE_FAILED;
+
+ spin_unlock(&session->lock);
+ spin_unlock_irqrestore(session->host->host_lock, flags);
+
+ if (flag == STOP_CONN_TERM || flag == STOP_CONN_RECOVER) {
+ struct iscsi_cmd_task *ctask;
+ struct iscsi_mgmt_task *mtask;
+
+ /*
+ * Socket must go now.
+ */
+ sock_hold(conn->sock->sk);
+ iscsi_conn_restore_callbacks(conn);
+ sock_put(conn->sock->sk);
+
+ /*
+ * flush xmit queues.
+ */
+ spin_lock_bh(&session->lock);
+ while (__kfifo_get(conn->writequeue, (void*)&ctask,
+ sizeof(void*)) ||
+ __kfifo_get(conn->xmitqueue, (void*)&ctask,
+ sizeof(void*))) {
+ struct iscsi_r2t_info *r2t;
+
+ /*
+ * flush ctask's r2t queues
+ */
+ while (__kfifo_get(ctask->r2tqueue, (void*)&r2t,
+ sizeof(void*)))
+ __kfifo_put(ctask->r2tpool.queue, (void*)&r2t,
+ sizeof(void*));
+
+ spin_unlock_bh(&session->lock);
+ local_bh_disable();
+ iscsi_ctask_cleanup(conn, ctask);
+ local_bh_enable();
+ spin_lock_bh(&session->lock);
+ }
+ conn->ctask = NULL;
+ while (__kfifo_get(conn->immqueue, (void*)&mtask,
+ sizeof(void*)) ||
+ __kfifo_get(conn->mgmtqueue, (void*)&mtask,
+ sizeof(void*))) {
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&mtask, sizeof(void*));
+ }
+ conn->mtask = NULL;
+ spin_unlock_bh(&session->lock);
+
+ /*
+ * release socket only after we stopped data_xmit()
+ * activity and flushed all outstandings
+ */
+ sock_release(conn->sock);
+ conn->sock = NULL;
+
+ /*
+ * for connection level recovery we should not calculate
+ * header digest. conn->hdr_size used for optimization
+ * in hdr_extract() and will be re-negotiated at
+ * set_param() time.
+ */
+ if (flag == STOP_CONN_RECOVER) {
+ conn->hdr_size = sizeof(struct iscsi_hdr);
+ conn->hdrdgst_en = 0;
+ conn->datadgst_en = 0;
+ }
+ }
+ mutex_unlock(&conn->xmitmutex);
}
-static void
-iscsi_tcp_terminate_conn(struct iscsi_conn *conn)
+static int
+iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+ char *data, uint32_t data_size)
{
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ struct iscsi_session *session = conn->session;
+ struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr;
+ struct iscsi_mgmt_task *mtask;
- if (!tcp_conn->sock)
- return;
+ spin_lock_bh(&session->lock);
+ if (session->state == ISCSI_STATE_TERMINATE) {
+ spin_unlock_bh(&session->lock);
+ return -EPERM;
+ }
+ if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) ||
+ hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
+ /*
+ * Login and Text are sent serially, in
+ * request-followed-by-response sequence.
+ * Same mtask can be used. Same ITT must be used.
+ * Note that login_mtask is preallocated at conn_create().
+ */
+ mtask = conn->login_mtask;
+ else {
+ BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
+ BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
+
+ if (!__kfifo_get(session->mgmtpool.queue,
+ (void*)&mtask, sizeof(void*))) {
+ spin_unlock_bh(&session->lock);
+ return -ENOSPC;
+ }
+ }
+
+ /*
+ * pre-format CmdSN and ExpStatSN for outgoing PDU.
+ */
+ if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) {
+ hdr->itt = mtask->itt | (conn->id << CID_SHIFT) |
+ (session->age << AGE_SHIFT);
+ nop->cmdsn = cpu_to_be32(session->cmdsn);
+ if (conn->c_stage == ISCSI_CONN_STARTED &&
+ !(hdr->opcode & ISCSI_OP_IMMEDIATE))
+ session->cmdsn++;
+ } else
+ /* do not advance CmdSN */
+ nop->cmdsn = cpu_to_be32(session->cmdsn);
+
+ nop->exp_statsn = cpu_to_be32(conn->exp_statsn);
+
+ memcpy(&mtask->hdr, hdr, sizeof(struct iscsi_hdr));
+
+ iscsi_buf_init_virt(&mtask->headbuf, (char*)&mtask->hdr,
+ sizeof(struct iscsi_hdr));
+
+ spin_unlock_bh(&session->lock);
+
+ if (data_size) {
+ memcpy(mtask->data, data, data_size);
+ mtask->data_count = data_size;
+ } else
+ mtask->data_count = 0;
+
+ mtask->xmstate = XMSTATE_IMM_HDR;
+
+ if (mtask->data_count) {
+ iscsi_buf_init_iov(&mtask->sendbuf, (char*)mtask->data,
+ mtask->data_count);
+ }
+
+ debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n",
+ hdr->opcode, hdr->itt, data_size);
- sock_hold(tcp_conn->sock->sk);
- iscsi_conn_restore_callbacks(conn);
- sock_put(tcp_conn->sock->sk);
+ /*
+ * since send_pdu() could be called at least from two contexts,
+ * we need to serialize __kfifo_put, so we don't have to take
+ * additional lock on fast data-path
+ */
+ if (hdr->opcode & ISCSI_OP_IMMEDIATE)
+ __kfifo_put(conn->immqueue, (void*)&mtask, sizeof(void*));
+ else
+ __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*));
- sock_release(tcp_conn->sock);
- tcp_conn->sock = NULL;
- conn->recv_lock = NULL;
+ scsi_queue_work(session->host, &conn->xmitwork);
+ return 0;
+}
+
+static int
+iscsi_eh_host_reset(struct scsi_cmnd *sc)
+{
+ struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
+ struct iscsi_conn *conn = ctask->conn;
+ struct iscsi_session *session = conn->session;
+
+ spin_lock_bh(&session->lock);
+ if (session->state == ISCSI_STATE_TERMINATE) {
+ debug_scsi("failing host reset: session terminated "
+ "[CID %d age %d]", conn->id, session->age);
+ spin_unlock_bh(&session->lock);
+ return FAILED;
+ }
+ spin_unlock_bh(&session->lock);
+
+ debug_scsi("failing connection CID %d due to SCSI host reset "
+ "[itt 0x%x age %d]", conn->id, ctask->itt,
+ session->age);
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+
+ return SUCCESS;
}
-/* called with host lock */
static void
-iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask,
- char *data, uint32_t data_size)
+iscsi_tmabort_timedout(unsigned long data)
{
- struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
+ struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)data;
+ struct iscsi_conn *conn = ctask->conn;
+ struct iscsi_session *session = conn->session;
- iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr,
- sizeof(struct iscsi_hdr));
- tcp_mtask->xmstate = XMSTATE_IMM_HDR;
+ spin_lock(&session->lock);
+ if (conn->tmabort_state == TMABORT_INITIAL) {
+ __kfifo_put(session->mgmtpool.queue,
+ (void*)&ctask->mtask, sizeof(void*));
+ conn->tmabort_state = TMABORT_TIMEDOUT;
+ debug_scsi("tmabort timedout [sc %lx itt 0x%x]\n",
+ (long)ctask->sc, ctask->itt);
+ /* unblock eh_abort() */
+ wake_up(&conn->ehwait);
+ }
+ spin_unlock(&session->lock);
+}
- if (mtask->data_count)
- iscsi_buf_init_iov(&tcp_mtask->sendbuf, (char*)mtask->data,
- mtask->data_count);
+static int
+iscsi_eh_abort(struct scsi_cmnd *sc)
+{
+ int rc;
+ struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
+ struct iscsi_conn *conn = ctask->conn;
+ struct iscsi_session *session = conn->session;
+
+ conn->eh_abort_cnt++;
+ debug_scsi("aborting [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
+
+ /*
+ * two cases for ERL=0 here:
+ *
+ * 1) connection-level failure;
+ * 2) recovery due protocol error;
+ */
+ mutex_lock(&conn->xmitmutex);
+ spin_lock_bh(&session->lock);
+ if (session->state != ISCSI_STATE_LOGGED_IN) {
+ if (session->state == ISCSI_STATE_TERMINATE) {
+ spin_unlock_bh(&session->lock);
+ mutex_unlock(&conn->xmitmutex);
+ goto failed;
+ }
+ spin_unlock_bh(&session->lock);
+ } else {
+ struct iscsi_tm *hdr = &conn->tmhdr;
+
+ /*
+ * Still LOGGED_IN...
+ */
+
+ if (!ctask->sc || sc->SCp.phase != session->age) {
+ /*
+ * 1) ctask completed before time out. But session
+ * is still ok => Happy Retry.
+ * 2) session was re-open during time out of ctask.
+ */
+ spin_unlock_bh(&session->lock);
+ mutex_unlock(&conn->xmitmutex);
+ goto success;
+ }
+ conn->tmabort_state = TMABORT_INITIAL;
+ spin_unlock_bh(&session->lock);
+
+ /*
+ * ctask timed out but session is OK
+ * ERL=0 requires task mgmt abort to be issued on each
+ * failed command. requests must be serialized.
+ */
+ memset(hdr, 0, sizeof(struct iscsi_tm));
+ hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
+ hdr->flags = ISCSI_TM_FUNC_ABORT_TASK;
+ hdr->flags |= ISCSI_FLAG_CMD_FINAL;
+ memcpy(hdr->lun, ctask->hdr.lun, sizeof(hdr->lun));
+ hdr->rtt = ctask->hdr.itt;
+ hdr->refcmdsn = ctask->hdr.cmdsn;
+
+ rc = iscsi_conn_send_generic(conn, (struct iscsi_hdr *)hdr,
+ NULL, 0);
+ if (rc) {
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ debug_scsi("abort sent failure [itt 0x%x]", ctask->itt);
+ } else {
+ struct iscsi_r2t_info *r2t;
+
+ /*
+ * TMF abort vs. TMF response race logic
+ */
+ spin_lock_bh(&session->lock);
+ ctask->mtask = (struct iscsi_mgmt_task *)
+ session->mgmt_cmds[(hdr->itt & ITT_MASK) -
+ ISCSI_MGMT_ITT_OFFSET];
+ /*
+ * have to flush r2tqueue to avoid r2t leaks
+ */
+ while (__kfifo_get(ctask->r2tqueue, (void*)&r2t,
+ sizeof(void*))) {
+ __kfifo_put(ctask->r2tpool.queue, (void*)&r2t,
+ sizeof(void*));
+ }
+ if (conn->tmabort_state == TMABORT_INITIAL) {
+ conn->tmfcmd_pdus_cnt++;
+ conn->tmabort_timer.expires = 3*HZ + jiffies;
+ conn->tmabort_timer.function =
+ iscsi_tmabort_timedout;
+ conn->tmabort_timer.data = (unsigned long)ctask;
+ add_timer(&conn->tmabort_timer);
+ debug_scsi("abort sent [itt 0x%x]", ctask->itt);
+ } else {
+ if (!ctask->sc ||
+ conn->tmabort_state == TMABORT_SUCCESS) {
+ conn->tmabort_state = TMABORT_INITIAL;
+ spin_unlock_bh(&session->lock);
+ mutex_unlock(&conn->xmitmutex);
+ goto success;
+ }
+ conn->tmabort_state = TMABORT_INITIAL;
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ }
+ spin_unlock_bh(&session->lock);
+ }
+ }
+ mutex_unlock(&conn->xmitmutex);
+
+
+ /*
+ * block eh thread until:
+ *
+ * 1) abort response;
+ * 2) abort timeout;
+ * 3) session re-opened;
+ * 4) session terminated;
+ */
+ for (;;) {
+ int p_state = session->state;
+
+ rc = wait_event_interruptible(conn->ehwait,
+ (p_state == ISCSI_STATE_LOGGED_IN ?
+ (session->state == ISCSI_STATE_TERMINATE ||
+ conn->tmabort_state != TMABORT_INITIAL) :
+ (session->state == ISCSI_STATE_TERMINATE ||
+ session->state == ISCSI_STATE_LOGGED_IN)));
+ if (rc) {
+ /* shutdown.. */
+ session->state = ISCSI_STATE_TERMINATE;
+ goto failed;
+ }
+
+ if (signal_pending(current))
+ flush_signals(current);
+
+ if (session->state == ISCSI_STATE_TERMINATE)
+ goto failed;
+
+ spin_lock_bh(&session->lock);
+ if (sc->SCp.phase == session->age &&
+ (conn->tmabort_state == TMABORT_TIMEDOUT ||
+ conn->tmabort_state == TMABORT_FAILED)) {
+ conn->tmabort_state = TMABORT_INITIAL;
+ if (!ctask->sc) {
+ /*
+ * ctask completed before tmf abort response or
+ * time out.
+ * But session is still ok => Happy Retry.
+ */
+ spin_unlock_bh(&session->lock);
+ break;
+ }
+ spin_unlock_bh(&session->lock);
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ continue;
+ }
+ spin_unlock_bh(&session->lock);
+ break;
+ }
+
+success:
+ debug_scsi("abort success [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
+ rc = SUCCESS;
+ goto exit;
+
+failed:
+ debug_scsi("abort failed [sc %lx itt 0x%x]\n", (long)sc, ctask->itt);
+ rc = FAILED;
+
+exit:
+ del_timer_sync(&conn->tmabort_timer);
+
+ mutex_lock(&conn->xmitmutex);
+ if (conn->sock) {
+ struct sock *sk = conn->sock->sk;
+
+ write_lock_bh(&sk->sk_callback_lock);
+ iscsi_ctask_cleanup(conn, ctask);
+ write_unlock_bh(&sk->sk_callback_lock);
+ }
+ mutex_unlock(&conn->xmitmutex);
+ return rc;
}
static int
*/
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
*/
/* R2T pool */
- if (iscsi_pool_init(&tcp_ctask->r2tpool, session->max_r2t * 4,
- (void***)&tcp_ctask->r2ts,
- sizeof(struct iscsi_r2t_info))) {
+ if (iscsi_pool_init(&ctask->r2tpool, session->max_r2t * 4,
+ (void***)&ctask->r2ts, sizeof(struct iscsi_r2t_info))) {
goto r2t_alloc_fail;
}
/* R2T xmit queue */
- tcp_ctask->r2tqueue = kfifo_alloc(
+ ctask->r2tqueue = kfifo_alloc(
session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL);
- if (tcp_ctask->r2tqueue == ERR_PTR(-ENOMEM)) {
- iscsi_pool_free(&tcp_ctask->r2tpool,
- (void**)tcp_ctask->r2ts);
+ if (ctask->r2tqueue == ERR_PTR(-ENOMEM)) {
+ iscsi_pool_free(&ctask->r2tpool, (void**)ctask->r2ts);
goto r2t_alloc_fail;
}
+
+ /*
+ * number of
+ * Data-Out PDU's within R2T-sequence can be quite big;
+ * using mempool
+ */
+ ctask->datapool = mempool_create_slab_pool(ISCSI_DTASK_DEFAULT_MAX,
+ taskcache);
+ if (ctask->datapool == NULL) {
+ kfifo_free(ctask->r2tqueue);
+ iscsi_pool_free(&ctask->r2tpool, (void**)ctask->r2ts);
+ goto r2t_alloc_fail;
+ }
+ INIT_LIST_HEAD(&ctask->dataqueue);
}
return 0;
r2t_alloc_fail:
for (i = 0; i < cmd_i; i++) {
- struct iscsi_cmd_task *ctask = session->cmds[i];
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
-
- kfifo_free(tcp_ctask->r2tqueue);
- iscsi_pool_free(&tcp_ctask->r2tpool,
- (void**)tcp_ctask->r2ts);
+ mempool_destroy(session->cmds[i]->datapool);
+ kfifo_free(session->cmds[i]->r2tqueue);
+ iscsi_pool_free(&session->cmds[i]->r2tpool,
+ (void**)session->cmds[i]->r2ts);
}
return -ENOMEM;
}
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
{
struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_session *session = conn->session;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+
+ spin_lock_bh(&session->lock);
+ if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE &&
+ conn->stop_stage != STOP_CONN_RECOVER) {
+ printk(KERN_ERR "iscsi_tcp: can not change parameter [%d]\n",
+ param);
+ spin_unlock_bh(&session->lock);
+ return 0;
+ }
+ spin_unlock_bh(&session->lock);
switch(param) {
case ISCSI_PARAM_MAX_RECV_DLENGTH: {
- char *saveptr = tcp_conn->data;
+ char *saveptr = conn->data;
gfp_t flags = GFP_KERNEL;
- if (tcp_conn->data_size >= value) {
+ if (conn->data_size >= value) {
conn->max_recv_dlength = value;
break;
}
spin_unlock_bh(&session->lock);
if (value <= PAGE_SIZE)
- tcp_conn->data = kmalloc(value, flags);
+ conn->data = kmalloc(value, flags);
else
- tcp_conn->data = (void*)__get_free_pages(flags,
+ conn->data = (void*)__get_free_pages(flags,
get_order(value));
- if (tcp_conn->data == NULL) {
- tcp_conn->data = saveptr;
+ if (conn->data == NULL) {
+ conn->data = saveptr;
return -ENOMEM;
}
- if (tcp_conn->data_size <= PAGE_SIZE)
+ if (conn->data_size <= PAGE_SIZE)
kfree(saveptr);
else
free_pages((unsigned long)saveptr,
- get_order(tcp_conn->data_size));
+ get_order(conn->data_size));
conn->max_recv_dlength = value;
- tcp_conn->data_size = value;
+ conn->data_size = value;
}
break;
case ISCSI_PARAM_MAX_XMIT_DLENGTH:
break;
case ISCSI_PARAM_HDRDGST_EN:
conn->hdrdgst_en = value;
- tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
+ conn->hdr_size = sizeof(struct iscsi_hdr);
if (conn->hdrdgst_en) {
- tcp_conn->hdr_size += sizeof(__u32);
- if (!tcp_conn->tx_tfm)
- tcp_conn->tx_tfm = crypto_alloc_tfm("crc32c",
- 0);
- if (!tcp_conn->tx_tfm)
+ conn->hdr_size += sizeof(__u32);
+ if (!conn->tx_tfm)
+ conn->tx_tfm = crypto_alloc_tfm("crc32c", 0);
+ if (!conn->tx_tfm)
return -ENOMEM;
- if (!tcp_conn->rx_tfm)
- tcp_conn->rx_tfm = crypto_alloc_tfm("crc32c",
- 0);
- if (!tcp_conn->rx_tfm) {
- crypto_free_tfm(tcp_conn->tx_tfm);
+ if (!conn->rx_tfm)
+ conn->rx_tfm = crypto_alloc_tfm("crc32c", 0);
+ if (!conn->rx_tfm) {
+ crypto_free_tfm(conn->tx_tfm);
return -ENOMEM;
}
} else {
- if (tcp_conn->tx_tfm)
- crypto_free_tfm(tcp_conn->tx_tfm);
- if (tcp_conn->rx_tfm)
- crypto_free_tfm(tcp_conn->rx_tfm);
+ if (conn->tx_tfm)
+ crypto_free_tfm(conn->tx_tfm);
+ if (conn->rx_tfm)
+ crypto_free_tfm(conn->rx_tfm);
}
break;
case ISCSI_PARAM_DATADGST_EN:
conn->datadgst_en = value;
if (conn->datadgst_en) {
- if (!tcp_conn->data_tx_tfm)
- tcp_conn->data_tx_tfm =
+ if (!conn->data_tx_tfm)
+ conn->data_tx_tfm =
crypto_alloc_tfm("crc32c", 0);
- if (!tcp_conn->data_tx_tfm)
+ if (!conn->data_tx_tfm)
return -ENOMEM;
- if (!tcp_conn->data_rx_tfm)
- tcp_conn->data_rx_tfm =
+ if (!conn->data_rx_tfm)
+ conn->data_rx_tfm =
crypto_alloc_tfm("crc32c", 0);
- if (!tcp_conn->data_rx_tfm) {
- crypto_free_tfm(tcp_conn->data_tx_tfm);
+ if (!conn->data_rx_tfm) {
+ crypto_free_tfm(conn->data_tx_tfm);
return -ENOMEM;
}
} else {
- if (tcp_conn->data_tx_tfm)
- crypto_free_tfm(tcp_conn->data_tx_tfm);
- if (tcp_conn->data_rx_tfm)
- crypto_free_tfm(tcp_conn->data_rx_tfm);
+ if (conn->data_tx_tfm)
+ crypto_free_tfm(conn->data_tx_tfm);
+ if (conn->data_rx_tfm)
+ crypto_free_tfm(conn->data_rx_tfm);
}
- tcp_conn->sendpage = conn->datadgst_en ?
- sock_no_sendpage : tcp_conn->sock->ops->sendpage;
+ conn->sendpage = conn->datadgst_en ?
+ sock_no_sendpage : conn->sock->ops->sendpage;
break;
case ISCSI_PARAM_INITIAL_R2T_EN:
session->initial_r2t_en = value;
BUG_ON(value);
session->ofmarker_en = value;
break;
- case ISCSI_PARAM_EXP_STATSN:
- conn->exp_statsn = value;
- break;
default:
break;
}
*value = session->ofmarker_en;
break;
default:
- return -EINVAL;
+ return ISCSI_ERR_PARAM_NOT_FOUND;
}
return 0;
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:
case ISCSI_PARAM_DATADGST_EN:
*value = conn->datadgst_en;
break;
- case ISCSI_PARAM_CONN_PORT:
- mutex_lock(&conn->xmitmutex);
- if (!tcp_conn->sock) {
- mutex_unlock(&conn->xmitmutex);
- return -EINVAL;
- }
-
- inet = inet_sk(tcp_conn->sock->sk);
- *value = be16_to_cpu(inet->dport);
- mutex_unlock(&conn->xmitmutex);
- case ISCSI_PARAM_EXP_STATSN:
- *value = conn->exp_statsn;
- break;
default:
- return -EINVAL;
+ return ISCSI_ERR_PARAM_NOT_FOUND;
}
return 0;
}
-static int
-iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn,
- enum iscsi_param param, char *buf)
-{
- struct iscsi_conn *conn = cls_conn->dd_data;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
- struct sock *sk;
- struct inet_sock *inet;
- struct ipv6_pinfo *np;
- int len = 0;
-
- switch (param) {
- case ISCSI_PARAM_CONN_ADDRESS:
- mutex_lock(&conn->xmitmutex);
- if (!tcp_conn->sock) {
- mutex_unlock(&conn->xmitmutex);
- return -EINVAL;
- }
-
- sk = tcp_conn->sock->sk;
- if (sk->sk_family == PF_INET) {
- inet = inet_sk(sk);
- len = sprintf(buf, "%u.%u.%u.%u\n",
- NIPQUAD(inet->daddr));
- } else {
- np = inet6_sk(sk);
- len = sprintf(buf,
- "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
- NIP6(np->daddr));
- }
- mutex_unlock(&conn->xmitmutex);
- break;
- default:
- return -EINVAL;
- }
-
- return len;
-}
-
static void
iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
{
struct iscsi_conn *conn = cls_conn->dd_data;
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
stats->txdata_octets = conn->txdata_octets;
stats->rxdata_octets = conn->rxdata_octets;
stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
stats->custom_length = 3;
strcpy(stats->custom[0].desc, "tx_sendpage_failures");
- stats->custom[0].value = tcp_conn->sendpage_failures_cnt;
+ stats->custom[0].value = conn->sendpage_failures_cnt;
strcpy(stats->custom[1].desc, "rx_discontiguous_hdr");
- stats->custom[1].value = tcp_conn->discontiguous_hdr_cnt;
+ stats->custom[1].value = conn->discontiguous_hdr_cnt;
strcpy(stats->custom[2].desc, "eh_abort_cnt");
stats->custom[2].value = conn->eh_abort_cnt;
}
-static struct iscsi_cls_session *
-iscsi_tcp_session_create(struct iscsi_transport *iscsit,
- struct scsi_transport_template *scsit,
- uint32_t initial_cmdsn, uint32_t *hostno)
+static int
+iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr,
+ char *data, uint32_t data_size)
{
- struct iscsi_cls_session *cls_session;
- struct iscsi_session *session;
- uint32_t hn;
- int cmd_i;
-
- cls_session = iscsi_session_setup(iscsit, scsit,
- sizeof(struct iscsi_tcp_cmd_task),
- sizeof(struct iscsi_tcp_mgmt_task),
- initial_cmdsn, &hn);
- if (!cls_session)
- return NULL;
- *hostno = hn;
-
- session = class_to_transport_session(cls_session);
- for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
- struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
- struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
-
- ctask->hdr = &tcp_ctask->hdr;
- }
-
- for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) {
- struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i];
- struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
-
- mtask->hdr = &tcp_mtask->hdr;
- }
-
- if (iscsi_r2tpool_alloc(class_to_transport_session(cls_session)))
- goto r2tpool_alloc_fail;
-
- return cls_session;
+ struct iscsi_conn *conn = cls_conn->dd_data;
+ int rc;
-r2tpool_alloc_fail:
- iscsi_session_teardown(cls_session);
- return NULL;
-}
+ mutex_lock(&conn->xmitmutex);
+ rc = iscsi_conn_send_generic(conn, hdr, data, data_size);
+ mutex_unlock(&conn->xmitmutex);
-static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session)
-{
- iscsi_r2tpool_free(class_to_transport_session(cls_session));
- iscsi_session_teardown(cls_session);
+ return rc;
}
-static struct scsi_host_template iscsi_sht = {
- .name = "iSCSI Initiator over TCP/IP, v"
- ISCSI_TCP_VERSION,
- .queuecommand = iscsi_queuecommand,
- .change_queue_depth = iscsi_change_queue_depth,
- .can_queue = ISCSI_XMIT_CMDS_MAX - 1,
- .sg_tablesize = ISCSI_SG_TABLESIZE,
- .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
- .eh_abort_handler = iscsi_eh_abort,
- .eh_host_reset_handler = iscsi_eh_host_reset,
- .use_clustering = DISABLE_CLUSTERING,
- .proc_name = "iscsi_tcp",
- .this_id = -1,
-};
-
static struct iscsi_transport iscsi_tcp_transport = {
.owner = THIS_MODULE,
.name = "tcp",
.caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST
| CAP_DATADGST,
- .param_mask = ISCSI_MAX_RECV_DLENGTH |
- ISCSI_MAX_XMIT_DLENGTH |
- ISCSI_HDRDGST_EN |
- ISCSI_DATADGST_EN |
- ISCSI_INITIAL_R2T_EN |
- ISCSI_MAX_R2T |
- ISCSI_IMM_DATA_EN |
- ISCSI_FIRST_BURST |
- ISCSI_MAX_BURST |
- ISCSI_PDU_INORDER_EN |
- ISCSI_DATASEQ_INORDER_EN |
- ISCSI_ERL |
- ISCSI_CONN_PORT |
- ISCSI_CONN_ADDRESS |
- ISCSI_EXP_STATSN,
.host_template = &iscsi_sht,
+ .hostdata_size = sizeof(struct iscsi_session),
.conndata_size = sizeof(struct iscsi_conn),
.max_conn = 1,
.max_cmd_len = ISCSI_TCP_MAX_CMD_LEN,
- /* session management */
- .create_session = iscsi_tcp_session_create,
- .destroy_session = iscsi_tcp_session_destroy,
- /* connection management */
- .create_conn = iscsi_tcp_conn_create,
- .bind_conn = iscsi_tcp_conn_bind,
- .destroy_conn = iscsi_tcp_conn_destroy,
+ .create_session = iscsi_session_create,
+ .destroy_session = iscsi_session_destroy,
+ .create_conn = iscsi_conn_create,
+ .bind_conn = iscsi_conn_bind,
+ .destroy_conn = iscsi_conn_destroy,
.set_param = iscsi_conn_set_param,
.get_conn_param = iscsi_conn_get_param,
- .get_conn_str_param = iscsi_conn_get_str_param,
.get_session_param = iscsi_session_get_param,
.start_conn = iscsi_conn_start,
.stop_conn = iscsi_conn_stop,
- /* these are called as part of conn recovery */
- .suspend_conn_recv = iscsi_tcp_suspend_conn_rx,
- .terminate_conn = iscsi_tcp_terminate_conn,
- /* IO */
.send_pdu = iscsi_conn_send_pdu,
.get_stats = iscsi_conn_get_stats,
- .init_cmd_task = iscsi_tcp_cmd_init,
- .init_mgmt_task = iscsi_tcp_mgmt_init,
- .xmit_cmd_task = iscsi_tcp_ctask_xmit,
- .xmit_mgmt_task = iscsi_tcp_mtask_xmit,
- .cleanup_cmd_task = iscsi_tcp_cleanup_ctask,
- /* recovery */
- .session_recovery_timedout = iscsi_session_recovery_timedout,
};
static int __init
iscsi_tcp_init(void)
{
if (iscsi_max_lun < 1) {
- printk(KERN_ERR "iscsi_tcp: Invalid max_lun value of %u\n",
- iscsi_max_lun);
+ printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun);
return -EINVAL;
}
iscsi_tcp_transport.max_lun = iscsi_max_lun;
+ taskcache = kmem_cache_create("iscsi_taskcache",
+ sizeof(struct iscsi_data_task), 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if (!taskcache)
+ return -ENOMEM;
+
if (!iscsi_register_transport(&iscsi_tcp_transport))
- return -ENODEV;
+ kmem_cache_destroy(taskcache);
return 0;
}
iscsi_tcp_exit(void)
{
iscsi_unregister_transport(&iscsi_tcp_transport);
+ kmem_cache_destroy(taskcache);
}
module_init(iscsi_tcp_init);
* 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
#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
#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
#define XMSTATE_W_PAD 0x200
#define XMSTATE_DATA_DIGEST 0x400
+#define ISCSI_CONN_MAX 1
#define ISCSI_CONN_RCVBUF_MIN 262144
#define ISCSI_CONN_SNDBUF_MIN 262144
#define ISCSI_PAD_LEN 4
#define ISCSI_R2T_MAX 16
+#define ISCSI_XMIT_CMDS_MAX 128 /* must be power of 2 */
+#define ISCSI_MGMT_CMDS_MAX 32 /* must be power of 2 */
+#define ISCSI_MGMT_ITT_OFFSET 0xa00
#define ISCSI_SG_TABLESIZE SG_ALL
+#define ISCSI_DEF_CMD_PER_LUN 32
+#define ISCSI_MAX_CMD_PER_LUN 128
#define ISCSI_TCP_MAX_CMD_LEN 16
-struct socket;
+#define ITT_MASK (0xfff)
+#define CID_SHIFT 12
+#define CID_MASK (0xffff<<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 {
struct iscsi_cmd_task *ctask; /* current cmd in progress */
/* copied and flipped values */
+ int opcode;
+ int flags;
+ int cmd_status;
+ int ahslen;
int datalen;
+ uint32_t itt;
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 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 */
+ uint32_t exp_statsn;
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 */
+ int senselen; /* scsi sense length */
+ int id; /* CID */
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 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);
/* 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 eh_abort_cnt;
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_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 */
};
+#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 data_count; /* counts data to be 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 {
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];
- 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*/
- 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 */
+ uint32_t unsol_datasn;
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 data_count; /* remaining Data-Out */
+ int pad_count; /* padded bytes */
+ struct scsi_cmnd *sc; /* associated SCSI cmd*/
+ int total_length;
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 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 */
- 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 */
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;
- }
case UNIT_ATTENTION:
if (sdev->removable) {
sdev->changed = 1;
#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 {
- int daemon_pid;
struct scsi_transport_template t;
struct iscsi_transport *iscsi_transport;
struct list_head list;
- struct class_device cdev;
+ /*
+ * based on transport capabilities, at register time we set these
+ * bits to tell the transport class it wants attributes displayed
+ * in sysfs or that it can support different iSCSI Data-Path
+ * capabilities
+ */
+ uint32_t param_mask;
- struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1];
+ struct class_device cdev;
+ /*
+ * We do not have any private or other attrs.
+ */
struct transport_container conn_cont;
struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1];
struct transport_container session_cont;
struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
};
-static int iscsi_session_nr; /* sysfs session id for next new session */
-
/*
* list of registered transports and lock that must
* be held while accessing list. The iscsi_transport_lock must
.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,
NULL);
static struct sock *nls;
+static int daemon_pid;
static DEFINE_MUTEX(rx_queue_mutex);
struct mempool_zone {
static LIST_HEAD(connlist);
static DEFINE_SPINLOCK(connlock);
-static uint32_t iscsi_conn_get_sid(struct iscsi_cls_conn *conn)
-{
- struct iscsi_cls_session *sess = iscsi_dev_to_session(conn->dev.parent);
- return sess->sid;
-}
-
-/*
- * Returns the matching session to a given sid
- */
-static struct iscsi_cls_session *iscsi_session_lookup(uint32_t sid)
+static struct iscsi_cls_session *iscsi_session_lookup(uint64_t handle)
{
unsigned long flags;
struct iscsi_cls_session *sess;
spin_lock_irqsave(&sesslock, flags);
list_for_each_entry(sess, &sesslist, sess_list) {
- if (sess->sid == sid) {
+ if (sess == iscsi_ptr(handle)) {
spin_unlock_irqrestore(&sesslock, flags);
return sess;
}
return NULL;
}
-/*
- * Returns the matching connection to a given sid / cid tuple
- */
-static struct iscsi_cls_conn *iscsi_conn_lookup(uint32_t sid, uint32_t cid)
+static struct iscsi_cls_conn *iscsi_conn_lookup(uint64_t handle)
{
unsigned long flags;
struct iscsi_cls_conn *conn;
spin_lock_irqsave(&connlock, flags);
list_for_each_entry(conn, &connlist, conn_list) {
- if ((conn->cid == cid) && (iscsi_conn_get_sid(conn) == sid)) {
+ if (conn == iscsi_ptr(handle)) {
spin_unlock_irqrestore(&connlock, flags);
return conn;
}
shost = iscsi_session_to_shost(session);
scsi_host_put(shost);
- kfree(session->targetname);
kfree(session);
module_put(transport->owner);
}
return dev->release == iscsi_session_release;
}
-static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
- uint id, uint lun)
-{
- struct iscsi_host *ihost = shost->shost_data;
- struct iscsi_cls_session *session;
-
- mutex_lock(&ihost->mutex);
- list_for_each_entry(session, &ihost->sessions, host_list) {
- if ((channel == SCAN_WILD_CARD ||
- channel == session->channel) &&
- (id == SCAN_WILD_CARD || id == session->target_id))
- scsi_scan_target(&session->dev, session->channel,
- session->target_id, lun, 1);
- }
- mutex_unlock(&ihost->mutex);
-
- return 0;
-}
-
-static void session_recovery_timedout(void *data)
-{
- struct iscsi_cls_session *session = data;
-
- dev_printk(KERN_INFO, &session->dev, "iscsi: session recovery timed "
- "out after %d secs\n", session->recovery_tmo);
-
- if (session->transport->session_recovery_timedout)
- session->transport->session_recovery_timedout(session);
-
- scsi_target_unblock(&session->dev);
-}
-
-void iscsi_unblock_session(struct iscsi_cls_session *session)
-{
- if (!cancel_delayed_work(&session->recovery_work))
- flush_scheduled_work();
- scsi_target_unblock(&session->dev);
-}
-EXPORT_SYMBOL_GPL(iscsi_unblock_session);
-
-void iscsi_block_session(struct iscsi_cls_session *session)
-{
- scsi_target_block(&session->dev);
- schedule_delayed_work(&session->recovery_work,
- session->recovery_tmo * HZ);
-}
-EXPORT_SYMBOL_GPL(iscsi_block_session);
-
/**
* iscsi_create_session - create iscsi class session
* @shost: scsi host
* @transport: iscsi transport
*
- * This can be called from a LLD or iscsi_transport.
+ * This can be called from a LLD or iscsi_transport
**/
struct iscsi_cls_session *
-iscsi_create_session(struct Scsi_Host *shost,
- struct iscsi_transport *transport, int channel)
+iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *transport)
{
- struct iscsi_host *ihost;
struct iscsi_cls_session *session;
int err;
if (!try_module_get(transport->owner))
return NULL;
- session = kzalloc(sizeof(*session) + transport->sessiondata_size,
- GFP_KERNEL);
+ session = kzalloc(sizeof(*session), GFP_KERNEL);
if (!session)
goto module_put;
session->transport = transport;
- session->recovery_tmo = 120;
- INIT_WORK(&session->recovery_work, session_recovery_timedout, session);
- INIT_LIST_HEAD(&session->host_list);
- INIT_LIST_HEAD(&session->sess_list);
-
- if (transport->sessiondata_size)
- session->dd_data = &session[1];
/* this is released in the dev's release function */
scsi_host_get(shost);
- ihost = shost->shost_data;
-
- session->sid = iscsi_session_nr++;
- session->channel = channel;
- session->target_id = ihost->next_target_id++;
-
- snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u",
- session->sid);
+ snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", shost->host_no);
session->dev.parent = &shost->shost_gendev;
session->dev.release = iscsi_session_release;
err = device_register(&session->dev);
}
transport_register_device(&session->dev);
- mutex_lock(&ihost->mutex);
- list_add(&session->host_list, &ihost->sessions);
- mutex_unlock(&ihost->mutex);
-
return session;
free_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;
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);
}
* This can be called from a LLD or iscsi_transport. The connection
* is child of the session so cid must be unique for all connections
* on the session.
- *
- * Since we do not support MCS, cid will normally be zero. In some cases
- * for software iscsi we could be trying to preallocate a connection struct
- * in which case there could be two connection structs and cid would be
- * non-zero.
**/
struct iscsi_cls_conn *
iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid)
{
struct iscsi_transport *transport = session->transport;
+ struct Scsi_Host *shost = iscsi_session_to_shost(session);
struct iscsi_cls_conn *conn;
int err;
INIT_LIST_HEAD(&conn->conn_list);
conn->transport = transport;
- conn->cid = cid;
/* this is released in the dev's release function */
if (!get_device(&session->dev))
goto free_conn;
-
snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u",
- session->sid, cid);
+ shost->host_no, cid);
conn->dev.parent = &session->dev;
conn->dev.release = iscsi_conn_release;
err = device_register(&conn->dev);
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
*/
}
static int
-iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid)
+iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb)
{
unsigned long flags;
int rc;
skb_get(skb);
- rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT);
+ rc = netlink_unicast(nls, skb, daemon_pid, MSG_DONTWAIT);
if (rc < 0) {
mempool_free(skb, zone->pool);
printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc);
}
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);
struct sk_buff *skb;
struct iscsi_uevent *ev;
char *pdu;
- struct iscsi_internal *priv;
int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) +
data_size);
- priv = iscsi_if_transport_lookup(conn->transport);
- if (!priv)
- return -EINVAL;
-
mempool_zone_complete(conn->z_pdu);
skb = mempool_zone_get_skb(conn->z_pdu);
return -ENOMEM;
}
- nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
+ nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
ev = NLMSG_DATA(nlh);
memset(ev, 0, sizeof(*ev));
ev->transport_handle = iscsi_handle(conn->transport);
ev->type = ISCSI_KEVENT_RECV_PDU;
if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat)
ev->iferror = -ENOMEM;
- ev->r.recv_req.cid = conn->cid;
- ev->r.recv_req.sid = iscsi_conn_get_sid(conn);
+ ev->r.recv_req.conn_handle = iscsi_handle(conn);
pdu = (char*)ev + sizeof(*ev);
memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
- return iscsi_unicast_skb(conn->z_pdu, skb, priv->daemon_pid);
+ return iscsi_unicast_skb(conn->z_pdu, skb);
}
EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
struct nlmsghdr *nlh;
struct sk_buff *skb;
struct iscsi_uevent *ev;
- struct iscsi_internal *priv;
int len = NLMSG_SPACE(sizeof(*ev));
- priv = iscsi_if_transport_lookup(conn->transport);
- if (!priv)
- return;
-
mempool_zone_complete(conn->z_error);
skb = mempool_zone_get_skb(conn->z_error);
return;
}
- nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
+ nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
ev = NLMSG_DATA(nlh);
ev->transport_handle = iscsi_handle(conn->transport);
ev->type = ISCSI_KEVENT_CONN_ERROR;
if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat)
ev->iferror = -ENOMEM;
ev->r.connerror.error = error;
- ev->r.connerror.cid = conn->cid;
- ev->r.connerror.sid = iscsi_conn_get_sid(conn);
+ ev->r.connerror.conn_handle = iscsi_handle(conn);
- iscsi_unicast_skb(conn->z_error, skb, priv->daemon_pid);
+ iscsi_unicast_skb(conn->z_error, skb);
dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n",
error);
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
struct iscsi_cls_conn *conn;
struct nlmsghdr *nlhstat;
struct iscsi_uevent *evstat;
- struct iscsi_internal *priv;
int len = NLMSG_SPACE(sizeof(*ev) +
sizeof(struct iscsi_stats) +
sizeof(struct iscsi_stats_custom) *
ISCSI_STATS_CUSTOM_MAX);
int err = 0;
- priv = iscsi_if_transport_lookup(transport);
- if (!priv)
- return -EINVAL;
-
- conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid);
+ conn = iscsi_conn_lookup(ev->u.get_stats.conn_handle);
if (!conn)
return -EEXIST;
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));
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));
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;
{
struct iscsi_transport *transport = priv->iscsi_transport;
struct iscsi_cls_session *session;
- unsigned long flags;
- uint32_t hostno;
+ uint32_t sid;
- session = transport->create_session(transport, &priv->t,
+ session = transport->create_session(&priv->t,
ev->u.c_session.initial_cmdsn,
- &hostno);
+ &sid);
if (!session)
return -ENOMEM;
- spin_lock_irqsave(&sesslock, flags);
- list_add(&session->sess_list, &sesslist);
- spin_unlock_irqrestore(&sesslock, flags);
-
- ev->r.c_session_ret.host_no = hostno;
- ev->r.c_session_ret.sid = session->sid;
+ ev->r.c_session_ret.session_handle = iscsi_handle(session);
+ ev->r.c_session_ret.sid = sid;
return 0;
}
struct iscsi_cls_session *session;
unsigned long flags;
- session = iscsi_session_lookup(ev->u.c_conn.sid);
- if (!session) {
- printk(KERN_ERR "iscsi: invalid session %d\n",
- ev->u.c_conn.sid);
+ session = iscsi_session_lookup(ev->u.c_conn.session_handle);
+ if (!session)
return -EINVAL;
- }
conn = transport->create_conn(session, ev->u.c_conn.cid);
- if (!conn) {
- printk(KERN_ERR "iscsi: couldn't create a new "
- "connection for session %d\n",
- session->sid);
+ if (!conn)
return -ENOMEM;
- }
conn->z_pdu = mempool_zone_init(Z_MAX_PDU,
NLMSG_SPACE(sizeof(struct iscsi_uevent) +
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);
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);
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)
{
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)
if (!try_module_get(transport->owner))
return -EINVAL;
- priv->daemon_pid = NETLINK_CREDS(skb)->pid;
-
switch (nlh->nlmsg_type) {
case ISCSI_UEVENT_CREATE_SESSION:
err = iscsi_if_create_session(priv, ev);
break;
case ISCSI_UEVENT_DESTROY_SESSION:
- session = iscsi_session_lookup(ev->u.d_session.sid);
- if (session) {
- spin_lock_irqsave(&sesslock, flags);
- list_del(&session->sess_list);
- spin_unlock_irqrestore(&sesslock, flags);
-
+ session = iscsi_session_lookup(ev->u.d_session.session_handle);
+ if (session)
transport->destroy_session(session);
- } else
+ else
err = -EINVAL;
break;
case ISCSI_UEVENT_CREATE_CONN:
err = iscsi_if_destroy_conn(transport, ev);
break;
case ISCSI_UEVENT_BIND_CONN:
- session = iscsi_session_lookup(ev->u.b_conn.sid);
- conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid);
+ session = iscsi_session_lookup(ev->u.b_conn.session_handle);
+ conn = iscsi_conn_lookup(ev->u.b_conn.conn_handle);
if (session && conn)
ev->r.retcode = transport->bind_conn(session, conn,
- ev->u.b_conn.transport_eph,
+ ev->u.b_conn.transport_fd,
ev->u.b_conn.is_leading);
else
err = -EINVAL;
break;
case ISCSI_UEVENT_SET_PARAM:
- err = iscsi_set_param(transport, ev);
+ conn = iscsi_conn_lookup(ev->u.set_param.conn_handle);
+ if (conn)
+ ev->r.retcode = transport->set_param(conn,
+ ev->u.set_param.param, ev->u.set_param.value);
+ else
+ err = -EINVAL;
break;
case ISCSI_UEVENT_START_CONN:
- conn = iscsi_conn_lookup(ev->u.start_conn.sid, ev->u.start_conn.cid);
+ conn = iscsi_conn_lookup(ev->u.start_conn.conn_handle);
if (conn)
ev->r.retcode = transport->start_conn(conn);
else
err = -EINVAL;
+
break;
case ISCSI_UEVENT_STOP_CONN:
- conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid);
+ conn = iscsi_conn_lookup(ev->u.stop_conn.conn_handle);
if (conn)
transport->stop_conn(conn, ev->u.stop_conn.flag);
else
err = -EINVAL;
break;
case ISCSI_UEVENT_SEND_PDU:
- conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid);
+ conn = iscsi_conn_lookup(ev->u.send_pdu.conn_handle);
if (conn)
ev->r.retcode = transport->send_pdu(conn,
(struct iscsi_hdr*)((char*)ev + sizeof(*ev)),
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;
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)
{
skb_pull(skb, skb->len);
goto free_skb;
}
+ daemon_pid = NETLINK_CREDS(skb)->pid;
while (skb->len >= NLMSG_SPACE(0)) {
int err;
#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
*/
#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(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_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(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d");
iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d");
iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d");
-iscsi_session_int_attr(tpgt, ISCSI_PARAM_TPGT, "%d");
-
-#define iscsi_session_str_attr_show(param) \
-static ssize_t \
-show_session_str_param_##param(struct class_device *cdev, char *buf) \
-{ \
- struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
- struct iscsi_transport *t = session->transport; \
- return t->get_session_str_param(session, param, buf); \
-}
-
-#define iscsi_session_str_attr(field, param) \
- iscsi_session_str_attr_show(param) \
-static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_str_param_##param, \
- NULL);
-
-iscsi_session_str_attr(targetname, ISCSI_PARAM_TARGET_NAME);
-
-/*
- * Private session and conn attrs. userspace uses several iscsi values
- * to identify each session between reboots. Some of these values may not
- * be present in the iscsi_transport/LLD driver becuase userspace handles
- * login (and failback for login redirect) so for these type of drivers
- * the class manages the attrs and values for the iscsi_transport/LLD
- */
-#define iscsi_priv_session_attr_show(field, format) \
-static ssize_t \
-show_priv_session_##field(struct class_device *cdev, char *buf) \
-{ \
- struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
- return sprintf(buf, format"\n", session->field); \
-}
-
-#define iscsi_priv_session_attr(field, format) \
- iscsi_priv_session_attr_show(field, format) \
-static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \
- NULL)
-iscsi_priv_session_attr(targetname, "%s");
-iscsi_priv_session_attr(tpgt, "%d");
-iscsi_priv_session_attr(recovery_tmo, "%d");
-
-#define iscsi_priv_conn_attr_show(field, format) \
-static ssize_t \
-show_priv_conn_##field(struct class_device *cdev, char *buf) \
-{ \
- struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \
- return sprintf(buf, format"\n", conn->field); \
-}
-#define iscsi_priv_conn_attr(field, format) \
- iscsi_priv_conn_attr_show(field, format) \
-static ISCSI_CLASS_ATTR(priv_conn, field, S_IRUGO, show_priv_conn_##field, \
- NULL)
-iscsi_priv_conn_attr(persistent_address, "%s");
-iscsi_priv_conn_attr(persistent_port, "%d");
-
-#define SETUP_PRIV_SESSION_RD_ATTR(field) \
-do { \
- priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \
- count++; \
-} while (0)
-
-#define SETUP_SESSION_RD_ATTR(field, param_flag) \
-do { \
- if (tt->param_mask & param_flag) { \
- priv->session_attrs[count] = &class_device_attr_sess_##field; \
+#define SETUP_SESSION_RD_ATTR(field, param) \
+ if (priv->param_mask & (1 << param)) { \
+ priv->session_attrs[count] = &class_device_attr_##field;\
count++; \
- } \
-} while (0)
-
-#define SETUP_PRIV_CONN_RD_ATTR(field) \
-do { \
- priv->conn_attrs[count] = &class_device_attr_priv_conn_##field; \
- count++; \
-} while (0)
-
-#define SETUP_CONN_RD_ATTR(field, param_flag) \
-do { \
- if (tt->param_mask & param_flag) { \
- priv->conn_attrs[count] = &class_device_attr_conn_##field; \
+ }
+
+#define SETUP_CONN_RD_ATTR(field, param) \
+ if (priv->param_mask & (1 << param)) { \
+ priv->conn_attrs[count] = &class_device_attr_##field; \
count++; \
- } \
-} while (0)
+ }
static int iscsi_session_match(struct attribute_container *cont,
struct device *dev)
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)
{
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);
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];
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;
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;
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);
if (err)
return err;
- err = transport_class_register(&iscsi_host_class);
- if (err)
- goto unregister_transport_class;
-
err = transport_class_register(&iscsi_connection_class);
if (err)
- goto unregister_host_class;
+ goto unregister_transport_class;
err = transport_class_register(&iscsi_session_class);
if (err)
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;
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);
}
*
* 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
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);
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:
/*
* 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);
/*
*/
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.
*/
touch_nmi_watchdog();
- if (oops_in_progress) {
- locked = spin_trylock_irqsave(&up->port.lock, flags);
+ local_irq_save(flags);
+ if (up->port.sysrq) {
+ /* serial8250_handle_port() already took the lock */
+ locked = 0;
+ } else if (oops_in_progress) {
+ locked = spin_trylock(&up->port.lock);
} else
- spin_lock_irqsave(&up->port.lock, flags);
+ spin_lock(&up->port.lock);
/*
* First save the IER then disable the interrupts
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)
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
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
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);
* 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;
/*
* This URB stopped short of its end. We have to
* fix up the toggles of the following URBs on the
- * queue and restart the queue.
+ * queue and restart the queue. But only if this
+ * TD isn't the last one in the URB.
*
* Do this only the first time we encounter the
* short URB.
*/
- if (!urbp->short_transfer) {
+ if (!urbp->short_transfer &&
+ &td->list != urbp->td_list.prev) {
urbp->short_transfer = 1;
urbp->qh->initial_toggle =
uhci_toggle(td_token(td)) ^ 1;
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 */
#define HIGH 1
#define LOW 0
+/* number of outstanding urbs to prevent userspace DoS from happening */
+#define URB_UPPER_LIMIT 42
+
/*
* ***************************************************************************
* Utlity functions
}
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 */
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("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);
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
static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
{
+ unsigned long flags;
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+ struct ftdi_private *priv;
+ int data_offset; /* will be 1 for the SIO and 0 otherwise */
+ unsigned long countback;
/* free up the transfer buffer, as usb_free_urb() does not do this */
kfree (urb->transfer_buffer);
return;
}
+ priv = usb_get_serial_port_data(port);
+ if (!priv) {
+ dbg("%s - bad port private data pointer - exiting", __FUNCTION__);
+ return;
+ }
+ /* account for transferred data */
+ countback = urb->actual_length;
+ data_offset = priv->write_offset;
+ if (data_offset > 0) {
+ /* Subtract the control bytes */
+ countback -= (data_offset * ((countback + (PKTSZ - 1)) / PKTSZ));
+ }
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ --priv->tx_outstanding_urbs;
+ priv->tx_outstanding_bytes -= countback;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+
schedule_work(&port->work);
} /* ftdi_write_bulk_callback */
static int ftdi_write_room( struct usb_serial_port *port )
{
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ int room;
+ unsigned long flags;
+
dbg("%s - port %d", __FUNCTION__, port->number);
- /*
- * We really can take anything the user throws at us
- * but let's pick a nice big number to tell the tty
- * layer that we have lots of free space
- */
- return 2048;
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ if (priv->tx_outstanding_urbs < URB_UPPER_LIMIT) {
+ /*
+ * We really can take anything the user throws at us
+ * but let's pick a nice big number to tell the tty
+ * layer that we have lots of free space
+ */
+ room = 2048;
+ } else {
+ room = 0;
+ }
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ return room;
} /* ftdi_write_room */
static int ftdi_chars_in_buffer (struct usb_serial_port *port)
{ /* ftdi_chars_in_buffer */
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ int buffered;
+ unsigned long flags;
+
dbg("%s - port %d", __FUNCTION__, port->number);
- /*
- * We can't really account for how much data we
- * have sent out, but hasn't made it through to the
- * device, so just tell the tty layer that everything
- * is flushed.
- */
- return 0;
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ buffered = (int)priv->tx_outstanding_bytes;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ if (buffered < 0) {
+ err("%s outstanding tx bytes is negative!", __FUNCTION__);
+ buffered = 0;
+ }
+ return buffered;
} /* ftdi_chars_in_buffer */
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",
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",
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;
}
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;
}
config VIDEO_SELECT
bool
- depends on (FB = y) && X86
+ depends on (FB = y) && X86 && !XEN
default y
config FB_SGIVW
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;
allocsize = dsize + sizeof(struct fb_image);
src = kmalloc(allocsize, GFP_ATOMIC);
- if (!src)
+ if (!src) {
+ allocsize = 0;
return -ENOMEM;
+ }
}
image = (struct fb_image *) (src + dsize);
-
-
+obj-y += core/
obj-y += console/
obj-y += evtchn/
-obj-y += balloon/
+obj-y += privcmd/
+obj-y += xenbus/
-obj-$(CONFIG_XEN_PRIVILEGED_GUEST) += privcmd/
+obj-$(CONFIG_XEN_UTIL) += util.o
+obj-$(CONFIG_XEN_BALLOON) += balloon/
+obj-$(CONFIG_XEN_DEVMEM) += char/
obj-$(CONFIG_XEN_BLKDEV_BACKEND) += blkback/
+obj-$(CONFIG_XEN_BLKDEV_TAP) += blktap/
obj-$(CONFIG_XEN_NETDEV_BACKEND) += netback/
+obj-$(CONFIG_XEN_TPMDEV_BACKEND) += tpmback/
obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += blkfront/
obj-$(CONFIG_XEN_NETDEV_FRONTEND) += netfront/
-obj-$(CONFIG_XEN_BLKDEV_TAP) += blktap/
-
+obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pciback/
+obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += pcifront/
*
* 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
#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 <xen/xenbus.h>
+
+#define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10))
+
+#ifdef CONFIG_PROC_FS
static struct proc_dir_entry *balloon_pde;
+#endif
static DECLARE_MUTEX(balloon_mutex);
-spinlock_t balloon_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Protects atomic reservation decrease/increase against concurrent increases.
+ * Also protects non-atomic updates of current_pages and driver_pages, and
+ * balloon lists.
+ */
+DEFINE_SPINLOCK(balloon_lock);
/* We aim for 'current allocation' == 'target allocation'. */
static unsigned long current_pages;
static unsigned long target_pages;
+/* We increase/decrease in batches which fit in a page */
+static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)];
+
+/* VM /proc information for memory */
+extern unsigned long totalram_pages;
+
/* We may hit the hard limit in Xen. If we do then we remember it. */
static unsigned long hard_limit;
static DECLARE_WORK(balloon_worker, balloon_process, NULL);
static struct timer_list balloon_timer;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-/* Use the private and mapping fields of struct page as a list. */
-#define PAGE_TO_LIST(p) ( (struct list_head *)&p->private )
-#define LIST_TO_PAGE(l) ( list_entry( ((unsigned long *)l), \
- struct page, private ) )
-#define UNLIST_PAGE(p) do { list_del(PAGE_TO_LIST(p)); \
- p->mapping = NULL; \
- p->private = 0; } while(0)
-#else
-/* There's a dedicated list field in struct page we can use. */
-#define PAGE_TO_LIST(p) ( &p->list )
-#define LIST_TO_PAGE(l) ( list_entry(l, struct page, list) )
-#define UNLIST_PAGE(p) ( list_del(&p->list) )
-#define pte_offset_kernel pte_offset
-#define pud_t pgd_t
-#define pud_offset(d, va) d
-#define pud_none(d) 0
-#define pud_bad(d) 0
-#define subsys_initcall(_fn) __initcall(_fn)
-#define pfn_to_page(_pfn) (mem_map + (_pfn))
-#endif
+/* When ballooning out (allocating memory to return to Xen) we don't really
+ want the kernel to try too hard since that can trigger the oom killer. */
+#define GFP_BALLOON \
+ (GFP_HIGHUSER | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC)
+
+#define PAGE_TO_LIST(p) (&(p)->lru)
+#define LIST_TO_PAGE(l) list_entry((l), struct page, lru)
+#define UNLIST_PAGE(p) \
+ do { \
+ list_del(PAGE_TO_LIST(p)); \
+ PAGE_TO_LIST(p)->next = NULL; \
+ PAGE_TO_LIST(p)->prev = NULL; \
+ } while(0)
#define IPRINTK(fmt, args...) \
- printk(KERN_INFO "xen_mem: " fmt, ##args)
+ printk(KERN_INFO "xen_mem: " fmt, ##args)
#define WPRINTK(fmt, args...) \
- printk(KERN_WARNING "xen_mem: " fmt, ##args)
+ printk(KERN_WARNING "xen_mem: " fmt, ##args)
/* balloon_append: add the given page to the balloon. */
static void balloon_append(struct page *page)
{
- /* Low memory is re-populated first, so highmem pages go at list tail. */
- if ( PageHighMem(page) )
- {
- list_add_tail(PAGE_TO_LIST(page), &ballooned_pages);
- balloon_high++;
- }
- else
- {
- list_add(PAGE_TO_LIST(page), &ballooned_pages);
- balloon_low++;
- }
+ /* Lowmem is re-populated first, so highmem pages go at list tail. */
+ if (PageHighMem(page)) {
+ list_add_tail(PAGE_TO_LIST(page), &ballooned_pages);
+ balloon_high++;
+ } else {
+ list_add(PAGE_TO_LIST(page), &ballooned_pages);
+ balloon_low++;
+ }
}
/* balloon_retrieve: rescue a page from the balloon, if it is not empty. */
static struct page *balloon_retrieve(void)
{
- struct page *page;
+ struct page *page;
+
+ if (list_empty(&ballooned_pages))
+ return NULL;
+
+ page = LIST_TO_PAGE(ballooned_pages.next);
+ UNLIST_PAGE(page);
- if ( list_empty(&ballooned_pages) )
- return NULL;
+ if (PageHighMem(page))
+ balloon_high--;
+ else
+ balloon_low--;
- page = LIST_TO_PAGE(ballooned_pages.next);
- UNLIST_PAGE(page);
+ return page;
+}
- if ( PageHighMem(page) )
- balloon_high--;
- else
- balloon_low--;
+static struct page *balloon_first_page(void)
+{
+ if (list_empty(&ballooned_pages))
+ return NULL;
+ return LIST_TO_PAGE(ballooned_pages.next);
+}
- return page;
+static struct page *balloon_next_page(struct page *page)
+{
+ struct list_head *next = PAGE_TO_LIST(page)->next;
+ if (next == &ballooned_pages)
+ return NULL;
+ return LIST_TO_PAGE(next);
}
static void balloon_alarm(unsigned long unused)
{
- schedule_work(&balloon_worker);
+ schedule_work(&balloon_worker);
}
static unsigned long current_target(void)
{
- unsigned long target = min(target_pages, hard_limit);
- if ( target > (current_pages + balloon_low + balloon_high) )
- target = current_pages + balloon_low + balloon_high;
- return target;
+ unsigned long target = min(target_pages, hard_limit);
+ if (target > (current_pages + balloon_low + balloon_high))
+ target = current_pages + balloon_low + balloon_high;
+ return target;
+}
+
+static int increase_reservation(unsigned long nr_pages)
+{
+ unsigned long pfn, i, flags;
+ struct page *page;
+ long rc;
+ struct xen_memory_reservation reservation = {
+ .address_bits = 0,
+ .extent_order = 0,
+ .domid = DOMID_SELF
+ };
+
+ if (nr_pages > ARRAY_SIZE(frame_list))
+ nr_pages = ARRAY_SIZE(frame_list);
+
+ balloon_lock(flags);
+
+ page = balloon_first_page();
+ for (i = 0; i < nr_pages; i++) {
+ BUG_ON(page == NULL);
+ frame_list[i] = page_to_pfn(page);;
+ page = balloon_next_page(page);
+ }
+
+ set_xen_guest_handle(reservation.extent_start, frame_list);
+ reservation.nr_extents = nr_pages;
+ rc = HYPERVISOR_memory_op(
+ XENMEM_populate_physmap, &reservation);
+ if (rc < nr_pages) {
+ if (rc > 0) {
+ int ret;
+
+ /* We hit the Xen hard limit: reprobe. */
+ reservation.nr_extents = rc;
+ ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+ &reservation);
+ BUG_ON(ret != rc);
+ }
+ if (rc >= 0)
+ hard_limit = current_pages + rc - driver_pages;
+ goto out;
+ }
+
+ for (i = 0; i < nr_pages; i++) {
+ page = balloon_retrieve();
+ BUG_ON(page == NULL);
+
+ pfn = page_to_pfn(page);
+ BUG_ON(!xen_feature(XENFEAT_auto_translated_physmap) &&
+ phys_to_machine_mapping_valid(pfn));
+
+ /* Update P->M and M->P tables. */
+ set_phys_to_machine(pfn, frame_list[i]);
+ xen_machphys_update(frame_list[i], pfn);
+
+ /* Link back into the page tables if not highmem. */
+ if (pfn < max_low_pfn) {
+ int ret;
+ ret = HYPERVISOR_update_va_mapping(
+ (unsigned long)__va(pfn << PAGE_SHIFT),
+ pfn_pte_ma(frame_list[i], PAGE_KERNEL),
+ 0);
+ BUG_ON(ret);
+ }
+
+ /* Relinquish the page back to the allocator. */
+ ClearPageReserved(page);
+ init_page_count(page);
+ __free_page(page);
+ }
+
+ current_pages += nr_pages;
+ totalram_pages = current_pages;
+
+ out:
+ balloon_unlock(flags);
+
+ return 0;
+}
+
+static int decrease_reservation(unsigned long nr_pages)
+{
+ unsigned long pfn, i, flags;
+ struct page *page;
+ void *v;
+ int need_sleep = 0;
+ int ret;
+ struct xen_memory_reservation reservation = {
+ .address_bits = 0,
+ .extent_order = 0,
+ .domid = DOMID_SELF
+ };
+
+ if (nr_pages > ARRAY_SIZE(frame_list))
+ nr_pages = ARRAY_SIZE(frame_list);
+
+ for (i = 0; i < nr_pages; i++) {
+ if ((page = alloc_page(GFP_BALLOON)) == NULL) {
+ nr_pages = i;
+ need_sleep = 1;
+ break;
+ }
+
+ pfn = page_to_pfn(page);
+ frame_list[i] = pfn_to_mfn(pfn);
+
+ if (!PageHighMem(page)) {
+ v = phys_to_virt(pfn << PAGE_SHIFT);
+ scrub_pages(v, 1);
+ ret = HYPERVISOR_update_va_mapping(
+ (unsigned long)v, __pte_ma(0), 0);
+ BUG_ON(ret);
+ }
+#ifdef CONFIG_XEN_SCRUB_PAGES
+ else {
+ v = kmap(page);
+ scrub_pages(v, 1);
+ kunmap(page);
+ }
+#endif
+ }
+
+ /* Ensure that ballooned highmem pages don't have kmaps. */
+ kmap_flush_unused();
+ flush_tlb_all();
+
+ balloon_lock(flags);
+
+ /* No more mappings: invalidate P2M and add to balloon. */
+ for (i = 0; i < nr_pages; i++) {
+ pfn = mfn_to_pfn(frame_list[i]);
+ set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
+ balloon_append(pfn_to_page(pfn));
+ }
+
+ set_xen_guest_handle(reservation.extent_start, frame_list);
+ reservation.nr_extents = nr_pages;
+ ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
+ BUG_ON(ret != nr_pages);
+
+ current_pages -= nr_pages;
+ totalram_pages = current_pages;
+
+ balloon_unlock(flags);
+
+ return need_sleep;
}
/*
*/
static void balloon_process(void *unused)
{
- unsigned long *mfn_list, pfn, i, flags;
- struct page *page;
- long credit, debt, rc;
- void *v;
-
- down(&balloon_mutex);
-
- retry:
- mfn_list = NULL;
-
- if ( (credit = current_target() - current_pages) > 0 )
- {
- mfn_list = (unsigned long *)vmalloc(credit * sizeof(*mfn_list));
- if ( mfn_list == NULL )
- goto out;
-
- balloon_lock(flags);
- rc = HYPERVISOR_dom_mem_op(
- MEMOP_increase_reservation, mfn_list, credit, 0);
- balloon_unlock(flags);
- if ( rc < credit )
- {
- /* We hit the Xen hard limit: reprobe. */
- if ( HYPERVISOR_dom_mem_op(
- MEMOP_decrease_reservation, mfn_list, rc, 0) != rc )
- BUG();
- hard_limit = current_pages + rc - driver_pages;
- vfree(mfn_list);
- goto retry;
- }
-
- for ( i = 0; i < credit; i++ )
- {
- if ( (page = balloon_retrieve()) == NULL )
- BUG();
-
- pfn = page - mem_map;
- if ( phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY )
- BUG();
-
- /* Update P->M and M->P tables. */
- phys_to_machine_mapping[pfn] = mfn_list[i];
- xen_machphys_update(mfn_list[i], pfn);
-
- /* Link back into the page tables if it's not a highmem page. */
- if ( pfn < max_low_pfn )
- {
- HYPERVISOR_update_va_mapping(
- (unsigned long)__va(pfn << PAGE_SHIFT),
- __pte_ma((mfn_list[i] << PAGE_SHIFT) |
- pgprot_val(PAGE_KERNEL)),
- 0);
- }
-
- /* Finally, relinquish the memory back to the system allocator. */
- ClearPageReserved(page);
- set_page_count(page, 1);
- __free_page(page);
- }
-
- current_pages += credit;
- }
- else if ( credit < 0 )
- {
- debt = -credit;
-
- mfn_list = (unsigned long *)vmalloc(debt * sizeof(*mfn_list));
- if ( mfn_list == NULL )
- goto out;
-
- for ( i = 0; i < debt; i++ )
- {
- if ( (page = alloc_page(GFP_HIGHUSER)) == NULL )
- {
- debt = i;
- break;
- }
-
- pfn = page - mem_map;
- mfn_list[i] = phys_to_machine_mapping[pfn];
-
- if ( !PageHighMem(page) )
- {
- v = phys_to_virt(pfn << PAGE_SHIFT);
- scrub_pages(v, 1);
- HYPERVISOR_update_va_mapping(
- (unsigned long)v, __pte_ma(0), 0);
- }
-#ifdef CONFIG_XEN_SCRUB_PAGES
- else
- {
- v = kmap(page);
- scrub_pages(v, 1);
- kunmap(page);
- }
-#endif
- }
+ int need_sleep = 0;
+ long credit;
- /* Ensure that ballooned highmem pages don't have cached mappings. */
- kmap_flush_unused();
- flush_tlb_all();
+ down(&balloon_mutex);
- /* No more mappings: invalidate pages in P2M and add to balloon. */
- for ( i = 0; i < debt; i++ )
- {
- pfn = mfn_to_pfn(mfn_list[i]);
- phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY;
- balloon_append(pfn_to_page(pfn));
- }
+ do {
+ credit = current_target() - current_pages;
+ if (credit > 0)
+ need_sleep = (increase_reservation(credit) != 0);
+ if (credit < 0)
+ need_sleep = (decrease_reservation(-credit) != 0);
- if ( HYPERVISOR_dom_mem_op(
- MEMOP_decrease_reservation, mfn_list, debt, 0) != debt )
- BUG();
-
- current_pages -= debt;
- }
-
- out:
- if ( mfn_list != NULL )
- vfree(mfn_list);
+#ifndef CONFIG_PREEMPT
+ if (need_resched())
+ schedule();
+#endif
+ } while ((credit != 0) && !need_sleep);
- /* Schedule more work if there is some still to be done. */
- if ( current_target() != current_pages )
- mod_timer(&balloon_timer, jiffies + HZ);
+ /* Schedule more work if there is some still to be done. */
+ if (current_target() != current_pages)
+ mod_timer(&balloon_timer, jiffies + HZ);
- up(&balloon_mutex);
+ up(&balloon_mutex);
}
/* Resets the Xen limit, sets new target, and kicks off processing. */
static void set_new_target(unsigned long target)
{
- /* No need for lock. Not read-modify-write updates. */
- hard_limit = ~0UL;
- target_pages = target;
- schedule_work(&balloon_worker);
+ /* No need for lock. Not read-modify-write updates. */
+ hard_limit = ~0UL;
+ target_pages = target;
+ schedule_work(&balloon_worker);
}
-static void balloon_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
+static struct xenbus_watch target_watch =
{
- switch ( msg->subtype )
- {
- case CMSG_MEM_REQUEST_SET:
- {
- mem_request_t *req = (mem_request_t *)&msg->msg[0];
- set_new_target(req->target);
- req->status = 0;
- }
- break;
-
- default:
- msg->length = 0;
- break;
- }
-
- ctrl_if_send_response(msg);
+ .node = "memory/target"
+};
+
+/* React to a change in the target key */
+static void watch_target(struct xenbus_watch *watch,
+ const char **vec, unsigned int len)
+{
+ unsigned long long new_target;
+ int err;
+
+ err = xenbus_scanf(XBT_NIL, "memory", "target", "%llu", &new_target);
+ if (err != 1) {
+ /* This is ok (for domain0 at least) - so just return */
+ return;
+ }
+
+ /* The given memory/target value is in KiB, so it needs converting to
+ * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10.
+ */
+ set_new_target(new_target >> (PAGE_SHIFT - 10));
+}
+
+static int balloon_init_watcher(struct notifier_block *notifier,
+ unsigned long event,
+ void *data)
+{
+ int err;
+
+ err = register_xenbus_watch(&target_watch);
+ if (err)
+ printk(KERN_ERR "Failed to set balloon watcher\n");
+
+ return NOTIFY_DONE;
}
+#ifdef CONFIG_PROC_FS
static int balloon_write(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
+ unsigned long count, void *data)
{
- char memstring[64], *endchar;
- unsigned long long target_bytes;
+ char memstring[64], *endchar;
+ unsigned long long target_bytes;
- if ( !capable(CAP_SYS_ADMIN) )
- return -EPERM;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
- if ( count <= 1 )
- return -EBADMSG; /* runt */
- if ( count > sizeof(memstring) )
- return -EFBIG; /* too long */
+ if (count <= 1)
+ return -EBADMSG; /* runt */
+ if (count > sizeof(memstring))
+ return -EFBIG; /* too long */
- if ( copy_from_user(memstring, buffer, count) )
- return -EFAULT;
- memstring[sizeof(memstring)-1] = '\0';
+ if (copy_from_user(memstring, buffer, count))
+ return -EFAULT;
+ memstring[sizeof(memstring)-1] = '\0';
- target_bytes = memparse(memstring, &endchar);
- set_new_target(target_bytes >> PAGE_SHIFT);
+ target_bytes = memparse(memstring, &endchar);
+ set_new_target(target_bytes >> PAGE_SHIFT);
- return count;
+ return count;
}
static int balloon_read(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+ int count, int *eof, void *data)
{
- int len;
-
-#define K(_p) ((_p)<<(PAGE_SHIFT-10))
- len = sprintf(
- page,
- "Current allocation: %8lu kB\n"
- "Requested target: %8lu kB\n"
- "Low-mem balloon: %8lu kB\n"
- "High-mem balloon: %8lu kB\n"
- "Xen hard limit: ",
- K(current_pages), K(target_pages), K(balloon_low), K(balloon_high));
-
- if ( hard_limit != ~0UL )
- len += sprintf(
- page + len,
- "%8lu kB (inc. %8lu kB driver headroom)\n",
- K(hard_limit), K(driver_pages));
- else
- len += sprintf(
- page + len,
- " ??? kB\n");
-
- *eof = 1;
- return len;
+ int len;
+
+ len = sprintf(
+ page,
+ "Current allocation: %8lu kB\n"
+ "Requested target: %8lu kB\n"
+ "Low-mem balloon: %8lu kB\n"
+ "High-mem balloon: %8lu kB\n"
+ "Xen hard limit: ",
+ PAGES2KB(current_pages), PAGES2KB(target_pages),
+ PAGES2KB(balloon_low), PAGES2KB(balloon_high));
+
+ if (hard_limit != ~0UL) {
+ len += sprintf(
+ page + len,
+ "%8lu kB (inc. %8lu kB driver headroom)\n",
+ PAGES2KB(hard_limit), PAGES2KB(driver_pages));
+ } else {
+ len += sprintf(
+ page + len,
+ " ??? kB\n");
+ }
+
+ *eof = 1;
+ return len;
}
+#endif
+
+static struct notifier_block xenstore_notifier;
static int __init balloon_init(void)
{
- unsigned long pfn;
- struct page *page;
+ unsigned long pfn;
+ struct page *page;
+
+ if (!is_running_on_xen())
+ return -ENODEV;
+
+ IPRINTK("Initialising balloon driver.\n");
+
+ current_pages = min(xen_start_info->nr_pages, max_pfn);
+ totalram_pages = current_pages;
+ target_pages = current_pages;
+ balloon_low = 0;
+ balloon_high = 0;
+ driver_pages = 0UL;
+ hard_limit = ~0UL;
- IPRINTK("Initialising balloon driver.\n");
+ init_timer(&balloon_timer);
+ balloon_timer.data = 0;
+ balloon_timer.function = balloon_alarm;
+
+#ifdef CONFIG_PROC_FS
+ if ((balloon_pde = create_xen_proc_entry("balloon", 0644)) == NULL) {
+ WPRINTK("Unable to create /proc/xen/balloon.\n");
+ return -1;
+ }
+
+ balloon_pde->read_proc = balloon_read;
+ balloon_pde->write_proc = balloon_write;
+#endif
+
+ /* Initialise the balloon with excess memory space. */
+ for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
+ page = pfn_to_page(pfn);
+ if (!PageReserved(page))
+ balloon_append(page);
+ }
- current_pages = min(xen_start_info.nr_pages, max_pfn);
- target_pages = current_pages;
- balloon_low = 0;
- balloon_high = 0;
- driver_pages = 0UL;
- hard_limit = ~0UL;
+ target_watch.callback = watch_target;
+ xenstore_notifier.notifier_call = balloon_init_watcher;
- init_timer(&balloon_timer);
- balloon_timer.data = 0;
- balloon_timer.function = balloon_alarm;
+ register_xenstore_notifier(&xenstore_notifier);
- if ( (balloon_pde = create_xen_proc_entry("balloon", 0644)) == NULL )
- {
- WPRINTK("Unable to create /proc/xen/balloon.\n");
- return -1;
- }
-
- balloon_pde->read_proc = balloon_read;
- balloon_pde->write_proc = balloon_write;
-
- (void)ctrl_if_register_receiver(CMSG_MEM_REQUEST, balloon_ctrlif_rx, 0);
-
- /* Initialise the balloon with excess memory space. */
- for ( pfn = xen_start_info.nr_pages; pfn < max_pfn; pfn++ )
- {
- page = &mem_map[pfn];
- if ( !PageReserved(page) )
- balloon_append(page);
- }
-
- return 0;
+ return 0;
}
subsys_initcall(balloon_init);
void balloon_update_driver_allowance(long delta)
{
- unsigned long flags;
- balloon_lock(flags);
- driver_pages += delta; /* non-atomic update */
- balloon_unlock(flags);
+ unsigned long flags;
+
+ balloon_lock(flags);
+ driver_pages += delta;
+ balloon_unlock(flags);
}
-void balloon_put_pages(unsigned long *mfn_list, unsigned long nr_mfns)
+static int dealloc_pte_fn(
+ pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
{
- unsigned long flags;
+ unsigned long mfn = pte_mfn(*pte);
+ int ret;
+ struct xen_memory_reservation reservation = {
+ .nr_extents = 1,
+ .extent_order = 0,
+ .domid = DOMID_SELF
+ };
+ set_xen_guest_handle(reservation.extent_start, &mfn);
+ set_pte_at(&init_mm, addr, pte, __pte_ma(0));
+ set_phys_to_machine(__pa(addr) >> PAGE_SHIFT, INVALID_P2M_ENTRY);
+ ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
+ BUG_ON(ret != 1);
+ return 0;
+}
- balloon_lock(flags);
- if ( HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation,
- mfn_list, nr_mfns, 0) != nr_mfns )
- BUG();
- current_pages -= nr_mfns; /* non-atomic update */
- balloon_unlock(flags);
+struct page *balloon_alloc_empty_page_range(unsigned long nr_pages)
+{
+ unsigned long vstart, flags;
+ unsigned int order = get_order(nr_pages * PAGE_SIZE);
+ int ret;
+ unsigned long i;
+ struct page *page;
+
+ vstart = __get_free_pages(GFP_KERNEL, order);
+ if (vstart == 0)
+ return NULL;
+
+ scrub_pages(vstart, 1 << order);
+
+ balloon_lock(flags);
+ if (xen_feature(XENFEAT_auto_translated_physmap)) {
+ unsigned long gmfn = __pa(vstart) >> PAGE_SHIFT;
+ struct xen_memory_reservation reservation = {
+ .nr_extents = 1,
+ .extent_order = order,
+ .domid = DOMID_SELF
+ };
+ set_xen_guest_handle(reservation.extent_start, &gmfn);
+ ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+ &reservation);
+ if (ret == -ENOSYS)
+ goto err;
+ BUG_ON(ret != 1);
+ } else {
+ ret = apply_to_page_range(&init_mm, vstart, PAGE_SIZE << order,
+ dealloc_pte_fn, NULL);
+ if (ret == -ENOSYS)
+ goto err;
+ BUG_ON(ret);
+ }
+ current_pages -= 1UL << order;
+ totalram_pages = current_pages;
+ balloon_unlock(flags);
+
+ schedule_work(&balloon_worker);
+
+ flush_tlb_all();
+
+ page = virt_to_page(vstart);
+
+ for (i = 0; i < (1UL << order); i++)
+ init_page_count(page + i);
+
+ return page;
+
+ err:
+ free_pages(vstart, order);
+ balloon_unlock(flags);
+ return NULL;
+}
- schedule_work(&balloon_worker);
+void balloon_dealloc_empty_page_range(
+ struct page *page, unsigned long nr_pages)
+{
+ unsigned long i, flags;
+ unsigned int order = get_order(nr_pages * PAGE_SIZE);
+
+ balloon_lock(flags);
+ for (i = 0; i < (1UL << order); i++) {
+ BUG_ON(page_count(page + i) != 1);
+ balloon_append(page + i);
+ }
+ balloon_unlock(flags);
+
+ schedule_work(&balloon_worker);
}
-EXPORT_SYMBOL(balloon_update_driver_allowance);
-EXPORT_SYMBOL(balloon_put_pages);
+EXPORT_SYMBOL_GPL(balloon_update_driver_allowance);
+EXPORT_SYMBOL_GPL(balloon_alloc_empty_page_range);
+EXPORT_SYMBOL_GPL(balloon_dealloc_empty_page_range);
+
+MODULE_LICENSE("Dual BSD/GPL");
+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
*
* 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 <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.
*
- * ** TRY INCREASING 'MAX_PENDING_REQS' IF WRITE SPEEDS SEEM TOO LOW **
+ * ** TRY INCREASING 'blkif_reqs' IF WRITE SPEEDS SEEM TOO LOW **
+ *
* This will increase the chances of being able to write whole tracks.
* 64 should be enough to keep us competitive with Linux.
*/
-#define MAX_PENDING_REQS 64
-#define BATCH_PER_DOMAIN 16
+static int blkif_reqs = 64;
+module_param_named(reqs, blkif_reqs, int, 0);
+MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate");
-static unsigned long mmap_vstart;
-#define MMAP_PAGES \
- (MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST)
-#define MMAP_VADDR(_req,_seg) \
- (mmap_vstart + \
- ((_req) * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE) + \
- ((_seg) * PAGE_SIZE))
+static int mmap_pages;
+
+/* Run-time switchable: /sys/module/blkback/parameters/ */
+static unsigned int log_stats = 0;
+static unsigned int debug_lvl = 0;
+module_param(log_stats, int, 0644);
+module_param(debug_lvl, int, 0644);
/*
* Each outstanding request that we've passed to the lower device layers has a
* response queued for it, with the saved 'id' passed back.
*/
typedef struct {
- blkif_t *blkif;
- unsigned long id;
- int nr_pages;
- atomic_t pendcnt;
- unsigned short operation;
- int status;
+ blkif_t *blkif;
+ unsigned long id;
+ int nr_pages;
+ atomic_t pendcnt;
+ unsigned short operation;
+ int status;
+ struct list_head free_list;
} pending_req_t;
-/*
- * We can't allocate pending_req's in order, since they may complete out of
- * order. We therefore maintain an allocation ring. This ring also indicates
- * when enough work has been passed down -- at that point the allocation ring
- * will be empty.
- */
-static pending_req_t pending_reqs[MAX_PENDING_REQS];
-static unsigned char pending_ring[MAX_PENDING_REQS];
-static spinlock_t pend_prod_lock = SPIN_LOCK_UNLOCKED;
-/* NB. We use a different index type to differentiate from shared blk rings. */
-typedef unsigned int PEND_RING_IDX;
-#define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1))
-static PEND_RING_IDX pending_prod, pending_cons;
-#define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons)
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static kmem_cache_t *buffer_head_cachep;
-#else
-static request_queue_t *plugged_queue;
-static inline void flush_plugged_queue(void)
-{
- request_queue_t *q = plugged_queue;
- if ( q != NULL )
- {
- if ( q->unplug_fn != NULL )
- q->unplug_fn(q);
- blk_put_queue(q);
- plugged_queue = NULL;
- }
-}
-#endif
+static pending_req_t *pending_reqs;
+static struct list_head pending_free;
+static DEFINE_SPINLOCK(pending_free_lock);
+static DECLARE_WAIT_QUEUE_HEAD(pending_free_wq);
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-/* When using grant tables to map a frame for device access then the
- * handle returned must be used to unmap the frame. This is needed to
- * drop the ref count on the frame.
- */
-static u16 pending_grant_handles[MMAP_PAGES];
-#define pending_handle(_idx, _i) \
- (pending_grant_handles[((_idx) * BLKIF_MAX_SEGMENTS_PER_REQUEST) + (_i)])
-#define BLKBACK_INVALID_HANDLE (0xFFFF)
-#endif
+#define BLKBACK_INVALID_HANDLE (~0)
-#ifdef CONFIG_XEN_BLKDEV_TAP_BE
-/*
- * If the tap driver is used, we may get pages belonging to either the tap
- * or (more likely) the real frontend. The backend must specify which domain
- * a given page belongs to in update_va_mapping though. For the moment,
- * the tap rewrites the ID field of the request to contain the request index
- * and the id of the real front end domain.
- */
-#define BLKTAP_COOKIE 0xbeadfeed
-static inline domid_t ID_TO_DOM(unsigned long id) { return (id >> 16); }
-#endif
+static unsigned long mmap_vstart;
+static unsigned long *pending_vaddrs;
+static grant_handle_t *pending_grant_handles;
-static int do_block_io_op(blkif_t *blkif, int max_to_do);
-static void dispatch_probe(blkif_t *blkif, blkif_request_t *req);
-static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req);
-static void make_response(blkif_t *blkif, unsigned long id,
- unsigned short op, int st);
+static inline int vaddr_pagenr(pending_req_t *req, int seg)
+{
+ return (req - pending_reqs) * BLKIF_MAX_SEGMENTS_PER_REQUEST + seg;
+}
-static void fast_flush_area(int idx, int nr_pages)
+static inline unsigned long vaddr(pending_req_t *req, int seg)
{
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- gnttab_op_t aop[BLKIF_MAX_SEGMENTS_PER_REQUEST];
- unsigned int i, invcount = 0;
- u16 handle;
-
- for ( i = 0; i < nr_pages; i++ )
- {
- if ( BLKBACK_INVALID_HANDLE != ( handle = pending_handle(idx, i) ) )
- {
- aop[i].u.unmap_grant_ref.host_virt_addr = MMAP_VADDR(idx, i);
- aop[i].u.unmap_grant_ref.dev_bus_addr = 0;
- aop[i].u.unmap_grant_ref.handle = handle;
- pending_handle(idx, i) = BLKBACK_INVALID_HANDLE;
- invcount++;
- }
- }
- if ( unlikely(HYPERVISOR_grant_table_op(
- GNTTABOP_unmap_grant_ref, aop, invcount)))
- BUG();
-#else
-
- multicall_entry_t mcl[BLKIF_MAX_SEGMENTS_PER_REQUEST];
- int i;
-
- for ( i = 0; i < nr_pages; i++ )
- {
- mcl[i].op = __HYPERVISOR_update_va_mapping;
- mcl[i].args[0] = MMAP_VADDR(idx, i);
- mcl[i].args[1] = 0;
- mcl[i].args[2] = 0;
- }
-
- mcl[nr_pages-1].args[2] = UVMF_TLB_FLUSH|UVMF_ALL;
- if ( unlikely(HYPERVISOR_multicall(mcl, nr_pages) != 0) )
- BUG();
-#endif
+ return pending_vaddrs[vaddr_pagenr(req, seg)];
}
+#define pending_handle(_req, _seg) \
+ (pending_grant_handles[vaddr_pagenr(_req, _seg)])
+
+
+static int do_block_io_op(blkif_t *blkif);
+static void dispatch_rw_block_io(blkif_t *blkif,
+ blkif_request_t *req,
+ pending_req_t *pending_req);
+static void make_response(blkif_t *blkif, unsigned long id,
+ unsigned short op, int st);
/******************************************************************
- * BLOCK-DEVICE SCHEDULER LIST MAINTENANCE
+ * misc small helpers
*/
+static pending_req_t* alloc_req(void)
+{
+ pending_req_t *req = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pending_free_lock, flags);
+ if (!list_empty(&pending_free)) {
+ req = list_entry(pending_free.next, pending_req_t, free_list);
+ list_del(&req->free_list);
+ }
+ spin_unlock_irqrestore(&pending_free_lock, flags);
+ return req;
+}
-static struct list_head blkio_schedule_list;
-static spinlock_t blkio_schedule_list_lock;
-
-static int __on_blkdev_list(blkif_t *blkif)
+static void free_req(pending_req_t *req)
{
- return blkif->blkdev_list.next != NULL;
+ unsigned long flags;
+ int was_empty;
+
+ spin_lock_irqsave(&pending_free_lock, flags);
+ was_empty = list_empty(&pending_free);
+ list_add(&req->free_list, &pending_free);
+ spin_unlock_irqrestore(&pending_free_lock, flags);
+ if (was_empty)
+ wake_up(&pending_free_wq);
}
-static void remove_from_blkdev_list(blkif_t *blkif)
+static void unplug_queue(blkif_t *blkif)
{
- unsigned long flags;
- if ( !__on_blkdev_list(blkif) ) return;
- spin_lock_irqsave(&blkio_schedule_list_lock, flags);
- if ( __on_blkdev_list(blkif) )
- {
- list_del(&blkif->blkdev_list);
- blkif->blkdev_list.next = NULL;
- blkif_put(blkif);
- }
- spin_unlock_irqrestore(&blkio_schedule_list_lock, flags);
+ if (blkif->plug == NULL)
+ return;
+ if (blkif->plug->unplug_fn)
+ blkif->plug->unplug_fn(blkif->plug);
+ blk_put_queue(blkif->plug);
+ blkif->plug = NULL;
}
-static void add_to_blkdev_list_tail(blkif_t *blkif)
+static void plug_queue(blkif_t *blkif, struct bio *bio)
{
- unsigned long flags;
- if ( __on_blkdev_list(blkif) ) return;
- spin_lock_irqsave(&blkio_schedule_list_lock, flags);
- if ( !__on_blkdev_list(blkif) && (blkif->status == CONNECTED) )
- {
- list_add_tail(&blkif->blkdev_list, &blkio_schedule_list);
- blkif_get(blkif);
- }
- spin_unlock_irqrestore(&blkio_schedule_list_lock, flags);
+ request_queue_t *q = bdev_get_queue(bio->bi_bdev);
+
+ if (q == blkif->plug)
+ return;
+ unplug_queue(blkif);
+ blk_get_queue(q);
+ blkif->plug = q;
}
+static void fast_flush_area(pending_req_t *req)
+{
+ struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+ unsigned int i, invcount = 0;
+ grant_handle_t handle;
+ int ret;
+
+ for (i = 0; i < req->nr_pages; i++) {
+ handle = pending_handle(req, i);
+ if (handle == BLKBACK_INVALID_HANDLE)
+ continue;
+ gnttab_set_unmap_op(&unmap[i], vaddr(req, i), GNTMAP_host_map,
+ handle);
+ pending_handle(req, i) = BLKBACK_INVALID_HANDLE;
+ invcount++;
+ }
+
+ ret = HYPERVISOR_grant_table_op(
+ GNTTABOP_unmap_grant_ref, unmap, invcount);
+ BUG_ON(ret);
+}
/******************************************************************
* SCHEDULER FUNCTIONS
*/
-static DECLARE_WAIT_QUEUE_HEAD(blkio_schedule_wait);
+static void print_stats(blkif_t *blkif)
+{
+ printk(KERN_DEBUG "%s: oo %3d | rd %4d | wr %4d\n",
+ current->comm, blkif->st_oo_req,
+ blkif->st_rd_req, blkif->st_wr_req);
+ blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
+ blkif->st_rd_req = 0;
+ blkif->st_wr_req = 0;
+ blkif->st_oo_req = 0;
+}
-static int blkio_schedule(void *arg)
+int blkif_schedule(void *arg)
{
- DECLARE_WAITQUEUE(wq, current);
+ blkif_t *blkif = arg;
- blkif_t *blkif;
- struct list_head *ent;
+ blkif_get(blkif);
- daemonize(
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- "xenblkd"
-#endif
- );
-
- for ( ; ; )
- {
- /* Wait for work to do. */
- add_wait_queue(&blkio_schedule_wait, &wq);
- set_current_state(TASK_INTERRUPTIBLE);
- if ( (NR_PENDING_REQS == MAX_PENDING_REQS) ||
- list_empty(&blkio_schedule_list) )
- schedule();
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(&blkio_schedule_wait, &wq);
-
- /* Queue up a batch of requests. */
- while ( (NR_PENDING_REQS < MAX_PENDING_REQS) &&
- !list_empty(&blkio_schedule_list) )
- {
- ent = blkio_schedule_list.next;
- blkif = list_entry(ent, blkif_t, blkdev_list);
- blkif_get(blkif);
- remove_from_blkdev_list(blkif);
- if ( do_block_io_op(blkif, BATCH_PER_DOMAIN) )
- add_to_blkdev_list_tail(blkif);
- blkif_put(blkif);
- }
-
- /* Push the batch through to disc. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- run_task_queue(&tq_disk);
-#else
- flush_plugged_queue();
-#endif
- }
-}
+ if (debug_lvl)
+ printk(KERN_DEBUG "%s: started\n", current->comm);
-static void maybe_trigger_blkio_schedule(void)
-{
- /*
- * Needed so that two processes, who together make the following predicate
- * true, don't both read stale values and evaluate the predicate
- * incorrectly. Incredibly unlikely to stall the scheduler on x86, but...
- */
- smp_mb();
-
- if ( (NR_PENDING_REQS < (MAX_PENDING_REQS/2)) &&
- !list_empty(&blkio_schedule_list) )
- wake_up(&blkio_schedule_wait);
-}
+ while (!kthread_should_stop()) {
+ wait_event_interruptible(
+ blkif->wq,
+ blkif->waiting_reqs || kthread_should_stop());
+ wait_event_interruptible(
+ pending_free_wq,
+ !list_empty(&pending_free) || kthread_should_stop());
+
+ blkif->waiting_reqs = 0;
+ smp_mb(); /* clear flag *before* checking for work */
+
+ if (do_block_io_op(blkif))
+ blkif->waiting_reqs = 1;
+ unplug_queue(blkif);
+ if (log_stats && time_after(jiffies, blkif->st_print))
+ print_stats(blkif);
+ }
+ if (log_stats)
+ print_stats(blkif);
+ if (debug_lvl)
+ printk(KERN_DEBUG "%s: exiting\n", current->comm);
+
+ blkif->xenblkd = NULL;
+ blkif_put(blkif);
+
+ return 0;
+}
/******************************************************************
* COMPLETION CALLBACK -- Called as bh->b_end_io()
static void __end_block_io_op(pending_req_t *pending_req, int uptodate)
{
- unsigned long flags;
-
- /* An error fails the entire request. */
- if ( !uptodate )
- {
- DPRINTK("Buffer not up-to-date at end of operation\n");
- pending_req->status = BLKIF_RSP_ERROR;
- }
-
- if ( atomic_dec_and_test(&pending_req->pendcnt) )
- {
- int pending_idx = pending_req - pending_reqs;
- fast_flush_area(pending_idx, pending_req->nr_pages);
- make_response(pending_req->blkif, pending_req->id,
- pending_req->operation, pending_req->status);
- blkif_put(pending_req->blkif);
- spin_lock_irqsave(&pend_prod_lock, flags);
- pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
- spin_unlock_irqrestore(&pend_prod_lock, flags);
- maybe_trigger_blkio_schedule();
- }
+ /* An error fails the entire request. */
+ if (!uptodate) {
+ DPRINTK("Buffer not up-to-date at end of operation\n");
+ pending_req->status = BLKIF_RSP_ERROR;
+ }
+
+ if (atomic_dec_and_test(&pending_req->pendcnt)) {
+ fast_flush_area(pending_req);
+ make_response(pending_req->blkif, pending_req->id,
+ pending_req->operation, pending_req->status);
+ blkif_put(pending_req->blkif);
+ free_req(pending_req);
+ }
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void end_block_io_op(struct buffer_head *bh, int uptodate)
-{
- __end_block_io_op(bh->b_private, uptodate);
- kmem_cache_free(buffer_head_cachep, bh);
-}
-#else
static int end_block_io_op(struct bio *bio, unsigned int done, int error)
{
- if ( done || error )
- __end_block_io_op(bio->bi_private, (done && !error));
- bio_put(bio);
- return error;
+ if (bio->bi_size != 0)
+ return 1;
+ __end_block_io_op(bio->bi_private, !error);
+ bio_put(bio);
+ return error;
}
-#endif
/******************************************************************************
* NOTIFICATION FROM GUEST OS.
*/
+static void blkif_notify_work(blkif_t *blkif)
+{
+ blkif->waiting_reqs = 1;
+ wake_up(&blkif->wq);
+}
+
irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
{
- blkif_t *blkif = dev_id;
- add_to_blkdev_list_tail(blkif);
- maybe_trigger_blkio_schedule();
- return IRQ_HANDLED;
+ blkif_notify_work(dev_id);
+ return IRQ_HANDLED;
}
* 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);
}
static void make_response(blkif_t *blkif, unsigned long id,
- unsigned short op, int st)
+ unsigned short op, int st)
{
- blkif_response_t *resp;
- unsigned long flags;
- blkif_back_ring_t *blk_ring = &blkif->blk_ring;
-
- /* Place on the response ring for the relevant domain. */
- spin_lock_irqsave(&blkif->blk_ring_lock, flags);
- resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt);
- resp->id = id;
- resp->operation = op;
- resp->status = st;
- wmb(); /* Ensure other side can see the response fields. */
- blk_ring->rsp_prod_pvt++;
- RING_PUSH_RESPONSES(blk_ring);
- spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
-
- /* Kick the relevant domain. */
- notify_via_evtchn(blkif->evtchn);
-}
-
-void blkif_deschedule(blkif_t *blkif)
-{
- remove_from_blkdev_list(blkif);
+ blkif_response_t *resp;
+ unsigned long flags;
+ blkif_back_ring_t *blk_ring = &blkif->blk_ring;
+ int more_to_do = 0;
+ int notify;
+
+ spin_lock_irqsave(&blkif->blk_ring_lock, flags);
+
+ /* Place on the response ring for the relevant domain. */
+ resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt);
+ resp->id = id;
+ resp->operation = op;
+ resp->status = st;
+ blk_ring->rsp_prod_pvt++;
+ RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify);
+
+ if (blk_ring->rsp_prod_pvt == blk_ring->req_cons) {
+ /*
+ * Tail check for pending requests. Allows frontend to avoid
+ * notifications if requests are already in flight (lower
+ * overheads and promotes batching).
+ */
+ RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do);
+
+ } else if (RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) {
+ more_to_do = 1;
+
+ }
+ spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
+
+ if (more_to_do)
+ blkif_notify_work(blkif);
+ if (notify)
+ notify_remote_via_irq(blkif->irq);
}
static int __init blkif_init(void)
{
- int i;
-
- if ( !(xen_start_info.flags & SIF_INITDOMAIN) &&
- !(xen_start_info.flags & SIF_BLK_BE_DOMAIN) )
- return 0;
-
- blkif_interface_init();
-
- if ( (mmap_vstart = allocate_empty_lowmem_region(MMAP_PAGES)) == 0 )
- BUG();
-
- pending_cons = 0;
- pending_prod = MAX_PENDING_REQS;
- memset(pending_reqs, 0, sizeof(pending_reqs));
- for ( i = 0; i < MAX_PENDING_REQS; i++ )
- pending_ring[i] = i;
-
- spin_lock_init(&blkio_schedule_list_lock);
- INIT_LIST_HEAD(&blkio_schedule_list);
-
- if ( kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES) < 0 )
- BUG();
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- buffer_head_cachep = kmem_cache_create(
- "buffer_head_cache", sizeof(struct buffer_head),
- 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+ struct page *page;
+ int i;
+
+ if (!is_running_on_xen())
+ return -ENODEV;
+
+ mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
+
+#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
+ extern unsigned long alloc_empty_foreign_map_page_range(
+ unsigned long pages);
+ mmap_vstart = (unsigned long)
+ alloc_empty_foreign_map_page_range(mmap_pages);
+#else /* ! ia64 */
+ page = balloon_alloc_empty_page_range(mmap_pages);
+ if (page == NULL)
+ return -ENOMEM;
+ mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
#endif
- blkif_ctrlif_init();
+ pending_reqs = kmalloc(sizeof(pending_reqs[0]) *
+ blkif_reqs, GFP_KERNEL);
+ pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) *
+ mmap_pages, GFP_KERNEL);
+ pending_vaddrs = kmalloc(sizeof(pending_vaddrs[0]) *
+ mmap_pages, GFP_KERNEL);
+ if (!pending_reqs || !pending_grant_handles || !pending_vaddrs) {
+ kfree(pending_reqs);
+ kfree(pending_grant_handles);
+ kfree(pending_vaddrs);
+ printk("%s: out of memory\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ blkif_interface_init();
+
+ printk("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
+ __FUNCTION__, blkif_reqs, mmap_pages, mmap_vstart);
+ BUG_ON(mmap_vstart == 0);
+ for (i = 0; i < mmap_pages; i++) {
+ pending_vaddrs[i] = mmap_vstart + (i << PAGE_SHIFT);
+ pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
+ }
+
+ memset(pending_reqs, 0, sizeof(pending_reqs));
+ INIT_LIST_HEAD(&pending_free);
+
+ for (i = 0; i < blkif_reqs; i++)
+ list_add_tail(&pending_reqs[i].free_list, &pending_free);
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- memset( pending_grant_handles, BLKBACK_INVALID_HANDLE, MMAP_PAGES );
- printk(KERN_ALERT "Blkif backend is using grant tables.\n");
-#endif
+ blkif_xenbus_init();
-#ifdef CONFIG_XEN_BLKDEV_TAP_BE
- printk(KERN_ALERT "NOTE: Blkif backend is running with tap support on!\n");
-#endif
-
- return 0;
+ return 0;
}
-__initcall(blkif_init);
+module_init(blkif_init);
+
+MODULE_LICENSE("Dual BSD/GPL");
+/*
+ * 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__
#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/vmalloc.h>
+#include <linux/wait.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 {
- /* Unique identifier for this interface. */
- domid_t domid;
- unsigned int handle;
- /* Physical parameters of the comms window. */
- unsigned long shmem_frame;
- unsigned int evtchn;
- int irq;
- /* Comms information. */
- blkif_back_ring_t blk_ring;
- /* VBDs attached to this interface. */
- rb_root_t vbd_rb; /* Mapping from 16-bit vdevices to VBDs.*/
- spinlock_t vbd_lock; /* Protects VBD mapping. */
- /* Private fields. */
- enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
- /*
- * DISCONNECT response is deferred until pending requests are ack'ed.
- * We therefore need to store the id from the original request.
- */
- u8 disconnect_rspid;
-#ifdef CONFIG_XEN_BLKDEV_TAP_BE
- /* Is this a blktap frontend */
- unsigned int is_blktap;
-#endif
- struct blkif_st *hash_next;
- struct list_head blkdev_list;
- spinlock_t blk_ring_lock;
- atomic_t refcnt;
-
- struct work_struct work;
+ /* Unique identifier for this interface. */
+ domid_t domid;
+ unsigned int handle;
+ /* Physical parameters of the comms window. */
+ unsigned int evtchn;
+ unsigned int irq;
+ /* Comms information. */
+ blkif_back_ring_t blk_ring;
+ struct vm_struct *blk_ring_area;
+ /* The VBD attached to this interface. */
+ struct vbd vbd;
+ /* Back pointer to the backend_info. */
+ struct backend_info *be;
+ /* Private fields. */
+ spinlock_t blk_ring_lock;
+ atomic_t refcnt;
+
+ wait_queue_head_t wq;
+ struct task_struct *xenblkd;
+ unsigned int waiting_reqs;
+ request_queue_t *plug;
+
+ /* statistics */
+ unsigned long st_print;
+ int st_rd_req;
+ int st_wr_req;
+ int st_oo_req;
+
+ wait_queue_head_t waiting_to_free;
+
+ grant_handle_t shmem_handle;
+ grant_ref_t shmem_ref;
} blkif_t;
-void blkif_create(blkif_be_create_t *create);
-void blkif_destroy(blkif_be_destroy_t *destroy);
-void blkif_connect(blkif_be_connect_t *connect);
-int blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id);
-void blkif_disconnect_complete(blkif_t *blkif);
-blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle);
+blkif_t *blkif_alloc(domid_t domid);
+void blkif_disconnect(blkif_t *blkif);
+void blkif_free(blkif_t *blkif);
+int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
+
#define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
-#define blkif_put(_b) \
- do { \
- if ( atomic_dec_and_test(&(_b)->refcnt) ) \
- blkif_disconnect_complete(_b); \
- } while (0)
+#define blkif_put(_b) \
+ do { \
+ if (atomic_dec_and_test(&(_b)->refcnt)) \
+ wake_up(&(_b)->waiting_to_free);\
+ } while (0)
+
+/* Create a vbd. */
+int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, unsigned major,
+ unsigned minor, int readonly);
+void vbd_free(struct vbd *vbd);
-void vbd_create(blkif_be_vbd_create_t *create);
-void vbd_destroy(blkif_be_vbd_destroy_t *delete);
-int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds);
-void destroy_all_vbds(blkif_t *blkif);
+unsigned long vbd_size(struct vbd *vbd);
+unsigned int vbd_info(struct vbd *vbd);
+unsigned long vbd_secsize(struct vbd *vbd);
struct phys_req {
- unsigned short dev;
- unsigned short nr_sects;
- struct block_device *bdev;
- blkif_sector_t sector_number;
+ unsigned short dev;
+ unsigned short nr_sects;
+ struct block_device *bdev;
+ blkif_sector_t sector_number;
};
int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation);
void blkif_interface_init(void);
-void blkif_ctrlif_init(void);
-void blkif_deschedule(blkif_t *blkif);
+void blkif_xenbus_init(void);
irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
+int blkif_schedule(void *arg);
#endif /* __BLKIF__BACKEND__COMMON_H__ */
* Block-device interface management.
*
* Copyright (c) 2004, Keir Fraser
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
*/
#include "common.h"
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#endif
-
-#define BLKIF_HASHSZ 1024
-#define BLKIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(BLKIF_HASHSZ-1))
+#include <xen/evtchn.h>
+#include <linux/kthread.h>
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)
{
- 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);
}
*
* Routines for managing virtual block devices (VBDs).
*
- * NOTE: vbd_lock protects updates to the rb_tree against concurrent lookups
- * in vbd_translate. All other lookups are implicitly protected because the
- * only caller (the control message dispatch routine) serializes the calls.
- *
* Copyright (c) 2003-2005, Keir Fraser & Steve Hand
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
*/
#include "common.h"
+#include <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)
{
- struct vbd *vbd;
- rb_node_t *rb;
- int rc = -EACCES;
-
- /* Take the vbd_lock because another thread could be updating the tree. */
- spin_lock(&blkif->vbd_lock);
-
- rb = blkif->vbd_rb.rb_node;
- while ( rb != NULL )
- {
- vbd = rb_entry(rb, struct vbd, rb);
- if ( req->dev < vbd->vdevice )
- rb = rb->rb_left;
- else if ( req->dev > vbd->vdevice )
- rb = rb->rb_right;
- else
- goto found;
- }
-
- DPRINTK("vbd_translate; domain %u attempted to access "
- "non-existent VBD.\n", blkif->domid);
- rc = -ENODEV;
- goto out;
-
- found:
+ struct vbd *vbd = &blkif->vbd;
+ int rc = -EACCES;
- if ( (operation == WRITE) && vbd->readonly )
- goto out;
+ if ((operation == WRITE) && vbd->readonly)
+ goto out;
- if ( unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd)) )
- goto out;
+ if (unlikely((req->sector_number + req->nr_sects) > vbd_sz(vbd)))
+ goto out;
- req->dev = vbd->pdevice;
- req->bdev = vbd->bdev;
- rc = 0;
+ req->dev = vbd->pdevice;
+ req->bdev = vbd->bdev;
+ rc = 0;
out:
- spin_unlock(&blkif->vbd_lock);
- return rc;
+ return rc;
}
-obj-y := blkfront.o vbd.o
+obj-$(CONFIG_XEN_BLKDEV_FRONTEND) := xenblk.o
+
+xenblk-objs := blkfront.o vbd.o
* 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
* 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>
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
#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 <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", §ors,
+ "info", "%u", &binfo,
+ "sector-size", "%lu", §or_size,
+ NULL);
+ if (err) {
+ xenbus_dev_fatal(info->xbdev, err,
+ "reading backend fields at %s",
+ info->xbdev->otherend);
+ return;
+ }
+
+ err = xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
+ if (err) {
+ xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
+ info->xbdev->otherend);
+ return;
+ }
+
+ (void)xenbus_switch_state(info->xbdev, XenbusStateConnected);
+
+ /* Kick pending requests. */
+ spin_lock_irq(&blkif_io_lock);
+ info->connected = BLKIF_STATE_CONNECTED;
+ kick_pending_request_queues(info);
+ spin_unlock_irq(&blkif_io_lock);
+
+ add_disk(info->gd);
+}
+
+/**
+ * Handle the change of state of the backend to Closing. We must delete our
+ * device-layer structures now, to ensure that writes are flushed through to
+ * the backend. Once is this done, we can switch to Closed in
+ * acknowledgement.
+ */
+static void blkfront_closing(struct xenbus_device *dev)
{
- DISABLE_SCATTERGATHER();
- RING_PUSH_REQUESTS(&blk_ring);
- notify_via_evtchn(blkif_evtchn);
-}
+ struct blkfront_info *info = dev->dev.driver_data;
+ unsigned long flags;
+ DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
-/************************** KERNEL VERSION 2.6 **************************/
+ if (info->rq == NULL)
+ return;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ spin_lock_irqsave(&blkif_io_lock, flags);
+ /* No more blkif_request(). */
+ blk_stop_queue(info->rq);
+ /* No more gnttab callback work. */
+ gnttab_cancel_free_callback(&info->callback);
+ flush_scheduled_work();
+ spin_unlock_irqrestore(&blkif_io_lock, flags);
-module_init(xlblk_init);
+ xlvbd_del(info);
-#if ENABLE_VBD_UPDATE
-static void update_vbds_task(void *unused)
-{
- xlvbd_update_vbds();
+ xenbus_switch_state(dev, XenbusStateClosed);
}
-static void vbd_update(void)
-{
- static DECLARE_WORK(update_tq, update_vbds_task, NULL);
- schedule_work(&update_tq);
-}
-#endif /* ENABLE_VBD_UPDATE */
-static void kick_pending_request_queues(void)
+static int blkfront_remove(struct xenbus_device *dev)
{
- if ( (xlbd_blk_queue != NULL) &&
- test_bit(QUEUE_FLAG_STOPPED, &xlbd_blk_queue->queue_flags) )
- {
- blk_start_queue(xlbd_blk_queue);
- /* XXXcl call to request_fn should not be needed but
- * we get stuck without... needs investigating
- */
- xlbd_blk_queue->request_fn(xlbd_blk_queue);
- }
-}
+ struct blkfront_info *info = dev->dev.driver_data;
+ DPRINTK("blkfront_remove: %s removed\n", dev->nodename);
-int blkif_open(struct inode *inode, struct file *filep)
-{
- struct gendisk *gd = inode->i_bdev->bd_disk;
- struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
+ blkif_free(info, 0);
- /* Update of usage count is protected by per-device semaphore. */
- di->mi->usage++;
-
- return 0;
-}
+ kfree(info);
-
-int blkif_release(struct inode *inode, struct file *filep)
-{
- struct gendisk *gd = inode->i_bdev->bd_disk;
- struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
-
- /*
- * When usage drops to zero it may allow more VBD updates to occur.
- * Update of usage count is protected by a per-device semaphore.
- */
- if ( --di->mi->usage == 0 )
- vbd_update();
-
- return 0;
+ return 0;
}
-int blkif_ioctl(struct inode *inode, struct file *filep,
- unsigned command, unsigned long argument)
+static inline int GET_ID_FROM_FREELIST(
+ struct blkfront_info *info)
{
- int i;
-
- DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
- command, (long)argument, inode->i_rdev);
-
- switch ( command )
- {
- case HDIO_GETGEO:
- /* return ENOSYS to use defaults */
- return -ENOSYS;
-
- case CDROMMULTISESSION:
- DPRINTK("FIXME: support multisession CDs later\n");
- for ( i = 0; i < sizeof(struct cdrom_multisession); i++ )
- if ( put_user(0, (byte *)(argument + i)) ) return -EFAULT;
- return 0;
-
- default:
- printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n",
- command);
- return -ENOSYS;
- }
-
- return 0;
+ unsigned long free = info->shadow_free;
+ BUG_ON(free > BLK_RING_SIZE);
+ info->shadow_free = info->shadow[free].req.id;
+ info->shadow[free].req.id = 0x0fffffee; /* debug */
+ return free;
}
-
-/*
- * blkif_queue_request
- *
- * request block io
- *
- * id: for guest use only.
- * operation: BLKIF_OP_{READ,WRITE,PROBE}
- * buffer: buffer to read/write into. this should be a
- * virtual address in the guest os.
- */
-static int blkif_queue_request(struct request *req)
+static inline void ADD_ID_TO_FREELIST(
+ struct blkfront_info *info, unsigned long id)
{
- struct xlbd_disk_info *di =
- (struct xlbd_disk_info *)req->rq_disk->private_data;
- unsigned long buffer_ma;
- blkif_request_t *ring_req;
- struct bio *bio;
- struct bio_vec *bvec;
- int idx;
- unsigned long id;
- unsigned int fsect, lsect;
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- int ref;
-#endif
-
- if ( unlikely(blkif_state != BLKIF_STATE_CONNECTED) )
- return 1;
-
- /* Fill out a communications ring structure. */
- ring_req = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
- id = GET_ID_FROM_FREELIST();
- blk_shadow[id].request = (unsigned long)req;
-
- ring_req->id = id;
- ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE :
- BLKIF_OP_READ;
- ring_req->sector_number = (blkif_sector_t)req->sector;
- ring_req->device = di->xd_device;
-
- ring_req->nr_segments = 0;
- rq_for_each_bio(bio, req)
- {
- bio_for_each_segment(bvec, bio, idx)
- {
- if ( ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST )
- BUG();
- buffer_ma = page_to_phys(bvec->bv_page);
- fsect = bvec->bv_offset >> 9;
- lsect = fsect + (bvec->bv_len >> 9) - 1;
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- /* install a grant reference. */
- ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
- ASSERT( ref != -ENOSPC );
-
- gnttab_grant_foreign_access_ref(
- ref,
- rdomid,
- buffer_ma >> PAGE_SHIFT,
- rq_data_dir(req) );
-
- blk_shadow[id].frame[ring_req->nr_segments] =
- buffer_ma >> PAGE_SHIFT;
-
- ring_req->frame_and_sects[ring_req->nr_segments++] =
- (((u32) ref) << 16) | (fsect << 3) | lsect;
-
-#else
- ring_req->frame_and_sects[ring_req->nr_segments++] =
- buffer_ma | (fsect << 3) | lsect;
-#endif
- }
- }
-
- blk_ring.req_prod_pvt++;
-
- /* Keep a private copy so we can reissue requests when recovering. */
- pickle_request(&blk_shadow[id], ring_req);
-
- return 0;
+ info->shadow[id].req.id = info->shadow_free;
+ info->shadow[id].request = 0;
+ info->shadow_free = id;
}
-
-/*
- * do_blkif_request
- * read a block; request is in a request queue
- */
-void do_blkif_request(request_queue_t *rq)
+static inline void flush_requests(struct blkfront_info *info)
{
- struct request *req;
- int queued;
-
- DPRINTK("Entered do_blkif_request\n");
-
- queued = 0;
-
- while ( (req = elv_next_request(rq)) != NULL )
- {
- if ( !blk_fs_request(req) )
- {
- end_request(req, 0);
- continue;
- }
-
- if ( RING_FULL(&blk_ring) )
- {
- blk_stop_queue(rq);
- break;
- }
-
- DPRINTK("do_blk_req %p: cmd %p, sec %lx, (%u/%li) buffer:%p [%s]\n",
- req, req->cmd, req->sector, req->current_nr_sectors,
- req->nr_sectors, req->buffer,
- rq_data_dir(req) ? "write" : "read");
-
- blkdev_dequeue_request(req);
- if ( blkif_queue_request(req) )
- {
- blk_stop_queue(rq);
- break;
- }
-
- queued++;
- }
-
- if ( queued != 0 )
- flush_requests();
-}
+ int notify;
+ RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->ring, notify);
-static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
-{
- struct request *req;
- blkif_response_t *bret;
- RING_IDX i, rp;
- unsigned long flags;
-
- spin_lock_irqsave(&blkif_io_lock, flags);
-
- if ( unlikely(blkif_state == BLKIF_STATE_CLOSED) ||
- unlikely(recovery) )
- {
- spin_unlock_irqrestore(&blkif_io_lock, flags);
- return IRQ_HANDLED;
- }
-
- rp = blk_ring.sring->rsp_prod;
- rmb(); /* Ensure we see queued responses up to 'rp'. */
-
- for ( i = blk_ring.rsp_cons; i != rp; i++ )
- {
- unsigned long id;
-
- bret = RING_GET_RESPONSE(&blk_ring, i);
- id = bret->id;
- req = (struct request *)blk_shadow[id].request;
-
- blkif_completion(&blk_shadow[id]);
-
- ADD_ID_TO_FREELIST(id);
-
- switch ( bret->operation )
- {
- case BLKIF_OP_READ:
- case BLKIF_OP_WRITE:
- if ( unlikely(bret->status != BLKIF_RSP_OKAY) )
- DPRINTK("Bad return from blkdev data request: %x\n",
- bret->status);
-
- if ( unlikely(end_that_request_first
- (req,
- (bret->status == BLKIF_RSP_OKAY),
- req->hard_nr_sectors)) )
- BUG();
- end_that_request_last(req);
-
- break;
- case BLKIF_OP_PROBE:
- memcpy(&blkif_control_rsp, bret, sizeof(*bret));
- blkif_control_rsp_valid = 1;
- break;
- default:
- BUG();
- }
- }
-
- blk_ring.rsp_cons = i;
-
- kick_pending_request_queues();
-
- spin_unlock_irqrestore(&blkif_io_lock, flags);
-
- return IRQ_HANDLED;
+ if (notify)
+ notify_remote_via_irq(info->irq);
}
-#else
-/************************** KERNEL VERSION 2.4 **************************/
-
-static kdev_t sg_dev;
-static unsigned long sg_next_sect;
-
-/*
- * Request queues with outstanding work, but ring is currently full.
- * We need no special lock here, as we always access this with the
- * blkif_io_lock held. We only need a small maximum list.
- */
-#define MAX_PENDING 8
-static request_queue_t *pending_queues[MAX_PENDING];
-static int nr_pending;
-
-
-#define blkif_io_lock io_request_lock
-
-/*============================================================================*/
-#if ENABLE_VBD_UPDATE
-
-/*
- * blkif_update_int/update-vbds_task - handle VBD update events.
- * Schedule a task for keventd to run, which will update the VBDs and perform
- * the corresponding updates to our view of VBD state.
- */
-static void update_vbds_task(void *unused)
-{
- xlvbd_update_vbds();
+static void kick_pending_request_queues(struct blkfront_info *info)
+{
+ if (!RING_FULL(&info->ring)) {
+ /* Re-enable calldowns. */
+ blk_start_queue(info->rq);
+ /* Kick things off immediately. */
+ do_blkif_request(info->rq);
+ }
}
-static void vbd_update(void)
+static void blkif_restart_queue(void *arg)
{
- static struct tq_struct update_tq;
- update_tq.routine = update_vbds_task;
- schedule_task(&update_tq);
+ struct blkfront_info *info = (struct blkfront_info *)arg;
+ spin_lock_irq(&blkif_io_lock);
+ if (info->connected == BLKIF_STATE_CONNECTED)
+ kick_pending_request_queues(info);
+ spin_unlock_irq(&blkif_io_lock);
}
-#endif /* ENABLE_VBD_UPDATE */
-/*============================================================================*/
-
-static void kick_pending_request_queues(void)
+static void blkif_restart_queue_callback(void *arg)
{
- /* We kick pending request queues if the ring is reasonably empty. */
- if ( (nr_pending != 0) &&
- (RING_PENDING_REQUESTS(&blk_ring) < (BLK_RING_SIZE >> 1)) )
- {
- /* Attempt to drain the queue, but bail if the ring becomes full. */
- while ( (nr_pending != 0) && !RING_FULL(&blk_ring) )
- do_blkif_request(pending_queues[--nr_pending]);
- }
+ struct blkfront_info *info = (struct blkfront_info *)arg;
+ schedule_work(&info->work);
}
int blkif_open(struct inode *inode, struct file *filep)
{
- short xldev = inode->i_rdev;
- struct gendisk *gd = get_gendisk(xldev);
- xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev);
- short minor = MINOR(xldev);
-
- if ( gd->part[minor].nr_sects == 0 )
- {
- /*
- * Device either doesn't exist, or has zero capacity; we use a few
- * cheesy heuristics to return the relevant error code
- */
- if ( (gd->sizes[minor >> gd->minor_shift] != 0) ||
- ((minor & (gd->max_p - 1)) != 0) )
- {
- /*
- * We have a real device, but no such partition, or we just have a
- * partition number so guess this is the problem.
- */
- return -ENXIO; /* no such device or address */
- }
- else if ( gd->flags[minor >> gd->minor_shift] & GENHD_FL_REMOVABLE )
- {
- /* This is a removable device => assume that media is missing. */
- return -ENOMEDIUM; /* media not present (this is a guess) */
- }
- else
- {
- /* Just go for the general 'no such device' error. */
- return -ENODEV; /* no such device */
- }
- }
-
- /* Update of usage count is protected by per-device semaphore. */
- disk->usage++;
-
- return 0;
+ struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
+ info->users++;
+ return 0;
}
int blkif_release(struct inode *inode, struct file *filep)
{
- xl_disk_t *disk = xldev_to_xldisk(inode->i_rdev);
+ struct blkfront_info *info = inode->i_bdev->bd_disk->private_data;
+ info->users--;
+ if (info->users == 0) {
+ /* Check whether we have been instructed to close. We will
+ have ignored this request initially, as the device was
+ still mounted. */
+ struct xenbus_device * dev = info->xbdev;
+ enum xenbus_state state = xenbus_read_driver_state(dev->otherend);
- /*
- * When usage drops to zero it may allow more VBD updates to occur.
- * Update of usage count is protected by a per-device semaphore.
- */
- if ( --disk->usage == 0 ) {
- vbd_update();
- }
-
- return 0;
+ if (state == XenbusStateClosing)
+ blkfront_closing(dev);
+ }
+ return 0;
}
int blkif_ioctl(struct inode *inode, struct file *filep,
- unsigned command, unsigned long argument)
+ unsigned command, unsigned long argument)
{
- kdev_t dev = inode->i_rdev;
- struct hd_geometry *geo = (struct hd_geometry *)argument;
- struct gendisk *gd;
- struct hd_struct *part;
- int i;
- unsigned short cylinders;
- byte heads, sectors;
-
- /* NB. No need to check permissions. That is done for us. */
-
- DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
- command, (long) argument, dev);
-
- gd = get_gendisk(dev);
- part = &gd->part[MINOR(dev)];
-
- switch ( command )
- {
- case BLKGETSIZE:
- DPRINTK_IOCTL(" BLKGETSIZE: %x %lx\n", BLKGETSIZE, part->nr_sects);
- return put_user(part->nr_sects, (unsigned long *) argument);
-
- case BLKGETSIZE64:
- DPRINTK_IOCTL(" BLKGETSIZE64: %x %llx\n", BLKGETSIZE64,
- (u64)part->nr_sects * 512);
- return put_user((u64)part->nr_sects * 512, (u64 *) argument);
-
- case BLKRRPART: /* re-read partition table */
- DPRINTK_IOCTL(" BLKRRPART: %x\n", BLKRRPART);
- return blkif_revalidate(dev);
-
- case BLKSSZGET:
- return hardsect_size[MAJOR(dev)][MINOR(dev)];
-
- case BLKBSZGET: /* get block size */
- DPRINTK_IOCTL(" BLKBSZGET: %x\n", BLKBSZGET);
- break;
-
- case BLKBSZSET: /* set block size */
- DPRINTK_IOCTL(" BLKBSZSET: %x\n", BLKBSZSET);
- break;
-
- case BLKRASET: /* set read-ahead */
- DPRINTK_IOCTL(" BLKRASET: %x\n", BLKRASET);
- break;
-
- case BLKRAGET: /* get read-ahead */
- DPRINTK_IOCTL(" BLKRAFET: %x\n", BLKRAGET);
- break;
-
- case HDIO_GETGEO:
- DPRINTK_IOCTL(" HDIO_GETGEO: %x\n", HDIO_GETGEO);
- if (!argument) return -EINVAL;
-
- /* We don't have real geometry info, but let's at least return
- values consistent with the size of the device */
-
- heads = 0xff;
- sectors = 0x3f;
- cylinders = part->nr_sects / (heads * sectors);
-
- if (put_user(0x00, (unsigned long *) &geo->start)) return -EFAULT;
- if (put_user(heads, (byte *)&geo->heads)) return -EFAULT;
- if (put_user(sectors, (byte *)&geo->sectors)) return -EFAULT;
- if (put_user(cylinders, (unsigned short *)&geo->cylinders)) return -EFAULT;
-
- return 0;
-
- case HDIO_GETGEO_BIG:
- DPRINTK_IOCTL(" HDIO_GETGEO_BIG: %x\n", HDIO_GETGEO_BIG);
- if (!argument) return -EINVAL;
-
- /* We don't have real geometry info, but let's at least return
- values consistent with the size of the device */
-
- heads = 0xff;
- sectors = 0x3f;
- cylinders = part->nr_sects / (heads * sectors);
-
- if (put_user(0x00, (unsigned long *) &geo->start)) return -EFAULT;
- if (put_user(heads, (byte *)&geo->heads)) return -EFAULT;
- if (put_user(sectors, (byte *)&geo->sectors)) return -EFAULT;
- if (put_user(cylinders, (unsigned int *) &geo->cylinders)) return -EFAULT;
-
- return 0;
-
- case CDROMMULTISESSION:
- DPRINTK("FIXME: support multisession CDs later\n");
- for ( i = 0; i < sizeof(struct cdrom_multisession); i++ )
- if ( put_user(0, (byte *)(argument + i)) ) return -EFAULT;
- return 0;
-
- case SCSI_IOCTL_GET_BUS_NUMBER:
- DPRINTK("FIXME: SCSI_IOCTL_GET_BUS_NUMBER ioctl in XL blkif");
- return -ENOSYS;
-
- default:
- printk(KERN_ALERT "ioctl %08x not supported by XL blkif\n", command);
- return -ENOSYS;
- }
-
- return 0;
-}
+ int i;
+ DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
+ command, (long)argument, inode->i_rdev);
+ switch (command) {
+ case CDROMMULTISESSION:
+ DPRINTK("FIXME: support multisession CDs later\n");
+ for (i = 0; i < sizeof(struct cdrom_multisession); i++)
+ if (put_user(0, (char __user *)(argument + i)))
+ return -EFAULT;
+ return 0;
-/* check media change: should probably do something here in some cases :-) */
-int blkif_check(kdev_t dev)
-{
- DPRINTK("blkif_check\n");
- return 0;
+ default:
+ /*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n",
+ command);*/
+ return -EINVAL; /* same return as native Linux */
+ }
+
+ return 0;
}
-int blkif_revalidate(kdev_t dev)
+
+int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg)
{
- struct block_device *bd;
- struct gendisk *gd;
- xl_disk_t *disk;
- unsigned long capacity;
- int i, rc = 0;
-
- if ( (bd = bdget(dev)) == NULL )
- return -EINVAL;
-
- /*
- * Update of partition info, and check of usage count, is protected
- * by the per-block-device semaphore.
- */
- down(&bd->bd_sem);
-
- if ( ((gd = get_gendisk(dev)) == NULL) ||
- ((disk = xldev_to_xldisk(dev)) == NULL) ||
- ((capacity = gd->part[MINOR(dev)].nr_sects) == 0) )
- {
- rc = -EINVAL;
- goto out;
- }
-
- if ( disk->usage > 1 )
- {
- rc = -EBUSY;
- goto out;
- }
-
- /* Only reread partition table if VBDs aren't mapped to partitions. */
- if ( !(gd->flags[MINOR(dev) >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS) )
- {
- for ( i = gd->max_p - 1; i >= 0; i-- )
- {
- invalidate_device(dev+i, 1);
- gd->part[MINOR(dev+i)].start_sect = 0;
- gd->part[MINOR(dev+i)].nr_sects = 0;
- gd->sizes[MINOR(dev+i)] = 0;
- }
-
- grok_partitions(gd, MINOR(dev)>>gd->minor_shift, gd->max_p, capacity);
- }
+ /* We don't have real geometry info, but let's at least return
+ values consistent with the size of the device */
+ sector_t nsect = get_capacity(bd->bd_disk);
+ sector_t cylinders = nsect;
- out:
- up(&bd->bd_sem);
- bdput(bd);
- return rc;
+ hg->heads = 0xff;
+ hg->sectors = 0x3f;
+ sector_div(cylinders, hg->heads * hg->sectors);
+ hg->cylinders = cylinders;
+ if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect)
+ hg->cylinders = 0xffff;
+ return 0;
}
/*
* blkif_queue_request
*
- * request block io
- *
+ * request block io
+ *
* id: for guest use only.
* operation: BLKIF_OP_{READ,WRITE,PROBE}
* buffer: buffer to read/write into. this should be a
* virtual address in the guest os.
*/
-static int blkif_queue_request(unsigned long id,
- int operation,
- char * buffer,
- unsigned long sector_number,
- unsigned short nr_sectors,
- kdev_t device)
+static int blkif_queue_request(struct request *req)
{
- unsigned long buffer_ma = virt_to_bus(buffer);
- unsigned long xid;
- struct gendisk *gd;
- blkif_request_t *req;
- struct buffer_head *bh;
- unsigned int fsect, lsect;
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- int ref;
-#endif
-
- fsect = (buffer_ma & ~PAGE_MASK) >> 9;
- lsect = fsect + nr_sectors - 1;
-
- /* Buffer must be sector-aligned. Extent mustn't cross a page boundary. */
- if ( unlikely((buffer_ma & ((1<<9)-1)) != 0) )
- BUG();
- if ( lsect > 7 )
- BUG();
-
- buffer_ma &= PAGE_MASK;
-
- if ( unlikely(blkif_state != BLKIF_STATE_CONNECTED) )
- return 1;
-
- switch ( operation )
- {
-
- case BLKIF_OP_READ:
- case BLKIF_OP_WRITE:
- gd = get_gendisk(device);
-
- /*
- * Update the sector_number we'll pass down as appropriate; note that
- * we could sanity check that resulting sector will be in this
- * partition, but this will happen in driver backend anyhow.
- */
- sector_number += gd->part[MINOR(device)].start_sect;
-
- /*
- * If this unit doesn't consist of virtual partitions then we clear
- * the partn bits from the device number.
- */
- if ( !(gd->flags[MINOR(device)>>gd->minor_shift] &
- GENHD_FL_VIRT_PARTNS) )
- device &= ~(gd->max_p - 1);
-
- if ( (sg_operation == operation) &&
- (sg_dev == device) &&
- (sg_next_sect == sector_number) )
- {
- req = RING_GET_REQUEST(&blk_ring,
- blk_ring.req_prod_pvt - 1);
- bh = (struct buffer_head *)id;
-
- bh->b_reqnext = (struct buffer_head *)blk_shadow[req->id].request;
- blk_shadow[req->id].request = (unsigned long)id;
-
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- /* install a grant reference. */
- ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
- ASSERT( ref != -ENOSPC );
-
- gnttab_grant_foreign_access_ref(
- ref,
- rdomid,
- buffer_ma >> PAGE_SHIFT,
- ( operation == BLKIF_OP_WRITE ? 1 : 0 ) );
-
- blk_shadow[id].frame[req->nr_segments] =
- buffer_ma >> PAGE_SHIFT;
-
- req->frame_and_sects[req->nr_segments] =
- (((u32) ref ) << 16) | (fsect << 3) | lsect;
-#else
- req->frame_and_sects[req->nr_segments] =
- buffer_ma | (fsect << 3) | lsect;
-#endif
- if ( ++req->nr_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST )
- sg_next_sect += nr_sectors;
- else
- DISABLE_SCATTERGATHER();
-
- /* Update the copy of the request in the recovery ring. */
- pickle_request(&blk_shadow[req->id], req );
-
- return 0;
- }
- else if ( RING_FULL(&blk_ring) )
- {
- return 1;
- }
- else
- {
- sg_operation = operation;
- sg_dev = device;
- sg_next_sect = sector_number + nr_sectors;
- }
- break;
-
- default:
- panic("unknown op %d\n", operation);
- }
-
- /* Fill out a communications ring structure. */
- req = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
-
- xid = GET_ID_FROM_FREELIST();
- blk_shadow[xid].request = (unsigned long)id;
-
- req->id = xid;
- req->operation = operation;
- req->sector_number = (blkif_sector_t)sector_number;
- req->device = device;
- req->nr_segments = 1;
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- /* install a grant reference. */
- ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
- ASSERT( ref != -ENOSPC );
-
- gnttab_grant_foreign_access_ref(
- ref,
- rdomid,
- buffer_ma >> PAGE_SHIFT,
- ( operation == BLKIF_OP_WRITE ? 1 : 0 ) );
-
- blk_shadow[xid].frame[0] = buffer_ma >> PAGE_SHIFT;
-
- req->frame_and_sects[0] = (((u32) ref)<<16) | (fsect<<3) | lsect;
-#else
- req->frame_and_sects[0] = buffer_ma | (fsect<<3) | lsect;
-#endif
-
- /* Keep a private copy so we can reissue requests when recovering. */
- pickle_request(&blk_shadow[xid], req);
-
- blk_ring.req_prod_pvt++;
-
- return 0;
+ struct blkfront_info *info = req->rq_disk->private_data;
+ unsigned long buffer_mfn;
+ blkif_request_t *ring_req;
+ struct bio *bio;
+ struct bio_vec *bvec;
+ int idx;
+ unsigned long id;
+ unsigned int fsect, lsect;
+ int ref;
+ grant_ref_t gref_head;
+
+ if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
+ return 1;
+
+ if (gnttab_alloc_grant_references(
+ BLKIF_MAX_SEGMENTS_PER_REQUEST, &gref_head) < 0) {
+ gnttab_request_free_callback(
+ &info->callback,
+ blkif_restart_queue_callback,
+ info,
+ BLKIF_MAX_SEGMENTS_PER_REQUEST);
+ return 1;
+ }
+
+ /* Fill out a communications ring structure. */
+ ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
+ id = GET_ID_FROM_FREELIST(info);
+ info->shadow[id].request = (unsigned long)req;
+
+ ring_req->id = id;
+ ring_req->operation = rq_data_dir(req) ?
+ BLKIF_OP_WRITE : BLKIF_OP_READ;
+ ring_req->sector_number = (blkif_sector_t)req->sector;
+ ring_req->handle = info->handle;
+
+ ring_req->nr_segments = 0;
+ rq_for_each_bio (bio, req) {
+ bio_for_each_segment (bvec, bio, idx) {
+ BUG_ON(ring_req->nr_segments
+ == BLKIF_MAX_SEGMENTS_PER_REQUEST);
+ buffer_mfn = page_to_phys(bvec->bv_page) >> PAGE_SHIFT;
+ fsect = bvec->bv_offset >> 9;
+ lsect = fsect + (bvec->bv_len >> 9) - 1;
+ /* install a grant reference. */
+ ref = gnttab_claim_grant_reference(&gref_head);
+ BUG_ON(ref == -ENOSPC);
+
+ gnttab_grant_foreign_access_ref(
+ ref,
+ info->xbdev->otherend_id,
+ buffer_mfn,
+ rq_data_dir(req) );
+
+ info->shadow[id].frame[ring_req->nr_segments] =
+ mfn_to_pfn(buffer_mfn);
+
+ ring_req->seg[ring_req->nr_segments] =
+ (struct blkif_request_segment) {
+ .gref = ref,
+ .first_sect = fsect,
+ .last_sect = lsect };
+
+ ring_req->nr_segments++;
+ }
+ }
+
+ info->ring.req_prod_pvt++;
+
+ /* Keep a private copy so we can reissue requests when recovering. */
+ info->shadow[id].req = *ring_req;
+
+ gnttab_free_grant_references(gref_head);
+
+ return 0;
}
-
/*
* do_blkif_request
* read a block; request is in a request queue
*/
void do_blkif_request(request_queue_t *rq)
{
- struct request *req;
- struct buffer_head *bh, *next_bh;
- int rw, nsect, full, queued = 0;
-
- DPRINTK("Entered do_blkif_request\n");
-
- while ( !rq->plugged && !list_empty(&rq->queue_head))
- {
- if ( (req = blkdev_entry_next_request(&rq->queue_head)) == NULL )
- goto out;
-
- DPRINTK("do_blkif_request %p: cmd %i, sec %lx, (%li/%li) bh:%p\n",
- req, req->cmd, req->sector,
- req->current_nr_sectors, req->nr_sectors, req->bh);
-
- rw = req->cmd;
- if ( rw == READA )
- rw = READ;
- if ( unlikely((rw != READ) && (rw != WRITE)) )
- panic("XenoLinux Virtual Block Device: bad cmd: %d\n", rw);
-
- req->errors = 0;
-
- bh = req->bh;
- while ( bh != NULL )
- {
- next_bh = bh->b_reqnext;
- bh->b_reqnext = NULL;
-
- full = blkif_queue_request(
- (unsigned long)bh,
- (rw == READ) ? BLKIF_OP_READ : BLKIF_OP_WRITE,
- bh->b_data, bh->b_rsector, bh->b_size>>9, bh->b_rdev);
-
- if ( full )
- {
- bh->b_reqnext = next_bh;
- pending_queues[nr_pending++] = rq;
- if ( unlikely(nr_pending >= MAX_PENDING) )
- BUG();
- goto out;
- }
-
- queued++;
-
- /* Dequeue the buffer head from the request. */
- nsect = bh->b_size >> 9;
- bh = req->bh = next_bh;
-
- if ( bh != NULL )
- {
- /* There's another buffer head to do. Update the request. */
- req->hard_sector += nsect;
- req->hard_nr_sectors -= nsect;
- req->sector = req->hard_sector;
- req->nr_sectors = req->hard_nr_sectors;
- req->current_nr_sectors = bh->b_size >> 9;
- req->buffer = bh->b_data;
- }
- else
- {
- /* That was the last buffer head. Finalise the request. */
- if ( unlikely(end_that_request_first(req, 1, "XenBlk")) )
- BUG();
- blkdev_dequeue_request(req);
- end_that_request_last(req);
- }
- }
- }
+ struct blkfront_info *info = NULL;
+ struct request *req;
+ int queued;
- out:
- if ( queued != 0 )
- flush_requests();
-}
+ DPRINTK("Entered do_blkif_request\n");
+ queued = 0;
-static void blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
-{
- RING_IDX i, rp;
- unsigned long flags;
- struct buffer_head *bh, *next_bh;
-
- spin_lock_irqsave(&io_request_lock, flags);
-
- if ( unlikely(blkif_state == BLKIF_STATE_CLOSED || recovery) )
- {
- spin_unlock_irqrestore(&io_request_lock, flags);
- return;
- }
-
- rp = blk_ring.sring->rsp_prod;
- rmb(); /* Ensure we see queued responses up to 'rp'. */
-
- for ( i = blk_ring.rsp_cons; i != rp; i++ )
- {
- unsigned long id;
- blkif_response_t *bret;
-
- bret = RING_GET_RESPONSE(&blk_ring, i);
- id = bret->id;
- bh = (struct buffer_head *)blk_shadow[id].request;
-
- blkif_completion(&blk_shadow[id]);
-
- ADD_ID_TO_FREELIST(id);
-
- switch ( bret->operation )
- {
- case BLKIF_OP_READ:
- case BLKIF_OP_WRITE:
- if ( unlikely(bret->status != BLKIF_RSP_OKAY) )
- DPRINTK("Bad return from blkdev data request: %lx\n",
- bret->status);
- for ( ; bh != NULL; bh = next_bh )
- {
- next_bh = bh->b_reqnext;
- bh->b_reqnext = NULL;
- bh->b_end_io(bh, bret->status == BLKIF_RSP_OKAY);
- }
-
- break;
- case BLKIF_OP_PROBE:
- memcpy(&blkif_control_rsp, bret, sizeof(*bret));
- blkif_control_rsp_valid = 1;
- break;
- default:
- BUG();
- }
-
- }
- blk_ring.rsp_cons = i;
-
- kick_pending_request_queues();
-
- spin_unlock_irqrestore(&io_request_lock, flags);
-}
+ while ((req = elv_next_request(rq)) != NULL) {
+ info = req->rq_disk->private_data;
+ if (!blk_fs_request(req)) {
+ end_request(req, 0);
+ continue;
+ }
-#endif
+ if (RING_FULL(&info->ring))
+ goto wait;
-/***************************** COMMON CODE *******************************/
+ DPRINTK("do_blk_req %p: cmd %p, sec %lx, "
+ "(%u/%li) buffer:%p [%s]\n",
+ req, req->cmd, req->sector, req->current_nr_sectors,
+ req->nr_sectors, req->buffer,
+ rq_data_dir(req) ? "write" : "read");
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-void blkif_control_probe_send(blkif_request_t *req, blkif_response_t *rsp,
- unsigned long address)
-{
- int ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
- ASSERT( ref != -ENOSPC );
- gnttab_grant_foreign_access_ref( ref, rdomid, address >> PAGE_SHIFT, 0 );
+ blkdev_dequeue_request(req);
+ if (blkif_queue_request(req)) {
+ blk_requeue_request(rq, req);
+ wait:
+ /* Avoid pointless unplugs. */
+ blk_stop_queue(rq);
+ break;
+ }
- req->frame_and_sects[0] = (((u32) ref) << 16) | 7;
+ queued++;
+ }
- blkif_control_send(req, rsp);
+ if (queued != 0)
+ flush_requests(info);
}
-#endif
-void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp)
-{
- unsigned long flags, id;
- blkif_request_t *req_d;
-
- retry:
- while ( RING_FULL(&blk_ring) )
- {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
-
- spin_lock_irqsave(&blkif_io_lock, flags);
- if ( RING_FULL(&blk_ring) )
- {
- spin_unlock_irqrestore(&blkif_io_lock, flags);
- goto retry;
- }
-
- DISABLE_SCATTERGATHER();
- req_d = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
- *req_d = *req;
-
- id = GET_ID_FROM_FREELIST();
- req_d->id = id;
- blk_shadow[id].request = (unsigned long)req;
-
- pickle_request(&blk_shadow[id], req);
-
- blk_ring.req_prod_pvt++;
- flush_requests();
-
- spin_unlock_irqrestore(&blkif_io_lock, flags);
-
- while ( !blkif_control_rsp_valid )
- {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
-
- memcpy(rsp, &blkif_control_rsp, sizeof(*rsp));
- blkif_control_rsp_valid = 0;
-}
-
-/* Send a driver status notification to the domain controller. */
-static void send_driver_status(int ok)
+static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
{
- ctrl_msg_t cmsg = {
- .type = CMSG_BLKIF_FE,
- .subtype = CMSG_BLKIF_FE_DRIVER_STATUS,
- .length = sizeof(blkif_fe_driver_status_t),
- };
- blkif_fe_driver_status_t *msg = (void*)cmsg.msg;
-
- msg->status = (ok ? BLKIF_DRIVER_STATUS_UP : BLKIF_DRIVER_STATUS_DOWN);
-
- ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-}
+ struct request *req;
+ blkif_response_t *bret;
+ RING_IDX i, rp;
+ unsigned long flags;
+ struct blkfront_info *info = (struct blkfront_info *)dev_id;
+
+ spin_lock_irqsave(&blkif_io_lock, flags);
+
+ if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
+ spin_unlock_irqrestore(&blkif_io_lock, flags);
+ return IRQ_HANDLED;
+ }
+
+ again:
+ rp = info->ring.sring->rsp_prod;
+ rmb(); /* Ensure we see queued responses up to 'rp'. */
+
+ for (i = info->ring.rsp_cons; i != rp; i++) {
+ unsigned long id;
+ int ret;
+
+ bret = RING_GET_RESPONSE(&info->ring, i);
+ id = bret->id;
+ req = (struct request *)info->shadow[id].request;
+
+ blkif_completion(&info->shadow[id]);
+
+ ADD_ID_TO_FREELIST(info, id);
+
+ switch (bret->operation) {
+ case BLKIF_OP_READ:
+ case BLKIF_OP_WRITE:
+ if (unlikely(bret->status != BLKIF_RSP_OKAY))
+ DPRINTK("Bad return from blkdev data "
+ "request: %x\n", bret->status);
+
+ ret = end_that_request_first(
+ req, (bret->status == BLKIF_RSP_OKAY),
+ req->hard_nr_sectors);
+ BUG_ON(ret);
+ end_that_request_last(
+ req, (bret->status == BLKIF_RSP_OKAY));
+ break;
+ default:
+ BUG();
+ }
+ }
+
+ info->ring.rsp_cons = i;
+
+ if (i != info->ring.req_prod_pvt) {
+ int more_to_do;
+ RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do);
+ if (more_to_do)
+ goto again;
+ } else
+ info->ring.sring->rsp_event = i + 1;
+
+ kick_pending_request_queues(info);
+
+ spin_unlock_irqrestore(&blkif_io_lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static void blkif_free(struct blkfront_info *info, int suspend)
+{
+ /* Prevent new requests being issued until we fix things up. */
+ spin_lock_irq(&blkif_io_lock);
+ info->connected = suspend ?
+ BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
+ /* No more blkif_request(). */
+ if (info->rq)
+ blk_stop_queue(info->rq);
+ /* No more gnttab callback work. */
+ gnttab_cancel_free_callback(&info->callback);
+ flush_scheduled_work();
+ spin_unlock_irq(&blkif_io_lock);
+
+ /* Free resources associated with old device channel. */
+ if (info->ring_ref != GRANT_INVALID_REF) {
+ gnttab_end_foreign_access(info->ring_ref, 0,
+ (unsigned long)info->ring.sring);
+ info->ring_ref = GRANT_INVALID_REF;
+ info->ring.sring = NULL;
+ }
+ if (info->irq)
+ unbind_from_irqhandler(info->irq, info);
+ info->evtchn = info->irq = 0;
-/* Tell the controller to bring up the interface. */
-static void blkif_send_interface_connect(void)
-{
- ctrl_msg_t cmsg = {
- .type = CMSG_BLKIF_FE,
- .subtype = CMSG_BLKIF_FE_INTERFACE_CONNECT,
- .length = sizeof(blkif_fe_interface_connect_t),
- };
- blkif_fe_interface_connect_t *msg = (void*)cmsg.msg;
-
- msg->handle = 0;
- msg->shmem_frame = (virt_to_machine(blk_ring.sring) >> PAGE_SHIFT);
-
- ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
}
-static void blkif_free(void)
+static void blkif_completion(struct blk_shadow *s)
{
- /* Prevent new requests being issued until we fix things up. */
- spin_lock_irq(&blkif_io_lock);
- recovery = 1;
- blkif_state = BLKIF_STATE_DISCONNECTED;
- spin_unlock_irq(&blkif_io_lock);
-
- /* Free resources associated with old device channel. */
- if ( blk_ring.sring != NULL )
- {
- free_page((unsigned long)blk_ring.sring);
- blk_ring.sring = NULL;
- }
- free_irq(blkif_irq, NULL);
- blkif_irq = 0;
-
- unbind_evtchn_from_irq(blkif_evtchn);
- blkif_evtchn = 0;
+ int i;
+ for (i = 0; i < s->req.nr_segments; i++)
+ gnttab_end_foreign_access(s->req.seg[i].gref, 0, 0UL);
}
-static void blkif_close(void)
+static void blkif_recover(struct blkfront_info *info)
{
-}
+ int i;
+ blkif_request_t *req;
+ struct blk_shadow *copy;
+ int j;
-/* Move from CLOSED to DISCONNECTED state. */
-static void blkif_disconnect(void)
-{
- blkif_sring_t *sring;
-
- if ( blk_ring.sring != NULL )
- free_page((unsigned long)blk_ring.sring);
-
- sring = (blkif_sring_t *)__get_free_page(GFP_KERNEL);
- SHARED_RING_INIT(sring);
- FRONT_RING_INIT(&blk_ring, sring, PAGE_SIZE);
- blkif_state = BLKIF_STATE_DISCONNECTED;
- blkif_send_interface_connect();
-}
+ /* Stage 1: Make a safe copy of the shadow state. */
+ copy = kmalloc(sizeof(info->shadow), GFP_KERNEL | __GFP_NOFAIL);
+ memcpy(copy, info->shadow, sizeof(info->shadow));
-static void blkif_reset(void)
-{
- blkif_free();
- blkif_disconnect();
-}
+ /* Stage 2: Set up free list. */
+ memset(&info->shadow, 0, sizeof(info->shadow));
+ for (i = 0; i < BLK_RING_SIZE; i++)
+ info->shadow[i].req.id = i+1;
+ info->shadow_free = info->ring.req_prod_pvt;
+ info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
-static void blkif_recover(void)
-{
- int i;
- blkif_request_t *req;
- struct blk_shadow *copy;
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- int j;
-#endif
-
- /* Stage 1: Make a safe copy of the shadow state. */
- copy = (struct blk_shadow *)kmalloc(sizeof(blk_shadow), GFP_KERNEL);
- BUG_ON(copy == NULL);
- memcpy(copy, blk_shadow, sizeof(blk_shadow));
-
- /* Stage 2: Set up free list. */
- memset(&blk_shadow, 0, sizeof(blk_shadow));
- for ( i = 0; i < BLK_RING_SIZE; i++ )
- blk_shadow[i].req.id = i+1;
- blk_shadow_free = blk_ring.req_prod_pvt;
- blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
-
- /* Stage 3: Find pending requests and requeue them. */
- for ( i = 0; i < BLK_RING_SIZE; i++ )
- {
- /* Not in use? */
- if ( copy[i].request == 0 )
- continue;
-
- /* Grab a request slot and unpickle shadow state into it. */
- req = RING_GET_REQUEST(
- &blk_ring, blk_ring.req_prod_pvt);
- unpickle_request(req, ©[i]);
-
- /* We get a new request id, and must reset the shadow state. */
- req->id = GET_ID_FROM_FREELIST();
- memcpy(&blk_shadow[req->id], ©[i], sizeof(copy[i]));
-
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- /* Rewrite any grant references invalidated by suspend/resume. */
- for ( j = 0; j < req->nr_segments; j++ )
- {
- if ( req->frame_and_sects[j] & GRANTREF_INVALID )
- gnttab_grant_foreign_access_ref(
- blkif_gref_from_fas(req->frame_and_sects[j]),
- rdomid,
- blk_shadow[req->id].frame[j],
- rq_data_dir((struct request *)
- blk_shadow[req->id].request));
- req->frame_and_sects[j] &= ~GRANTREF_INVALID;
- }
- blk_shadow[req->id].req = *req;
-#endif
-
- blk_ring.req_prod_pvt++;
- }
-
- kfree(copy);
-
- recovery = 0;
-
- /* blk_ring->req_prod will be set when we flush_requests().*/
- wmb();
-
- /* Kicks things back into life. */
- flush_requests();
-
- /* Now safe to left other people use the interface. */
- blkif_state = BLKIF_STATE_CONNECTED;
-}
+ /* Stage 3: Find pending requests and requeue them. */
+ for (i = 0; i < BLK_RING_SIZE; i++) {
+ /* Not in use? */
+ if (copy[i].request == 0)
+ continue;
-static void blkif_connect(blkif_fe_interface_status_t *status)
-{
- int err = 0;
-
- blkif_evtchn = status->evtchn;
- blkif_irq = bind_evtchn_to_irq(blkif_evtchn);
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- rdomid = status->domid;
-#endif
-
- err = request_irq(blkif_irq, blkif_int, SA_SAMPLE_RANDOM, "blkif", NULL);
- if ( err )
- {
- printk(KERN_ALERT "xen_blk: request_irq failed (err=%d)\n", err);
- return;
- }
-
- if ( recovery )
- {
- blkif_recover();
- }
- else
- {
- /* Transition to connected in case we need to do
- * a partition probe on a whole disk. */
- blkif_state = BLKIF_STATE_CONNECTED;
-
- /* Probe for discs attached to the interface. */
- xlvbd_init();
- }
-
- /* Kick pending requests. */
- spin_lock_irq(&blkif_io_lock);
- kick_pending_request_queues();
- spin_unlock_irq(&blkif_io_lock);
-}
+ /* Grab a request slot and copy shadow state into it. */
+ req = RING_GET_REQUEST(
+ &info->ring, info->ring.req_prod_pvt);
+ *req = copy[i].req;
-static void unexpected(blkif_fe_interface_status_t *status)
-{
- DPRINTK(" Unexpected blkif status %u in state %u\n",
- status->status, blkif_state);
-}
+ /* We get a new request id, and must reset the shadow state. */
+ req->id = GET_ID_FROM_FREELIST(info);
+ memcpy(&info->shadow[req->id], ©[i], sizeof(copy[i]));
-static void blkif_status(blkif_fe_interface_status_t *status)
-{
- if ( status->handle != blkif_handle )
- {
- WPRINTK(" Invalid blkif: handle=%u\n", status->handle);
- unexpected(status);
- return;
- }
-
- switch ( status->status )
- {
- case BLKIF_INTERFACE_STATUS_CLOSED:
- switch ( blkif_state )
- {
- case BLKIF_STATE_CLOSED:
- unexpected(status);
- break;
- case BLKIF_STATE_DISCONNECTED:
- case BLKIF_STATE_CONNECTED:
- unexpected(status);
- blkif_close();
- break;
- }
- break;
-
- case BLKIF_INTERFACE_STATUS_DISCONNECTED:
- switch ( blkif_state )
- {
- case BLKIF_STATE_CLOSED:
- blkif_disconnect();
- break;
- case BLKIF_STATE_DISCONNECTED:
- case BLKIF_STATE_CONNECTED:
- /* unexpected(status); */ /* occurs during suspend/resume */
- blkif_reset();
- break;
- }
- break;
-
- case BLKIF_INTERFACE_STATUS_CONNECTED:
- switch ( blkif_state )
- {
- case BLKIF_STATE_CLOSED:
- unexpected(status);
- blkif_disconnect();
- blkif_connect(status);
- break;
- case BLKIF_STATE_DISCONNECTED:
- blkif_connect(status);
- break;
- case BLKIF_STATE_CONNECTED:
- unexpected(status);
- blkif_connect(status);
- break;
- }
- break;
-
- case BLKIF_INTERFACE_STATUS_CHANGED:
- switch ( blkif_state )
- {
- case BLKIF_STATE_CLOSED:
- case BLKIF_STATE_DISCONNECTED:
- unexpected(status);
- break;
- case BLKIF_STATE_CONNECTED:
- vbd_update();
- break;
- }
- break;
-
- default:
- WPRINTK(" Invalid blkif status: %d\n", status->status);
- break;
- }
-}
+ /* Rewrite any grant references invalidated by susp/resume. */
+ for (j = 0; j < req->nr_segments; j++)
+ gnttab_grant_foreign_access_ref(
+ req->seg[j].gref,
+ info->xbdev->otherend_id,
+ pfn_to_mfn(info->shadow[req->id].frame[j]),
+ rq_data_dir(
+ (struct request *)
+ info->shadow[req->id].request));
+ info->shadow[req->id].req = *req;
+ info->ring.req_prod_pvt++;
+ }
-static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
-{
- switch ( msg->subtype )
- {
- case CMSG_BLKIF_FE_INTERFACE_STATUS:
- blkif_status((blkif_fe_interface_status_t *)
- &msg->msg[0]);
- break;
- default:
- msg->length = 0;
- break;
- }
-
- ctrl_if_send_response(msg);
-}
+ kfree(copy);
-int wait_for_blkif(void)
-{
- int err = 0;
- int i;
- send_driver_status(1);
-
- /*
- * We should read 'nr_interfaces' from response message and wait
- * for notifications before proceeding. For now we assume that we
- * will be notified of exactly one interface.
- */
- for ( i=0; (blkif_state != BLKIF_STATE_CONNECTED) && (i < 10*HZ); i++ )
- {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
-
- if ( blkif_state != BLKIF_STATE_CONNECTED )
- {
- printk(KERN_INFO "xen_blk: Timeout connecting to device!\n");
- err = -ENOSYS;
- }
- return err;
-}
+ (void)xenbus_switch_state(info->xbdev, XenbusStateConnected);
-int __init xlblk_init(void)
-{
- int i;
+ spin_lock_irq(&blkif_io_lock);
+
+ /* Now safe for us to use the shared ring */
+ info->connected = BLKIF_STATE_CONNECTED;
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- if ( 0 > gnttab_alloc_grant_references( MAXIMUM_OUTSTANDING_BLOCK_REQS,
- &gref_head, &gref_terminal ))
- return 1;
- printk(KERN_ALERT "Blkif frontend is using grant tables.\n");
-#endif
+ /* Send off requeued requests */
+ flush_requests(info);
- if ( (xen_start_info.flags & SIF_INITDOMAIN) ||
- (xen_start_info.flags & SIF_BLK_BE_DOMAIN) )
- return 0;
+ /* Kick any other new requests queued since we resumed */
+ kick_pending_request_queues(info);
- printk(KERN_INFO "xen_blk: Initialising virtual block device driver\n");
+ spin_unlock_irq(&blkif_io_lock);
+}
- blk_shadow_free = 0;
- memset(blk_shadow, 0, sizeof(blk_shadow));
- for ( i = 0; i < BLK_RING_SIZE; i++ )
- blk_shadow[i].req.id = i+1;
- blk_shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
- (void)ctrl_if_register_receiver(CMSG_BLKIF_FE, blkif_ctrlif_rx,
- CALLBACK_IN_BLOCKING_CONTEXT);
+/* ** Driver Registration ** */
- wait_for_blkif();
- return 0;
-}
+static struct xenbus_device_id blkfront_ids[] = {
+ { "vbd" },
+ { "" }
+};
-void blkdev_suspend(void)
-{
-}
-void blkdev_resume(void)
+static struct xenbus_driver blkfront = {
+ .name = "vbd",
+ .owner = THIS_MODULE,
+ .ids = blkfront_ids,
+ .probe = blkfront_probe,
+ .remove = blkfront_remove,
+ .resume = blkfront_resume,
+ .otherend_changed = backend_changed,
+};
+
+
+static int __init xlblk_init(void)
{
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- int i, j;
- for ( i = 0; i < BLK_RING_SIZE; i++ )
- for ( j = 0; j < BLKIF_MAX_SEGMENTS_PER_REQUEST; j++ )
- blk_shadow[i].req.frame_and_sects[j] |= GRANTREF_INVALID;
-#endif
- send_driver_status(1);
+ if (!is_running_on_xen())
+ return -ENODEV;
+
+ return xenbus_register_frontend(&blkfront);
}
+module_init(xlblk_init);
-static void blkif_completion(struct blk_shadow *s)
+
+static void xlblk_exit(void)
{
- int i;
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- for ( i = 0; i < s->req.nr_segments; i++ )
- gnttab_release_grant_reference(
- &gref_head, blkif_gref_from_fas(s->req.frame_and_sects[i]));
-#else
- /* This is a hack to get the dirty logging bits set */
- if ( s->req.operation == BLKIF_OP_READ )
- {
- for ( i = 0; i < s->req.nr_segments; i++ )
- {
- unsigned long pfn = s->req.frame_and_sects[i] >> PAGE_SHIFT;
- unsigned long mfn = phys_to_machine_mapping[pfn];
- xen_machphys_update(mfn, pfn);
- }
- }
-#endif
+ return xenbus_unregister_driver(&blkfront);
}
+module_exit(xlblk_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
* 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
#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/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>
-#if 0
-#define DPRINTK(_f, _a...) printk ( KERN_ALERT _f , ## _a )
+#if 1
+#define IPRINTK(fmt, args...) \
+ printk(KERN_INFO "xen_blk: " fmt, ##args)
+#else
+#define IPRINTK(fmt, args...) ((void)0)
+#endif
+
+#if 1
+#define WPRINTK(fmt, args...) \
+ printk(KERN_WARNING "xen_blk: " fmt, ##args)
#else
-#define DPRINTK(_f, _a...) ((void)0)
+#define WPRINTK(fmt, args...) ((void)0)
#endif
+#define DPRINTK(_f, _a...) pr_debug(_f, ## _a)
+
#if 0
-#define DPRINTK_IOCTL(_f, _a...) printk ( KERN_ALERT _f , ## _a )
+#define DPRINTK_IOCTL(_f, _a...) printk(KERN_ALERT _f, ## _a)
#else
#define DPRINTK_IOCTL(_f, _a...) ((void)0)
#endif
-struct xlbd_type_info {
- int partn_shift;
- int partn_per_major;
- int devs_per_major;
- char *devname;
- char *diskname;
+struct xlbd_type_info
+{
+ int partn_shift;
+ int disks_per_major;
+ char *devname;
+ char *diskname;
+};
+
+struct xlbd_major_info
+{
+ int major;
+ int index;
+ int usage;
+ struct xlbd_type_info *type;
};
+struct blk_shadow {
+ blkif_request_t req;
+ unsigned long request;
+ unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+};
+
+#define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
+
/*
* We have one of these per vbd, whether ide, scsi or 'other'. They
* hang in private_data off the gendisk structure. We may end up
* putting all kinds of interesting stuff here :-)
*/
-struct xlbd_major_info {
- int major;
- int index;
- int usage;
- struct xlbd_type_info *type;
-};
+struct blkfront_info
+{
+ struct xenbus_device *xbdev;
+ dev_t dev;
+ struct gendisk *gd;
+ int vdevice;
+ blkif_vdev_t handle;
+ int connected;
+ int ring_ref;
+ blkif_front_ring_t ring;
+ unsigned int evtchn, irq;
+ struct xlbd_major_info *mi;
+ request_queue_t *rq;
+ struct work_struct work;
+ struct gnttab_free_callback callback;
+ struct blk_shadow shadow[BLK_RING_SIZE];
+ unsigned long shadow_free;
-struct xlbd_disk_info {
- int xd_device;
- struct xlbd_major_info *mi;
+ /**
+ * The number of people holding this device open. We won't allow a
+ * hot-unplug unless this is 0.
+ */
+ int users;
};
-typedef struct xen_block {
- int usage;
-} xen_block_t;
-
-extern struct request_queue *xlbd_blk_queue;
extern spinlock_t blkif_io_lock;
extern int blkif_open(struct inode *inode, struct file *filep);
extern int blkif_release(struct inode *inode, struct file *filep);
extern int blkif_ioctl(struct inode *inode, struct file *filep,
- unsigned command, unsigned long argument);
+ unsigned command, unsigned long argument);
+extern int blkif_getgeo(struct block_device *, struct hd_geometry *);
extern int blkif_check(dev_t dev);
extern int blkif_revalidate(dev_t dev);
-extern void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp);
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-extern void blkif_control_probe_send(
- blkif_request_t *req, blkif_response_t *rsp, unsigned long address);
-#endif
-extern void do_blkif_request (request_queue_t *rq);
-
-extern void xlvbd_update_vbds(void);
+extern void do_blkif_request (request_queue_t *rq);
/* Virtual block-device subsystem. */
-extern int xlvbd_init(void);
-extern void xlvbd_cleanup(void);
+/* Note that xlvbd_add doesn't call add_disk for you: you're expected
+ to call add_disk on info->gd once the disk is properly connected
+ up. */
+int xlvbd_add(blkif_sector_t capacity, int device,
+ u16 vdisk_info, u16 sector_size, struct blkfront_info *info);
+void xlvbd_del(struct blkfront_info *info);
#endif /* __XEN_DRIVERS_BLOCK_H__ */
* 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
#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
#define NUM_SCSI_MAJORS 9
#define NUM_VBD_MAJORS 1
-struct lvdisk
-{
- blkif_sector_t capacity; /* 0: Size in terms of 512-byte sectors. */
- blkif_vdev_t device; /* 8: Device number (opaque 16 bit value). */
- u16 info;
- struct list_head list;
-};
-
static struct xlbd_type_info xlbd_ide_type = {
- .partn_shift = 6,
- .partn_per_major = 2,
- .devname = "ide",
- .diskname = "hd",
+ .partn_shift = 6,
+ .disks_per_major = 2,
+ .devname = "ide",
+ .diskname = "hd",
};
static struct xlbd_type_info xlbd_scsi_type = {
- .partn_shift = 4,
- .partn_per_major = 16,
- .devname = "sd",
- .diskname = "sd",
+ .partn_shift = 4,
+ .disks_per_major = 16,
+ .devname = "sd",
+ .diskname = "sd",
};
static struct xlbd_type_info xlbd_vbd_type = {
- .partn_shift = 4,
- .partn_per_major = 16,
- .devname = "xvd",
- .diskname = "xvd",
+ .partn_shift = 4,
+ .disks_per_major = 16,
+ .devname = "xvd",
+ .diskname = "xvd",
};
static struct xlbd_major_info *major_info[NUM_IDE_MAJORS + NUM_SCSI_MAJORS +
- NUM_VBD_MAJORS];
+ NUM_VBD_MAJORS];
-#define XLBD_MAJOR_IDE_START 0
-#define XLBD_MAJOR_SCSI_START (NUM_IDE_MAJORS)
-#define XLBD_MAJOR_VBD_START (NUM_IDE_MAJORS + NUM_SCSI_MAJORS)
+#define XLBD_MAJOR_IDE_START 0
+#define XLBD_MAJOR_SCSI_START (NUM_IDE_MAJORS)
+#define XLBD_MAJOR_VBD_START (NUM_IDE_MAJORS + NUM_SCSI_MAJORS)
-#define XLBD_MAJOR_IDE_RANGE XLBD_MAJOR_IDE_START ... XLBD_MAJOR_SCSI_START - 1
-#define XLBD_MAJOR_SCSI_RANGE XLBD_MAJOR_SCSI_START ... XLBD_MAJOR_VBD_START - 1
-#define XLBD_MAJOR_VBD_RANGE XLBD_MAJOR_VBD_START ... XLBD_MAJOR_VBD_START + NUM_VBD_MAJORS - 1
+#define XLBD_MAJOR_IDE_RANGE XLBD_MAJOR_IDE_START ... XLBD_MAJOR_SCSI_START - 1
+#define XLBD_MAJOR_SCSI_RANGE XLBD_MAJOR_SCSI_START ... XLBD_MAJOR_VBD_START - 1
+#define XLBD_MAJOR_VBD_RANGE XLBD_MAJOR_VBD_START ... XLBD_MAJOR_VBD_START + NUM_VBD_MAJORS - 1
/* Information about our VBDs. */
#define MAX_VBDS 64
-struct list_head vbds_list;
+static LIST_HEAD(vbds_list);
-struct request_queue *xlbd_blk_queue = NULL;
-
-#define MAJOR_XEN(dev) ((dev)>>8)
-#define MINOR_XEN(dev) ((dev) & 0xff)
-
-static struct block_device_operations xlvbd_block_fops =
+static struct block_device_operations xlvbd_block_fops =
{
- .owner = THIS_MODULE,
- .open = blkif_open,
- .release = blkif_release,
- .ioctl = blkif_ioctl,
+ .owner = THIS_MODULE,
+ .open = blkif_open,
+ .release = blkif_release,
+ .ioctl = blkif_ioctl,
+ .getgeo = blkif_getgeo
};
-spinlock_t blkif_io_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(blkif_io_lock);
-static struct lvdisk * xlvbd_device_alloc(void)
+static struct xlbd_major_info *
+xlbd_alloc_major_info(int major, int minor, int index)
{
- struct lvdisk *ret;
-
- ret = kmalloc(sizeof(struct lvdisk), GFP_KERNEL);
- if ( ret ) {
- memset(ret, '\0', sizeof(struct lvdisk));
- INIT_LIST_HEAD(&ret->list);
- }
- return ret;
+ struct xlbd_major_info *ptr;
+
+ ptr = kzalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
+ if (ptr == NULL)
+ return NULL;
+
+ ptr->major = major;
+
+ switch (index) {
+ case XLBD_MAJOR_IDE_RANGE:
+ ptr->type = &xlbd_ide_type;
+ ptr->index = index - XLBD_MAJOR_IDE_START;
+ break;
+ case XLBD_MAJOR_SCSI_RANGE:
+ ptr->type = &xlbd_scsi_type;
+ ptr->index = index - XLBD_MAJOR_SCSI_START;
+ break;
+ case XLBD_MAJOR_VBD_RANGE:
+ ptr->type = &xlbd_vbd_type;
+ ptr->index = index - XLBD_MAJOR_VBD_START;
+ break;
+ }
+
+ printk("Registering block device major %i\n", ptr->major);
+ if (register_blkdev(ptr->major, ptr->type->devname)) {
+ WPRINTK("can't get major %d with name %s\n",
+ ptr->major, ptr->type->devname);
+ kfree(ptr);
+ return NULL;
+ }
+
+ devfs_mk_dir(ptr->type->devname);
+ major_info[index] = ptr;
+ return ptr;
}
-static void xlvbd_device_free(struct lvdisk *disk)
+static struct xlbd_major_info *
+xlbd_get_major_info(int vdevice)
{
- list_del(&disk->list);
- kfree(disk);
+ struct xlbd_major_info *mi;
+ int major, minor, index;
+
+ major = BLKIF_MAJOR(vdevice);
+ minor = BLKIF_MINOR(vdevice);
+
+ switch (major) {
+ case IDE0_MAJOR: index = 0; break;
+ case IDE1_MAJOR: index = 1; break;
+ case IDE2_MAJOR: index = 2; break;
+ case IDE3_MAJOR: index = 3; break;
+ case IDE4_MAJOR: index = 4; break;
+ case IDE5_MAJOR: index = 5; break;
+ case IDE6_MAJOR: index = 6; break;
+ case IDE7_MAJOR: index = 7; break;
+ case IDE8_MAJOR: index = 8; break;
+ case IDE9_MAJOR: index = 9; break;
+ case SCSI_DISK0_MAJOR: index = 10; break;
+ case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR:
+ index = 11 + major - SCSI_DISK1_MAJOR;
+ break;
+ case SCSI_CDROM_MAJOR: index = 18; break;
+ default: index = 19; break;
+ }
+
+ mi = ((major_info[index] != NULL) ? major_info[index] :
+ xlbd_alloc_major_info(major, minor, index));
+ if (mi)
+ mi->usage++;
+ return mi;
}
-static vdisk_t * xlvbd_probe(int *ret)
+static void
+xlbd_put_major_info(struct xlbd_major_info *mi)
{
- blkif_response_t rsp;
- blkif_request_t req;
- vdisk_t *disk_info = NULL;
- unsigned long buf;
- int nr;
-
- buf = __get_free_page(GFP_KERNEL);
- if ( !buf )
- goto out;
-
- memset(&req, 0, sizeof(req));
- req.operation = BLKIF_OP_PROBE;
- req.nr_segments = 1;
-#ifdef CONFIG_XEN_BLKDEV_GRANT
- blkif_control_probe_send(&req, &rsp,
- (unsigned long)(virt_to_machine(buf)));
-#else
- req.frame_and_sects[0] = virt_to_machine(buf) | 7;
-
- blkif_control_send(&req, &rsp);
-#endif
- if ( rsp.status <= 0 ) {
- printk(KERN_ALERT "Could not probe disks (%d)\n", rsp.status);
- goto out;
- }
- nr = rsp.status;
- if ( nr > MAX_VBDS )
- nr = MAX_VBDS;
-
- disk_info = kmalloc(nr * sizeof(vdisk_t), GFP_KERNEL);
- if ( disk_info )
- memcpy(disk_info, (void *) buf, nr * sizeof(vdisk_t));
- if ( ret )
- *ret = nr;
-out:
- free_page(buf);
- return disk_info;
+ mi->usage--;
+ /* XXX: release major if 0 */
}
-static struct xlbd_major_info *xlbd_alloc_major_info(int major, int minor, int index)
+static int
+xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
{
- struct xlbd_major_info *ptr;
-
- ptr = kmalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
- if ( !ptr )
- return NULL;
-
- memset(ptr, 0, sizeof(struct xlbd_major_info));
-
- ptr->major = major;
-
- switch (index) {
- case XLBD_MAJOR_IDE_RANGE:
- ptr->type = &xlbd_ide_type;
- ptr->index = index - XLBD_MAJOR_IDE_START;
- break;
- case XLBD_MAJOR_SCSI_RANGE:
- ptr->type = &xlbd_scsi_type;
- ptr->index = index - XLBD_MAJOR_SCSI_START;
- break;
- case XLBD_MAJOR_VBD_RANGE:
- ptr->type = &xlbd_vbd_type;
- ptr->index = index - XLBD_MAJOR_VBD_START;
- break;
- }
-
- if ( register_blkdev(ptr->major, ptr->type->devname) ) {
- printk(KERN_ALERT "XL VBD: can't get major %d with name %s\n",
- ptr->major, ptr->type->devname);
- kfree(ptr);
- return NULL;
- }
-
- devfs_mk_dir(ptr->type->devname);
- major_info[index] = ptr;
- return ptr;
-}
+ request_queue_t *rq;
-static struct xlbd_major_info *xlbd_get_major_info(int device)
-{
- int major, minor, index;
-
- major = MAJOR_XEN(device);
- minor = MINOR_XEN(device);
-
- switch (major) {
- case IDE0_MAJOR: index = 0; break;
- case IDE1_MAJOR: index = 1; break;
- case IDE2_MAJOR: index = 2; break;
- case IDE3_MAJOR: index = 3; break;
- case IDE4_MAJOR: index = 4; break;
- case IDE5_MAJOR: index = 5; break;
- case IDE6_MAJOR: index = 6; break;
- case IDE7_MAJOR: index = 7; break;
- case IDE8_MAJOR: index = 8; break;
- case IDE9_MAJOR: index = 9; break;
- case SCSI_DISK0_MAJOR: index = 10; break;
- case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR:
- index = 11 + major - SCSI_DISK1_MAJOR;
- break;
- case SCSI_CDROM_MAJOR: index = 18; break;
- default: index = 19; break;
- }
-
- return major_info[index]
- ? major_info[index]
- : xlbd_alloc_major_info(major, minor, index);
-}
+ rq = blk_init_queue(do_blkif_request, &blkif_io_lock);
+ if (rq == NULL)
+ return -1;
-static int xlvbd_blk_queue_alloc(struct xlbd_type_info *type)
-{
- xlbd_blk_queue = blk_init_queue(do_blkif_request, &blkif_io_lock);
- if ( !xlbd_blk_queue )
- return -1;
-
- elevator_init(xlbd_blk_queue, "noop");
-
- /*
- * Turn off barking 'headactive' mode. We dequeue
- * buffer heads as soon as we pass them to back-end
- * driver.
- */
- blk_queue_headactive(xlbd_blk_queue, 0);
-
- /* Hard sector size and max sectors impersonate the equiv. hardware. */
- blk_queue_hardsect_size(xlbd_blk_queue, 512);
- blk_queue_max_sectors(xlbd_blk_queue, 512);
-
- /* Each segment in a request is up to an aligned page in size. */
- blk_queue_segment_boundary(xlbd_blk_queue, PAGE_SIZE - 1);
- blk_queue_max_segment_size(xlbd_blk_queue, PAGE_SIZE);
-
- /* Ensure a merged request will fit in a single I/O ring slot. */
- blk_queue_max_phys_segments(xlbd_blk_queue, BLKIF_MAX_SEGMENTS_PER_REQUEST);
- blk_queue_max_hw_segments(xlbd_blk_queue, BLKIF_MAX_SEGMENTS_PER_REQUEST);
-
- /* Make sure buffer addresses are sector-aligned. */
- blk_queue_dma_alignment(xlbd_blk_queue, 511);
- return 0;
-}
+ elevator_init(rq, "noop");
-struct gendisk *xlvbd_alloc_gendisk(struct xlbd_major_info *mi, int minor,
- vdisk_t *disk)
-{
- struct gendisk *gd;
- struct xlbd_disk_info *di;
- int nb_minors;
-
- di = kmalloc(sizeof(struct xlbd_disk_info), GFP_KERNEL);
- if ( !di )
- goto out;
- di->mi = mi;
- di->xd_device = disk->device;
-
- nb_minors = ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
- ? mi->type->partn_per_major
- : 1;
-
- gd = alloc_disk(nb_minors);
- if ( !gd )
- goto out;
-
- if ( nb_minors > 1 )
- sprintf(gd->disk_name, "%s%c", mi->type->diskname,
- 'a' + mi->index * mi->type->partn_per_major +
- (minor >> mi->type->partn_shift));
- else
- sprintf(gd->disk_name, "%s%c%d", mi->type->diskname,
- 'a' + mi->index * mi->type->partn_per_major +
- (minor >> mi->type->partn_shift),
- minor & ((1 << mi->type->partn_shift) - 1));
-
- gd->major = mi->major;
- gd->first_minor = minor;
- gd->fops = &xlvbd_block_fops;
- gd->private_data = di;
- set_capacity(gd, disk->capacity);
-
- if ( !xlbd_blk_queue )
- if ( xlvbd_blk_queue_alloc(mi->type) )
- goto out_gendisk;
-
- gd->queue = xlbd_blk_queue;
- add_disk(gd);
- return gd;
-out_gendisk:
- printk(KERN_ALERT "error gendisk\n");
- del_gendisk(gd);
-out:
- printk(KERN_ALERT "error out\n");
- kfree(di);
- return NULL;
-}
+ /* Hard sector size and max sectors impersonate the equiv. hardware. */
+ blk_queue_hardsect_size(rq, sector_size);
+ blk_queue_max_sectors(rq, 512);
-static int xlvbd_device_add(struct list_head *list, vdisk_t *disk)
-{
- struct lvdisk *new;
- int minor;
- dev_t device;
- struct block_device *bd;
- struct gendisk *gd;
- struct xlbd_major_info *mi;
-
- mi = xlbd_get_major_info(disk->device);
- if ( !mi )
- return -EPERM;
-
- new = xlvbd_device_alloc();
- if ( !new )
- return -1;
- new->capacity = disk->capacity;
- new->device = disk->device;
- new->info = disk->info;
-
- minor = MINOR_XEN(disk->device);
- device = MKDEV(mi->major, minor);
-
- bd = bdget(device);
- if ( !bd )
- goto out;
-
- gd = xlvbd_alloc_gendisk(mi, minor, disk);
- if ( !gd )
- goto out_bd;
-
- if ( VDISK_READONLY(disk->info) )
- set_disk_ro(gd, 1);
-
- switch (VDISK_TYPE(disk->info)) {
- case VDISK_TYPE_CDROM:
- gd->flags |= GENHD_FL_REMOVABLE | GENHD_FL_CD;
- break;
- case VDISK_TYPE_FLOPPY:
- case VDISK_TYPE_TAPE:
- gd->flags |= GENHD_FL_REMOVABLE;
- break;
- case VDISK_TYPE_DISK:
- break;
- default:
- printk(KERN_ALERT "XenLinux: unknown device type %d\n",
- VDISK_TYPE(disk->info));
- break;
- }
-
- list_add(&new->list, list);
-out_bd:
- bdput(bd);
-out:
- return 0;
-}
+ /* Each segment in a request is up to an aligned page in size. */
+ blk_queue_segment_boundary(rq, PAGE_SIZE - 1);
+ blk_queue_max_segment_size(rq, PAGE_SIZE);
-static int xlvbd_device_del(struct lvdisk *disk)
-{
- dev_t device;
- struct block_device *bd;
- struct gendisk *gd;
- struct xlbd_disk_info *di;
- int ret = 0, unused;
+ /* Ensure a merged request will fit in a single I/O ring slot. */
+ blk_queue_max_phys_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
+ blk_queue_max_hw_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
- device = MKDEV(MAJOR_XEN(disk->device), MINOR_XEN(disk->device));
+ /* Make sure buffer addresses are sector-aligned. */
+ blk_queue_dma_alignment(rq, 511);
- bd = bdget(device);
- if ( !bd )
- return -1;
+ gd->queue = rq;
- gd = get_gendisk(device, &unused);
- di = gd->private_data;
-
- if ( di->mi->usage != 0 ) {
- printk(KERN_ALERT "VBD removal failed: used [dev=%x]\n", device);
- ret = -1;
- goto out;
- }
-
- del_gendisk(gd);
-
- xlvbd_device_free(disk);
-out:
- bdput(bd);
- return ret;
+ return 0;
}
-static int xlvbd_device_update(struct lvdisk *ldisk, vdisk_t *disk)
+static int
+xlvbd_alloc_gendisk(int minor, blkif_sector_t capacity, int vdevice,
+ u16 vdisk_info, u16 sector_size,
+ struct blkfront_info *info)
{
- dev_t device;
- struct block_device *bd;
- struct gendisk *gd;
- int unused;
-
- if ( ldisk->capacity == disk->capacity && ldisk->info == disk->info )
- return 0;
+ struct gendisk *gd;
+ struct xlbd_major_info *mi;
+ int nr_minors = 1;
+ int err = -ENODEV;
+
+ BUG_ON(info->gd != NULL);
+ BUG_ON(info->mi != NULL);
+ BUG_ON(info->rq != NULL);
+
+ mi = xlbd_get_major_info(vdevice);
+ if (mi == NULL)
+ goto out;
+ info->mi = mi;
+
+ if ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
+ nr_minors = 1 << mi->type->partn_shift;
+
+ gd = alloc_disk(nr_minors);
+ if (gd == NULL)
+ goto out;
+
+ if (nr_minors > 1)
+ sprintf(gd->disk_name, "%s%c", mi->type->diskname,
+ 'a' + mi->index * mi->type->disks_per_major +
+ (minor >> mi->type->partn_shift));
+ else
+ sprintf(gd->disk_name, "%s%c%d", mi->type->diskname,
+ 'a' + mi->index * mi->type->disks_per_major +
+ (minor >> mi->type->partn_shift),
+ minor & ((1 << mi->type->partn_shift) - 1));
+
+ gd->major = mi->major;
+ gd->first_minor = minor;
+ gd->fops = &xlvbd_block_fops;
+ gd->private_data = info;
+ gd->driverfs_dev = &(info->xbdev->dev);
+ set_capacity(gd, capacity);
+
+ if (xlvbd_init_blk_queue(gd, sector_size)) {
+ del_gendisk(gd);
+ goto out;
+ }
+
+ info->rq = gd->queue;
+
+ if (vdisk_info & VDISK_READONLY)
+ set_disk_ro(gd, 1);
+
+ if (vdisk_info & VDISK_REMOVABLE)
+ gd->flags |= GENHD_FL_REMOVABLE;
+
+ if (vdisk_info & VDISK_CDROM)
+ gd->flags |= GENHD_FL_CD;
+
+ info->gd = gd;
+
+ return 0;
+
+ out:
+ if (mi)
+ xlbd_put_major_info(mi);
+ info->mi = NULL;
+ return err;
+}
- device = MKDEV(MAJOR_XEN(ldisk->device), MINOR_XEN(ldisk->device));
+int
+xlvbd_add(blkif_sector_t capacity, int vdevice, u16 vdisk_info,
+ u16 sector_size, struct blkfront_info *info)
+{
+ struct block_device *bd;
+ int err = 0;
- bd = bdget(device);
- if ( !bd )
- return -1;
+ info->dev = MKDEV(BLKIF_MAJOR(vdevice), BLKIF_MINOR(vdevice));
- gd = get_gendisk(device, &unused);
- set_capacity(gd, disk->capacity);
- ldisk->capacity = disk->capacity;
+ bd = bdget(info->dev);
+ if (bd == NULL)
+ return -ENODEV;
- bdput(bd);
+ err = xlvbd_alloc_gendisk(BLKIF_MINOR(vdevice), capacity, vdevice,
+ vdisk_info, sector_size, info);
- return 0;
+ bdput(bd);
+ return err;
}
-void xlvbd_refresh(void)
+void
+xlvbd_del(struct blkfront_info *info)
{
- vdisk_t *newdisks;
- struct list_head *tmp, *tmp2;
- struct lvdisk *disk;
- int i, nr;
-
- newdisks = xlvbd_probe(&nr);
- if ( !newdisks ) {
- printk(KERN_ALERT "failed to probe\n");
- return;
- }
-
- i = 0;
- list_for_each_safe(tmp, tmp2, &vbds_list) {
- disk = list_entry(tmp, struct lvdisk, list);
-
- for (i = 0; i < nr; i++) {
- if ( !newdisks[i].device )
- continue;
- if ( disk->device == newdisks[i].device ) {
- xlvbd_device_update(disk, &newdisks[i]);
- newdisks[i].device = 0;
- break;
- }
- }
- if ( i == nr ) {
- xlvbd_device_del(disk);
- newdisks[i].device = 0;
- }
- }
- for (i = 0; i < nr; i++)
- if ( newdisks[i].device )
- xlvbd_device_add(&vbds_list, &newdisks[i]);
- kfree(newdisks);
-}
+ if (info->mi == NULL)
+ return;
-/*
- * xlvbd_update_vbds - reprobes the VBD status and performs updates driver
- * state. The VBDs need to be updated in this way when the domain is
- * initialised and also each time we receive an XLBLK_UPDATE event.
- */
-void xlvbd_update_vbds(void)
-{
- xlvbd_refresh();
-}
+ BUG_ON(info->gd == NULL);
+ del_gendisk(info->gd);
+ put_disk(info->gd);
+ info->gd = NULL;
-/*
- * Set up all the linux device goop for the virtual block devices
- * (vbd's) that we know about. Note that although from the backend
- * driver's p.o.v. VBDs are addressed simply an opaque 16-bit device
- * number, the domain creation tools conventionally allocate these
- * numbers to correspond to those used by 'real' linux -- this is just
- * for convenience as it means e.g. that the same /etc/fstab can be
- * used when booting with or without Xen.
- */
-int xlvbd_init(void)
-{
- int i, nr;
- vdisk_t *disks;
-
- INIT_LIST_HEAD(&vbds_list);
-
- memset(major_info, 0, sizeof(major_info));
-
- disks = xlvbd_probe(&nr);
- if ( !disks ) {
- printk(KERN_ALERT "failed to probe\n");
- return -1;
- }
-
- for (i = 0; i < nr; i++)
- xlvbd_device_add(&vbds_list, &disks[i]);
- kfree(disks);
- return 0;
+ xlbd_put_major_info(info->mi);
+ info->mi = NULL;
+
+ BUG_ON(info->rq == NULL);
+ blk_cleanup_queue(info->rq);
+ info->rq = NULL;
}
-
-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
/******************************************************************************
- * 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
-__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");
-obj-y := console.o
+obj-y := console.o xencons_ring.o
*
* 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
#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-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:
static enum { XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL } xc_mode = XC_DEFAULT;
static int xc_num = -1;
+#ifdef CONFIG_MAGIC_SYSRQ
+static unsigned long sysrq_requested;
+extern int sysrq_enabled;
+#endif
+
static int __init xencons_setup(char *str)
{
- char *q;
- int n;
-
- if ( !strncmp(str, "ttyS", 4) )
- xc_mode = XC_SERIAL;
- else if ( !strncmp(str, "tty", 3) )
- xc_mode = XC_TTY;
- else if ( !strncmp(str, "off", 3) )
- xc_mode = XC_OFF;
-
- switch ( xc_mode )
- {
- case XC_SERIAL:
- n = simple_strtol( str+4, &q, 10 );
- if ( q > (str + 4) ) xc_num = n;
- break;
- case XC_TTY:
- n = simple_strtol( str+3, &q, 10 );
- if ( q > (str + 3) ) xc_num = n;
- break;
- default:
- break;
- }
-
- return 1;
+ char *q;
+ int n;
+
+ if (!strncmp(str, "ttyS", 4))
+ xc_mode = XC_SERIAL;
+ else if (!strncmp(str, "tty", 3))
+ xc_mode = XC_TTY;
+ else if (!strncmp(str, "off", 3))
+ xc_mode = XC_OFF;
+
+ switch (xc_mode) {
+ case XC_SERIAL:
+ n = simple_strtol(str+4, &q, 10);
+ if (q > (str + 4))
+ xc_num = n;
+ break;
+ case XC_TTY:
+ n = simple_strtol(str+3, &q, 10);
+ if (q > (str + 3))
+ xc_num = n;
+ break;
+ default:
+ break;
+ }
+
+ return 1;
}
__setup("xencons=", xencons_setup);
static int __init xencons_bufsz_setup(char *str)
{
- unsigned int goal;
- goal = simple_strtoul(str, NULL, 0);
- while ( wbuf_size < goal )
- wbuf_size <<= 1;
- return 1;
+ unsigned int goal;
+ goal = simple_strtoul(str, NULL, 0);
+ if (goal) {
+ goal = roundup_pow_of_two(goal);
+ if (wbuf_size < goal)
+ wbuf_size = goal;
+ }
+ return 1;
}
__setup("xencons_bufsz=", xencons_bufsz_setup);
/* This lock protects accesses to the common transmit buffer. */
-static spinlock_t xencons_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(xencons_lock);
/* Common transmit-kick routine. */
static void __xencons_tx_flush(void);
-/* This task is used to defer sending console data until there is space. */
-static void xencons_tx_flush_task_routine(void *data);
-
-static DECLARE_TQUEUE(xencons_tx_flush_task,
- xencons_tx_flush_task_routine,
- NULL);
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
static struct tty_driver *xencons_driver;
-#else
-static struct tty_driver xencons_driver;
-#endif
-
/******************** Kernel console driver ********************************/
-static void kcons_write(
- struct console *c, const char *s, unsigned int count)
+static void kcons_write(struct console *c, const char *s, unsigned int count)
{
- int i;
- unsigned long flags;
-
- spin_lock_irqsave(&xencons_lock, flags);
-
- for ( i = 0; i < count; i++ )
- {
- if ( (wp - wc) >= (wbuf_size - 1) )
- break;
- if ( (wbuf[WBUF_MASK(wp++)] = s[i]) == '\n' )
- wbuf[WBUF_MASK(wp++)] = '\r';
- }
-
- __xencons_tx_flush();
-
- spin_unlock_irqrestore(&xencons_lock, flags);
+ int i = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&xencons_lock, flags);
+
+ while (i < count) {
+ for (; i < count; i++) {
+ if ((wp - wc) >= (wbuf_size - 1))
+ break;
+ if ((wbuf[WBUF_MASK(wp++)] = s[i]) == '\n')
+ wbuf[WBUF_MASK(wp++)] = '\r';
+ }
+
+ __xencons_tx_flush();
+ }
+
+ spin_unlock_irqrestore(&xencons_lock, flags);
}
-static void kcons_write_dom0(
- struct console *c, const char *s, unsigned int count)
+static void kcons_write_dom0(struct console *c, const char *s, unsigned int count)
{
- int rc;
-
- while ( (count > 0) &&
- ((rc = HYPERVISOR_console_io(
- CONSOLEIO_write, count, (char *)s)) > 0) )
- {
- count -= rc;
- s += rc;
- }
+
+ while (count > 0) {
+ int rc;
+ rc = HYPERVISOR_console_io( CONSOLEIO_write, count, (char *)s);
+ if (rc <= 0)
+ break;
+ count -= rc;
+ s += rc;
+ }
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
static struct tty_driver *kcons_device(struct console *c, int *index)
{
- *index = c->index;
- return xencons_driver;
-}
-#else
-static kdev_t kcons_device(struct console *c)
-{
- return MKDEV(TTY_MAJOR, (xc_mode == XC_SERIAL) ? 64 : 1);
+ *index = 0;
+ return xencons_driver;
}
-#endif
static struct console kcons_info = {
- device: kcons_device,
- flags: CON_PRINTBUFFER,
- index: -1
+ .device = kcons_device,
+ .flags = CON_PRINTBUFFER | CON_ENABLED,
+ .index = -1,
};
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
#define __RETCODE 0
static int __init xen_console_init(void)
-#else
-#define __RETCODE
-void xen_console_init(void)
-#endif
{
- if ( xen_start_info.flags & SIF_INITDOMAIN )
- {
- if ( xc_mode == XC_DEFAULT )
- xc_mode = XC_SERIAL;
- kcons_info.write = kcons_write_dom0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- if ( xc_mode == XC_SERIAL )
- kcons_info.flags |= CON_ENABLED;
-#endif
- }
- else
- {
- if ( xc_mode == XC_DEFAULT )
- xc_mode = XC_TTY;
- kcons_info.write = kcons_write;
- }
-
- switch ( xc_mode )
- {
- case XC_SERIAL:
- strcpy(kcons_info.name, "ttyS");
- if ( xc_num == -1 ) xc_num = 0;
- break;
-
- case XC_TTY:
- strcpy(kcons_info.name, "tty");
- if ( xc_num == -1 ) xc_num = 1;
- break;
-
- default:
- return __RETCODE;
- }
-
- wbuf = alloc_bootmem(wbuf_size);
-
- register_console(&kcons_info);
-
- return __RETCODE;
+ if (!is_running_on_xen())
+ return __RETCODE;
+
+ if (xen_start_info->flags & SIF_INITDOMAIN) {
+ if (xc_mode == XC_DEFAULT)
+ xc_mode = XC_SERIAL;
+ kcons_info.write = kcons_write_dom0;
+ } else {
+ if (xc_mode == XC_DEFAULT)
+ xc_mode = XC_TTY;
+ kcons_info.write = kcons_write;
+ }
+
+ switch (xc_mode) {
+ case XC_SERIAL:
+ strcpy(kcons_info.name, "ttyS");
+ if (xc_num == -1)
+ xc_num = 0;
+ break;
+
+ case XC_TTY:
+ strcpy(kcons_info.name, "tty");
+ if (xc_num == -1)
+ xc_num = 1;
+ break;
+
+ default:
+ return __RETCODE;
+ }
+
+ wbuf = alloc_bootmem(wbuf_size);
+
+ register_console(&kcons_info);
+
+ return __RETCODE;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
console_initcall(xen_console_init);
-#endif
/*** Useful function for console debugging -- goes straight to Xen. ***/
asmlinkage int xprintk(const char *fmt, ...)
{
- va_list args;
- int printk_len;
- static char printk_buf[1024];
-
- /* Emit the output into the temporary buffer */
- va_start(args, fmt);
- printk_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
- va_end(args);
-
- /* Send the processed output directly to Xen. */
- kcons_write_dom0(NULL, printk_buf, printk_len);
-
- return 0;
+ va_list args;
+ int printk_len;
+ static char printk_buf[1024];
+
+ /* Emit the output into the temporary buffer */
+ va_start(args, fmt);
+ printk_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
+ va_end(args);
+
+ /* Send the processed output directly to Xen. */
+ kcons_write_dom0(NULL, printk_buf, printk_len);
+
+ return 0;
}
/*** Forcibly flush console data before dying. ***/
void xencons_force_flush(void)
{
- ctrl_msg_t msg;
- int sz;
-
- /* Emergency console is synchronous, so there's nothing to flush. */
- if ( xen_start_info.flags & SIF_INITDOMAIN )
- return;
-
- /*
- * We use dangerous control-interface functions that require a quiescent
- * system and no interrupts. Try to ensure this with a global cli().
- */
- local_irq_disable(); /* XXXsmp */
-
- /* Spin until console data is flushed through to the domain controller. */
- while ( (wc != wp) && !ctrl_if_transmitter_empty() )
- {
- /* Interrupts are disabled -- we must manually reap responses. */
- ctrl_if_discard_responses();
-
- if ( (sz = wp - wc) == 0 )
- continue;
- if ( sz > sizeof(msg.msg) )
- sz = sizeof(msg.msg);
- if ( sz > (wbuf_size - WBUF_MASK(wc)) )
- sz = wbuf_size - WBUF_MASK(wc);
-
- msg.type = CMSG_CONSOLE;
- msg.subtype = CMSG_CONSOLE_DATA;
- msg.length = sz;
- memcpy(msg.msg, &wbuf[WBUF_MASK(wc)], sz);
-
- if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 )
- wc += sz;
- }
+ int sz;
+
+ /* Emergency console is synchronous, so there's nothing to flush. */
+ if (xen_start_info->flags & SIF_INITDOMAIN)
+ return;
+
+ /* Spin until console data is flushed through to the daemon. */
+ while (wc != wp) {
+ int sent = 0;
+ if ((sz = wp - wc) == 0)
+ continue;
+ sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz);
+ if (sent > 0)
+ wc += sent;
+ }
}
/******************** User-space console driver (/dev/console) ************/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
#define DRV(_d) (_d)
-#define TTY_INDEX(_tty) ((_tty)->index)
-#else
-static int xencons_refcount;
-static struct tty_struct *xencons_table[MAX_NR_CONSOLES];
-#define DRV(_d) (&(_d))
-#define TTY_INDEX(_tty) (MINOR((_tty)->device) - xencons_driver.minor_start)
-#endif
+#define DUMMY_TTY(_tty) ((xc_mode != XC_SERIAL) && \
+ ((_tty)->index != (xc_num - 1)))
static struct termios *xencons_termios[MAX_NR_CONSOLES];
static struct termios *xencons_termios_locked[MAX_NR_CONSOLES];
static int xencons_priv_irq;
static char x_char;
-/* Non-privileged receive callback. */
-static void xencons_rx(ctrl_msg_t *msg, unsigned long id)
+void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
{
- int i;
- unsigned long flags;
-
- spin_lock_irqsave(&xencons_lock, flags);
- if ( xencons_tty != NULL )
- {
- for ( i = 0; i < msg->length; i++ )
- tty_insert_flip_char(xencons_tty, msg->msg[i], 0);
- tty_flip_buffer_push(xencons_tty);
- }
- spin_unlock_irqrestore(&xencons_lock, flags);
-
- msg->length = 0;
- ctrl_if_send_response(msg);
+ int i;
+ unsigned long flags;
+
+ spin_lock_irqsave(&xencons_lock, flags);
+ if (xencons_tty == NULL)
+ goto out;
+
+ for (i = 0; i < len; i++) {
+#ifdef CONFIG_MAGIC_SYSRQ
+ if (sysrq_enabled) {
+ if (buf[i] == '\x0f') { /* ^O */
+ sysrq_requested = jiffies;
+ continue; /* don't print the sysrq key */
+ } else if (sysrq_requested) {
+ unsigned long sysrq_timeout =
+ sysrq_requested + HZ*2;
+ sysrq_requested = 0;
+ if (time_before(jiffies, sysrq_timeout)) {
+ spin_unlock_irqrestore(
+ &xencons_lock, flags);
+ handle_sysrq(
+ buf[i], regs, xencons_tty);
+ spin_lock_irqsave(
+ &xencons_lock, flags);
+ continue;
+ }
+ }
+ }
+#endif
+ tty_insert_flip_char(xencons_tty, buf[i], 0);
+ }
+ tty_flip_buffer_push(xencons_tty);
+
+ out:
+ spin_unlock_irqrestore(&xencons_lock, flags);
}
-/* Privileged and non-privileged transmit worker. */
static void __xencons_tx_flush(void)
{
- int sz, work_done = 0;
- ctrl_msg_t msg;
-
- if ( xen_start_info.flags & SIF_INITDOMAIN )
- {
- if ( x_char )
- {
- kcons_write_dom0(NULL, &x_char, 1);
- x_char = 0;
- work_done = 1;
- }
-
- while ( wc != wp )
- {
- sz = wp - wc;
- if ( sz > (wbuf_size - WBUF_MASK(wc)) )
- sz = wbuf_size - WBUF_MASK(wc);
- kcons_write_dom0(NULL, &wbuf[WBUF_MASK(wc)], sz);
- wc += sz;
- work_done = 1;
- }
- }
- else
- {
- while ( x_char )
- {
- msg.type = CMSG_CONSOLE;
- msg.subtype = CMSG_CONSOLE_DATA;
- msg.length = 1;
- msg.msg[0] = x_char;
-
- if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 )
- x_char = 0;
- else if ( ctrl_if_enqueue_space_callback(&xencons_tx_flush_task) )
- break;
-
- work_done = 1;
- }
-
- while ( wc != wp )
- {
- sz = wp - wc;
- if ( sz > sizeof(msg.msg) )
- sz = sizeof(msg.msg);
- if ( sz > (wbuf_size - WBUF_MASK(wc)) )
- sz = wbuf_size - WBUF_MASK(wc);
-
- msg.type = CMSG_CONSOLE;
- msg.subtype = CMSG_CONSOLE_DATA;
- msg.length = sz;
- memcpy(msg.msg, &wbuf[WBUF_MASK(wc)], sz);
-
- if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 )
- wc += sz;
- else if ( ctrl_if_enqueue_space_callback(&xencons_tx_flush_task) )
- break;
-
- work_done = 1;
- }
- }
-
- if ( work_done && (xencons_tty != NULL) )
- {
- wake_up_interruptible(&xencons_tty->write_wait);
- if ( (xencons_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- (xencons_tty->ldisc.write_wakeup != NULL) )
- (xencons_tty->ldisc.write_wakeup)(xencons_tty);
- }
+ int sent, sz, work_done = 0;
+
+ if (x_char) {
+ if (xen_start_info->flags & SIF_INITDOMAIN)
+ kcons_write_dom0(NULL, &x_char, 1);
+ else
+ while (x_char)
+ if (xencons_ring_send(&x_char, 1) == 1)
+ break;
+ x_char = 0;
+ work_done = 1;
+ }
+
+ while (wc != wp) {
+ sz = wp - wc;
+ if (sz > (wbuf_size - WBUF_MASK(wc)))
+ sz = wbuf_size - WBUF_MASK(wc);
+ if (xen_start_info->flags & SIF_INITDOMAIN) {
+ kcons_write_dom0(NULL, &wbuf[WBUF_MASK(wc)], sz);
+ wc += sz;
+ } else {
+ sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz);
+ if (sent == 0)
+ break;
+ wc += sent;
+ }
+ work_done = 1;
+ }
+
+ if (work_done && (xencons_tty != NULL)) {
+ wake_up_interruptible(&xencons_tty->write_wait);
+ if ((xencons_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+ (xencons_tty->ldisc.write_wakeup != NULL))
+ (xencons_tty->ldisc.write_wakeup)(xencons_tty);
+ }
}
-/* Non-privileged transmit kicker. */
-static void xencons_tx_flush_task_routine(void *data)
+void xencons_tx(void)
{
- unsigned long flags;
- spin_lock_irqsave(&xencons_lock, flags);
- __xencons_tx_flush();
- spin_unlock_irqrestore(&xencons_lock, flags);
+ unsigned long flags;
+
+ spin_lock_irqsave(&xencons_lock, flags);
+ __xencons_tx_flush();
+ spin_unlock_irqrestore(&xencons_lock, flags);
}
/* Privileged receive callback and transmit kicker. */
static irqreturn_t xencons_priv_interrupt(int irq, void *dev_id,
- struct pt_regs *regs)
+ struct pt_regs *regs)
{
- static char rbuf[16];
- int i, l;
- unsigned long flags;
+ static char rbuf[16];
+ int l;
- spin_lock_irqsave(&xencons_lock, flags);
+ while ((l = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0)
+ xencons_rx(rbuf, l, regs);
- if ( xencons_tty != NULL )
- {
- /* Receive work. */
- while ( (l = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0 )
- for ( i = 0; i < l; i++ )
- tty_insert_flip_char(xencons_tty, rbuf[i], 0);
- if ( xencons_tty->flip.count != 0 )
- tty_flip_buffer_push(xencons_tty);
- }
+ xencons_tx();
- /* Transmit work. */
- __xencons_tx_flush();
-
- spin_unlock_irqrestore(&xencons_lock, flags);
-
- return IRQ_HANDLED;
+ return IRQ_HANDLED;
}
static int xencons_write_room(struct tty_struct *tty)
{
- return wbuf_size - (wp - wc);
+ return wbuf_size - (wp - wc);
}
static int xencons_chars_in_buffer(struct tty_struct *tty)
{
- return wp - wc;
+ return wp - wc;
}
static void xencons_send_xchar(struct tty_struct *tty, char ch)
{
- unsigned long flags;
+ unsigned long flags;
- if ( TTY_INDEX(tty) != 0 )
- return;
+ if (DUMMY_TTY(tty))
+ return;
- spin_lock_irqsave(&xencons_lock, flags);
- x_char = ch;
- __xencons_tx_flush();
- spin_unlock_irqrestore(&xencons_lock, flags);
+ spin_lock_irqsave(&xencons_lock, flags);
+ x_char = ch;
+ __xencons_tx_flush();
+ spin_unlock_irqrestore(&xencons_lock, flags);
}
static void xencons_throttle(struct tty_struct *tty)
{
- if ( TTY_INDEX(tty) != 0 )
- return;
+ if (DUMMY_TTY(tty))
+ return;
- if ( I_IXOFF(tty) )
- xencons_send_xchar(tty, STOP_CHAR(tty));
+ if (I_IXOFF(tty))
+ xencons_send_xchar(tty, STOP_CHAR(tty));
}
static void xencons_unthrottle(struct tty_struct *tty)
{
- if ( TTY_INDEX(tty) != 0 )
- return;
-
- if ( I_IXOFF(tty) )
- {
- if ( x_char != 0 )
- x_char = 0;
- else
- xencons_send_xchar(tty, START_CHAR(tty));
- }
+ if (DUMMY_TTY(tty))
+ return;
+
+ if (I_IXOFF(tty)) {
+ if (x_char != 0)
+ x_char = 0;
+ else
+ xencons_send_xchar(tty, START_CHAR(tty));
+ }
}
static void xencons_flush_buffer(struct tty_struct *tty)
{
- unsigned long flags;
+ unsigned long flags;
- if ( TTY_INDEX(tty) != 0 )
- return;
+ if (DUMMY_TTY(tty))
+ return;
- spin_lock_irqsave(&xencons_lock, flags);
- wc = wp = 0;
- spin_unlock_irqrestore(&xencons_lock, flags);
+ spin_lock_irqsave(&xencons_lock, flags);
+ wc = wp = 0;
+ spin_unlock_irqrestore(&xencons_lock, flags);
}
static inline int __xencons_put_char(int ch)
{
- char _ch = (char)ch;
- if ( (wp - wc) == wbuf_size )
- return 0;
- wbuf[WBUF_MASK(wp++)] = _ch;
- return 1;
+ char _ch = (char)ch;
+ if ((wp - wc) == wbuf_size)
+ return 0;
+ wbuf[WBUF_MASK(wp++)] = _ch;
+ return 1;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
static int xencons_write(
- struct tty_struct *tty,
- const unsigned char *buf,
- int count)
+ struct tty_struct *tty,
+ const unsigned char *buf,
+ int count)
{
- int i;
- unsigned long flags;
+ int i;
+ unsigned long flags;
- if ( TTY_INDEX(tty) != 0 )
- return count;
+ if (DUMMY_TTY(tty))
+ return count;
- spin_lock_irqsave(&xencons_lock, flags);
+ spin_lock_irqsave(&xencons_lock, flags);
- for ( i = 0; i < count; i++ )
- if ( !__xencons_put_char(buf[i]) )
- break;
+ for (i = 0; i < count; i++)
+ if (!__xencons_put_char(buf[i]))
+ break;
- if ( i != 0 )
- __xencons_tx_flush();
+ if (i != 0)
+ __xencons_tx_flush();
- spin_unlock_irqrestore(&xencons_lock, flags);
+ spin_unlock_irqrestore(&xencons_lock, flags);
- return i;
+ return i;
}
-#else
-static int xencons_write(
- struct tty_struct *tty,
- int from_user,
- const u_char *buf,
- int count)
-{
- int i;
- unsigned long flags;
-
- if ( from_user && verify_area(VERIFY_READ, buf, count) )
- return -EINVAL;
-
- if ( TTY_INDEX(tty) != 0 )
- return count;
-
- spin_lock_irqsave(&xencons_lock, flags);
-
- for ( i = 0; i < count; i++ )
- {
- char ch;
- if ( from_user )
- __get_user(ch, buf + i);
- else
- ch = buf[i];
- if ( !__xencons_put_char(ch) )
- break;
- }
-
- if ( i != 0 )
- __xencons_tx_flush();
-
- spin_unlock_irqrestore(&xencons_lock, flags);
-
- return i;
-}
-#endif
static void xencons_put_char(struct tty_struct *tty, u_char ch)
{
- unsigned long flags;
+ unsigned long flags;
- if ( TTY_INDEX(tty) != 0 )
- return;
+ if (DUMMY_TTY(tty))
+ return;
- spin_lock_irqsave(&xencons_lock, flags);
- (void)__xencons_put_char(ch);
- spin_unlock_irqrestore(&xencons_lock, flags);
+ spin_lock_irqsave(&xencons_lock, flags);
+ (void)__xencons_put_char(ch);
+ spin_unlock_irqrestore(&xencons_lock, flags);
}
static void xencons_flush_chars(struct tty_struct *tty)
{
- unsigned long flags;
+ unsigned long flags;
- if ( TTY_INDEX(tty) != 0 )
- return;
+ if (DUMMY_TTY(tty))
+ return;
- spin_lock_irqsave(&xencons_lock, flags);
- __xencons_tx_flush();
- spin_unlock_irqrestore(&xencons_lock, flags);
+ spin_lock_irqsave(&xencons_lock, flags);
+ __xencons_tx_flush();
+ spin_unlock_irqrestore(&xencons_lock, flags);
}
static void xencons_wait_until_sent(struct tty_struct *tty, int timeout)
{
- unsigned long orig_jiffies = jiffies;
-
- if ( TTY_INDEX(tty) != 0 )
- return;
-
- while ( DRV(tty->driver)->chars_in_buffer(tty) )
- {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- if ( signal_pending(current) )
- break;
- if ( (timeout != 0) && time_after(jiffies, orig_jiffies + timeout) )
- break;
- }
-
- set_current_state(TASK_RUNNING);
+ unsigned long orig_jiffies = jiffies;
+
+ if (DUMMY_TTY(tty))
+ return;
+
+ while (DRV(tty->driver)->chars_in_buffer(tty)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ if (signal_pending(current))
+ break;
+ if (timeout && time_after(jiffies, orig_jiffies + timeout))
+ break;
+ }
+
+ set_current_state(TASK_RUNNING);
}
static int xencons_open(struct tty_struct *tty, struct file *filp)
{
- unsigned long flags;
+ unsigned long flags;
- if ( TTY_INDEX(tty) != 0 )
- return 0;
+ if (DUMMY_TTY(tty))
+ return 0;
- spin_lock_irqsave(&xencons_lock, flags);
- tty->driver_data = NULL;
- if ( xencons_tty == NULL )
- xencons_tty = tty;
- __xencons_tx_flush();
- spin_unlock_irqrestore(&xencons_lock, flags);
+ spin_lock_irqsave(&xencons_lock, flags);
+ tty->driver_data = NULL;
+ if (xencons_tty == NULL)
+ xencons_tty = tty;
+ __xencons_tx_flush();
+ spin_unlock_irqrestore(&xencons_lock, flags);
- return 0;
+ return 0;
}
static void xencons_close(struct tty_struct *tty, struct file *filp)
{
- unsigned long flags;
-
- if ( TTY_INDEX(tty) != 0 )
- return;
-
- if ( tty->count == 1 )
- {
- tty->closing = 1;
- tty_wait_until_sent(tty, 0);
- if ( DRV(tty->driver)->flush_buffer != NULL )
- DRV(tty->driver)->flush_buffer(tty);
- if ( tty->ldisc.flush_buffer != NULL )
- tty->ldisc.flush_buffer(tty);
- tty->closing = 0;
- spin_lock_irqsave(&xencons_lock, flags);
- xencons_tty = NULL;
- spin_unlock_irqrestore(&xencons_lock, flags);
- }
+ unsigned long flags;
+
+ if (DUMMY_TTY(tty))
+ return;
+
+ mutex_lock(&tty_mutex);
+
+ if (tty->count != 1) {
+ mutex_unlock(&tty_mutex);
+ return;
+ }
+
+ /* Prevent other threads from re-opening this tty. */
+ set_bit(TTY_CLOSING, &tty->flags);
+ mutex_unlock(&tty_mutex);
+
+ tty->closing = 1;
+ tty_wait_until_sent(tty, 0);
+ if (DRV(tty->driver)->flush_buffer != NULL)
+ DRV(tty->driver)->flush_buffer(tty);
+ if (tty->ldisc.flush_buffer != NULL)
+ tty->ldisc.flush_buffer(tty);
+ tty->closing = 0;
+ spin_lock_irqsave(&xencons_lock, flags);
+ xencons_tty = NULL;
+ spin_unlock_irqrestore(&xencons_lock, flags);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
static struct tty_operations xencons_ops = {
- .open = xencons_open,
- .close = xencons_close,
- .write = xencons_write,
- .write_room = xencons_write_room,
- .put_char = xencons_put_char,
- .flush_chars = xencons_flush_chars,
- .chars_in_buffer = xencons_chars_in_buffer,
- .send_xchar = xencons_send_xchar,
- .flush_buffer = xencons_flush_buffer,
- .throttle = xencons_throttle,
- .unthrottle = xencons_unthrottle,
- .wait_until_sent = xencons_wait_until_sent,
+ .open = xencons_open,
+ .close = xencons_close,
+ .write = xencons_write,
+ .write_room = xencons_write_room,
+ .put_char = xencons_put_char,
+ .flush_chars = xencons_flush_chars,
+ .chars_in_buffer = xencons_chars_in_buffer,
+ .send_xchar = xencons_send_xchar,
+ .flush_buffer = xencons_flush_buffer,
+ .throttle = xencons_throttle,
+ .unthrottle = xencons_unthrottle,
+ .wait_until_sent = xencons_wait_until_sent,
};
-#ifdef CONFIG_XEN_PRIVILEGED_GUEST
-static const char *xennullcon_startup(void)
-{
- return NULL;
-}
-
-static int xennullcon_dummy(void)
-{
- return 0;
-}
-
-#define DUMMY (void *)xennullcon_dummy
-
-/*
- * The console `switch' structure for the dummy console
- *
- * Most of the operations are dummies.
- */
-
-const struct consw xennull_con = {
- .owner = THIS_MODULE,
- .con_startup = xennullcon_startup,
- .con_init = DUMMY,
- .con_deinit = DUMMY,
- .con_clear = DUMMY,
- .con_putc = DUMMY,
- .con_putcs = DUMMY,
- .con_cursor = DUMMY,
- .con_scroll = DUMMY,
- .con_bmove = DUMMY,
- .con_switch = DUMMY,
- .con_blank = DUMMY,
- .con_font_set = DUMMY,
- .con_font_get = DUMMY,
- .con_font_default = DUMMY,
- .con_font_copy = DUMMY,
- .con_set_palette = DUMMY,
- .con_scrolldelta = DUMMY,
-};
-#endif
-#endif
-
static int __init xencons_init(void)
{
- int rc;
-
- if ( xc_mode == XC_OFF )
- return 0;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- xencons_driver = alloc_tty_driver((xc_mode == XC_SERIAL) ?
- 1 : MAX_NR_CONSOLES);
- if ( xencons_driver == NULL )
- return -ENOMEM;
-#else
- memset(&xencons_driver, 0, sizeof(struct tty_driver));
- xencons_driver.magic = TTY_DRIVER_MAGIC;
- xencons_driver.refcount = &xencons_refcount;
- xencons_driver.table = xencons_table;
- xencons_driver.num = (xc_mode == XC_SERIAL) ? 1 : MAX_NR_CONSOLES;
-#endif
-
- DRV(xencons_driver)->major = TTY_MAJOR;
- DRV(xencons_driver)->type = TTY_DRIVER_TYPE_SERIAL;
- DRV(xencons_driver)->subtype = SERIAL_TYPE_NORMAL;
- DRV(xencons_driver)->init_termios = tty_std_termios;
- DRV(xencons_driver)->flags =
- TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_NO_DEVFS;
- DRV(xencons_driver)->termios = xencons_termios;
- DRV(xencons_driver)->termios_locked = xencons_termios_locked;
-
- if ( xc_mode == XC_SERIAL )
- {
- DRV(xencons_driver)->name = "ttyS";
- DRV(xencons_driver)->minor_start = 64 + xc_num;
- DRV(xencons_driver)->name_base = 0 + xc_num;
- }
- else
- {
- DRV(xencons_driver)->name = "tty";
- DRV(xencons_driver)->minor_start = xc_num;
- DRV(xencons_driver)->name_base = xc_num;
- }
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- tty_set_operations(xencons_driver, &xencons_ops);
-#else
- xencons_driver.open = xencons_open;
- xencons_driver.close = xencons_close;
- xencons_driver.write = xencons_write;
- xencons_driver.write_room = xencons_write_room;
- xencons_driver.put_char = xencons_put_char;
- xencons_driver.flush_chars = xencons_flush_chars;
- xencons_driver.chars_in_buffer = xencons_chars_in_buffer;
- xencons_driver.send_xchar = xencons_send_xchar;
- xencons_driver.flush_buffer = xencons_flush_buffer;
- xencons_driver.throttle = xencons_throttle;
- xencons_driver.unthrottle = xencons_unthrottle;
- xencons_driver.wait_until_sent = xencons_wait_until_sent;
-#endif
-
- if ( (rc = tty_register_driver(DRV(xencons_driver))) != 0 )
- {
- printk("WARNING: Failed to register Xen virtual "
- "console driver as '%s%d'\n",
- DRV(xencons_driver)->name, DRV(xencons_driver)->name_base);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- put_tty_driver(xencons_driver);
- xencons_driver = NULL;
-#endif
- return rc;
- }
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- tty_register_device(xencons_driver, 0, NULL);
-#endif
-
- if ( xen_start_info.flags & SIF_INITDOMAIN )
- {
- xencons_priv_irq = bind_virq_to_irq(VIRQ_CONSOLE);
- (void)request_irq(xencons_priv_irq,
- xencons_priv_interrupt, 0, "console", NULL);
- }
- else
- {
- (void)ctrl_if_register_receiver(CMSG_CONSOLE, xencons_rx, 0);
- }
-
- printk("Xen virtual console successfully installed as %s%d\n",
- DRV(xencons_driver)->name,
- DRV(xencons_driver)->name_base );
-
- return 0;
+ int rc;
+
+ if (!is_running_on_xen())
+ return -ENODEV;
+
+ if (xc_mode == XC_OFF)
+ return 0;
+
+ xencons_ring_init();
+
+ xencons_driver = alloc_tty_driver((xc_mode == XC_SERIAL) ?
+ 1 : MAX_NR_CONSOLES);
+ if (xencons_driver == NULL)
+ return -ENOMEM;
+
+ DRV(xencons_driver)->name = "xencons";
+ DRV(xencons_driver)->major = TTY_MAJOR;
+ DRV(xencons_driver)->type = TTY_DRIVER_TYPE_SERIAL;
+ DRV(xencons_driver)->subtype = SERIAL_TYPE_NORMAL;
+ DRV(xencons_driver)->init_termios = tty_std_termios;
+ DRV(xencons_driver)->flags =
+ TTY_DRIVER_REAL_RAW |
+ TTY_DRIVER_RESET_TERMIOS;
+ DRV(xencons_driver)->termios = xencons_termios;
+ DRV(xencons_driver)->termios_locked = xencons_termios_locked;
+
+ if (xc_mode == XC_SERIAL) {
+ DRV(xencons_driver)->name = "ttyS";
+ DRV(xencons_driver)->minor_start = 64 + xc_num;
+ DRV(xencons_driver)->name_base = 0 + xc_num;
+ } else {
+ DRV(xencons_driver)->name = "tty";
+ DRV(xencons_driver)->minor_start = 1;
+ DRV(xencons_driver)->name_base = 1;
+ }
+
+ tty_set_operations(xencons_driver, &xencons_ops);
+
+ if ((rc = tty_register_driver(DRV(xencons_driver))) != 0) {
+ printk("WARNING: Failed to register Xen virtual "
+ "console driver as '%s%d'\n",
+ DRV(xencons_driver)->name,
+ DRV(xencons_driver)->name_base);
+ put_tty_driver(xencons_driver);
+ xencons_driver = NULL;
+ return rc;
+ }
+
+ if (xen_start_info->flags & SIF_INITDOMAIN) {
+ xencons_priv_irq = bind_virq_to_irqhandler(
+ VIRQ_CONSOLE,
+ 0,
+ xencons_priv_interrupt,
+ 0,
+ "console",
+ NULL);
+ BUG_ON(xencons_priv_irq < 0);
+ }
+
+ printk("Xen virtual console successfully installed as %s%d\n",
+ DRV(xencons_driver)->name, xc_num);
+
+ return 0;
}
module_init(xencons_init);
+
+MODULE_LICENSE("Dual BSD/GPL");
/******************************************************************************
* evtchn.c
*
- * Xenolinux driver for receiving and demuxing event-channel signals.
+ * Driver for receiving and demuxing event-channel signals.
*
- * Copyright (c) 2004, K A Fraser
+ * Copyright (c) 2004-2005, K A Fraser
* Multi-process extensions Copyright (c) 2004, Steven Smith
*
- * This file may be distributed separately from the Linux kernel, or
- * incorporated into other software packages, subject to the following license:
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this source file (the "Software"), to deal in the Software without
#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>
-#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 {
- /* 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? */
void evtchn_device_upcall(int port)
{
- struct per_user_data *u;
-
- spin_lock(&port_user_lock);
-
- mask_evtchn(port);
- clear_evtchn(port);
-
- if ( (u = port_user[port]) != NULL )
- {
- if ( (u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE )
- {
- u->ring[EVTCHN_RING_MASK(u->ring_prod)] = (u16)port;
- if ( u->ring_cons == u->ring_prod++ )
- {
- wake_up_interruptible(&u->evtchn_wait);
- kill_fasync(&u->evtchn_async_queue, SIGIO, POLL_IN);
- }
- }
- else
- {
- u->ring_overflow = 1;
- }
- }
-
- spin_unlock(&port_user_lock);
+ struct per_user_data *u;
+
+ spin_lock(&port_user_lock);
+
+ mask_evtchn(port);
+ clear_evtchn(port);
+
+ if ((u = port_user[port]) != NULL) {
+ if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) {
+ u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port;
+ if (u->ring_cons == u->ring_prod++) {
+ wake_up_interruptible(&u->evtchn_wait);
+ kill_fasync(&u->evtchn_async_queue,
+ SIGIO, POLL_IN);
+ }
+ } else {
+ u->ring_overflow = 1;
+ }
+ }
+
+ spin_unlock(&port_user_lock);
}
-static ssize_t evtchn_read(struct file *file, char *buf,
- size_t count, loff_t *ppos)
+static ssize_t evtchn_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
{
- int rc;
- unsigned int c, p, bytes1 = 0, bytes2 = 0;
- DECLARE_WAITQUEUE(wait, current);
- struct per_user_data *u = file->private_data;
-
- add_wait_queue(&u->evtchn_wait, &wait);
-
- count &= ~1; /* even number of bytes */
-
- if ( count == 0 )
- {
- rc = 0;
- goto out;
- }
-
- if ( count > PAGE_SIZE )
- count = PAGE_SIZE;
-
- for ( ; ; )
- {
- set_current_state(TASK_INTERRUPTIBLE);
-
- if ( (c = u->ring_cons) != (p = u->ring_prod) )
- break;
-
- if ( u->ring_overflow )
- {
- rc = -EFBIG;
- goto out;
- }
-
- if ( file->f_flags & O_NONBLOCK )
- {
- rc = -EAGAIN;
- goto out;
- }
-
- if ( signal_pending(current) )
- {
- rc = -ERESTARTSYS;
- goto out;
- }
-
- schedule();
- }
-
- /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
- if ( ((c ^ p) & EVTCHN_RING_SIZE) != 0 )
- {
- bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) * sizeof(u16);
- bytes2 = EVTCHN_RING_MASK(p) * sizeof(u16);
- }
- else
- {
- bytes1 = (p - c) * sizeof(u16);
- bytes2 = 0;
- }
-
- /* Truncate chunks according to caller's maximum byte count. */
- if ( bytes1 > count )
- {
- bytes1 = count;
- bytes2 = 0;
- }
- else if ( (bytes1 + bytes2) > count )
- {
- bytes2 = count - bytes1;
- }
-
- if ( copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) ||
- ((bytes2 != 0) && copy_to_user(&buf[bytes1], &u->ring[0], bytes2)) )
- {
- rc = -EFAULT;
- goto out;
- }
-
- u->ring_cons += (bytes1 + bytes2) / sizeof(u16);
-
- rc = bytes1 + bytes2;
-
- out:
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(&u->evtchn_wait, &wait);
- return rc;
+ int rc;
+ unsigned int c, p, bytes1 = 0, bytes2 = 0;
+ struct per_user_data *u = file->private_data;
+
+ /* Whole number of ports. */
+ count &= ~(sizeof(evtchn_port_t)-1);
+
+ if (count == 0)
+ return 0;
+
+ if (count > PAGE_SIZE)
+ count = PAGE_SIZE;
+
+ for (;;) {
+ if (u->ring_overflow)
+ return -EFBIG;
+
+ if ((c = u->ring_cons) != (p = u->ring_prod))
+ break;
+
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ rc = wait_event_interruptible(
+ u->evtchn_wait, u->ring_cons != u->ring_prod);
+ if (rc)
+ return rc;
+ }
+
+ /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
+ if (((c ^ p) & EVTCHN_RING_SIZE) != 0) {
+ bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) *
+ sizeof(evtchn_port_t);
+ bytes2 = EVTCHN_RING_MASK(p) * sizeof(evtchn_port_t);
+ } else {
+ bytes1 = (p - c) * sizeof(evtchn_port_t);
+ bytes2 = 0;
+ }
+
+ /* Truncate chunks according to caller's maximum byte count. */
+ if (bytes1 > count) {
+ bytes1 = count;
+ bytes2 = 0;
+ } else if ((bytes1 + bytes2) > count) {
+ bytes2 = count - bytes1;
+ }
+
+ if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) ||
+ ((bytes2 != 0) &&
+ copy_to_user(&buf[bytes1], &u->ring[0], bytes2)))
+ return -EFAULT;
+
+ u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t);
+
+ return bytes1 + bytes2;
}
-static ssize_t evtchn_write(struct file *file, const char *buf,
- size_t count, loff_t *ppos)
+static ssize_t evtchn_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
{
- int rc, i;
- u16 *kbuf = (u16 *)__get_free_page(GFP_KERNEL);
- struct per_user_data *u = file->private_data;
+ int rc, i;
+ evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
+ struct per_user_data *u = file->private_data;
- if ( kbuf == NULL )
- return -ENOMEM;
+ if (kbuf == NULL)
+ return -ENOMEM;
- count &= ~1; /* even number of bytes */
+ /* Whole number of ports. */
+ count &= ~(sizeof(evtchn_port_t)-1);
- if ( count == 0 )
- {
- rc = 0;
- goto out;
- }
+ if (count == 0) {
+ rc = 0;
+ goto out;
+ }
- if ( count > PAGE_SIZE )
- count = PAGE_SIZE;
+ if (count > PAGE_SIZE)
+ count = PAGE_SIZE;
- if ( copy_from_user(kbuf, buf, count) != 0 )
- {
- rc = -EFAULT;
- goto out;
- }
+ if (copy_from_user(kbuf, buf, count) != 0) {
+ rc = -EFAULT;
+ goto out;
+ }
- spin_lock_irq(&port_user_lock);
- for ( i = 0; i < (count/2); i++ )
- if ( (kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u) )
- unmask_evtchn(kbuf[i]);
- spin_unlock_irq(&port_user_lock);
+ spin_lock_irq(&port_user_lock);
+ for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
+ if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u))
+ unmask_evtchn(kbuf[i]);
+ spin_unlock_irq(&port_user_lock);
- rc = count;
+ rc = count;
out:
- free_page((unsigned long)kbuf);
- return rc;
+ free_page((unsigned long)kbuf);
+ return rc;
}
-static int evtchn_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static void evtchn_bind_to_user(struct per_user_data *u, int port)
{
- int rc = 0;
- struct per_user_data *u = file->private_data;
+ spin_lock_irq(&port_user_lock);
+ BUG_ON(port_user[port] != NULL);
+ port_user[port] = u;
+ unmask_evtchn(port);
+ spin_unlock_irq(&port_user_lock);
+}
- spin_lock_irq(&port_user_lock);
+static int evtchn_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int rc;
+ struct per_user_data *u = file->private_data;
+ void __user *uarg = (void __user *) arg;
+
+ switch (cmd) {
+ case IOCTL_EVTCHN_BIND_VIRQ: {
+ struct ioctl_evtchn_bind_virq bind;
+ struct evtchn_bind_virq bind_virq;
+
+ rc = -EFAULT;
+ if (copy_from_user(&bind, uarg, sizeof(bind)))
+ break;
+
+ bind_virq.virq = bind.virq;
+ bind_virq.vcpu = 0;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+ &bind_virq);
+ if (rc != 0)
+ break;
+
+ rc = bind_virq.port;
+ evtchn_bind_to_user(u, rc);
+ break;
+ }
+
+ case IOCTL_EVTCHN_BIND_INTERDOMAIN: {
+ struct ioctl_evtchn_bind_interdomain bind;
+ struct evtchn_bind_interdomain bind_interdomain;
+
+ rc = -EFAULT;
+ if (copy_from_user(&bind, uarg, sizeof(bind)))
+ break;
+
+ bind_interdomain.remote_dom = bind.remote_domain;
+ bind_interdomain.remote_port = bind.remote_port;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
+ if (rc != 0)
+ break;
+
+ rc = bind_interdomain.local_port;
+ evtchn_bind_to_user(u, rc);
+ break;
+ }
+
+ case IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
+ struct ioctl_evtchn_bind_unbound_port bind;
+ struct evtchn_alloc_unbound alloc_unbound;
+
+ rc = -EFAULT;
+ if (copy_from_user(&bind, uarg, sizeof(bind)))
+ break;
+
+ alloc_unbound.dom = DOMID_SELF;
+ alloc_unbound.remote_dom = bind.remote_domain;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+ &alloc_unbound);
+ if (rc != 0)
+ break;
+
+ rc = alloc_unbound.port;
+ evtchn_bind_to_user(u, rc);
+ break;
+ }
+
+ case IOCTL_EVTCHN_UNBIND: {
+ struct ioctl_evtchn_unbind unbind;
+ struct evtchn_close close;
+ int ret;
+
+ rc = -EFAULT;
+ if (copy_from_user(&unbind, uarg, sizeof(unbind)))
+ break;
+
+ rc = -EINVAL;
+ if (unbind.port >= NR_EVENT_CHANNELS)
+ break;
+
+ spin_lock_irq(&port_user_lock);
- switch ( cmd )
- {
- case EVTCHN_RESET:
- /* Initialise the ring to empty. Clear errors. */
- u->ring_cons = u->ring_prod = u->ring_overflow = 0;
- break;
-
- case EVTCHN_BIND:
- if ( arg >= NR_EVENT_CHANNELS )
- {
- rc = -EINVAL;
- }
- else if ( port_user[arg] != NULL )
- {
- rc = -EISCONN;
- }
- else
- {
- port_user[arg] = u;
- unmask_evtchn(arg);
- }
- break;
-
- case EVTCHN_UNBIND:
- if ( arg >= NR_EVENT_CHANNELS )
- {
- rc = -EINVAL;
- }
- else if ( port_user[arg] != u )
- {
- rc = -ENOTCONN;
- }
- else
- {
- port_user[arg] = NULL;
- mask_evtchn(arg);
- }
- break;
-
- default:
- rc = -ENOSYS;
- break;
- }
-
- spin_unlock_irq(&port_user_lock);
-
- return rc;
+ rc = -ENOTCONN;
+ if (port_user[unbind.port] != u) {
+ spin_unlock_irq(&port_user_lock);
+ break;
+ }
+
+ port_user[unbind.port] = NULL;
+ mask_evtchn(unbind.port);
+
+ spin_unlock_irq(&port_user_lock);
+
+ close.port = unbind.port;
+ ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+ BUG_ON(ret);
+
+ rc = 0;
+ break;
+ }
+
+ case IOCTL_EVTCHN_NOTIFY: {
+ struct ioctl_evtchn_notify notify;
+
+ rc = -EFAULT;
+ if (copy_from_user(¬ify, uarg, sizeof(notify)))
+ break;
+
+ if (notify.port >= NR_EVENT_CHANNELS) {
+ rc = -EINVAL;
+ } else if (port_user[notify.port] != u) {
+ rc = -ENOTCONN;
+ } else {
+ notify_remote_via_evtchn(notify.port);
+ rc = 0;
+ }
+ break;
+ }
+
+ case IOCTL_EVTCHN_RESET: {
+ /* Initialise the ring to empty. Clear errors. */
+ spin_lock_irq(&port_user_lock);
+ u->ring_cons = u->ring_prod = u->ring_overflow = 0;
+ spin_unlock_irq(&port_user_lock);
+ rc = 0;
+ break;
+ }
+
+ default:
+ rc = -ENOSYS;
+ break;
+ }
+
+ return rc;
}
static unsigned int evtchn_poll(struct file *file, poll_table *wait)
{
- unsigned int mask = POLLOUT | POLLWRNORM;
- struct per_user_data *u = file->private_data;
-
- poll_wait(file, &u->evtchn_wait, wait);
- if ( u->ring_cons != u->ring_prod )
- mask |= POLLIN | POLLRDNORM;
- if ( u->ring_overflow )
- mask = POLLERR;
- return mask;
+ unsigned int mask = POLLOUT | POLLWRNORM;
+ struct per_user_data *u = file->private_data;
+
+ poll_wait(file, &u->evtchn_wait, wait);
+ if (u->ring_cons != u->ring_prod)
+ mask |= POLLIN | POLLRDNORM;
+ if (u->ring_overflow)
+ mask = POLLERR;
+ return mask;
}
static int evtchn_fasync(int fd, struct file *filp, int on)
{
- struct per_user_data *u = filp->private_data;
- return fasync_helper(fd, filp, on, &u->evtchn_async_queue);
+ struct per_user_data *u = filp->private_data;
+ return fasync_helper(fd, filp, on, &u->evtchn_async_queue);
}
static int evtchn_open(struct inode *inode, struct file *filp)
{
- struct per_user_data *u;
+ struct per_user_data *u;
- if ( (u = kmalloc(sizeof(*u), GFP_KERNEL)) == NULL )
- return -ENOMEM;
+ if ((u = kmalloc(sizeof(*u), GFP_KERNEL)) == NULL)
+ return -ENOMEM;
- memset(u, 0, sizeof(*u));
- init_waitqueue_head(&u->evtchn_wait);
+ memset(u, 0, sizeof(*u));
+ init_waitqueue_head(&u->evtchn_wait);
- if ( (u->ring = (u16 *)__get_free_page(GFP_KERNEL)) == NULL )
- {
- kfree(u);
- return -ENOMEM;
- }
+ u->ring = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
+ if (u->ring == NULL) {
+ kfree(u);
+ return -ENOMEM;
+ }
- filp->private_data = u;
+ filp->private_data = u;
- return 0;
+ return 0;
}
static int evtchn_release(struct inode *inode, struct file *filp)
{
- int i;
- struct per_user_data *u = filp->private_data;
+ int i;
+ struct per_user_data *u = filp->private_data;
+ struct evtchn_close close;
+
+ spin_lock_irq(&port_user_lock);
- spin_lock_irq(&port_user_lock);
+ free_page((unsigned long)u->ring);
- free_page((unsigned long)u->ring);
+ for (i = 0; i < NR_EVENT_CHANNELS; i++) {
+ int ret;
+ if (port_user[i] != u)
+ continue;
- for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
- {
- if ( port_user[i] == u )
- {
- port_user[i] = NULL;
- mask_evtchn(i);
- }
- }
+ port_user[i] = NULL;
+ mask_evtchn(i);
- spin_unlock_irq(&port_user_lock);
+ close.port = i;
+ ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+ BUG_ON(ret);
+ }
- return 0;
+ spin_unlock_irq(&port_user_lock);
+
+ kfree(u);
+
+ return 0;
}
static struct file_operations evtchn_fops = {
- owner: THIS_MODULE,
- read: evtchn_read,
- write: evtchn_write,
- ioctl: evtchn_ioctl,
- poll: evtchn_poll,
- fasync: evtchn_fasync,
- open: evtchn_open,
- release: evtchn_release
+ .owner = THIS_MODULE,
+ .read = evtchn_read,
+ .write = evtchn_write,
+ .ioctl = evtchn_ioctl,
+ .poll = evtchn_poll,
+ .fasync = evtchn_fasync,
+ .open = evtchn_open,
+ .release = evtchn_release,
};
static struct miscdevice evtchn_miscdev = {
- .minor = EVTCHN_MINOR,
- .name = "evtchn",
- .fops = &evtchn_fops,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- .devfs_name = "misc/evtchn",
-#endif
+ .minor = EVTCHN_MINOR,
+ .name = "evtchn",
+ .fops = &evtchn_fops,
+ .devfs_name = "misc/evtchn",
};
static int __init evtchn_init(void)
{
-#ifdef OLD_DEVFS
- devfs_handle_t symlink_handle;
- int pos;
- char link_dest[64];
-#endif
- int err;
-
- spin_lock_init(&port_user_lock);
- memset(port_user, 0, sizeof(port_user));
-
- /* (DEVFS) create '/dev/misc/evtchn'. */
- err = misc_register(&evtchn_miscdev);
- if ( err != 0 )
- {
- printk(KERN_ALERT "Could not register /dev/misc/evtchn\n");
- return err;
- }
-
-#ifdef OLD_DEVFS
- /* (DEVFS) create directory '/dev/xen'. */
- xen_dev_dir = devfs_mk_dir(NULL, "xen", NULL);
-
- /* (DEVFS) &link_dest[pos] == '../misc/evtchn'. */
- pos = devfs_generate_path(evtchn_miscdev.devfs_handle,
- &link_dest[3],
- sizeof(link_dest) - 3);
- if ( pos >= 0 )
- strncpy(&link_dest[pos], "../", 3);
-
- /* (DEVFS) symlink '/dev/xen/evtchn' -> '../misc/evtchn'. */
- (void)devfs_mk_symlink(xen_dev_dir,
- "evtchn",
- DEVFS_FL_DEFAULT,
- &link_dest[pos],
- &symlink_handle,
- NULL);
-
- /* (DEVFS) automatically destroy the symlink with its destination. */
- devfs_auto_unregister(evtchn_miscdev.devfs_handle, symlink_handle);
-#endif
-
- printk("Event-channel device installed.\n");
-
- return 0;
+ int err;
+
+ if (!is_running_on_xen())
+ return -ENODEV;
+
+ spin_lock_init(&port_user_lock);
+ memset(port_user, 0, sizeof(port_user));
+
+ /* Create '/dev/misc/evtchn'. */
+ err = misc_register(&evtchn_miscdev);
+ if (err != 0) {
+ printk(KERN_ALERT "Could not register /dev/misc/evtchn\n");
+ return err;
+ }
+
+ printk("Event-channel device installed.\n");
+
+ return 0;
}
static void evtchn_cleanup(void)
{
- misc_deregister(&evtchn_miscdev);
+ misc_deregister(&evtchn_miscdev);
}
module_init(evtchn_init);
module_exit(evtchn_cleanup);
+
+MODULE_LICENSE("Dual BSD/GPL");
+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
/******************************************************************************
* 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__
#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>
-
-#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 {
- /* Unique identifier for this interface. */
- domid_t domid;
- unsigned int handle;
-
- u8 fe_dev_addr[6];
-
- /* Physical parameters of the comms window. */
- unsigned long tx_shmem_frame;
- unsigned long rx_shmem_frame;
- unsigned int evtchn;
- int irq;
-
- /* The shared rings and indexes. */
- netif_tx_interface_t *tx;
- netif_rx_interface_t *rx;
-
- /* Private indexes into shared ring. */
- NETIF_RING_IDX rx_req_cons;
- NETIF_RING_IDX rx_resp_prod; /* private version of shared variable */
- NETIF_RING_IDX tx_req_cons;
- NETIF_RING_IDX tx_resp_prod; /* private version of shared variable */
-
- /* Transmit shaping: allow 'credit_bytes' every 'credit_usec'. */
- unsigned long credit_bytes;
- unsigned long credit_usec;
- unsigned long remaining_credit;
- struct timer_list credit_timeout;
-
- /* Miscellaneous private stuff. */
- enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
- int active;
- /*
- * DISCONNECT response is deferred until pending requests are ack'ed.
- * We therefore need to store the id from the original request.
- */
- u8 disconnect_rspid;
- struct netif_st *hash_next;
- struct list_head list; /* scheduling list */
- atomic_t refcnt;
- struct net_device *dev;
- struct net_device_stats stats;
-
- struct work_struct work;
+ /* Unique identifier for this interface. */
+ domid_t domid;
+ unsigned int handle;
+
+ u8 fe_dev_addr[6];
+
+ /* Physical parameters of the comms window. */
+ grant_handle_t tx_shmem_handle;
+ grant_ref_t tx_shmem_ref;
+ grant_handle_t rx_shmem_handle;
+ grant_ref_t rx_shmem_ref;
+ unsigned int evtchn;
+ unsigned int irq;
+
+ /* The shared rings and indexes. */
+ netif_tx_back_ring_t tx;
+ netif_rx_back_ring_t rx;
+ struct vm_struct *tx_comms_area;
+ struct vm_struct *rx_comms_area;
+
+ /* Set of features that can be turned on in dev->features. */
+ int features;
+ int can_queue;
+
+ /* Allow netif_be_start_xmit() to peek ahead in the rx request ring. */
+ RING_IDX rx_req_cons_peek;
+
+ /* Transmit shaping: allow 'credit_bytes' every 'credit_usec'. */
+ unsigned long credit_bytes;
+ unsigned long credit_usec;
+ unsigned long remaining_credit;
+ struct timer_list credit_timeout;
+
+ /* Miscellaneous private stuff. */
+ struct list_head list; /* scheduling list */
+ atomic_t refcnt;
+ struct net_device *dev;
+ struct net_device_stats stats;
+
+ wait_queue_head_t waiting_to_free;
} netif_t;
-void netif_create(netif_be_create_t *create);
-void netif_destroy(netif_be_destroy_t *destroy);
-void netif_creditlimit(netif_be_creditlimit_t *creditlimit);
-void netif_connect(netif_be_connect_t *connect);
-int netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id);
-void netif_disconnect_complete(netif_t *netif);
-netif_t *netif_find_by_handle(domid_t domid, unsigned int handle);
+#define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
+#define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
+
+void netif_disconnect(netif_t *netif);
+
+netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
+int netif_map(netif_t *netif, unsigned long tx_ring_ref,
+ unsigned long rx_ring_ref, unsigned int evtchn);
+
#define netif_get(_b) (atomic_inc(&(_b)->refcnt))
-#define netif_put(_b) \
- do { \
- if ( atomic_dec_and_test(&(_b)->refcnt) ) \
- netif_disconnect_complete(_b); \
- } while (0)
+#define netif_put(_b) \
+ do { \
+ if ( atomic_dec_and_test(&(_b)->refcnt) ) \
+ wake_up(&(_b)->waiting_to_free); \
+ } while (0)
-void netif_interface_init(void);
-void netif_ctrlif_init(void);
+void netif_xenbus_init(void);
void netif_schedule_work(netif_t *netif);
void netif_deschedule_work(netif_t *netif);
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__ */
* 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 <linux/ethtool.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)
{
- struct net_device *dev = netif->dev;
- spin_lock_bh(&dev->xmit_lock);
- netif->active = 1;
- spin_unlock_bh(&dev->xmit_lock);
- (void)request_irq(netif->irq, netif_be_int, 0, dev->name, netif);
- netif_schedule_work(netif);
+ enable_irq(netif->irq);
+ netif_schedule_work(netif);
}
static void __netif_down(netif_t *netif)
{
- struct net_device *dev = netif->dev;
- spin_lock_bh(&dev->xmit_lock);
- netif->active = 0;
- spin_unlock_bh(&dev->xmit_lock);
- free_irq(netif->irq, netif);
- netif_deschedule_work(netif);
+ disable_irq(netif->irq);
+ netif_deschedule_work(netif);
}
static int net_open(struct net_device *dev)
{
- netif_t *netif = netdev_priv(dev);
- if ( netif->status == CONNECTED )
- __netif_up(netif);
- netif_start_queue(dev);
- return 0;
+ netif_t *netif = netdev_priv(dev);
+ if (netif_carrier_ok(dev))
+ __netif_up(netif);
+ return 0;
}
static int net_close(struct net_device *dev)
{
- netif_t *netif = netdev_priv(dev);
- netif_stop_queue(dev);
- if ( netif->status == CONNECTED )
- __netif_down(netif);
- return 0;
+ netif_t *netif = netdev_priv(dev);
+ if (netif_carrier_ok(dev))
+ __netif_down(netif);
+ return 0;
}
-static void __netif_disconnect_complete(void *arg)
+static int netbk_change_mtu(struct net_device *dev, int mtu)
{
- netif_t *netif = (netif_t *)arg;
- ctrl_msg_t cmsg;
- netif_be_disconnect_t disc;
-
- /*
- * These can't be done in netif_disconnect() because at that point there
- * may be outstanding requests in the network stack whose asynchronous
- * responses must still be notified to the remote driver.
- */
- unbind_evtchn_from_irq(netif->evtchn);
- vfree(netif->tx); /* Frees netif->rx as well. */
-
- /* Construct the deferred response message. */
- cmsg.type = CMSG_NETIF_BE;
- cmsg.subtype = CMSG_NETIF_BE_DISCONNECT;
- cmsg.id = netif->disconnect_rspid;
- cmsg.length = sizeof(netif_be_disconnect_t);
- disc.domid = netif->domid;
- disc.netif_handle = netif->handle;
- disc.status = NETIF_BE_STATUS_OKAY;
- memcpy(cmsg.msg, &disc, sizeof(disc));
-
- /*
- * Make sure message is constructed /before/ status change, because
- * after the status change the 'netif' structure could be deallocated at
- * any time. Also make sure we send the response /after/ status change,
- * as otherwise a subsequent CONNECT request could spuriously fail if
- * another CPU doesn't see the status change yet.
- */
- mb();
- if ( netif->status != DISCONNECTING )
- BUG();
- netif->status = DISCONNECTED;
- mb();
-
- /* Send the successful response. */
- ctrl_if_send_response(&cmsg);
+ int max = netbk_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN;
+
+ if (mtu > max)
+ return -EINVAL;
+ dev->mtu = mtu;
+ return 0;
}
-void netif_disconnect_complete(netif_t *netif)
+static int netbk_set_sg(struct net_device *dev, u32 data)
{
- INIT_WORK(&netif->work, __netif_disconnect_complete, (void *)netif);
- schedule_work(&netif->work);
+ if (data) {
+ netif_t *netif = netdev_priv(dev);
+
+ if (!(netif->features & NETIF_F_SG))
+ return -ENOSYS;
+ }
+
+ return ethtool_op_set_sg(dev, data);
}
-void netif_create(netif_be_create_t *create)
+static int netbk_set_tso(struct net_device *dev, u32 data)
{
- int err = 0;
- domid_t domid = create->domid;
- unsigned int handle = create->netif_handle;
- struct net_device *dev;
- netif_t **pnetif, *netif;
- char name[IFNAMSIZ] = {};
-
- snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle);
- dev = alloc_netdev(sizeof(netif_t), name, ether_setup);
- if ( dev == NULL )
- {
- DPRINTK("Could not create netif: out of memory\n");
- create->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
- return;
- }
-
- netif = netdev_priv(dev);
- memset(netif, 0, sizeof(*netif));
- netif->domid = domid;
- netif->handle = handle;
- netif->status = DISCONNECTED;
- atomic_set(&netif->refcnt, 0);
- netif->dev = dev;
-
- netif->credit_bytes = netif->remaining_credit = ~0UL;
- netif->credit_usec = 0UL;
- init_timer(&netif->credit_timeout);
-
- pnetif = &netif_hash[NETIF_HASH(domid, handle)];
- while ( *pnetif != NULL )
- {
- if ( ((*pnetif)->domid == domid) && ((*pnetif)->handle == handle) )
- {
- DPRINTK("Could not create netif: already exists\n");
- create->status = NETIF_BE_STATUS_INTERFACE_EXISTS;
- free_netdev(dev);
- return;
- }
- pnetif = &(*pnetif)->hash_next;
- }
-
- dev->hard_start_xmit = netif_be_start_xmit;
- dev->get_stats = netif_be_get_stats;
- dev->open = net_open;
- dev->stop = net_close;
-
- /* Disable queuing. */
- dev->tx_queue_len = 0;
-
- if ( (create->be_mac[0] == 0) && (create->be_mac[1] == 0) &&
- (create->be_mac[2] == 0) && (create->be_mac[3] == 0) &&
- (create->be_mac[4] == 0) && (create->be_mac[5] == 0) )
- {
- /*
- * Initialise a dummy MAC address. We choose the numerically largest
- * non-broadcast address to prevent the address getting stolen by an
- * Ethernet bridge for STP purposes. (FE:FF:FF:FF:FF:FF)
- */
- memset(dev->dev_addr, 0xFF, ETH_ALEN);
- dev->dev_addr[0] &= ~0x01;
- }
- else
- {
- memcpy(dev->dev_addr, create->be_mac, ETH_ALEN);
- }
-
- memcpy(netif->fe_dev_addr, create->mac, ETH_ALEN);
-
- rtnl_lock();
- err = register_netdevice(dev);
- rtnl_unlock();
-
- if ( err != 0 )
- {
- DPRINTK("Could not register new net device %s: err=%d\n",
- dev->name, err);
- create->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
- free_netdev(dev);
- return;
- }
-
- netif->hash_next = *pnetif;
- *pnetif = netif;
-
- DPRINTK("Successfully created netif\n");
- create->status = NETIF_BE_STATUS_OKAY;
+ if (data) {
+ netif_t *netif = netdev_priv(dev);
+
+ if (!(netif->features & NETIF_F_TSO))
+ return -ENOSYS;
+ }
+
+ return ethtool_op_set_tso(dev, data);
}
-void netif_destroy(netif_be_destroy_t *destroy)
+static struct ethtool_ops network_ethtool_ops =
{
- domid_t domid = destroy->domid;
- unsigned int handle = destroy->netif_handle;
- netif_t **pnetif, *netif;
-
- pnetif = &netif_hash[NETIF_HASH(domid, handle)];
- while ( (netif = *pnetif) != NULL )
- {
- if ( (netif->domid == domid) && (netif->handle == handle) )
- {
- if ( netif->status != DISCONNECTED )
- goto still_connected;
- goto destroy;
- }
- pnetif = &netif->hash_next;
- }
-
- destroy->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND;
- return;
-
- still_connected:
- destroy->status = NETIF_BE_STATUS_INTERFACE_CONNECTED;
- return;
-
- destroy:
- *pnetif = netif->hash_next;
- unregister_netdev(netif->dev);
- free_netdev(netif->dev);
- destroy->status = NETIF_BE_STATUS_OKAY;
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = netbk_set_sg,
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = netbk_set_tso,
+ .get_link = ethtool_op_get_link,
+};
+
+netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
+{
+ int err = 0, i;
+ struct net_device *dev;
+ netif_t *netif;
+ char name[IFNAMSIZ] = {};
+
+ snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle);
+ dev = alloc_netdev(sizeof(netif_t), name, ether_setup);
+ if (dev == NULL) {
+ DPRINTK("Could not create netif: out of memory\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ netif_carrier_off(dev);
+
+ netif = netdev_priv(dev);
+ memset(netif, 0, sizeof(*netif));
+ netif->domid = domid;
+ netif->handle = handle;
+ atomic_set(&netif->refcnt, 1);
+ init_waitqueue_head(&netif->waiting_to_free);
+ netif->dev = dev;
+
+ netif->credit_bytes = netif->remaining_credit = ~0UL;
+ netif->credit_usec = 0UL;
+ init_timer(&netif->credit_timeout);
+
+ dev->hard_start_xmit = netif_be_start_xmit;
+ dev->get_stats = netif_be_get_stats;
+ dev->open = net_open;
+ dev->stop = net_close;
+ dev->change_mtu = netbk_change_mtu;
+ dev->features = NETIF_F_IP_CSUM;
+
+ SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
+
+ /*
+ * Reduce default TX queuelen so that each guest interface only
+ * allows it to eat around 6.4MB of host memory.
+ */
+ dev->tx_queue_len = 100;
+
+ for (i = 0; i < ETH_ALEN; i++)
+ if (be_mac[i] != 0)
+ break;
+ if (i == ETH_ALEN) {
+ /*
+ * Initialise a dummy MAC address. We choose the numerically
+ * largest non-broadcast address to prevent the address getting
+ * stolen by an Ethernet bridge for STP purposes.
+ * (FE:FF:FF:FF:FF:FF)
+ */
+ memset(dev->dev_addr, 0xFF, ETH_ALEN);
+ dev->dev_addr[0] &= ~0x01;
+ } else
+ memcpy(dev->dev_addr, be_mac, ETH_ALEN);
+
+ rtnl_lock();
+ err = register_netdevice(dev);
+ rtnl_unlock();
+ if (err) {
+ DPRINTK("Could not register new net device %s: err=%d\n",
+ dev->name, err);
+ free_netdev(dev);
+ return ERR_PTR(err);
+ }
+
+ DPRINTK("Successfully created netif\n");
+ return netif;
}
-void netif_creditlimit(netif_be_creditlimit_t *creditlimit)
+static int map_frontend_pages(
+ netif_t *netif, grant_ref_t tx_ring_ref, grant_ref_t rx_ring_ref)
{
- domid_t domid = creditlimit->domid;
- unsigned int handle = creditlimit->netif_handle;
- netif_t *netif;
-
- netif = netif_find_by_handle(domid, handle);
- if ( unlikely(netif == NULL) )
- {
- DPRINTK("netif_creditlimit attempted for non-existent netif"
- " (%u,%u)\n", creditlimit->domid, creditlimit->netif_handle);
- creditlimit->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND;
- return;
- }
-
- /* Set the credit limit (reset remaining credit to new limit). */
- netif->credit_bytes = netif->remaining_credit = creditlimit->credit_bytes;
- netif->credit_usec = creditlimit->period_usec;
-
- if ( netif->status == CONNECTED )
- {
- /*
- * Schedule work so that any packets waiting under previous credit
- * limit are dealt with (acts like a replenishment point).
- */
- netif->credit_timeout.expires = jiffies;
- netif_schedule_work(netif);
- }
+ struct gnttab_map_grant_ref op;
+ int ret;
+
+ gnttab_set_map_op(&op, (unsigned long)netif->tx_comms_area->addr,
+ GNTMAP_host_map, tx_ring_ref, netif->domid);
- creditlimit->status = NETIF_BE_STATUS_OKAY;
+ lock_vm_area(netif->tx_comms_area);
+ ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
+ unlock_vm_area(netif->tx_comms_area);
+ BUG_ON(ret);
+
+ if (op.status) {
+ DPRINTK(" Gnttab failure mapping tx_ring_ref!\n");
+ return op.status;
+ }
+
+ netif->tx_shmem_ref = tx_ring_ref;
+ netif->tx_shmem_handle = op.handle;
+
+ gnttab_set_map_op(&op, (unsigned long)netif->rx_comms_area->addr,
+ GNTMAP_host_map, rx_ring_ref, netif->domid);
+
+ lock_vm_area(netif->rx_comms_area);
+ ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
+ unlock_vm_area(netif->rx_comms_area);
+ BUG_ON(ret);
+
+ if (op.status) {
+ DPRINTK(" Gnttab failure mapping rx_ring_ref!\n");
+ return op.status;
+ }
+
+ netif->rx_shmem_ref = rx_ring_ref;
+ netif->rx_shmem_handle = op.handle;
+
+ return 0;
}
-void netif_connect(netif_be_connect_t *connect)
+static void unmap_frontend_pages(netif_t *netif)
{
- domid_t domid = connect->domid;
- unsigned int handle = connect->netif_handle;
- unsigned int evtchn = connect->evtchn;
- unsigned long tx_shmem_frame = connect->tx_shmem_frame;
- unsigned long rx_shmem_frame = connect->rx_shmem_frame;
- struct vm_struct *vma;
- pgprot_t prot;
- int error;
- netif_t *netif;
-
- netif = netif_find_by_handle(domid, handle);
- if ( unlikely(netif == NULL) )
- {
- DPRINTK("netif_connect attempted for non-existent netif (%u,%u)\n",
- connect->domid, connect->netif_handle);
- connect->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND;
- return;
- }
-
- if ( netif->status != DISCONNECTED )
- {
- connect->status = NETIF_BE_STATUS_INTERFACE_CONNECTED;
- return;
- }
-
- if ( (vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP)) == NULL )
- {
- connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
- return;
- }
-
- prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED);
- error = direct_remap_area_pages(&init_mm,
- VMALLOC_VMADDR(vma->addr),
- tx_shmem_frame<<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);
}
* 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 <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,
- 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 struct timer_list net_timer;
-static struct sk_buff_head rx_queue;
-static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2+1];
-static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE];
-static struct mmuext_op rx_mmuext[NETIF_RX_RING_SIZE];
-static unsigned char rx_notify[NR_EVENT_CHANNELS];
+#define MAX_PENDING_REQS 256
-/* Don't currently gate addition of an interface to the tx scheduling list. */
-#define tx_work_exists(_if) (1)
+static struct sk_buff_head rx_queue;
+static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1];
+static mmu_update_t rx_mmu[NET_RX_RING_SIZE];
+static gnttab_transfer_t grant_rx_op[NET_RX_RING_SIZE];
+static unsigned char rx_notify[NR_IRQS];
-#define MAX_PENDING_REQS 256
static unsigned long mmap_vstart;
#define MMAP_VADDR(_req) (mmap_vstart + ((_req) * PAGE_SIZE))
#define PKT_PROT_LEN 64
static struct {
- netif_tx_request_t req;
- netif_t *netif;
+ netif_tx_request_t req;
+ netif_t *netif;
} pending_tx_info[MAX_PENDING_REQS];
static u16 pending_ring[MAX_PENDING_REQS];
typedef unsigned int PEND_RING_IDX;
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;
#define MAX_MFN_ALLOC 64
static unsigned long mfn_list[MAX_MFN_ALLOC];
static unsigned int alloc_index = 0;
-static spinlock_t mfn_lock = SPIN_LOCK_UNLOCKED;
-static unsigned long alloc_mfn(void)
+static inline unsigned long alloc_mfn(void)
{
- unsigned long mfn = 0, flags;
- spin_lock_irqsave(&mfn_lock, flags);
- if ( unlikely(alloc_index == 0) )
- alloc_index = HYPERVISOR_dom_mem_op(
- MEMOP_increase_reservation, mfn_list, MAX_MFN_ALLOC, 0);
- if ( alloc_index != 0 )
- mfn = mfn_list[--alloc_index];
- spin_unlock_irqrestore(&mfn_lock, flags);
- return mfn;
+ return mfn_list[--alloc_index];
}
-static void free_mfn(unsigned long mfn)
+static int check_mfn(int nr)
{
- unsigned long flags;
- spin_lock_irqsave(&mfn_lock, flags);
- if ( alloc_index != MAX_MFN_ALLOC )
- mfn_list[alloc_index++] = mfn;
- else if ( HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation,
- &mfn, 1, 0) != 1 )
- BUG();
- spin_unlock_irqrestore(&mfn_lock, flags);
+ struct xen_memory_reservation reservation = {
+ .extent_order = 0,
+ .domid = DOMID_SELF
+ };
+
+ if (likely(alloc_index >= nr))
+ return 0;
+
+ set_xen_guest_handle(reservation.extent_start, mfn_list + alloc_index);
+ reservation.nr_extents = MAX_MFN_ALLOC - alloc_index;
+ alloc_index += HYPERVISOR_memory_op(XENMEM_increase_reservation,
+ &reservation);
+
+ return alloc_index >= nr ? 0 : -ENOMEM;
}
static inline void maybe_schedule_tx_action(void)
{
- smp_mb();
- if ( (NR_PENDING_REQS < (MAX_PENDING_REQS/2)) &&
- !list_empty(&net_schedule_list) )
- tasklet_schedule(&net_tx_tasklet);
+ smp_mb();
+ if ((NR_PENDING_REQS < (MAX_PENDING_REQS/2)) &&
+ !list_empty(&net_schedule_list))
+ tasklet_schedule(&net_tx_tasklet);
}
/*
*/
static inline int is_xen_skb(struct sk_buff *skb)
{
- extern kmem_cache_t *skbuff_cachep;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->lru.next;
-#else
- kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->list.next;
-#endif
- return (cp == skbuff_cachep);
+ extern kmem_cache_t *skbuff_cachep;
+ kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->lru.next;
+ return (cp == skbuff_cachep);
+}
+
+static struct sk_buff *netbk_copy_skb(struct sk_buff *skb)
+{
+ struct skb_shared_info *ninfo;
+ struct sk_buff *nskb;
+ unsigned long offset;
+ int ret;
+ int len;
+ int headlen;
+
+ nskb = alloc_skb(SKB_MAX_HEAD(0), GFP_ATOMIC);
+ if (unlikely(!nskb))
+ goto err;
+
+ skb_reserve(nskb, 16);
+ headlen = nskb->end - nskb->data;
+ if (headlen > skb_headlen(skb))
+ headlen = skb_headlen(skb);
+ ret = skb_copy_bits(skb, 0, __skb_put(nskb, headlen), headlen);
+ BUG_ON(ret);
+
+ ninfo = skb_shinfo(nskb);
+ ninfo->gso_size = skb_shinfo(skb)->gso_size;
+ ninfo->gso_type = skb_shinfo(skb)->gso_type;
+
+ offset = headlen;
+ len = skb->len - headlen;
+
+ nskb->len = skb->len;
+ nskb->data_len = len;
+ nskb->truesize += len;
+
+ while (len) {
+ struct page *page;
+ int copy;
+ int zero;
+
+ if (unlikely(ninfo->nr_frags >= MAX_SKB_FRAGS)) {
+ dump_stack();
+ goto err_free;
+ }
+
+ copy = len >= PAGE_SIZE ? PAGE_SIZE : len;
+ zero = len >= PAGE_SIZE ? 0 : __GFP_ZERO;
+
+ page = alloc_page(GFP_ATOMIC | zero);
+ if (unlikely(!page))
+ goto err_free;
+
+ ret = skb_copy_bits(skb, offset, page_address(page), copy);
+ BUG_ON(ret);
+
+ ninfo->frags[ninfo->nr_frags].page = page;
+ ninfo->frags[ninfo->nr_frags].page_offset = 0;
+ ninfo->frags[ninfo->nr_frags].size = copy;
+ ninfo->nr_frags++;
+
+ offset += copy;
+ len -= copy;
+ }
+
+ offset = nskb->data - skb->data;
+
+ nskb->h.raw = skb->h.raw + offset;
+ nskb->nh.raw = skb->nh.raw + offset;
+ nskb->mac.raw = skb->mac.raw + offset;
+
+ return nskb;
+
+ err_free:
+ kfree_skb(nskb);
+ err:
+ return NULL;
+}
+
+static inline int netbk_max_required_rx_slots(netif_t *netif)
+{
+ if (netif->features & (NETIF_F_SG|NETIF_F_TSO))
+ return MAX_SKB_FRAGS + 2; /* header + extra_info + frags */
+ return 1; /* all in one */
+}
+
+static inline int netbk_queue_full(netif_t *netif)
+{
+ RING_IDX peek = netif->rx_req_cons_peek;
+ RING_IDX needed = netbk_max_required_rx_slots(netif);
+
+ return ((netif->rx.sring->req_prod - peek) < needed) ||
+ ((netif->rx.rsp_prod_pvt + NET_RX_RING_SIZE - peek) < needed);
}
int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- netif_t *netif = netdev_priv(dev);
-
- ASSERT(skb->dev == dev);
-
- /* Drop the packet if the target domain has no receive buffers. */
- if ( !netif->active ||
- (netif->rx_req_cons == netif->rx->req_prod) ||
- ((netif->rx_req_cons-netif->rx_resp_prod) == NETIF_RX_RING_SIZE) )
- goto drop;
-
- /*
- * We do not copy the packet unless:
- * 1. The data is shared; or
- * 2. The data is not allocated from our special cache.
- * NB. We also couldn't cope with fragmented packets, but we won't get
- * any because we not advertise the NETIF_F_SG feature.
- */
- if ( skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb) )
- {
- int hlen = skb->data - skb->head;
- struct sk_buff *nskb = dev_alloc_skb(hlen + skb->len);
- if ( unlikely(nskb == NULL) )
- goto drop;
- skb_reserve(nskb, hlen);
- __skb_put(nskb, skb->len);
- (void)skb_copy_bits(skb, -hlen, nskb->data - hlen, skb->len + hlen);
- nskb->dev = skb->dev;
- dev_kfree_skb(skb);
- skb = nskb;
- }
-
- netif->rx_req_cons++;
- netif_get(netif);
-
- skb_queue_tail(&rx_queue, skb);
- tasklet_schedule(&net_rx_tasklet);
-
- return 0;
+ netif_t *netif = netdev_priv(dev);
+
+ BUG_ON(skb->dev != dev);
+
+ /* Drop the packet if the target domain has no receive buffers. */
+ if (unlikely(!netif_running(dev) || !netif_carrier_ok(dev)))
+ goto drop;
+
+ if (unlikely(netbk_queue_full(netif))) {
+ /* Not a BUG_ON() -- misbehaving netfront can trigger this. */
+ if (netbk_can_queue(dev))
+ DPRINTK("Queue full but not stopped!\n");
+ goto drop;
+ }
+
+ /*
+ * We do not copy the packet unless:
+ * 1. The data is shared; or
+ * 2. The data is not allocated from our special cache.
+ * 3. The data is fragmented.
+ */
+ if (skb_cloned(skb) || skb_is_nonlinear(skb) || !is_xen_skb(skb)) {
+ struct sk_buff *nskb = netbk_copy_skb(skb);
+ if ( unlikely(nskb == NULL) )
+ goto drop;
+ /* Copy only the header fields we use in this driver. */
+ nskb->dev = skb->dev;
+ nskb->ip_summed = skb->ip_summed;
+ nskb->proto_data_valid = skb->proto_data_valid;
+ dev_kfree_skb(skb);
+ skb = nskb;
+ }
+
+ netif->rx_req_cons_peek += skb_shinfo(skb)->nr_frags + 1 +
+ !!skb_shinfo(skb)->gso_size;
+ netif_get(netif);
+
+ if (netbk_can_queue(dev) && netbk_queue_full(netif)) {
+ netif->rx.sring->req_event = netif->rx_req_cons_peek +
+ netbk_max_required_rx_slots(netif);
+ mb(); /* request notification /then/ check & stop the queue */
+ if (netbk_queue_full(netif))
+ netif_stop_queue(dev);
+ }
+
+ skb_queue_tail(&rx_queue, skb);
+ tasklet_schedule(&net_rx_tasklet);
+
+ return 0;
drop:
- netif->stats.tx_dropped++;
- dev_kfree_skb(skb);
- return 0;
+ netif->stats.tx_dropped++;
+ dev_kfree_skb(skb);
+ return 0;
}
#if 0
static void xen_network_done_notify(void)
{
- static struct net_device *eth0_dev = NULL;
- if ( unlikely(eth0_dev == NULL) )
- eth0_dev = __dev_get_by_name("eth0");
- netif_rx_schedule(eth0_dev);
+ static struct net_device *eth0_dev = NULL;
+ if (unlikely(eth0_dev == NULL))
+ eth0_dev = __dev_get_by_name("eth0");
+ netif_rx_schedule(eth0_dev);
}
/*
* Add following to poll() function in NAPI driver (Tigon3 is example):
*/
int xen_network_done(void)
{
- return skb_queue_empty(&rx_queue);
+ return skb_queue_empty(&rx_queue);
}
#endif
+static u16 netbk_gop_frag(netif_t *netif, struct page *page, int count, int i)
+{
+ multicall_entry_t *mcl = rx_mcl + count;
+ mmu_update_t *mmu = rx_mmu + count;
+ gnttab_transfer_t *gop = grant_rx_op + count;
+ netif_rx_request_t *req;
+ unsigned long old_mfn, new_mfn;
+
+ old_mfn = virt_to_mfn(page_address(page));
+
+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+ new_mfn = alloc_mfn();
+
+ /*
+ * Set the new P2M table entry before reassigning
+ * the old data page. Heed the comment in
+ * pgtable-2level.h:pte_page(). :-)
+ */
+ set_phys_to_machine(page_to_pfn(page), new_mfn);
+
+ MULTI_update_va_mapping(mcl, (unsigned long)page_address(page),
+ pfn_pte_ma(new_mfn, PAGE_KERNEL), 0);
+
+ mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
+ MMU_MACHPHYS_UPDATE;
+ mmu->val = page_to_pfn(page);
+ }
+
+ req = RING_GET_REQUEST(&netif->rx, netif->rx.req_cons + i);
+ gop->mfn = old_mfn;
+ gop->domid = netif->domid;
+ gop->ref = req->gref;
+ return req->id;
+}
+
+static void netbk_gop_skb(struct sk_buff *skb, struct netbk_rx_meta *meta,
+ int count)
+{
+ netif_t *netif = netdev_priv(skb->dev);
+ int nr_frags = skb_shinfo(skb)->nr_frags;
+ int i;
+ int extra;
+
+ meta[count].frag.page_offset = skb_shinfo(skb)->gso_type;
+ meta[count].frag.size = skb_shinfo(skb)->gso_size;
+ extra = !!meta[count].frag.size + 1;
+
+ for (i = 0; i < nr_frags; i++) {
+ meta[++count].frag = skb_shinfo(skb)->frags[i];
+ meta[count].id = netbk_gop_frag(netif, meta[count].frag.page,
+ count, i + extra);
+ }
+
+ /*
+ * This must occur at the end to ensure that we don't trash
+ * skb_shinfo until we're done.
+ */
+ meta[count - nr_frags].id = netbk_gop_frag(netif,
+ virt_to_page(skb->data),
+ count - nr_frags, 0);
+ netif->rx.req_cons += nr_frags + extra;
+}
+
+static inline void netbk_free_pages(int nr_frags, struct netbk_rx_meta *meta)
+{
+ int i;
+
+ for (i = 0; i < nr_frags; i++)
+ put_page(meta[i].frag.page);
+}
+
+static int netbk_check_gop(int nr_frags, domid_t domid, int count)
+{
+ multicall_entry_t *mcl = rx_mcl + count;
+ gnttab_transfer_t *gop = grant_rx_op + count;
+ int status = NETIF_RSP_OKAY;
+ int i;
+
+ for (i = 0; i <= nr_frags; i++) {
+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+ /* The update_va_mapping() must not fail. */
+ BUG_ON(mcl->result != 0);
+ mcl++;
+ }
+
+ /* Check the reassignment error code. */
+ if (gop->status != 0) {
+ DPRINTK("Bad status %d from grant transfer to DOM%u\n",
+ gop->status, domid);
+ /*
+ * Page no longer belongs to us unless GNTST_bad_page,
+ * but that should be a fatal error anyway.
+ */
+ BUG_ON(gop->status == GNTST_bad_page);
+ status = NETIF_RSP_ERROR;
+ }
+ gop++;
+ }
+
+ return status;
+}
+
+static void netbk_add_frag_responses(netif_t *netif, int status,
+ struct netbk_rx_meta *meta, int nr_frags)
+{
+ int i;
+
+ for (i = 0; i < nr_frags; i++) {
+ int id = meta[i].id;
+ int flags = (i == nr_frags - 1) ? 0 : NETRXF_more_data;
+
+ make_rx_response(netif, id, status, meta[i].frag.page_offset,
+ meta[i].frag.size, flags);
+ }
+}
+
static void net_rx_action(unsigned long unused)
{
- netif_t *netif;
- s8 status;
- u16 size, id, evtchn;
- multicall_entry_t *mcl;
- mmu_update_t *mmu;
- struct mmuext_op *mmuext;
- unsigned long vdata, mdata, new_mfn;
- struct sk_buff_head rxq;
- struct sk_buff *skb;
- u16 notify_list[NETIF_RX_RING_SIZE];
- int notify_nr = 0;
-
- skb_queue_head_init(&rxq);
-
- mcl = rx_mcl;
- mmu = rx_mmu;
- mmuext = rx_mmuext;
- while ( (skb = skb_dequeue(&rx_queue)) != NULL )
- {
- netif = netdev_priv(skb->dev);
- vdata = (unsigned long)skb->data;
- mdata = virt_to_machine(vdata);
-
- /* Memory squeeze? Back off for an arbitrary while. */
- if ( (new_mfn = alloc_mfn()) == 0 )
- {
- if ( net_ratelimit() )
- printk(KERN_WARNING "Memory squeeze in netback driver.\n");
- mod_timer(&net_timer, jiffies + HZ);
- skb_queue_head(&rx_queue, skb);
- break;
- }
-
- /*
- * Set the new P2M table entry before reassigning the old data page.
- * Heed the comment in pgtable-2level.h:pte_page(). :-)
- */
- phys_to_machine_mapping[__pa(skb->data) >> PAGE_SHIFT] = new_mfn;
-
- mcl->op = __HYPERVISOR_update_va_mapping;
- mcl->args[0] = vdata;
- mcl->args[1] = (new_mfn << PAGE_SHIFT) | __PAGE_KERNEL;
- mcl->args[2] = 0;
- mcl++;
-
- mcl->op = __HYPERVISOR_mmuext_op;
- mcl->args[0] = (unsigned long)mmuext;
- mcl->args[1] = 1;
- mcl->args[2] = 0;
- mcl->args[3] = netif->domid;
- mcl++;
-
- mmuext->cmd = MMUEXT_REASSIGN_PAGE;
- mmuext->mfn = mdata >> PAGE_SHIFT;
- mmuext++;
-
- mmu->ptr = (new_mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
- mmu->val = __pa(vdata) >> PAGE_SHIFT;
- mmu++;
-
- __skb_queue_tail(&rxq, skb);
-
- /* Filled the batch queue? */
- if ( (mcl - rx_mcl) == ARRAY_SIZE(rx_mcl) )
- break;
- }
-
- if ( mcl == rx_mcl )
- return;
-
- mcl->op = __HYPERVISOR_mmu_update;
- mcl->args[0] = (unsigned long)rx_mmu;
- mcl->args[1] = mmu - rx_mmu;
- mcl->args[2] = 0;
- mcl->args[3] = DOMID_SELF;
- mcl++;
-
- mcl[-3].args[2] = UVMF_TLB_FLUSH|UVMF_ALL;
- if ( unlikely(HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl) != 0) )
- BUG();
-
- mcl = rx_mcl;
- mmuext = rx_mmuext;
- while ( (skb = __skb_dequeue(&rxq)) != NULL )
- {
- netif = netdev_priv(skb->dev);
- size = skb->tail - skb->data;
-
- /* Rederive the machine addresses. */
- new_mfn = mcl[0].args[1] >> PAGE_SHIFT;
- mdata = ((mmuext[0].mfn << PAGE_SHIFT) |
- ((unsigned long)skb->data & ~PAGE_MASK));
-
- atomic_set(&(skb_shinfo(skb)->dataref), 1);
- skb_shinfo(skb)->nr_frags = 0;
- skb_shinfo(skb)->frag_list = NULL;
-
- netif->stats.tx_bytes += size;
- netif->stats.tx_packets++;
-
- /* The update_va_mapping() must not fail. */
- if ( unlikely(mcl[0].args[5] != 0) )
- BUG();
-
- /* Check the reassignment error code. */
- status = NETIF_RSP_OKAY;
- if ( unlikely(mcl[1].args[5] != 0) )
- {
- DPRINTK("Failed MMU update transferring to DOM%u\n", netif->domid);
- free_mfn(mdata >> PAGE_SHIFT);
- status = NETIF_RSP_ERROR;
- }
-
- evtchn = netif->evtchn;
- id = netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
- if ( make_rx_response(netif, id, status, mdata, size) &&
- (rx_notify[evtchn] == 0) )
- {
- rx_notify[evtchn] = 1;
- notify_list[notify_nr++] = evtchn;
- }
-
- netif_put(netif);
- dev_kfree_skb(skb);
-
- mcl += 2;
- mmuext += 1;
- }
-
- while ( notify_nr != 0 )
- {
- evtchn = notify_list[--notify_nr];
- rx_notify[evtchn] = 0;
- notify_via_evtchn(evtchn);
- }
-
- /* More work to do? */
- if ( !skb_queue_empty(&rx_queue) && !timer_pending(&net_timer) )
- tasklet_schedule(&net_rx_tasklet);
+ netif_t *netif = NULL;
+ s8 status;
+ u16 id, irq, flags;
+ netif_rx_response_t *resp;
+ struct netif_extra_info *extra;
+ multicall_entry_t *mcl;
+ struct sk_buff_head rxq;
+ struct sk_buff *skb;
+ int notify_nr = 0;
+ int ret;
+ int nr_frags;
+ int count;
+
+ /*
+ * Putting hundreds of bytes on the stack is considered rude.
+ * Static works because a tasklet can only be on one CPU at any time.
+ */
+ static u16 notify_list[NET_RX_RING_SIZE];
+ static struct netbk_rx_meta meta[NET_RX_RING_SIZE];
+
+ skb_queue_head_init(&rxq);
+
+ count = 0;
+
+ while ((skb = skb_dequeue(&rx_queue)) != NULL) {
+ nr_frags = skb_shinfo(skb)->nr_frags;
+ *(int *)skb->cb = nr_frags;
+
+ if (!xen_feature(XENFEAT_auto_translated_physmap) &&
+ check_mfn(nr_frags + 1)) {
+ /* Memory squeeze? Back off for an arbitrary while. */
+ if ( net_ratelimit() )
+ WPRINTK("Memory squeeze in netback "
+ "driver.\n");
+ mod_timer(&net_timer, jiffies + HZ);
+ skb_queue_head(&rx_queue, skb);
+ break;
+ }
+
+ netbk_gop_skb(skb, meta, count);
+
+ count += nr_frags + 1;
+
+ __skb_queue_tail(&rxq, skb);
+
+ /* Filled the batch queue? */
+ if (count + MAX_SKB_FRAGS >= NET_RX_RING_SIZE)
+ break;
+ }
+
+ if (!count)
+ return;
+
+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+ mcl = rx_mcl + count;
+
+ mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
+
+ mcl->op = __HYPERVISOR_mmu_update;
+ mcl->args[0] = (unsigned long)rx_mmu;
+ mcl->args[1] = count;
+ mcl->args[2] = 0;
+ mcl->args[3] = DOMID_SELF;
+
+ ret = HYPERVISOR_multicall(rx_mcl, count + 1);
+ BUG_ON(ret != 0);
+ }
+
+ ret = HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, count);
+ BUG_ON(ret != 0);
+
+ count = 0;
+ while ((skb = __skb_dequeue(&rxq)) != NULL) {
+ nr_frags = *(int *)skb->cb;
+
+ atomic_set(&(skb_shinfo(skb)->dataref), 1);
+ skb_shinfo(skb)->nr_frags = 0;
+ skb_shinfo(skb)->frag_list = NULL;
+
+ netif = netdev_priv(skb->dev);
+ netif->stats.tx_bytes += skb->len;
+ netif->stats.tx_packets++;
+
+ netbk_free_pages(nr_frags, meta + count + 1);
+ status = netbk_check_gop(nr_frags, netif->domid, count);
+
+ id = meta[count].id;
+ flags = nr_frags ? NETRXF_more_data : 0;
+
+ if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
+ flags |= NETRXF_csum_blank | NETRXF_data_validated;
+ else if (skb->proto_data_valid) /* remote but checksummed? */
+ flags |= NETRXF_data_validated;
+
+ resp = make_rx_response(netif, id, status,
+ offset_in_page(skb->data),
+ skb_headlen(skb), flags);
+
+ extra = NULL;
+
+ if (meta[count].frag.size) {
+ struct netif_extra_info *gso =
+ (struct netif_extra_info *)
+ RING_GET_RESPONSE(&netif->rx,
+ netif->rx.rsp_prod_pvt++);
+
+ if (extra)
+ extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE;
+ else
+ resp->flags |= NETRXF_extra_info;
+
+ gso->u.gso.size = meta[count].frag.size;
+ gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4;
+ gso->u.gso.pad = 0;
+ gso->u.gso.features = 0;
+
+ gso->type = XEN_NETIF_EXTRA_TYPE_GSO;
+ gso->flags = 0;
+ extra = gso;
+ }
+
+ netbk_add_frag_responses(netif, status, meta + count + 1,
+ nr_frags);
+
+ RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->rx, ret);
+ irq = netif->irq;
+ if (ret && !rx_notify[irq]) {
+ rx_notify[irq] = 1;
+ notify_list[notify_nr++] = irq;
+ }
+
+ if (netif_queue_stopped(netif->dev) &&
+ !netbk_queue_full(netif))
+ netif_wake_queue(netif->dev);
+
+ netif_put(netif);
+ dev_kfree_skb(skb);
+ count += nr_frags + 1;
+ }
+
+ while (notify_nr != 0) {
+ irq = notify_list[--notify_nr];
+ rx_notify[irq] = 0;
+ notify_remote_via_irq(irq);
+ }
+
+ /* More work to do? */
+ if (!skb_queue_empty(&rx_queue) && !timer_pending(&net_timer))
+ tasklet_schedule(&net_rx_tasklet);
#if 0
- else
- xen_network_done_notify();
+ else
+ xen_network_done_notify();
#endif
}
static void net_alarm(unsigned long unused)
{
- tasklet_schedule(&net_rx_tasklet);
+ tasklet_schedule(&net_rx_tasklet);
}
struct net_device_stats *netif_be_get_stats(struct net_device *dev)
{
- netif_t *netif = netdev_priv(dev);
- return &netif->stats;
+ netif_t *netif = netdev_priv(dev);
+ return &netif->stats;
}
static int __on_net_schedule_list(netif_t *netif)
{
- return netif->list.next != NULL;
+ return netif->list.next != NULL;
}
static void remove_from_net_schedule_list(netif_t *netif)
{
- spin_lock_irq(&net_schedule_list_lock);
- if ( likely(__on_net_schedule_list(netif)) )
- {
- list_del(&netif->list);
- netif->list.next = NULL;
- netif_put(netif);
- }
- spin_unlock_irq(&net_schedule_list_lock);
+ spin_lock_irq(&net_schedule_list_lock);
+ if (likely(__on_net_schedule_list(netif))) {
+ list_del(&netif->list);
+ netif->list.next = NULL;
+ netif_put(netif);
+ }
+ spin_unlock_irq(&net_schedule_list_lock);
}
static void add_to_net_schedule_list_tail(netif_t *netif)
{
- if ( __on_net_schedule_list(netif) )
- return;
-
- spin_lock_irq(&net_schedule_list_lock);
- if ( !__on_net_schedule_list(netif) && netif->active )
- {
- list_add_tail(&netif->list, &net_schedule_list);
- netif_get(netif);
- }
- spin_unlock_irq(&net_schedule_list_lock);
+ if (__on_net_schedule_list(netif))
+ return;
+
+ spin_lock_irq(&net_schedule_list_lock);
+ if (!__on_net_schedule_list(netif) &&
+ likely(netif_running(netif->dev) &&
+ netif_carrier_ok(netif->dev))) {
+ list_add_tail(&netif->list, &net_schedule_list);
+ netif_get(netif);
+ }
+ spin_unlock_irq(&net_schedule_list_lock);
}
+/*
+ * Note on CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER:
+ * If this driver is pipelining transmit requests then we can be very
+ * aggressive in avoiding new-packet notifications -- frontend only needs to
+ * send a notification if there are no outstanding unreceived responses.
+ * If we may be buffer transmit buffers for any reason then we must be rather
+ * more conservative and treat this as the final check for pending work.
+ */
void netif_schedule_work(netif_t *netif)
{
- if ( (netif->tx_req_cons != netif->tx->req_prod) &&
- ((netif->tx_req_cons-netif->tx_resp_prod) != NETIF_TX_RING_SIZE) )
- {
- add_to_net_schedule_list_tail(netif);
- maybe_schedule_tx_action();
- }
+ int more_to_do;
+
+#ifdef CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER
+ more_to_do = RING_HAS_UNCONSUMED_REQUESTS(&netif->tx);
+#else
+ RING_FINAL_CHECK_FOR_REQUESTS(&netif->tx, more_to_do);
+#endif
+
+ if (more_to_do) {
+ add_to_net_schedule_list_tail(netif);
+ maybe_schedule_tx_action();
+ }
}
void netif_deschedule_work(netif_t *netif)
{
- remove_from_net_schedule_list(netif);
+ remove_from_net_schedule_list(netif);
}
static void tx_credit_callback(unsigned long data)
{
- netif_t *netif = (netif_t *)data;
- netif->remaining_credit = netif->credit_bytes;
- netif_schedule_work(netif);
+ netif_t *netif = (netif_t *)data;
+ netif->remaining_credit = netif->credit_bytes;
+ netif_schedule_work(netif);
}
-static void net_tx_action(unsigned long unused)
+inline static void net_tx_action_dealloc(void)
{
- struct list_head *ent;
- struct sk_buff *skb;
- netif_t *netif;
- netif_tx_request_t txreq;
- u16 pending_idx;
- NETIF_RING_IDX i;
- multicall_entry_t *mcl;
- PEND_RING_IDX dc, dp;
- unsigned int data_len;
-
- if ( (dc = dealloc_cons) == (dp = dealloc_prod) )
- goto skip_dealloc;
-
- mcl = tx_mcl;
- while ( dc != dp )
- {
- pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
- mcl[0].op = __HYPERVISOR_update_va_mapping;
- mcl[0].args[0] = MMAP_VADDR(pending_idx);
- mcl[0].args[1] = 0;
- mcl[0].args[2] = 0;
- mcl++;
- }
-
- mcl[-1].args[2] = UVMF_TLB_FLUSH|UVMF_ALL;
- if ( unlikely(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0) )
- BUG();
-
- mcl = tx_mcl;
- while ( dealloc_cons != dp )
- {
- /* The update_va_mapping() must not fail. */
- if ( unlikely(mcl[0].args[5] != 0) )
- BUG();
-
- pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)];
-
- netif = pending_tx_info[pending_idx].netif;
-
- make_tx_response(netif, pending_tx_info[pending_idx].req.id,
- NETIF_RSP_OKAY);
-
- pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
-
- /*
- * Scheduling checks must happen after the above response is posted.
- * This avoids a possible race with a guest OS on another CPU if that
- * guest is testing against 'resp_prod' when deciding whether to notify
- * us when it queues additional packets.
- */
- mb();
- if ( (netif->tx_req_cons != netif->tx->req_prod) &&
- ((netif->tx_req_cons-netif->tx_resp_prod) != NETIF_TX_RING_SIZE) )
- add_to_net_schedule_list_tail(netif);
-
- netif_put(netif);
-
- mcl++;
- }
-
- skip_dealloc:
- mcl = tx_mcl;
- while ( (NR_PENDING_REQS < MAX_PENDING_REQS) &&
- !list_empty(&net_schedule_list) )
- {
- /* Get a netif from the list with work to do. */
- ent = net_schedule_list.next;
- netif = list_entry(ent, netif_t, list);
- netif_get(netif);
- remove_from_net_schedule_list(netif);
-
- /* Work to do? */
- i = netif->tx_req_cons;
- if ( (i == netif->tx->req_prod) ||
- ((i-netif->tx_resp_prod) == NETIF_TX_RING_SIZE) )
- {
- netif_put(netif);
- continue;
- }
-
- rmb(); /* Ensure that we see the request before we copy it. */
- memcpy(&txreq, &netif->tx->ring[MASK_NETIF_TX_IDX(i)].req,
- sizeof(txreq));
-
- /* Credit-based scheduling. */
- if ( txreq.size > netif->remaining_credit )
- {
- unsigned long now = jiffies;
- unsigned long next_credit =
- netif->credit_timeout.expires +
- msecs_to_jiffies(netif->credit_usec / 1000);
-
- /* Timer could already be pending in some rare cases. */
- if ( timer_pending(&netif->credit_timeout) )
- break;
-
- /* Already passed the point at which we can replenish credit? */
- if ( time_after_eq(now, next_credit) )
- {
- netif->credit_timeout.expires = now;
- netif->remaining_credit = netif->credit_bytes;
- }
-
- /* Still too big to send right now? Then set a timer callback. */
- if ( txreq.size > netif->remaining_credit )
- {
- netif->remaining_credit = 0;
- netif->credit_timeout.expires = next_credit;
- netif->credit_timeout.data = (unsigned long)netif;
- netif->credit_timeout.function = tx_credit_callback;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- add_timer_on(&netif->credit_timeout, smp_processor_id());
-#else
- add_timer(&netif->credit_timeout);
-#endif
- break;
- }
- }
- netif->remaining_credit -= txreq.size;
-
- /*
- * Why the barrier? It ensures that the frontend sees updated req_cons
- * before we check for more work to schedule.
- */
- netif->tx->req_cons = ++netif->tx_req_cons;
- mb();
-
- netif_schedule_work(netif);
-
- if ( unlikely(txreq.size < ETH_HLEN) ||
- unlikely(txreq.size > ETH_FRAME_LEN) )
- {
- DPRINTK("Bad packet size: %d\n", txreq.size);
- make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
- netif_put(netif);
- continue;
- }
-
- /* No crossing a page boundary as the payload mustn't fragment. */
- if ( unlikely(((txreq.addr & ~PAGE_MASK) + txreq.size) >= PAGE_SIZE) )
- {
- DPRINTK("txreq.addr: %lx, size: %u, end: %lu\n",
- txreq.addr, txreq.size,
- (txreq.addr &~PAGE_MASK) + txreq.size);
- make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
- netif_put(netif);
- continue;
- }
-
- pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
-
- data_len = (txreq.size > PKT_PROT_LEN) ? PKT_PROT_LEN : txreq.size;
-
- if ( unlikely((skb = alloc_skb(data_len+16, GFP_ATOMIC)) == NULL) )
- {
- DPRINTK("Can't allocate a skb in start_xmit.\n");
- make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
- netif_put(netif);
- break;
- }
-
- /* Packets passed to netif_rx() must have some headroom. */
- skb_reserve(skb, 16);
-
- mcl[0].op = __HYPERVISOR_update_va_mapping_otherdomain;
- mcl[0].args[0] = MMAP_VADDR(pending_idx);
- mcl[0].args[1] = (txreq.addr & PAGE_MASK) | __PAGE_KERNEL;
- mcl[0].args[2] = 0;
- mcl[0].args[3] = netif->domid;
- mcl++;
-
- memcpy(&pending_tx_info[pending_idx].req, &txreq, sizeof(txreq));
- pending_tx_info[pending_idx].netif = netif;
- *((u16 *)skb->data) = pending_idx;
-
- __skb_queue_tail(&tx_queue, skb);
-
- pending_cons++;
-
- /* Filled the batch queue? */
- if ( (mcl - tx_mcl) == ARRAY_SIZE(tx_mcl) )
- break;
- }
-
- if ( mcl == tx_mcl )
- return;
-
- if ( unlikely(HYPERVISOR_multicall(tx_mcl, mcl - tx_mcl) != 0) )
- BUG();
-
- mcl = tx_mcl;
- while ( (skb = __skb_dequeue(&tx_queue)) != NULL )
- {
- pending_idx = *((u16 *)skb->data);
- netif = pending_tx_info[pending_idx].netif;
- memcpy(&txreq, &pending_tx_info[pending_idx].req, sizeof(txreq));
-
- /* Check the remap error code. */
- if ( unlikely(mcl[0].args[5] != 0) )
- {
- DPRINTK("Bad page frame\n");
- make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
- netif_put(netif);
- kfree_skb(skb);
- mcl++;
- pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
- continue;
- }
-
- phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] =
- FOREIGN_FRAME(txreq.addr >> PAGE_SHIFT);
-
- data_len = (txreq.size > PKT_PROT_LEN) ? PKT_PROT_LEN : txreq.size;
-
- __skb_put(skb, data_len);
- memcpy(skb->data,
- (void *)(MMAP_VADDR(pending_idx)|(txreq.addr&~PAGE_MASK)),
- data_len);
-
- if ( data_len < txreq.size )
- {
- /* Append the packet payload as a fragment. */
- skb_shinfo(skb)->frags[0].page =
- virt_to_page(MMAP_VADDR(pending_idx));
- skb_shinfo(skb)->frags[0].size = txreq.size - data_len;
- skb_shinfo(skb)->frags[0].page_offset =
- (txreq.addr + data_len) & ~PAGE_MASK;
- skb_shinfo(skb)->nr_frags = 1;
- }
- else
- {
- /* Schedule a response immediately. */
- netif_idx_release(pending_idx);
- }
-
- skb->data_len = txreq.size - data_len;
- skb->len += skb->data_len;
-
- skb->dev = netif->dev;
- skb->protocol = eth_type_trans(skb, skb->dev);
-
- netif->stats.rx_bytes += txreq.size;
- netif->stats.rx_packets++;
-
- netif_rx(skb);
- netif->dev->last_rx = jiffies;
-
- mcl++;
- }
+ gnttab_unmap_grant_ref_t *gop;
+ u16 pending_idx;
+ PEND_RING_IDX dc, dp;
+ netif_t *netif;
+ int ret;
+
+ dc = dealloc_cons;
+ dp = dealloc_prod;
+
+ /* Ensure we see all indexes enqueued by netif_idx_release(). */
+ smp_rmb();
+
+ /*
+ * Free up any grants we have finished using
+ */
+ gop = tx_unmap_ops;
+ while (dc != dp) {
+ pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)];
+ gnttab_set_unmap_op(gop, MMAP_VADDR(pending_idx),
+ GNTMAP_host_map,
+ grant_tx_handle[pending_idx]);
+ gop++;
+ }
+ ret = HYPERVISOR_grant_table_op(
+ GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops);
+ BUG_ON(ret);
+
+ while (dealloc_cons != dp) {
+ pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)];
+
+ netif = pending_tx_info[pending_idx].netif;
+
+ make_tx_response(netif, &pending_tx_info[pending_idx].req,
+ NETIF_RSP_OKAY);
+
+ pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
+
+ netif_put(netif);
+ }
}
-static void netif_idx_release(u16 pending_idx)
+static void netbk_tx_err(netif_t *netif, netif_tx_request_t *txp, RING_IDX end)
{
- static spinlock_t _lock = SPIN_LOCK_UNLOCKED;
- unsigned long flags;
-
- spin_lock_irqsave(&_lock, flags);
- dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx;
- spin_unlock_irqrestore(&_lock, flags);
-
- tasklet_schedule(&net_tx_tasklet);
+ RING_IDX cons = netif->tx.req_cons;
+
+ do {
+ make_tx_response(netif, txp, NETIF_RSP_ERROR);
+ if (cons >= end)
+ break;
+ txp = RING_GET_REQUEST(&netif->tx, cons++);
+ } while (1);
+ netif->tx.req_cons = cons;
+ netif_schedule_work(netif);
+ netif_put(netif);
}
-static void netif_page_release(struct page *page)
+static int netbk_count_requests(netif_t *netif, netif_tx_request_t *txp,
+ int work_to_do)
{
- u16 pending_idx = page - virt_to_page(mmap_vstart);
-
- /* Ready for next use. */
- set_page_count(page, 1);
-
- netif_idx_release(pending_idx);
+ netif_tx_request_t *first = txp;
+ RING_IDX cons = netif->tx.req_cons;
+ int frags = 0;
+
+ while (txp->flags & NETTXF_more_data) {
+ if (frags >= work_to_do) {
+ DPRINTK("Need more frags\n");
+ return -frags;
+ }
+
+ txp = RING_GET_REQUEST(&netif->tx, cons + frags);
+ if (txp->size > first->size) {
+ DPRINTK("Frags galore\n");
+ return -frags;
+ }
+
+ first->size -= txp->size;
+ frags++;
+
+ if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) {
+ DPRINTK("txp->offset: %x, size: %u\n",
+ txp->offset, txp->size);
+ return -frags;
+ }
+ }
+
+ return frags;
}
-irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
+static gnttab_map_grant_ref_t *netbk_get_requests(netif_t *netif,
+ struct sk_buff *skb,
+ gnttab_map_grant_ref_t *mop)
{
- netif_t *netif = dev_id;
- if ( tx_work_exists(netif) )
- {
- add_to_net_schedule_list_tail(netif);
- maybe_schedule_tx_action();
- }
- return IRQ_HANDLED;
+ struct skb_shared_info *shinfo = skb_shinfo(skb);
+ skb_frag_t *frags = shinfo->frags;
+ netif_tx_request_t *txp;
+ unsigned long pending_idx = *((u16 *)skb->data);
+ RING_IDX cons = netif->tx.req_cons;
+ int i, start;
+
+ /* Skip first skb fragment if it is on same page as header fragment. */
+ start = ((unsigned long)shinfo->frags[0].page == pending_idx);
+
+ for (i = start; i < shinfo->nr_frags; i++) {
+ txp = RING_GET_REQUEST(&netif->tx, cons++);
+ pending_idx = pending_ring[MASK_PEND_IDX(pending_cons++)];
+
+ gnttab_set_map_op(mop++, MMAP_VADDR(pending_idx),
+ GNTMAP_host_map | GNTMAP_readonly,
+ txp->gref, netif->domid);
+
+ memcpy(&pending_tx_info[pending_idx].req, txp, sizeof(*txp));
+ netif_get(netif);
+ pending_tx_info[pending_idx].netif = netif;
+ frags[i].page = (void *)pending_idx;
+ }
+
+ return mop;
}
-static void make_tx_response(netif_t *netif,
- u16 id,
- s8 st)
+static int netbk_tx_check_mop(struct sk_buff *skb,
+ gnttab_map_grant_ref_t **mopp)
{
- NETIF_RING_IDX i = netif->tx_resp_prod;
- netif_tx_response_t *resp;
+ gnttab_map_grant_ref_t *mop = *mopp;
+ int pending_idx = *((u16 *)skb->data);
+ netif_t *netif = pending_tx_info[pending_idx].netif;
+ netif_tx_request_t *txp;
+ struct skb_shared_info *shinfo = skb_shinfo(skb);
+ int nr_frags = shinfo->nr_frags;
+ int i, err, start;
+
+ /* Check status of header. */
+ err = mop->status;
+ if (unlikely(err)) {
+ txp = &pending_tx_info[pending_idx].req;
+ make_tx_response(netif, txp, NETIF_RSP_ERROR);
+ pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
+ netif_put(netif);
+ } else {
+ set_phys_to_machine(
+ __pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT,
+ FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT));
+ grant_tx_handle[pending_idx] = mop->handle;
+ }
+
+ /* Skip first skb fragment if it is on same page as header fragment. */
+ start = ((unsigned long)shinfo->frags[0].page == pending_idx);
+
+ for (i = start; i < nr_frags; i++) {
+ int j, newerr;
+
+ pending_idx = (unsigned long)shinfo->frags[i].page;
+
+ /* Check error status: if okay then remember grant handle. */
+ newerr = (++mop)->status;
+ if (likely(!newerr)) {
+ set_phys_to_machine(
+ __pa(MMAP_VADDR(pending_idx))>>PAGE_SHIFT,
+ FOREIGN_FRAME(mop->dev_bus_addr>>PAGE_SHIFT));
+ grant_tx_handle[pending_idx] = mop->handle;
+ /* Had a previous error? Invalidate this fragment. */
+ if (unlikely(err))
+ netif_idx_release(pending_idx);
+ continue;
+ }
+
+ /* Error on this fragment: respond to client with an error. */
+ txp = &pending_tx_info[pending_idx].req;
+ make_tx_response(netif, txp, NETIF_RSP_ERROR);
+ pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
+ netif_put(netif);
+
+ /* Not the first error? Preceding frags already invalidated. */
+ if (err)
+ continue;
+
+ /* First error: invalidate header and preceding fragments. */
+ pending_idx = *((u16 *)skb->data);
+ netif_idx_release(pending_idx);
+ for (j = start; j < i; j++) {
+ pending_idx = (unsigned long)shinfo->frags[i].page;
+ netif_idx_release(pending_idx);
+ }
+
+ /* Remember the error: invalidate all subsequent fragments. */
+ err = newerr;
+ }
+
+ *mopp = mop + 1;
+ return err;
+}
- resp = &netif->tx->ring[MASK_NETIF_TX_IDX(i)].resp;
- resp->id = id;
- resp->status = st;
- wmb();
- netif->tx->resp_prod = netif->tx_resp_prod = ++i;
+static void netbk_fill_frags(struct sk_buff *skb)
+{
+ struct skb_shared_info *shinfo = skb_shinfo(skb);
+ int nr_frags = shinfo->nr_frags;
+ int i;
+
+ for (i = 0; i < nr_frags; i++) {
+ skb_frag_t *frag = shinfo->frags + i;
+ netif_tx_request_t *txp;
+ unsigned long pending_idx;
+
+ pending_idx = (unsigned long)frag->page;
+ txp = &pending_tx_info[pending_idx].req;
+ frag->page = virt_to_page(MMAP_VADDR(pending_idx));
+ frag->size = txp->size;
+ frag->page_offset = txp->offset;
+
+ skb->len += txp->size;
+ skb->data_len += txp->size;
+ skb->truesize += txp->size;
+ }
+}
- mb(); /* Update producer before checking event threshold. */
- if ( i == netif->tx->event )
- notify_via_evtchn(netif->evtchn);
+int netbk_get_extras(netif_t *netif, struct netif_extra_info *extras,
+ int work_to_do)
+{
+ struct netif_extra_info *extra;
+ RING_IDX cons = netif->tx.req_cons;
+
+ do {
+ if (unlikely(work_to_do-- <= 0)) {
+ DPRINTK("Missing extra info\n");
+ return -EBADR;
+ }
+
+ extra = (struct netif_extra_info *)
+ RING_GET_REQUEST(&netif->tx, cons);
+ if (unlikely(!extra->type ||
+ extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
+ netif->tx.req_cons = ++cons;
+ DPRINTK("Invalid extra type: %d\n", extra->type);
+ return -EINVAL;
+ }
+
+ memcpy(&extras[extra->type - 1], extra, sizeof(*extra));
+ netif->tx.req_cons = ++cons;
+ } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
+
+ return work_to_do;
}
-static int make_rx_response(netif_t *netif,
- u16 id,
- s8 st,
- memory_t addr,
- u16 size)
+static int netbk_set_skb_gso(struct sk_buff *skb, struct netif_extra_info *gso)
{
- NETIF_RING_IDX i = netif->rx_resp_prod;
- netif_rx_response_t *resp;
+ if (!gso->u.gso.size) {
+ DPRINTK("GSO size must not be zero.\n");
+ return -EINVAL;
+ }
+
+ /* Currently only TCPv4 S.O. is supported. */
+ if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) {
+ DPRINTK("Bad GSO type %d.\n", gso->u.gso.type);
+ return -EINVAL;
+ }
+
+ skb_shinfo(skb)->gso_size = gso->u.gso.size;
+ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
- resp = &netif->rx->ring[MASK_NETIF_RX_IDX(i)].resp;
- resp->addr = addr;
- resp->id = id;
- resp->status = (s16)size;
- if ( st < 0 )
- resp->status = (s16)st;
- wmb();
- netif->rx->resp_prod = netif->rx_resp_prod = ++i;
+ /* Header must be checked, and gso_segs computed. */
+ skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+ skb_shinfo(skb)->gso_segs = 0;
- mb(); /* Update producer before checking event threshold. */
- return (i == netif->rx->event);
+ return 0;
}
-static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs)
+/* Called after netfront has transmitted */
+static void net_tx_action(unsigned long unused)
{
- struct list_head *ent;
- netif_t *netif;
- int i = 0;
-
- printk(KERN_ALERT "netif_schedule_list:\n");
- spin_lock_irq(&net_schedule_list_lock);
+ struct list_head *ent;
+ struct sk_buff *skb;
+ netif_t *netif;
+ netif_tx_request_t txreq;
+ struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
+ u16 pending_idx;
+ RING_IDX i;
+ gnttab_map_grant_ref_t *mop;
+ unsigned int data_len;
+ int ret, work_to_do;
+
+ if (dealloc_cons != dealloc_prod)
+ net_tx_action_dealloc();
+
+ mop = tx_map_ops;
+ while (((NR_PENDING_REQS + MAX_SKB_FRAGS) < MAX_PENDING_REQS) &&
+ !list_empty(&net_schedule_list)) {
+ /* Get a netif from the list with work to do. */
+ ent = net_schedule_list.next;
+ netif = list_entry(ent, netif_t, list);
+ netif_get(netif);
+ remove_from_net_schedule_list(netif);
+
+ RING_FINAL_CHECK_FOR_REQUESTS(&netif->tx, work_to_do);
+ if (!work_to_do) {
+ netif_put(netif);
+ continue;
+ }
+
+ i = netif->tx.req_cons;
+ rmb(); /* Ensure that we see the request before we copy it. */
+ memcpy(&txreq, RING_GET_REQUEST(&netif->tx, i), sizeof(txreq));
+ /* Credit-based scheduling. */
+ if (txreq.size > netif->remaining_credit) {
+ unsigned long now = jiffies;
+ unsigned long next_credit =
+ netif->credit_timeout.expires +
+ msecs_to_jiffies(netif->credit_usec / 1000);
+
+ /* Timer could already be pending in rare cases. */
+ if (timer_pending(&netif->credit_timeout))
+ break;
+
+ /* Passed the point where we can replenish credit? */
+ if (time_after_eq(now, next_credit)) {
+ netif->credit_timeout.expires = now;
+ netif->remaining_credit = netif->credit_bytes;
+ }
+
+ /* Still too big to send right now? Set a callback. */
+ if (txreq.size > netif->remaining_credit) {
+ netif->remaining_credit = 0;
+ netif->credit_timeout.data =
+ (unsigned long)netif;
+ netif->credit_timeout.function =
+ tx_credit_callback;
+ __mod_timer(&netif->credit_timeout,
+ next_credit);
+ break;
+ }
+ }
+ netif->remaining_credit -= txreq.size;
+
+ work_to_do--;
+ netif->tx.req_cons = ++i;
+
+ memset(extras, 0, sizeof(extras));
+ if (txreq.flags & NETTXF_extra_info) {
+ work_to_do = netbk_get_extras(netif, extras,
+ work_to_do);
+ i = netif->tx.req_cons;
+ if (unlikely(work_to_do < 0)) {
+ netbk_tx_err(netif, &txreq, i);
+ continue;
+ }
+ }
+
+ ret = netbk_count_requests(netif, &txreq, work_to_do);
+ if (unlikely(ret < 0)) {
+ netbk_tx_err(netif, &txreq, i - ret);
+ continue;
+ }
+ i += ret;
+
+ if (unlikely(ret > MAX_SKB_FRAGS)) {
+ DPRINTK("Too many frags\n");
+ netbk_tx_err(netif, &txreq, i);
+ continue;
+ }
+
+ if (unlikely(txreq.size < ETH_HLEN)) {
+ DPRINTK("Bad packet size: %d\n", txreq.size);
+ netbk_tx_err(netif, &txreq, i);
+ continue;
+ }
+
+ /* No crossing a page as the payload mustn't fragment. */
+ if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) {
+ DPRINTK("txreq.offset: %x, size: %u, end: %lu\n",
+ txreq.offset, txreq.size,
+ (txreq.offset &~PAGE_MASK) + txreq.size);
+ netbk_tx_err(netif, &txreq, i);
+ continue;
+ }
+
+ pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
+
+ data_len = (txreq.size > PKT_PROT_LEN &&
+ ret < MAX_SKB_FRAGS) ?
+ PKT_PROT_LEN : txreq.size;
+
+ skb = alloc_skb(data_len+16, GFP_ATOMIC);
+ if (unlikely(skb == NULL)) {
+ DPRINTK("Can't allocate a skb in start_xmit.\n");
+ netbk_tx_err(netif, &txreq, i);
+ break;
+ }
+
+ /* Packets passed to netif_rx() must have some headroom. */
+ skb_reserve(skb, 16);
+
+ if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) {
+ struct netif_extra_info *gso;
+ gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
+
+ if (netbk_set_skb_gso(skb, gso)) {
+ kfree_skb(skb);
+ netbk_tx_err(netif, &txreq, i);
+ continue;
+ }
+ }
+
+ gnttab_set_map_op(mop, MMAP_VADDR(pending_idx),
+ GNTMAP_host_map | GNTMAP_readonly,
+ txreq.gref, netif->domid);
+ mop++;
+
+ memcpy(&pending_tx_info[pending_idx].req,
+ &txreq, sizeof(txreq));
+ pending_tx_info[pending_idx].netif = netif;
+ *((u16 *)skb->data) = pending_idx;
+
+ __skb_put(skb, data_len);
+
+ skb_shinfo(skb)->nr_frags = ret;
+ if (data_len < txreq.size) {
+ skb_shinfo(skb)->nr_frags++;
+ skb_shinfo(skb)->frags[0].page =
+ (void *)(unsigned long)pending_idx;
+ }
+
+ __skb_queue_tail(&tx_queue, skb);
+
+ pending_cons++;
+
+ mop = netbk_get_requests(netif, skb, mop);
+
+ netif->tx.req_cons = i;
+ netif_schedule_work(netif);
+
+ if ((mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops))
+ break;
+ }
+
+ if (mop == tx_map_ops)
+ return;
+
+ ret = HYPERVISOR_grant_table_op(
+ GNTTABOP_map_grant_ref, tx_map_ops, mop - tx_map_ops);
+ BUG_ON(ret);
+
+ mop = tx_map_ops;
+ while ((skb = __skb_dequeue(&tx_queue)) != NULL) {
+ netif_tx_request_t *txp;
+
+ pending_idx = *((u16 *)skb->data);
+ netif = pending_tx_info[pending_idx].netif;
+ txp = &pending_tx_info[pending_idx].req;
+
+ /* Check the remap error code. */
+ if (unlikely(netbk_tx_check_mop(skb, &mop))) {
+ printk(KERN_ALERT "#### netback grant fails\n");
+ skb_shinfo(skb)->nr_frags = 0;
+ kfree_skb(skb);
+ continue;
+ }
+
+ data_len = skb->len;
+ memcpy(skb->data,
+ (void *)(MMAP_VADDR(pending_idx)|txp->offset),
+ data_len);
+ if (data_len < txp->size) {
+ /* Append the packet payload as a fragment. */
+ txp->offset += data_len;
+ txp->size -= data_len;
+ } else {
+ /* Schedule a response immediately. */
+ netif_idx_release(pending_idx);
+ }
+
+ /*
+ * Old frontends do not assert data_validated but we
+ * can infer it from csum_blank so test both flags.
+ */
+ if (txp->flags & (NETTXF_data_validated|NETTXF_csum_blank)) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->proto_data_valid = 1;
+ } else {
+ skb->ip_summed = CHECKSUM_NONE;
+ skb->proto_data_valid = 0;
+ }
+ skb->proto_csum_blank = !!(txp->flags & NETTXF_csum_blank);
+
+ netbk_fill_frags(skb);
+
+ skb->dev = netif->dev;
+ skb->protocol = eth_type_trans(skb, skb->dev);
+
+ netif->stats.rx_bytes += skb->len;
+ netif->stats.rx_packets++;
+
+ netif_rx(skb);
+ netif->dev->last_rx = jiffies;
+ }
+}
- list_for_each ( ent, &net_schedule_list )
- {
- netif = list_entry(ent, netif_t, list);
- printk(KERN_ALERT " %d: private(rx_req_cons=%08x rx_resp_prod=%08x\n",
- i, netif->rx_req_cons, netif->rx_resp_prod);
- printk(KERN_ALERT " tx_req_cons=%08x tx_resp_prod=%08x)\n",
- netif->tx_req_cons, netif->tx_resp_prod);
- printk(KERN_ALERT " shared(rx_req_prod=%08x rx_resp_prod=%08x\n",
- netif->rx->req_prod, netif->rx->resp_prod);
- printk(KERN_ALERT " rx_event=%08x tx_req_prod=%08x\n",
- netif->rx->event, netif->tx->req_prod);
- printk(KERN_ALERT " tx_resp_prod=%08x, tx_event=%08x)\n",
- netif->tx->resp_prod, netif->tx->event);
- i++;
- }
+static void netif_idx_release(u16 pending_idx)
+{
+ static DEFINE_SPINLOCK(_lock);
+ unsigned long flags;
- spin_unlock_irq(&net_schedule_list_lock);
- printk(KERN_ALERT " ** End of netif_schedule_list **\n");
+ spin_lock_irqsave(&_lock, flags);
+ dealloc_ring[MASK_PEND_IDX(dealloc_prod)] = pending_idx;
+ /* Sync with net_tx_action_dealloc: insert idx /then/ incr producer. */
+ smp_wmb();
+ dealloc_prod++;
+ spin_unlock_irqrestore(&_lock, flags);
- return IRQ_HANDLED;
+ tasklet_schedule(&net_tx_tasklet);
}
-static int __init netback_init(void)
+static void netif_page_release(struct page *page)
{
- int i;
- struct page *page;
+ u16 pending_idx = page - virt_to_page(mmap_vstart);
- if ( !(xen_start_info.flags & SIF_NET_BE_DOMAIN) &&
- !(xen_start_info.flags & SIF_INITDOMAIN) )
- return 0;
+ /* Ready for next use. */
+ init_page_count(page);
- printk("Initialising Xen netif backend\n");
+ netif_idx_release(pending_idx);
+}
- /* We can increase reservation by this much in net_rx_action(). */
- balloon_update_driver_allowance(NETIF_RX_RING_SIZE);
+irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+ netif_t *netif = dev_id;
- skb_queue_head_init(&rx_queue);
- skb_queue_head_init(&tx_queue);
+ add_to_net_schedule_list_tail(netif);
+ maybe_schedule_tx_action();
- init_timer(&net_timer);
- net_timer.data = 0;
- net_timer.function = net_alarm;
-
- netif_interface_init();
+ if (netif_queue_stopped(netif->dev) && !netbk_queue_full(netif))
+ netif_wake_queue(netif->dev);
- if ( (mmap_vstart = allocate_empty_lowmem_region(MAX_PENDING_REQS)) == 0 )
- BUG();
+ return IRQ_HANDLED;
+}
- for ( i = 0; i < MAX_PENDING_REQS; i++ )
- {
- page = virt_to_page(MMAP_VADDR(i));
- set_page_count(page, 1);
- SetPageForeign(page, netif_page_release);
- }
+static void make_tx_response(netif_t *netif,
+ netif_tx_request_t *txp,
+ s8 st)
+{
+ RING_IDX i = netif->tx.rsp_prod_pvt;
+ netif_tx_response_t *resp;
+ int notify;
+
+ resp = RING_GET_RESPONSE(&netif->tx, i);
+ resp->id = txp->id;
+ resp->status = st;
+
+ if (txp->flags & NETTXF_extra_info)
+ RING_GET_RESPONSE(&netif->tx, ++i)->status = NETIF_RSP_NULL;
+
+ netif->tx.rsp_prod_pvt = ++i;
+ RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->tx, notify);
+ if (notify)
+ notify_remote_via_irq(netif->irq);
+
+#ifdef CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER
+ if (i == netif->tx.req_cons) {
+ int more_to_do;
+ RING_FINAL_CHECK_FOR_REQUESTS(&netif->tx, more_to_do);
+ if (more_to_do)
+ add_to_net_schedule_list_tail(netif);
+ }
+#endif
+}
- pending_cons = 0;
- pending_prod = MAX_PENDING_REQS;
- for ( i = 0; i < MAX_PENDING_REQS; i++ )
- pending_ring[i] = i;
+static netif_rx_response_t *make_rx_response(netif_t *netif,
+ u16 id,
+ s8 st,
+ u16 offset,
+ u16 size,
+ u16 flags)
+{
+ RING_IDX i = netif->rx.rsp_prod_pvt;
+ netif_rx_response_t *resp;
- spin_lock_init(&net_schedule_list_lock);
- INIT_LIST_HEAD(&net_schedule_list);
+ resp = RING_GET_RESPONSE(&netif->rx, i);
+ resp->offset = offset;
+ resp->flags = flags;
+ resp->id = id;
+ resp->status = (s16)size;
+ if (st < 0)
+ resp->status = (s16)st;
- netif_ctrlif_init();
+ netif->rx.rsp_prod_pvt = ++i;
- (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG),
- netif_be_dbg, SA_SHIRQ,
- "net-be-dbg", &netif_be_dbg);
+ return resp;
+}
- return 0;
+#ifdef NETBE_DEBUG_INTERRUPT
+static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct list_head *ent;
+ netif_t *netif;
+ int i = 0;
+
+ printk(KERN_ALERT "netif_schedule_list:\n");
+ spin_lock_irq(&net_schedule_list_lock);
+
+ list_for_each (ent, &net_schedule_list) {
+ netif = list_entry(ent, netif_t, list);
+ printk(KERN_ALERT " %d: private(rx_req_cons=%08x "
+ "rx_resp_prod=%08x\n",
+ i, netif->rx.req_cons, netif->rx.rsp_prod_pvt);
+ printk(KERN_ALERT " tx_req_cons=%08x tx_resp_prod=%08x)\n",
+ netif->tx.req_cons, netif->tx.rsp_prod_pvt);
+ printk(KERN_ALERT " shared(rx_req_prod=%08x "
+ "rx_resp_prod=%08x\n",
+ netif->rx.sring->req_prod, netif->rx.sring->rsp_prod);
+ printk(KERN_ALERT " rx_event=%08x tx_req_prod=%08x\n",
+ netif->rx.sring->rsp_event, netif->tx.sring->req_prod);
+ printk(KERN_ALERT " tx_resp_prod=%08x, tx_event=%08x)\n",
+ netif->tx.sring->rsp_prod, netif->tx.sring->rsp_event);
+ i++;
+ }
+
+ spin_unlock_irq(&net_schedule_list_lock);
+ printk(KERN_ALERT " ** End of netif_schedule_list **\n");
+
+ return IRQ_HANDLED;
}
+#endif
-static void netback_cleanup(void)
+static int __init netback_init(void)
{
- BUG();
+ int i;
+ struct page *page;
+
+ if (!is_running_on_xen())
+ return -ENODEV;
+
+ /* We can increase reservation by this much in net_rx_action(). */
+ balloon_update_driver_allowance(NET_RX_RING_SIZE);
+
+ skb_queue_head_init(&rx_queue);
+ skb_queue_head_init(&tx_queue);
+
+ init_timer(&net_timer);
+ net_timer.data = 0;
+ net_timer.function = net_alarm;
+
+ page = balloon_alloc_empty_page_range(MAX_PENDING_REQS);
+ if (page == NULL)
+ return -ENOMEM;
+
+ mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+
+ for (i = 0; i < MAX_PENDING_REQS; i++) {
+ page = virt_to_page(MMAP_VADDR(i));
+ init_page_count(page);
+ SetPageForeign(page, netif_page_release);
+ }
+
+ pending_cons = 0;
+ pending_prod = MAX_PENDING_REQS;
+ for (i = 0; i < MAX_PENDING_REQS; i++)
+ pending_ring[i] = i;
+
+ spin_lock_init(&net_schedule_list_lock);
+ INIT_LIST_HEAD(&net_schedule_list);
+
+ netif_xenbus_init();
+
+#ifdef NETBE_DEBUG_INTERRUPT
+ (void)bind_virq_to_irqhandler(
+ VIRQ_DEBUG,
+ 0,
+ netif_be_dbg,
+ SA_SHIRQ,
+ "net-be-dbg",
+ &netif_be_dbg);
+#endif
+
+ return 0;
}
module_init(netback_init);
-module_exit(netback_cleanup);
+
+MODULE_LICENSE("Dual BSD/GPL");
-obj-y := netfront.o
+obj-$(CONFIG_XEN_NETDEV_FRONTEND) := xennet.o
+
+xennet-objs := netfront.o
/******************************************************************************
* Virtual network driver for conversing with remote driver backends.
- *
- * Copyright (c) 2002-2004, K A Fraser
- *
- * This file may be distributed separately from the Linux kernel, or
- * incorporated into other software packages, subject to the following license:
- *
+ *
+ * Copyright (c) 2002-2005, K A Fraser
+ * Copyright (c) 2005, XenSource Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this source file (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify,
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#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 <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/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_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.
*
*/
static int send_fake_arp(struct net_device *dev)
{
- struct sk_buff *skb;
- u32 src_ip, dst_ip;
+ struct sk_buff *skb;
+ u32 src_ip, dst_ip;
- dst_ip = INADDR_BROADCAST;
- src_ip = inet_select_addr(dev, dst_ip, RT_SCOPE_LINK);
+ dst_ip = INADDR_BROADCAST;
+ src_ip = inet_select_addr(dev, dst_ip, RT_SCOPE_LINK);
- /* No IP? Then nothing to do. */
- if (src_ip == 0)
- return 0;
+ /* No IP? Then nothing to do. */
+ if (src_ip == 0)
+ return 0;
- skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
- dst_ip, dev, src_ip,
- /*dst_hw*/ NULL, /*src_hw*/ NULL,
- /*target_hw*/ dev->dev_addr);
- if (skb == NULL)
- return -ENOMEM;
+ skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
+ dst_ip, dev, src_ip,
+ /*dst_hw*/ NULL, /*src_hw*/ NULL,
+ /*target_hw*/ dev->dev_addr);
+ if (skb == NULL)
+ return -ENOMEM;
- return dev_queue_xmit(skb);
+ return dev_queue_xmit(skb);
}
+
static int network_open(struct net_device *dev)
{
- struct net_private *np = netdev_priv(dev);
+ struct netfront_info *np = netdev_priv(dev);
+
+ memset(&np->stats, 0, sizeof(np->stats));
- memset(&np->stats, 0, sizeof(np->stats));
+ network_alloc_rx_buffers(dev);
+ np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
- np->user_state = UST_OPEN;
+ if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
+ netif_rx_schedule(dev);
- network_alloc_rx_buffers(dev);
- np->rx->event = np->rx_resp_cons + 1;
+ netif_start_queue(dev);
- netif_start_queue(dev);
+ return 0;
+}
- return 0;
+static inline int netfront_tx_slot_available(struct netfront_info *np)
+{
+ return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 2;
+}
+
+static inline void network_maybe_wake_tx(struct net_device *dev)
+{
+ struct netfront_info *np = netdev_priv(dev);
+
+ if (unlikely(netif_queue_stopped(dev)) &&
+ netfront_tx_slot_available(np) &&
+ likely(netif_running(dev)))
+ netif_wake_queue(dev);
}
static void network_tx_buf_gc(struct net_device *dev)
{
- NETIF_RING_IDX i, prod;
- unsigned short id;
- struct net_private *np = netdev_priv(dev);
- struct sk_buff *skb;
-
- if (np->backend_state != BEST_CONNECTED)
- return;
-
- do {
- prod = np->tx->resp_prod;
- rmb(); /* Ensure we see responses up to 'rp'. */
-
- for (i = np->tx_resp_cons; i != prod; i++) {
- id = np->tx->ring[MASK_NETIF_TX_IDX(i)].resp.id;
- skb = np->tx_skbs[id];
- ADD_ID_TO_FREELIST(np->tx_skbs, id);
- dev_kfree_skb_irq(skb);
- }
-
- np->tx_resp_cons = prod;
-
- /*
- * Set a new event, then check for race with update of tx_cons. Note
- * that it is essential to schedule a callback, no matter how few
- * buffers are pending. Even if there is space in the transmit ring,
- * higher layers may be blocked because too much data is outstanding:
- * in such cases notification from Xen is likely to be the only kick
- * that we'll get.
- */
- np->tx->event =
- prod + ((np->tx->req_prod - prod) >> 1) + 1;
- mb();
- } while (prod != np->tx->resp_prod);
-
- if (np->tx_full && ((np->tx->req_prod - prod) < NETIF_TX_RING_SIZE)) {
- np->tx_full = 0;
- if (np->user_state == UST_OPEN)
- netif_wake_queue(dev);
- }
+ RING_IDX cons, prod;
+ unsigned short id;
+ struct netfront_info *np = netdev_priv(dev);
+ struct sk_buff *skb;
+
+ if (unlikely(!netif_carrier_ok(dev)))
+ return;
+
+ do {
+ prod = np->tx.sring->rsp_prod;
+ rmb(); /* Ensure we see responses up to 'rp'. */
+
+ for (cons = np->tx.rsp_cons; cons != prod; cons++) {
+ struct netif_tx_response *txrsp;
+
+ txrsp = RING_GET_RESPONSE(&np->tx, cons);
+ if (txrsp->status == NETIF_RSP_NULL)
+ continue;
+
+ id = txrsp->id;
+ skb = np->tx_skbs[id];
+ if (unlikely(gnttab_query_foreign_access(
+ np->grant_tx_ref[id]) != 0)) {
+ printk(KERN_ALERT "network_tx_buf_gc: warning "
+ "-- grant still in use by backend "
+ "domain.\n");
+ BUG();
+ }
+ gnttab_end_foreign_access_ref(
+ np->grant_tx_ref[id], GNTMAP_readonly);
+ gnttab_release_grant_reference(
+ &np->gref_tx_head, np->grant_tx_ref[id]);
+ np->grant_tx_ref[id] = GRANT_INVALID_REF;
+ add_id_to_freelist(np->tx_skbs, id);
+ dev_kfree_skb_irq(skb);
+ }
+
+ np->tx.rsp_cons = prod;
+
+ /*
+ * Set a new event, then check for race with update of tx_cons.
+ * Note that it is essential to schedule a callback, no matter
+ * how few buffers are pending. Even if there is space in the
+ * transmit ring, higher layers may be blocked because too much
+ * data is outstanding: in such cases notification from Xen is
+ * likely to be the only kick that we'll get.
+ */
+ np->tx.sring->rsp_event =
+ prod + ((np->tx.sring->req_prod - prod) >> 1) + 1;
+ mb();
+ } while ((cons == prod) && (prod != np->tx.sring->rsp_prod));
+
+ network_maybe_wake_tx(dev);
+}
+
+
+static void rx_refill_timeout(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ netif_rx_schedule(dev);
}
static void network_alloc_rx_buffers(struct net_device *dev)
{
- unsigned short id;
- struct net_private *np = netdev_priv(dev);
- struct sk_buff *skb;
- int i, batch_target;
- NETIF_RING_IDX req_prod = np->rx->req_prod;
-
- if (unlikely(np->backend_state != BEST_CONNECTED))
- return;
-
- /*
- * Allocate skbuffs greedily, even though we batch updates to the
- * receive ring. This creates a less bursty demand on the memory allocator,
- * so should reduce the chance of failed allocation requests both for
- * ourself and for other kernel subsystems.
- */
- batch_target = np->rx_target - (req_prod - np->rx_resp_cons);
- for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) {
- if (unlikely((skb = alloc_xen_skb(dev->mtu + RX_HEADROOM)) == NULL))
- break;
- __skb_queue_tail(&np->rx_batch, skb);
- }
-
- /* Is the batch large enough to be worthwhile? */
- if (i < (np->rx_target/2))
- return;
-
- for (i = 0; ; i++) {
- if ((skb = __skb_dequeue(&np->rx_batch)) == NULL)
- break;
-
- skb->dev = dev;
-
- id = GET_ID_FROM_FREELIST(np->rx_skbs);
-
- np->rx_skbs[id] = skb;
-
- np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.id = id;
-
- rx_pfn_array[i] = virt_to_machine(skb->head) >> PAGE_SHIFT;
-
- /* Remove this page from pseudo phys map before passing back to Xen. */
- phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT]
- = INVALID_P2M_ENTRY;
-
- rx_mcl[i].op = __HYPERVISOR_update_va_mapping;
- rx_mcl[i].args[0] = (unsigned long)skb->head;
- rx_mcl[i].args[1] = 0;
- rx_mcl[i].args[2] = 0;
- }
-
- /* After all PTEs have been zapped we blow away stale TLB entries. */
- rx_mcl[i-1].args[2] = UVMF_TLB_FLUSH|UVMF_ALL;
-
- /* Give away a batch of pages. */
- rx_mcl[i].op = __HYPERVISOR_dom_mem_op;
- rx_mcl[i].args[0] = MEMOP_decrease_reservation;
- rx_mcl[i].args[1] = (unsigned long)rx_pfn_array;
- rx_mcl[i].args[2] = (unsigned long)i;
- rx_mcl[i].args[3] = 0;
- rx_mcl[i].args[4] = DOMID_SELF;
-
- /* Tell the ballon driver what is going on. */
- balloon_update_driver_allowance(i);
-
- /* Zap PTEs and give away pages in one big multicall. */
- (void)HYPERVISOR_multicall(rx_mcl, i+1);
-
- /* Check return status of HYPERVISOR_dom_mem_op(). */
- if (unlikely(rx_mcl[i].args[5] != i))
- panic("Unable to reduce memory reservation\n");
-
- /* Above is a suitable barrier to ensure backend will see requests. */
- np->rx->req_prod = req_prod + i;
-
- /* Adjust our floating fill target if we risked running out of buffers. */
- if (((req_prod - np->rx->resp_prod) < (np->rx_target / 4)) &&
- ((np->rx_target *= 2) > RX_MAX_TARGET))
- np->rx_target = RX_MAX_TARGET;
+ unsigned short id;
+ struct netfront_info *np = netdev_priv(dev);
+ struct sk_buff *skb;
+ struct page *page;
+ int i, batch_target, notify;
+ RING_IDX req_prod = np->rx.req_prod_pvt;
+ struct xen_memory_reservation reservation;
+ grant_ref_t ref;
+ unsigned long pfn;
+ void *vaddr;
+
+ if (unlikely(!netif_carrier_ok(dev)))
+ return;
+
+ /*
+ * Allocate skbuffs greedily, even though we batch updates to the
+ * receive ring. This creates a less bursty demand on the memory
+ * allocator, so should reduce the chance of failed allocation requests
+ * both for ourself and for other kernel subsystems.
+ */
+ batch_target = np->rx_target - (req_prod - np->rx.rsp_cons);
+ for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) {
+ /*
+ * Allocate an skb and a page. Do not use __dev_alloc_skb as
+ * that will allocate page-sized buffers which is not
+ * necessary here.
+ * 16 bytes added as necessary headroom for netif_receive_skb.
+ */
+ skb = alloc_skb(RX_COPY_THRESHOLD + 16,
+ GFP_ATOMIC | __GFP_NOWARN);
+ if (unlikely(!skb))
+ goto no_skb;
+
+ page = alloc_page(GFP_ATOMIC | __GFP_NOWARN);
+ if (!page) {
+ kfree_skb(skb);
+no_skb:
+ /* Any skbuffs queued for refill? Force them out. */
+ if (i != 0)
+ goto refill;
+ /* Could not allocate any skbuffs. Try again later. */
+ mod_timer(&np->rx_refill_timer,
+ jiffies + (HZ/10));
+ break;
+ }
+
+ skb_reserve(skb, 16); /* mimic dev_alloc_skb() */
+ skb_shinfo(skb)->frags[0].page = page;
+ skb_shinfo(skb)->nr_frags = 1;
+ __skb_queue_tail(&np->rx_batch, skb);
+ }
+
+ /* Is the batch large enough to be worthwhile? */
+ if (i < (np->rx_target/2)) {
+ if (req_prod > np->rx.sring->req_prod)
+ goto push;
+ return;
+ }
+
+ /* Adjust our fill target if we risked running out of buffers. */
+ if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) &&
+ ((np->rx_target *= 2) > np->rx_max_target))
+ np->rx_target = np->rx_max_target;
+
+ refill:
+ for (i = 0; ; i++) {
+ if ((skb = __skb_dequeue(&np->rx_batch)) == NULL)
+ break;
+
+ skb->dev = dev;
+
+ id = xennet_rxidx(req_prod + i);
+
+ BUG_ON(np->rx_skbs[id]);
+ np->rx_skbs[id] = skb;
+
+ RING_GET_REQUEST(&np->rx, req_prod + i)->id = id;
+ ref = gnttab_claim_grant_reference(&np->gref_rx_head);
+ BUG_ON((signed short)ref < 0);
+ np->grant_rx_ref[id] = ref;
+
+ pfn = page_to_pfn(skb_shinfo(skb)->frags[0].page);
+ vaddr = page_address(skb_shinfo(skb)->frags[0].page);
+
+ gnttab_grant_foreign_transfer_ref(ref,
+ np->xbdev->otherend_id, pfn);
+ RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref;
+ np->rx_pfn_array[i] = pfn_to_mfn(pfn);
+
+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+ /* Remove this page before passing back to Xen. */
+ set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
+ MULTI_update_va_mapping(np->rx_mcl+i,
+ (unsigned long)vaddr,
+ __pte(0), 0);
+ }
+ }
+
+ /* Tell the ballon driver what is going on. */
+ balloon_update_driver_allowance(i);
+
+ set_xen_guest_handle(reservation.extent_start, np->rx_pfn_array);
+ reservation.nr_extents = i;
+ reservation.extent_order = 0;
+ reservation.address_bits = 0;
+ reservation.domid = DOMID_SELF;
+
+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+ /* After all PTEs have been zapped, flush the TLB. */
+ np->rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] =
+ UVMF_TLB_FLUSH|UVMF_ALL;
+
+ /* Give away a batch of pages. */
+ np->rx_mcl[i].op = __HYPERVISOR_memory_op;
+ np->rx_mcl[i].args[0] = XENMEM_decrease_reservation;
+ np->rx_mcl[i].args[1] = (unsigned long)&reservation;
+
+ /* Zap PTEs and give away pages in one big multicall. */
+ (void)HYPERVISOR_multicall(np->rx_mcl, i+1);
+
+ /* Check return status of HYPERVISOR_memory_op(). */
+ if (unlikely(np->rx_mcl[i].result != i))
+ panic("Unable to reduce memory reservation\n");
+ } else
+ if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+ &reservation) != i)
+ panic("Unable to reduce memory reservation\n");
+
+ /* Above is a suitable barrier to ensure backend will see requests. */
+ np->rx.req_prod_pvt = req_prod + i;
+ push:
+ RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify);
+ if (notify)
+ notify_remote_via_irq(np->irq);
}
+static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev,
+ struct netif_tx_request *tx)
+{
+ struct netfront_info *np = netdev_priv(dev);
+ char *data = skb->data;
+ unsigned long mfn;
+ RING_IDX prod = np->tx.req_prod_pvt;
+ int frags = skb_shinfo(skb)->nr_frags;
+ unsigned int offset = offset_in_page(data);
+ unsigned int len = skb_headlen(skb);
+ unsigned int id;
+ grant_ref_t ref;
+ int i;
+
+ while (len > PAGE_SIZE - offset) {
+ tx->size = PAGE_SIZE - offset;
+ tx->flags |= NETTXF_more_data;
+ len -= tx->size;
+ data += tx->size;
+ offset = 0;
+
+ id = get_id_from_freelist(np->tx_skbs);
+ np->tx_skbs[id] = skb_get(skb);
+ tx = RING_GET_REQUEST(&np->tx, prod++);
+ tx->id = id;
+ ref = gnttab_claim_grant_reference(&np->gref_tx_head);
+ BUG_ON((signed short)ref < 0);
+
+ mfn = virt_to_mfn(data);
+ gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
+ mfn, GNTMAP_readonly);
+
+ tx->gref = np->grant_tx_ref[id] = ref;
+ tx->offset = offset;
+ tx->size = len;
+ tx->flags = 0;
+ }
+
+ for (i = 0; i < frags; i++) {
+ skb_frag_t *frag = skb_shinfo(skb)->frags + i;
+
+ tx->flags |= NETTXF_more_data;
+
+ id = get_id_from_freelist(np->tx_skbs);
+ np->tx_skbs[id] = skb_get(skb);
+ tx = RING_GET_REQUEST(&np->tx, prod++);
+ tx->id = id;
+ ref = gnttab_claim_grant_reference(&np->gref_tx_head);
+ BUG_ON((signed short)ref < 0);
+
+ mfn = pfn_to_mfn(page_to_pfn(frag->page));
+ gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
+ mfn, GNTMAP_readonly);
+
+ tx->gref = np->grant_tx_ref[id] = ref;
+ tx->offset = frag->page_offset;
+ tx->size = frag->size;
+ tx->flags = 0;
+ }
+
+ np->tx.req_prod_pvt = prod;
+}
static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- unsigned short id;
- struct net_private *np = netdev_priv(dev);
- netif_tx_request_t *tx;
- NETIF_RING_IDX i;
+ unsigned short id;
+ struct netfront_info *np = netdev_priv(dev);
+ struct netif_tx_request *tx;
+ struct netif_extra_info *extra;
+ char *data = skb->data;
+ RING_IDX i;
+ grant_ref_t ref;
+ unsigned long mfn;
+ int notify;
+ int frags = skb_shinfo(skb)->nr_frags;
+ unsigned int offset = offset_in_page(data);
+ unsigned int len = skb_headlen(skb);
+
+ frags += (offset + len + PAGE_SIZE - 1) / PAGE_SIZE;
+ if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
+ printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
+ frags);
+ dump_stack();
+ goto drop;
+ }
+
+ spin_lock_irq(&np->tx_lock);
+
+ if (unlikely(!netif_carrier_ok(dev) ||
+ (frags > 1 && !xennet_can_sg(dev)) ||
+ netif_needs_gso(dev, skb))) {
+ spin_unlock_irq(&np->tx_lock);
+ goto drop;
+ }
+
+ i = np->tx.req_prod_pvt;
+
+ id = get_id_from_freelist(np->tx_skbs);
+ np->tx_skbs[id] = skb;
+
+ tx = RING_GET_REQUEST(&np->tx, i);
+
+ tx->id = id;
+ ref = gnttab_claim_grant_reference(&np->gref_tx_head);
+ BUG_ON((signed short)ref < 0);
+ mfn = virt_to_mfn(data);
+ gnttab_grant_foreign_access_ref(
+ ref, np->xbdev->otherend_id, mfn, GNTMAP_readonly);
+ tx->gref = np->grant_tx_ref[id] = ref;
+ tx->offset = offset;
+ tx->size = len;
+
+ tx->flags = 0;
+ extra = NULL;
+
+ if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
+ tx->flags |= NETTXF_csum_blank | NETTXF_data_validated;
+ if (skb->proto_data_valid) /* remote but checksummed? */
+ tx->flags |= NETTXF_data_validated;
+
+ if (skb_shinfo(skb)->gso_size) {
+ struct netif_extra_info *gso = (struct netif_extra_info *)
+ RING_GET_REQUEST(&np->tx, ++i);
+
+ if (extra)
+ extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE;
+ else
+ tx->flags |= NETTXF_extra_info;
+
+ gso->u.gso.size = skb_shinfo(skb)->gso_size;
+ gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4;
+ gso->u.gso.pad = 0;
+ gso->u.gso.features = 0;
+
+ gso->type = XEN_NETIF_EXTRA_TYPE_GSO;
+ gso->flags = 0;
+ extra = gso;
+ }
+
+ np->tx.req_prod_pvt = i + 1;
+
+ xennet_make_frags(skb, dev, tx);
+ tx->size = skb->len;
+
+ RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify);
+ if (notify)
+ notify_remote_via_irq(np->irq);
+
+ network_tx_buf_gc(dev);
+
+ if (!netfront_tx_slot_available(np))
+ netif_stop_queue(dev);
+
+ spin_unlock_irq(&np->tx_lock);
+
+ np->stats.tx_bytes += skb->len;
+ np->stats.tx_packets++;
+
+ return 0;
- if (unlikely(np->tx_full)) {
- printk(KERN_ALERT "%s: full queue wasn't stopped!\n", dev->name);
- netif_stop_queue(dev);
- goto drop;
- }
+ drop:
+ np->stats.tx_dropped++;
+ dev_kfree_skb(skb);
+ return 0;
+}
+
+static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs)
+{
+ struct net_device *dev = dev_id;
+ struct netfront_info *np = netdev_priv(dev);
+ unsigned long flags;
- if (unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >=
- PAGE_SIZE)) {
- struct sk_buff *nskb;
- if (unlikely((nskb = alloc_xen_skb(skb->len)) == NULL))
- goto drop;
- skb_put(nskb, skb->len);
- memcpy(nskb->data, skb->data, skb->len);
- nskb->dev = skb->dev;
- dev_kfree_skb(skb);
- skb = nskb;
- }
-
- spin_lock_irq(&np->tx_lock);
+ spin_lock_irqsave(&np->tx_lock, flags);
+ network_tx_buf_gc(dev);
+ spin_unlock_irqrestore(&np->tx_lock, flags);
- if (np->backend_state != BEST_CONNECTED) {
- spin_unlock_irq(&np->tx_lock);
- goto drop;
- }
+ if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx) &&
+ likely(netif_running(dev)))
+ netif_rx_schedule(dev);
- i = np->tx->req_prod;
+ return IRQ_HANDLED;
+}
- id = GET_ID_FROM_FREELIST(np->tx_skbs);
- np->tx_skbs[id] = skb;
+static void xennet_move_rx_slot(struct netfront_info *np, struct sk_buff *skb,
+ grant_ref_t ref)
+{
+ int new = xennet_rxidx(np->rx.req_prod_pvt);
+
+ BUG_ON(np->rx_skbs[new]);
+ np->rx_skbs[new] = skb;
+ np->grant_rx_ref[new] = ref;
+ RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->id = new;
+ RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->gref = ref;
+ np->rx.req_prod_pvt++;
+}
- tx = &np->tx->ring[MASK_NETIF_TX_IDX(i)].req;
+int xennet_get_extras(struct netfront_info *np,
+ struct netif_extra_info *extras, RING_IDX rp)
- tx->id = id;
- tx->addr = virt_to_machine(skb->data);
- tx->size = skb->len;
+{
+ struct netif_extra_info *extra;
+ RING_IDX cons = np->rx.rsp_cons;
+ int err = 0;
+
+ do {
+ struct sk_buff *skb;
+ grant_ref_t ref;
+
+ if (unlikely(cons + 1 == rp)) {
+ if (net_ratelimit())
+ WPRINTK("Missing extra info\n");
+ err = -EBADR;
+ break;
+ }
+
+ extra = (struct netif_extra_info *)
+ RING_GET_RESPONSE(&np->rx, ++cons);
+
+ if (unlikely(!extra->type ||
+ extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
+ if (net_ratelimit())
+ WPRINTK("Invalid extra type: %d\n",
+ extra->type);
+ err = -EINVAL;
+ } else
+ memcpy(&extras[extra->type - 1], extra, sizeof(*extra));
+
+ skb = xennet_get_rx_skb(np, cons);
+ ref = xennet_get_rx_ref(np, cons);
+ xennet_move_rx_slot(np, skb, ref);
+ } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
+
+ np->rx.rsp_cons = cons;
+ return err;
+}
- wmb(); /* Ensure that backend will see the request. */
- np->tx->req_prod = i + 1;
+static int xennet_get_responses(struct netfront_info *np,
+ struct netfront_rx_info *rinfo, RING_IDX rp,
+ struct sk_buff_head *list, int count)
+{
+ struct mmu_update *mmu = np->rx_mmu + count;
+ struct multicall_entry *mcl = np->rx_mcl + count;
+ struct netif_rx_response *rx = &rinfo->rx;
+ struct netif_extra_info *extras = rinfo->extras;
+ RING_IDX cons = np->rx.rsp_cons;
+ struct sk_buff *skb = xennet_get_rx_skb(np, cons);
+ grant_ref_t ref = xennet_get_rx_ref(np, cons);
+ int max = MAX_SKB_FRAGS + (rx->status <= RX_COPY_THRESHOLD);
+ int frags = 1;
+ int err = 0;
+
+ if (rx->flags & NETRXF_extra_info) {
+ err = xennet_get_extras(np, extras, rp);
+ cons = np->rx.rsp_cons;
+ }
+
+ for (;;) {
+ unsigned long mfn;
+
+ if (unlikely(rx->status < 0 ||
+ rx->offset + rx->status > PAGE_SIZE)) {
+ if (net_ratelimit())
+ WPRINTK("rx->offset: %x, size: %u\n",
+ rx->offset, rx->status);
+ err = -EINVAL;
+ }
+
+ /*
+ * This definitely indicates a bug, either in this driver or in
+ * the backend driver. In future this should flag the bad
+ * situation to the system controller to reboot the backed.
+ */
+ if (ref == GRANT_INVALID_REF) {
+ WPRINTK("Bad rx response id %d.\n", rx->id);
+ err = -EINVAL;
+ goto next;
+ }
+
+ /* Memory pressure, insufficient buffer headroom, ... */
+ if ((mfn = gnttab_end_foreign_transfer_ref(ref)) == 0) {
+ if (net_ratelimit())
+ WPRINTK("Unfulfilled rx req (id=%d, st=%d).\n",
+ rx->id, rx->status);
+ xennet_move_rx_slot(np, skb, ref);
+ err = -ENOMEM;
+ goto next;
+ }
+
+ gnttab_release_grant_reference(&np->gref_rx_head, ref);
+
+ if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+ /* Remap the page. */
+ struct page *page = skb_shinfo(skb)->frags[0].page;
+ unsigned long pfn = page_to_pfn(page);
+ void *vaddr = page_address(page);
+
+ MULTI_update_va_mapping(mcl, (unsigned long)vaddr,
+ pfn_pte_ma(mfn, PAGE_KERNEL),
+ 0);
+ mcl++;
+ mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT)
+ | MMU_MACHPHYS_UPDATE;
+ mmu->val = pfn;
+ mmu++;
+
+ set_phys_to_machine(pfn, mfn);
+ }
+
+ __skb_queue_tail(list, skb);
+
+next:
+ if (!(rx->flags & NETRXF_more_data))
+ break;
+
+ if (cons + frags == rp) {
+ if (net_ratelimit())
+ WPRINTK("Need more frags\n");
+ err = -ENOENT;
+ break;
+ }
+
+ rx = RING_GET_RESPONSE(&np->rx, cons + frags);
+ skb = xennet_get_rx_skb(np, cons + frags);
+ ref = xennet_get_rx_ref(np, cons + frags);
+ frags++;
+ }
+
+ if (unlikely(frags > max)) {
+ if (net_ratelimit())
+ WPRINTK("Too many frags\n");
+ err = -E2BIG;
+ }
+
+ return err;
+}
- network_tx_buf_gc(dev);
+static RING_IDX xennet_fill_frags(struct netfront_info *np,
+ struct sk_buff *skb,
+ struct sk_buff_head *list)
+{
+ struct skb_shared_info *shinfo = skb_shinfo(skb);
+ int nr_frags = shinfo->nr_frags;
+ RING_IDX cons = np->rx.rsp_cons;
+ skb_frag_t *frag = shinfo->frags + nr_frags;
+ struct sk_buff *nskb;
- if ((i - np->tx_resp_cons) == (NETIF_TX_RING_SIZE - 1)) {
- np->tx_full = 1;
- netif_stop_queue(dev);
- }
+ while ((nskb = __skb_dequeue(list))) {
+ struct netif_rx_response *rx =
+ RING_GET_RESPONSE(&np->rx, ++cons);
- spin_unlock_irq(&np->tx_lock);
+ frag->page = skb_shinfo(nskb)->frags[0].page;
+ frag->page_offset = rx->offset;
+ frag->size = rx->status;
- np->stats.tx_bytes += skb->len;
- np->stats.tx_packets++;
+ skb->data_len += rx->status;
- /* Only notify Xen if we really have to. */
- mb();
- if (np->tx->TX_TEST_IDX == i)
- notify_via_evtchn(np->evtchn);
+ skb_shinfo(nskb)->nr_frags = 0;
+ kfree_skb(nskb);
- return 0;
+ frag++;
+ nr_frags++;
+ }
- drop:
- np->stats.tx_dropped++;
- dev_kfree_skb(skb);
- return 0;
+ shinfo->nr_frags = nr_frags;
+ return cons;
}
-static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs)
+static int xennet_set_skb_gso(struct sk_buff *skb, struct netif_extra_info *gso)
{
- struct net_device *dev = dev_id;
- struct net_private *np = netdev_priv(dev);
- unsigned long flags;
+ if (!gso->u.gso.size) {
+ if (net_ratelimit())
+ WPRINTK("GSO size must not be zero.\n");
+ return -EINVAL;
+ }
+
+ /* Currently only TCPv4 S.O. is supported. */
+ if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) {
+ if (net_ratelimit())
+ WPRINTK("Bad GSO type %d.\n", gso->u.gso.type);
+ return -EINVAL;
+ }
+
+ skb_shinfo(skb)->gso_size = gso->u.gso.size;
+ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+
+ /* Header must be checked, and gso_segs computed. */
+ skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+ skb_shinfo(skb)->gso_segs = 0;
+
+ return 0;
+}
- spin_lock_irqsave(&np->tx_lock, flags);
- network_tx_buf_gc(dev);
- spin_unlock_irqrestore(&np->tx_lock, flags);
+static int netif_poll(struct net_device *dev, int *pbudget)
+{
+ struct netfront_info *np = netdev_priv(dev);
+ struct sk_buff *skb;
+ struct netfront_rx_info rinfo;
+ struct netif_rx_response *rx = &rinfo.rx;
+ struct netif_extra_info *extras = rinfo.extras;
+ RING_IDX i, rp;
+ struct multicall_entry *mcl;
+ int work_done, budget, more_to_do = 1;
+ struct sk_buff_head rxq;
+ struct sk_buff_head errq;
+ struct sk_buff_head tmpq;
+ unsigned long flags;
+ unsigned int len;
+ int pages_done;
+ int err;
+
+ spin_lock(&np->rx_lock);
+
+ if (unlikely(!netif_carrier_ok(dev))) {
+ spin_unlock(&np->rx_lock);
+ return 0;
+ }
+
+ skb_queue_head_init(&rxq);
+ skb_queue_head_init(&errq);
+ skb_queue_head_init(&tmpq);
+
+ if ((budget = *pbudget) > dev->quota)
+ budget = dev->quota;
+ rp = np->rx.sring->rsp_prod;
+ rmb(); /* Ensure we see queued responses up to 'rp'. */
+
+ for (i = np->rx.rsp_cons, work_done = 0, pages_done = 0;
+ (i != rp) && (work_done < budget);
+ np->rx.rsp_cons = ++i, work_done++) {
+ memcpy(rx, RING_GET_RESPONSE(&np->rx, i), sizeof(*rx));
+ memset(extras, 0, sizeof(extras));
+
+ err = xennet_get_responses(np, &rinfo, rp, &tmpq, pages_done);
+ pages_done += skb_queue_len(&tmpq);
+
+ if (unlikely(err)) {
+err:
+ i = np->rx.rsp_cons + skb_queue_len(&tmpq) - 1;
+ work_done--;
+ while ((skb = __skb_dequeue(&tmpq)))
+ __skb_queue_tail(&errq, skb);
+ np->stats.rx_errors++;
+ continue;
+ }
+
+ skb = __skb_dequeue(&tmpq);
+
+ if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) {
+ struct netif_extra_info *gso;
+ gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
+
+ if (unlikely(xennet_set_skb_gso(skb, gso))) {
+ __skb_queue_head(&tmpq, skb);
+ goto err;
+ }
+ }
+
+ skb->nh.raw = (void *)skb_shinfo(skb)->frags[0].page;
+ skb->h.raw = skb->nh.raw + rx->offset;
+
+ len = rx->status;
+ if (len > RX_COPY_THRESHOLD)
+ len = RX_COPY_THRESHOLD;
+ skb_put(skb, len);
+
+ if (rx->status > len) {
+ skb_shinfo(skb)->frags[0].page_offset =
+ rx->offset + len;
+ skb_shinfo(skb)->frags[0].size = rx->status - len;
+ skb->data_len = rx->status - len;
+ } else {
+ skb_shinfo(skb)->frags[0].page = NULL;
+ skb_shinfo(skb)->nr_frags = 0;
+ }
+
+ i = xennet_fill_frags(np, skb, &tmpq);
+ skb->truesize += skb->data_len;
+ skb->len += skb->data_len;
+
+ /*
+ * Old backends do not assert data_validated but we
+ * can infer it from csum_blank so test both flags.
+ */
+ if (rx->flags & (NETRXF_data_validated|NETRXF_csum_blank)) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->proto_data_valid = 1;
+ } else {
+ skb->ip_summed = CHECKSUM_NONE;
+ skb->proto_data_valid = 0;
+ }
+ skb->proto_csum_blank = !!(rx->flags & NETRXF_csum_blank);
+
+ np->stats.rx_packets++;
+ np->stats.rx_bytes += skb->len;
+
+ __skb_queue_tail(&rxq, skb);
+ }
+
+ /* Some pages are no longer absent... */
+ balloon_update_driver_allowance(-pages_done);
+
+ /* Do all the remapping work, and M2P updates, in one big hypercall. */
+ if (likely(pages_done)) {
+ mcl = np->rx_mcl + pages_done;
+ mcl->op = __HYPERVISOR_mmu_update;
+ mcl->args[0] = (unsigned long)np->rx_mmu;
+ mcl->args[1] = pages_done;
+ mcl->args[2] = 0;
+ mcl->args[3] = DOMID_SELF;
+ (void)HYPERVISOR_multicall(np->rx_mcl, pages_done + 1);
+ }
+
+ while ((skb = __skb_dequeue(&errq)))
+ kfree_skb(skb);
+
+ while ((skb = __skb_dequeue(&rxq)) != NULL) {
+ struct page *page = (struct page *)skb->nh.raw;
+ void *vaddr = page_address(page);
+
+ memcpy(skb->data, vaddr + (skb->h.raw - skb->nh.raw),
+ skb_headlen(skb));
+
+ if (page != skb_shinfo(skb)->frags[0].page)
+ __free_page(page);
+
+ /* Ethernet work: Delayed to here as it peeks the header. */
+ skb->protocol = eth_type_trans(skb, dev);
+
+ /* Pass it up. */
+ netif_receive_skb(skb);
+ dev->last_rx = jiffies;
+ }
+
+ /* If we get a callback with very few responses, reduce fill target. */
+ /* NB. Note exponential increase, linear decrease. */
+ if (((np->rx.req_prod_pvt - np->rx.sring->rsp_prod) >
+ ((3*np->rx_target) / 4)) &&
+ (--np->rx_target < np->rx_min_target))
+ np->rx_target = np->rx_min_target;
+
+ network_alloc_rx_buffers(dev);
+
+ *pbudget -= work_done;
+ dev->quota -= work_done;
+
+ if (work_done < budget) {
+ local_irq_save(flags);
+
+ RING_FINAL_CHECK_FOR_RESPONSES(&np->rx, more_to_do);
+ if (!more_to_do)
+ __netif_rx_complete(dev);
+
+ local_irq_restore(flags);
+ }
+
+ spin_unlock(&np->rx_lock);
+
+ return more_to_do;
+}
- if ((np->rx_resp_cons != np->rx->resp_prod) && (np->user_state == UST_OPEN))
- netif_rx_schedule(dev);
- return IRQ_HANDLED;
+static int network_close(struct net_device *dev)
+{
+ struct netfront_info *np = netdev_priv(dev);
+ netif_stop_queue(np->netdev);
+ return 0;
}
-static int netif_poll(struct net_device *dev, int *pbudget)
+static struct net_device_stats *network_get_stats(struct net_device *dev)
{
- struct net_private *np = netdev_priv(dev);
- struct sk_buff *skb, *nskb;
- netif_rx_response_t *rx;
- NETIF_RING_IDX i, rp;
- mmu_update_t *mmu = rx_mmu;
- multicall_entry_t *mcl = rx_mcl;
- int work_done, budget, more_to_do = 1;
- struct sk_buff_head rxq;
- unsigned long flags;
-
- spin_lock(&np->rx_lock);
-
- if (np->backend_state != BEST_CONNECTED) {
- spin_unlock(&np->rx_lock);
- return 0;
- }
-
- skb_queue_head_init(&rxq);
-
- if ((budget = *pbudget) > dev->quota)
- budget = dev->quota;
-
- rp = np->rx->resp_prod;
- rmb(); /* Ensure we see queued responses up to 'rp'. */
-
- for (i = np->rx_resp_cons, work_done = 0;
- (i != rp) && (work_done < budget);
- i++, work_done++) {
- rx = &np->rx->ring[MASK_NETIF_RX_IDX(i)].resp;
-
- /*
- * An error here is very odd. Usually indicates a backend bug,
- * low-memory condition, or that we didn't have reservation headroom.
- */
- if (unlikely(rx->status <= 0)) {
- if (net_ratelimit())
- printk(KERN_WARNING "Bad rx buffer (memory squeeze?).\n");
- np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id;
- wmb();
- np->rx->req_prod++;
- work_done--;
- continue;
- }
-
- skb = np->rx_skbs[rx->id];
- ADD_ID_TO_FREELIST(np->rx_skbs, rx->id);
-
- /* NB. We handle skb overflow later. */
- skb->data = skb->head + (rx->addr & ~PAGE_MASK);
- skb->len = rx->status;
- skb->tail = skb->data + skb->len;
-
- np->stats.rx_packets++;
- np->stats.rx_bytes += rx->status;
-
- /* Remap the page. */
- mmu->ptr = (rx->addr & PAGE_MASK) | MMU_MACHPHYS_UPDATE;
- mmu->val = __pa(skb->head) >> PAGE_SHIFT;
- mmu++;
- mcl->op = __HYPERVISOR_update_va_mapping;
- mcl->args[0] = (unsigned long)skb->head;
- mcl->args[1] = (rx->addr & PAGE_MASK) | __PAGE_KERNEL;
- mcl->args[2] = 0;
- mcl++;
-
- phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] =
- rx->addr >> PAGE_SHIFT;
-
- __skb_queue_tail(&rxq, skb);
- }
-
- /* Some pages are no longer absent... */
- balloon_update_driver_allowance(-work_done);
-
- /* Do all the remapping work, and M->P updates, in one big hypercall. */
- if (likely((mcl - rx_mcl) != 0)) {
- mcl->op = __HYPERVISOR_mmu_update;
- mcl->args[0] = (unsigned long)rx_mmu;
- mcl->args[1] = mmu - rx_mmu;
- mcl->args[2] = 0;
- mcl->args[3] = DOMID_SELF;
- mcl++;
- (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
- }
-
- while ((skb = __skb_dequeue(&rxq)) != NULL) {
- /*
- * Enough room in skbuff for the data we were passed? Also, Linux
- * expects at least 16 bytes headroom in each receive buffer.
- */
- if (unlikely(skb->tail > skb->end) ||
- unlikely((skb->data - skb->head) < 16)) {
- nskb = NULL;
-
- /* Only copy the packet if it fits in the current MTU. */
- if (skb->len <= (dev->mtu + ETH_HLEN)) {
- if ((skb->tail > skb->end) && net_ratelimit())
- printk(KERN_INFO "Received packet needs %d bytes more "
- "headroom.\n", skb->tail - skb->end);
-
- if ((nskb = alloc_xen_skb(skb->len + 2)) != NULL) {
- skb_reserve(nskb, 2);
- skb_put(nskb, skb->len);
- memcpy(nskb->data, skb->data, skb->len);
- nskb->dev = skb->dev;
- }
- }
- else if (net_ratelimit())
- printk(KERN_INFO "Received packet too big for MTU "
- "(%d > %d)\n", skb->len - ETH_HLEN, dev->mtu);
-
- /* Reinitialise and then destroy the old skbuff. */
- skb->len = 0;
- skb->tail = skb->data;
- init_skb_shinfo(skb);
- dev_kfree_skb(skb);
-
- /* Switch old for new, if we copied the buffer. */
- if ((skb = nskb) == NULL)
- continue;
- }
-
- /* Set the shared-info area, which is hidden behind the real data. */
- init_skb_shinfo(skb);
-
- /* Ethernet-specific work. Delayed to here as it peeks the header. */
- skb->protocol = eth_type_trans(skb, dev);
-
- /* Pass it up. */
- netif_receive_skb(skb);
- dev->last_rx = jiffies;
- }
-
- np->rx_resp_cons = i;
-
- /* If we get a callback with very few responses, reduce fill target. */
- /* NB. Note exponential increase, linear decrease. */
- if (((np->rx->req_prod - np->rx->resp_prod) > ((3*np->rx_target) / 4)) &&
- (--np->rx_target < RX_MIN_TARGET))
- np->rx_target = RX_MIN_TARGET;
-
- network_alloc_rx_buffers(dev);
-
- *pbudget -= work_done;
- dev->quota -= work_done;
-
- if (work_done < budget) {
- local_irq_save(flags);
-
- np->rx->event = i + 1;
-
- /* Deal with hypervisor racing our resetting of rx_event. */
- mb();
- if (np->rx->resp_prod == i) {
- __netif_rx_complete(dev);
- more_to_do = 0;
- }
-
- local_irq_restore(flags);
- }
-
- spin_unlock(&np->rx_lock);
-
- return more_to_do;
+ struct netfront_info *np = netdev_priv(dev);
+ return &np->stats;
}
+static int xennet_change_mtu(struct net_device *dev, int mtu)
+{
+ int max = xennet_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN;
-static int network_close(struct net_device *dev)
+ if (mtu > max)
+ return -EINVAL;
+ dev->mtu = mtu;
+ return 0;
+}
+
+static int xennet_set_sg(struct net_device *dev, u32 data)
{
- struct net_private *np = netdev_priv(dev);
- np->user_state = UST_CLOSED;
- netif_stop_queue(np->dev);
- return 0;
+ if (data) {
+ struct netfront_info *np = netdev_priv(dev);
+ int val;
+
+ if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg",
+ "%d", &val) < 0)
+ val = 0;
+ if (!val)
+ return -ENOSYS;
+ } else if (dev->mtu > ETH_DATA_LEN)
+ dev->mtu = ETH_DATA_LEN;
+
+ return ethtool_op_set_sg(dev, data);
}
+static int xennet_set_tso(struct net_device *dev, u32 data)
+{
+ if (data) {
+ struct netfront_info *np = netdev_priv(dev);
+ int val;
+
+ if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
+ "feature-gso-tcpv4", "%d", &val) < 0)
+ val = 0;
+ if (!val)
+ return -ENOSYS;
+ }
+
+ return ethtool_op_set_tso(dev, data);
+}
-static struct net_device_stats *network_get_stats(struct net_device *dev)
+static void xennet_set_features(struct net_device *dev)
{
- struct net_private *np = netdev_priv(dev);
- return &np->stats;
+ /* Turn off all GSO bits except ROBUST. */
+ dev->features &= (1 << NETIF_F_GSO_SHIFT) - 1;
+ dev->features |= NETIF_F_GSO_ROBUST;
+ xennet_set_sg(dev, 0);
+
+ if (!xennet_set_sg(dev, 1))
+ xennet_set_tso(dev, 1);
}
+static void network_connect(struct net_device *dev)
+{
+ struct netfront_info *np = netdev_priv(dev);
+ int i, requeue_idx;
+ struct sk_buff *skb;
+ grant_ref_t ref;
+
+ xennet_set_features(dev);
+
+ spin_lock_irq(&np->tx_lock);
+ spin_lock(&np->rx_lock);
+
+ /*
+ * Recovery procedure:
+ * NB. Freelist index entries are always going to be less than
+ * PAGE_OFFSET, whereas pointers to skbs will always be equal or
+ * greater than PAGE_OFFSET: we use this property to distinguish
+ * them.
+ */
+
+ /* Step 1: Discard all pending TX packet fragments. */
+ for (requeue_idx = 0, i = 1; i <= NET_TX_RING_SIZE; i++) {
+ if ((unsigned long)np->tx_skbs[i] < PAGE_OFFSET)
+ continue;
+
+ skb = np->tx_skbs[i];
+ gnttab_end_foreign_access_ref(
+ np->grant_tx_ref[i], GNTMAP_readonly);
+ gnttab_release_grant_reference(
+ &np->gref_tx_head, np->grant_tx_ref[i]);
+ np->grant_tx_ref[i] = GRANT_INVALID_REF;
+ add_id_to_freelist(np->tx_skbs, i);
+ dev_kfree_skb_irq(skb);
+ }
+
+ /* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */
+ for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) {
+ if (!np->rx_skbs[i])
+ continue;
+
+ skb = np->rx_skbs[requeue_idx] = xennet_get_rx_skb(np, i);
+ ref = np->grant_rx_ref[requeue_idx] = xennet_get_rx_ref(np, i);
+
+ gnttab_grant_foreign_transfer_ref(
+ ref, np->xbdev->otherend_id,
+ page_to_pfn(skb_shinfo(skb)->frags->page));
+
+ RING_GET_REQUEST(&np->rx, requeue_idx)->gref = ref;
+ RING_GET_REQUEST(&np->rx, requeue_idx)->id = requeue_idx;
+
+ requeue_idx++;
+ }
+
+ np->rx.req_prod_pvt = requeue_idx;
+
+ /*
+ * Step 3: All public and private state should now be sane. Get
+ * ready to start sending and receiving packets and give the driver
+ * domain a kick because we've probably just requeued some
+ * packets.
+ */
+ netif_carrier_on(dev);
+ notify_remote_via_irq(np->irq);
+ network_tx_buf_gc(dev);
+ network_alloc_rx_buffers(dev);
+
+ spin_unlock(&np->rx_lock);
+ spin_unlock_irq(&np->tx_lock);
+}
-static void network_connect(struct net_device *dev,
- netif_fe_interface_status_t *status)
+static void netif_uninit(struct net_device *dev)
{
- struct net_private *np;
- int i, requeue_idx;
- netif_tx_request_t *tx;
-
- np = netdev_priv(dev);
- spin_lock_irq(&np->tx_lock);
- spin_lock(&np->rx_lock);
-
- /* Recovery procedure: */
-
- /* Step 1: Reinitialise variables. */
- np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0;
- np->rx->event = np->tx->event = 1;
-
- /* Step 2: Rebuild the RX and TX ring contents.
- * NB. We could just free the queued TX packets now but we hope
- * that sending them out might do some good. We have to rebuild
- * the RX ring because some of our pages are currently flipped out
- * so we can't just free the RX skbs.
- * NB2. Freelist index entries are always going to be less than
- * __PAGE_OFFSET, whereas pointers to skbs will always be equal or
- * greater than __PAGE_OFFSET: we use this property to distinguish
- * them.
- */
-
- /* Rebuild the TX buffer freelist and the TX ring itself.
- * NB. This reorders packets. We could keep more private state
- * to avoid this but maybe it doesn't matter so much given the
- * interface has been down.
- */
- for (requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++) {
- if ((unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET) {
- struct sk_buff *skb = np->tx_skbs[i];
-
- tx = &np->tx->ring[requeue_idx++].req;
-
- tx->id = i;
- tx->addr = virt_to_machine(skb->data);
- tx->size = skb->len;
-
- np->stats.tx_bytes += skb->len;
- np->stats.tx_packets++;
- }
- }
- wmb();
- np->tx->req_prod = requeue_idx;
-
- /* Rebuild the RX buffer freelist and the RX ring itself. */
- for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++)
- if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET)
- np->rx->ring[requeue_idx++].req.id = i;
- wmb();
- np->rx->req_prod = requeue_idx;
-
- /* Step 3: All public and private state should now be sane. Get
- * ready to start sending and receiving packets and give the driver
- * domain a kick because we've probably just requeued some
- * packets.
- */
- np->backend_state = BEST_CONNECTED;
- wmb();
- notify_via_evtchn(status->evtchn);
- network_tx_buf_gc(dev);
-
- if (np->user_state == UST_OPEN)
- netif_start_queue(dev);
-
- spin_unlock(&np->rx_lock);
- spin_unlock_irq(&np->tx_lock);
+ struct netfront_info *np = netdev_priv(dev);
+ gnttab_free_grant_references(np->gref_tx_head);
+ gnttab_free_grant_references(np->gref_rx_head);
}
-static void vif_show(struct net_private *np)
+static struct ethtool_ops network_ethtool_ops =
{
-#if DEBUG
- if (np) {
- IPRINTK("<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
*/
-static int create_netdev(int handle, struct net_device **val)
+static struct net_device * __devinit create_netdev(int handle,
+ struct xenbus_device *dev)
{
- int i, err = 0;
- struct net_device *dev = NULL;
- struct net_private *np = NULL;
-
- if ((dev = alloc_etherdev(sizeof(struct net_private))) == NULL) {
- printk(KERN_WARNING "%s> alloc_etherdev failed.\n", __FUNCTION__);
- err = -ENOMEM;
- goto exit;
- }
-
- np = netdev_priv(dev);
- np->backend_state = BEST_CLOSED;
- np->user_state = UST_CLOSED;
- np->handle = handle;
-
- spin_lock_init(&np->tx_lock);
- spin_lock_init(&np->rx_lock);
-
- skb_queue_head_init(&np->rx_batch);
- np->rx_target = RX_MIN_TARGET;
-
- /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
- for (i = 0; i <= NETIF_TX_RING_SIZE; i++)
- np->tx_skbs[i] = (void *)(i+1);
- for (i = 0; i <= NETIF_RX_RING_SIZE; i++)
- np->rx_skbs[i] = (void *)(i+1);
-
- dev->open = network_open;
- dev->hard_start_xmit = network_start_xmit;
- dev->stop = network_close;
- dev->get_stats = network_get_stats;
- dev->poll = netif_poll;
- dev->weight = 64;
-
- if ((err = register_netdev(dev)) != 0) {
- printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err);
- goto exit;
- }
- np->dev = dev;
- list_add(&np->list, &dev_list);
-
- exit:
- if ((err != 0) && (dev != NULL ))
- kfree(dev);
- else if (val != NULL)
- *val = dev;
- return err;
+ int i, err = 0;
+ struct net_device *netdev = NULL;
+ struct netfront_info *np = NULL;
+
+ netdev = alloc_etherdev(sizeof(struct netfront_info));
+ if (!netdev) {
+ printk(KERN_WARNING "%s> alloc_etherdev failed.\n",
+ __FUNCTION__);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ np = netdev_priv(netdev);
+ np->handle = handle;
+ np->xbdev = dev;
+
+ netif_carrier_off(netdev);
+
+ spin_lock_init(&np->tx_lock);
+ spin_lock_init(&np->rx_lock);
+
+ skb_queue_head_init(&np->rx_batch);
+ np->rx_target = RX_DFL_MIN_TARGET;
+ np->rx_min_target = RX_DFL_MIN_TARGET;
+ np->rx_max_target = RX_MAX_TARGET;
+
+ init_timer(&np->rx_refill_timer);
+ np->rx_refill_timer.data = (unsigned long)netdev;
+ np->rx_refill_timer.function = rx_refill_timeout;
+
+ /* Initialise {tx,rx}_skbs as a free chain containing every entry. */
+ for (i = 0; i <= NET_TX_RING_SIZE; i++) {
+ np->tx_skbs[i] = (void *)((unsigned long) i+1);
+ np->grant_tx_ref[i] = GRANT_INVALID_REF;
+ }
+
+ for (i = 0; i < NET_RX_RING_SIZE; i++) {
+ np->rx_skbs[i] = NULL;
+ np->grant_rx_ref[i] = GRANT_INVALID_REF;
+ }
+
+ /* A grant for every tx ring slot */
+ if (gnttab_alloc_grant_references(TX_MAX_TARGET,
+ &np->gref_tx_head) < 0) {
+ printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
+ err = -ENOMEM;
+ goto exit;
+ }
+ /* A grant for every rx ring slot */
+ if (gnttab_alloc_grant_references(RX_MAX_TARGET,
+ &np->gref_rx_head) < 0) {
+ printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
+ err = -ENOMEM;
+ goto exit_free_tx;
+ }
+
+ netdev->open = network_open;
+ netdev->hard_start_xmit = network_start_xmit;
+ netdev->stop = network_close;
+ netdev->get_stats = network_get_stats;
+ netdev->poll = netif_poll;
+ netdev->set_multicast_list = network_set_multicast_list;
+ netdev->uninit = netif_uninit;
+ netdev->change_mtu = xennet_change_mtu;
+ netdev->weight = 64;
+ netdev->features = NETIF_F_IP_CSUM;
+
+ SET_ETHTOOL_OPS(netdev, &network_ethtool_ops);
+ SET_MODULE_OWNER(netdev);
+ SET_NETDEV_DEV(netdev, &dev->dev);
+
+ err = register_netdev(netdev);
+ if (err) {
+ printk(KERN_WARNING "%s> register_netdev err=%d\n",
+ __FUNCTION__, err);
+ goto exit_free_rx;
+ }
+
+ err = xennet_sysfs_addif(netdev);
+ if (err) {
+ /* This can be non-fatal: it only means no tuning parameters */
+ printk(KERN_WARNING "%s> add sysfs failed err=%d\n",
+ __FUNCTION__, err);
+ }
+
+ np->netdev = netdev;
+
+ return netdev;
+
+
+ exit_free_rx:
+ gnttab_free_grant_references(np->gref_rx_head);
+ exit_free_tx:
+ gnttab_free_grant_references(np->gref_tx_head);
+ exit:
+ free_netdev(netdev);
+ return ERR_PTR(err);
}
-/* Get the target interface for a status message.
- * Creates the interface when it makes sense.
- * The returned interface may be null when there is no error.
- *
- * @param status status message
- * @param np return parameter for interface state
- * @return 0 on success, error code otherwise
+/*
+ * We use this notifier to send out a fake ARP reply to reset switches and
+ * router ARP caches when an IP interface is brought up on a VIF.
*/
-static int
-target_vif(netif_fe_interface_status_t *status, struct net_private **np)
+static int
+inetdev_notify(struct notifier_block *this, unsigned long event, void *ptr)
{
- int err = 0;
- struct net_device *dev;
-
- DPRINTK("> handle=%d\n", status->handle);
- if (status->handle < 0) {
- err = -EINVAL;
- goto exit;
- }
-
- if ((dev = find_dev_by_handle(status->handle)) != NULL)
- goto exit;
-
- if (status->status == NETIF_INTERFACE_STATUS_CLOSED)
- goto exit;
- if (status->status == NETIF_INTERFACE_STATUS_CHANGED)
- goto exit;
-
- /* It's a new interface in a good state - create it. */
- DPRINTK("> create device...\n");
- if ((err = create_netdev(status->handle, &dev)) != 0)
- goto exit;
-
- netctrl.interface_n++;
-
- exit:
- if (np != NULL)
- *np = ((dev && !err) ? netdev_priv(dev) : NULL);
- DPRINTK("< err=%d\n", err);
- return err;
+ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
+ struct net_device *dev = ifa->ifa_dev->dev;
+
+ /* UP event and is it one of our devices? */
+ if (event == NETDEV_UP && dev->open == network_open)
+ (void)send_fake_arp(dev);
+
+ return NOTIFY_DONE;
}
-/* Handle an interface status message. */
-static void netif_interface_status(netif_fe_interface_status_t *status)
-{
- int err = 0;
- struct net_private *np = NULL;
-
- DPRINTK("> status=%s handle=%d\n",
- status_name[status->status], status->handle);
-
- if ((err = target_vif(status, &np)) != 0) {
- WPRINTK("Invalid netif: handle=%u\n", status->handle);
- return;
- }
-
- if (np == NULL) {
- DPRINTK("> no vif\n");
- return;
- }
-
- switch (status->status) {
- case NETIF_INTERFACE_STATUS_CLOSED:
- switch (np->backend_state) {
- case BEST_CLOSED:
- case BEST_DISCONNECTED:
- case BEST_CONNECTED:
- vif_close(np);
- break;
- }
- break;
-
- case NETIF_INTERFACE_STATUS_DISCONNECTED:
- switch (np->backend_state) {
- case BEST_CLOSED:
- vif_disconnect(np);
- break;
- case BEST_DISCONNECTED:
- case BEST_CONNECTED:
- vif_reset(np);
- break;
- }
- break;
-
- case NETIF_INTERFACE_STATUS_CONNECTED:
- switch (np->backend_state) {
- case BEST_CLOSED:
- WPRINTK("Unexpected netif status %s in state %s\n",
- status_name[status->status],
- be_state_name[np->backend_state]);
- vif_disconnect(np);
- vif_connect(np, status);
- break;
- case BEST_DISCONNECTED:
- vif_connect(np, status);
- break;
- }
- break;
-
- case NETIF_INTERFACE_STATUS_CHANGED:
- /*
- * The domain controller is notifying us that a device has been
- * added or removed.
- */
- break;
- default:
- WPRINTK("Invalid netif status code %d\n", status->status);
- break;
- }
+/* ** Close down ** */
- vif_show(np);
-}
-/*
- * Initialize the network control interface.
+/**
+ * Handle the change of state of the backend to Closing. We must delete our
+ * device-layer structures now, to ensure that writes are flushed through to
+ * the backend. Once is this done, we can switch to Closed in
+ * acknowledgement.
*/
-static void netif_driver_status(netif_fe_driver_status_t *status)
+static void netfront_closing(struct xenbus_device *dev)
{
- netctrl.up = status->status;
- netctrl_connected_count();
+ struct netfront_info *info = dev->dev.driver_data;
+
+ DPRINTK("netfront_closing: %s removed\n", dev->nodename);
+
+ close_netdev(info);
+
+ xenbus_switch_state(dev, XenbusStateClosed);
}
-/* Receive handler for control messages. */
-static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
-{
- switch (msg->subtype) {
- case CMSG_NETIF_FE_INTERFACE_STATUS:
- netif_interface_status((netif_fe_interface_status_t *) &msg->msg[0]);
- break;
+static int __devexit netfront_remove(struct xenbus_device *dev)
+{
+ struct netfront_info *info = dev->dev.driver_data;
- case CMSG_NETIF_FE_DRIVER_STATUS:
- netif_driver_status((netif_fe_driver_status_t *) &msg->msg[0]);
- break;
+ DPRINTK("%s\n", dev->nodename);
- default:
- msg->length = 0;
- break;
- }
+ netif_disconnect_backend(info);
+ free_netdev(info->netdev);
- ctrl_if_send_response(msg);
+ return 0;
}
-#if 1
-/* Wait for all interfaces to be connected.
- *
- * This works OK, but we'd like to use the probing mode (see below).
- */
-static int probe_interfaces(void)
+static void close_netdev(struct netfront_info *info)
{
- int err = 0, conn = 0;
- int wait_i, wait_n = 100;
+ del_timer_sync(&info->rx_refill_timer);
- DPRINTK(">\n");
+ xennet_sysfs_delif(info->netdev);
+ unregister_netdev(info->netdev);
+}
- for (wait_i = 0; wait_i < wait_n; wait_i++) {
- DPRINTK("> wait_i=%d\n", wait_i);
- conn = netctrl_connected();
- if(conn) break;
- DPRINTK("> schedule_timeout...\n");
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(10);
- }
- DPRINTK("> wait finished...\n");
- if (conn <= 0) {
- err = netctrl_err(-ENETDOWN);
- WPRINTK("Failed to connect all virtual interfaces: err=%d\n", err);
- }
+static void netif_disconnect_backend(struct netfront_info *info)
+{
+ /* Stop old i/f to prevent errors whilst we rebuild the state. */
+ spin_lock_irq(&info->tx_lock);
+ spin_lock(&info->rx_lock);
+ netif_carrier_off(info->netdev);
+ spin_unlock(&info->rx_lock);
+ spin_unlock_irq(&info->tx_lock);
+
+ if (info->irq)
+ unbind_from_irqhandler(info->irq, info->netdev);
+ info->evtchn = info->irq = 0;
+
+ end_access(info->tx_ring_ref, info->tx.sring);
+ end_access(info->rx_ring_ref, info->rx.sring);
+ info->tx_ring_ref = GRANT_INVALID_REF;
+ info->rx_ring_ref = GRANT_INVALID_REF;
+ info->tx.sring = NULL;
+ info->rx.sring = NULL;
+}
- DPRINTK("< err=%d\n", err);
- return err;
-}
-#else
-/* Probe for interfaces until no more are found.
- *
- * This is the mode we'd like to use, but at the moment it panics the kernel.
-*/
-static int probe_interfaces(void)
+static void netif_free(struct netfront_info *info)
{
- int err = 0;
- int wait_i, wait_n = 100;
- ctrl_msg_t cmsg = {
- .type = CMSG_NETIF_FE,
- .subtype = CMSG_NETIF_FE_INTERFACE_STATUS,
- .length = sizeof(netif_fe_interface_status_t),
- };
- netif_fe_interface_status_t msg = {};
- ctrl_msg_t rmsg = {};
- netif_fe_interface_status_t *reply = (void*)rmsg.msg;
- int state = TASK_UNINTERRUPTIBLE;
- u32 query = -1;
-
- DPRINTK(">\n");
-
- netctrl.interface_n = 0;
- for (wait_i = 0; wait_i < wait_n; wait_i++) {
- DPRINTK("> wait_i=%d query=%d\n", wait_i, query);
- msg.handle = query;
- memcpy(cmsg.msg, &msg, sizeof(msg));
- DPRINTK("> set_current_state...\n");
- set_current_state(state);
- DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply);
- DPRINTK("> sending...\n");
- err = ctrl_if_send_message_and_get_response(&cmsg, &rmsg, state);
- DPRINTK("> err=%d\n", err);
- if(err) goto exit;
- DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply);
- if((int)reply->handle < 0) {
- // No more interfaces.
- break;
- }
- query = -reply->handle - 2;
- DPRINTK(">netif_interface_status ...\n");
- netif_interface_status(reply);
- }
-
- exit:
- if (err) {
- err = netctrl_err(-ENETDOWN);
- WPRINTK("Connecting virtual network interfaces failed: err=%d\n", err);
- }
-
- DPRINTK("< err=%d\n", err);
- return err;
+ close_netdev(info);
+ netif_disconnect_backend(info);
+ free_netdev(info->netdev);
}
-#endif
-/*
- * We use this notifier to send out a fake ARP reply to reset switches and
- * router ARP caches when an IP interface is brought up on a VIF.
- */
-static int
-inetdev_notify(struct notifier_block *this, unsigned long event, void *ptr)
+static void end_access(int ref, void *page)
{
- struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
- struct net_device *dev = ifa->ifa_dev->dev;
- struct list_head *ent;
- struct net_private *np;
-
- if (event != NETDEV_UP)
- goto out;
-
- list_for_each (ent, &dev_list) {
- np = list_entry(ent, struct net_private, list);
- if (np->dev == dev)
- (void)send_fake_arp(dev);
- }
-
- out:
- return NOTIFY_DONE;
+ if (ref != GRANT_INVALID_REF)
+ gnttab_end_foreign_access(ref, 0, (unsigned long)page);
}
+
+/* ** Driver registration ** */
+
+
+static struct xenbus_device_id netfront_ids[] = {
+ { "vif" },
+ { "" }
+};
+
+
+static struct xenbus_driver netfront = {
+ .name = "vif",
+ .owner = THIS_MODULE,
+ .ids = netfront_ids,
+ .probe = netfront_probe,
+ .remove = __devexit_p(netfront_remove),
+ .resume = netfront_resume,
+ .otherend_changed = backend_changed,
+};
+
+
static struct notifier_block notifier_inetdev = {
- .notifier_call = inetdev_notify,
- .next = NULL,
- .priority = 0
+ .notifier_call = inetdev_notify,
+ .next = NULL,
+ .priority = 0
};
static int __init netif_init(void)
{
- int err = 0;
-
- if (xen_start_info.flags & SIF_INITDOMAIN)
- return 0;
-
- IPRINTK("Initialising virtual ethernet driver.\n");
- INIT_LIST_HEAD(&dev_list);
- (void)register_inetaddr_notifier(¬ifier_inetdev);
- netctrl_init();
- (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx,
- CALLBACK_IN_BLOCKING_CONTEXT);
- send_driver_status(1);
- err = probe_interfaces();
- if (err)
- ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx);
-
- DPRINTK("< err=%d\n", err);
- return err;
-}
+ if (!is_running_on_xen())
+ return -ENODEV;
-static void vif_suspend(struct net_private *np)
-{
- /* Avoid having tx/rx stuff happen until we're ready. */
- free_irq(np->irq, np->dev);
- unbind_evtchn_from_irq(np->evtchn);
-}
+ if (xen_start_info->flags & SIF_INITDOMAIN)
+ return 0;
-static void vif_resume(struct net_private *np)
-{
- /*
- * Connect regardless of whether IFF_UP flag set.
- * Stop bad things from happening until we're back up.
- */
- np->backend_state = BEST_DISCONNECTED;
- memset(np->tx, 0, PAGE_SIZE);
- memset(np->rx, 0, PAGE_SIZE);
-
- send_interface_connect(np);
-}
+ IPRINTK("Initialising virtual ethernet driver.\n");
-void netif_suspend(void)
-{
- struct list_head *ent;
- struct net_private *np;
-
- list_for_each (ent, &dev_list) {
- np = list_entry(ent, struct net_private, list);
- vif_suspend(np);
- }
+ (void)register_inetaddr_notifier(¬ifier_inetdev);
+
+ return xenbus_register_frontend(&netfront);
}
+module_init(netif_init);
+
-void netif_resume(void)
+static void __exit netif_exit(void)
{
- struct list_head *ent;
- struct net_private *np;
+ unregister_inetaddr_notifier(¬ifier_inetdev);
- list_for_each (ent, &dev_list) {
- np = list_entry(ent, struct net_private, list);
- vif_resume(np);
- }
+ return xenbus_unregister_driver(&netfront);
}
+module_exit(netif_exit);
-
-module_init(netif_init);
-
+MODULE_LICENSE("Dual BSD/GPL");
-obj-y := privcmd.o
+obj-$(CONFIG_XEN_PRIVCMD) := privcmd.o
#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-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 *capabilities_intf;
+
+#define NR_HYPERCALLS 64
+static DECLARE_BITMAP(hypercall_permission_map, NR_HYPERCALLS);
static int privcmd_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long data)
+ unsigned int cmd, unsigned long data)
{
- int ret = -ENOSYS;
+ int ret = -ENOSYS;
+ void __user *udata = (void __user *) data;
- switch ( cmd )
- {
- case IOCTL_PRIVCMD_HYPERCALL:
- {
- privcmd_hypercall_t hypercall;
+ switch (cmd) {
+ case IOCTL_PRIVCMD_HYPERCALL: {
+ privcmd_hypercall_t hypercall;
- if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
- return -EFAULT;
+ if (copy_from_user(&hypercall, udata, sizeof(hypercall)))
+ return -EFAULT;
+
+ /* Check hypercall number for validity. */
+ if (hypercall.op >= NR_HYPERCALLS)
+ return -EINVAL;
+ if (!test_bit(hypercall.op, hypercall_permission_map))
+ return -EINVAL;
#if defined(__i386__)
- __asm__ __volatile__ (
- "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
- "movl 4(%%eax),%%ebx ;"
- "movl 8(%%eax),%%ecx ;"
- "movl 12(%%eax),%%edx ;"
- "movl 16(%%eax),%%esi ;"
- "movl 20(%%eax),%%edi ;"
- "movl (%%eax),%%eax ;"
- TRAP_INSTR "; "
- "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
- : "=a" (ret) : "0" (&hypercall) : "memory" );
+ __asm__ __volatile__ (
+ "pushl %%ebx; pushl %%ecx; pushl %%edx; "
+ "pushl %%esi; pushl %%edi; "
+ "movl 8(%%eax),%%ebx ;"
+ "movl 16(%%eax),%%ecx ;"
+ "movl 24(%%eax),%%edx ;"
+ "movl 32(%%eax),%%esi ;"
+ "movl 40(%%eax),%%edi ;"
+ "movl (%%eax),%%eax ;"
+ "shll $5,%%eax ;"
+ "addl $hypercall_page,%%eax ;"
+ "call *%%eax ;"
+ "popl %%edi; popl %%esi; popl %%edx; "
+ "popl %%ecx; popl %%ebx"
+ : "=a" (ret) : "0" (&hypercall) : "memory" );
#elif defined (__x86_64__)
- __asm__ __volatile__ (
- "movq %5,%%r10; movq %6,%%r8;" TRAP_INSTR
- : "=a" (ret)
- : "a" ((unsigned long)hypercall.op),
- "D" ((unsigned long)hypercall.arg[0]),
- "S" ((unsigned long)hypercall.arg[1]),
- "d" ((unsigned long)hypercall.arg[2]),
- "g" ((unsigned long)hypercall.arg[3]),
- "g" ((unsigned long)hypercall.arg[4])
- : "r11","rcx","r8","r10","memory");
+ {
+ long ign1, ign2, ign3;
+ __asm__ __volatile__ (
+ "movq %8,%%r10; movq %9,%%r8;"
+ "shlq $5,%%rax ;"
+ "addq $hypercall_page,%%rax ;"
+ "call *%%rax"
+ : "=a" (ret), "=D" (ign1),
+ "=S" (ign2), "=d" (ign3)
+ : "0" ((unsigned long)hypercall.op),
+ "1" ((unsigned long)hypercall.arg[0]),
+ "2" ((unsigned long)hypercall.arg[1]),
+ "3" ((unsigned long)hypercall.arg[2]),
+ "g" ((unsigned long)hypercall.arg[3]),
+ "g" ((unsigned long)hypercall.arg[4])
+ : "r8", "r10", "memory" );
+ }
+#elif defined (__ia64__)
+ __asm__ __volatile__ (
+ ";; mov r14=%2; mov r15=%3; "
+ "mov r16=%4; mov r17=%5; mov r18=%6;"
+ "mov r2=%1; break 0x1000;; mov %0=r8 ;;"
+ : "=r" (ret)
+ : "r" (hypercall.op),
+ "r" (hypercall.arg[0]),
+ "r" (hypercall.arg[1]),
+ "r" (hypercall.arg[2]),
+ "r" (hypercall.arg[3]),
+ "r" (hypercall.arg[4])
+ : "r14","r15","r16","r17","r18","r2","r8","memory");
#endif
- }
- break;
-
- case IOCTL_PRIVCMD_INITDOMAIN_EVTCHN:
- {
- extern int initdom_ctrlif_domcontroller_port;
- ret = initdom_ctrlif_domcontroller_port;
- }
- break;
-
+ }
+ break;
+
#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
- case IOCTL_PRIVCMD_MMAP:
- {
+ case IOCTL_PRIVCMD_MMAP: {
#define PRIVCMD_MMAP_SZ 32
- privcmd_mmap_t mmapcmd;
- privcmd_mmap_entry_t msg[PRIVCMD_MMAP_SZ], *p;
- int i, rc;
-
- if ( copy_from_user(&mmapcmd, (void *)data, sizeof(mmapcmd)) )
- return -EFAULT;
+ privcmd_mmap_t mmapcmd;
+ privcmd_mmap_entry_t msg[PRIVCMD_MMAP_SZ];
+ privcmd_mmap_entry_t __user *p;
+ int i, rc;
- p = mmapcmd.entry;
+ if (copy_from_user(&mmapcmd, udata, sizeof(mmapcmd)))
+ return -EFAULT;
- for (i=0; 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
- case IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN:
- {
- unsigned long m2pv = (unsigned long)machine_to_phys_mapping;
- pgd_t *pgd = pgd_offset_k(m2pv);
- pud_t *pud = pud_offset(pgd, m2pv);
- pmd_t *pmd = pmd_offset(pud, m2pv);
- unsigned long m2p_start_mfn = (*(unsigned long *)pmd) >> PAGE_SHIFT;
- ret = put_user(m2p_start_mfn, (unsigned long *)data) ? -EFAULT: 0;
- }
- break;
-
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
}
+#ifndef HAVE_ARCH_PRIVCMD_MMAP
static int privcmd_mmap(struct file * file, struct vm_area_struct * vma)
{
- /* DONTCOPY is essential for Xen as copy_page_range is broken. */
- vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
+ /* DONTCOPY is essential for Xen as copy_page_range is broken. */
+ vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
- return 0;
+ return 0;
}
+#endif
static struct file_operations privcmd_file_ops = {
- ioctl : privcmd_ioctl,
- mmap: privcmd_mmap
+ .ioctl = privcmd_ioctl,
+ .mmap = privcmd_mmap,
};
-
-static int __init privcmd_init(void)
+static int capabilities_read(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
{
- if ( !(xen_start_info.flags & SIF_PRIVILEGED) )
- return 0;
+ int len = 0;
+ *page = 0;
- privcmd_intf = create_xen_proc_entry("privcmd", 0400);
- if ( privcmd_intf != NULL )
- privcmd_intf->proc_fops = &privcmd_file_ops;
+ if (xen_start_info->flags & SIF_INITDOMAIN)
+ len = sprintf( page, "control_d\n" );
- return 0;
+ *eof = 1;
+ return len;
+}
+
+static int __init privcmd_init(void)
+{
+ if (!is_running_on_xen())
+ return -ENODEV;
+
+ /* Set of hypercalls that privileged applications may execute. */
+ set_bit(__HYPERVISOR_acm_op, hypercall_permission_map);
+ set_bit(__HYPERVISOR_dom0_op, hypercall_permission_map);
+ set_bit(__HYPERVISOR_event_channel_op, hypercall_permission_map);
+ set_bit(__HYPERVISOR_memory_op, hypercall_permission_map);
+ set_bit(__HYPERVISOR_mmu_update, hypercall_permission_map);
+ set_bit(__HYPERVISOR_mmuext_op, hypercall_permission_map);
+ set_bit(__HYPERVISOR_xen_version, hypercall_permission_map);
+ set_bit(__HYPERVISOR_sched_op, hypercall_permission_map);
+ set_bit(__HYPERVISOR_sched_op_compat, hypercall_permission_map);
+ set_bit(__HYPERVISOR_event_channel_op_compat,
+ hypercall_permission_map);
+ set_bit(__HYPERVISOR_hvm_op, hypercall_permission_map);
+
+ privcmd_intf = create_xen_proc_entry("privcmd", 0400);
+ if (privcmd_intf != NULL)
+ privcmd_intf->proc_fops = &privcmd_file_ops;
+
+ capabilities_intf = create_xen_proc_entry("capabilities", 0400 );
+ if (capabilities_intf != NULL)
+ capabilities_intf->read_proc = capabilities_read;
+
+ return 0;
}
__initcall(privcmd_init);
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
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()");
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");
.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)
{
* <= 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;
* 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. */
}
}
if (BAD_ADDR(elf_entry)) {
- printk(KERN_ERR "Unable to load interpreter %.128s\n",
- elf_interpreter);
force_sig(SIGSEGV, current);
- retval = -ENOEXEC; /* Nobody gets to see this, but.. */
+ retval = IS_ERR((void *)elf_entry) ?
+ (int)elf_entry : -EINVAL;
goto out_free_dentry;
}
reloc_func_desc = interp_load_addr;
} 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;
}
}
pass does the actual I/O. */
void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers)
{
+ struct address_space *mapping = bdev->bd_inode->i_mapping;
+
+ if (mapping->nrpages == 0)
+ return;
+
invalidate_bh_lrus();
/*
* FIXME: what about destroy_dirty_buffers?
* We really want to use invalidate_inode_pages2() for
* that, but not until that's cleaned up.
*/
- invalidate_inode_pages(bdev->bd_inode->i_mapping);
+ invalidate_inode_pages(mapping);
}
/*
#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.
*/
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)
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);
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);
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);
struct buffer_head *bh;
struct ext3_group_desc * gdp;
-
- if ((ino != EXT3_ROOT_INO && ino != EXT3_JOURNAL_INO &&
- ino != EXT3_RESIZE_INO && ino < EXT3_FIRST_INO(sb)) ||
- ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)) {
- ext3_error(sb, "ext3_get_inode_block",
- "bad inode number: %lu", ino);
+ if (!ext3_valid_inum(sb, ino)) {
+ /*
+ * This error is already checked for in namei.c unless we are
+ * looking at an NFS filehandle, in which case no error
+ * report is needed
+ */
return 0;
}
+
block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb);
if (block_group >= EXT3_SB(sb)->s_groups_count) {
ext3_error(sb,"ext3_get_inode_block","group >= groups count");
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);
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);
#endif
};
+static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp)
+{
+ __u32 *objp = vobjp;
+ unsigned long ino = objp[0];
+ __u32 generation = objp[1];
+ struct inode *inode;
+ struct dentry *result;
+
+ if (ino != EXT3_ROOT_INO && ino < EXT3_FIRST_INO(sb))
+ return ERR_PTR(-ESTALE);
+ if (ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count))
+ return ERR_PTR(-ESTALE);
+
+ /* iget isn't really right if the inode is currently unallocated!!
+ * ext3_read_inode currently does appropriate checks, but
+ * it might be "neater" to call ext3_get_inode first and check
+ * if the inode is valid.....
+ */
+ inode = iget(sb, ino);
+ if (inode == NULL)
+ return ERR_PTR(-ENOMEM);
+ if (is_bad_inode(inode)
+ || (generation && inode->i_generation != generation)
+ ) {
+ /* we didn't find the right inode.. */
+ iput(inode);
+ return ERR_PTR(-ESTALE);
+ }
+ /* now to find a dentry.
+ * If possible, get a well-connected one
+ */
+ result = d_alloc_anon(inode);
+ if (!result) {
+ iput(inode);
+ return ERR_PTR(-ENOMEM);
+ }
+ return result;
+}
+
static struct export_operations ext3_export_ops = {
.get_parent = ext3_get_parent,
+ .get_dentry = ext3_get_dentry,
};
enum {
} while (nfds <= nr);
new_fds = alloc_fd_array(nfds);
if (!new_fds)
- goto out;
+ goto out2;
fdt->fd = new_fds;
fdt->max_fds = nfds;
fdt->free_files = NULL;
return fdt;
+out2:
+ nfds = fdt->max_fdset;
out:
if (new_openset)
free_fdset(new_openset, nfds);
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);
locks_insert_lock(before, fl);
*flp = fl;
+ error = 0;
out:
return error;
}
if (error)
goto exit_dput;
error = __do_follow_link(&path, nd);
- if (error)
+ if (error) {
+ /* Does someone understand code flow here? Or it is only
+ * me so stupid? Anathema to whoever designed this non-sense
+ * with "intent.open".
+ */
+ release_open_intent(nd);
return error;
+ }
nd->flags &= ~LOOKUP_PARENT;
if (nd->last_type == LAST_BIND)
goto ok;
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 struct inode_operations proc_mem_inode_operations = {
.permission = proc_permission,
+ .setattr = proc_setattr,
};
#ifdef CONFIG_AUDITSYSCALL
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
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;
inode->i_uid = 0;
inode->i_gid = 0;
}
+ inode->i_mode &= ~(S_ISUID | S_ISGID);
security_task_to_inode(task, inode);
return 1;
}
inode->i_uid = 0;
inode->i_gid = 0;
}
+ inode->i_mode &= ~(S_ISUID | S_ISGID);
security_task_to_inode(task, inode);
return 1;
}
static struct inode_operations proc_fd_inode_operations = {
.lookup = proc_lookupfd,
.permission = proc_permission,
+ .setattr = proc_setattr,
};
static struct inode_operations proc_task_inode_operations = {
.lookup = proc_task_lookup,
.permission = proc_task_permission,
+ .setattr = proc_setattr,
};
#ifdef CONFIG_SECURITY
static struct inode_operations proc_tgid_base_inode_operations = {
.lookup = proc_tgid_base_lookup,
+ .setattr = proc_setattr,
};
static struct inode_operations proc_tid_base_inode_operations = {
.lookup = proc_tid_base_lookup,
+ .setattr = proc_setattr,
};
#ifdef CONFIG_SECURITY
static struct inode_operations proc_tgid_attr_inode_operations = {
.lookup = proc_tgid_attr_lookup,
+ .setattr = proc_setattr,
};
static struct inode_operations proc_tid_attr_inode_operations = {
.lookup = proc_tid_attr_lookup,
+ .setattr = proc_setattr,
};
#endif
static struct inode_operations proc_self_inode_operations = {
.readlink = proc_self_readlink,
.follow_link = proc_self_follow_link,
+ .setattr = proc_setattr,
};
/**
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.
*/
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
* 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);
}
- for (i = 0;; i++) {
+ do {
if (!opipe->readers) {
send_sig(SIGPIPE, current, 0);
if (!ret)
ret = -EPIPE;
break;
}
- if (ipipe->nrbufs - i) {
- ibuf = ipipe->bufs + ((ipipe->curbuf + i) & (PIPE_BUFFERS - 1));
- /*
- * If we have room, fill this buffer
- */
- if (opipe->nrbufs < PIPE_BUFFERS) {
- int nbuf = (opipe->curbuf + opipe->nrbufs) & (PIPE_BUFFERS - 1);
-
- /*
- * Get a reference to this pipe buffer,
- * so we can copy the contents over.
- */
- ibuf->ops->get(ipipe, ibuf);
-
- obuf = opipe->bufs + nbuf;
- *obuf = *ibuf;
-
- /*
- * Don't inherit the gift flag, we need to
- * prevent multiple steals of this page.
- */
- obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
-
- if (obuf->len > len)
- obuf->len = len;
-
- opipe->nrbufs++;
- do_wakeup = 1;
- ret += obuf->len;
- len -= obuf->len;
-
- if (!len)
- break;
- if (opipe->nrbufs < PIPE_BUFFERS)
- continue;
- }
-
- /*
- * We have input available, but no output room.
- * If we already copied data, return that. If we
- * need to drop the opipe lock, it must be ordered
- * last to avoid deadlocks.
- */
- if ((flags & SPLICE_F_NONBLOCK) || !ipipe_first) {
- if (!ret)
- ret = -EAGAIN;
- break;
- }
- if (signal_pending(current)) {
- if (!ret)
- ret = -ERESTARTSYS;
- break;
- }
- if (do_wakeup) {
- smp_mb();
- if (waitqueue_active(&opipe->wait))
- wake_up_interruptible(&opipe->wait);
- kill_fasync(&opipe->fasync_readers, SIGIO, POLL_IN);
- do_wakeup = 0;
- }
+ /*
+ * If we have iterated all input buffers or ran out of
+ * output room, break.
+ */
+ if (i >= ipipe->nrbufs || opipe->nrbufs >= PIPE_BUFFERS)
+ break;
- opipe->waiting_writers++;
- pipe_wait(opipe);
- opipe->waiting_writers--;
- continue;
- }
+ ibuf = ipipe->bufs + ((ipipe->curbuf + i) & (PIPE_BUFFERS - 1));
+ nbuf = (opipe->curbuf + opipe->nrbufs) & (PIPE_BUFFERS - 1);
/*
- * No input buffers, do the usual checks for available
- * writers and blocking and wait if necessary
+ * Get a reference to this pipe buffer,
+ * so we can copy the contents over.
*/
- if (!ipipe->writers)
- break;
- if (!ipipe->waiting_writers) {
- if (ret)
- break;
- }
+ ibuf->ops->get(ipipe, ibuf);
+
+ obuf = opipe->bufs + nbuf;
+ *obuf = *ibuf;
+
/*
- * pipe_wait() drops the ipipe mutex. To avoid deadlocks
- * with another process, we can only safely do that if
- * the ipipe lock is ordered last.
+ * Don't inherit the gift flag, we need to
+ * prevent multiple steals of this page.
*/
- if ((flags & SPLICE_F_NONBLOCK) || ipipe_first) {
- if (!ret)
- ret = -EAGAIN;
- break;
- }
- if (signal_pending(current)) {
- if (!ret)
- ret = -ERESTARTSYS;
- break;
- }
+ obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
- if (waitqueue_active(&ipipe->wait))
- wake_up_interruptible_sync(&ipipe->wait);
- kill_fasync(&ipipe->fasync_writers, SIGIO, POLL_OUT);
+ if (obuf->len > len)
+ obuf->len = len;
- pipe_wait(ipipe);
- }
+ opipe->nrbufs++;
+ ret += obuf->len;
+ len -= obuf->len;
+ i++;
+ } while (len);
mutex_unlock(&ipipe->inode->i_mutex);
mutex_unlock(&opipe->inode->i_mutex);
- if (do_wakeup) {
+ /*
+ * If we put data in the output pipe, wakeup any potential readers.
+ */
+ if (ret > 0) {
smp_mb();
if (waitqueue_active(&opipe->wait))
wake_up_interruptible(&opipe->wait);
{
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)
iput(inode);
goto error_out;
}
- sb->s_maxbytes = MAX_LFS_FILESIZE;
+ sb->s_maxbytes = 1<<30;
return 0;
error_out:
{
if (offset)
{
- extoffset -= adsize;
- etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
- if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
- {
- extoffset -= adsize;
- elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset);
- udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
+ /*
+ * OK, there is not extent covering inode->i_size and
+ * no extent above inode->i_size => truncate is
+ * extending the file by 'offset'.
+ */
+ if ((!bh && extoffset == udf_file_entry_alloc_offset(inode)) ||
+ (bh && extoffset == sizeof(struct allocExtDesc))) {
+ /* File has no extents at all! */
+ memset(&eloc, 0x00, sizeof(kernel_lb_addr));
+ elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
+ udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
}
- else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
- {
- kernel_lb_addr neloc = { 0, 0 };
+ else {
extoffset -= adsize;
- nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
- ((elen + offset + inode->i_sb->s_blocksize - 1) &
- ~(inode->i_sb->s_blocksize - 1));
- udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
- udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
- }
- else
- {
- if (elen & (inode->i_sb->s_blocksize - 1))
+ etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
+ if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
+ {
+ extoffset -= adsize;
+ elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset);
+ udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
+ }
+ else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
{
+ kernel_lb_addr neloc = { 0, 0 };
extoffset -= adsize;
- elen = EXT_RECORDED_ALLOCATED |
- ((elen + inode->i_sb->s_blocksize - 1) &
+ nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
+ ((elen + offset + inode->i_sb->s_blocksize - 1) &
~(inode->i_sb->s_blocksize - 1));
- udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
+ udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
+ udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
+ }
+ else
+ {
+ if (elen & (inode->i_sb->s_blocksize - 1))
+ {
+ extoffset -= adsize;
+ elen = EXT_RECORDED_ALLOCATED |
+ ((elen + inode->i_sb->s_blocksize - 1) &
+ ~(inode->i_sb->s_blocksize - 1));
+ udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
+ }
+ memset(&eloc, 0x00, sizeof(kernel_lb_addr));
+ elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
+ udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
}
- memset(&eloc, 0x00, sizeof(kernel_lb_addr));
- elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
- udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
}
}
}
/*
* 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
#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
extern int disable_timer_pin_1;
+#ifndef CONFIG_XEN
void smp_send_timer_broadcast_ipi(struct pt_regs *regs);
void switch_APIC_timer_to_ipi(void *cpumask);
void switch_ipi_to_APIC_timer(void *cpumask);
#define ARCH_APICTIMER_STOPS_ON_C3 1
+#endif
extern int timer_over_8254;
}
#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);
* 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>
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)
/*
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);
#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)
#ifndef _I386_PGTABLE_2LEVEL_DEFS_H
#define _I386_PGTABLE_2LEVEL_DEFS_H
+#define HAVE_SHARED_KERNEL_PMD 0
+
/*
* traditional i386 two-level paging structure:
*/
#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
*/
"\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" \
* 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 */
* the bte_copy() once in the hope that the failure was due to a temporary
* aberration (i.e., the link going down temporarily).
*
- * See bte_copy for definition of the input parameters.
+ * src - physical address of the source of the transfer.
+ * vdst - virtual address of the destination of the transfer.
+ * len - number of bytes to transfer from source to destination.
+ * mode - see bte_copy() for definition.
+ * notification - see bte_copy() for definition.
*
* Note: xp_bte_copy() should never be called while holding a spinlock.
*/
static inline bte_result_t
-xp_bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
+xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification)
{
bte_result_t ret;
+ u64 pdst = ia64_tpa(vdst);
- ret = bte_copy(src, dest, len, mode, notification);
+ /*
+ * Ensure that the physically mapped memory is contiguous.
+ *
+ * We do this by ensuring that the memory is from region 7 only.
+ * If the need should arise to use memory from one of the other
+ * regions, then modify the BUG_ON() statement to ensure that the
+ * memory from that region is always physically contiguous.
+ */
+ BUG_ON(REGION_NUMBER(vdst) != RGN_KERNEL);
+ ret = bte_copy(src, pdst, len, mode, notification);
if (ret != BTE_SUCCESS) {
if (!in_interrupt()) {
cond_resched();
}
- ret = bte_copy(src, dest, len, mode, notification);
+ ret = bte_copy(src, pdst, len, mode, notification);
}
return ret;
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);
if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
- asm volatile(" cs %1,%4,0(%5)\n"
+ asm volatile(" sacf 256\n"
+ " cs %1,%4,0(%5)\n"
"0: lr %0,%1\n"
- "1:\n"
+ "1: sacf 0\n"
#ifndef __s390x__
".section __ex_table,\"a\"\n"
" .align 4\n"
#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... */
#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... */
#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 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>
extern void setup_threshold_lvt(unsigned long lvt_off);
+#ifndef CONFIG_XEN
void smp_send_timer_broadcast_ipi(void);
void switch_APIC_timer_to_ipi(void *cpumask);
void switch_ipi_to_APIC_timer(void *cpumask);
#define ARCH_APICTIMER_STOPS_ON_C3 1
+#endif
#endif /* CONFIG_X86_LOCAL_APIC */
__asm__( \
"\n.p2align\n" \
"IRQ" #nr "_interrupt:\n\t" \
- "push $" #nr "-256 ; " \
+ "push $~(" #nr ") ; " \
"jmp common_interrupt");
#if defined(CONFIG_X86_IO_APIC)
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)
{
/*
}
local_irq_restore(flags);
}
+#endif /* CONFIG_XEN_UNPRIVILEGED_GUEST */
#endif /* __ASM_IPI_H */
#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);
/*
* Automatically generated C config: don't edit
+ * Linux kernel version: 2.6.17.13
+ * Wed Oct 18 17:15:54 2006
*/
#define AUTOCONF_INCLUDED
+#define CONFIG_X86_32 1
+#define CONFIG_SEMAPHORE_SLEEPERS 1
#define CONFIG_X86 1
#define CONFIG_MMU 1
-#define CONFIG_UID16 1
#define CONFIG_GENERIC_ISA_DMA 1
+#define CONFIG_GENERIC_IOMAP 1
+#define CONFIG_GENERIC_HWEIGHT 1
+#define CONFIG_ARCH_MAY_HAVE_PC_FDC 1
+#define CONFIG_DMI 1
/*
* Code maturity level options
*/
#define CONFIG_EXPERIMENTAL 1
-#define CONFIG_CLEAN_COMPILE 1
-#define CONFIG_STANDALONE 1
+#define CONFIG_BROKEN_ON_SMP 1
+#define CONFIG_INIT_ENV_ARG_LIMIT 32
/*
* General setup
*/
+#define CONFIG_LOCALVERSION ""
+#undef CONFIG_LOCALVERSION_AUTO
#define CONFIG_SWAP 1
#define CONFIG_SYSVIPC 1
#define CONFIG_POSIX_MQUEUE 1
#define CONFIG_BSD_PROCESS_ACCT 1
+#undef CONFIG_BSD_PROCESS_ACCT_V3
#define CONFIG_SYSCTL 1
-#undef CONFIG_AUDIT
-#define CONFIG_LOG_BUF_SHIFT 17
-#define CONFIG_HOTPLUG 1
+#define CONFIG_AUDIT 1
+#define CONFIG_AUDITSYSCALL 1
#undef CONFIG_IKCONFIG
+#define CONFIG_RELAY 1
+#define CONFIG_INITRAMFS_SOURCE ""
+#define CONFIG_UID16 1
+#define CONFIG_VM86 1
+#define CONFIG_CC_OPTIMIZE_FOR_SIZE 1
#undef CONFIG_EMBEDDED
#define CONFIG_KALLSYMS 1
#undef CONFIG_KALLSYMS_ALL
+#define CONFIG_KALLSYMS_EXTRA_PASS 1
+#define CONFIG_HOTPLUG 1
+#define CONFIG_PRINTK 1
+#define CONFIG_BUG 1
+#define CONFIG_ELF_CORE 1
+#define CONFIG_BASE_FULL 1
#define CONFIG_FUTEX 1
#define CONFIG_EPOLL 1
-#define CONFIG_IOSCHED_NOOP 1
-#define CONFIG_IOSCHED_AS 1
-#define CONFIG_IOSCHED_DEADLINE 1
-#define CONFIG_IOSCHED_CFQ 1
-#define CONFIG_CC_OPTIMIZE_FOR_SIZE 1
+#define CONFIG_SHMEM 1
+#define CONFIG_SLAB 1
+#undef CONFIG_TINY_SHMEM
+#define CONFIG_BASE_SMALL 0
+#undef CONFIG_SLOB
+#define CONFIG_OBSOLETE_INTERMODULE_MODULE 1
/*
* Loadable module support
#define CONFIG_MODULES 1
#define CONFIG_MODULE_UNLOAD 1
#undef CONFIG_MODULE_FORCE_UNLOAD
-#define CONFIG_OBSOLETE_MODPARM 1
-#undef CONFIG_MODVERSIONS
+#define CONFIG_MODVERSIONS 1
+#define CONFIG_MODULE_SRCVERSION_ALL 1
+#define CONFIG_MODULE_SIG 1
+#undef CONFIG_MODULE_SIG_FORCE
#define CONFIG_KMOD 1
-#define CONFIG_STOP_MACHINE 1
+
+/*
+ * Block layer
+ */
+#define CONFIG_LBD 1
+#define CONFIG_BLK_DEV_IO_TRACE 1
+#define CONFIG_LSF 1
+
+/*
+ * IO Schedulers
+ */
+#define CONFIG_IOSCHED_NOOP 1
+#define CONFIG_IOSCHED_AS 1
+#define CONFIG_IOSCHED_DEADLINE 1
+#define CONFIG_IOSCHED_CFQ 1
+#undef CONFIG_DEFAULT_AS
+#undef CONFIG_DEFAULT_DEADLINE
+#define CONFIG_DEFAULT_CFQ 1
+#undef CONFIG_DEFAULT_NOOP
+#define CONFIG_DEFAULT_IOSCHED "cfq"
/*
* Processor type and features
*/
-#undef CONFIG_X86_PC
+#undef CONFIG_SMP
+#define CONFIG_X86_PC 1
+#undef CONFIG_X86_XEN
#undef CONFIG_X86_ELAN
#undef CONFIG_X86_VOYAGER
#undef CONFIG_X86_NUMAQ
#undef CONFIG_X86_SUMMIT
#undef CONFIG_X86_BIGSMP
#undef CONFIG_X86_VISWS
-#define CONFIG_X86_GENERICARCH 1
+#undef CONFIG_X86_GENERICARCH
#undef CONFIG_X86_ES7000
-#define CONFIG_X86_CYCLONE_TIMER 1
#undef CONFIG_M386
#undef CONFIG_M486
#undef CONFIG_M586
#undef CONFIG_MK7
#undef CONFIG_MK8
#undef CONFIG_MCRUSOE
+#undef CONFIG_MEFFICEON
#undef CONFIG_MWINCHIPC6
#undef CONFIG_MWINCHIP2
#undef CONFIG_MWINCHIP3D
+#undef CONFIG_MGEODEGX1
+#undef CONFIG_MGEODE_LX
#undef CONFIG_MCYRIXIII
#undef CONFIG_MVIAC3_2
#define CONFIG_X86_GENERIC 1
#define CONFIG_X86_XADD 1
#define CONFIG_X86_L1_CACHE_SHIFT 7
#define CONFIG_RWSEM_XCHGADD_ALGORITHM 1
+#define CONFIG_GENERIC_CALIBRATE_DELAY 1
#define CONFIG_X86_PPRO_FENCE 1
#define CONFIG_X86_WP_WORKS_OK 1
#define CONFIG_X86_INVLPG 1
#define CONFIG_X86_BSWAP 1
#define CONFIG_X86_POPAD_OK 1
+#define CONFIG_X86_CMPXCHG64 1
#define CONFIG_X86_GOOD_APIC 1
#define CONFIG_X86_INTEL_USERCOPY 1
#define CONFIG_X86_USE_PPRO_CHECKSUM 1
-#define CONFIG_X86_4G 1
-#define CONFIG_X86_SWITCH_PAGETABLES 1
-#define CONFIG_X86_4G_VM_LAYOUT 1
-#define CONFIG_X86_UACCESS_INDIRECT 1
-#define CONFIG_X86_HIGH_ENTRY 1
+#define CONFIG_X86_TSC 1
#define CONFIG_HPET_TIMER 1
#define CONFIG_HPET_EMULATE_RTC 1
-#define CONFIG_SMP 1
-#define CONFIG_NR_CPUS 32
-#define CONFIG_SCHED_SMT 1
+#undef CONFIG_PREEMPT_NONE
+#define CONFIG_PREEMPT_VOLUNTARY 1
#undef CONFIG_PREEMPT
+#define CONFIG_X86_UP_APIC 1
+#define CONFIG_X86_UP_IOAPIC 1
#define CONFIG_X86_LOCAL_APIC 1
#define CONFIG_X86_IO_APIC 1
-#define CONFIG_X86_TSC 1
#define CONFIG_X86_MCE 1
#undef CONFIG_X86_MCE_NONFATAL
#define CONFIG_X86_MCE_P4THERMAL 1
#define CONFIG_TOSHIBA_MODULE 1
#define CONFIG_I8K_MODULE 1
+#undef CONFIG_X86_REBOOTFIXUPS
#define CONFIG_MICROCODE_MODULE 1
#define CONFIG_X86_MSR_MODULE 1
#define CONFIG_X86_CPUID_MODULE 1
+#undef CONFIG_SWIOTLB
/*
* Firmware Drivers
*/
#define CONFIG_EDD_MODULE 1
+#define CONFIG_EFI_VARS 1
+#define CONFIG_DELL_RBU_MODULE 1
+#define CONFIG_DCDBAS_MODULE 1
#undef CONFIG_NOHIGHMEM
-#undef CONFIG_HIGHMEM4G
-#define CONFIG_HIGHMEM64G 1
+#define CONFIG_HIGHMEM4G 1
+#undef CONFIG_HIGHMEM64G
+#define CONFIG_PAGE_OFFSET 0xC0000000
#define CONFIG_HIGHMEM 1
-#define CONFIG_X86_PAE 1
-#undef CONFIG_NUMA
+#define CONFIG_ARCH_FLATMEM_ENABLE 1
+#define CONFIG_ARCH_SPARSEMEM_ENABLE 1
+#define CONFIG_ARCH_SELECT_MEMORY_MODEL 1
+#define CONFIG_SELECT_MEMORY_MODEL 1
+#define CONFIG_FLATMEM_MANUAL 1
+#undef CONFIG_DISCONTIGMEM_MANUAL
+#undef CONFIG_SPARSEMEM_MANUAL
+#define CONFIG_FLATMEM 1
+#define CONFIG_FLAT_NODE_MEM_MAP 1
+#define CONFIG_SPARSEMEM_STATIC 1
+#define CONFIG_SPLIT_PTLOCK_CPUS 4096
#define CONFIG_HIGHPTE 1
#undef CONFIG_MATH_EMULATION
#define CONFIG_MTRR 1
-#undef CONFIG_EFI
-#undef CONFIG_IRQBALANCE
-#define CONFIG_HAVE_DEC_LOCK 1
+#define CONFIG_EFI 1
+#define CONFIG_BOOT_IOREMAP 1
#define CONFIG_REGPARM 1
+#undef CONFIG_SECCOMP
+#undef CONFIG_HZ_100
+#define CONFIG_HZ_250 1
+#undef CONFIG_HZ_1000
+#define CONFIG_HZ 250
+#define CONFIG_KEXEC 1
+#undef CONFIG_CRASH_DUMP
+#define CONFIG_PHYSICAL_START 0x400000
+#define CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG 1
/*
* Power management options (ACPI, APM)
*/
#define CONFIG_PM 1
-#undef CONFIG_SOFTWARE_SUSPEND
-#undef CONFIG_PM_DISK
+#define CONFIG_PM_LEGACY 1
+#define CONFIG_PM_DEBUG 1
+#define CONFIG_SOFTWARE_SUSPEND 1
+#define CONFIG_PM_STD_PARTITION ""
/*
* ACPI (Advanced Configuration and Power Interface) Support
*/
#define CONFIG_ACPI 1
-#define CONFIG_ACPI_BOOT 1
-#define CONFIG_ACPI_INTERPRETER 1
#define CONFIG_ACPI_SLEEP 1
#define CONFIG_ACPI_SLEEP_PROC_FS 1
+#undef CONFIG_ACPI_SLEEP_PROC_SLEEP
#define CONFIG_ACPI_AC_MODULE 1
#define CONFIG_ACPI_BATTERY_MODULE 1
#define CONFIG_ACPI_BUTTON_MODULE 1
+#define CONFIG_ACPI_VIDEO_MODULE 1
+#undef CONFIG_ACPI_HOTKEY
#define CONFIG_ACPI_FAN 1
#define CONFIG_ACPI_PROCESSOR 1
#define CONFIG_ACPI_THERMAL 1
#define CONFIG_ACPI_ASUS_MODULE 1
+#define CONFIG_ACPI_IBM_MODULE 1
+#define CONFIG_ACPI_IBM_DOCK 1
#define CONFIG_ACPI_TOSHIBA_MODULE 1
+#define CONFIG_ACPI_BLACKLIST_YEAR 1999
#undef CONFIG_ACPI_DEBUG
-#define CONFIG_ACPI_BUS 1
#define CONFIG_ACPI_EC 1
#define CONFIG_ACPI_POWER 1
-#define CONFIG_ACPI_PCI 1
#define CONFIG_ACPI_SYSTEM 1
#define CONFIG_X86_PM_TIMER 1
+#undef CONFIG_ACPI_CONTAINER
/*
* APM (Advanced Power Management) BIOS Support
* CPU Frequency scaling
*/
#define CONFIG_CPU_FREQ 1
-#undef CONFIG_CPU_FREQ_PROC_INTF
+#define CONFIG_CPU_FREQ_TABLE 1
+#define CONFIG_CPU_FREQ_DEBUG 1
+#define CONFIG_CPU_FREQ_STAT_MODULE 1
+#define CONFIG_CPU_FREQ_STAT_DETAILS 1
#undef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE
#define CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE 1
#define CONFIG_CPU_FREQ_GOV_PERFORMANCE 1
#define CONFIG_CPU_FREQ_GOV_POWERSAVE_MODULE 1
#define CONFIG_CPU_FREQ_GOV_USERSPACE 1
-#undef CONFIG_CPU_FREQ_24_API
-#define CONFIG_CPU_FREQ_TABLE 1
+#define CONFIG_CPU_FREQ_GOV_ONDEMAND_MODULE 1
+#define CONFIG_CPU_FREQ_GOV_CONSERVATIVE_MODULE 1
/*
* CPUFreq processor drivers
*/
#define CONFIG_X86_ACPI_CPUFREQ_MODULE 1
-#undef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
-#define CONFIG_X86_POWERNOW_K6_MODULE 1
+#undef CONFIG_X86_POWERNOW_K6
#define CONFIG_X86_POWERNOW_K7 1
-#define CONFIG_X86_POWERNOW_K8_MODULE 1
+#define CONFIG_X86_POWERNOW_K7_ACPI 1
+#define CONFIG_X86_POWERNOW_K8 1
+#define CONFIG_X86_POWERNOW_K8_ACPI 1
#undef CONFIG_X86_GX_SUSPMOD
#define CONFIG_X86_SPEEDSTEP_CENTRINO 1
-#define CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE 1
#define CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI 1
+#define CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE 1
#define CONFIG_X86_SPEEDSTEP_ICH 1
-#define CONFIG_X86_SPEEDSTEP_SMI_MODULE 1
+#define CONFIG_X86_SPEEDSTEP_SMI 1
#define CONFIG_X86_P4_CLOCKMOD_MODULE 1
+#undef CONFIG_X86_CPUFREQ_NFORCE2
+#define CONFIG_X86_LONGRUN 1
+
+/*
+ * shared options
+ */
+#undef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
#define CONFIG_X86_SPEEDSTEP_LIB 1
#undef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
-#define CONFIG_X86_LONGRUN 1
-#undef CONFIG_X86_LONGHAUL
/*
* Bus options (PCI, PCMCIA, EISA, MCA, ISA)
#undef CONFIG_PCI_GOBIOS
#undef CONFIG_PCI_GOMMCONFIG
#undef CONFIG_PCI_GODIRECT
+#undef CONFIG_PCI_GOXEN_FE
#define CONFIG_PCI_GOANY 1
#define CONFIG_PCI_BIOS 1
#define CONFIG_PCI_DIRECT 1
#define CONFIG_PCI_MMCONFIG 1
-#define CONFIG_PCI_USE_VECTOR 1
-#define CONFIG_PCI_LEGACY_PROC 1
-#undef CONFIG_PCI_NAMES
+#define CONFIG_PCIEPORTBUS 1
+#define CONFIG_HOTPLUG_PCI_PCIE_MODULE 1
+#undef CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE
+#define CONFIG_PCI_MSI 1
+#undef CONFIG_PCI_DEBUG
+#define CONFIG_ISA_DMA_API 1
#define CONFIG_ISA 1
#undef CONFIG_EISA
#undef CONFIG_MCA
#undef CONFIG_SCx200
/*
- * PCMCIA/CardBus support
+ * PCCARD (PCMCIA/CardBus) support
*/
-#define CONFIG_PCMCIA_MODULE 1
+#define CONFIG_PCCARD 1
#undef CONFIG_PCMCIA_DEBUG
-#define CONFIG_YENTA_MODULE 1
+#define CONFIG_PCMCIA 1
+#define CONFIG_PCMCIA_LOAD_CIS 1
+#define CONFIG_PCMCIA_IOCTL 1
#define CONFIG_CARDBUS 1
+
+/*
+ * PC-card bridges
+ */
+#define CONFIG_YENTA 1
+#define CONFIG_YENTA_O2 1
+#define CONFIG_YENTA_RICOH 1
+#define CONFIG_YENTA_TI 1
+#define CONFIG_YENTA_ENE_TUNE 1
+#define CONFIG_YENTA_TOSHIBA 1
+#define CONFIG_PD6729_MODULE 1
#define CONFIG_I82092_MODULE 1
-#define CONFIG_I82365_MODULE 1
-#define CONFIG_TCIC_MODULE 1
+#undef CONFIG_I82365
+#undef CONFIG_TCIC
#define CONFIG_PCMCIA_PROBE 1
+#define CONFIG_PCCARD_NONSTATIC 1
/*
* PCI Hotplug Support
*/
#define CONFIG_HOTPLUG_PCI 1
-#undef CONFIG_HOTPLUG_PCI_FAKE
+#define CONFIG_HOTPLUG_PCI_FAKE_MODULE 1
#define CONFIG_HOTPLUG_PCI_COMPAQ_MODULE 1
#undef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM
#define CONFIG_HOTPLUG_PCI_IBM_MODULE 1
-#undef CONFIG_HOTPLUG_PCI_ACPI
+#define CONFIG_HOTPLUG_PCI_ACPI_MODULE 1
+#define CONFIG_HOTPLUG_PCI_ACPI_IBM_MODULE 1
#undef CONFIG_HOTPLUG_PCI_CPCI
-#define CONFIG_HOTPLUG_PCI_PCIE_MODULE 1
-#define CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE 1
-#define CONFIG_HOTPLUG_PCI_SHPC_MODULE 1
-#define CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE 1
+#undef CONFIG_HOTPLUG_PCI_SHPC
/*
* Executable file formats
*/
#define CONFIG_BINFMT_ELF 1
#undef CONFIG_BINFMT_AOUT
-#define CONFIG_BINFMT_MISC_MODULE 1
+#define CONFIG_BINFMT_MISC 1
/*
- * Device Drivers
+ * Networking
*/
+#define CONFIG_NET 1
/*
- * Generic Driver Options
+ * Networking options
*/
-#define CONFIG_FW_LOADER 1
-#undef CONFIG_DEBUG_DRIVER
+#undef CONFIG_NETDEBUG
+#define CONFIG_PACKET 1
+#define CONFIG_PACKET_MMAP 1
+#define CONFIG_UNIX 1
+#define CONFIG_XFRM 1
+#define CONFIG_XFRM_USER 1
+#define CONFIG_NET_KEY_MODULE 1
+#define CONFIG_INET 1
+#define CONFIG_IP_MULTICAST 1
+#define CONFIG_IP_ADVANCED_ROUTER 1
+#define CONFIG_ASK_IP_FIB_HASH 1
+#undef CONFIG_IP_FIB_TRIE
+#define CONFIG_IP_FIB_HASH 1
+#define CONFIG_IP_MULTIPLE_TABLES 1
+#define CONFIG_IP_ROUTE_FWMARK 1
+#define CONFIG_IP_ROUTE_MULTIPATH 1
+#undef CONFIG_IP_ROUTE_MULTIPATH_CACHED
+#define CONFIG_IP_ROUTE_VERBOSE 1
+#undef CONFIG_IP_PNP
+#define CONFIG_NET_IPIP_MODULE 1
+#define CONFIG_NET_IPGRE_MODULE 1
+#define CONFIG_NET_IPGRE_BROADCAST 1
+#define CONFIG_IP_MROUTE 1
+#define CONFIG_IP_PIMSM_V1 1
+#define CONFIG_IP_PIMSM_V2 1
+#undef CONFIG_ARPD
+#define CONFIG_SYN_COOKIES 1
+#define CONFIG_INET_AH_MODULE 1
+#define CONFIG_INET_ESP_MODULE 1
+#define CONFIG_INET_IPCOMP_MODULE 1
+#define CONFIG_INET_XFRM_TUNNEL_MODULE 1
+#define CONFIG_INET_TUNNEL_MODULE 1
+#define CONFIG_INET_DIAG_MODULE 1
+#define CONFIG_INET_TCP_DIAG_MODULE 1
+#undef CONFIG_TCP_CONG_ADVANCED
+#define CONFIG_TCP_CONG_BIC 1
/*
- * Memory Technology Devices (MTD)
+ * IP: Virtual Server Configuration
*/
-#define CONFIG_MTD_MODULE 1
-#undef CONFIG_MTD_DEBUG
-#define CONFIG_MTD_PARTITIONS_MODULE 1
-#define CONFIG_MTD_CONCAT_MODULE 1
-#define CONFIG_MTD_REDBOOT_PARTS_MODULE 1
-#define CONFIG_MTD_CMDLINE_PARTS_MODULE 1
+#define CONFIG_IP_VS_MODULE 1
+#undef CONFIG_IP_VS_DEBUG
+#define CONFIG_IP_VS_TAB_BITS 12
/*
- * User Modules And Translation Layers
+ * IPVS transport protocol load balancing support
*/
-#define CONFIG_MTD_CHAR_MODULE 1
-#define CONFIG_MTD_BLOCK_MODULE 1
-#define CONFIG_MTD_BLOCK_RO_MODULE 1
-#define CONFIG_FTL_MODULE 1
-#define CONFIG_NFTL_MODULE 1
-#define CONFIG_NFTL_RW 1
-#define CONFIG_INFTL_MODULE 1
+#define CONFIG_IP_VS_PROTO_TCP 1
+#define CONFIG_IP_VS_PROTO_UDP 1
+#define CONFIG_IP_VS_PROTO_ESP 1
+#define CONFIG_IP_VS_PROTO_AH 1
/*
- * RAM/ROM/Flash chip drivers
+ * IPVS scheduler
*/
-#define CONFIG_MTD_CFI_MODULE 1
-#define CONFIG_MTD_JEDECPROBE_MODULE 1
-#define CONFIG_MTD_GEN_PROBE_MODULE 1
-#undef CONFIG_MTD_CFI_ADV_OPTIONS
-#define CONFIG_MTD_CFI_INTELEXT_MODULE 1
-#define CONFIG_MTD_CFI_AMDSTD_MODULE 1
-#define CONFIG_MTD_CFI_STAA_MODULE 1
-#define CONFIG_MTD_RAM_MODULE 1
-#define CONFIG_MTD_ROM_MODULE 1
-#define CONFIG_MTD_ABSENT_MODULE 1
-#undef CONFIG_MTD_OBSOLETE_CHIPS
+#define CONFIG_IP_VS_RR_MODULE 1
+#define CONFIG_IP_VS_WRR_MODULE 1
+#define CONFIG_IP_VS_LC_MODULE 1
+#define CONFIG_IP_VS_WLC_MODULE 1
+#define CONFIG_IP_VS_LBLC_MODULE 1
+#define CONFIG_IP_VS_LBLCR_MODULE 1
+#define CONFIG_IP_VS_DH_MODULE 1
+#define CONFIG_IP_VS_SH_MODULE 1
+#define CONFIG_IP_VS_SED_MODULE 1
+#define CONFIG_IP_VS_NQ_MODULE 1
/*
- * Mapping drivers for chip access
+ * IPVS application helper
*/
-#define CONFIG_MTD_COMPLEX_MAPPINGS 1
-#undef CONFIG_MTD_PHYSMAP
-#undef CONFIG_MTD_PNC2000
-#define CONFIG_MTD_SC520CDP_MODULE 1
-#define CONFIG_MTD_NETSC520_MODULE 1
-#define CONFIG_MTD_SBC_GXX_MODULE 1
-#define CONFIG_MTD_ELAN_104NC_MODULE 1
-#define CONFIG_MTD_SCx200_DOCFLASH_MODULE 1
-#define CONFIG_MTD_AMD76XROM_MODULE 1
-#define CONFIG_MTD_ICH2ROM_MODULE 1
-#define CONFIG_MTD_SCB2_FLASH_MODULE 1
-#undef CONFIG_MTD_NETtel
-#undef CONFIG_MTD_DILNETPC
-#define CONFIG_MTD_L440GX_MODULE 1
-#define CONFIG_MTD_PCI_MODULE 1
+#define CONFIG_IP_VS_FTP_MODULE 1
+#define CONFIG_IPV6_MODULE 1
+#define CONFIG_IPV6_PRIVACY 1
+#define CONFIG_IPV6_ROUTER_PREF 1
+#define CONFIG_IPV6_ROUTE_INFO 1
+#define CONFIG_INET6_AH_MODULE 1
+#define CONFIG_INET6_ESP_MODULE 1
+#define CONFIG_INET6_IPCOMP_MODULE 1
+#define CONFIG_INET6_XFRM_TUNNEL_MODULE 1
+#define CONFIG_INET6_TUNNEL_MODULE 1
+#define CONFIG_IPV6_TUNNEL_MODULE 1
+#define CONFIG_NETFILTER 1
+#undef CONFIG_NETFILTER_DEBUG
+#define CONFIG_BRIDGE_NETFILTER 1
/*
- * Self-contained MTD device drivers
+ * Core Netfilter Configuration
+ */
+#define CONFIG_NETFILTER_NETLINK_MODULE 1
+#define CONFIG_NETFILTER_NETLINK_QUEUE_MODULE 1
+#define CONFIG_NETFILTER_NETLINK_LOG_MODULE 1
+#define CONFIG_NETFILTER_XTABLES_MODULE 1
+#define CONFIG_NETFILTER_XT_TARGET_CLASSIFY_MODULE 1
+#define CONFIG_NETFILTER_XT_TARGET_CONNMARK_MODULE 1
+#define CONFIG_NETFILTER_XT_TARGET_MARK_MODULE 1
+#define CONFIG_NETFILTER_XT_TARGET_NFQUEUE_MODULE 1
+#define CONFIG_NETFILTER_XT_TARGET_NOTRACK_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_COMMENT_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_CONNBYTES_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_CONNMARK_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_CONNTRACK_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_DCCP_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_ESP_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_HELPER_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_LENGTH_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_LIMIT_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_MAC_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_MARK_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_POLICY_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_MULTIPORT_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_PHYSDEV_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_PKTTYPE_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_REALM_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_SCTP_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_STATE_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_STRING_MODULE 1
+#define CONFIG_NETFILTER_XT_MATCH_TCPMSS_MODULE 1
+
+/*
+ * IP: Netfilter Configuration
*/
-#define CONFIG_MTD_PMC551_MODULE 1
-#undef CONFIG_MTD_PMC551_BUGFIX
-#undef CONFIG_MTD_PMC551_DEBUG
-#undef CONFIG_MTD_SLRAM
-#define CONFIG_MTD_MTDRAM_MODULE 1
-#define CONFIG_MTDRAM_TOTAL_SIZE 4096
-#define CONFIG_MTDRAM_ERASE_SIZE 128
-#undef CONFIG_MTD_BLKMTD
+#define CONFIG_IP_NF_CONNTRACK_MODULE 1
+#define CONFIG_IP_NF_CT_ACCT 1
+#define CONFIG_IP_NF_CONNTRACK_MARK 1
+#define CONFIG_IP_NF_CONNTRACK_EVENTS 1
+#define CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE 1
+#define CONFIG_IP_NF_CT_PROTO_SCTP_MODULE 1
+#define CONFIG_IP_NF_FTP_MODULE 1
+#define CONFIG_IP_NF_IRC_MODULE 1
+#define CONFIG_IP_NF_NETBIOS_NS_MODULE 1
+#define CONFIG_IP_NF_TFTP_MODULE 1
+#define CONFIG_IP_NF_AMANDA_MODULE 1
+#define CONFIG_IP_NF_PPTP_MODULE 1
+#define CONFIG_IP_NF_H323_MODULE 1
+#define CONFIG_IP_NF_QUEUE_MODULE 1
+#define CONFIG_IP_NF_IPTABLES_MODULE 1
+#define CONFIG_IP_NF_MATCH_IPRANGE_MODULE 1
+#define CONFIG_IP_NF_MATCH_TOS_MODULE 1
+#define CONFIG_IP_NF_MATCH_RECENT_MODULE 1
+#define CONFIG_IP_NF_MATCH_ECN_MODULE 1
+#define CONFIG_IP_NF_MATCH_DSCP_MODULE 1
+#define CONFIG_IP_NF_MATCH_AH_MODULE 1
+#define CONFIG_IP_NF_MATCH_TTL_MODULE 1
+#define CONFIG_IP_NF_MATCH_OWNER_MODULE 1
+#define CONFIG_IP_NF_MATCH_ADDRTYPE_MODULE 1
+#define CONFIG_IP_NF_MATCH_HASHLIMIT_MODULE 1
+#define CONFIG_IP_NF_FILTER_MODULE 1
+#define CONFIG_IP_NF_TARGET_REJECT_MODULE 1
+#define CONFIG_IP_NF_TARGET_LOG_MODULE 1
+#define CONFIG_IP_NF_TARGET_ULOG_MODULE 1
+#define CONFIG_IP_NF_TARGET_TCPMSS_MODULE 1
+#define CONFIG_IP_NF_NAT_MODULE 1
+#define CONFIG_IP_NF_NAT_NEEDED 1
+#define CONFIG_IP_NF_TARGET_MASQUERADE_MODULE 1
+#define CONFIG_IP_NF_TARGET_REDIRECT_MODULE 1
+#define CONFIG_IP_NF_TARGET_NETMAP_MODULE 1
+#define CONFIG_IP_NF_TARGET_SAME_MODULE 1
+#define CONFIG_IP_NF_NAT_SNMP_BASIC_MODULE 1
+#define CONFIG_IP_NF_NAT_IRC_MODULE 1
+#define CONFIG_IP_NF_NAT_FTP_MODULE 1
+#define CONFIG_IP_NF_NAT_TFTP_MODULE 1
+#define CONFIG_IP_NF_NAT_AMANDA_MODULE 1
+#define CONFIG_IP_NF_NAT_PPTP_MODULE 1
+#define CONFIG_IP_NF_NAT_H323_MODULE 1
+#define CONFIG_IP_NF_MANGLE_MODULE 1
+#define CONFIG_IP_NF_TARGET_TOS_MODULE 1
+#define CONFIG_IP_NF_TARGET_ECN_MODULE 1
+#define CONFIG_IP_NF_TARGET_DSCP_MODULE 1
+#define CONFIG_IP_NF_TARGET_TTL_MODULE 1
+#define CONFIG_IP_NF_TARGET_CLUSTERIP_MODULE 1
+#define CONFIG_IP_NF_RAW_MODULE 1
+#define CONFIG_IP_NF_ARPTABLES_MODULE 1
+#define CONFIG_IP_NF_ARPFILTER_MODULE 1
+#define CONFIG_IP_NF_ARP_MANGLE_MODULE 1
/*
- * Disk-On-Chip Device Drivers
+ * IPv6: Netfilter Configuration (EXPERIMENTAL)
*/
-#define CONFIG_MTD_DOC2000_MODULE 1
-#undef CONFIG_MTD_DOC2001
-#define CONFIG_MTD_DOC2001PLUS_MODULE 1
-#define CONFIG_MTD_DOCPROBE_MODULE 1
-#undef CONFIG_MTD_DOCPROBE_ADVANCED
-#define CONFIG_MTD_DOCPROBE_ADDRESS 0x0
+#define CONFIG_IP6_NF_QUEUE_MODULE 1
+#define CONFIG_IP6_NF_IPTABLES_MODULE 1
+#define CONFIG_IP6_NF_MATCH_RT_MODULE 1
+#define CONFIG_IP6_NF_MATCH_OPTS_MODULE 1
+#define CONFIG_IP6_NF_MATCH_FRAG_MODULE 1
+#define CONFIG_IP6_NF_MATCH_HL_MODULE 1
+#define CONFIG_IP6_NF_MATCH_OWNER_MODULE 1
+#define CONFIG_IP6_NF_MATCH_IPV6HEADER_MODULE 1
+#define CONFIG_IP6_NF_MATCH_AH_MODULE 1
+#define CONFIG_IP6_NF_MATCH_EUI64_MODULE 1
+#define CONFIG_IP6_NF_FILTER_MODULE 1
+#define CONFIG_IP6_NF_TARGET_LOG_MODULE 1
+#define CONFIG_IP6_NF_TARGET_REJECT_MODULE 1
+#define CONFIG_IP6_NF_MANGLE_MODULE 1
+#define CONFIG_IP6_NF_TARGET_HL_MODULE 1
+#define CONFIG_IP6_NF_RAW_MODULE 1
/*
- * NAND Flash Device Drivers
+ * DECnet: Netfilter Configuration
*/
-#define CONFIG_MTD_NAND_MODULE 1
-#undef CONFIG_MTD_NAND_VERIFY_WRITE
-#define CONFIG_MTD_NAND_IDS_MODULE 1
+#undef CONFIG_DECNET_NF_GRABULATOR
/*
- * Parallel port support
+ * Bridge: Netfilter Configuration
*/
-#define CONFIG_PARPORT_MODULE 1
-#define CONFIG_PARPORT_PC_MODULE 1
-#define CONFIG_PARPORT_PC_CML1_MODULE 1
-#define CONFIG_PARPORT_SERIAL_MODULE 1
-#undef CONFIG_PARPORT_PC_FIFO
-#undef CONFIG_PARPORT_PC_SUPERIO
-#define CONFIG_PARPORT_PC_PCMCIA_MODULE 1
-#undef CONFIG_PARPORT_OTHER
-#define CONFIG_PARPORT_1284 1
+#define CONFIG_BRIDGE_NF_EBTABLES_MODULE 1
+#define CONFIG_BRIDGE_EBT_BROUTE_MODULE 1
+#define CONFIG_BRIDGE_EBT_T_FILTER_MODULE 1
+#define CONFIG_BRIDGE_EBT_T_NAT_MODULE 1
+#define CONFIG_BRIDGE_EBT_802_3_MODULE 1
+#define CONFIG_BRIDGE_EBT_AMONG_MODULE 1
+#define CONFIG_BRIDGE_EBT_ARP_MODULE 1
+#define CONFIG_BRIDGE_EBT_IP_MODULE 1
+#define CONFIG_BRIDGE_EBT_LIMIT_MODULE 1
+#define CONFIG_BRIDGE_EBT_MARK_MODULE 1
+#define CONFIG_BRIDGE_EBT_PKTTYPE_MODULE 1
+#define CONFIG_BRIDGE_EBT_STP_MODULE 1
+#define CONFIG_BRIDGE_EBT_VLAN_MODULE 1
+#define CONFIG_BRIDGE_EBT_ARPREPLY_MODULE 1
+#define CONFIG_BRIDGE_EBT_DNAT_MODULE 1
+#define CONFIG_BRIDGE_EBT_MARK_T_MODULE 1
+#define CONFIG_BRIDGE_EBT_REDIRECT_MODULE 1
+#define CONFIG_BRIDGE_EBT_SNAT_MODULE 1
+#define CONFIG_BRIDGE_EBT_LOG_MODULE 1
+#define CONFIG_BRIDGE_EBT_ULOG_MODULE 1
/*
- * Plug and Play support
+ * DCCP Configuration (EXPERIMENTAL)
*/
-#define CONFIG_PNP 1
-#undef CONFIG_PNP_DEBUG
+#define CONFIG_IP_DCCP_MODULE 1
+#define CONFIG_INET_DCCP_DIAG_MODULE 1
+#define CONFIG_IP_DCCP_ACKVEC 1
/*
- * Protocols
+ * DCCP CCIDs Configuration (EXPERIMENTAL)
*/
-#define CONFIG_ISAPNP 1
-#undef CONFIG_PNPBIOS
+#define CONFIG_IP_DCCP_CCID2_MODULE 1
+#define CONFIG_IP_DCCP_CCID3_MODULE 1
+#define CONFIG_IP_DCCP_TFRC_LIB_MODULE 1
/*
- * Block devices
+ * DCCP Kernel Hacking
*/
-#define CONFIG_BLK_DEV_FD_MODULE 1
-#undef CONFIG_BLK_DEV_XD
-#undef CONFIG_PARIDE
-#define CONFIG_BLK_CPQ_DA_MODULE 1
-#define CONFIG_BLK_CPQ_CISS_DA_MODULE 1
-#define CONFIG_CISS_SCSI_TAPE 1
-#define CONFIG_BLK_DEV_DAC960_MODULE 1
-#define CONFIG_BLK_DEV_UMEM_MODULE 1
-#define CONFIG_BLK_DEV_LOOP_MODULE 1
-#define CONFIG_BLK_DEV_CRYPTOLOOP_MODULE 1
-#define CONFIG_BLK_DEV_NBD_MODULE 1
-#define CONFIG_BLK_DEV_CARMEL_MODULE 1
-#define CONFIG_BLK_DEV_RAM 1
-#define CONFIG_BLK_DEV_RAM_SIZE 16384
-#define CONFIG_BLK_DEV_INITRD 1
-#define CONFIG_LBD 1
+#undef CONFIG_IP_DCCP_DEBUG
/*
- * ATA/ATAPI/MFM/RLL support
+ * SCTP Configuration (EXPERIMENTAL)
*/
-#define CONFIG_IDE 1
-#define CONFIG_BLK_DEV_IDE 1
+#define CONFIG_IP_SCTP_MODULE 1
+#undef CONFIG_SCTP_DBG_MSG
+#undef CONFIG_SCTP_DBG_OBJCNT
+#undef CONFIG_SCTP_HMAC_NONE
+#undef CONFIG_SCTP_HMAC_SHA1
+#define CONFIG_SCTP_HMAC_MD5 1
/*
- * Please see Documentation/ide.txt for help/info on IDE drives
+ * TIPC Configuration (EXPERIMENTAL)
*/
-#undef CONFIG_BLK_DEV_HD_IDE
-#define CONFIG_BLK_DEV_IDEDISK 1
-#define CONFIG_IDEDISK_MULTI_MODE 1
-#undef CONFIG_IDEDISK_STROKE
-#define CONFIG_BLK_DEV_IDECS_MODULE 1
-#define CONFIG_BLK_DEV_IDECD 1
-#define CONFIG_BLK_DEV_IDETAPE_MODULE 1
-#define CONFIG_BLK_DEV_IDEFLOPPY 1
-#undef CONFIG_BLK_DEV_IDESCSI
-#undef CONFIG_IDE_TASK_IOCTL
-#undef CONFIG_IDE_TASKFILE_IO
+#define CONFIG_TIPC_MODULE 1
+#undef CONFIG_TIPC_ADVANCED
+#undef CONFIG_TIPC_DEBUG
+#define CONFIG_ATM_MODULE 1
+#define CONFIG_ATM_CLIP_MODULE 1
+#undef CONFIG_ATM_CLIP_NO_ICMP
+#define CONFIG_ATM_LANE_MODULE 1
+#undef CONFIG_ATM_MPOA
+#define CONFIG_ATM_BR2684_MODULE 1
+#undef CONFIG_ATM_BR2684_IPFILTER
+#define CONFIG_BRIDGE_MODULE 1
+#define CONFIG_VLAN_8021Q_MODULE 1
+#define CONFIG_DECNET_MODULE 1
+#define CONFIG_DECNET_ROUTER 1
+#define CONFIG_DECNET_ROUTE_FWMARK 1
+#define CONFIG_LLC 1
+#undef CONFIG_LLC2
+#define CONFIG_IPX_MODULE 1
+#undef CONFIG_IPX_INTERN
+#define CONFIG_ATALK_MODULE 1
+#define CONFIG_DEV_APPLETALK 1
+#undef CONFIG_LTPC
+#undef CONFIG_COPS
+#define CONFIG_IPDDP_MODULE 1
+#define CONFIG_IPDDP_ENCAP 1
+#define CONFIG_IPDDP_DECAP 1
+#undef CONFIG_X25
+#undef CONFIG_LAPB
+#define CONFIG_NET_DIVERT 1
+#undef CONFIG_ECONET
+#define CONFIG_WAN_ROUTER_MODULE 1
/*
- * IDE chipset support/bugfixes
+ * QoS and/or fair queueing
*/
-#define CONFIG_IDE_GENERIC 1
-#undef CONFIG_BLK_DEV_CMD640
-#define CONFIG_BLK_DEV_IDEPNP 1
-#define CONFIG_BLK_DEV_IDEPCI 1
-#define CONFIG_IDEPCI_SHARE_IRQ 1
-#undef CONFIG_BLK_DEV_OFFBOARD
-#define CONFIG_BLK_DEV_GENERIC 1
-#undef CONFIG_BLK_DEV_OPTI621
-#define CONFIG_BLK_DEV_RZ1000 1
-#define CONFIG_BLK_DEV_IDEDMA_PCI 1
-#undef CONFIG_BLK_DEV_IDEDMA_FORCED
-#define CONFIG_IDEDMA_PCI_AUTO 1
-#undef CONFIG_IDEDMA_ONLYDISK
-#define CONFIG_BLK_DEV_ADMA 1
-#define CONFIG_BLK_DEV_AEC62XX 1
-#define CONFIG_BLK_DEV_ALI15X3 1
-#undef CONFIG_WDC_ALI15X3
-#define CONFIG_BLK_DEV_AMD74XX 1
-#define CONFIG_BLK_DEV_ATIIXP 1
-#define CONFIG_BLK_DEV_CMD64X 1
-#define CONFIG_BLK_DEV_TRIFLEX 1
-#define CONFIG_BLK_DEV_CY82C693 1
-#define CONFIG_BLK_DEV_CS5520 1
-#define CONFIG_BLK_DEV_CS5530 1
-#define CONFIG_BLK_DEV_HPT34X 1
-#undef CONFIG_HPT34X_AUTODMA
-#define CONFIG_BLK_DEV_HPT366 1
-#undef CONFIG_BLK_DEV_SC1200
-#define CONFIG_BLK_DEV_PIIX 1
-#undef CONFIG_BLK_DEV_NS87415
-#define CONFIG_BLK_DEV_PDC202XX_OLD 1
-#undef CONFIG_PDC202XX_BURST
-#define CONFIG_BLK_DEV_PDC202XX_NEW 1
-#define CONFIG_PDC202XX_FORCE 1
-#define CONFIG_BLK_DEV_SVWKS 1
-#define CONFIG_BLK_DEV_SIIMAGE 1
-#define CONFIG_BLK_DEV_SIS5513 1
-#define CONFIG_BLK_DEV_SLC90E66 1
-#undef CONFIG_BLK_DEV_TRM290
-#define CONFIG_BLK_DEV_VIA82CXXX 1
-#undef CONFIG_IDE_ARM
-#undef CONFIG_IDE_CHIPSETS
-#define CONFIG_BLK_DEV_IDEDMA 1
-#undef CONFIG_IDEDMA_IVB
-#define CONFIG_IDEDMA_AUTO 1
-#undef CONFIG_BLK_DEV_HD
+#define CONFIG_NET_SCHED 1
+#undef CONFIG_NET_SCH_CLK_JIFFIES
+#define CONFIG_NET_SCH_CLK_GETTIMEOFDAY 1
+#undef CONFIG_NET_SCH_CLK_CPU
/*
- * SCSI device support
+ * Queueing/Scheduling
*/
-#define CONFIG_SCSI_MODULE 1
-#define CONFIG_SCSI_PROC_FS 1
+#define CONFIG_NET_SCH_CBQ_MODULE 1
+#define CONFIG_NET_SCH_HTB_MODULE 1
+#define CONFIG_NET_SCH_HFSC_MODULE 1
+#define CONFIG_NET_SCH_ATM_MODULE 1
+#define CONFIG_NET_SCH_PRIO_MODULE 1
+#define CONFIG_NET_SCH_RED_MODULE 1
+#define CONFIG_NET_SCH_SFQ_MODULE 1
+#define CONFIG_NET_SCH_TEQL_MODULE 1
+#define CONFIG_NET_SCH_TBF_MODULE 1
+#define CONFIG_NET_SCH_GRED_MODULE 1
+#define CONFIG_NET_SCH_DSMARK_MODULE 1
+#define CONFIG_NET_SCH_NETEM_MODULE 1
+#define CONFIG_NET_SCH_INGRESS_MODULE 1
/*
- * SCSI support type (disk, tape, CD-ROM)
+ * Classification
*/
-#define CONFIG_BLK_DEV_SD_MODULE 1
-#define CONFIG_CHR_DEV_ST_MODULE 1
-#define CONFIG_CHR_DEV_OSST_MODULE 1
-#define CONFIG_BLK_DEV_SR_MODULE 1
-#define CONFIG_BLK_DEV_SR_VENDOR 1
-#define CONFIG_CHR_DEV_SG_MODULE 1
+#define CONFIG_NET_CLS 1
+#define CONFIG_NET_CLS_BASIC_MODULE 1
+#define CONFIG_NET_CLS_TCINDEX_MODULE 1
+#define CONFIG_NET_CLS_ROUTE4_MODULE 1
+#define CONFIG_NET_CLS_ROUTE 1
+#define CONFIG_NET_CLS_FW_MODULE 1
+#define CONFIG_NET_CLS_U32_MODULE 1
+#define CONFIG_CLS_U32_PERF 1
+#define CONFIG_CLS_U32_MARK 1
+#define CONFIG_NET_CLS_RSVP_MODULE 1
+#define CONFIG_NET_CLS_RSVP6_MODULE 1
+#define CONFIG_NET_EMATCH 1
+#define CONFIG_NET_EMATCH_STACK 32
+#define CONFIG_NET_EMATCH_CMP_MODULE 1
+#define CONFIG_NET_EMATCH_NBYTE_MODULE 1
+#define CONFIG_NET_EMATCH_U32_MODULE 1
+#define CONFIG_NET_EMATCH_META_MODULE 1
+#define CONFIG_NET_EMATCH_TEXT_MODULE 1
+#undef CONFIG_NET_CLS_ACT
+#define CONFIG_NET_CLS_POLICE 1
+#define CONFIG_NET_CLS_IND 1
+#define CONFIG_NET_ESTIMATOR 1
/*
- * Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+ * Network testing
*/
-#undef CONFIG_SCSI_MULTI_LUN
-#define CONFIG_SCSI_CONSTANTS 1
-#define CONFIG_SCSI_LOGGING 1
+#define CONFIG_NET_PKTGEN_MODULE 1
+#undef CONFIG_HAMRADIO
+#define CONFIG_IRDA_MODULE 1
/*
- * SCSI Transport Attributes
+ * IrDA protocols
*/
-#define CONFIG_SCSI_SPI_ATTRS_MODULE 1
-#define CONFIG_SCSI_FC_ATTRS_MODULE 1
+#define CONFIG_IRLAN_MODULE 1
+#define CONFIG_IRNET_MODULE 1
+#define CONFIG_IRCOMM_MODULE 1
+#undef CONFIG_IRDA_ULTRA
/*
- * SCSI low-level drivers
+ * IrDA options
*/
-#define CONFIG_BLK_DEV_3W_XXXX_RAID_MODULE 1
-#undef CONFIG_SCSI_7000FASST
-#define CONFIG_SCSI_ACARD_MODULE 1
-#define CONFIG_SCSI_AHA152X_MODULE 1
-#define CONFIG_SCSI_AHA1542_MODULE 1
-#define CONFIG_SCSI_AACRAID_MODULE 1
-#define CONFIG_SCSI_AIC7XXX_MODULE 1
-#define CONFIG_AIC7XXX_CMDS_PER_DEVICE 4
-#define CONFIG_AIC7XXX_RESET_DELAY_MS 15000
-#undef CONFIG_AIC7XXX_BUILD_FIRMWARE
-#undef CONFIG_AIC7XXX_DEBUG_ENABLE
-#define CONFIG_AIC7XXX_DEBUG_MASK 0
-#undef CONFIG_AIC7XXX_REG_PRETTY_PRINT
-#define CONFIG_SCSI_AIC7XXX_OLD_MODULE 1
-#define CONFIG_SCSI_AIC79XX_MODULE 1
-#define CONFIG_AIC79XX_CMDS_PER_DEVICE 4
-#define CONFIG_AIC79XX_RESET_DELAY_MS 15000
-#undef CONFIG_AIC79XX_BUILD_FIRMWARE
-#undef CONFIG_AIC79XX_ENABLE_RD_STRM
-#undef CONFIG_AIC79XX_DEBUG_ENABLE
-#define CONFIG_AIC79XX_DEBUG_MASK 0
-#undef CONFIG_AIC79XX_REG_PRETTY_PRINT
-#undef CONFIG_SCSI_DPT_I2O
-#define CONFIG_SCSI_ADVANSYS_MODULE 1
-#define CONFIG_SCSI_IN2000_MODULE 1
-#define CONFIG_SCSI_MEGARAID_MODULE 1
-#define CONFIG_SCSI_SATA 1
-#define CONFIG_SCSI_SATA_SVW_MODULE 1
-#define CONFIG_SCSI_ATA_PIIX_MODULE 1
-#define CONFIG_SCSI_SATA_PROMISE_MODULE 1
-#define CONFIG_SCSI_SATA_SX4_MODULE 1
-#define CONFIG_SCSI_SATA_SIL_MODULE 1
-#define CONFIG_SCSI_SATA_SIS_MODULE 1
-#define CONFIG_SCSI_SATA_VIA_MODULE 1
-#define CONFIG_SCSI_SATA_VITESSE_MODULE 1
-#define CONFIG_SCSI_BUSLOGIC_MODULE 1
-#undef CONFIG_SCSI_OMIT_FLASHPOINT
-#undef CONFIG_SCSI_CPQFCTS
-#undef CONFIG_SCSI_DMX3191D
-#undef CONFIG_SCSI_DTC3280
-#undef CONFIG_SCSI_EATA
-#undef CONFIG_SCSI_EATA_PIO
-#define CONFIG_SCSI_FUTURE_DOMAIN_MODULE 1
-#define CONFIG_SCSI_GDTH_MODULE 1
-#undef CONFIG_SCSI_GENERIC_NCR5380
-#undef CONFIG_SCSI_GENERIC_NCR5380_MMIO
-#define CONFIG_SCSI_IPS_MODULE 1
-#define CONFIG_SCSI_INIA100_MODULE 1
-#define CONFIG_SCSI_PPA_MODULE 1
-#define CONFIG_SCSI_IMM_MODULE 1
-#undef CONFIG_SCSI_IZIP_EPP16
-#undef CONFIG_SCSI_IZIP_SLOW_CTR
-#undef CONFIG_SCSI_NCR53C406A
-#define CONFIG_SCSI_SYM53C8XX_2_MODULE 1
-#define CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE 1
-#define CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS 16
-#define CONFIG_SCSI_SYM53C8XX_MAX_TAGS 64
-#undef CONFIG_SCSI_SYM53C8XX_IOMAPPED
-#undef CONFIG_SCSI_IPR
-#undef CONFIG_SCSI_PAS16
-#undef CONFIG_SCSI_PSI240I
-#define CONFIG_SCSI_QLOGIC_FAS_MODULE 1
-#define CONFIG_SCSI_QLOGIC_ISP_MODULE 1
-#undef CONFIG_SCSI_QLOGIC_FC
-#define CONFIG_SCSI_QLOGIC_1280_MODULE 1
-#define CONFIG_SCSI_QLA2XXX_MODULE 1
-#define CONFIG_SCSI_QLA21XX_MODULE 1
-#define CONFIG_SCSI_QLA22XX_MODULE 1
-#define CONFIG_SCSI_QLA2300_MODULE 1
-#define CONFIG_SCSI_QLA2322_MODULE 1
-#define CONFIG_SCSI_QLA6312_MODULE 1
-#define CONFIG_SCSI_QLA6322_MODULE 1
-#undef CONFIG_SCSI_SYM53C416
-#undef CONFIG_SCSI_DC395x
-#define CONFIG_SCSI_DC390T_MODULE 1
-#undef CONFIG_SCSI_T128
-#undef CONFIG_SCSI_U14_34F
-#undef CONFIG_SCSI_ULTRASTOR
-#undef CONFIG_SCSI_NSP32
-#undef CONFIG_SCSI_DEBUG
+#define CONFIG_IRDA_CACHE_LAST_LSAP 1
+#define CONFIG_IRDA_FAST_RR 1
+#undef CONFIG_IRDA_DEBUG
/*
- * PCMCIA SCSI adapter support
+ * Infrared-port device drivers
*/
-#define CONFIG_PCMCIA_AHA152X_MODULE 1
-#define CONFIG_PCMCIA_FDOMAIN_MODULE 1
-#define CONFIG_PCMCIA_NINJA_SCSI_MODULE 1
-#define CONFIG_PCMCIA_QLOGIC_MODULE 1
-#define CONFIG_PCMCIA_SYM53C500_MODULE 1
/*
- * Old CD-ROM drivers (not SCSI, not IDE)
+ * SIR device drivers
*/
-#undef CONFIG_CD_NO_IDESCSI
+#define CONFIG_IRTTY_SIR_MODULE 1
/*
- * Multi-device support (RAID and LVM)
+ * Dongle support
*/
-#define CONFIG_MD 1
-#define CONFIG_BLK_DEV_MD 1
-#define CONFIG_MD_LINEAR_MODULE 1
-#define CONFIG_MD_RAID0_MODULE 1
-#define CONFIG_MD_RAID1_MODULE 1
-#define CONFIG_MD_RAID5_MODULE 1
-#define CONFIG_MD_RAID6_MODULE 1
-#define CONFIG_MD_MULTIPATH_MODULE 1
-#define CONFIG_BLK_DEV_DM_MODULE 1
-#define CONFIG_DM_CRYPT_MODULE 1
+#define CONFIG_DONGLE 1
+#define CONFIG_ESI_DONGLE_MODULE 1
+#define CONFIG_ACTISYS_DONGLE_MODULE 1
+#define CONFIG_TEKRAM_DONGLE_MODULE 1
+#define CONFIG_TOIM3232_DONGLE_MODULE 1
+#define CONFIG_LITELINK_DONGLE_MODULE 1
+#define CONFIG_MA600_DONGLE_MODULE 1
+#define CONFIG_GIRBIL_DONGLE_MODULE 1
+#define CONFIG_MCP2120_DONGLE_MODULE 1
+#define CONFIG_OLD_BELKIN_DONGLE_MODULE 1
+#define CONFIG_ACT200L_DONGLE_MODULE 1
/*
- * Fusion MPT device support
+ * Old SIR device drivers
*/
-#define CONFIG_FUSION_MODULE 1
-#define CONFIG_FUSION_MAX_SGE 40
-#undef CONFIG_FUSION_ISENSE
-#define CONFIG_FUSION_CTL_MODULE 1
-#define CONFIG_FUSION_LAN_MODULE 1
+#define CONFIG_IRPORT_SIR_MODULE 1
/*
- * IEEE 1394 (FireWire) support
+ * Old Serial dongle support
*/
-#define CONFIG_IEEE1394_MODULE 1
+#undef CONFIG_DONGLE_OLD
/*
- * Subsystem Options
+ * FIR device drivers
*/
-#undef CONFIG_IEEE1394_VERBOSEDEBUG
-#define CONFIG_IEEE1394_OUI_DB 1
-#undef CONFIG_IEEE1394_EXTRA_CONFIG_ROMS
+#define CONFIG_USB_IRDA_MODULE 1
+#define CONFIG_SIGMATEL_FIR_MODULE 1
+#define CONFIG_NSC_FIR_MODULE 1
+#define CONFIG_WINBOND_FIR_MODULE 1
+#define CONFIG_TOSHIBA_FIR_MODULE 1
+#define CONFIG_SMC_IRCC_FIR_MODULE 1
+#define CONFIG_ALI_FIR_MODULE 1
+#define CONFIG_VLSI_FIR_MODULE 1
+#define CONFIG_VIA_FIR_MODULE 1
+#define CONFIG_BT_MODULE 1
+#define CONFIG_BT_L2CAP_MODULE 1
+#define CONFIG_BT_SCO_MODULE 1
+#define CONFIG_BT_RFCOMM_MODULE 1
+#define CONFIG_BT_RFCOMM_TTY 1
+#define CONFIG_BT_BNEP_MODULE 1
+#define CONFIG_BT_BNEP_MC_FILTER 1
+#define CONFIG_BT_BNEP_PROTO_FILTER 1
+#define CONFIG_BT_CMTP_MODULE 1
+#define CONFIG_BT_HIDP_MODULE 1
/*
- * Device Drivers
+ * Bluetooth device drivers
*/
-#undef CONFIG_IEEE1394_PCILYNX
-#define CONFIG_IEEE1394_OHCI1394_MODULE 1
+#define CONFIG_BT_HCIUSB_MODULE 1
+#define CONFIG_BT_HCIUSB_SCO 1
+#define CONFIG_BT_HCIUART_MODULE 1
+#define CONFIG_BT_HCIUART_H4 1
+#define CONFIG_BT_HCIUART_BCSP 1
+#define CONFIG_BT_HCIBCM203X_MODULE 1
+#define CONFIG_BT_HCIBPA10X_MODULE 1
+#define CONFIG_BT_HCIBFUSB_MODULE 1
+#define CONFIG_BT_HCIDTL1_MODULE 1
+#define CONFIG_BT_HCIBT3C_MODULE 1
+#define CONFIG_BT_HCIBLUECARD_MODULE 1
+#define CONFIG_BT_HCIBTUART_MODULE 1
+#define CONFIG_BT_HCIVHCI_MODULE 1
+#define CONFIG_IEEE80211_MODULE 1
+#undef CONFIG_IEEE80211_DEBUG
+#define CONFIG_IEEE80211_CRYPT_WEP_MODULE 1
+#define CONFIG_IEEE80211_CRYPT_CCMP_MODULE 1
+#define CONFIG_IEEE80211_CRYPT_TKIP_MODULE 1
+#define CONFIG_IEEE80211_SOFTMAC_MODULE 1
+#define CONFIG_IEEE80211_SOFTMAC_DEBUG 1
+#define CONFIG_TUX_MODULE 1
/*
- * Protocol Drivers
+ * TUX options
*/
-#define CONFIG_IEEE1394_VIDEO1394_MODULE 1
-#define CONFIG_IEEE1394_SBP2_MODULE 1
-#undef CONFIG_IEEE1394_SBP2_PHYS_DMA
-#undef CONFIG_IEEE1394_ETH1394
-#define CONFIG_IEEE1394_DV1394_MODULE 1
-#define CONFIG_IEEE1394_RAWIO_MODULE 1
-#define CONFIG_IEEE1394_CMP_MODULE 1
-#define CONFIG_IEEE1394_AMDTP_MODULE 1
+#define CONFIG_TUX_EXTCGI 1
+#define CONFIG_TUX_EXTENDED_LOG 1
+#undef CONFIG_TUX_DEBUG
+#define CONFIG_WIRELESS_EXT 1
/*
- * I2O device support
+ * Device Drivers
*/
-#define CONFIG_I2O_MODULE 1
-#define CONFIG_I2O_CONFIG_MODULE 1
-#define CONFIG_I2O_BLOCK_MODULE 1
-#define CONFIG_I2O_SCSI_MODULE 1
-#define CONFIG_I2O_PROC_MODULE 1
/*
- * Networking support
+ * Generic Driver Options
*/
-#define CONFIG_NET 1
+#define CONFIG_STANDALONE 1
+#define CONFIG_PREVENT_FIRMWARE_BUILD 1
+#define CONFIG_FW_LOADER 1
+#undef CONFIG_DEBUG_DRIVER
/*
- * Networking options
+ * Connector - unified userspace <-> kernelspace linker
*/
-#define CONFIG_PACKET 1
-#define CONFIG_PACKET_MMAP 1
-#define CONFIG_NETLINK_DEV 1
-#define CONFIG_UNIX 1
-#define CONFIG_NET_KEY_MODULE 1
-#define CONFIG_INET 1
-#define CONFIG_IP_MULTICAST 1
-#define CONFIG_IP_ADVANCED_ROUTER 1
-#define CONFIG_IP_MULTIPLE_TABLES 1
-#define CONFIG_IP_ROUTE_FWMARK 1
-#define CONFIG_IP_ROUTE_NAT 1
-#define CONFIG_IP_ROUTE_MULTIPATH 1
-#define CONFIG_IP_ROUTE_TOS 1
-#define CONFIG_IP_ROUTE_VERBOSE 1
-#undef CONFIG_IP_PNP
-#define CONFIG_NET_IPIP_MODULE 1
-#define CONFIG_NET_IPGRE_MODULE 1
-#define CONFIG_NET_IPGRE_BROADCAST 1
-#define CONFIG_IP_MROUTE 1
-#define CONFIG_IP_PIMSM_V1 1
-#define CONFIG_IP_PIMSM_V2 1
-#undef CONFIG_ARPD
-#define CONFIG_SYN_COOKIES 1
-#define CONFIG_INET_AH_MODULE 1
-#define CONFIG_INET_ESP_MODULE 1
-#define CONFIG_INET_IPCOMP_MODULE 1
+#define CONFIG_CONNECTOR_MODULE 1
/*
- * IP: Virtual Server Configuration
+ * Memory Technology Devices (MTD)
*/
-#define CONFIG_IP_VS_MODULE 1
-#undef CONFIG_IP_VS_DEBUG
-#define CONFIG_IP_VS_TAB_BITS 12
+#define CONFIG_MTD_MODULE 1
+#undef CONFIG_MTD_DEBUG
+#define CONFIG_MTD_CONCAT_MODULE 1
+#define CONFIG_MTD_PARTITIONS 1
+#define CONFIG_MTD_REDBOOT_PARTS_MODULE 1
+#define CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK -1
+#undef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
+#undef CONFIG_MTD_REDBOOT_PARTS_READONLY
+#define CONFIG_MTD_CMDLINE_PARTS 1
/*
- * IPVS transport protocol load balancing support
+ * User Modules And Translation Layers
*/
-#define CONFIG_IP_VS_PROTO_TCP 1
-#define CONFIG_IP_VS_PROTO_UDP 1
-#define CONFIG_IP_VS_PROTO_ESP 1
-#define CONFIG_IP_VS_PROTO_AH 1
+#define CONFIG_MTD_CHAR_MODULE 1
+#define CONFIG_MTD_BLOCK_MODULE 1
+#define CONFIG_MTD_BLOCK_RO_MODULE 1
+#define CONFIG_FTL_MODULE 1
+#define CONFIG_NFTL_MODULE 1
+#define CONFIG_NFTL_RW 1
+#define CONFIG_INFTL_MODULE 1
+#define CONFIG_RFD_FTL_MODULE 1
/*
- * IPVS scheduler
+ * RAM/ROM/Flash chip drivers
*/
-#define CONFIG_IP_VS_RR_MODULE 1
-#define CONFIG_IP_VS_WRR_MODULE 1
-#define CONFIG_IP_VS_LC_MODULE 1
-#define CONFIG_IP_VS_WLC_MODULE 1
-#define CONFIG_IP_VS_LBLC_MODULE 1
-#define CONFIG_IP_VS_LBLCR_MODULE 1
-#define CONFIG_IP_VS_DH_MODULE 1
-#define CONFIG_IP_VS_SH_MODULE 1
-#define CONFIG_IP_VS_SED_MODULE 1
-#define CONFIG_IP_VS_NQ_MODULE 1
+#define CONFIG_MTD_CFI_MODULE 1
+#define CONFIG_MTD_JEDECPROBE_MODULE 1
+#define CONFIG_MTD_GEN_PROBE_MODULE 1
+#undef CONFIG_MTD_CFI_ADV_OPTIONS
+#define CONFIG_MTD_MAP_BANK_WIDTH_1 1
+#define CONFIG_MTD_MAP_BANK_WIDTH_2 1
+#define CONFIG_MTD_MAP_BANK_WIDTH_4 1
+#undef CONFIG_MTD_MAP_BANK_WIDTH_8
+#undef CONFIG_MTD_MAP_BANK_WIDTH_16
+#undef CONFIG_MTD_MAP_BANK_WIDTH_32
+#define CONFIG_MTD_CFI_I1 1
+#define CONFIG_MTD_CFI_I2 1
+#undef CONFIG_MTD_CFI_I4
+#undef CONFIG_MTD_CFI_I8
+#define CONFIG_MTD_CFI_INTELEXT_MODULE 1
+#define CONFIG_MTD_CFI_AMDSTD_MODULE 1
+#define CONFIG_MTD_CFI_STAA_MODULE 1
+#define CONFIG_MTD_CFI_UTIL_MODULE 1
+#define CONFIG_MTD_RAM_MODULE 1
+#define CONFIG_MTD_ROM_MODULE 1
+#define CONFIG_MTD_ABSENT_MODULE 1
+#undef CONFIG_MTD_OBSOLETE_CHIPS
/*
- * IPVS application helper
+ * Mapping drivers for chip access
*/
-#define CONFIG_IP_VS_FTP_MODULE 1
-#define CONFIG_IPV6_MODULE 1
-#define CONFIG_IPV6_PRIVACY 1
-#define CONFIG_INET6_AH_MODULE 1
-#define CONFIG_INET6_ESP_MODULE 1
-#define CONFIG_INET6_IPCOMP_MODULE 1
-#define CONFIG_IPV6_TUNNEL_MODULE 1
-#define CONFIG_NETFILTER 1
-#undef CONFIG_NETFILTER_DEBUG
-#define CONFIG_BRIDGE_NETFILTER 1
+#define CONFIG_MTD_COMPLEX_MAPPINGS 1
+#undef CONFIG_MTD_PHYSMAP
+#undef CONFIG_MTD_PNC2000
+#define CONFIG_MTD_SC520CDP_MODULE 1
+#define CONFIG_MTD_NETSC520_MODULE 1
+#define CONFIG_MTD_TS5500_MODULE 1
+#undef CONFIG_MTD_SBC_GXX
+#undef CONFIG_MTD_AMD76XROM
+#undef CONFIG_MTD_ICHXROM
+#define CONFIG_MTD_SCB2_FLASH_MODULE 1
+#undef CONFIG_MTD_NETtel
+#undef CONFIG_MTD_DILNETPC
+#undef CONFIG_MTD_L440GX
+#define CONFIG_MTD_PCI_MODULE 1
+#undef CONFIG_MTD_PLATRAM
/*
- * IP: Netfilter Configuration
+ * Self-contained MTD device drivers
*/
-#define CONFIG_IP_NF_CONNTRACK_MODULE 1
-#define CONFIG_IP_NF_FTP_MODULE 1
-#define CONFIG_IP_NF_IRC_MODULE 1
-#define CONFIG_IP_NF_TFTP_MODULE 1
-#define CONFIG_IP_NF_AMANDA_MODULE 1
-#define CONFIG_IP_NF_QUEUE_MODULE 1
-#define CONFIG_IP_NF_IPTABLES_MODULE 1
-#define CONFIG_IP_NF_MATCH_LIMIT_MODULE 1
-#define CONFIG_IP_NF_MATCH_IPRANGE_MODULE 1
-#define CONFIG_IP_NF_MATCH_MAC_MODULE 1
-#define CONFIG_IP_NF_MATCH_PKTTYPE_MODULE 1
-#define CONFIG_IP_NF_MATCH_MARK_MODULE 1
-#define CONFIG_IP_NF_MATCH_MULTIPORT_MODULE 1
-#define CONFIG_IP_NF_MATCH_TOS_MODULE 1
-#define CONFIG_IP_NF_MATCH_RECENT_MODULE 1
-#define CONFIG_IP_NF_MATCH_ECN_MODULE 1
-#define CONFIG_IP_NF_MATCH_DSCP_MODULE 1
-#define CONFIG_IP_NF_MATCH_AH_ESP_MODULE 1
-#define CONFIG_IP_NF_MATCH_LENGTH_MODULE 1
-#define CONFIG_IP_NF_MATCH_TTL_MODULE 1
-#define CONFIG_IP_NF_MATCH_TCPMSS_MODULE 1
-#define CONFIG_IP_NF_MATCH_HELPER_MODULE 1
-#define CONFIG_IP_NF_MATCH_STATE_MODULE 1
-#define CONFIG_IP_NF_MATCH_CONNTRACK_MODULE 1
-#define CONFIG_IP_NF_MATCH_OWNER_MODULE 1
-#define CONFIG_IP_NF_MATCH_PHYSDEV_MODULE 1
-#define CONFIG_IP_NF_FILTER_MODULE 1
-#define CONFIG_IP_NF_TARGET_REJECT_MODULE 1
-#define CONFIG_IP_NF_NAT_MODULE 1
-#define CONFIG_IP_NF_NAT_NEEDED 1
-#define CONFIG_IP_NF_TARGET_MASQUERADE_MODULE 1
-#define CONFIG_IP_NF_TARGET_REDIRECT_MODULE 1
-#define CONFIG_IP_NF_TARGET_NETMAP_MODULE 1
-#define CONFIG_IP_NF_TARGET_SAME_MODULE 1
-#define CONFIG_IP_NF_NAT_LOCAL 1
-#define CONFIG_IP_NF_NAT_SNMP_BASIC_MODULE 1
-#define CONFIG_IP_NF_NAT_IRC_MODULE 1
-#define CONFIG_IP_NF_NAT_FTP_MODULE 1
-#define CONFIG_IP_NF_NAT_TFTP_MODULE 1
-#define CONFIG_IP_NF_NAT_AMANDA_MODULE 1
-#define CONFIG_IP_NF_MANGLE_MODULE 1
-#define CONFIG_IP_NF_TARGET_TOS_MODULE 1
-#define CONFIG_IP_NF_TARGET_ECN_MODULE 1
-#define CONFIG_IP_NF_TARGET_DSCP_MODULE 1
-#define CONFIG_IP_NF_TARGET_MARK_MODULE 1
-#define CONFIG_IP_NF_TARGET_CLASSIFY_MODULE 1
-#define CONFIG_IP_NF_TARGET_LOG_MODULE 1
-#define CONFIG_IP_NF_TARGET_ULOG_MODULE 1
-#define CONFIG_IP_NF_TARGET_TCPMSS_MODULE 1
-#define CONFIG_IP_NF_ARPTABLES_MODULE 1
-#define CONFIG_IP_NF_ARPFILTER_MODULE 1
-#define CONFIG_IP_NF_ARP_MANGLE_MODULE 1
-#undef CONFIG_IP_NF_COMPAT_IPCHAINS
-#undef CONFIG_IP_NF_COMPAT_IPFWADM
-#define CONFIG_IP_NF_TARGET_NOTRACK_MODULE 1
-#define CONFIG_IP_NF_RAW_MODULE 1
+#define CONFIG_MTD_PMC551_MODULE 1
+#undef CONFIG_MTD_PMC551_BUGFIX
+#undef CONFIG_MTD_PMC551_DEBUG
+#undef CONFIG_MTD_SLRAM
+#undef CONFIG_MTD_PHRAM
+#define CONFIG_MTD_MTDRAM_MODULE 1
+#define CONFIG_MTDRAM_TOTAL_SIZE 4096
+#define CONFIG_MTDRAM_ERASE_SIZE 128
+#define CONFIG_MTD_BLOCK2MTD_MODULE 1
/*
- * IPv6: Netfilter Configuration
+ * Disk-On-Chip Device Drivers
*/
-#undef CONFIG_IP6_NF_QUEUE
-#define CONFIG_IP6_NF_IPTABLES_MODULE 1
-#define CONFIG_IP6_NF_MATCH_LIMIT_MODULE 1
-#define CONFIG_IP6_NF_MATCH_MAC_MODULE 1
-#define CONFIG_IP6_NF_MATCH_RT_MODULE 1
-#define CONFIG_IP6_NF_MATCH_OPTS_MODULE 1
-#define CONFIG_IP6_NF_MATCH_FRAG_MODULE 1
-#define CONFIG_IP6_NF_MATCH_HL_MODULE 1
-#define CONFIG_IP6_NF_MATCH_MULTIPORT_MODULE 1
-#define CONFIG_IP6_NF_MATCH_OWNER_MODULE 1
-#define CONFIG_IP6_NF_MATCH_MARK_MODULE 1
-#define CONFIG_IP6_NF_MATCH_IPV6HEADER_MODULE 1
-#define CONFIG_IP6_NF_MATCH_AHESP_MODULE 1
-#define CONFIG_IP6_NF_MATCH_LENGTH_MODULE 1
-#define CONFIG_IP6_NF_MATCH_EUI64_MODULE 1
-#define CONFIG_IP6_NF_FILTER_MODULE 1
-#define CONFIG_IP6_NF_TARGET_LOG_MODULE 1
-#define CONFIG_IP6_NF_MANGLE_MODULE 1
-#define CONFIG_IP6_NF_TARGET_MARK_MODULE 1
-#define CONFIG_IP6_NF_RAW_MODULE 1
+#define CONFIG_MTD_DOC2000_MODULE 1
+#undef CONFIG_MTD_DOC2001
+#define CONFIG_MTD_DOC2001PLUS_MODULE 1
+#define CONFIG_MTD_DOCPROBE_MODULE 1
+#define CONFIG_MTD_DOCECC_MODULE 1
+#undef CONFIG_MTD_DOCPROBE_ADVANCED
+#define CONFIG_MTD_DOCPROBE_ADDRESS 0x0
+
+/*
+ * NAND Flash Device Drivers
+ */
+#define CONFIG_MTD_NAND_MODULE 1
+#undef CONFIG_MTD_NAND_VERIFY_WRITE
+#define CONFIG_MTD_NAND_IDS_MODULE 1
+#undef CONFIG_MTD_NAND_DISKONCHIP
+#define CONFIG_MTD_NAND_NANDSIM_MODULE 1
+
+/*
+ * OneNAND Flash Device Drivers
+ */
+#undef CONFIG_MTD_ONENAND
+
+/*
+ * Parallel port support
+ */
+#define CONFIG_PARPORT_MODULE 1
+#define CONFIG_PARPORT_PC_MODULE 1
+#define CONFIG_PARPORT_SERIAL_MODULE 1
+#undef CONFIG_PARPORT_PC_FIFO
+#undef CONFIG_PARPORT_PC_SUPERIO
+#define CONFIG_PARPORT_PC_PCMCIA_MODULE 1
+#define CONFIG_PARPORT_NOT_PC 1
+#undef CONFIG_PARPORT_GSC
+#define CONFIG_PARPORT_1284 1
+
+/*
+ * Plug and Play support
+ */
+#define CONFIG_PNP 1
+#undef CONFIG_PNP_DEBUG
+
+/*
+ * Protocols
+ */
+#define CONFIG_ISAPNP 1
+#undef CONFIG_PNPBIOS
+#define CONFIG_PNPACPI 1
+
+/*
+ * Block devices
+ */
+#define CONFIG_BLK_DEV_FD_MODULE 1
+#undef CONFIG_BLK_DEV_XD
+#define CONFIG_PARIDE_MODULE 1
+#define CONFIG_PARIDE_PARPORT_MODULE 1
+
+/*
+ * Parallel IDE high-level drivers
+ */
+#define CONFIG_PARIDE_PD_MODULE 1
+#define CONFIG_PARIDE_PCD_MODULE 1
+#define CONFIG_PARIDE_PF_MODULE 1
+#define CONFIG_PARIDE_PT_MODULE 1
+#define CONFIG_PARIDE_PG_MODULE 1
+
+/*
+ * Parallel IDE protocol modules
+ */
+#define CONFIG_PARIDE_ATEN_MODULE 1
+#define CONFIG_PARIDE_BPCK_MODULE 1
+#define CONFIG_PARIDE_BPCK6_MODULE 1
+#define CONFIG_PARIDE_COMM_MODULE 1
+#define CONFIG_PARIDE_DSTR_MODULE 1
+#define CONFIG_PARIDE_FIT2_MODULE 1
+#define CONFIG_PARIDE_FIT3_MODULE 1
+#define CONFIG_PARIDE_EPAT_MODULE 1
+#define CONFIG_PARIDE_EPATC8 1
+#define CONFIG_PARIDE_EPIA_MODULE 1
+#define CONFIG_PARIDE_FRIQ_MODULE 1
+#define CONFIG_PARIDE_FRPW_MODULE 1
+#define CONFIG_PARIDE_KBIC_MODULE 1
+#define CONFIG_PARIDE_KTTI_MODULE 1
+#define CONFIG_PARIDE_ON20_MODULE 1
+#define CONFIG_PARIDE_ON26_MODULE 1
+#define CONFIG_BLK_CPQ_DA_MODULE 1
+#define CONFIG_BLK_CPQ_CISS_DA_MODULE 1
+#define CONFIG_CISS_SCSI_TAPE 1
+#define CONFIG_BLK_DEV_DAC960_MODULE 1
+#define CONFIG_BLK_DEV_UMEM_MODULE 1
+#undef CONFIG_BLK_DEV_COW_COMMON
+#define CONFIG_BLK_DEV_LOOP_MODULE 1
+#define CONFIG_BLK_DEV_CRYPTOLOOP_MODULE 1
+#define CONFIG_BLK_DEV_NBD_MODULE 1
+#define CONFIG_BLK_DEV_SX8_MODULE 1
+#define CONFIG_BLK_DEV_UB_MODULE 1
+#define CONFIG_BLK_DEV_RAM 1
+#define CONFIG_BLK_DEV_RAM_COUNT 16
+#define CONFIG_BLK_DEV_RAM_SIZE 16384
+#define CONFIG_BLK_DEV_INITRD 1
+#define CONFIG_CDROM_PKTCDVD_MODULE 1
+#define CONFIG_CDROM_PKTCDVD_BUFFERS 8
+#undef CONFIG_CDROM_PKTCDVD_WCACHE
+#define CONFIG_ATA_OVER_ETH_MODULE 1
+
+/*
+ * ATA/ATAPI/MFM/RLL support
+ */
+#define CONFIG_IDE 1
+#define CONFIG_BLK_DEV_IDE 1
+
+/*
+ * Please see Documentation/ide.txt for help/info on IDE drives
+ */
+#undef CONFIG_BLK_DEV_IDE_SATA
+#undef CONFIG_BLK_DEV_HD_IDE
+#define CONFIG_BLK_DEV_IDEDISK 1
+#define CONFIG_IDEDISK_MULTI_MODE 1
+#define CONFIG_BLK_DEV_IDECS_MODULE 1
+#define CONFIG_BLK_DEV_IDECD 1
+#undef CONFIG_BLK_DEV_IDETAPE
+#define CONFIG_BLK_DEV_IDEFLOPPY 1
+#define CONFIG_BLK_DEV_IDESCSI_MODULE 1
+#define CONFIG_IDE_TASK_IOCTL 1
+
+/*
+ * IDE chipset support/bugfixes
+ */
+#define CONFIG_IDE_GENERIC 1
+#define CONFIG_BLK_DEV_CMD640 1
+#define CONFIG_BLK_DEV_CMD640_ENHANCED 1
+#define CONFIG_BLK_DEV_IDEPNP 1
+#define CONFIG_BLK_DEV_IDEPCI 1
+#define CONFIG_IDEPCI_SHARE_IRQ 1
+#undef CONFIG_BLK_DEV_OFFBOARD
+#define CONFIG_BLK_DEV_GENERIC 1
+#undef CONFIG_BLK_DEV_OPTI621
+#define CONFIG_BLK_DEV_RZ1000 1
+#define CONFIG_BLK_DEV_IDEDMA_PCI 1
+#undef CONFIG_BLK_DEV_IDEDMA_FORCED
+#define CONFIG_IDEDMA_PCI_AUTO 1
+#undef CONFIG_IDEDMA_ONLYDISK
+#define CONFIG_BLK_DEV_AEC62XX 1
+#define CONFIG_BLK_DEV_ALI15X3 1
+#undef CONFIG_WDC_ALI15X3
+#define CONFIG_BLK_DEV_AMD74XX 1
+#define CONFIG_BLK_DEV_ATIIXP 1
+#define CONFIG_BLK_DEV_CMD64X 1
+#define CONFIG_BLK_DEV_TRIFLEX 1
+#define CONFIG_BLK_DEV_CY82C693 1
+#define CONFIG_BLK_DEV_CS5520 1
+#define CONFIG_BLK_DEV_CS5530 1
+#define CONFIG_BLK_DEV_CS5535 1
+#define CONFIG_BLK_DEV_HPT34X 1
+#undef CONFIG_HPT34X_AUTODMA
+#define CONFIG_BLK_DEV_HPT366 1
+#undef CONFIG_BLK_DEV_SC1200
+#define CONFIG_BLK_DEV_PIIX 1
+#define CONFIG_BLK_DEV_IT821X 1
+#undef CONFIG_BLK_DEV_NS87415
+#define CONFIG_BLK_DEV_PDC202XX_OLD 1
+#undef CONFIG_PDC202XX_BURST
+#define CONFIG_BLK_DEV_PDC202XX_NEW 1
+#define CONFIG_BLK_DEV_SVWKS 1
+#define CONFIG_BLK_DEV_SIIMAGE 1
+#define CONFIG_BLK_DEV_SIS5513 1
+#define CONFIG_BLK_DEV_SLC90E66 1
+#undef CONFIG_BLK_DEV_TRM290
+#define CONFIG_BLK_DEV_VIA82CXXX 1
+#undef CONFIG_IDE_ARM
+#undef CONFIG_IDE_CHIPSETS
+#define CONFIG_BLK_DEV_IDEDMA 1
+#undef CONFIG_IDEDMA_IVB
+#define CONFIG_IDEDMA_AUTO 1
+#undef CONFIG_BLK_DEV_HD
/*
- * Bridge: Netfilter Configuration
+ * SCSI device support
*/
-#define CONFIG_BRIDGE_NF_EBTABLES_MODULE 1
-#define CONFIG_BRIDGE_EBT_BROUTE_MODULE 1
-#define CONFIG_BRIDGE_EBT_T_FILTER_MODULE 1
-#define CONFIG_BRIDGE_EBT_T_NAT_MODULE 1
-#define CONFIG_BRIDGE_EBT_802_3_MODULE 1
-#define CONFIG_BRIDGE_EBT_AMONG_MODULE 1
-#define CONFIG_BRIDGE_EBT_ARP_MODULE 1
-#define CONFIG_BRIDGE_EBT_IP_MODULE 1
-#define CONFIG_BRIDGE_EBT_LIMIT_MODULE 1
-#define CONFIG_BRIDGE_EBT_MARK_MODULE 1
-#define CONFIG_BRIDGE_EBT_PKTTYPE_MODULE 1
-#define CONFIG_BRIDGE_EBT_STP_MODULE 1
-#define CONFIG_BRIDGE_EBT_VLAN_MODULE 1
-#define CONFIG_BRIDGE_EBT_ARPREPLY_MODULE 1
-#define CONFIG_BRIDGE_EBT_DNAT_MODULE 1
-#define CONFIG_BRIDGE_EBT_MARK_T_MODULE 1
-#define CONFIG_BRIDGE_EBT_REDIRECT_MODULE 1
-#define CONFIG_BRIDGE_EBT_SNAT_MODULE 1
-#define CONFIG_BRIDGE_EBT_LOG_MODULE 1
-#define CONFIG_XFRM 1
-#define CONFIG_XFRM_USER 1
+#define CONFIG_RAID_ATTRS_MODULE 1
+#define CONFIG_SCSI_MODULE 1
+#define CONFIG_SCSI_PROC_FS 1
/*
- * SCTP Configuration (EXPERIMENTAL)
+ * SCSI support type (disk, tape, CD-ROM)
*/
-#define CONFIG_IP_SCTP_MODULE 1
-#undef CONFIG_SCTP_DBG_MSG
-#undef CONFIG_SCTP_DBG_OBJCNT
-#undef CONFIG_SCTP_HMAC_NONE
-#undef CONFIG_SCTP_HMAC_SHA1
-#define CONFIG_SCTP_HMAC_MD5 1
-#undef CONFIG_ATM
-#define CONFIG_BRIDGE_MODULE 1
-#define CONFIG_VLAN_8021Q_MODULE 1
-#undef CONFIG_DECNET
-#define CONFIG_LLC_MODULE 1
-#undef CONFIG_LLC2
-#define CONFIG_IPX_MODULE 1
-#undef CONFIG_IPX_INTERN
-#define CONFIG_ATALK_MODULE 1
-#define CONFIG_DEV_APPLETALK 1
-#define CONFIG_LTPC_MODULE 1
-#define CONFIG_COPS_MODULE 1
-#define CONFIG_COPS_DAYNA 1
-#define CONFIG_COPS_TANGENT 1
-#define CONFIG_IPDDP_MODULE 1
-#define CONFIG_IPDDP_ENCAP 1
-#define CONFIG_IPDDP_DECAP 1
-#undef CONFIG_X25
-#undef CONFIG_LAPB
-#define CONFIG_NET_DIVERT 1
-#undef CONFIG_ECONET
-#define CONFIG_WAN_ROUTER_MODULE 1
-#undef CONFIG_NET_FASTROUTE
-#undef CONFIG_NET_HW_FLOWCONTROL
+#define CONFIG_BLK_DEV_SD_MODULE 1
+#define CONFIG_CHR_DEV_ST_MODULE 1
+#define CONFIG_CHR_DEV_OSST_MODULE 1
+#define CONFIG_BLK_DEV_SR_MODULE 1
+#define CONFIG_BLK_DEV_SR_VENDOR 1
+#define CONFIG_CHR_DEV_SG_MODULE 1
+#define CONFIG_CHR_DEV_SCH_MODULE 1
/*
- * QoS and/or fair queueing
+ * Some SCSI devices (e.g. CD jukebox) support multiple LUNs
*/
-#define CONFIG_NET_SCHED 1
-#define CONFIG_NET_SCH_CBQ_MODULE 1
-#define CONFIG_NET_SCH_HTB_MODULE 1
-#define CONFIG_NET_SCH_HFSC_MODULE 1
-#define CONFIG_NET_SCH_CSZ_MODULE 1
-#define CONFIG_NET_SCH_PRIO_MODULE 1
-#define CONFIG_NET_SCH_RED_MODULE 1
-#define CONFIG_NET_SCH_SFQ_MODULE 1
-#define CONFIG_NET_SCH_TEQL_MODULE 1
-#define CONFIG_NET_SCH_TBF_MODULE 1
-#define CONFIG_NET_SCH_GRED_MODULE 1
-#define CONFIG_NET_SCH_DSMARK_MODULE 1
-#define CONFIG_NET_SCH_DELAY_MODULE 1
-#define CONFIG_NET_SCH_INGRESS_MODULE 1
-#define CONFIG_NET_QOS 1
-#define CONFIG_NET_ESTIMATOR 1
-#define CONFIG_NET_CLS 1
-#define CONFIG_NET_CLS_TCINDEX_MODULE 1
-#define CONFIG_NET_CLS_ROUTE4_MODULE 1
-#define CONFIG_NET_CLS_ROUTE 1
-#define CONFIG_NET_CLS_FW_MODULE 1
-#define CONFIG_NET_CLS_U32_MODULE 1
-#define CONFIG_NET_CLS_RSVP_MODULE 1
-#define CONFIG_NET_CLS_RSVP6_MODULE 1
-#define CONFIG_NET_CLS_POLICE 1
+#define CONFIG_SCSI_MULTI_LUN 1
+#define CONFIG_SCSI_CONSTANTS 1
+#define CONFIG_SCSI_LOGGING 1
/*
- * Network testing
+ * SCSI Transport Attributes
*/
-#undef CONFIG_NET_PKTGEN
-#define CONFIG_NETPOLL 1
-#undef CONFIG_NETPOLL_RX
-#undef CONFIG_NETPOLL_TRAP
-#define CONFIG_NET_POLL_CONTROLLER 1
-#undef CONFIG_HAMRADIO
-#define CONFIG_IRDA_MODULE 1
+#define CONFIG_SCSI_SPI_ATTRS_MODULE 1
+#define CONFIG_SCSI_FC_ATTRS_MODULE 1
+#define CONFIG_SCSI_ISCSI_ATTRS_MODULE 1
+#define CONFIG_SCSI_SAS_ATTRS_MODULE 1
/*
- * IrDA protocols
+ * SCSI low-level drivers
*/
-#define CONFIG_IRLAN_MODULE 1
-#define CONFIG_IRNET_MODULE 1
-#define CONFIG_IRCOMM_MODULE 1
-#undef CONFIG_IRDA_ULTRA
+#define CONFIG_ISCSI_TCP_MODULE 1
+#define CONFIG_BLK_DEV_3W_XXXX_RAID_MODULE 1
+#define CONFIG_SCSI_3W_9XXX_MODULE 1
+#undef CONFIG_SCSI_7000FASST
+#define CONFIG_SCSI_ACARD_MODULE 1
+#define CONFIG_SCSI_AHA152X_MODULE 1
+#define CONFIG_SCSI_AHA1542_MODULE 1
+#define CONFIG_SCSI_AACRAID_MODULE 1
+#define CONFIG_SCSI_AIC7XXX_MODULE 1
+#define CONFIG_AIC7XXX_CMDS_PER_DEVICE 4
+#define CONFIG_AIC7XXX_RESET_DELAY_MS 15000
+#undef CONFIG_AIC7XXX_DEBUG_ENABLE
+#define CONFIG_AIC7XXX_DEBUG_MASK 0
+#undef CONFIG_AIC7XXX_REG_PRETTY_PRINT
+#define CONFIG_SCSI_AIC7XXX_OLD_MODULE 1
+#define CONFIG_SCSI_AIC79XX_MODULE 1
+#define CONFIG_AIC79XX_CMDS_PER_DEVICE 4
+#define CONFIG_AIC79XX_RESET_DELAY_MS 15000
+#undef CONFIG_AIC79XX_ENABLE_RD_STRM
+#undef CONFIG_AIC79XX_DEBUG_ENABLE
+#define CONFIG_AIC79XX_DEBUG_MASK 0
+#undef CONFIG_AIC79XX_REG_PRETTY_PRINT
+#undef CONFIG_SCSI_DPT_I2O
+#define CONFIG_SCSI_ADVANSYS_MODULE 1
+#undef CONFIG_SCSI_IN2000
+#define CONFIG_MEGARAID_NEWGEN 1
+#define CONFIG_MEGARAID_MM_MODULE 1
+#define CONFIG_MEGARAID_MAILBOX_MODULE 1
+#define CONFIG_MEGARAID_LEGACY_MODULE 1
+#define CONFIG_MEGARAID_SAS_MODULE 1
+#define CONFIG_SCSI_SATA_MODULE 1
+#define CONFIG_SCSI_SATA_AHCI_MODULE 1
+#define CONFIG_SCSI_SATA_SVW_MODULE 1
+#define CONFIG_SCSI_ATA_PIIX_MODULE 1
+#define CONFIG_SCSI_SATA_MV_MODULE 1
+#define CONFIG_SCSI_SATA_NV_MODULE 1
+#define CONFIG_SCSI_PDC_ADMA_MODULE 1
+#define CONFIG_SCSI_SATA_QSTOR_MODULE 1
+#define CONFIG_SCSI_SATA_PROMISE_MODULE 1
+#define CONFIG_SCSI_SATA_SX4_MODULE 1
+#define CONFIG_SCSI_SATA_SIL_MODULE 1
+#define CONFIG_SCSI_SATA_SIL24_MODULE 1
+#define CONFIG_SCSI_SATA_SIS_MODULE 1
+#define CONFIG_SCSI_SATA_ULI_MODULE 1
+#define CONFIG_SCSI_SATA_VIA_MODULE 1
+#define CONFIG_SCSI_SATA_VITESSE_MODULE 1
+#define CONFIG_SCSI_SATA_INTEL_COMBINED 1
+#define CONFIG_SCSI_BUSLOGIC_MODULE 1
+#undef CONFIG_SCSI_OMIT_FLASHPOINT
+#undef CONFIG_SCSI_DMX3191D
+#undef CONFIG_SCSI_DTC3280
+#undef CONFIG_SCSI_EATA
+#define CONFIG_SCSI_FUTURE_DOMAIN_MODULE 1
+#define CONFIG_SCSI_GDTH_MODULE 1
+#undef CONFIG_SCSI_GENERIC_NCR5380
+#undef CONFIG_SCSI_GENERIC_NCR5380_MMIO
+#define CONFIG_SCSI_IPS_MODULE 1
+#define CONFIG_SCSI_INITIO_MODULE 1
+#define CONFIG_SCSI_INIA100_MODULE 1
+#define CONFIG_SCSI_PPA_MODULE 1
+#define CONFIG_SCSI_IMM_MODULE 1
+#undef CONFIG_SCSI_IZIP_EPP16
+#undef CONFIG_SCSI_IZIP_SLOW_CTR
+#undef CONFIG_SCSI_NCR53C406A
+#define CONFIG_SCSI_SYM53C8XX_2_MODULE 1
+#define CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE 1
+#define CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS 16
+#define CONFIG_SCSI_SYM53C8XX_MAX_TAGS 64
+#define CONFIG_SCSI_SYM53C8XX_MMIO 1
+#undef CONFIG_SCSI_IPR
+#undef CONFIG_SCSI_PAS16
+#undef CONFIG_SCSI_PSI240I
+#undef CONFIG_SCSI_QLOGIC_FAS
+#define CONFIG_SCSI_QLOGIC_1280_MODULE 1
+#define CONFIG_SCSI_QLA_FC_MODULE 1
+#define CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE 1
+#define CONFIG_SCSI_QLA21XX_MODULE 1
+#define CONFIG_SCSI_QLA22XX_MODULE 1
+#define CONFIG_SCSI_QLA2300_MODULE 1
+#define CONFIG_SCSI_QLA2322_MODULE 1
+#define CONFIG_SCSI_QLA24XX_MODULE 1
+#define CONFIG_SCSI_LPFC_MODULE 1
+#undef CONFIG_SCSI_SYM53C416
+#define CONFIG_SCSI_DC395x_MODULE 1
+#define CONFIG_SCSI_DC390T_MODULE 1
+#undef CONFIG_SCSI_T128
+#undef CONFIG_SCSI_U14_34F
+#undef CONFIG_SCSI_ULTRASTOR
+#undef CONFIG_SCSI_NSP32
+#undef CONFIG_SCSI_DEBUG
/*
- * IrDA options
+ * PCMCIA SCSI adapter support
*/
-#define CONFIG_IRDA_CACHE_LAST_LSAP 1
-#define CONFIG_IRDA_FAST_RR 1
-#undef CONFIG_IRDA_DEBUG
+#define CONFIG_PCMCIA_AHA152X_MODULE 1
+#define CONFIG_PCMCIA_FDOMAIN_MODULE 1
+#define CONFIG_PCMCIA_NINJA_SCSI_MODULE 1
+#define CONFIG_PCMCIA_QLOGIC_MODULE 1
+#define CONFIG_PCMCIA_SYM53C500_MODULE 1
/*
- * Infrared-port device drivers
+ * Old CD-ROM drivers (not SCSI, not IDE)
*/
+#undef CONFIG_CD_NO_IDESCSI
/*
- * SIR device drivers
+ * Multi-device support (RAID and LVM)
*/
-#define CONFIG_IRTTY_SIR_MODULE 1
+#define CONFIG_MD 1
+#define CONFIG_BLK_DEV_MD 1
+#define CONFIG_MD_LINEAR_MODULE 1
+#define CONFIG_MD_RAID0_MODULE 1
+#define CONFIG_MD_RAID1_MODULE 1
+#define CONFIG_MD_RAID10_MODULE 1
+#define CONFIG_MD_RAID5_MODULE 1
+#define CONFIG_MD_RAID5_RESHAPE 1
+#define CONFIG_MD_RAID6_MODULE 1
+#define CONFIG_MD_MULTIPATH_MODULE 1
+#define CONFIG_MD_FAULTY_MODULE 1
+#define CONFIG_BLK_DEV_DM_MODULE 1
+#define CONFIG_DM_CRYPT_MODULE 1
+#define CONFIG_DM_SNAPSHOT_MODULE 1
+#define CONFIG_DM_MIRROR_MODULE 1
+#define CONFIG_DM_ZERO_MODULE 1
+#define CONFIG_DM_MULTIPATH_MODULE 1
+#define CONFIG_DM_MULTIPATH_EMC_MODULE 1
/*
- * Dongle support
+ * Fusion MPT device support
*/
-#define CONFIG_DONGLE 1
-#define CONFIG_ESI_DONGLE_MODULE 1
-#define CONFIG_ACTISYS_DONGLE_MODULE 1
-#define CONFIG_TEKRAM_DONGLE_MODULE 1
-#define CONFIG_LITELINK_DONGLE_MODULE 1
-#define CONFIG_MA600_DONGLE_MODULE 1
-#define CONFIG_GIRBIL_DONGLE_MODULE 1
-#define CONFIG_MCP2120_DONGLE_MODULE 1
-#define CONFIG_OLD_BELKIN_DONGLE_MODULE 1
-#define CONFIG_ACT200L_DONGLE_MODULE 1
+#define CONFIG_FUSION 1
+#define CONFIG_FUSION_SPI_MODULE 1
+#define CONFIG_FUSION_FC_MODULE 1
+#define CONFIG_FUSION_SAS_MODULE 1
+#define CONFIG_FUSION_MAX_SGE 40
+#define CONFIG_FUSION_CTL_MODULE 1
+#define CONFIG_FUSION_LAN_MODULE 1
/*
- * Old SIR device drivers
+ * IEEE 1394 (FireWire) support
*/
+#define CONFIG_IEEE1394_MODULE 1
/*
- * Old Serial dongle support
+ * Subsystem Options
*/
+#undef CONFIG_IEEE1394_VERBOSEDEBUG
+#define CONFIG_IEEE1394_OUI_DB 1
+#define CONFIG_IEEE1394_EXTRA_CONFIG_ROMS 1
+#define CONFIG_IEEE1394_CONFIG_ROM_IP1394 1
+#undef CONFIG_IEEE1394_EXPORT_FULL_API
/*
- * FIR device drivers
+ * Device Drivers
*/
-#define CONFIG_USB_IRDA_MODULE 1
-#define CONFIG_SIGMATEL_FIR_MODULE 1
-#define CONFIG_NSC_FIR_MODULE 1
-#undef CONFIG_WINBOND_FIR
-#undef CONFIG_TOSHIBA_FIR
-#undef CONFIG_SMC_IRCC_FIR
-#undef CONFIG_ALI_FIR
-#undef CONFIG_VLSI_FIR
-#undef CONFIG_VIA_FIR
-#define CONFIG_BT_MODULE 1
-#define CONFIG_BT_L2CAP_MODULE 1
-#define CONFIG_BT_SCO_MODULE 1
-#define CONFIG_BT_RFCOMM_MODULE 1
-#define CONFIG_BT_RFCOMM_TTY 1
-#define CONFIG_BT_BNEP_MODULE 1
-#define CONFIG_BT_BNEP_MC_FILTER 1
-#define CONFIG_BT_BNEP_PROTO_FILTER 1
-#define CONFIG_BT_CMTP_MODULE 1
+#define CONFIG_IEEE1394_PCILYNX_MODULE 1
+#define CONFIG_IEEE1394_OHCI1394_MODULE 1
/*
- * Bluetooth device drivers
+ * Protocol Drivers
*/
-#define CONFIG_BT_HCIUSB_MODULE 1
-#define CONFIG_BT_HCIUSB_SCO 1
-#define CONFIG_BT_HCIUART_MODULE 1
-#define CONFIG_BT_HCIUART_H4 1
-#define CONFIG_BT_HCIUART_BCSP 1
-#define CONFIG_BT_HCIUART_BCSP_TXCRC 1
-#define CONFIG_BT_HCIBCM203X_MODULE 1
-#define CONFIG_BT_HCIBFUSB_MODULE 1
-#define CONFIG_BT_HCIDTL1_MODULE 1
-#define CONFIG_BT_HCIBT3C_MODULE 1
-#define CONFIG_BT_HCIBLUECARD_MODULE 1
-#define CONFIG_BT_HCIBTUART_MODULE 1
-#define CONFIG_BT_HCIVHCI_MODULE 1
-#define CONFIG_TUX_MODULE 1
+#define CONFIG_IEEE1394_VIDEO1394_MODULE 1
+#define CONFIG_IEEE1394_SBP2_MODULE 1
+#undef CONFIG_IEEE1394_SBP2_PHYS_DMA
+#define CONFIG_IEEE1394_ETH1394_MODULE 1
+#define CONFIG_IEEE1394_DV1394_MODULE 1
+#define CONFIG_IEEE1394_RAWIO_MODULE 1
/*
- * TUX options
+ * I2O device support
+ */
+#define CONFIG_I2O_MODULE 1
+#undef CONFIG_I2O_LCT_NOTIFY_ON_CHANGES
+#define CONFIG_I2O_EXT_ADAPTEC 1
+#define CONFIG_I2O_CONFIG_MODULE 1
+#define CONFIG_I2O_CONFIG_OLD_IOCTL 1
+#define CONFIG_I2O_BUS_MODULE 1
+#define CONFIG_I2O_BLOCK_MODULE 1
+#define CONFIG_I2O_SCSI_MODULE 1
+#define CONFIG_I2O_PROC_MODULE 1
+
+/*
+ * Network device support
*/
-#define CONFIG_TUX_EXTCGI 1
-#undef CONFIG_TUX_EXTENDED_LOG
-#undef CONFIG_TUX_DEBUG
#define CONFIG_NETDEVICES 1
#define CONFIG_DUMMY_MODULE 1
#define CONFIG_BONDING_MODULE 1
#define CONFIG_EQUALIZER_MODULE 1
#define CONFIG_TUN_MODULE 1
-#define CONFIG_ETHERTAP_MODULE 1
#define CONFIG_NET_SB1000_MODULE 1
/*
*/
#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)
*/
#define CONFIG_MII_MODULE 1
#define CONFIG_HAPPYMEAL_MODULE 1
#define CONFIG_SUNGEM_MODULE 1
+#define CONFIG_CASSINI_MODULE 1
#define CONFIG_NET_VENDOR_3COM 1
-#define CONFIG_EL1_MODULE 1
-#define CONFIG_EL2_MODULE 1
-#define CONFIG_ELPLUS_MODULE 1
-#define CONFIG_EL16_MODULE 1
+#undef CONFIG_EL1
+#undef CONFIG_EL2
+#undef CONFIG_ELPLUS
+#undef CONFIG_EL16
#define CONFIG_EL3_MODULE 1
-#define CONFIG_3C515_MODULE 1
+#undef CONFIG_3C515
#define CONFIG_VORTEX_MODULE 1
#define CONFIG_TYPHOON_MODULE 1
-#define CONFIG_LANCE_MODULE 1
+#undef CONFIG_LANCE
#define CONFIG_NET_VENDOR_SMC 1
-#define CONFIG_WD80x3_MODULE 1
+#undef CONFIG_WD80x3
#define CONFIG_ULTRA_MODULE 1
-#define CONFIG_SMC9194_MODULE 1
-#define CONFIG_NET_VENDOR_RACAL 1
-#define CONFIG_NI52_MODULE 1
-#define CONFIG_NI65_MODULE 1
+#undef CONFIG_SMC9194
+#undef CONFIG_NET_VENDOR_RACAL
/*
* Tulip family network device support
#define CONFIG_DE4X5_MODULE 1
#define CONFIG_WINBOND_840_MODULE 1
#define CONFIG_DM9102_MODULE 1
+#define CONFIG_ULI526X_MODULE 1
#define CONFIG_PCMCIA_XIRCOM_MODULE 1
+#undef CONFIG_PCMCIA_XIRTULIP
#undef CONFIG_AT1700
-#define CONFIG_DEPCA_MODULE 1
+#undef CONFIG_DEPCA
#define CONFIG_HP100_MODULE 1
-#undef CONFIG_NET_ISA
+#define CONFIG_NET_ISA 1
+#undef CONFIG_E2100
+#define CONFIG_EWRK3_MODULE 1
+#undef CONFIG_EEXPRESS
+#undef CONFIG_EEXPRESS_PRO
+#undef CONFIG_HPLAN_PLUS
+#undef CONFIG_HPLAN
+#undef CONFIG_LP486E
+#undef CONFIG_ETH16I
#define CONFIG_NE2000_MODULE 1
+#undef CONFIG_ZNET
+#undef CONFIG_SEEQ8005
#define CONFIG_NET_PCI 1
#define CONFIG_PCNET32_MODULE 1
#define CONFIG_AMD8111_ETH_MODULE 1
#define CONFIG_AMD8111E_NAPI 1
#define CONFIG_ADAPTEC_STARFIRE_MODULE 1
#define CONFIG_ADAPTEC_STARFIRE_NAPI 1
-#define CONFIG_AC3200_MODULE 1
-#define CONFIG_APRICOT_MODULE 1
+#undef CONFIG_AC3200
+#undef CONFIG_APRICOT
#define CONFIG_B44_MODULE 1
#define CONFIG_FORCEDETH_MODULE 1
-#define CONFIG_CS89x0_MODULE 1
+#undef CONFIG_CS89x0
#define CONFIG_DGRS_MODULE 1
-#define CONFIG_EEPRO100_MODULE 1
-#undef CONFIG_EEPRO100_PIO
+#undef CONFIG_EEPRO100
#define CONFIG_E100_MODULE 1
-#define CONFIG_E100_NAPI 1
#define CONFIG_FEALNX_MODULE 1
#define CONFIG_NATSEMI_MODULE 1
#define CONFIG_NE2K_PCI_MODULE 1
#define CONFIG_8139CP_MODULE 1
#define CONFIG_8139TOO_MODULE 1
-#define CONFIG_8139TOO_PIO 1
+#undef CONFIG_8139TOO_PIO
#undef CONFIG_8139TOO_TUNE_TWISTER
#define CONFIG_8139TOO_8129 1
#undef CONFIG_8139_OLD_RX_RESET
#define CONFIG_DE620_MODULE 1
/*
- * Gigabit Ethernet (1000/10000 Mbit)
+ * Ethernet (1000 Mbit)
*/
-#define CONFIG_NET_GIGE 1
#define CONFIG_ACENIC_MODULE 1
#undef CONFIG_ACENIC_OMIT_TIGON_I
#define CONFIG_DL2K_MODULE 1
#define CONFIG_E1000_MODULE 1
#define CONFIG_E1000_NAPI 1
+#undef CONFIG_E1000_DISABLE_PACKET_SPLIT
#define CONFIG_NS83820_MODULE 1
#define CONFIG_HAMACHI_MODULE 1
#define CONFIG_YELLOWFIN_MODULE 1
#define CONFIG_R8169_MODULE 1
-#define CONFIG_SK98LIN_MODULE 1
+#define CONFIG_R8169_NAPI 1
+#define CONFIG_R8169_VLAN 1
+#define CONFIG_SIS190_MODULE 1
+#define CONFIG_SKGE_MODULE 1
+#define CONFIG_SKY2_MODULE 1
+#undef CONFIG_SK98LIN
+#define CONFIG_VIA_VELOCITY_MODULE 1
#define CONFIG_TIGON3_MODULE 1
+#define CONFIG_BNX2_MODULE 1
+
+/*
+ * Ethernet (10000 Mbit)
+ */
+#define CONFIG_CHELSIO_T1_MODULE 1
#define CONFIG_IXGB_MODULE 1
#define CONFIG_IXGB_NAPI 1
#define CONFIG_S2IO_MODULE 1
/*
* Token Ring devices
*/
-#undef CONFIG_TR
+#define CONFIG_TR 1
+#undef CONFIG_IBMTR
+#define CONFIG_IBMOL_MODULE 1
+#define CONFIG_IBMLS_MODULE 1
+#define CONFIG_3C359_MODULE 1
+#undef CONFIG_TMS380TR
+#undef CONFIG_SMCTR
/*
* Wireless LAN (non-hamradio)
*/
#define CONFIG_NET_RADIO 1
+#define CONFIG_NET_WIRELESS_RTNETLINK 1
/*
* Obsolete Wireless cards support (pre-802.11)
*/
#undef CONFIG_STRIP
#undef CONFIG_ARLAN
-#define CONFIG_WAVELAN_MODULE 1
+#undef CONFIG_WAVELAN
#define CONFIG_PCMCIA_WAVELAN_MODULE 1
#define CONFIG_PCMCIA_NETWAVE_MODULE 1
/*
* Wireless 802.11b ISA/PCI cards support
*/
+#define CONFIG_IPW2100_MODULE 1
+#define CONFIG_IPW2100_MONITOR 1
+#undef CONFIG_IPW2100_DEBUG
+#define CONFIG_IPW2200_MODULE 1
+#define CONFIG_IPW2200_MONITOR 1
+#define CONFIG_IPW_QOS 1
+#undef CONFIG_IPW2200_DEBUG
#define CONFIG_AIRO_MODULE 1
#define CONFIG_HERMES_MODULE 1
#define CONFIG_PLX_HERMES_MODULE 1
#define CONFIG_TMD_HERMES_MODULE 1
+#define CONFIG_NORTEL_HERMES_MODULE 1
#define CONFIG_PCI_HERMES_MODULE 1
#define CONFIG_ATMEL_MODULE 1
#define CONFIG_PCI_ATMEL_MODULE 1
* 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
* 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_PCMCIA_SMC91C92_MODULE 1
#define CONFIG_PCMCIA_XIRC2PS_MODULE 1
#define CONFIG_PCMCIA_AXNET_MODULE 1
+#define CONFIG_PCMCIA_IBMTR_MODULE 1
/*
* Wan interfaces
*/
#undef CONFIG_WAN
+
+/*
+ * ATM drivers
+ */
+#undef CONFIG_ATM_DUMMY
+#define CONFIG_ATM_TCP_MODULE 1
+#define CONFIG_ATM_LANAI_MODULE 1
+#define CONFIG_ATM_ENI_MODULE 1
+#undef CONFIG_ATM_ENI_DEBUG
+#undef CONFIG_ATM_ENI_TUNE_BURST
+#define CONFIG_ATM_FIRESTREAM_MODULE 1
+#undef CONFIG_ATM_ZATM
+#define CONFIG_ATM_NICSTAR_MODULE 1
+#undef CONFIG_ATM_NICSTAR_USE_SUNI
+#undef CONFIG_ATM_NICSTAR_USE_IDT77105
+#define CONFIG_ATM_IDT77252_MODULE 1
+#undef CONFIG_ATM_IDT77252_DEBUG
+#undef CONFIG_ATM_IDT77252_RCV_ALL
+#define CONFIG_ATM_IDT77252_USE_SUNI 1
+#define CONFIG_ATM_AMBASSADOR_MODULE 1
+#undef CONFIG_ATM_AMBASSADOR_DEBUG
+#define CONFIG_ATM_HORIZON_MODULE 1
+#undef CONFIG_ATM_HORIZON_DEBUG
+#undef CONFIG_ATM_IA
+#define CONFIG_ATM_FORE200E_MAYBE_MODULE 1
+#undef CONFIG_ATM_FORE200E_PCA
+#define CONFIG_ATM_HE_MODULE 1
+#undef CONFIG_ATM_HE_USE_SUNI
#define CONFIG_FDDI 1
#undef CONFIG_DEFXX
#define CONFIG_SKFP_MODULE 1
#define CONFIG_PPP_SYNC_TTY_MODULE 1
#define CONFIG_PPP_DEFLATE_MODULE 1
#undef CONFIG_PPP_BSDCOMP
+#define CONFIG_PPP_MPPE_MODULE 1
#define CONFIG_PPPOE_MODULE 1
-#undef CONFIG_SLIP
+#define CONFIG_PPPOATM_MODULE 1
+#define CONFIG_SLIP_MODULE 1
+#define CONFIG_SLIP_COMPRESSED 1
+#define CONFIG_SLIP_SMART 1
+#undef CONFIG_SLIP_MODE_SLIP6
#define CONFIG_NET_FC 1
#undef CONFIG_SHAPER
#define CONFIG_NETCONSOLE_MODULE 1
+#define CONFIG_NETPOLL 1
+#undef CONFIG_NETPOLL_RX
+#define CONFIG_NETPOLL_TRAP 1
+#define CONFIG_NET_POLL_CONTROLLER 1
/*
* ISDN subsystem
/*
* ISDN feature submodules
*/
+#define CONFIG_ISDN_DRV_LOOP_MODULE 1
+#define CONFIG_ISDN_DIVERSION_MODULE 1
/*
* ISDN4Linux hardware drivers
/*
* HiSax supported cards
*/
-#define CONFIG_HISAX_16_0 1
+#undef CONFIG_HISAX_16_0
#define CONFIG_HISAX_16_3 1
#define CONFIG_HISAX_TELESPCI 1
#define CONFIG_HISAX_S0BOX 1
-#define CONFIG_HISAX_AVM_A1 1
+#undef CONFIG_HISAX_AVM_A1
#define CONFIG_HISAX_FRITZPCI 1
#define CONFIG_HISAX_AVM_A1_PCMCIA 1
#define CONFIG_HISAX_ELSA 1
-#define CONFIG_HISAX_IX1MICROR2 1
+#undef CONFIG_HISAX_IX1MICROR2
#define CONFIG_HISAX_DIEHLDIVA 1
-#define CONFIG_HISAX_ASUSCOM 1
-#define CONFIG_HISAX_TELEINT 1
-#define CONFIG_HISAX_HFCS 1
+#undef CONFIG_HISAX_ASUSCOM
+#undef CONFIG_HISAX_TELEINT
+#undef CONFIG_HISAX_HFCS
#define CONFIG_HISAX_SEDLBAUER 1
-#define CONFIG_HISAX_SPORTSTER 1
-#define CONFIG_HISAX_MIC 1
+#undef CONFIG_HISAX_SPORTSTER
+#undef CONFIG_HISAX_MIC
#define CONFIG_HISAX_NETJET 1
#define CONFIG_HISAX_NETJET_U 1
#define CONFIG_HISAX_NICCY 1
-#define CONFIG_HISAX_ISURF 1
-#define CONFIG_HISAX_HSTSAPHIR 1
+#undef CONFIG_HISAX_ISURF
+#undef CONFIG_HISAX_HSTSAPHIR
#define CONFIG_HISAX_BKM_A4T 1
#define CONFIG_HISAX_SCT_QUADRO 1
#define CONFIG_HISAX_GAZEL 1
* HiSax sub driver modules
*/
#define CONFIG_HISAX_ST5481_MODULE 1
-#define CONFIG_HISAX_HFCUSB_MODULE 1
+#undef CONFIG_HISAX_HFCUSB
+#define CONFIG_HISAX_HFC4S8S_MODULE 1
#define CONFIG_HISAX_FRITZ_PCIPNP_MODULE 1
#define CONFIG_HISAX_HDLC 1
/*
* Active cards
*/
-#define CONFIG_ISDN_DRV_ICN_MODULE 1
-#define CONFIG_ISDN_DRV_PCBIT_MODULE 1
-#define CONFIG_ISDN_DRV_SC_MODULE 1
-#define CONFIG_ISDN_DRV_ACT2000_MODULE 1
-#define CONFIG_ISDN_DRV_TPAM_MODULE 1
+#undef CONFIG_ISDN_DRV_ICN
+#undef CONFIG_ISDN_DRV_PCBIT
+#undef CONFIG_ISDN_DRV_SC
+#undef CONFIG_ISDN_DRV_ACT2000
+#define CONFIG_HYSDN_MODULE 1
+#define CONFIG_HYSDN_CAPI 1
+
+/*
+ * Siemens Gigaset
+ */
+#define CONFIG_ISDN_DRV_GIGASET_MODULE 1
+#define CONFIG_GIGASET_BASE_MODULE 1
+#define CONFIG_GIGASET_M105_MODULE 1
+#undef CONFIG_GIGASET_DEBUG
+#undef CONFIG_GIGASET_UNDOCREQ
/*
* CAPI subsystem
* 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
#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
*/
#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_JOYSTICK_SPACEORB_MODULE 1
#define CONFIG_JOYSTICK_SPACEBALL_MODULE 1
#define CONFIG_JOYSTICK_STINGER_MODULE 1
-#define CONFIG_JOYSTICK_TWIDDLER_MODULE 1
+#define CONFIG_JOYSTICK_TWIDJOY_MODULE 1
#define CONFIG_JOYSTICK_DB9_MODULE 1
#define CONFIG_JOYSTICK_GAMECON_MODULE 1
#define CONFIG_JOYSTICK_TURBOGRAFX_MODULE 1
-#undef CONFIG_INPUT_JOYDUMP
+#define CONFIG_JOYSTICK_JOYDUMP_MODULE 1
#define CONFIG_INPUT_TOUCHSCREEN 1
#define CONFIG_TOUCHSCREEN_GUNZE_MODULE 1
+#define CONFIG_TOUCHSCREEN_ELO_MODULE 1
+#define CONFIG_TOUCHSCREEN_MTOUCH_MODULE 1
+#define CONFIG_TOUCHSCREEN_MK712_MODULE 1
#define CONFIG_INPUT_MISC 1
#define CONFIG_INPUT_PCSPKR_MODULE 1
-#undef CONFIG_INPUT_UINPUT
+#define CONFIG_INPUT_WISTRON_BTNS_MODULE 1
+#define CONFIG_INPUT_UINPUT_MODULE 1
+
+/*
+ * Hardware I/O ports
+ */
+#define CONFIG_SERIO 1
+#define CONFIG_SERIO_I8042 1
+#define CONFIG_SERIO_SERPORT 1
+#undef CONFIG_SERIO_CT82C710
+#undef CONFIG_SERIO_PARKBD
+#undef CONFIG_SERIO_PCIPS2
+#define CONFIG_SERIO_LIBPS2 1
+#define CONFIG_SERIO_RAW_MODULE 1
+#define CONFIG_GAMEPORT_MODULE 1
+#define CONFIG_GAMEPORT_NS558_MODULE 1
+#define CONFIG_GAMEPORT_L4_MODULE 1
+#define CONFIG_GAMEPORT_EMU10K1_MODULE 1
+#define CONFIG_GAMEPORT_FM801_MODULE 1
/*
* Character devices
#define CONFIG_VT_CONSOLE 1
#define CONFIG_HW_CONSOLE 1
#define CONFIG_SERIAL_NONSTANDARD 1
+#undef CONFIG_COMPUTONE
#define CONFIG_ROCKETPORT_MODULE 1
#undef CONFIG_CYCLADES
+#undef CONFIG_DIGIEPCA
+#undef CONFIG_ESPSERIAL
+#undef CONFIG_MOXA_INTELLIO
+#undef CONFIG_MOXA_SMARTIO
+#undef CONFIG_ISI
#define CONFIG_SYNCLINK_MODULE 1
#define CONFIG_SYNCLINKMP_MODULE 1
+#undef CONFIG_SYNCLINK_GT
#define CONFIG_N_HDLC_MODULE 1
-#define CONFIG_STALDRV 1
+#undef CONFIG_RISCOM8
+#undef CONFIG_SPECIALIX
+#undef CONFIG_SX
+#undef CONFIG_RIO
+#undef CONFIG_STALDRV
/*
* Serial drivers
*/
#define CONFIG_SERIAL_8250 1
#define CONFIG_SERIAL_8250_CONSOLE 1
+#define CONFIG_SERIAL_8250_PCI 1
+#define CONFIG_SERIAL_8250_PNP 1
#define CONFIG_SERIAL_8250_CS_MODULE 1
-#undef CONFIG_SERIAL_8250_ACPI
-#define CONFIG_SERIAL_8250_NR_UARTS 4
+#define CONFIG_SERIAL_8250_NR_UARTS 32
+#define CONFIG_SERIAL_8250_RUNTIME_UARTS 4
#define CONFIG_SERIAL_8250_EXTENDED 1
-#undef CONFIG_SERIAL_8250_MANY_PORTS
+#define CONFIG_SERIAL_8250_MANY_PORTS 1
#define CONFIG_SERIAL_8250_SHARE_IRQ 1
#define CONFIG_SERIAL_8250_DETECT_IRQ 1
-#define CONFIG_SERIAL_8250_MULTIPORT 1
#define CONFIG_SERIAL_8250_RSA 1
+#undef CONFIG_SERIAL_8250_FOURPORT
+#undef CONFIG_SERIAL_8250_ACCENT
+#undef CONFIG_SERIAL_8250_BOCA
+#undef CONFIG_SERIAL_8250_HUB6
/*
* Non-8250 serial port support
*/
#define CONFIG_SERIAL_CORE 1
#define CONFIG_SERIAL_CORE_CONSOLE 1
+#undef CONFIG_SERIAL_JSM
#define CONFIG_UNIX98_PTYS 1
#undef CONFIG_LEGACY_PTYS
#define CONFIG_CRASH_MODULE 1
#define CONFIG_LP_CONSOLE 1
#define CONFIG_PPDEV_MODULE 1
#define CONFIG_TIPAR_MODULE 1
-#undef CONFIG_QIC02_TAPE
/*
* IPMI
#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 Device Drivers
*/
#define CONFIG_SOFT_WATCHDOG_MODULE 1
-#define CONFIG_ACQUIRE_WDT_MODULE 1
-#define CONFIG_ADVANTECH_WDT_MODULE 1
+#undef CONFIG_ACQUIRE_WDT
+#undef CONFIG_ADVANTECH_WDT
#define CONFIG_ALIM1535_WDT_MODULE 1
#define CONFIG_ALIM7101_WDT_MODULE 1
-#define CONFIG_SC520_WDT_MODULE 1
-#define CONFIG_EUROTECH_WDT_MODULE 1
-#define CONFIG_IB700_WDT_MODULE 1
-#define CONFIG_WAFER_WDT_MODULE 1
+#undef CONFIG_SC520_WDT
+#undef CONFIG_EUROTECH_WDT
+#undef CONFIG_IB700_WDT
+#define CONFIG_IBMASR_MODULE 1
+#undef CONFIG_WAFER_WDT
+#define CONFIG_I6300ESB_WDT_MODULE 1
#define CONFIG_I8XX_TCO_MODULE 1
-#define CONFIG_SC1200_WDT_MODULE 1
-#undef CONFIG_SCx200_WDT
+#undef CONFIG_SC1200_WDT
#undef CONFIG_60XX_WDT
-#define CONFIG_CPU5_WDT_MODULE 1
+#undef CONFIG_SBC8360_WDT
+#undef CONFIG_CPU5_WDT
#define CONFIG_W83627HF_WDT_MODULE 1
#define CONFIG_W83877F_WDT_MODULE 1
+#define CONFIG_W83977F_WDT_MODULE 1
#define CONFIG_MACHZ_WDT_MODULE 1
+#undef CONFIG_SBC_EPX_C3_WATCHDOG
/*
* ISA-based Watchdog Cards
*/
-#define CONFIG_PCWATCHDOG_MODULE 1
+#undef CONFIG_PCWATCHDOG
#undef CONFIG_MIXCOMWD
-#define CONFIG_WDT_MODULE 1
-#undef CONFIG_WDT_501
+#undef CONFIG_WDT
/*
* PCI-based Watchdog Cards
*/
#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
/*
* Ftape, the floppy tape device driver
*/
+#undef CONFIG_FTAPE
#define CONFIG_AGP 1
#define CONFIG_AGP_ALI 1
#define CONFIG_AGP_ATI 1
#define CONFIG_AGP_AMD 1
#define CONFIG_AGP_AMD64 1
#define CONFIG_AGP_INTEL 1
-#define CONFIG_AGP_INTEL_MCH 1
#define CONFIG_AGP_NVIDIA 1
#define CONFIG_AGP_SIS 1
#define CONFIG_AGP_SWORKS 1
#define CONFIG_AGP_VIA 1
#define CONFIG_AGP_EFFICEON 1
-#define CONFIG_DRM 1
+#define CONFIG_DRM_MODULE 1
#define CONFIG_DRM_TDFX_MODULE 1
-#define CONFIG_DRM_GAMMA_MODULE 1
#define CONFIG_DRM_R128_MODULE 1
#define CONFIG_DRM_RADEON_MODULE 1
#define CONFIG_DRM_I810_MODULE 1
#define CONFIG_DRM_I830_MODULE 1
+#define CONFIG_DRM_I915_MODULE 1
#define CONFIG_DRM_MGA_MODULE 1
#define CONFIG_DRM_SIS_MODULE 1
+#define CONFIG_DRM_VIA_MODULE 1
+#define CONFIG_DRM_SAVAGE_MODULE 1
/*
* PCMCIA character devices
*/
#define CONFIG_SYNCLINK_CS_MODULE 1
+#define CONFIG_CARDMAN_4000_MODULE 1
+#define CONFIG_CARDMAN_4040_MODULE 1
#define CONFIG_MWAVE_MODULE 1
+#define CONFIG_CS5535_GPIO_MODULE 1
#undef CONFIG_RAW_DRIVER
+#define CONFIG_HPET 1
+#undef CONFIG_HPET_RTC_IRQ
+#undef CONFIG_HPET_MMAP
#define CONFIG_HANGCHECK_TIMER_MODULE 1
+/*
+ * TPM devices
+ */
+#undef CONFIG_TCG_TPM
+#undef CONFIG_TELCLOCK
+
/*
* I2C support
*/
*/
#define CONFIG_I2C_ALGOBIT_MODULE 1
#define CONFIG_I2C_ALGOPCF_MODULE 1
+#define CONFIG_I2C_ALGOPCA_MODULE 1
/*
* 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_AMD756_S4882_MODULE 1
#define CONFIG_I2C_AMD8111_MODULE 1
+#undef CONFIG_I2C_ELEKTOR
#define CONFIG_I2C_I801_MODULE 1
#define CONFIG_I2C_I810_MODULE 1
+#define CONFIG_I2C_PIIX4_MODULE 1
#define CONFIG_I2C_ISA_MODULE 1
#define CONFIG_I2C_NFORCE2_MODULE 1
-#undef CONFIG_I2C_PARPORT
-#undef CONFIG_I2C_PARPORT_LIGHT
-#define CONFIG_I2C_PIIX4_MODULE 1
+#define CONFIG_I2C_PARPORT_MODULE 1
+#define CONFIG_I2C_PARPORT_LIGHT_MODULE 1
#define CONFIG_I2C_PROSAVAGE_MODULE 1
#define CONFIG_I2C_SAVAGE4_MODULE 1
#undef CONFIG_SCx200_ACB
#define CONFIG_I2C_SIS5595_MODULE 1
#define CONFIG_I2C_SIS630_MODULE 1
#define CONFIG_I2C_SIS96X_MODULE 1
+#define CONFIG_I2C_STUB_MODULE 1
#define CONFIG_I2C_VIA_MODULE 1
#define CONFIG_I2C_VIAPRO_MODULE 1
#define CONFIG_I2C_VOODOO3_MODULE 1
+#define CONFIG_I2C_PCA_ISA_MODULE 1
+
+/*
+ * Miscellaneous I2C Chip support
+ */
+#define CONFIG_SENSORS_DS1337_MODULE 1
+#define CONFIG_SENSORS_DS1374_MODULE 1
+#define CONFIG_SENSORS_EEPROM_MODULE 1
+#define CONFIG_SENSORS_PCF8574_MODULE 1
+#define CONFIG_SENSORS_PCA9539_MODULE 1
+#define CONFIG_SENSORS_PCF8591_MODULE 1
+#define CONFIG_SENSORS_MAX6875_MODULE 1
+#undef CONFIG_I2C_DEBUG_CORE
+#undef CONFIG_I2C_DEBUG_ALGO
+#undef CONFIG_I2C_DEBUG_BUS
+#undef CONFIG_I2C_DEBUG_CHIP
+
+/*
+ * SPI support
+ */
+#undef CONFIG_SPI
+#undef CONFIG_SPI_MASTER
+
+/*
+ * Dallas's 1-wire bus
+ */
+#define CONFIG_W1_MODULE 1
+
+/*
+ * 1-wire Bus Masters
+ */
+#define CONFIG_W1_MASTER_MATROX_MODULE 1
+#define CONFIG_W1_MASTER_DS9490_MODULE 1
+#define CONFIG_W1_MASTER_DS9490_BRIDGE_MODULE 1
+#define CONFIG_W1_MASTER_DS2482_MODULE 1
+
+/*
+ * 1-wire Slaves
+ */
+#define CONFIG_W1_SLAVE_THERM_MODULE 1
+#define CONFIG_W1_SLAVE_SMEM_MODULE 1
+#define CONFIG_W1_SLAVE_DS2433_MODULE 1
/*
- * Hardware Sensors Chip support
+ * Hardware Monitoring support
*/
-#define CONFIG_I2C_SENSOR_MODULE 1
+#define CONFIG_HWMON_MODULE 1
+#define CONFIG_HWMON_VID_MODULE 1
#define CONFIG_SENSORS_ADM1021_MODULE 1
+#define CONFIG_SENSORS_ADM1025_MODULE 1
+#define CONFIG_SENSORS_ADM1026_MODULE 1
+#define CONFIG_SENSORS_ADM1031_MODULE 1
+#define CONFIG_SENSORS_ADM9240_MODULE 1
#define CONFIG_SENSORS_ASB100_MODULE 1
+#define CONFIG_SENSORS_ATXP1_MODULE 1
#define CONFIG_SENSORS_DS1621_MODULE 1
+#define CONFIG_SENSORS_F71805F_MODULE 1
#define CONFIG_SENSORS_FSCHER_MODULE 1
+#define CONFIG_SENSORS_FSCPOS_MODULE 1
#define CONFIG_SENSORS_GL518SM_MODULE 1
+#define CONFIG_SENSORS_GL520SM_MODULE 1
#define CONFIG_SENSORS_IT87_MODULE 1
+#define CONFIG_SENSORS_LM63_MODULE 1
#define CONFIG_SENSORS_LM75_MODULE 1
+#define CONFIG_SENSORS_LM77_MODULE 1
#define CONFIG_SENSORS_LM78_MODULE 1
#define CONFIG_SENSORS_LM80_MODULE 1
#define CONFIG_SENSORS_LM83_MODULE 1
#define CONFIG_SENSORS_LM85_MODULE 1
+#define CONFIG_SENSORS_LM87_MODULE 1
#define CONFIG_SENSORS_LM90_MODULE 1
+#define CONFIG_SENSORS_LM92_MODULE 1
#define CONFIG_SENSORS_MAX1619_MODULE 1
+#define CONFIG_SENSORS_PC87360_MODULE 1
+#define CONFIG_SENSORS_SIS5595_MODULE 1
+#define CONFIG_SENSORS_SMSC47M1_MODULE 1
+#define CONFIG_SENSORS_SMSC47B397_MODULE 1
#define CONFIG_SENSORS_VIA686A_MODULE 1
+#define CONFIG_SENSORS_VT8231_MODULE 1
#define CONFIG_SENSORS_W83781D_MODULE 1
+#define CONFIG_SENSORS_W83792D_MODULE 1
#define CONFIG_SENSORS_W83L785TS_MODULE 1
#define CONFIG_SENSORS_W83627HF_MODULE 1
-
-/*
- * Other I2C Chip support
- */
-#define CONFIG_SENSORS_EEPROM_MODULE 1
-#define CONFIG_SENSORS_PCF8574_MODULE 1
-#define CONFIG_SENSORS_PCF8591_MODULE 1
-#define CONFIG_SENSORS_RTC8564_MODULE 1
-#undef CONFIG_I2C_DEBUG_CORE
-#undef CONFIG_I2C_DEBUG_ALGO
-#undef CONFIG_I2C_DEBUG_BUS
-#undef CONFIG_I2C_DEBUG_CHIP
+#define CONFIG_SENSORS_W83627EHF_MODULE 1
+#define CONFIG_SENSORS_HDAPS_MODULE 1
+#undef CONFIG_HWMON_DEBUG_CHIP
/*
* Misc devices
* Multimedia devices
*/
#define CONFIG_VIDEO_DEV_MODULE 1
+#define CONFIG_VIDEO_V4L1 1
+#define CONFIG_VIDEO_V4L1_COMPAT 1
+#define CONFIG_VIDEO_V4L2_MODULE 1
/*
- * Video For Linux
+ * Video Capture Adapters
*/
/*
- * Video Adapters
+ * Video Capture Adapters
*/
+#undef CONFIG_VIDEO_ADV_DEBUG
+#undef CONFIG_VIDEO_VIVI
#define CONFIG_VIDEO_BT848_MODULE 1
-#define CONFIG_VIDEO_PMS_MODULE 1
+#define CONFIG_VIDEO_BT848_DVB 1
+#define CONFIG_VIDEO_SAA6588_MODULE 1
+#undef CONFIG_VIDEO_PMS
#define CONFIG_VIDEO_BWQCAM_MODULE 1
#define CONFIG_VIDEO_CQCAM_MODULE 1
#define CONFIG_VIDEO_W9966_MODULE 1
#define CONFIG_VIDEO_CPIA_MODULE 1
#define CONFIG_VIDEO_CPIA_PP_MODULE 1
#define CONFIG_VIDEO_CPIA_USB_MODULE 1
+#define CONFIG_VIDEO_CPIA2_MODULE 1
#define CONFIG_VIDEO_SAA5246A_MODULE 1
#define CONFIG_VIDEO_SAA5249_MODULE 1
#define CONFIG_TUNER_3036_MODULE 1
#define CONFIG_VIDEO_ZORAN_DC30_MODULE 1
#define CONFIG_VIDEO_ZORAN_LML33_MODULE 1
#define CONFIG_VIDEO_ZORAN_LML33R10_MODULE 1
+#define CONFIG_VIDEO_MEYE_MODULE 1
#define CONFIG_VIDEO_SAA7134_MODULE 1
+#define CONFIG_VIDEO_SAA7134_ALSA_MODULE 1
+#define CONFIG_VIDEO_SAA7134_DVB_MODULE 1
+#define CONFIG_VIDEO_SAA7134_DVB_ALL_FRONTENDS 1
#define CONFIG_VIDEO_MXB_MODULE 1
#define CONFIG_VIDEO_DPC_MODULE 1
#define CONFIG_VIDEO_HEXIUM_ORION_MODULE 1
#define CONFIG_VIDEO_HEXIUM_GEMINI_MODULE 1
+#define CONFIG_VIDEO_CX88_VP3054_MODULE 1
#define CONFIG_VIDEO_CX88_MODULE 1
+#define CONFIG_VIDEO_CX88_ALSA_MODULE 1
+#define CONFIG_VIDEO_CX88_DVB_MODULE 1
+#define CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS 1
+#define CONFIG_VIDEO_OVCAMCHIP_MODULE 1
+
+/*
+ * Encoders and Decoders
+ */
+#define CONFIG_VIDEO_MSP3400_MODULE 1
+#define CONFIG_VIDEO_CS53L32A_MODULE 1
+#define CONFIG_VIDEO_WM8775_MODULE 1
+#define CONFIG_VIDEO_WM8739_MODULE 1
+#define CONFIG_VIDEO_CX25840_MODULE 1
+#define CONFIG_VIDEO_SAA711X_MODULE 1
+#define CONFIG_VIDEO_SAA7127_MODULE 1
+#define CONFIG_VIDEO_UPD64031A_MODULE 1
+#define CONFIG_VIDEO_UPD64083_MODULE 1
+
+/*
+ * V4L USB devices
+ */
+#define CONFIG_VIDEO_EM28XX_MODULE 1
+#define CONFIG_USB_DSBR_MODULE 1
+#define CONFIG_VIDEO_USBVIDEO_MODULE 1
+#define CONFIG_USB_VICAM_MODULE 1
+#define CONFIG_USB_IBMCAM_MODULE 1
+#define CONFIG_USB_KONICAWC_MODULE 1
+#define CONFIG_USB_ET61X251_MODULE 1
+#define CONFIG_USB_OV511_MODULE 1
+#define CONFIG_USB_SE401_MODULE 1
+#define CONFIG_USB_SN9C102_MODULE 1
+#define CONFIG_USB_STV680_MODULE 1
+#define CONFIG_USB_W9968CF_MODULE 1
+#define CONFIG_USB_ZC0301_MODULE 1
+#define CONFIG_USB_PWC_MODULE 1
/*
* Radio Adapters
*/
-#define CONFIG_RADIO_CADET_MODULE 1
-#define CONFIG_RADIO_RTRACK_MODULE 1
-#define CONFIG_RADIO_RTRACK2_MODULE 1
-#define CONFIG_RADIO_AZTECH_MODULE 1
-#define CONFIG_RADIO_GEMTEK_MODULE 1
+#undef CONFIG_RADIO_CADET
+#undef CONFIG_RADIO_RTRACK
+#undef CONFIG_RADIO_RTRACK2
+#undef CONFIG_RADIO_AZTECH
+#undef CONFIG_RADIO_GEMTEK
#define CONFIG_RADIO_GEMTEK_PCI_MODULE 1
#define CONFIG_RADIO_MAXIRADIO_MODULE 1
#define CONFIG_RADIO_MAESTRO_MODULE 1
-#define CONFIG_RADIO_SF16FMI_MODULE 1
-#define CONFIG_RADIO_SF16FMR2_MODULE 1
-#define CONFIG_RADIO_TERRATEC_MODULE 1
-#define CONFIG_RADIO_TRUST_MODULE 1
-#define CONFIG_RADIO_TYPHOON_MODULE 1
-#define CONFIG_RADIO_TYPHOON_PROC_FS 1
-#define CONFIG_RADIO_ZOLTRIX_MODULE 1
+#undef CONFIG_RADIO_SF16FMI
+#undef CONFIG_RADIO_SF16FMR2
+#undef CONFIG_RADIO_TERRATEC
+#undef CONFIG_RADIO_TRUST
+#undef CONFIG_RADIO_TYPHOON
+#undef CONFIG_RADIO_ZOLTRIX
/*
* Digital Video Broadcasting Devices
*/
-#undef CONFIG_DVB
+#define CONFIG_DVB 1
+#define CONFIG_DVB_CORE_MODULE 1
+
+/*
+ * Supported SAA7146 based PCI Adapters
+ */
+#define CONFIG_DVB_AV7110_MODULE 1
+#define CONFIG_DVB_AV7110_OSD 1
+#define CONFIG_DVB_BUDGET_MODULE 1
+#define CONFIG_DVB_BUDGET_CI_MODULE 1
+#define CONFIG_DVB_BUDGET_AV_MODULE 1
+#define CONFIG_DVB_BUDGET_PATCH_MODULE 1
+
+/*
+ * Supported USB Adapters
+ */
+#define CONFIG_DVB_USB_MODULE 1
+#undef CONFIG_DVB_USB_DEBUG
+#define CONFIG_DVB_USB_A800_MODULE 1
+#define CONFIG_DVB_USB_DIBUSB_MB_MODULE 1
+#undef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
+#define CONFIG_DVB_USB_DIBUSB_MC_MODULE 1
+#define CONFIG_DVB_USB_UMT_010_MODULE 1
+#define CONFIG_DVB_USB_CXUSB_MODULE 1
+#define CONFIG_DVB_USB_DIGITV_MODULE 1
+#define CONFIG_DVB_USB_VP7045_MODULE 1
+#define CONFIG_DVB_USB_VP702X_MODULE 1
+#define CONFIG_DVB_USB_NOVA_T_USB2_MODULE 1
+#define CONFIG_DVB_USB_DTT200U_MODULE 1
+#define CONFIG_DVB_TTUSB_BUDGET_MODULE 1
+#define CONFIG_DVB_TTUSB_DEC_MODULE 1
+#define CONFIG_DVB_CINERGYT2_MODULE 1
+#define CONFIG_DVB_CINERGYT2_TUNING 1
+#define CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT 32
+#define CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE 512
+#define CONFIG_DVB_CINERGYT2_QUERY_INTERVAL 250
+#define CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE 1
+#define CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL 100
+
+/*
+ * Supported FlexCopII (B2C2) Adapters
+ */
+#define CONFIG_DVB_B2C2_FLEXCOP_MODULE 1
+#define CONFIG_DVB_B2C2_FLEXCOP_PCI_MODULE 1
+#define CONFIG_DVB_B2C2_FLEXCOP_USB_MODULE 1
+#undef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
+
+/*
+ * Supported BT878 Adapters
+ */
+#define CONFIG_DVB_BT8XX_MODULE 1
+
+/*
+ * Supported Pluto2 Adapters
+ */
+#define CONFIG_DVB_PLUTO2_MODULE 1
+
+/*
+ * Supported DVB Frontends
+ */
+
+/*
+ * Customise DVB Frontends
+ */
+
+/*
+ * DVB-S (satellite) frontends
+ */
+#define CONFIG_DVB_STV0299_MODULE 1
+#define CONFIG_DVB_CX24110_MODULE 1
+#define CONFIG_DVB_CX24123_MODULE 1
+#define CONFIG_DVB_TDA8083_MODULE 1
+#define CONFIG_DVB_MT312_MODULE 1
+#define CONFIG_DVB_VES1X93_MODULE 1
+#define CONFIG_DVB_S5H1420_MODULE 1
+
+/*
+ * DVB-T (terrestrial) frontends
+ */
+#define CONFIG_DVB_SP8870_MODULE 1
+#define CONFIG_DVB_SP887X_MODULE 1
+#define CONFIG_DVB_CX22700_MODULE 1
+#define CONFIG_DVB_CX22702_MODULE 1
+#define CONFIG_DVB_L64781_MODULE 1
+#define CONFIG_DVB_TDA1004X_MODULE 1
+#define CONFIG_DVB_NXT6000_MODULE 1
+#define CONFIG_DVB_MT352_MODULE 1
+#define CONFIG_DVB_ZL10353_MODULE 1
+#define CONFIG_DVB_DIB3000MB_MODULE 1
+#define CONFIG_DVB_DIB3000MC_MODULE 1
+
+/*
+ * DVB-C (cable) frontends
+ */
+#define CONFIG_DVB_VES1820_MODULE 1
+#define CONFIG_DVB_TDA10021_MODULE 1
+#define CONFIG_DVB_STV0297_MODULE 1
+
+/*
+ * ATSC (North American/Korean Terresterial DTV) frontends
+ */
+#define CONFIG_DVB_NXT200X_MODULE 1
+#define CONFIG_DVB_OR51211_MODULE 1
+#define CONFIG_DVB_OR51132_MODULE 1
+#define CONFIG_DVB_BCM3510_MODULE 1
+#define CONFIG_DVB_LGDT330X_MODULE 1
#define CONFIG_VIDEO_SAA7146_MODULE 1
#define CONFIG_VIDEO_SAA7146_VV_MODULE 1
#define CONFIG_VIDEO_VIDEOBUF_MODULE 1
#define CONFIG_VIDEO_TUNER_MODULE 1
#define CONFIG_VIDEO_BUF_MODULE 1
+#define CONFIG_VIDEO_BUF_DVB_MODULE 1
#define CONFIG_VIDEO_BTCX_MODULE 1
#define CONFIG_VIDEO_IR_MODULE 1
+#define CONFIG_VIDEO_TVEEPROM_MODULE 1
+#define CONFIG_USB_DABUSB_MODULE 1
/*
* Graphics support
*/
#define CONFIG_FB 1
+#define CONFIG_FB_CFB_FILLRECT 1
+#define CONFIG_FB_CFB_COPYAREA 1
+#define CONFIG_FB_CFB_IMAGEBLIT 1
+#undef CONFIG_FB_MACMODES
+#undef CONFIG_FB_FIRMWARE_EDID
+#define CONFIG_FB_MODE_HELPERS 1
+#define CONFIG_FB_TILEBLITTING 1
+#define CONFIG_FB_CIRRUS_MODULE 1
#undef CONFIG_FB_PM2
#undef CONFIG_FB_CYBER2000
+#undef CONFIG_FB_ARC
#undef CONFIG_FB_ASILIANT
#undef CONFIG_FB_IMSTT
#define CONFIG_FB_VGA16_MODULE 1
#define CONFIG_FB_VESA 1
#define CONFIG_VIDEO_SELECT 1
-#define CONFIG_FB_HGA_MODULE 1
-#define CONFIG_FB_HGA_ACCEL 1
+#undef CONFIG_FB_HGA
+#undef CONFIG_FB_S1D13XXX
+#undef CONFIG_FB_NVIDIA
#define CONFIG_FB_RIVA_MODULE 1
+#undef CONFIG_FB_RIVA_I2C
+#undef CONFIG_FB_RIVA_DEBUG
#define CONFIG_FB_I810_MODULE 1
#define CONFIG_FB_I810_GTF 1
+#define CONFIG_FB_I810_I2C 1
+#define CONFIG_FB_INTEL_MODULE 1
+#undef CONFIG_FB_INTEL_DEBUG
#define CONFIG_FB_MATROX_MODULE 1
#define CONFIG_FB_MATROX_MILLENIUM 1
#define CONFIG_FB_MATROX_MYSTIQUE 1
-#define CONFIG_FB_MATROX_G450 1
-#define CONFIG_FB_MATROX_G100 1
+#define CONFIG_FB_MATROX_G 1
#define CONFIG_FB_MATROX_I2C_MODULE 1
#define CONFIG_FB_MATROX_MAVEN_MODULE 1
#define CONFIG_FB_MATROX_MULTIHEAD 1
-#undef CONFIG_FB_RADEON_OLD
#define CONFIG_FB_RADEON_MODULE 1
#define CONFIG_FB_RADEON_I2C 1
#undef CONFIG_FB_RADEON_DEBUG
#define CONFIG_FB_ATY128_MODULE 1
#define CONFIG_FB_ATY_MODULE 1
#define CONFIG_FB_ATY_CT 1
+#define CONFIG_FB_ATY_GENERIC_LCD 1
#define CONFIG_FB_ATY_GX 1
-#undef CONFIG_FB_ATY_XL_INIT
+#define CONFIG_FB_SAVAGE_MODULE 1
+#define CONFIG_FB_SAVAGE_I2C 1
+#define CONFIG_FB_SAVAGE_ACCEL 1
#undef CONFIG_FB_SIS
#define CONFIG_FB_NEOMAGIC_MODULE 1
#define CONFIG_FB_KYRO_MODULE 1
#define CONFIG_FB_3DFX_MODULE 1
#define CONFIG_FB_3DFX_ACCEL 1
#define CONFIG_FB_VOODOO1_MODULE 1
+#define CONFIG_FB_CYBLA_MODULE 1
#define CONFIG_FB_TRIDENT_MODULE 1
#define CONFIG_FB_TRIDENT_ACCEL 1
+#undef CONFIG_FB_GEODE
#undef CONFIG_FB_VIRTUAL
/*
* Console display driver support
*/
#define CONFIG_VGA_CONSOLE 1
-#define CONFIG_MDA_CONSOLE_MODULE 1
+#define CONFIG_VGACON_SOFT_SCROLLBACK 1
+#define CONFIG_VGACON_SOFT_SCROLLBACK_SIZE 64
+#undef CONFIG_MDA_CONSOLE
#define CONFIG_DUMMY_CONSOLE 1
#define CONFIG_FRAMEBUFFER_CONSOLE 1
-#define CONFIG_PCI_CONSOLE 1
+#define CONFIG_FRAMEBUFFER_CONSOLE_ROTATION 1
#undef CONFIG_FONTS
#define CONFIG_FONT_8x8 1
#define CONFIG_FONT_8x16 1
#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
#define CONFIG_SND_OSSEMUL 1
#define CONFIG_SND_MIXER_OSS_MODULE 1
#define CONFIG_SND_PCM_OSS_MODULE 1
+#define CONFIG_SND_PCM_OSS_PLUGINS 1
#define CONFIG_SND_SEQUENCER_OSS 1
#define CONFIG_SND_RTCTIMER_MODULE 1
+#define CONFIG_SND_SEQ_RTCTIMER_DEFAULT 1
+#define CONFIG_SND_DYNAMIC_MINORS 1
+#undef CONFIG_SND_SUPPORT_OLD_API
+#define CONFIG_SND_VERBOSE_PROCFS 1
#undef CONFIG_SND_VERBOSE_PRINTK
#undef CONFIG_SND_DEBUG
#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
/*
* ISA devices
*/
-#define CONFIG_SND_AD1816A_MODULE 1
-#define CONFIG_SND_AD1848_MODULE 1
-#define CONFIG_SND_CS4231_MODULE 1
-#define CONFIG_SND_CS4232_MODULE 1
+#define CONFIG_SND_CS4231_LIB_MODULE 1
+#define CONFIG_SND_ADLIB_MODULE 1
+#undef CONFIG_SND_AD1816A
+#undef CONFIG_SND_AD1848
+#undef CONFIG_SND_ALS100
+#undef CONFIG_SND_AZT2320
+#undef CONFIG_SND_CMI8330
+#undef CONFIG_SND_CS4231
+#undef CONFIG_SND_CS4232
#define CONFIG_SND_CS4236_MODULE 1
-#define CONFIG_SND_ES968_MODULE 1
-#define CONFIG_SND_ES1688_MODULE 1
+#undef CONFIG_SND_DT019X
+#undef CONFIG_SND_ES968
+#undef CONFIG_SND_ES1688
#define CONFIG_SND_ES18XX_MODULE 1
-#define CONFIG_SND_GUSCLASSIC_MODULE 1
-#define CONFIG_SND_GUSEXTREME_MODULE 1
-#define CONFIG_SND_GUSMAX_MODULE 1
-#define CONFIG_SND_INTERWAVE_MODULE 1
-#define CONFIG_SND_INTERWAVE_STB_MODULE 1
-#define CONFIG_SND_OPTI92X_AD1848_MODULE 1
-#define CONFIG_SND_OPTI92X_CS4231_MODULE 1
-#define CONFIG_SND_OPTI93X_MODULE 1
-#define CONFIG_SND_SB8_MODULE 1
+#undef CONFIG_SND_GUSCLASSIC
+#undef CONFIG_SND_GUSEXTREME
+#undef CONFIG_SND_GUSMAX
+#undef CONFIG_SND_INTERWAVE
+#undef CONFIG_SND_INTERWAVE_STB
+#define CONFIG_SND_OPL3SA2_MODULE 1
+#undef CONFIG_SND_OPTI92X_AD1848
+#undef CONFIG_SND_OPTI92X_CS4231
+#undef CONFIG_SND_OPTI93X
+#define CONFIG_SND_MIRO_MODULE 1
+#undef CONFIG_SND_SB8
#define CONFIG_SND_SB16_MODULE 1
#define CONFIG_SND_SBAWE_MODULE 1
-#define CONFIG_SND_SB16_CSP 1
+#undef CONFIG_SND_SB16_CSP
+#undef CONFIG_SND_SGALAXY
+#undef CONFIG_SND_SSCAPE
#undef CONFIG_SND_WAVEFRONT
-#define CONFIG_SND_ALS100_MODULE 1
-#define CONFIG_SND_AZT2320_MODULE 1
-#define CONFIG_SND_CMI8330_MODULE 1
-#define CONFIG_SND_DT019X_MODULE 1
-#define CONFIG_SND_OPL3SA2_MODULE 1
-#define CONFIG_SND_SGALAXY_MODULE 1
-#define CONFIG_SND_SSCAPE_MODULE 1
/*
* PCI devices
*/
-#define CONFIG_SND_AC97_CODEC_MODULE 1
+#define CONFIG_SND_AD1889_MODULE 1
+#define CONFIG_SND_ALS300_MODULE 1
+#define CONFIG_SND_ALS4000_MODULE 1
#define CONFIG_SND_ALI5451_MODULE 1
#define CONFIG_SND_ATIIXP_MODULE 1
+#define CONFIG_SND_ATIIXP_MODEM_MODULE 1
#define CONFIG_SND_AU8810_MODULE 1
#define CONFIG_SND_AU8820_MODULE 1
#define CONFIG_SND_AU8830_MODULE 1
#define CONFIG_SND_AZT3328_MODULE 1
#define CONFIG_SND_BT87X_MODULE 1
+#undef CONFIG_SND_BT87X_OVERCLOCK
+#define CONFIG_SND_CA0106_MODULE 1
+#define CONFIG_SND_CMIPCI_MODULE 1
+#define CONFIG_SND_CS4281_MODULE 1
#define CONFIG_SND_CS46XX_MODULE 1
#define CONFIG_SND_CS46XX_NEW_DSP 1
-#define CONFIG_SND_CS4281_MODULE 1
+#define CONFIG_SND_CS5535AUDIO_MODULE 1
#define CONFIG_SND_EMU10K1_MODULE 1
-#define CONFIG_SND_KORG1212_MODULE 1
-#define CONFIG_SND_MIXART_MODULE 1
-#define CONFIG_SND_NM256_MODULE 1
-#define CONFIG_SND_RME32_MODULE 1
-#define CONFIG_SND_RME96_MODULE 1
-#define CONFIG_SND_RME9652_MODULE 1
-#define CONFIG_SND_HDSP_MODULE 1
-#define CONFIG_SND_TRIDENT_MODULE 1
-#define CONFIG_SND_YMFPCI_MODULE 1
-#define CONFIG_SND_ALS4000_MODULE 1
-#define CONFIG_SND_CMIPCI_MODULE 1
+#define CONFIG_SND_EMU10K1X_MODULE 1
#define CONFIG_SND_ENS1370_MODULE 1
#define CONFIG_SND_ENS1371_MODULE 1
#define CONFIG_SND_ES1938_MODULE 1
#define CONFIG_SND_ES1968_MODULE 1
-#define CONFIG_SND_MAESTRO3_MODULE 1
#define CONFIG_SND_FM801_MODULE 1
+#define CONFIG_SND_FM801_TEA575X_BOOL 1
#define CONFIG_SND_FM801_TEA575X_MODULE 1
+#define CONFIG_SND_HDA_INTEL_MODULE 1
+#define CONFIG_SND_HDSP_MODULE 1
+#define CONFIG_SND_HDSPM_MODULE 1
#define CONFIG_SND_ICE1712_MODULE 1
#define CONFIG_SND_ICE1724_MODULE 1
#define CONFIG_SND_INTEL8X0_MODULE 1
#define CONFIG_SND_INTEL8X0M_MODULE 1
+#define CONFIG_SND_KORG1212_MODULE 1
+#define CONFIG_SND_MAESTRO3_MODULE 1
+#define CONFIG_SND_MIXART_MODULE 1
+#define CONFIG_SND_NM256_MODULE 1
+#define CONFIG_SND_PCXHR_MODULE 1
+#define CONFIG_SND_RIPTIDE_MODULE 1
+#define CONFIG_SND_RME32_MODULE 1
+#define CONFIG_SND_RME96_MODULE 1
+#define CONFIG_SND_RME9652_MODULE 1
#define CONFIG_SND_SONICVIBES_MODULE 1
+#define CONFIG_SND_TRIDENT_MODULE 1
#define CONFIG_SND_VIA82XX_MODULE 1
+#define CONFIG_SND_VIA82XX_MODEM_MODULE 1
#define CONFIG_SND_VX222_MODULE 1
+#define CONFIG_SND_YMFPCI_MODULE 1
/*
- * ALSA USB devices
+ * USB devices
*/
#define CONFIG_SND_USB_AUDIO_MODULE 1
+#define CONFIG_SND_USB_USX2Y_MODULE 1
/*
* PCMCIA devices
*/
#undef CONFIG_SND_VXPOCKET
-#undef CONFIG_SND_VXP440
-#define CONFIG_SND_PDAUDIOCF_MODULE 1
+#undef CONFIG_SND_PDAUDIOCF
/*
* Open Sound System
/*
* 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_DEVICEFS 1
#undef CONFIG_USB_BANDWIDTH
#undef CONFIG_USB_DYNAMIC_MINORS
+#undef CONFIG_USB_SUSPEND
+#undef CONFIG_USB_OTG
/*
* 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_ISP116X_HCD_MODULE 1
#define CONFIG_USB_OHCI_HCD_MODULE 1
+#undef CONFIG_USB_OHCI_BIG_ENDIAN
+#define CONFIG_USB_OHCI_LITTLE_ENDIAN 1
#define CONFIG_USB_UHCI_HCD_MODULE 1
+#define CONFIG_USB_SL811_HCD_MODULE 1
+#define CONFIG_USB_SL811_CS_MODULE 1
/*
* USB Device Class drivers
*/
-#define CONFIG_USB_AUDIO_MODULE 1
+#define CONFIG_USB_ACM_MODULE 1
+#define CONFIG_USB_PRINTER_MODULE 1
/*
- * USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
+ * NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+ */
+
+/*
+ * may also be needed; see USB_STORAGE Help for more information
*/
-#define CONFIG_USB_MIDI_MODULE 1
-#define CONFIG_USB_ACM_MODULE 1
-#define CONFIG_USB_PRINTER_MODULE 1
#define CONFIG_USB_STORAGE_MODULE 1
#undef CONFIG_USB_STORAGE_DEBUG
#define CONFIG_USB_STORAGE_DATAFAB 1
#define CONFIG_USB_STORAGE_FREECOM 1
#define CONFIG_USB_STORAGE_ISD200 1
#define CONFIG_USB_STORAGE_DPCM 1
-#define CONFIG_USB_STORAGE_HP8200e 1
+#define CONFIG_USB_STORAGE_USBAT 1
#define CONFIG_USB_STORAGE_SDDR09 1
#define CONFIG_USB_STORAGE_SDDR55 1
#define CONFIG_USB_STORAGE_JUMPSHOT 1
+#define CONFIG_USB_STORAGE_ALAUDA 1
+#define CONFIG_USB_LIBUSUAL 1
/*
- * USB Human Interface Devices (HID)
+ * USB Input Devices
*/
#define CONFIG_USB_HID 1
#define CONFIG_USB_HIDINPUT 1
+#undef CONFIG_USB_HIDINPUT_POWERBOOK
#define CONFIG_HID_FF 1
#define CONFIG_HID_PID 1
#define CONFIG_LOGITECH_FF 1
#define CONFIG_USB_HIDDEV 1
#define CONFIG_USB_AIPTEK_MODULE 1
#define CONFIG_USB_WACOM_MODULE 1
+#define CONFIG_USB_ACECAD_MODULE 1
#define CONFIG_USB_KBTAB_MODULE 1
#define CONFIG_USB_POWERMATE_MODULE 1
-#define CONFIG_USB_MTOUCH_MODULE 1
-#define CONFIG_USB_EGALAX_MODULE 1
+#define CONFIG_USB_TOUCHSCREEN_MODULE 1
+#define CONFIG_USB_TOUCHSCREEN_EGALAX 1
+#define CONFIG_USB_TOUCHSCREEN_PANJIT 1
+#define CONFIG_USB_TOUCHSCREEN_3M 1
+#define CONFIG_USB_TOUCHSCREEN_ITM 1
+#undef CONFIG_USB_YEALINK
#define CONFIG_USB_XPAD_MODULE 1
#define CONFIG_USB_ATI_REMOTE_MODULE 1
+#define CONFIG_USB_ATI_REMOTE2_MODULE 1
+#define CONFIG_USB_KEYSPAN_REMOTE_MODULE 1
+#define CONFIG_USB_APPLETOUCH_MODULE 1
/*
* USB Imaging devices
*/
#define CONFIG_USB_MDC800_MODULE 1
#define CONFIG_USB_MICROTEK_MODULE 1
-#define CONFIG_USB_HPUSBSCSI_MODULE 1
-
-/*
- * USB Multimedia devices
- */
-#define CONFIG_USB_DABUSB_MODULE 1
-#define CONFIG_USB_VICAM_MODULE 1
-#define CONFIG_USB_DSBR_MODULE 1
-#define CONFIG_USB_IBMCAM_MODULE 1
-#define CONFIG_USB_KONICAWC_MODULE 1
-#define CONFIG_USB_OV511_MODULE 1
-#define CONFIG_USB_SE401_MODULE 1
-#define CONFIG_USB_STV680_MODULE 1
-#define CONFIG_USB_W9968CF_MODULE 1
/*
- * USB Network adaptors
+ * USB Network Adapters
*/
#define CONFIG_USB_CATC_MODULE 1
#define CONFIG_USB_KAWETH_MODULE 1
#define CONFIG_USB_PEGASUS_MODULE 1
#define CONFIG_USB_RTL8150_MODULE 1
#define CONFIG_USB_USBNET_MODULE 1
-
-/*
- * USB Host-to-Host Cables
- */
+#define CONFIG_USB_NET_AX8817X_MODULE 1
+#define CONFIG_USB_NET_CDCETHER_MODULE 1
+#define CONFIG_USB_NET_GL620A_MODULE 1
+#define CONFIG_USB_NET_NET1080_MODULE 1
+#define CONFIG_USB_NET_PLUSB_MODULE 1
+#define CONFIG_USB_NET_RNDIS_HOST_MODULE 1
+#define CONFIG_USB_NET_CDC_SUBSET_MODULE 1
#define CONFIG_USB_ALI_M5632 1
#define CONFIG_USB_AN2720 1
#define CONFIG_USB_BELKIN 1
-#define CONFIG_USB_GENESYS 1
-#define CONFIG_USB_NET1080 1
-#define CONFIG_USB_PL2301 1
-
-/*
- * Intelligent USB Devices/Gadgets
- */
#define CONFIG_USB_ARMLINUX 1
#define CONFIG_USB_EPSON2888 1
-#define CONFIG_USB_ZAURUS 1
-#define CONFIG_USB_CDCETHER 1
-
-/*
- * USB Network Adapters
- */
-#define CONFIG_USB_AX8817X 1
+#define CONFIG_USB_NET_ZAURUS_MODULE 1
+#define CONFIG_USB_ZD1201_MODULE 1
+#define CONFIG_USB_MON 1
/*
* USB port drivers
*/
#define CONFIG_USB_SERIAL_MODULE 1
#define CONFIG_USB_SERIAL_GENERIC 1
+#define CONFIG_USB_SERIAL_AIRPRIME_MODULE 1
+#define CONFIG_USB_SERIAL_ANYDATA_MODULE 1
+#define CONFIG_USB_SERIAL_ARK3116_MODULE 1
#define CONFIG_USB_SERIAL_BELKIN_MODULE 1
+#define CONFIG_USB_SERIAL_WHITEHEAT_MODULE 1
#define CONFIG_USB_SERIAL_DIGI_ACCELEPORT_MODULE 1
+#define CONFIG_USB_SERIAL_CP2101_MODULE 1
+#define CONFIG_USB_SERIAL_CYPRESS_M8_MODULE 1
#define CONFIG_USB_SERIAL_EMPEG_MODULE 1
#define CONFIG_USB_SERIAL_FTDI_SIO_MODULE 1
+#define CONFIG_USB_SERIAL_FUNSOFT_MODULE 1
#define CONFIG_USB_SERIAL_VISOR_MODULE 1
#define CONFIG_USB_SERIAL_IPAQ_MODULE 1
#define CONFIG_USB_SERIAL_IR_MODULE 1
#define CONFIG_USB_SERIAL_EDGEPORT_MODULE 1
#define CONFIG_USB_SERIAL_EDGEPORT_TI_MODULE 1
+#define CONFIG_USB_SERIAL_GARMIN_MODULE 1
+#define CONFIG_USB_SERIAL_IPW_MODULE 1
#define CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE 1
#define CONFIG_USB_SERIAL_KEYSPAN_MODULE 1
#define CONFIG_USB_SERIAL_KEYSPAN_MPR 1
#define CONFIG_USB_SERIAL_KLSI_MODULE 1
#define CONFIG_USB_SERIAL_KOBIL_SCT_MODULE 1
#define CONFIG_USB_SERIAL_MCT_U232_MODULE 1
+#define CONFIG_USB_SERIAL_NAVMAN_MODULE 1
#define CONFIG_USB_SERIAL_PL2303_MODULE 1
+#define CONFIG_USB_SERIAL_HP4X_MODULE 1
#define CONFIG_USB_SERIAL_SAFE_MODULE 1
#define CONFIG_USB_SERIAL_SAFE_PADDED 1
+#define CONFIG_USB_SERIAL_TI_MODULE 1
#define CONFIG_USB_SERIAL_CYBERJACK_MODULE 1
#define CONFIG_USB_SERIAL_XIRCOM_MODULE 1
+#define CONFIG_USB_SERIAL_OPTION_MODULE 1
#define CONFIG_USB_SERIAL_OMNINET_MODULE 1
#define CONFIG_USB_EZUSB 1
* USB Miscellaneous drivers
*/
#define CONFIG_USB_EMI62_MODULE 1
-#undef CONFIG_USB_EMI26
-#define CONFIG_USB_TIGL_MODULE 1
+#define CONFIG_USB_EMI26_MODULE 1
#define CONFIG_USB_AUERSWALD_MODULE 1
#define CONFIG_USB_RIO500_MODULE 1
#define CONFIG_USB_LEGOTOWER_MODULE 1
#define CONFIG_USB_LCD_MODULE 1
#define CONFIG_USB_LED_MODULE 1
#undef CONFIG_USB_CYTHERM
+#define CONFIG_USB_PHIDGETKIT_MODULE 1
#define CONFIG_USB_PHIDGETSERVO_MODULE 1
+#define CONFIG_USB_IDMOUSE_MODULE 1
+#define CONFIG_USB_SISUSBVGA_MODULE 1
+#define CONFIG_USB_SISUSBVGA_CON 1
+#define CONFIG_USB_LD_MODULE 1
#define CONFIG_USB_TEST_MODULE 1
+/*
+ * USB DSL modem support
+ */
+#define CONFIG_USB_ATM_MODULE 1
+#define CONFIG_USB_SPEEDTOUCH_MODULE 1
+#define CONFIG_USB_CXACRU_MODULE 1
+#define CONFIG_USB_UEAGLEATM_MODULE 1
+#define CONFIG_USB_XUSBATM_MODULE 1
+
/*
* USB Gadget Support
*/
#undef CONFIG_USB_GADGET
+/*
+ * MMC/SD Card support
+ */
+#define CONFIG_MMC_MODULE 1
+#undef CONFIG_MMC_DEBUG
+#define CONFIG_MMC_BLOCK_MODULE 1
+#define CONFIG_MMC_SDHCI_MODULE 1
+#define CONFIG_MMC_WBSD_MODULE 1
+
+/*
+ * LED devices
+ */
+#undef CONFIG_NEW_LEDS
+
+/*
+ * LED drivers
+ */
+
+/*
+ * LED Triggers
+ */
+
+/*
+ * InfiniBand support
+ */
+#define CONFIG_INFINIBAND_MODULE 1
+#define CONFIG_INFINIBAND_USER_MAD_MODULE 1
+#define CONFIG_INFINIBAND_USER_ACCESS_MODULE 1
+#define CONFIG_INFINIBAND_MTHCA_MODULE 1
+#define CONFIG_INFINIBAND_MTHCA_DEBUG 1
+#define CONFIG_INFINIBAND_IPOIB_MODULE 1
+#define CONFIG_INFINIBAND_IPOIB_DEBUG 1
+#define CONFIG_INFINIBAND_IPOIB_DEBUG_DATA 1
+#define CONFIG_INFINIBAND_SRP_MODULE 1
+
+/*
+ * EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+ */
+#define CONFIG_EDAC 1
+
+/*
+ * Reporting subsystems
+ */
+#undef CONFIG_EDAC_DEBUG
+#define CONFIG_EDAC_MM_EDAC_MODULE 1
+#define CONFIG_EDAC_AMD76X_MODULE 1
+#define CONFIG_EDAC_E7XXX_MODULE 1
+#define CONFIG_EDAC_E752X_MODULE 1
+#define CONFIG_EDAC_I82875P_MODULE 1
+#define CONFIG_EDAC_I82860_MODULE 1
+#define CONFIG_EDAC_R82600_MODULE 1
+#define CONFIG_EDAC_POLL 1
+
+/*
+ * Real Time Clock
+ */
+#define CONFIG_RTC_LIB_MODULE 1
+#define CONFIG_RTC_CLASS_MODULE 1
+
+/*
+ * RTC interfaces
+ */
+#define CONFIG_RTC_INTF_SYSFS_MODULE 1
+#define CONFIG_RTC_INTF_PROC_MODULE 1
+#define CONFIG_RTC_INTF_DEV_MODULE 1
+
+/*
+ * RTC drivers
+ */
+#define CONFIG_RTC_DRV_X1205_MODULE 1
+#define CONFIG_RTC_DRV_DS1672_MODULE 1
+#define CONFIG_RTC_DRV_PCF8563_MODULE 1
+#define CONFIG_RTC_DRV_RS5C372_MODULE 1
+#undef CONFIG_RTC_DRV_M48T86
+#undef CONFIG_RTC_DRV_TEST
+
/*
* File systems
*/
#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_REISERFS_FS_SECURITY 1
#define CONFIG_JFS_FS_MODULE 1
#define CONFIG_JFS_POSIX_ACL 1
+#define CONFIG_JFS_SECURITY 1
#undef CONFIG_JFS_DEBUG
#undef CONFIG_JFS_STATISTICS
#define CONFIG_FS_POSIX_ACL 1
#define CONFIG_XFS_FS_MODULE 1
-#undef CONFIG_XFS_RT
+#define CONFIG_XFS_EXPORT 1
#define CONFIG_XFS_QUOTA 1
#define CONFIG_XFS_SECURITY 1
#define CONFIG_XFS_POSIX_ACL 1
+#undef CONFIG_XFS_RT
+#define CONFIG_OCFS2_FS_MODULE 1
#define CONFIG_MINIX_FS_MODULE 1
#define CONFIG_ROMFS_FS_MODULE 1
+#define CONFIG_INOTIFY 1
#define CONFIG_QUOTA 1
#undef CONFIG_QFMT_V1
#define CONFIG_QFMT_V2 1
#define CONFIG_QUOTACTL 1
+#define CONFIG_DNOTIFY 1
#define CONFIG_AUTOFS_FS_MODULE 1
#define CONFIG_AUTOFS4_FS_MODULE 1
+#define CONFIG_FUSE_FS_MODULE 1
/*
* CD-ROM/DVD Filesystems
#define CONFIG_ZISOFS 1
#define CONFIG_ZISOFS_FS 1
#define CONFIG_UDF_FS_MODULE 1
+#define CONFIG_UDF_NLS 1
/*
* 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_DEFAULT_CODEPAGE 437
+#define CONFIG_FAT_DEFAULT_IOCHARSET "ascii"
#undef CONFIG_NTFS_FS
/*
#define CONFIG_PROC_FS 1
#define CONFIG_PROC_KCORE 1
#define CONFIG_SYSFS 1
-#undef CONFIG_DEVFS_FS
-#define CONFIG_DEVPTS_FS_XATTR 1
-#define CONFIG_DEVPTS_FS_SECURITY 1
#define CONFIG_TMPFS 1
#define CONFIG_HUGETLBFS 1
#define CONFIG_HUGETLB_PAGE 1
#define CONFIG_RAMFS 1
+#define CONFIG_CONFIGFS_FS_MODULE 1
/*
* Miscellaneous filesystems
#undef CONFIG_JFFS_FS
#define CONFIG_JFFS2_FS_MODULE 1
#define CONFIG_JFFS2_FS_DEBUG 0
-#define CONFIG_JFFS2_FS_NAND 1
+#define CONFIG_JFFS2_FS_WRITEBUFFER 1
+#define CONFIG_JFFS2_SUMMARY 1
+#undef CONFIG_JFFS2_COMPRESSION_OPTIONS
+#define CONFIG_JFFS2_ZLIB 1
+#define CONFIG_JFFS2_RTIME 1
+#undef CONFIG_JFFS2_RUBIN
#define CONFIG_CRAMFS_MODULE 1
+#define CONFIG_SQUASHFS_MODULE 1
+#undef CONFIG_SQUASHFS_EMBEDDED
+#define CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE 3
+#undef CONFIG_SQUASHFS_VMALLOC
#define CONFIG_VXFS_FS_MODULE 1
#undef CONFIG_HPFS_FS
#define CONFIG_QNX4FS_FS_MODULE 1
-#undef CONFIG_QNX4FS_RW
#define CONFIG_SYSV_FS_MODULE 1
#define CONFIG_UFS_FS_MODULE 1
-#undef CONFIG_UFS_FS_WRITE
/*
* Network File Systems
*/
#define CONFIG_NFS_FS_MODULE 1
#define CONFIG_NFS_V3 1
+#define CONFIG_NFS_V3_ACL 1
#define CONFIG_NFS_V4 1
#define CONFIG_NFS_DIRECTIO 1
#define CONFIG_NFSD_MODULE 1
+#define CONFIG_NFSD_V2_ACL 1
#define CONFIG_NFSD_V3 1
+#define CONFIG_NFSD_V3_ACL 1
#define CONFIG_NFSD_V4 1
#define CONFIG_NFSD_TCP 1
#define CONFIG_LOCKD_MODULE 1
#define CONFIG_LOCKD_V4 1
#define CONFIG_EXPORTFS_MODULE 1
+#define CONFIG_NFS_ACL_SUPPORT_MODULE 1
+#define CONFIG_NFS_COMMON 1
#define CONFIG_SUNRPC_MODULE 1
#define CONFIG_SUNRPC_GSS_MODULE 1
#define CONFIG_RPCSEC_GSS_KRB5_MODULE 1
-#define CONFIG_SMB_FS_MODULE 1
-#undef CONFIG_SMB_NLS_DEFAULT
+#define CONFIG_RPCSEC_GSS_SPKM3_MODULE 1
+#undef CONFIG_SMB_FS
#define CONFIG_CIFS_MODULE 1
#undef CONFIG_CIFS_STATS
+#define CONFIG_CIFS_XATTR 1
+#define CONFIG_CIFS_POSIX 1
+#undef CONFIG_CIFS_EXPERIMENTAL
#define CONFIG_NCP_FS_MODULE 1
#define CONFIG_NCPFS_PACKET_SIGNING 1
#define CONFIG_NCPFS_IOCTL_LOCKING 1
#define CONFIG_NCPFS_SMALLDOS 1
#define CONFIG_NCPFS_NLS 1
#define CONFIG_NCPFS_EXTRAS 1
-#undef CONFIG_CODA_FS
+#define CONFIG_CODA_FS_MODULE 1
+#undef CONFIG_CODA_FS_OLD_API
#undef CONFIG_AFS_FS
+#define CONFIG_9P_FS_MODULE 1
/*
* Partition Types
#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
#define CONFIG_SOLARIS_X86_PARTITION 1
#define CONFIG_UNIXWARE_DISKLABEL 1
#undef CONFIG_LDM_PARTITION
-#undef CONFIG_NEC98_PARTITION
#define CONFIG_SGI_PARTITION 1
#undef CONFIG_ULTRIX_PARTITION
#define CONFIG_SUN_PARTITION 1
+#define CONFIG_KARMA_PARTITION 1
#define CONFIG_EFI_PARTITION 1
/*
*/
#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_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_UTF8_MODULE 1
/*
- * Profiling support
+ * Instrumentation Support
*/
#define CONFIG_PROFILING 1
#define CONFIG_OPROFILE_MODULE 1
+#define CONFIG_KPROBES 1
/*
* Kernel hacking
*/
+#undef CONFIG_PRINTK_TIME
+#define CONFIG_MAGIC_SYSRQ 1
#define CONFIG_DEBUG_KERNEL 1
-#define CONFIG_EARLY_PRINTK 1
-#define CONFIG_DEBUG_STACKOVERFLOW 1
-#undef CONFIG_DEBUG_STACK_USAGE
+#define CONFIG_LOG_BUF_SHIFT 17
+#define CONFIG_DETECT_SOFTLOCKUP 1
+#define CONFIG_SCHEDSTATS 1
#undef CONFIG_DEBUG_SLAB
-#define CONFIG_MAGIC_SYSRQ 1
-#undef CONFIG_DEBUG_SPINLOCK
-#undef CONFIG_DEBUG_PAGEALLOC
-#undef CONFIG_DEBUG_HIGHMEM
-#define CONFIG_DEBUG_INFO 1
+#define CONFIG_DEBUG_MUTEXES 1
+#define CONFIG_DEBUG_SPINLOCK 1
#define CONFIG_DEBUG_SPINLOCK_SLEEP 1
+#undef CONFIG_DEBUG_KOBJECT
+#define CONFIG_DEBUG_HIGHMEM 1
+#define CONFIG_DEBUG_BUGVERBOSE 1
+#define CONFIG_DEBUG_INFO 1
+#define CONFIG_DEBUG_FS 1
+#define CONFIG_DEBUG_VM 1
#undef CONFIG_FRAME_POINTER
+#define CONFIG_UNWIND_INFO 1
+#undef CONFIG_FORCED_INLINING
+#define CONFIG_BOOT_DELAY 1
+#undef CONFIG_RCU_TORTURE_TEST
+#define CONFIG_EARLY_PRINTK 1
+#define CONFIG_DEBUG_STACKOVERFLOW 1
+#define CONFIG_DEBUG_STACK_USAGE 1
+#define CONFIG_STACK_BACKTRACE_COLS 2
+
+/*
+ * Page alloc debug is incompatible with Software Suspend on i386
+ */
+#define CONFIG_DEBUG_RODATA 1
+#define CONFIG_4KSTACKS 1
#define CONFIG_X86_FIND_SMP_CONFIG 1
#define CONFIG_X86_MPPARSE 1
+#define CONFIG_DOUBLEFAULT 1
/*
* Security options
*/
+#define CONFIG_KEYS 1
+#define CONFIG_KEYS_DEBUG_PROC_KEYS 1
#define CONFIG_SECURITY 1
#define CONFIG_SECURITY_NETWORK 1
+#define CONFIG_SECURITY_NETWORK_XFRM 1
#define CONFIG_SECURITY_CAPABILITIES 1
#undef CONFIG_SECURITY_ROOTPLUG
+#undef CONFIG_SECURITY_SECLVL
#define CONFIG_SECURITY_SELINUX 1
#define CONFIG_SECURITY_SELINUX_BOOTPARAM 1
+#define CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE 1
#define CONFIG_SECURITY_SELINUX_DISABLE 1
#define CONFIG_SECURITY_SELINUX_DEVELOP 1
-#undef CONFIG_SECURITY_SELINUX_MLS
+#define CONFIG_SECURITY_SELINUX_AVC_STATS 1
+#define CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE 1
/*
* Cryptographic options
#define CONFIG_CRYPTO_NULL_MODULE 1
#define CONFIG_CRYPTO_MD4_MODULE 1
#define CONFIG_CRYPTO_MD5 1
-#define CONFIG_CRYPTO_SHA1_MODULE 1
+#define CONFIG_CRYPTO_SHA1 1
#define CONFIG_CRYPTO_SHA256_MODULE 1
#define CONFIG_CRYPTO_SHA512_MODULE 1
+#define CONFIG_CRYPTO_WP512_MODULE 1
+#define CONFIG_CRYPTO_TGR192_MODULE 1
#define CONFIG_CRYPTO_DES_MODULE 1
#define CONFIG_CRYPTO_BLOWFISH_MODULE 1
#define CONFIG_CRYPTO_TWOFISH_MODULE 1
#define CONFIG_CRYPTO_SERPENT_MODULE 1
#define CONFIG_CRYPTO_AES_MODULE 1
+#define CONFIG_CRYPTO_AES_586_MODULE 1
#define CONFIG_CRYPTO_CAST5_MODULE 1
#define CONFIG_CRYPTO_CAST6_MODULE 1
+#define CONFIG_CRYPTO_TEA_MODULE 1
#define CONFIG_CRYPTO_ARC4_MODULE 1
+#define CONFIG_CRYPTO_KHAZAD_MODULE 1
+#define CONFIG_CRYPTO_ANUBIS_MODULE 1
#define CONFIG_CRYPTO_DEFLATE_MODULE 1
#define CONFIG_CRYPTO_MICHAEL_MIC_MODULE 1
#define CONFIG_CRYPTO_CRC32C_MODULE 1
#undef CONFIG_CRYPTO_TEST
+#define CONFIG_CRYPTO_SIGNATURE 1
+#define CONFIG_CRYPTO_SIGNATURE_DSA 1
+#define CONFIG_CRYPTO_MPILIB 1
+
+/*
+ * Hardware crypto devices
+ */
+#define CONFIG_CRYPTO_DEV_PADLOCK_MODULE 1
+#define CONFIG_CRYPTO_DEV_PADLOCK_AES 1
/*
* Library routines
*/
+#define CONFIG_CRC_CCITT_MODULE 1
+#define CONFIG_CRC16_MODULE 1
#define CONFIG_CRC32 1
#define CONFIG_LIBCRC32C_MODULE 1
#define CONFIG_ZLIB_INFLATE 1
#define CONFIG_ZLIB_DEFLATE_MODULE 1
-#define CONFIG_X86_SMP 1
-#define CONFIG_X86_HT 1
+#define CONFIG_TEXTSEARCH 1
+#define CONFIG_TEXTSEARCH_KMP_MODULE 1
+#define CONFIG_TEXTSEARCH_BM_MODULE 1
+#define CONFIG_TEXTSEARCH_FSM_MODULE 1
+#define CONFIG_GENERIC_HARDIRQS 1
+#define CONFIG_GENERIC_IRQ_PROBE 1
#define CONFIG_X86_BIOS_REBOOT 1
-#define CONFIG_X86_TRAMPOLINE 1
-#define CONFIG_X86_STD_RESOURCES 1
-#define CONFIG_PC 1
+#define CONFIG_KTIME_SCALAR 1
#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
{
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
*/
#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 *
/* declarations for linux/mm/highmem.c */
unsigned int nr_free_highpages(void);
+#ifdef CONFIG_XEN
+void kmap_flush_unused(void);
+#endif
#else /* CONFIG_HIGHMEM */
static inline unsigned int nr_free_highpages(void) { return 0; }
+#ifdef CONFIG_XEN
+static inline void kmap_flush_unused(void) { }
+#endif
static inline void *kmap(struct page *page)
{
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);
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))
#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
#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
__LINK_STATE_RX_SCHED,
__LINK_STATE_LINKWATCH_PENDING,
__LINK_STATE_DORMANT,
+ __LINK_STATE_QDISC_RUNNING,
};
#define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */
#define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */
#define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */
-#define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */
+#define NETIF_F_GSO 2048 /* Enable software GSO. */
#define NETIF_F_LLTX 4096 /* LockLess TX */
-#define NETIF_F_UFO 8192 /* Can offload UDP Large Send*/
+
+ /* Segmentation offload features */
+#define NETIF_F_GSO_SHIFT 16
+#define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
+#define NETIF_F_UFO (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT)
+#define NETIF_F_GSO_ROBUST (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
+
+#define NETIF_F_GEN_CSUM (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
+#define NETIF_F_ALL_CSUM (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM)
struct net_device *next_sched;
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;
* 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.
*/
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;
};
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);
clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
}
+static inline void netif_tx_lock(struct net_device *dev)
+{
+ spin_lock(&dev->_xmit_lock);
+ dev->xmit_lock_owner = smp_processor_id();
+}
+
+static inline void netif_tx_lock_bh(struct net_device *dev)
+{
+ spin_lock_bh(&dev->_xmit_lock);
+ dev->xmit_lock_owner = smp_processor_id();
+}
+
+static inline int netif_tx_trylock(struct net_device *dev)
+{
+ int ok = spin_trylock(&dev->_xmit_lock);
+ if (likely(ok))
+ dev->xmit_lock_owner = smp_processor_id();
+ return ok;
+}
+
+static inline void netif_tx_unlock(struct net_device *dev)
+{
+ dev->xmit_lock_owner = -1;
+ spin_unlock(&dev->_xmit_lock);
+}
+
+static inline void netif_tx_unlock_bh(struct net_device *dev)
+{
+ dev->xmit_lock_owner = -1;
+ spin_unlock_bh(&dev->_xmit_lock);
+}
+
static inline void netif_tx_disable(struct net_device *dev)
{
- spin_lock_bh(&dev->xmit_lock);
+ netif_tx_lock_bh(dev);
netif_stop_queue(dev);
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
}
/* These functions live elsewhere (drivers/net/net_init.c, but related) */
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
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 */
#define BRNF_BRIDGED 0x08
#define BRNF_NF_BRIDGE_PREROUTING 0x10
-
/* Only used in br_forward.c */
-static inline
-void nf_bridge_maybe_copy_header(struct sk_buff *skb)
+static inline int nf_bridge_maybe_copy_header(struct sk_buff *skb)
{
+ int err;
+
if (skb->nf_bridge) {
if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+ err = skb_cow(skb, 18);
+ if (err)
+ return err;
memcpy(skb->data - 18, skb->nf_bridge->data, 18);
skb_push(skb, 4);
- } else
+ } else {
+ err = skb_cow(skb, 16);
+ if (err)
+ return err;
memcpy(skb->data - 16, skb->nf_bridge->data, 16);
+ }
}
+ return 0;
}
/* This is called by the IP fragmenting code and it ensures there is
#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;
/* 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. */
/* 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
#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_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_8783_0 0x3208
#define PCI_DEVICE_ID_VIA_8237 0x3227
#define PCI_DEVICE_ID_VIA_8251 0x3287
-#define PCI_DEVICE_ID_VIA_3296_0 0x0296
+#define PCI_DEVICE_ID_VIA_8237A 0x3337
#define PCI_DEVICE_ID_VIA_8231 0x8231
#define PCI_DEVICE_ID_VIA_8231_4 0x8235
#define PCI_DEVICE_ID_VIA_8365_1 0x8305
+#define PCI_DEVICE_ID_VIA_CX700 0x8324
#define PCI_DEVICE_ID_VIA_8371_1 0x8391
#define PCI_DEVICE_ID_VIA_82C598_1 0x8598
#define PCI_DEVICE_ID_VIA_838X_1 0xB188
#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
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];
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
* @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
nfctinfo:3;
__u8 pkt_type:3,
fclone:2,
+#ifndef CONFIG_XEN
ipvs_property:1;
+#else
+ ipvs_property:1,
+ proto_data_valid:1,
+ proto_csum_blank:1;
+#endif
__be16 protocol;
void (*destructor)(struct sk_buff *skb);
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);
#define NET_SKB_PAD 16
#endif
-extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc);
+extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
{
- if (!skb->data_len) {
- skb->len = len;
- skb->tail = skb->data + len;
- } else
- ___pskb_trim(skb, len, 0);
+ if (unlikely(skb->data_len)) {
+ WARN_ON(1);
+ return;
+ }
+ skb->len = len;
+ skb->tail = skb->data + len;
}
/**
*
* 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 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)
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
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
/**
return 0;
}
+static inline int __skb_linearize(struct sk_buff *skb)
+{
+ return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
+}
+
/**
* skb_linearize - convert paged skb to linear one
* @skb: buffer to linarize
- * @gfp: allocation mode
*
* If there is no free memory -ENOMEM is returned, otherwise zero
* is returned and the old skb data released.
*/
-extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
-static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
+static inline int skb_linearize(struct sk_buff *skb)
+{
+ return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;
+}
+
+/**
+ * skb_linearize_cow - make sure skb is linear and writable
+ * @skb: buffer to process
+ *
+ * If there is no free memory -ENOMEM is returned, otherwise zero
+ * is returned and the old skb data released.
+ */
+static inline int skb_linearize_cow(struct sk_buff *skb)
{
- return __skb_linearize(skb, gfp);
+ return skb_is_nonlinear(skb) || skb_cloned(skb) ?
+ __skb_linearize(skb) : 0;
}
/**
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 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 */
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);
struct rtattr *tab);
extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
-extern int qdisc_restart(struct net_device *dev);
+extern void __qdisc_run(struct net_device *dev);
static inline void qdisc_run(struct net_device *dev)
{
- while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0)
- /* NOTHING */;
+ if (!netif_queue_stopped(dev) &&
+ !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
+ __qdisc_run(dev);
}
extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
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;
};
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)
{
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 *,
{
__sk_dst_set(sk, dst);
sk->sk_route_caps = dst->dev->features;
+ if (sk->sk_route_caps & NETIF_F_GSO)
+ sk->sk_route_caps |= NETIF_F_TSO;
if (sk->sk_route_caps & NETIF_F_TSO) {
if (sock_flag(sk, SOCK_NO_LARGESEND) || dst->header_len)
sk->sk_route_caps &= ~NETIF_F_TSO;
+ else
+ sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
}
}
*/
static inline int tcp_skb_pcount(const struct sk_buff *skb)
{
- return skb_shinfo(skb)->tso_segs;
+ return skb_shinfo(skb)->gso_segs;
}
/* This is valid iff tcp_skb_pcount() > 1. */
static inline int tcp_skb_mss(const struct sk_buff *skb)
{
- return skb_shinfo(skb)->tso_size;
+ return skb_shinfo(skb)->gso_size;
}
static inline void tcp_dec_pcount_approx(__u32 *count,
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);
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,
uint32_t initial_cmdsn;
} c_session;
struct msg_destroy_session {
+ uint64_t session_handle;
uint32_t sid;
} d_session;
struct msg_create_conn {
- uint32_t sid;
+ uint64_t session_handle;
uint32_t cid;
+ uint32_t sid;
} c_conn;
struct msg_bind_conn {
- uint32_t sid;
- uint32_t cid;
- uint64_t transport_eph;
+ uint64_t session_handle;
+ uint64_t conn_handle;
+ uint32_t transport_fd;
uint32_t is_leading;
} b_conn;
struct msg_destroy_conn {
- uint32_t sid;
+ uint64_t conn_handle;
uint32_t cid;
} d_conn;
struct msg_send_pdu {
- uint32_t sid;
- uint32_t cid;
uint32_t hdr_size;
uint32_t data_size;
+ uint64_t conn_handle;
} send_pdu;
struct msg_set_param {
- uint32_t sid;
- uint32_t cid;
+ uint64_t conn_handle;
uint32_t param; /* enum iscsi_param */
- uint32_t len;
+ uint32_t value;
} set_param;
struct msg_start_conn {
- uint32_t sid;
- uint32_t cid;
+ uint64_t conn_handle;
} start_conn;
struct msg_stop_conn {
- uint32_t sid;
- uint32_t cid;
uint64_t conn_handle;
uint32_t flag;
} stop_conn;
struct msg_get_stats {
- uint32_t sid;
- uint32_t cid;
+ uint64_t conn_handle;
} get_stats;
- struct msg_transport_connect {
- uint32_t non_blocking;
- } ep_connect;
- struct msg_transport_poll {
- uint64_t ep_handle;
- uint32_t timeout_ms;
- } ep_poll;
- struct msg_transport_disconnect {
- uint64_t ep_handle;
- } ep_disconnect;
} u;
union {
/* messages k -> u */
+ uint64_t handle;
int retcode;
struct msg_create_session_ret {
+ uint64_t session_handle;
uint32_t sid;
- uint32_t host_no;
} c_session_ret;
- struct msg_create_conn_ret {
- uint32_t sid;
- uint32_t cid;
- } c_conn_ret;
struct msg_recv_req {
- uint32_t sid;
- uint32_t cid;
uint64_t recv_handle;
+ uint64_t conn_handle;
} recv_req;
struct msg_conn_error {
- uint32_t sid;
- uint32_t cid;
+ uint64_t conn_handle;
uint32_t error; /* enum iscsi_err */
} connerror;
- struct msg_transport_connect_ret {
- uint64_t handle;
- } ep_connect_ret;
} r;
} __attribute__ ((aligned (sizeof(uint64_t))));
ISCSI_ERR_SESSION_FAILED = ISCSI_ERR_BASE + 13,
ISCSI_ERR_HDR_DGST = ISCSI_ERR_BASE + 14,
ISCSI_ERR_DATA_DGST = ISCSI_ERR_BASE + 15,
- ISCSI_ERR_PARAM_NOT_FOUND = ISCSI_ERR_BASE + 16,
- ISCSI_ERR_NO_SCSI_CMD = ISCSI_ERR_BASE + 17,
+ ISCSI_ERR_PARAM_NOT_FOUND = ISCSI_ERR_BASE + 16
};
/*
* iSCSI Parameters (RFC3720)
*/
enum iscsi_param {
- /* passed in using netlink set param */
- ISCSI_PARAM_MAX_RECV_DLENGTH,
- ISCSI_PARAM_MAX_XMIT_DLENGTH,
- ISCSI_PARAM_HDRDGST_EN,
- ISCSI_PARAM_DATADGST_EN,
- ISCSI_PARAM_INITIAL_R2T_EN,
- ISCSI_PARAM_MAX_R2T,
- ISCSI_PARAM_IMM_DATA_EN,
- ISCSI_PARAM_FIRST_BURST,
- ISCSI_PARAM_MAX_BURST,
- ISCSI_PARAM_PDU_INORDER_EN,
- ISCSI_PARAM_DATASEQ_INORDER_EN,
- ISCSI_PARAM_ERL,
- ISCSI_PARAM_IFMARKER_EN,
- ISCSI_PARAM_OFMARKER_EN,
- ISCSI_PARAM_EXP_STATSN,
- ISCSI_PARAM_TARGET_NAME,
- ISCSI_PARAM_TPGT,
- ISCSI_PARAM_PERSISTENT_ADDRESS,
- ISCSI_PARAM_PERSISTENT_PORT,
- ISCSI_PARAM_SESS_RECOVERY_TMO,
-
- /* pased in through bind conn using transport_fd */
- ISCSI_PARAM_CONN_PORT,
- ISCSI_PARAM_CONN_ADDRESS,
-
- /* must always be last */
- ISCSI_PARAM_MAX,
+ ISCSI_PARAM_MAX_RECV_DLENGTH = 0,
+ ISCSI_PARAM_MAX_XMIT_DLENGTH = 1,
+ ISCSI_PARAM_HDRDGST_EN = 2,
+ ISCSI_PARAM_DATADGST_EN = 3,
+ ISCSI_PARAM_INITIAL_R2T_EN = 4,
+ ISCSI_PARAM_MAX_R2T = 5,
+ ISCSI_PARAM_IMM_DATA_EN = 6,
+ ISCSI_PARAM_FIRST_BURST = 7,
+ ISCSI_PARAM_MAX_BURST = 8,
+ ISCSI_PARAM_PDU_INORDER_EN = 9,
+ ISCSI_PARAM_DATASEQ_INORDER_EN = 10,
+ ISCSI_PARAM_ERL = 11,
+ ISCSI_PARAM_IFMARKER_EN = 12,
+ ISCSI_PARAM_OFMARKER_EN = 13,
};
-
-#define ISCSI_MAX_RECV_DLENGTH (1 << ISCSI_PARAM_MAX_RECV_DLENGTH)
-#define ISCSI_MAX_XMIT_DLENGTH (1 << ISCSI_PARAM_MAX_XMIT_DLENGTH)
-#define ISCSI_HDRDGST_EN (1 << ISCSI_PARAM_HDRDGST_EN)
-#define ISCSI_DATADGST_EN (1 << ISCSI_PARAM_DATADGST_EN)
-#define ISCSI_INITIAL_R2T_EN (1 << ISCSI_PARAM_INITIAL_R2T_EN)
-#define ISCSI_MAX_R2T (1 << ISCSI_PARAM_MAX_R2T)
-#define ISCSI_IMM_DATA_EN (1 << ISCSI_PARAM_IMM_DATA_EN)
-#define ISCSI_FIRST_BURST (1 << ISCSI_PARAM_FIRST_BURST)
-#define ISCSI_MAX_BURST (1 << ISCSI_PARAM_MAX_BURST)
-#define ISCSI_PDU_INORDER_EN (1 << ISCSI_PARAM_PDU_INORDER_EN)
-#define ISCSI_DATASEQ_INORDER_EN (1 << ISCSI_PARAM_DATASEQ_INORDER_EN)
-#define ISCSI_ERL (1 << ISCSI_PARAM_ERL)
-#define ISCSI_IFMARKER_EN (1 << ISCSI_PARAM_IFMARKER_EN)
-#define ISCSI_OFMARKER_EN (1 << ISCSI_PARAM_OFMARKER_EN)
-#define ISCSI_EXP_STATSN (1 << ISCSI_PARAM_EXP_STATSN)
-#define ISCSI_TARGET_NAME (1 << ISCSI_PARAM_TARGET_NAME)
-#define ISCSI_TPGT (1 << ISCSI_PARAM_TPGT)
-#define ISCSI_PERSISTENT_ADDRESS (1 << ISCSI_PARAM_PERSISTENT_ADDRESS)
-#define ISCSI_PERSISTENT_PORT (1 << ISCSI_PARAM_PERSISTENT_PORT)
-#define ISCSI_SESS_RECOVERY_TMO (1 << ISCSI_PARAM_SESS_RECOVERY_TMO)
-#define ISCSI_CONN_PORT (1 << ISCSI_PARAM_CONN_PORT)
-#define ISCSI_CONN_ADDRESS (1 << ISCSI_PARAM_CONN_ADDRESS)
+#define ISCSI_PARAM_MAX 14
#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
* 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
#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 */
* 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
*
#include <scsi/iscsi_if.h>
struct scsi_transport_template;
-struct iscsi_transport;
struct Scsi_Host;
struct mempool_zone;
struct iscsi_cls_conn;
-struct iscsi_conn;
-struct iscsi_cmd_task;
-struct iscsi_mgmt_task;
/**
* struct iscsi_transport - iSCSI Transport template
* @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
*/
struct module *owner;
char *name;
unsigned int caps;
- /* LLD sets this to indicate what values it can export to sysfs */
- unsigned int param_mask;
struct scsi_host_template *host_template;
+ /* LLD session/scsi_host data size */
+ int hostdata_size;
+ /* LLD iscsi_host data size */
+ int ihostdata_size;
/* LLD connection data size */
int conndata_size;
- /* LLD session data size */
- int sessiondata_size;
int max_lun;
unsigned int max_conn;
unsigned int max_cmd_len;
- struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it,
- struct scsi_transport_template *t, uint32_t sn, uint32_t *hn);
+ struct iscsi_cls_session *(*create_session)
+ (struct scsi_transport_template *t, uint32_t sn, uint32_t *sid);
void (*destroy_session) (struct iscsi_cls_session *session);
struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,
uint32_t cid);
int (*bind_conn) (struct iscsi_cls_session *session,
struct iscsi_cls_conn *cls_conn,
- uint64_t transport_eph, int is_leading);
+ uint32_t transport_fd, int is_leading);
int (*start_conn) (struct iscsi_cls_conn *conn);
void (*stop_conn) (struct iscsi_cls_conn *conn, int flag);
void (*destroy_conn) (struct iscsi_cls_conn *conn);
int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param,
uint32_t value);
int (*get_conn_param) (struct iscsi_cls_conn *conn,
- enum iscsi_param param, uint32_t *value);
+ enum iscsi_param param,
+ uint32_t *value);
int (*get_session_param) (struct iscsi_cls_session *session,
enum iscsi_param param, uint32_t *value);
- int (*get_conn_str_param) (struct iscsi_cls_conn *conn,
- enum iscsi_param param, char *buf);
- int (*get_session_str_param) (struct iscsi_cls_session *session,
- enum iscsi_param param, char *buf);
int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
char *data, uint32_t data_size);
void (*get_stats) (struct iscsi_cls_conn *conn,
struct iscsi_stats *stats);
- void (*suspend_conn_recv) (struct iscsi_conn *conn);
- void (*terminate_conn) (struct iscsi_conn *conn);
- void (*init_cmd_task) (struct iscsi_cmd_task *ctask);
- void (*init_mgmt_task) (struct iscsi_conn *conn,
- struct iscsi_mgmt_task *mtask,
- char *data, uint32_t data_size);
- int (*xmit_cmd_task) (struct iscsi_conn *conn,
- struct iscsi_cmd_task *ctask);
- void (*cleanup_cmd_task) (struct iscsi_conn *conn,
- struct iscsi_cmd_task *ctask);
- int (*xmit_mgmt_task) (struct iscsi_conn *conn,
- struct iscsi_mgmt_task *mtask);
- void (*session_recovery_timedout) (struct iscsi_cls_session *session);
- int (*ep_connect) (struct sockaddr *dst_addr, int non_blocking,
- uint64_t *ep_handle);
- int (*ep_poll) (uint64_t ep_handle, int timeout_ms);
- void (*ep_disconnect) (uint64_t ep_handle);
};
/*
extern int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
char *data, uint32_t data_size);
-
-/* Connection's states */
-#define ISCSI_CONN_INITIAL_STAGE 0
-#define ISCSI_CONN_STARTED 1
-#define ISCSI_CONN_STOPPED 2
-#define ISCSI_CONN_CLEANUP_WAIT 3
-
struct iscsi_cls_conn {
struct list_head conn_list; /* item in connlist */
void *dd_data; /* LLD private data */
struct iscsi_transport *transport;
- uint32_t cid; /* connection id */
-
- /* portal/group values we got during discovery */
- char *persistent_address;
- int persistent_port;
- /* portal/group values we are currently using */
- char *address;
- int port;
-
int active; /* must be accessed with the connlock */
struct device dev; /* sysfs transport/container device */
struct mempool_zone *z_error;
#define iscsi_dev_to_conn(_dev) \
container_of(_dev, struct iscsi_cls_conn, dev)
-/* Session's states */
-#define ISCSI_STATE_FREE 1
-#define ISCSI_STATE_LOGGED_IN 2
-#define ISCSI_STATE_FAILED 3
-#define ISCSI_STATE_TERMINATE 4
-#define ISCSI_STATE_IN_RECOVERY 5
-#define ISCSI_STATE_RECOVERY_FAILED 6
-
struct iscsi_cls_session {
struct list_head sess_list; /* item in session_list */
- struct list_head host_list;
struct iscsi_transport *transport;
-
- /* iSCSI values used as unique id by userspace. */
- char *targetname;
- int tpgt;
-
- /* recovery fields */
- int recovery_tmo;
- struct work_struct recovery_work;
-
- int target_id;
- int channel;
-
- int sid; /* session id */
- void *dd_data; /* LLD private data */
struct device dev; /* sysfs transport/container device */
};
#define iscsi_session_to_shost(_session) \
dev_to_shost(_session->dev.parent)
-struct iscsi_host {
- int next_target_id;
- struct list_head sessions;
- struct mutex mutex;
-};
-
/*
* session and connection functions that can be used by HW iSCSI LLDs
*/
extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
- struct iscsi_transport *t, int channel);
+ struct iscsi_transport *t);
extern int iscsi_destroy_session(struct iscsi_cls_session *session);
extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
uint32_t cid);
extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
-extern void iscsi_unblock_session(struct iscsi_cls_session *session);
-extern void iscsi_block_session(struct iscsi_cls_session *session);
+
+/*
+ * session functions used by software iscsi
+ */
+extern struct Scsi_Host *
+iscsi_transport_create_session(struct scsi_transport_template *scsit,
+ struct iscsi_transport *transport);
+extern int iscsi_transport_destroy_session(struct Scsi_Host *shost);
#endif
{
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;
}
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)
if (retval)
goto out;
}
+#ifdef arch_dup_mmap
+ arch_dup_mmap(mm, oldmm);
+#endif
retval = 0;
out:
up_write(&mm->mmap_sem);
/* 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);
/*
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 {
}
*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 |
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;
}
/**
struct irqaction **p;
unsigned long flags;
- WARN_ON(in_interrupt());
if (irq >= NR_IRQS)
return;
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);
}
return 0;
}
-static inline void __cond_resched(void)
+static inline int __resched_legal(int expected_preempt_count)
+{
+ if (unlikely(preempt_count() != expected_preempt_count))
+ return 0;
+ if (unlikely(system_state != SYSTEM_RUNNING))
+ return 0;
+ return 1;
+}
+
+static void __cond_resched(void)
{
/*
* The BKS might be reacquired before we have dropped
* PREEMPT_ACTIVE, which could trigger a second
* cond_resched() call.
*/
- if (unlikely(preempt_count()))
- return;
- if (unlikely(system_state != SYSTEM_RUNNING))
- return;
do {
add_preempt_count(PREEMPT_ACTIVE);
schedule();
int __sched cond_resched(void)
{
- if (need_resched()) {
+ if (need_resched() && __resched_legal(0)) {
__cond_resched();
return 1;
}
return 0;
}
-
EXPORT_SYMBOL(cond_resched);
/*
ret = 1;
spin_lock(lock);
}
- if (need_resched()) {
+ if (need_resched() && __resched_legal(1)) {
_raw_spin_unlock(lock);
preempt_enable_no_resched();
__cond_resched();
}
return ret;
}
-
EXPORT_SYMBOL(cond_resched_lock);
int __sched cond_resched_softirq(void)
{
BUG_ON(!in_softirq());
- if (need_resched()) {
+ if (need_resched() && __resched_legal(0)) {
__local_bh_enable();
__cond_resched();
local_bh_disable();
}
return 0;
}
-
EXPORT_SYMBOL(cond_resched_softirq);
-
/**
* yield - yield the current processor to other threads.
*
/* If some failed, kill them all. */
if (ret < 0) {
stopmachine_set_state(STOPMACHINE_EXIT);
- up(&stopmachine_mutex);
return ret;
}
}
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
}
/*
- * Accessing ->group_leader->real_parent is not SMP-safe, it could
- * change from under us. However, rather than getting any lock
- * we can use an optimistic algorithm: get the parent
- * pid, and go back and check that the parent is still
- * the same. If it has changed (which is extremely unlikely
- * indeed), we just try again..
- *
- * NOTE! This depends on the fact that even if we _do_
- * get an old value of "parent", we can happily dereference
- * the pointer (it was and remains a dereferencable kernel pointer
- * no matter what): we just can't necessarily trust the result
- * until we know that the parent pointer is valid.
- *
- * NOTE2: ->group_leader never changes from under us.
+ * Accessing ->real_parent is not SMP-safe, it could
+ * change from under us. However, we can use a stale
+ * value of ->real_parent under rcu_read_lock(), see
+ * release_task()->call_rcu(delayed_put_task_struct).
*/
asmlinkage long sys_getppid(void)
{
int pid;
- struct task_struct *me = current;
- struct task_struct *parent;
- parent = me->group_leader->real_parent;
- for (;;) {
- pid = parent->tgid;
-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
-{
- struct task_struct *old = parent;
-
- /*
- * Make sure we read the pid before re-reading the
- * parent pointer:
- */
- smp_rmb();
- parent = me->group_leader->real_parent;
- if (old != parent)
- continue;
-}
-#endif
- break;
- }
+ rcu_read_lock();
+ pid = rcu_dereference(current->real_parent)->tgid;
+ rcu_read_unlock();
return vx_map_pid(pid);
}
*ppid = sys_getppid();
return sys_getpid();
}
-
+
#else /* _alpha_ */
asmlinkage long sys_getuid(void)
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
#include <linux/init.h>
#include <linux/module.h>
#endif
+#include <linux/err.h>
#include <linux/string.h>
#include <linux/idr.h>
}
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)
{
#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;
}
}
}
+#endif
void _raw_read_lock(rwlock_t *lock)
{
RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
- if (unlikely(!__raw_read_trylock(&lock->raw_lock)))
- __read_lock_debug(lock);
+ __raw_read_lock(&lock->raw_lock);
}
int _raw_read_trylock(rwlock_t *lock)
lock->owner_cpu = -1;
}
+#if 0 /* This can cause lockups */
static void __write_lock_debug(rwlock_t *lock)
{
int print_once = 1;
}
}
}
+#endif
void _raw_write_lock(rwlock_t *lock)
{
debug_write_lock_before(lock);
- if (unlikely(!__raw_write_trylock(&lock->raw_lock)))
- __write_lock_debug(lock);
+ __raw_write_lock(&lock->raw_lock);
debug_write_lock_after(lock);
}
return ret;
}
-static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern,
- unsigned int len)
+static void compute_prefix_tbl(struct ts_bm *bm)
{
int i, j, g;
for (i = 0; i < ASIZE; i++)
- bm->bad_shift[i] = len;
- for (i = 0; i < len - 1; i++)
- bm->bad_shift[pattern[i]] = len - 1 - i;
+ bm->bad_shift[i] = bm->patlen;
+ for (i = 0; i < bm->patlen - 1; i++)
+ bm->bad_shift[bm->pattern[i]] = bm->patlen - 1 - i;
/* Compute the good shift array, used to match reocurrences
* of a subpattern */
bm = ts_config_priv(conf);
bm->patlen = len;
bm->pattern = (u8 *) bm->good_shift + prefix_tbl_len;
- compute_prefix_tbl(bm, pattern, len);
memcpy(bm->pattern, pattern, len);
+ compute_prefix_tbl(bm);
return conf;
}
# 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
# Default to 4 for wider testing, though 8 might be more appropriate.
# ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock.
# PA-RISC 7xxx's spinlock_t would enlarge struct page from 32 to 44 bytes.
+# XEN on x86 architecture uses the mapping field on pagetable pages to store a
+# pointer to the destructor. This conflicts with pte_lock_deinit().
#
config SPLIT_PTLOCK_CPUS
int
default "4096" if ARM && !CPU_CACHE_VIPT
default "4096" if PARISC && !PA20
- default "4096"
+ default "4096" if X86_XEN || X86_64_XEN
+ default "4096" if !64BIT
+ default "4"
#
# support for page migration
*/
void end_page_writeback(struct page *page)
{
- struct zone *zone = page_zone(page);
if (!TestClearPageReclaim(page) || rotate_reclaimable_page(page)) {
if (!test_clear_page_writeback(page))
BUG();
}
smp_mb__after_clear_bit();
- if (zone->all_unreclaimable) {
- spin_lock(&zone->lock);
- zone->all_unreclaimable = 0;
- zone->pages_scanned = 0;
- spin_unlock(&zone->lock);
- }
wake_up_page(page, PG_writeback);
}
EXPORT_SYMBOL(end_page_writeback);
do {
unsigned long index;
unsigned long offset;
- unsigned long maxlen;
size_t copied;
offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
index = pos >> PAGE_CACHE_SHIFT;
bytes = PAGE_CACHE_SIZE - offset;
- if (bytes > count)
- bytes = count;
+
+ /* Limit the size of the copy to the caller's write size */
+ bytes = min(bytes, count);
+
+ /*
+ * Limit the size of the copy to that of the current segment,
+ * because fault_in_pages_readable() doesn't know how to walk
+ * segments.
+ */
+ bytes = min(bytes, cur_iov->iov_len - iov_base);
/*
* Bring in the user page that we will copy from _first_.
* 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) {
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);
page_cache_release(page);
continue;
}
- if (likely(copied > 0)) {
+zero_length_segment:
+ if (likely(copied >= 0)) {
if (!status)
status = copied;
const struct iovec *iov = *iovp;
size_t base = *basep;
- while (bytes) {
+ do {
int copy = min(bytes, iov->iov_len - base);
bytes -= copy;
iov++;
base = 0;
}
- }
+ } while (bytes);
*iovp = iov;
*basep = base;
}
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;
* 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;
}
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;
}
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
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)
unsigned long flags;
struct rb_node ** rb_link, * rb_parent;
pgoff_t pgoff = addr >> PAGE_SHIFT;
+ int error;
len = PAGE_ALIGN(len);
if (!len)
if ((addr + len) > TASK_SIZE || (addr + len) < addr)
return -EINVAL;
+ flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
+
+ error = arch_mmap_check(addr, len, flags);
+ if (error)
+ return error;
+
/*
* mlock MCL_FUTURE?
*/
!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))
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);
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);
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 (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();
list_move(&my_work->list, &pdflush_list);
my_work->when_i_went_to_sleep = jiffies;
spin_unlock_irq(&pdflush_lock);
-
schedule();
- if (try_to_freeze()) {
- spin_lock_irq(&pdflush_lock);
- continue;
- }
-
+ try_to_freeze();
spin_lock_irq(&pdflush_lock);
if (!list_empty(&my_work->list)) {
- printk("pdflush: bogus wakeup!\n");
+ /*
+ * Someone woke us up, but without removing our control
+ * structure from the global list. swsusp will do this
+ * in try_to_freeze()->refrigerator(). Handle it.
+ */
my_work->fn = NULL;
continue;
}
if (my_work->fn == NULL) {
- printk("pdflush: NULL work function\n");
+ printk("pdflush: bogus wakeup\n");
continue;
}
spin_unlock_irq(&pdflush_lock);
if (!(swap_info[i].flags & SWP_WRITEOK))
continue;
+
if (!device) {
spin_unlock(&swap_lock);
return i;
}
- inode = swap_info->swap_file->f_dentry->d_inode;
+ inode = swap_info[i].swap_file->f_dentry->d_inode;
if (S_ISBLK(inode->i_mode) &&
device == MKDEV(imajor(inode), iminor(inode))) {
spin_unlock(&swap_lock);
.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. */
/*
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.
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) {
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. */
struct net_bridge *br = netdev_priv(dev);
if (data)
- br->feature_mask |= NETIF_F_IP_CSUM;
+ br->feature_mask |= NETIF_F_NO_CSUM;
else
- br->feature_mask &= ~NETIF_F_IP_CSUM;
+ br->feature_mask &= ~NETIF_F_ALL_CSUM;
br_features_recompute(br);
return 0;
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;
}
int br_dev_queue_push_xmit(struct sk_buff *skb)
{
/* drop mtu oversized packets except tso */
- if (packet_length(skb) > skb->dev->mtu && !skb_shinfo(skb)->tso_size)
+ if (skb->len > skb->dev->mtu && !skb_is_gso(skb))
kfree_skb(skb);
else {
#ifdef CONFIG_BRIDGE_NETFILTER
/* ip_refrag calls ip_fragment, doesn't copy the MAC header. */
- nf_bridge_maybe_copy_header(skb);
+ if (nf_bridge_maybe_copy_header(skb))
+ kfree_skb(skb);
+ else
#endif
- skb_push(skb, ETH_HLEN);
+ {
+ skb_push(skb, ETH_HLEN);
- dev_queue_xmit(skb);
+ dev_queue_xmit(skb);
+ }
}
return 0;
struct net_bridge_port *p;
unsigned long features, checksum;
- features = br->feature_mask &~ NETIF_F_IP_CSUM;
- checksum = br->feature_mask & NETIF_F_IP_CSUM;
+ checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0;
+ features = br->feature_mask & ~NETIF_F_ALL_CSUM;
list_for_each_entry(p, &br->port_list, list) {
- if (!(p->dev->features
- & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
+ unsigned long feature = p->dev->features;
+
+ if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
+ checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
+ if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
+ checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM;
+ if (!(feature & NETIF_F_IP_CSUM))
checksum = 0;
- features &= p->dev->features;
+
+ if (feature & NETIF_F_GSO)
+ feature |= NETIF_F_TSO;
+ feature |= NETIF_F_GSO;
+
+ features &= feature;
}
- br->dev->features = features | checksum | NETIF_F_LLTX;
+ br->dev->features = features | checksum | NETIF_F_LLTX |
+ NETIF_F_GSO_ROBUST;
}
/* called with RTNL */
{
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);
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 (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;
#include <net/iw_handler.h>
#include <asm/current.h>
#include <linux/audit.h>
+#include <linux/err.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.
* 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;
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)
#define illegal_highdma(dev, skb) (0)
#endif
-/* Keep head the same: replace data */
-int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
-{
- unsigned int size;
- u8 *data;
- long offset;
- struct skb_shared_info *ninfo;
- int headerlen = skb->data - skb->head;
- int expand = (skb->tail + skb->data_len) - skb->end;
-
- if (skb_shared(skb))
- BUG();
-
- if (expand <= 0)
- expand = 0;
-
- size = skb->end - skb->head + expand;
- size = SKB_DATA_ALIGN(size);
- data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
- if (!data)
- return -ENOMEM;
-
- /* Copy entire thing */
- if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
- BUG();
-
- /* Set up shinfo */
- ninfo = (struct skb_shared_info*)(data + size);
- atomic_set(&ninfo->dataref, 1);
- ninfo->tso_size = skb_shinfo(skb)->tso_size;
- ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
- ninfo->nr_frags = 0;
- ninfo->frag_list = NULL;
-
- /* Offset between the two in bytes */
- offset = data - skb->head;
-
- /* Free old data. */
- skb_release_data(skb);
-
- skb->head = data;
- skb->end = data + size;
-
- /* Set up new pointers */
- skb->h.raw += offset;
- skb->nh.raw += offset;
- skb->mac.raw += offset;
- skb->tail += offset;
- skb->data += offset;
-
- /* We are no longer a clone, even if we were. */
- skb->cloned = 0;
-
- skb->tail += skb->data_len;
- skb->data_len = 0;
+struct dev_gso_cb {
+ void (*destructor)(struct sk_buff *skb);
+};
+
+#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
+
+static void dev_gso_skb_destructor(struct sk_buff *skb)
+{
+ struct dev_gso_cb *cb;
+
+ do {
+ struct sk_buff *nskb = skb->next;
+
+ skb->next = nskb->next;
+ nskb->next = NULL;
+ kfree_skb(nskb);
+ } while (skb->next);
+
+ cb = DEV_GSO_CB(skb);
+ if (cb->destructor)
+ cb->destructor(skb);
+}
+
+/**
+ * dev_gso_segment - Perform emulated hardware segmentation on skb.
+ * @skb: buffer to segment
+ *
+ * This function segments the given skb and stores the list of segments
+ * in skb->next.
+ */
+static int dev_gso_segment(struct sk_buff *skb)
+{
+ struct net_device *dev = skb->dev;
+ struct sk_buff *segs;
+ int features = dev->features & ~(illegal_highdma(dev, skb) ?
+ NETIF_F_SG : 0);
+
+ segs = skb_gso_segment(skb, features);
+
+ /* Verifying header integrity only. */
+ if (!segs)
+ return 0;
+
+ if (unlikely(IS_ERR(segs)))
+ return PTR_ERR(segs);
+
+ skb->next = segs;
+ DEV_GSO_CB(skb)->destructor = skb->destructor;
+ skb->destructor = dev_gso_skb_destructor;
+
+ return 0;
+}
+
+int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ if (likely(!skb->next)) {
+ if (netdev_nit)
+ dev_queue_xmit_nit(skb, dev);
+
+ if (netif_needs_gso(dev, skb)) {
+ if (unlikely(dev_gso_segment(skb)))
+ goto out_kfree_skb;
+ if (skb->next)
+ goto gso;
+ }
+
+ return dev->hard_start_xmit(skb, dev);
+ }
+
+gso:
+ do {
+ struct sk_buff *nskb = skb->next;
+ int rc;
+
+ skb->next = nskb->next;
+ nskb->next = NULL;
+ rc = dev->hard_start_xmit(nskb, dev);
+ if (unlikely(rc)) {
+ nskb->next = skb->next;
+ skb->next = nskb;
+ return rc;
+ }
+ if (unlikely(netif_queue_stopped(dev) && skb->next))
+ return NETDEV_TX_BUSY;
+ } while (skb->next);
+
+ skb->destructor = DEV_GSO_CB(skb)->destructor;
+
+out_kfree_skb:
+ kfree_skb(skb);
return 0;
}
#define HARD_TX_LOCK(dev, cpu) { \
if ((dev->features & NETIF_F_LLTX) == 0) { \
- spin_lock(&dev->xmit_lock); \
- dev->xmit_lock_owner = cpu; \
+ netif_tx_lock(dev); \
} \
}
#define HARD_TX_UNLOCK(dev) { \
if ((dev->features & NETIF_F_LLTX) == 0) { \
- dev->xmit_lock_owner = -1; \
- spin_unlock(&dev->xmit_lock); \
+ netif_tx_unlock(dev); \
} \
}
+#ifdef CONFIG_XEN
+inline int skb_checksum_setup(struct sk_buff *skb)
+{
+ if (skb->proto_csum_blank) {
+ if (skb->protocol != htons(ETH_P_IP))
+ goto out;
+ skb->h.raw = (unsigned char *)skb->nh.iph + 4*skb->nh.iph->ihl;
+ if (skb->h.raw >= skb->tail)
+ goto out;
+ switch (skb->nh.iph->protocol) {
+ case IPPROTO_TCP:
+ skb->csum = offsetof(struct tcphdr, check);
+ break;
+ case IPPROTO_UDP:
+ skb->csum = offsetof(struct udphdr, check);
+ break;
+ default:
+ if (net_ratelimit())
+ printk(KERN_ERR "Attempting to checksum a non-"
+ "TCP/UDP packet, dropping a protocol"
+ " %d packet", skb->nh.iph->protocol);
+ goto out;
+ }
+ if ((skb->h.raw + skb->csum + 2) > skb->tail)
+ goto out;
+ skb->ip_summed = CHECKSUM_HW;
+ skb->proto_csum_blank = 0;
+ }
+ return 0;
+out:
+ return -EPROTO;
+}
+#else
+inline int skb_checksum_setup(struct sk_buff *skb) { return 0; }
+#endif
+
+
/**
* dev_queue_xmit - transmit a buffer
* @skb: buffer to transmit
struct Qdisc *q;
int rc = -ENOMEM;
+ /* If a checksum-deferred packet is forwarded to a device that needs a
+ * checksum, correct the pointers and force checksumming.
+ */
+ if (skb_checksum_setup(skb))
+ goto out_kfree_skb;
+
+ /* GSO will handle the following emulations directly. */
+ if (netif_needs_gso(dev, skb))
+ goto gso;
+
if (skb_shinfo(skb)->frag_list &&
!(dev->features & NETIF_F_FRAGLIST) &&
- __skb_linearize(skb, GFP_ATOMIC))
+ __skb_linearize(skb))
goto out_kfree_skb;
/* Fragmented skb is linearized if device does not support SG,
*/
if (skb_shinfo(skb)->nr_frags &&
(!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
- __skb_linearize(skb, GFP_ATOMIC))
+ __skb_linearize(skb))
goto out_kfree_skb;
/* If packet is not checksummed and device does not support
* checksumming for this protocol, complete checksumming here.
*/
if (skb->ip_summed == CHECKSUM_HW &&
- (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
+ (!(dev->features & NETIF_F_GEN_CSUM) &&
(!(dev->features & NETIF_F_IP_CSUM) ||
skb->protocol != htons(ETH_P_IP))))
if (skb_checksum_help(skb, 0))
goto out_kfree_skb;
+gso:
spin_lock_prefetch(&dev->queue_lock);
/* Disable soft irqs for various locks below. Also
* stops preemption for RCU.
*/
- local_bh_disable();
+ rcu_read_lock_bh();
/* Updates of qdisc are serialized by queue_lock.
* The struct Qdisc which is pointed to by qdisc is now a
/* 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.
HARD_TX_LOCK(dev, cpu);
if (!netif_queue_stopped(dev)) {
- if (netdev_nit)
- dev_queue_xmit_nit(skb, dev);
-
rc = 0;
- if (!dev->hard_start_xmit(skb, dev)) {
+ if (!dev_hard_start_xmit(skb, dev)) {
HARD_TX_UNLOCK(dev);
goto out;
}
}
rc = -ENETDOWN;
- local_bh_enable();
+ rcu_read_unlock_bh();
out_kfree_skb:
kfree_skb(skb);
return rc;
out:
- local_bh_enable();
+ rcu_read_unlock_bh();
return rc;
}
}
#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)
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);
/* 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;
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(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);
* 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.
*/
/*
void dev_mc_upload(struct net_device *dev)
{
- spin_lock_bh(&dev->xmit_lock);
+ netif_tx_lock_bh(dev);
__dev_mc_upload(dev);
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
}
/*
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) {
/*
*/
__dev_mc_upload(dev);
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
return 0;
}
}
err = -ENOENT;
done:
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
return err;
}
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) {
}
if ((dmi = dmi1) == NULL) {
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
return -ENOMEM;
}
memcpy(dmi->dmi_addr, addr, alen);
__dev_mc_upload(dev);
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
return 0;
done:
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
kfree(dmi1);
return err;
}
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;
}
dev->mc_count = 0;
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
}
#ifdef CONFIG_PROC_FS
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;
seq_putc(seq, '\n');
}
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
return 0;
}
dst_gc_timer_inc = DST_GC_INC;
dst_gc_timer_expires = DST_GC_MIN;
}
- dst_gc_timer.expires = jiffies + dst_gc_timer_expires;
#if RT_CACHE_DEBUG >= 2
printk("dst_total: %d/%d %ld\n",
atomic_read(&dst_total), delayed, dst_gc_timer_expires);
#endif
- add_timer(&dst_gc_timer);
+ mod_timer(&dst_gc_timer, jiffies + dst_gc_timer_expires);
out:
spin_unlock(&dst_lock);
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)
{
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 -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);
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;
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;
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;
}
do {
npinfo->tries--;
- spin_lock(&np->dev->xmit_lock);
- np->dev->xmit_lock_owner = smp_processor_id();
+ netif_tx_lock(np->dev);
/*
* network drivers do not expect to be called if the queue is
* stopped.
*/
if (netif_queue_stopped(np->dev)) {
- np->dev->xmit_lock_owner = -1;
- spin_unlock(&np->dev->xmit_lock);
+ netif_tx_unlock(np->dev);
netpoll_poll(np);
udelay(50);
continue;
}
status = np->dev->hard_start_xmit(skb, np->dev);
- np->dev->xmit_lock_owner = -1;
- spin_unlock(&np->dev->xmit_lock);
+ netif_tx_unlock(np->dev);
/* success */
if(!status) {
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);
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);
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));
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 (ida[IFLA_ADDRESS - 1]) {
+ struct sockaddr *sa;
+ int len;
+
if (!dev->set_mac_address) {
err = -EOPNOTSUPP;
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;
* 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)
{
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;
skb = NULL;
goto out;
}
+#endif /* !CONFIG_HAVE_ARCH_ALLOC_SKB */
/**
* alloc_skb_from_cache - allocate a network buffer
*/
struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
unsigned int size,
- gfp_t gfp_mask)
+ gfp_t gfp_mask,
+ int fclone)
{
+ kmem_cache_t *cache;
+ struct skb_shared_info *shinfo;
struct sk_buff *skb;
u8 *data;
+ cache = fclone ? skbuff_fclone_cache : skbuff_head_cache;
+
/* Get the HEAD */
- skb = kmem_cache_alloc(skbuff_head_cache,
- gfp_mask & ~__GFP_DMA);
+ skb = kmem_cache_alloc(cache, gfp_mask & ~__GFP_DMA);
if (!skb)
goto out;
skb->data = data;
skb->tail = data;
skb->end = data + size;
+ /* make sure we initialize shinfo sequentially */
+ shinfo = skb_shinfo(skb);
+ atomic_set(&shinfo->dataref, 1);
+ shinfo->nr_frags = 0;
+ shinfo->gso_size = 0;
+ shinfo->gso_segs = 0;
+ shinfo->gso_type = 0;
+ shinfo->ip6_frag_id = 0;
+ shinfo->frag_list = NULL;
- atomic_set(&(skb_shinfo(skb)->dataref), 1);
- skb_shinfo(skb)->nr_frags = 0;
- skb_shinfo(skb)->tso_size = 0;
- skb_shinfo(skb)->tso_segs = 0;
- skb_shinfo(skb)->frag_list = NULL;
+ if (fclone) {
+ struct sk_buff *child = skb + 1;
+ atomic_t *fclone_ref = (atomic_t *) (child + 1);
+
+ skb->fclone = SKB_FCLONE_ORIG;
+ atomic_set(fclone_ref, 1);
+
+ child->fclone = SKB_FCLONE_UNAVAILABLE;
+ }
out:
return skb;
nodata:
- kmem_cache_free(skbuff_head_cache, skb);
+ kmem_cache_free(cache, skb);
skb = NULL;
goto out;
}
-static void skb_drop_fraglist(struct sk_buff *skb)
+static void skb_drop_list(struct sk_buff **listp)
{
- struct sk_buff *list = skb_shinfo(skb)->frag_list;
+ struct sk_buff *list = *listp;
- skb_shinfo(skb)->frag_list = NULL;
+ *listp = NULL;
do {
struct sk_buff *this = list;
} 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;
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);
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;
}
/**
return nskb;
}
-/* Trims skb to length len. It can change skb pointers, if "realloc" is 1.
- * If realloc==0 and trimming is impossible without change of data,
- * it is BUG().
+/* Trims skb to length len. It can change skb pointers.
*/
-int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc)
+int ___pskb_trim(struct sk_buff *skb, unsigned int len)
{
+ struct sk_buff **fragp;
+ struct sk_buff *frag;
int offset = skb_headlen(skb);
int nfrags = skb_shinfo(skb)->nr_frags;
int i;
+ int err;
- for (i = 0; i < nfrags; i++) {
+ if (skb_cloned(skb) &&
+ unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))))
+ return err;
+
+ i = 0;
+ if (offset >= len)
+ goto drop_pages;
+
+ for (; i < nfrags; i++) {
int end = offset + skb_shinfo(skb)->frags[i].size;
- if (end > len) {
- if (skb_cloned(skb)) {
- BUG_ON(!realloc);
- if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
- return -ENOMEM;
- }
- if (len <= offset) {
- put_page(skb_shinfo(skb)->frags[i].page);
- skb_shinfo(skb)->nr_frags--;
- } else {
- skb_shinfo(skb)->frags[i].size = len - offset;
- }
+
+ if (end < len) {
+ offset = end;
+ continue;
}
- offset = end;
+
+ skb_shinfo(skb)->frags[i++].size = len - offset;
+
+drop_pages:
+ skb_shinfo(skb)->nr_frags = i;
+
+ for (; i < nfrags; i++)
+ put_page(skb_shinfo(skb)->frags[i].page);
+
+ if (skb_shinfo(skb)->frag_list)
+ skb_drop_fraglist(skb);
+ goto done;
}
- if (offset < len) {
+ for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp);
+ fragp = &frag->next) {
+ int end = offset + frag->len;
+
+ if (skb_shared(frag)) {
+ struct sk_buff *nfrag;
+
+ nfrag = skb_clone(frag, GFP_ATOMIC);
+ if (unlikely(!nfrag))
+ return -ENOMEM;
+
+ nfrag->next = frag->next;
+ kfree_skb(frag);
+ frag = nfrag;
+ *fragp = frag;
+ }
+
+ if (end < len) {
+ offset = end;
+ continue;
+ }
+
+ if (end > len &&
+ unlikely((err = pskb_trim(frag, len - offset))))
+ return err;
+
+ if (frag->next)
+ skb_drop_list(&frag->next);
+ break;
+ }
+
+done:
+ if (len > skb_headlen(skb)) {
skb->data_len -= skb->len - len;
skb->len = len;
} else {
- if (len <= skb_headlen(skb)) {
- skb->len = len;
- skb->data_len = 0;
- skb->tail = skb->data + len;
- if (skb_shinfo(skb)->frag_list && !skb_cloned(skb))
- skb_drop_fraglist(skb);
- } else {
- skb->data_len -= skb->len - len;
- skb->len = len;
- }
+ skb->len = len;
+ skb->data_len = 0;
+ skb->tail = skb->data + len;
}
return 0;
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",
* 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;
}
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) {
rcu_read_lock();
hlist_for_each_entry(r, node, &dn_fib_rules, r_hlist) {
if (idx < s_idx)
- continue;
+ goto next;
if (dn_fib_fill_rule(skb, r, cb, NLM_F_MULTI) < 0)
break;
+next:
idx++;
}
rcu_read_unlock();
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
*/
#include <linux/config.h>
+#include <linux/err.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
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,
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,
};
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)
rcu_read_lock();
hlist_for_each_entry(r, node, &fib_rules, hlist) {
-
if (idx < s_idx)
- continue;
+ goto next;
if (inet_fill_rule(skb, r, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq,
RTM_NEWRULE, NLM_F_MULTI) < 0)
break;
+next:
idx++;
}
rcu_read_unlock();
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)
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)
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;
}
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);
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) {
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 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);
}
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);
(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;
*/
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;
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;
inet->cork.length += size;
if ((sk->sk_protocol == IPPROTO_UDP) &&
- (rt->u.dst.dev->features & NETIF_F_UFO))
- skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
+ (rt->u.dst.dev->features & NETIF_F_UFO)) {
+ skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
+ skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
+ }
while (size > 0) {
int i;
- if (skb_shinfo(skb)->ufo_size)
+ if (skb_is_gso(skb))
len = size;
else {
data, fraggap, 0);
skb_prev->csum = csum_sub(skb_prev->csum,
skb->csum);
- skb_trim(skb_prev, maxfraglen);
+ pskb_trim_unique(skb_prev, maxfraglen);
}
/*
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;
} tmp_iph;
- if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
- skb_linearize(skb, GFP_ATOMIC) != 0) {
- err = -ENOMEM;
+ if (skb_linearize_cow(skb))
goto out;
- }
skb->ip_summed = CHECKSUM_NONE;
goto out_ok;
}
- if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
- skb_linearize(skb, GFP_ATOMIC) != 0) {
+ if (skb_linearize_cow(skb))
goto out_ok;
- }
err = ipcomp_compress(x, skb);
iph = skb->nh.iph;
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) +
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]);
tuple.dst.protonum = IPPROTO_TCP;
exp = __ip_conntrack_expect_find(&tuple);
- if (exp->master == ct)
+ if (exp && exp->master == ct)
return exp;
return NULL;
}
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));
newport = tuple->dst.u.udp.port;
portptr = &hdr->dest;
}
- if (hdr->check) /* 0 is a special case meaning no checksum */
- hdr->check = ip_nat_cheat_check(~oldip, newip,
+ if (hdr->check) { /* 0 is a special case meaning no checksum */
+#ifdef CONFIG_XEN
+ if ((*pskb)->proto_csum_blank)
+ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
+ else
+#endif
+ hdr->check = ip_nat_cheat_check(~oldip, newip,
ip_nat_cheat_check(*portptr ^ 0xFFFF,
newport,
hdr->check));
+ }
*portptr = newport;
return 1;
}
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;
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]);
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;
rhash_entries,
(num_physpages >= 128 * 1024) ?
15 : 17,
- HASH_HIGHMEM,
+ 0,
&rt_hash_log,
&rt_hash_mask,
0);
#include <linux/random.h>
#include <linux/bootmem.h>
#include <linux/cache.h>
+#include <linux/err.h>
#include <linux/in.h>
#include <net/icmp.h>
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;
ssize_t res;
struct sock *sk = sock->sk;
-#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
-
if (!(sk->sk_route_caps & NETIF_F_SG) ||
- !(sk->sk_route_caps & TCP_ZC_CSUM_FLAGS))
+ !(sk->sk_route_caps & NETIF_F_ALL_CSUM))
return sock_no_sendpage(sock, page, offset, size, flags);
-#undef TCP_ZC_CSUM_FLAGS
-
lock_sock(sk);
TCP_CHECK_TIMER(sk);
res = do_tcp_sendpages(sk, &page, offset, size, flags);
/*
* 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);
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;
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;
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);
}
}
}
+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.
*
* 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)++;
/* Avoid the costly divide in the normal
* non-TSO case.
*/
- skb_shinfo(skb)->tso_segs = 1;
- skb_shinfo(skb)->tso_size = 0;
+ skb_shinfo(skb)->gso_segs = 1;
+ skb_shinfo(skb)->gso_size = 0;
+ skb_shinfo(skb)->gso_type = 0;
} else {
unsigned int factor;
factor = skb->len + (mss_now - 1);
factor /= mss_now;
- skb_shinfo(skb)->tso_segs = factor;
- skb_shinfo(skb)->tso_size = mss_now;
+ skb_shinfo(skb)->gso_segs = factor;
+ skb_shinfo(skb)->gso_size = mss_now;
+ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
}
}
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);
}
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->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;
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);
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 */
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)->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);
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
*/
#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 <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
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)
goto out_exit;
}
-static int xfrm4_output_finish(struct sk_buff *skb)
+static int xfrm4_output_finish2(struct sk_buff *skb)
{
int err;
-#ifdef CONFIG_NETFILTER
- if (!skb->dst->xfrm) {
- IPCB(skb)->flags |= IPSKB_REROUTED;
- return dst_output(skb);
- }
-#endif
while (likely((err = xfrm4_output_one(skb)) == 0)) {
nf_reset(skb);
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;
}
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,
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);
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;
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);
opt2->tot_len = tot_len;
p = (char *)(opt2 + 1);
- err = ipv6_renew_option(opt->hopopt, newopt, newoptlen,
+ err = ipv6_renew_option(opt ? opt->hopopt : NULL, newopt, newoptlen,
newtype != IPV6_HOPOPTS,
&opt2->hopopt, &p);
if (err)
goto out;
- err = ipv6_renew_option(opt->dst0opt, newopt, newoptlen,
+ err = ipv6_renew_option(opt ? opt->dst0opt : NULL, newopt, newoptlen,
newtype != IPV6_RTHDRDSTOPTS,
&opt2->dst0opt, &p);
if (err)
goto out;
- err = ipv6_renew_option(opt->srcrt, newopt, newoptlen,
+ err = ipv6_renew_option(opt ? opt->srcrt : NULL, newopt, newoptlen,
newtype != IPV6_RTHDR,
- (struct ipv6_opt_hdr **)opt2->srcrt, &p);
+ (struct ipv6_opt_hdr **)&opt2->srcrt, &p);
if (err)
goto out;
- err = ipv6_renew_option(opt->dst1opt, newopt, newoptlen,
+ err = ipv6_renew_option(opt ? opt->dst1opt : NULL, newopt, newoptlen,
newtype != IPV6_DSTOPTS,
&opt2->dst1opt, &p);
if (err)
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
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);
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) {
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;
struct crypto_tfm *tfm;
int cpu;
- if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
- skb_linearize(skb, GFP_ATOMIC) != 0) {
- err = -ENOMEM;
+ if (skb_linearize_cow(skb))
goto out;
- }
skb->ip_summed = CHECKSUM_NONE;
goto out_ok;
}
- if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
- skb_linearize(skb, GFP_ATOMIC) != 0) {
+ if (skb_linearize_cow(skb))
goto out_ok;
- }
/* compression */
plen = skb->len - hdr_len;
goto out_exit;
}
-static int xfrm6_output_finish(struct sk_buff *skb)
+static int xfrm6_output_finish2(struct sk_buff *skb)
{
int err;
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;
}
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,
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 &&
if (timer_pending(&inst->timer))
del_timer(&inst->timer);
+ if (!inst->skb)
+ return 0;
+
if (inst->qlen > 1)
inst->lastnlh->nlmsg_type = NLMSG_DONE;
RTA_PUT(skb, a->order, 0, NULL);
err = tcf_action_dump_1(skb, a, bind, ref);
if (err < 0)
- goto rtattr_failure;
+ goto errout;
r->rta_len = skb->tail - (u8*)r;
}
return 0;
rtattr_failure:
+ err = -EINVAL;
+errout:
skb_trim(skb, b - skb->data);
- return -err;
+ return err;
}
struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est,
goto err_mod;
}
#endif
+ *err = -ENOENT;
goto err_out;
}
return ret;
}
-static char *
+static struct rtattr *
find_dump_kind(struct nlmsghdr *n)
{
struct rtattr *tb1, *tb2[TCA_ACT_MAX+1];
return NULL;
kind = tb2[TCA_ACT_KIND-1];
- return (char *) RTA_DATA(kind);
+ return kind;
}
static int
struct tc_action a;
int ret = 0;
struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
- char *kind = find_dump_kind(cb->nlh);
+ struct rtattr *kind = find_dump_kind(cb->nlh);
if (kind == NULL) {
printk("tc_dump_action: action bad kind\n");
return 0;
}
- a_o = tc_lookup_action_n(kind);
+ a_o = tc_lookup_action(kind);
if (a_o == NULL) {
- printk("failed to find %s\n", kind);
return 0;
}
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;
}
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.
*/
NOTE: Called under dev->queue_lock with locally disabled BH.
*/
-int qdisc_restart(struct net_device *dev)
+static inline int qdisc_restart(struct net_device *dev)
{
struct Qdisc *q = dev->qdisc;
struct sk_buff *skb;
/* Dequeue packet */
- if ((skb = q->dequeue(q)) != NULL) {
+ if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) {
unsigned nolock = (dev->features & NETIF_F_LLTX);
+
+ dev->gso_skb = NULL;
+
/*
* When the driver has LLTX set it does its own locking
* in start_xmit. No need to add additional overhead by
* will be requeued.
*/
if (!nolock) {
- if (!spin_trylock(&dev->xmit_lock)) {
+ if (!netif_tx_trylock(dev)) {
collision:
/* So, someone grabbed the driver. */
__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();
}
{
if (!netif_queue_stopped(dev)) {
int ret;
- if (netdev_nit)
- dev_queue_xmit_nit(skb, dev);
- ret = dev->hard_start_xmit(skb, dev);
+ ret = dev_hard_start_xmit(skb, dev);
if (ret == NETDEV_TX_OK) {
if (!nolock) {
- dev->xmit_lock_owner = -1;
- spin_unlock(&dev->xmit_lock);
+ netif_tx_unlock(dev);
}
spin_lock(&dev->queue_lock);
return -1;
/* 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;
*/
requeue:
- q->ops->requeue(skb, q);
+ if (skb->next)
+ dev->gso_skb = skb;
+ else
+ q->ops->requeue(skb, q);
netif_schedule(dev);
return 1;
}
return q->q.qlen;
}
+void __qdisc_run(struct net_device *dev)
+{
+ if (unlikely(dev->qdisc == &noop_qdisc))
+ goto out;
+
+ while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev))
+ /* NOTHING */;
+
+out:
+ clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
+}
+
static void dev_watchdog(unsigned long arg)
{
struct net_device *dev = (struct net_device *)arg;
- spin_lock(&dev->xmit_lock);
+ netif_tx_lock(dev);
if (dev->qdisc != &noop_qdisc) {
if (netif_device_present(dev) &&
netif_running(dev) &&
dev_hold(dev);
}
}
- spin_unlock(&dev->xmit_lock);
+ netif_tx_unlock(dev);
dev_put(dev);
}
static void dev_watchdog_up(struct net_device *dev)
{
- spin_lock_bh(&dev->xmit_lock);
+ netif_tx_lock_bh(dev);
__netdev_watchdog_up(dev);
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
}
static void dev_watchdog_down(struct net_device *dev)
{
- spin_lock_bh(&dev->xmit_lock);
+ netif_tx_lock_bh(dev);
if (del_timer(&dev->watchdog_timer))
dev_put(dev);
- spin_unlock_bh(&dev->xmit_lock);
+ netif_tx_unlock_bh(dev);
}
void netif_carrier_on(struct net_device *dev)
dev_watchdog_down(dev);
- while (test_bit(__LINK_STATE_SCHED, &dev->state))
+ /* Wait for outstanding dev_queue_xmit calls. */
+ synchronize_rcu();
+
+ /* Wait for outstanding qdisc_run calls. */
+ while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
yield();
- spin_unlock_wait(&dev->xmit_lock);
+ if (dev->gso_skb) {
+ kfree_skb(dev->gso_skb);
+ dev->gso_skb = NULL;
+ }
}
void dev_init_scheduler(struct net_device *dev)
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);
switch (teql_resolve(skb, skb_res, slave)) {
case 0:
- if (spin_trylock(&slave->xmit_lock)) {
- slave->xmit_lock_owner = smp_processor_id();
+ if (netif_tx_trylock(slave)) {
if (!netif_queue_stopped(slave) &&
slave->hard_start_xmit(skb, slave) == 0) {
- slave->xmit_lock_owner = -1;
- spin_unlock(&slave->xmit_lock);
+ netif_tx_unlock(slave);
master->slaves = NEXT_SLAVE(q);
netif_wake_queue(dev);
master->stats.tx_packets++;
master->stats.tx_bytes += len;
return 0;
}
- slave->xmit_lock_owner = -1;
- spin_unlock(&slave->xmit_lock);
+ netif_tx_unlock(slave);
}
if (netif_queue_stopped(dev))
busy = 1;
/* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error. */
struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc,
- const struct sctp_chunk *chunk,
- const struct msghdr *msg)
+ const struct msghdr *msg,
+ size_t paylen)
{
struct sctp_chunk *retval;
- void *payload = NULL, *payoff;
- size_t paylen = 0;
- struct iovec *iov = NULL;
- int iovlen = 0;
-
- if (msg) {
- iov = msg->msg_iov;
- iovlen = msg->msg_iovlen;
- paylen = get_user_iov_size(iov, iovlen);
- }
+ void *payload = NULL;
+ int err;
- retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen);
+ retval = sctp_make_abort(asoc, NULL, sizeof(sctp_errhdr_t) + paylen);
if (!retval)
goto err_chunk;
if (paylen) {
/* Put the msg_iov together into payload. */
- payload = kmalloc(paylen, GFP_ATOMIC);
+ payload = kmalloc(paylen, GFP_KERNEL);
if (!payload)
goto err_payload;
- payoff = payload;
- for (; iovlen > 0; --iovlen) {
- if (copy_from_user(payoff, iov->iov_base,iov->iov_len))
- goto err_copy;
- payoff += iov->iov_len;
- iov++;
- }
+ err = memcpy_fromiovec(payload, msg->msg_iov, paylen);
+ if (err < 0)
+ goto err_copy;
}
sctp_init_cause(retval, SCTP_ERROR_USER_ABORT, payload, paylen);
* from its upper layer, but retransmits data to the far end
* if necessary to fill gaps.
*/
- struct msghdr *msg = arg;
- struct sctp_chunk *abort;
+ struct sctp_chunk *abort = arg;
sctp_disposition_t retval;
retval = SCTP_DISPOSITION_CONSUME;
- /* Generate ABORT chunk to send the peer. */
- abort = sctp_make_abort_user(asoc, NULL, msg);
- if (!abort)
- retval = SCTP_DISPOSITION_NOMEM;
- else
- sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
/* Even if we can't send the ABORT due to low memory delete the
* TCB. This is a departure from our typical NOMEM handling.
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_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));
}
}
- 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);
}
goto out_unlock;
}
if (sinfo_flags & SCTP_ABORT) {
+ struct sctp_chunk *chunk;
+
+ chunk = sctp_make_abort_user(asoc, msg, msg_len);
+ if (!chunk) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+
SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc);
- sctp_primitive_ABORT(asoc, msg);
+ sctp_primitive_ABORT(asoc, chunk);
err = 0;
goto out_unlock;
}
new = detail->alloc();
if (!new)
return NULL;
+ /* must fully initialise 'new', else
+ * we might get lose if we need to
+ * cache_put it soon.
+ */
cache_init(new);
+ detail->init(new, key);
write_lock(&detail->hash_lock);
return tmp;
}
}
- detail->init(new, key);
new->next = *head;
*head = new;
detail->entries++;
-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 \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
- /usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
+ /usr/include/gnu/stubs-32.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stddef.h \
+ /usr/include/bits/types.h \
/usr/include/bits/typesizes.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/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/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/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 \
-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 \
$(wildcard include/config/my/option.h) \
$(wildcard include/config/.h) \
$(wildcard include/config/foo.h) \
+ $(wildcard include/config/boom.h) \
/usr/include/sys/types.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
- /usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+ /usr/include/gnu/stubs-32.h \
+ /usr/include/bits/types.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/endian.h \
/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/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/limits.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/syslimits.h \
/usr/include/limits.h \
/usr/include/bits/posix1_lim.h \
/usr/include/bits/local_lim.h \
/usr/include/linux/limits.h \
/usr/include/bits/posix2_lim.h \
/usr/include/ctype.h \
+ /usr/include/arpa/inet.h \
/usr/include/netinet/in.h \
/usr/include/stdint.h \
/usr/include/sys/socket.h \
-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 \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
- /usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+ /usr/include/gnu/stubs-32.h \
+ /usr/include/bits/types.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/bits/stat.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
- /usr/include/bits/sched.h \
/usr/include/ctype.h \
/usr/include/errno.h \
/usr/include/bits/errno.h \
/usr/include/linux/errno.h \
/usr/include/asm/errno.h \
- /usr/include/asm-generic/errno.h \
- /usr/include/asm-generic/errno-base.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/stdio.h \
/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 \
-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
deps_scripts/kconfig/conf.o := \
scripts/kconfig/conf.c \
$(wildcard include/config/.h) \
+ $(wildcard include/config/allconfig.h) \
/usr/include/ctype.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
- /usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+ /usr/include/gnu/stubs-32.h \
+ /usr/include/bits/types.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
- /usr/include/bits/sched.h \
/usr/include/alloca.h \
+ /usr/include/stdio.h \
+ /usr/include/libio.h \
+ /usr/include/_G_config.h \
+ /usr/include/wchar.h \
+ /usr/include/bits/wchar.h \
+ /usr/include/gconv.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdarg.h \
+ /usr/include/bits/stdio_lim.h \
+ /usr/include/bits/sys_errlist.h \
+ /usr/include/bits/stdio.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
/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)
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
- /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stddef.h \
+ /usr/include/bits/wordsize.h \
+ /usr/include/gnu/stubs-32.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stddef.h \
/usr/include/sys/types.h \
/usr/include/bits/types.h \
- /usr/include/bits/wordsize.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/endian.h \
/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/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
- /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stdarg.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
- /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stdbool.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdbool.h \
/usr/include/libintl.h \
/usr/include/locale.h \
/usr/include/bits/locale.h \
deps_scripts/kconfig/mconf.o := \
scripts/kconfig/mconf.c \
- $(wildcard include/config/.h) \
$(wildcard include/config/mode.h) \
+ $(wildcard include/config/.h) \
/usr/include/sys/ioctl.h \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
+ /usr/include/bits/wordsize.h \
+ /usr/include/gnu/stubs-32.h \
/usr/include/bits/ioctls.h \
/usr/include/asm/ioctls.h \
/usr/include/asm/ioctl.h \
/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/sigaction.h \
/usr/include/bits/sigcontext.h \
/usr/include/asm/sigcontext.h \
- /usr/include/linux/compiler.h \
- /usr/include/linux/compiler-gcc3.h \
- /usr/include/linux/compiler-gcc.h \
/usr/include/bits/sigstack.h \
/usr/include/bits/pthreadtypes.h \
- /usr/include/bits/sched.h \
/usr/include/bits/sigthread.h \
/usr/include/sys/resource.h \
/usr/include/bits/resource.h \
/usr/include/bits/errno.h \
/usr/include/linux/errno.h \
/usr/include/asm/errno.h \
- /usr/include/asm-generic/errno.h \
- /usr/include/asm-generic/errno-base.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/sys/types.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/sys/sysmacros.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/limits.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/syslimits.h \
/usr/include/limits.h \
/usr/include/bits/posix1_lim.h \
/usr/include/bits/local_lim.h \
/usr/include/linux/limits.h \
/usr/include/bits/posix2_lim.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdarg.h \
/usr/include/stdlib.h \
/usr/include/alloca.h \
/usr/include/string.h \
/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 \
/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)
-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 \
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
- /usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+ /usr/include/gnu/stubs-32.h \
+ /usr/include/bits/types.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdarg.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/bits/time.h \
/usr/include/sys/sysmacros.h \
/usr/include/bits/pthreadtypes.h \
- /usr/include/bits/sched.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdbool.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/stdbool.h \
scripts/kconfig/lkc.h \
scripts/kconfig/expr.h \
+ /usr/include/libintl.h \
+ /usr/include/locale.h \
+ /usr/include/bits/locale.h \
scripts/kconfig/lkc_proto.h \
+ scripts/kconfig/zconf.hash.c \
scripts/kconfig/lex.zconf.c \
/usr/include/errno.h \
/usr/include/bits/errno.h \
/usr/include/linux/errno.h \
/usr/include/asm/errno.h \
- /usr/include/asm-generic/errno.h \
- /usr/include/asm-generic/errno-base.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/limits.h \
+ /usr/lib/gcc/i386-redhat-linux/4.0.1/include/syslimits.h \
/usr/include/limits.h \
/usr/include/bits/posix1_lim.h \
/usr/include/bits/local_lim.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
+ scripts/kconfig/lkc.h \
+ scripts/kconfig/util.c \
+ scripts/kconfig/lkc.h \
scripts/kconfig/confdata.c \
$(wildcard include/config/.h) \
+ $(wildcard include/config/notimestamp.h) \
/usr/include/sys/stat.h \
/usr/include/bits/stat.h \
+ scripts/kconfig/lkc.h \
scripts/kconfig/expr.c \
+ scripts/kconfig/lkc.h \
scripts/kconfig/symbol.c \
+ /usr/include/regex.h \
/usr/include/sys/utsname.h \
/usr/include/bits/utsname.h \
+ scripts/kconfig/lkc.h \
scripts/kconfig/menu.c \
+ scripts/kconfig/lkc.h \
scripts/kconfig/zconf.tab.o: $(deps_scripts/kconfig/zconf.tab.o)
-#line 3 "lex.zconf.c"
+#line 3 "scripts/kconfig/lex.zconf.c"
#define YY_INT_ALIGNED short int
/* Begin user sect3 */
-#define zconfwrap(n) 1
+#define zconfwrap() 1
#define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR;
extern char *zconftext;
#define yytext_ptr zconftext
-static yyconst flex_int16_t yy_nxt[][38] =
+static yyconst flex_int16_t yy_nxt[][17] =
{
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
- },
-
- {
- 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12
- },
-
- {
- 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-
- 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12
- },
-
- {
- 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 18, 16, 16, 18, 18, 19, 20,
- 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
- 27, 18, 28, 29, 30, 18, 18, 16
- },
-
- {
- 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 18, 16, 16, 18, 18, 19, 20,
- 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
- 27, 18, 28, 29, 30, 18, 18, 16
-
- },
-
- {
- 11, 31, 32, 33, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31
- },
-
- {
- 11, 31, 32, 33, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31
- },
-
- {
- 11, 34, 34, 35, 34, 36, 34, 34, 36, 34,
- 34, 34, 34, 34, 34, 37, 34, 34, 34, 34,
-
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34
- },
-
- {
- 11, 34, 34, 35, 34, 36, 34, 34, 36, 34,
- 34, 34, 34, 34, 34, 37, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
- 34, 34, 34, 34, 34, 34, 34, 34
- },
-
- {
- 11, 38, 38, 39, 40, 41, 42, 43, 41, 44,
- 45, 46, 47, 47, 48, 49, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
- 47, 47, 47, 47, 47, 47, 47, 52
-
- },
-
- {
- 11, 38, 38, 39, 40, 41, 42, 43, 41, 44,
- 45, 46, 47, 47, 48, 49, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
- 47, 47, 47, 47, 47, 47, 47, 52
- },
-
- {
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11, -11
- },
-
- {
- 11, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
-
- -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12, -12
- },
-
- {
- 11, -13, 53, 54, -13, -13, 55, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13, -13
- },
-
- {
- 11, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14, -14
-
- },
-
- {
- 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56
- },
-
- {
- 11, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16, -16
- },
-
- {
- 11, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
-
- -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17, -17
- },
-
- {
- 11, -18, -18, -18, -18, -18, -18, -18, -18, -18,
- -18, -18, -18, 58, -18, -18, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -18
- },
-
- {
- 11, -19, -19, -19, -19, -19, -19, -19, -19, -19,
- -19, -19, -19, 58, -19, -19, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 59,
- 58, 58, 58, 58, 58, 58, 58, -19
-
- },
-
- {
- 11, -20, -20, -20, -20, -20, -20, -20, -20, -20,
- -20, -20, -20, 58, -20, -20, 58, 58, 58, 58,
- 58, 58, 58, 58, 60, 58, 58, 58, 58, 61,
- 58, 58, 58, 58, 58, 58, 58, -20
- },
-
- {
- 11, -21, -21, -21, -21, -21, -21, -21, -21, -21,
- -21, -21, -21, 58, -21, -21, 58, 58, 58, 58,
- 58, 62, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -21
- },
-
- {
- 11, -22, -22, -22, -22, -22, -22, -22, -22, -22,
- -22, -22, -22, 58, -22, -22, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 63, 58,
- 58, 58, 58, 58, 58, 58, 58, -22
- },
-
- {
- 11, -23, -23, -23, -23, -23, -23, -23, -23, -23,
- -23, -23, -23, 58, -23, -23, 58, 58, 58, 58,
- 58, 64, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -23
- },
-
- {
- 11, -24, -24, -24, -24, -24, -24, -24, -24, -24,
- -24, -24, -24, 58, -24, -24, 58, 58, 58, 58,
- 58, 58, 65, 58, 58, 58, 58, 58, 66, 58,
- 58, 58, 58, 58, 58, 58, 58, -24
-
- },
-
- {
- 11, -25, -25, -25, -25, -25, -25, -25, -25, -25,
- -25, -25, -25, 58, -25, -25, 58, 67, 58, 58,
- 58, 68, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -25
- },
-
- {
- 11, -26, -26, -26, -26, -26, -26, -26, -26, -26,
- -26, -26, -26, 58, -26, -26, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 69, 58, 58, 58, 58, 58, 58, -26
- },
-
- {
- 11, -27, -27, -27, -27, -27, -27, -27, -27, -27,
- -27, -27, -27, 58, -27, -27, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 70, 58, 58, 58, 58, -27
- },
-
- {
- 11, -28, -28, -28, -28, -28, -28, -28, -28, -28,
- -28, -28, -28, 58, -28, -28, 58, 71, 58, 58,
- 58, 72, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -28
- },
-
- {
- 11, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, 58, -29, -29, 58, 58, 58, 58,
- 58, 73, 58, 58, 58, 58, 58, 58, 58, 74,
- 58, 58, 58, 58, 75, 58, 58, -29
-
- },
-
- {
- 11, -30, -30, -30, -30, -30, -30, -30, -30, -30,
- -30, -30, -30, 58, -30, -30, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 76, 58, 58, 58, 58, -30
- },
-
- {
- 11, 77, 77, -31, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77
- },
-
- {
- 11, -32, 78, 79, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
-
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32
- },
-
- {
- 11, 80, -33, -33, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80
- },
-
- {
- 11, 81, 81, 82, 81, -34, 81, 81, -34, 81,
- 81, 81, 81, 81, 81, -34, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81
-
- },
-
- {
- 11, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, -35, -35, -35, -35, -35, -35, -35
- },
-
- {
- 11, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36, -36
- },
-
- {
- 11, 83, 83, 84, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
-
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83
- },
-
- {
- 11, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38
- },
-
- {
- 11, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39, -39
-
- },
-
- {
- 11, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, 85, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40, -40
- },
-
- {
- 11, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
- -41, -41, -41, -41, -41, -41, -41, -41
- },
-
- {
- 11, 86, 86, -42, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
-
- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86
- },
-
- {
- 11, -43, -43, -43, -43, -43, -43, 87, -43, -43,
- -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
- -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
- -43, -43, -43, -43, -43, -43, -43, -43
- },
-
- {
- 11, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, -44, -44, -44, -44, -44
-
- },
-
- {
- 11, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
- -45, -45, -45, -45, -45, -45, -45, -45
- },
-
- {
- 11, -46, -46, -46, -46, -46, -46, -46, -46, -46,
- -46, 88, 89, 89, -46, -46, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -46
- },
-
- {
- 11, -47, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, 89, 89, 89, -47, -47, 89, 89, 89, 89,
-
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -47
- },
-
- {
- 11, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48
- },
-
- {
- 11, -49, -49, 90, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
- -49, -49, -49, -49, -49, -49, -49, -49
-
- },
-
- {
- 11, -50, -50, -50, -50, -50, -50, -50, -50, -50,
- -50, 89, 89, 89, -50, -50, 89, 89, 89, 89,
- 89, 89, 91, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -50
- },
-
- {
- 11, -51, -51, -51, -51, -51, -51, -51, -51, -51,
- -51, 89, 89, 89, -51, -51, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 92, 89,
- 89, 89, 89, 89, 89, 89, 89, -51
- },
-
- {
- 11, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
-
- -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52, 93
- },
-
- {
- 11, -53, 53, 54, -53, -53, 55, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53, -53
- },
-
- {
- 11, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
- -54, -54, -54, -54, -54, -54, -54, -54
-
- },
-
- {
- 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56
- },
-
- {
- 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56
- },
-
- {
- 11, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
-
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57
- },
-
- {
- 11, -58, -58, -58, -58, -58, -58, -58, -58, -58,
- -58, -58, -58, 58, -58, -58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -58
- },
-
- {
- 11, -59, -59, -59, -59, -59, -59, -59, -59, -59,
- -59, -59, -59, 58, -59, -59, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 94,
- 58, 58, 58, 58, 58, 58, 58, -59
-
- },
-
- {
- 11, -60, -60, -60, -60, -60, -60, -60, -60, -60,
- -60, -60, -60, 58, -60, -60, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 95,
- 58, 58, 58, 58, 58, 58, 58, -60
- },
-
- {
- 11, -61, -61, -61, -61, -61, -61, -61, -61, -61,
- -61, -61, -61, 58, -61, -61, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 96, 97, 58,
- 58, 58, 58, 58, 58, 58, 58, -61
- },
-
- {
- 11, -62, -62, -62, -62, -62, -62, -62, -62, -62,
- -62, -62, -62, 58, -62, -62, 58, 58, 58, 58,
-
- 58, 58, 98, 58, 58, 58, 58, 58, 58, 58,
- 99, 58, 58, 58, 58, 58, 58, -62
- },
-
- {
- 11, -63, -63, -63, -63, -63, -63, -63, -63, -63,
- -63, -63, -63, 58, -63, -63, 58, 100, 58, 58,
- 101, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -63
- },
-
- {
- 11, -64, -64, -64, -64, -64, -64, -64, -64, -64,
- -64, -64, -64, 58, -64, -64, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 102, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 103, -64
-
- },
-
- {
- 11, -65, -65, -65, -65, -65, -65, -65, -65, -65,
- -65, -65, -65, 58, -65, -65, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -65
- },
-
- {
- 11, -66, -66, -66, -66, -66, -66, -66, -66, -66,
- -66, -66, -66, 58, -66, -66, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 104, 58, 58, -66
- },
-
- {
- 11, -67, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, 58, -67, -67, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 105, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -67
- },
-
- {
- 11, -68, -68, -68, -68, -68, -68, -68, -68, -68,
- -68, -68, -68, 58, -68, -68, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 106, 58,
- 58, 58, 58, 58, 58, 58, 58, -68
- },
-
- {
- 11, -69, -69, -69, -69, -69, -69, -69, -69, -69,
- -69, -69, -69, 58, -69, -69, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 107, 58, 58, -69
-
- },
-
- {
- 11, -70, -70, -70, -70, -70, -70, -70, -70, -70,
- -70, -70, -70, 58, -70, -70, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 108,
- 58, 58, 58, 58, 58, 58, 58, -70
- },
-
- {
- 11, -71, -71, -71, -71, -71, -71, -71, -71, -71,
- -71, -71, -71, 58, -71, -71, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 109, 58,
- 58, 58, 58, 58, 58, 58, 58, -71
- },
-
- {
- 11, -72, -72, -72, -72, -72, -72, -72, -72, -72,
- -72, -72, -72, 58, -72, -72, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 110, 58, 58, 58, 58, 58, -72
- },
-
- {
- 11, -73, -73, -73, -73, -73, -73, -73, -73, -73,
- -73, -73, -73, 58, -73, -73, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 111, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -73
- },
-
- {
- 11, -74, -74, -74, -74, -74, -74, -74, -74, -74,
- -74, -74, -74, 58, -74, -74, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 112, 58, -74
-
- },
-
- {
- 11, -75, -75, -75, -75, -75, -75, -75, -75, -75,
- -75, -75, -75, 58, -75, -75, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 113, 58, 58, 58, 58, -75
- },
-
- {
- 11, -76, -76, -76, -76, -76, -76, -76, -76, -76,
- -76, -76, -76, 58, -76, -76, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 114, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -76
- },
-
- {
- 11, 77, 77, -77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
-
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77
- },
-
- {
- 11, -78, 78, 79, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
- -78, -78, -78, -78, -78, -78, -78, -78
- },
-
- {
- 11, 80, -79, -79, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80
-
- },
-
- {
- 11, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80
- },
-
- {
- 11, 81, 81, 82, 81, -81, 81, 81, -81, 81,
- 81, 81, 81, 81, 81, -81, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, 81
- },
-
- {
- 11, -82, -82, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
-
- -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
- -82, -82, -82, -82, -82, -82, -82, -82
- },
-
- {
- 11, -83, -83, 84, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
- -83, -83, -83, -83, -83, -83, -83, -83
- },
-
- {
- 11, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
- -84, -84, -84, -84, -84, -84, -84, -84
-
- },
-
- {
- 11, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
- -85, -85, -85, -85, -85, -85, -85, -85
- },
-
- {
- 11, 86, 86, -86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86
- },
-
- {
- 11, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
-
- -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
- -87, -87, -87, -87, -87, -87, -87, -87
- },
-
- {
- 11, -88, -88, -88, -88, -88, -88, -88, -88, -88,
- -88, 115, 89, 89, -88, -88, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -88
- },
-
- {
- 11, -89, -89, -89, -89, -89, -89, -89, -89, -89,
- -89, 89, 89, 89, -89, -89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -89
-
- },
-
- {
- 11, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
- -90, -90, -90, -90, -90, -90, -90, -90
- },
-
- {
- 11, -91, -91, -91, -91, -91, -91, -91, -91, -91,
- -91, 89, 89, 89, -91, -91, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -91
- },
-
- {
- 11, -92, -92, -92, -92, -92, -92, -92, -92, -92,
- -92, 89, 89, 89, -92, -92, 89, 89, 89, 89,
-
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -92
- },
-
- {
- 11, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
- -93, -93, -93, -93, -93, -93, -93, -93
- },
-
- {
- 11, -94, -94, -94, -94, -94, -94, -94, -94, -94,
- -94, -94, -94, 58, -94, -94, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 116, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -94
-
- },
-
- {
- 11, -95, -95, -95, -95, -95, -95, -95, -95, -95,
- -95, -95, -95, 58, -95, -95, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 117, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -95
- },
-
- {
- 11, -96, -96, -96, -96, -96, -96, -96, -96, -96,
- -96, -96, -96, 58, -96, -96, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 118, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -96
- },
-
- {
- 11, -97, -97, -97, -97, -97, -97, -97, -97, -97,
- -97, -97, -97, 58, -97, -97, 58, 58, 58, 58,
-
- 58, 58, 119, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -97
- },
-
- {
- 11, -98, -98, -98, -98, -98, -98, -98, -98, -98,
- -98, -98, -98, 58, -98, -98, 120, 121, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -98
- },
-
- {
- 11, -99, -99, -99, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, 58, -99, -99, 58, 58, 58, 58,
- 58, 122, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -99
-
- },
-
- {
- 11, -100, -100, -100, -100, -100, -100, -100, -100, -100,
- -100, -100, -100, 58, -100, -100, 58, 58, 123, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -100
- },
-
- {
- 11, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, 58, -101, -101, 58, 58, 58, 124,
- 58, 58, 58, 58, 58, 125, 58, 126, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -101
- },
-
- {
- 11, -102, -102, -102, -102, -102, -102, -102, -102, -102,
- -102, -102, -102, 58, -102, -102, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 127, 58, 58, 58, 58, 58, 58, -102
- },
-
- {
- 11, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- -103, -103, -103, 58, -103, -103, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -103
- },
-
- {
- 11, -104, -104, -104, -104, -104, -104, -104, -104, -104,
- -104, -104, -104, 58, -104, -104, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -104
-
- },
-
- {
- 11, -105, -105, -105, -105, -105, -105, -105, -105, -105,
- -105, -105, -105, 58, -105, -105, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 128, 58,
- 58, 58, 58, 58, 58, 58, 58, -105
- },
-
- {
- 11, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, 58, -106, -106, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 129, 58, -106
- },
-
- {
- 11, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, 58, -107, -107, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 130, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -107
- },
-
- {
- 11, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, 58, -108, -108, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 131, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -108
- },
-
- {
- 11, -109, -109, -109, -109, -109, -109, -109, -109, -109,
- -109, -109, -109, 58, -109, -109, 58, 58, 58, 58,
- 58, 58, 58, 132, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -109
-
- },
-
- {
- 11, -110, -110, -110, -110, -110, -110, -110, -110, -110,
- -110, -110, -110, 58, -110, -110, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 133, 58, -110
- },
-
- {
- 11, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, 58, -111, -111, 58, 58, 58, 58,
- 58, 134, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -111
- },
-
- {
- 11, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, 58, -112, -112, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 135, 58, 58, 58, 58, -112
- },
-
- {
- 11, -113, -113, -113, -113, -113, -113, -113, -113, -113,
- -113, -113, -113, 58, -113, -113, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 136, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -113
- },
-
- {
- 11, -114, -114, -114, -114, -114, -114, -114, -114, -114,
- -114, -114, -114, 58, -114, -114, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 137, 58, 58, 58, -114
-
- },
-
- {
- 11, -115, -115, -115, -115, -115, -115, -115, -115, -115,
- -115, 89, 89, 89, -115, -115, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, -115
- },
-
- {
- 11, -116, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -116, -116, 58, -116, -116, 58, 58, 58, 58,
- 58, 138, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -116
- },
-
- {
- 11, -117, -117, -117, -117, -117, -117, -117, -117, -117,
- -117, -117, -117, 58, -117, -117, 58, 58, 58, 139,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -117
- },
-
- {
- 11, -118, -118, -118, -118, -118, -118, -118, -118, -118,
- -118, -118, -118, 58, -118, -118, 58, 58, 58, 58,
- 58, 140, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -118
- },
-
- {
- 11, -119, -119, -119, -119, -119, -119, -119, -119, -119,
- -119, -119, -119, 58, -119, -119, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 141, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -119
-
- },
-
- {
- 11, -120, -120, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, 58, -120, -120, 58, 58, 142, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 143, 58, 58, -120
- },
-
- {
- 11, -121, -121, -121, -121, -121, -121, -121, -121, -121,
- -121, -121, -121, 58, -121, -121, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 144, 58, -121
- },
-
- {
- 11, -122, -122, -122, -122, -122, -122, -122, -122, -122,
- -122, -122, -122, 58, -122, -122, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 145, 58,
- 58, 58, 58, 58, 58, 58, 58, -122
- },
-
- {
- 11, -123, -123, -123, -123, -123, -123, -123, -123, -123,
- -123, -123, -123, 58, -123, -123, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 146, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -123
- },
-
- {
- 11, -124, -124, -124, -124, -124, -124, -124, -124, -124,
- -124, -124, -124, 58, -124, -124, 58, 58, 58, 58,
- 58, 58, 58, 58, 147, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -124
-
- },
-
- {
- 11, -125, -125, -125, -125, -125, -125, -125, -125, -125,
- -125, -125, -125, 58, -125, -125, 58, 58, 58, 58,
- 58, 58, 148, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -125
- },
-
- {
- 11, -126, -126, -126, -126, -126, -126, -126, -126, -126,
- -126, -126, -126, 58, -126, -126, 58, 58, 58, 58,
- 58, 149, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -126
- },
-
- {
- 11, -127, -127, -127, -127, -127, -127, -127, -127, -127,
- -127, -127, -127, 58, -127, -127, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -127
- },
-
- {
- 11, -128, -128, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, 58, -128, -128, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 150, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -128
- },
-
- {
- 11, -129, -129, -129, -129, -129, -129, -129, -129, -129,
- -129, -129, -129, 58, -129, -129, 58, 58, 58, 151,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -129
-
- },
-
- {
- 11, -130, -130, -130, -130, -130, -130, -130, -130, -130,
- -130, -130, -130, 58, -130, -130, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 152,
- 58, 58, 58, 58, 58, 58, 58, -130
- },
-
- {
- 11, -131, -131, -131, -131, -131, -131, -131, -131, -131,
- -131, -131, -131, 58, -131, -131, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 153, 58, 58, 58, 58, 58, 58, -131
- },
-
- {
- 11, -132, -132, -132, -132, -132, -132, -132, -132, -132,
- -132, -132, -132, 58, -132, -132, 58, 58, 58, 58,
-
- 58, 154, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -132
- },
-
- {
- 11, -133, -133, -133, -133, -133, -133, -133, -133, -133,
- -133, -133, -133, 58, -133, -133, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 155, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -133
- },
-
- {
- 11, -134, -134, -134, -134, -134, -134, -134, -134, -134,
- -134, -134, -134, 58, -134, -134, 58, 58, 58, 156,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -134
-
- },
-
- {
- 11, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, 58, -135, -135, 58, 58, 58, 157,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -135
- },
-
- {
- 11, -136, -136, -136, -136, -136, -136, -136, -136, -136,
- -136, -136, -136, 58, -136, -136, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 158, 58,
- 58, 58, 58, 58, 58, 58, 58, -136
- },
-
- {
- 11, -137, -137, -137, -137, -137, -137, -137, -137, -137,
- -137, -137, -137, 58, -137, -137, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 159, 58, 58, -137
- },
-
- {
- 11, -138, -138, -138, -138, -138, -138, -138, -138, -138,
- -138, -138, -138, 58, -138, -138, 58, 160, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -138
- },
-
- {
- 11, -139, -139, -139, -139, -139, -139, -139, -139, -139,
- -139, -139, -139, 58, -139, -139, 58, 58, 58, 58,
- 58, 161, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -139
-
- },
-
- {
- 11, -140, -140, -140, -140, -140, -140, -140, -140, -140,
- -140, -140, -140, 58, -140, -140, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 162, 58,
- 58, 58, 58, 58, 58, 58, 58, -140
- },
-
- {
- 11, -141, -141, -141, -141, -141, -141, -141, -141, -141,
- -141, -141, -141, 58, -141, -141, 58, 58, 58, 58,
- 58, 58, 58, 163, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -141
- },
-
- {
- 11, -142, -142, -142, -142, -142, -142, -142, -142, -142,
- -142, -142, -142, 58, -142, -142, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 164,
- 58, 58, 58, 58, 58, 58, 58, -142
- },
-
- {
- 11, -143, -143, -143, -143, -143, -143, -143, -143, -143,
- -143, -143, -143, 58, -143, -143, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 165, 58, 58, 58, 58, -143
- },
-
- {
- 11, -144, -144, -144, -144, -144, -144, -144, -144, -144,
- -144, -144, -144, 58, -144, -144, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 166, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -144
-
- },
-
- {
- 11, -145, -145, -145, -145, -145, -145, -145, -145, -145,
- -145, -145, -145, 58, -145, -145, 58, 58, 58, 58,
- 167, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -145
- },
-
- {
- 11, -146, -146, -146, -146, -146, -146, -146, -146, -146,
- -146, -146, -146, 58, -146, -146, 58, 58, 58, 58,
- 58, 168, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -146
- },
-
- {
- 11, -147, -147, -147, -147, -147, -147, -147, -147, -147,
- -147, -147, -147, 58, -147, -147, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 169,
- 58, 58, 58, 58, 58, 58, 58, -147
- },
-
- {
- 11, -148, -148, -148, -148, -148, -148, -148, -148, -148,
- -148, -148, -148, 58, -148, -148, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -148
- },
-
- {
- 11, -149, -149, -149, -149, -149, -149, -149, -149, -149,
- -149, -149, -149, 58, -149, -149, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 170, 58,
- 58, 58, 58, 58, 58, 58, 58, -149
-
- },
-
- {
- 11, -150, -150, -150, -150, -150, -150, -150, -150, -150,
- -150, -150, -150, 58, -150, -150, 58, 58, 58, 58,
- 58, 171, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -150
+ 0, 0, 0, 0, 0, 0, 0
},
{
- 11, -151, -151, -151, -151, -151, -151, -151, -151, -151,
- -151, -151, -151, 58, -151, -151, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 172,
- 58, 58, 58, 58, 58, 58, 58, -151
+ 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12
},
{
- 11, -152, -152, -152, -152, -152, -152, -152, -152, -152,
- -152, -152, -152, 58, -152, -152, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 173, 58,
- 58, 58, 58, 58, 58, 58, 58, -152
+ 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12
},
{
- 11, -153, -153, -153, -153, -153, -153, -153, -153, -153,
- -153, -153, -153, 58, -153, -153, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 174, 58, 58, -153
+ 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 18, 16, 16, 16
},
{
- 11, -154, -154, -154, -154, -154, -154, -154, -154, -154,
- -154, -154, -154, 58, -154, -154, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -154
+ 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 18, 16, 16, 16
},
{
- 11, -155, -155, -155, -155, -155, -155, -155, -155, -155,
- -155, -155, -155, 58, -155, -155, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 175, 58, 58, 58, 58, -155
+ 11, 19, 20, 21, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19
},
{
- 11, -156, -156, -156, -156, -156, -156, -156, -156, -156,
- -156, -156, -156, 58, -156, -156, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 176, 58, 58, -156
+ 11, 19, 20, 21, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19
},
{
- 11, -157, -157, -157, -157, -157, -157, -157, -157, -157,
- -157, -157, -157, 58, -157, -157, 58, 58, 58, 58,
-
- 58, 177, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -157
+ 11, 22, 22, 23, 22, 24, 22, 22, 24, 22,
+ 22, 22, 22, 22, 22, 25, 22
},
{
- 11, -158, -158, -158, -158, -158, -158, -158, -158, -158,
- -158, -158, -158, 58, -158, -158, 58, 58, 58, 58,
- 58, 58, 58, 178, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -158
+ 11, 22, 22, 23, 22, 24, 22, 22, 24, 22,
+ 22, 22, 22, 22, 22, 25, 22
},
{
- 11, -159, -159, -159, -159, -159, -159, -159, -159, -159,
- -159, -159, -159, 58, -159, -159, 58, 179, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -159
+ 11, 26, 26, 27, 28, 29, 30, 31, 29, 32,
+ 33, 34, 35, 35, 36, 37, 38
},
{
- 11, -160, -160, -160, -160, -160, -160, -160, -160, -160,
- -160, -160, -160, 58, -160, -160, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 180, 58,
- 58, 58, 58, 58, 58, 58, 58, -160
+ 11, 26, 26, 27, 28, 29, 30, 31, 29, 32,
+ 33, 34, 35, 35, 36, 37, 38
},
{
- 11, -161, -161, -161, -161, -161, -161, -161, -161, -161,
- -161, -161, -161, 58, -161, -161, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -161
+ -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
+ -11, -11, -11, -11, -11, -11, -11
},
{
- 11, -162, -162, -162, -162, -162, -162, -162, -162, -162,
- -162, -162, -162, 58, -162, -162, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 181, 58, 58, -162
+ 11, -12, -12, -12, -12, -12, -12, -12, -12, -12,
+ -12, -12, -12, -12, -12, -12, -12
},
{
- 11, -163, -163, -163, -163, -163, -163, -163, -163, -163,
- -163, -163, -163, 58, -163, -163, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -163
+ 11, -13, 39, 40, -13, -13, 41, -13, -13, -13,
+ -13, -13, -13, -13, -13, -13, -13
},
{
- 11, -164, -164, -164, -164, -164, -164, -164, -164, -164,
- -164, -164, -164, 58, -164, -164, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 182,
- 58, 58, 58, 58, 58, 58, 58, -164
+ 11, -14, -14, -14, -14, -14, -14, -14, -14, -14,
+ -14, -14, -14, -14, -14, -14, -14
},
{
- 11, -165, -165, -165, -165, -165, -165, -165, -165, -165,
- -165, -165, -165, 58, -165, -165, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 183, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -165
+ 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42
},
{
- 11, -166, -166, -166, -166, -166, -166, -166, -166, -166,
- -166, -166, -166, 58, -166, -166, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 184, 58, 58, -166
+ 11, -16, -16, -16, -16, -16, -16, -16, -16, -16,
+ -16, -16, -16, -16, -16, -16, -16
},
{
- 11, -167, -167, -167, -167, -167, -167, -167, -167, -167,
- -167, -167, -167, 58, -167, -167, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 185, 58, 58, 58, -167
+ 11, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17
},
{
- 11, -168, -168, -168, -168, -168, -168, -168, -168, -168,
- -168, -168, -168, 58, -168, -168, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -168
+ 11, -18, -18, -18, -18, -18, -18, -18, -18, -18,
+ -18, -18, -18, 44, -18, -18, -18
},
{
- 11, -169, -169, -169, -169, -169, -169, -169, -169, -169,
- -169, -169, -169, 58, -169, -169, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 186, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -169
+ 11, 45, 45, -19, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45
},
{
- 11, -170, -170, -170, -170, -170, -170, -170, -170, -170,
- -170, -170, -170, 58, -170, -170, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 187, 58, -170
+ 11, -20, 46, 47, -20, -20, -20, -20, -20, -20,
+ -20, -20, -20, -20, -20, -20, -20
},
{
- 11, -171, -171, -171, -171, -171, -171, -171, -171, -171,
- -171, -171, -171, 58, -171, -171, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 188, 58,
- 58, 58, 58, 58, 58, 58, 58, -171
+ 11, 48, -21, -21, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48
},
{
- 11, -172, -172, -172, -172, -172, -172, -172, -172, -172,
- -172, -172, -172, 58, -172, -172, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 189, 58,
- 58, 58, 58, 58, 58, 58, 58, -172
+ 11, 49, 49, 50, 49, -22, 49, 49, -22, 49,
+ 49, 49, 49, 49, 49, -22, 49
},
{
- 11, -173, -173, -173, -173, -173, -173, -173, -173, -173,
- -173, -173, -173, 58, -173, -173, 58, 190, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -173
+ 11, -23, -23, -23, -23, -23, -23, -23, -23, -23,
+ -23, -23, -23, -23, -23, -23, -23
},
{
- 11, -174, -174, -174, -174, -174, -174, -174, -174, -174,
- -174, -174, -174, 58, -174, -174, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -174
+ 11, -24, -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, -24
},
{
- 11, -175, -175, -175, -175, -175, -175, -175, -175, -175,
- -175, -175, -175, 58, -175, -175, 58, 58, 58, 58,
- 58, 191, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -175
+ 11, 51, 51, 52, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51
},
{
- 11, -176, -176, -176, -176, -176, -176, -176, -176, -176,
- -176, -176, -176, 58, -176, -176, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -176
+ 11, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+ -26, -26, -26, -26, -26, -26, -26
},
{
- 11, -177, -177, -177, -177, -177, -177, -177, -177, -177,
- -177, -177, -177, 58, -177, -177, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -177
+ 11, -27, -27, -27, -27, -27, -27, -27, -27, -27,
+ -27, -27, -27, -27, -27, -27, -27
},
{
- 11, -178, -178, -178, -178, -178, -178, -178, -178, -178,
- -178, -178, -178, 58, -178, -178, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -178
+ 11, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, -28, -28, -28, 53, -28, -28
},
{
- 11, -179, -179, -179, -179, -179, -179, -179, -179, -179,
- -179, -179, -179, 58, -179, -179, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 192, 58, 58, -179
+ 11, -29, -29, -29, -29, -29, -29, -29, -29, -29,
+ -29, -29, -29, -29, -29, -29, -29
},
{
- 11, -180, -180, -180, -180, -180, -180, -180, -180, -180,
- -180, -180, -180, 58, -180, -180, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -180
+ 11, 54, 54, -30, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54
},
{
- 11, -181, -181, -181, -181, -181, -181, -181, -181, -181,
- -181, -181, -181, 58, -181, -181, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -181
+ 11, -31, -31, -31, -31, -31, -31, 55, -31, -31,
+ -31, -31, -31, -31, -31, -31, -31
},
{
- 11, -182, -182, -182, -182, -182, -182, -182, -182, -182,
- -182, -182, -182, 58, -182, -182, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 193, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -182
+ 11, -32, -32, -32, -32, -32, -32, -32, -32, -32,
+ -32, -32, -32, -32, -32, -32, -32
},
{
- 11, -183, -183, -183, -183, -183, -183, -183, -183, -183,
- -183, -183, -183, 58, -183, -183, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 194, 58, 58, 58, -183
+ 11, -33, -33, -33, -33, -33, -33, -33, -33, -33,
+ -33, -33, -33, -33, -33, -33, -33
},
{
- 11, -184, -184, -184, -184, -184, -184, -184, -184, -184,
- -184, -184, -184, 58, -184, -184, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -184
+ 11, -34, -34, -34, -34, -34, -34, -34, -34, -34,
+ -34, 56, 57, 57, -34, -34, -34
},
{
- 11, -185, -185, -185, -185, -185, -185, -185, -185, -185,
- -185, -185, -185, 58, -185, -185, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -185
+ 11, -35, -35, -35, -35, -35, -35, -35, -35, -35,
+ -35, 57, 57, 57, -35, -35, -35
},
{
- 11, -186, -186, -186, -186, -186, -186, -186, -186, -186,
- -186, -186, -186, 58, -186, -186, 58, 58, 58, 195,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -186
+ 11, -36, -36, -36, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -36, -36, -36, -36
},
{
- 11, -187, -187, -187, -187, -187, -187, -187, -187, -187,
- -187, -187, -187, 58, -187, -187, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -187
+ 11, -37, -37, 58, -37, -37, -37, -37, -37, -37,
+ -37, -37, -37, -37, -37, -37, -37
},
{
- 11, -188, -188, -188, -188, -188, -188, -188, -188, -188,
- -188, -188, -188, 58, -188, -188, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 196, 58, -188
+ 11, -38, -38, -38, -38, -38, -38, -38, -38, -38,
+ -38, -38, -38, -38, -38, -38, 59
},
{
- 11, -189, -189, -189, -189, -189, -189, -189, -189, -189,
- -189, -189, -189, 58, -189, -189, 58, 58, 58, 58,
- 58, 58, 197, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -189
+ 11, -39, 39, 40, -39, -39, 41, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -39
},
{
- 11, -190, -190, -190, -190, -190, -190, -190, -190, -190,
- -190, -190, -190, 58, -190, -190, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 198, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -190
+ 11, -40, -40, -40, -40, -40, -40, -40, -40, -40,
+ -40, -40, -40, -40, -40, -40, -40
},
{
- 11, -191, -191, -191, -191, -191, -191, -191, -191, -191,
- -191, -191, -191, 58, -191, -191, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 199, 58, 58, 58, -191
+ 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42
},
{
- 11, -192, -192, -192, -192, -192, -192, -192, -192, -192,
- -192, -192, -192, 58, -192, -192, 58, 58, 58, 58,
-
- 58, 200, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -192
+ 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42
},
{
- 11, -193, -193, -193, -193, -193, -193, -193, -193, -193,
- -193, -193, -193, 58, -193, -193, 58, 58, 58, 58,
- 58, 201, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -193
+ 11, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43
},
{
- 11, -194, -194, -194, -194, -194, -194, -194, -194, -194,
- -194, -194, -194, 58, -194, -194, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 202, 58, 58, -194
+ 11, -44, -44, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, 44, -44, -44, -44
},
{
- 11, -195, -195, -195, -195, -195, -195, -195, -195, -195,
- -195, -195, -195, 58, -195, -195, 58, 58, 58, 58,
- 58, 203, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -195
+ 11, 45, 45, -45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45
},
{
- 11, -196, -196, -196, -196, -196, -196, -196, -196, -196,
- -196, -196, -196, 58, -196, -196, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -196
+ 11, -46, 46, 47, -46, -46, -46, -46, -46, -46,
+ -46, -46, -46, -46, -46, -46, -46
},
{
- 11, -197, -197, -197, -197, -197, -197, -197, -197, -197,
- -197, -197, -197, 58, -197, -197, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 204, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -197
+ 11, 48, -47, -47, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48
},
{
- 11, -198, -198, -198, -198, -198, -198, -198, -198, -198,
- -198, -198, -198, 58, -198, -198, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -198
+ 11, -48, -48, -48, -48, -48, -48, -48, -48, -48,
+ -48, -48, -48, -48, -48, -48, -48
},
{
- 11, -199, -199, -199, -199, -199, -199, -199, -199, -199,
- -199, -199, -199, 58, -199, -199, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -199
+ 11, 49, 49, 50, 49, -49, 49, 49, -49, 49,
+ 49, 49, 49, 49, 49, -49, 49
},
{
- 11, -200, -200, -200, -200, -200, -200, -200, -200, -200,
- -200, -200, -200, 58, -200, -200, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -200
+ 11, -50, -50, -50, -50, -50, -50, -50, -50, -50,
+ -50, -50, -50, -50, -50, -50, -50
},
{
- 11, -201, -201, -201, -201, -201, -201, -201, -201, -201,
- -201, -201, -201, 58, -201, -201, 58, 205, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -201
+ 11, -51, -51, 52, -51, -51, -51, -51, -51, -51,
+ -51, -51, -51, -51, -51, -51, -51
},
{
- 11, -202, -202, -202, -202, -202, -202, -202, -202, -202,
- -202, -202, -202, 58, -202, -202, 58, 206, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -202
+ 11, -52, -52, -52, -52, -52, -52, -52, -52, -52,
+ -52, -52, -52, -52, -52, -52, -52
},
{
- 11, -203, -203, -203, -203, -203, -203, -203, -203, -203,
- -203, -203, -203, 58, -203, -203, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -203
+ 11, -53, -53, -53, -53, -53, -53, -53, -53, -53,
+ -53, -53, -53, -53, -53, -53, -53
},
{
- 11, -204, -204, -204, -204, -204, -204, -204, -204, -204,
- -204, -204, -204, 58, -204, -204, 58, 58, 58, 58,
- 58, 58, 58, 207, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -204
+ 11, 54, 54, -54, 54, 54, 54, 54, 54, 54,
+ 54, 54, 54, 54, 54, 54, 54
},
{
- 11, -205, -205, -205, -205, -205, -205, -205, -205, -205,
- -205, -205, -205, 58, -205, -205, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 208, 58,
- 58, 58, 58, 58, 58, 58, 58, -205
+ 11, -55, -55, -55, -55, -55, -55, -55, -55, -55,
+ -55, -55, -55, -55, -55, -55, -55
},
{
- 11, -206, -206, -206, -206, -206, -206, -206, -206, -206,
- -206, -206, -206, 58, -206, -206, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 209, 58, 58, -206
+ 11, -56, -56, -56, -56, -56, -56, -56, -56, -56,
+ -56, 60, 57, 57, -56, -56, -56
},
{
- 11, -207, -207, -207, -207, -207, -207, -207, -207, -207,
- -207, -207, -207, 58, -207, -207, 58, 58, 58, 58,
-
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -207
+ 11, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, 57, 57, 57, -57, -57, -57
},
{
- 11, -208, -208, -208, -208, -208, -208, -208, -208, -208,
- -208, -208, -208, 58, -208, -208, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -208
+ 11, -58, -58, -58, -58, -58, -58, -58, -58, -58,
+ -58, -58, -58, -58, -58, -58, -58
},
{
- 11, -209, -209, -209, -209, -209, -209, -209, -209, -209,
- -209, -209, -209, 58, -209, -209, 58, 58, 58, 58,
- 58, 210, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -209
+ 11, -59, -59, -59, -59, -59, -59, -59, -59, -59,
+ -59, -59, -59, -59, -59, -59, -59
},
{
- 11, -210, -210, -210, -210, -210, -210, -210, -210, -210,
- -210, -210, -210, 58, -210, -210, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, -210
+ 11, -60, -60, -60, -60, -60, -60, -60, -60, -60,
+ -60, 57, 57, 57, -60, -60, -60
},
} ;
*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
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[211] =
+static yyconst flex_int16_t yy_accept[61] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 65, 5, 4, 3, 2, 36, 37, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 63, 60, 62, 55, 59, 58, 57, 53, 48, 42,
- 47, 51, 53, 40, 41, 50, 50, 43, 53, 50,
- 50, 53, 4, 3, 2, 2, 1, 35, 35, 35,
- 35, 35, 35, 35, 16, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 63, 60, 62, 61,
- 55, 54, 57, 56, 44, 51, 38, 50, 50, 52,
- 45, 46, 39, 35, 35, 35, 35, 35, 35, 35,
-
- 35, 35, 30, 29, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 49, 25, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 15, 35, 7, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 17, 35, 35,
- 35, 35, 35, 34, 35, 35, 35, 35, 35, 35,
- 10, 35, 13, 35, 35, 35, 35, 33, 35, 35,
- 35, 35, 35, 22, 35, 32, 9, 31, 35, 26,
- 12, 35, 35, 21, 18, 35, 8, 35, 35, 35,
- 35, 35, 27, 35, 35, 6, 35, 20, 19, 23,
-
- 35, 35, 11, 35, 35, 35, 14, 28, 35, 24
+ 34, 5, 4, 2, 3, 7, 8, 6, 32, 29,
+ 31, 24, 28, 27, 26, 22, 17, 13, 16, 20,
+ 22, 11, 12, 19, 19, 14, 22, 22, 4, 2,
+ 3, 3, 1, 6, 32, 29, 31, 30, 24, 23,
+ 26, 25, 15, 20, 9, 19, 19, 21, 10, 18
} ;
static yyconst flex_int32_t yy_ec[256] =
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,
#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 last_ts, first_ts;
static void zconf_endhelp(void);
-static struct buffer *zconf_endfile(void);
+static void zconf_endfile(void);
void new_string(void)
{
text = malloc(START_STRSIZE);
text_asize = START_STRSIZE;
- text_ptr = text;
text_size = 0;
- *text_ptr = 0;
+ *text = 0;
}
void append_string(const char *str, int size)
{
int new_size = text_size + size + 1;
if (new_size > text_asize) {
+ new_size += START_STRSIZE - 1;
+ new_size &= -START_STRSIZE;
text = realloc(text, new_size);
text_asize = new_size;
- text_ptr = text + text_size;
}
- memcpy(text_ptr, str, size);
- text_ptr += size;
+ memcpy(text + text_size, str, size);
text_size += size;
- *text_ptr = 0;
+ text[text_size] = 0;
}
void alloc_string(const char *str, int size)
#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>
+#endif
#ifndef YY_EXTRA_TYPE
#define YY_EXTRA_TYPE void *
{ /* beginning of action switch */
case 1:
/* rule 1 can match eol */
-YY_RULE_SETUP
-current_file->lineno++;
- YY_BREAK
case 2:
+/* rule 2 can match eol */
YY_RULE_SETUP
-
+{
+ current_file->lineno++;
+ return T_EOL;
+}
YY_BREAK
case 3:
-/* rule 3 can match eol */
YY_RULE_SETUP
-current_file->lineno++; return T_EOL;
+
YY_BREAK
case 4:
YY_RULE_SETUP
case 6:
YY_RULE_SETUP
-BEGIN(PARAM); return T_MAINMENU;
- YY_BREAK
-case 7:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_MENU;
- YY_BREAK
-case 8:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_ENDMENU;
- YY_BREAK
-case 9:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_SOURCE;
- YY_BREAK
-case 10:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_CHOICE;
- YY_BREAK
-case 11:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_ENDCHOICE;
- YY_BREAK
-case 12:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_COMMENT;
- YY_BREAK
-case 13:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_CONFIG;
- YY_BREAK
-case 14:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_MENUCONFIG;
- YY_BREAK
-case 15:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_HELP;
- YY_BREAK
-case 16:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_IF;
- YY_BREAK
-case 17:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_ENDIF;
- YY_BREAK
-case 18:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_DEPENDS;
- YY_BREAK
-case 19:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_REQUIRES;
- YY_BREAK
-case 20:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_OPTIONAL;
- YY_BREAK
-case 21:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_DEFAULT;
- YY_BREAK
-case 22:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_PROMPT;
- YY_BREAK
-case 23:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_TRISTATE;
- YY_BREAK
-case 24:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_DEF_TRISTATE;
- YY_BREAK
-case 25:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_BOOLEAN;
- YY_BREAK
-case 26:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_BOOLEAN;
- YY_BREAK
-case 27:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_DEF_BOOLEAN;
- YY_BREAK
-case 28:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_DEF_BOOLEAN;
- YY_BREAK
-case 29:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_INT;
- YY_BREAK
-case 30:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_HEX;
- YY_BREAK
-case 31:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_STRING;
- YY_BREAK
-case 32:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_SELECT;
- YY_BREAK
-case 33:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_SELECT;
- YY_BREAK
-case 34:
-YY_RULE_SETUP
-BEGIN(PARAM); return T_RANGE;
- YY_BREAK
-case 35:
-YY_RULE_SETUP
{
+ struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
+ BEGIN(PARAM);
+ current_pos.file = current_file;
+ current_pos.lineno = current_file->lineno;
+ if (id && id->flags & TF_COMMAND) {
+ zconflval.id = id;
+ return id->token;
+ }
alloc_string(zconftext, zconfleng);
zconflval.string = text;
return T_WORD;
}
YY_BREAK
-case 36:
+case 7:
YY_RULE_SETUP
YY_BREAK
-case 37:
-/* rule 37 can match eol */
+case 8:
+/* rule 8 can match eol */
YY_RULE_SETUP
-current_file->lineno++; BEGIN(INITIAL);
+{
+ BEGIN(INITIAL);
+ current_file->lineno++;
+ return T_EOL;
+ }
YY_BREAK
-case 38:
+case 9:
YY_RULE_SETUP
return T_AND;
YY_BREAK
-case 39:
+case 10:
YY_RULE_SETUP
return T_OR;
YY_BREAK
-case 40:
+case 11:
YY_RULE_SETUP
return T_OPEN_PAREN;
YY_BREAK
-case 41:
+case 12:
YY_RULE_SETUP
return T_CLOSE_PAREN;
YY_BREAK
-case 42:
+case 13:
YY_RULE_SETUP
return T_NOT;
YY_BREAK
-case 43:
+case 14:
YY_RULE_SETUP
return T_EQUAL;
YY_BREAK
-case 44:
+case 15:
YY_RULE_SETUP
return T_UNEQUAL;
YY_BREAK
-case 45:
-YY_RULE_SETUP
-return T_IF;
- YY_BREAK
-case 46:
-YY_RULE_SETUP
-return T_ON;
- YY_BREAK
-case 47:
+case 16:
YY_RULE_SETUP
{
str = zconftext[0];
BEGIN(STRING);
}
YY_BREAK
-case 48:
-/* rule 48 can match eol */
+case 17:
+/* rule 17 can match eol */
YY_RULE_SETUP
BEGIN(INITIAL); current_file->lineno++; return T_EOL;
YY_BREAK
-case 49:
+case 18:
YY_RULE_SETUP
/* ignore */
YY_BREAK
-case 50:
+case 19:
YY_RULE_SETUP
{
+ struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
+ if (id && id->flags & TF_PARAM) {
+ zconflval.id = id;
+ return id->token;
+ }
alloc_string(zconftext, zconfleng);
zconflval.string = text;
return T_WORD;
}
YY_BREAK
-case 51:
+case 20:
YY_RULE_SETUP
/* comment */
YY_BREAK
-case 52:
-/* rule 52 can match eol */
+case 21:
+/* rule 21 can match eol */
YY_RULE_SETUP
current_file->lineno++;
YY_BREAK
-case 53:
+case 22:
YY_RULE_SETUP
YY_BREAK
}
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 */
return T_WORD_QUOTE;
}
YY_BREAK
-case 55:
+case 24:
YY_RULE_SETUP
{
append_string(zconftext, zconfleng);
}
YY_BREAK
-case 56:
-/* rule 56 can match eol */
+case 25:
+/* rule 25 can match eol */
*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
(yy_c_buf_p) = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up zconftext again */
return T_WORD_QUOTE;
}
YY_BREAK
-case 57:
+case 26:
YY_RULE_SETUP
{
append_string(zconftext + 1, zconfleng - 1);
}
YY_BREAK
-case 58:
+case 27:
YY_RULE_SETUP
{
if (str == zconftext[0]) {
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_BREAK
-case 60:
+case 29:
YY_RULE_SETUP
{
ts = 0;
}
}
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 */
return T_HELPTEXT;
}
YY_BREAK
-case 62:
-/* rule 62 can match eol */
+case 31:
+/* rule 31 can match eol */
YY_RULE_SETUP
{
current_file->lineno++;
append_string("\n", 1);
}
YY_BREAK
-case 63:
+case 32:
YY_RULE_SETUP
{
append_string(zconftext, zconfleng);
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(COMMAND):
{
- if (current_buf) {
+ if (current_file) {
zconf_endfile();
- return T_EOF;
+ return T_EOL;
}
fclose(zconfin);
yyterminate();
}
YY_BREAK
-case 64:
+case 33:
YY_RULE_SETUP
YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK
/** Setup the input buffer state to scan a string. The next call to zconflex() will
* scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
+ * @param yy_str a NUL-terminated string to scan
*
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
* zconf_scan_bytes() instead.
*/
-YY_BUFFER_STATE zconf_scan_string (yyconst char * str )
+YY_BUFFER_STATE zconf_scan_string (yyconst char * yy_str )
{
- return zconf_scan_bytes(str,strlen(str) );
+ return zconf_scan_bytes(yy_str,strlen(yy_str) );
}
/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
current_file = file;
}
-static struct buffer *zconf_endfile(void)
+static void zconf_endfile(void)
{
struct buffer *parent;
}
free(current_buf);
current_buf = parent;
-
- return parent;
}
int zconf_lineno(void)
{
- if (current_buf)
- return current_file->lineno - 1;
- else
- return 0;
+ return current_pos.lineno;
}
char *zconf_curname(void)
{
- if (current_buf)
- return current_file->name;
- else
- return "<none>";
+ return current_pos.file ? current_pos.file->name : "<none>";
}
-/* A Bison parser, made by GNU Bison 1.875a. */
+/* A Bison parser, made by GNU Bison 2.0. */
/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/* 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
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
#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>
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+#include "zconf.hash.c"
+
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
#define PRINTD 0x0001
extern int zconflex(void);
static void zconfprint(const char *err, ...);
+static void zconf_error(const char *err, ...);
static void zconferror(const char *err);
-static bool zconf_endtoken(int token, int starttoken, int endtoken);
+static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
struct symbol *symbol_hash[257];
+static struct menu *current_menu, *current_entry;
+
+#define YYDEBUG 0
+#if YYDEBUG
#define YYERROR_VERBOSE
+#endif
/* Enabling traces. */
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
typedef union YYSTYPE {
- int token;
char *string;
+ struct file *file;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
+ struct kconf_id *id;
} YYSTYPE;
-/* Line 191 of yacc.c. */
+/* Line 190 of yacc.c. */
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
/* Copy the second part of user declarations. */
-#define LKC_DIRECT_LINK
-#include "lkc.h"
-
-
-/* Line 214 of yacc.c. */
+/* Line 213 of yacc.c. */
#if ! defined (yyoverflow) || YYERROR_VERBOSE
+# ifndef YYFREE
+# define YYFREE free
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# endif
+
/* The parser invokes alloca or malloc; define the necessary symbols. */
-# if YYSTACK_USE_ALLOCA
-# define YYSTACK_ALLOC alloca
-# else
-# ifndef YYSTACK_USE_ALLOCA
-# if defined (alloca) || defined (_ALLOCA_H)
-# define YYSTACK_ALLOC alloca
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
# else
-# ifdef __GNUC__
-# define YYSTACK_ALLOC __builtin_alloca
-# endif
+# define YYSTACK_ALLOC alloca
# endif
# endif
# endif
# 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) \
- || (YYSTYPE_IS_TRIVIAL)))
+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- short yyss;
+ short int yyss;
YYSTYPE yyvs;
};
/* The size of an array large to enough to hold all stacks, each with
N elements. */
# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
-# if 1 < __GNUC__
+# if defined (__GNUC__) && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
#if defined (__STDC__) || defined (__cplusplus)
typedef signed char yysigned_char;
#else
- typedef short yysigned_char;
+ typedef short int yysigned_char;
#endif
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 2
+#define YYFINAL 3
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 201
+#define YYLAST 264
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 42
+#define YYNTOKENS 35
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 41
+#define YYNNTS 42
/* YYNRULES -- Number of rules. */
#define YYNRULES 104
/* YYNRULES -- Number of states. */
-#define YYNSTATES 182
+#define YYNSTATES 175
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 296
+#define YYMAXUTOK 289
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 41
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34
};
#if YYDEBUG
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */
-static const unsigned short yyprhs[] =
+static const unsigned short int yyprhs[] =
{
- 0, 0, 3, 4, 7, 9, 11, 13, 17, 19,
- 21, 23, 26, 28, 30, 32, 34, 36, 38, 42,
- 45, 49, 52, 53, 56, 59, 62, 65, 69, 74,
- 78, 83, 87, 91, 95, 100, 105, 110, 116, 119,
- 122, 124, 128, 131, 132, 135, 138, 141, 144, 149,
- 153, 157, 160, 165, 166, 169, 173, 175, 179, 182,
- 183, 186, 189, 192, 196, 199, 201, 205, 208, 209,
- 212, 215, 218, 222, 226, 228, 232, 235, 238, 241,
- 242, 245, 248, 253, 257, 261, 262, 265, 267, 269,
- 272, 275, 278, 280, 282, 283, 286, 288, 292, 296,
- 300, 303, 307, 311, 313
+ 0, 0, 3, 5, 6, 9, 12, 15, 20, 23,
+ 28, 33, 37, 39, 41, 43, 45, 47, 49, 51,
+ 53, 55, 57, 59, 61, 63, 67, 70, 74, 77,
+ 81, 84, 85, 88, 91, 94, 97, 100, 104, 109,
+ 114, 119, 125, 128, 131, 133, 137, 138, 141, 144,
+ 147, 150, 153, 158, 162, 165, 170, 171, 174, 178,
+ 180, 184, 185, 188, 191, 194, 198, 201, 203, 207,
+ 208, 211, 214, 217, 221, 225, 228, 231, 234, 235,
+ 238, 241, 244, 249, 253, 257, 258, 261, 263, 265,
+ 268, 271, 274, 276, 279, 280, 283, 285, 289, 293,
+ 297, 300, 304, 308, 310
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yysigned_char yyrhs[] =
{
- 43, 0, -1, -1, 43, 44, -1, 45, -1, 55,
- -1, 66, -1, 3, 77, 79, -1, 5, -1, 15,
- -1, 8, -1, 1, 79, -1, 61, -1, 71, -1,
- 47, -1, 49, -1, 69, -1, 79, -1, 10, 28,
- 32, -1, 46, 50, -1, 11, 28, 32, -1, 48,
- 50, -1, -1, 50, 51, -1, 50, 75, -1, 50,
- 73, -1, 50, 32, -1, 21, 76, 32, -1, 22,
- 81, 80, 32, -1, 23, 76, 32, -1, 24, 81,
- 80, 32, -1, 26, 76, 32, -1, 27, 76, 32,
- -1, 25, 76, 32, -1, 19, 77, 80, 32, -1,
- 20, 81, 80, 32, -1, 36, 28, 80, 32, -1,
- 37, 82, 82, 80, 32, -1, 7, 32, -1, 52,
- 56, -1, 78, -1, 53, 58, 54, -1, 53, 58,
- -1, -1, 56, 57, -1, 56, 75, -1, 56, 73,
- -1, 56, 32, -1, 19, 77, 80, 32, -1, 21,
- 76, 32, -1, 23, 76, 32, -1, 18, 32, -1,
- 20, 28, 80, 32, -1, -1, 58, 45, -1, 14,
- 81, 32, -1, 78, -1, 59, 62, 60, -1, 59,
- 62, -1, -1, 62, 45, -1, 62, 66, -1, 62,
- 55, -1, 4, 77, 32, -1, 63, 74, -1, 78,
- -1, 64, 67, 65, -1, 64, 67, -1, -1, 67,
- 45, -1, 67, 66, -1, 67, 55, -1, 67, 1,
- 32, -1, 6, 77, 32, -1, 68, -1, 9, 77,
- 32, -1, 70, 74, -1, 12, 32, -1, 72, 13,
- -1, -1, 74, 75, -1, 74, 32, -1, 16, 35,
- 81, 32, -1, 16, 81, 32, -1, 17, 81, 32,
- -1, -1, 77, 80, -1, 28, -1, 29, -1, 5,
- 79, -1, 8, 79, -1, 15, 79, -1, 32, -1,
- 31, -1, -1, 14, 81, -1, 82, -1, 82, 40,
- 82, -1, 82, 30, 82, -1, 34, 81, 33, -1,
- 41, 81, -1, 81, 38, 81, -1, 81, 39, 81,
- -1, 28, -1, 29, -1
+ 36, 0, -1, 37, -1, -1, 37, 39, -1, 37,
+ 50, -1, 37, 61, -1, 37, 3, 71, 73, -1,
+ 37, 72, -1, 37, 25, 1, 30, -1, 37, 38,
+ 1, 30, -1, 37, 1, 30, -1, 16, -1, 19,
+ -1, 20, -1, 22, -1, 18, -1, 23, -1, 21,
+ -1, 30, -1, 56, -1, 65, -1, 42, -1, 44,
+ -1, 63, -1, 25, 1, 30, -1, 1, 30, -1,
+ 10, 25, 30, -1, 41, 45, -1, 11, 25, 30,
+ -1, 43, 45, -1, -1, 45, 46, -1, 45, 69,
+ -1, 45, 67, -1, 45, 40, -1, 45, 30, -1,
+ 20, 70, 30, -1, 19, 71, 74, 30, -1, 21,
+ 75, 74, 30, -1, 22, 25, 74, 30, -1, 23,
+ 76, 76, 74, 30, -1, 7, 30, -1, 47, 51,
+ -1, 72, -1, 48, 53, 49, -1, -1, 51, 52,
+ -1, 51, 69, -1, 51, 67, -1, 51, 30, -1,
+ 51, 40, -1, 19, 71, 74, 30, -1, 20, 70,
+ 30, -1, 18, 30, -1, 21, 25, 74, 30, -1,
+ -1, 53, 39, -1, 14, 75, 73, -1, 72, -1,
+ 54, 57, 55, -1, -1, 57, 39, -1, 57, 61,
+ -1, 57, 50, -1, 4, 71, 30, -1, 58, 68,
+ -1, 72, -1, 59, 62, 60, -1, -1, 62, 39,
+ -1, 62, 61, -1, 62, 50, -1, 6, 71, 30,
+ -1, 9, 71, 30, -1, 64, 68, -1, 12, 30,
+ -1, 66, 13, -1, -1, 68, 69, -1, 68, 30,
+ -1, 68, 40, -1, 16, 24, 75, 30, -1, 16,
+ 75, 30, -1, 17, 75, 30, -1, -1, 71, 74,
+ -1, 25, -1, 26, -1, 5, 30, -1, 8, 30,
+ -1, 15, 30, -1, 30, -1, 73, 30, -1, -1,
+ 14, 75, -1, 76, -1, 76, 33, 76, -1, 76,
+ 27, 76, -1, 29, 75, 28, -1, 34, 75, -1,
+ 75, 31, 75, -1, 75, 32, 75, -1, 25, -1,
+ 26, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const unsigned short yyrline[] =
+static const unsigned short int yyrline[] =
{
- 0, 94, 94, 95, 98, 99, 100, 101, 102, 103,
- 104, 105, 109, 110, 111, 112, 113, 114, 120, 128,
- 134, 142, 152, 154, 155, 156, 157, 160, 166, 173,
- 179, 186, 192, 198, 204, 210, 216, 222, 230, 239,
- 245, 254, 255, 261, 263, 264, 265, 266, 269, 275,
- 281, 287, 293, 299, 301, 306, 315, 324, 325, 331,
- 333, 334, 335, 340, 347, 353, 362, 363, 369, 371,
- 372, 373, 374, 377, 383, 390, 397, 404, 410, 417,
- 418, 419, 422, 427, 432, 440, 442, 447, 448, 451,
- 452, 453, 457, 457, 459, 460, 463, 464, 465, 466,
- 467, 468, 469, 472, 473
+ 0, 103, 103, 105, 107, 108, 109, 110, 111, 112,
+ 113, 117, 121, 121, 121, 121, 121, 121, 121, 125,
+ 126, 127, 128, 129, 130, 134, 135, 141, 149, 155,
+ 163, 173, 175, 176, 177, 178, 179, 182, 190, 196,
+ 206, 212, 220, 229, 234, 242, 245, 247, 248, 249,
+ 250, 251, 254, 260, 271, 277, 287, 289, 294, 302,
+ 310, 313, 315, 316, 317, 322, 329, 334, 342, 345,
+ 347, 348, 349, 352, 360, 367, 374, 380, 387, 389,
+ 390, 391, 394, 399, 404, 412, 414, 419, 420, 423,
+ 424, 425, 429, 430, 433, 434, 437, 438, 439, 440,
+ 441, 442, 443, 446, 447
};
#endif
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
- "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
- "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
- "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
- "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_DEFAULT", "T_TRISTATE",
- "T_DEF_TRISTATE", "T_BOOLEAN", "T_DEF_BOOLEAN", "T_STRING", "T_INT",
- "T_HEX", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", "T_EOF", "T_EOL",
- "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_ON", "T_SELECT", "T_RANGE", "T_OR",
- "T_AND", "T_EQUAL", "T_NOT", "$accept", "input", "block",
- "common_block", "config_entry_start", "config_stmt",
- "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
- "config_option", "choice", "choice_entry", "choice_end", "choice_stmt",
- "choice_option_list", "choice_option", "choice_block", "if", "if_end",
- "if_stmt", "if_block", "menu", "menu_entry", "menu_end", "menu_stmt",
- "menu_block", "source", "source_stmt", "comment", "comment_stmt",
- "help_start", "help", "depends_list", "depends", "prompt_stmt_opt",
- "prompt", "end", "nl_or_eof", "if_expr", "expr", "symbol", 0
+ "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
+ "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
+ "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
+ "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT",
+ "T_SELECT", "T_RANGE", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
+ "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL",
+ "T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt",
+ "option_error", "config_entry_start", "config_stmt",
+ "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
+ "config_option", "choice", "choice_entry", "choice_end", "choice_stmt",
+ "choice_option_list", "choice_option", "choice_block", "if_entry",
+ "if_end", "if_stmt", "if_block", "menu", "menu_entry", "menu_end",
+ "menu_stmt", "menu_block", "source_stmt", "comment", "comment_stmt",
+ "help_start", "help", "depends_list", "depends", "prompt_stmt_opt",
+ "prompt", "end", "nl", "if_expr", "expr", "symbol", 0
};
#endif
# ifdef YYPRINT
/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
token YYLEX-NUM. */
-static const unsigned short yytoknum[] =
+static const unsigned short int yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
- 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
- 295, 296
+ 285, 286, 287, 288, 289
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const unsigned char yyr1[] =
{
- 0, 42, 43, 43, 44, 44, 44, 44, 44, 44,
- 44, 44, 45, 45, 45, 45, 45, 45, 46, 47,
- 48, 49, 50, 50, 50, 50, 50, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 51, 52, 53,
- 54, 55, 55, 56, 56, 56, 56, 56, 57, 57,
- 57, 57, 57, 58, 58, 59, 60, 61, 61, 62,
- 62, 62, 62, 63, 64, 65, 66, 66, 67, 67,
- 67, 67, 67, 68, 69, 70, 71, 72, 73, 74,
- 74, 74, 75, 75, 75, 76, 76, 77, 77, 78,
- 78, 78, 79, 79, 80, 80, 81, 81, 81, 81,
- 81, 81, 81, 82, 82
+ 0, 35, 36, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 38, 38, 38, 38, 38, 38, 38, 39,
+ 39, 39, 39, 39, 39, 40, 40, 41, 42, 43,
+ 44, 45, 45, 45, 45, 45, 45, 46, 46, 46,
+ 46, 46, 47, 48, 49, 50, 51, 51, 51, 51,
+ 51, 51, 52, 52, 52, 52, 53, 53, 54, 55,
+ 56, 57, 57, 57, 57, 58, 59, 60, 61, 62,
+ 62, 62, 62, 63, 64, 65, 66, 67, 68, 68,
+ 68, 68, 69, 69, 69, 70, 70, 71, 71, 72,
+ 72, 72, 73, 73, 74, 74, 75, 75, 75, 75,
+ 75, 75, 75, 76, 76
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const unsigned char yyr2[] =
{
- 0, 2, 0, 2, 1, 1, 1, 3, 1, 1,
- 1, 2, 1, 1, 1, 1, 1, 1, 3, 2,
- 3, 2, 0, 2, 2, 2, 2, 3, 4, 3,
- 4, 3, 3, 3, 4, 4, 4, 5, 2, 2,
- 1, 3, 2, 0, 2, 2, 2, 2, 4, 3,
- 3, 2, 4, 0, 2, 3, 1, 3, 2, 0,
- 2, 2, 2, 3, 2, 1, 3, 2, 0, 2,
- 2, 2, 3, 3, 1, 3, 2, 2, 2, 0,
+ 0, 2, 1, 0, 2, 2, 2, 4, 2, 4,
+ 4, 3, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 3, 2, 3, 2, 3,
+ 2, 0, 2, 2, 2, 2, 2, 3, 4, 4,
+ 4, 5, 2, 2, 1, 3, 0, 2, 2, 2,
+ 2, 2, 4, 3, 2, 4, 0, 2, 3, 1,
+ 3, 0, 2, 2, 2, 3, 2, 1, 3, 0,
+ 2, 2, 2, 3, 3, 2, 2, 2, 0, 2,
2, 2, 4, 3, 3, 0, 2, 1, 1, 2,
- 2, 2, 1, 1, 0, 2, 1, 3, 3, 3,
+ 2, 2, 1, 2, 0, 2, 1, 3, 3, 3,
2, 3, 3, 1, 1
};
means the default is an error. */
static const unsigned char yydefact[] =
{
- 2, 0, 1, 0, 0, 0, 8, 0, 0, 10,
- 0, 0, 0, 0, 9, 93, 92, 3, 4, 22,
- 14, 22, 15, 43, 53, 5, 59, 12, 79, 68,
- 6, 74, 16, 79, 13, 17, 11, 87, 88, 0,
- 0, 0, 38, 0, 0, 0, 103, 104, 0, 0,
- 0, 96, 19, 21, 39, 42, 58, 64, 0, 76,
- 7, 63, 73, 75, 18, 20, 0, 100, 55, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 85, 0,
- 85, 0, 85, 85, 85, 26, 0, 0, 23, 0,
- 25, 24, 0, 0, 0, 85, 85, 47, 44, 46,
- 45, 0, 0, 0, 54, 41, 40, 60, 62, 57,
- 61, 56, 81, 80, 0, 69, 71, 66, 70, 65,
- 99, 101, 102, 98, 97, 77, 0, 0, 0, 94,
- 94, 0, 94, 94, 0, 94, 0, 0, 0, 94,
- 0, 78, 51, 94, 94, 0, 0, 89, 90, 91,
- 72, 0, 83, 84, 0, 0, 0, 27, 86, 0,
- 29, 0, 33, 31, 32, 0, 94, 0, 0, 49,
- 50, 82, 95, 34, 35, 28, 30, 36, 0, 48,
- 52, 37
+ 3, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 12, 16, 13, 14,
+ 18, 15, 17, 0, 19, 0, 4, 31, 22, 31,
+ 23, 46, 56, 5, 61, 20, 78, 69, 6, 24,
+ 78, 21, 8, 11, 87, 88, 0, 0, 89, 0,
+ 42, 90, 0, 0, 0, 103, 104, 0, 0, 0,
+ 96, 91, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 92, 7, 65, 73, 74, 27, 29, 0,
+ 100, 0, 0, 58, 0, 0, 9, 10, 0, 0,
+ 0, 0, 0, 85, 0, 0, 0, 0, 36, 35,
+ 32, 0, 34, 33, 0, 0, 85, 0, 50, 51,
+ 47, 49, 48, 57, 45, 44, 62, 64, 60, 63,
+ 59, 80, 81, 79, 70, 72, 68, 71, 67, 93,
+ 99, 101, 102, 98, 97, 26, 76, 0, 0, 0,
+ 94, 0, 94, 94, 94, 0, 0, 77, 54, 94,
+ 0, 94, 0, 83, 84, 0, 0, 37, 86, 0,
+ 0, 94, 25, 0, 53, 0, 82, 95, 38, 39,
+ 40, 0, 52, 55, 41
};
/* YYDEFGOTO[NTERM-NUM]. */
-static const short yydefgoto[] =
+static const short int yydefgoto[] =
{
- -1, 1, 17, 18, 19, 20, 21, 22, 52, 88,
- 23, 24, 105, 25, 54, 98, 55, 26, 109, 27,
- 56, 28, 29, 117, 30, 58, 31, 32, 33, 34,
- 89, 90, 57, 91, 131, 132, 106, 35, 155, 50,
- 51
+ -1, 1, 2, 25, 26, 99, 27, 28, 29, 30,
+ 64, 100, 31, 32, 114, 33, 66, 110, 67, 34,
+ 118, 35, 68, 36, 37, 126, 38, 70, 39, 40,
+ 41, 101, 102, 69, 103, 141, 142, 42, 73, 156,
+ 59, 60
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -99
-static const short yypact[] =
+#define YYPACT_NINF -78
+static const short int yypact[] =
{
- -99, 48, -99, 38, 46, 46, -99, 46, -29, -99,
- 46, -17, -3, -11, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, -99, -99, -99, -99, -99, 38,
- 12, 15, -99, 18, 51, 62, -99, -99, -11, -11,
- 4, -24, 138, 138, 160, 121, 110, -4, 81, -4,
- -99, -99, -99, -99, -99, -99, -19, -99, -99, -11,
- -11, 70, 70, 73, 32, -11, 46, -11, 46, -11,
- 46, -11, 46, 46, 46, -99, 36, 70, -99, 95,
- -99, -99, 96, 46, 106, 46, 46, -99, -99, -99,
- -99, 38, 38, 38, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, 112, -99, -99, -99, -99, -99,
- -99, 117, -99, -99, -99, -99, -11, 33, 65, 131,
- 1, 119, 131, 1, 136, 1, 153, 154, 155, 131,
- 70, -99, -99, 131, 131, 156, 157, -99, -99, -99,
- -99, 101, -99, -99, -11, 158, 159, -99, -99, 161,
- -99, 162, -99, -99, -99, 163, 131, 164, 165, -99,
- -99, -99, 99, -99, -99, -99, -99, -99, 166, -99,
- -99, -99
+ -78, 2, 159, -78, -21, 0, 0, -12, 0, 1,
+ 4, 0, 27, 38, 60, 58, -78, -78, -78, -78,
+ -78, -78, -78, 100, -78, 104, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, 86, 113, -78, 114,
+ -78, -78, 125, 127, 128, -78, -78, 60, 60, 210,
+ 65, -78, 141, 142, 39, 103, 182, 200, 6, 66,
+ 6, 131, -78, 146, -78, -78, -78, -78, -78, 196,
+ -78, 60, 60, 146, 40, 40, -78, -78, 155, 156,
+ -2, 60, 0, 0, 60, 105, 40, 194, -78, -78,
+ -78, 206, -78, -78, 183, 0, 0, 195, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, 197, -78, -78, -78, -78, -78, 60, 213, 216,
+ 212, 203, 212, 190, 212, 40, 208, -78, -78, 212,
+ 222, 212, 219, -78, -78, 60, 223, -78, -78, 224,
+ 225, 212, -78, 226, -78, 227, -78, 47, -78, -78,
+ -78, 228, -78, -78, -78
};
/* YYPGOTO[NTERM-NUM]. */
-static const short yypgoto[] =
+static const short int yypgoto[] =
{
- -99, -99, -99, 111, -99, -99, -99, -99, 178, -99,
- -99, -99, -99, 91, -99, -99, -99, -99, -99, -99,
- -99, -99, -99, -99, 115, -99, -99, -99, -99, -99,
- -99, 146, 168, 89, 27, 0, 126, -1, -98, -48,
- -63
+ -78, -78, -78, -78, 164, -36, -78, -78, -78, -78,
+ 230, -78, -78, -78, -78, 29, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, 59, -78, -78, -78,
+ -78, -78, 198, 220, 24, 157, -5, 169, 202, 74,
+ -53, -77
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -68
-static const short yytable[] =
+#define YYTABLE_NINF -76
+static const short int yytable[] =
{
- 66, 67, 36, 42, 39, 40, 71, 41, 123, 124,
- 43, 44, 74, 75, 120, 154, 72, 46, 47, 69,
- 70, 121, 122, 48, 140, 45, 127, 128, 112, 130,
- 49, 133, 156, 135, 158, 159, 68, 161, 60, 69,
- 70, 165, 69, 70, 61, 167, 168, 62, 2, 3,
- 63, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 46, 47, 13, 14, 139, 152, 48, 126, 178, 15,
- 16, 69, 70, 49, 37, 38, 129, 166, 151, 15,
- 16, -67, 114, 64, -67, 5, 101, 7, 8, 102,
- 10, 11, 12, 143, 65, 13, 103, 153, 46, 47,
- 147, 148, 149, 69, 70, 125, 172, 134, 141, 136,
- 137, 138, 15, 16, 5, 101, 7, 8, 102, 10,
- 11, 12, 145, 146, 13, 103, 101, 7, 142, 102,
- 10, 11, 12, 171, 144, 13, 103, 69, 70, 69,
- 70, 15, 16, 100, 150, 154, 113, 108, 113, 116,
- 73, 157, 15, 16, 74, 75, 70, 76, 77, 78,
- 79, 80, 81, 82, 83, 84, 104, 107, 160, 115,
- 85, 110, 73, 118, 86, 87, 74, 75, 92, 93,
- 94, 95, 111, 96, 119, 162, 163, 164, 169, 170,
- 173, 174, 97, 175, 176, 177, 179, 180, 181, 53,
- 99, 59
+ 46, 47, 3, 49, 79, 80, 52, 133, 134, 43,
+ 6, 7, 8, 9, 10, 11, 12, 13, 48, 145,
+ 14, 15, 137, 55, 56, 44, 45, 57, 131, 132,
+ 109, 50, 58, 122, 51, 122, 24, 138, 139, -28,
+ 88, 143, -28, -28, -28, -28, -28, -28, -28, -28,
+ -28, 89, 53, -28, -28, 90, 91, -28, 92, 93,
+ 94, 95, 96, 54, 97, 55, 56, 88, 161, 98,
+ -66, -66, -66, -66, -66, -66, -66, -66, 81, 82,
+ -66, -66, 90, 91, 152, 55, 56, 140, 61, 57,
+ 112, 97, 84, 123, 58, 123, 121, 117, 85, 125,
+ 149, 62, 167, -30, 88, 63, -30, -30, -30, -30,
+ -30, -30, -30, -30, -30, 89, 72, -30, -30, 90,
+ 91, -30, 92, 93, 94, 95, 96, 119, 97, 127,
+ 144, -75, 88, 98, -75, -75, -75, -75, -75, -75,
+ -75, -75, -75, 74, 75, -75, -75, 90, 91, -75,
+ -75, -75, -75, -75, -75, 76, 97, 77, 78, -2,
+ 4, 121, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 86, 87, 14, 15, 16, 129, 17, 18, 19,
+ 20, 21, 22, 88, 23, 135, 136, -43, -43, 24,
+ -43, -43, -43, -43, 89, 146, -43, -43, 90, 91,
+ 104, 105, 106, 107, 155, 7, 8, 97, 10, 11,
+ 12, 13, 108, 148, 14, 15, 158, 159, 160, 147,
+ 151, 81, 82, 163, 130, 165, 155, 81, 82, 82,
+ 24, 113, 116, 157, 124, 171, 115, 120, 162, 128,
+ 72, 81, 82, 153, 81, 82, 154, 81, 82, 166,
+ 81, 82, 164, 168, 169, 170, 172, 173, 174, 65,
+ 71, 83, 0, 150, 111
};
-static const unsigned char yycheck[] =
+static const short int yycheck[] =
{
- 48, 49, 3, 32, 4, 5, 30, 7, 71, 72,
- 10, 28, 16, 17, 33, 14, 40, 28, 29, 38,
- 39, 69, 70, 34, 87, 28, 74, 75, 32, 77,
- 41, 79, 130, 81, 132, 133, 32, 135, 39, 38,
- 39, 139, 38, 39, 32, 143, 144, 32, 0, 1,
- 32, 3, 4, 5, 6, 7, 8, 9, 10, 11,
- 28, 29, 14, 15, 28, 32, 34, 35, 166, 31,
- 32, 38, 39, 41, 28, 29, 76, 140, 126, 31,
- 32, 0, 1, 32, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 93, 32, 14, 15, 32, 28, 29,
- 101, 102, 103, 38, 39, 32, 154, 80, 13, 82,
- 83, 84, 31, 32, 4, 5, 6, 7, 8, 9,
- 10, 11, 95, 96, 14, 15, 5, 6, 32, 8,
- 9, 10, 11, 32, 28, 14, 15, 38, 39, 38,
- 39, 31, 32, 54, 32, 14, 57, 56, 59, 58,
- 12, 32, 31, 32, 16, 17, 39, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 55, 56, 32, 58,
- 32, 56, 12, 58, 36, 37, 16, 17, 18, 19,
- 20, 21, 56, 23, 58, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 21,
- 54, 33
+ 5, 6, 0, 8, 57, 58, 11, 84, 85, 30,
+ 4, 5, 6, 7, 8, 9, 10, 11, 30, 96,
+ 14, 15, 24, 25, 26, 25, 26, 29, 81, 82,
+ 66, 30, 34, 69, 30, 71, 30, 90, 91, 0,
+ 1, 94, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 25, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 25, 25, 25, 26, 1, 145, 30,
+ 4, 5, 6, 7, 8, 9, 10, 11, 31, 32,
+ 14, 15, 16, 17, 137, 25, 26, 92, 30, 29,
+ 66, 25, 27, 69, 34, 71, 30, 68, 33, 70,
+ 105, 1, 155, 0, 1, 1, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 30, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 68, 25, 70,
+ 25, 0, 1, 30, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 30, 30, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 30, 25, 30, 30, 0,
+ 1, 30, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 30, 30, 14, 15, 16, 30, 18, 19, 20,
+ 21, 22, 23, 1, 25, 30, 30, 5, 6, 30,
+ 8, 9, 10, 11, 12, 1, 14, 15, 16, 17,
+ 18, 19, 20, 21, 14, 5, 6, 25, 8, 9,
+ 10, 11, 30, 30, 14, 15, 142, 143, 144, 13,
+ 25, 31, 32, 149, 28, 151, 14, 31, 32, 32,
+ 30, 67, 68, 30, 70, 161, 67, 68, 30, 70,
+ 30, 31, 32, 30, 31, 32, 30, 31, 32, 30,
+ 31, 32, 30, 30, 30, 30, 30, 30, 30, 29,
+ 40, 59, -1, 106, 66
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const unsigned char yystos[] =
{
- 0, 43, 0, 1, 3, 4, 5, 6, 7, 8,
- 9, 10, 11, 14, 15, 31, 32, 44, 45, 46,
- 47, 48, 49, 52, 53, 55, 59, 61, 63, 64,
- 66, 68, 69, 70, 71, 79, 79, 28, 29, 77,
- 77, 77, 32, 77, 28, 28, 28, 29, 34, 41,
- 81, 82, 50, 50, 56, 58, 62, 74, 67, 74,
- 79, 32, 32, 32, 32, 32, 81, 81, 32, 38,
- 39, 30, 40, 12, 16, 17, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 32, 36, 37, 51, 72,
- 73, 75, 18, 19, 20, 21, 23, 32, 57, 73,
- 75, 5, 8, 15, 45, 54, 78, 45, 55, 60,
- 66, 78, 32, 75, 1, 45, 55, 65, 66, 78,
- 33, 81, 81, 82, 82, 32, 35, 81, 81, 77,
- 81, 76, 77, 81, 76, 81, 76, 76, 76, 28,
- 82, 13, 32, 77, 28, 76, 76, 79, 79, 79,
- 32, 81, 32, 32, 14, 80, 80, 32, 80, 80,
- 32, 80, 32, 32, 32, 80, 82, 80, 80, 32,
- 32, 32, 81, 32, 32, 32, 32, 32, 80, 32,
- 32, 32
+ 0, 36, 37, 0, 1, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 14, 15, 16, 18, 19, 20,
+ 21, 22, 23, 25, 30, 38, 39, 41, 42, 43,
+ 44, 47, 48, 50, 54, 56, 58, 59, 61, 63,
+ 64, 65, 72, 30, 25, 26, 71, 71, 30, 71,
+ 30, 30, 71, 25, 25, 25, 26, 29, 34, 75,
+ 76, 30, 1, 1, 45, 45, 51, 53, 57, 68,
+ 62, 68, 30, 73, 30, 30, 30, 30, 30, 75,
+ 75, 31, 32, 73, 27, 33, 30, 30, 1, 12,
+ 16, 17, 19, 20, 21, 22, 23, 25, 30, 40,
+ 46, 66, 67, 69, 18, 19, 20, 21, 30, 40,
+ 52, 67, 69, 39, 49, 72, 39, 50, 55, 61,
+ 72, 30, 40, 69, 39, 50, 60, 61, 72, 30,
+ 28, 75, 75, 76, 76, 30, 30, 24, 75, 75,
+ 71, 70, 71, 75, 25, 76, 1, 13, 30, 71,
+ 70, 25, 75, 30, 30, 14, 74, 30, 74, 74,
+ 74, 76, 30, 74, 30, 74, 30, 75, 30, 30,
+ 30, 74, 30, 30, 30
};
#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
#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
} \
while (0)
+
#define YYTERROR 1
#define YYERRCODE 256
-/* YYLLOC_DEFAULT -- Compute the default location (before the actions
- are run). */
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- Current.first_line = Rhs[1].first_line; \
- Current.first_column = Rhs[1].first_column; \
- Current.last_line = Rhs[N].last_line; \
- Current.last_column = Rhs[N].last_column;
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (N) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (0)
#endif
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
/* YYLEX -- calling `yylex' with the right arguments. */
#ifdef YYLEX_PARAM
YYFPRINTF Args; \
} while (0)
-# define YYDSYMPRINT(Args) \
-do { \
- if (yydebug) \
- yysymprint Args; \
-} while (0)
-
-# define YYDSYMPRINTF(Title, Token, Value, Location) \
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
do { \
if (yydebug) \
{ \
YYFPRINTF (stderr, "%s ", Title); \
yysymprint (stderr, \
- Token, Value); \
+ Type, Value); \
YYFPRINTF (stderr, "\n"); \
} \
} while (0)
/*------------------------------------------------------------------.
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (cinluded). |
+| TOP (included). |
`------------------------------------------------------------------*/
#if defined (__STDC__) || defined (__cplusplus)
static void
-yy_stack_print (short *bottom, short *top)
+yy_stack_print (short int *bottom, short int *top)
#else
static void
yy_stack_print (bottom, top)
- short *bottom;
- short *top;
+ short int *bottom;
+ short int *top;
#endif
{
YYFPRINTF (stderr, "Stack now");
#endif
{
int yyi;
- unsigned int yylineno = yyrline[yyrule];
+ unsigned int yylno = yyrline[yyrule];
YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
- yyrule - 1, yylineno);
+ yyrule - 1, yylno);
/* Print the symbols being reduced, and their result. */
for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
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 */
SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
evaluated with infinite-precision integer arithmetic. */
-#if YYMAXDEPTH == 0
-# undef YYMAXDEPTH
-#endif
-
#ifndef YYMAXDEPTH
# define YYMAXDEPTH 10000
#endif
(void) yyvaluep;
if (yytype < YYNTOKENS)
- {
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-# ifdef YYPRINT
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
- }
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
else
YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
switch (yytype)
{
default:
#if defined (__STDC__) || defined (__cplusplus)
static void
-yydestruct (int yytype, YYSTYPE *yyvaluep)
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
#else
static void
-yydestruct (yytype, yyvaluep)
+yydestruct (yymsg, yytype, yyvaluep)
+ const char *yymsg;
int yytype;
YYSTYPE *yyvaluep;
#endif
/* Pacify ``unused variable'' warnings. */
(void) yyvaluep;
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
switch (yytype)
{
+ case 48: /* choice_entry */
+
+ {
+ fprintf(stderr, "%s:%d: missing end statement for this entry\n",
+ (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
+ if (current_menu == (yyvaluep->menu))
+ menu_end_menu();
+};
+
+ break;
+ case 54: /* if_entry */
+
+ {
+ fprintf(stderr, "%s:%d: missing end statement for this entry\n",
+ (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
+ if (current_menu == (yyvaluep->menu))
+ menu_end_menu();
+};
+
+ break;
+ case 59: /* menu_entry */
+
+ {
+ fprintf(stderr, "%s:%d: missing end statement for this entry\n",
+ (yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
+ if (current_menu == (yyvaluep->menu))
+ menu_end_menu();
+};
+
+ break;
default:
break;
-/* The lookahead symbol. */
+/* The look-ahead symbol. */
int yychar;
-/* The semantic value of the lookahead symbol. */
+/* The semantic value of the look-ahead symbol. */
YYSTYPE yylval;
/* Number of syntax errors so far. */
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:
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];
yyssp = yyss;
yyvsp = yyvs;
+
+ yyvsp[0] = yylval;
+
goto yysetstate;
/*------------------------------------------------------------.
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
yystacksize = YYMAXDEPTH;
{
- short *yyss1 = yyss;
+ short int *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
yybackup:
/* Do appropriate processing given the current state. */
-/* Read a lookahead token if we need one and don't already have one. */
+/* Read a look-ahead token if we need one and don't already have one. */
/* yyresume: */
- /* First try to decide what to do without reference to lookahead token. */
+ /* First try to decide what to do without reference to look-ahead token. */
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
goto yydefault;
- /* Not known => get a lookahead token if don't already have one. */
+ /* Not known => get a look-ahead token if don't already have one. */
- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
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 (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)
{
case 8:
- { zconfprint("unexpected 'endmenu' statement"); ;}
+ { zconf_error("unexpected end statement"); ;}
break;
case 9:
- { zconfprint("unexpected 'endif' statement"); ;}
+ { zconf_error("unknown statement \"%s\"", (yyvsp[-2].string)); ;}
break;
case 10:
- { zconfprint("unexpected 'endchoice' statement"); ;}
+ {
+ zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name);
+;}
break;
case 11:
- { zconfprint("syntax error"); yyerrok; ;}
+ { zconf_error("invalid statement"); ;}
break;
- case 18:
+ case 25:
- {
- struct symbol *sym = sym_lookup(yyvsp[-1].string, 0);
- sym->flags |= SYMBOL_OPTIONAL;
- menu_add_entry(sym);
- printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
-;}
+ { zconf_error("unknown option \"%s\"", (yyvsp[-2].string)); ;}
break;
- case 19:
+ case 26:
- {
- menu_end_entry();
- printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
-;}
+ { zconf_error("invalid option"); ;}
break;
- case 20:
+ case 27:
{
- struct symbol *sym = sym_lookup(yyvsp[-1].string, 0);
+ struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
sym->flags |= SYMBOL_OPTIONAL;
menu_add_entry(sym);
- printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
+ printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
;}
break;
- case 21:
+ case 28:
{
- if (current_entry->prompt)
- current_entry->prompt->type = P_MENU;
- else
- zconfprint("warning: menuconfig statement without prompt");
menu_end_entry();
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
;}
break;
- case 27:
-
- {
- menu_set_type(S_TRISTATE);
- printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
-;}
- break;
-
- case 28:
-
- {
- menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
- menu_set_type(S_TRISTATE);
- printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
-;}
- break;
-
case 29:
{
- menu_set_type(S_BOOLEAN);
- printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
+ struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
+ sym->flags |= SYMBOL_OPTIONAL;
+ menu_add_entry(sym);
+ printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
;}
break;
case 30:
{
- menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
- menu_set_type(S_BOOLEAN);
- printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
-;}
- break;
-
- case 31:
-
- {
- menu_set_type(S_INT);
- printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
-;}
- break;
-
- case 32:
-
- {
- menu_set_type(S_HEX);
- printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
+ if (current_entry->prompt)
+ current_entry->prompt->type = P_MENU;
+ else
+ zconfprint("warning: menuconfig statement without prompt");
+ menu_end_entry();
+ printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
;}
break;
- case 33:
+ case 37:
{
- menu_set_type(S_STRING);
- printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
+ menu_set_type((yyvsp[-2].id)->stype);
+ printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
+ zconf_curname(), zconf_lineno(),
+ (yyvsp[-2].id)->stype);
;}
break;
- case 34:
+ case 38:
{
- menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr);
+ menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
;}
break;
- case 35:
+ case 39:
{
- menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
- printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+ menu_add_expr(P_DEFAULT, (yyvsp[-2].expr), (yyvsp[-1].expr));
+ if ((yyvsp[-3].id)->stype != S_UNKNOWN)
+ menu_set_type((yyvsp[-3].id)->stype);
+ printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
+ zconf_curname(), zconf_lineno(),
+ (yyvsp[-3].id)->stype);
;}
break;
- case 36:
+ case 40:
{
- menu_add_symbol(P_SELECT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr);
+ menu_add_symbol(P_SELECT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
;}
break;
- case 37:
+ case 41:
{
- menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,yyvsp[-3].symbol, yyvsp[-2].symbol), yyvsp[-1].expr);
+ menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[-3].symbol), (yyvsp[-2].symbol)), (yyvsp[-1].expr));
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
;}
break;
- case 38:
+ case 42:
{
struct symbol *sym = sym_lookup(NULL, 0);
;}
break;
- case 39:
+ case 43:
{
- menu_end_entry();
- menu_add_menu();
+ (yyval.menu) = menu_add_menu();
;}
break;
- case 40:
+ case 44:
{
- if (zconf_endtoken(yyvsp[0].token, T_CHOICE, T_ENDCHOICE)) {
+ if (zconf_endtoken((yyvsp[0].id), T_CHOICE, T_ENDCHOICE)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
}
;}
break;
- case 42:
-
- {
- printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
- zconfnerrs++;
-;}
- break;
-
- case 48:
+ case 52:
{
- menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr);
+ menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
;}
break;
- case 49:
+ case 53:
{
- menu_set_type(S_TRISTATE);
- printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
+ if ((yyvsp[-2].id)->stype == S_BOOLEAN || (yyvsp[-2].id)->stype == S_TRISTATE) {
+ menu_set_type((yyvsp[-2].id)->stype);
+ printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
+ zconf_curname(), zconf_lineno(),
+ (yyvsp[-2].id)->stype);
+ } else
+ YYERROR;
;}
break;
- case 50:
-
- {
- menu_set_type(S_BOOLEAN);
- printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
-;}
- break;
-
- case 51:
+ case 54:
{
current_entry->sym->flags |= SYMBOL_OPTIONAL;
;}
break;
- case 52:
+ case 55:
{
- menu_add_symbol(P_DEFAULT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr);
- printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
+ if ((yyvsp[-3].id)->stype == S_UNKNOWN) {
+ menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
+ printd(DEBUG_PARSE, "%s:%d:default\n",
+ zconf_curname(), zconf_lineno());
+ } else
+ YYERROR;
;}
break;
- case 55:
+ case 58:
{
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
menu_add_entry(NULL);
- menu_add_dep(yyvsp[-1].expr);
- menu_end_entry();
- menu_add_menu();
+ menu_add_dep((yyvsp[-1].expr));
+ (yyval.menu) = menu_add_menu();
;}
break;
- case 56:
+ case 59:
{
- if (zconf_endtoken(yyvsp[0].token, T_IF, T_ENDIF)) {
+ if (zconf_endtoken((yyvsp[0].id), T_IF, T_ENDIF)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
}
;}
break;
- case 58:
-
- {
- printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
- zconfnerrs++;
-;}
- break;
-
- case 63:
+ case 65:
{
menu_add_entry(NULL);
- menu_add_prop(P_MENU, yyvsp[-1].string, NULL, NULL);
+ menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL);
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
;}
break;
- case 64:
+ case 66:
{
- menu_end_entry();
- menu_add_menu();
+ (yyval.menu) = menu_add_menu();
;}
break;
- case 65:
+ case 67:
{
- if (zconf_endtoken(yyvsp[0].token, T_MENU, T_ENDMENU)) {
+ if (zconf_endtoken((yyvsp[0].id), T_MENU, T_ENDMENU)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
}
;}
break;
- case 67:
-
- {
- printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
- zconfnerrs++;
-;}
- break;
-
- case 72:
-
- { zconfprint("invalid menu option"); yyerrok; ;}
- break;
-
case 73:
{
- yyval.string = yyvsp[-1].string;
- printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
+ printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
+ zconf_nextfile((yyvsp[-1].string));
;}
break;
case 74:
- {
- zconf_nextfile(yyvsp[0].string);
-;}
- break;
-
- case 75:
-
{
menu_add_entry(NULL);
- menu_add_prop(P_COMMENT, yyvsp[-1].string, NULL, NULL);
+ menu_add_prompt(P_COMMENT, (yyvsp[-1].string), NULL);
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
;}
break;
- case 76:
+ case 75:
{
menu_end_entry();
;}
break;
- case 77:
+ case 76:
{
printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
;}
break;
- case 78:
+ case 77:
{
- current_entry->sym->help = yyvsp[0].string;
+ current_entry->sym->help = (yyvsp[0].string);
;}
break;
case 82:
{
- menu_add_dep(yyvsp[-1].expr);
+ menu_add_dep((yyvsp[-1].expr));
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
;}
break;
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;
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;
case 86:
{
- menu_add_prop(P_PROMPT, yyvsp[-1].string, NULL, yyvsp[0].expr);
+ menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr));
;}
break;
case 89:
- { yyval.token = T_ENDMENU; ;}
+ { (yyval.id) = (yyvsp[-1].id); ;}
break;
case 90:
- { yyval.token = T_ENDCHOICE; ;}
+ { (yyval.id) = (yyvsp[-1].id); ;}
break;
case 91:
- { yyval.token = T_ENDIF; ;}
+ { (yyval.id) = (yyvsp[-1].id); ;}
break;
case 94:
- { yyval.expr = NULL; ;}
+ { (yyval.expr) = NULL; ;}
break;
case 95:
- { yyval.expr = yyvsp[0].expr; ;}
+ { (yyval.expr) = (yyvsp[0].expr); ;}
break;
case 96:
- { yyval.expr = expr_alloc_symbol(yyvsp[0].symbol); ;}
+ { (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); ;}
break;
case 97:
- { yyval.expr = expr_alloc_comp(E_EQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;}
+ { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
break;
case 98:
- { yyval.expr = expr_alloc_comp(E_UNEQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;}
+ { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
break;
case 99:
- { yyval.expr = yyvsp[-1].expr; ;}
+ { (yyval.expr) = (yyvsp[-1].expr); ;}
break;
case 100:
- { yyval.expr = expr_alloc_one(E_NOT, yyvsp[0].expr); ;}
+ { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[0].expr)); ;}
break;
case 101:
- { yyval.expr = expr_alloc_two(E_OR, yyvsp[-2].expr, yyvsp[0].expr); ;}
+ { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
break;
case 102:
- { yyval.expr = expr_alloc_two(E_AND, yyvsp[-2].expr, yyvsp[0].expr); ;}
+ { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
break;
case 103:
- { yyval.symbol = sym_lookup(yyvsp[0].string, 0); free(yyvsp[0].string); ;}
+ { (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); free((yyvsp[0].string)); ;}
break;
case 104:
- { yyval.symbol = sym_lookup(yyvsp[0].string, 1); free(yyvsp[0].string); ;}
+ { (yyval.symbol) = sym_lookup((yyvsp[0].string), 1); free((yyvsp[0].string)); ;}
break;
}
-/* Line 999 of yacc.c. */
+/* Line 1037 of yacc.c. */
\f
yyvsp -= yylen;
{
YYSIZE_T yysize = 0;
int yytype = YYTRANSLATE (yychar);
+ const char* yyprefix;
char *yymsg;
- int yyx, yycount;
+ int yyx;
- yycount = 0;
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. */
- for (yyx = yyn < 0 ? -yyn : 0;
- yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 0;
+
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- yysize += yystrlen (yytname[yyx]) + 15, yycount++;
- yysize += yystrlen ("syntax error, unexpected ") + 1;
- yysize += yystrlen (yytname[yytype]);
+ {
+ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
+ yycount += 1;
+ if (yycount == 5)
+ {
+ yysize = 0;
+ break;
+ }
+ }
+ yysize += (sizeof ("syntax error, unexpected ")
+ + yystrlen (yytname[yytype]));
yymsg = (char *) YYSTACK_ALLOC (yysize);
if (yymsg != 0)
{
if (yycount < 5)
{
- yycount = 0;
- for (yyx = yyn < 0 ? -yyn : 0;
- yyx < (int) (sizeof (yytname) / sizeof (char *));
- yyx++)
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
{
- const char *yyq = ! yycount ? ", expecting " : " or ";
- yyp = yystpcpy (yyp, yyq);
+ yyp = yystpcpy (yyp, yyprefix);
yyp = yystpcpy (yyp, yytname[yyx]);
- yycount++;
+ yyprefix = " or ";
}
}
yyerror (yymsg);
if (yyerrstatus == 3)
{
- /* If just tried and failed to reuse lookahead token after an
+ /* If just tried and failed to reuse look-ahead token after an
error, discard it. */
- /* Return failure if at end of input. */
- if (yychar == YYEOF)
+ if (yychar <= YYEOF)
{
- /* Pop the error token. */
- YYPOPSTACK;
- /* Pop the rest of the stack. */
- while (yyss < yyssp)
- {
- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
- yydestruct (yystos[*yyssp], yyvsp);
- YYPOPSTACK;
- }
- YYABORT;
+ /* If at end of input, pop the error token,
+ then the rest of the stack, then return failure. */
+ if (yychar == YYEOF)
+ for (;;)
+ {
+
+ YYPOPSTACK;
+ if (yyssp == yyss)
+ YYABORT;
+ yydestruct ("Error: popping",
+ yystos[*yyssp], yyvsp);
+ }
}
-
- YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
- yydestruct (yytoken, &yylval);
- yychar = YYEMPTY;
-
+ else
+ {
+ yydestruct ("Error: discarding", yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
}
- /* Else will try to reuse lookahead token after shifting the error
+ /* Else will try to reuse look-ahead token after shifting the error
token. */
goto yyerrlab1;
-/*----------------------------------------------------.
-| yyerrlab1 -- error raised explicitly by an action. |
-`----------------------------------------------------*/
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+#ifdef __GNUC__
+ /* Pacify GCC when the user code never invokes YYERROR and the label
+ yyerrorlab therefore never appears in user code. */
+ if (0)
+ goto yyerrorlab;
+#endif
+
+yyvsp -= yylen;
+ yyssp -= yylen;
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
yyerrlab1:
yyerrstatus = 3; /* Each real token shifted decrements this. */
if (yyssp == yyss)
YYABORT;
- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
- yydestruct (yystos[yystate], yyvsp);
- yyvsp--;
- yystate = *--yyssp;
+ yydestruct ("Error: popping", yystos[yystate], yyvsp);
+ YYPOPSTACK;
+ yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
if (yyn == YYFINAL)
YYACCEPT;
- YYDPRINTF ((stderr, "Shifting error token, "));
-
*++yyvsp = yylval;
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
yystate = yyn;
goto yynewstate;
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
yyabortlab:
+ yydestruct ("Error: discarding lookahead",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
yyresult = 1;
goto yyreturn;
sym_init();
menu_init();
modules_sym = sym_lookup("MODULES", 0);
- rootmenu.prompt = menu_add_prop(P_MENU, "Linux Kernel Configuration", NULL, NULL);
+ rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
- //zconfdebug = 1;
+#if YYDEBUG
+ if (getenv("ZCONF_DEBUG"))
+ zconfdebug = 1;
+#endif
zconfparse();
if (zconfnerrs)
exit(1);
menu_finalize(&rootmenu);
for_all_symbols(i, sym) {
- if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
- printf("\n");
- else
- sym->flags |= SYMBOL_CHECK_DONE;
+ sym_check_deps(sym);
}
sym_change_count = 1;
case T_ENDCHOICE: return "endchoice";
case T_IF: return "if";
case T_ENDIF: return "endif";
+ case T_DEPENDS: return "depends";
}
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) {
- 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;
}
{
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);
static void zconferror(const char *err)
{
+#if YYDEBUG
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
+#endif
}
void print_quoted_string(FILE *out, const char *str)
}
#include "lex.zconf.c"
+#include "util.c"
#include "confdata.c"
#include "expr.c"
#include "symbol.c"
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;
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 */
spin_lock(&timer->lock);
ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK;
}
- spin_unlock(&timer->lock);
+ spin_unlock_irqrestore(&timer->lock, flags);
}
/*
# 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
To compile this driver as a module, choose M here: the module
will be called snd-fm801.
-config SND_FM801_TEA575X
- tristate "ForteMedia FM801 + TEA5757 tuner"
+config SND_FM801_TEA575X_BOOL
+ bool "ForteMedia FM801 + TEA5757 tuner"
depends on SND_FM801
- select VIDEO_DEV
help
Say Y here to include support for soundcards based on the ForteMedia
FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media
- Forte SF256-PCS-02).
+ Forte SF256-PCS-02) into the snd-fm801 driver.
- To compile this driver as a module, choose M here: the module
- will be called snd-fm801-tea575x.
+config SND_FM801_TEA575X
+ tristate
+ depends on SND_FM801_TEA575X_BOOL
+ default SND_FM801
+ select VIDEO_DEV
config SND_HDA_INTEL
tristate "Intel HD Audio"
struct snd_rawmidi *rmidi;
int temp, mode;
struct snd_mpu401 *mpu;
- int port;
+ unsigned long port;
#ifdef VORTEX_MPU401_LEGACY
/* EnableHardCodedMPU401Port() */
#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
msleep(1);
}
- if (chip->remap_addr)
- iounmap(chip->remap_addr);
if (chip->irq >= 0)
free_irq(chip->irq, (void*)chip);
+ if (chip->remap_addr)
+ iounmap(chip->remap_addr);
if (chip->bdl.area)
snd_dma_free_pages(&chip->bdl);
/* reivision id to check workarounds */
#define AD1988A_REV2 0x100200
+#define is_rev2(codec) \
+ ((codec)->vendor_id == 0x11d41988 && \
+ (codec)->revision_id == AD1988A_REV2)
/*
* mixers
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[] = {
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[] = {
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[] = {
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[] = {
/* 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];
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);
case AD1988_6STACK_DIG:
spec->multiout.max_channels = 8;
spec->multiout.num_dacs = 4;
- if (codec->revision_id == AD1988A_REV2)
+ if (is_rev2(codec))
spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
else
spec->multiout.dac_nids = ad1988_6stack_dac_nids;
spec->input_mux = &ad1988_6stack_capture_source;
spec->num_mixers = 2;
- if (codec->revision_id == AD1988A_REV2)
+ if (is_rev2(codec))
spec->mixers[0] = ad1988_6stack_mixers1_rev2;
else
spec->mixers[0] = ad1988_6stack_mixers1;
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->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;
{ .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 },
int change;
change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0,
- 0x80, valp[0] & 0x80);
+ 0x80, (valp[0] ? 0 : 0x80));
change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0,
- 0x80, valp[1] & 0x80);
+ 0x80, (valp[1] ? 0 : 0x80));
snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
- 0x80, valp[0] & 0x80);
+ 0x80, (valp[0] ? 0 : 0x80));
snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
- 0x80, valp[1] & 0x80);
+ 0x80, (valp[1] ? 0 : 0x80));
return change;
}
/* 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
char *clock_source;
int x;
- if (hdsp_check_for_iobox (hdsp))
+ if (hdsp_check_for_iobox (hdsp)) {
snd_iprintf(buffer, "No I/O box connected.\nPlease connect one and upload firmware.\n");
return;
+ }
if (hdsp_check_for_firmware(hdsp, 0)) {
if (hdsp->state & HDSP_FirmwareCached) {