From 79187def07f6d015fa2affb2f3a6c964aae520e7 Mon Sep 17 00:00:00 2001 From: Erik Hovland Date: Wed, 26 Jul 2006 21:22:37 +0000 Subject: Found out that gcc that comes with mandriva 2006.0 will barf on compiling glibc if these two patches are not applied. These patches are backports from glibc 2.3.6. --- .../glibc/files/glibc-2.3.5-fix-week-alias-arm-2.patch | 11 +++++++++++ packages/glibc/files/glibc-2.3.5-fix-week-alias-arm.patch | 15 +++++++++++++++ packages/glibc/glibc_2.3.5+cvs20050627.bb | 4 +++- 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 packages/glibc/files/glibc-2.3.5-fix-week-alias-arm-2.patch create mode 100644 packages/glibc/files/glibc-2.3.5-fix-week-alias-arm.patch diff --git a/packages/glibc/files/glibc-2.3.5-fix-week-alias-arm-2.patch b/packages/glibc/files/glibc-2.3.5-fix-week-alias-arm-2.patch new file mode 100644 index 0000000000..bf2f31e479 --- /dev/null +++ b/packages/glibc/files/glibc-2.3.5-fix-week-alias-arm-2.patch @@ -0,0 +1,11 @@ +--- glibc-2.3.3/ports/sysdeps/unix/sysv/linux/arm/socket.S.orig 2006-07-12 14:38:22.208228359 -0700 ++++ glibc-2.3.3/ports/sysdeps/unix/sysv/linux/arm/socket.S 2006-07-12 14:39:56.911675066 -0700 +@@ -123,5 +123,7 @@ + #endif + + PSEUDO_END (__socket) +- ++ ++#ifndef NO_WEAK_ALIAS + weak_alias (__socket, socket) ++#endif diff --git a/packages/glibc/files/glibc-2.3.5-fix-week-alias-arm.patch b/packages/glibc/files/glibc-2.3.5-fix-week-alias-arm.patch new file mode 100644 index 0000000000..0097ff94d3 --- /dev/null +++ b/packages/glibc/files/glibc-2.3.5-fix-week-alias-arm.patch @@ -0,0 +1,15 @@ +--- glibc-2.3.3/ports/sysdeps/unix/sysv/linux/arm/socket.S.orig 2006-07-12 13:57:05.990485563 -0700 ++++ glibc-2.3.3/ports/sysdeps/unix/sysv/linux/arm/socket.S 2006-07-12 13:58:41.197865230 -0700 +@@ -32,7 +32,11 @@ + The .S files for the other calls just #define socket and #include this. */ + + #ifndef __socket +-#define __socket P(__,socket) ++# ifndef NO_WEAK_ALIAS ++# define __socket P(__,socket) ++# else ++# define __socket socket ++# endif + #endif + + #define PUSHARGS_1 str a1, [sp, $-4]! diff --git a/packages/glibc/glibc_2.3.5+cvs20050627.bb b/packages/glibc/glibc_2.3.5+cvs20050627.bb index fc5abcc266..fbab2d7afc 100644 --- a/packages/glibc/glibc_2.3.5+cvs20050627.bb +++ b/packages/glibc/glibc_2.3.5+cvs20050627.bb @@ -7,7 +7,7 @@ MAINTAINER = "Phil Blundell " FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/glibc-cvs-2.3.5" SRCDATE = "20050627" -PR = "r7" +PR = "r8" GLIBC_ADDONS ?= "ports,linuxthreads" GLIBC_EXTRA_OECONF ?= "" @@ -55,6 +55,8 @@ SRC_URI = "http://familiar.handhelds.org/source/v0.8.3/stash_libc_sources.redhat file://ldsocache-varrun.patch;patch=1 \ file://5090_all_stubs-rule-fix.patch;patch=1 \ file://raise.patch;patch=1 \ + file://glibc-2.3.3-fix-week-alias-arm.patch;patch=1 \ + file://glibc-2.3.3-fix-week-alias-arm-2.patch;patch=1 \ file://etc/ld.so.conf \ file://generate-supported.mk" -- cgit v1.2.3 From 469410c81b3d651f54cbf399de4e8e8f139922f7 Mon Sep 17 00:00:00 2001 From: Erik Hovland Date: Fri, 28 Jul 2006 23:47:13 +0000 Subject: This commit adds the necessary bitbake recipes for the newer 2.4 kernel versions in the hh.org cvs repo. --- .../.mtn2git_empty | 0 .../defconfig-h3900 | 1627 ++++++++++++++++++++ .../.mtn2git_empty | 0 .../defconfig-h3900 | 1627 ++++++++++++++++++++ .../linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh41.1.bb | 76 + .../linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh41.bb | 74 + 6 files changed, 3404 insertions(+) create mode 100644 packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41.1/.mtn2git_empty create mode 100644 packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41.1/defconfig-h3900 create mode 100644 packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41/.mtn2git_empty create mode 100644 packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41/defconfig-h3900 create mode 100644 packages/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh41.1.bb create mode 100644 packages/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh41.bb diff --git a/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41.1/.mtn2git_empty b/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41.1/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41.1/defconfig-h3900 b/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41.1/defconfig-h3900 new file mode 100644 index 0000000000..4d012c89e0 --- /dev/null +++ b/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41.1/defconfig-h3900 @@ -0,0 +1,1627 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_OMAHA is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_RISCSTATION is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_AT91RM9200DK is not set +# CONFIG_MINIMAL_OOPS is not set + +# +# Linux As Bootldr support +# +# CONFIG_LAB is not set +# CONFIG_BIG_KERNEL is not set +# CONFIG_USE_DATE_CODE is not set + +# +# Archimedes/A5000 Implementations +# + +# +# Archimedes/A5000 Implementations (select only ONE) +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ACCELENT is not set +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_CONSUS is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_JORNADA56X is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SIMPUTER is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_REGISTERS is not set + +# +# Intel PXA250/210 Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +# CONFIG_ARCH_PXA_IDP is not set +# CONFIG_ARCH_PXA_CERF is not set +CONFIG_ARCH_H3900=y +CONFIG_ARCH_H1900=y +CONFIG_ARCH_H5400=y +# CONFIG_ARCH_H2200 is not set +CONFIG_ARCH_AXIM=y +CONFIG_PXA_USB=m +CONFIG_PXA_USB_NETLINK=m +CONFIG_PXA_USB_CHAR=m + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_PLD is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_SA110 is not set +# CONFIG_CPU_SA1100 is not set +CONFIG_CPU_32v5=y +CONFIG_CPU_XSCALE=y +CONFIG_XSCALE_PXA250=y +# CONFIG_XSCALE_80200_OLD is not set +# CONFIG_CPU_32v3 is not set +# CONFIG_CPU_32v4 is not set +# CONFIG_SA1100_IPAQ is not set +CONFIG_PXA_IPAQ=y +CONFIG_IPAQ_HANDHELD=y + +# +# Compaq iPAQ Handheld +# +CONFIG_IPAQ_HAL=m +# CONFIG_H3600_MICRO is not set +CONFIG_IPAQ_HAS_ROSELLA=y +CONFIG_IPAQ_HAS_ASIC3=y +CONFIG_H3600_ASIC=m +CONFIG_H3900_ASIC_DEBUG=m +CONFIG_H5400_ASIC=m +CONFIG_H1900_ASIC=m +CONFIG_H1900_TS=m +CONFIG_H3600_HARDWARE=y +CONFIG_IPAQ_SLEEVE=m +CONFIG_SLEEVE_DEBUG=y +CONFIG_SLEEVE_DEBUG_VERBOSE=0 +# CONFIG_SLEEVE_IRQ_DEMUX is not set + +# +# Dell Axim X5 +# +CONFIG_AXIM_HAL=m + +# +# Processor Features +# +# CONFIG_DISCONTIGMEM is not set + +# +# General setup +# +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CPU_FREQ=y +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +# CONFIG_PCMCIA_CLPS6700 is not set +# CONFIG_PCMCIA_SA1100 is not set +CONFIG_PCMCIA_PXA=m +# CONFIG_MERCURY_BACKPAQ is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SAMSUNG_ASIC=m +# CONFIG_MMC_S3C2410 is not set +CONFIG_MMC_H5400=m +CONFIG_MMC_ASIC3=m +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_XIP_KERNEL is not set + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_PM=y +CONFIG_APM=m +# CONFIG_HWTIMER is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="keepinitrd" +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_CML1=m +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_IDP is not set +# CONFIG_PARPORT_AMIGA is not set +# CONFIG_PARPORT_MFC3 is not set +# CONFIG_PARPORT_ATARI is not set +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_SUNBPP is not set +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=1 +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +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=y +CONFIG_MTD_MAP_BANK_WIDTH_16=y +CONFIG_MTD_MAP_BANK_WIDTH_32=y +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=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_IPAQ=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +# CONFIG_MTD_SA1100 is not set +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_LUBBOCK is not set +# CONFIG_MTD_IXP425 is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_H720X is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_CEIVA is not set +# CONFIG_MTD_NOR_TOTO is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +CONFIG_MTD_BLKMTD=m + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_DOCPROBE is not set +# CONFIG_MTD_DOCECC is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_NAND_SPIA is not set +# CONFIG_MTD_NAND_TOTO is not set +# CONFIG_MTD_NAND_AUTCPU12 is not set +# CONFIG_MTD_NAND_EDB7312 is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_NVRD=m + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +CONFIG_BLK_DEV_LVM=m +CONFIG_BLK_DEV_DM=m + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_TFTP is not set +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +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 is not set +CONFIG_IP_NF_MATCH_STATE=m +# CONFIG_IP_NF_MATCH_CONNTRACK is not set +# CONFIG_IP_NF_MATCH_UNCLEAN is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_FILTER=m +# CONFIG_IP_NF_TARGET_REJECT is not set +# CONFIG_IP_NF_TARGET_MIRROR is not set +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_NAT_LOCAL is not set +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_DSCP is not set +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_ARPTABLES is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +CONFIG_IPV6=m +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MOBILITY=m +CONFIG_IPV6_MOBILITY_MN=m +# CONFIG_IPV6_MOBILITY_HA is not set +CONFIG_IPV6_MOBILITY_DEBUG=y + +# +# IPv6: Netfilter Configuration +# +# 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 is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_HL is not set +CONFIG_IP6_NF_MATCH_MULTIPORT=m +# CONFIG_IP6_NF_MATCH_OWNER is not set +CONFIG_IP6_NF_MATCH_MARK=m +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_AHESP is not set +# CONFIG_IP6_NF_MATCH_LENGTH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +CONFIG_BRIDGE=m +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_IPSEC=m + +# +# IPSec options (FreeS/WAN) +# +CONFIG_KLIPS_AUTH_HMAC_MD5=y +CONFIG_KLIPS_AUTH_HMAC_SHA1=y +CONFIG_KLIPS_ENC_3DES=y + +# +# ESP always enabled with tunnel mode +# +CONFIG_KLIPS_IPCOMP=y +CONFIG_KLIPS_DEBUG=y + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_HERMES is not set +# CONFIG_SPECTRUM24T is not set + +# +# Wireless Pcmcia cards support +# +# CONFIG_PCMCIA_HERMES is not set +CONFIG_AIRO_CS=m +# CONFIG_WVLAN_CS is not set +# CONFIG_MWVLAN_CS is not set +# CONFIG_HOSTAP is not set +# CONFIG_HOSTAP_CS is not set +CONFIG_NET_WIRELESS=y +# CONFIG_ATMELWLAN is not set +# CONFIG_ATMELWLAN_USB_503A_RFMD is not set +# CONFIG_ATMELWLAN_PCMCIA_502A is not set +# CONFIG_ATMELWLAN_PCMCIA_3COM is not set +# CONFIG_ATMELWLAN_PCMCIA_502AD is not set +# CONFIG_ATMELWLAN_PCMCIA_502AE is not set +# CONFIG_ATMELWLAN_PCMCIA_504 is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_AXNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +# CONFIG_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +CONFIG_NET_PCMCIA_RADIO=y +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_WAVELAN=m +# CONFIG_AIRONET4500_CS is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m +CONFIG_IRPORT_SIR=m + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# 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_PXA_FIR=m + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=m + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDEFLOPPY=m +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL 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_ISAPNP is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +CONFIG_SCSI=m + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set + +# +# PCMCIA SCSI adapter support +# +CONFIG_SCSI_PCMCIA=y +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=m +CONFIG_INPUT_KEYBDEV=m +CONFIG_INPUT_MOUSEDEV=m +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_UINPUT=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL_EXTENDED=y +# CONFIG_SERIAL_MANY_PORTS is not set +# CONFIG_SERIAL_SHARE_IRQ is not set +# CONFIG_SERIAL_DETECT_IRQ is not set +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_S3C2410 is not set +# CONFIG_SERIAL_S3C2410_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +# CONFIG_SERIAL_SA1100 is not set +# CONFIG_SERIAL_SA1100_CONSOLE is not set +# CONFIG_SERIAL_SIR_PXA is not set +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +CONFIG_NEWTONKBD=m +# CONFIG_SA1100_PROFILER is not set + +# +# Compaq iPAQ H3600 support +# +CONFIG_TOUCHSCREEN_H3600=m +# CONFIG_H3600_BACKPAQ_FPGA is not set +# CONFIG_H3600_BACKPAQ_ACCEL is not set +# CONFIG_H3600_BACKPAQ_GASGAUGE is not set +# CONFIG_H3600_BACKPAQ_SRAM is not set +# CONFIG_H3600_BACKPAQ_AUDIO is not set +# CONFIG_H3600_STOWAWAY is not set +# CONFIG_H3800_MICROKBD is not set +# CONFIG_SA1100_LIRC is not set +CONFIG_H5400_BUZZER=m +CONFIG_H5400_FSI=m + +# +# I2C support +# +CONFIG_I2C=m +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_PXA_ALGO=m +CONFIG_I2C_PXA_ADAP=m +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_PROC=m +# CONFIG_I2C_DS1307 is not set + +# +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set + +# +# Other L3 adapters +# +# CONFIG_L3_S3C2410 is not set +# CONFIG_L3_SA1111 is not set +# CONFIG_L3_BACKPAQ is not set +# CONFIG_BIT_SA1100_GPIO is not set + +# +# SPI support +# +# CONFIG_SPI is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +CONFIG_MOUSE=m +# CONFIG_PSMOUSE is not set +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set +# CONFIG_MK712_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +CONFIG_INPUT_SERIO=m +CONFIG_INPUT_SERPORT=m + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_21285_WATCHDOG is not set +# CONFIG_977_WATCHDOG is not set +# CONFIG_SA1100_WATCHDOG is not set +CONFIG_PXA_WATCHDOG=m +# CONFIG_OMAHA_WATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_PXA_RTC=m +CONFIG_PXA_RTC_HACK=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +CONFIG_PCMCIA_SERIAL_CS=m +CONFIG_PCMCIA_MOBILISCAN_CS=m +# CONFIG_AXIM_TS is not set +CONFIG_AXIM_KEY=m +# CONFIG_AXIM_KEY_FIX is not set + +# +# Multimedia devices +# +CONFIG_MEDIA=m +CONFIG_VIDEO_DEV=m +CONFIG_V4L2_DEV=m + +# +# Video For Linux +# +CONFIG_VIDEO_PROC_FS=y +# CONFIG_I2C_PARPORT is not set + +# +# Video Adapters +# +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA_USB=m +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZR36120 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_CYBERPRO is not set +# CONFIG_VIDEO_H3600_BACKPAQ is not set +# CONFIG_VIDEO_HAWKEYE is not set + +# +# Video for Linux 2 (V4L2) +# +CONFIG_VIDEO_WINNOV_CS=m + +# +# Radio Adapters +# +# 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 is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI 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 + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=m +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_UMSDOS_FS=m +CONFIG_VFAT_FS=m +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_LZO is not set +# CONFIG_JFFS2_LZARI is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_PROC=y +CONFIG_CRAMFS=y +CONFIG_TMPFS=y +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=m +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DRIVERFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=m +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_SUNRPC=m +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m + +# +# Console drivers +# +CONFIG_PC_KEYMAP=y +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_ACORN is not set +# CONFIG_FB_ANAKIN is not set +# CONFIG_FB_CLPS711X is not set +# CONFIG_FB_S3C2410 is not set +# CONFIG_FB_SA1100 is not set +# CONFIG_FB_EPSON1356 is not set +# CONFIG_FB_MQ200 is not set +CONFIG_FB_PXA=y +# CONFIG_FB_PXA_8BPP is not set +CONFIG_FB_PXA_16BPP=y +CONFIG_FB_MQ1100=y +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +# CONFIG_FBCON_CFB4 is not set +# CONFIG_FBCON_CFB8 is not set +CONFIG_FBCON_CFB16=y +# CONFIG_FBCON_CFB24 is not set +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +# CONFIG_FBCON_NO_LOGO is not set +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +CONFIG_FBCON_FONTS=y +CONFIG_FONT_8x8=y +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +CONFIG_SOUND_H3900_UDA1380=m +CONFIG_SOUND_H5400=m +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_PAS_JOYSTICK is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_YMFPCI_LEGACY is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_VIDC is not set +# CONFIG_SOUND_WAVEARTIST is not set +CONFIG_SOUND_PXA_AC97=m +# CONFIG_SOUND_TVMIXER is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set +# CONFIG_MCP_UCB1400_TS is not set + +# +# Console Switches +# +# CONFIG_SWITCHES is not set + +# +# USB support +# +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_LONG_TIMEOUT is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=m +# CONFIG_USB_OHCI_SA1111 is not set +CONFIG_USB_OHCI_H5400=m +CONFIG_USB_SL811HS=m +CONFIG_USB_SL811HS_CS=m + +# +# USB Device Class drivers +# +CONFIG_USB_AUDIO=m +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=m + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=m +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_WACOM is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# +CONFIG_USB_IBMCAM=m +CONFIG_USB_OV511=m +CONFIG_USB_PWC=m +# CONFIG_USB_QC is not set +CONFIG_USB_SE401=m +CONFIG_USB_STV680=m +CONFIG_USB_VICAM=m +# CONFIG_USB_DSBR is not set +# CONFIG_USB_DABUSB is not set + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +CONFIG_USB_CDCETHER=m +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +CONFIG_USB_SERIAL_IPAQ=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_KLSI is not set +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_BRLVGER is not set + +# +# Support for USB gadgets +# +CONFIG_USB_GADGET=m +CONFIG_USB_GADGET_PXA2XX=y +# CONFIG_USB_GADGET_N9604 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_SUPERH is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_CONTROLLER is not set +CONFIG_USB_PXA2XX=m +CONFIG_USB_GADGET_CONTROLLER=m +# CONFIG_USB_GADGET_DUALSPEED is not set + +# +# USB Gadget Drivers +# +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m + +# +# Linux As Bootldr Modules +# +# CONFIG_BIG_KERNEL is not set +# CONFIG_USE_DATE_CODE is not set +# CONFIG_YMODEM is not set +# CONFIG_LAB_DUMMY is not set +# CONFIG_LAB_CRC is not set +# CONFIG_LAB_YMODEM is not set +# CONFIG_LAB_MTD is not set +# CONFIG_LAB_COPY is not set +# CONFIG_LAB_COPY_YMODEM is not set +# CONFIG_LAB_COPY_FLASH is not set +# CONFIG_LAB_COPY_FS is not set +# CONFIG_LAB_COPY_WRAPPER is not set + +# +# Bluetooth support +# +CONFIG_BLUEZ=m +CONFIG_BLUEZ_L2CAP=m +CONFIG_BLUEZ_SCO=m +CONFIG_BLUEZ_RFCOMM=m +CONFIG_BLUEZ_RFCOMM_TTY=y +CONFIG_BLUEZ_BNEP=m +CONFIG_BLUEZ_BNEP_MC_FILTER=y +CONFIG_BLUEZ_BNEP_PROTO_FILTER=y +CONFIG_BLUEZ_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BLUEZ_HCIUSB=m +# CONFIG_BLUEZ_HCIUSB_SCO is not set +CONFIG_BLUEZ_HCIUART=m +CONFIG_BLUEZ_HCIUART_H4=y +CONFIG_BLUEZ_HCIUART_BCSP=y +# CONFIG_BLUEZ_HCIUART_BCSP_TXCRC is not set +# CONFIG_BLUEZ_HCIBFUSB is not set +CONFIG_BLUEZ_HCIDTL1=m +CONFIG_BLUEZ_HCIBT3C=m +CONFIG_BLUEZ_HCIBLUECARD=m +CONFIG_BLUEZ_HCIBTUART=m +# CONFIG_BLUEZ_HCIVHCI is not set + +# +# Kernel hacking +# +# CONFIG_FRAME_POINTER is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +# CONFIG_REED_SOLOMON is not set +CONFIG_FW_LOADER=m diff --git a/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41/.mtn2git_empty b/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41/defconfig-h3900 b/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41/defconfig-h3900 new file mode 100644 index 0000000000..4d012c89e0 --- /dev/null +++ b/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh41/defconfig-h3900 @@ -0,0 +1,1627 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_OMAHA is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_RISCSTATION is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_AT91RM9200DK is not set +# CONFIG_MINIMAL_OOPS is not set + +# +# Linux As Bootldr support +# +# CONFIG_LAB is not set +# CONFIG_BIG_KERNEL is not set +# CONFIG_USE_DATE_CODE is not set + +# +# Archimedes/A5000 Implementations +# + +# +# Archimedes/A5000 Implementations (select only ONE) +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ACCELENT is not set +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_CONSUS is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_JORNADA56X is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SIMPUTER is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_REGISTERS is not set + +# +# Intel PXA250/210 Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +# CONFIG_ARCH_PXA_IDP is not set +# CONFIG_ARCH_PXA_CERF is not set +CONFIG_ARCH_H3900=y +CONFIG_ARCH_H1900=y +CONFIG_ARCH_H5400=y +# CONFIG_ARCH_H2200 is not set +CONFIG_ARCH_AXIM=y +CONFIG_PXA_USB=m +CONFIG_PXA_USB_NETLINK=m +CONFIG_PXA_USB_CHAR=m + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_PLD is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_SA110 is not set +# CONFIG_CPU_SA1100 is not set +CONFIG_CPU_32v5=y +CONFIG_CPU_XSCALE=y +CONFIG_XSCALE_PXA250=y +# CONFIG_XSCALE_80200_OLD is not set +# CONFIG_CPU_32v3 is not set +# CONFIG_CPU_32v4 is not set +# CONFIG_SA1100_IPAQ is not set +CONFIG_PXA_IPAQ=y +CONFIG_IPAQ_HANDHELD=y + +# +# Compaq iPAQ Handheld +# +CONFIG_IPAQ_HAL=m +# CONFIG_H3600_MICRO is not set +CONFIG_IPAQ_HAS_ROSELLA=y +CONFIG_IPAQ_HAS_ASIC3=y +CONFIG_H3600_ASIC=m +CONFIG_H3900_ASIC_DEBUG=m +CONFIG_H5400_ASIC=m +CONFIG_H1900_ASIC=m +CONFIG_H1900_TS=m +CONFIG_H3600_HARDWARE=y +CONFIG_IPAQ_SLEEVE=m +CONFIG_SLEEVE_DEBUG=y +CONFIG_SLEEVE_DEBUG_VERBOSE=0 +# CONFIG_SLEEVE_IRQ_DEMUX is not set + +# +# Dell Axim X5 +# +CONFIG_AXIM_HAL=m + +# +# Processor Features +# +# CONFIG_DISCONTIGMEM is not set + +# +# General setup +# +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CPU_FREQ=y +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +# CONFIG_PCMCIA_CLPS6700 is not set +# CONFIG_PCMCIA_SA1100 is not set +CONFIG_PCMCIA_PXA=m +# CONFIG_MERCURY_BACKPAQ is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SAMSUNG_ASIC=m +# CONFIG_MMC_S3C2410 is not set +CONFIG_MMC_H5400=m +CONFIG_MMC_ASIC3=m +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_XIP_KERNEL is not set + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_PM=y +CONFIG_APM=m +# CONFIG_HWTIMER is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="keepinitrd" +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_CML1=m +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_IDP is not set +# CONFIG_PARPORT_AMIGA is not set +# CONFIG_PARPORT_MFC3 is not set +# CONFIG_PARPORT_ATARI is not set +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_SUNBPP is not set +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=1 +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +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=y +CONFIG_MTD_MAP_BANK_WIDTH_16=y +CONFIG_MTD_MAP_BANK_WIDTH_32=y +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=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_IPAQ=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +# CONFIG_MTD_SA1100 is not set +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_LUBBOCK is not set +# CONFIG_MTD_IXP425 is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_H720X is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_CEIVA is not set +# CONFIG_MTD_NOR_TOTO is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +CONFIG_MTD_BLKMTD=m + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_DOCPROBE is not set +# CONFIG_MTD_DOCECC is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_NAND_SPIA is not set +# CONFIG_MTD_NAND_TOTO is not set +# CONFIG_MTD_NAND_AUTCPU12 is not set +# CONFIG_MTD_NAND_EDB7312 is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_NVRD=m + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +CONFIG_BLK_DEV_LVM=m +CONFIG_BLK_DEV_DM=m + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_TFTP is not set +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +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 is not set +CONFIG_IP_NF_MATCH_STATE=m +# CONFIG_IP_NF_MATCH_CONNTRACK is not set +# CONFIG_IP_NF_MATCH_UNCLEAN is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_FILTER=m +# CONFIG_IP_NF_TARGET_REJECT is not set +# CONFIG_IP_NF_TARGET_MIRROR is not set +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_NAT_LOCAL is not set +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_DSCP is not set +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_ARPTABLES is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +CONFIG_IPV6=m +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MOBILITY=m +CONFIG_IPV6_MOBILITY_MN=m +# CONFIG_IPV6_MOBILITY_HA is not set +CONFIG_IPV6_MOBILITY_DEBUG=y + +# +# IPv6: Netfilter Configuration +# +# 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 is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_HL is not set +CONFIG_IP6_NF_MATCH_MULTIPORT=m +# CONFIG_IP6_NF_MATCH_OWNER is not set +CONFIG_IP6_NF_MATCH_MARK=m +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_AHESP is not set +# CONFIG_IP6_NF_MATCH_LENGTH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +CONFIG_BRIDGE=m +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_IPSEC=m + +# +# IPSec options (FreeS/WAN) +# +CONFIG_KLIPS_AUTH_HMAC_MD5=y +CONFIG_KLIPS_AUTH_HMAC_SHA1=y +CONFIG_KLIPS_ENC_3DES=y + +# +# ESP always enabled with tunnel mode +# +CONFIG_KLIPS_IPCOMP=y +CONFIG_KLIPS_DEBUG=y + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_HERMES is not set +# CONFIG_SPECTRUM24T is not set + +# +# Wireless Pcmcia cards support +# +# CONFIG_PCMCIA_HERMES is not set +CONFIG_AIRO_CS=m +# CONFIG_WVLAN_CS is not set +# CONFIG_MWVLAN_CS is not set +# CONFIG_HOSTAP is not set +# CONFIG_HOSTAP_CS is not set +CONFIG_NET_WIRELESS=y +# CONFIG_ATMELWLAN is not set +# CONFIG_ATMELWLAN_USB_503A_RFMD is not set +# CONFIG_ATMELWLAN_PCMCIA_502A is not set +# CONFIG_ATMELWLAN_PCMCIA_3COM is not set +# CONFIG_ATMELWLAN_PCMCIA_502AD is not set +# CONFIG_ATMELWLAN_PCMCIA_502AE is not set +# CONFIG_ATMELWLAN_PCMCIA_504 is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_AXNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +# CONFIG_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +CONFIG_NET_PCMCIA_RADIO=y +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_WAVELAN=m +# CONFIG_AIRONET4500_CS is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m +CONFIG_IRPORT_SIR=m + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# 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_PXA_FIR=m + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=m + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDEFLOPPY=m +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL 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_ISAPNP is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +CONFIG_SCSI=m + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set + +# +# PCMCIA SCSI adapter support +# +CONFIG_SCSI_PCMCIA=y +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=m +CONFIG_INPUT_KEYBDEV=m +CONFIG_INPUT_MOUSEDEV=m +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_UINPUT=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL_EXTENDED=y +# CONFIG_SERIAL_MANY_PORTS is not set +# CONFIG_SERIAL_SHARE_IRQ is not set +# CONFIG_SERIAL_DETECT_IRQ is not set +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_S3C2410 is not set +# CONFIG_SERIAL_S3C2410_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +# CONFIG_SERIAL_SA1100 is not set +# CONFIG_SERIAL_SA1100_CONSOLE is not set +# CONFIG_SERIAL_SIR_PXA is not set +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +CONFIG_NEWTONKBD=m +# CONFIG_SA1100_PROFILER is not set + +# +# Compaq iPAQ H3600 support +# +CONFIG_TOUCHSCREEN_H3600=m +# CONFIG_H3600_BACKPAQ_FPGA is not set +# CONFIG_H3600_BACKPAQ_ACCEL is not set +# CONFIG_H3600_BACKPAQ_GASGAUGE is not set +# CONFIG_H3600_BACKPAQ_SRAM is not set +# CONFIG_H3600_BACKPAQ_AUDIO is not set +# CONFIG_H3600_STOWAWAY is not set +# CONFIG_H3800_MICROKBD is not set +# CONFIG_SA1100_LIRC is not set +CONFIG_H5400_BUZZER=m +CONFIG_H5400_FSI=m + +# +# I2C support +# +CONFIG_I2C=m +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_PXA_ALGO=m +CONFIG_I2C_PXA_ADAP=m +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_PROC=m +# CONFIG_I2C_DS1307 is not set + +# +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set + +# +# Other L3 adapters +# +# CONFIG_L3_S3C2410 is not set +# CONFIG_L3_SA1111 is not set +# CONFIG_L3_BACKPAQ is not set +# CONFIG_BIT_SA1100_GPIO is not set + +# +# SPI support +# +# CONFIG_SPI is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +CONFIG_MOUSE=m +# CONFIG_PSMOUSE is not set +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set +# CONFIG_MK712_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +CONFIG_INPUT_SERIO=m +CONFIG_INPUT_SERPORT=m + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_21285_WATCHDOG is not set +# CONFIG_977_WATCHDOG is not set +# CONFIG_SA1100_WATCHDOG is not set +CONFIG_PXA_WATCHDOG=m +# CONFIG_OMAHA_WATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_PXA_RTC=m +CONFIG_PXA_RTC_HACK=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +CONFIG_PCMCIA_SERIAL_CS=m +CONFIG_PCMCIA_MOBILISCAN_CS=m +# CONFIG_AXIM_TS is not set +CONFIG_AXIM_KEY=m +# CONFIG_AXIM_KEY_FIX is not set + +# +# Multimedia devices +# +CONFIG_MEDIA=m +CONFIG_VIDEO_DEV=m +CONFIG_V4L2_DEV=m + +# +# Video For Linux +# +CONFIG_VIDEO_PROC_FS=y +# CONFIG_I2C_PARPORT is not set + +# +# Video Adapters +# +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA_USB=m +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZR36120 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_CYBERPRO is not set +# CONFIG_VIDEO_H3600_BACKPAQ is not set +# CONFIG_VIDEO_HAWKEYE is not set + +# +# Video for Linux 2 (V4L2) +# +CONFIG_VIDEO_WINNOV_CS=m + +# +# Radio Adapters +# +# 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 is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI 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 + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=m +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_UMSDOS_FS=m +CONFIG_VFAT_FS=m +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_LZO is not set +# CONFIG_JFFS2_LZARI is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_PROC=y +CONFIG_CRAMFS=y +CONFIG_TMPFS=y +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=m +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DRIVERFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=m +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_SUNRPC=m +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m + +# +# Console drivers +# +CONFIG_PC_KEYMAP=y +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_ACORN is not set +# CONFIG_FB_ANAKIN is not set +# CONFIG_FB_CLPS711X is not set +# CONFIG_FB_S3C2410 is not set +# CONFIG_FB_SA1100 is not set +# CONFIG_FB_EPSON1356 is not set +# CONFIG_FB_MQ200 is not set +CONFIG_FB_PXA=y +# CONFIG_FB_PXA_8BPP is not set +CONFIG_FB_PXA_16BPP=y +CONFIG_FB_MQ1100=y +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +# CONFIG_FBCON_CFB4 is not set +# CONFIG_FBCON_CFB8 is not set +CONFIG_FBCON_CFB16=y +# CONFIG_FBCON_CFB24 is not set +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +# CONFIG_FBCON_NO_LOGO is not set +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +CONFIG_FBCON_FONTS=y +CONFIG_FONT_8x8=y +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +CONFIG_SOUND_H3900_UDA1380=m +CONFIG_SOUND_H5400=m +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_PAS_JOYSTICK is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_YMFPCI_LEGACY is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_VIDC is not set +# CONFIG_SOUND_WAVEARTIST is not set +CONFIG_SOUND_PXA_AC97=m +# CONFIG_SOUND_TVMIXER is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set +# CONFIG_MCP_UCB1400_TS is not set + +# +# Console Switches +# +# CONFIG_SWITCHES is not set + +# +# USB support +# +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_LONG_TIMEOUT is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=m +# CONFIG_USB_OHCI_SA1111 is not set +CONFIG_USB_OHCI_H5400=m +CONFIG_USB_SL811HS=m +CONFIG_USB_SL811HS_CS=m + +# +# USB Device Class drivers +# +CONFIG_USB_AUDIO=m +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=m + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=m +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_WACOM is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# +CONFIG_USB_IBMCAM=m +CONFIG_USB_OV511=m +CONFIG_USB_PWC=m +# CONFIG_USB_QC is not set +CONFIG_USB_SE401=m +CONFIG_USB_STV680=m +CONFIG_USB_VICAM=m +# CONFIG_USB_DSBR is not set +# CONFIG_USB_DABUSB is not set + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +CONFIG_USB_CDCETHER=m +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +CONFIG_USB_SERIAL_IPAQ=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_KLSI is not set +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_BRLVGER is not set + +# +# Support for USB gadgets +# +CONFIG_USB_GADGET=m +CONFIG_USB_GADGET_PXA2XX=y +# CONFIG_USB_GADGET_N9604 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_SUPERH is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_CONTROLLER is not set +CONFIG_USB_PXA2XX=m +CONFIG_USB_GADGET_CONTROLLER=m +# CONFIG_USB_GADGET_DUALSPEED is not set + +# +# USB Gadget Drivers +# +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m + +# +# Linux As Bootldr Modules +# +# CONFIG_BIG_KERNEL is not set +# CONFIG_USE_DATE_CODE is not set +# CONFIG_YMODEM is not set +# CONFIG_LAB_DUMMY is not set +# CONFIG_LAB_CRC is not set +# CONFIG_LAB_YMODEM is not set +# CONFIG_LAB_MTD is not set +# CONFIG_LAB_COPY is not set +# CONFIG_LAB_COPY_YMODEM is not set +# CONFIG_LAB_COPY_FLASH is not set +# CONFIG_LAB_COPY_FS is not set +# CONFIG_LAB_COPY_WRAPPER is not set + +# +# Bluetooth support +# +CONFIG_BLUEZ=m +CONFIG_BLUEZ_L2CAP=m +CONFIG_BLUEZ_SCO=m +CONFIG_BLUEZ_RFCOMM=m +CONFIG_BLUEZ_RFCOMM_TTY=y +CONFIG_BLUEZ_BNEP=m +CONFIG_BLUEZ_BNEP_MC_FILTER=y +CONFIG_BLUEZ_BNEP_PROTO_FILTER=y +CONFIG_BLUEZ_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BLUEZ_HCIUSB=m +# CONFIG_BLUEZ_HCIUSB_SCO is not set +CONFIG_BLUEZ_HCIUART=m +CONFIG_BLUEZ_HCIUART_H4=y +CONFIG_BLUEZ_HCIUART_BCSP=y +# CONFIG_BLUEZ_HCIUART_BCSP_TXCRC is not set +# CONFIG_BLUEZ_HCIBFUSB is not set +CONFIG_BLUEZ_HCIDTL1=m +CONFIG_BLUEZ_HCIBT3C=m +CONFIG_BLUEZ_HCIBLUECARD=m +CONFIG_BLUEZ_HCIBTUART=m +# CONFIG_BLUEZ_HCIVHCI is not set + +# +# Kernel hacking +# +# CONFIG_FRAME_POINTER is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +# CONFIG_REED_SOLOMON is not set +CONFIG_FW_LOADER=m diff --git a/packages/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh41.1.bb b/packages/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh41.1.bb new file mode 100644 index 0000000000..f278af0185 --- /dev/null +++ b/packages/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh41.1.bb @@ -0,0 +1,76 @@ +SECTION = "kernel" +DESCRIPTION = "handhelds.org Linux kernel for PXA25x based devices." +MAINTAINER = "Phil Blundell " +LICENSE = "GPL" +PR = "r2" + + +KERNEL_CCSUFFIX = "-3.3.4" +COMPATIBLE_HOST = "arm.*-linux" + +SRC_URI = "${HANDHELDS_CVS};module=linux/kernel;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \ + file://defconfig-${PACKAGE_ARCH} \ + file://ipaq-hal.init \ + file://linux-2.4-mmc-debugging.patch;patch=1 \ + file://linux-2.4-usb-gadget.patch;patch=1 \ + file://usb-gadget-ether-compat.patch;patch=1 \ + file://linux-2.4-no-short-loads.patch;patch=1 \ + file://linux-2.4-cpufreq.patch;patch=1" + +S = "${WORKDIR}/kernel" + +KERNEL_PRESERVE_HH_MINOR_VER = "1" + +inherit kernel update-rc.d + +K_MAJOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[0]}" +K_MINOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[1]}" +K_MICRO = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[2]}" +RMKV = "${@bb.data.getVar('PV',d,1).split('-')[1].split('rmk')[-1]}" +PXAV = "${@bb.data.getVar('PV',d,1).split('-')[2].split('pxa')[-1]}" +HHV = "${@bb.data.getVar('PV',d,1).split('-')[3].split('hh')[-1]}" + +KERNEL_PRIORITY = "${@'%d' % (int(bb.data.getVar('K_MAJOR',d,1)) * 100000000 + int(bb.data.getVar('K_MINOR',d,1)) * 1000000 + int(bb.data.getVar('K_MICRO',d,1)) * 10000 + int(bb.data.getVar('RMKV',d,1)) * 1000 + int(bb.data.getVar('PXAV',d,1)) * 100 + float(bb.data.getVar('HHV',d,1)))}" + +module_conf_h3900_asic = "alias ipaq_hal_3900 h3900_asic" +module_conf_h5400_asic = "alias ipaq_hal_5400 h5400_asic" +module_conf_pxa_ir = "alias irda0 pxa_ir" +module_conf_i2c-algo-pxa = "options i2c-algo-pxa pxa_scan=0" +module_conf_pcmcia_core = "options pcmcia_core ignore_cis_vcc=1" +module_conf_ppp_async = "alias ppp0 ppp_async" +module_conf_orinoco_cs = "options orinoco_cs ignore_cis_vcc=1" +module_conf_hostap_cs = "options hostap_cs ignore_cis_vcc=1" +module_conf_hidp = "alias bt-prot-5 hidp" + +module_autoload_h3600_ts = "h3600_ts" +module_autoload_apm = "apm" +module_autoload_af_packet = "af_packet" +module_autoload_usb-ohci-h5400 = "usb-ohci-h5400" +module_autoload_ppp_async = "ppp_async" +module_autoload_usb-eth = "usb-eth" +module_autoload_h5400_buzzer = "h5400_buzzer" +# breaks booting on first install of h3900 handhelds +#module_autoload_mmc_asic3 = "mmc_asic3" +module_autoload_mmc_h5400 = "mmc_h5400" +module_autoload_h5400-audio = "h5400-audio" +module_autoload_h3900-uda1380 = "h3900-uda1380" +module_autoload_sa1100-rtc = "sa1100-rtc" +module_autoload_ak4535 = "ak4535" +module_autoload_i2c-adap-pxa = "i2c-adap-pxa" + +FILES_kernel += "/etc/init.d/ipaq-hal" +INITSCRIPT_NAME = "ipaq-hal" +INITSCRIPT_PARAMS = "start 21 S ." + +# extra depends +RDEPENDS_kernel-module-h5400-audio = "kernel-module-ak4535 kernel-module-i2c-adap-pxa" +RDEPENDS_kernel-module-h3900-uda1380 = "kernel-module-uda1380 kernel-module-i2c-adap-pxa" + +do_configure_prepend() { + install -m 0644 ${WORKDIR}/defconfig-${PACKAGE_ARCH} ${S}/.config +} + +do_install_append() { + install -d ${D}${sysconfdir}/init.d + install ${WORKDIR}/ipaq-hal.init ${D}${sysconfdir}/init.d/ipaq-hal +} diff --git a/packages/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh41.bb b/packages/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh41.bb new file mode 100644 index 0000000000..bed92aa6ea --- /dev/null +++ b/packages/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh41.bb @@ -0,0 +1,74 @@ +SECTION = "kernel" +DESCRIPTION = "handhelds.org Linux kernel for PXA25x based devices." +MAINTAINER = "Phil Blundell " +LICENSE = "GPL" +PR = "r1" + + +KERNEL_CCSUFFIX = "-3.3.4" +COMPATIBLE_HOST = "arm.*-linux" + +SRC_URI = "${HANDHELDS_CVS};module=linux/kernel;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \ + file://defconfig-${PACKAGE_ARCH} \ + file://ipaq-hal.init \ + file://linux-2.4-mmc-debugging.patch;patch=1 \ + file://linux-2.4-usb-gadget.patch;patch=1 \ + file://usb-gadget-ether-compat.patch;patch=1 \ + file://linux-2.4-no-short-loads.patch;patch=1 \ + file://linux-2.4-cpufreq.patch;patch=1" + +S = "${WORKDIR}/kernel" + +inherit kernel update-rc.d + +K_MAJOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[0]}" +K_MINOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[1]}" +K_MICRO = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[2]}" +RMKV = "${@bb.data.getVar('PV',d,1).split('-')[1].split('rmk')[-1]}" +PXAV = "${@bb.data.getVar('PV',d,1).split('-')[2].split('pxa')[-1]}" +HHV = "${@bb.data.getVar('PV',d,1).split('-')[3].split('hh')[-1]}" + +KERNEL_PRIORITY = "${@'%d' % (int(bb.data.getVar('K_MAJOR',d,1)) * 100000000 + int(bb.data.getVar('K_MINOR',d,1)) * 1000000 + int(bb.data.getVar('K_MICRO',d,1)) * 10000 + int(bb.data.getVar('RMKV',d,1)) * 1000 + int(bb.data.getVar('PXAV',d,1)) * 100 + float(bb.data.getVar('HHV',d,1)))}" + +module_conf_h3900_asic = "alias ipaq_hal_3900 h3900_asic" +module_conf_h5400_asic = "alias ipaq_hal_5400 h5400_asic" +module_conf_pxa_ir = "alias irda0 pxa_ir" +module_conf_i2c-algo-pxa = "options i2c-algo-pxa pxa_scan=0" +module_conf_pcmcia_core = "options pcmcia_core ignore_cis_vcc=1" +module_conf_ppp_async = "alias ppp0 ppp_async" +module_conf_orinoco_cs = "options orinoco_cs ignore_cis_vcc=1" +module_conf_hostap_cs = "options hostap_cs ignore_cis_vcc=1" +module_conf_hidp = "alias bt-prot-5 hidp" + +module_autoload_h3600_ts = "h3600_ts" +module_autoload_apm = "apm" +module_autoload_af_packet = "af_packet" +module_autoload_usb-ohci-h5400 = "usb-ohci-h5400" +module_autoload_ppp_async = "ppp_async" +module_autoload_usb-eth = "usb-eth" +module_autoload_h5400_buzzer = "h5400_buzzer" +# breaks booting on first install of h3900 handhelds +#module_autoload_mmc_asic3 = "mmc_asic3" +module_autoload_mmc_h5400 = "mmc_h5400" +module_autoload_h5400-audio = "h5400-audio" +module_autoload_h3900-uda1380 = "h3900-uda1380" +module_autoload_sa1100-rtc = "sa1100-rtc" +module_autoload_ak4535 = "ak4535" +module_autoload_i2c-adap-pxa = "i2c-adap-pxa" + +FILES_kernel += "/etc/init.d/ipaq-hal" +INITSCRIPT_NAME = "ipaq-hal" +INITSCRIPT_PARAMS = "start 21 S ." + +# extra depends +RDEPENDS_kernel-module-h5400-audio = "kernel-module-ak4535 kernel-module-i2c-adap-pxa" +RDEPENDS_kernel-module-h3900-uda1380 = "kernel-module-uda1380 kernel-module-i2c-adap-pxa" + +do_configure_prepend() { + install -m 0644 ${WORKDIR}/defconfig-${PACKAGE_ARCH} ${S}/.config +} + +do_install_append() { + install -d ${D}${sysconfdir}/init.d + install ${WORKDIR}/ipaq-hal.init ${D}${sysconfdir}/init.d/ipaq-hal +} -- cgit v1.2.3 From 5a7bb23659fa97a1ac55bf6769605cf342a62911 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 25 Aug 2006 10:09:02 +0000 Subject: initscripts: don't run the devices (devfs) script when udev is active, update for new udev versions --- packages/initscripts/initscripts-1.0/checkroot.sh | 5 +++++ packages/initscripts/initscripts-1.0/devices | 2 +- packages/initscripts/initscripts_1.0.bb | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/initscripts/initscripts-1.0/checkroot.sh b/packages/initscripts/initscripts-1.0/checkroot.sh index 8255038c32..0283e1acca 100755 --- a/packages/initscripts/initscripts-1.0/checkroot.sh +++ b/packages/initscripts/initscripts-1.0/checkroot.sh @@ -148,7 +148,12 @@ fi # remount the rootfs rw but do not try to change mtab because it # is on a ro fs until the remount succeeded. Then clean up old mtabs # and finally write the new mtab. +# This part is only needed if the rootfs was mounted ro. # +if [ $(grep rootfs /proc/mounts | awk '{print $4}') = rw ]; then + exit 0 +fi +echo "Remounting root file system..." mount -n -o remount,$rootmode / if test "$rootmode" = rw then diff --git a/packages/initscripts/initscripts-1.0/devices b/packages/initscripts/initscripts-1.0/devices index 28fb71fe3f..fb0f851d16 100755 --- a/packages/initscripts/initscripts-1.0/devices +++ b/packages/initscripts/initscripts-1.0/devices @@ -6,7 +6,7 @@ . /etc/default/rcS # exit without doing anything if udev is active -if test -e /dev/.udevdb; then +if test -e /dev/.udev -o -e /dev/.udevdb; then exit 0 fi diff --git a/packages/initscripts/initscripts_1.0.bb b/packages/initscripts/initscripts_1.0.bb index 0d14403a36..29747d41c2 100644 --- a/packages/initscripts/initscripts_1.0.bb +++ b/packages/initscripts/initscripts_1.0.bb @@ -6,7 +6,7 @@ DEPENDS = "makedevs" DEPENDS_openzaurus = "makedevs virtual/kernel" RDEPENDS = "makedevs" LICENSE = "GPL" -PR = "r74" +PR = "r75" SRC_URI = "file://halt \ file://ramdisk \ -- cgit v1.2.3 From b007bb8a853a60ab918584da2e89ca75b21ab543 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 25 Aug 2006 10:16:09 +0000 Subject: gpe-edit: insert \n to unbreak metadata --- packages/gpe-edit/gpe-edit_0.32.bb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/gpe-edit/gpe-edit_0.32.bb b/packages/gpe-edit/gpe-edit_0.32.bb index af59b81e43..e504ec2271 100644 --- a/packages/gpe-edit/gpe-edit_0.32.bb +++ b/packages/gpe-edit/gpe-edit_0.32.bb @@ -1,6 +1,8 @@ MAINTAINER = "Phil Blundell " -SECTION = "gpe"DESCRIPTION = "Editor for the GPE Palmtop Environment" +SECTION = "gpe" +DESCRIPTION = "Editor for the GPE Palmtop Environment" LICENSE = "GPL" +PR = "r1" DEPENDS = "gtk+ libgpewidget" -- cgit v1.2.3 From 6a96d189f181e57619d0c20cbae1b926953f10d9 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 25 Aug 2006 10:16:16 +0000 Subject: handhelds-pxa-2.6-cvs: bump version to 2.6.17-hh0 --- packages/linux/handhelds-pxa-2.6_cvs.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/linux/handhelds-pxa-2.6_cvs.bb b/packages/linux/handhelds-pxa-2.6_cvs.bb index 7dfcb4d237..75f4425638 100644 --- a/packages/linux/handhelds-pxa-2.6_cvs.bb +++ b/packages/linux/handhelds-pxa-2.6_cvs.bb @@ -27,8 +27,8 @@ ALLOW_EMPTY_htcuniversal = 1 K_MAJOR = "2" K_MINOR = "6" -K_MICRO = "16" -HHV = "5" +K_MICRO = "17" +HHV = "0" # KERNEL_PRIORITY = "${@'%d' % (int(bb.data.getVar('K_MAJOR',d,1)) * 100000000 + int(bb.data.getVar('K_MINOR',d,1)) * 1000000 + int(bb.data.getVar('K_MICRO',d,1)) * 10000 + float(bb.data.getVar('HHV',d,1)))}" -- cgit v1.2.3 From a4d66865597b43a26875dd649bedf0ca25099e8f Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Fri, 25 Aug 2006 10:20:16 +0000 Subject: feed-browser: feeds adding improved, updater more silent - includes/config.inc contain array with all feeds - check_database() adds feeds if they are not present - updater does not show feed URL --- contrib/feed-browser/includes/config.inc | 118 ++++++++++++++++++++++++++++ contrib/feed-browser/includes/functions.inc | 101 ++++-------------------- contrib/feed-browser/index.php | 1 + contrib/feed-browser/update.php | 3 +- 4 files changed, 138 insertions(+), 85 deletions(-) create mode 100644 contrib/feed-browser/includes/config.inc diff --git a/contrib/feed-browser/includes/config.inc b/contrib/feed-browser/includes/config.inc new file mode 100644 index 0000000000..1397d2c947 --- /dev/null +++ b/contrib/feed-browser/includes/config.inc @@ -0,0 +1,118 @@ +'OpenZaurus', + 'distro_version'=>'3.5.4', + 'feed_base_url'=>'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4/feed/', + 'feeds'=>array( + array( + 'name'=>'base', + 'url'=>'base', + ), + array( + 'name'=>'opie', + 'url'=>'opie', + ), + array( + 'name'=>'x11', + 'url'=>'x11', + ), + array( + 'name'=>'upgrades', + 'url'=>'upgrades', + ), + array( + 'name'=>'perl', + 'url'=>'perl', + ), + array( + 'name'=>'python', + 'url'=>'python', + ), + array( + 'name'=>'Collie upgrades', + 'url'=>'upgrades/machine/collie', + ), + array( + 'name'=>'Tosa upgrades', + 'url'=>'upgrades/machine/tosa', + ), + array( + 'name'=>'Poodle upgrades', + 'url'=>'upgrades/machine/poodle', + ), + array( + 'name'=>'Poodle', + 'url'=>'machine/poodle', + ), + array( + 'name'=>'Collie', + 'url'=>'machine/collie', + ), + array( + 'name'=>'Tosa', + 'url'=>'machine/tosa', + ) + ) + ), + array( + 'distro_name'=>'OpenZaurus', + 'distro_version'=>'3.5.4.1', + 'feed_base_url'=>'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/', + 'feeds'=>array( + array( + 'name'=>'base', + 'url'=>'base', + ), + array( + 'name'=>'opie', + 'url'=>'opie', + ), + array( + 'name'=>'perl', + 'url'=>'perl', + ), + array( + 'name'=>'python', + 'url'=>'python', + ), + array( + 'name'=>'upgrades', + 'url'=>'upgrades', + ), + array( + 'name'=>'x11', + 'url'=>'x11', + ), + array( + 'name'=>'C7x0', + 'url'=>'machine/c7x0', + ), + array( + 'name'=>'Spitz', + 'url'=>'machine/spitz', + ), + array( + 'name'=>'Akita', + 'url'=>'machine/akita', + ), + array( + 'name'=>'Akita upgrades', + 'url'=>'upgrades/machine/akita', + ), + array( + 'name'=>'C7x0 upgrades', + 'url'=>'upgrades/machine/c7x0', + ), + array( + 'name'=>'Spitz upgrades', + 'url'=>'upgrades/machine/spitz', + ) + ) + ) +); + +?> diff --git a/contrib/feed-browser/includes/functions.inc b/contrib/feed-browser/includes/functions.inc index d18b129650..4edf3f4369 100644 --- a/contrib/feed-browser/includes/functions.inc +++ b/contrib/feed-browser/includes/functions.inc @@ -20,8 +20,6 @@ error_reporting(E_ALL); -define('DB_FILENAME', './feeds.db'); - function db_query($query) { $result = FALSE; @@ -36,7 +34,6 @@ function db_query($query) return $result; } - function db_query_n($query) { $result = FALSE; @@ -76,88 +73,24 @@ function db_table_exists ($db, $mytable) return FALSE; } -function test_insert_ipkgs ($db) +function insert_feeds ($db) { + global $feeds; - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('3541-base', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/base') - "); - - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('3541-opie', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/opie') - "); - - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('3541-perl', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/perl') - "); - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('3541-python', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/python') - "); - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('3541-upgrades', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/upgrades') - "); - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('3541-x11', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/x11') - "); - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('3541-machine-c7x0', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/machine/c7x0') - "); - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('3541-machine-spitz', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/machine/spitz') - "); - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('3541-machine-akita', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/machine/akita') - "); - - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('3541-upgrades-machine-akita', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/upgrades/machine/akita') - "); - - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('3541-upgrades-machine-c7x0', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/upgrades/machine/c7x0') - "); - - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('3541-upgrades-machine-spitz', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/upgrades/machine/spitz') - "); - - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('3541-upgrades-machine-tosa', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4.1/feed/upgrades/machine/tosa') - "); - - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('354-base', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4/feed/base') - "); - - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('354-opie', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4/feed/opie') - "); - - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('354-x11', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4/feed/x11') - "); - - sqlite_query($db, - "INSERT INTO feeds (f_name, f_uri) - VALUES ('354-upgrades', 'http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4/feed/upgrades') - "); - + if(isset($feeds)) + { + foreach($feeds as $distro) + { + foreach($distro['feeds'] as $feed) + { + sqlite_query($db, "INSERT INTO feeds (f_name, f_uri) VALUES + ( + '{$distro['distro_name']} {$distro['distro_version']} {$feed['name']}', + '{$distro['feed_base_url']}{$feed['url']}' + )"); + } + } + } } function searchletter($searchletter = '') @@ -492,7 +425,7 @@ function check_database() f_uri varchar(100), f_comments varchar(500))"); - test_insert_ipkgs ($db) ; + insert_feeds ($db) ; } sqlite_close($db); diff --git a/contrib/feed-browser/index.php b/contrib/feed-browser/index.php index b3fb41bcd8..df7282db7d 100644 --- a/contrib/feed-browser/index.php +++ b/contrib/feed-browser/index.php @@ -30,6 +30,7 @@ * */ +require_once 'includes/config.inc'; require_once 'includes/functions.inc'; check_database(); diff --git a/contrib/feed-browser/update.php b/contrib/feed-browser/update.php index ed7d6e47ef..94c8608616 100644 --- a/contrib/feed-browser/update.php +++ b/contrib/feed-browser/update.php @@ -16,6 +16,7 @@ * */ +require_once 'includes/config.inc'; require_once 'includes/functions.inc'; /* @@ -45,7 +46,7 @@ $feeds = db_query("SELECT f_name, f_uri FROM feeds"); foreach($feeds as $feed) { - print("Updating {$feed['f_name']}: {$feed['f_uri']}: "); + print("Updating {$feed['f_name']}: "); db_query_n("DELETE FROM packages WHERE p_feed = '{$feed['f_name']}'"); $count = 0; -- cgit v1.2.3 From 0ef0aaaef45154d538d943c4bcbe340814c72628 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 25 Aug 2006 10:20:41 +0000 Subject: libgnomecups: add dep on libgnomeui --- packages/gnome/libgnomecups_0.2.2.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gnome/libgnomecups_0.2.2.bb b/packages/gnome/libgnomecups_0.2.2.bb index 86214904c8..53251ba84b 100644 --- a/packages/gnome/libgnomecups_0.2.2.bb +++ b/packages/gnome/libgnomecups_0.2.2.bb @@ -2,7 +2,7 @@ DESCRIPTION="Gnome Cups Manager" LICENSE="GPLv2" PR="r0" -DEPENDS="glib-2.0 gtk+ pango cups intltool" +DEPENDS="glib-2.0 gtk+ pango cups intltool libgnomeui" inherit gnome pkgconfig -- cgit v1.2.3 From 15fe10f53b83794d42ff5d59b9006e21cc3f7652 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Fri, 25 Aug 2006 10:45:56 +0000 Subject: feed-browser: FIX: feed structure was changed - database NEED to be rebuilt - package.p_feed is now int -> feeds.f_id --- contrib/feed-browser/includes/config.inc | 2 +- contrib/feed-browser/includes/functions.inc | 9 +++++++-- contrib/feed-browser/update.php | 12 ++++++------ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/contrib/feed-browser/includes/config.inc b/contrib/feed-browser/includes/config.inc index 1397d2c947..0a270a8eb0 100644 --- a/contrib/feed-browser/includes/config.inc +++ b/contrib/feed-browser/includes/config.inc @@ -1,6 +1,6 @@ '', 'version'=>'', 'arch'=>'', 'depends'=>'', 'maintainer'=>'', 'homepage'=>'', 'section'=>'', 'replaces'=>'', 'provides'=>'', 'recommends'=>'', 'conflicts'=>'', 'size'=>'', - 'md5sum'=>'', 'source'=>'', 'feed'=>'', 'file'=>'', 'desc'=>'' - ); + 'md5sum'=>'', 'source'=>'', 'feed'=>$feed['f_id'], 'file'=>'', 'desc'=>'' + ); while (!feof($packagesgz_h)) { @@ -75,7 +75,7 @@ foreach($feeds as $feed) 'name'=>'', 'version'=>'', 'arch'=>'', 'depends'=>'', 'maintainer'=>'', 'homepage'=>'', 'section'=>'', 'replaces'=>'', 'provides'=>'', 'recommends'=>'', 'conflicts'=>'', 'size'=>'', - 'md5sum'=>'', 'source'=>'', 'feed'=>'', 'file'=>'', 'desc'=>'' + 'md5sum'=>'', 'source'=>'', 'feed'=>$feed['f_id'], 'file'=>'', 'desc'=>'' ); } @@ -161,7 +161,7 @@ function insert_ipkgs(&$package_info) { db_query_n("INSERT INTO packages VALUES ( '{$package_info['name']}', '{$package_info['version']}', - '{$package_info['arch']}', '{$package_info['depends']}', + '{$package_info['arch']}', '{$package_info['depends']}', '{$package_info['maintainer']}', '{$package_info['homepage']}', '{$package_info['section']}', '{$package_info['replaces']}', '{$package_info['provides']}', '{$package_info['recommends']}', @@ -169,7 +169,7 @@ function insert_ipkgs(&$package_info) '{$package_info['md5sum']}', '{$package_info['source']}', '{$package_info['feed']}', '{$package_info['file']}', '{$package_info['desc']}' - )"); + )"); } ?> -- cgit v1.2.3 From d5f25d3bad63b36e72105732291d0b18d63aab11 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Fri, 25 Aug 2006 10:52:54 +0000 Subject: ipsec-tools: s/net/network/ --- packages/ipsec-tools/ipsec-tools.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ipsec-tools/ipsec-tools.inc b/packages/ipsec-tools/ipsec-tools.inc index 2b1669f987..31ec6c87bf 100644 --- a/packages/ipsec-tools/ipsec-tools.inc +++ b/packages/ipsec-tools/ipsec-tools.inc @@ -3,7 +3,8 @@ Linux-2.6 IPsec implementation." DEPENDS = "virtual/kernel openssl readline flex" LICENSE = "BSD" MAINTAINER = "Chris Larson " -SECTION = "console/net" +SECTION = "console/network" +PR = "r1" inherit autotools -- cgit v1.2.3 From cf5b9a1071cea6f65d9abe979c9c42d4542efb63 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Fri, 25 Aug 2006 10:53:36 +0000 Subject: nfs-utils: s/networking/network/ --- packages/nfs-utils/nfs-utils_1.0.6.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nfs-utils/nfs-utils_1.0.6.bb b/packages/nfs-utils/nfs-utils_1.0.6.bb index 17bc5a6f9f..4f5e64b352 100644 --- a/packages/nfs-utils/nfs-utils_1.0.6.bb +++ b/packages/nfs-utils/nfs-utils_1.0.6.bb @@ -1,9 +1,9 @@ DESCRIPTION = "userspace utilities for kernel nfs" PRIORITY = "optional" -SECTION = "console/networking" +SECTION = "console/network" MAINTAINER = "dyoung " LICENSE = "GPL" -PR = "r5" +PR = "r6" SRC_URI = "${SOURCEFORGE_MIRROR}/nfs/nfs-utils-${PV}.tar.gz \ file://acinclude-lossage.patch;patch=1 \ -- cgit v1.2.3 From 3e688c76d26f9a04cef8b719e433220a4691575e Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Fri, 25 Aug 2006 11:11:23 +0000 Subject: feed-browser: forgotten structure change --- contrib/feed-browser/includes/functions.inc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contrib/feed-browser/includes/functions.inc b/contrib/feed-browser/includes/functions.inc index 77afca6f5e..4b0b898118 100644 --- a/contrib/feed-browser/includes/functions.inc +++ b/contrib/feed-browser/includes/functions.inc @@ -426,9 +426,10 @@ function check_database() if (db_table_exists ($db, 'feeds') === FALSE) { sqlite_query ($db, "CREATE TABLE feeds ( - f_name varchar(20), + f_id int(8), + f_name varchar(32), f_uri varchar(100), - f_comments varchar(500))"); + f_comments varchar(500))"); insert_feeds ($db) ; } -- cgit v1.2.3 From 62873b87b2c414f7101d2765f59870e9b5d79e0a Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 25 Aug 2006 11:28:13 +0000 Subject: xserver-kdrive git: fix packaging so Security Policy ends up in the rootfs --- packages/xorg-xserver/xserver-kdrive_git.bb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/xorg-xserver/xserver-kdrive_git.bb b/packages/xorg-xserver/xserver-kdrive_git.bb index 90fa12aebb..aa5784e1c7 100644 --- a/packages/xorg-xserver/xserver-kdrive_git.bb +++ b/packages/xorg-xserver/xserver-kdrive_git.bb @@ -1,22 +1,30 @@ PV = "1.1.0+git${SRCDATE}" DEFAULT_PREFERENCE = "-2" +PR = "r1" + LICENSE = "MIT" DEPENDS = "tslib libxkbfile xf86dgaproto xf86vidmodeproto xf86miscproto xproto libxdmcp xextproto xtrans libxau virtual/libx11 libxext libxrandr fixesproto damageproto libxfont resourceproto compositeproto xcalibrateext recordproto videoproto scrnsaverproto" PROVIDES = "virtual/xserver" RPROVIDES = "virtual/xserver" -PACKAGES = "xserver-kdrive-fbdev xserver-kdrive-fake xserver-kdrive-xephyr ${PN}-doc ${PN}-dev ${PN}-locale" +PACKAGES =+ "xserver-kdrive-fbdev xserver-kdrive-fake xserver-kdrive-xephyr ${PN}-doc ${PN}-dev ${PN}-locale" SECTION = "x11/base" DESCRIPTION = "X server from freedesktop.org" DESCRIPTION_xserver-kdrive-fbdev = "X server from freedesktop.org, supporting generic framebuffer devices" DESCRIPTION_xserver-kdrive-fake = "Fake X server" DESCRIPTION_xserver-kdrive-xephyr = "X server in an X window" +FILES_${PN} += "${libdir}/xserver/SecurityPolicy" + FILES_xserver-kdrive-fbdev = "${bindir}/Xfbdev" FILES_xserver-kdrive-fake = "${bindir}/Xfake" FILES_xserver-kdrive-xephyr = "${bindir}/Xephyr" +RDEPENDS_xserver-kdrive-fbdev = "${PN}" +RDEPENDS_xserver-kdrive-fake = "${PN}" +RDEPENDS_xserver-kdrive-xephyr = "${PN}" + SRC_URI = "git://anongit.freedesktop.org/xorg/xserver;protocol=git \ file://kmode.patch;patch=1 \ file://disable-apm.patch;patch=1 \ -- cgit v1.2.3 From 5855ee2bfcfe65a2e57723d1fcd299a1c86685cf Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Fri, 25 Aug 2006 12:50:17 +0000 Subject: libvncserver: depends on libxext --- packages/libvncserver/libvncserver_0.8.2.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/libvncserver/libvncserver_0.8.2.bb b/packages/libvncserver/libvncserver_0.8.2.bb index 480a888745..8ceec7e62a 100644 --- a/packages/libvncserver/libvncserver_0.8.2.bb +++ b/packages/libvncserver/libvncserver_0.8.2.bb @@ -6,7 +6,7 @@ MAINTAINER = "Patrik Gfeller " SECTION = "libs" PRIORITY = "optional" PROVIDES = "x11vnc" -DEPENDS = "virtual/libsdl virtual/libx11 zlib jpeg" +DEPENDS = "virtual/libsdl virtual/libx11 zlib jpeg libxext" PR = "r2" SRC_URI = "${SOURCEFORGE_MIRROR}/libvncserver/LibVNCServer-${PV}.tar.gz;md5sum=17a18e398af6c1730f72068022a152aa" -- cgit v1.2.3 From 06d323b74ee2c9c83684bbafd7b8362525e82ae2 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Fri, 25 Aug 2006 12:56:23 +0000 Subject: contrib/python: add the script that I use to generate the python manifest file --- contrib/python/.mtn2git_empty | 0 contrib/python/generate-manifest.py | 278 ++++++++++++++++++++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 contrib/python/.mtn2git_empty create mode 100755 contrib/python/generate-manifest.py diff --git a/contrib/python/.mtn2git_empty b/contrib/python/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/contrib/python/generate-manifest.py b/contrib/python/generate-manifest.py new file mode 100755 index 0000000000..9eb3522682 --- /dev/null +++ b/contrib/python/generate-manifest.py @@ -0,0 +1,278 @@ +#!/usr/bin/env python + +# generate Python Manifest for the OpenEmbedded build system +# (C) 2002-2006 Michael Lauer +# MIT license + +import os +import sys +import time + +# major version +VERSION = "2.4.0" +# increase when touching python-core +BASEREV = 1 + +__author__ = "Michael 'Mickey' Lauer " +__version__ = "$Revision: 1.6 $" + +class MakefileMaker: + + def __init__( self, outfile ): + """initialize""" + self.packages = {} + self.sourcePrefix = "/lib/python%s/" % VERSION[:3] + self.targetPrefix = "${libdir}/python%s" % VERSION[:3] + self.output = outfile + self.out( "### AUTO-GENERATED by '%s' [(C) 2002-2006 Michael Lauer] on %s" % ( sys.argv[0], time.asctime() ) ) + self.out( "###" ) + self.out( "### Warning: Manual edits will be lost!" ) + self.out( "###" ) + # + # helper functions + # + + def out( self, data ): + """print a line to the output file""" + print >> self.output, data + + def setPrefix( self, sourcePrefix, targetPrefix ): + """set a file prefix for addPackage files""" + self.sourcePrefix = sourcePrefix + self.targetPrefix = targetPrefix + + def doProlog( self ): + self.out( """ """ ) + self.out( "" ) + + def addPackage( self, revision, name, description, dependencies, filenames ): + """add a package to the Makefile""" + if type( filenames ) == type( "" ): + filenames = filenames.split() + fullFilenames = [] + for filename in filenames: + if filename[0] != "/": + fullFilenames.append( ( "%s%s" % ( self.sourcePrefix, filename ), "%s%s" % ( self.targetPrefix, filename ) ) ) + else: + fullFilenames.append( ( filename, filename ) ) + self.packages[name] = revision, description, dependencies, fullFilenames + + def doBody( self ): + """generate body of Makefile""" + + global VERSION + + # + # generate package line + # + + packageLine = 'PACKAGES="' + for name in self.packages: + packageLine += "%s " % name + packageLine += '"' + + self.out( packageLine ) + self.out( "" ) + + # + # generate package variables + # + + for name, data in self.packages.iteritems(): + rev, desc, deps, files = data + + # + # write out the description, revision and dependencies + # + self.out( 'DESCRIPTION_%s="%s"' % ( name, desc ) ) + self.out( 'PR_%s="ml%d"' % ( name, rev + BASEREV ) ) + self.out( 'RDEPENDS_%s="%s"' % ( name, deps.replace( ",", "" ) ) ) + + line = 'FILES_%s="' % name + + # + # check which directories to make in the temporary directory + # + + dirset = {} # if python had a set-datatype this would be sufficient. for now, we're using a dict instead. + for source, target in files: + dirset[os.path.dirname( target )] = True + + # + # generate which files to copy for the target (-dfR because whole directories are also allowed) + # + + for source, target in files: + line += "%s " % target + + line += '"' + self.out( line ) + +# for source, target in files: +# if ( source.find( "lib-dynload" ) != -1 ) or \ +# ( source.endswith( "python" ) ) or \ +# ( source.endswith( "pydoc" ) ): # MACHDEP +# self.out( "\t cp -dfR $(STAGING_LIBDIR)/..%s $(IPKTMP_DIR)%s/;" % ( source, os.path.dirname( target ) ) ) +# else: +# self.out( "\t cp -dfR $(STAGING_DIR)%s $(IPKTMP_DIR)%s/;" % ( source, os.path.dirname( target ) ) ) +# + self.out( "" ) + + def doEpilog( self ): + self.out( """""" ) + self.out( "" ) + + def make( self ): + self.doProlog() + self.doBody() + self.doEpilog() + +if __name__ == "__main__": + + if len( sys.argv ) > 1: + os.popen( "rm -f ./%s" % sys.argv[1] ) + outfile = file( sys.argv[1], "w" ) + else: + outfile = sys.stdout + + m = MakefileMaker( outfile ) + + # Add packages here. + # Note: Only supply dlopen link library dependencies here. Aautomatic link libraries are getting added by the shlibs dependency code + + m.setPrefix( "/", "/usr/" ) + + m.addPackage( 1, "python-core", "Python Interpreter and core modules (needed!)", "", + "lib/python2.4/__future__.* lib/python2.4/copy.* lib/python2.4/copy_reg.* lib/python2.4/ConfigParser.py " + + "lib/python2.4/getopt.* lib/python2.4/new.* " + + "lib/python2.4/os.* lib/python2.4/posixpath.* "+ + "lib/python2.4/warnings.* lib/python2.4/site.* lib/python2.4/stat.* lib/python2.4/UserDict.* " + + "lib/python2.4/lib-dynload/binascii.so lib/python2.4/lib-dynload/struct.so lib/python2.4/lib-dynload/time.so " + + "lib/python2.4/lib-dynload/xreadlines.so lib/python2.4/types.* bin/python" ) + + m.addPackage( 1, "python-pydoc", "Python Interactive Help Support", "python-core, python-lang, python-stringold, python-re", + "bin/pydoc lib/python2.4/pydoc.*" ) + + m.setPrefix( "/lib/python2.4/", "${libdir}/python2.4/" ) + + m.addPackage( 1, "python-audio", "Python Audio Handling", "python-core", + "wave.* chunk.* lib-dynload/ossaudiodev.so lib-dynload/audioop.so" ) + + m.addPackage( 1, "python-codecs", "Python Codecs, Encodings & i18n Support", "python-core", + "codecs.* encodings locale.* lib-dynload/_locale.so lib-dynload/unicodedata.so gettext.* xdrlib.*" ) + + m.addPackage( 1, "python-compile", "Python Bytecode Compilation Support", "python-core", + "py_compile.* compileall.*" ) + + m.addPackage( 1, "python-compiler", "Python Compiler Support", "python-core", + "compiler" ) # package + + m.addPackage( 1, "python-compression", "Python High Level Compression Support", "python-core, python-zlib", + "gzip.* zipfile.*" ) + + m.addPackage( 1, "python-crypt", "Python Basic Cryptographic and Hashing Support", "python-core", + "lib-dynload/crypt.so lib-dynload/md5.so lib-dynload/rotor.so lib-dynload/sha.so" ) + + m.addPackage( 1, "python-textutils", "Python Option Parsing, Text Wrapping and Comma-Separated-Value Support", "python-core, python-io, python-re, python-stringold", + "lib-dynload/_csv.so csv.* optparse.* textwrap.*" ) + + m.addPackage( 1, "python-curses", "Python Curses Support", "python-core", + "curses lib-dynload/_curses.so lib-dynload/_curses_panel.so" ) # package + + m.addPackage( 1, "python-db", "Python File-Based Database Support", "python-core", + "anydbm.* dumbdbm.* whichdb.* " ) + + m.addPackage( 1, "python-distutils", "Python Distribution Utility", "python-core", + "distutils" ) # package + + m.addPackage( 1, "python-email", "Python Email Support", "python-core, python-io, python-re", + "email" ) # package + + m.addPackage( 1, "python-fcntl", "Python's fcntl Interface", "python-core", + "lib-dynload/fcntl.so" ) + + m.addPackage( 1, "python-hotshot", "Python Hotshot Profiler", "python-core", + "hotshot lib-dynload/_hotshot.so" ) + + m.addPackage( 1, "python-html", "Python HTML Processing", "python-core", + "formatter.* htmlentitydefs.* htmllib.* markupbase.* sgmllib.* " ) + + m.addPackage( 1, "python-gdbm", "Python GNU Database Support", "python-core, libgdbm3", + "lib-dynload/gdbm.so" ) + + m.addPackage( 1, "python-image", "Python Graphical Image Handling", "python-core", + "colorsys.* imghdr.* lib-dynload/imageop.so lib-dynload/rgbimg.so" ) + + m.addPackage( 1, "python-io", "Python Low-Level I/O", "python-core, python-math", + "lib-dynload/_socket.so lib-dynload/select.so lib-dynload/termios.so lib-dynload/cStringIO.so pipes.* socket.* tempfile.* StringIO.* " ) + + m.addPackage( 2, "python-lang", "Python Low-Level Language Support", "python-core", + "lib-dynload/array.so lib-dynload/parser.so lib-dynload/operator.so lib-dynload/_weakref.so " + + "lib-dynload/itertools.so lib-dynload/collections.so " + + "atexit.* code.* codeop.* dis.* inspect.* keyword.* opcode.* repr.* token.* tokenize.* traceback.* linecache.* weakref.*" ) + + m.addPackage( 2, "python-math", "Python Math Support", "python-core", + "lib-dynload/cmath.so lib-dynload/math.so lib-dynload/_random.so random.* sets.*" ) + + m.addPackage( 1, "python-mime", "Python MIME Handling APIs", "python-core, python-io", + "mimetools.* rfc822.*" ) + + m.addPackage( 1, "python-mmap", "Python Memory-Mapped-File Support", "python-core, python-io", + "lib-dynload/mmap.so " ) + + m.addPackage( 1, "python-unixadmin", "Python Unix Administration Support", "python-core", + "lib-dynload/nis.so lib-dynload/grp.so lib-dynload/pwd.so getpass.*" ) + + m.addPackage( 1, "python-netclient", "Python Internet Protocol Clients", "python-core, python-io, python-mime", + "base64.* ftplib.* gopherlib.* hmac.* httplib.* mimetypes.* nntplib.* poplib.* smtplib.* telnetlib.* urllib.* urllib2.* urlparse.*" ) + + m.addPackage( 1, "python-netserver", "Python Internet Protocol Servers", "python-core, python-netclient", + "cgi.* BaseHTTPServer.* SimpleHTTPServer.* SocketServer.*" ) + + m.addPackage( 1, "python-pickle", "Python Persistence Support", "python-core, python-re", + "pickle.* shelve.* lib-dynload/cPickle.so" ) + + m.addPackage( 1, "python-pprint", "Python Pretty-Print Support", "python-core", + "pprint.*" ) + + # python-pyqt has its own subdirectory + + # python-pyxml has its own subdirectory + + m.addPackage( 1, "python-re", "Python Regular Expression APIs", "python-core, python-stringold", + "re.* sre.* sre_compile.* sre_constants* sre_parse.*" ) # _sre is builtin + + m.addPackage( 1, "python-readline", "Python Readline Support", "python-core, libreadline4", + "lib-dynload/readline.so rlcompleter.*" ) + + m.addPackage( 1, "python-resource", "Python Resource Control Interface", "python-core", + "lib-dynload/resource.so" ) + + m.addPackage( 1, "python-shell", "Python Shell-Like Functionality", "python-core, python-re", + "commands.* dircache.* fnmatch.* glob.* popen2.* shutil.*" ) + + m.addPackage( 1, "python-stringold", "Python Deprecated String APIs", "python-core", + "lib-dynload/strop.so string.*" ) + + m.addPackage( 1, "python-syslog", "Python's syslog Interface", "python-core", + "lib-dynload/syslog.so" ) + + m.addPackage( 1, "python-terminal", "Python Terminal Controlling Support", "python-core, python-io", + "pty.* tty.*" ) + + m.addPackage( 1, "python-threading", "Python Threading & Synchronization Support", "python-core, python-lang", + "bisect.* threading.* Queue.*" ) + + m.addPackage( 1, "python-unittest", "Python Unit Testing Framework", "python-core, python-stringold, python-lang", + "unittest.*" ) + + m.addPackage( 1, "python-xml", "Python basic XML support.", "python-core, python-re", + "lib-dynload/pyexpat.so xml xmllib.*" ) # package + + m.addPackage( 1, "python-xmlrpc", "Python XMLRPC Support", "python-core, python-xml, python-netserver, python-lang", + "xmlrpclib.* SimpleXMLRPCServer.*" ) + + m.addPackage( 2, "python-zlib", "Python zlib Support.", "python-core, libz1", + "lib-dynload/zlib.so" ) + + m.make() -- cgit v1.2.3 From e14eeb8bf649ac2479ccd1a5181b0e27c06ed8e2 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Fri, 25 Aug 2006 13:02:44 +0000 Subject: contrib/python/generate-manifest.py: update to latest version --- contrib/python/generate-manifest.py | 162 +++++++++++++++++++++++------------- 1 file changed, 105 insertions(+), 57 deletions(-) diff --git a/contrib/python/generate-manifest.py b/contrib/python/generate-manifest.py index 9eb3522682..2fd681dc01 100755 --- a/contrib/python/generate-manifest.py +++ b/contrib/python/generate-manifest.py @@ -8,13 +8,12 @@ import os import sys import time -# major version -VERSION = "2.4.0" +VERSION = "2.4.3" # increase when touching python-core -BASEREV = 1 +BASEREV = 0 __author__ = "Michael 'Mickey' Lauer " -__version__ = "$Revision: 1.6 $" +__version__ = "$Revision: 1.20 $" class MakefileMaker: @@ -24,10 +23,14 @@ class MakefileMaker: self.sourcePrefix = "/lib/python%s/" % VERSION[:3] self.targetPrefix = "${libdir}/python%s" % VERSION[:3] self.output = outfile - self.out( "### AUTO-GENERATED by '%s' [(C) 2002-2006 Michael Lauer] on %s" % ( sys.argv[0], time.asctime() ) ) + self.out( "#" * 120 ) + self.out( "### AUTO-GENERATED by '%s' [(C) 2002-2006 Michael 'Mickey' Lauer ] on %s" % ( sys.argv[0], time.asctime() ) ) + self.out( "###" ) + self.out( "### Visit THE Python for Embedded Systems Site => http://www.Vanille.de/projects/python.spy" ) self.out( "###" ) self.out( "### Warning: Manual edits will be lost!" ) self.out( "###" ) + self.out( "#" * 120 ) # # helper functions # @@ -62,6 +65,18 @@ class MakefileMaker: global VERSION + # + # generate provides line + # + + provideLine = 'PROVIDES+="' + for name in self.packages: + provideLine += "%s " % name + provideLine += '"' + + self.out( provideLine ) + self.out( "" ) + # # generate package line # @@ -137,142 +152,175 @@ if __name__ == "__main__": m = MakefileMaker( outfile ) - # Add packages here. - # Note: Only supply dlopen link library dependencies here. Aautomatic link libraries are getting added by the shlibs dependency code + # Add packages here. Only specify dlopen-style library dependencies here, no ldd-style dependencies! + # Parameters: revision, name, description, dependencies, filenames + # m.setPrefix( "/", "/usr/" ) m.addPackage( 1, "python-core", "Python Interpreter and core modules (needed!)", "", "lib/python2.4/__future__.* lib/python2.4/copy.* lib/python2.4/copy_reg.* lib/python2.4/ConfigParser.py " + - "lib/python2.4/getopt.* lib/python2.4/new.* " + - "lib/python2.4/os.* lib/python2.4/posixpath.* "+ - "lib/python2.4/warnings.* lib/python2.4/site.* lib/python2.4/stat.* lib/python2.4/UserDict.* " + + "lib/python2.4/getopt.* lib/python2.4/linecache.* lib/python2.4/new.* " + + "lib/python2.4/os.* lib/python2.4/posixpath.* " + + "lib/python2.4/warnings.* lib/python2.4/site.* lib/python2.4/stat.* " + + "lib/python2.4/UserDict.* lib/python2.4/UserList.* lib/python2.4/UserString.* " + "lib/python2.4/lib-dynload/binascii.so lib/python2.4/lib-dynload/struct.so lib/python2.4/lib-dynload/time.so " + "lib/python2.4/lib-dynload/xreadlines.so lib/python2.4/types.* bin/python" ) - m.addPackage( 1, "python-pydoc", "Python Interactive Help Support", "python-core, python-lang, python-stringold, python-re", + m.addPackage( 0, "python-devel", "Python Development Package", "python-core", + "include lib/python2.4/config" ) # package + + m.addPackage( 0, "python-idle", "Python Integrated Development Environment", "python-core, python-tkinter", + "bin/idle lib/python2.4/idlelib" ) # package + + m.addPackage( 0, "python-pydoc", "Python Interactive Help Support", "python-core, python-lang, python-stringold, python-re", "bin/pydoc lib/python2.4/pydoc.*" ) m.setPrefix( "/lib/python2.4/", "${libdir}/python2.4/" ) - m.addPackage( 1, "python-audio", "Python Audio Handling", "python-core", + m.addPackage( 0, "python-audio", "Python Audio Handling", "python-core", "wave.* chunk.* lib-dynload/ossaudiodev.so lib-dynload/audioop.so" ) - m.addPackage( 1, "python-codecs", "Python Codecs, Encodings & i18n Support", "python-core", - "codecs.* encodings locale.* lib-dynload/_locale.so lib-dynload/unicodedata.so gettext.* xdrlib.*" ) + m.addPackage( 0, "python-bsddb", "Python Berkeley Database Bindings", "python-core", + "bsddb" ) # package + + m.addPackage( 0, "python-codecs", "Python Codecs, Encodings & i18n Support", "python-core", + "codecs.* encodings gettext.* locale.* lib-dynload/_locale.so lib-dynload/unicodedata.so stringprep.* xdrlib.*" ) - m.addPackage( 1, "python-compile", "Python Bytecode Compilation Support", "python-core", + m.addPackage( 0, "python-compile", "Python Bytecode Compilation Support", "python-core", "py_compile.* compileall.*" ) - m.addPackage( 1, "python-compiler", "Python Compiler Support", "python-core", + m.addPackage( 0, "python-compiler", "Python Compiler Support", "python-core", "compiler" ) # package - m.addPackage( 1, "python-compression", "Python High Level Compression Support", "python-core, python-zlib", + m.addPackage( 0, "python-compression", "Python High Level Compression Support", "python-core, python-zlib", "gzip.* zipfile.*" ) - m.addPackage( 1, "python-crypt", "Python Basic Cryptographic and Hashing Support", "python-core", + m.addPackage( 0, "python-crypt", "Python Basic Cryptographic and Hashing Support", "python-core", "lib-dynload/crypt.so lib-dynload/md5.so lib-dynload/rotor.so lib-dynload/sha.so" ) - m.addPackage( 1, "python-textutils", "Python Option Parsing, Text Wrapping and Comma-Separated-Value Support", "python-core, python-io, python-re, python-stringold", + m.addPackage( 0, "python-textutils", "Python Option Parsing, Text Wrapping and Comma-Separated-Value Support", "python-core, python-io, python-re, python-stringold", "lib-dynload/_csv.so csv.* optparse.* textwrap.*" ) m.addPackage( 1, "python-curses", "Python Curses Support", "python-core", "curses lib-dynload/_curses.so lib-dynload/_curses_panel.so" ) # package - m.addPackage( 1, "python-db", "Python File-Based Database Support", "python-core", + m.addPackage( 0, "python-datetime", "Python Calendar and Time support", "python-core, python-codecs", + "_strptime.* calendar.* lib-dynload/datetime.so" ) + + m.addPackage( 0, "python-db", "Python File-Based Database Support", "python-core", "anydbm.* dumbdbm.* whichdb.* " ) - m.addPackage( 1, "python-distutils", "Python Distribution Utility", "python-core", - "distutils" ) # package + m.addPackage( 0, "python-distutils", "Python Distribution Utilities", "python-core", + "config distutils" ) # package - m.addPackage( 1, "python-email", "Python Email Support", "python-core, python-io, python-re", + m.addPackage( 0, "python-email", "Python Email Support", "python-core, python-io, python-re", "email" ) # package - m.addPackage( 1, "python-fcntl", "Python's fcntl Interface", "python-core", + m.addPackage( 0, "python-fcntl", "Python's fcntl Interface", "python-core", "lib-dynload/fcntl.so" ) - m.addPackage( 1, "python-hotshot", "Python Hotshot Profiler", "python-core", + m.addPackage( 0, "python-hotshot", "Python Hotshot Profiler", "python-core", "hotshot lib-dynload/_hotshot.so" ) - m.addPackage( 1, "python-html", "Python HTML Processing", "python-core", + m.addPackage( 0, "python-html", "Python HTML Processing", "python-core", "formatter.* htmlentitydefs.* htmllib.* markupbase.* sgmllib.* " ) - m.addPackage( 1, "python-gdbm", "Python GNU Database Support", "python-core, libgdbm3", + m.addPackage( 0, "python-gdbm", "Python GNU Database Support", "python-core, libgdbm3", "lib-dynload/gdbm.so" ) - m.addPackage( 1, "python-image", "Python Graphical Image Handling", "python-core", + m.addPackage( 0, "python-image", "Python Graphical Image Handling", "python-core", "colorsys.* imghdr.* lib-dynload/imageop.so lib-dynload/rgbimg.so" ) - m.addPackage( 1, "python-io", "Python Low-Level I/O", "python-core, python-math", - "lib-dynload/_socket.so lib-dynload/select.so lib-dynload/termios.so lib-dynload/cStringIO.so pipes.* socket.* tempfile.* StringIO.* " ) + m.addPackage( 0, "python-io", "Python Low-Level I/O", "python-core, python-math", + "lib-dynload/_socket.so lib-dynload/_ssl.so lib-dynload/select.so lib-dynload/termios.so lib-dynload/cStringIO.so " + "pipes.* socket.* tempfile.* StringIO.* " ) - m.addPackage( 2, "python-lang", "Python Low-Level Language Support", "python-core", + m.addPackage( 0, "python-lang", "Python Low-Level Language Support", "python-core", "lib-dynload/array.so lib-dynload/parser.so lib-dynload/operator.so lib-dynload/_weakref.so " + "lib-dynload/itertools.so lib-dynload/collections.so " + "atexit.* code.* codeop.* dis.* inspect.* keyword.* opcode.* repr.* token.* tokenize.* traceback.* linecache.* weakref.*" ) - m.addPackage( 2, "python-math", "Python Math Support", "python-core", + m.addPackage( 0, "python-logging", "Python Logging Support", "python-core", + "logging" ) # package + + m.addPackage( 0, "python-lib-old-and-deprecated", "Python Deprecated Libraries", "python-core", + "lib-old" ) # package + + m.addPackage( 0, "python-tkinter", "Python Tcl/Tk Bindings", "python-core", + "lib-dynload/_tkinter.so lib-tk" ) # package + + m.addPackage( 0, "python-math", "Python Math Support", "python-core", "lib-dynload/cmath.so lib-dynload/math.so lib-dynload/_random.so random.* sets.*" ) - m.addPackage( 1, "python-mime", "Python MIME Handling APIs", "python-core, python-io", - "mimetools.* rfc822.*" ) + m.addPackage( 0, "python-mime", "Python MIME Handling APIs", "python-core, python-io", + "mimetools.* quopri.* rfc822.*" ) - m.addPackage( 1, "python-mmap", "Python Memory-Mapped-File Support", "python-core, python-io", + m.addPackage( 0, "python-mmap", "Python Memory-Mapped-File Support", "python-core, python-io", "lib-dynload/mmap.so " ) - m.addPackage( 1, "python-unixadmin", "Python Unix Administration Support", "python-core", + m.addPackage( 0, "python-unixadmin", "Python Unix Administration Support", "python-core", "lib-dynload/nis.so lib-dynload/grp.so lib-dynload/pwd.so getpass.*" ) - m.addPackage( 1, "python-netclient", "Python Internet Protocol Clients", "python-core, python-io, python-mime", - "base64.* ftplib.* gopherlib.* hmac.* httplib.* mimetypes.* nntplib.* poplib.* smtplib.* telnetlib.* urllib.* urllib2.* urlparse.*" ) + m.addPackage( 1, "python-netclient", "Python Internet Protocol Clients", "python-core, python-datetime, python-io, python-lang, python-logging, python-mime", + "*Cookie*.* " + + "base64.* cookielib.* ftplib.* gopherlib.* hmac.* httplib.* mimetypes.* nntplib.* poplib.* smtplib.* telnetlib.* urllib.* urllib2.* urlparse.*" ) - m.addPackage( 1, "python-netserver", "Python Internet Protocol Servers", "python-core, python-netclient", + m.addPackage( 0, "python-netserver", "Python Internet Protocol Servers", "python-core, python-netclient", "cgi.* BaseHTTPServer.* SimpleHTTPServer.* SocketServer.*" ) - m.addPackage( 1, "python-pickle", "Python Persistence Support", "python-core, python-re", + m.addPackage( 0, "python-pickle", "Python Persistence Support", "python-core, python-codecs, python-re", "pickle.* shelve.* lib-dynload/cPickle.so" ) - m.addPackage( 1, "python-pprint", "Python Pretty-Print Support", "python-core", + m.addPackage( 0, "python-pprint", "Python Pretty-Print Support", "python-core", "pprint.*" ) - # python-pyqt has its own subdirectory + m.addPackage( 0, "python-profile", "Python Basic Profiling Support", "python-core", + "profile.* pstats.*" ) - # python-pyxml has its own subdirectory - - m.addPackage( 1, "python-re", "Python Regular Expression APIs", "python-core, python-stringold", + m.addPackage( 0, "python-re", "Python Regular Expression APIs", "python-core", "re.* sre.* sre_compile.* sre_constants* sre_parse.*" ) # _sre is builtin - m.addPackage( 1, "python-readline", "Python Readline Support", "python-core, libreadline4", + m.addPackage( 0, "python-readline", "Python Readline Support", "python-core, libreadline4", "lib-dynload/readline.so rlcompleter.*" ) - m.addPackage( 1, "python-resource", "Python Resource Control Interface", "python-core", + m.addPackage( 0, "python-resource", "Python Resource Control Interface", "python-core", "lib-dynload/resource.so" ) - m.addPackage( 1, "python-shell", "Python Shell-Like Functionality", "python-core, python-re", + m.addPackage( 0, "python-shell", "Python Shell-Like Functionality", "python-core, python-re", "commands.* dircache.* fnmatch.* glob.* popen2.* shutil.*" ) - m.addPackage( 1, "python-stringold", "Python Deprecated String APIs", "python-core", + m.addPackage( 0, "python-subprocess", "Python Subprocess Support", "python-core, python-io, python-re", + "subprocess.*" ) + + m.addPackage( 0, "python-stringold", "Python String APIs [deprecated]", "python-core, python-re", "lib-dynload/strop.so string.*" ) - m.addPackage( 1, "python-syslog", "Python's syslog Interface", "python-core", + m.addPackage( 0, "python-syslog", "Python's syslog Interface", "python-core", "lib-dynload/syslog.so" ) - m.addPackage( 1, "python-terminal", "Python Terminal Controlling Support", "python-core, python-io", + m.addPackage( 0, "python-terminal", "Python Terminal Controlling Support", "python-core, python-io", "pty.* tty.*" ) - m.addPackage( 1, "python-threading", "Python Threading & Synchronization Support", "python-core, python-lang", - "bisect.* threading.* Queue.*" ) + m.addPackage( 0, "python-tests", "Python Tests", "python-core", + "test" ) # package - m.addPackage( 1, "python-unittest", "Python Unit Testing Framework", "python-core, python-stringold, python-lang", + m.addPackage( 0, "python-threading", "Python Threading & Synchronization Support", "python-core, python-lang", + "_threading_local.* bisect.* dummy_thread.* dummy_threading.* mutex.* threading.* Queue.*" ) + + m.addPackage( 0, "python-unittest", "Python Unit Testing Framework", "python-core, python-stringold, python-lang", "unittest.*" ) - m.addPackage( 1, "python-xml", "Python basic XML support.", "python-core, python-re", + m.addPackage( 0, "python-xml", "Python basic XML support.", "python-core, python-re", "lib-dynload/pyexpat.so xml xmllib.*" ) # package - m.addPackage( 1, "python-xmlrpc", "Python XMLRPC Support", "python-core, python-xml, python-netserver, python-lang", + m.addPackage( 0, "python-xmlrpc", "Python XMLRPC Support", "python-core, python-xml, python-netserver, python-lang", "xmlrpclib.* SimpleXMLRPCServer.*" ) - m.addPackage( 2, "python-zlib", "Python zlib Support.", "python-core, libz1", + m.addPackage( 1, "python-zlib", "Python zlib Support.", "python-core", "lib-dynload/zlib.so" ) + m.addPackage( 0, "python-mailbox", "Python Mailbox Format Support", "python-core, python-mime", + "mailbox.*" ) + m.make() -- cgit v1.2.3 From 1b5f7764622b8f117f228a5ef0bb487a95a10092 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Fri, 25 Aug 2006 13:03:35 +0000 Subject: python-manifest: remove explicit rdependency on libncurses5 --- packages/python/python-2.4.3-manifest.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/python/python-2.4.3-manifest.inc b/packages/python/python-2.4.3-manifest.inc index 82c886658c..1d14654f85 100644 --- a/packages/python/python-2.4.3-manifest.inc +++ b/packages/python/python-2.4.3-manifest.inc @@ -1,5 +1,5 @@ ######################################################################################################################## -### AUTO-GENERATED by './generate-oe.py' [(C) 2002-2005 Michael 'Mickey' Lauer ] on Wed Aug 2 23:25:58 2006 +### AUTO-GENERATED by './generate-oe.py' [(C) 2002-2006 Michael 'Mickey' Lauer ] on Fri Aug 25 15:00:35 2006 ### ### Visit THE Python for Embedded Systems Site => http://www.Vanille.de/projects/python.spy ### @@ -148,8 +148,8 @@ RDEPENDS_python-netserver="python-core python-netclient" FILES_python-netserver="${libdir}/python2.4/cgi.* ${libdir}/python2.4/BaseHTTPServer.* ${libdir}/python2.4/SimpleHTTPServer.* ${libdir}/python2.4/SocketServer.* " DESCRIPTION_python-curses="Python Curses Support" -PR_python-curses="ml0" -RDEPENDS_python-curses="python-core libncurses5" +PR_python-curses="ml1" +RDEPENDS_python-curses="python-core" FILES_python-curses="${libdir}/python2.4/curses ${libdir}/python2.4/lib-dynload/_curses.so ${libdir}/python2.4/lib-dynload/_curses_panel.so " DESCRIPTION_python-syslog="Python's syslog Interface" -- cgit v1.2.3 From b9a8c3254310d3839dee97146c00ab0400543fbb Mon Sep 17 00:00:00 2001 From: Florian Boor Date: Fri, 25 Aug 2006 13:18:31 +0000 Subject: networkmanager: depend on libglade --- packages/networkmanager/networkmanager_0.6.4.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/networkmanager/networkmanager_0.6.4.bb b/packages/networkmanager/networkmanager_0.6.4.bb index d30a101bcb..e9c02ba3dd 100644 --- a/packages/networkmanager/networkmanager_0.6.4.bb +++ b/packages/networkmanager/networkmanager_0.6.4.bb @@ -4,7 +4,7 @@ LICENSE = "GPL" HOMEPAGE = "http://www.gnome.org" MAINTAINER = "Milan Plzik " PRIORITY = "optional" -DEPENDS = "libnl dbus dbus-glib libhal-nm libgpewidget gnome-keyring gconf-dbus wireless-tools" +DEPENDS = "libnl dbus dbus-glib libhal-nm libgpewidget gnome-keyring gconf-dbus wireless-tools libglade" RDEPENDS = "wpa-supplicant dhcdbd gnome-keyring hicolor-icon-theme" PR = "r1" -- cgit v1.2.3 From b152323dc21356129868e19d6a65804c10b7757d Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 25 Aug 2006 15:19:22 +0000 Subject: h4000: Use modutils 2.6. --- conf/machine/h4000.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/machine/h4000.conf b/conf/machine/h4000.conf index 410de9a100..41301c1721 100644 --- a/conf/machine/h4000.conf +++ b/conf/machine/h4000.conf @@ -11,6 +11,7 @@ PREFERRED_PROVIDER_xserver = "xserver-kdrive" PREFERRED_PROVIDER_virtual/kernel = "handhelds-pxa-2.6" ROOT_FLASH_SIZE = "32" +MODUTILS = "26" PCMCIA_MANAGER = "pcmciautils" BOOT_MODULES = " ${@linux_module_packages('${H4000_MODULES}', d)}" -- cgit v1.2.3 From 4b0d1a5487be990fcb99badadb8068283b9e1a06 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Fri, 25 Aug 2006 15:29:19 +0000 Subject: feed-browser: much better sectionlist (rewrite to be recursive anyone?) --- contrib/feed-browser/includes/functions.inc | 94 ++++++++++++++++------------- 1 file changed, 53 insertions(+), 41 deletions(-) diff --git a/contrib/feed-browser/includes/functions.inc b/contrib/feed-browser/includes/functions.inc index 4b0b898118..4745c75910 100644 --- a/contrib/feed-browser/includes/functions.inc +++ b/contrib/feed-browser/includes/functions.inc @@ -332,68 +332,80 @@ function sectionslist() if($result = db_query ("SELECT DISTINCT p_section FROM packages ORDER BY p_section")) { - $ipkgoutput = "
    \n"; + $section_up = ''; - $section_up = $result[0]['p_section']; - $section_level = FALSE; - $opie_top = FALSE; + $sections = array(); - foreach($result as $item) + foreach($result as $package) { - $section_name = $item['p_section']; + $section_split = explode('/', $package['p_section']); - if(0 === strpos($section_name, 'opie') AND !$opie_top) + if($section_up != $section_split[0]) { - $opie_top = TRUE; - - $section_up = 'opie'; + $section_up = $section_split[0]; } - elseif($opie_top AND 0 !== strpos($section_name, 'opie')) + + if(isset($section_split[1])) // x11/gnome/libs { - $opie_top = FALSE; + $sections[$section_up][$section_split[1]] = $section_split[1]; + + if(isset($section_split[2])) // x11/gnome/libs + { + $sections[ $section_up ][ $section_split[1] ] = array($section_split[2]=>$section_split[2]); + } } + } + + $output = "
      \n"; - if( - strpos($section_name, '/') // subsection - ) + foreach($sections as $section_name1=>$item) + { + $output .= sprintf ("
    • %s", + urlencode($section_name1), + urlencode($section_name1), + $section_name1); + + if(is_array($item)) { - if(0 === strpos($section_name, $section_up . '/')) // console/network are not part of console/net + $output .= '
        '; + + foreach($item as $section_name2=>$subitem) { - if(!$section_level) + $section_name = "{$section_name1}/{$section_name2}"; + $output .= sprintf ("
      • %s", + urlencode($section_name), + urlencode($section_name), + $section_name2); + + if(is_array($subitem)) { - $ipkgoutput .= '
        • '; + $output .= '
            '; + + foreach($subitem as $section_name3=>$subitem2) + { + $section_name = "{$section_name1}/{$section_name2}/{$section_name3}"; + $output .= sprintf ("
          • %s
          • ", + urlencode($section_name), + urlencode($section_name), + $section_name3); + } + + $output .= '
          '; } - $section_name = str_replace($section_up . '/', '', $item['p_section']); - $section_level = TRUE; + $output .= ''; } - } - elseif($section_level) - { - $section_up = $section_name; - $ipkgoutput .= '
      • '; - $section_level = FALSE; - } - else - { - $section_up = $section_name; + + $output .= '
      '; } - $ipkgoutput .= sprintf ("
    • %s
    • ", - urlencode($item['p_section']), - urlencode($item['p_section']), - $section_name); + $output .= ''; } - if($section_level) - { - $ipkgoutput .= '
    '; - } - - $ipkgoutput .= "
\n"; + $output .= "\n"; } - return $ipkgoutput; + return $output; } function check_database() -- cgit v1.2.3 From 31489e5e5023c60be052aa263c53d33ddfcb6742 Mon Sep 17 00:00:00 2001 From: Mustafa Yuecel Date: Fri, 25 Aug 2006 16:13:33 +0000 Subject: initscripts-1.0/slugos/devices.patch: adapt patch to the current devices file --- packages/initscripts/initscripts-1.0/slugos/devices.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/initscripts/initscripts-1.0/slugos/devices.patch b/packages/initscripts/initscripts-1.0/slugos/devices.patch index 26b1841d5b..2583b62f48 100644 --- a/packages/initscripts/initscripts-1.0/slugos/devices.patch +++ b/packages/initscripts/initscripts-1.0/slugos/devices.patch @@ -8,8 +8,8 @@ . /etc/default/rcS # exit without doing anything if udev is active --if test -e /dev/.udevdb; then -+if test -e /dev/.udevdb -o -e /dev/.permanent; then +-if test -e /dev/.udev -o -e /dev/.udevdb; then ++if test -e /dev/.udev -o -e /dev/.udevdb -o -e /dev/.permanent; then exit 0 fi -- cgit v1.2.3 From b3556207e1db3ecae008038a3d837959de12bc22 Mon Sep 17 00:00:00 2001 From: Mustafa Yuecel Date: Fri, 25 Aug 2006 16:32:16 +0000 Subject: avetanabt: add version 20060413 - cvs version: updated path to CVS repository, DEFAULT_PREFERENCE = "-1" --- packages/avetanabt/avetanabt_20060413.bb | 63 ++++++++++++++++++++++++++++++++ packages/avetanabt/avetanabt_cvs.bb | 8 ++-- 2 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 packages/avetanabt/avetanabt_20060413.bb diff --git a/packages/avetanabt/avetanabt_20060413.bb b/packages/avetanabt/avetanabt_20060413.bb new file mode 100644 index 0000000000..8472e0e0ce --- /dev/null +++ b/packages/avetanabt/avetanabt_20060413.bb @@ -0,0 +1,63 @@ +DESCRIPTION = "avetanaBT: Bluetooth API implementation for Java (JSR-82)" +SECTION = "devel" +DEPENDS = "findutils-native jikes-native kaffeh-native fastjar-native bluez-libs classpath" +MAINTAINER = "Mustafa Yuecel " +LICENSE = "GPL" +HOMEPAGE = "http://sourceforge.net/projects/avetanabt/" + +PR = "r0" + +SRC_URI = "${SOURCEFORGE_MIRROR}/avetanabt/avetanaBluetooth-${PV}.tgz" + +S = "${WORKDIR}/avetanabt" + +PACKAGES = "${PN}" +FILES_${PN} = "${libdir}/libavetanaBT.so ${datadir}/avetanabt/avetanaBT.jar" + +do_compile() { + + # doing nearly the same as in Makefile written... + + # clean build directory + mkdir -p build + rm -fr build/* + + # generate classes + # javac -> jikes + ${STAGING_BINDIR}/find {de,javax,com} -iname *.java > file.list + ${STAGING_BINDIR}/jikes -verbose --bootclasspath ${STAGING_DIR}/${BUILD_SYS}/share/kaffeh/rt.jar -d build @file.list + + # create own version.xml (add version information available at runtime) + head -n 4 version.xml >> build/version.xml + echo " " >> build/version.xml + tail -n 3 version.xml >> build/version.xml + + # move classes into jar archive + # jar -> fastjar + ${STAGING_BINDIR}/fastjar -v -cf avetanaBT.jar -C build de -C build javax -C build com -C build version.xml + + # JNI generated header file - de_avetana_bluetooth_stack_BlueZ.h + # javah -> kaffeh + ${STAGING_BINDIR}/kaffeh -jni -classpath avetanaBT.jar:${STAGING_DIR}/${BUILD_SYS}/share/kaffeh/rt.jar -d c de.avetana.bluetooth.stack.BlueZ + + # Native language (C) library - libavetanaBT.so + ${CXX} ${CXXFLAGS} -shared -lbluetooth -I${STAGING_INCDIR}/classpath c/BlueZ.cpp -o libavetanaBT.so ${LDFLAGS} + +} + +do_stage() { + + install -d ${STAGING_DIR}/${BUILD_SYS}/share/avetanabt + install avetanaBT.jar ${STAGING_DIR}/${BUILD_SYS}/share/avetanabt/ + +} + +do_install() { + + install -d ${D}${libdir} + install -m 0755 libavetanaBT.so ${D}${libdir}/ + + install -d ${D}${datadir}/avetanabt + install avetanaBT.jar ${D}${datadir}/avetanabt/ + +} diff --git a/packages/avetanabt/avetanabt_cvs.bb b/packages/avetanabt/avetanabt_cvs.bb index 7f6bea2a20..c25699caf0 100644 --- a/packages/avetanabt/avetanabt_cvs.bb +++ b/packages/avetanabt/avetanabt_cvs.bb @@ -5,10 +5,12 @@ MAINTAINER = "Mustafa Yuecel " LICENSE = "GPL" HOMEPAGE = "http://sourceforge.net/projects/avetanabt/" -PV = "0.0+cvs${SRCDATE}" -PR = "r3" +DEFAULT_PREFERENCE = "-1" -SRC_URI = "cvs://anonymous@cvs.sourceforge.net/cvsroot/avetanabt;module=avetanabt" +PV = "20060413+cvs${SRCDATE}" +PR = "r5" + +SRC_URI = "cvs://anonymous@avetanabt.cvs.sourceforge.net/cvsroot/avetanabt;module=avetanabt" S = "${WORKDIR}/avetanabt" -- cgit v1.2.3 From 0d607195ebad2d7b4ccd2fc985e9daaf2dd70b80 Mon Sep 17 00:00:00 2001 From: Mustafa Yuecel Date: Fri, 25 Aug 2006 17:25:34 +0000 Subject: subversion: add (disabled) version 1.3.2 - DEFAULT_PREFERENCE = "-1" due to errors on stage phase - bug report follows soon --- packages/subversion/subversion_1.3.2.bb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 packages/subversion/subversion_1.3.2.bb diff --git a/packages/subversion/subversion_1.3.2.bb b/packages/subversion/subversion_1.3.2.bb new file mode 100644 index 0000000000..f508381d15 --- /dev/null +++ b/packages/subversion/subversion_1.3.2.bb @@ -0,0 +1,23 @@ +DESCRIPTION = "The Subversion (svn) client" +SECTION = "console/network" +DEPENDS = "apr-util-0.9.12 neon" +MAINTAINER = "Mustafa Yuecel " +LICENSE = "Apache/BSD" +HOMEPAGE = "http://subversion.tigris.org" +PR = "r0" + +DEFAULT_PREFERENCE = "-1" + +SRC_URI = "http://subversion.tigris.org/downloads/${P}.tar.bz2 \ + file://disable-revision-install.patch;patch=1" + +EXTRA_OECONF = "--with-neon=${STAGING_DIR}/${BUILD_SYS} \ + --without-berkeley-db --without-apxs --without-apache \ + --without-swig --with-apr=${STAGING_BINDIR} \ + --with-apr-util=${STAGING_BINDIR}" + +inherit autotools + +do_configure() { + oe_runconf +} -- cgit v1.2.3 From 0b914dfc958842c1959290d9d14eaf498582b18d Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 25 Aug 2006 17:56:44 +0000 Subject: omap5912conf : Fix preferred version variables * use linux-omap1_2.6.12-rc2 for now * prepare to use linux-omap1_2.6.17-omap1 when it works --- conf/machine/omap5912osk.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conf/machine/omap5912osk.conf b/conf/machine/omap5912osk.conf index 49ea6f6b90..a2c01add5d 100644 --- a/conf/machine/omap5912osk.conf +++ b/conf/machine/omap5912osk.conf @@ -10,6 +10,8 @@ PREFERRED_PROVIDER_virtual/kernel = "linux-omap1" PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}depmod:module-init-tools-cross" PREFERRED_VERSION_u-boot = "LABEL.2006.06.30.2020" +#PREFERRED_VERSION_linux-omap1 = "2.6.17-omap1" +PREFERRED_VERSION_linux-omap1 = "2.6.12-rc2" BOOTSTRAP_EXTRA_RDEPENDS += "modutils-collateral" -- cgit v1.2.3 From d03fe953c4afa07e1200a3705ab86e6f3d3586e8 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 25 Aug 2006 17:58:17 +0000 Subject: distro/openomap.conf : Update toolchain versions --- conf/distro/openomap.conf | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/conf/distro/openomap.conf b/conf/distro/openomap.conf index 192400b9a1..fb06ca7f47 100644 --- a/conf/distro/openomap.conf +++ b/conf/distro/openomap.conf @@ -9,3 +9,26 @@ TARGET_FPU ?= "soft" # 2.4 vs 2.6 is a distro decision. MODUTILS = "26" BOOTSTRAP_EXTRA_RDEPENDS += "udev" + +PREFERRED_PROVIDER_task-bootstrap = "task-bootstrap" + +PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}gcc-initial:gcc-cross-initial" +PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}gcc:gcc-cross" +PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}g++:gcc-cross" + +#EABI stuff +PREFERRED_PROVIDER_virtual/${TARGET_PREFIX}-libc-for-gcc = "glibc-intermediate" +PREFERRED_PROVIDER_virtual/arm-angstrom-linux-gnueabi-libc-for-gcc = "glibc-intermediate" +PREFERRED_PROVIDER_virtual/arm-linux-libc-for-gcc = "glibc-intermediate" + + +#use EABI toolchain +PREFERRED_VERSION_gcc ?= "4.1.1" +PREFERRED_VERSION_gcc-cross ?= "4.1.1" +PREFERRED_VERSION_gcc-cross-initial ?= "4.1.1" +PREFERRED_VERSION_binutils ?= "2.17" +PREFERRED_VERSION_binutils-cross ?= "2.17" +PREFERRED_VERSION_linux-libc-headers ?= "2.6.15.99" +PREFERRED_VERSION_glibc ?= "2.4" +PREFERRED_VERSION_glibc-intermediate ?= "2.4" + -- cgit v1.2.3 From 4f1963886d9d2227be98a4473ceefc9c1011d1fd Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Fri, 25 Aug 2006 18:03:06 +0000 Subject: linux-omap1_2.6.12-rc2.bb : Fixes so it builds reliably * add dependency on u-boot * Fix do_deploy to massage kernel for use on omap5912osk board --- packages/linux/linux-omap1_2.6.12-rc2.bb | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/linux/linux-omap1_2.6.12-rc2.bb b/packages/linux/linux-omap1_2.6.12-rc2.bb index 7ea9e16091..46e7d0ba95 100644 --- a/packages/linux/linux-omap1_2.6.12-rc2.bb +++ b/packages/linux/linux-omap1_2.6.12-rc2.bb @@ -14,7 +14,7 @@ KERNEL_IMAGETYPE = "vmlinux" KERNEL_OUTPUT = "arch/${ARCH}/boot/compressed/${KERNEL_IMAGETYPE}" KERNEL_CCSUFFIX = "-3.3.4" -#DEPENDS = "uboot" +DEPENDS = "u-boot" inherit kernel @@ -25,13 +25,17 @@ do_configure_prepend() { oe_runmake oldconfig } -do_deploy_omap5912osk() { - install -d ${DEPLOY_DIR_IMAGE} - arm-linux-objcopy -O binary -R .note -R .comment -S arch/arm/boot/compressed/vmlinux ${DEPLOY_DIR}/linux.bin - gzip -f -9 ${DEPLOY_DIR}/linux.bin - mkimage -A arm -O linux -T kernel -C gzip -a 0x10c08000 -e 0x10c08000 -n "OE" -d ${DEPLOY_DIR}/linux.bin.gz ${DEPLOY_DIR}/uImage_bb.cc - cp ${DEPLOY_DIR}/uImage_bb.cc /tftpboot -# install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${MACHINE}-${DATETIME}.bin +do_deploy() { + if [ "${MACHINE}" == "omap5912osk" ]; then + install -d ${DEPLOY_DIR_IMAGE} + arm-linux-objcopy -O binary -R .note -R .comment -S arch/arm/boot/compressed/vmlinux ${DEPLOY_DIR_IMAGE}/linux.bin + gzip -f -9 ${DEPLOY_DIR_IMAGE}/linux.bin + mkimage -A arm -O linux -T kernel -C gzip -a 0x10c08000 -e 0x10c08000 -n "OE" -d ${DEPLOY_DIR_IMAGE}/linux.bin.gz ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${MACHINE}-${DATETIME}.bin + rm ${DEPLOY_DIR_IMAGE}/linux.bin.gz + +# cp ${DEPLOY_DIR}/uImage_bb.cc /tftpboot +# install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${MACHINE}-${DATETIME}.bin + fi } -- cgit v1.2.3 From 6bdb98734e08cf7f1adb65a39ddfc108b1e85b45 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 25 Aug 2006 18:14:28 +0000 Subject: classes: run do_package before do_stage so we can populate staging with package if we want --- classes/base.bbclass | 6 ++---- classes/package.bbclass | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/classes/base.bbclass b/classes/base.bbclass index 6f8468b119..f936dff870 100644 --- a/classes/base.bbclass +++ b/classes/base.bbclass @@ -601,8 +601,6 @@ base_do_compile() { fi } - -addtask stage after do_compile base_do_stage () { : } @@ -614,13 +612,13 @@ do_populate_staging[dirs] = "${STAGING_DIR}/${TARGET_SYS}/bin ${STAGING_DIR}/${T ${STAGING_DATADIR} \ ${S} ${B}" -addtask populate_staging after do_compile +addtask populate_staging after do_package python do_populate_staging () { bb.build.exec_func('do_stage', d) } -addtask install after do_compile +addtask install after do_compile do_install[dirs] = "${S} ${B}" base_do_install() { diff --git a/classes/package.bbclass b/classes/package.bbclass index 0d6a7734af..d6f50fb49d 100644 --- a/classes/package.bbclass +++ b/classes/package.bbclass @@ -738,4 +738,4 @@ do_package[dirs] = "${D}" do_package[deptask] = "do_package" populate_packages[dirs] = "${D}" EXPORT_FUNCTIONS do_package do_shlibs do_split_locales mapping_rename_hook -addtask package before do_build after do_populate_staging +addtask package before do_build after do_install -- cgit v1.2.3 From 302b477c6e599fec386e4c66adcfbf38e427217e Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 26 Aug 2006 11:39:30 +0000 Subject: pango 1.14: add appropriate PACKAGES_DYNAMIC to stop bitbake trunk from building pango 1.10 to satisfy dependencies on pango-module-* --- packages/pango/pango_1.14.0.bb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/pango/pango_1.14.0.bb b/packages/pango/pango_1.14.0.bb index 77eee85214..19fc1d7a92 100644 --- a/packages/pango/pango_1.14.0.bb +++ b/packages/pango/pango_1.14.0.bb @@ -7,6 +7,8 @@ Open Source framework for the layout and rendering of \ internationalized text." PR = "r0" +PACKAGES_DYNAMIC = "pango-module-*" + RRECOMMENDS_${PN} = "pango-module-basic-x pango-module-basic-fc" # seems to go wrong with default cflags @@ -26,11 +28,7 @@ FILES_${PN} = "/etc ${bindir} ${libdir}/libpango*.so.*" LIBV = "1.5.0" do_stage () { - for lib in pango pangox pangoft2 pangoxft pangocairo; do - oe_libinstall -so -C pango lib$lib-1.0 ${STAGING_LIBDIR}/ - done - install -d ${STAGING_INCDIR}/pango - install -m 0644 ${S}/pango/pango*.h ${STAGING_INCDIR}/pango/ + autotools_stage_all } postinst_prologue() { -- cgit v1.2.3 From 0b32edd66ab6a06eaad0b2c749d385a686ca8ffc Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sat, 26 Aug 2006 13:52:23 +0000 Subject: avahi: add 0.6.13 --- packages/avahi/avahi_0.6.13.bb | 64 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 packages/avahi/avahi_0.6.13.bb diff --git a/packages/avahi/avahi_0.6.13.bb b/packages/avahi/avahi_0.6.13.bb new file mode 100644 index 0000000000..7584a02514 --- /dev/null +++ b/packages/avahi/avahi_0.6.13.bb @@ -0,0 +1,64 @@ +DESCRIPTION = "Avahi implements the DNS-SD over Multicast DNS" +SECTION = "network" +PRIORITY = "optional" +AUTHOR = "Lennart Poettering " +HOMEPAGE = "http://avahi.org" +MAINTAINER = "Philipp Zabel " +LICENSE= "GPL" +PR = "r0" + +DEPENDS = "expat libdaemon dbus" +RRECOMMENDS = "libnss-mdns" + +SRC_URI = "http://avahi.org/download/avahi-${PV}.tar.gz" + +PACKAGES =+ "avahi-daemon libavahi-common libavahi-core libavahi-client avahi-dnsconfd libavahi-glib avahi-dev avahi-doc avahi-utils" + +FILES_libavahi-common = "${libdir}/libavahi-common.so.*" +FILES_libavahi-core= "${libdir}/libavahi-core.so.*" +FILES_avahi-daemon = "${sbindir}/avahi-daemon \ + ${sysconfdir}/avahi/avahi-daemon.conf \ + ${sysconfdir}/avahi/hosts \ + ${sysconfdir}/avahi/services \ + ${sysconfdir}/dbus-1 \ + ${sysconfdir}/init.d/avahi-daemon \ + ${datadir}/avahi/introspection/*.introspect \ + ${datadir}/avahi/avahi-service.dtd \ + ${datadir}/avahi/service-types" +FILES_libavahi-client = "${libdir}/libavahi-client.so.*" +FILES_avahi-dnsconfd = "${sbindir}/avahi-dnsconfd \ + ${sysconfdir}/avahi/avahi-dnsconfd.action \ + ${sysconfdir}/init.d/avahi-dnsconfd" +FILES_libavahi-glib = "${libdir}/libavahi-glib.so.*" +FILES_avahi-utils = "${bindir}/avahi-*" + +CONFFILES_avahi-daemon = "${sysconfdir}/avahi/avahi-daemon.conf" + +EXTRA_OECONF = "--with-distro=debian --disable-gdbm --disable-gtk --disable-mono --disable-monodoc --disable-qt3 --disable-qt4 --disable-python" +inherit autotools pkgconfig update-rc.d + + +do_stage() { + autotools_stage_all +} + +INITSCRIPT_PACKAGES = "avahi-daemon avahi-dnsconfd" +INITSCRIPT_NAME_avahi-daemon = "avahi-daemon" +INITSCRIPT_PARAMS_avahi-daemon = "defaults 21 19" +INITSCRIPT_NAME_avahi-dnsconfd = "avahi-dnsconfd" +INITSCRIPT_PARAMS_avahi-dnsconfd = "defaults 22 19" + +pkg_postinst_avahi-daemon () { + # can't do this offline + if [ "x$D" != "x" ]; then + exit 1 + fi + grep avahi /etc/group || addgroup avahi + grep avahi /etc/passwd || adduser --disabled-password --system --home /var/run/avahi-daemon --no-create-home avahi --ingroup avahi -g Avahi + /etc/init.d/dbus-1 force-reload +} + +pkg_postrm_avahi-daemon () { + deluser avahi || true + delgroup avahi || true +} -- cgit v1.2.3 From f7f1ac27e90f042fa1c4322b193b5b6a27cd4c07 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 26 Aug 2006 14:02:37 +0000 Subject: busybox 1.2.1: replace mv with a non-gnu-ish cp --- packages/busybox/busybox_1.2.1.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/busybox/busybox_1.2.1.bb b/packages/busybox/busybox_1.2.1.bb index 8b399f1626..741df3f62d 100644 --- a/packages/busybox/busybox_1.2.1.bb +++ b/packages/busybox/busybox_1.2.1.bb @@ -74,7 +74,7 @@ do_install () { install -d ${D}/busybox ls ${D} -R - mv ${D}${base_bindir} ${D}${base_sbindir} ${D}${prefix} ${D}/busybox/ + cp -dPr ${D}${base_bindir} ${D}${base_sbindir} ${D}${prefix} ${D}/busybox/ # Move the busybox binary back to /bin install -d ${D}${base_bindir} mv ${D}/busybox${base_bindir}/busybox ${D}${base_bindir}/ -- cgit v1.2.3 From 295f7fdd9aa9556b023d3e7cce312ed33d251020 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 26 Aug 2006 14:28:29 +0000 Subject: db-native: make sure do_package() is empty --- packages/db/db-native_4.3.29.bb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/db/db-native_4.3.29.bb b/packages/db/db-native_4.3.29.bb index 12a875ff13..aac4e2021b 100644 --- a/packages/db/db-native_4.3.29.bb +++ b/packages/db/db-native_4.3.29.bb @@ -10,4 +10,8 @@ inherit native require db_${PV}.bb +do_package() { +: +} + PACKAGES = "" -- cgit v1.2.3 From 0814eff011ab9a23abc7681b4236b05b5b9927df Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sat, 26 Aug 2006 16:49:16 +0000 Subject: qemu: Add arm nptl patch (as used in scratchbox) to fix EABI locale generation, add version 0.8.2, apply patches to some fixed verisons --- packages/qemu/files/arm_nptl.patch | 857 ++++++++++++++++++++++++++++++++ packages/qemu/qemu-0.8.0/.mtn2git_empty | 0 packages/qemu/qemu-0.8.0/arm_nptl.patch | 854 +++++++++++++++++++++++++++++++ packages/qemu/qemu-0.8.2/.mtn2git_empty | 0 packages/qemu/qemu-0.8.2/arm_nptl.patch | 857 ++++++++++++++++++++++++++++++++ packages/qemu/qemu-native_0.8.0.bb | 1 + packages/qemu/qemu-native_0.8.2.bb | 6 + packages/qemu/qemu_0.8.0.bb | 5 +- packages/qemu/qemu_0.8.2.bb | 9 + packages/qemu/qemu_cvs.bb | 5 +- 10 files changed, 2591 insertions(+), 3 deletions(-) create mode 100644 packages/qemu/files/arm_nptl.patch create mode 100644 packages/qemu/qemu-0.8.0/.mtn2git_empty create mode 100644 packages/qemu/qemu-0.8.0/arm_nptl.patch create mode 100644 packages/qemu/qemu-0.8.2/.mtn2git_empty create mode 100644 packages/qemu/qemu-0.8.2/arm_nptl.patch create mode 100644 packages/qemu/qemu-native_0.8.2.bb create mode 100644 packages/qemu/qemu_0.8.2.bb diff --git a/packages/qemu/files/arm_nptl.patch b/packages/qemu/files/arm_nptl.patch new file mode 100644 index 0000000000..958c27e5e1 --- /dev/null +++ b/packages/qemu/files/arm_nptl.patch @@ -0,0 +1,857 @@ +Index: qemu/configure +=================================================================== +--- qemu.orig/configure 2006-08-14 22:09:39.000000000 +0100 ++++ qemu/configure 2006-08-14 22:38:54.000000000 +0100 +@@ -96,6 +96,7 @@ + user="no" + build_docs="no" + uname_release="" ++nptl="yes" + + # OS specific + targetos=`uname -s` +@@ -240,6 +241,8 @@ + ;; + --enable-uname-release=*) uname_release="$optarg" + ;; ++ --disable-nptl) nptl="no" ++ ;; + esac + done + +@@ -438,6 +441,23 @@ + fi + fi + ++# check NPTL support ++cat > $TMPC < ++void foo() ++{ ++#ifndef CLONE_SETTLS ++#error bork ++#endif ++} ++EOF ++ ++if $cc -c -o $TMPO $TMPC 2> /dev/null ; then ++ : ++else ++ nptl="no" ++fi ++ + ########################################## + # SDL probe + +@@ -556,6 +576,7 @@ + fi + echo "FMOD support $fmod $fmod_support" + echo "kqemu support $kqemu" ++echo "NPTL support $nptl" + echo "Documentation $build_docs" + [ ! -z "$uname_release" ] && \ + echo "uname -r $uname_release" +@@ -864,6 +885,14 @@ + echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak + fi + fi ++else ++ if test "$nptl" = "yes" ; then ++ case "$target_cpu" in ++ arm | armeb) ++ echo "#define USE_NPTL 1" >> $config_h ++ ;; ++ esac ++ fi + fi + + if test "$cocoa" = "yes" ; then +Index: qemu/exec-all.h +=================================================================== +--- qemu.orig/exec-all.h 2006-05-26 18:10:52.000000000 +0100 ++++ qemu/exec-all.h 2006-08-14 22:37:29.000000000 +0100 +@@ -347,163 +347,7 @@ + extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; + extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; + +-#ifdef __powerpc__ +-static inline int testandset (int *p) +-{ +- int ret; +- __asm__ __volatile__ ( +- "0: lwarx %0,0,%1\n" +- " xor. %0,%3,%0\n" +- " bne 1f\n" +- " stwcx. %2,0,%1\n" +- " bne- 0b\n" +- "1: " +- : "=&r" (ret) +- : "r" (p), "r" (1), "r" (0) +- : "cr0", "memory"); +- return ret; +-} +-#endif +- +-#ifdef __i386__ +-static inline int testandset (int *p) +-{ +- long int readval = 0; +- +- __asm__ __volatile__ ("lock; cmpxchgl %2, %0" +- : "+m" (*p), "+a" (readval) +- : "r" (1) +- : "cc"); +- return readval; +-} +-#endif +- +-#ifdef __x86_64__ +-static inline int testandset (int *p) +-{ +- long int readval = 0; +- +- __asm__ __volatile__ ("lock; cmpxchgl %2, %0" +- : "+m" (*p), "+a" (readval) +- : "r" (1) +- : "cc"); +- return readval; +-} +-#endif +- +-#ifdef __s390__ +-static inline int testandset (int *p) +-{ +- int ret; +- +- __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" +- " jl 0b" +- : "=&d" (ret) +- : "r" (1), "a" (p), "0" (*p) +- : "cc", "memory" ); +- return ret; +-} +-#endif +- +-#ifdef __alpha__ +-static inline int testandset (int *p) +-{ +- int ret; +- unsigned long one; +- +- __asm__ __volatile__ ("0: mov 1,%2\n" +- " ldl_l %0,%1\n" +- " stl_c %2,%1\n" +- " beq %2,1f\n" +- ".subsection 2\n" +- "1: br 0b\n" +- ".previous" +- : "=r" (ret), "=m" (*p), "=r" (one) +- : "m" (*p)); +- return ret; +-} +-#endif +- +-#ifdef __sparc__ +-static inline int testandset (int *p) +-{ +- int ret; +- +- __asm__ __volatile__("ldstub [%1], %0" +- : "=r" (ret) +- : "r" (p) +- : "memory"); +- +- return (ret ? 1 : 0); +-} +-#endif +- +-#ifdef __arm__ +-static inline int testandset (int *spinlock) +-{ +- register unsigned int ret; +- __asm__ __volatile__("swp %0, %1, [%2]" +- : "=r"(ret) +- : "0"(1), "r"(spinlock)); +- +- return ret; +-} +-#endif +- +-#ifdef __mc68000 +-static inline int testandset (int *p) +-{ +- char ret; +- __asm__ __volatile__("tas %1; sne %0" +- : "=r" (ret) +- : "m" (p) +- : "cc","memory"); +- return ret; +-} +-#endif +- +-#ifdef __ia64 +-#include +- +-static inline int testandset (int *p) +-{ +- return __sync_lock_test_and_set (p, 1); +-} +-#endif +- +-typedef int spinlock_t; +- +-#define SPIN_LOCK_UNLOCKED 0 +- +-#if defined(CONFIG_USER_ONLY) +-static inline void spin_lock(spinlock_t *lock) +-{ +- while (testandset(lock)); +-} +- +-static inline void spin_unlock(spinlock_t *lock) +-{ +- *lock = 0; +-} +- +-static inline int spin_trylock(spinlock_t *lock) +-{ +- return !testandset(lock); +-} +-#else +-static inline void spin_lock(spinlock_t *lock) +-{ +-} +- +-static inline void spin_unlock(spinlock_t *lock) +-{ +-} +- +-static inline int spin_trylock(spinlock_t *lock) +-{ +- return 1; +-} +-#endif ++#include "qemu_spinlock.h" + + extern spinlock_t tb_lock; + +Index: qemu/linux-user/arm/syscall.h +=================================================================== +--- qemu.orig/linux-user/arm/syscall.h 2005-04-27 21:11:21.000000000 +0100 ++++ qemu/linux-user/arm/syscall.h 2006-08-14 22:37:29.000000000 +0100 +@@ -28,7 +28,9 @@ + #define ARM_SYSCALL_BASE 0x900000 + #define ARM_THUMB_SYSCALL 0 + +-#define ARM_NR_cacheflush (ARM_SYSCALL_BASE + 0xf0000 + 2) ++#define ARM_NR_BASE 0xf0000 ++#define ARM_NR_cacheflush (ARM_NR_BASE + 2) ++#define ARM_NR_set_tls (ARM_NR_BASE + 5) + + #define ARM_NR_semihosting 0x123456 + #define ARM_NR_thumb_semihosting 0xAB +Index: qemu/linux-user/main.c +=================================================================== +--- qemu.orig/linux-user/main.c 2006-05-26 18:11:01.000000000 +0100 ++++ qemu/linux-user/main.c 2006-08-14 22:37:29.000000000 +0100 +@@ -331,6 +331,50 @@ + } + } + ++/* Handle a jump to the kernel code page. */ ++static int ++do_kernel_trap(CPUARMState *env) ++{ ++ uint32_t addr; ++ uint32_t *ptr; ++ uint32_t cpsr; ++ ++ switch (env->regs[15]) { ++ case 0xffff0fc0: /* __kernel_cmpxchg */ ++ /* XXX: This only works between threads, not between processes. ++ Use native atomic operations. */ ++ /* ??? This probably breaks horribly if the access segfaults. */ ++ cpu_lock(); ++ ptr = (uint32_t *)env->regs[2]; ++ cpsr = cpsr_read(env); ++ if (*ptr == env->regs[0]) { ++ *ptr = env->regs[1]; ++ env->regs[0] = 0; ++ cpsr |= CPSR_C; ++ } else { ++ env->regs[0] = -1; ++ cpsr &= ~CPSR_C; ++ } ++ cpsr_write(env, cpsr, CPSR_C); ++ cpu_unlock(); ++ break; ++ case 0xffff0fe0: /* __kernel_get_tls */ ++ env->regs[0] = env->cp15.c13_tls; ++ break; ++ default: ++ return 1; ++ } ++ /* Jump back to the caller. */ ++ addr = env->regs[14]; ++ if (addr & 1) { ++ env->thumb = 1; ++ addr &= ~1; ++ } ++ env->regs[15] = addr; ++ ++ return 0; ++} ++ + void cpu_loop(CPUARMState *env) + { + int trapnr; +@@ -387,10 +431,8 @@ + } + } + +- if (n == ARM_NR_cacheflush) { +- arm_cache_flush(env->regs[0], env->regs[1]); +- } else if (n == ARM_NR_semihosting +- || n == ARM_NR_thumb_semihosting) { ++ if (n == ARM_NR_semihosting ++ || n == ARM_NR_thumb_semihosting) { + env->regs[0] = do_arm_semihosting (env); + } else if (n == 0 || n >= ARM_SYSCALL_BASE + || (env->thumb && n == ARM_THUMB_SYSCALL)) { +@@ -401,14 +443,34 @@ + n -= ARM_SYSCALL_BASE; + env->eabi = 0; + } +- env->regs[0] = do_syscall(env, +- n, +- env->regs[0], +- env->regs[1], +- env->regs[2], +- env->regs[3], +- env->regs[4], +- env->regs[5]); ++ if ( n > ARM_NR_BASE) { ++ switch (n) ++ { ++ case ARM_NR_cacheflush: ++ arm_cache_flush(env->regs[0], env->regs[1]); ++ break; ++#ifdef USE_NPTL ++ case ARM_NR_set_tls: ++ cpu_set_tls(env, env->regs[0]); ++ env->regs[0] = 0; ++ break; ++#endif ++ default: ++ printf ("Error: Bad syscall: %x\n", n); ++ goto error; ++ } ++ } ++ else ++ { ++ env->regs[0] = do_syscall(env, ++ n, ++ env->regs[0], ++ env->regs[1], ++ env->regs[2], ++ env->regs[3], ++ env->regs[4], ++ env->regs[5]); ++ } + } else { + goto error; + } +@@ -447,6 +509,10 @@ + } + } + break; ++ case EXCP_KERNEL_TRAP: ++ if (do_kernel_trap(env)) ++ goto error; ++ break; + default: + error: + fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", +@@ -1649,6 +1715,10 @@ + ts->heap_base = info->brk; + /* This will be filled in on the first SYS_HEAPINFO call. */ + ts->heap_limit = 0; ++ /* Register the magic kernel code page. The cpu will generate a ++ special exception when it tries to execute code here. We can't ++ put real code here because it may be in use by the host kernel. */ ++ page_set_flags(0xffff0000, 0xffff0fff, 0); + } + #elif defined(TARGET_SPARC) + { +Index: qemu/linux-user/qemu.h +=================================================================== +--- qemu.orig/linux-user/qemu.h 2006-05-26 18:11:01.000000000 +0100 ++++ qemu/linux-user/qemu.h 2006-08-14 22:37:29.000000000 +0100 +@@ -76,6 +76,9 @@ + uint32_t v86mask; + #endif + int used; /* non zero if used */ ++#ifdef USE_NPTL ++ uint32_t *child_tidptr; ++#endif + uint8_t stack[0]; + } __attribute__((aligned(16))) TaskState; + +Index: qemu/linux-user/syscall.c +=================================================================== +--- qemu.orig/linux-user/syscall.c 2006-05-26 18:11:01.000000000 +0100 ++++ qemu/linux-user/syscall.c 2006-08-14 22:44:47.000000000 +0100 +@@ -66,9 +66,18 @@ + #include + + #include "qemu.h" ++#include "qemu_spinlock.h" + + //#define DEBUG + ++#ifdef USE_NPTL ++#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \ ++ CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID) ++#else ++/* XXX: Hardcode the above values. */ ++#define CLONE_NPTL_FLAGS2 0 ++#endif ++ + #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) + /* 16 bit uid wrappers emulation */ + #define USE_UID16 +@@ -1569,20 +1578,38 @@ + thread/process */ + #define NEW_STACK_SIZE 8192 + ++#ifdef USE_NPTL ++static spinlock_t nptl_lock = SPIN_LOCK_UNLOCKED; ++#endif ++ + static int clone_func(void *arg) + { + CPUState *env = arg; ++#ifdef HAVE_NPTL ++ /* Wait until the parent has finshed initializing the tls state. */ ++ while (!spin_trylock(&nptl_lock)) ++ usleep(1); ++ spin_unlock(&nptl_lock); ++#endif + cpu_loop(env); + /* never exits */ + return 0; + } + +-int do_fork(CPUState *env, unsigned int flags, unsigned long newsp) ++int do_fork(CPUState *env, unsigned int flags, unsigned long newsp, ++ uint32_t *parent_tidptr, void *newtls, ++ uint32_t *child_tidptr) + { + int ret; + TaskState *ts; + uint8_t *new_stack; + CPUState *new_env; ++#ifdef USE_NPTL ++ unsigned int nptl_flags; ++ ++ if (flags & CLONE_PARENT_SETTID) ++ *parent_tidptr = gettid(); ++#endif + + if (flags & CLONE_VM) { + ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); +@@ -1627,16 +1654,60 @@ + #error unsupported target CPU + #endif + new_env->opaque = ts; ++#ifdef USE_NPTL ++ nptl_flags = flags; ++ flags &= ~CLONE_NPTL_FLAGS2; ++ if (nptl_flags & CLONE_CHILD_CLEARTID) { ++ ts->child_tidptr = child_tidptr; ++ } ++ if (nptl_flags & CLONE_SETTLS) ++ cpu_set_tls (new_env, newtls); ++ /* Grab the global cpu lock so that the thread setup appears ++ atomic. */ ++ if (nptl_flags & CLONE_CHILD_SETTID) ++ spin_lock(&nptl_lock); ++#else ++ if (flags & CLONE_NPTL_FLAGS2) ++ return -EINVAL; ++#endif ++ + #ifdef __ia64__ + ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); + #else + ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); + #endif ++#ifdef USE_NPTL ++ if (ret != -1) { ++ if (nptl_flags & CLONE_CHILD_SETTID) ++ *child_tidptr = ret; ++ } ++ /* Allow the child to continue. */ ++ if (nptl_flags & CLONE_CHILD_SETTID) ++ spin_unlock(&nptl_lock); ++#endif + } else { +- /* if no CLONE_VM, we consider it is a fork */ +- if ((flags & ~CSIGNAL) != 0) +- return -EINVAL; +- ret = fork(); ++ /* if no CLONE_VM, we consider it is a fork */ ++ if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) ++ return -EINVAL; ++ ret = fork(); ++#ifdef USE_NPTL ++ /* There is a race condition here. The parent process could ++ theoretically read the TID in the child process before the child ++ tid is set. This would require using either ptrace ++ (not implemented) or having *_tidptr to point at a shared memory ++ mapping. We can't repeat the spinlock hack used above because ++ the child process gets its own copy of the lock. */ ++ if (ret == 0) { ++ /* Child Process. */ ++ if (flags & CLONE_CHILD_SETTID) ++ *child_tidptr = gettid(); ++ ts = (TaskState *)env->opaque; ++ if (flags & CLONE_CHILD_CLEARTID) ++ ts->child_tidptr = child_tidptr; ++ if (flags & CLONE_SETTLS) ++ cpu_set_tls (env, newtls); ++ } ++#endif + } + return ret; + } +@@ -1880,7 +1951,7 @@ + ret = do_brk(arg1); + break; + case TARGET_NR_fork: +- ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); ++ ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, NULL, NULL, NULL)); + break; + case TARGET_NR_waitpid: + { +@@ -2836,7 +2907,8 @@ + ret = get_errno(fsync(arg1)); + break; + case TARGET_NR_clone: +- ret = get_errno(do_fork(cpu_env, arg1, arg2)); ++ ret = get_errno(do_fork(cpu_env, arg1, arg2, (uint32_t *)arg3, ++ (void *)arg4, (uint32_t *)arg5)); + break; + #ifdef __NR_exit_group + /* new thread calls */ +@@ -3186,7 +3258,8 @@ + #endif + #ifdef TARGET_NR_vfork + case TARGET_NR_vfork: +- ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0)); ++ ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0, ++ NULL, NULL, NULL)); + break; + #endif + #ifdef TARGET_NR_ugetrlimit +@@ -3681,4 +3754,3 @@ + #endif + return ret; + } +- +Index: qemu/target-arm/cpu.h +=================================================================== +--- qemu.orig/target-arm/cpu.h 2006-02-20 00:33:36.000000000 +0000 ++++ qemu/target-arm/cpu.h 2006-08-14 22:39:35.000000000 +0100 +@@ -35,6 +35,9 @@ + #define EXCP_IRQ 5 + #define EXCP_FIQ 6 + #define EXCP_BKPT 7 ++#define EXCP_KERNEL_TRAP 8 /* Jumped to kernel code page. */ ++ ++ + + /* We currently assume float and double are IEEE single and double + precision respectively. +@@ -85,6 +88,7 @@ + uint32_t c9_data; + uint32_t c13_fcse; /* FCSE PID. */ + uint32_t c13_context; /* Context ID. */ ++ uint32_t c13_tls; /* Paul Brook told me to just add this ;) */ + } cp15; + + /* Internal CPU feature flags. */ +@@ -135,6 +139,15 @@ + int cpu_arm_signal_handler(int host_signum, struct siginfo *info, + void *puc); + ++void cpu_lock(void); ++void cpu_unlock(void); ++#if defined(USE_NPTL) ++static inline void cpu_set_tls(CPUARMState *env, void *newtls) ++{ ++ env->cp15.c13_tls = (uint32_t)newtls; ++} ++#endif ++ + #define CPSR_M (0x1f) + #define CPSR_T (1 << 5) + #define CPSR_F (1 << 6) +@@ -146,7 +159,11 @@ + #define CPSR_J (1 << 24) + #define CPSR_IT_0_1 (3 << 25) + #define CPSR_Q (1 << 27) +-#define CPSR_NZCV (0xf << 28) ++#define CPSR_V (1 << 28) ++#define CPSR_C (1 << 29) ++#define CPSR_Z (1 << 30) ++#define CPSR_N (1 << 31) ++#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V) + + #define CACHED_CPSR_BITS (CPSR_T | CPSR_Q | CPSR_NZCV) + /* Return the current CPSR value. */ +Index: qemu/target-arm/exec.h +=================================================================== +--- qemu.orig/target-arm/exec.h 2005-11-26 10:38:39.000000000 +0000 ++++ qemu/target-arm/exec.h 2006-08-14 22:37:29.000000000 +0100 +@@ -51,8 +51,6 @@ + + /* In op_helper.c */ + +-void cpu_lock(void); +-void cpu_unlock(void); + void helper_set_cp15(CPUState *, uint32_t, uint32_t); + uint32_t helper_get_cp15(CPUState *, uint32_t); + +Index: qemu/target-arm/op.c +=================================================================== +--- qemu.orig/target-arm/op.c 2006-02-20 00:33:36.000000000 +0000 ++++ qemu/target-arm/op.c 2006-08-14 22:37:29.000000000 +0100 +@@ -891,6 +891,12 @@ + cpu_loop_exit(); + } + ++void OPPROTO op_kernel_trap(void) ++{ ++ env->exception_index = EXCP_KERNEL_TRAP; ++ cpu_loop_exit(); ++} ++ + /* VFP support. We follow the convention used for VFP instrunctions: + Single precition routines have a "s" suffix, double precision a + "d" suffix. */ +Index: qemu/target-arm/translate.c +=================================================================== +--- qemu.orig/target-arm/translate.c 2006-05-26 18:11:04.000000000 +0100 ++++ qemu/target-arm/translate.c 2006-08-14 22:37:29.000000000 +0100 +@@ -2377,6 +2377,7 @@ + s->is_jmp = DISAS_JUMP; + } + ++ + /* generate intermediate code in gen_opc_buf and gen_opparam_buf for + basic block 'tb'. If search_pc is TRUE, also generate PC + information for each intermediate instruction. */ +@@ -2411,6 +2412,15 @@ + nb_gen_labels = 0; + lj = -1; + do { ++#ifdef CONFIG_USER_ONLY ++ /* Intercept jump to the magic kernel page. */ ++ if (dc->pc > 0xffff0000) { ++ gen_op_kernel_trap(); ++ dc->is_jmp = DISAS_UPDATE; ++ break; ++ } ++#endif ++ + if (env->nb_breakpoints > 0) { + for(j = 0; j < env->nb_breakpoints; j++) { + if (env->breakpoints[j] == dc->pc) { +Index: qemu/qemu_spinlock.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ qemu/qemu_spinlock.h 2006-08-14 22:37:29.000000000 +0100 +@@ -0,0 +1,182 @@ ++/* ++ * internal execution defines for qemu ++ * ++ * Copyright (c) 2003 Fabrice Bellard ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef _QEMU_SPINLOCK_H ++#define _QEMU_SPINLOCK_H ++ ++#ifdef __powerpc__ ++static inline int testandset (int *p) ++{ ++ int ret; ++ __asm__ __volatile__ ( ++ "0: lwarx %0,0,%1\n" ++ " xor. %0,%3,%0\n" ++ " bne 1f\n" ++ " stwcx. %2,0,%1\n" ++ " bne- 0b\n" ++ "1: " ++ : "=&r" (ret) ++ : "r" (p), "r" (1), "r" (0) ++ : "cr0", "memory"); ++ return ret; ++} ++#endif ++ ++#ifdef __i386__ ++static inline int testandset (int *p) ++{ ++ long int readval = 0; ++ ++ __asm__ __volatile__ ("lock; cmpxchgl %2, %0" ++ : "+m" (*p), "+a" (readval) ++ : "r" (1) ++ : "cc"); ++ return readval; ++} ++#endif ++ ++#ifdef __x86_64__ ++static inline int testandset (int *p) ++{ ++ long int readval = 0; ++ ++ __asm__ __volatile__ ("lock; cmpxchgl %2, %0" ++ : "+m" (*p), "+a" (readval) ++ : "r" (1) ++ : "cc"); ++ return readval; ++} ++#endif ++ ++#ifdef __s390__ ++static inline int testandset (int *p) ++{ ++ int ret; ++ ++ __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" ++ " jl 0b" ++ : "=&d" (ret) ++ : "r" (1), "a" (p), "0" (*p) ++ : "cc", "memory" ); ++ return ret; ++} ++#endif ++ ++#ifdef __alpha__ ++static inline int testandset (int *p) ++{ ++ int ret; ++ unsigned long one; ++ ++ __asm__ __volatile__ ("0: mov 1,%2\n" ++ " ldl_l %0,%1\n" ++ " stl_c %2,%1\n" ++ " beq %2,1f\n" ++ ".subsection 2\n" ++ "1: br 0b\n" ++ ".previous" ++ : "=r" (ret), "=m" (*p), "=r" (one) ++ : "m" (*p)); ++ return ret; ++} ++#endif ++ ++#ifdef __sparc__ ++static inline int testandset (int *p) ++{ ++ int ret; ++ ++ __asm__ __volatile__("ldstub [%1], %0" ++ : "=r" (ret) ++ : "r" (p) ++ : "memory"); ++ ++ return (ret ? 1 : 0); ++} ++#endif ++ ++#ifdef __arm__ ++static inline int testandset (int *spinlock) ++{ ++ register unsigned int ret; ++ __asm__ __volatile__("swp %0, %1, [%2]" ++ : "=r"(ret) ++ : "0"(1), "r"(spinlock)); ++ ++ return ret; ++} ++#endif ++ ++#ifdef __mc68000 ++static inline int testandset (int *p) ++{ ++ char ret; ++ __asm__ __volatile__("tas %1; sne %0" ++ : "=r" (ret) ++ : "m" (p) ++ : "cc","memory"); ++ return ret; ++} ++#endif ++ ++#ifdef __ia64 ++#include ++ ++static inline int testandset (int *p) ++{ ++ return __sync_lock_test_and_set (p, 1); ++} ++#endif ++ ++typedef int spinlock_t; ++ ++#define SPIN_LOCK_UNLOCKED 0 ++ ++#if defined(CONFIG_USER_ONLY) ++static inline void spin_lock(spinlock_t *lock) ++{ ++ while (testandset(lock)); ++} ++ ++static inline void spin_unlock(spinlock_t *lock) ++{ ++ *lock = 0; ++} ++ ++static inline int spin_trylock(spinlock_t *lock) ++{ ++ return !testandset(lock); ++} ++#else ++static inline void spin_lock(spinlock_t *lock) ++{ ++} ++ ++static inline void spin_unlock(spinlock_t *lock) ++{ ++} ++ ++static inline int spin_trylock(spinlock_t *lock) ++{ ++ return 1; ++} ++#endif ++ ++#endif /* ! _QEMU_SPINLOCK_H */ diff --git a/packages/qemu/qemu-0.8.0/.mtn2git_empty b/packages/qemu/qemu-0.8.0/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/qemu/qemu-0.8.0/arm_nptl.patch b/packages/qemu/qemu-0.8.0/arm_nptl.patch new file mode 100644 index 0000000000..daf105071c --- /dev/null +++ b/packages/qemu/qemu-0.8.0/arm_nptl.patch @@ -0,0 +1,854 @@ +diff -ur qemu-0.8.0.orig/configure qemu-0.8.0/configure +--- qemu-0.8.0.orig/configure 2005-12-20 00:51:53.000000000 +0200 ++++ qemu-0.8.0/configure 2006-07-12 15:26:40.000000000 +0300 +@@ -89,6 +89,7 @@ + cocoa="no" + check_gfx="yes" + check_gcc="yes" ++nptl=yes + + # OS specific + targetos=`uname -s` +@@ -205,6 +206,8 @@ + ;; + --disable-gcc-check) check_gcc="no" + ;; ++ --disable-nptl) nptl="no" ++ ;; + esac + done + +@@ -299,6 +302,23 @@ + fi + fi + ++# check NPTL support ++cat > $TMPC < ++void foo() ++{ ++#ifndef CLONE_SETTLS ++#error bork ++#endif ++} ++EOF ++ ++if $cc -c -o $TMPO $TMPC 2> /dev/null ; then ++ : ++else ++ nptl="no" ++fi ++ + ########################################## + # SDL probe + +@@ -489,6 +509,7 @@ + fi + echo "" + echo "kqemu support $kqemu" ++echo "NPTL support $nptl" + if test $kqemu = "yes" -a $linux = "yes" ; then + echo "" + echo "KQEMU Linux module configuration:" +@@ -793,6 +814,14 @@ + fi + echo "" >> $config_mak + fi ++else ++ if test "$nptl" = "yes" ; then ++ case "$target_cpu" in ++ arm | armeb) ++ echo "#define USE_NPTL 1" >> $config_h ++ ;; ++ esac ++ fi + fi + + if test "$cocoa" = "yes" ; then +Only in qemu-0.8.0: configure.rej~ +Only in qemu-0.8.0: configure~ +diff -ur qemu-0.8.0.orig/exec-all.h qemu-0.8.0/exec-all.h +--- qemu-0.8.0.orig/exec-all.h 2005-12-20 00:51:53.000000000 +0200 ++++ qemu-0.8.0/exec-all.h 2006-07-12 15:23:46.000000000 +0300 +@@ -347,163 +347,7 @@ + extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; + extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; + +-#ifdef __powerpc__ +-static inline int testandset (int *p) +-{ +- int ret; +- __asm__ __volatile__ ( +- "0: lwarx %0,0,%1\n" +- " xor. %0,%3,%0\n" +- " bne 1f\n" +- " stwcx. %2,0,%1\n" +- " bne- 0b\n" +- "1: " +- : "=&r" (ret) +- : "r" (p), "r" (1), "r" (0) +- : "cr0", "memory"); +- return ret; +-} +-#endif +- +-#ifdef __i386__ +-static inline int testandset (int *p) +-{ +- long int readval = 0; +- +- __asm__ __volatile__ ("lock; cmpxchgl %2, %0" +- : "+m" (*p), "+a" (readval) +- : "r" (1) +- : "cc"); +- return readval; +-} +-#endif +- +-#ifdef __x86_64__ +-static inline int testandset (int *p) +-{ +- long int readval = 0; +- +- __asm__ __volatile__ ("lock; cmpxchgl %2, %0" +- : "+m" (*p), "+a" (readval) +- : "r" (1) +- : "cc"); +- return readval; +-} +-#endif +- +-#ifdef __s390__ +-static inline int testandset (int *p) +-{ +- int ret; +- +- __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" +- " jl 0b" +- : "=&d" (ret) +- : "r" (1), "a" (p), "0" (*p) +- : "cc", "memory" ); +- return ret; +-} +-#endif +- +-#ifdef __alpha__ +-static inline int testandset (int *p) +-{ +- int ret; +- unsigned long one; +- +- __asm__ __volatile__ ("0: mov 1,%2\n" +- " ldl_l %0,%1\n" +- " stl_c %2,%1\n" +- " beq %2,1f\n" +- ".subsection 2\n" +- "1: br 0b\n" +- ".previous" +- : "=r" (ret), "=m" (*p), "=r" (one) +- : "m" (*p)); +- return ret; +-} +-#endif +- +-#ifdef __sparc__ +-static inline int testandset (int *p) +-{ +- int ret; +- +- __asm__ __volatile__("ldstub [%1], %0" +- : "=r" (ret) +- : "r" (p) +- : "memory"); +- +- return (ret ? 1 : 0); +-} +-#endif +- +-#ifdef __arm__ +-static inline int testandset (int *spinlock) +-{ +- register unsigned int ret; +- __asm__ __volatile__("swp %0, %1, [%2]" +- : "=r"(ret) +- : "0"(1), "r"(spinlock)); +- +- return ret; +-} +-#endif +- +-#ifdef __mc68000 +-static inline int testandset (int *p) +-{ +- char ret; +- __asm__ __volatile__("tas %1; sne %0" +- : "=r" (ret) +- : "m" (p) +- : "cc","memory"); +- return ret; +-} +-#endif +- +-#ifdef __ia64 +-#include +- +-static inline int testandset (int *p) +-{ +- return __sync_lock_test_and_set (p, 1); +-} +-#endif +- +-typedef int spinlock_t; +- +-#define SPIN_LOCK_UNLOCKED 0 +- +-#if defined(CONFIG_USER_ONLY) +-static inline void spin_lock(spinlock_t *lock) +-{ +- while (testandset(lock)); +-} +- +-static inline void spin_unlock(spinlock_t *lock) +-{ +- *lock = 0; +-} +- +-static inline int spin_trylock(spinlock_t *lock) +-{ +- return !testandset(lock); +-} +-#else +-static inline void spin_lock(spinlock_t *lock) +-{ +-} +- +-static inline void spin_unlock(spinlock_t *lock) +-{ +-} +- +-static inline int spin_trylock(spinlock_t *lock) +-{ +- return 1; +-} +-#endif ++#include "qemu_spinlock.h" + + extern spinlock_t tb_lock; + +diff -ur qemu-0.8.0.orig/linux-user/arm/syscall.h qemu-0.8.0/linux-user/arm/syscall.h +--- qemu-0.8.0.orig/linux-user/arm/syscall.h 2005-12-20 00:51:53.000000000 +0200 ++++ qemu-0.8.0/linux-user/arm/syscall.h 2006-07-12 15:23:46.000000000 +0300 +@@ -28,7 +28,9 @@ + #define ARM_SYSCALL_BASE 0x900000 + #define ARM_THUMB_SYSCALL 0 + +-#define ARM_NR_cacheflush (ARM_SYSCALL_BASE + 0xf0000 + 2) ++#define ARM_NR_BASE 0xf0000 ++#define ARM_NR_cacheflush (ARM_NR_BASE + 2) ++#define ARM_NR_set_tls (ARM_NR_BASE + 5) + + #define ARM_NR_semihosting 0x123456 + #define ARM_NR_thumb_semihosting 0xAB +diff -ur qemu-0.8.0.orig/linux-user/main.c qemu-0.8.0/linux-user/main.c +--- qemu-0.8.0.orig/linux-user/main.c 2006-07-12 15:20:37.000000000 +0300 ++++ qemu-0.8.0/linux-user/main.c 2006-07-12 15:23:46.000000000 +0300 +@@ -326,6 +326,50 @@ + } + } + ++/* Handle a jump to the kernel code page. */ ++static int ++do_kernel_trap(CPUARMState *env) ++{ ++ uint32_t addr; ++ uint32_t *ptr; ++ uint32_t cpsr; ++ ++ switch (env->regs[15]) { ++ case 0xffff0fc0: /* __kernel_cmpxchg */ ++ /* XXX: This only works between threads, not between processes. ++ Use native atomic operations. */ ++ /* ??? This probably breaks horribly if the access segfaults. */ ++ cpu_lock(); ++ ptr = (uint32_t *)env->regs[2]; ++ cpsr = cpsr_read(env); ++ if (*ptr == env->regs[0]) { ++ *ptr = env->regs[1]; ++ env->regs[0] = 0; ++ cpsr |= CPSR_C; ++ } else { ++ env->regs[0] = -1; ++ cpsr &= ~CPSR_C; ++ } ++ cpsr_write(env, cpsr, CPSR_C); ++ cpu_unlock(); ++ break; ++ case 0xffff0fe0: /* __kernel_get_tls */ ++ env->regs[0] = env->cp15.c13_tls; ++ break; ++ default: ++ return 1; ++ } ++ /* Jump back to the caller. */ ++ addr = env->regs[14]; ++ if (addr & 1) { ++ env->thumb = 1; ++ addr &= ~1; ++ } ++ env->regs[15] = addr; ++ ++ return 0; ++} ++ + void cpu_loop(CPUARMState *env) + { + int trapnr; +@@ -368,10 +412,8 @@ + n = insn & 0xffffff; + } + +- if (n == ARM_NR_cacheflush) { +- arm_cache_flush(env->regs[0], env->regs[1]); +- } else if (n == ARM_NR_semihosting +- || n == ARM_NR_thumb_semihosting) { ++ if (n == ARM_NR_semihosting ++ || n == ARM_NR_thumb_semihosting) { + env->regs[0] = do_arm_semihosting (env); + } else if (n >= ARM_SYSCALL_BASE + || (env->thumb && n == ARM_THUMB_SYSCALL)) { +@@ -381,14 +423,34 @@ + } else { + n -= ARM_SYSCALL_BASE; + } +- env->regs[0] = do_syscall(env, +- n, +- env->regs[0], +- env->regs[1], +- env->regs[2], +- env->regs[3], +- env->regs[4], +- env->regs[5]); ++ if ( n > ARM_NR_BASE) { ++ switch (n) ++ { ++ case ARM_NR_cacheflush: ++ arm_cache_flush(env->regs[0], env->regs[1]); ++ break; ++#ifdef USE_NPTL ++ case ARM_NR_set_tls: ++ cpu_set_tls(env, env->regs[0]); ++ env->regs[0] = 0; ++ break; ++#endif ++ default: ++ printf ("Error: Bad syscall: %x\n", n); ++ goto error; ++ } ++ } ++ else ++ { ++ env->regs[0] = do_syscall(env, ++ n, ++ env->regs[0], ++ env->regs[1], ++ env->regs[2], ++ env->regs[3], ++ env->regs[4], ++ env->regs[5]); ++ } + } else { + goto error; + } +@@ -427,6 +489,10 @@ + } + } + break; ++ case EXCP_KERNEL_TRAP: ++ if (do_kernel_trap(env)) ++ goto error; ++ break; + default: + error: + fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", +@@ -1602,6 +1668,10 @@ + ts->heap_base = info->brk; + /* This will be filled in on the first SYS_HEAPINFO call. */ + ts->heap_limit = 0; ++ /* Register the magic kernel code page. The cpu will generate a ++ special exception when it tries to execute code here. We can't ++ put real code here because it may be in use by the host kernel. */ ++ page_set_flags(0xffff0000, 0xffff0fff, 0); + } + #elif defined(TARGET_SPARC) + { +diff -ur qemu-0.8.0.orig/linux-user/qemu.h qemu-0.8.0/linux-user/qemu.h +--- qemu-0.8.0.orig/linux-user/qemu.h 2005-12-20 00:51:53.000000000 +0200 ++++ qemu-0.8.0/linux-user/qemu.h 2006-07-12 15:23:46.000000000 +0300 +@@ -76,6 +76,9 @@ + uint32_t v86mask; + #endif + int used; /* non zero if used */ ++#ifdef USE_NPTL ++ uint32_t *child_tidptr; ++#endif + uint8_t stack[0]; + } __attribute__((aligned(16))) TaskState; + +Only in qemu-0.8.0.orig/linux-user: signal.c.orig +diff -ur qemu-0.8.0.orig/linux-user/syscall.c qemu-0.8.0/linux-user/syscall.c +--- qemu-0.8.0.orig/linux-user/syscall.c 2006-07-12 15:20:37.000000000 +0300 ++++ qemu-0.8.0/linux-user/syscall.c 2006-07-12 15:36:51.000000000 +0300 +@@ -72,9 +72,18 @@ + #include + + #include "qemu.h" ++#include "qemu_spinlock.h" + + //#define DEBUG + ++#ifdef USE_NPTL ++#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \ ++ CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID) ++#else ++/* XXX: Hardcode the above values. */ ++#define CLONE_NPTL_FLAGS2 0 ++#endif ++ + #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) + /* 16 bit uid wrappers emulation */ + #define USE_UID16 +@@ -1527,20 +1536,38 @@ + thread/process */ + #define NEW_STACK_SIZE 8192 + ++#ifdef USE_NPTL ++static spinlock_t nptl_lock = SPIN_LOCK_UNLOCKED; ++#endif ++ + static int clone_func(void *arg) + { + CPUState *env = arg; ++#ifdef HAVE_NPTL ++ /* Wait until the parent has finshed initializing the tls state. */ ++ while (!spin_trylock(&nptl_lock)) ++ usleep(1); ++ spin_unlock(&nptl_lock); ++#endif + cpu_loop(env); + /* never exits */ + return 0; + } + +-int do_fork(CPUState *env, unsigned int flags, unsigned long newsp) ++int do_fork(CPUState *env, unsigned int flags, unsigned long newsp, ++ uint32_t *parent_tidptr, void *newtls, ++ uint32_t *child_tidptr) + { + int ret; + TaskState *ts; + uint8_t *new_stack; + CPUState *new_env; ++#ifdef USE_NPTL ++ unsigned int nptl_flags; ++ ++ if (flags & CLONE_PARENT_SETTID) ++ *parent_tidptr = gettid(); ++#endif + + if (flags & CLONE_VM) { + ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); +@@ -1576,16 +1603,62 @@ + #error unsupported target CPU + #endif + new_env->opaque = ts; ++#ifdef USE_NPTL ++ nptl_flags = flags; ++ flags &= ~CLONE_NPTL_FLAGS2; ++ ++ if (nptl_flags & CLONE_CHILD_CLEARTID) { ++ ts->child_tidptr = child_tidptr; ++ } ++ ++ if (nptl_flags & CLONE_SETTLS) ++ cpu_set_tls (new_env, newtls); ++ /* Grab the global cpu lock so that the thread setup appears ++ atomic. */ ++ if (nptl_flags & CLONE_CHILD_SETTID) ++ spin_lock(&nptl_lock); ++#else ++ if (flags & CLONE_NPTL_FLAGS2) ++ return -EINVAL; ++#endif ++ + #ifdef __ia64__ + ret = clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); + #else + ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); + #endif ++#ifdef USE_NPTL ++ if (ret != -1) { ++ if (nptl_flags & CLONE_CHILD_SETTID) ++ *child_tidptr = ret; ++ } ++ /* Allow the child to continue. */ ++ if (nptl_flags & CLONE_CHILD_SETTID) ++ spin_unlock(&nptl_lock); ++#endif + } else { + /* if no CLONE_VM, we consider it is a fork */ +- if ((flags & ~CSIGNAL) != 0) ++ if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) + return -EINVAL; + ret = fork(); ++#ifdef USE_NPTL ++ /* There is a race condition here. The parent process could ++ theoretically read the TID in the child process before the child ++ tid is set. This would require using either ptrace ++ (not implemented) or having *_tidptr to point at a shared memory ++ mapping. We can't repeat the spinlock hack used above because ++ the child process gets its own copy of the lock. */ ++ if (ret == 0) { ++ /* Child Process. */ ++ if (flags & CLONE_CHILD_SETTID) ++ *child_tidptr = gettid(); ++ ts = (TaskState *)env->opaque; ++ if (flags & CLONE_CHILD_CLEARTID) ++ ts->child_tidptr = child_tidptr; ++ if (flags & CLONE_SETTLS) ++ cpu_set_tls (env, newtls); ++ } ++#endif + } + return ret; + } +@@ -1757,7 +1830,7 @@ + ret = do_brk((char *)arg1); + break; + case TARGET_NR_fork: +- ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); ++ ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, NULL, NULL, NULL)); + break; + case TARGET_NR_waitpid: + { +@@ -2564,7 +2637,8 @@ + ret = get_errno(fsync(arg1)); + break; + case TARGET_NR_clone: +- ret = get_errno(do_fork(cpu_env, arg1, arg2)); ++ ret = get_errno(do_fork(cpu_env, arg1, arg2, (uint32_t *)arg3, ++ (void *)arg4, (uint32_t *)arg5)); + break; + #ifdef __NR_exit_group + /* new thread calls */ +@@ -2925,7 +2999,8 @@ + #endif + #ifdef TARGET_NR_vfork + case TARGET_NR_vfork: +- ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0)); ++ ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0, ++ NULL, NULL, NULL)); + break; + #endif + #ifdef TARGET_NR_ugetrlimit +@@ -3347,4 +3422,3 @@ + #endif + return ret; + } +- +Only in qemu-0.8.0.orig/linux-user: syscall.c.orig +Only in qemu-0.8.0/linux-user: syscall.c.rej~ +Only in qemu-0.8.0/linux-user: syscall.c~ +Only in qemu-0.8.0: qemu_spinlock.h +diff -ur qemu-0.8.0.orig/target-arm/cpu.h qemu-0.8.0/target-arm/cpu.h +--- qemu-0.8.0.orig/target-arm/cpu.h 2005-12-20 00:51:53.000000000 +0200 ++++ qemu-0.8.0/target-arm/cpu.h 2006-07-12 15:27:28.000000000 +0300 +@@ -34,6 +34,9 @@ + #define EXCP_DATA_ABORT 4 + #define EXCP_IRQ 5 + #define EXCP_FIQ 6 ++#define EXCP_BKPT 7 ++#define EXCP_KERNEL_TRAP 8 /* Jumped to kernel code page. */ ++ + + /* We currently assume float and double are IEEE single and double + precision respectively. +@@ -83,6 +86,7 @@ + uint32_t c9_data; + uint32_t c13_fcse; /* FCSE PID. */ + uint32_t c13_context; /* Context ID. */ ++ uint32_t c13_tls; /* Paul Brook told me to just add this ;) */ + } cp15; + + /* exception/interrupt handling */ +@@ -126,6 +130,15 @@ + int cpu_arm_signal_handler(int host_signum, struct siginfo *info, + void *puc); + ++void cpu_lock(void); ++void cpu_unlock(void); ++#if defined(USE_NPTL) ++static inline void cpu_set_tls(CPUARMState *env, void *newtls) ++{ ++ env->cp15.c13_tls = (uint32_t)newtls; ++} ++#endif ++ + #define CPSR_M (0x1f) + #define CPSR_T (1 << 5) + #define CPSR_F (1 << 6) +@@ -137,7 +150,11 @@ + #define CPSR_J (1 << 24) + #define CPSR_IT_0_1 (3 << 25) + #define CPSR_Q (1 << 27) +-#define CPSR_NZCV (0xf << 28) ++#define CPSR_V (1 << 28) ++#define CPSR_C (1 << 29) ++#define CPSR_Z (1 << 30) ++#define CPSR_N (1 << 31) ++#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V) + + #define CACHED_CPSR_BITS (CPSR_T | CPSR_Q | CPSR_NZCV) + /* Return the current CPSR value. */ +Only in qemu-0.8.0/target-arm: cpu.h~ +diff -ur qemu-0.8.0.orig/target-arm/exec.h qemu-0.8.0/target-arm/exec.h +--- qemu-0.8.0.orig/target-arm/exec.h 2005-12-20 00:51:53.000000000 +0200 ++++ qemu-0.8.0/target-arm/exec.h 2006-07-12 15:23:46.000000000 +0300 +@@ -51,8 +51,6 @@ + + /* In op_helper.c */ + +-void cpu_lock(void); +-void cpu_unlock(void); + void helper_set_cp15(CPUState *, uint32_t, uint32_t); + uint32_t helper_get_cp15(CPUState *, uint32_t); + +diff -ur qemu-0.8.0.orig/target-arm/op.c qemu-0.8.0/target-arm/op.c +--- qemu-0.8.0.orig/target-arm/op.c 2005-12-20 00:51:53.000000000 +0200 ++++ qemu-0.8.0/target-arm/op.c 2006-07-12 15:23:46.000000000 +0300 +@@ -885,6 +885,12 @@ + cpu_loop_exit(); + } + ++void OPPROTO op_kernel_trap(void) ++{ ++ env->exception_index = EXCP_KERNEL_TRAP; ++ cpu_loop_exit(); ++} ++ + /* VFP support. We follow the convention used for VFP instrunctions: + Single precition routines have a "s" suffix, double precision a + "d" suffix. */ +diff -ur qemu-0.8.0.orig/target-arm/translate.c qemu-0.8.0/target-arm/translate.c +--- qemu-0.8.0.orig/target-arm/translate.c 2005-12-20 00:51:53.000000000 +0200 ++++ qemu-0.8.0/target-arm/translate.c 2006-07-12 15:23:46.000000000 +0300 +@@ -2282,6 +2282,7 @@ + s->is_jmp = DISAS_JUMP; + } + ++ + /* generate intermediate code in gen_opc_buf and gen_opparam_buf for + basic block 'tb'. If search_pc is TRUE, also generate PC + information for each intermediate instruction. */ +@@ -2316,6 +2317,15 @@ + nb_gen_labels = 0; + lj = -1; + do { ++#ifdef CONFIG_USER_ONLY ++ /* Intercept jump to the magic kernel page. */ ++ if (dc->pc > 0xffff0000) { ++ gen_op_kernel_trap(); ++ dc->is_jmp = DISAS_UPDATE; ++ break; ++ } ++#endif ++ + if (env->nb_breakpoints > 0) { + for(j = 0; j < env->nb_breakpoints; j++) { + if (env->breakpoints[j] == dc->pc) { +diff -urN qemu-0.8.1.orig/qemu_spinlock.h qemu-0.8.1/qemu_spinlock.h +--- qemu-0.8.1.orig/qemu_spinlock.h 1970-01-01 02:00:00.000000000 +0200 ++++ qemu-0.8.1/qemu_spinlock.h 2006-06-04 00:59:23.000000000 +0300 +@@ -0,0 +1,182 @@ ++/* ++ * internal execution defines for qemu ++ * ++ * Copyright (c) 2003 Fabrice Bellard ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef _QEMU_SPINLOCK_H ++#define _QEMU_SPINLOCK_H ++ ++#ifdef __powerpc__ ++static inline int testandset (int *p) ++{ ++ int ret; ++ __asm__ __volatile__ ( ++ "0: lwarx %0,0,%1\n" ++ " xor. %0,%3,%0\n" ++ " bne 1f\n" ++ " stwcx. %2,0,%1\n" ++ " bne- 0b\n" ++ "1: " ++ : "=&r" (ret) ++ : "r" (p), "r" (1), "r" (0) ++ : "cr0", "memory"); ++ return ret; ++} ++#endif ++ ++#ifdef __i386__ ++static inline int testandset (int *p) ++{ ++ long int readval = 0; ++ ++ __asm__ __volatile__ ("lock; cmpxchgl %2, %0" ++ : "+m" (*p), "+a" (readval) ++ : "r" (1) ++ : "cc"); ++ return readval; ++} ++#endif ++ ++#ifdef __x86_64__ ++static inline int testandset (int *p) ++{ ++ long int readval = 0; ++ ++ __asm__ __volatile__ ("lock; cmpxchgl %2, %0" ++ : "+m" (*p), "+a" (readval) ++ : "r" (1) ++ : "cc"); ++ return readval; ++} ++#endif ++ ++#ifdef __s390__ ++static inline int testandset (int *p) ++{ ++ int ret; ++ ++ __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" ++ " jl 0b" ++ : "=&d" (ret) ++ : "r" (1), "a" (p), "0" (*p) ++ : "cc", "memory" ); ++ return ret; ++} ++#endif ++ ++#ifdef __alpha__ ++static inline int testandset (int *p) ++{ ++ int ret; ++ unsigned long one; ++ ++ __asm__ __volatile__ ("0: mov 1,%2\n" ++ " ldl_l %0,%1\n" ++ " stl_c %2,%1\n" ++ " beq %2,1f\n" ++ ".subsection 2\n" ++ "1: br 0b\n" ++ ".previous" ++ : "=r" (ret), "=m" (*p), "=r" (one) ++ : "m" (*p)); ++ return ret; ++} ++#endif ++ ++#ifdef __sparc__ ++static inline int testandset (int *p) ++{ ++ int ret; ++ ++ __asm__ __volatile__("ldstub [%1], %0" ++ : "=r" (ret) ++ : "r" (p) ++ : "memory"); ++ ++ return (ret ? 1 : 0); ++} ++#endif ++ ++#ifdef __arm__ ++static inline int testandset (int *spinlock) ++{ ++ register unsigned int ret; ++ __asm__ __volatile__("swp %0, %1, [%2]" ++ : "=r"(ret) ++ : "0"(1), "r"(spinlock)); ++ ++ return ret; ++} ++#endif ++ ++#ifdef __mc68000 ++static inline int testandset (int *p) ++{ ++ char ret; ++ __asm__ __volatile__("tas %1; sne %0" ++ : "=r" (ret) ++ : "m" (p) ++ : "cc","memory"); ++ return ret; ++} ++#endif ++ ++#ifdef __ia64 ++#include ++ ++static inline int testandset (int *p) ++{ ++ return __sync_lock_test_and_set (p, 1); ++} ++#endif ++ ++typedef int spinlock_t; ++ ++#define SPIN_LOCK_UNLOCKED 0 ++ ++#if defined(CONFIG_USER_ONLY) ++static inline void spin_lock(spinlock_t *lock) ++{ ++ while (testandset(lock)); ++} ++ ++static inline void spin_unlock(spinlock_t *lock) ++{ ++ *lock = 0; ++} ++ ++static inline int spin_trylock(spinlock_t *lock) ++{ ++ return !testandset(lock); ++} ++#else ++static inline void spin_lock(spinlock_t *lock) ++{ ++} ++ ++static inline void spin_unlock(spinlock_t *lock) ++{ ++} ++ ++static inline int spin_trylock(spinlock_t *lock) ++{ ++ return 1; ++} ++#endif ++ ++#endif /* ! _QEMU_SPINLOCK_H */ + diff --git a/packages/qemu/qemu-0.8.2/.mtn2git_empty b/packages/qemu/qemu-0.8.2/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/qemu/qemu-0.8.2/arm_nptl.patch b/packages/qemu/qemu-0.8.2/arm_nptl.patch new file mode 100644 index 0000000000..f9b10aebc5 --- /dev/null +++ b/packages/qemu/qemu-0.8.2/arm_nptl.patch @@ -0,0 +1,857 @@ +Index: qemu/configure +=================================================================== +--- qemu.orig/configure 2006-08-26 16:31:53.000000000 +0100 ++++ qemu/configure 2006-08-26 16:31:53.000000000 +0100 +@@ -97,6 +97,7 @@ + build_docs="no" + build_acpi_tables="no" + uname_release="" ++nptl="yes" + + # OS specific + targetos=`uname -s` +@@ -243,6 +244,8 @@ + ;; + --enable-iasl) build_acpi_tables="yes" + ;; ++ --disable-nptl) nptl="no" ++ ;; + esac + done + +@@ -441,6 +444,23 @@ + fi + fi + ++# check NPTL support ++cat > $TMPC < ++void foo() ++{ ++#ifndef CLONE_SETTLS ++#error bork ++#endif ++} ++EOF ++ ++if $cc -c -o $TMPO $TMPC 2> /dev/null ; then ++ : ++else ++ nptl="no" ++fi ++ + ########################################## + # SDL probe + +@@ -559,6 +579,7 @@ + fi + echo "FMOD support $fmod $fmod_support" + echo "kqemu support $kqemu" ++echo "NPTL support $nptl" + echo "Documentation $build_docs" + [ ! -z "$uname_release" ] && \ + echo "uname -r $uname_release" +@@ -880,6 +901,14 @@ + echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak + fi + fi ++else ++ if test "$nptl" = "yes" ; then ++ case "$target_cpu" in ++ arm | armeb) ++ echo "#define USE_NPTL 1" >> $config_h ++ ;; ++ esac ++ fi + fi + + if test "$cocoa" = "yes" ; then +Index: qemu/exec-all.h +=================================================================== +--- qemu.orig/exec-all.h 2006-08-26 16:28:32.000000000 +0100 ++++ qemu/exec-all.h 2006-08-26 16:31:53.000000000 +0100 +@@ -347,163 +347,7 @@ + extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; + extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; + +-#ifdef __powerpc__ +-static inline int testandset (int *p) +-{ +- int ret; +- __asm__ __volatile__ ( +- "0: lwarx %0,0,%1\n" +- " xor. %0,%3,%0\n" +- " bne 1f\n" +- " stwcx. %2,0,%1\n" +- " bne- 0b\n" +- "1: " +- : "=&r" (ret) +- : "r" (p), "r" (1), "r" (0) +- : "cr0", "memory"); +- return ret; +-} +-#endif +- +-#ifdef __i386__ +-static inline int testandset (int *p) +-{ +- long int readval = 0; +- +- __asm__ __volatile__ ("lock; cmpxchgl %2, %0" +- : "+m" (*p), "+a" (readval) +- : "r" (1) +- : "cc"); +- return readval; +-} +-#endif +- +-#ifdef __x86_64__ +-static inline int testandset (int *p) +-{ +- long int readval = 0; +- +- __asm__ __volatile__ ("lock; cmpxchgl %2, %0" +- : "+m" (*p), "+a" (readval) +- : "r" (1) +- : "cc"); +- return readval; +-} +-#endif +- +-#ifdef __s390__ +-static inline int testandset (int *p) +-{ +- int ret; +- +- __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" +- " jl 0b" +- : "=&d" (ret) +- : "r" (1), "a" (p), "0" (*p) +- : "cc", "memory" ); +- return ret; +-} +-#endif +- +-#ifdef __alpha__ +-static inline int testandset (int *p) +-{ +- int ret; +- unsigned long one; +- +- __asm__ __volatile__ ("0: mov 1,%2\n" +- " ldl_l %0,%1\n" +- " stl_c %2,%1\n" +- " beq %2,1f\n" +- ".subsection 2\n" +- "1: br 0b\n" +- ".previous" +- : "=r" (ret), "=m" (*p), "=r" (one) +- : "m" (*p)); +- return ret; +-} +-#endif +- +-#ifdef __sparc__ +-static inline int testandset (int *p) +-{ +- int ret; +- +- __asm__ __volatile__("ldstub [%1], %0" +- : "=r" (ret) +- : "r" (p) +- : "memory"); +- +- return (ret ? 1 : 0); +-} +-#endif +- +-#ifdef __arm__ +-static inline int testandset (int *spinlock) +-{ +- register unsigned int ret; +- __asm__ __volatile__("swp %0, %1, [%2]" +- : "=r"(ret) +- : "0"(1), "r"(spinlock)); +- +- return ret; +-} +-#endif +- +-#ifdef __mc68000 +-static inline int testandset (int *p) +-{ +- char ret; +- __asm__ __volatile__("tas %1; sne %0" +- : "=r" (ret) +- : "m" (p) +- : "cc","memory"); +- return ret; +-} +-#endif +- +-#ifdef __ia64 +-#include +- +-static inline int testandset (int *p) +-{ +- return __sync_lock_test_and_set (p, 1); +-} +-#endif +- +-typedef int spinlock_t; +- +-#define SPIN_LOCK_UNLOCKED 0 +- +-#if defined(CONFIG_USER_ONLY) +-static inline void spin_lock(spinlock_t *lock) +-{ +- while (testandset(lock)); +-} +- +-static inline void spin_unlock(spinlock_t *lock) +-{ +- *lock = 0; +-} +- +-static inline int spin_trylock(spinlock_t *lock) +-{ +- return !testandset(lock); +-} +-#else +-static inline void spin_lock(spinlock_t *lock) +-{ +-} +- +-static inline void spin_unlock(spinlock_t *lock) +-{ +-} +- +-static inline int spin_trylock(spinlock_t *lock) +-{ +- return 1; +-} +-#endif ++#include "qemu_spinlock.h" + + extern spinlock_t tb_lock; + +Index: qemu/linux-user/arm/syscall.h +=================================================================== +--- qemu.orig/linux-user/arm/syscall.h 2006-03-09 19:18:11.000000000 +0000 ++++ qemu/linux-user/arm/syscall.h 2006-08-26 16:31:53.000000000 +0100 +@@ -28,7 +28,9 @@ + #define ARM_SYSCALL_BASE 0x900000 + #define ARM_THUMB_SYSCALL 0 + +-#define ARM_NR_cacheflush (ARM_SYSCALL_BASE + 0xf0000 + 2) ++#define ARM_NR_BASE 0xf0000 ++#define ARM_NR_cacheflush (ARM_NR_BASE + 2) ++#define ARM_NR_set_tls (ARM_NR_BASE + 5) + + #define ARM_NR_semihosting 0x123456 + #define ARM_NR_thumb_semihosting 0xAB +Index: qemu/linux-user/main.c +=================================================================== +--- qemu.orig/linux-user/main.c 2006-08-26 16:28:40.000000000 +0100 ++++ qemu/linux-user/main.c 2006-08-26 16:31:53.000000000 +0100 +@@ -309,6 +309,50 @@ + } + } + ++/* Handle a jump to the kernel code page. */ ++static int ++do_kernel_trap(CPUARMState *env) ++{ ++ uint32_t addr; ++ uint32_t *ptr; ++ uint32_t cpsr; ++ ++ switch (env->regs[15]) { ++ case 0xffff0fc0: /* __kernel_cmpxchg */ ++ /* XXX: This only works between threads, not between processes. ++ Use native atomic operations. */ ++ /* ??? This probably breaks horribly if the access segfaults. */ ++ cpu_lock(); ++ ptr = (uint32_t *)env->regs[2]; ++ cpsr = cpsr_read(env); ++ if (*ptr == env->regs[0]) { ++ *ptr = env->regs[1]; ++ env->regs[0] = 0; ++ cpsr |= CPSR_C; ++ } else { ++ env->regs[0] = -1; ++ cpsr &= ~CPSR_C; ++ } ++ cpsr_write(env, cpsr, CPSR_C); ++ cpu_unlock(); ++ break; ++ case 0xffff0fe0: /* __kernel_get_tls */ ++ env->regs[0] = env->cp15.c13_tls; ++ break; ++ default: ++ return 1; ++ } ++ /* Jump back to the caller. */ ++ addr = env->regs[14]; ++ if (addr & 1) { ++ env->thumb = 1; ++ addr &= ~1; ++ } ++ env->regs[15] = addr; ++ ++ return 0; ++} ++ + void cpu_loop(CPUARMState *env) + { + int trapnr; +@@ -365,10 +409,8 @@ + } + } + +- if (n == ARM_NR_cacheflush) { +- arm_cache_flush(env->regs[0], env->regs[1]); +- } else if (n == ARM_NR_semihosting +- || n == ARM_NR_thumb_semihosting) { ++ if (n == ARM_NR_semihosting ++ || n == ARM_NR_thumb_semihosting) { + env->regs[0] = do_arm_semihosting (env); + } else if (n == 0 || n >= ARM_SYSCALL_BASE + || (env->thumb && n == ARM_THUMB_SYSCALL)) { +@@ -379,14 +421,34 @@ + n -= ARM_SYSCALL_BASE; + env->eabi = 0; + } +- env->regs[0] = do_syscall(env, +- n, +- env->regs[0], +- env->regs[1], +- env->regs[2], +- env->regs[3], +- env->regs[4], +- env->regs[5]); ++ if ( n > ARM_NR_BASE) { ++ switch (n) ++ { ++ case ARM_NR_cacheflush: ++ arm_cache_flush(env->regs[0], env->regs[1]); ++ break; ++#ifdef USE_NPTL ++ case ARM_NR_set_tls: ++ cpu_set_tls(env, env->regs[0]); ++ env->regs[0] = 0; ++ break; ++#endif ++ default: ++ printf ("Error: Bad syscall: %x\n", n); ++ goto error; ++ } ++ } ++ else ++ { ++ env->regs[0] = do_syscall(env, ++ n, ++ env->regs[0], ++ env->regs[1], ++ env->regs[2], ++ env->regs[3], ++ env->regs[4], ++ env->regs[5]); ++ } + } else { + goto error; + } +@@ -425,6 +487,10 @@ + } + } + break; ++ case EXCP_KERNEL_TRAP: ++ if (do_kernel_trap(env)) ++ goto error; ++ break; + default: + error: + fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", +@@ -1639,6 +1705,10 @@ + ts->heap_base = info->brk; + /* This will be filled in on the first SYS_HEAPINFO call. */ + ts->heap_limit = 0; ++ /* Register the magic kernel code page. The cpu will generate a ++ special exception when it tries to execute code here. We can't ++ put real code here because it may be in use by the host kernel. */ ++ page_set_flags(0xffff0000, 0xffff0fff, 0); + } + #elif defined(TARGET_SPARC) + { +Index: qemu/linux-user/qemu.h +=================================================================== +--- qemu.orig/linux-user/qemu.h 2006-08-26 16:28:40.000000000 +0100 ++++ qemu/linux-user/qemu.h 2006-08-26 16:33:50.000000000 +0100 +@@ -75,6 +75,9 @@ + uint32_t v86mask; + #endif + int used; /* non zero if used */ ++#ifdef USE_NPTL ++ uint32_t *child_tidptr; ++#endif + struct image_info *info; + uint8_t stack[0]; + } __attribute__((aligned(16))) TaskState; +Index: qemu/linux-user/syscall.c +=================================================================== +--- qemu.orig/linux-user/syscall.c 2006-08-26 16:28:40.000000000 +0100 ++++ qemu/linux-user/syscall.c 2006-08-26 16:31:53.000000000 +0100 +@@ -66,9 +66,18 @@ + #include + + #include "qemu.h" ++#include "qemu_spinlock.h" + + //#define DEBUG + ++#ifdef USE_NPTL ++#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \ ++ CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID) ++#else ++/* XXX: Hardcode the above values. */ ++#define CLONE_NPTL_FLAGS2 0 ++#endif ++ + #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) + /* 16 bit uid wrappers emulation */ + #define USE_UID16 +@@ -1602,20 +1611,38 @@ + thread/process */ + #define NEW_STACK_SIZE 8192 + ++#ifdef USE_NPTL ++static spinlock_t nptl_lock = SPIN_LOCK_UNLOCKED; ++#endif ++ + static int clone_func(void *arg) + { + CPUState *env = arg; ++#ifdef HAVE_NPTL ++ /* Wait until the parent has finshed initializing the tls state. */ ++ while (!spin_trylock(&nptl_lock)) ++ usleep(1); ++ spin_unlock(&nptl_lock); ++#endif + cpu_loop(env); + /* never exits */ + return 0; + } + +-int do_fork(CPUState *env, unsigned int flags, unsigned long newsp) ++int do_fork(CPUState *env, unsigned int flags, unsigned long newsp, ++ uint32_t *parent_tidptr, void *newtls, ++ uint32_t *child_tidptr) + { + int ret; + TaskState *ts; + uint8_t *new_stack; + CPUState *new_env; ++#ifdef USE_NPTL ++ unsigned int nptl_flags; ++ ++ if (flags & CLONE_PARENT_SETTID) ++ *parent_tidptr = gettid(); ++#endif + + if (flags & CLONE_VM) { + ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); +@@ -1665,16 +1692,60 @@ + #error unsupported target CPU + #endif + new_env->opaque = ts; ++#ifdef USE_NPTL ++ nptl_flags = flags; ++ flags &= ~CLONE_NPTL_FLAGS2; ++ if (nptl_flags & CLONE_CHILD_CLEARTID) { ++ ts->child_tidptr = child_tidptr; ++ } ++ if (nptl_flags & CLONE_SETTLS) ++ cpu_set_tls (new_env, newtls); ++ /* Grab the global cpu lock so that the thread setup appears ++ atomic. */ ++ if (nptl_flags & CLONE_CHILD_SETTID) ++ spin_lock(&nptl_lock); ++#else ++ if (flags & CLONE_NPTL_FLAGS2) ++ return -EINVAL; ++#endif ++ + #ifdef __ia64__ + ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); + #else + ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); + #endif ++#ifdef USE_NPTL ++ if (ret != -1) { ++ if (nptl_flags & CLONE_CHILD_SETTID) ++ *child_tidptr = ret; ++ } ++ /* Allow the child to continue. */ ++ if (nptl_flags & CLONE_CHILD_SETTID) ++ spin_unlock(&nptl_lock); ++#endif + } else { +- /* if no CLONE_VM, we consider it is a fork */ +- if ((flags & ~CSIGNAL) != 0) +- return -EINVAL; +- ret = fork(); ++ /* if no CLONE_VM, we consider it is a fork */ ++ if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) ++ return -EINVAL; ++ ret = fork(); ++#ifdef USE_NPTL ++ /* There is a race condition here. The parent process could ++ theoretically read the TID in the child process before the child ++ tid is set. This would require using either ptrace ++ (not implemented) or having *_tidptr to point at a shared memory ++ mapping. We can't repeat the spinlock hack used above because ++ the child process gets its own copy of the lock. */ ++ if (ret == 0) { ++ /* Child Process. */ ++ if (flags & CLONE_CHILD_SETTID) ++ *child_tidptr = gettid(); ++ ts = (TaskState *)env->opaque; ++ if (flags & CLONE_CHILD_CLEARTID) ++ ts->child_tidptr = child_tidptr; ++ if (flags & CLONE_SETTLS) ++ cpu_set_tls (env, newtls); ++ } ++#endif + } + return ret; + } +@@ -1918,7 +1989,7 @@ + ret = do_brk(arg1); + break; + case TARGET_NR_fork: +- ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); ++ ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, NULL, NULL, NULL)); + break; + case TARGET_NR_waitpid: + { +@@ -2989,7 +3060,8 @@ + ret = get_errno(fsync(arg1)); + break; + case TARGET_NR_clone: +- ret = get_errno(do_fork(cpu_env, arg1, arg2)); ++ ret = get_errno(do_fork(cpu_env, arg1, arg2, (uint32_t *)arg3, ++ (void *)arg4, (uint32_t *)arg5)); + break; + #ifdef __NR_exit_group + /* new thread calls */ +@@ -3339,7 +3411,8 @@ + #endif + #ifdef TARGET_NR_vfork + case TARGET_NR_vfork: +- ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0)); ++ ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0, ++ NULL, NULL, NULL)); + break; + #endif + #ifdef TARGET_NR_ugetrlimit +@@ -3838,4 +3911,3 @@ + #endif + return ret; + } +- +Index: qemu/target-arm/cpu.h +=================================================================== +--- qemu.orig/target-arm/cpu.h 2006-03-09 19:18:27.000000000 +0000 ++++ qemu/target-arm/cpu.h 2006-08-26 16:31:53.000000000 +0100 +@@ -35,6 +35,9 @@ + #define EXCP_IRQ 5 + #define EXCP_FIQ 6 + #define EXCP_BKPT 7 ++#define EXCP_KERNEL_TRAP 8 /* Jumped to kernel code page. */ ++ ++ + + /* We currently assume float and double are IEEE single and double + precision respectively. +@@ -85,6 +88,7 @@ + uint32_t c9_data; + uint32_t c13_fcse; /* FCSE PID. */ + uint32_t c13_context; /* Context ID. */ ++ uint32_t c13_tls; /* Paul Brook told me to just add this ;) */ + } cp15; + + /* Internal CPU feature flags. */ +@@ -135,6 +139,15 @@ + int cpu_arm_signal_handler(int host_signum, struct siginfo *info, + void *puc); + ++void cpu_lock(void); ++void cpu_unlock(void); ++#if defined(USE_NPTL) ++static inline void cpu_set_tls(CPUARMState *env, void *newtls) ++{ ++ env->cp15.c13_tls = (uint32_t)newtls; ++} ++#endif ++ + #define CPSR_M (0x1f) + #define CPSR_T (1 << 5) + #define CPSR_F (1 << 6) +@@ -146,7 +159,11 @@ + #define CPSR_J (1 << 24) + #define CPSR_IT_0_1 (3 << 25) + #define CPSR_Q (1 << 27) +-#define CPSR_NZCV (0xf << 28) ++#define CPSR_V (1 << 28) ++#define CPSR_C (1 << 29) ++#define CPSR_Z (1 << 30) ++#define CPSR_N (1 << 31) ++#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V) + + #define CACHED_CPSR_BITS (CPSR_T | CPSR_Q | CPSR_NZCV) + /* Return the current CPSR value. */ +Index: qemu/target-arm/exec.h +=================================================================== +--- qemu.orig/target-arm/exec.h 2006-03-09 19:18:27.000000000 +0000 ++++ qemu/target-arm/exec.h 2006-08-26 16:31:53.000000000 +0100 +@@ -51,8 +51,6 @@ + + /* In op_helper.c */ + +-void cpu_lock(void); +-void cpu_unlock(void); + void helper_set_cp15(CPUState *, uint32_t, uint32_t); + uint32_t helper_get_cp15(CPUState *, uint32_t); + +Index: qemu/target-arm/op.c +=================================================================== +--- qemu.orig/target-arm/op.c 2006-08-26 16:28:48.000000000 +0100 ++++ qemu/target-arm/op.c 2006-08-26 16:31:53.000000000 +0100 +@@ -891,6 +891,12 @@ + cpu_loop_exit(); + } + ++void OPPROTO op_kernel_trap(void) ++{ ++ env->exception_index = EXCP_KERNEL_TRAP; ++ cpu_loop_exit(); ++} ++ + /* VFP support. We follow the convention used for VFP instrunctions: + Single precition routines have a "s" suffix, double precision a + "d" suffix. */ +Index: qemu/target-arm/translate.c +=================================================================== +--- qemu.orig/target-arm/translate.c 2006-08-26 16:28:48.000000000 +0100 ++++ qemu/target-arm/translate.c 2006-08-26 16:31:53.000000000 +0100 +@@ -2382,6 +2382,7 @@ + s->is_jmp = DISAS_JUMP; + } + ++ + /* generate intermediate code in gen_opc_buf and gen_opparam_buf for + basic block 'tb'. If search_pc is TRUE, also generate PC + information for each intermediate instruction. */ +@@ -2416,6 +2417,15 @@ + nb_gen_labels = 0; + lj = -1; + do { ++#ifdef CONFIG_USER_ONLY ++ /* Intercept jump to the magic kernel page. */ ++ if (dc->pc > 0xffff0000) { ++ gen_op_kernel_trap(); ++ dc->is_jmp = DISAS_UPDATE; ++ break; ++ } ++#endif ++ + if (env->nb_breakpoints > 0) { + for(j = 0; j < env->nb_breakpoints; j++) { + if (env->breakpoints[j] == dc->pc) { +Index: qemu/qemu_spinlock.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ qemu/qemu_spinlock.h 2006-08-26 16:31:53.000000000 +0100 +@@ -0,0 +1,182 @@ ++/* ++ * internal execution defines for qemu ++ * ++ * Copyright (c) 2003 Fabrice Bellard ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#ifndef _QEMU_SPINLOCK_H ++#define _QEMU_SPINLOCK_H ++ ++#ifdef __powerpc__ ++static inline int testandset (int *p) ++{ ++ int ret; ++ __asm__ __volatile__ ( ++ "0: lwarx %0,0,%1\n" ++ " xor. %0,%3,%0\n" ++ " bne 1f\n" ++ " stwcx. %2,0,%1\n" ++ " bne- 0b\n" ++ "1: " ++ : "=&r" (ret) ++ : "r" (p), "r" (1), "r" (0) ++ : "cr0", "memory"); ++ return ret; ++} ++#endif ++ ++#ifdef __i386__ ++static inline int testandset (int *p) ++{ ++ long int readval = 0; ++ ++ __asm__ __volatile__ ("lock; cmpxchgl %2, %0" ++ : "+m" (*p), "+a" (readval) ++ : "r" (1) ++ : "cc"); ++ return readval; ++} ++#endif ++ ++#ifdef __x86_64__ ++static inline int testandset (int *p) ++{ ++ long int readval = 0; ++ ++ __asm__ __volatile__ ("lock; cmpxchgl %2, %0" ++ : "+m" (*p), "+a" (readval) ++ : "r" (1) ++ : "cc"); ++ return readval; ++} ++#endif ++ ++#ifdef __s390__ ++static inline int testandset (int *p) ++{ ++ int ret; ++ ++ __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" ++ " jl 0b" ++ : "=&d" (ret) ++ : "r" (1), "a" (p), "0" (*p) ++ : "cc", "memory" ); ++ return ret; ++} ++#endif ++ ++#ifdef __alpha__ ++static inline int testandset (int *p) ++{ ++ int ret; ++ unsigned long one; ++ ++ __asm__ __volatile__ ("0: mov 1,%2\n" ++ " ldl_l %0,%1\n" ++ " stl_c %2,%1\n" ++ " beq %2,1f\n" ++ ".subsection 2\n" ++ "1: br 0b\n" ++ ".previous" ++ : "=r" (ret), "=m" (*p), "=r" (one) ++ : "m" (*p)); ++ return ret; ++} ++#endif ++ ++#ifdef __sparc__ ++static inline int testandset (int *p) ++{ ++ int ret; ++ ++ __asm__ __volatile__("ldstub [%1], %0" ++ : "=r" (ret) ++ : "r" (p) ++ : "memory"); ++ ++ return (ret ? 1 : 0); ++} ++#endif ++ ++#ifdef __arm__ ++static inline int testandset (int *spinlock) ++{ ++ register unsigned int ret; ++ __asm__ __volatile__("swp %0, %1, [%2]" ++ : "=r"(ret) ++ : "0"(1), "r"(spinlock)); ++ ++ return ret; ++} ++#endif ++ ++#ifdef __mc68000 ++static inline int testandset (int *p) ++{ ++ char ret; ++ __asm__ __volatile__("tas %1; sne %0" ++ : "=r" (ret) ++ : "m" (p) ++ : "cc","memory"); ++ return ret; ++} ++#endif ++ ++#ifdef __ia64 ++#include ++ ++static inline int testandset (int *p) ++{ ++ return __sync_lock_test_and_set (p, 1); ++} ++#endif ++ ++typedef int spinlock_t; ++ ++#define SPIN_LOCK_UNLOCKED 0 ++ ++#if defined(CONFIG_USER_ONLY) ++static inline void spin_lock(spinlock_t *lock) ++{ ++ while (testandset(lock)); ++} ++ ++static inline void spin_unlock(spinlock_t *lock) ++{ ++ *lock = 0; ++} ++ ++static inline int spin_trylock(spinlock_t *lock) ++{ ++ return !testandset(lock); ++} ++#else ++static inline void spin_lock(spinlock_t *lock) ++{ ++} ++ ++static inline void spin_unlock(spinlock_t *lock) ++{ ++} ++ ++static inline int spin_trylock(spinlock_t *lock) ++{ ++ return 1; ++} ++#endif ++ ++#endif /* ! _QEMU_SPINLOCK_H */ diff --git a/packages/qemu/qemu-native_0.8.0.bb b/packages/qemu/qemu-native_0.8.0.bb index acb5543a90..2b143bdc0f 100644 --- a/packages/qemu/qemu-native_0.8.0.bb +++ b/packages/qemu/qemu-native_0.8.0.bb @@ -1,5 +1,6 @@ require qemu_${PV}.bb inherit native +FILESPATH =. "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/qemu-${PV}:" S = "${WORKDIR}/qemu-${PV}" prefix = "${STAGING_DIR}/${BUILD_SYS}" diff --git a/packages/qemu/qemu-native_0.8.2.bb b/packages/qemu/qemu-native_0.8.2.bb new file mode 100644 index 0000000000..2b143bdc0f --- /dev/null +++ b/packages/qemu/qemu-native_0.8.2.bb @@ -0,0 +1,6 @@ +require qemu_${PV}.bb +inherit native +FILESPATH =. "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/qemu-${PV}:" +S = "${WORKDIR}/qemu-${PV}" +prefix = "${STAGING_DIR}/${BUILD_SYS}" + diff --git a/packages/qemu/qemu_0.8.0.bb b/packages/qemu/qemu_0.8.0.bb index fd7a892347..38bbcbacad 100644 --- a/packages/qemu/qemu_0.8.0.bb +++ b/packages/qemu/qemu_0.8.0.bb @@ -1,6 +1,9 @@ LICENSE = "GPL" -SRC_URI = "http://fabrice.bellard.free.fr/qemu/qemu-${PV}.tar.gz" +SRC_URI = "http://fabrice.bellard.free.fr/qemu/qemu-${PV}.tar.gz \ + file://configure.patch;patch=1 \ + file://arm_nptl.patch;patch=1" +PR = "r1" inherit autotools diff --git a/packages/qemu/qemu_0.8.2.bb b/packages/qemu/qemu_0.8.2.bb new file mode 100644 index 0000000000..368eb44666 --- /dev/null +++ b/packages/qemu/qemu_0.8.2.bb @@ -0,0 +1,9 @@ +LICENSE = "GPL" + +SRC_URI = "http://fabrice.bellard.free.fr/qemu/qemu-${PV}.tar.gz \ + file://configure.patch;patch=1 \ + file://pl110_rgb-r0.patch;patch=1 \ + file://arm_nptl.patch;patch=1" + +inherit autotools + diff --git a/packages/qemu/qemu_cvs.bb b/packages/qemu/qemu_cvs.bb index 5697e69578..a44ff2bdbc 100644 --- a/packages/qemu/qemu_cvs.bb +++ b/packages/qemu/qemu_cvs.bb @@ -1,11 +1,12 @@ LICENSE = "GPL" PV = "0.8.0+cvs${SRCDATE}" -PR = "r1" +PR = "r2" SRC_URI = "cvs://anonymous@cvs.savannah.nongnu.org/sources/qemu;method=pserver;rsh=ssh;module=qemu \ file://configure.patch;patch=1 \ file://mouse_fix-r0.patch;patch=1 \ - file://pl110_rgb-r0.patch;patch=1" + file://pl110_rgb-r0.patch;patch=1 \ + file://arm_nptl.patch;patch=1" S = "${WORKDIR}/qemu" -- cgit v1.2.3 From eda54eb6defc01f75d6cc5b4e604911375592f2b Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sat, 26 Aug 2006 16:51:18 +0000 Subject: base.bbclass: Change FILESPATH handling to allow it to be appended/prepended to. Should be backwards compatible. --- classes/base.bbclass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/base.bbclass b/classes/base.bbclass index f936dff870..e413afb2b3 100644 --- a/classes/base.bbclass +++ b/classes/base.bbclass @@ -50,7 +50,7 @@ def base_set_filespath(path, d): overrides = overrides + ":" for o in overrides.split(":"): filespath.append(os.path.join(p, o)) - bb.data.setVar("FILESPATH", ":".join(filespath), d) + return ":".join(filespath) FILESPATH = "${@base_set_filespath([ "${FILE_DIRNAME}/${PF}", "${FILE_DIRNAME}/${P}", "${FILE_DIRNAME}/${PN}", "${FILE_DIRNAME}/files", "${FILE_DIRNAME}" ], d)}" -- cgit v1.2.3 From ddd6d1fd26416a3766d754eeda4237a680a65520 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 26 Aug 2006 17:39:33 +0000 Subject: angstrom: enable binary locale generation and add visbility stuff to cxxflags --- conf/distro/angstrom-2006.9.conf | 2 ++ conf/distro/include/angstrom.inc | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/conf/distro/angstrom-2006.9.conf b/conf/distro/angstrom-2006.9.conf index ca7ddc873d..327d4123cc 100644 --- a/conf/distro/angstrom-2006.9.conf +++ b/conf/distro/angstrom-2006.9.conf @@ -32,6 +32,8 @@ FEED_URIS += " \ SRCDATE_gconf-dbus = "20060719" SRCDATE_gnome-vfs-dbus = "20060803" +PREFERRED_VERSION_qemu-native = "0.8.2" + CVS_TARBALL_STASH = "\ http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4/sources/ \ http://www.oesources.org/source/current/" diff --git a/conf/distro/include/angstrom.inc b/conf/distro/include/angstrom.inc index 9c2679aff1..7e765bd925 100644 --- a/conf/distro/include/angstrom.inc +++ b/conf/distro/include/angstrom.inc @@ -16,8 +16,8 @@ MAINTAINER = "Angstrom Developers " INHERIT += "package_ipk debian multimachine" #Generate locales on the buildsystem instead of on the target. Speeds up first boot, set to "1" to enable -PREFERRED_PROVIDER_qemu-native = "qemu-qop-nogfx-native" -ENABLE_BINARY_LOCALE_GENERATION ?= "" +PREFERRED_PROVIDER_qemu-native = "qemu-native" +ENABLE_BINARY_LOCALE_GENERATION ?= "1" #Use the ARM EABI when building for an ARM cpu. We can't use overrides @@ -32,6 +32,7 @@ TARGET_OS = "linux${@['','-gnueabi'][bb.data.getVar('TARGET_ARCH',d,1)=='arm']}" #Please see http://free-electrons.com/doc/embedded_linux_optimizations/img47.html for some more info FULL_OPTIMIZATION = "-fexpensive-optimizations -fomit-frame-pointer -frename-registers -Os" BUILD_OPTIMIZATION = "-Os" +CXXFLAGS += "-fvisibility-inlines-hidden" #ARM EABI is softfloat by default, but let's make sure :) TARGET_FPU_arm = "soft" -- cgit v1.2.3 From cedf219f704f423b219b602de22b1ea7663df189 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sat, 26 Aug 2006 17:40:06 +0000 Subject: qemu cvs: Update SRCDATE to 20060723 --- conf/distro/include/sane-srcdates.inc | 2 +- packages/qemu/files/arm_nptl.patch | 86 +++++++++++++++++------------------ packages/qemu/qemu_cvs.bb | 4 +- 3 files changed, 45 insertions(+), 47 deletions(-) diff --git a/conf/distro/include/sane-srcdates.inc b/conf/distro/include/sane-srcdates.inc index b9cc82e1d3..0696ad1909 100644 --- a/conf/distro/include/sane-srcdates.inc +++ b/conf/distro/include/sane-srcdates.inc @@ -72,7 +72,7 @@ SRCDATE_oprofile ?= "20060214" SRCDATE_portaudio ?= "20060814" SRCDATE_putty ?= "20060814" SRCDATE_python-cairo ?= "20060814" -SRCDATE_qemu-native ?= "20060526" +SRCDATE_qemu-native ?= "20060723" SRCDATE_roadster ?= "20060814" SRCDATE_sctzap ?= "20060814" SRCDATE_tslib ?= "20051101" diff --git a/packages/qemu/files/arm_nptl.patch b/packages/qemu/files/arm_nptl.patch index 958c27e5e1..f9b10aebc5 100644 --- a/packages/qemu/files/arm_nptl.patch +++ b/packages/qemu/files/arm_nptl.patch @@ -1,25 +1,25 @@ Index: qemu/configure =================================================================== ---- qemu.orig/configure 2006-08-14 22:09:39.000000000 +0100 -+++ qemu/configure 2006-08-14 22:38:54.000000000 +0100 -@@ -96,6 +96,7 @@ - user="no" +--- qemu.orig/configure 2006-08-26 16:31:53.000000000 +0100 ++++ qemu/configure 2006-08-26 16:31:53.000000000 +0100 +@@ -97,6 +97,7 @@ build_docs="no" + build_acpi_tables="no" uname_release="" +nptl="yes" # OS specific targetos=`uname -s` -@@ -240,6 +241,8 @@ +@@ -243,6 +244,8 @@ ;; - --enable-uname-release=*) uname_release="$optarg" + --enable-iasl) build_acpi_tables="yes" ;; + --disable-nptl) nptl="no" + ;; esac done -@@ -438,6 +441,23 @@ +@@ -441,6 +444,23 @@ fi fi @@ -43,7 +43,7 @@ Index: qemu/configure ########################################## # SDL probe -@@ -556,6 +576,7 @@ +@@ -559,6 +579,7 @@ fi echo "FMOD support $fmod $fmod_support" echo "kqemu support $kqemu" @@ -51,7 +51,7 @@ Index: qemu/configure echo "Documentation $build_docs" [ ! -z "$uname_release" ] && \ echo "uname -r $uname_release" -@@ -864,6 +885,14 @@ +@@ -880,6 +901,14 @@ echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak fi fi @@ -68,8 +68,8 @@ Index: qemu/configure if test "$cocoa" = "yes" ; then Index: qemu/exec-all.h =================================================================== ---- qemu.orig/exec-all.h 2006-05-26 18:10:52.000000000 +0100 -+++ qemu/exec-all.h 2006-08-14 22:37:29.000000000 +0100 +--- qemu.orig/exec-all.h 2006-08-26 16:28:32.000000000 +0100 ++++ qemu/exec-all.h 2006-08-26 16:31:53.000000000 +0100 @@ -347,163 +347,7 @@ extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; @@ -237,8 +237,8 @@ Index: qemu/exec-all.h Index: qemu/linux-user/arm/syscall.h =================================================================== ---- qemu.orig/linux-user/arm/syscall.h 2005-04-27 21:11:21.000000000 +0100 -+++ qemu/linux-user/arm/syscall.h 2006-08-14 22:37:29.000000000 +0100 +--- qemu.orig/linux-user/arm/syscall.h 2006-03-09 19:18:11.000000000 +0000 ++++ qemu/linux-user/arm/syscall.h 2006-08-26 16:31:53.000000000 +0100 @@ -28,7 +28,9 @@ #define ARM_SYSCALL_BASE 0x900000 #define ARM_THUMB_SYSCALL 0 @@ -252,9 +252,9 @@ Index: qemu/linux-user/arm/syscall.h #define ARM_NR_thumb_semihosting 0xAB Index: qemu/linux-user/main.c =================================================================== ---- qemu.orig/linux-user/main.c 2006-05-26 18:11:01.000000000 +0100 -+++ qemu/linux-user/main.c 2006-08-14 22:37:29.000000000 +0100 -@@ -331,6 +331,50 @@ +--- qemu.orig/linux-user/main.c 2006-08-26 16:28:40.000000000 +0100 ++++ qemu/linux-user/main.c 2006-08-26 16:31:53.000000000 +0100 +@@ -309,6 +309,50 @@ } } @@ -305,7 +305,7 @@ Index: qemu/linux-user/main.c void cpu_loop(CPUARMState *env) { int trapnr; -@@ -387,10 +431,8 @@ +@@ -365,10 +409,8 @@ } } @@ -318,7 +318,7 @@ Index: qemu/linux-user/main.c env->regs[0] = do_arm_semihosting (env); } else if (n == 0 || n >= ARM_SYSCALL_BASE || (env->thumb && n == ARM_THUMB_SYSCALL)) { -@@ -401,14 +443,34 @@ +@@ -379,14 +421,34 @@ n -= ARM_SYSCALL_BASE; env->eabi = 0; } @@ -361,7 +361,7 @@ Index: qemu/linux-user/main.c } else { goto error; } -@@ -447,6 +509,10 @@ +@@ -425,6 +487,10 @@ } } break; @@ -372,7 +372,7 @@ Index: qemu/linux-user/main.c default: error: fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", -@@ -1649,6 +1715,10 @@ +@@ -1639,6 +1705,10 @@ ts->heap_base = info->brk; /* This will be filled in on the first SYS_HEAPINFO call. */ ts->heap_limit = 0; @@ -385,22 +385,22 @@ Index: qemu/linux-user/main.c { Index: qemu/linux-user/qemu.h =================================================================== ---- qemu.orig/linux-user/qemu.h 2006-05-26 18:11:01.000000000 +0100 -+++ qemu/linux-user/qemu.h 2006-08-14 22:37:29.000000000 +0100 -@@ -76,6 +76,9 @@ +--- qemu.orig/linux-user/qemu.h 2006-08-26 16:28:40.000000000 +0100 ++++ qemu/linux-user/qemu.h 2006-08-26 16:33:50.000000000 +0100 +@@ -75,6 +75,9 @@ uint32_t v86mask; #endif int used; /* non zero if used */ +#ifdef USE_NPTL + uint32_t *child_tidptr; +#endif + struct image_info *info; uint8_t stack[0]; } __attribute__((aligned(16))) TaskState; - Index: qemu/linux-user/syscall.c =================================================================== ---- qemu.orig/linux-user/syscall.c 2006-05-26 18:11:01.000000000 +0100 -+++ qemu/linux-user/syscall.c 2006-08-14 22:44:47.000000000 +0100 +--- qemu.orig/linux-user/syscall.c 2006-08-26 16:28:40.000000000 +0100 ++++ qemu/linux-user/syscall.c 2006-08-26 16:31:53.000000000 +0100 @@ -66,9 +66,18 @@ #include @@ -420,7 +420,7 @@ Index: qemu/linux-user/syscall.c #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) /* 16 bit uid wrappers emulation */ #define USE_UID16 -@@ -1569,20 +1578,38 @@ +@@ -1602,20 +1611,38 @@ thread/process */ #define NEW_STACK_SIZE 8192 @@ -460,7 +460,7 @@ Index: qemu/linux-user/syscall.c if (flags & CLONE_VM) { ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); -@@ -1627,16 +1654,60 @@ +@@ -1665,16 +1692,60 @@ #error unsupported target CPU #endif new_env->opaque = ts; @@ -525,7 +525,7 @@ Index: qemu/linux-user/syscall.c } return ret; } -@@ -1880,7 +1951,7 @@ +@@ -1918,7 +1989,7 @@ ret = do_brk(arg1); break; case TARGET_NR_fork: @@ -534,7 +534,7 @@ Index: qemu/linux-user/syscall.c break; case TARGET_NR_waitpid: { -@@ -2836,7 +2907,8 @@ +@@ -2989,7 +3060,8 @@ ret = get_errno(fsync(arg1)); break; case TARGET_NR_clone: @@ -544,7 +544,7 @@ Index: qemu/linux-user/syscall.c break; #ifdef __NR_exit_group /* new thread calls */ -@@ -3186,7 +3258,8 @@ +@@ -3339,7 +3411,8 @@ #endif #ifdef TARGET_NR_vfork case TARGET_NR_vfork: @@ -554,15 +554,15 @@ Index: qemu/linux-user/syscall.c break; #endif #ifdef TARGET_NR_ugetrlimit -@@ -3681,4 +3754,3 @@ +@@ -3838,4 +3911,3 @@ #endif return ret; } - Index: qemu/target-arm/cpu.h =================================================================== ---- qemu.orig/target-arm/cpu.h 2006-02-20 00:33:36.000000000 +0000 -+++ qemu/target-arm/cpu.h 2006-08-14 22:39:35.000000000 +0100 +--- qemu.orig/target-arm/cpu.h 2006-03-09 19:18:27.000000000 +0000 ++++ qemu/target-arm/cpu.h 2006-08-26 16:31:53.000000000 +0100 @@ -35,6 +35,9 @@ #define EXCP_IRQ 5 #define EXCP_FIQ 6 @@ -612,8 +612,8 @@ Index: qemu/target-arm/cpu.h /* Return the current CPSR value. */ Index: qemu/target-arm/exec.h =================================================================== ---- qemu.orig/target-arm/exec.h 2005-11-26 10:38:39.000000000 +0000 -+++ qemu/target-arm/exec.h 2006-08-14 22:37:29.000000000 +0100 +--- qemu.orig/target-arm/exec.h 2006-03-09 19:18:27.000000000 +0000 ++++ qemu/target-arm/exec.h 2006-08-26 16:31:53.000000000 +0100 @@ -51,8 +51,6 @@ /* In op_helper.c */ @@ -625,8 +625,8 @@ Index: qemu/target-arm/exec.h Index: qemu/target-arm/op.c =================================================================== ---- qemu.orig/target-arm/op.c 2006-02-20 00:33:36.000000000 +0000 -+++ qemu/target-arm/op.c 2006-08-14 22:37:29.000000000 +0100 +--- qemu.orig/target-arm/op.c 2006-08-26 16:28:48.000000000 +0100 ++++ qemu/target-arm/op.c 2006-08-26 16:31:53.000000000 +0100 @@ -891,6 +891,12 @@ cpu_loop_exit(); } @@ -642,9 +642,9 @@ Index: qemu/target-arm/op.c "d" suffix. */ Index: qemu/target-arm/translate.c =================================================================== ---- qemu.orig/target-arm/translate.c 2006-05-26 18:11:04.000000000 +0100 -+++ qemu/target-arm/translate.c 2006-08-14 22:37:29.000000000 +0100 -@@ -2377,6 +2377,7 @@ +--- qemu.orig/target-arm/translate.c 2006-08-26 16:28:48.000000000 +0100 ++++ qemu/target-arm/translate.c 2006-08-26 16:31:53.000000000 +0100 +@@ -2382,6 +2382,7 @@ s->is_jmp = DISAS_JUMP; } @@ -652,7 +652,7 @@ Index: qemu/target-arm/translate.c /* generate intermediate code in gen_opc_buf and gen_opparam_buf for basic block 'tb'. If search_pc is TRUE, also generate PC information for each intermediate instruction. */ -@@ -2411,6 +2412,15 @@ +@@ -2416,6 +2417,15 @@ nb_gen_labels = 0; lj = -1; do { @@ -671,7 +671,7 @@ Index: qemu/target-arm/translate.c Index: qemu/qemu_spinlock.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ qemu/qemu_spinlock.h 2006-08-14 22:37:29.000000000 +0100 ++++ qemu/qemu_spinlock.h 2006-08-26 16:31:53.000000000 +0100 @@ -0,0 +1,182 @@ +/* + * internal execution defines for qemu diff --git a/packages/qemu/qemu_cvs.bb b/packages/qemu/qemu_cvs.bb index a44ff2bdbc..0dfe01aa11 100644 --- a/packages/qemu/qemu_cvs.bb +++ b/packages/qemu/qemu_cvs.bb @@ -1,10 +1,8 @@ LICENSE = "GPL" -PV = "0.8.0+cvs${SRCDATE}" -PR = "r2" +PV = "0.8.2+cvs${SRCDATE}" SRC_URI = "cvs://anonymous@cvs.savannah.nongnu.org/sources/qemu;method=pserver;rsh=ssh;module=qemu \ file://configure.patch;patch=1 \ - file://mouse_fix-r0.patch;patch=1 \ file://pl110_rgb-r0.patch;patch=1 \ file://arm_nptl.patch;patch=1" -- cgit v1.2.3 From 01bd80f46affbbfd3000b116c67c1052f5f2f344 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sat, 26 Aug 2006 17:53:27 +0000 Subject: syslog-ng: Add modified syslog-ng.conf which enables kernel logging by default --- packages/syslog-ng/files/syslog-ng.conf | 89 +++++++++++++++++++++++++++++++++ packages/syslog-ng/syslog-ng_1.6.8.bb | 5 +- 2 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 packages/syslog-ng/files/syslog-ng.conf diff --git a/packages/syslog-ng/files/syslog-ng.conf b/packages/syslog-ng/files/syslog-ng.conf new file mode 100644 index 0000000000..4d1e9f8b22 --- /dev/null +++ b/packages/syslog-ng/files/syslog-ng.conf @@ -0,0 +1,89 @@ +# +# Syslog-ng example configuration for for Debian GNU/Linux +# +# Copyright (c) 1999 anonymous +# Copyright (c) 1999 Balazs Scheidler +# $Id: syslog-ng.conf.sample,v 1.3 2003/05/20 08:57:27 asd Exp $ +# +# Syslog-ng configuration file, compatible with default Debian syslogd +# installation. +# + +options { long_hostnames(off); sync(0); }; + +source src { file("/proc/kmsg"); unix-stream("/dev/log"); internal(); }; +source net { udp(); }; + +destination authlog { file("/var/log/auth.log"); }; +destination syslog { file("/var/log/syslog"); }; +destination cron { file("/var/log/cron.log"); }; +destination daemon { file("/var/log/daemon.log"); }; +destination kern { file("/var/log/kern.log"); }; +destination lpr { file("/var/log/lpr.log"); }; +destination user { file("/var/log/user.log"); }; +destination uucp { file("/var/log/uucp.log"); }; +destination ppp { file("/var/log/ppp.log"); }; +destination mail { file("/var/log/mail.log"); }; + +destination mailinfo { file("/var/log/mail.info"); }; +destination mailwarn { file("/var/log/mail.warn"); }; +destination mailerr { file("/var/log/mail.err"); }; + +destination newscrit { file("/var/log/news/news.crit"); }; +destination newserr { file("/var/log/news/news.err"); }; +destination newsnotice { file("/var/log/news/news.notice"); }; + +destination debug { file("/var/log/debug"); }; +destination messages { file("/var/log/messages"); }; +destination console { usertty("root"); }; +destination console_all { file("/dev/tty12"); }; +#destination loghost { udp("loghost" port(999)); }; + + +destination xconsole { pipe("/dev/xconsole"); }; + +filter f_auth { facility(auth); }; +filter f_authpriv { facility(auth, authpriv); }; +filter f_syslog { not facility(authpriv, mail); }; +filter f_cron { facility(cron); }; +filter f_daemon { facility(daemon); }; +filter f_kern { facility(kern); }; +filter f_lpr { facility(lpr); }; +filter f_mail { facility(mail); }; +filter f_user { facility(user); }; +filter f_uucp { facility(cron); }; +filter f_ppp { facility(local2); }; +filter f_news { facility(news); }; +filter f_debug { not facility(auth, authpriv, news, mail); }; +filter f_messages { level(info..warn) + and not facility(auth, authpriv, mail, news); }; +filter f_emergency { level(emerg); }; + +filter f_info { level(info); }; +filter f_notice { level(notice); }; +filter f_warn { level(warn); }; +filter f_crit { level(crit); }; +filter f_err { level(err); }; + +log { source(src); filter(f_authpriv); destination(authlog); }; +log { source(src); filter(f_syslog); destination(syslog); }; +log { source(src); filter(f_cron); destination(cron); }; +log { source(src); filter(f_daemon); destination(daemon); }; +log { source(src); filter(f_kern); destination(kern); }; +log { source(src); filter(f_lpr); destination(lpr); }; +log { source(src); filter(f_mail); destination(mail); }; +log { source(src); filter(f_user); destination(user); }; +log { source(src); filter(f_uucp); destination(uucp); }; +log { source(src); filter(f_mail); filter(f_info); destination(mailinfo); }; +log { source(src); filter(f_mail); filter(f_warn); destination(mailwarn); }; +log { source(src); filter(f_mail); filter(f_err); destination(mailerr); }; +log { source(src); filter(f_news); filter(f_crit); destination(newscrit); }; +log { source(src); filter(f_news); filter(f_err); destination(newserr); }; +log { source(src); filter(f_news); filter(f_notice); destination(newsnotice); }; +log { source(src); filter(f_debug); destination(debug); }; +log { source(src); filter(f_messages); destination(messages); }; +log { source(src); filter(f_emergency); destination(console); }; +log { source(src); filter(f_ppp); destination(ppp); }; +log { source(src); destination(console_all); }; + + diff --git a/packages/syslog-ng/syslog-ng_1.6.8.bb b/packages/syslog-ng/syslog-ng_1.6.8.bb index 734dc310fb..ce1f77813c 100644 --- a/packages/syslog-ng/syslog-ng_1.6.8.bb +++ b/packages/syslog-ng/syslog-ng_1.6.8.bb @@ -1,9 +1,10 @@ -PR = "r8" +PR = "r9" MAINTAINER = "Oyvind Repvik Date: Sat, 26 Aug 2006 18:01:57 +0000 Subject: patch: Add patches to enable unifed reject files and a global reject file (from debian) --- packages/patch/patch-2.5.9/global-reject-file.diff | 201 ++++++++++++++ .../patch/patch-2.5.9/unified-reject-files.diff | 305 +++++++++++++++++++++ packages/patch/patch_2.5.9.bb | 5 +- 3 files changed, 510 insertions(+), 1 deletion(-) create mode 100644 packages/patch/patch-2.5.9/global-reject-file.diff create mode 100644 packages/patch/patch-2.5.9/unified-reject-files.diff diff --git a/packages/patch/patch-2.5.9/global-reject-file.diff b/packages/patch/patch-2.5.9/global-reject-file.diff new file mode 100644 index 0000000000..66065fcbf5 --- /dev/null +++ b/packages/patch/patch-2.5.9/global-reject-file.diff @@ -0,0 +1,201 @@ +Index: patch-2.5.9/patch.man +=================================================================== +--- patch-2.5.9.orig/patch.man ++++ patch-2.5.9/patch.man +@@ -520,6 +520,15 @@ file. + \fB\*=reject\-unified\fP + Produce unified reject files. The default is to produce context type reject files. + .TP ++.BI \*=global\-reject\-file= rejectfile ++Put all rejects into ++.I rejectfile ++instead of creating separate reject files for all files that have rejects. The ++.I rejectfile ++will contain headers that identify which file each reject refers to. Note that ++the global reject file is created even if \-\-dry\-run is specified (while ++non-global reject files will only be created without \-\-dry\-run). ++.TP + \fB\-R\fP or \fB\*=reverse\fP + Assume that this patch was created with the old and new files swapped. + (Yes, I'm afraid that does happen occasionally, human nature being what it +Index: patch-2.5.9/patch.c +=================================================================== +--- patch-2.5.9.orig/patch.c ++++ patch-2.5.9/patch.c +@@ -67,6 +67,7 @@ static bool similar (char const *, size_ + static bool spew_output (struct outstate *); + static char const *make_temp (char); + static int numeric_string (char const *, bool, char const *); ++static void reject_header (const char *filename); + static void abort_hunk (void); + static void cleanup (void); + static void get_some_switches (void); +@@ -98,6 +99,7 @@ static int Argc; + static char * const *Argv; + + static FILE *rejfp; /* reject file pointer */ ++static char *global_reject; + + static char const *patchname; + static char *rejname; +@@ -172,6 +174,10 @@ main (int argc, char **argv) + /* Make sure we clean up in case of disaster. */ + set_signals (false); + ++ /* initialize global reject file */ ++ if (global_reject) ++ init_reject (); ++ + for ( + open_patch_file (patchname); + there_is_another_patch(); +@@ -208,8 +214,9 @@ main (int argc, char **argv) + init_output (TMPOUTNAME, exclusive, &outstate); + } + +- /* initialize reject file */ +- init_reject (); ++ /* initialize per-patch reject file */ ++ if (!global_reject) ++ init_reject (); + + /* find out where all the lines are */ + if (!skip_rest_of_patch) +@@ -278,6 +285,8 @@ main (int argc, char **argv) + + newwhere = pch_newfirst() + last_offset; + if (skip_rest_of_patch) { ++ if (!failed) ++ reject_header(outname); + abort_hunk(); + failed++; + if (verbosity == VERBOSE) +@@ -292,6 +301,8 @@ main (int argc, char **argv) + say ("Patch attempted to create file %s, which already exists.\n", + quotearg (inname)); + ++ if (!failed) ++ reject_header(outname); + abort_hunk(); + failed++; + if (verbosity != SILENT) +@@ -299,6 +310,8 @@ main (int argc, char **argv) + format_linenum (numbuf, newwhere)); + } + else if (! apply_hunk (&outstate, where)) { ++ if (!failed) ++ reject_header(outname); + abort_hunk (); + failed++; + if (verbosity != SILENT) +@@ -332,7 +345,8 @@ main (int argc, char **argv) + fclose (outstate.ofp); + outstate.ofp = 0; + } +- fclose (rejfp); ++ if (!global_reject) ++ fclose (rejfp); + continue; + } + +@@ -412,13 +426,13 @@ main (int argc, char **argv) + } + } + if (diff_type != ED_DIFF) { +- if (fclose (rejfp) != 0) ++ if (!global_reject && fclose (rejfp) != 0) + write_fatal (); + if (failed) { + somefailed = true; + say ("%d out of %d hunk%s %s", failed, hunk, "s" + (hunk == 1), + skip_rest_of_patch ? "ignored" : "FAILED"); +- if (outname) { ++ if (!global_reject && outname) { + char *rej = rejname; + if (!rejname) { + rej = xmalloc (strlen (outname) + 5); +@@ -445,6 +459,20 @@ main (int argc, char **argv) + } + set_signals (true); + } ++ if (global_reject) ++ { ++ if (fclose (rejfp) != 0) ++ write_fatal (); ++ if (somefailed) ++ { ++ say (" -- saving rejects to file %s\n", quotearg (global_reject)); ++ /*if (! dry_run) ++ {*/ ++ move_file (TMPREJNAME, &TMPREJNAME_needs_removal, ++ global_reject, 0644, false); ++ /*}*/ ++ } ++ } + if (outstate.ofp && (ferror (outstate.ofp) || fclose (outstate.ofp) != 0)) + write_fatal (); + cleanup (); +@@ -523,6 +551,7 @@ static struct option const longopts[] = + {"posix", no_argument, NULL, CHAR_MAX + 7}, + {"quoting-style", required_argument, NULL, CHAR_MAX + 8}, + {"unified-reject-files", no_argument, NULL, CHAR_MAX + 9}, ++ {"global-reject-file", required_argument, NULL, CHAR_MAX + 10}, + {NULL, no_argument, NULL, 0} + }; + +@@ -582,6 +611,7 @@ static char const *const option_help[] = + " --dry-run Do not actually change any files; just print what would happen.", + " --posix Conform to the POSIX standard.", + " --unified-reject-files Create unified reject files.", ++" --global-reject-file=file Put all rejects into one file.", + "", + " -d DIR --directory=DIR Change the working directory to DIR first.", + #if HAVE_SETMODE_DOS +@@ -784,6 +814,9 @@ get_some_switches (void) + case CHAR_MAX + 9: + unified_reject_files = true; + break; ++ case CHAR_MAX + 10: ++ global_reject = savestr (optarg); ++ break; + default: + usage (stderr, 2); + } +@@ -933,6 +966,37 @@ locate_hunk (LINENUM fuzz) + } + + static char * ++format_timestamp (char timebuf[37], bool which) ++{ ++ time_t ts = pch_timestamp(which); ++ if (ts != -1) ++ { ++ struct tm *tm = localtime(&ts); ++ strftime(timebuf, 37, "\t%Y-%m-%d %H:%M:%S.000000000 %z", tm); ++ } ++ else ++ timebuf[0] = 0; ++ return timebuf; ++} ++ ++/* Write a header in a reject file that combines multiple hunks. */ ++static void ++reject_header (const char *outname) ++{ ++ char timebuf0[37], timebuf1[37]; ++ if (!global_reject) ++ return; ++ if (diff_type == UNI_DIFF) ++ fprintf(rejfp, "--- %s.orig%s\n+++ %s%s\n", ++ outname, format_timestamp(timebuf0, reverse), ++ outname, format_timestamp(timebuf1, !reverse)); ++ else ++ fprintf(rejfp, "*** %s.orig%s\n--- %s%s\n", ++ outname, format_timestamp(timebuf0, reverse), ++ outname, format_timestamp(timebuf1, !reverse)); ++} ++ ++static char * + format_linerange (char rangebuf[LINENUM_LENGTH_BOUND*2 + 2], + LINENUM first, LINENUM lines) + { diff --git a/packages/patch/patch-2.5.9/unified-reject-files.diff b/packages/patch/patch-2.5.9/unified-reject-files.diff new file mode 100644 index 0000000000..6bfa00dd75 --- /dev/null +++ b/packages/patch/patch-2.5.9/unified-reject-files.diff @@ -0,0 +1,305 @@ +Generate unified diff style reject files. Also include the C function names +in reject files whenever possible. + + $ cat > f.orig + < a() { + < 2 + < 3 + < + < 5 + < 6 + < } + + $ sed -e 's/5/5a/' f.orig > f + $ diff -U2 -p f.orig f > f.diff + $ sed -e 's/5/5a/' -e 's/6/6x/' f.orig > f + $ ./patch -F0 -s --no-backup-if-mismatch f --reject-unified < f.diff + > 1 out of 1 hunk FAILED -- saving rejects to file f.rej + + $ cat f.rej + > @@ -3,5 +3,5 @@ a() { + > 3 + > + > -5 + > +5a + > 6 + > } + + $ ./patch -F0 -s --no-backup-if-mismatch f < f.diff + > 1 out of 1 hunk FAILED -- saving rejects to file f.rej + + $ cat f.rej + > *************** a() { + > *** 3,7 **** + > 3 + > + > - 5 + > 6 + > } + > --- 3,7 ---- + > 3 + > + > + 5a + > 6 + > } + + $ diff -Nu -p /dev/null f.orig > f2.diff + $ ./patch -F0 -s --no-backup-if-mismatch f --reject-unified < f2.diff + > Patch attempted to create file f, which already exists. + > 1 out of 1 hunk FAILED -- saving rejects to file f.rej + + $ cat f.rej + > @@ -0,0 +1,7 @@ + > +a() { + > +2 + > +3 + > + + > +5 + > +6 + > +} + + $ rm -f f f.orig f.rej f.diff f2.diff + +Index: patch-2.5.9/pch.c +=================================================================== +--- patch-2.5.9.orig/pch.c ++++ patch-2.5.9/pch.c +@@ -68,6 +68,7 @@ static LINENUM p_sline; /* and the lin + static LINENUM p_hunk_beg; /* line number of current hunk */ + static LINENUM p_efake = -1; /* end of faked up lines--don't free */ + static LINENUM p_bfake = -1; /* beg of faked up lines */ ++static char *p_c_function; /* the C function a hunk is in */ + + enum nametype { OLD, NEW, INDEX, NONE }; + +@@ -888,6 +889,19 @@ another_hunk (enum diff difftype, bool r + next_intuit_at(line_beginning,p_input_line); + return chars_read == (size_t) -1 ? -1 : 0; + } ++ s = buf; ++ while (*s == '*') ++ s++; ++ if (*s == ' ') ++ { ++ p_c_function = s; ++ while (*s != '\n') ++ s++; ++ *s = '\0'; ++ p_c_function = savestr (p_c_function); ++ } ++ else ++ p_c_function = NULL; + p_hunk_beg = p_input_line + 1; + while (p_end < p_max) { + chars_read = get_line (); +@@ -1277,8 +1291,18 @@ another_hunk (enum diff difftype, bool r + else + p_repl_lines = 1; + if (*s == ' ') s++; +- if (*s != '@') ++ if (*s++ != '@') + malformed (); ++ if (*s++ == '@' && *s == ' ' && *s != '\0') ++ { ++ p_c_function = s; ++ while (*s != '\n') ++ s++; ++ *s = '\0'; ++ p_c_function = savestr (p_c_function); ++ } ++ else ++ p_c_function = NULL; + if (!p_ptrn_lines) + p_first++; /* do append rather than insert */ + if (!p_repl_lines) +@@ -1884,6 +1908,12 @@ pch_hunk_beg (void) + return p_hunk_beg; + } + ++char const * ++pch_c_function (void) ++{ ++ return p_c_function; ++} ++ + /* Is the newline-terminated line a valid `ed' command for patch + input? If so, return the command character; if not, return 0. + This accepts accepts just a subset of the valid commands, but it's +Index: patch-2.5.9/pch.h +=================================================================== +--- patch-2.5.9.orig/pch.h ++++ patch-2.5.9/pch.h +@@ -25,6 +25,7 @@ + LINENUM pch_end (void); + LINENUM pch_first (void); + LINENUM pch_hunk_beg (void); ++char const *pch_c_function (void); + LINENUM pch_newfirst (void); + LINENUM pch_prefix_context (void); + LINENUM pch_ptrn_lines (void); +Index: patch-2.5.9/patch.man +=================================================================== +--- patch-2.5.9.orig/patch.man ++++ patch-2.5.9/patch.man +@@ -517,6 +517,9 @@ instead of the default + .B \&.rej + file. + .TP ++\fB\*=reject\-unified\fP ++Produce unified reject files. The default is to produce context type reject files. ++.TP + \fB\-R\fP or \fB\*=reverse\fP + Assume that this patch was created with the old and new files swapped. + (Yes, I'm afraid that does happen occasionally, human nature being what it +Index: patch-2.5.9/common.h +=================================================================== +--- patch-2.5.9.orig/common.h ++++ patch-2.5.9/common.h +@@ -146,6 +146,7 @@ XTERN int invc; + XTERN struct stat instat; + XTERN bool dry_run; + XTERN bool posixly_correct; ++XTERN bool unified_reject_files; + + XTERN char const *origprae; + XTERN char const *origbase; +Index: patch-2.5.9/patch.c +=================================================================== +--- patch-2.5.9.orig/patch.c ++++ patch-2.5.9/patch.c +@@ -522,6 +522,7 @@ static struct option const longopts[] = + {"no-backup-if-mismatch", no_argument, NULL, CHAR_MAX + 6}, + {"posix", no_argument, NULL, CHAR_MAX + 7}, + {"quoting-style", required_argument, NULL, CHAR_MAX + 8}, ++ {"unified-reject-files", no_argument, NULL, CHAR_MAX + 9}, + {NULL, no_argument, NULL, 0} + }; + +@@ -580,6 +581,7 @@ static char const *const option_help[] = + " --verbose Output extra information about the work being done.", + " --dry-run Do not actually change any files; just print what would happen.", + " --posix Conform to the POSIX standard.", ++" --unified-reject-files Create unified reject files.", + "", + " -d DIR --directory=DIR Change the working directory to DIR first.", + #if HAVE_SETMODE_DOS +@@ -779,6 +781,9 @@ get_some_switches (void) + (enum quoting_style) i); + } + break; ++ case CHAR_MAX + 9: ++ unified_reject_files = true; ++ break; + default: + usage (stderr, 2); + } +@@ -927,6 +932,24 @@ locate_hunk (LINENUM fuzz) + return 0; + } + ++static char * ++format_linerange (char rangebuf[LINENUM_LENGTH_BOUND*2 + 2], ++ LINENUM first, LINENUM lines) ++{ ++ if (lines == 1) ++ rangebuf = format_linenum (rangebuf, first); ++ else ++ { ++ char *rb; ++ rangebuf = format_linenum (rangebuf + LINENUM_LENGTH_BOUND + 1, lines); ++ rb = rangebuf-1; ++ rangebuf = format_linenum (rangebuf - LINENUM_LENGTH_BOUND - 1, ++ (lines > 0) ? first : 0); ++ *rb = ','; ++ } ++ return rangebuf; ++} ++ + /* We did not find the pattern, dump out the hunk so they can handle it. */ + + static void +@@ -943,8 +966,83 @@ abort_hunk (void) + (int) NEW_CONTEXT_DIFF <= (int) diff_type ? " ****" : ""; + char const *minuses = + (int) NEW_CONTEXT_DIFF <= (int) diff_type ? " ----" : " -----"; ++ char const *function = pch_c_function(); ++ if (function == NULL) ++ function = ""; ++ ++ if (unified_reject_files) ++ { ++ /* produce unified reject files */ ++ char rangebuf0[LINENUM_LENGTH_BOUND*2 + 2]; ++ char rangebuf1[LINENUM_LENGTH_BOUND*2 + 2]; ++ LINENUM j; ++ ++ /* Find the beginning of the remove and insert section. */ ++ for (j = 0; j <= pat_end; j++) ++ if (pch_char (j) == '=') ++ break; ++ for (i = j+1; i <= pat_end; i++) ++ if (pch_char (i) == '^') ++ break; ++ if (pch_char (0) != '*' || j > pat_end || i > pat_end+1) ++ fatal ("internal error in abort_hunk"); ++ i = 1; j++; ++ ++ /* @@ -from,lines +to,lines @@ */ ++ fprintf (rejfp, "@@ -%s +%s @@%s\n", ++ format_linerange (rangebuf0, oldfirst, pch_ptrn_lines()), ++ format_linerange (rangebuf1, newfirst, pch_repl_lines()), ++ function); ++ ++ while ( (i <= pat_end && pch_char (i) != '=') ++ || (j <= pat_end && pch_char (j) != '^')) ++ { ++ if (i <= pat_end ++ && (pch_char (i) == '-' || pch_char (i) == '!')) ++ { ++ fputc('-', rejfp); ++ pch_write_line (i++, rejfp); ++ } ++ else if (j <= pat_end ++ && (pch_char (j) == '+' || pch_char (j) == '!')) ++ { ++ fputc('+', rejfp); ++ pch_write_line (j++, rejfp); ++ } ++ else if ((i <= pat_end ++ && (pch_char (i) == ' ' || pch_char (i) == '\n')) && ++ (j > pat_end ++ || (pch_char (j) == ' ' || pch_char (j) == '\n'))) ++ { ++ /* Unless j is already past the end, lines i and j ++ must be equal here. */ ++ ++ if (pch_char (i) == ' ') ++ fputc(' ', rejfp); ++ pch_write_line (i++, rejfp); ++ if (j <= pat_end) ++ j++; ++ } ++ else if ((j <= pat_end && ++ (pch_char (j) == ' ' || pch_char (j) == '\n')) && ++ (pch_char (i) == '=')) ++ { ++ if (pch_char (j) == ' ') ++ fputc(' ', rejfp); ++ pch_write_line (j++, rejfp); ++ } ++ else ++ fatal ("internal error in abort_hunk"); ++ } ++ ++ if (ferror (rejfp)) ++ write_fatal (); ++ return; ++ } + +- fprintf(rejfp, "***************\n"); ++ /* produce context type reject files */ ++ ++ fprintf(rejfp, "***************%s\n", function); + for (i=0; i<=pat_end; i++) { + char numbuf0[LINENUM_LENGTH_BOUND + 1]; + char numbuf1[LINENUM_LENGTH_BOUND + 1]; diff --git a/packages/patch/patch_2.5.9.bb b/packages/patch/patch_2.5.9.bb index 103337b4c9..940b15a205 100644 --- a/packages/patch/patch_2.5.9.bb +++ b/packages/patch/patch_2.5.9.bb @@ -3,5 +3,8 @@ require patch.inc SRC_URI = "${GNU_MIRROR}/patch/patch-2.5.4.tar.gz \ file://2.5.9.patch;patch=1 \ file://debian.patch;patch=1 \ - file://install.patch;patch=1" + file://install.patch;patch=1 \ + file://unified-reject-files.diff;patch=1 \ + file://global-reject-file.diff;patch=1 " S = "${WORKDIR}/patch-2.5.4" +PR = "r1" \ No newline at end of file -- cgit v1.2.3 From 553620188432efddff8026b8afe4c07b4adc3913 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 26 Aug 2006 20:54:18 +0000 Subject: glibc 2.4: mask out more broken locales --- packages/glibc/glibc_2.4.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/glibc/glibc_2.4.bb b/packages/glibc/glibc_2.4.bb index 5d8df56280..c9eaf189df 100644 --- a/packages/glibc/glibc_2.4.bb +++ b/packages/glibc/glibc_2.4.bb @@ -16,7 +16,7 @@ FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/glibc-2.4" GLIBC_ADDONS ?= "ports,nptl,libidn" GLIBC_EXTRA_OECONF ?= "" -GLIBC_BROKEN_LOCALES = "sid_ET tr_TR mn_MN" +GLIBC_BROKEN_LOCALES = "sid_ET tr_TR mn_MN gez_ET bn_BD te_IN" # # For now, we will skip building of a gcc package if it is a uclibc one -- cgit v1.2.3 From 04a0af140ea6b29dac41a393c97e77a5b17ad8ef Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 26 Aug 2006 21:17:45 +0000 Subject: qemu 0.8.2: use the cross compiler to build 'qemu' --- packages/qemu/qemu-native_0.8.2.bb | 1 + packages/qemu/qemu_0.8.2.bb | 2 ++ 2 files changed, 3 insertions(+) diff --git a/packages/qemu/qemu-native_0.8.2.bb b/packages/qemu/qemu-native_0.8.2.bb index 2b143bdc0f..e064723e4e 100644 --- a/packages/qemu/qemu-native_0.8.2.bb +++ b/packages/qemu/qemu-native_0.8.2.bb @@ -1,4 +1,5 @@ require qemu_${PV}.bb +EXTRA_OECONF = "" inherit native FILESPATH =. "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/qemu-${PV}:" S = "${WORKDIR}/qemu-${PV}" diff --git a/packages/qemu/qemu_0.8.2.bb b/packages/qemu/qemu_0.8.2.bb index 368eb44666..87ebc2369d 100644 --- a/packages/qemu/qemu_0.8.2.bb +++ b/packages/qemu/qemu_0.8.2.bb @@ -7,3 +7,5 @@ SRC_URI = "http://fabrice.bellard.free.fr/qemu/qemu-${PV}.tar.gz \ inherit autotools +EXTRA_OECONF = "--cc=$CC}" + -- cgit v1.2.3 From b09fe32ebb5375215820ba5b2f2def3a8b7db730 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 26 Aug 2006 21:20:14 +0000 Subject: glibc 2.4: also mask out gez_ER --- packages/glibc/glibc_2.4.bb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/glibc/glibc_2.4.bb b/packages/glibc/glibc_2.4.bb index 5d8df56280..62be40d299 100644 --- a/packages/glibc/glibc_2.4.bb +++ b/packages/glibc/glibc_2.4.bb @@ -3,7 +3,6 @@ HOMEPAGE = "http://www.gnu.org/software/libc/libc.html" LICENSE = "LGPL" SECTION = "libs" PRIORITY = "required" -DEFAULT_PREFERENCE = "-1" PR = "r10" # the -isystem in bitbake.conf screws up glibc do_stage @@ -16,7 +15,7 @@ FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/glibc-2.4" GLIBC_ADDONS ?= "ports,nptl,libidn" GLIBC_EXTRA_OECONF ?= "" -GLIBC_BROKEN_LOCALES = "sid_ET tr_TR mn_MN" +GLIBC_BROKEN_LOCALES = "sid_ET tr_TR mn_MN gez_ET gez_ER bn_BD te_IN" # # For now, we will skip building of a gcc package if it is a uclibc one @@ -123,6 +122,12 @@ do_munge() { addtask munge before do_patch after do_unpack +# gcc uses -Werror which break on a "you have no thumb interwork" _warning_ +do_configure_prepend() { + sed -i s:-Werror:: ${S}/configure +} + + do_configure () { # override this function to avoid the autoconf/automake/aclocal/autoheader # calls for now -- cgit v1.2.3 From 539d4da18a4337f44d0fd98dc04d5ebf00ce82a0 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 26 Aug 2006 21:33:21 +0000 Subject: glibc 2.4: remove spurious committed Werror bit --- packages/glibc/glibc_2.4.bb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/glibc/glibc_2.4.bb b/packages/glibc/glibc_2.4.bb index 62be40d299..5ee57d4430 100644 --- a/packages/glibc/glibc_2.4.bb +++ b/packages/glibc/glibc_2.4.bb @@ -122,11 +122,6 @@ do_munge() { addtask munge before do_patch after do_unpack -# gcc uses -Werror which break on a "you have no thumb interwork" _warning_ -do_configure_prepend() { - sed -i s:-Werror:: ${S}/configure -} - do_configure () { # override this function to avoid the autoconf/automake/aclocal/autoheader -- cgit v1.2.3 From 442c141f76ec7cb9b3ca0b8db52c655ef0ec9f43 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 26 Aug 2006 21:35:23 +0000 Subject: qemu: fix typo --- packages/qemu/qemu_0.8.2.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/qemu/qemu_0.8.2.bb b/packages/qemu/qemu_0.8.2.bb index 87ebc2369d..49032fa59d 100644 --- a/packages/qemu/qemu_0.8.2.bb +++ b/packages/qemu/qemu_0.8.2.bb @@ -7,5 +7,5 @@ SRC_URI = "http://fabrice.bellard.free.fr/qemu/qemu-${PV}.tar.gz \ inherit autotools -EXTRA_OECONF = "--cc=$CC}" +EXTRA_OECONF = "--cc=${CC}" -- cgit v1.2.3 From 6d0f7e06b5dac45bc9ebbf418bb465a440d6bf8c Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 27 Aug 2006 08:30:17 +0000 Subject: package.bbclass: remove do_install from PACKAGE_FUNCS, as noted by Philipp Zabel --- classes/package.bbclass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/package.bbclass b/classes/package.bbclass index d6f50fb49d..9b913ecf82 100644 --- a/classes/package.bbclass +++ b/classes/package.bbclass @@ -725,7 +725,7 @@ python package_do_split_locales() { bb.data.setVar('RDEPENDS_%s' % mainpkg, ' '.join(rdep), d) } -PACKAGEFUNCS ?= " do_install package_do_split_locales \ +PACKAGEFUNCS ?= " package_do_split_locales \ populate_packages package_do_shlibs \ package_do_pkgconfig read_shlibdeps" python package_do_package () { -- cgit v1.2.3 From 141aa7a6d1789fc9e31835b5e1172770403bae57 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 27 Aug 2006 08:48:35 +0000 Subject: gconf-dbus: depend on dbus-glib --- packages/gnome/gconf-dbus_svn.bb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/gnome/gconf-dbus_svn.bb b/packages/gnome/gconf-dbus_svn.bb index 9fb02f8211..5ab880d921 100644 --- a/packages/gnome/gconf-dbus_svn.bb +++ b/packages/gnome/gconf-dbus_svn.bb @@ -1,5 +1,5 @@ SECTION = "x11/utils" -DEPENDS = "gtk+ glib-2.0 dbus libxml2 popt" +DEPENDS = "gtk+ glib-2.0 dbus dbus-glib libxml2 popt" DESCRIPTION = "Settings daemon using DBUS for communication." LICENSE = "GPL" MAINTAINER = "Florian Boor " @@ -21,7 +21,8 @@ S = "${WORKDIR}/trunk" PARALLEL_MAKE = "" -FILES_${PN} += " ${libdir}/GConf/2/*.so ${libdir}/dbus-1.0 ${sysconfdir} ${datadir}/dbus*" +FILES_${PN} += " ${libdir}/gconf-dbus/2/*.so ${libdir}/dbus-1.0 ${sysconfdir} ${datadir}/dbus*" +FILES_${PN}-dbg += "${libdir}/gconf-dbus/2/.debug" EXTRA_OECONF = " --with-ipc=dbus --disable-gtk-doc --enable-gtk --host=${HOST_SYS} --enable-shared --disable-static" -- cgit v1.2.3 From d949d9d992ebc26e021a5c94f3bca9e7c2efb2d8 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 27 Aug 2006 10:01:10 +0000 Subject: dbus 0.92: remove default pref = -1 --- packages/dbus/dbus_0.92.bb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/dbus/dbus_0.92.bb b/packages/dbus/dbus_0.92.bb index a4ab61322f..7981a3f525 100644 --- a/packages/dbus/dbus_0.92.bb +++ b/packages/dbus/dbus_0.92.bb @@ -1,12 +1,11 @@ -DEFAULT_PREFERENCE="-1" - SECTION = "base" -PR = "r1" HOMEPAGE = "http://www.freedesktop.org/Software/dbus" DESCRIPTION = "message bus system for applications to talk to one another" LICENSE = "GPL" DEPENDS = "expat glib-2.0 virtual/libintl" +PR = "r1" + SRC_URI = "http://freedesktop.org/software/dbus/releases/dbus-${PV}.tar.gz \ file://cross.patch;patch=1 \ file://tmpdir.patch;patch=1 \ -- cgit v1.2.3 From 4be216128262f49d669c3c224a398eb4bfb5c32b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 27 Aug 2006 11:31:19 +0000 Subject: glibc: use libs from /lib instead of for binary locale generation --- packages/glibc/glibc-package.bbclass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/glibc/glibc-package.bbclass b/packages/glibc/glibc-package.bbclass index 3ce10b54de..ecf086815d 100644 --- a/packages/glibc/glibc-package.bbclass +++ b/packages/glibc/glibc-package.bbclass @@ -143,7 +143,7 @@ do_prep_locale_tree() { for i in $treedir/${datadir}/i18n/charmaps/*gz; do gunzip $i done - cp -a ${STAGING_LIBDIR}/* $treedir/lib + cp -a ${D}/lib/* $treedir/lib if [ -f ${CROSS_DIR}/${TARGET_SYS}/lib/libgcc_s.* ]; then cp -a ${CROSS_DIR}/${TARGET_SYS}/lib/libgcc_s.* $treedir/lib fi -- cgit v1.2.3 From a2d4bed15938b2b37d033d37b8d4a939fc51752b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 27 Aug 2006 11:33:11 +0000 Subject: dbus-native: add 0.92 --- packages/dbus/dbus-native_0.92.bb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 packages/dbus/dbus-native_0.92.bb diff --git a/packages/dbus/dbus-native_0.92.bb b/packages/dbus/dbus-native_0.92.bb new file mode 100644 index 0000000000..db2d7014ef --- /dev/null +++ b/packages/dbus/dbus-native_0.92.bb @@ -0,0 +1,27 @@ +SECTION = "base" +PR = "r0" +HOMEPAGE = "http://www.freedesktop.org/Software/dbus" +DESCRIPTION = "message bus system for applications to talk to one another" +LICENSE = "GPL" + +S = "${WORKDIR}/dbus-${PV}" +FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/dbus" +DEPENDS = "glib-2.0-native" + +SRC_URI = "http://freedesktop.org/software/dbus/releases/dbus-${PV}.tar.gz \ + file://cross.patch;patch=1 \ + file://tmpdir.patch;patch=1" + +inherit autotools pkgconfig gettext native + +EXTRA_OECONF = "--disable-qt --disable-qt3 --disable-gtk --disable-tests \ + --disable-checks --disable-xml-docs --disable-doxygen-docs \ + --with-xml=expat --without-x" + +do_stage () { + oe_runmake install + autotools_stage_all + + # for dbus-glib-native introspection generation + install -m 0644 bus/session.conf ${STAGING_DATADIR}/dbus/session.conf +} -- cgit v1.2.3 From b83b07220adda9d7985605dc382473bb039237c5 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sun, 27 Aug 2006 11:35:57 +0000 Subject: dbus-glib-native-0.71: fix introspection data / binding header generation --- packages/dbus/dbus-glib-native/.mtn2git_empty | 0 .../run-with-tmp-session-bus.patch | 32 ++++++++++++++++++++++ packages/dbus/dbus-glib-native_0.71.bb | 3 +- 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 packages/dbus/dbus-glib-native/.mtn2git_empty create mode 100644 packages/dbus/dbus-glib-native/run-with-tmp-session-bus.patch diff --git a/packages/dbus/dbus-glib-native/.mtn2git_empty b/packages/dbus/dbus-glib-native/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/dbus/dbus-glib-native/run-with-tmp-session-bus.patch b/packages/dbus/dbus-glib-native/run-with-tmp-session-bus.patch new file mode 100644 index 0000000000..186abdb56b --- /dev/null +++ b/packages/dbus/dbus-glib-native/run-with-tmp-session-bus.patch @@ -0,0 +1,32 @@ +--- dbus-glib-0.71/tools/Makefile.am.orig 2006-08-27 12:54:34.351198198 +0200 ++++ dbus-glib-0.71/tools/Makefile.am 2006-08-27 12:55:12.533584373 +0200 +@@ -9,7 +9,7 @@ + BUILT_SOURCES = dbus-glib-bindings.h dbus-bus-introspect.xml + + dbus-bus-introspect.xml: +- DBUS_TOP_BUILDDIR=$(top_builddir) dbus-send --system --print-reply=literal --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.Introspectable.Introspect > dbus-bus-introspect.xml.tmp && mv dbus-bus-introspect.xml.tmp dbus-bus-introspect.xml ++ DBUS_TOP_BUILDDIR=$(top_builddir) ./run-with-tmp-session-bus.sh dbus-send --print-reply=literal --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.Introspectable.Introspect > dbus-bus-introspect.xml.tmp && mv dbus-bus-introspect.xml.tmp dbus-bus-introspect.xml + + EXTRA_DIST = run-with-tmp-session-bus.sh + +--- dbus-glib-0.71/tools/run-with-tmp-session-bus.sh.orig 2006-08-27 11:52:17.497666746 +0200 ++++ dbus-glib-0.71/tools/run-with-tmp-session-bus.sh 2006-08-27 12:53:22.626715838 +0200 +@@ -27,16 +27,15 @@ + echo "escaped service dir is: $ESCAPED_SERVICE_DIR" >&2 + + ## create a configuration file based on the standard session.conf +-cat $DBUS_TOP_BUILDDIR/tools/session.conf | \ ++cat $datadir/dbus/session.conf | \ + sed -e 's/.*$/'$ESCAPED_SERVICE_DIR'<\/servicedir>/g' | \ + sed -e 's/ $CONFIG_FILE + + echo "Created configuration file $CONFIG_FILE" >&2 + +-export PATH=$DBUS_TOP_BUILDDIR/bus:$PATH + ## the libtool script found by the path search should already do this, but +-export LD_LIBRARY_PATH=$DBUS_TOP_BUILDDIR/dbus/.libs:$LD_LIBRARY_PATH ++export LD_LIBRARY_PATH=$libdir:$LD_LIBRARY_PATH + + unset DBUS_SESSION_BUS_ADDRESS + unset DBUS_SESSION_BUS_PID diff --git a/packages/dbus/dbus-glib-native_0.71.bb b/packages/dbus/dbus-glib-native_0.71.bb index 81a15c9b35..200a7133b2 100644 --- a/packages/dbus/dbus-glib-native_0.71.bb +++ b/packages/dbus/dbus-glib-native_0.71.bb @@ -6,7 +6,8 @@ LICENSE = "GPL" DEPENDS = "expat glib-2.0 virtual/libintl dbus-native" SRC_URI = "http://freedesktop.org/software/dbus/releases/dbus-glib-${PV}.tar.gz \ - file://cross.patch;patch=1" + file://cross.patch;patch=1 \ + file://run-with-tmp-session-bus.patch;patch=1" inherit autotools pkgconfig gettext native -- cgit v1.2.3 From cb3b0daa43161b4089584835a60c18f32feaa23b Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 27 Aug 2006 11:53:10 +0000 Subject: gstreamer: add 0.10.8 --- packages/gstreamer/gstreamer_0.10.8.bb | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 packages/gstreamer/gstreamer_0.10.8.bb diff --git a/packages/gstreamer/gstreamer_0.10.8.bb b/packages/gstreamer/gstreamer_0.10.8.bb new file mode 100644 index 0000000000..251eb42a5d --- /dev/null +++ b/packages/gstreamer/gstreamer_0.10.8.bb @@ -0,0 +1,31 @@ +DESCRIPTION = "GStreamer is a multimedia framework for encoding and decoding video and sound. \ +It supports a wide range of formats including mp3, ogg, avi, mpeg and quicktime." +SECTION = "multimedia" +PRIORITY = "optional" +LICENSE = "LGPL" +HOMEPAGE = "http://www.gstreamer.net/" +MAINTAINER = "Felix Domke " +DEPENDS = "libxml2 glib-2.0 gettext-native popt" + +PR = "r0" +# until we have decided a final naming scheme, +# don't use this package as a replacement for +# version 0.8 +DEFAULT_PREFERENCE = "-1" + +inherit autotools pkgconfig + +SRC_URI = "http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-${PV}.tar.bz2" +EXTRA_OECONF = "--disable-docs-build --disable-dependency-tracking --with-check=no" + +do_stage() { + oe_runmake install prefix=${STAGING_DIR} \ + bindir=${STAGING_BINDIR} \ + includedir=${STAGING_INCDIR} \ + libdir=${STAGING_LIBDIR} \ + datadir=${STAGING_DATADIR} \ + mandir=${STAGING_DIR}/share/man +} + +FILES_${PN} += " ${libdir}/gstreamer-0.10/*.so" +FILES_${PN}-dev += " ${libdir}/gstreamer-0.10/*.la ${libdir}/gstreamer-0.10/*.a" -- cgit v1.2.3 From 3462c88d344b57fac725113f4c3c13a92f57b226 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 27 Aug 2006 12:35:49 +0000 Subject: gst-plugins base: stage things so good, bad and ugly can proceed to build stuff --- packages/gstreamer/gst-plugins-base_0.10.7.bb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/gstreamer/gst-plugins-base_0.10.7.bb b/packages/gstreamer/gst-plugins-base_0.10.7.bb index 48e24bf756..1679ecb1ca 100644 --- a/packages/gstreamer/gst-plugins-base_0.10.7.bb +++ b/packages/gstreamer/gst-plugins-base_0.10.7.bb @@ -1,2 +1,7 @@ require gst-plugins.inc PROVIDES_${PN} += "gst-plugins" + +do_stage() { + autotools_stage_all +} + -- cgit v1.2.3 From 167cb2622b1f5b06e4459e840ce5dda7eec83718 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 27 Aug 2006 12:48:55 +0000 Subject: angstrom: slide data a teensy bit forward * BIG FAT NOTE: adjust your {local,site,auto}.conf --- conf/distro/angstrom-2006.9.conf | 176 --------------------------------------- conf/distro/angstrom-2007.1.conf | 176 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+), 176 deletions(-) delete mode 100644 conf/distro/angstrom-2006.9.conf create mode 100644 conf/distro/angstrom-2007.1.conf diff --git a/conf/distro/angstrom-2006.9.conf b/conf/distro/angstrom-2006.9.conf deleted file mode 100644 index 327d4123cc..0000000000 --- a/conf/distro/angstrom-2006.9.conf +++ /dev/null @@ -1,176 +0,0 @@ -#@-------------------------------------------------------------------- -#@TYPE: Distribution -#@NAME: Angstrom -#@DESCRIPTION: The Linux Distribution for Kernel 2.6 based devices -#@MAINTAINER: Koen Kooi -#@MAINTAINER: Michael 'Mickey' Lauer -#@-------------------------------------------------------------------- - -#DISTRO_VERSION = "2006.9" -DISTRO_VERSION = "test-${DATE}" - -require conf/distro/include/angstrom.inc -require conf/distro/include/sane-srcdates.inc - -DISTRO_TYPE = "debug" -#DISTRO_TYPE = "release" -#!!!!! DON'T FORGET TO ENABLE ZAPROOTPASSWD !!!!! - - -FEED_URIS += " \ - base##${ANGSTROM_URI}/unstable/feed/base \ - perl##${ANGSTROM_URI}/unstable/feed/perl \ - python##${ANGSTROM_URI}/unstable/feed/python \ - debug##${ANGSTROM_URI}/unstable/feed/debug \ - ${MACHINE}##${ANGSTROM_URI}/unstable/feed/machine/${MACHINE}" -# base##${ANGSTROM_URI}/releases/${DISTRO_VERSION}/feed/base \ -# ${MACHINE}##${ANGSTROM_URI}/releases/${DISTRO_VERSION}/feed/${MACHINE} \ -# updates##${ANGSTROM_URI}/releases/${DISTRO_VERSION}/feed/updates" - -#SRCDATE = "20060630" -#SRCDATE_handhelds-pxa-2.6 = "20060622" -SRCDATE_gconf-dbus = "20060719" -SRCDATE_gnome-vfs-dbus = "20060803" - -PREFERRED_VERSION_qemu-native = "0.8.2" - -CVS_TARBALL_STASH = "\ -http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4/sources/ \ -http://www.oesources.org/source/current/" - -# Opie -#use 1337 mt version of opie to have a webbrowser -PALMTOP_USE_MULTITHREADED_QT = "yes" -QTE_VERSION = "2.3.10" -OPIE_VERSION = "1.2.2" -require conf/distro/include/preferred-opie-versions.inc - -# GPE -require conf/distro/include/preferred-gpe-versions-2.8.inc - -PREFERRED_PROVIDER_dbus-glib = "dbus-glib" - -PREFERRED_VERSION_fontconfig = "2.3.95" -PREFERRED_VERSION_freetype = "2.2.1" - -#Small machines prefer kdrive, but we might ship full Xorg in other images -PREFERRED_PROVIDER_virtual/xserver ?= "xserver-kdrive" -PREFERRED_PROVIDER_xserver ?= "xserver-kdrive" - -require conf/distro/include/preferred-xorg-versions-X11R7.1.inc - -PREFERRED_VERSION_xserver-kdrive = "1.1.0+git${SRCDATE}" - -#zap extra stuff taking place in $MACHINE.conf -GPE_EXTRA_INSTALL = "" - - -# E -require conf/distro/include/preferred-e-versions.inc - -#Make sure we use 2.6 on machines with a 2.4/2.6 selector -KERNEL = "kernel26" -MACHINE_KERNEL_VERSION = "2.6" - -PREFERRED_PROVIDER_task-bootstrap = "task-bootstrap" - -PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}gcc-initial:gcc-cross-initial" -PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}gcc:gcc-cross" -PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}g++:gcc-cross" - -# Libc/uclibc: -#fix some iconv issues, needs to be adjusted when doing uclibc builds -PREFERRED_PROVIDER_virtual/libiconv ?= glibc -PREFERRED_PROVIDER_virtual/libintl ?= glibc - -# Virtuals: -PREFERRED_PROVIDER_virtual/db ?= "db" -PREFERRED_PROVIDER_virtual/db-native ?= "db-native" -PREFERRED_PROVIDER_virtual/xserver ?= xserver-kdrive - -# Others: -PREFERRED_PROVIDER_virtual/libx11 ?= "diet-x11" -PREFERRED_PROVIDER_gconf ?= gconf-dbus -PREFERRED_PROVIDER_gnome-vfs ?= gnome-vfs -PREFERRED_PROVIDER_tslib ?= tslib -PREFERRED_PROVIDER_libgpewidget ?= "libgpewidget" -PREFERRED_PROVIDER_ntp = "ntp" -PREFERRED_PROVIDER_hotplug = "udev" -PREFERRED_PROVIDER_libxss = "libxss" - -#EABI stuff -PREFERRED_PROVIDER_virtual/${TARGET_PREFIX}-libc-for-gcc = "glibc-intermediate" -PREFERRED_PROVIDER_virtual/arm-angstrom-linux-gnueabi-libc-for-gcc = "glibc-intermediate" -PREFERRED_PROVIDER_virtual/arm-linux-libc-for-gcc = "glibc-intermediate" - - -#use EABI toolchain -PREFERRED_VERSION_gcc ?= "4.1.1" -PREFERRED_VERSION_gcc-cross ?= "4.1.1" -PREFERRED_VERSION_gcc-cross-initial ?= "4.1.1" -PREFERRED_VERSION_binutils ?= "2.17" -PREFERRED_VERSION_binutils-cross ?= "2.17" -PREFERRED_VERSION_linux-libc-headers ?= "2.6.15.99" -PREFERRED_VERSION_glibc ?= "2.4" -PREFERRED_VERSION_glibc-intermediate ?= "2.4" - -# To use an EABI compatible version 3 series gcc, either uncomment -# the lines below or set them in local.conf: -# -# PREFERRED_VERSION_gcc-cross = "3.4.4+csl-arm-2005q3" -# PREFERRED_VERSION_gcc-cross-initial = "3.4.4+csl-arm-2005q3" - - -# Busybox <1.1.0 doesn't have EABI support -PREFERRED_VERSION_busybox = "1.2.1" - -PREFERRED_VERSION_orinoco-modules_h3600 = "0.13e" -PREFERRED_VERSION_orinoco-modules_h3900 = "0.13e" -PREFERRED_VERSION_dbus ?= "0.92" -PREFERRED_VERSION_gstreamer ?= "0.10.6" - -PREFERRED_PROVIDER_hostap-conf ?= "hostap-conf" -PREFERRED_PROVIDER_hostap-modules_h2200 ?= "hostap-modules" -PREFERRED_PROVIDER_hostap-modules_hx4700 ?= "hostap-modules" -PREFERRED_VERSION_hostap-modules ?= "0.4.7" - -#Down here we put stuff we want to install into machines without polluting conf/machine/ with distro stuff -# c7x0, akita, spitz, nokia770, h2200, h6300, ipaq-pxa270, simpad - -#### Bootstrap options #### - -PCMCIA_MANAGER_c7x0 = "pcmciautils" -PCMCIA_MANAGER_akita = "pcmciautils" -PCMCIA_MANAGER_spitz = "pcmciautils" -PCMCIA_MANAGER_tosa = "pcmciautils" -PCMCIA_MANAGER_poodle = "pcmciautils" -PCMCIA_MANAGER_nokia770 = "pcmciautils" -PCMCIA_MANAGER_h2200 = "pcmciautils" -PCMCIA_MANAGER_h4000 = "pcmciautils" -PCMCIA_MANAGER_h6300 = "pcmciautils" -PCMCIA_MANAGER_ipaq-pxa270 = "pcmciautils" - -# add altboot to compatible models, will be replaced with angstrom-bootmanager -#EXTRA_STUFF_append_c7x0 = "altboot" -#EXTRA_STUFF_append_akita = "altboot" -#EXTRA_STUFF_append_spitz = "altboot" -#EXTRA_STUFF_append_poodle = "altboot" -#EXTRA_STUFF_append_tosa = "altboot" - -### GPE section ### - -#Install libgtkinput in devices without a keyboard -GPE_EXTRA_INSTALL_append_ipaq-pxa270 = " libgtkinput" -GPE_EXTRA_INSTALL_append_h2200 = " libgtkinput" -GPE_EXTRA_INSTALL_append_h4000 = " libgtkinput" -GPE_EXTRA_INSTALL_append_h6300 = " libgtkinput" -GPE_EXTRA_INSTALL_append_simpad = " libgtkinput" -GPE_EXTRA_INSTALL_append_nokia770 = " libgtkinput" - -#As soon as a kill switch is in place we can add it to devices with a keyboard -#GPE_EXTRA_INSTALL_append_c7x0 = " libgtkinput" -#GPE_EXTRA_INSTALL_append_tosa = " libgtkinput" -#GPE_EXTRA_INSTALL_append_akita = " libgtkinput" -#GPE_EXTRA_INSTALL_append_spitz = " libgtkinput" - - diff --git a/conf/distro/angstrom-2007.1.conf b/conf/distro/angstrom-2007.1.conf new file mode 100644 index 0000000000..327d4123cc --- /dev/null +++ b/conf/distro/angstrom-2007.1.conf @@ -0,0 +1,176 @@ +#@-------------------------------------------------------------------- +#@TYPE: Distribution +#@NAME: Angstrom +#@DESCRIPTION: The Linux Distribution for Kernel 2.6 based devices +#@MAINTAINER: Koen Kooi +#@MAINTAINER: Michael 'Mickey' Lauer +#@-------------------------------------------------------------------- + +#DISTRO_VERSION = "2006.9" +DISTRO_VERSION = "test-${DATE}" + +require conf/distro/include/angstrom.inc +require conf/distro/include/sane-srcdates.inc + +DISTRO_TYPE = "debug" +#DISTRO_TYPE = "release" +#!!!!! DON'T FORGET TO ENABLE ZAPROOTPASSWD !!!!! + + +FEED_URIS += " \ + base##${ANGSTROM_URI}/unstable/feed/base \ + perl##${ANGSTROM_URI}/unstable/feed/perl \ + python##${ANGSTROM_URI}/unstable/feed/python \ + debug##${ANGSTROM_URI}/unstable/feed/debug \ + ${MACHINE}##${ANGSTROM_URI}/unstable/feed/machine/${MACHINE}" +# base##${ANGSTROM_URI}/releases/${DISTRO_VERSION}/feed/base \ +# ${MACHINE}##${ANGSTROM_URI}/releases/${DISTRO_VERSION}/feed/${MACHINE} \ +# updates##${ANGSTROM_URI}/releases/${DISTRO_VERSION}/feed/updates" + +#SRCDATE = "20060630" +#SRCDATE_handhelds-pxa-2.6 = "20060622" +SRCDATE_gconf-dbus = "20060719" +SRCDATE_gnome-vfs-dbus = "20060803" + +PREFERRED_VERSION_qemu-native = "0.8.2" + +CVS_TARBALL_STASH = "\ +http://ewi546.ewi.utwente.nl/mirror/www.openzaurus.org/official/unstable/3.5.4/sources/ \ +http://www.oesources.org/source/current/" + +# Opie +#use 1337 mt version of opie to have a webbrowser +PALMTOP_USE_MULTITHREADED_QT = "yes" +QTE_VERSION = "2.3.10" +OPIE_VERSION = "1.2.2" +require conf/distro/include/preferred-opie-versions.inc + +# GPE +require conf/distro/include/preferred-gpe-versions-2.8.inc + +PREFERRED_PROVIDER_dbus-glib = "dbus-glib" + +PREFERRED_VERSION_fontconfig = "2.3.95" +PREFERRED_VERSION_freetype = "2.2.1" + +#Small machines prefer kdrive, but we might ship full Xorg in other images +PREFERRED_PROVIDER_virtual/xserver ?= "xserver-kdrive" +PREFERRED_PROVIDER_xserver ?= "xserver-kdrive" + +require conf/distro/include/preferred-xorg-versions-X11R7.1.inc + +PREFERRED_VERSION_xserver-kdrive = "1.1.0+git${SRCDATE}" + +#zap extra stuff taking place in $MACHINE.conf +GPE_EXTRA_INSTALL = "" + + +# E +require conf/distro/include/preferred-e-versions.inc + +#Make sure we use 2.6 on machines with a 2.4/2.6 selector +KERNEL = "kernel26" +MACHINE_KERNEL_VERSION = "2.6" + +PREFERRED_PROVIDER_task-bootstrap = "task-bootstrap" + +PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}gcc-initial:gcc-cross-initial" +PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}gcc:gcc-cross" +PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}g++:gcc-cross" + +# Libc/uclibc: +#fix some iconv issues, needs to be adjusted when doing uclibc builds +PREFERRED_PROVIDER_virtual/libiconv ?= glibc +PREFERRED_PROVIDER_virtual/libintl ?= glibc + +# Virtuals: +PREFERRED_PROVIDER_virtual/db ?= "db" +PREFERRED_PROVIDER_virtual/db-native ?= "db-native" +PREFERRED_PROVIDER_virtual/xserver ?= xserver-kdrive + +# Others: +PREFERRED_PROVIDER_virtual/libx11 ?= "diet-x11" +PREFERRED_PROVIDER_gconf ?= gconf-dbus +PREFERRED_PROVIDER_gnome-vfs ?= gnome-vfs +PREFERRED_PROVIDER_tslib ?= tslib +PREFERRED_PROVIDER_libgpewidget ?= "libgpewidget" +PREFERRED_PROVIDER_ntp = "ntp" +PREFERRED_PROVIDER_hotplug = "udev" +PREFERRED_PROVIDER_libxss = "libxss" + +#EABI stuff +PREFERRED_PROVIDER_virtual/${TARGET_PREFIX}-libc-for-gcc = "glibc-intermediate" +PREFERRED_PROVIDER_virtual/arm-angstrom-linux-gnueabi-libc-for-gcc = "glibc-intermediate" +PREFERRED_PROVIDER_virtual/arm-linux-libc-for-gcc = "glibc-intermediate" + + +#use EABI toolchain +PREFERRED_VERSION_gcc ?= "4.1.1" +PREFERRED_VERSION_gcc-cross ?= "4.1.1" +PREFERRED_VERSION_gcc-cross-initial ?= "4.1.1" +PREFERRED_VERSION_binutils ?= "2.17" +PREFERRED_VERSION_binutils-cross ?= "2.17" +PREFERRED_VERSION_linux-libc-headers ?= "2.6.15.99" +PREFERRED_VERSION_glibc ?= "2.4" +PREFERRED_VERSION_glibc-intermediate ?= "2.4" + +# To use an EABI compatible version 3 series gcc, either uncomment +# the lines below or set them in local.conf: +# +# PREFERRED_VERSION_gcc-cross = "3.4.4+csl-arm-2005q3" +# PREFERRED_VERSION_gcc-cross-initial = "3.4.4+csl-arm-2005q3" + + +# Busybox <1.1.0 doesn't have EABI support +PREFERRED_VERSION_busybox = "1.2.1" + +PREFERRED_VERSION_orinoco-modules_h3600 = "0.13e" +PREFERRED_VERSION_orinoco-modules_h3900 = "0.13e" +PREFERRED_VERSION_dbus ?= "0.92" +PREFERRED_VERSION_gstreamer ?= "0.10.6" + +PREFERRED_PROVIDER_hostap-conf ?= "hostap-conf" +PREFERRED_PROVIDER_hostap-modules_h2200 ?= "hostap-modules" +PREFERRED_PROVIDER_hostap-modules_hx4700 ?= "hostap-modules" +PREFERRED_VERSION_hostap-modules ?= "0.4.7" + +#Down here we put stuff we want to install into machines without polluting conf/machine/ with distro stuff +# c7x0, akita, spitz, nokia770, h2200, h6300, ipaq-pxa270, simpad + +#### Bootstrap options #### + +PCMCIA_MANAGER_c7x0 = "pcmciautils" +PCMCIA_MANAGER_akita = "pcmciautils" +PCMCIA_MANAGER_spitz = "pcmciautils" +PCMCIA_MANAGER_tosa = "pcmciautils" +PCMCIA_MANAGER_poodle = "pcmciautils" +PCMCIA_MANAGER_nokia770 = "pcmciautils" +PCMCIA_MANAGER_h2200 = "pcmciautils" +PCMCIA_MANAGER_h4000 = "pcmciautils" +PCMCIA_MANAGER_h6300 = "pcmciautils" +PCMCIA_MANAGER_ipaq-pxa270 = "pcmciautils" + +# add altboot to compatible models, will be replaced with angstrom-bootmanager +#EXTRA_STUFF_append_c7x0 = "altboot" +#EXTRA_STUFF_append_akita = "altboot" +#EXTRA_STUFF_append_spitz = "altboot" +#EXTRA_STUFF_append_poodle = "altboot" +#EXTRA_STUFF_append_tosa = "altboot" + +### GPE section ### + +#Install libgtkinput in devices without a keyboard +GPE_EXTRA_INSTALL_append_ipaq-pxa270 = " libgtkinput" +GPE_EXTRA_INSTALL_append_h2200 = " libgtkinput" +GPE_EXTRA_INSTALL_append_h4000 = " libgtkinput" +GPE_EXTRA_INSTALL_append_h6300 = " libgtkinput" +GPE_EXTRA_INSTALL_append_simpad = " libgtkinput" +GPE_EXTRA_INSTALL_append_nokia770 = " libgtkinput" + +#As soon as a kill switch is in place we can add it to devices with a keyboard +#GPE_EXTRA_INSTALL_append_c7x0 = " libgtkinput" +#GPE_EXTRA_INSTALL_append_tosa = " libgtkinput" +#GPE_EXTRA_INSTALL_append_akita = " libgtkinput" +#GPE_EXTRA_INSTALL_append_spitz = " libgtkinput" + + -- cgit v1.2.3 From 2ef9cf97f34b7ec69f1df908413afa462e09ba61 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 27 Aug 2006 14:21:30 +0000 Subject: gst plugins ugly: add 0.10.4 --- packages/gstreamer/gst-plugins-ugly_0.10.4.bb | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 packages/gstreamer/gst-plugins-ugly_0.10.4.bb diff --git a/packages/gstreamer/gst-plugins-ugly_0.10.4.bb b/packages/gstreamer/gst-plugins-ugly_0.10.4.bb new file mode 100644 index 0000000000..7c548acf7d --- /dev/null +++ b/packages/gstreamer/gst-plugins-ugly_0.10.4.bb @@ -0,0 +1,2 @@ +require gst-plugins.inc +DEPENDS += "gst-plugins-base" -- cgit v1.2.3 From c3352186941a100ee3812472531ca3359fef4b95 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 16:00:40 +0000 Subject: gconf.bbclass: Add gconf to DEPENDS (from poky) --- classes/gconf.bbclass | 2 ++ 1 file changed, 2 insertions(+) diff --git a/classes/gconf.bbclass b/classes/gconf.bbclass index b0c5723873..686f8e6596 100644 --- a/classes/gconf.bbclass +++ b/classes/gconf.bbclass @@ -1,3 +1,5 @@ +DEPENDS += "gconf" + gconf_postinst() { if [ "$1" = configure ]; then if [ "x$D" != "x" ]; then -- cgit v1.2.3 From e609b8070d657674563ae304991f8b3307dc1b73 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 16:02:10 +0000 Subject: base.bbclass: Add base_contains and base_both_containg - useful functions for the new task-machine code (from poky) --- classes/base.bbclass | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/classes/base.bbclass b/classes/base.bbclass index e413afb2b3..670b97a72d 100644 --- a/classes/base.bbclass +++ b/classes/base.bbclass @@ -40,6 +40,20 @@ def base_conditional(variable, checkvalue, truevalue, falsevalue, d): else: return falsevalue +def base_contains(variable, checkvalue, truevalue, falsevalue, d): + import bb + if bb.data.getVar(variable,d,1).find(checkvalue) != -1: + return truevalue + else: + return falsevalue + +def base_both_contain(variable1, variable2, checkvalue, d): + import bb + if bb.data.getVar(variable1,d,1).find(checkvalue) != -1 and bb.data.getVar(variable2,d,1).find(checkvalue) != -1: + return checkvalue + else: + return "" + DEPENDS_prepend="${@base_dep_prepend(d)} " def base_set_filespath(path, d): -- cgit v1.2.3 From e71a84f77fd700c1001a68795e3220c41915f105 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 16:06:28 +0000 Subject: gtk-icon-cache.bbclass: Add from poky --- classes/gtk-icon-cache.bbclass | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 classes/gtk-icon-cache.bbclass diff --git a/classes/gtk-icon-cache.bbclass b/classes/gtk-icon-cache.bbclass new file mode 100644 index 0000000000..0f68e6812b --- /dev/null +++ b/classes/gtk-icon-cache.bbclass @@ -0,0 +1,38 @@ +FILES_${PN} += "${datadir}/icons/hicolor" + +gtk-icon-cache_postinst() { +if [ "x$D" != "x" ]; then + exit 1 +fi +gtk-update-icon-cache -q /usr/share/icons/hicolor +} + +gtk-icon-cache_postrm() { +gtk-update-icon-cache -q /usr/share/icons/hicolor +} + +python populate_packages_append () { + import os.path + packages = bb.data.getVar('PACKAGES', d, 1).split() + workdir = bb.data.getVar('WORKDIR', d, 1) + + for pkg in packages: + icon_dir = '%s/install/%s/%s/icons/hicolor' % (workdir, pkg, bb.data.getVar('datadir', d, 1)) + if not os.path.exists(icon_dir): + continue + + bb.note("adding gtk-icon-cache postinst and postrm scripts to %s" % pkg) + + postinst = bb.data.getVar('pkg_postinst_%s' % pkg, d, 1) or bb.data.getVar('pkg_postinst', d, 1) + if not postinst: + postinst = '#!/bin/sh\n' + postinst += bb.data.getVar('gtk-icon-cache_postinst', d, 1) + bb.data.setVar('pkg_postinst_%s' % pkg, postinst, d) + + postrm = bb.data.getVar('pkg_postrm_%s' % pkg, d, 1) or bb.data.getVar('pkg_postrm', d, 1) + if not postrm: + postrm = '#!/bin/sh\n' + postrm += bb.data.getVar('gtk-icon-cache_postrm', d, 1) + bb.data.setVar('pkg_postrm_%s' % pkg, postrm, d) +} + -- cgit v1.2.3 From 4012ee3240c15fdb40288596d0111b22ffcbf71e Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 16:25:48 +0000 Subject: tune-arm926ejs.conf: Be a little more specific about gcc version issues (from poky) --- conf/machine/include/tune-arm926ejs.conf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/conf/machine/include/tune-arm926ejs.conf b/conf/machine/include/tune-arm926ejs.conf index 5e2f6b7c62..ce1d4f7203 100644 --- a/conf/machine/include/tune-arm926ejs.conf +++ b/conf/machine/include/tune-arm926ejs.conf @@ -1,3 +1,5 @@ -#if gcc breaks change arm926ejs to arm926ej-s +# For gcc 3.x you need: TARGET_CC_ARCH = "-march=armv5te -mtune=arm926ejs" +# For gcc 4.x you need: +#TARGET_CC_ARCH = "-march=armv5te -mtune=arm926ej-s" PACKAGE_ARCH = "armv5te" -- cgit v1.2.3 From 36433bdc0e94f518ef2ee66d9b15f7ffe01f7d0c Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 16:35:59 +0000 Subject: bitbake.conf: Remove old style IMAGE_FSTYPE in favour of IMAGE_FSTYPES (which is weakly set to a default allowing machines to override/append) (from poky) --- conf/bitbake.conf | 3 +-- conf/distro/openmn.conf | 2 +- conf/distro/unslung.conf | 2 +- conf/machine/epia.conf | 2 +- conf/machine/netvista.conf | 4 ++-- conf/machine/sun4cdm.conf | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/conf/bitbake.conf b/conf/bitbake.conf index 0a141f883e..a6b995a241 100644 --- a/conf/bitbake.conf +++ b/conf/bitbake.conf @@ -188,8 +188,6 @@ IMAGE_CMD_tar.bz2 = "cd ${IMAGE_ROOTFS} && tar -jcvf ${DEPLOY_DIR_IMAGE}/${IMAGE EXTRA_IMAGECMD = "" EXTRA_IMAGECMD_jffs2 = "--pad --little-endian --eraseblock=0x40000" EXTRA_IMAGECMD_squashfs = "-le -b 16384" -IMAGE_FSTYPE = "jffs2" -IMAGE_FSTYPES = "${IMAGE_FSTYPE}" IMAGE_ROOTFS_SIZE_ext2 = "65536" IMAGE_ROOTFS_SIZE_ext2.gz = "65536" @@ -409,6 +407,7 @@ require conf/sanity.conf # Weak variables (usually to retain backwards compatibility) ################################################################## +IMAGE_FSTYPES ?= "jffs2" PCMCIA_MANAGER ?= "pcmcia-cs" diff --git a/conf/distro/openmn.conf b/conf/distro/openmn.conf index 0e3d36ed2d..8118acb1da 100644 --- a/conf/distro/openmn.conf +++ b/conf/distro/openmn.conf @@ -16,6 +16,6 @@ IPKG_EXTRA_ARCHS = "armv5te openmn" FEED_URIS = "mnci54##http://www.mn-solutions.de/feed/mnci54/base" -IMAGE_FSTYPE = "jffs2" +IMAGE_FSTYPES = "jffs2" EXTRA_IMAGECMD_jffs2 = "--pad=0x1ec0000 --eraseblock=0x40000" IMAGE_CMD_jffs2 = "mkfs.jffs2 --root=${IMAGE_ROOTFS} --faketime --output=${DEPLOY_DIR_IMAGE}/rootfs.${MACHINE} ${EXTRA_IMAGECMD}" diff --git a/conf/distro/unslung.conf b/conf/distro/unslung.conf index 0c757edc45..da1efa9cc4 100644 --- a/conf/distro/unslung.conf +++ b/conf/distro/unslung.conf @@ -34,7 +34,7 @@ FULL_OPTIMIZATION = "-fexpensive-optimizations -fomit-frame-pointer -frename-reg INHERIT += " package_ipk nslu2-jffs2-image" -IMAGE_FSTYPE = "jffs2" +IMAGE_FSTYPES = "jffs2" UNSLUNG_DEVICE_TABLE = "${@bb.which(bb.data.getVar('BBPATH', d, 1), 'files/device_table-unslung.txt')}" EXTRA_IMAGECMD_jffs2 = "--no-eraseblock-headers --pad --big-endian --eraseblock=0x20000 -D ${UNSLUNG_DEVICE_TABLE}" diff --git a/conf/machine/epia.conf b/conf/machine/epia.conf index dd6b0f0b93..e82da27574 100644 --- a/conf/machine/epia.conf +++ b/conf/machine/epia.conf @@ -1,7 +1,7 @@ TARGET_ARCH = "i586" TARGET_VENDOR = "-oe" PREFERRED_PROVIDER_virtual/kernel = "linux-epia" -IMAGE_FSTYPE = "ext2.gz" +IMAGE_FSTYPES = "ext2.gz" BOOTSTRAP_EXTRA_RDEPENDS = "pciutils udev kernel-modules" udevdir = "/dev" OLDEST_KERNEL = "2.6.5" diff --git a/conf/machine/netvista.conf b/conf/machine/netvista.conf index 9d483d4c55..2b9b572024 100644 --- a/conf/machine/netvista.conf +++ b/conf/machine/netvista.conf @@ -7,13 +7,13 @@ PREFERRED_PROVIDER_xserver = "xserver-xorg" PREFERRED_PROVIDER_virtual/kernel = "linux-netvista" BOOTSTRAP_EXTRA_RDEPENDS = "kernel pciutils" #BOOTSTRAP_EXTRA_RRECOMMENDS = "hostap-modules" -#IMAGE_FSTYPE = "cramfs" +#IMAGE_FSTYPES = "cramfs" EXTRA_IMAGEDEPENDS = "" SERIAL_CONSOLE = "ttyS0 115200 vt100" TARGET_VENDOR = "-oe" PREFERRED_PROVIDERS_append = " virtual/kernel:linux-netvista" -IMAGE_FSTYPE = "ext2" +IMAGE_FSTYPES = "ext2" GUI_MACHINE_CLASS = "bigscreen" GPE_EXTRA_INSTALL += "gaim sylpheed gpe-mini-browser abiword" diff --git a/conf/machine/sun4cdm.conf b/conf/machine/sun4cdm.conf index 5376be0dda..36974d1336 100644 --- a/conf/machine/sun4cdm.conf +++ b/conf/machine/sun4cdm.conf @@ -1,6 +1,6 @@ TARGET_ARCH = "sparc" -IMAGE_FSTYPE = "cramfs" +IMAGE_FSTYPES = "cramfs" BOOTSTRAP_EXTRA_RDEPENDS = "kernel module-init-tools udev" -- cgit v1.2.3 From 7632c92656c9aec7e77255584d6bb942a0abc6ae Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 16:37:32 +0000 Subject: bitbake.conf: Add PN to OVERRIDES in the form pn-PN (from poky) --- conf/bitbake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/bitbake.conf b/conf/bitbake.conf index a6b995a241..1cb03f30bd 100644 --- a/conf/bitbake.conf +++ b/conf/bitbake.conf @@ -387,7 +387,7 @@ AUTO_LIBNAME_PKGS = "${PACKAGES}" # This works for functions as well, they are really just environment variables. #OVERRIDES = "local:${MACHINE}:${DISTRO}:${TARGET_OS}:${TARGET_ARCH}:build-${BUILD_OS}" # Alternative OVERRIDES to make compilation fail fast, we will enable it by default soon -OVERRIDES = "local:${MACHINE}:${DISTRO}:${TARGET_OS}:${TARGET_ARCH}:build-${BUILD_OS}:fail-fast" +OVERRIDES = "local:${MACHINE}:${DISTRO}:${TARGET_OS}:${TARGET_ARCH}:build-${BUILD_OS}:fail-fast:pn-${PN}" ################################################################## # Include the rest of the config files. -- cgit v1.2.3 From 17865ab4a2fb5f6c5eeb53a229cc1fc21dbcfd39 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 16:59:08 +0000 Subject: zaurus machines: Clean up IPKG_EXTRA_ARCHS and IMAGE_FSTPES (from poky) --- conf/machine/akita.conf | 4 +++- conf/machine/c7x0.conf | 2 ++ conf/machine/include/zaurus-clamshell.conf | 2 +- conf/machine/ipaq-pxa270.conf | 2 ++ conf/machine/nokia770.conf | 2 ++ conf/machine/spitz.conf | 5 ++--- 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/conf/machine/akita.conf b/conf/machine/akita.conf index 005a70e664..0358864c70 100644 --- a/conf/machine/akita.conf +++ b/conf/machine/akita.conf @@ -4,6 +4,8 @@ include conf/machine/include/zaurus-clamshell.conf include conf/machine/include/zaurus-clamshell-2.6.conf -IPKG_EXTRA_ARCHS += "armv4 armv4t iwmmxt" + +IPKG_EXTRA_ARCHS += "iwmmxt" +IMAGE_FSTYPES ?= "jffs2" ROOT_FLASH_SIZE = "58" diff --git a/conf/machine/c7x0.conf b/conf/machine/c7x0.conf index 0bd9623526..4b1d8edb80 100644 --- a/conf/machine/c7x0.conf +++ b/conf/machine/c7x0.conf @@ -5,5 +5,7 @@ include conf/machine/include/zaurus-clamshell.conf include conf/machine/include/zaurus-clamshell-2.6.conf +IMAGE_FSTYPES ?= "jffs2" + ROOT_FLASH_SIZE = "25" # yes, we are aware that the husky (c760,c860) has 54MB rootfs, but we don't make a special image for it. diff --git a/conf/machine/include/zaurus-clamshell.conf b/conf/machine/include/zaurus-clamshell.conf index f85c2a1221..97728fa5b6 100644 --- a/conf/machine/include/zaurus-clamshell.conf +++ b/conf/machine/include/zaurus-clamshell.conf @@ -14,7 +14,7 @@ IMAGE_CMD_jffs2 = "mkfs.jffs2 --root=${IMAGE_ROOTFS} --faketime \ # add a summary to the jffs2 file to make it mount a lot faster EXTRA_IMAGECMD_jffs2 += "&& sumtool -i ${T}/${IMAGE_NAME}.rootfs.jffs2 \ -o ${T}/${IMAGE_NAME}.rootfs.jffs2.summary \ - --eraseblock=0x4000 -l -p" + --eraseblock=0x4000 -l -p" IMAGE_CMD_jffs2 += "; cat ${STAGING_LIBDIR}/sharp-flash-header/header-c700.bin \ ${T}/${IMAGE_NAME}.rootfs.jffs2.summary > ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.summary.img" diff --git a/conf/machine/ipaq-pxa270.conf b/conf/machine/ipaq-pxa270.conf index fa3675fb59..d6281e3016 100644 --- a/conf/machine/ipaq-pxa270.conf +++ b/conf/machine/ipaq-pxa270.conf @@ -18,6 +18,8 @@ EXTRA_IMAGECMD_jffs2 = "; sumtool -i ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jf -o ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs-summary.jffs2 \ -e 256KiB -p" +IMAGE_FSTYPES ?= "jffs2" + MODUTILS = "26" PCMCIA_MANAGER = "pcmciautils" BOOTSTRAP_EXTRA_RDEPENDS = "kernel ipaq-boot-params " diff --git a/conf/machine/nokia770.conf b/conf/machine/nokia770.conf index edd7213346..eee389faf1 100644 --- a/conf/machine/nokia770.conf +++ b/conf/machine/nokia770.conf @@ -21,6 +21,8 @@ include conf/machine/include/tune-arm926ejs.conf ROOT_FLASH_SIZE = "123" EXTRA_IMAGECMD_jffs2_nokia770 = "--pad --little-endian --eraseblock=0x20000" +IMAGE_FSTYPES ?= "jffs2" + # serial console port on devboard rev. B3 SERIAL_CONSOLE = "115200 ttyS0" diff --git a/conf/machine/spitz.conf b/conf/machine/spitz.conf index 3d80a41486..b8851f6170 100644 --- a/conf/machine/spitz.conf +++ b/conf/machine/spitz.conf @@ -5,15 +5,14 @@ include conf/machine/include/zaurus-clamshell.conf include conf/machine/include/zaurus-clamshell-2.6.conf -IPKG_EXTRA_ARCHS += "armv4 armv4t iwmmxt" - PIVOTBOOT_EXTRA_RDEPENDS += "pivotinit ${PCMCIA_MANAGER}" PIVOTBOOT_EXTRA_RRECOMMENDS += "" # Useful things for the built-in Harddisk BOOTSTRAP_EXTRA_RDEPENDS += "hdparm e2fsprogs e2fsprogs-e2fsck e2fsprogs-mke2fs" -IMAGE_FSTYPES = "jffs2 tar.gz" +IPKG_EXTRA_ARCHS += "iwmmxt" +IMAGE_FSTYPES ?= "tar.gz" ROOT_FLASH_SIZE = "100" # actually that should really read ROOTFS_SIZE = "100", because with modern kernels, -- cgit v1.2.3 From ec79ca5996b24f3b3bd39f43774b5b1bbbbce50b Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 17:06:28 +0000 Subject: task-base.bb: Add from poky --- packages/tasks/task-base.bb | 255 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 packages/tasks/task-base.bb diff --git a/packages/tasks/task-base.bb b/packages/tasks/task-base.bb new file mode 100644 index 0000000000..61b8744105 --- /dev/null +++ b/packages/tasks/task-base.bb @@ -0,0 +1,255 @@ +DESCRIPTION = "Merge machine and distro options to create a basic machine task/package" +MAINTAINER = "Richard Purdie " +PR = "r0" + +PACKAGES = "task-base \ + task-base-oh-minimal" + +ALLOW_EMPTY = "1" + +PACKAGE_ARCH = "${MACHINE_ARCH}" + +# Valid only in MACHINE_FEATURES: +# +# kernel24 +# kernel26 +# apm + +# Valid only in DISTO_FEATURES: +# +# nfs +# smbfs +# ipsec +# wifi +# ppp + +# Valid COMBINED_FEATURES: +# (These features need to be supported by both the machine and the distro) +# +# alsa +# bluetooth +# ext2 +# irda +# pcmcia +# usbgadget +# usbhost + + +MACHINE_FEATURES ?= "kernel26" +DISTRO_FEATURES ?= "" + +DISTRO_EXTRA_RDEPENDS ?= "" +DISTRO_EXTRA_RRECOMMENDS ?= "" +MACHINE_EXTRA_RDEPENDS ?= "" +MACHINE_EXTRA_RRECOMMENDS ?= "" +MACHINE_ESSENTIAL_EXTRA_RDEPENDS ?= "" +MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS ?= "" + + +COMBINED_FEATURES = "\ + ${@base_both_contain("DISTRO_FEATURES", "MACHINE_FEATURES", "alsa", d)} \ + ${@base_both_contain("DISTRO_FEATURES", "MACHINE_FEATURES", "bluetooth", d)} \ + ${@base_both_contain("DISTRO_FEATURES", "MACHINE_FEATURES", "ext2", d)} \ + ${@base_both_contain("DISTRO_FEATURES", "MACHINE_FEATURES", "irda", d)} \ + ${@base_both_contain("DISTRO_FEATURES", "MACHINE_FEATURES", "pcmcia", d)} \ + ${@base_both_contain("DISTRO_FEATURES", "MACHINE_FEATURES", "usbgadget", d)} \ + ${@base_both_contain("DISTRO_FEATURES", "MACHINE_FEATURES", "usbhost", d)}" + + +# +# task-base +# +RDEPENDS_task-base = "\ + kernel \ + ${@base_contains("MACHINE_FEATURES", "kernel26", "${task-base-kernel26-rdepends}", "",d)} \ + ${@base_contains("MACHINE_FEATURES", "apm", "${task-base-apm-rdepends}", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "alsa", "${task-base-alsa-rdepends}", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "ext2", "${task-base-ext2-rdepends}", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "irda", "${task-base-irda-rdepends}", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "pcmcia", "${task-base-pcmcia-rdepends}", "",d)} \ + ${@base_contains("DISTRO_FEATURES", "ipsec", "${task-distro-ipsec-rdepends}", "",d)} \ + ${@base_contains("DISTRO_FEATURES", "ppp", "${task-distro-ppp-rdepends}", "",d)} \ + ${@base_contains("DISTRO_FEATURES", "wifi", "${task-distro-wifi-rdepends}", "",d)} \ + ${MACHINE_ESSENTIAL_EXTRA_RDEPENDS} \ + ${MACHINE_EXTRA_RDEPENDS} \ + ${DISTRO_EXTRA_RDEPENDS}" + +RRECOMMENDS_task-base = "\ + ${@base_contains("MACHINE_FEATURES", "kernel26", "${task-base-kernel26-extras-rrecommends}", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "alsa", "${task-base-alsa-rrecommends}", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "pcmcia", "${task-base-pcmcia-rrecommends}", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "bluetooth", "${task-base-bluetooth-rrecommends}", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "irda", "${task-base-irda-rrecommends}", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "usbgadget", "${task-base-usbgadget-rrecommends}", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "usbhost", "${task-base-usbhost-rrecommends}", "",d)} \ + ${@base_contains("DISTRO_FEATURES", "ppp", "${task-distro-ppp-rrecommends}", "",d)} \ + ${@base_contains("DISTRO_FEATURES", "nfs", "${task-distro-nfs-rrecommends}", "",d)} \ + ${@base_contains("DISTRO_FEATURES", "ipsec", "${task-distro-ipsec-rrecommends}", "",d)} \ + ${@base_contains("DISTRO_FEATURES", "cramfs", "${task-distro-cramfs-rrecommends}", "",d)} \ + ${MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS} \ + ${MACHINE_EXTRA_RRECOMMENDS} \ + ${DISTRO_EXTRA_RRECOMMENDS}" + + +# +# task-base-oh-minimal +# An example of a small cut down machine configuration +# +RDEPENDS_task-base-oh-minimal = "\ + kernel \ + ${@base_contains("MACHINE_FEATURES", "kernel26", "${task-base-kernel26-rdepends}", "",d)} \ + ${@base_contains("MACHINE_FEATURES", "apm", "${task-base-apm-rdepends}", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "pcmcia", "${PCMCIA_MANAGER}", "",d)} \ + ${MACHINE_ESSENTIAL_EXTRA_RDEPENDS}" + +RRECOMMENDS_task-base-minimal = "\ + ${MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS}" + +task-base-kernel26-rdepends = "\ + udev \ + keymaps \ + sysfsutils \ + module-init-tools" + +task-base-kernel26-extras-rrecommends = "\ + kernel-module-input \ + kernel-module-uinput" + +task-base-apm-rdepends = "\ + apm \ + apmd \ + ${@base_contains("MACHINE_FEATURES", "kernel24", "network-suspend-scripts", "",d)}" + +task-base-ext2-rdepends = "\ + hdparm \ + e2fsprogs \ + e2fsprogs-e2fsck \ + e2fsprogs-mke2fs" + +task-base-alsa-rdepends = "\ + alsa-utils-alsactl \ + alsa-utils-alsamixer \ + alsa-conf" + +task-base-alsa-rrecommends = "\ + kernel-module-snd-mixer-oss \ + kernel-module-snd-pcm-oss" + +task-base-pcmcia-rdepends = "\ + ${PCMCIA_MANAGER} \ + ${@base_contains("DISTRO_FEATURES", "wifi", "prism3-firmware", "",d)} \ + ${@base_contains("DISTRO_FEATURES", "wifi", "prism3-support", "",d)} \ + ${@base_contains("DISTRO_FEATURES", "wifi", "spectrum-fw", "",d)} \ + ${@base_contains("DISTRO_FEATURES", "wifi", "hostap-conf", "",d)} \ + ${@base_contains("DISTRO_FEATURES", "wifi", "orinoco-conf", "",d)}" + +task-base-pcmcia-rrecommends = "\ + kernel-module-airo-cs \ + kernel-module-pcnet-cs \ + kernel-module-serial-cs \ + kernel-module-hostap-cs \ + kernel-module-ide-cs \ + ${@base_contains("DISTRO_FEATURES", "wifi", "kernel-module-orinoco-cs", "",d)} \ + ${@base_contains("DISTRO_FEATURES", "wifi", "kernel-module-spectrum-cs", "",d)}" + +task-base-bluetooth-rrecommends = "\ + kernel-module-bluetooth \ + kernel-module-l2cap \ + kernel-module-rfcomm \ + kernel-module-hci-vhci \ + kernel-module-bnep \ + kernel-module-hidp \ + kernel-module-hci-uart \ + kernel-module-sco \ + ${@base_contains("COMBINED_FEATURES", "pcmcia", "kernel-module-bluetooth3c-cs", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "pcmcia", "kernel-module-bluecard-cs", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "pcmcia", "kernel-module-bluetoothuart-cs", "",d)} \ + ${@base_contains("COMBINED_FEATURES", "pcmcia", "kernel-module-dtl1-cs", "",d)}" + +task-base-irda-rdepends = "\ + irda-utils" + +task-base-irda-rrecommends = "\ + kernel-module-pxaficp-ir \ + kernel-module-irda \ + kernel-module-ircomm \ + kernel-module-ircomm-tty \ + kernel-module-irlan \ + kernel-module-irnet \ + kernel-module-irport \ + kernel-module-irtty \ + kernel-module-ir-usb" + +task-base-usbgadget-rrecommends = "\ + kernel-module-gadgetfs \ + kernel-module-g-file-storage \ + kernel-module-g-serial \ + kernel-module-g-ether" + +task-base-usbhost-rrecommends = "\ + kernel-module-ohci-hcd \ + kernel-module-usbcore \ + kernel-module-usbhid \ + kernel-module-usbnet \ + kernel-module-sd-mod \ + kernel-module-scsi-mod \ + kernel-module-usbmouse \ + kernel-module-mousedev \ + kernel-module-hci-usb \ + kernel-module-usbserial \ + kernel-module-usb-storage \ + kernel-module-ir-usb" + +task-distro-ppp-rdepends = "\ + ppp \ + ppp-dialin" + +task-distro-ppp-rrecommends = "\ + kernel-module-ppp-async \ + kernel-module-ppp-deflate \ + kernel-module-ppp-mppe" + +task-distro-ipsec-rdepends = "\ + openswan" + +task-distro-ipsec-rrecommends = "\ + kernel-module-ipsec" + +task-distro-wifi-rdepends = "\ + wireless-tools \ + hostap-utils \ + wpa-supplicant-nossl" + +task-distro-smbfs-rrecommends = "\ + kernel-module-smbfs" + +task-distro-cramfs-rrecommends = "\ + kernel-module-cramfs" + +task-distro-nfs-rrecommends = "\ + kernel-module-nfs \ + kernel-module-lockd \ + kernel-module-sunrpc" + + +# Tosort +# kernel-module-ipv6 +# kernel-module-ipsec +# kernel-module-nvrd +# kernel-module-mip6-mn +# kernel-module-tun +# kernel-module-ide-disk +# kernel-module-ide-probe-mo +# kernel-module-loop +# kernel-module-vfat +# kernel-module-ext2 +# kernel-module-nfs +# kernel-module-sco +# kernel-module-af_packet +# kernel-module-ip-gre +# kernel-module-ip-tables +# kernel-module-ipip +# kernel-module-des +# kernel-module-md5 +# kernel-module-8250 +# Should be DISTRO_EXTRA_RRECOMMENDS: lrzsz -- cgit v1.2.3 From b59ce10791fa913ef0915e48a514f04ca2815977 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Sun, 27 Aug 2006 17:17:14 +0000 Subject: links-x11_2.1pre21.bb, links_2.1pre12.bb : patches for cookie saving and preventing segfault on cookies imported from MDK rpms. packages/links/* : drop old versions --- packages/links/files/cookies-save-0.96.patch | 106 + ...-2.1pre17-fix-segfault-on-loading-cookies.patch | 20 + packages/links/links-2.1pre12/.mtn2git_empty | 0 packages/links/links-2.1pre12/configure.patch | 21443 ------------------- packages/links/links-2.1pre14/.mtn2git_empty | 0 packages/links/links-2.1pre14/configure.patch | 258 - packages/links/links-x11_2.1pre21.bb | 21 - packages/links/links-x11_2.1pre22.bb | 6 +- packages/links/links_2.1pre12.bb | 16 - packages/links/links_2.1pre14.bb | 16 - packages/links/links_2.1pre21.bb | 19 - packages/links/links_2.1pre22.bb | 6 +- 12 files changed, 136 insertions(+), 21775 deletions(-) create mode 100644 packages/links/files/cookies-save-0.96.patch create mode 100644 packages/links/files/links-2.1pre17-fix-segfault-on-loading-cookies.patch delete mode 100644 packages/links/links-2.1pre12/.mtn2git_empty delete mode 100644 packages/links/links-2.1pre12/configure.patch delete mode 100644 packages/links/links-2.1pre14/.mtn2git_empty delete mode 100644 packages/links/links-2.1pre14/configure.patch delete mode 100644 packages/links/links-x11_2.1pre21.bb delete mode 100644 packages/links/links_2.1pre12.bb delete mode 100644 packages/links/links_2.1pre14.bb delete mode 100644 packages/links/links_2.1pre21.bb diff --git a/packages/links/files/cookies-save-0.96.patch b/packages/links/files/cookies-save-0.96.patch new file mode 100644 index 0000000000..a1e35c01ca --- /dev/null +++ b/packages/links/files/cookies-save-0.96.patch @@ -0,0 +1,106 @@ +diff -ru links-0.96/cookies.c links-0.96+cookies-save/cookies.c +--- links-0.96/cookies.c Mon Sep 3 07:19:37 2001 ++++ links-0.96+cookies-save/cookies.c Mon Sep 3 07:18:42 2001 +@@ -276,15 +276,99 @@ + + void init_cookies(void) + { +- /* !!! FIXME: read cookies */ ++ unsigned char in_buffer[MAX_STR_LEN]; ++ unsigned char *cookfile, *p, *q; ++ FILE *fp; ++ ++ /* must be called after init_home */ ++ if (! links_home) return; ++ ++ cookfile = stracpy(links_home); ++ if (! cookfile) return; ++ add_to_strn(&cookfile, "cookies"); ++ ++ fp = fopen(cookfile, "r"); ++ mem_free(cookfile); ++ if (fp == NULL) return; ++ ++ while (fgets(in_buffer, MAX_STR_LEN, fp)) { ++ struct cookie *cookie; ++ ++ if (!(cookie = mem_alloc(sizeof(struct cookie)))) return; ++ memset(cookie, 0, sizeof(struct cookie)); ++ ++ q = in_buffer; p = strchr(in_buffer, ' '); ++ if (p == NULL) goto inv; ++ *p++ = '\0'; ++ cookie->name = stracpy(q); ++ ++ q = p; p = strchr(p, ' '); ++ if (p == NULL) goto inv; ++ *p++ = '\0'; ++ cookie->value = stracpy(q); ++ ++ q = p; p = strchr(p, ' '); ++ if (p == NULL) goto inv; ++ *p++ = '\0'; ++ cookie->server = stracpy(q); ++ ++ q = p; p = strchr(p, ' '); ++ if (p == NULL) goto inv; ++ *p++ = '\0'; ++ cookie->path = stracpy(q); ++ ++ q = p; p = strchr(p, ' '); ++ if (p == NULL) goto inv; ++ *p++ = '\0'; ++ cookie->domain = stracpy(q); ++ ++ q = p; p = strchr(p, ' '); ++ if (p == NULL) goto inv; ++ *p++ = '\0'; ++ cookie->expires = atoi(q); ++ ++ cookie->secure = atoi(p); ++ ++ cookie->id = cookie_id++; ++ ++ accept_cookie(cookie); ++ ++ continue; ++ ++inv: ++ free_cookie(cookie); ++ free(cookie); ++ } ++ fclose(fp); + } + + void cleanup_cookies(void) + { + struct cookie *c; ++ unsigned char *cookfile; ++ FILE *fp; ++ + free_list(c_domains); +- /* !!! FIXME: save cookies */ +- foreach (c, cookies) free_cookie(c); ++ ++ cookfile = stracpy(links_home); ++ if (! cookfile) return; ++ add_to_strn(&cookfile, "cookies"); ++ ++ fp = fopen(cookfile, "w"); ++ mem_free(cookfile); ++ if (fp == NULL) return; ++ ++ foreach (c, cookies) { ++ if (c->expires && ! cookie_expired(c)) ++ fprintf(fp, "%s %s %s %s %s %d %d\n", c->name, c->value, ++ c->server?c->server:(unsigned char *)"", c->path?c->path:(unsigned char *)"", ++ c->domain?c->domain:(unsigned char *)"", c->expires, c->secure); ++ ++ free_cookie(c); ++ } ++ ++ fclose(fp); ++ + free_list(cookies); + } + diff --git a/packages/links/files/links-2.1pre17-fix-segfault-on-loading-cookies.patch b/packages/links/files/links-2.1pre17-fix-segfault-on-loading-cookies.patch new file mode 100644 index 0000000000..0d3b407e2a --- /dev/null +++ b/packages/links/files/links-2.1pre17-fix-segfault-on-loading-cookies.patch @@ -0,0 +1,20 @@ +--- links-2.1pre17/cookies.c.pix 2005-05-15 23:05:10.000000000 +0800 ++++ links-2.1pre17/cookies.c 2005-05-15 23:17:21.000000000 +0800 +@@ -41,7 +41,7 @@ + + void free_cookie(struct cookie *c) + { +- mem_free(c->name); ++ if (c->value) mem_free(c->name); + if (c->value) mem_free(c->value); + if (c->server) mem_free(c->server); + if (c->path) mem_free(c->path); +@@ -355,7 +355,7 @@ + + inv: + free_cookie(cookie); +- free(cookie); ++ mem_free(cookie); + } + fclose(fp); + } diff --git a/packages/links/links-2.1pre12/.mtn2git_empty b/packages/links/links-2.1pre12/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/links/links-2.1pre12/configure.patch b/packages/links/links-2.1pre12/configure.patch deleted file mode 100644 index 0425843f60..0000000000 --- a/packages/links/links-2.1pre12/configure.patch +++ /dev/null @@ -1,21443 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- links-2.1pre12/configure.in~configure -+++ links-2.1pre12/configure.in -@@ -3,7 +3,8 @@ - # Martin 'PerM' Pergel - # This file is a part of the Links program, released under GPL. - --AC_INIT(main.c) -+AC_INIT -+AC_CONFIG_SRCDIR([main.c]) - - AM_INIT_AUTOMAKE(links, 2.1pre12) - -@@ -13,12 +14,12 @@ - AUTOHEADER="./missing autoheader" - image_formats="GIF PNG XBM" - --AM_CONFIG_HEADER(config.h) -+AC_CONFIG_HEADERS([config.h]) - - dnl Checks for programs. - AC_PROG_CC - --#AC_PROG_CXX -+AC_PROG_CXX - #AC_PROG_AWK - #AM_PROG_LEX - #AC_PROG_YACC -@@ -27,20 +28,20 @@ - #AC_CHECK_LIB(fl,main,AC_DEFINE(JS) LIBS="$LIBS -lfl",AC_MSG_WARN(You don't have libfl; you won't be able to run javascript)) - - AC_CACHE_CHECK([for EMX], ac_cv_have_emx, -- AC_TRY_COMPILE(, [#ifndef __EMX__ -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[#ifndef __EMX__ - kill me! -- #endif ], ac_cv_have_emx=yes, ac_cv_have_emx=no) -+ #endif ]])],[ac_cv_have_emx=yes],[ac_cv_have_emx=no]) - ) - test "$ac_cv_have_emx" = yes && LDFLAGS=`echo "$LDFLAGS" | sed "s/-Zexe//g" | sed "s/-Zbin-files//g"` - - AC_CACHE_CHECK([for typeof], ac_cv_have_typeof, -- AC_TRY_COMPILE(, [int a; -- typeof(a) b;], ac_cv_have_typeof=yes, ac_cv_have_typeof=no) -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[int a; -+ typeof(a) b;]])],[ac_cv_have_typeof=yes],[ac_cv_have_typeof=no]) - ) - test "$ac_cv_have_typeof" = yes && AC_DEFINE(HAVE_TYPEOF) - - AC_CACHE_CHECK([for long long], ac_cv_have_long_long, -- AC_TRY_COMPILE(, [unsigned long long a; ], ac_cv_have_long_long=yes, ac_cv_have_long_long=no) -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[unsigned long long a; ]])],[ac_cv_have_long_long=yes],[ac_cv_have_long_long=no]) - ) - test "$ac_cv_have_long_long" = yes && AC_DEFINE(HAVE_LONG_LONG) - -@@ -87,7 +88,7 @@ - AC_CHECK_SIZEOF(long, "$default_int") - AC_CHECK_SIZEOF(unsigned long, "$default_int") - AC_CACHE_CHECK([for big endian], ac_cv_big_endian, -- AC_TRY_RUN([ -+ AC_RUN_IFELSE([AC_LANG_SOURCE([[ - long l; - char *c = (char *)&l; - int main() -@@ -95,10 +96,10 @@ - l = 0x12345678L; - return !(c[[sizeof(long) - 1]] == 0x78 && c[[sizeof(long) - 2]] == 0x56 && c[[sizeof(long) - 3]] == 0x34 && c[[sizeof(long) - 4]] == 0x12); - } -- ], ac_cv_big_endian=yes, ac_cv_big_endian=no, ac_cv_big_endian=no) -+ ]])],[ac_cv_big_endian=yes],[ac_cv_big_endian=no],[ac_cv_big_endian=no]) - ) - AC_CACHE_CHECK([for little endian], ac_cv_little_endian, -- AC_TRY_RUN([ -+ AC_RUN_IFELSE([AC_LANG_SOURCE([[ - long l; - char *c = (char *)&l; - int main() -@@ -106,9 +107,12 @@ - l = 0x12345678L; - return !(c[[0]] == 0x78 && c[[1]] == 0x56 && c[[2]] == 0x34 && c[[3]] == 0x12); - } -- ], ac_cv_little_endian=yes, ac_cv_little_endian=no, ac_cv_little_endian="$ac_cv_have_emx") -+ ]])],[ac_cv_little_endian=yes],[ac_cv_little_endian=no],[ac_cv_little_endian="$ac_cv_have_emx"]) - ) - -+AC_DEFUN([AC_BIG_ENDIAN],[],[]) -+AC_DEFUN([AC_LITTLE_ENDIAN],[],[]) -+ - if test "$ac_cv_big_endian" = yes; then - AC_DEFINE(AC_BIG_ENDIAN) - else if test "$ac_cv_little_endian" = yes; then -@@ -122,19 +126,19 @@ - AC_TYPE_SIGNAL - AC_FUNC_STRFTIME - AC_FUNC_VPRINTF --AC_HAVE_FUNCS(calloc) --AC_HAVE_FUNCS(snprintf) --AC_HAVE_FUNCS(gettimeofday mkdir select strcspn strerror strstr strtol strtoul alarm chmod) --AC_HAVE_FUNCS(getpid setpgid getpgid setpgrp getpgrp) --AC_HAVE_FUNCS(popen) --AC_HAVE_FUNCS(uname) --AC_HAVE_FUNCS(strptime) --AC_HAVE_FUNCS(setlocale) --AC_HAVE_FUNCS(nl_langinfo) --dnl AC_HAVE_FUNCS(sigsetjmp siglongjmp) -+AC_CHECK_FUNCS([calloc]) -+AC_CHECK_FUNCS([snprintf]) -+AC_CHECK_FUNCS([gettimeofday mkdir select strcspn strerror strstr strtol strtoul alarm chmod]) -+AC_CHECK_FUNCS([getpid setpgid getpgid setpgrp getpgrp]) -+AC_CHECK_FUNCS([popen]) -+AC_CHECK_FUNCS([uname]) -+AC_CHECK_FUNCS([strptime]) -+AC_CHECK_FUNCS([setlocale]) -+AC_CHECK_FUNCS([nl_langinfo]) -+dnl AC_CHECK_FUNCS([sigsetjmp siglongjmp]) - - AC_CACHE_CHECK([for sigsetjmp/siglongjmp], ac_cv_have_sigsetjmp, -- AC_TRY_LINK([#include ], [sigjmp_buf env;sigsetjmp(env, 1);siglongjmp(env, 2);], ac_cv_have_sigsetjmp=yes, ac_cv_have_sigsetjmp=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[sigjmp_buf env;sigsetjmp(env, 1);siglongjmp(env, 2);]])],[ac_cv_have_sigsetjmp=yes],[ac_cv_have_sigsetjmp=no]) - ) - if test "$ac_cv_have_sigsetjmp" = yes; then - AC_DEFINE(HAVE_SIGSETJMP) -@@ -153,7 +157,7 @@ - fi - - #AC_MSG_CHECKING([for gethostbyname]) --#AC_TRY_LINK([#include ], [gethostbyname("")], cf_result=yes, cf_result=no) -+#AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[gethostbyname("")]])],[cf_result=yes],[cf_result=no]) - #AC_MSG_RESULT($cf_result) - AC_CHECK_FUNC(gethostbyname, cf_result=yes, cf_result=no) - if test "$cf_result" = no; then -@@ -168,7 +172,7 @@ - AC_CHECK_FUNC(herror, AC_DEFINE(HAVE_HERROR)) - AC_CHECK_FUNC(cfmakeraw, AC_DEFINE(HAVE_CFMAKERAW)) - --AC_HAVE_FUNCS(cygwin_conv_to_full_win32_path) -+AC_CHECK_FUNCS([cygwin_conv_to_full_win32_path]) - - AC_MSG_CHECKING([if you want to enable javascript]) - AC_ARG_ENABLE(javascript, [ --enable-javascript use javascript interpreter], cf_use_javascript=yes, cf_use_javascript=no) -@@ -192,7 +196,7 @@ - AC_CACHE_CHECK([for OS/2 threads], ac_cv_have_beginthread, - CFLAGS_X="$CFLAGS" - CFLAGS="$CFLAGS -Zmt" -- AC_TRY_LINK([#include ], [_beginthread(NULL, NULL, 0, NULL)], ac_cv_have_beginthread=yes, ac_cv_have_beginthread=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[_beginthread(NULL, NULL, 0, NULL)]])],[ac_cv_have_beginthread=yes],[ac_cv_have_beginthread=no]) - CFLAGS="$CFLAGS_X" - ) - if test "$ac_cv_have_beginthread" = yes; then -@@ -209,8 +213,8 @@ - fi - #AC_CHECK_FUNC(clone, AC_DEFINE(HAVE_CLONE)) - AC_CHECK_HEADERS(atheos/threads.h) --AC_HAVE_FUNCS(spawn_thread) --AC_HAVE_FUNCS(resume_thread) -+AC_CHECK_FUNCS([spawn_thread]) -+AC_CHECK_FUNCS([resume_thread]) - - AC_CHECK_FUNC(MouOpen, AC_DEFINE(HAVE_MOUOPEN)) - AC_CHECK_FUNC(_read_kbd, AC_DEFINE(HAVE_READ_KBD)) -@@ -222,10 +226,10 @@ - if test -n "$X11ROOT"; then - CPPFLAGS="$CPPFLAGS_X -I$X11ROOT/XFree86/include" - LIBS="$LIBS_X -L$X11ROOT/XFree86/lib -lxf86_gcc" -- AC_TRY_LINK([#include ], [struct winsize win;ptioctl(1, TIOCGWINSZ, &win)], ac_cv_have_x2=xf86_gcc, ac_cv_have_x2=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct winsize win;ptioctl(1, TIOCGWINSZ, &win)]])],[ac_cv_have_x2=xf86_gcc],[ac_cv_have_x2=no]) - if test "$ac_cv_have_x2" = no; then - LIBS="$LIBS_X -L$X11ROOT/XFree86/lib -lxf86" -- AC_TRY_LINK([#include ], [struct winsize win;ptioctl(1, TIOCGWINSZ, &win)], ac_cv_have_x2=xf86, ac_cv_have_x2=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct winsize win;ptioctl(1, TIOCGWINSZ, &win)]])],[ac_cv_have_x2=xf86],[ac_cv_have_x2=no]) - fi - fi - CPPFLAGS="$CPPFLAGS_X" -@@ -254,9 +258,9 @@ - else - LIBS="-lssl -lcrypto $LIBS_X" - fi -- AC_TRY_LINK([#include ], [OpenSSL_add_all_algorithms()], cf_result=yes, cf_result=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[OpenSSL_add_all_algorithms()]])],[cf_result=yes],[cf_result=no]) - if test "$cf_result" != yes; then -- AC_TRY_LINK([#include ], [SSLeay_add_ssl_algorithms()], cf_result=yes, cf_result=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[SSLeay_add_ssl_algorithms()]])],[cf_result=yes],[cf_result=no]) - fi - fi - done -@@ -287,14 +291,14 @@ - AC_CHECK_HEADERS(png.h libpng/png.h) - AC_CHECK_LIB(png, png_create_info_struct) - if test "$ac_cv_header_png_h" != yes && test "$ac_cv_header_libpng_png_h" != yes || test "$ac_cv_lib_png_png_create_info_struct" != yes; then -- AC_ERROR([You need libpng to compile Links in graphics mode]) -+ AC_MSG_ERROR([You need libpng to compile Links in graphics mode]) - fi - -- AC_HAVE_FUNCS(png_set_rgb_to_gray) -+ AC_CHECK_FUNCS([png_set_rgb_to_gray]) - - AC_CACHE_CHECK(if you can include both setjmp.h and png.h, ac_cv_include_setjmp_png, -- AC_TRY_COMPILE([#include -- #include ], [jmp_buf bla;], ac_cv_include_setjmp_png=yes, ac_cv_include_setjmp_png=no) -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include -+ #include ]], [[jmp_buf bla;]])],[ac_cv_include_setjmp_png=yes],[ac_cv_include_setjmp_png=no]) - ) - - if test "$ac_cv_include_setjmp_png" != yes; then -@@ -338,7 +342,7 @@ - AC_CACHE_CHECK([for svgalib], ac_cv_have_svgalib, - LIBS_X="$LIBS" - LIBS="$LIBS -lvga" -- AC_TRY_LINK([#include ], [vga_setmode(0)], ac_cv_have_svgalib=yes, ac_cv_have_svgalib=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[vga_setmode(0)]])],[ac_cv_have_svgalib=yes],[ac_cv_have_svgalib=no]) - LIBS="$LIBS_X" - ) - -@@ -351,9 +355,9 @@ - - dnl braine, tohle jsem predelal - dnl AC_CACHE_CHECK([for framebuffer], ac_cv_have_fb, --dnl AC_TRY_RUN([#include -+dnl AC_RUN_IFELSE([AC_LANG_SOURCE([[#include - dnl #include --dnl main(){return open("/dev/fb",O_RDWR)==-1;}], ac_cv_have_fb=yes, ac_cv_have_fb=no, ac_cv_have_fb=no) -+dnl main(){return open("/dev/fb",O_RDWR)==-1;}]])],[ac_cv_have_fb=yes],[ac_cv_have_fb=no],[ac_cv_have_fb=no]) - dnl ) - - if test "$disable_fb" != yes ; then -@@ -406,14 +410,12 @@ - - if test "$disable_pmshell" != yes ; then - AC_CACHE_CHECK([for pmshell], ac_cv_have_pmshell, -- AC_TRY_LINK([#define INCL_WIN -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define INCL_WIN - #define INCL_GPI - #include -- #include ], -- [_fmutex mutex; -+ #include ]], [[_fmutex mutex; - WinDrawText(NULLHANDLE, -1, NULL, NULL, 0, 0, 0), -- GpiSetPel(NULLHANDLE, NULL)], -- ac_cv_have_pmshell=yes, ac_cv_have_pmshell=no) -+ GpiSetPel(NULLHANDLE, NULL)]])],[ac_cv_have_pmshell=yes],[ac_cv_have_pmshell=no]) - ) - - if test "$ac_cv_have_pmshell" = yes; then -@@ -463,7 +465,8 @@ - test "$ac_cv_have_emx" = yes && LDFLAGS="$LDFLAGS -Zexe" - test "$ac_cv_have_emx" = yes && LDFLAGS=`echo "$LDFLAGS" | sed "s/-Zbin-files//g"` - --AC_OUTPUT(Makefile) -+AC_CONFIG_FILES([Makefile]) -+AC_OUTPUT - - echo "---------------------------------------------------------" - echo "Configuration results:" -@@ -485,5 +488,5 @@ - #rm Makefile.tmp - - #if test -z "$AWK"; then --# AC_WARN([awk not found. You won't be able to rebuild code page table.]); -+# AC_MSG_WARN([awk not found. You won't be able to rebuild code page table.]); - #fi ---- links-2.1pre12/configure~configure -+++ links-2.1pre12/configure -@@ -1,52 +1,324 @@ - #! /bin/sh -- - # Guess values for system-dependent variables and create Makefiles. --# Generated automatically using autoconf version 2.13 --# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. -+# Generated by GNU Autoconf 2.57. - # -+# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 -+# Free Software Foundation, Inc. - # This configure script is free software; the Free Software Foundation - # gives unlimited permission to copy, distribute and modify it. -+## --------------------- ## -+## M4sh Initialization. ## -+## --------------------- ## - --# Defaults: --ac_help= -+# Be Bourne compatible -+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then -+ emulate sh -+ NULLCMD=: -+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which -+ # is contrary to our usage. Disable this feature. -+ alias -g '${1+"$@"}'='"$@"' -+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then -+ set -o posix -+fi -+ -+# Support unset when possible. -+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then -+ as_unset=unset -+else -+ as_unset=false -+fi -+ -+ -+# Work around bugs in pre-3.0 UWIN ksh. -+$as_unset ENV MAIL MAILPATH -+PS1='$ ' -+PS2='> ' -+PS4='+ ' -+ -+# NLS nuisances. -+for as_var in \ -+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ -+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ -+ LC_TELEPHONE LC_TIME -+do -+ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then -+ eval $as_var=C; export $as_var -+ else -+ $as_unset $as_var -+ fi -+done -+ -+# Required to use basename. -+if expr a : '\(a\)' >/dev/null 2>&1; then -+ as_expr=expr -+else -+ as_expr=false -+fi -+ -+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then -+ as_basename=basename -+else -+ as_basename=false -+fi -+ -+ -+# Name of the executable. -+as_me=`$as_basename "$0" || -+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ -+ X"$0" : 'X\(//\)$' \| \ -+ X"$0" : 'X\(/\)$' \| \ -+ . : '\(.\)' 2>/dev/null || -+echo X/"$0" | -+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } -+ /^X\/\(\/\/\)$/{ s//\1/; q; } -+ /^X\/\(\/\).*/{ s//\1/; q; } -+ s/.*/./; q'` -+ -+ -+# PATH needs CR, and LINENO needs CR and PATH. -+# Avoid depending upon Character Ranges. -+as_cr_letters='abcdefghijklmnopqrstuvwxyz' -+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -+as_cr_Letters=$as_cr_letters$as_cr_LETTERS -+as_cr_digits='0123456789' -+as_cr_alnum=$as_cr_Letters$as_cr_digits -+ -+# The user is always right. -+if test "${PATH_SEPARATOR+set}" != set; then -+ echo "#! /bin/sh" >conf$$.sh -+ echo "exit 0" >>conf$$.sh -+ chmod +x conf$$.sh -+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then -+ PATH_SEPARATOR=';' -+ else -+ PATH_SEPARATOR=: -+ fi -+ rm -f conf$$.sh -+fi -+ -+ -+ as_lineno_1=$LINENO -+ as_lineno_2=$LINENO -+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` -+ test "x$as_lineno_1" != "x$as_lineno_2" && -+ test "x$as_lineno_3" = "x$as_lineno_2" || { -+ # Find who we are. Look in the path if we contain no path at all -+ # relative or not. -+ case $0 in -+ *[\\/]* ) as_myself=$0 ;; -+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -+done -+ -+ ;; -+ esac -+ # We did not find ourselves, most probably we were run as `sh COMMAND' -+ # in which case we are not to be found in the path. -+ if test "x$as_myself" = x; then -+ as_myself=$0 -+ fi -+ if test ! -f "$as_myself"; then -+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 -+ { (exit 1); exit 1; }; } -+ fi -+ case $CONFIG_SHELL in -+ '') -+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for as_base in sh bash ksh sh5; do -+ case $as_dir in -+ /*) -+ if ("$as_dir/$as_base" -c ' -+ as_lineno_1=$LINENO -+ as_lineno_2=$LINENO -+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` -+ test "x$as_lineno_1" != "x$as_lineno_2" && -+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then -+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } -+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } -+ CONFIG_SHELL=$as_dir/$as_base -+ export CONFIG_SHELL -+ exec "$CONFIG_SHELL" "$0" ${1+"$@"} -+ fi;; -+ esac -+ done -+done -+;; -+ esac -+ -+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO -+ # uniformly replaced by the line number. The first 'sed' inserts a -+ # line-number line before each line; the second 'sed' does the real -+ # work. The second script uses 'N' to pair each line-number line -+ # with the numbered line, and appends trailing '-' during -+ # substitution so that $LINENO is not a special case at line end. -+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the -+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) -+ sed '=' <$as_myself | -+ sed ' -+ N -+ s,$,-, -+ : loop -+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, -+ t loop -+ s,-$,, -+ s,^['$as_cr_digits']*\n,, -+ ' >$as_me.lineno && -+ chmod +x $as_me.lineno || -+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 -+ { (exit 1); exit 1; }; } -+ -+ # Don't try to exec as it changes $[0], causing all sort of problems -+ # (the dirname of $[0] is not the place where we might find the -+ # original and so on. Autoconf is especially sensible to this). -+ . ./$as_me.lineno -+ # Exit status is that of the last command. -+ exit -+} -+ -+ -+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in -+ *c*,-n*) ECHO_N= ECHO_C=' -+' ECHO_T=' ' ;; -+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; -+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -+esac -+ -+if expr a : '\(a\)' >/dev/null 2>&1; then -+ as_expr=expr -+else -+ as_expr=false -+fi -+ -+rm -f conf$$ conf$$.exe conf$$.file -+echo >conf$$.file -+if ln -s conf$$.file conf$$ 2>/dev/null; then -+ # We could just check for DJGPP; but this test a) works b) is more generic -+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). -+ if test -f conf$$.exe; then -+ # Don't use ln at all; we don't have any links -+ as_ln_s='cp -p' -+ else -+ as_ln_s='ln -s' -+ fi -+elif ln conf$$.file conf$$ 2>/dev/null; then -+ as_ln_s=ln -+else -+ as_ln_s='cp -p' -+fi -+rm -f conf$$ conf$$.exe conf$$.file -+ -+if mkdir -p . 2>/dev/null; then -+ as_mkdir_p=: -+else -+ as_mkdir_p=false -+fi -+ -+as_executable_p="test -f" -+ -+# Sed expression to map a string onto a valid CPP name. -+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" -+ -+# Sed expression to map a string onto a valid variable name. -+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" -+ -+ -+# IFS -+# We need space, tab and new line, in precisely that order. -+as_nl=' -+' -+IFS=" $as_nl" -+ -+# CDPATH. -+$as_unset CDPATH -+ -+ -+# Name of the host. -+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -+# so uname gets run too. -+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` -+ -+exec 6>&1 -+ -+# -+# Initializations. -+# - ac_default_prefix=/usr/local --# Any additions from configure.in: --ac_help="$ac_help -- --enable-javascript use javascript interpreter" --ac_help="$ac_help -- --with-libfl use libfl" --ac_help="$ac_help -- --enable-graphics use graphics" --ac_help="$ac_help -- --with-ssl(=directory) enable SSL support" --ac_help="$ac_help -- --without-libjpeg compile without JPEG support" --ac_help="$ac_help -- --without-libtiff compile without TIFF support" --ac_help="$ac_help -- --without-svgalib compile without svgalib graphics driver" --ac_help="$ac_help -- --without-x compile without X Window System graphics driver" --ac_help="$ac_help -- --without-fb compile without Linux Framebuffer graphics driver" --ac_help="$ac_help -- --without-directfb compile without DirectFB graphics driver" --ac_help="$ac_help -- --without-pmshell compile without PMShell graphics driver" --ac_help="$ac_help -- --without-atheos compile without Atheos graphics driver" --ac_help="$ac_help -- --with-x use the X Window System" -+ac_config_libobj_dir=. -+cross_compiling=no -+subdirs= -+MFLAGS= -+MAKEFLAGS= -+SHELL=${CONFIG_SHELL-/bin/sh} -+ -+# Maximum number of lines to put in a shell here document. -+# This variable seems obsolete. It should probably be removed, and -+# only ac_max_sed_lines should be used. -+: ${ac_max_here_lines=38} -+ -+# Identity of this package. -+PACKAGE_NAME= -+PACKAGE_TARNAME= -+PACKAGE_VERSION= -+PACKAGE_STRING= -+PACKAGE_BUGREPORT= -+ -+ac_unique_file="main.c" -+# Factoring default headers for most tests. -+ac_includes_default="\ -+#include -+#if HAVE_SYS_TYPES_H -+# include -+#endif -+#if HAVE_SYS_STAT_H -+# include -+#endif -+#if STDC_HEADERS -+# include -+# include -+#else -+# if HAVE_STDLIB_H -+# include -+# endif -+#endif -+#if HAVE_STRING_H -+# if !STDC_HEADERS && HAVE_MEMORY_H -+# include -+# endif -+# include -+#endif -+#if HAVE_STRINGS_H -+# include -+#endif -+#if HAVE_INTTYPES_H -+# include -+#else -+# if HAVE_STDINT_H -+# include -+# endif -+#endif -+#if HAVE_UNISTD_H -+# include -+#endif" -+ -+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CPP EGREP LIBOBJS DIRECTFB_CONFIG ATHEOS_GR_TRUE ATHEOS_GR_FALSE LTLIBOBJS' -+ac_subst_files='' - - # Initialize some variables set by options. -+ac_init_help= -+ac_init_version=false - # The variables have the same names as the options, with - # dashes changed to underlines. --build=NONE --cache_file=./config.cache -+cache_file=/dev/null - exec_prefix=NONE --host=NONE - no_create= --nonopt=NONE - no_recursion= - prefix=NONE - program_prefix=NONE -@@ -55,10 +327,15 @@ - silent= - site= - srcdir= --target=NONE - verbose= - x_includes=NONE - x_libraries=NONE -+ -+# Installation directory options. -+# These are left unexpanded so users can "make install exec_prefix=/foo" -+# and all the variables that are supposed to be based on exec_prefix -+# by default will actually change. -+# Use braces instead of parens because sh, perl, etc. also accept them. - bindir='${exec_prefix}/bin' - sbindir='${exec_prefix}/sbin' - libexecdir='${exec_prefix}/libexec' -@@ -72,17 +349,9 @@ - infodir='${prefix}/info' - mandir='${prefix}/man' - --# Initialize some other variables. --subdirs= --MFLAGS= MAKEFLAGS= --SHELL=${CONFIG_SHELL-/bin/sh} --# Maximum number of lines to put in a shell here document. --ac_max_here_lines=12 -- - ac_prev= - for ac_option - do -- - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" -@@ -90,59 +359,59 @@ - continue - fi - -- case "$ac_option" in -- -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; -- *) ac_optarg= ;; -- esac -+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` - - # Accept the important Cygnus configure options, so we can diagnose typos. - -- case "$ac_option" in -+ case $ac_option in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) -- bindir="$ac_optarg" ;; -+ bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) -- ac_prev=build ;; -+ ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) -- build="$ac_optarg" ;; -+ build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) -- cache_file="$ac_optarg" ;; -+ cache_file=$ac_optarg ;; -+ -+ --config-cache | -C) -+ cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) -- datadir="$ac_optarg" ;; -+ datadir=$ac_optarg ;; - - -disable-* | --disable-*) -- ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` -+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. -- if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then -- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } -- fi -- ac_feature=`echo $ac_feature| sed 's/-/_/g'` -- eval "enable_${ac_feature}=no" ;; -+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && -+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2 -+ { (exit 1); exit 1; }; } -+ ac_feature=`echo $ac_feature | sed 's/-/_/g'` -+ eval "enable_$ac_feature=no" ;; - - -enable-* | --enable-*) -- ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` -+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. -- if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then -- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } -- fi -- ac_feature=`echo $ac_feature| sed 's/-/_/g'` -- case "$ac_option" in -- *=*) ;; -+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && -+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2 -+ { (exit 1); exit 1; }; } -+ ac_feature=`echo $ac_feature | sed 's/-/_/g'` -+ case $ac_option in -+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac -- eval "enable_${ac_feature}='$ac_optarg'" ;; -+ eval "enable_$ac_feature='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ -@@ -151,95 +420,47 @@ - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) -- exec_prefix="$ac_optarg" ;; -+ exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - -- -help | --help | --hel | --he) -- # Omit some internal or obsolete options to make the list less imposing. -- # This message is too long to be a string in the A/UX 3.1 sh. -- cat << EOF --Usage: configure [options] [host] --Options: [defaults in brackets after descriptions] --Configuration: -- --cache-file=FILE cache test results in FILE -- --help print this message -- --no-create do not create output files -- --quiet, --silent do not print \`checking...' messages -- --version print the version of autoconf that created configure --Directory and file names: -- --prefix=PREFIX install architecture-independent files in PREFIX -- [$ac_default_prefix] -- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX -- [same as prefix] -- --bindir=DIR user executables in DIR [EPREFIX/bin] -- --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] -- --libexecdir=DIR program executables in DIR [EPREFIX/libexec] -- --datadir=DIR read-only architecture-independent data in DIR -- [PREFIX/share] -- --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] -- --sharedstatedir=DIR modifiable architecture-independent data in DIR -- [PREFIX/com] -- --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] -- --libdir=DIR object code libraries in DIR [EPREFIX/lib] -- --includedir=DIR C header files in DIR [PREFIX/include] -- --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] -- --infodir=DIR info documentation in DIR [PREFIX/info] -- --mandir=DIR man documentation in DIR [PREFIX/man] -- --srcdir=DIR find the sources in DIR [configure dir or ..] -- --program-prefix=PREFIX prepend PREFIX to installed program names -- --program-suffix=SUFFIX append SUFFIX to installed program names -- --program-transform-name=PROGRAM -- run sed PROGRAM on installed program names --EOF -- cat << EOF --Host type: -- --build=BUILD configure for building on BUILD [BUILD=HOST] -- --host=HOST configure for HOST [guessed] -- --target=TARGET configure for TARGET [TARGET=HOST] --Features and packages: -- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) -- --enable-FEATURE[=ARG] include FEATURE [ARG=yes] -- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] -- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) -- --x-includes=DIR X include files are in DIR -- --x-libraries=DIR X library files are in DIR --EOF -- if test -n "$ac_help"; then -- echo "--enable and --with options recognized:$ac_help" -- fi -- exit 0 ;; -+ -help | --help | --hel | --he | -h) -+ ac_init_help=long ;; -+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) -+ ac_init_help=recursive ;; -+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) -+ ac_init_help=short ;; - - -host | --host | --hos | --ho) -- ac_prev=host ;; -+ ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) -- host="$ac_optarg" ;; -+ host_alias=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) -- includedir="$ac_optarg" ;; -+ includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) -- infodir="$ac_optarg" ;; -+ infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) -- libdir="$ac_optarg" ;; -+ libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) -- libexecdir="$ac_optarg" ;; -+ libexecdir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ -@@ -248,19 +469,19 @@ - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) -- localstatedir="$ac_optarg" ;; -+ localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) -- mandir="$ac_optarg" ;; -+ mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ -- | --no-cr | --no-c) -+ | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ -@@ -274,26 +495,26 @@ - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) -- oldincludedir="$ac_optarg" ;; -+ oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) -- prefix="$ac_optarg" ;; -+ prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) -- program_prefix="$ac_optarg" ;; -+ program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) -- program_suffix="$ac_optarg" ;; -+ program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ -@@ -310,7 +531,7 @@ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) -- program_transform_name="$ac_optarg" ;; -+ program_transform_name=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) -@@ -320,7 +541,7 @@ - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) -- sbindir="$ac_optarg" ;; -+ sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ -@@ -331,58 +552,57 @@ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) -- sharedstatedir="$ac_optarg" ;; -+ sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) -- site="$ac_optarg" ;; -+ site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) -- srcdir="$ac_optarg" ;; -+ srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) -- sysconfdir="$ac_optarg" ;; -+ sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) -- ac_prev=target ;; -+ ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) -- target="$ac_optarg" ;; -+ target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - -- -version | --version | --versio | --versi | --vers) -- echo "configure generated by autoconf version 2.13" -- exit 0 ;; -+ -version | --version | --versio | --versi | --vers | -V) -+ ac_init_version=: ;; - - -with-* | --with-*) -- ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` -+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. -- if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then -- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } -- fi -+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && -+ { echo "$as_me: error: invalid package name: $ac_package" >&2 -+ { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` -- case "$ac_option" in -- *=*) ;; -+ case $ac_option in -+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac -- eval "with_${ac_package}='$ac_optarg'" ;; -+ eval "with_$ac_package='$ac_optarg'" ;; - - -without-* | --without-*) -- ac_package=`echo $ac_option|sed -e 's/-*without-//'` -+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. -- if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then -- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } -- fi -- ac_package=`echo $ac_package| sed 's/-/_/g'` -- eval "with_${ac_package}=no" ;; -+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && -+ { echo "$as_me: error: invalid package name: $ac_package" >&2 -+ { (exit 1); exit 1; }; } -+ ac_package=`echo $ac_package | sed 's/-/_/g'` -+ eval "with_$ac_package=no" ;; - - --x) - # Obsolete; use --with-x. -@@ -393,99 +613,110 @@ - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) -- x_includes="$ac_optarg" ;; -+ x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) -- x_libraries="$ac_optarg" ;; -+ x_libraries=$ac_optarg ;; - -- -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } -+ -*) { echo "$as_me: error: unrecognized option: $ac_option -+Try \`$0 --help' for more information." >&2 -+ { (exit 1); exit 1; }; } - ;; - -+ *=*) -+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` -+ # Reject names that are not valid shell variable names. -+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && -+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 -+ { (exit 1); exit 1; }; } -+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` -+ eval "$ac_envvar='$ac_optarg'" -+ export $ac_envvar ;; -+ - *) -- if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then -- echo "configure: warning: $ac_option: invalid host type" 1>&2 -- fi -- if test "x$nonopt" != xNONE; then -- { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } -- fi -- nonopt="$ac_option" -+ # FIXME: should be removed in autoconf 3.0. -+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2 -+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && -+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2 -+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac - done - - if test -n "$ac_prev"; then -- { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } --fi -- --trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 -- --# File descriptor usage: --# 0 standard input --# 1 file creation --# 2 errors and warnings --# 3 some systems may open it to /dev/tty --# 4 used on the Kubota Titan --# 6 checking for... messages and results --# 5 compiler messages saved in config.log --if test "$silent" = yes; then -- exec 6>/dev/null --else -- exec 6>&1 -+ ac_option=--`echo $ac_prev | sed 's/_/-/g'` -+ { echo "$as_me: error: missing argument to $ac_option" >&2 -+ { (exit 1); exit 1; }; } - fi --exec 5>./config.log - --echo "\ --This file contains any messages produced by compilers while --running configure, to aid debugging if configure makes a mistake. --" 1>&5 -+# Be sure to have absolute paths. -+for ac_var in exec_prefix prefix -+do -+ eval ac_val=$`echo $ac_var` -+ case $ac_val in -+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;; -+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 -+ { (exit 1); exit 1; }; };; -+ esac -+done - --# Strip out --no-create and --no-recursion so they do not pile up. --# Also quote any args containing shell metacharacters. --ac_configure_args= --for ac_arg -+# Be sure to have absolute paths. -+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ -+ localstatedir libdir includedir oldincludedir infodir mandir - do -- case "$ac_arg" in -- -no-create | --no-create | --no-creat | --no-crea | --no-cre \ -- | --no-cr | --no-c) ;; -- -no-recursion | --no-recursion | --no-recursio | --no-recursi \ -- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; -- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) -- ac_configure_args="$ac_configure_args '$ac_arg'" ;; -- *) ac_configure_args="$ac_configure_args $ac_arg" ;; -+ eval ac_val=$`echo $ac_var` -+ case $ac_val in -+ [\\/$]* | ?:[\\/]* ) ;; -+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 -+ { (exit 1); exit 1; }; };; - esac - done - --# NLS nuisances. --# Only set these to C if already set. These must not be set unconditionally --# because not all systems understand e.g. LANG=C (notably SCO). --# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! --# Non-C LC_CTYPE values break the ctype check. --if test "${LANG+set}" = set; then LANG=C; export LANG; fi --if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi --if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi --if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi -+# There might be people who depend on the old broken behavior: `$host' -+# used to hold the argument of --host etc. -+# FIXME: To remove some day. -+build=$build_alias -+host=$host_alias -+target=$target_alias - --# confdefs.h avoids OS command line length limits that DEFS can exceed. --rm -rf conftest* confdefs.h --# AIX cpp loses on an empty file, so make sure it contains at least a newline. --echo > confdefs.h -+# FIXME: To remove some day. -+if test "x$host_alias" != x; then -+ if test "x$build_alias" = x; then -+ cross_compiling=maybe -+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. -+ If a cross compiler is detected then cross compile mode will be used." >&2 -+ elif test "x$build_alias" != "x$host_alias"; then -+ cross_compiling=yes -+ fi -+fi -+ -+ac_tool_prefix= -+test -n "$host_alias" && ac_tool_prefix=$host_alias- -+ -+test "$silent" = yes && exec 6>/dev/null - --# A filename unique to this package, relative to the directory that --# configure is in, which we can look for to find out if srcdir is correct. --ac_unique_file=main.c - - # Find the source files, if location was not specified. - if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. -- ac_prog=$0 -- ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` -- test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. -+ ac_confdir=`(dirname "$0") 2>/dev/null || -+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ -+ X"$0" : 'X\(//\)[^/]' \| \ -+ X"$0" : 'X\(//\)$' \| \ -+ X"$0" : 'X\(/\)' \| \ -+ . : '\(.\)' 2>/dev/null || -+echo X"$0" | -+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } -+ /^X\(\/\/\)[^/].*/{ s//\1/; q; } -+ /^X\(\/\/\)$/{ s//\1/; q; } -+ /^X\(\/\).*/{ s//\1/; q; } -+ s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. -@@ -495,13 +726,464 @@ - fi - if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then -- { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } -+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 -+ { (exit 1); exit 1; }; } - else -- { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } -+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 -+ { (exit 1); exit 1; }; } - fi - fi --srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` -+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || -+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 -+ { (exit 1); exit 1; }; } -+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` -+ac_env_build_alias_set=${build_alias+set} -+ac_env_build_alias_value=$build_alias -+ac_cv_env_build_alias_set=${build_alias+set} -+ac_cv_env_build_alias_value=$build_alias -+ac_env_host_alias_set=${host_alias+set} -+ac_env_host_alias_value=$host_alias -+ac_cv_env_host_alias_set=${host_alias+set} -+ac_cv_env_host_alias_value=$host_alias -+ac_env_target_alias_set=${target_alias+set} -+ac_env_target_alias_value=$target_alias -+ac_cv_env_target_alias_set=${target_alias+set} -+ac_cv_env_target_alias_value=$target_alias -+ac_env_CC_set=${CC+set} -+ac_env_CC_value=$CC -+ac_cv_env_CC_set=${CC+set} -+ac_cv_env_CC_value=$CC -+ac_env_CFLAGS_set=${CFLAGS+set} -+ac_env_CFLAGS_value=$CFLAGS -+ac_cv_env_CFLAGS_set=${CFLAGS+set} -+ac_cv_env_CFLAGS_value=$CFLAGS -+ac_env_LDFLAGS_set=${LDFLAGS+set} -+ac_env_LDFLAGS_value=$LDFLAGS -+ac_cv_env_LDFLAGS_set=${LDFLAGS+set} -+ac_cv_env_LDFLAGS_value=$LDFLAGS -+ac_env_CPPFLAGS_set=${CPPFLAGS+set} -+ac_env_CPPFLAGS_value=$CPPFLAGS -+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} -+ac_cv_env_CPPFLAGS_value=$CPPFLAGS -+ac_env_CXX_set=${CXX+set} -+ac_env_CXX_value=$CXX -+ac_cv_env_CXX_set=${CXX+set} -+ac_cv_env_CXX_value=$CXX -+ac_env_CXXFLAGS_set=${CXXFLAGS+set} -+ac_env_CXXFLAGS_value=$CXXFLAGS -+ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} -+ac_cv_env_CXXFLAGS_value=$CXXFLAGS -+ac_env_CPP_set=${CPP+set} -+ac_env_CPP_value=$CPP -+ac_cv_env_CPP_set=${CPP+set} -+ac_cv_env_CPP_value=$CPP -+ -+# -+# Report the --help message. -+# -+if test "$ac_init_help" = "long"; then -+ # Omit some internal or obsolete options to make the list less imposing. -+ # This message is too long to be a string in the A/UX 3.1 sh. -+ cat <<_ACEOF -+\`configure' configures this package to adapt to many kinds of systems. -+ -+Usage: $0 [OPTION]... [VAR=VALUE]... -+ -+To assign environment variables (e.g., CC, CFLAGS...), specify them as -+VAR=VALUE. See below for descriptions of some of the useful variables. -+ -+Defaults for the options are specified in brackets. -+ -+Configuration: -+ -h, --help display this help and exit -+ --help=short display options specific to this package -+ --help=recursive display the short help of all the included packages -+ -V, --version display version information and exit -+ -q, --quiet, --silent do not print \`checking...' messages -+ --cache-file=FILE cache test results in FILE [disabled] -+ -C, --config-cache alias for \`--cache-file=config.cache' -+ -n, --no-create do not create output files -+ --srcdir=DIR find the sources in DIR [configure dir or \`..'] -+ -+_ACEOF -+ -+ cat <<_ACEOF -+Installation directories: -+ --prefix=PREFIX install architecture-independent files in PREFIX -+ [$ac_default_prefix] -+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX -+ [PREFIX] -+ -+By default, \`make install' will install all the files in -+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -+an installation prefix other than \`$ac_default_prefix' using \`--prefix', -+for instance \`--prefix=\$HOME'. -+ -+For better control, use the options below. -+ -+Fine tuning of the installation directories: -+ --bindir=DIR user executables [EPREFIX/bin] -+ --sbindir=DIR system admin executables [EPREFIX/sbin] -+ --libexecdir=DIR program executables [EPREFIX/libexec] -+ --datadir=DIR read-only architecture-independent data [PREFIX/share] -+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc] -+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] -+ --localstatedir=DIR modifiable single-machine data [PREFIX/var] -+ --libdir=DIR object code libraries [EPREFIX/lib] -+ --includedir=DIR C header files [PREFIX/include] -+ --oldincludedir=DIR C header files for non-gcc [/usr/include] -+ --infodir=DIR info documentation [PREFIX/info] -+ --mandir=DIR man documentation [PREFIX/man] -+_ACEOF -+ -+ cat <<\_ACEOF -+ -+Program names: -+ --program-prefix=PREFIX prepend PREFIX to installed program names -+ --program-suffix=SUFFIX append SUFFIX to installed program names -+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names -+ -+X features: -+ --x-includes=DIR X include files are in DIR -+ --x-libraries=DIR X library files are in DIR -+_ACEOF -+fi -+ -+if test -n "$ac_init_help"; then -+ -+ cat <<\_ACEOF -+ -+Optional Features: -+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) -+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes] -+ --disable-dependency-tracking Speeds up one-time builds -+ --enable-dependency-tracking Do not reject slow dependency extractors -+ --enable-javascript use javascript interpreter -+ --enable-graphics use graphics -+ -+Optional Packages: -+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] -+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) -+ --with-libfl use libfl -+ --with-ssl(=directory) enable SSL support -+ --without-libjpeg compile without JPEG support -+ --without-libtiff compile without TIFF support -+ --without-svgalib compile without svgalib graphics driver -+ --without-x compile without X Window System graphics driver -+ --without-fb compile without Linux Framebuffer graphics driver -+ --without-directfb compile without DirectFB graphics driver -+ --without-pmshell compile without PMShell graphics driver -+ --without-atheos compile without Atheos graphics driver -+ --with-x use the X Window System -+ -+Some influential environment variables: -+ CC C compiler command -+ CFLAGS C compiler flags -+ LDFLAGS linker flags, e.g. -L if you have libraries in a -+ nonstandard directory -+ CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have -+ headers in a nonstandard directory -+ CXX C++ compiler command -+ CXXFLAGS C++ compiler flags -+ CPP C preprocessor -+ -+Use these variables to override the choices made by `configure' or to help -+it to find libraries and programs with nonstandard names/locations. -+ -+_ACEOF -+fi -+ -+if test "$ac_init_help" = "recursive"; then -+ # If there are subdirs, report their specific --help. -+ ac_popdir=`pwd` -+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue -+ test -d $ac_dir || continue -+ ac_builddir=. -+ -+if test "$ac_dir" != .; then -+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` -+ # A "../" for each directory in $ac_dir_suffix. -+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -+else -+ ac_dir_suffix= ac_top_builddir= -+fi -+ -+case $srcdir in -+ .) # No --srcdir option. We are building in place. -+ ac_srcdir=. -+ if test -z "$ac_top_builddir"; then -+ ac_top_srcdir=. -+ else -+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` -+ fi ;; -+ [\\/]* | ?:[\\/]* ) # Absolute path. -+ ac_srcdir=$srcdir$ac_dir_suffix; -+ ac_top_srcdir=$srcdir ;; -+ *) # Relative path. -+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix -+ ac_top_srcdir=$ac_top_builddir$srcdir ;; -+esac -+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -+# absolute. -+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` -+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` - -+ cd $ac_dir -+ # Check for guested configure; otherwise get Cygnus style configure. -+ if test -f $ac_srcdir/configure.gnu; then -+ echo -+ $SHELL $ac_srcdir/configure.gnu --help=recursive -+ elif test -f $ac_srcdir/configure; then -+ echo -+ $SHELL $ac_srcdir/configure --help=recursive -+ elif test -f $ac_srcdir/configure.ac || -+ test -f $ac_srcdir/configure.in; then -+ echo -+ $ac_configure --help -+ else -+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 -+ fi -+ cd $ac_popdir -+ done -+fi -+ -+test -n "$ac_init_help" && exit 0 -+if $ac_init_version; then -+ cat <<\_ACEOF -+ -+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 -+Free Software Foundation, Inc. -+This configure script is free software; the Free Software Foundation -+gives unlimited permission to copy, distribute and modify it. -+_ACEOF -+ exit 0 -+fi -+exec 5>config.log -+cat >&5 <<_ACEOF -+This file contains any messages produced by compilers while -+running configure, to aid debugging if configure makes a mistake. -+ -+It was created by $as_me, which was -+generated by GNU Autoconf 2.57. Invocation command line was -+ -+ $ $0 $@ -+ -+_ACEOF -+{ -+cat <<_ASUNAME -+## --------- ## -+## Platform. ## -+## --------- ## -+ -+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -+uname -m = `(uname -m) 2>/dev/null || echo unknown` -+uname -r = `(uname -r) 2>/dev/null || echo unknown` -+uname -s = `(uname -s) 2>/dev/null || echo unknown` -+uname -v = `(uname -v) 2>/dev/null || echo unknown` -+ -+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` -+ -+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -+hostinfo = `(hostinfo) 2>/dev/null || echo unknown` -+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` -+ -+_ASUNAME -+ -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ echo "PATH: $as_dir" -+done -+ -+} >&5 -+ -+cat >&5 <<_ACEOF -+ -+ -+## ----------- ## -+## Core tests. ## -+## ----------- ## -+ -+_ACEOF -+ -+ -+# Keep a trace of the command line. -+# Strip out --no-create and --no-recursion so they do not pile up. -+# Strip out --silent because we don't want to record it for future runs. -+# Also quote any args containing shell meta-characters. -+# Make two passes to allow for proper duplicate-argument suppression. -+ac_configure_args= -+ac_configure_args0= -+ac_configure_args1= -+ac_sep= -+ac_must_keep_next=false -+for ac_pass in 1 2 -+do -+ for ac_arg -+ do -+ case $ac_arg in -+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ -+ | -silent | --silent | --silen | --sile | --sil) -+ continue ;; -+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) -+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; -+ esac -+ case $ac_pass in -+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; -+ 2) -+ ac_configure_args1="$ac_configure_args1 '$ac_arg'" -+ if test $ac_must_keep_next = true; then -+ ac_must_keep_next=false # Got value, back to normal. -+ else -+ case $ac_arg in -+ *=* | --config-cache | -C | -disable-* | --disable-* \ -+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ -+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ -+ | -with-* | --with-* | -without-* | --without-* | --x) -+ case "$ac_configure_args0 " in -+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; -+ esac -+ ;; -+ -* ) ac_must_keep_next=true ;; -+ esac -+ fi -+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" -+ # Get rid of the leading space. -+ ac_sep=" " -+ ;; -+ esac -+ done -+done -+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } -+ -+# When interrupted or exit'd, cleanup temporary files, and complete -+# config.log. We remove comments because anyway the quotes in there -+# would cause problems or look ugly. -+# WARNING: Be sure not to use single quotes in there, as some shells, -+# such as our DU 5.0 friend, will then `close' the trap. -+trap 'exit_status=$? -+ # Save into config.log some information that might help in debugging. -+ { -+ echo -+ -+ cat <<\_ASBOX -+## ---------------- ## -+## Cache variables. ## -+## ---------------- ## -+_ASBOX -+ echo -+ # The following way of writing the cache mishandles newlines in values, -+{ -+ (set) 2>&1 | -+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in -+ *ac_space=\ *) -+ sed -n \ -+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; -+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" -+ ;; -+ *) -+ sed -n \ -+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" -+ ;; -+ esac; -+} -+ echo -+ -+ cat <<\_ASBOX -+## ----------------- ## -+## Output variables. ## -+## ----------------- ## -+_ASBOX -+ echo -+ for ac_var in $ac_subst_vars -+ do -+ eval ac_val=$`echo $ac_var` -+ echo "$ac_var='"'"'$ac_val'"'"'" -+ done | sort -+ echo -+ -+ if test -n "$ac_subst_files"; then -+ cat <<\_ASBOX -+## ------------- ## -+## Output files. ## -+## ------------- ## -+_ASBOX -+ echo -+ for ac_var in $ac_subst_files -+ do -+ eval ac_val=$`echo $ac_var` -+ echo "$ac_var='"'"'$ac_val'"'"'" -+ done | sort -+ echo -+ fi -+ -+ if test -s confdefs.h; then -+ cat <<\_ASBOX -+## ----------- ## -+## confdefs.h. ## -+## ----------- ## -+_ASBOX -+ echo -+ sed "/^$/d" confdefs.h | sort -+ echo -+ fi -+ test "$ac_signal" != 0 && -+ echo "$as_me: caught signal $ac_signal" -+ echo "$as_me: exit $exit_status" -+ } >&5 -+ rm -f core core.* *.core && -+ rm -rf conftest* confdefs* conf$$* $ac_clean_files && -+ exit $exit_status -+ ' 0 -+for ac_signal in 1 2 13 15; do -+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -+done -+ac_signal=0 -+ -+# confdefs.h avoids OS command line length limits that DEFS can exceed. -+rm -rf conftest* confdefs.h -+# AIX cpp loses on an empty file, so make sure it contains at least a newline. -+echo >confdefs.h -+ -+# Predefined preprocessor variables. -+ -+cat >>confdefs.h <<_ACEOF -+#define PACKAGE_NAME "$PACKAGE_NAME" -+_ACEOF -+ -+ -+cat >>confdefs.h <<_ACEOF -+#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -+_ACEOF -+ -+ -+cat >>confdefs.h <<_ACEOF -+#define PACKAGE_VERSION "$PACKAGE_VERSION" -+_ACEOF -+ -+ -+cat >>confdefs.h <<_ACEOF -+#define PACKAGE_STRING "$PACKAGE_STRING" -+_ACEOF -+ -+ -+cat >>confdefs.h <<_ACEOF -+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -+_ACEOF -+ -+ -+# Let the site file select an alternate cache file if it wants to. - # Prefer explicitly selected file to automatically selected ones. - if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then -@@ -512,42 +1194,108 @@ - fi - for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then -- echo "loading site script $ac_site_file" -+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -+echo "$as_me: loading site script $ac_site_file" >&6;} -+ sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi - done - - if test -r "$cache_file"; then -- echo "loading cache $cache_file" -- . $cache_file -+ # Some versions of bash will fail to source /dev/null (special -+ # files actually), so we avoid doing that. -+ if test -f "$cache_file"; then -+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -+echo "$as_me: loading cache $cache_file" >&6;} -+ case $cache_file in -+ [\\/]* | ?:[\\/]* ) . $cache_file;; -+ *) . ./$cache_file;; -+ esac -+ fi - else -- echo "creating cache $cache_file" -- > $cache_file -+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -+echo "$as_me: creating cache $cache_file" >&6;} -+ >$cache_file -+fi -+ -+# Check that the precious variables saved in the cache have kept the same -+# value. -+ac_cache_corrupted=false -+for ac_var in `(set) 2>&1 | -+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do -+ eval ac_old_set=\$ac_cv_env_${ac_var}_set -+ eval ac_new_set=\$ac_env_${ac_var}_set -+ eval ac_old_val="\$ac_cv_env_${ac_var}_value" -+ eval ac_new_val="\$ac_env_${ac_var}_value" -+ case $ac_old_set,$ac_new_set in -+ set,) -+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} -+ ac_cache_corrupted=: ;; -+ ,set) -+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} -+ ac_cache_corrupted=: ;; -+ ,);; -+ *) -+ if test "x$ac_old_val" != "x$ac_new_val"; then -+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} -+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -+echo "$as_me: former value: $ac_old_val" >&2;} -+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -+echo "$as_me: current value: $ac_new_val" >&2;} -+ ac_cache_corrupted=: -+ fi;; -+ esac -+ # Pass precious variables to config.status. -+ if test "$ac_new_set" = set; then -+ case $ac_new_val in -+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) -+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; -+ *) ac_arg=$ac_var=$ac_new_val ;; -+ esac -+ case " $ac_configure_args " in -+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. -+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; -+ esac -+ fi -+done -+if $ac_cache_corrupted; then -+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -+echo "$as_me: error: changes in the environment can compromise the build" >&2;} -+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} -+ { (exit 1); exit 1; }; } - fi - - ac_ext=c --# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. - ac_cpp='$CPP $CPPFLAGS' --ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' --ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' --cross_compiling=$ac_cv_prog_cc_cross -+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -+ac_compiler_gnu=$ac_cv_c_compiler_gnu -+ -+ -+ -+ - --ac_exeext= --ac_objext=o --if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then -- # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. -- if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then -- ac_n= ac_c=' --' ac_t=' ' -- else -- ac_n=-n ac_c= ac_t= -- fi --else -- ac_n= ac_c='\c' ac_t= --fi - - - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+am__api_version="1.7" - ac_aux_dir= - for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do - if test -f $ac_dir/install-sh; then -@@ -558,14 +1306,20 @@ - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break -+ elif test -f $ac_dir/shtool; then -+ ac_aux_dir=$ac_dir -+ ac_install_sh="$ac_aux_dir/shtool install -c" -+ break - fi - done - if test -z "$ac_aux_dir"; then -- { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } -+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 -+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} -+ { (exit 1); exit 1; }; } - fi --ac_config_guess=$ac_aux_dir/config.guess --ac_config_sub=$ac_aux_dir/config.sub --ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. -+ac_config_guess="$SHELL $ac_aux_dir/config.guess" -+ac_config_sub="$SHELL $ac_aux_dir/config.sub" -+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. - - # Find a good install program. We prefer a C program (faster), - # so one script is as good as another. But avoid the broken or -@@ -574,231 +1328,371 @@ - # SunOS /usr/etc/install - # IRIX /sbin/install - # AIX /bin/install -+# AmigaOS /C/install, which installs bootblocks on floppy discs - # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag - # AFS /usr/afsws/bin/install, which mishandles nonexistent args - # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" - # ./install, which can be erroneously created by make from ./install.sh. --echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 --echo "configure:583: checking for a BSD compatible install" >&5 -+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 - if test -z "$INSTALL"; then --if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+if test "${ac_cv_path_install+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" -- for ac_dir in $PATH; do -- # Account for people who put trailing slashes in PATH elements. -- case "$ac_dir/" in -- /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; -- *) -- # OSF1 and SCO ODT 3.0 have their own names for install. -- # Don't use installbsd from OSF since it installs stuff as root -- # by default. -- for ac_prog in ginstall scoinst install; do -- if test -f $ac_dir/$ac_prog; then -- if test $ac_prog = install && -- grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then -- # AIX install. It has an incompatible calling convention. -- : -- else -- ac_cv_path_install="$ac_dir/$ac_prog -c" -- break 2 -- fi -- fi -+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ # Account for people who put trailing slashes in PATH elements. -+case $as_dir/ in -+ ./ | .// | /cC/* | \ -+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ -+ /usr/ucb/* ) ;; -+ *) -+ # OSF1 and SCO ODT 3.0 have their own names for install. -+ # Don't use installbsd from OSF since it installs stuff as root -+ # by default. -+ for ac_prog in ginstall scoinst install; do -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then -+ if test $ac_prog = install && -+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then -+ # AIX install. It has an incompatible calling convention. -+ : -+ elif test $ac_prog = install && -+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then -+ # program-specific install script used by HP pwplus--don't use. -+ : -+ else -+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" -+ break 3 -+ fi -+ fi - done -- ;; -- esac -- done -- IFS="$ac_save_IFS" -+ done -+ ;; -+esac -+done -+ - - fi - if test "${ac_cv_path_install+set}" = set; then -- INSTALL="$ac_cv_path_install" -+ INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. -- INSTALL="$ac_install_sh" -+ INSTALL=$ac_install_sh - fi - fi --echo "$ac_t""$INSTALL" 1>&6 -+echo "$as_me:$LINENO: result: $INSTALL" >&5 -+echo "${ECHO_T}$INSTALL" >&6 - - # Use test -z because SunOS4 sh mishandles braces in ${var-val}. - # It thinks the first close brace ends the variable substitution. - test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - --test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' -+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - - test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - --echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 --echo "configure:636: checking whether build environment is sane" >&5 -+echo "$as_me:$LINENO: checking whether build environment is sane" >&5 -+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 - # Just in case - sleep 1 --echo timestamp > conftestfile -+echo timestamp > conftest.file - # Do `set' in a subshell so we don't clobber the current shell's - # arguments. Must try -L first in case configure is actually a - # symlink; some systems play weird games with the mod time of symlinks - # (eg FreeBSD returns the mod time of the symlink's containing - # directory). - if ( -- set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` -+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. -- set X `ls -t $srcdir/configure conftestfile` -+ set X `ls -t $srcdir/configure conftest.file` - fi -- if test "$*" != "X $srcdir/configure conftestfile" \ -- && test "$*" != "X conftestfile $srcdir/configure"; then -+ rm -f conftest.file -+ if test "$*" != "X $srcdir/configure conftest.file" \ -+ && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". -- { echo "configure: error: ls -t appears to fail. Make sure there is not a broken --alias in your environment" 1>&2; exit 1; } -+ { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken -+alias in your environment" >&5 -+echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken -+alias in your environment" >&2;} -+ { (exit 1); exit 1; }; } - fi - -- test "$2" = conftestfile -+ test "$2" = conftest.file - ) - then - # Ok. - : - else -- { echo "configure: error: newly created file is older than distributed files! --Check your system clock" 1>&2; exit 1; } --fi --rm -f conftest* --echo "$ac_t""yes" 1>&6 --if test "$program_transform_name" = s,x,x,; then -- program_transform_name= --else -- # Double any \ or $. echo might interpret backslashes. -- cat <<\EOF_SED > conftestsed --s,\\,\\\\,g; s,\$,$$,g --EOF_SED -- program_transform_name="`echo $program_transform_name|sed -f conftestsed`" -- rm -f conftestsed -+ { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! -+Check your system clock" >&5 -+echo "$as_me: error: newly created file is older than distributed files! -+Check your system clock" >&2;} -+ { (exit 1); exit 1; }; } - fi -+echo "$as_me:$LINENO: result: yes" >&5 -+echo "${ECHO_T}yes" >&6 - test "$program_prefix" != NONE && -- program_transform_name="s,^,${program_prefix},; $program_transform_name" -+ program_transform_name="s,^,$program_prefix,;$program_transform_name" - # Use a double $ so make ignores it. - test "$program_suffix" != NONE && -- program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" -+ program_transform_name="s,\$,$program_suffix,;$program_transform_name" -+# Double any \ or $. echo might interpret backslashes. -+# By default was `s,x,x', remove it if useless. -+cat <<\_ACEOF >conftest.sed -+s/[\\$]/&&/g;s/;s,x,x,$// -+_ACEOF -+program_transform_name=`echo $program_transform_name | sed -f conftest.sed` -+rm conftest.sed - --# sed with no file args requires a program. --test "$program_transform_name" = "" && program_transform_name="s,x,x," - --echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 --echo "configure:693: checking whether ${MAKE-make} sets \${MAKE}" >&5 --set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+# expand $ac_aux_dir to an absolute path -+am_aux_dir=`cd $ac_aux_dir && pwd` -+ -+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" -+# Use eval to expand $SHELL -+if eval "$MISSING --run true"; then -+ am_missing_run="$MISSING --run " - else -- cat > conftestmake <<\EOF -+ am_missing_run= -+ { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 -+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} -+fi -+ -+for ac_prog in gawk mawk nawk awk -+do -+ # Extract the first word of "$ac_prog", so it can be a program name with args. -+set dummy $ac_prog; ac_word=$2 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_AWK+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test -n "$AWK"; then -+ ac_cv_prog_AWK="$AWK" # Let the user override the test. -+else -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_AWK="$ac_prog" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+done -+ -+fi -+fi -+AWK=$ac_cv_prog_AWK -+if test -n "$AWK"; then -+ echo "$as_me:$LINENO: result: $AWK" >&5 -+echo "${ECHO_T}$AWK" >&6 -+else -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 -+fi -+ -+ test -n "$AWK" && break -+done -+ -+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 -+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` -+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ cat >conftest.make <<\_ACEOF - all: -- @echo 'ac_maketemp="${MAKE}"' --EOF -+ @echo 'ac_maketemp="$(MAKE)"' -+_ACEOF - # GNU make sometimes prints "make[1]: Entering...", which would confuse us. --eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` -+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` - if test -n "$ac_maketemp"; then - eval ac_cv_prog_make_${ac_make}_set=yes - else - eval ac_cv_prog_make_${ac_make}_set=no - fi --rm -f conftestmake -+rm -f conftest.make - fi - if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -+ echo "$as_me:$LINENO: result: yes" >&5 -+echo "${ECHO_T}yes" >&6 - SET_MAKE= - else -- echo "$ac_t""no" 1>&6 -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 - SET_MAKE="MAKE=${MAKE-make}" - fi - -+rm -rf .tst 2>/dev/null -+mkdir .tst 2>/dev/null -+if test -d .tst; then -+ am__leading_dot=. -+else -+ am__leading_dot=_ -+fi -+rmdir .tst 2>/dev/null - --PACKAGE=links -- --VERSION=2.1pre12 -+ # test to see if srcdir already configured -+if test "`cd $srcdir && pwd`" != "`pwd`" && -+ test -f $srcdir/config.status; then -+ { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 -+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} -+ { (exit 1); exit 1; }; } -+fi - --if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then -- { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } -+# test whether we have cygpath -+if test -z "$CYGPATH_W"; then -+ if (cygpath --version) >/dev/null 2>/dev/null; then -+ CYGPATH_W='cygpath -w' -+ else -+ CYGPATH_W=echo -+ fi - fi --cat >> confdefs.h <>confdefs.h <<_ACEOF - #define PACKAGE "$PACKAGE" --EOF -+_ACEOF - --cat >> confdefs.h <>confdefs.h <<_ACEOF - #define VERSION "$VERSION" --EOF -+_ACEOF - -+# Some tools Automake needs. - -+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - --missing_dir=`cd $ac_aux_dir && pwd` --echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 --echo "configure:739: checking for working aclocal" >&5 --# Run test in a subshell; some versions of sh will print an error if --# an executable is not found, even if stderr is redirected. --# Redirect stdin to placate older versions of autoconf. Sigh. --if (aclocal --version) < /dev/null > /dev/null 2>&1; then -- ACLOCAL=aclocal -- echo "$ac_t""found" 1>&6 -+ -+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} -+ -+ -+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} -+ -+ -+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} -+ -+ -+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} -+ -+ -+AMTAR=${AMTAR-"${am_missing_run}tar"} -+ -+install_sh=${install_sh-"$am_aux_dir/install-sh"} -+ -+# Installed binaries are usually stripped using `strip' when the user -+# run `make install-strip'. However `strip' might not be the right -+# tool to use in cross-compilation environments, therefore Automake -+# will honor the `STRIP' environment variable to overrule this program. -+if test "$cross_compiling" != no; then -+ if test -n "$ac_tool_prefix"; then -+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -+set dummy ${ac_tool_prefix}strip; ac_word=$2 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_STRIP+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ACLOCAL="$missing_dir/missing aclocal" -- echo "$ac_t""missing" 1>&6 --fi -+ if test -n "$STRIP"; then -+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -+else -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_STRIP="${ac_tool_prefix}strip" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+done - --echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 --echo "configure:752: checking for working autoconf" >&5 --# Run test in a subshell; some versions of sh will print an error if --# an executable is not found, even if stderr is redirected. --# Redirect stdin to placate older versions of autoconf. Sigh. --if (autoconf --version) < /dev/null > /dev/null 2>&1; then -- AUTOCONF=autoconf -- echo "$ac_t""found" 1>&6 -+fi -+fi -+STRIP=$ac_cv_prog_STRIP -+if test -n "$STRIP"; then -+ echo "$as_me:$LINENO: result: $STRIP" >&5 -+echo "${ECHO_T}$STRIP" >&6 - else -- AUTOCONF="$missing_dir/missing autoconf" -- echo "$ac_t""missing" 1>&6 -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 - fi - --echo $ac_n "checking for working automake""... $ac_c" 1>&6 --echo "configure:765: checking for working automake" >&5 --# Run test in a subshell; some versions of sh will print an error if --# an executable is not found, even if stderr is redirected. --# Redirect stdin to placate older versions of autoconf. Sigh. --if (automake --version) < /dev/null > /dev/null 2>&1; then -- AUTOMAKE=automake -- echo "$ac_t""found" 1>&6 --else -- AUTOMAKE="$missing_dir/missing automake" -- echo "$ac_t""missing" 1>&6 - fi -+if test -z "$ac_cv_prog_STRIP"; then -+ ac_ct_STRIP=$STRIP -+ # Extract the first word of "strip", so it can be a program name with args. -+set dummy strip; ac_word=$2 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test -n "$ac_ct_STRIP"; then -+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -+else -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_ac_ct_STRIP="strip" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+done - --echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 --echo "configure:778: checking for working autoheader" >&5 --# Run test in a subshell; some versions of sh will print an error if --# an executable is not found, even if stderr is redirected. --# Redirect stdin to placate older versions of autoconf. Sigh. --if (autoheader --version) < /dev/null > /dev/null 2>&1; then -- AUTOHEADER=autoheader -- echo "$ac_t""found" 1>&6 -+ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" -+fi -+fi -+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -+if test -n "$ac_ct_STRIP"; then -+ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 -+echo "${ECHO_T}$ac_ct_STRIP" >&6 - else -- AUTOHEADER="$missing_dir/missing autoheader" -- echo "$ac_t""missing" 1>&6 -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 - fi - --echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 --echo "configure:791: checking for working makeinfo" >&5 --# Run test in a subshell; some versions of sh will print an error if --# an executable is not found, even if stderr is redirected. --# Redirect stdin to placate older versions of autoconf. Sigh. --if (makeinfo --version) < /dev/null > /dev/null 2>&1; then -- MAKEINFO=makeinfo -- echo "$ac_t""found" 1>&6 -+ STRIP=$ac_ct_STRIP - else -- MAKEINFO="$missing_dir/missing makeinfo" -- echo "$ac_t""missing" 1>&6 -+ STRIP="$ac_cv_prog_STRIP" - fi - -+fi -+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" -+ -+# We need awk for the "check" target. The system "awk" is bad on -+# some platforms. -+ -+ - - - ACLOCAL="./missing aclocal" -@@ -807,218 +1701,646 @@ - AUTOHEADER="./missing autoheader" - image_formats="GIF PNG XBM" - -+ ac_config_headers="$ac_config_headers config.h" - - -+ac_ext=c -+ac_cpp='$CPP $CPPFLAGS' -+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -+ac_compiler_gnu=$ac_cv_c_compiler_gnu -+if test -n "$ac_tool_prefix"; then -+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -+set dummy ${ac_tool_prefix}gcc; ac_word=$2 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_CC+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test -n "$CC"; then -+ ac_cv_prog_CC="$CC" # Let the user override the test. -+else -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_CC="${ac_tool_prefix}gcc" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+done - -+fi -+fi -+CC=$ac_cv_prog_CC -+if test -n "$CC"; then -+ echo "$as_me:$LINENO: result: $CC" >&5 -+echo "${ECHO_T}$CC" >&6 -+else -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 -+fi - --# Extract the first word of "gcc", so it can be a program name with args. -+fi -+if test -z "$ac_cv_prog_CC"; then -+ ac_ct_CC=$CC -+ # Extract the first word of "gcc", so it can be a program name with args. - set dummy gcc; ac_word=$2 --echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:818: checking for $ac_word" >&5 --if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test -n "$ac_ct_CC"; then -+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -+else -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_ac_ct_CC="gcc" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+done -+ -+fi -+fi -+ac_ct_CC=$ac_cv_prog_ac_ct_CC -+if test -n "$ac_ct_CC"; then -+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -+echo "${ECHO_T}$ac_ct_CC" >&6 -+else -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 -+fi -+ -+ CC=$ac_ct_CC -+else -+ CC="$ac_cv_prog_CC" -+fi -+ -+if test -z "$CC"; then -+ if test -n "$ac_tool_prefix"; then -+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -+set dummy ${ac_tool_prefix}cc; ac_word=$2 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_CC+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. - else -- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" -- ac_dummy="$PATH" -- for ac_dir in $ac_dummy; do -- test -z "$ac_dir" && ac_dir=. -- if test -f $ac_dir/$ac_word; then -- ac_cv_prog_CC="gcc" -- break -- fi -- done -- IFS="$ac_save_ifs" -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_CC="${ac_tool_prefix}cc" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+done -+ - fi - fi --CC="$ac_cv_prog_CC" -+CC=$ac_cv_prog_CC - if test -n "$CC"; then -- echo "$ac_t""$CC" 1>&6 -+ echo "$as_me:$LINENO: result: $CC" >&5 -+echo "${ECHO_T}$CC" >&6 - else -- echo "$ac_t""no" 1>&6 -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 -+fi -+ -+fi -+if test -z "$ac_cv_prog_CC"; then -+ ac_ct_CC=$CC -+ # Extract the first word of "cc", so it can be a program name with args. -+set dummy cc; ac_word=$2 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test -n "$ac_ct_CC"; then -+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -+else -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_ac_ct_CC="cc" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+done -+ -+fi -+fi -+ac_ct_CC=$ac_cv_prog_ac_ct_CC -+if test -n "$ac_ct_CC"; then -+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -+echo "${ECHO_T}$ac_ct_CC" >&6 -+else -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 -+fi -+ -+ CC=$ac_ct_CC -+else -+ CC="$ac_cv_prog_CC" - fi - -+fi - if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. - set dummy cc; ac_word=$2 --echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:848: checking for $ac_word" >&5 --if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_CC+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. - else -- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_prog_rejected=no -- ac_dummy="$PATH" -- for ac_dir in $ac_dummy; do -- test -z "$ac_dir" && ac_dir=. -- if test -f $ac_dir/$ac_word; then -- if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then -- ac_prog_rejected=yes -- continue -- fi -- ac_cv_prog_CC="cc" -- break -- fi -- done -- IFS="$ac_save_ifs" -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then -+ ac_prog_rejected=yes -+ continue -+ fi -+ ac_cv_prog_CC="cc" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+done -+ - if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift -- if test $# -gt 0; then -+ if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift -- set dummy "$ac_dir/$ac_word" "$@" -- shift -- ac_cv_prog_CC="$@" -+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi - fi - fi - fi --CC="$ac_cv_prog_CC" -+CC=$ac_cv_prog_CC - if test -n "$CC"; then -- echo "$ac_t""$CC" 1>&6 -+ echo "$as_me:$LINENO: result: $CC" >&5 -+echo "${ECHO_T}$CC" >&6 - else -- echo "$ac_t""no" 1>&6 -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 - fi - -- if test -z "$CC"; then -- case "`uname -s`" in -- *win32* | *WIN32*) -- # Extract the first word of "cl", so it can be a program name with args. --set dummy cl; ac_word=$2 --echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:899: checking for $ac_word" >&5 --if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+fi -+if test -z "$CC"; then -+ if test -n "$ac_tool_prefix"; then -+ for ac_prog in cl -+ do -+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -+set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_CC+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. - else -- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" -- ac_dummy="$PATH" -- for ac_dir in $ac_dummy; do -- test -z "$ac_dir" && ac_dir=. -- if test -f $ac_dir/$ac_word; then -- ac_cv_prog_CC="cl" -- break -- fi -- done -- IFS="$ac_save_ifs" -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+done -+ - fi - fi --CC="$ac_cv_prog_CC" -+CC=$ac_cv_prog_CC - if test -n "$CC"; then -- echo "$ac_t""$CC" 1>&6 -+ echo "$as_me:$LINENO: result: $CC" >&5 -+echo "${ECHO_T}$CC" >&6 - else -- echo "$ac_t""no" 1>&6 -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 - fi -- ;; -- esac -+ -+ test -n "$CC" && break -+ done -+fi -+if test -z "$CC"; then -+ ac_ct_CC=$CC -+ for ac_prog in cl -+do -+ # Extract the first word of "$ac_prog", so it can be a program name with args. -+set dummy $ac_prog; ac_word=$2 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test -n "$ac_ct_CC"; then -+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -+else -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_ac_ct_CC="$ac_prog" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 - fi -- test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } -+done -+done -+ -+fi -+fi -+ac_ct_CC=$ac_cv_prog_ac_ct_CC -+if test -n "$ac_ct_CC"; then -+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -+echo "${ECHO_T}$ac_ct_CC" >&6 -+else -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 - fi - --echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 --echo "configure:931: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 -+ test -n "$ac_ct_CC" && break -+done - --ac_ext=c --# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. --ac_cpp='$CPP $CPPFLAGS' --ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' --ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' --cross_compiling=$ac_cv_prog_cc_cross -+ CC=$ac_ct_CC -+fi - --cat > conftest.$ac_ext << EOF -+fi - --#line 942 "configure" --#include "confdefs.h" - --main(){return(0);} --EOF --if { (eval echo configure:947: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- ac_cv_prog_cc_works=yes -- # If we can't run a trivial program, we are probably using a cross compiler. -- if (./conftest; exit) 2>/dev/null; then -- ac_cv_prog_cc_cross=no -+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -+See \`config.log' for more details." >&5 -+echo "$as_me: error: no acceptable C compiler found in \$PATH -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } -+ -+# Provide some information about the compiler. -+echo "$as_me:$LINENO:" \ -+ "checking for C compiler version" >&5 -+ac_compiler=`set X $ac_compile; echo $2` -+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 -+ (eval $ac_compiler --version &5) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } -+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 -+ (eval $ac_compiler -v &5) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } -+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 -+ (eval $ac_compiler -V &5) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } -+ -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ -+int -+main () -+{ -+ -+ ; -+ return 0; -+} -+_ACEOF -+ac_clean_files_save=$ac_clean_files -+ac_clean_files="$ac_clean_files a.out a.exe b.out" -+# Try to create an executable without -o first, disregard a.out. -+# It will help us diagnose broken compilers, and finding out an intuition -+# of exeext. -+echo "$as_me:$LINENO: checking for C compiler default output" >&5 -+echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 -+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 -+ (eval $ac_link_default) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; then -+ # Find the output, starting from the most likely. This scheme is -+# not robust to junk in `.', hence go to wildcards (a.*) only as a last -+# resort. -+ -+# Be careful to initialize this variable, since it used to be cached. -+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. -+ac_cv_exeext= -+# b.out is created by i960 compilers. -+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out -+do -+ test -f "$ac_file" || continue -+ case $ac_file in -+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) -+ ;; -+ conftest.$ac_ext ) -+ # This is the source file. -+ ;; -+ [ab].out ) -+ # We found the default executable, but exeext='' is most -+ # certainly right. -+ break;; -+ *.* ) -+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` -+ # FIXME: I believe we export ac_cv_exeext for Libtool, -+ # but it would be cool to find out if it's true. Does anybody -+ # maintain Libtool? --akim. -+ export ac_cv_exeext -+ break;; -+ * ) -+ break;; -+ esac -+done -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables -+See \`config.log' for more details." >&5 -+echo "$as_me: error: C compiler cannot create executables -+See \`config.log' for more details." >&2;} -+ { (exit 77); exit 77; }; } -+fi -+ -+ac_exeext=$ac_cv_exeext -+echo "$as_me:$LINENO: result: $ac_file" >&5 -+echo "${ECHO_T}$ac_file" >&6 -+ -+# Check the compiler produces executables we can run. If not, either -+# the compiler is broken, or we cross compile. -+echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 -+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -+# If not cross compiling, check that we can run a simple program. -+if test "$cross_compiling" != yes; then -+ if { ac_try='./$ac_file' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ cross_compiling=no - else -- ac_cv_prog_cc_cross=yes -+ if test "$cross_compiling" = maybe; then -+ cross_compiling=yes -+ else -+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -+If you meant to cross compile, use \`--host'. -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot run C compiled programs. -+If you meant to cross compile, use \`--host'. -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } -+ fi - fi --else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- ac_cv_prog_cc_works=no - fi --rm -fr conftest* --ac_ext=c --# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. --ac_cpp='$CPP $CPPFLAGS' --ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' --ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' --cross_compiling=$ac_cv_prog_cc_cross -+echo "$as_me:$LINENO: result: yes" >&5 -+echo "${ECHO_T}yes" >&6 - --echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 --if test $ac_cv_prog_cc_works = no; then -- { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } -+rm -f a.out a.exe conftest$ac_cv_exeext b.out -+ac_clean_files=$ac_clean_files_save -+# Check the compiler produces executables we can run. If not, either -+# the compiler is broken, or we cross compile. -+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 -+echo "$as_me:$LINENO: result: $cross_compiling" >&5 -+echo "${ECHO_T}$cross_compiling" >&6 -+ -+echo "$as_me:$LINENO: checking for suffix of executables" >&5 -+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; then -+ # If both `conftest.exe' and `conftest' are `present' (well, observable) -+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -+# work properly (i.e., refer to `conftest.exe'), while it won't with -+# `rm'. -+for ac_file in conftest.exe conftest conftest.*; do -+ test -f "$ac_file" || continue -+ case $ac_file in -+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; -+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` -+ export ac_cv_exeext -+ break;; -+ * ) break;; -+ esac -+done -+else -+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } - fi --echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 --echo "configure:973: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 --echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 --cross_compiling=$ac_cv_prog_cc_cross - --echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 --echo "configure:978: checking whether we are using GNU C" >&5 --if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+rm -f conftest$ac_cv_exeext -+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -+echo "${ECHO_T}$ac_cv_exeext" >&6 -+ -+rm -f conftest.$ac_ext -+EXEEXT=$ac_cv_exeext -+ac_exeext=$EXEEXT -+echo "$as_me:$LINENO: checking for suffix of object files" >&5 -+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 -+if test "${ac_cv_objext+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then -- ac_cv_prog_gcc=yes -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ -+int -+main () -+{ -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.o conftest.obj -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; then -+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do -+ case $ac_file in -+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; -+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` -+ break;; -+ esac -+done - else -- ac_cv_prog_gcc=no -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute suffix of object files: cannot compile -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } - fi -+ -+rm -f conftest.$ac_cv_objext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -+echo "${ECHO_T}$ac_cv_objext" >&6 -+OBJEXT=$ac_cv_objext -+ac_objext=$OBJEXT -+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 -+if test "${ac_cv_c_compiler_gnu+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - --echo "$ac_t""$ac_cv_prog_gcc" 1>&6 -+int -+main () -+{ -+#ifndef __GNUC__ -+ choke me -+#endif - --if test $ac_cv_prog_gcc = yes; then -- GCC=yes -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_compiler_gnu=yes - else -- GCC= -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_compiler_gnu=no - fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ac_cv_c_compiler_gnu=$ac_compiler_gnu - --ac_test_CFLAGS="${CFLAGS+set}" --ac_save_CFLAGS="$CFLAGS" --CFLAGS= --echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 --echo "configure:1006: checking whether ${CC-cc} accepts -g" >&5 --if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+fi -+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 -+GCC=`test $ac_compiler_gnu = yes && echo yes` -+ac_test_CFLAGS=${CFLAGS+set} -+ac_save_CFLAGS=$CFLAGS -+CFLAGS="-g" -+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 -+if test "${ac_cv_prog_cc_g+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- echo 'void f(){}' > conftest.c --if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ -+int -+main () -+{ -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes - else -- ac_cv_prog_cc_g=no --fi --rm -f conftest* -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_prog_cc_g=no - fi -- --echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 -+rm -f conftest.$ac_objext conftest.$ac_ext -+fi -+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 - if test "$ac_test_CFLAGS" = set; then -- CFLAGS="$ac_save_CFLAGS" -+ CFLAGS=$ac_save_CFLAGS - elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" -@@ -1032,356 +2354,1564 @@ - CFLAGS= - fi - fi -+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 -+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 -+if test "${ac_cv_prog_cc_stdc+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ ac_cv_prog_cc_stdc=no -+ac_save_CC=$CC -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include -+#include -+#include -+#include -+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -+struct buf { int x; }; -+FILE * (*rcsopen) (struct buf *, struct stat *, int); -+static char *e (p, i) -+ char **p; -+ int i; -+{ -+ return p[i]; -+} -+static char *f (char * (*g) (char **, int), char **p, ...) -+{ -+ char *s; -+ va_list v; -+ va_start (v,p); -+ s = g (p, va_arg (v,int)); -+ va_end (v); -+ return s; -+} -+int test (int i, double x); -+struct s1 {int (*f) (int a);}; -+struct s2 {int (*f) (double a);}; -+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -+int argc; -+char **argv; -+int -+main () -+{ -+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; -+ ; -+ return 0; -+} -+_ACEOF -+# Don't try gcc -ansi; that turns off useful extensions and -+# breaks some systems' header files. -+# AIX -qlanglvl=ansi -+# Ultrix and OSF/1 -std1 -+# HP-UX 10.20 and later -Ae -+# HP-UX older versions -Aa -D_HPUX_SOURCE -+# SVR4 -Xc -D__EXTENSIONS__ -+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -+do -+ CC="$ac_save_CC $ac_arg" -+ rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_prog_cc_stdc=$ac_arg -+break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+fi -+rm -f conftest.$ac_objext -+done -+rm -f conftest.$ac_ext conftest.$ac_objext -+CC=$ac_save_CC -+ -+fi -+ -+case "x$ac_cv_prog_cc_stdc" in -+ x|xno) -+ echo "$as_me:$LINENO: result: none needed" >&5 -+echo "${ECHO_T}none needed" >&6 ;; -+ *) -+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 -+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 -+ CC="$CC $ac_cv_prog_cc_stdc" ;; -+esac -+ -+# Some people use a C++ compiler to compile C. Since we use `exit', -+# in C++ we need to declare it. In case someone uses the same compiler -+# for both compiling C and C++ we need to have the C++ compiler decide -+# the declaration of exit, since it's the most demanding environment. -+cat >conftest.$ac_ext <<_ACEOF -+#ifndef __cplusplus -+ choke me -+#endif -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ for ac_declaration in \ -+ ''\ -+ '#include ' \ -+ 'extern "C" void std::exit (int) throw (); using std::exit;' \ -+ 'extern "C" void std::exit (int); using std::exit;' \ -+ 'extern "C" void exit (int) throw ();' \ -+ 'extern "C" void exit (int);' \ -+ 'void exit (int);' -+do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include -+$ac_declaration -+int -+main () -+{ -+exit (42); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ : -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+continue -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_declaration -+int -+main () -+{ -+exit (42); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+done -+rm -f conftest* -+if test -n "$ac_declaration"; then -+ echo '#ifdef __cplusplus' >>confdefs.h -+ echo $ac_declaration >>confdefs.h -+ echo '#endif' >>confdefs.h -+fi -+ -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ac_ext=c -+ac_cpp='$CPP $CPPFLAGS' -+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -+ac_compiler_gnu=$ac_cv_c_compiler_gnu -+DEPDIR="${am__leading_dot}deps" -+ -+ ac_config_commands="$ac_config_commands depfiles" -+ -+ -+am_make=${MAKE-make} -+cat > confinc << 'END' -+am__doit: -+ @echo done -+.PHONY: am__doit -+END -+# If we don't find an include directive, just comment out the code. -+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 -+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 -+am__include="#" -+am__quote= -+_am_result=none -+# First try GNU make style include. -+echo "include confinc" > confmf -+# We grep out `Entering directory' and `Leaving directory' -+# messages which can occur if `w' ends up in MAKEFLAGS. -+# In particular we don't look at `^make:' because GNU make might -+# be invoked under some other name (usually "gmake"), in which -+# case it prints its new name instead of `make'. -+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then -+ am__include=include -+ am__quote= -+ _am_result=GNU -+fi -+# Now try BSD make style include. -+if test "$am__include" = "#"; then -+ echo '.include "confinc"' > confmf -+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then -+ am__include=.include -+ am__quote="\"" -+ _am_result=BSD -+ fi -+fi -+ -+ -+echo "$as_me:$LINENO: result: $_am_result" >&5 -+echo "${ECHO_T}$_am_result" >&6 -+rm -f confinc confmf -+ -+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. -+if test "${enable_dependency_tracking+set}" = set; then -+ enableval="$enable_dependency_tracking" -+ -+fi; -+if test "x$enable_dependency_tracking" != xno; then -+ am_depcomp="$ac_aux_dir/depcomp" -+ AMDEPBACKSLASH='\' -+fi -+ -+ -+if test "x$enable_dependency_tracking" != xno; then -+ AMDEP_TRUE= -+ AMDEP_FALSE='#' -+else -+ AMDEP_TRUE='#' -+ AMDEP_FALSE= -+fi -+ -+ -+ -+ -+depcc="$CC" am_compiler_list= -+ -+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 -+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 -+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then -+ # We make a subdir and do the tests there. Otherwise we can end up -+ # making bogus files that we don't know about and never remove. For -+ # instance it was reported that on HP-UX the gcc test will end up -+ # making a dummy file named `D' -- because `-MD' means `put the output -+ # in D'. -+ mkdir conftest.dir -+ # Copy depcomp to subdir because otherwise we won't find it if we're -+ # using a relative directory. -+ cp "$am_depcomp" conftest.dir -+ cd conftest.dir -+ # We will build objects and dependencies in a subdirectory because -+ # it helps to detect inapplicable dependency modes. For instance -+ # both Tru64's cc and ICC support -MD to output dependencies as a -+ # side effect of compilation, but ICC will put the dependencies in -+ # the current directory while Tru64 will put them in the object -+ # directory. -+ mkdir sub -+ -+ am_cv_CC_dependencies_compiler_type=none -+ if test "$am_compiler_list" = ""; then -+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` -+ fi -+ for depmode in $am_compiler_list; do -+ # Setup a source with many dependencies, because some compilers -+ # like to wrap large dependency lists on column 80 (with \), and -+ # we should not choose a depcomp mode which is confused by this. -+ # -+ # We need to recreate these files for each test, as the compiler may -+ # overwrite some of them when testing with obscure command lines. -+ # This happens at least with the AIX C compiler. -+ : > sub/conftest.c -+ for i in 1 2 3 4 5 6; do -+ echo '#include "conftst'$i'.h"' >> sub/conftest.c -+ : > sub/conftst$i.h -+ done -+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf -+ -+ case $depmode in -+ nosideeffect) -+ # after this tag, mechanisms are not by side-effect, so they'll -+ # only be used when explicitly requested -+ if test "x$enable_dependency_tracking" = xyes; then -+ continue -+ else -+ break -+ fi -+ ;; -+ none) break ;; -+ esac -+ # We check with `-c' and `-o' for the sake of the "dashmstdout" -+ # mode. It turns out that the SunPro C++ compiler does not properly -+ # handle `-M -o', and we need to detect this. -+ if depmode=$depmode \ -+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ -+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ -+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ -+ >/dev/null 2>conftest.err && -+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && -+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && -+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then -+ # icc doesn't choke on unknown options, it will just issue warnings -+ # (even with -Werror). So we grep stderr for any message -+ # that says an option was ignored. -+ if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else -+ am_cv_CC_dependencies_compiler_type=$depmode -+ break -+ fi -+ fi -+ done -+ -+ cd .. -+ rm -rf conftest.dir -+else -+ am_cv_CC_dependencies_compiler_type=none -+fi -+ -+fi -+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 -+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 -+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type -+ -+ -+ -+if -+ test "x$enable_dependency_tracking" != xno \ -+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then -+ am__fastdepCC_TRUE= -+ am__fastdepCC_FALSE='#' -+else -+ am__fastdepCC_TRUE='#' -+ am__fastdepCC_FALSE= -+fi -+ -+ -+ -+ac_ext=cc -+ac_cpp='$CXXCPP $CPPFLAGS' -+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -+if test -n "$ac_tool_prefix"; then -+ for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC -+ do -+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -+set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_CXX+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test -n "$CXX"; then -+ ac_cv_prog_CXX="$CXX" # Let the user override the test. -+else -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+done -+ -+fi -+fi -+CXX=$ac_cv_prog_CXX -+if test -n "$CXX"; then -+ echo "$as_me:$LINENO: result: $CXX" >&5 -+echo "${ECHO_T}$CXX" >&6 -+else -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 -+fi -+ -+ test -n "$CXX" && break -+ done -+fi -+if test -z "$CXX"; then -+ ac_ct_CXX=$CXX -+ for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC -+do -+ # Extract the first word of "$ac_prog", so it can be a program name with args. -+set dummy $ac_prog; ac_word=$2 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test -n "$ac_ct_CXX"; then -+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -+else -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_ac_ct_CXX="$ac_prog" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+done -+ -+fi -+fi -+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -+if test -n "$ac_ct_CXX"; then -+ echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 -+echo "${ECHO_T}$ac_ct_CXX" >&6 -+else -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 -+fi -+ -+ test -n "$ac_ct_CXX" && break -+done -+test -n "$ac_ct_CXX" || ac_ct_CXX="g++" -+ -+ CXX=$ac_ct_CXX -+fi -+ -+ -+# Provide some information about the compiler. -+echo "$as_me:$LINENO:" \ -+ "checking for C++ compiler version" >&5 -+ac_compiler=`set X $ac_compile; echo $2` -+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 -+ (eval $ac_compiler --version &5) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } -+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 -+ (eval $ac_compiler -v &5) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } -+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 -+ (eval $ac_compiler -V &5) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } -+ -+echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 -+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 -+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ -+int -+main () -+{ -+#ifndef __GNUC__ -+ choke me -+#endif -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_compiler_gnu=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_compiler_gnu=no -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu -+ -+fi -+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 -+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 -+GXX=`test $ac_compiler_gnu = yes && echo yes` -+ac_test_CXXFLAGS=${CXXFLAGS+set} -+ac_save_CXXFLAGS=$CXXFLAGS -+CXXFLAGS="-g" -+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 -+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 -+if test "${ac_cv_prog_cxx_g+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ -+int -+main () -+{ -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_prog_cxx_g=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_prog_cxx_g=no -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+fi -+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 -+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 -+if test "$ac_test_CXXFLAGS" = set; then -+ CXXFLAGS=$ac_save_CXXFLAGS -+elif test $ac_cv_prog_cxx_g = yes; then -+ if test "$GXX" = yes; then -+ CXXFLAGS="-g -O2" -+ else -+ CXXFLAGS="-g" -+ fi -+else -+ if test "$GXX" = yes; then -+ CXXFLAGS="-O2" -+ else -+ CXXFLAGS= -+ fi -+fi -+for ac_declaration in \ -+ ''\ -+ '#include ' \ -+ 'extern "C" void std::exit (int) throw (); using std::exit;' \ -+ 'extern "C" void std::exit (int); using std::exit;' \ -+ 'extern "C" void exit (int) throw ();' \ -+ 'extern "C" void exit (int);' \ -+ 'void exit (int);' -+do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include -+$ac_declaration -+int -+main () -+{ -+exit (42); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ : -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+continue -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_declaration -+int -+main () -+{ -+exit (42); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+done -+rm -f conftest* -+if test -n "$ac_declaration"; then -+ echo '#ifdef __cplusplus' >>confdefs.h -+ echo $ac_declaration >>confdefs.h -+ echo '#endif' >>confdefs.h -+fi -+ -+ac_ext=c -+ac_cpp='$CPP $CPPFLAGS' -+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -+ac_compiler_gnu=$ac_cv_c_compiler_gnu -+ -+depcc="$CXX" am_compiler_list= -+ -+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 -+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 -+if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then -+ # We make a subdir and do the tests there. Otherwise we can end up -+ # making bogus files that we don't know about and never remove. For -+ # instance it was reported that on HP-UX the gcc test will end up -+ # making a dummy file named `D' -- because `-MD' means `put the output -+ # in D'. -+ mkdir conftest.dir -+ # Copy depcomp to subdir because otherwise we won't find it if we're -+ # using a relative directory. -+ cp "$am_depcomp" conftest.dir -+ cd conftest.dir -+ # We will build objects and dependencies in a subdirectory because -+ # it helps to detect inapplicable dependency modes. For instance -+ # both Tru64's cc and ICC support -MD to output dependencies as a -+ # side effect of compilation, but ICC will put the dependencies in -+ # the current directory while Tru64 will put them in the object -+ # directory. -+ mkdir sub -+ -+ am_cv_CXX_dependencies_compiler_type=none -+ if test "$am_compiler_list" = ""; then -+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` -+ fi -+ for depmode in $am_compiler_list; do -+ # Setup a source with many dependencies, because some compilers -+ # like to wrap large dependency lists on column 80 (with \), and -+ # we should not choose a depcomp mode which is confused by this. -+ # -+ # We need to recreate these files for each test, as the compiler may -+ # overwrite some of them when testing with obscure command lines. -+ # This happens at least with the AIX C compiler. -+ : > sub/conftest.c -+ for i in 1 2 3 4 5 6; do -+ echo '#include "conftst'$i'.h"' >> sub/conftest.c -+ : > sub/conftst$i.h -+ done -+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf -+ -+ case $depmode in -+ nosideeffect) -+ # after this tag, mechanisms are not by side-effect, so they'll -+ # only be used when explicitly requested -+ if test "x$enable_dependency_tracking" = xyes; then -+ continue -+ else -+ break -+ fi -+ ;; -+ none) break ;; -+ esac -+ # We check with `-c' and `-o' for the sake of the "dashmstdout" -+ # mode. It turns out that the SunPro C++ compiler does not properly -+ # handle `-M -o', and we need to detect this. -+ if depmode=$depmode \ -+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ -+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ -+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ -+ >/dev/null 2>conftest.err && -+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && -+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && -+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then -+ # icc doesn't choke on unknown options, it will just issue warnings -+ # (even with -Werror). So we grep stderr for any message -+ # that says an option was ignored. -+ if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else -+ am_cv_CXX_dependencies_compiler_type=$depmode -+ break -+ fi -+ fi -+ done -+ -+ cd .. -+ rm -rf conftest.dir -+else -+ am_cv_CXX_dependencies_compiler_type=none -+fi -+ -+fi -+echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 -+echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6 -+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type -+ -+ -+ -+if -+ test "x$enable_dependency_tracking" != xno \ -+ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then -+ am__fastdepCXX_TRUE= -+ am__fastdepCXX_FALSE='#' -+else -+ am__fastdepCXX_TRUE='#' -+ am__fastdepCXX_FALSE= -+fi - - --#AC_PROG_CXX - #AC_PROG_AWK - #AM_PROG_LEX - #AC_PROG_YACC - - #AC_CHECK_LIB(fl,main,AC_DEFINE(JS) LIBS="$LIBS -lfl",AC_MSG_WARN(You don't have libfl; you won't be able to run javascript)) - --echo $ac_n "checking for EMX""... $ac_c" 1>&6 --echo "configure:1046: checking for EMX" >&5 --if eval "test \"`echo '$''{'ac_cv_have_emx'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for EMX" >&5 -+echo $ECHO_N "checking for EMX... $ECHO_C" >&6 -+if test "${ac_cv_have_emx+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ -+int -+main () -+{ - #ifndef __EMX__ - kill me! -- #endif --; return 0; } --EOF --if { (eval echo configure:1060: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then -- rm -rf conftest* -+ #endif -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_have_emx=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_have_emx=no --fi --rm -f conftest* -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_have_emx=no - fi -+rm -f conftest.$ac_objext conftest.$ac_ext - --echo "$ac_t""$ac_cv_have_emx" 1>&6 -+fi -+echo "$as_me:$LINENO: result: $ac_cv_have_emx" >&5 -+echo "${ECHO_T}$ac_cv_have_emx" >&6 - test "$ac_cv_have_emx" = yes && LDFLAGS=`echo "$LDFLAGS" | sed "s/-Zexe//g" | sed "s/-Zbin-files//g"` - --echo $ac_n "checking for typeof""... $ac_c" 1>&6 --echo "configure:1077: checking for typeof" >&5 --if eval "test \"`echo '$''{'ac_cv_have_typeof'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for typeof" >&5 -+echo $ECHO_N "checking for typeof... $ECHO_C" >&6 -+if test "${ac_cv_have_typeof+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - --int main() { -+int -+main () -+{ - int a; - typeof(a) b; --; return 0; } --EOF --if { (eval echo configure:1090: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then -- rm -rf conftest* -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_have_typeof=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_have_typeof=no --fi --rm -f conftest* -- -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_have_typeof=no - fi -+rm -f conftest.$ac_objext conftest.$ac_ext - --echo "$ac_t""$ac_cv_have_typeof" 1>&6 --test "$ac_cv_have_typeof" = yes && cat >> confdefs.h <<\EOF -+fi -+echo "$as_me:$LINENO: result: $ac_cv_have_typeof" >&5 -+echo "${ECHO_T}$ac_cv_have_typeof" >&6 -+test "$ac_cv_have_typeof" = yes && cat >>confdefs.h <<\_ACEOF - #define HAVE_TYPEOF 1 --EOF -+_ACEOF - - --echo $ac_n "checking for long long""... $ac_c" 1>&6 --echo "configure:1110: checking for long long" >&5 --if eval "test \"`echo '$''{'ac_cv_have_long_long'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for long long" >&5 -+echo $ECHO_N "checking for long long... $ECHO_C" >&6 -+if test "${ac_cv_have_long_long+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - --int main() { --unsigned long long a; --; return 0; } --EOF --if { (eval echo configure:1122: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then -- rm -rf conftest* -+int -+main () -+{ -+unsigned long long a; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_have_long_long=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_have_long_long=no --fi --rm -f conftest* -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_have_long_long=no - fi -+rm -f conftest.$ac_objext conftest.$ac_ext - --echo "$ac_t""$ac_cv_have_long_long" 1>&6 --test "$ac_cv_have_long_long" = yes && cat >> confdefs.h <<\EOF -+fi -+echo "$as_me:$LINENO: result: $ac_cv_have_long_long" >&5 -+echo "${ECHO_T}$ac_cv_have_long_long" >&6 -+test "$ac_cv_have_long_long" = yes && cat >>confdefs.h <<\_ACEOF - #define HAVE_LONG_LONG 1 --EOF -+_ACEOF -+ -+ -+ -+ -+ - - - ac_header_dirent=no --for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h --do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 --echo "configure:1146: checking for $ac_hdr that defines DIR" >&5 --if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do -+ as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 -+echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include - #include <$ac_hdr> --int main() { --DIR *dirp = 0; --; return 0; } --EOF --if { (eval echo configure:1159: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then -- rm -rf conftest* -- eval "ac_cv_header_dirent_$ac_safe=yes" -+ -+int -+main () -+{ -+if ((DIR *) 0) -+return 0; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_Header=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_dirent_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_Header=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext - fi --if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 -+_ACEOF -+ -+ac_header_dirent=$ac_hdr; break - fi -+ - done - # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. - if test $ac_header_dirent = dirent.h; then --echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 --echo "configure:1184: checking for opendir in -ldir" >&5 --ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ echo "$as_me:$LINENO: checking for library containing opendir" >&5 -+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6 -+if test "${ac_cv_search_opendir+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" --LIBS="-ldir $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char opendir(); -- --int main() { --opendir() --; return 0; } --EOF --if { (eval echo configure:1203: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char opendir (); -+int -+main () -+{ -+opendir (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_search_opendir="none required" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- LIBS="$LIBS -ldir" -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -+if test "$ac_cv_search_opendir" = no; then -+ for ac_lib in dir; do -+ LIBS="-l$ac_lib $ac_func_search_save_LIBS" -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ -+/* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif -+/* We use char because int might match the return type of a gcc2 -+ builtin and then its argument prototype would still apply. */ -+char opendir (); -+int -+main () -+{ -+opendir (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_search_opendir="-l$ac_lib" -+break - else -- echo "$ac_t""no" 1>&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+fi -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -+ done -+fi -+LIBS=$ac_func_search_save_LIBS -+fi -+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 -+echo "${ECHO_T}$ac_cv_search_opendir" >&6 -+if test "$ac_cv_search_opendir" != no; then -+ test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS" -+ - fi - - else --echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 --echo "configure:1225: checking for opendir in -lx" >&5 --ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ echo "$as_me:$LINENO: checking for library containing opendir" >&5 -+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6 -+if test "${ac_cv_search_opendir+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" --LIBS="-lx $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char opendir(); -- --int main() { --opendir() --; return 0; } --EOF --if { (eval echo configure:1244: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char opendir (); -+int -+main () -+{ -+opendir (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_search_opendir="none required" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- LIBS="$LIBS -lx" -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -+if test "$ac_cv_search_opendir" = no; then -+ for ac_lib in x; do -+ LIBS="-l$ac_lib $ac_func_search_save_LIBS" -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ -+/* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif -+/* We use char because int might match the return type of a gcc2 -+ builtin and then its argument prototype would still apply. */ -+char opendir (); -+int -+main () -+{ -+opendir (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_search_opendir="-l$ac_lib" -+break - else -- echo "$ac_t""no" 1>&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+fi -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -+ done - fi -+LIBS=$ac_func_search_save_LIBS -+fi -+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 -+echo "${ECHO_T}$ac_cv_search_opendir" >&6 -+if test "$ac_cv_search_opendir" != no; then -+ test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS" - - fi - --echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 --echo "configure:1267: checking how to run the C preprocessor" >&5 -+fi -+ -+ac_ext=c -+ac_cpp='$CPP $CPPFLAGS' -+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -+ac_compiler_gnu=$ac_cv_c_compiler_gnu -+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 - # On Suns, sometimes $CPP names a directory. - if test -n "$CPP" && test -d "$CPP"; then - CPP= - fi - if test -z "$CPP"; then --if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ if test "${ac_cv_prog_CPP+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- # This must be in double quotes, not single quotes, because CPP may get -- # substituted into the Makefile and "${CC-cc}" will confuse make. -- CPP="${CC-cc} -E" -+ # Double quotes because CPP needs to be expanded -+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" -+ do -+ ac_preproc_ok=false -+for ac_c_preproc_warn_flag in '' yes -+do -+ # Use a header file that comes with gcc, so configuring glibc -+ # with a fresh cross-compiler works. -+ # Prefer to if __STDC__ is defined, since -+ # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, -- # not just through cpp. -- cat > conftest.$ac_ext < --Syntax Error --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1288: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- : -+ # not just through cpp. "Syntax error" is here to catch this case. -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif -+ Syntax error -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- CPP="${CC-cc} -E -traditional-cpp" -- cat > conftest.$ac_ext < --Syntax Error --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1305: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -+ ac_cpp_err=yes -+fi -+if test -z "$ac_cpp_err"; then - : - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- CPP="${CC-cc} -nologo -E" -- cat > conftest.$ac_ext < --Syntax Error --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1322: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ # Broken: fails on valid input. -+continue -+fi -+rm -f conftest.err conftest.$ac_ext -+ -+ # OK, works on sane cases. Now check whether non-existent headers -+ # can be detected and how. -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes -+fi -+if test -z "$ac_cpp_err"; then -+ # Broken: success on invalid input. -+continue -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ # Passes both tests. -+ac_preproc_ok=: -+break -+fi -+rm -f conftest.err conftest.$ac_ext -+ -+done -+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -+rm -f conftest.err conftest.$ac_ext -+if $ac_preproc_ok; then -+ break -+fi -+ -+ done -+ ac_cv_prog_CPP=$CPP -+ -+fi -+ CPP=$ac_cv_prog_CPP -+else -+ ac_cv_prog_CPP=$CPP -+fi -+echo "$as_me:$LINENO: result: $CPP" >&5 -+echo "${ECHO_T}$CPP" >&6 -+ac_preproc_ok=false -+for ac_c_preproc_warn_flag in '' yes -+do -+ # Use a header file that comes with gcc, so configuring glibc -+ # with a fresh cross-compiler works. -+ # Prefer to if __STDC__ is defined, since -+ # exists even on freestanding compilers. -+ # On the NeXT, cc -E runs the code through the compiler's parser, -+ # not just through cpp. "Syntax error" is here to catch this case. -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif -+ Syntax error -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes -+fi -+if test -z "$ac_cpp_err"; then - : - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- CPP=/lib/cpp -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ # Broken: fails on valid input. -+continue - fi --rm -f conftest* -+rm -f conftest.err conftest.$ac_ext -+ -+ # OK, works on sane cases. Now check whether non-existent headers -+ # can be detected and how. -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --rm -f conftest* -+if test -z "$ac_cpp_err"; then -+ # Broken: success on invalid input. -+continue -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ # Passes both tests. -+ac_preproc_ok=: -+break - fi --rm -f conftest* -- ac_cv_prog_CPP="$CPP" -+rm -f conftest.err conftest.$ac_ext -+ -+done -+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -+rm -f conftest.err conftest.$ac_ext -+if $ac_preproc_ok; then -+ : -+else -+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -+See \`config.log' for more details." >&5 -+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } - fi -- CPP="$ac_cv_prog_CPP" -+ -+ac_ext=c -+ac_cpp='$CPP $CPPFLAGS' -+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -+ac_compiler_gnu=$ac_cv_c_compiler_gnu -+ -+ -+echo "$as_me:$LINENO: checking for egrep" >&5 -+echo $ECHO_N "checking for egrep... $ECHO_C" >&6 -+if test "${ac_cv_prog_egrep+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_cv_prog_CPP="$CPP" -+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1 -+ then ac_cv_prog_egrep='grep -E' -+ else ac_cv_prog_egrep='egrep' -+ fi - fi --echo "$ac_t""$CPP" 1>&6 -+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 -+echo "${ECHO_T}$ac_cv_prog_egrep" >&6 -+ EGREP=$ac_cv_prog_egrep - --echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 --echo "configure:1347: checking for ANSI C header files" >&5 --if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 -+if test "${ac_cv_header_stdc+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include - #include - #include - #include --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1360: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -+ -+int -+main () -+{ -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_header_stdc=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_header_stdc=no -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_header_stdc=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext - - if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include --EOF -+ -+_ACEOF - if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | -- egrep "memchr" >/dev/null 2>&1; then -+ $EGREP "memchr" >/dev/null 2>&1; then - : - else -- rm -rf conftest* - ac_cv_header_stdc=no - fi - rm -f conftest* -@@ -1390,16 +3920,20 @@ - - if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include --EOF -+ -+_ACEOF - if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | -- egrep "free" >/dev/null 2>&1; then -+ $EGREP "free" >/dev/null 2>&1; then - : - else -- rm -rf conftest* - ac_cv_header_stdc=no - fi - rm -f conftest* -@@ -1408,901 +3942,2658 @@ - - if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. --if test "$cross_compiling" = yes; then -+ if test "$cross_compiling" = yes; then - : - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include --#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') --#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) --#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) --int main () { int i; for (i = 0; i < 256; i++) --if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); --exit (0); } -+#if ((' ' & 0x0FF) == 0x020) -+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -+#else -+# define ISLOWER(c) \ -+ (('a' <= (c) && (c) <= 'i') \ -+ || ('j' <= (c) && (c) <= 'r') \ -+ || ('s' <= (c) && (c) <= 'z')) -+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -+#endif - --EOF --if { (eval echo configure:1427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null --then -+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -+int -+main () -+{ -+ int i; -+ for (i = 0; i < 256; i++) -+ if (XOR (islower (i), ISLOWER (i)) -+ || toupper (i) != TOUPPER (i)) -+ exit(2); -+ exit (0); -+} -+_ACEOF -+rm -f conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - : - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -fr conftest* -- ac_cv_header_stdc=no -+ echo "$as_me: program exited with status $ac_status" >&5 -+echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+( exit $ac_status ) -+ac_cv_header_stdc=no - fi --rm -fr conftest* -+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext - fi -- - fi - fi -- --echo "$ac_t""$ac_cv_header_stdc" 1>&6 -+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -+echo "${ECHO_T}$ac_cv_header_stdc" >&6 - if test $ac_cv_header_stdc = yes; then -- cat >> confdefs.h <<\EOF -+ -+cat >>confdefs.h <<\_ACEOF - #define STDC_HEADERS 1 --EOF -+_ACEOF - - fi - --echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 --echo "configure:1451: checking for sys/wait.h that is POSIX.1 compatible" >&5 --if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 -+echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6 -+if test "${ac_cv_header_sys_wait_h+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include - #include - #ifndef WEXITSTATUS --#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) -+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) - #endif - #ifndef WIFEXITED --#define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) - #endif --int main() { --int s; --wait (&s); --s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; --; return 0; } --EOF --if { (eval echo configure:1472: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then -- rm -rf conftest* -+ -+int -+main () -+{ -+ int s; -+ wait (&s); -+ s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_header_sys_wait_h=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_header_sys_wait_h=no -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_header_sys_wait_h=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext - fi -- --echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6 -+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 -+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 - if test $ac_cv_header_sys_wait_h = yes; then -- cat >> confdefs.h <<\EOF -+ -+cat >>confdefs.h <<\_ACEOF - #define HAVE_SYS_WAIT_H 1 --EOF -+_ACEOF - - fi - --for ac_hdr in fcntl.h limits.h sys/ioctl.h sys/time.h time.h unistd.h math.h ieee.h endian.h -+# On IRIX 5.3, sys/types and inttypes.h are conflicting. -+ -+ -+ -+ -+ -+ -+ -+ -+ -+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ -+ inttypes.h stdint.h unistd.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:1496: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1506: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+ -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_Header=yes" - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_Header=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ -+done -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+for ac_header in fcntl.h limits.h sys/ioctl.h sys/time.h time.h unistd.h math.h ieee.h endian.h -+do -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- echo "$ac_t""no" 1>&6 -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes -+fi -+if test -z "$ac_cpp_err"; then -+ ac_header_preproc=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - --for ac_hdr in values.h -+ -+for ac_header in values.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:1536: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1546: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - --for ac_hdr in sigaction.h -+ -+for ac_header in sigaction.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:1576: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1586: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - --for ac_hdr in netinet/in_systm.h -+ -+for ac_header in netinet/in_systm.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:1616: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1626: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - --for ac_hdr in netinet/in_system.h -+ -+for ac_header in netinet/in_system.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:1656: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1666: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - --for ac_hdr in netinet/ip.h -+ -+for ac_header in netinet/ip.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:1696: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1706: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - --for ac_hdr in sys/select.h -+ -+for ac_header in sys/select.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:1736: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1746: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no -+fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - --for ac_hdr in sys/resource.h -+ -+for ac_header in sys/resource.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:1776: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1786: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no -+fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - --for ac_hdr in sys/utsname.h -+ -+for ac_header in sys/utsname.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:1816: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1826: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no -+fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ - fi -+ - done - --for ac_hdr in sys/un.h -+ -+for ac_header in sys/un.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:1856: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1866: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no -+fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - --for ac_hdr in sys/fmutex.h -+ -+for ac_header in sys/fmutex.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:1896: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1906: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no -+fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - --for ac_hdr in sys/cygwin.h -+ -+for ac_header in sys/cygwin.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:1936: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1946: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - --for ac_hdr in io.h -+ -+for ac_header in io.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:1976: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:1986: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - --for ac_hdr in setjmp.h -+ -+for ac_header in setjmp.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:2016: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:2026: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - --for ac_hdr in langinfo.h -+ -+for ac_header in langinfo.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:2056: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:2066: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - - --echo $ac_n "checking for working const""... $ac_c" 1>&6 --echo "configure:2094: checking for working const" >&5 --if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 -+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 -+if test "${ac_cv_c_const+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - --int main() { -+int -+main () -+{ -+/* FIXME: Include the comments suggested by Paul. */ -+#ifndef __cplusplus -+ /* Ultrix mips cc rejects this. */ -+ typedef int charset[2]; -+ const charset x; -+ /* SunOS 4.1.1 cc rejects this. */ -+ char const *const *ccp; -+ char **p; -+ /* NEC SVR4.0.2 mips cc rejects this. */ -+ struct point {int x, y;}; -+ static struct point const zero = {0,0}; -+ /* AIX XL C 1.02.0.0 rejects this. -+ It does not let you subtract one const X* pointer from another in -+ an arm of an if-expression whose if-part is not a constant -+ expression */ -+ const char *g = "string"; -+ ccp = &g + (g ? g-g : 0); -+ /* HPUX 7.0 cc rejects these. */ -+ ++ccp; -+ p = (char**) ccp; -+ ccp = (char const *const *) p; -+ { /* SCO 3.2v4 cc rejects this. */ -+ char *t; -+ char const *s = 0 ? (char *) 0 : (char const *) 0; - --/* Ultrix mips cc rejects this. */ --typedef int charset[2]; const charset x; --/* SunOS 4.1.1 cc rejects this. */ --char const *const *ccp; --char **p; --/* NEC SVR4.0.2 mips cc rejects this. */ --struct point {int x, y;}; --static struct point const zero = {0,0}; --/* AIX XL C 1.02.0.0 rejects this. -- It does not let you subtract one const X* pointer from another in an arm -- of an if-expression whose if-part is not a constant expression */ --const char *g = "string"; --ccp = &g + (g ? g-g : 0); --/* HPUX 7.0 cc rejects these. */ --++ccp; --p = (char**) ccp; --ccp = (char const *const *) p; --{ /* SCO 3.2v4 cc rejects this. */ -- char *t; -- char const *s = 0 ? (char *) 0 : (char const *) 0; -+ *t++ = 0; -+ } -+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ -+ int x[] = {25, 17}; -+ const int *foo = &x[0]; -+ ++foo; -+ } -+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ -+ typedef const int *iptr; -+ iptr p = 0; -+ ++p; -+ } -+ { /* AIX XL C 1.02.0.0 rejects this saying -+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ -+ struct s { int j; const int *ap[3]; }; -+ struct s *b; b->j = 5; -+ } -+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ -+ const int foo = 10; -+ } -+#endif - -- *t++ = 0; --} --{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ -- int x[] = {25, 17}; -- const int *foo = &x[0]; -- ++foo; --} --{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ -- typedef const int *iptr; -- iptr p = 0; -- ++p; --} --{ /* AIX XL C 1.02.0.0 rejects this saying -- "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ -- struct s { int j; const int *ap[3]; }; -- struct s *b; b->j = 5; --} --{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ -- const int foo = 10; -+ ; -+ return 0; - } -- --; return 0; } --EOF --if { (eval echo configure:2148: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then -- rm -rf conftest* -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_c_const=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_c_const=no -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_c_const=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext - fi -- --echo "$ac_t""$ac_cv_c_const" 1>&6 -+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 -+echo "${ECHO_T}$ac_cv_c_const" >&6 - if test $ac_cv_c_const = no; then -- cat >> confdefs.h <<\EOF --#define const --EOF -+ -+cat >>confdefs.h <<\_ACEOF -+#define const -+_ACEOF - - fi - --echo $ac_n "checking for inline""... $ac_c" 1>&6 --echo "configure:2169: checking for inline" >&5 --if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for inline" >&5 -+echo $ECHO_N "checking for inline... $ECHO_C" >&6 -+if test "${ac_cv_c_inline+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else - ac_cv_c_inline=no - for ac_kw in inline __inline__ __inline; do -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#ifndef __cplusplus -+typedef int foo_t; -+static $ac_kw foo_t static_foo () {return 0; } -+$ac_kw foo_t foo () {return 0; } -+#endif - --int main() { --} $ac_kw foo() { --; return 0; } --EOF --if { (eval echo configure:2183: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then -- rm -rf conftest* -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_c_inline=$ac_kw; break - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext - done - - fi -- --echo "$ac_t""$ac_cv_c_inline" 1>&6 --case "$ac_cv_c_inline" in -+echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 -+echo "${ECHO_T}$ac_cv_c_inline" >&6 -+case $ac_cv_c_inline in - inline | yes) ;; -- no) cat >> confdefs.h <<\EOF --#define inline --EOF -+ no) -+cat >>confdefs.h <<\_ACEOF -+#define inline -+_ACEOF - ;; -- *) cat >> confdefs.h <>confdefs.h <<_ACEOF - #define inline $ac_cv_c_inline --EOF -+_ACEOF - ;; - esac - --echo $ac_n "checking for size_t""... $ac_c" 1>&6 --echo "configure:2209: checking for size_t" >&5 --if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for size_t" >&5 -+echo $ECHO_N "checking for size_t... $ECHO_C" >&6 -+if test "${ac_cv_type_size_t+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext < --#if STDC_HEADERS --#include --#include --#endif --EOF --if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | -- egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then -- rm -rf conftest* -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+if ((size_t *) 0) -+ return 0; -+if (sizeof (size_t)) -+ return 0; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_type_size_t=yes - else -- rm -rf conftest* -- ac_cv_type_size_t=no --fi --rm -f conftest* -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_type_size_t=no - fi --echo "$ac_t""$ac_cv_type_size_t" 1>&6 --if test $ac_cv_type_size_t = no; then -- cat >> confdefs.h <<\EOF -+rm -f conftest.$ac_objext conftest.$ac_ext -+fi -+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 -+echo "${ECHO_T}$ac_cv_type_size_t" >&6 -+if test $ac_cv_type_size_t = yes; then -+ : -+else -+ -+cat >>confdefs.h <<_ACEOF - #define size_t unsigned --EOF -+_ACEOF - - fi - --echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 --echo "configure:2242: checking whether time.h and sys/time.h may both be included" >&5 --if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 -+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 -+if test "${ac_cv_header_time+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include - #include - #include --int main() { --struct tm *tp; --; return 0; } --EOF --if { (eval echo configure:2256: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then -- rm -rf conftest* -+ -+int -+main () -+{ -+if ((struct tm *) 0) -+return 0; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_header_time=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_header_time=no -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_header_time=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext - fi -- --echo "$ac_t""$ac_cv_header_time" 1>&6 -+echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 -+echo "${ECHO_T}$ac_cv_header_time" >&6 - if test $ac_cv_header_time = yes; then -- cat >> confdefs.h <<\EOF -+ -+cat >>confdefs.h <<\_ACEOF - #define TIME_WITH_SYS_TIME 1 --EOF -+_ACEOF - - fi - --echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6 --echo "configure:2277: checking whether struct tm is in sys/time.h or time.h" >&5 --if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5 -+echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6 -+if test "${ac_cv_struct_tm+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include - #include --int main() { -+ -+int -+main () -+{ - struct tm *tp; tp->tm_sec; --; return 0; } --EOF --if { (eval echo configure:2290: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then -- rm -rf conftest* -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_struct_tm=time.h - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_struct_tm=sys/time.h -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_struct_tm=sys/time.h - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext - fi -- --echo "$ac_t""$ac_cv_struct_tm" 1>&6 -+echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 -+echo "${ECHO_T}$ac_cv_struct_tm" >&6 - if test $ac_cv_struct_tm = sys/time.h; then -- cat >> confdefs.h <<\EOF -+ -+cat >>confdefs.h <<\_ACEOF - #define TM_IN_SYS_TIME 1 --EOF -+_ACEOF - - fi - -@@ -2315,251 +6606,2187 @@ - default_int=0 - fi - --echo $ac_n "checking size of short""... $ac_c" 1>&6 --echo "configure:2320: checking size of short" >&5 --if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for short" >&5 -+echo $ECHO_N "checking for short... $ECHO_C" >&6 -+if test "${ac_cv_type_short+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+if ((short *) 0) -+ return 0; -+if (sizeof (short)) -+ return 0; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_type_short=yes - else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_type_short=no -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+fi -+echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5 -+echo "${ECHO_T}$ac_cv_type_short" >&6 -+ -+echo "$as_me:$LINENO: checking size of short" >&5 -+echo $ECHO_N "checking size of short... $ECHO_C" >&6 -+if test "${ac_cv_sizeof_short+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test "$ac_cv_type_short" = yes; then -+ # The cast to unsigned long works around a bug in the HP C Compiler -+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -+ # This bug is HP SR number 8606223364. - if test "$cross_compiling" = yes; then -- ac_cv_sizeof_short="$default_short" -+ # Depending upon the size, compute the lo and hi bounds. -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (short))) >= 0)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_lo=0 ac_mid=0 -+ while :; do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=$ac_mid; break - else -- cat > conftest.$ac_ext <&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo=`expr $ac_mid + 1` -+ if test $ac_lo -le $ac_mid; then -+ ac_lo= ac_hi= -+ break -+ fi -+ ac_mid=`expr 2 '*' $ac_mid + 1` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ done -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (short))) < 0)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=-1 ac_mid=-1 -+ while :; do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (short))) >= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_lo=$ac_mid; break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_hi=`expr '(' $ac_mid ')' - 1` -+ if test $ac_mid -le $ac_hi; then -+ ac_lo= ac_hi= -+ break -+ fi -+ ac_mid=`expr 2 '*' $ac_mid` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ done -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo= ac_hi= -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+# Binary search between lo and hi bounds. -+while test "x$ac_lo" != "x$ac_hi"; do -+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=$ac_mid -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo=`expr '(' $ac_mid ')' + 1` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+done -+case $ac_lo in -+?*) ac_cv_sizeof_short=$ac_lo;; -+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77 -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute sizeof (short), 77 -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } ;; -+esac -+else -+ if test "$cross_compiling" = yes; then -+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot run test program while cross compiling -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } -+else -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+long longval () { return (long) (sizeof (short)); } -+unsigned long ulongval () { return (long) (sizeof (short)); } - #include --main() -+#include -+int -+main () - { -- FILE *f=fopen("conftestval", "w"); -- if (!f) exit(1); -- fprintf(f, "%d\n", sizeof(short)); -- exit(0); -+ -+ FILE *f = fopen ("conftest.val", "w"); -+ if (! f) -+ exit (1); -+ if (((long) (sizeof (short))) < 0) -+ { -+ long i = longval (); -+ if (i != ((long) (sizeof (short)))) -+ exit (1); -+ fprintf (f, "%ld\n", i); -+ } -+ else -+ { -+ unsigned long i = ulongval (); -+ if (i != ((long) (sizeof (short)))) -+ exit (1); -+ fprintf (f, "%lu\n", i); -+ } -+ exit (ferror (f) || fclose (f) != 0); -+ -+ ; -+ return 0; - } --EOF --if { (eval echo configure:2339: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null --then -- ac_cv_sizeof_short=`cat conftestval` -+_ACEOF -+rm -f conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_sizeof_short=`cat conftest.val` -+else -+ echo "$as_me: program exited with status $ac_status" >&5 -+echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+( exit $ac_status ) -+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77 -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute sizeof (short), 77 -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } -+fi -+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -+fi -+fi -+rm -f conftest.val - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -fr conftest* - ac_cv_sizeof_short=0 - fi --rm -fr conftest* - fi -+echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5 -+echo "${ECHO_T}$ac_cv_sizeof_short" >&6 -+cat >>confdefs.h <<_ACEOF -+#define SIZEOF_SHORT $ac_cv_sizeof_short -+_ACEOF -+ - -+echo "$as_me:$LINENO: checking for unsigned short" >&5 -+echo $ECHO_N "checking for unsigned short... $ECHO_C" >&6 -+if test "${ac_cv_type_unsigned_short+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+if ((unsigned short *) 0) -+ return 0; -+if (sizeof (unsigned short)) -+ return 0; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_type_unsigned_short=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_type_unsigned_short=no - fi --echo "$ac_t""$ac_cv_sizeof_short" 1>&6 --cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_type_unsigned_short" >&6 - -+echo "$as_me:$LINENO: checking size of unsigned short" >&5 -+echo $ECHO_N "checking size of unsigned short... $ECHO_C" >&6 -+if test "${ac_cv_sizeof_unsigned_short+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test "$ac_cv_type_unsigned_short" = yes; then -+ # The cast to unsigned long works around a bug in the HP C Compiler -+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -+ # This bug is HP SR number 8606223364. -+ if test "$cross_compiling" = yes; then -+ # Depending upon the size, compute the lo and hi bounds. -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned short))) >= 0)]; -+test_array [0] = 0 - --echo $ac_n "checking size of unsigned short""... $ac_c" 1>&6 --echo "configure:2359: checking size of unsigned short" >&5 --if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_short'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_lo=0 ac_mid=0 -+ while :; do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned short))) <= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=$ac_mid; break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo=`expr $ac_mid + 1` -+ if test $ac_lo -le $ac_mid; then -+ ac_lo= ac_hi= -+ break -+ fi -+ ac_mid=`expr 2 '*' $ac_mid + 1` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ done -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned short))) < 0)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=-1 ac_mid=-1 -+ while :; do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned short))) >= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_lo=$ac_mid; break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_hi=`expr '(' $ac_mid ')' - 1` -+ if test $ac_mid -le $ac_hi; then -+ ac_lo= ac_hi= -+ break -+ fi -+ ac_mid=`expr 2 '*' $ac_mid` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ done -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo= ac_hi= -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+# Binary search between lo and hi bounds. -+while test "x$ac_lo" != "x$ac_hi"; do -+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned short))) <= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=$ac_mid -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo=`expr '(' $ac_mid ')' + 1` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+done -+case $ac_lo in -+?*) ac_cv_sizeof_unsigned_short=$ac_lo;; -+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned short), 77 -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute sizeof (unsigned short), 77 -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } ;; -+esac - else - if test "$cross_compiling" = yes; then -- ac_cv_sizeof_unsigned_short="$default_short" -+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot run test program while cross compiling -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+long longval () { return (long) (sizeof (unsigned short)); } -+unsigned long ulongval () { return (long) (sizeof (unsigned short)); } - #include --main() -+#include -+int -+main () - { -- FILE *f=fopen("conftestval", "w"); -- if (!f) exit(1); -- fprintf(f, "%d\n", sizeof(unsigned short)); -- exit(0); -+ -+ FILE *f = fopen ("conftest.val", "w"); -+ if (! f) -+ exit (1); -+ if (((long) (sizeof (unsigned short))) < 0) -+ { -+ long i = longval (); -+ if (i != ((long) (sizeof (unsigned short)))) -+ exit (1); -+ fprintf (f, "%ld\n", i); -+ } -+ else -+ { -+ unsigned long i = ulongval (); -+ if (i != ((long) (sizeof (unsigned short)))) -+ exit (1); -+ fprintf (f, "%lu\n", i); -+ } -+ exit (ferror (f) || fclose (f) != 0); -+ -+ ; -+ return 0; - } --EOF --if { (eval echo configure:2378: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null --then -- ac_cv_sizeof_unsigned_short=`cat conftestval` -+_ACEOF -+rm -f conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_sizeof_unsigned_short=`cat conftest.val` -+else -+ echo "$as_me: program exited with status $ac_status" >&5 -+echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+( exit $ac_status ) -+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned short), 77 -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute sizeof (unsigned short), 77 -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } -+fi -+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -+fi -+fi -+rm -f conftest.val - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -fr conftest* - ac_cv_sizeof_unsigned_short=0 - fi --rm -fr conftest* - fi -+echo "$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_short" >&5 -+echo "${ECHO_T}$ac_cv_sizeof_unsigned_short" >&6 -+cat >>confdefs.h <<_ACEOF -+#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short -+_ACEOF -+ - -+echo "$as_me:$LINENO: checking for int" >&5 -+echo $ECHO_N "checking for int... $ECHO_C" >&6 -+if test "${ac_cv_type_int+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+if ((int *) 0) -+ return 0; -+if (sizeof (int)) -+ return 0; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_type_int=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_type_int=no - fi --echo "$ac_t""$ac_cv_sizeof_unsigned_short" 1>&6 --cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_type_int" >&6 - -+echo "$as_me:$LINENO: checking size of int" >&5 -+echo $ECHO_N "checking size of int... $ECHO_C" >&6 -+if test "${ac_cv_sizeof_int+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test "$ac_cv_type_int" = yes; then -+ # The cast to unsigned long works around a bug in the HP C Compiler -+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -+ # This bug is HP SR number 8606223364. -+ if test "$cross_compiling" = yes; then -+ # Depending upon the size, compute the lo and hi bounds. -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)]; -+test_array [0] = 0 - --echo $ac_n "checking size of int""... $ac_c" 1>&6 --echo "configure:2398: checking size of int" >&5 --if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_lo=0 ac_mid=0 -+ while :; do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=$ac_mid; break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo=`expr $ac_mid + 1` -+ if test $ac_lo -le $ac_mid; then -+ ac_lo= ac_hi= -+ break -+ fi -+ ac_mid=`expr 2 '*' $ac_mid + 1` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ done -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=-1 ac_mid=-1 -+ while :; do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_lo=$ac_mid; break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_hi=`expr '(' $ac_mid ')' - 1` -+ if test $ac_mid -le $ac_hi; then -+ ac_lo= ac_hi= -+ break -+ fi -+ ac_mid=`expr 2 '*' $ac_mid` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ done -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo= ac_hi= -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+# Binary search between lo and hi bounds. -+while test "x$ac_lo" != "x$ac_hi"; do -+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=$ac_mid -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo=`expr '(' $ac_mid ')' + 1` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+done -+case $ac_lo in -+?*) ac_cv_sizeof_int=$ac_lo;; -+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77 -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute sizeof (int), 77 -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } ;; -+esac - else - if test "$cross_compiling" = yes; then -- ac_cv_sizeof_int="$default_int" -+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot run test program while cross compiling -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+long longval () { return (long) (sizeof (int)); } -+unsigned long ulongval () { return (long) (sizeof (int)); } - #include --main() -+#include -+int -+main () - { -- FILE *f=fopen("conftestval", "w"); -- if (!f) exit(1); -- fprintf(f, "%d\n", sizeof(int)); -- exit(0); -+ -+ FILE *f = fopen ("conftest.val", "w"); -+ if (! f) -+ exit (1); -+ if (((long) (sizeof (int))) < 0) -+ { -+ long i = longval (); -+ if (i != ((long) (sizeof (int)))) -+ exit (1); -+ fprintf (f, "%ld\n", i); -+ } -+ else -+ { -+ unsigned long i = ulongval (); -+ if (i != ((long) (sizeof (int)))) -+ exit (1); -+ fprintf (f, "%lu\n", i); -+ } -+ exit (ferror (f) || fclose (f) != 0); -+ -+ ; -+ return 0; - } --EOF --if { (eval echo configure:2417: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null --then -- ac_cv_sizeof_int=`cat conftestval` -+_ACEOF -+rm -f conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_sizeof_int=`cat conftest.val` -+else -+ echo "$as_me: program exited with status $ac_status" >&5 -+echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+( exit $ac_status ) -+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77 -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute sizeof (int), 77 -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } -+fi -+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -+fi -+fi -+rm -f conftest.val - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -fr conftest* - ac_cv_sizeof_int=0 - fi --rm -fr conftest* - fi -+echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 -+echo "${ECHO_T}$ac_cv_sizeof_int" >&6 -+cat >>confdefs.h <<_ACEOF -+#define SIZEOF_INT $ac_cv_sizeof_int -+_ACEOF -+ - -+echo "$as_me:$LINENO: checking for unsigned" >&5 -+echo $ECHO_N "checking for unsigned... $ECHO_C" >&6 -+if test "${ac_cv_type_unsigned+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+if ((unsigned *) 0) -+ return 0; -+if (sizeof (unsigned)) -+ return 0; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_type_unsigned=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_type_unsigned=no - fi --echo "$ac_t""$ac_cv_sizeof_int" 1>&6 --cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_type_unsigned" >&6 - -+echo "$as_me:$LINENO: checking size of unsigned" >&5 -+echo $ECHO_N "checking size of unsigned... $ECHO_C" >&6 -+if test "${ac_cv_sizeof_unsigned+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test "$ac_cv_type_unsigned" = yes; then -+ # The cast to unsigned long works around a bug in the HP C Compiler -+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -+ # This bug is HP SR number 8606223364. -+ if test "$cross_compiling" = yes; then -+ # Depending upon the size, compute the lo and hi bounds. -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned))) >= 0)]; -+test_array [0] = 0 - --echo $ac_n "checking size of unsigned""... $ac_c" 1>&6 --echo "configure:2437: checking size of unsigned" >&5 --if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_lo=0 ac_mid=0 -+ while :; do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned))) <= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=$ac_mid; break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo=`expr $ac_mid + 1` -+ if test $ac_lo -le $ac_mid; then -+ ac_lo= ac_hi= -+ break -+ fi -+ ac_mid=`expr 2 '*' $ac_mid + 1` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ done -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned))) < 0)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=-1 ac_mid=-1 -+ while :; do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned))) >= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_lo=$ac_mid; break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_hi=`expr '(' $ac_mid ')' - 1` -+ if test $ac_mid -le $ac_hi; then -+ ac_lo= ac_hi= -+ break -+ fi -+ ac_mid=`expr 2 '*' $ac_mid` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ done -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo= ac_hi= -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+# Binary search between lo and hi bounds. -+while test "x$ac_lo" != "x$ac_hi"; do -+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned))) <= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=$ac_mid -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo=`expr '(' $ac_mid ')' + 1` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+done -+case $ac_lo in -+?*) ac_cv_sizeof_unsigned=$ac_lo;; -+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned), 77 -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute sizeof (unsigned), 77 -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } ;; -+esac - else - if test "$cross_compiling" = yes; then -- ac_cv_sizeof_unsigned="$default_int" -+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot run test program while cross compiling -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+long longval () { return (long) (sizeof (unsigned)); } -+unsigned long ulongval () { return (long) (sizeof (unsigned)); } - #include --main() -+#include -+int -+main () - { -- FILE *f=fopen("conftestval", "w"); -- if (!f) exit(1); -- fprintf(f, "%d\n", sizeof(unsigned)); -- exit(0); -+ -+ FILE *f = fopen ("conftest.val", "w"); -+ if (! f) -+ exit (1); -+ if (((long) (sizeof (unsigned))) < 0) -+ { -+ long i = longval (); -+ if (i != ((long) (sizeof (unsigned)))) -+ exit (1); -+ fprintf (f, "%ld\n", i); -+ } -+ else -+ { -+ unsigned long i = ulongval (); -+ if (i != ((long) (sizeof (unsigned)))) -+ exit (1); -+ fprintf (f, "%lu\n", i); -+ } -+ exit (ferror (f) || fclose (f) != 0); -+ -+ ; -+ return 0; - } --EOF --if { (eval echo configure:2456: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null --then -- ac_cv_sizeof_unsigned=`cat conftestval` -+_ACEOF -+rm -f conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_sizeof_unsigned=`cat conftest.val` -+else -+ echo "$as_me: program exited with status $ac_status" >&5 -+echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+( exit $ac_status ) -+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned), 77 -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute sizeof (unsigned), 77 -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } -+fi -+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -+fi -+fi -+rm -f conftest.val - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -fr conftest* - ac_cv_sizeof_unsigned=0 - fi --rm -fr conftest* - fi -+echo "$as_me:$LINENO: result: $ac_cv_sizeof_unsigned" >&5 -+echo "${ECHO_T}$ac_cv_sizeof_unsigned" >&6 -+cat >>confdefs.h <<_ACEOF -+#define SIZEOF_UNSIGNED $ac_cv_sizeof_unsigned -+_ACEOF -+ -+ -+echo "$as_me:$LINENO: checking for long" >&5 -+echo $ECHO_N "checking for long... $ECHO_C" >&6 -+if test "${ac_cv_type_long+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+if ((long *) 0) -+ return 0; -+if (sizeof (long)) -+ return 0; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_type_long=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_type_long=no - fi --echo "$ac_t""$ac_cv_sizeof_unsigned" 1>&6 --cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_type_long" >&6 - -+echo "$as_me:$LINENO: checking size of long" >&5 -+echo $ECHO_N "checking size of long... $ECHO_C" >&6 -+if test "${ac_cv_sizeof_long+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test "$ac_cv_type_long" = yes; then -+ # The cast to unsigned long works around a bug in the HP C Compiler -+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -+ # This bug is HP SR number 8606223364. -+ if test "$cross_compiling" = yes; then -+ # Depending upon the size, compute the lo and hi bounds. -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)]; -+test_array [0] = 0 - --echo $ac_n "checking size of long""... $ac_c" 1>&6 --echo "configure:2476: checking size of long" >&5 --if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_lo=0 ac_mid=0 -+ while :; do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=$ac_mid; break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo=`expr $ac_mid + 1` -+ if test $ac_lo -le $ac_mid; then -+ ac_lo= ac_hi= -+ break -+ fi -+ ac_mid=`expr 2 '*' $ac_mid + 1` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ done -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=-1 ac_mid=-1 -+ while :; do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_lo=$ac_mid; break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_hi=`expr '(' $ac_mid ')' - 1` -+ if test $ac_mid -le $ac_hi; then -+ ac_lo= ac_hi= -+ break -+ fi -+ ac_mid=`expr 2 '*' $ac_mid` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ done -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo= ac_hi= -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+# Binary search between lo and hi bounds. -+while test "x$ac_lo" != "x$ac_hi"; do -+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=$ac_mid -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo=`expr '(' $ac_mid ')' + 1` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+done -+case $ac_lo in -+?*) ac_cv_sizeof_long=$ac_lo;; -+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77 -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute sizeof (long), 77 -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } ;; -+esac - else - if test "$cross_compiling" = yes; then -- ac_cv_sizeof_long="$default_int" -+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot run test program while cross compiling -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+long longval () { return (long) (sizeof (long)); } -+unsigned long ulongval () { return (long) (sizeof (long)); } - #include --main() -+#include -+int -+main () - { -- FILE *f=fopen("conftestval", "w"); -- if (!f) exit(1); -- fprintf(f, "%d\n", sizeof(long)); -- exit(0); -+ -+ FILE *f = fopen ("conftest.val", "w"); -+ if (! f) -+ exit (1); -+ if (((long) (sizeof (long))) < 0) -+ { -+ long i = longval (); -+ if (i != ((long) (sizeof (long)))) -+ exit (1); -+ fprintf (f, "%ld\n", i); -+ } -+ else -+ { -+ unsigned long i = ulongval (); -+ if (i != ((long) (sizeof (long)))) -+ exit (1); -+ fprintf (f, "%lu\n", i); -+ } -+ exit (ferror (f) || fclose (f) != 0); -+ -+ ; -+ return 0; - } --EOF --if { (eval echo configure:2495: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null --then -- ac_cv_sizeof_long=`cat conftestval` -+_ACEOF -+rm -f conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_sizeof_long=`cat conftest.val` -+else -+ echo "$as_me: program exited with status $ac_status" >&5 -+echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+( exit $ac_status ) -+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77 -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute sizeof (long), 77 -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } -+fi -+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -+fi -+fi -+rm -f conftest.val - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -fr conftest* - ac_cv_sizeof_long=0 - fi --rm -fr conftest* - fi -+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 -+echo "${ECHO_T}$ac_cv_sizeof_long" >&6 -+cat >>confdefs.h <<_ACEOF -+#define SIZEOF_LONG $ac_cv_sizeof_long -+_ACEOF -+ - -+echo "$as_me:$LINENO: checking for unsigned long" >&5 -+echo $ECHO_N "checking for unsigned long... $ECHO_C" >&6 -+if test "${ac_cv_type_unsigned_long+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+if ((unsigned long *) 0) -+ return 0; -+if (sizeof (unsigned long)) -+ return 0; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_type_unsigned_long=yes -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_type_unsigned_long=no - fi --echo "$ac_t""$ac_cv_sizeof_long" 1>&6 --cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_type_unsigned_long" >&6 - -+echo "$as_me:$LINENO: checking size of unsigned long" >&5 -+echo $ECHO_N "checking size of unsigned long... $ECHO_C" >&6 -+if test "${ac_cv_sizeof_unsigned_long+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test "$ac_cv_type_unsigned_long" = yes; then -+ # The cast to unsigned long works around a bug in the HP C Compiler -+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -+ # This bug is HP SR number 8606223364. -+ if test "$cross_compiling" = yes; then -+ # Depending upon the size, compute the lo and hi bounds. -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) >= 0)]; -+test_array [0] = 0 - --echo $ac_n "checking size of unsigned long""... $ac_c" 1>&6 --echo "configure:2515: checking size of unsigned long" >&5 --if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_long'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_lo=0 ac_mid=0 -+ while :; do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) <= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=$ac_mid; break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo=`expr $ac_mid + 1` -+ if test $ac_lo -le $ac_mid; then -+ ac_lo= ac_hi= -+ break -+ fi -+ ac_mid=`expr 2 '*' $ac_mid + 1` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ done -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) < 0)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=-1 ac_mid=-1 -+ while :; do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) >= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_lo=$ac_mid; break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_hi=`expr '(' $ac_mid ')' - 1` -+ if test $ac_mid -le $ac_hi; then -+ ac_lo= ac_hi= -+ break -+ fi -+ ac_mid=`expr 2 '*' $ac_mid` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ done -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo= ac_hi= -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+# Binary search between lo and hi bounds. -+while test "x$ac_lo" != "x$ac_hi"; do -+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+int -+main () -+{ -+static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) <= $ac_mid)]; -+test_array [0] = 0 -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_hi=$ac_mid -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_lo=`expr '(' $ac_mid ')' + 1` -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+done -+case $ac_lo in -+?*) ac_cv_sizeof_unsigned_long=$ac_lo;; -+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long), 77 -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute sizeof (unsigned long), 77 -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } ;; -+esac - else - if test "$cross_compiling" = yes; then -- ac_cv_sizeof_unsigned_long="$default_int" -+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot run test program while cross compiling -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+long longval () { return (long) (sizeof (unsigned long)); } -+unsigned long ulongval () { return (long) (sizeof (unsigned long)); } - #include --main() -+#include -+int -+main () - { -- FILE *f=fopen("conftestval", "w"); -- if (!f) exit(1); -- fprintf(f, "%d\n", sizeof(unsigned long)); -- exit(0); -+ -+ FILE *f = fopen ("conftest.val", "w"); -+ if (! f) -+ exit (1); -+ if (((long) (sizeof (unsigned long))) < 0) -+ { -+ long i = longval (); -+ if (i != ((long) (sizeof (unsigned long)))) -+ exit (1); -+ fprintf (f, "%ld\n", i); -+ } -+ else -+ { -+ unsigned long i = ulongval (); -+ if (i != ((long) (sizeof (unsigned long)))) -+ exit (1); -+ fprintf (f, "%lu\n", i); -+ } -+ exit (ferror (f) || fclose (f) != 0); -+ -+ ; -+ return 0; - } --EOF --if { (eval echo configure:2534: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null --then -- ac_cv_sizeof_unsigned_long=`cat conftestval` -+_ACEOF -+rm -f conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_sizeof_unsigned_long=`cat conftest.val` - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -fr conftest* -- ac_cv_sizeof_unsigned_long=0 -+ echo "$as_me: program exited with status $ac_status" >&5 -+echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+( exit $ac_status ) -+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long), 77 -+See \`config.log' for more details." >&5 -+echo "$as_me: error: cannot compute sizeof (unsigned long), 77 -+See \`config.log' for more details." >&2;} -+ { (exit 1); exit 1; }; } - fi --rm -fr conftest* -+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext - fi -- - fi --echo "$ac_t""$ac_cv_sizeof_unsigned_long" 1>&6 --cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_sizeof_unsigned_long" >&6 -+cat >>confdefs.h <<_ACEOF - #define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long --EOF -+_ACEOF - - --echo $ac_n "checking for big endian""... $ac_c" 1>&6 --echo "configure:2554: checking for big endian" >&5 --if eval "test \"`echo '$''{'ac_cv_big_endian'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for big endian" >&5 -+echo $ECHO_N "checking for big endian... $ECHO_C" >&6 -+if test "${ac_cv_big_endian+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else - if test "$cross_compiling" = yes; then - ac_cv_big_endian=no - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - - long l; - char *c = (char *)&l; -@@ -2568,35 +8795,49 @@ - l = 0x12345678L; - return !(c[sizeof(long) - 1] == 0x78 && c[sizeof(long) - 2] == 0x56 && c[sizeof(long) - 3] == 0x34 && c[sizeof(long) - 4] == 0x12); - } -- --EOF --if { (eval echo configure:2574: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null --then -+ -+_ACEOF -+rm -f conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_big_endian=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -fr conftest* -- ac_cv_big_endian=no -+ echo "$as_me: program exited with status $ac_status" >&5 -+echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+( exit $ac_status ) -+ac_cv_big_endian=no - fi --rm -fr conftest* -+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext - fi - -- - fi -- --echo "$ac_t""$ac_cv_big_endian" 1>&6 --echo $ac_n "checking for little endian""... $ac_c" 1>&6 --echo "configure:2591: checking for little endian" >&5 --if eval "test \"`echo '$''{'ac_cv_little_endian'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: result: $ac_cv_big_endian" >&5 -+echo "${ECHO_T}$ac_cv_big_endian" >&6 -+echo "$as_me:$LINENO: checking for little endian" >&5 -+echo $ECHO_N "checking for little endian... $ECHO_C" >&6 -+if test "${ac_cv_little_endian+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else - if test "$cross_compiling" = yes; then - ac_cv_little_endian="$ac_cv_have_emx" - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - - long l; - char *c = (char *)&l; -@@ -2605,133 +8846,194 @@ - l = 0x12345678L; - return !(c[0] == 0x78 && c[1] == 0x56 && c[2] == 0x34 && c[3] == 0x12); - } -- --EOF --if { (eval echo configure:2611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null --then -+ -+_ACEOF -+rm -f conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_little_endian=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -fr conftest* -- ac_cv_little_endian=no -+ echo "$as_me: program exited with status $ac_status" >&5 -+echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+( exit $ac_status ) -+ac_cv_little_endian=no - fi --rm -fr conftest* -+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext - fi - -- - fi -+echo "$as_me:$LINENO: result: $ac_cv_little_endian" >&5 -+echo "${ECHO_T}$ac_cv_little_endian" >&6 -+ -+ - --echo "$ac_t""$ac_cv_little_endian" 1>&6 - - if test "$ac_cv_big_endian" = yes; then -- cat >> confdefs.h <<\EOF --#define AC_BIG_ENDIAN 1 --EOF -+ cat >>confdefs.h <<\_ACEOF -+#define 1 -+_ACEOF - - else if test "$ac_cv_little_endian" = yes; then -- cat >> confdefs.h <<\EOF --#define AC_LITTLE_ENDIAN 1 --EOF -+ cat >>confdefs.h <<\_ACEOF -+#define 1 -+_ACEOF - - fi - fi - --if test $ac_cv_prog_gcc = yes; then -- echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 --echo "configure:2643: checking whether ${CC-cc} needs -traditional" >&5 --if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+if test $ac_cv_c_compiler_gnu = yes; then -+ echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 -+echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6 -+if test "${ac_cv_prog_gcc_traditional+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else - ac_pattern="Autoconf.*'x'" -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include - Autoconf TIOCGETP --EOF -+_ACEOF - if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | -- egrep "$ac_pattern" >/dev/null 2>&1; then -- rm -rf conftest* -+ $EGREP "$ac_pattern" >/dev/null 2>&1; then - ac_cv_prog_gcc_traditional=yes - else -- rm -rf conftest* - ac_cv_prog_gcc_traditional=no - fi - rm -f conftest* - - - if test $ac_cv_prog_gcc_traditional = no; then -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include - Autoconf TCGETA --EOF -+_ACEOF - if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | -- egrep "$ac_pattern" >/dev/null 2>&1; then -- rm -rf conftest* -+ $EGREP "$ac_pattern" >/dev/null 2>&1; then - ac_cv_prog_gcc_traditional=yes - fi - rm -f conftest* - - fi - fi -- --echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6 -+echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 -+echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6 - if test $ac_cv_prog_gcc_traditional = yes; then - CC="$CC -traditional" - fi - fi - --echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 --echo "configure:2689: checking for 8-bit clean memcmp" >&5 --if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for working memcmp" >&5 -+echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6 -+if test "${ac_cv_func_memcmp_working+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else - if test "$cross_compiling" = yes; then -- ac_cv_func_memcmp_clean=no -+ ac_cv_func_memcmp_working=no - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - --main() -+int -+main () - { -+ -+ /* Some versions of memcmp are not 8-bit clean. */ - char c0 = 0x40, c1 = 0x80, c2 = 0x81; -- exit(memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0 ? 0 : 1); --} -+ if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) -+ exit (1); - --EOF --if { (eval echo configure:2707: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null --then -- ac_cv_func_memcmp_clean=yes -+ /* The Next x86 OpenStep bug shows up only when comparing 16 bytes -+ or more and with at least one buffer not starting on a 4-byte boundary. -+ William Lewis provided this test program. */ -+ { -+ char foo[21]; -+ char bar[21]; -+ int i; -+ for (i = 0; i < 4; i++) -+ { -+ char *a = foo + i; -+ char *b = bar + i; -+ strcpy (a, "--------01111111"); -+ strcpy (b, "--------10000000"); -+ if (memcmp (a, b, 16) >= 0) -+ exit (1); -+ } -+ exit (0); -+ } -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_func_memcmp_working=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -fr conftest* -- ac_cv_func_memcmp_clean=no -+ echo "$as_me: program exited with status $ac_status" >&5 -+echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+( exit $ac_status ) -+ac_cv_func_memcmp_working=no - fi --rm -fr conftest* -+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext - fi -- - fi -+echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5 -+echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6 -+test $ac_cv_func_memcmp_working = no && LIBOBJS="$LIBOBJS memcmp.$ac_objext" - --echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6 --test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}" -- --echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 --echo "configure:2725: checking return type of signal handlers" >&5 --if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking return type of signal handlers" >&5 -+echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6 -+if test "${ac_cv_type_signal+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include - #include - #ifdef signal --#undef signal -+# undef signal - #endif - #ifdef __cplusplus - extern "C" void (*signal (int, void (*)(int)))(int); -@@ -2739,1144 +9041,1737 @@ - void (*signal ()) (); - #endif - --int main() { -+int -+main () -+{ - int i; --; return 0; } --EOF --if { (eval echo configure:2747: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then -- rm -rf conftest* -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_type_signal=void - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_type_signal=int -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_type_signal=int - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 -+echo "${ECHO_T}$ac_cv_type_signal" >&6 - --echo "$ac_t""$ac_cv_type_signal" 1>&6 --cat >> confdefs.h <>confdefs.h <<_ACEOF - #define RETSIGTYPE $ac_cv_type_signal --EOF -+_ACEOF - - --echo $ac_n "checking for strftime""... $ac_c" 1>&6 --echo "configure:2766: checking for strftime" >&5 --if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+for ac_func in strftime -+do -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char strftime(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char strftime(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ --#if defined (__stub_strftime) || defined (__stub___strftime) -+#if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --strftime(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:2794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_strftime=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_strftime=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -- --if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- cat >> confdefs.h <<\EOF --#define HAVE_STRFTIME 1 --EOF -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - - else -- echo "$ac_t""no" 1>&6 --# strftime is in -lintl on SCO UNIX. --echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6 --echo "configure:2816: checking for strftime in -lintl" >&5 --ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ # strftime is in -lintl on SCO UNIX. -+echo "$as_me:$LINENO: checking for strftime in -lintl" >&5 -+echo $ECHO_N "checking for strftime in -lintl... $ECHO_C" >&6 -+if test "${ac_cv_lib_intl_strftime+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-lintl $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char strftime(); -- --int main() { --strftime() --; return 0; } --EOF --if { (eval echo configure:2835: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char strftime (); -+int -+main () -+{ -+strftime (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_intl_strftime=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_intl_strftime=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- cat >> confdefs.h <<\EOF -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -+LIBS=$ac_check_lib_save_LIBS -+fi -+echo "$as_me:$LINENO: result: $ac_cv_lib_intl_strftime" >&5 -+echo "${ECHO_T}$ac_cv_lib_intl_strftime" >&6 -+if test $ac_cv_lib_intl_strftime = yes; then -+ cat >>confdefs.h <<\_ACEOF - #define HAVE_STRFTIME 1 --EOF -+_ACEOF - - LIBS="-lintl $LIBS" --else -- echo "$ac_t""no" 1>&6 - fi - - fi -+done - --echo $ac_n "checking for vprintf""... $ac_c" 1>&6 --echo "configure:2862: checking for vprintf" >&5 --if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+for ac_func in vprintf -+do -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char vprintf(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char vprintf(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ --#if defined (__stub_vprintf) || defined (__stub___vprintf) -+#if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --vprintf(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:2890: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_vprintf=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_vprintf=no" --fi --rm -f conftest* --fi -- --if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- cat >> confdefs.h <<\EOF --#define HAVE_VPRINTF 1 --EOF -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - --else -- echo "$ac_t""no" 1>&6 -+eval "$as_ac_var=no" -+fi -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if test "$ac_cv_func_vprintf" != yes; then --echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 --echo "configure:2914: checking for _doprnt" >&5 --if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for _doprnt" >&5 -+echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6 -+if test "${ac_cv_func__doprnt+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char _doprnt(); below. */ --#include -+ which can conflict with char _doprnt (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char _doprnt(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char _doprnt (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub__doprnt) || defined (__stub____doprnt) - choke me - #else --_doprnt(); -+char (*f) () = _doprnt; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:2942: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func__doprnt=yes" -+int -+main () -+{ -+return f != _doprnt; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_func__doprnt=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func__doprnt=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_func__doprnt=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 -+echo "${ECHO_T}$ac_cv_func__doprnt" >&6 -+if test $ac_cv_func__doprnt = yes; then - --if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- cat >> confdefs.h <<\EOF -+cat >>confdefs.h <<\_ACEOF - #define HAVE_DOPRNT 1 --EOF -+_ACEOF - --else -- echo "$ac_t""no" 1>&6 - fi - - fi -+done -+ -+ - - for ac_func in calloc - do --echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:2969: checking for $ac_func" >&5 --if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char $ac_func(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --$ac_func(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:2997: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -- cat >> confdefs.h <&6 - fi - done - -+ - for ac_func in snprintf - do --echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:3024: checking for $ac_func" >&5 --if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char $ac_func(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --$ac_func(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:3052: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -- cat >> confdefs.h <&6 - fi - done - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - for ac_func in gettimeofday mkdir select strcspn strerror strstr strtol strtoul alarm chmod - do --echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:3079: checking for $ac_func" >&5 --if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char $ac_func(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --$ac_func(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:3107: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -- cat >> confdefs.h <&6 - fi - done - -+ -+ -+ -+ -+ - for ac_func in getpid setpgid getpgid setpgrp getpgrp - do --echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:3134: checking for $ac_func" >&5 --if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char $ac_func(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --$ac_func(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:3162: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -- cat >> confdefs.h <&6 - fi - done - -+ - for ac_func in popen - do --echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:3189: checking for $ac_func" >&5 --if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char $ac_func(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --$ac_func(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:3217: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -- cat >> confdefs.h <&6 - fi - done - -+ - for ac_func in uname - do --echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:3244: checking for $ac_func" >&5 --if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char $ac_func(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --$ac_func(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:3272: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -- cat >> confdefs.h <&6 - fi - done - -+ - for ac_func in strptime - do --echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:3299: checking for $ac_func" >&5 --if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char $ac_func(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --$ac_func(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:3327: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -- cat >> confdefs.h <&6 - fi - done - -+ - for ac_func in setlocale - do --echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:3354: checking for $ac_func" >&5 --if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char $ac_func(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --$ac_func(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:3382: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -- cat >> confdefs.h <&6 - fi - done - -+ - for ac_func in nl_langinfo - do --echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:3409: checking for $ac_func" >&5 --if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char $ac_func(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --$ac_func(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:3437: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -- cat >> confdefs.h <&6 - fi - done - - --echo $ac_n "checking for sigsetjmp/siglongjmp""... $ac_c" 1>&6 --echo "configure:3463: checking for sigsetjmp/siglongjmp" >&5 --if eval "test \"`echo '$''{'ac_cv_have_sigsetjmp'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for sigsetjmp/siglongjmp" >&5 -+echo $ECHO_N "checking for sigsetjmp/siglongjmp... $ECHO_C" >&6 -+if test "${ac_cv_have_sigsetjmp+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include --int main() { -+int -+main () -+{ - sigjmp_buf env;sigsetjmp(env, 1);siglongjmp(env, 2); --; return 0; } --EOF --if { (eval echo configure:3475: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_have_sigsetjmp=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_have_sigsetjmp=no --fi --rm -f conftest* -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_have_sigsetjmp=no - fi -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - --echo "$ac_t""$ac_cv_have_sigsetjmp" 1>&6 -+fi -+echo "$as_me:$LINENO: result: $ac_cv_have_sigsetjmp" >&5 -+echo "${ECHO_T}$ac_cv_have_sigsetjmp" >&6 - if test "$ac_cv_have_sigsetjmp" = yes; then -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define HAVE_SIGSETJMP 1 --EOF -+_ACEOF - - fi - --echo $ac_n "checking for atan in -lm""... $ac_c" 1>&6 --echo "configure:3497: checking for atan in -lm" >&5 --ac_lib_var=`echo m'_'atan | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+echo "$as_me:$LINENO: checking for atan in -lm" >&5 -+echo $ECHO_N "checking for atan in -lm... $ECHO_C" >&6 -+if test "${ac_cv_lib_m_atan+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-lm $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char atan(); -- --int main() { --atan() --; return 0; } --EOF --if { (eval echo configure:3516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char atan (); -+int -+main () -+{ -+atan (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_m_atan=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_m_atan=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_lib_m_atan" >&6 -+if test $ac_cv_lib_m_atan = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBM 1 -+_ACEOF - - LIBS="-lm $LIBS" - --else -- echo "$ac_t""no" 1>&6 - fi - - --echo $ac_n "checking for socket""... $ac_c" 1>&6 --echo "configure:3545: checking for socket" >&5 --if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for socket" >&5 -+echo $ECHO_N "checking for socket... $ECHO_C" >&6 -+if test "${ac_cv_func_socket+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char socket(); below. */ --#include -+ which can conflict with char socket (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char socket(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char socket (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_socket) || defined (__stub___socket) - choke me - #else --socket(); -+char (*f) () = socket; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:3573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_socket=yes" -+int -+main () -+{ -+return f != socket; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_func_socket=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_socket=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_func_socket=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -- --if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -+echo "$as_me:$LINENO: result: $ac_cv_func_socket" >&5 -+echo "${ECHO_T}$ac_cv_func_socket" >&6 -+if test $ac_cv_func_socket = yes; then - cf_result=yes - else -- echo "$ac_t""no" 1>&6 --cf_result=no -+ cf_result=no - fi - - if test "$cf_result" = no; then -- echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 --echo "configure:3595: checking for socket in -lsocket" >&5 --ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+echo "$as_me:$LINENO: checking for socket in -lsocket" >&5 -+echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6 -+if test "${ac_cv_lib_socket_socket+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-lsocket $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char socket(); -- --int main() { --socket() --; return 0; } --EOF --if { (eval echo configure:3614: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char socket (); -+int -+main () -+{ -+socket (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_socket_socket=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_socket_socket=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6 -+if test $ac_cv_lib_socket_socket = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBSOCKET 1 -+_ACEOF - - LIBS="-lsocket $LIBS" - --else -- echo "$ac_t""no" 1>&6 - fi - - fi --echo $ac_n "checking for setsockopt""... $ac_c" 1>&6 --echo "configure:3643: checking for setsockopt" >&5 --if eval "test \"`echo '$''{'ac_cv_func_setsockopt'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for setsockopt" >&5 -+echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6 -+if test "${ac_cv_func_setsockopt+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char setsockopt(); below. */ --#include -+ which can conflict with char setsockopt (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char setsockopt(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char setsockopt (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_setsockopt) || defined (__stub___setsockopt) - choke me - #else --setsockopt(); -+char (*f) () = setsockopt; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:3671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_setsockopt=yes" -+int -+main () -+{ -+return f != setsockopt; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_func_setsockopt=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_setsockopt=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_func_setsockopt=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -- --if eval "test \"`echo '$ac_cv_func_'setsockopt`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -+echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5 -+echo "${ECHO_T}$ac_cv_func_setsockopt" >&6 -+if test $ac_cv_func_setsockopt = yes; then - cf_result=yes - else -- echo "$ac_t""no" 1>&6 --cf_result=no -+ cf_result=no - fi - - if test "$cf_result" = no; then -- echo $ac_n "checking for setsockopt in -lsocket""... $ac_c" 1>&6 --echo "configure:3693: checking for setsockopt in -lsocket" >&5 --ac_lib_var=`echo socket'_'setsockopt | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5 -+echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6 -+if test "${ac_cv_lib_socket_setsockopt+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-lsocket $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char setsockopt(); -- --int main() { --setsockopt() --; return 0; } --EOF --if { (eval echo configure:3712: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char setsockopt (); -+int -+main () -+{ -+setsockopt (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_socket_setsockopt=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_socket_setsockopt=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6 -+if test $ac_cv_lib_socket_setsockopt = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBSOCKET 1 -+_ACEOF - - LIBS="-lsocket $LIBS" - --else -- echo "$ac_t""no" 1>&6 - fi - - fi - - #AC_MSG_CHECKING([for gethostbyname]) --#AC_TRY_LINK([#include ], [gethostbyname("")], cf_result=yes, cf_result=no) -+#AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[gethostbyname("")]])],[cf_result=yes],[cf_result=no]) - #AC_MSG_RESULT($cf_result) --echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 --echo "configure:3745: checking for gethostbyname" >&5 --if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for gethostbyname" >&5 -+echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 -+if test "${ac_cv_func_gethostbyname+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char gethostbyname(); below. */ --#include -+ which can conflict with char gethostbyname (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char gethostbyname(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char gethostbyname (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) - choke me - #else --gethostbyname(); -+char (*f) () = gethostbyname; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:3773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_gethostbyname=yes" -+int -+main () -+{ -+return f != gethostbyname; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_func_gethostbyname=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_gethostbyname=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_func_gethostbyname=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -- --if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -+echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 -+echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 -+if test $ac_cv_func_gethostbyname = yes; then - cf_result=yes - else -- echo "$ac_t""no" 1>&6 --cf_result=no -+ cf_result=no - fi - - if test "$cf_result" = no; then -- echo $ac_n "checking for gethostbyname in -lsocket""... $ac_c" 1>&6 --echo "configure:3795: checking for gethostbyname in -lsocket" >&5 --ac_lib_var=`echo socket'_'gethostbyname | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ echo "$as_me:$LINENO: checking for gethostbyname in -lsocket" >&5 -+echo $ECHO_N "checking for gethostbyname in -lsocket... $ECHO_C" >&6 -+if test "${ac_cv_lib_socket_gethostbyname+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-lsocket $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char gethostbyname(); -- --int main() { --gethostbyname() --; return 0; } --EOF --if { (eval echo configure:3814: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char gethostbyname (); -+int -+main () -+{ -+gethostbyname (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_socket_gethostbyname=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_socket_gethostbyname=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -+LIBS=$ac_check_lib_save_LIBS -+fi -+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_gethostbyname" >&5 -+echo "${ECHO_T}$ac_cv_lib_socket_gethostbyname" >&6 -+if test $ac_cv_lib_socket_gethostbyname = yes; then - cf_result=yes - else -- echo "$ac_t""no" 1>&6 --cf_result=no -+ cf_result=no - fi - - if test "$cf_result" = no; then -- echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 --echo "configure:3837: checking for gethostbyname in -lnsl" >&5 --ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 -+echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 -+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-lnsl $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char gethostbyname(); -- --int main() { --gethostbyname() --; return 0; } --EOF --if { (eval echo configure:3856: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char gethostbyname (); -+int -+main () -+{ -+gethostbyname (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_nsl_gethostbyname=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_nsl_gethostbyname=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 -+if test $ac_cv_lib_nsl_gethostbyname = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBNSL 1 -+_ACEOF - - LIBS="-lnsl $LIBS" - --else -- echo "$ac_t""no" 1>&6 - fi - - else -@@ -3884,333 +10779,555 @@ - fi - fi - --echo $ac_n "checking for herror""... $ac_c" 1>&6 --echo "configure:3889: checking for herror" >&5 --if eval "test \"`echo '$''{'ac_cv_func_herror'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for herror" >&5 -+echo $ECHO_N "checking for herror... $ECHO_C" >&6 -+if test "${ac_cv_func_herror+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char herror(); below. */ --#include -+ which can conflict with char herror (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char herror(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char herror (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_herror) || defined (__stub___herror) - choke me - #else --herror(); -+char (*f) () = herror; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:3917: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_herror=yes" -+int -+main () -+{ -+return f != herror; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_func_herror=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_herror=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_func_herror=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -- --if eval "test \"`echo '$ac_cv_func_'herror`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- cat >> confdefs.h <<\EOF -+echo "$as_me:$LINENO: result: $ac_cv_func_herror" >&5 -+echo "${ECHO_T}$ac_cv_func_herror" >&6 -+if test $ac_cv_func_herror = yes; then -+ cat >>confdefs.h <<\_ACEOF - #define HAVE_HERROR 1 --EOF -+_ACEOF - --else -- echo "$ac_t""no" 1>&6 - fi - --echo $ac_n "checking for cfmakeraw""... $ac_c" 1>&6 --echo "configure:3940: checking for cfmakeraw" >&5 --if eval "test \"`echo '$''{'ac_cv_func_cfmakeraw'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for cfmakeraw" >&5 -+echo $ECHO_N "checking for cfmakeraw... $ECHO_C" >&6 -+if test "${ac_cv_func_cfmakeraw+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char cfmakeraw(); below. */ --#include -+ which can conflict with char cfmakeraw (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char cfmakeraw(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char cfmakeraw (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_cfmakeraw) || defined (__stub___cfmakeraw) - choke me - #else --cfmakeraw(); -+char (*f) () = cfmakeraw; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:3968: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_cfmakeraw=yes" -+int -+main () -+{ -+return f != cfmakeraw; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_func_cfmakeraw=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_cfmakeraw=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_func_cfmakeraw=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -- --if eval "test \"`echo '$ac_cv_func_'cfmakeraw`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- cat >> confdefs.h <<\EOF -+echo "$as_me:$LINENO: result: $ac_cv_func_cfmakeraw" >&5 -+echo "${ECHO_T}$ac_cv_func_cfmakeraw" >&6 -+if test $ac_cv_func_cfmakeraw = yes; then -+ cat >>confdefs.h <<\_ACEOF - #define HAVE_CFMAKERAW 1 --EOF -+_ACEOF - --else -- echo "$ac_t""no" 1>&6 - fi - - -+ - for ac_func in cygwin_conv_to_full_win32_path - do --echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:3994: checking for $ac_func" >&5 --if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char $ac_func(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --$ac_func(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:4022: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -- cat >> confdefs.h <&6 - fi - done - - --echo $ac_n "checking if you want to enable javascript""... $ac_c" 1>&6 --echo "configure:4048: checking if you want to enable javascript" >&5 -+echo "$as_me:$LINENO: checking if you want to enable javascript" >&5 -+echo $ECHO_N "checking if you want to enable javascript... $ECHO_C" >&6 - # Check whether --enable-javascript or --disable-javascript was given. - if test "${enable_javascript+set}" = set; then - enableval="$enable_javascript" - cf_use_javascript=yes - else - cf_use_javascript=no --fi -- --echo "$ac_t""$cf_use_javascript" 1>&6 -+fi; -+echo "$as_me:$LINENO: result: $cf_use_javascript" >&5 -+echo "${ECHO_T}$cf_use_javascript" >&6 - if test "$cf_use_javascript" = yes; then -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define JS 1 --EOF -+_ACEOF - - fi - -+ - # Check whether --with-libfl or --without-libfl was given. - if test "${with_libfl+set}" = set; then - withval="$with_libfl" - LIBS="$LIBS -lfl" - else -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define CHCEME_FLEXI_LIBU 1 --EOF -- --fi -+_ACEOF - -+fi; - --echo $ac_n "checking if you want to use graphics""... $ac_c" 1>&6 --echo "configure:4078: checking if you want to use graphics" >&5 -+echo "$as_me:$LINENO: checking if you want to use graphics" >&5 -+echo $ECHO_N "checking if you want to use graphics... $ECHO_C" >&6 - # Check whether --enable-graphics or --disable-graphics was given. - if test "${enable_graphics+set}" = set; then - enableval="$enable_graphics" - cf_use_graphics=yes - else - cf_use_graphics=no --fi -+fi; -+echo "$as_me:$LINENO: result: $cf_use_graphics" >&5 -+echo "${ECHO_T}$cf_use_graphics" >&6 - --echo "$ac_t""$cf_use_graphics" 1>&6 - --echo $ac_n "checking for Gpm_Open in -lgpm""... $ac_c" 1>&6 --echo "configure:4090: checking for Gpm_Open in -lgpm" >&5 --ac_lib_var=`echo gpm'_'Gpm_Open | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for Gpm_Open in -lgpm" >&5 -+echo $ECHO_N "checking for Gpm_Open in -lgpm... $ECHO_C" >&6 -+if test "${ac_cv_lib_gpm_Gpm_Open+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-lgpm $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char Gpm_Open(); -- --int main() { --Gpm_Open() --; return 0; } --EOF --if { (eval echo configure:4109: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char Gpm_Open (); -+int -+main () -+{ -+Gpm_Open (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_gpm_Gpm_Open=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_gpm_Gpm_Open=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_lib=HAVE_LIB`echo gpm | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_lib_gpm_Gpm_Open" >&6 -+if test $ac_cv_lib_gpm_Gpm_Open = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBGPM 1 -+_ACEOF - - LIBS="-lgpm $LIBS" - --else -- echo "$ac_t""no" 1>&6 - fi - - cf_have_gpm_lib=$ac_cv_lib_gpm_Gpm_Open --for ac_hdr in gpm.h -+ -+for ac_header in gpm.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:4141: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:4151: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - - cf_have_gpm_includes=$ac_cv_header_gpm_h - if test "$cf_have_gpm_lib" = yes && test "$cf_have_gpm_includes" = yes ; then cf_have_gpm=yes ; else cf_have_gpm=no; fi - --echo $ac_n "checking for OS/2 threads""... $ac_c" 1>&6 --echo "configure:4181: checking for OS/2 threads" >&5 --if eval "test \"`echo '$''{'ac_cv_have_beginthread'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for OS/2 threads" >&5 -+echo $ECHO_N "checking for OS/2 threads... $ECHO_C" >&6 -+if test "${ac_cv_have_beginthread+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else - CFLAGS_X="$CFLAGS" - CFLAGS="$CFLAGS -Zmt" -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include --int main() { -+int -+main () -+{ - _beginthread(NULL, NULL, 0, NULL) --; return 0; } --EOF --if { (eval echo configure:4195: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_have_beginthread=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_have_beginthread=no -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_have_beginthread=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - CFLAGS="$CFLAGS_X" - - fi -- --echo "$ac_t""$ac_cv_have_beginthread" 1>&6 -+echo "$as_me:$LINENO: result: $ac_cv_have_beginthread" >&5 -+echo "${ECHO_T}$ac_cv_have_beginthread" >&6 - if test "$ac_cv_have_beginthread" = yes; then - CFLAGS="$CFLAGS -Zmt" -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define HAVE_BEGINTHREAD 1 --EOF -+_ACEOF - - #else - # AC_CHECK_FUNC(pthread_create, cf_result=yes, cf_result=no) -@@ -4222,264 +11339,480 @@ - # fi - fi - #AC_CHECK_FUNC(clone, AC_DEFINE(HAVE_CLONE)) --for ac_hdr in atheos/threads.h -+ -+for ac_header in atheos/threads.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:4230: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:4240: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no -+fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ - fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - -+ - for ac_func in spawn_thread - do --echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:4269: checking for $ac_func" >&5 --if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char $ac_func(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --$ac_func(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:4297: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -- cat >> confdefs.h <&6 - fi - done - -+ - for ac_func in resume_thread - do --echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:4324: checking for $ac_func" >&5 --if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char $ac_func(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --$ac_func(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:4352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -- cat >> confdefs.h <&6 - fi - done - - --echo $ac_n "checking for MouOpen""... $ac_c" 1>&6 --echo "configure:4378: checking for MouOpen" >&5 --if eval "test \"`echo '$''{'ac_cv_func_MouOpen'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for MouOpen" >&5 -+echo $ECHO_N "checking for MouOpen... $ECHO_C" >&6 -+if test "${ac_cv_func_MouOpen+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char MouOpen(); below. */ --#include -+ which can conflict with char MouOpen (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char MouOpen(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char MouOpen (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_MouOpen) || defined (__stub___MouOpen) - choke me - #else --MouOpen(); -+char (*f) () = MouOpen; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:4406: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_MouOpen=yes" -+int -+main () -+{ -+return f != MouOpen; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_func_MouOpen=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_MouOpen=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_func_MouOpen=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -- --if eval "test \"`echo '$ac_cv_func_'MouOpen`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- cat >> confdefs.h <<\EOF -+echo "$as_me:$LINENO: result: $ac_cv_func_MouOpen" >&5 -+echo "${ECHO_T}$ac_cv_func_MouOpen" >&6 -+if test $ac_cv_func_MouOpen = yes; then -+ cat >>confdefs.h <<\_ACEOF - #define HAVE_MOUOPEN 1 --EOF -+_ACEOF - --else -- echo "$ac_t""no" 1>&6 - fi - --echo $ac_n "checking for _read_kbd""... $ac_c" 1>&6 --echo "configure:4429: checking for _read_kbd" >&5 --if eval "test \"`echo '$''{'ac_cv_func__read_kbd'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for _read_kbd" >&5 -+echo $ECHO_N "checking for _read_kbd... $ECHO_C" >&6 -+if test "${ac_cv_func__read_kbd+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char _read_kbd(); below. */ --#include -+ which can conflict with char _read_kbd (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char _read_kbd(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char _read_kbd (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub__read_kbd) || defined (__stub____read_kbd) - choke me - #else --_read_kbd(); -+char (*f) () = _read_kbd; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:4457: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func__read_kbd=yes" -+int -+main () -+{ -+return f != _read_kbd; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_func__read_kbd=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func__read_kbd=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_func__read_kbd=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -- --if eval "test \"`echo '$ac_cv_func_'_read_kbd`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- cat >> confdefs.h <<\EOF -+echo "$as_me:$LINENO: result: $ac_cv_func__read_kbd" >&5 -+echo "${ECHO_T}$ac_cv_func__read_kbd" >&6 -+if test $ac_cv_func__read_kbd = yes; then -+ cat >>confdefs.h <<\_ACEOF - #define HAVE_READ_KBD 1 --EOF -+_ACEOF - --else -- echo "$ac_t""no" 1>&6 - fi - - --echo $ac_n "checking for XFree for OS/2""... $ac_c" 1>&6 --echo "configure:4481: checking for XFree for OS/2" >&5 --if eval "test \"`echo '$''{'ac_cv_have_x2'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for XFree for OS/2" >&5 -+echo $ECHO_N "checking for XFree for OS/2... $ECHO_C" >&6 -+if test "${ac_cv_have_x2+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else - CPPFLAGS_X="$CPPFLAGS" - LIBS_X="$LIBS" -@@ -4487,118 +11820,171 @@ - if test -n "$X11ROOT"; then - CPPFLAGS="$CPPFLAGS_X -I$X11ROOT/XFree86/include" - LIBS="$LIBS_X -L$X11ROOT/XFree86/lib -lxf86_gcc" -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include --int main() { -+int -+main () -+{ - struct winsize win;ptioctl(1, TIOCGWINSZ, &win) --; return 0; } --EOF --if { (eval echo configure:4499: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_have_x2=xf86_gcc - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_have_x2=no -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_have_x2=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - if test "$ac_cv_have_x2" = no; then - LIBS="$LIBS_X -L$X11ROOT/XFree86/lib -lxf86" -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include --int main() { -+int -+main () -+{ - struct winsize win;ptioctl(1, TIOCGWINSZ, &win) --; return 0; } --EOF --if { (eval echo configure:4519: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_have_x2=xf86 - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_have_x2=no -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_have_x2=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi - fi - CPPFLAGS="$CPPFLAGS_X" - LIBS="$LIBS_X" - - fi -- --echo "$ac_t""$ac_cv_have_x2" 1>&6 -+echo "$as_me:$LINENO: result: $ac_cv_have_x2" >&5 -+echo "${ECHO_T}$ac_cv_have_x2" >&6 - if test "$ac_cv_have_x2" != no; then - CPPFLAGS="$CPPFLAGS -I$X11ROOT/XFree86/include" - LIBS="$LIBS -L$X11ROOT/XFree86/lib -l$ac_cv_have_x2" -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define X2 1 --EOF -+_ACEOF - - fi - --echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 --echo "configure:4547: checking for dlopen in -ldl" >&5 --ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -+if test "${ac_cv_lib_dl_dlopen+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-ldl $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char dlopen(); -- --int main() { --dlopen() --; return 0; } --EOF --if { (eval echo configure:4566: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char dlopen (); -+int -+main () -+{ -+dlopen (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_dl_dlopen=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_dl_dlopen=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -+if test $ac_cv_lib_dl_dlopen = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBDL 1 -+_ACEOF - - LIBS="-ldl $LIBS" - --else -- echo "$ac_t""no" 1>&6 - fi - - - #ifdef HAVE_SSL -+ - # Check whether --with-ssl or --without-ssl was given. - if test "${with_ssl+set}" = set; then - withval="$with_ssl" - if test "$withval" = no; then disable_ssl=yes; else ssld="$withval"; fi --fi -- --echo $ac_n "checking for OpenSSL""... $ac_c" 1>&6 --echo "configure:4602: checking for OpenSSL" >&5 -+fi; -+echo "$as_me:$LINENO: checking for OpenSSL" >&5 -+echo $ECHO_N "checking for OpenSSL... $ECHO_C" >&6 - CPPFLAGS_X="$CPPFLAGS" - LIBS_X="$LIBS" - cf_result=no -@@ -4611,762 +11997,1651 @@ - else - LIBS="-lssl -lcrypto $LIBS_X" - fi -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include --int main() { -+int -+main () -+{ - OpenSSL_add_all_algorithms() --; return 0; } --EOF --if { (eval echo configure:4623: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - cf_result=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- cf_result=no -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+cf_result=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - if test "$cf_result" != yes; then -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include --int main() { -+int -+main () -+{ - SSLeay_add_ssl_algorithms() --; return 0; } --EOF --if { (eval echo configure:4642: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - cf_result=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- cf_result=no -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+cf_result=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi - fi - done - - if test "$cf_result" != yes; then - if test "$withval" = yes; then -- { echo "configure: error: "OpenSSL not found"" 1>&2; exit 1; } -+ { { echo "$as_me:$LINENO: error: \"OpenSSL not found\"" >&5 -+echo "$as_me: error: \"OpenSSL not found\"" >&2;} -+ { (exit 1); exit 1; }; } - fi - CPPFLAGS="$CPPFLAGS_X" - LIBS="$LIBS_X" - else -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define HAVE_SSL 1 --EOF -+_ACEOF - - fi - fi --echo "$ac_t""$cf_result" 1>&6 -+echo "$as_me:$LINENO: result: $cf_result" >&5 -+echo "${ECHO_T}$cf_result" >&6 - cf_have_ssl=$cf_result; - #endif - - cf_have_atheos=no - - if test "$cf_use_graphics" = yes; then -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define G 1 --EOF -+_ACEOF - - - # OpenBSD needs it, but gcc-3.1 doens't work with it !!! - # CPPFLAGS="$CPPFLAGS -I/usr/local/include" - # LDFLAGS="$LDFLAGS -L/usr/local/lib" -- echo $ac_n "checking for inflate in -lz""... $ac_c" 1>&6 --echo "configure:4685: checking for inflate in -lz" >&5 --ac_lib_var=`echo z'_'inflate | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+echo "$as_me:$LINENO: checking for inflate in -lz" >&5 -+echo $ECHO_N "checking for inflate in -lz... $ECHO_C" >&6 -+if test "${ac_cv_lib_z_inflate+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-lz $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char inflate(); -- --int main() { --inflate() --; return 0; } --EOF --if { (eval echo configure:4704: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char inflate (); -+int -+main () -+{ -+inflate (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_z_inflate=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_z_inflate=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_lib=HAVE_LIB`echo z | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_lib_z_inflate" >&6 -+if test $ac_cv_lib_z_inflate = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBZ 1 -+_ACEOF - - LIBS="-lz $LIBS" - --else -- echo "$ac_t""no" 1>&6 - fi - -- for ac_hdr in png.h libpng/png.h -+ -+ -+for ac_header in png.h libpng/png.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:4735: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:4745: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - -- echo $ac_n "checking for png_create_info_struct in -lpng""... $ac_c" 1>&6 --echo "configure:4772: checking for png_create_info_struct in -lpng" >&5 --ac_lib_var=`echo png'_'png_create_info_struct | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+echo "$as_me:$LINENO: checking for png_create_info_struct in -lpng" >&5 -+echo $ECHO_N "checking for png_create_info_struct in -lpng... $ECHO_C" >&6 -+if test "${ac_cv_lib_png_png_create_info_struct+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-lpng $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char png_create_info_struct(); -- --int main() { --png_create_info_struct() --; return 0; } --EOF --if { (eval echo configure:4791: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char png_create_info_struct (); -+int -+main () -+{ -+png_create_info_struct (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_png_png_create_info_struct=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_png_png_create_info_struct=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_lib=HAVE_LIB`echo png | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_lib_png_png_create_info_struct" >&6 -+if test $ac_cv_lib_png_png_create_info_struct = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBPNG 1 -+_ACEOF - - LIBS="-lpng $LIBS" - --else -- echo "$ac_t""no" 1>&6 - fi - - if test "$ac_cv_header_png_h" != yes && test "$ac_cv_header_libpng_png_h" != yes || test "$ac_cv_lib_png_png_create_info_struct" != yes; then -- { echo "configure: error: You need libpng to compile Links in graphics mode" 1>&2; exit 1; } -+ { { echo "$as_me:$LINENO: error: You need libpng to compile Links in graphics mode" >&5 -+echo "$as_me: error: You need libpng to compile Links in graphics mode" >&2;} -+ { (exit 1); exit 1; }; } - fi - -- for ac_func in png_set_rgb_to_gray -+ -+for ac_func in png_set_rgb_to_gray - do --echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --echo "configure:4825: checking for $ac_func" >&5 --if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -+echo "$as_me:$LINENO: checking for $ac_func" >&5 -+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_var+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - /* System header to define __stub macros and hopefully few prototypes, -- which can conflict with char $ac_func(); below. */ --#include -+ which can conflict with char $ac_func (); below. -+ Prefer to if __STDC__ is defined, since -+ exists even on freestanding compilers. */ -+#ifdef __STDC__ -+# include -+#else -+# include -+#endif - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char $ac_func(); -- --int main() { -- -+ builtin and then its argument prototype would still apply. */ -+char $ac_func (); - /* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ - #if defined (__stub_$ac_func) || defined (__stub___$ac_func) - choke me - #else --$ac_func(); -+char (*f) () = $ac_func; -+#endif -+#ifdef __cplusplus -+} - #endif - --; return 0; } --EOF --if { (eval echo configure:4853: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=yes" -+int -+main () -+{ -+return f != $ac_func; -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ eval "$as_ac_var=yes" - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_func_$ac_func=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+eval "$as_ac_var=no" - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -+if test `eval echo '${'$as_ac_var'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -+_ACEOF - --if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -- cat >> confdefs.h <&6 - fi - done - - -- echo $ac_n "checking if you can include both setjmp.h and png.h""... $ac_c" 1>&6 --echo "configure:4879: checking if you can include both setjmp.h and png.h" >&5 --if eval "test \"`echo '$''{'ac_cv_include_setjmp_png'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ echo "$as_me:$LINENO: checking if you can include both setjmp.h and png.h" >&5 -+echo $ECHO_N "checking if you can include both setjmp.h and png.h... $ECHO_C" >&6 -+if test "${ac_cv_include_setjmp_png+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include - #include --int main() { -+int -+main () -+{ - jmp_buf bla; --; return 0; } --EOF --if { (eval echo configure:4892: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then -- rm -rf conftest* -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_include_setjmp_png=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_include_setjmp_png=no --fi --rm -f conftest* -- -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_include_setjmp_png=no - fi -+rm -f conftest.$ac_objext conftest.$ac_ext - --echo "$ac_t""$ac_cv_include_setjmp_png" 1>&6 -+fi -+echo "$as_me:$LINENO: result: $ac_cv_include_setjmp_png" >&5 -+echo "${ECHO_T}$ac_cv_include_setjmp_png" >&6 - - if test "$ac_cv_include_setjmp_png" != yes; then -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define DONT_INCLUDE_SETJMP 1 --EOF -+_ACEOF - - fi - -+ - # Check whether --with-libjpeg or --without-libjpeg was given. - if test "${with_libjpeg+set}" = set; then - withval="$with_libjpeg" - if test "$withval" = no; then disable_jpeg=yes; else disable_jpeg=no; fi --fi -- -+fi; - cf_have_jpeg=no - if test "$disable_jpeg" != yes ; then -- for ac_hdr in jpeglib.h -+ -+for ac_header in jpeglib.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:4926: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:4936: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no -+fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - -- echo $ac_n "checking for jpeg_destroy_decompress in -ljpeg""... $ac_c" 1>&6 --echo "configure:4963: checking for jpeg_destroy_decompress in -ljpeg" >&5 --ac_lib_var=`echo jpeg'_'jpeg_destroy_decompress | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+echo "$as_me:$LINENO: checking for jpeg_destroy_decompress in -ljpeg" >&5 -+echo $ECHO_N "checking for jpeg_destroy_decompress in -ljpeg... $ECHO_C" >&6 -+if test "${ac_cv_lib_jpeg_jpeg_destroy_decompress+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-ljpeg $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char jpeg_destroy_decompress(); -- --int main() { --jpeg_destroy_decompress() --; return 0; } --EOF --if { (eval echo configure:4982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char jpeg_destroy_decompress (); -+int -+main () -+{ -+jpeg_destroy_decompress (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_jpeg_jpeg_destroy_decompress=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_jpeg_jpeg_destroy_decompress=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_lib=HAVE_LIB`echo jpeg | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_lib_jpeg_jpeg_destroy_decompress" >&6 -+if test $ac_cv_lib_jpeg_jpeg_destroy_decompress = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBJPEG 1 -+_ACEOF - - LIBS="-ljpeg $LIBS" - --else -- echo "$ac_t""no" 1>&6 - fi - - if test "$ac_cv_header_jpeglib_h" = yes && test "$ac_cv_lib_jpeg_jpeg_destroy_decompress" = yes; then -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define HAVE_JPEG 1 --EOF -+_ACEOF - - cf_have_jpeg=yes - image_formats="$image_formats JPEG" - fi - fi - -+ - # Check whether --with-libtiff or --without-libtiff was given. - if test "${with_libtiff+set}" = set; then - withval="$with_libtiff" - if test "$withval" = no; then disable_tiff=yes; else disable_tiff=no; fi --fi -- -+fi; - cf_have_tiff=no - if test "$disable_tiff" != yes ; then -- for ac_hdr in tiffio.h -+ -+for ac_header in tiffio.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:5031: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:5041: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - -- echo $ac_n "checking for TIFFOpen in -ltiff""... $ac_c" 1>&6 --echo "configure:5068: checking for TIFFOpen in -ltiff" >&5 --ac_lib_var=`echo tiff'_'TIFFOpen | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+echo "$as_me:$LINENO: checking for TIFFOpen in -ltiff" >&5 -+echo $ECHO_N "checking for TIFFOpen in -ltiff... $ECHO_C" >&6 -+if test "${ac_cv_lib_tiff_TIFFOpen+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-ltiff $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char TIFFOpen(); -- --int main() { --TIFFOpen() --; return 0; } --EOF --if { (eval echo configure:5087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char TIFFOpen (); -+int -+main () -+{ -+TIFFOpen (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_tiff_TIFFOpen=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_tiff_TIFFOpen=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_lib=HAVE_LIB`echo tiff | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_lib_tiff_TIFFOpen" >&6 -+if test $ac_cv_lib_tiff_TIFFOpen = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBTIFF 1 -+_ACEOF - - LIBS="-ltiff $LIBS" - --else -- echo "$ac_t""no" 1>&6 - fi - - if test "$ac_cv_header_tiffio_h" = yes && test "$ac_cv_lib_tiff_TIFFOpen" = yes; then -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define HAVE_TIFF 1 --EOF -+_ACEOF - - cf_have_tiff=yes - image_formats="$image_formats TIFF" - fi - fi - -+ - # Check whether --with-svgalib or --without-svgalib was given. - if test "${with_svgalib+set}" = set; then - withval="$with_svgalib" - if test "$withval" = no; then disable_svgalib=yes; else disable_svgalib=no; fi --fi -+fi; - - # Check whether --with-x or --without-x was given. - if test "${with_x+set}" = set; then - withval="$with_x" - if test "$withval" = no; then disable_x=yes; else disable_x=no; fi --fi -+fi; - - # Check whether --with-fb or --without-fb was given. - if test "${with_fb+set}" = set; then - withval="$with_fb" - if test "$withval" = no; then disable_fb=yes; else disable_fb=no; fi --fi -+fi; - - # Check whether --with-directfb or --without-directfb was given. - if test "${with_directfb+set}" = set; then - withval="$with_directfb" - if test "$withval" = no; then disable_directfb=yes; else disable_directfb=no; fi --fi -+fi; - - # Check whether --with-pmshell or --without-pmshell was given. - if test "${with_pmshell+set}" = set; then - withval="$with_pmshell" - if test "$withval" = no; then disable_pmshell=yes; else disable_pmshell=no; fi --fi -+fi; - - # Check whether --with-atheos or --without-atheos was given. - if test "${with_atheos+set}" = set; then - withval="$with_atheos" - if test "$withval" = no; then disable_atheos=yes; else disable_atheos; fi --fi -- -+fi; - - drivers="" - - if test "$disable_svgalib" != yes ; then -- echo $ac_n "checking for svgalib""... $ac_c" 1>&6 --echo "configure:5165: checking for svgalib" >&5 --if eval "test \"`echo '$''{'ac_cv_have_svgalib'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ echo "$as_me:$LINENO: checking for svgalib" >&5 -+echo $ECHO_N "checking for svgalib... $ECHO_C" >&6 -+if test "${ac_cv_have_svgalib+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else - LIBS_X="$LIBS" - LIBS="$LIBS -lvga" -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #include --int main() { -+int -+main () -+{ - vga_setmode(0) --; return 0; } --EOF --if { (eval echo configure:5179: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_have_svgalib=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_have_svgalib=no -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_have_svgalib=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - LIBS="$LIBS_X" -- --fi - --echo "$ac_t""$ac_cv_have_svgalib" 1>&6 -+fi -+echo "$as_me:$LINENO: result: $ac_cv_have_svgalib" >&5 -+echo "${ECHO_T}$ac_cv_have_svgalib" >&6 - - if test "$ac_cv_have_svgalib" = yes; then -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define GRDRV_SVGALIB 1 --EOF -+_ACEOF - - LIBS="$LIBS -lvga" - drivers="$drivers SVGALIB" - fi - fi - -- -+ - if test "$disable_fb" != yes ; then -- for ac_hdr in linux/fb.h -+ -+for ac_header in linux/fb.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:5211: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:5221: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no -+fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ - fi -+ - done - -- for ac_hdr in linux/kd.h -+ -+for ac_header in linux/kd.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:5251: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:5261: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - -- for ac_hdr in linux/vt.h -+ -+for ac_header in linux/vt.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:5291: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:5301: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - -- for ac_hdr in sys/mman.h -+ -+for ac_header in sys/mman.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:5331: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:5341: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - - if test "$ac_cv_header_linux_fb_h" = yes && test "$ac_cv_header_linux_kd_h" = yes && test "$ac_cv_header_linux_vt_h" = yes && test "$ac_cv_header_sys_mman_h" = yes && test "$ac_cv_header_sys_ioctl_h" = yes && test "$cf_have_gpm" = yes; then -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define GRDRV_FB 1 --EOF -+_ACEOF - - drivers="$drivers FB" - fi -@@ -5375,74 +13650,76 @@ - if test "$disable_directfb" != yes ; then - # Extract the first word of "directfb-config", so it can be a program name with args. - set dummy directfb-config; ac_word=$2 --echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:5380: checking for $ac_word" >&5 --if eval "test \"`echo '$''{'ac_cv_path_DIRECTFB_CONFIG'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_path_DIRECTFB_CONFIG+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- case "$DIRECTFB_CONFIG" in -- /*) -+ case $DIRECTFB_CONFIG in -+ [\\/]* | ?:[\\/]*) - ac_cv_path_DIRECTFB_CONFIG="$DIRECTFB_CONFIG" # Let the user override the test with a path. - ;; -- ?:/*) -- ac_cv_path_DIRECTFB_CONFIG="$DIRECTFB_CONFIG" # Let the user override the test with a dos path. -- ;; - *) -- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" -- ac_dummy="$PATH" -- for ac_dir in $ac_dummy; do -- test -z "$ac_dir" && ac_dir=. -- if test -f $ac_dir/$ac_word; then -- ac_cv_path_DIRECTFB_CONFIG="$ac_dir/$ac_word" -- break -- fi -- done -- IFS="$ac_save_ifs" -+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_path_DIRECTFB_CONFIG="$as_dir/$ac_word$ac_exec_ext" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+done -+ - test -z "$ac_cv_path_DIRECTFB_CONFIG" && ac_cv_path_DIRECTFB_CONFIG="no" - ;; - esac - fi --DIRECTFB_CONFIG="$ac_cv_path_DIRECTFB_CONFIG" -+DIRECTFB_CONFIG=$ac_cv_path_DIRECTFB_CONFIG -+ - if test -n "$DIRECTFB_CONFIG"; then -- echo "$ac_t""$DIRECTFB_CONFIG" 1>&6 -+ echo "$as_me:$LINENO: result: $DIRECTFB_CONFIG" >&5 -+echo "${ECHO_T}$DIRECTFB_CONFIG" >&6 - else -- echo "$ac_t""no" 1>&6 -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 - fi - - if test "$DIRECTFB_CONFIG" != "no"; then -- echo $ac_n "checking for DirectFB >= 0.9.17""... $ac_c" 1>&6 --echo "configure:5415: checking for DirectFB >= 0.9.17" >&5 -+ echo "$as_me:$LINENO: checking for DirectFB >= 0.9.17" >&5 -+echo $ECHO_N "checking for DirectFB >= 0.9.17... $ECHO_C" >&6 - directfb_version=`$DIRECTFB_CONFIG --version` - if expr $directfb_version \>= 0.9.17 >/dev/null; then -- echo "$ac_t""yes" 1>&6 -+ echo "$as_me:$LINENO: result: yes" >&5 -+echo "${ECHO_T}yes" >&6 - DIRECTFB_CFLAGS=`$DIRECTFB_CONFIG --cflags` - DIRECTFB_LIBS=`$DIRECTFB_CONFIG --libs` -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define GRDRV_DIRECTFB 1 --EOF -+_ACEOF - - drivers="$drivers DIRECTFB" - CPPFLAGS="$CPPFLAGS $DIRECTFB_CFLAGS" - LIBS="$LIBS $DIRECTFB_LIBS" - else -- echo "$ac_t""no" 1>&6 -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 - fi - fi - fi - -- # If we find X, set shell vars x_includes and x_libraries to the --# paths, otherwise set no_x=yes. --# Uses ac_ vars as temps to allow command line to override cache and checks. --# --without-x overrides everything else, but does not touch the cache. --echo $ac_n "checking for X""... $ac_c" 1>&6 --echo "configure:5439: checking for X" >&5 -+ echo "$as_me:$LINENO: checking for X" >&5 -+echo $ECHO_N "checking for X... $ECHO_C" >&6 -+ - - # Check whether --with-x or --without-x was given. - if test "${with_x+set}" = set; then - withval="$with_x" -- : --fi - -+fi; - # $have_x is `yes', `no', `disabled', or empty when we do not yet know. - if test "x$with_x" = xno; then - # The user explicitly disabled X. -@@ -5452,193 +13729,184 @@ - # Both variables are already set. - have_x=yes - else --if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ if test "${ac_cv_have_x+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else - # One or both of the vars are not set, and there is no cached value. --ac_x_includes=NO ac_x_libraries=NO --rm -fr conftestdir --if mkdir conftestdir; then -- cd conftestdir -+ac_x_includes=no ac_x_libraries=no -+rm -fr conftest.dir -+if mkdir conftest.dir; then -+ cd conftest.dir - # Make sure to not put "make" in the Imakefile rules, since we grep it out. -- cat > Imakefile <<'EOF' -+ cat >Imakefile <<'_ACEOF' - acfindx: - @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' --EOF -+_ACEOF - if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then - # GNU make sometimes prints "make[1]: Entering...", which would confuse us. - eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` - # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. - for ac_extension in a so sl; do - if test ! -f $ac_im_usrlibdir/libX11.$ac_extension && -- test -f $ac_im_libdir/libX11.$ac_extension; then -+ test -f $ac_im_libdir/libX11.$ac_extension; then - ac_im_usrlibdir=$ac_im_libdir; break - fi - done - # Screen out bogus values from the imake configuration. They are - # bogus both because they are the default anyway, and because - # using them would break gcc on systems where it needs fixed includes. -- case "$ac_im_incroot" in -+ case $ac_im_incroot in - /usr/include) ;; -- *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;; -+ *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; - esac -- case "$ac_im_usrlibdir" in -+ case $ac_im_usrlibdir in - /usr/lib | /lib) ;; -- *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;; -+ *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; - esac - fi - cd .. -- rm -fr conftestdir -+ rm -fr conftest.dir - fi - --if test "$ac_x_includes" = NO; then -- # Guess where to find include files, by looking for this one X11 .h file. -- test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h -+# Standard set of common directories for X headers. -+# Check X11 before X11Rn because it is often a symlink to the current release. -+ac_x_header_dirs=' -+/usr/X11/include -+/usr/X11R6/include -+/usr/X11R5/include -+/usr/X11R4/include - -+/usr/include/X11 -+/usr/include/X11R6 -+/usr/include/X11R5 -+/usr/include/X11R4 -+ -+/usr/local/X11/include -+/usr/local/X11R6/include -+/usr/local/X11R5/include -+/usr/local/X11R4/include -+ -+/usr/local/include/X11 -+/usr/local/include/X11R6 -+/usr/local/include/X11R5 -+/usr/local/include/X11R4 -+ -+/usr/X386/include -+/usr/x386/include -+/usr/XFree86/include/X11 -+ -+/usr/include -+/usr/local/include -+/usr/unsupported/include -+/usr/athena/include -+/usr/local/x11r5/include -+/usr/lpp/Xamples/include -+ -+/usr/openwin/include -+/usr/openwin/share/include' -+ -+if test "$ac_x_includes" = no; then -+ # Guess where to find include files, by looking for Intrinsic.h. - # First, try using that file with no special directory specified. --cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:5506: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes -+fi -+if test -z "$ac_cpp_err"; then - # We can compile using X headers with no special include directory. - ac_x_includes= - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- # Look for the header file in a standard set of common directories. --# Check X11 before X11Rn because it is often a symlink to the current release. -- for ac_dir in \ -- /usr/X11/include \ -- /usr/X11R6/include \ -- /usr/X11R5/include \ -- /usr/X11R4/include \ -- \ -- /usr/include/X11 \ -- /usr/include/X11R6 \ -- /usr/include/X11R5 \ -- /usr/include/X11R4 \ -- \ -- /usr/local/X11/include \ -- /usr/local/X11R6/include \ -- /usr/local/X11R5/include \ -- /usr/local/X11R4/include \ -- \ -- /usr/local/include/X11 \ -- /usr/local/include/X11R6 \ -- /usr/local/include/X11R5 \ -- /usr/local/include/X11R4 \ -- \ -- /usr/X386/include \ -- /usr/x386/include \ -- /usr/XFree86/include/X11 \ -- \ -- /usr/include \ -- /usr/local/include \ -- /usr/unsupported/include \ -- /usr/athena/include \ -- /usr/local/x11r5/include \ -- /usr/lpp/Xamples/include \ -- \ -- /usr/openwin/include \ -- /usr/openwin/share/include \ -- ; \ -- do -- if test -r "$ac_dir/$x_direct_test_include"; then -- ac_x_includes=$ac_dir -- break -- fi -- done -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ for ac_dir in $ac_x_header_dirs; do -+ if test -r "$ac_dir/X11/Intrinsic.h"; then -+ ac_x_includes=$ac_dir -+ break -+ fi -+done - fi --rm -f conftest* --fi # $ac_x_includes = NO -+rm -f conftest.err conftest.$ac_ext -+fi # $ac_x_includes = no - --if test "$ac_x_libraries" = NO; then -+if test "$ac_x_libraries" = no; then - # Check for the libraries. -- -- test -z "$x_direct_test_library" && x_direct_test_library=Xt -- test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc -- - # See if we find them without any special options. - # Don't add to $LIBS permanently. -- ac_save_LIBS="$LIBS" -- LIBS="-l$x_direct_test_library $LIBS" --cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- LIBS="$ac_save_LIBS" -+ ac_save_LIBS=$LIBS -+ LIBS="-lXt $LIBS" -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include -+int -+main () -+{ -+XtMalloc (0) -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ LIBS=$ac_save_LIBS - # We can link X programs with no special library path. - ac_x_libraries= - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- LIBS="$ac_save_LIBS" --# First see if replacing the include by lib works. --# Check X11 before X11Rn because it is often a symlink to the current release. --for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \ -- /usr/X11/lib \ -- /usr/X11R6/lib \ -- /usr/X11R5/lib \ -- /usr/X11R4/lib \ -- \ -- /usr/lib/X11 \ -- /usr/lib/X11R6 \ -- /usr/lib/X11R5 \ -- /usr/lib/X11R4 \ -- \ -- /usr/local/X11/lib \ -- /usr/local/X11R6/lib \ -- /usr/local/X11R5/lib \ -- /usr/local/X11R4/lib \ -- \ -- /usr/local/lib/X11 \ -- /usr/local/lib/X11R6 \ -- /usr/local/lib/X11R5 \ -- /usr/local/lib/X11R4 \ -- \ -- /usr/X386/lib \ -- /usr/x386/lib \ -- /usr/XFree86/lib/X11 \ -- \ -- /usr/lib \ -- /usr/local/lib \ -- /usr/unsupported/lib \ -- /usr/athena/lib \ -- /usr/local/x11r5/lib \ -- /usr/lpp/Xamples/lib \ -- /lib/usr/lib/X11 \ -- \ -- /usr/openwin/lib \ -- /usr/openwin/share/lib \ -- ; \ -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+LIBS=$ac_save_LIBS -+for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` - do -+ # Don't even attempt the hair of trying to link an X program! - for ac_extension in a so sl; do -- if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then -+ if test -r $ac_dir/libXt.$ac_extension; then - ac_x_libraries=$ac_dir - break 2 - fi - done - done - fi --rm -f conftest* --fi # $ac_x_libraries = NO -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -+fi # $ac_x_libraries = no - --if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then -+if test "$ac_x_includes" = no || test "$ac_x_libraries" = no; then - # Didn't find X anywhere. Cache the known absence of X. - ac_cv_have_x="have_x=no" - else -@@ -5647,12 +13915,14 @@ - ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" - fi - fi -+ - fi - eval "$ac_cv_have_x" - fi # $with_x != no - - if test "$have_x" != yes; then -- echo "$ac_t""$have_x" 1>&6 -+ echo "$as_me:$LINENO: result: $have_x" >&5 -+echo "${ECHO_T}$have_x" >&6 - no_x=yes - else - # If each of the values was on the command line, it overrides each guess. -@@ -5661,111 +13931,234 @@ - # Update the cache value to reflect the command line values. - ac_cv_have_x="have_x=yes \ - ac_x_includes=$x_includes ac_x_libraries=$x_libraries" -- echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6 -+ echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5 -+echo "${ECHO_T}libraries $x_libraries, headers $x_includes" >&6 - fi - - - if test "$have_x" = yes; then -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define GRDRV_X 1 --EOF -+_ACEOF - - test -n "$x_libraries" && LIBS="$LIBS -L$x_libraries" - LIBS="$LIBS -lX11" - test -n "$x_includes" && CPPFLAGS="$CPPFLAGS -I$x_includes" - drivers="$drivers X" - elif test "$ac_cv_have_x2" != no; then -- echo $ac_n "checking for XOpenDisplay in -lX11""... $ac_c" 1>&6 --echo "configure:5680: checking for XOpenDisplay in -lX11" >&5 --ac_lib_var=`echo X11'_'XOpenDisplay | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+echo "$as_me:$LINENO: checking for XOpenDisplay in -lX11" >&5 -+echo $ECHO_N "checking for XOpenDisplay in -lX11... $ECHO_C" >&6 -+if test "${ac_cv_lib_X11_XOpenDisplay+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-lX11 $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ - /* Override any gcc2 internal prototype to avoid an error. */ -+#ifdef __cplusplus -+extern "C" -+#endif - /* We use char because int might match the return type of a gcc2 -- builtin and then its argument prototype would still apply. */ --char XOpenDisplay(); -- --int main() { --XOpenDisplay() --; return 0; } --EOF --if { (eval echo configure:5699: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ builtin and then its argument prototype would still apply. */ -+char XOpenDisplay (); -+int -+main () -+{ -+XOpenDisplay (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_X11_XOpenDisplay=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_X11_XOpenDisplay=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_lib=HAVE_LIB`echo X11 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_lib_X11_XOpenDisplay" >&6 -+if test $ac_cv_lib_X11_XOpenDisplay = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBX11 1 -+_ACEOF - - LIBS="-lX11 $LIBS" - --else -- echo "$ac_t""no" 1>&6 - fi - -- for ac_hdr in X11/Xlib.h X11/X.h X11/Xutil.h X11/Xlocale.h -+ -+ -+ -+ -+for ac_header in X11/Xlib.h X11/X.h X11/Xutil.h X11/Xlocale.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:5730: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:5740: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no -+fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ - fi -+ - done - - if test "$ac_cv_have_libx11" = yes && test "$ac_cv_have_x11_xlib_h" = test && test "$ac_cv_have_x11_x_h" = test && test "$ac_cv_have_x11_xutil_h" = test && test "$ac_cv_have_x11_xlocale_h" = test; then -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define GRDRV_X 1 --EOF -+_ACEOF - - drivers="$drivers X" - LIBS="$LIBS -lX11" -@@ -5773,43 +14166,61 @@ - fi - - if test "$disable_pmshell" != yes ; then -- echo $ac_n "checking for pmshell""... $ac_c" 1>&6 --echo "configure:5778: checking for pmshell" >&5 --if eval "test \"`echo '$''{'ac_cv_have_pmshell'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ echo "$as_me:$LINENO: checking for pmshell" >&5 -+echo $ECHO_N "checking for pmshell... $ECHO_C" >&6 -+if test "${ac_cv_have_pmshell+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - #define INCL_WIN - #define INCL_GPI - #include - #include --int main() { -+int -+main () -+{ - _fmutex mutex; - WinDrawText(NULLHANDLE, -1, NULL, NULL, 0, 0, 0), - GpiSetPel(NULLHANDLE, NULL) --; return 0; } --EOF --if { (eval echo configure:5795: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_have_pmshell=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- ac_cv_have_pmshell=no -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_cv_have_pmshell=no - fi --rm -f conftest* -- -+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -+ - fi -+echo "$as_me:$LINENO: result: $ac_cv_have_pmshell" >&5 -+echo "${ECHO_T}$ac_cv_have_pmshell" >&6 - --echo "$ac_t""$ac_cv_have_pmshell" 1>&6 -- - if test "$ac_cv_have_pmshell" = yes; then -- cat >> confdefs.h <<\EOF -+ cat >>confdefs.h <<\_ACEOF - #define GRDRV_PMSHELL 1 --EOF -+_ACEOF - - drivers="$drivers PMSHELL" - fi -@@ -5818,244 +14229,856 @@ - if test "$disable_atheos" != yes ; then - old_ext="$ac_ext" - ac_ext=cpp -- for ac_hdr in gui/view.h -+ -+for ac_header in gui/view.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:5826: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:5836: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no -+fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - -- for ac_hdr in gui/window.h -+ -+for ac_header in gui/window.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:5866: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:5876: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - -- for ac_hdr in gui/desktop.h -+ -+for ac_header in gui/desktop.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:5906: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:5916: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - -- for ac_hdr in gui/bitmap.h -+ -+for ac_header in gui/bitmap.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:5946: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:5956: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no - fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - -- for ac_hdr in util/locker.h -+ -+for ac_header in util/locker.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:5986: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:5996: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no -+fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ - fi -+ - done - -- for ac_hdr in util/application.h -+ -+for ac_header in util/application.h - do --ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` --echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 --echo "configure:6026: checking for $ac_hdr" >&5 --if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - else -- cat > conftest.$ac_ext < --EOF --ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" --{ (eval echo configure:6036: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } --ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` --if test -z "$ac_err"; then -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=yes" -+ # Is the header compilable? -+echo "$as_me:$LINENO: checking $ac_header usability" >&5 -+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_includes_default -+#include <$ac_header> -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_header_compiler=yes - else -- echo "$ac_err" >&5 -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_header_$ac_safe=no" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_header_compiler=no - fi --rm -f conftest* -+rm -f conftest.$ac_objext conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -+echo "${ECHO_T}$ac_header_compiler" >&6 -+ -+# Is the header present? -+echo "$as_me:$LINENO: checking $ac_header presence" >&5 -+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -+cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include <$ac_header> -+_ACEOF -+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 -+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 -+ ac_status=$? -+ grep -v '^ *+' conftest.er1 >conftest.err -+ rm -f conftest.er1 -+ cat conftest.err >&5 -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } >/dev/null; then -+ if test -s conftest.err; then -+ ac_cpp_err=$ac_c_preproc_warn_flag -+ else -+ ac_cpp_err= -+ fi -+else -+ ac_cpp_err=yes - fi --if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` -- cat >> confdefs.h <&6 -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ ac_header_preproc=no -+fi -+rm -f conftest.err conftest.$ac_ext -+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -+echo "${ECHO_T}$ac_header_preproc" >&6 -+ -+# So? What about this header? -+case $ac_header_compiler:$ac_header_preproc in -+ yes:no ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+ no:yes ) -+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} -+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} -+ ( -+ cat <<\_ASBOX -+## ------------------------------------ ## -+## Report this to bug-autoconf@gnu.org. ## -+## ------------------------------------ ## -+_ASBOX -+ ) | -+ sed "s/^/$as_me: WARNING: /" >&2 -+ ;; -+esac -+echo "$as_me:$LINENO: checking for $ac_header" >&5 -+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -+if eval "test \"\${$as_ac_Header+set}\" = set"; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ eval "$as_ac_Header=$ac_header_preproc" - fi -+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -+ -+fi -+if test `eval echo '${'$as_ac_Header'}'` = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -+_ACEOF -+ -+fi -+ - done - - ac_ext="$old_ext" -@@ -6067,222 +15090,335 @@ - test "$ac_cv_header_gui_bitmap_h" = yes && - test "$ac_cv_header_util_locker_h" = yes && - test "$ac_cv_header_util_application_h" = yes; then -- echo $ac_n "checking for main in -lstdc++""... $ac_c" 1>&6 --echo "configure:6072: checking for main in -lstdc++" >&5 --ac_lib_var=`echo stdc++'_'main | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+echo "$as_me:$LINENO: checking for main in -lstdc++" >&5 -+echo $ECHO_N "checking for main in -lstdc++... $ECHO_C" >&6 -+if test "${ac_cv_lib_stdcpp_main+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-lstdc++ $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - --int main() { --main() --; return 0; } --EOF --if { (eval echo configure:6087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ -+int -+main () -+{ -+main (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_stdcpp_main=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_stdcpp_main=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_lib=HAVE_LIB`echo stdc++ | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_lib_stdcpp_main" >&6 -+if test $ac_cv_lib_stdcpp_main = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBSTDC__ 1 -+_ACEOF - - LIBS="-lstdc++ $LIBS" - --else -- echo "$ac_t""no" 1>&6 - fi - -- echo $ac_n "checking for main in -latheos""... $ac_c" 1>&6 --echo "configure:6115: checking for main in -latheos" >&5 --ac_lib_var=`echo atheos'_'main | sed 'y%./+-%__p_%'` --if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ -+echo "$as_me:$LINENO: checking for main in -latheos" >&5 -+echo $ECHO_N "checking for main in -latheos... $ECHO_C" >&6 -+if test "${ac_cv_lib_atheos_main+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- ac_save_LIBS="$LIBS" -+ ac_check_lib_save_LIBS=$LIBS - LIBS="-latheos $LIBS" --cat > conftest.$ac_ext <conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - --int main() { --main() --; return 0; } --EOF --if { (eval echo configure:6130: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=yes" -+ -+int -+main () -+{ -+main (); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext conftest$ac_exeext -+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 -+ (eval $ac_link) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest$ac_exeext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_cv_lib_atheos_main=yes - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- rm -rf conftest* -- eval "ac_cv_lib_$ac_lib_var=no" --fi --rm -f conftest* --LIBS="$ac_save_LIBS" -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_lib_atheos_main=no - fi --if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then -- echo "$ac_t""yes" 1>&6 -- ac_tr_lib=HAVE_LIB`echo atheos | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` -- cat >> confdefs.h <&5 -+echo "${ECHO_T}$ac_cv_lib_atheos_main" >&6 -+if test $ac_cv_lib_atheos_main = yes; then -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBATHEOS 1 -+_ACEOF - - LIBS="-latheos $LIBS" - --else -- echo "$ac_t""no" 1>&6 - fi - - if test "$ac_cv_lib_atheos_main" = yes; then -- for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl --do --# Extract the first word of "$ac_prog", so it can be a program name with args. --set dummy $ac_prog; ac_word=$2 --echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 --echo "configure:6163: checking for $ac_word" >&5 --if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+ ac_ext=cc -+ac_cpp='$CXXCPP $CPPFLAGS' -+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -+if test -n "$ac_tool_prefix"; then -+ for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC -+ do -+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -+set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_CXX+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. - else -- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" -- ac_dummy="$PATH" -- for ac_dir in $ac_dummy; do -- test -z "$ac_dir" && ac_dir=. -- if test -f $ac_dir/$ac_word; then -- ac_cv_prog_CXX="$ac_prog" -- break -- fi -- done -- IFS="$ac_save_ifs" -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done -+done -+ - fi - fi --CXX="$ac_cv_prog_CXX" -+CXX=$ac_cv_prog_CXX - if test -n "$CXX"; then -- echo "$ac_t""$CXX" 1>&6 -+ echo "$as_me:$LINENO: result: $CXX" >&5 -+echo "${ECHO_T}$CXX" >&6 - else -- echo "$ac_t""no" 1>&6 -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 - fi - --test -n "$CXX" && break -+ test -n "$CXX" && break -+ done -+fi -+if test -z "$CXX"; then -+ ac_ct_CXX=$CXX -+ for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC -+do -+ # Extract the first word of "$ac_prog", so it can be a program name with args. -+set dummy $ac_prog; ac_word=$2 -+echo "$as_me:$LINENO: checking for $ac_word" >&5 -+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test -n "$ac_ct_CXX"; then -+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -+else -+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for ac_exec_ext in '' $ac_executable_extensions; do -+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then -+ ac_cv_prog_ac_ct_CXX="$ac_prog" -+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 -+ break 2 -+ fi -+done - done --test -n "$CXX" || CXX="gcc" - -+fi -+fi -+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -+if test -n "$ac_ct_CXX"; then -+ echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 -+echo "${ECHO_T}$ac_ct_CXX" >&6 -+else -+ echo "$as_me:$LINENO: result: no" >&5 -+echo "${ECHO_T}no" >&6 -+fi - --echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 --echo "configure:6195: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 -+ test -n "$ac_ct_CXX" && break -+done -+test -n "$ac_ct_CXX" || ac_ct_CXX="g++" - --ac_ext=C --# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. --ac_cpp='$CXXCPP $CPPFLAGS' --ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' --ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' --cross_compiling=$ac_cv_prog_cxx_cross -+ CXX=$ac_ct_CXX -+fi - --cat > conftest.$ac_ext << EOF - --#line 6206 "configure" --#include "confdefs.h" -+# Provide some information about the compiler. -+echo "$as_me:$LINENO:" \ -+ "checking for C++ compiler version" >&5 -+ac_compiler=`set X $ac_compile; echo $2` -+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 -+ (eval $ac_compiler --version &5) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } -+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 -+ (eval $ac_compiler -v &5) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } -+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 -+ (eval $ac_compiler -V &5) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } - --int main(){return(0);} --EOF --if { (eval echo configure:6211: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then -- ac_cv_prog_cxx_works=yes -- # If we can't run a trivial program, we are probably using a cross compiler. -- if (./conftest; exit) 2>/dev/null; then -- ac_cv_prog_cxx_cross=no -- else -- ac_cv_prog_cxx_cross=yes -- fi -+echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 -+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 -+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- echo "configure: failed program was:" >&5 -- cat conftest.$ac_ext >&5 -- ac_cv_prog_cxx_works=no --fi --rm -fr conftest* --ac_ext=c --# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. --ac_cpp='$CPP $CPPFLAGS' --ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' --ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' --cross_compiling=$ac_cv_prog_cc_cross -- --echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6 --if test $ac_cv_prog_cxx_works = no; then -- { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } --fi --echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 --echo "configure:6237: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 --echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 --cross_compiling=$ac_cv_prog_cxx_cross -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ - --echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 --echo "configure:6242: checking whether we are using GNU C++" >&5 --if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 --else -- cat > conftest.C <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then -- ac_cv_prog_gxx=yes --else -- ac_cv_prog_gxx=no --fi --fi -- --echo "$ac_t""$ac_cv_prog_gxx" 1>&6 - --if test $ac_cv_prog_gxx = yes; then -- GXX=yes -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ ac_compiler_gnu=yes - else -- GXX= -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+ac_compiler_gnu=no - fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - --ac_test_CXXFLAGS="${CXXFLAGS+set}" --ac_save_CXXFLAGS="$CXXFLAGS" --CXXFLAGS= --echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 --echo "configure:6270: checking whether ${CXX-g++} accepts -g" >&5 --if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then -- echo $ac_n "(cached) $ac_c" 1>&6 -+fi -+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 -+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 -+GXX=`test $ac_compiler_gnu = yes && echo yes` -+ac_test_CXXFLAGS=${CXXFLAGS+set} -+ac_save_CXXFLAGS=$CXXFLAGS -+CXXFLAGS="-g" -+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 -+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 -+if test "${ac_cv_prog_cxx_g+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 - else -- echo 'void f(){}' > conftest.cc --if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+ -+int -+main () -+{ -+ -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then - ac_cv_prog_cxx_g=yes - else -- ac_cv_prog_cxx_g=no --fi --rm -f conftest* -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -+ac_cv_prog_cxx_g=no - fi -- --echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6 -+rm -f conftest.$ac_objext conftest.$ac_ext -+fi -+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 -+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 - if test "$ac_test_CXXFLAGS" = set; then -- CXXFLAGS="$ac_save_CXXFLAGS" -+ CXXFLAGS=$ac_save_CXXFLAGS - elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" -@@ -6296,10 +15432,206 @@ - CXXFLAGS= - fi - fi -+for ac_declaration in \ -+ ''\ -+ '#include ' \ -+ 'extern "C" void std::exit (int) throw (); using std::exit;' \ -+ 'extern "C" void std::exit (int); using std::exit;' \ -+ 'extern "C" void exit (int) throw ();' \ -+ 'extern "C" void exit (int);' \ -+ 'void exit (int);' -+do -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+#include -+$ac_declaration -+int -+main () -+{ -+exit (42); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ : -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 - -- cat >> confdefs.h <<\EOF -+continue -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+ cat >conftest.$ac_ext <<_ACEOF -+#line $LINENO "configure" -+/* confdefs.h. */ -+_ACEOF -+cat confdefs.h >>conftest.$ac_ext -+cat >>conftest.$ac_ext <<_ACEOF -+/* end confdefs.h. */ -+$ac_declaration -+int -+main () -+{ -+exit (42); -+ ; -+ return 0; -+} -+_ACEOF -+rm -f conftest.$ac_objext -+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 -+ (eval $ac_compile) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); } && -+ { ac_try='test -s conftest.$ac_objext' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; }; then -+ break -+else -+ echo "$as_me: failed program was:" >&5 -+sed 's/^/| /' conftest.$ac_ext >&5 -+ -+fi -+rm -f conftest.$ac_objext conftest.$ac_ext -+done -+rm -f conftest* -+if test -n "$ac_declaration"; then -+ echo '#ifdef __cplusplus' >>confdefs.h -+ echo $ac_declaration >>confdefs.h -+ echo '#endif' >>confdefs.h -+fi -+ -+ac_ext=c -+ac_cpp='$CPP $CPPFLAGS' -+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -+ac_compiler_gnu=$ac_cv_c_compiler_gnu -+ -+depcc="$CXX" am_compiler_list= -+ -+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 -+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 -+if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then -+ # We make a subdir and do the tests there. Otherwise we can end up -+ # making bogus files that we don't know about and never remove. For -+ # instance it was reported that on HP-UX the gcc test will end up -+ # making a dummy file named `D' -- because `-MD' means `put the output -+ # in D'. -+ mkdir conftest.dir -+ # Copy depcomp to subdir because otherwise we won't find it if we're -+ # using a relative directory. -+ cp "$am_depcomp" conftest.dir -+ cd conftest.dir -+ # We will build objects and dependencies in a subdirectory because -+ # it helps to detect inapplicable dependency modes. For instance -+ # both Tru64's cc and ICC support -MD to output dependencies as a -+ # side effect of compilation, but ICC will put the dependencies in -+ # the current directory while Tru64 will put them in the object -+ # directory. -+ mkdir sub -+ -+ am_cv_CXX_dependencies_compiler_type=none -+ if test "$am_compiler_list" = ""; then -+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` -+ fi -+ for depmode in $am_compiler_list; do -+ # Setup a source with many dependencies, because some compilers -+ # like to wrap large dependency lists on column 80 (with \), and -+ # we should not choose a depcomp mode which is confused by this. -+ # -+ # We need to recreate these files for each test, as the compiler may -+ # overwrite some of them when testing with obscure command lines. -+ # This happens at least with the AIX C compiler. -+ : > sub/conftest.c -+ for i in 1 2 3 4 5 6; do -+ echo '#include "conftst'$i'.h"' >> sub/conftest.c -+ : > sub/conftst$i.h -+ done -+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf -+ -+ case $depmode in -+ nosideeffect) -+ # after this tag, mechanisms are not by side-effect, so they'll -+ # only be used when explicitly requested -+ if test "x$enable_dependency_tracking" = xyes; then -+ continue -+ else -+ break -+ fi -+ ;; -+ none) break ;; -+ esac -+ # We check with `-c' and `-o' for the sake of the "dashmstdout" -+ # mode. It turns out that the SunPro C++ compiler does not properly -+ # handle `-M -o', and we need to detect this. -+ if depmode=$depmode \ -+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ -+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ -+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ -+ >/dev/null 2>conftest.err && -+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && -+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && -+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then -+ # icc doesn't choke on unknown options, it will just issue warnings -+ # (even with -Werror). So we grep stderr for any message -+ # that says an option was ignored. -+ if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else -+ am_cv_CXX_dependencies_compiler_type=$depmode -+ break -+ fi -+ fi -+ done -+ -+ cd .. -+ rm -rf conftest.dir -+else -+ am_cv_CXX_dependencies_compiler_type=none -+fi -+ -+fi -+echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 -+echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6 -+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type -+ -+ -+ -+if -+ test "x$enable_dependency_tracking" != xno \ -+ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then -+ am__fastdepCXX_TRUE= -+ am__fastdepCXX_FALSE='#' -+else -+ am__fastdepCXX_TRUE='#' -+ am__fastdepCXX_FALSE= -+fi -+ -+ -+ cat >>confdefs.h <<\_ACEOF - #define GRDRV_ATHEOS 1 --EOF -+_ACEOF - - drivers="$drivers ATHEOS" - cf_have_atheos=yes -@@ -6308,7 +15640,9 @@ - fi - - if test -z "$drivers" && test "$cf_use_graphics" = yes; then -- { echo "configure: error: No graphics drivers found." 1>&2; exit 1; } -+ { { echo "$as_me:$LINENO: error: No graphics drivers found." >&5 -+echo "$as_me: error: No graphics drivers found." >&2;} -+ { (exit 1); exit 1; }; } - fi - fi - -@@ -6322,380 +15656,1345 @@ - ATHEOS_GR_FALSE= - fi - -+ - test "$ac_cv_have_emx" = yes && LDFLAGS="$LDFLAGS -Zexe" - test "$ac_cv_have_emx" = yes && LDFLAGS=`echo "$LDFLAGS" | sed "s/-Zbin-files//g"` - --trap '' 1 2 15 --cat > confcache <<\EOF -+ ac_config_files="$ac_config_files Makefile" -+ -+cat >confcache <<\_ACEOF - # This file is a shell script that caches the results of configure - # tests run on this system so they can be shared between configure --# scripts and configure runs. It is not useful on other systems. --# If it contains results you don't want to keep, you may remove or edit it. -+# scripts and configure runs, see configure's option --config-cache. -+# It is not useful on other systems. If it contains results you don't -+# want to keep, you may remove or edit it. - # --# By default, configure uses ./config.cache as the cache file, --# creating it if it does not exist already. You can give configure --# the --cache-file=FILE option to use a different cache file; that is --# what configure does when it calls configure scripts in --# subdirectories, so they share the cache. --# Giving --cache-file=/dev/null disables caching, for debugging configure. --# config.status only pays attention to the cache file if you give it the --# --recheck option to rerun configure. -+# config.status only pays attention to the cache file if you give it -+# the --recheck option to rerun configure. - # --EOF -+# `ac_cv_env_foo' variables (set or unset) will be overridden when -+# loading this file, other *unset* `ac_cv_foo' will be assigned the -+# following values. -+ -+_ACEOF -+ - # The following way of writing the cache mishandles newlines in values, - # but we know of no workaround that is simple, portable, and efficient. - # So, don't put newlines in cache variables' values. - # Ultrix sh set writes to stderr and can't be redirected directly, - # and sets the high bit in the cache file unless we assign to the vars. --(set) 2>&1 | -- case `(ac_space=' '; set | grep ac_space) 2>&1` in -- *ac_space=\ *) -- # `set' does not quote correctly, so add quotes (double-quote substitution -- # turns \\\\ into \\, and sed turns \\ into \). -- sed -n \ -- -e "s/'/'\\\\''/g" \ -- -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" -- ;; -- *) -- # `set' quotes correctly as required by POSIX, so do not add quotes. -- sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' -- ;; -- esac >> confcache --if cmp -s $cache_file confcache; then -- : --else -+{ -+ (set) 2>&1 | -+ case `(ac_space=' '; set | grep ac_space) 2>&1` in -+ *ac_space=\ *) -+ # `set' does not quote correctly, so add quotes (double-quote -+ # substitution turns \\\\ into \\, and sed turns \\ into \). -+ sed -n \ -+ "s/'/'\\\\''/g; -+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" -+ ;; -+ *) -+ # `set' quotes correctly as required by POSIX, so do not add quotes. -+ sed -n \ -+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" -+ ;; -+ esac; -+} | -+ sed ' -+ t clear -+ : clear -+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ -+ t end -+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ -+ : end' >>confcache -+if diff $cache_file confcache >/dev/null 2>&1; then :; else - if test -w $cache_file; then -- echo "updating cache $cache_file" -- cat confcache > $cache_file -+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" -+ cat confcache >$cache_file - else - echo "not updating unwritable cache $cache_file" - fi - fi - rm -f confcache - --trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 -- - test "x$prefix" = xNONE && prefix=$ac_default_prefix - # Let make expand exec_prefix. - test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - --# Any assignment to VPATH causes Sun make to only execute --# the first set of double-colon rules, so remove it if not needed. --# If there is a colon in the path, we need to keep it. -+# VPATH may cause trouble with some makes, so we remove $(srcdir), -+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -+# trailing colons and then remove the whole line if VPATH becomes empty -+# (actually we leave an empty line to preserve line numbers). - if test "x$srcdir" = x.; then -- ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' -+ ac_vpsub='/^[ ]*VPATH[ ]*=/{ -+s/:*\$(srcdir):*/:/; -+s/:*\${srcdir}:*/:/; -+s/:*@srcdir@:*/:/; -+s/^\([^=]*=[ ]*\):*/\1/; -+s/:*$//; -+s/^[^=]*=[ ]*$//; -+}' - fi - --trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 -- - DEFS=-DHAVE_CONFIG_H - --# Without the "./", some shells look in PATH for config.status. --: ${CONFIG_STATUS=./config.status} -+ac_libobjs= -+ac_ltlibobjs= -+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue -+ # 1. Remove the extension, and $U if already installed. -+ ac_i=`echo "$ac_i" | -+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'` -+ # 2. Add them. -+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" -+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' -+done -+LIBOBJS=$ac_libobjs - --echo creating $CONFIG_STATUS --rm -f $CONFIG_STATUS --cat > $CONFIG_STATUS <&5 -+echo "$as_me: error: conditional \"AMDEP\" was never defined. -+Usually this means the macro was only invoked conditionally." >&2;} -+ { (exit 1); exit 1; }; } -+fi -+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then -+ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. -+Usually this means the macro was only invoked conditionally." >&5 -+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. -+Usually this means the macro was only invoked conditionally." >&2;} -+ { (exit 1); exit 1; }; } -+fi -+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then -+ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. -+Usually this means the macro was only invoked conditionally." >&5 -+echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. -+Usually this means the macro was only invoked conditionally." >&2;} -+ { (exit 1); exit 1; }; } -+fi -+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then -+ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. -+Usually this means the macro was only invoked conditionally." >&5 -+echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. -+Usually this means the macro was only invoked conditionally." >&2;} -+ { (exit 1); exit 1; }; } -+fi -+if test -z "${ATHEOS_GR_TRUE}" && test -z "${ATHEOS_GR_FALSE}"; then -+ { { echo "$as_me:$LINENO: error: conditional \"ATHEOS_GR\" was never defined. -+Usually this means the macro was only invoked conditionally." >&5 -+echo "$as_me: error: conditional \"ATHEOS_GR\" was never defined. -+Usually this means the macro was only invoked conditionally." >&2;} -+ { (exit 1); exit 1; }; } -+fi -+ -+: ${CONFIG_STATUS=./config.status} -+ac_clean_files_save=$ac_clean_files -+ac_clean_files="$ac_clean_files $CONFIG_STATUS" -+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -+echo "$as_me: creating $CONFIG_STATUS" >&6;} -+cat >$CONFIG_STATUS <<_ACEOF -+#! $SHELL -+# Generated by $as_me. - # Run this file to recreate the current configuration. --# This directory was configured as follows, --# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: --# --# $0 $ac_configure_args --# - # Compiler output produced by configure, useful for debugging --# configure, is in ./config.log if it exists. -+# configure, is in config.log if it exists. - --ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" --for ac_option -+debug=false -+ac_cs_recheck=false -+ac_cs_silent=false -+SHELL=\${CONFIG_SHELL-$SHELL} -+_ACEOF -+ -+cat >>$CONFIG_STATUS <<\_ACEOF -+## --------------------- ## -+## M4sh Initialization. ## -+## --------------------- ## -+ -+# Be Bourne compatible -+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then -+ emulate sh -+ NULLCMD=: -+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which -+ # is contrary to our usage. Disable this feature. -+ alias -g '${1+"$@"}'='"$@"' -+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then -+ set -o posix -+fi -+ -+# Support unset when possible. -+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then -+ as_unset=unset -+else -+ as_unset=false -+fi -+ -+ -+# Work around bugs in pre-3.0 UWIN ksh. -+$as_unset ENV MAIL MAILPATH -+PS1='$ ' -+PS2='> ' -+PS4='+ ' -+ -+# NLS nuisances. -+for as_var in \ -+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ -+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ -+ LC_TELEPHONE LC_TIME - do -- case "\$ac_option" in -- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) -- echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" -- exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -- -version | --version | --versio | --versi | --vers | --ver | --ve | --v) -- echo "$CONFIG_STATUS generated by autoconf version 2.13" -- exit 0 ;; -- -help | --help | --hel | --he | --h) -- echo "\$ac_cs_usage"; exit 0 ;; -- *) echo "\$ac_cs_usage"; exit 1 ;; -- esac -+ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then -+ eval $as_var=C; export $as_var -+ else -+ $as_unset $as_var -+ fi - done - --ac_given_srcdir=$srcdir --ac_given_INSTALL="$INSTALL" -+# Required to use basename. -+if expr a : '\(a\)' >/dev/null 2>&1; then -+ as_expr=expr -+else -+ as_expr=false -+fi - --trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 --EOF --cat >> $CONFIG_STATUS </dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then -+ as_basename=basename -+else -+ as_basename=false -+fi - --# Protect against being on the right side of a sed subst in config.status. --sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; -- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF --$ac_vpsub --$extrasub --s%@SHELL@%$SHELL%g --s%@CFLAGS@%$CFLAGS%g --s%@CPPFLAGS@%$CPPFLAGS%g --s%@CXXFLAGS@%$CXXFLAGS%g --s%@FFLAGS@%$FFLAGS%g --s%@DEFS@%$DEFS%g --s%@LDFLAGS@%$LDFLAGS%g --s%@LIBS@%$LIBS%g --s%@exec_prefix@%$exec_prefix%g --s%@prefix@%$prefix%g --s%@program_transform_name@%$program_transform_name%g --s%@bindir@%$bindir%g --s%@sbindir@%$sbindir%g --s%@libexecdir@%$libexecdir%g --s%@datadir@%$datadir%g --s%@sysconfdir@%$sysconfdir%g --s%@sharedstatedir@%$sharedstatedir%g --s%@localstatedir@%$localstatedir%g --s%@libdir@%$libdir%g --s%@includedir@%$includedir%g --s%@oldincludedir@%$oldincludedir%g --s%@infodir@%$infodir%g --s%@mandir@%$mandir%g --s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g --s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g --s%@INSTALL_DATA@%$INSTALL_DATA%g --s%@PACKAGE@%$PACKAGE%g --s%@VERSION@%$VERSION%g --s%@ACLOCAL@%$ACLOCAL%g --s%@AUTOCONF@%$AUTOCONF%g --s%@AUTOMAKE@%$AUTOMAKE%g --s%@AUTOHEADER@%$AUTOHEADER%g --s%@MAKEINFO@%$MAKEINFO%g --s%@SET_MAKE@%$SET_MAKE%g --s%@CC@%$CC%g --s%@CPP@%$CPP%g --s%@LIBOBJS@%$LIBOBJS%g --s%@DIRECTFB_CONFIG@%$DIRECTFB_CONFIG%g --s%@CXX@%$CXX%g --s%@ATHEOS_GR_TRUE@%$ATHEOS_GR_TRUE%g --s%@ATHEOS_GR_FALSE@%$ATHEOS_GR_FALSE%g - --CEOF --EOF -+# Name of the executable. -+as_me=`$as_basename "$0" || -+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ -+ X"$0" : 'X\(//\)$' \| \ -+ X"$0" : 'X\(/\)$' \| \ -+ . : '\(.\)' 2>/dev/null || -+echo X/"$0" | -+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } -+ /^X\/\(\/\/\)$/{ s//\1/; q; } -+ /^X\/\(\/\).*/{ s//\1/; q; } -+ s/.*/./; q'` - --cat >> $CONFIG_STATUS <<\EOF - --# Split the substitutions into bite-sized pieces for seds with --# small command number limits, like on Digital OSF/1 and HP-UX. --ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. --ac_file=1 # Number of current file. --ac_beg=1 # First line for current file. --ac_end=$ac_max_sed_cmds # Line after last line for current file. --ac_more_lines=: --ac_sed_cmds="" --while $ac_more_lines; do -- if test $ac_beg -gt 1; then -- sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file -+# PATH needs CR, and LINENO needs CR and PATH. -+# Avoid depending upon Character Ranges. -+as_cr_letters='abcdefghijklmnopqrstuvwxyz' -+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -+as_cr_Letters=$as_cr_letters$as_cr_LETTERS -+as_cr_digits='0123456789' -+as_cr_alnum=$as_cr_Letters$as_cr_digits -+ -+# The user is always right. -+if test "${PATH_SEPARATOR+set}" != set; then -+ echo "#! /bin/sh" >conf$$.sh -+ echo "exit 0" >>conf$$.sh -+ chmod +x conf$$.sh -+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then -+ PATH_SEPARATOR=';' - else -- sed "${ac_end}q" conftest.subs > conftest.s$ac_file -+ PATH_SEPARATOR=: - fi -- if test ! -s conftest.s$ac_file; then -- ac_more_lines=false -- rm -f conftest.s$ac_file -+ rm -f conf$$.sh -+fi -+ -+ -+ as_lineno_1=$LINENO -+ as_lineno_2=$LINENO -+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` -+ test "x$as_lineno_1" != "x$as_lineno_2" && -+ test "x$as_lineno_3" = "x$as_lineno_2" || { -+ # Find who we are. Look in the path if we contain no path at all -+ # relative or not. -+ case $0 in -+ *[\\/]* ) as_myself=$0 ;; -+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in $PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -+done -+ -+ ;; -+ esac -+ # We did not find ourselves, most probably we were run as `sh COMMAND' -+ # in which case we are not to be found in the path. -+ if test "x$as_myself" = x; then -+ as_myself=$0 -+ fi -+ if test ! -f "$as_myself"; then -+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 -+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} -+ { (exit 1); exit 1; }; } -+ fi -+ case $CONFIG_SHELL in -+ '') -+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -+do -+ IFS=$as_save_IFS -+ test -z "$as_dir" && as_dir=. -+ for as_base in sh bash ksh sh5; do -+ case $as_dir in -+ /*) -+ if ("$as_dir/$as_base" -c ' -+ as_lineno_1=$LINENO -+ as_lineno_2=$LINENO -+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` -+ test "x$as_lineno_1" != "x$as_lineno_2" && -+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then -+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } -+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } -+ CONFIG_SHELL=$as_dir/$as_base -+ export CONFIG_SHELL -+ exec "$CONFIG_SHELL" "$0" ${1+"$@"} -+ fi;; -+ esac -+ done -+done -+;; -+ esac -+ -+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO -+ # uniformly replaced by the line number. The first 'sed' inserts a -+ # line-number line before each line; the second 'sed' does the real -+ # work. The second script uses 'N' to pair each line-number line -+ # with the numbered line, and appends trailing '-' during -+ # substitution so that $LINENO is not a special case at line end. -+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the -+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) -+ sed '=' <$as_myself | -+ sed ' -+ N -+ s,$,-, -+ : loop -+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, -+ t loop -+ s,-$,, -+ s,^['$as_cr_digits']*\n,, -+ ' >$as_me.lineno && -+ chmod +x $as_me.lineno || -+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 -+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} -+ { (exit 1); exit 1; }; } -+ -+ # Don't try to exec as it changes $[0], causing all sort of problems -+ # (the dirname of $[0] is not the place where we might find the -+ # original and so on. Autoconf is especially sensible to this). -+ . ./$as_me.lineno -+ # Exit status is that of the last command. -+ exit -+} -+ -+ -+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in -+ *c*,-n*) ECHO_N= ECHO_C=' -+' ECHO_T=' ' ;; -+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; -+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -+esac -+ -+if expr a : '\(a\)' >/dev/null 2>&1; then -+ as_expr=expr -+else -+ as_expr=false -+fi -+ -+rm -f conf$$ conf$$.exe conf$$.file -+echo >conf$$.file -+if ln -s conf$$.file conf$$ 2>/dev/null; then -+ # We could just check for DJGPP; but this test a) works b) is more generic -+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). -+ if test -f conf$$.exe; then -+ # Don't use ln at all; we don't have any links -+ as_ln_s='cp -p' - else -- if test -z "$ac_sed_cmds"; then -- ac_sed_cmds="sed -f conftest.s$ac_file" -- else -- ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" -- fi -- ac_file=`expr $ac_file + 1` -- ac_beg=$ac_end -- ac_end=`expr $ac_end + $ac_max_sed_cmds` -+ as_ln_s='ln -s' - fi -+elif ln conf$$.file conf$$ 2>/dev/null; then -+ as_ln_s=ln -+else -+ as_ln_s='cp -p' -+fi -+rm -f conf$$ conf$$.exe conf$$.file -+ -+if mkdir -p . 2>/dev/null; then -+ as_mkdir_p=: -+else -+ as_mkdir_p=false -+fi -+ -+as_executable_p="test -f" -+ -+# Sed expression to map a string onto a valid CPP name. -+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" -+ -+# Sed expression to map a string onto a valid variable name. -+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" -+ -+ -+# IFS -+# We need space, tab and new line, in precisely that order. -+as_nl=' -+' -+IFS=" $as_nl" -+ -+# CDPATH. -+$as_unset CDPATH -+ -+exec 6>&1 -+ -+# Open the log real soon, to keep \$[0] and so on meaningful, and to -+# report actual input values of CONFIG_FILES etc. instead of their -+# values after options handling. Logging --version etc. is OK. -+exec 5>>config.log -+{ -+ echo -+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -+## Running $as_me. ## -+_ASBOX -+} >&5 -+cat >&5 <<_CSEOF -+ -+This file was extended by $as_me, which was -+generated by GNU Autoconf 2.57. Invocation command line was -+ -+ CONFIG_FILES = $CONFIG_FILES -+ CONFIG_HEADERS = $CONFIG_HEADERS -+ CONFIG_LINKS = $CONFIG_LINKS -+ CONFIG_COMMANDS = $CONFIG_COMMANDS -+ $ $0 $@ -+ -+_CSEOF -+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 -+echo >&5 -+_ACEOF -+ -+# Files that config.status was made for. -+if test -n "$ac_config_files"; then -+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS -+fi -+ -+if test -n "$ac_config_headers"; then -+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS -+fi -+ -+if test -n "$ac_config_links"; then -+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS -+fi -+ -+if test -n "$ac_config_commands"; then -+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS -+fi -+ -+cat >>$CONFIG_STATUS <<\_ACEOF -+ -+ac_cs_usage="\ -+\`$as_me' instantiates files from templates according to the -+current configuration. -+ -+Usage: $0 [OPTIONS] [FILE]... -+ -+ -h, --help print this help, then exit -+ -V, --version print version number, then exit -+ -q, --quiet do not print progress messages -+ -d, --debug don't remove temporary files -+ --recheck update $as_me by reconfiguring in the same conditions -+ --file=FILE[:TEMPLATE] -+ instantiate the configuration file FILE -+ --header=FILE[:TEMPLATE] -+ instantiate the configuration header FILE -+ -+Configuration files: -+$config_files -+ -+Configuration headers: -+$config_headers -+ -+Configuration commands: -+$config_commands -+ -+Report bugs to ." -+_ACEOF -+ -+cat >>$CONFIG_STATUS <<_ACEOF -+ac_cs_version="\\ -+config.status -+configured by $0, generated by GNU Autoconf 2.57, -+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" -+ -+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 -+Free Software Foundation, Inc. -+This config.status script is free software; the Free Software Foundation -+gives unlimited permission to copy, distribute and modify it." -+srcdir=$srcdir -+INSTALL="$INSTALL" -+_ACEOF -+ -+cat >>$CONFIG_STATUS <<\_ACEOF -+# If no file are specified by the user, then we need to provide default -+# value. By we need to know if files were specified by the user. -+ac_need_defaults=: -+while test $# != 0 -+do -+ case $1 in -+ --*=*) -+ ac_option=`expr "x$1" : 'x\([^=]*\)='` -+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` -+ ac_shift=: -+ ;; -+ -*) -+ ac_option=$1 -+ ac_optarg=$2 -+ ac_shift=shift -+ ;; -+ *) # This is not an option, so the user has probably given explicit -+ # arguments. -+ ac_option=$1 -+ ac_need_defaults=false;; -+ esac -+ -+ case $ac_option in -+ # Handling of the options. -+_ACEOF -+cat >>$CONFIG_STATUS <<\_ACEOF -+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) -+ ac_cs_recheck=: ;; -+ --version | --vers* | -V ) -+ echo "$ac_cs_version"; exit 0 ;; -+ --he | --h) -+ # Conflict between --help and --header -+ { { echo "$as_me:$LINENO: error: ambiguous option: $1 -+Try \`$0 --help' for more information." >&5 -+echo "$as_me: error: ambiguous option: $1 -+Try \`$0 --help' for more information." >&2;} -+ { (exit 1); exit 1; }; };; -+ --help | --hel | -h ) -+ echo "$ac_cs_usage"; exit 0 ;; -+ --debug | --d* | -d ) -+ debug=: ;; -+ --file | --fil | --fi | --f ) -+ $ac_shift -+ CONFIG_FILES="$CONFIG_FILES $ac_optarg" -+ ac_need_defaults=false;; -+ --header | --heade | --head | --hea ) -+ $ac_shift -+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" -+ ac_need_defaults=false;; -+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ -+ | -silent | --silent | --silen | --sile | --sil | --si | --s) -+ ac_cs_silent=: ;; -+ -+ # This is an error. -+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 -+Try \`$0 --help' for more information." >&5 -+echo "$as_me: error: unrecognized option: $1 -+Try \`$0 --help' for more information." >&2;} -+ { (exit 1); exit 1; }; } ;; -+ -+ *) ac_config_targets="$ac_config_targets $1" ;; -+ -+ esac -+ shift - done --if test -z "$ac_sed_cmds"; then -- ac_sed_cmds=cat -+ -+ac_configure_extra_args= -+ -+if $ac_cs_silent; then -+ exec 6>/dev/null -+ ac_configure_extra_args="$ac_configure_extra_args --silent" - fi --EOF - --cat >> $CONFIG_STATUS <>$CONFIG_STATUS <<_ACEOF -+if \$ac_cs_recheck; then -+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 -+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion -+fi - --CONFIG_FILES=\${CONFIG_FILES-"Makefile"} --EOF --cat >> $CONFIG_STATUS <<\EOF --for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then -- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". -- case "$ac_file" in -- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` -- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; -- *) ac_file_in="${ac_file}.in" ;; -+_ACEOF -+ -+cat >>$CONFIG_STATUS <<_ACEOF -+# -+# INIT-COMMANDS section. -+# -+ -+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" -+ -+_ACEOF -+ -+ -+ -+cat >>$CONFIG_STATUS <<\_ACEOF -+for ac_config_target in $ac_config_targets -+do -+ case "$ac_config_target" in -+ # Handling of arguments. -+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; -+ "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; -+ "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; -+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -+echo "$as_me: error: invalid argument: $ac_config_target" >&2;} -+ { (exit 1); exit 1; }; };; - esac -+done - -- # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. -+# If the user did not use the arguments to specify the items to instantiate, -+# then the envvar interface is used. Set only those that are not. -+# We use the long form for the default assignment because of an extremely -+# bizarre bug on SunOS 4.1.3. -+if $ac_need_defaults; then -+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files -+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers -+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -+fi - -- # Remove last slash and all that follows it. Not all systems have dirname. -- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` -- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then -- # The file is in a subdirectory. -- test ! -d "$ac_dir" && mkdir "$ac_dir" -- ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" -- # A "../" for each directory in $ac_dir_suffix. -- ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` -- else -- ac_dir_suffix= ac_dots= -+# Have a temporary directory for convenience. Make it in the build tree -+# simply because there is no reason to put it here, and in addition, -+# creating and moving files from /tmp can sometimes cause problems. -+# Create a temporary directory, and hook for its removal unless debugging. -+$debug || -+{ -+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 -+ trap '{ (exit 1); exit 1; }' 1 2 13 15 -+} -+ -+# Create a (secure) tmp directory for tmp files. -+ -+{ -+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && -+ test -n "$tmp" && test -d "$tmp" -+} || -+{ -+ tmp=./confstat$$-$RANDOM -+ (umask 077 && mkdir $tmp) -+} || -+{ -+ echo "$me: cannot create a temporary directory in ." >&2 -+ { (exit 1); exit 1; } -+} -+ -+_ACEOF -+ -+cat >>$CONFIG_STATUS <<_ACEOF -+ -+# -+# CONFIG_FILES section. -+# -+ -+# No need to generate the scripts if there are no CONFIG_FILES. -+# This happens for instance when ./config.status config.h -+if test -n "\$CONFIG_FILES"; then -+ # Protect against being on the right side of a sed subst in config.status. -+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; -+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF -+s,@SHELL@,$SHELL,;t t -+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t -+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t -+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t -+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t -+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t -+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t -+s,@exec_prefix@,$exec_prefix,;t t -+s,@prefix@,$prefix,;t t -+s,@program_transform_name@,$program_transform_name,;t t -+s,@bindir@,$bindir,;t t -+s,@sbindir@,$sbindir,;t t -+s,@libexecdir@,$libexecdir,;t t -+s,@datadir@,$datadir,;t t -+s,@sysconfdir@,$sysconfdir,;t t -+s,@sharedstatedir@,$sharedstatedir,;t t -+s,@localstatedir@,$localstatedir,;t t -+s,@libdir@,$libdir,;t t -+s,@includedir@,$includedir,;t t -+s,@oldincludedir@,$oldincludedir,;t t -+s,@infodir@,$infodir,;t t -+s,@mandir@,$mandir,;t t -+s,@build_alias@,$build_alias,;t t -+s,@host_alias@,$host_alias,;t t -+s,@target_alias@,$target_alias,;t t -+s,@DEFS@,$DEFS,;t t -+s,@ECHO_C@,$ECHO_C,;t t -+s,@ECHO_N@,$ECHO_N,;t t -+s,@ECHO_T@,$ECHO_T,;t t -+s,@LIBS@,$LIBS,;t t -+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t -+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t -+s,@INSTALL_DATA@,$INSTALL_DATA,;t t -+s,@CYGPATH_W@,$CYGPATH_W,;t t -+s,@PACKAGE@,$PACKAGE,;t t -+s,@VERSION@,$VERSION,;t t -+s,@ACLOCAL@,$ACLOCAL,;t t -+s,@AUTOCONF@,$AUTOCONF,;t t -+s,@AUTOMAKE@,$AUTOMAKE,;t t -+s,@AUTOHEADER@,$AUTOHEADER,;t t -+s,@MAKEINFO@,$MAKEINFO,;t t -+s,@AMTAR@,$AMTAR,;t t -+s,@install_sh@,$install_sh,;t t -+s,@STRIP@,$STRIP,;t t -+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t -+s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t -+s,@AWK@,$AWK,;t t -+s,@SET_MAKE@,$SET_MAKE,;t t -+s,@am__leading_dot@,$am__leading_dot,;t t -+s,@CC@,$CC,;t t -+s,@CFLAGS@,$CFLAGS,;t t -+s,@LDFLAGS@,$LDFLAGS,;t t -+s,@CPPFLAGS@,$CPPFLAGS,;t t -+s,@ac_ct_CC@,$ac_ct_CC,;t t -+s,@EXEEXT@,$EXEEXT,;t t -+s,@OBJEXT@,$OBJEXT,;t t -+s,@DEPDIR@,$DEPDIR,;t t -+s,@am__include@,$am__include,;t t -+s,@am__quote@,$am__quote,;t t -+s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t -+s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t -+s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t -+s,@CCDEPMODE@,$CCDEPMODE,;t t -+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t -+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t -+s,@CXX@,$CXX,;t t -+s,@CXXFLAGS@,$CXXFLAGS,;t t -+s,@ac_ct_CXX@,$ac_ct_CXX,;t t -+s,@CXXDEPMODE@,$CXXDEPMODE,;t t -+s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t -+s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t -+s,@CPP@,$CPP,;t t -+s,@EGREP@,$EGREP,;t t -+s,@LIBOBJS@,$LIBOBJS,;t t -+s,@DIRECTFB_CONFIG@,$DIRECTFB_CONFIG,;t t -+s,@ATHEOS_GR_TRUE@,$ATHEOS_GR_TRUE,;t t -+s,@ATHEOS_GR_FALSE@,$ATHEOS_GR_FALSE,;t t -+s,@LTLIBOBJS@,$LTLIBOBJS,;t t -+CEOF -+ -+_ACEOF -+ -+ cat >>$CONFIG_STATUS <<\_ACEOF -+ # Split the substitutions into bite-sized pieces for seds with -+ # small command number limits, like on Digital OSF/1 and HP-UX. -+ ac_max_sed_lines=48 -+ ac_sed_frag=1 # Number of current file. -+ ac_beg=1 # First line for current file. -+ ac_end=$ac_max_sed_lines # Line after last line for current file. -+ ac_more_lines=: -+ ac_sed_cmds= -+ while $ac_more_lines; do -+ if test $ac_beg -gt 1; then -+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag -+ else -+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag -+ fi -+ if test ! -s $tmp/subs.frag; then -+ ac_more_lines=false -+ else -+ # The purpose of the label and of the branching condition is to -+ # speed up the sed processing (if there are no `@' at all, there -+ # is no need to browse any of the substitutions). -+ # These are the two extra sed commands mentioned above. -+ (echo ':t -+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed -+ if test -z "$ac_sed_cmds"; then -+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" -+ else -+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" -+ fi -+ ac_sed_frag=`expr $ac_sed_frag + 1` -+ ac_beg=$ac_end -+ ac_end=`expr $ac_end + $ac_max_sed_lines` -+ fi -+ done -+ if test -z "$ac_sed_cmds"; then -+ ac_sed_cmds=cat - fi -+fi # test -n "$CONFIG_FILES" - -- case "$ac_given_srcdir" in -- .) srcdir=. -- if test -z "$ac_dots"; then top_srcdir=. -- else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; -- /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; -- *) # Relative path. -- srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" -- top_srcdir="$ac_dots$ac_given_srcdir" ;; -+_ACEOF -+cat >>$CONFIG_STATUS <<\_ACEOF -+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue -+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". -+ case $ac_file in -+ - | *:- | *:-:* ) # input from stdin -+ cat >$tmp/stdin -+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` -+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; -+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` -+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; -+ * ) ac_file_in=$ac_file.in ;; - esac - -- case "$ac_given_INSTALL" in -- [/$]*) INSTALL="$ac_given_INSTALL" ;; -- *) INSTALL="$ac_dots$ac_given_INSTALL" ;; -- esac -+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. -+ ac_dir=`(dirname "$ac_file") 2>/dev/null || -+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ -+ X"$ac_file" : 'X\(//\)[^/]' \| \ -+ X"$ac_file" : 'X\(//\)$' \| \ -+ X"$ac_file" : 'X\(/\)' \| \ -+ . : '\(.\)' 2>/dev/null || -+echo X"$ac_file" | -+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } -+ /^X\(\/\/\)[^/].*/{ s//\1/; q; } -+ /^X\(\/\/\)$/{ s//\1/; q; } -+ /^X\(\/\).*/{ s//\1/; q; } -+ s/.*/./; q'` -+ { if $as_mkdir_p; then -+ mkdir -p "$ac_dir" -+ else -+ as_dir="$ac_dir" -+ as_dirs= -+ while test ! -d "$as_dir"; do -+ as_dirs="$as_dir $as_dirs" -+ as_dir=`(dirname "$as_dir") 2>/dev/null || -+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ -+ X"$as_dir" : 'X\(//\)[^/]' \| \ -+ X"$as_dir" : 'X\(//\)$' \| \ -+ X"$as_dir" : 'X\(/\)' \| \ -+ . : '\(.\)' 2>/dev/null || -+echo X"$as_dir" | -+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } -+ /^X\(\/\/\)[^/].*/{ s//\1/; q; } -+ /^X\(\/\/\)$/{ s//\1/; q; } -+ /^X\(\/\).*/{ s//\1/; q; } -+ s/.*/./; q'` -+ done -+ test ! -n "$as_dirs" || mkdir $as_dirs -+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} -+ { (exit 1); exit 1; }; }; } - -- echo creating "$ac_file" -- rm -f "$ac_file" -- configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." -- case "$ac_file" in -- *Makefile*) ac_comsub="1i\\ --# $configure_input" ;; -- *) ac_comsub= ;; -+ ac_builddir=. -+ -+if test "$ac_dir" != .; then -+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` -+ # A "../" for each directory in $ac_dir_suffix. -+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -+else -+ ac_dir_suffix= ac_top_builddir= -+fi -+ -+case $srcdir in -+ .) # No --srcdir option. We are building in place. -+ ac_srcdir=. -+ if test -z "$ac_top_builddir"; then -+ ac_top_srcdir=. -+ else -+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` -+ fi ;; -+ [\\/]* | ?:[\\/]* ) # Absolute path. -+ ac_srcdir=$srcdir$ac_dir_suffix; -+ ac_top_srcdir=$srcdir ;; -+ *) # Relative path. -+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix -+ ac_top_srcdir=$ac_top_builddir$srcdir ;; -+esac -+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -+# absolute. -+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` -+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` -+ -+ -+ case $INSTALL in -+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; -+ *) ac_INSTALL=$ac_top_builddir$INSTALL ;; - esac - -- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` -- sed -e "$ac_comsub --s%@configure_input@%$configure_input%g --s%@srcdir@%$srcdir%g --s%@top_srcdir@%$top_srcdir%g --s%@INSTALL@%$INSTALL%g --" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file --fi; done --rm -f conftest.s* -+ if test x"$ac_file" != x-; then -+ { echo "$as_me:$LINENO: creating $ac_file" >&5 -+echo "$as_me: creating $ac_file" >&6;} -+ rm -f "$ac_file" -+ fi -+ # Let's still pretend it is `configure' which instantiates (i.e., don't -+ # use $as_me), people would be surprised to read: -+ # /* config.h. Generated by config.status. */ -+ if test x"$ac_file" = x-; then -+ configure_input= -+ else -+ configure_input="$ac_file. " -+ fi -+ configure_input=$configure_input"Generated from `echo $ac_file_in | -+ sed 's,.*/,,'` by configure." -+ -+ # First look for the input files in the build tree, otherwise in the -+ # src tree. -+ ac_file_inputs=`IFS=: -+ for f in $ac_file_in; do -+ case $f in -+ -) echo $tmp/stdin ;; -+ [\\/$]*) -+ # Absolute (can't be DOS-style, as IFS=:) -+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -+echo "$as_me: error: cannot find input file: $f" >&2;} -+ { (exit 1); exit 1; }; } -+ echo $f;; -+ *) # Relative -+ if test -f "$f"; then -+ # Build tree -+ echo $f -+ elif test -f "$srcdir/$f"; then -+ # Source tree -+ echo $srcdir/$f -+ else -+ # /dev/null tree -+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -+echo "$as_me: error: cannot find input file: $f" >&2;} -+ { (exit 1); exit 1; }; } -+ fi;; -+ esac -+ done` || { (exit 1); exit 1; } -+_ACEOF -+cat >>$CONFIG_STATUS <<_ACEOF -+ sed "$ac_vpsub -+$extrasub -+_ACEOF -+cat >>$CONFIG_STATUS <<\_ACEOF -+:t -+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -+s,@configure_input@,$configure_input,;t t -+s,@srcdir@,$ac_srcdir,;t t -+s,@abs_srcdir@,$ac_abs_srcdir,;t t -+s,@top_srcdir@,$ac_top_srcdir,;t t -+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t -+s,@builddir@,$ac_builddir,;t t -+s,@abs_builddir@,$ac_abs_builddir,;t t -+s,@top_builddir@,$ac_top_builddir,;t t -+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t -+s,@INSTALL@,$ac_INSTALL,;t t -+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out -+ rm -f $tmp/stdin -+ if test x"$ac_file" != x-; then -+ mv $tmp/out $ac_file -+ else -+ cat $tmp/out -+ rm -f $tmp/out -+ fi -+ -+done -+_ACEOF -+cat >>$CONFIG_STATUS <<\_ACEOF -+ -+# -+# CONFIG_HEADER section. -+# - - # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where - # NAME is the cpp macro being defined and VALUE is the value it is being given. - # - # ac_d sets the value in "#define NAME VALUE" lines. --ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' --ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' --ac_dC='\3' --ac_dD='%g' --# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". --ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' --ac_uB='\([ ]\)%\1#\2define\3' -+ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' -+ac_dB='[ ].*$,\1#\2' -+ac_dC=' ' -+ac_dD=',;t' -+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". -+ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' -+ac_uB='$,\1#\2define\3' - ac_uC=' ' --ac_uD='\4%g' --# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". --ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' --ac_eB='$%\1#\2define\3' --ac_eC=' ' --ac_eD='%g' -+ac_uD=',;t' - --if test "${CONFIG_HEADERS+set}" != set; then --EOF --cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF --fi --for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then -+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". -- case "$ac_file" in -- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` -- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; -- *) ac_file_in="${ac_file}.in" ;; -+ case $ac_file in -+ - | *:- | *:-:* ) # input from stdin -+ cat >$tmp/stdin -+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` -+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; -+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` -+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; -+ * ) ac_file_in=$ac_file.in ;; - esac - -- echo creating $ac_file -+ test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 -+echo "$as_me: creating $ac_file" >&6;} - -- rm -f conftest.frag conftest.in conftest.out -- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` -- cat $ac_file_inputs > conftest.in -+ # First look for the input files in the build tree, otherwise in the -+ # src tree. -+ ac_file_inputs=`IFS=: -+ for f in $ac_file_in; do -+ case $f in -+ -) echo $tmp/stdin ;; -+ [\\/$]*) -+ # Absolute (can't be DOS-style, as IFS=:) -+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -+echo "$as_me: error: cannot find input file: $f" >&2;} -+ { (exit 1); exit 1; }; } -+ echo $f;; -+ *) # Relative -+ if test -f "$f"; then -+ # Build tree -+ echo $f -+ elif test -f "$srcdir/$f"; then -+ # Source tree -+ echo $srcdir/$f -+ else -+ # /dev/null tree -+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -+echo "$as_me: error: cannot find input file: $f" >&2;} -+ { (exit 1); exit 1; }; } -+ fi;; -+ esac -+ done` || { (exit 1); exit 1; } -+ # Remove the trailing spaces. -+ sed 's/[ ]*$//' $ac_file_inputs >$tmp/in - --EOF -+_ACEOF - --# Transform confdefs.h into a sed script conftest.vals that substitutes --# the proper values into config.h.in to produce config.h. And first: --# Protect against being on the right side of a sed subst in config.status. --# Protect against being in an unquoted here document in config.status. --rm -f conftest.vals --cat > conftest.hdr <<\EOF --s/[\\&%]/\\&/g --s%[\\$`]%\\&%g --s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp --s%ac_d%ac_u%gp --s%ac_u%ac_e%gp --EOF --sed -n -f conftest.hdr confdefs.h > conftest.vals --rm -f conftest.hdr -+# Transform confdefs.h into two sed scripts, `conftest.defines' and -+# `conftest.undefs', that substitutes the proper values into -+# config.h.in to produce config.h. The first handles `#define' -+# templates, and the second `#undef' templates. -+# And first: Protect against being on the right side of a sed subst in -+# config.status. Protect against being in an unquoted here document -+# in config.status. -+rm -f conftest.defines conftest.undefs -+# Using a here document instead of a string reduces the quoting nightmare. -+# Putting comments in sed scripts is not portable. -+# -+# `end' is used to avoid that the second main sed command (meant for -+# 0-ary CPP macros) applies to n-ary macro definitions. -+# See the Autoconf documentation for `clear'. -+cat >confdef2sed.sed <<\_ACEOF -+s/[\\&,]/\\&/g -+s,[\\$`],\\&,g -+t clear -+: clear -+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp -+t end -+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp -+: end -+_ACEOF -+# If some macros were called several times there might be several times -+# the same #defines, which is useless. Nevertheless, we may not want to -+# sort them, since we want the *last* AC-DEFINE to be honored. -+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines -+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs -+rm -f confdef2sed.sed - - # This sed command replaces #undef with comments. This is necessary, for - # example, in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. --cat >> conftest.vals <<\EOF --s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% --EOF -+cat >>conftest.undefs <<\_ACEOF -+s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, -+_ACEOF - --# Break up conftest.vals because some shells have a limit on --# the size of here documents, and old seds have small limits too. -+# Break up conftest.defines because some shells have a limit on the size -+# of here documents, and old seds have small limits too (100 cmds). -+echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS -+echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS -+echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS -+echo ' :' >>$CONFIG_STATUS -+rm -f conftest.tail -+while grep . conftest.defines >/dev/null -+do -+ # Write a limited-size here document to $tmp/defines.sed. -+ echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS -+ # Speed up: don't consider the non `#define' lines. -+ echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS -+ # Work around the forget-to-reset-the-flag bug. -+ echo 't clr' >>$CONFIG_STATUS -+ echo ': clr' >>$CONFIG_STATUS -+ sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS -+ echo 'CEOF -+ sed -f $tmp/defines.sed $tmp/in >$tmp/out -+ rm -f $tmp/in -+ mv $tmp/out $tmp/in -+' >>$CONFIG_STATUS -+ sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail -+ rm -f conftest.defines -+ mv conftest.tail conftest.defines -+done -+rm -f conftest.defines -+echo ' fi # grep' >>$CONFIG_STATUS -+echo >>$CONFIG_STATUS - -+# Break up conftest.undefs because some shells have a limit on the size -+# of here documents, and old seds have small limits too (100 cmds). -+echo ' # Handle all the #undef templates' >>$CONFIG_STATUS - rm -f conftest.tail --while : -+while grep . conftest.undefs >/dev/null - do -- ac_lines=`grep -c . conftest.vals` -- # grep -c gives empty output for an empty file on some AIX systems. -- if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi -- # Write a limited-size here document to conftest.frag. -- echo ' cat > conftest.frag <> $CONFIG_STATUS -- sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS -+ # Write a limited-size here document to $tmp/undefs.sed. -+ echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS -+ # Speed up: don't consider the non `#undef' -+ echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS -+ # Work around the forget-to-reset-the-flag bug. -+ echo 't clr' >>$CONFIG_STATUS -+ echo ': clr' >>$CONFIG_STATUS -+ sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS - echo 'CEOF -- sed -f conftest.frag conftest.in > conftest.out -- rm -f conftest.in -- mv conftest.out conftest.in --' >> $CONFIG_STATUS -- sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail -- rm -f conftest.vals -- mv conftest.tail conftest.vals -+ sed -f $tmp/undefs.sed $tmp/in >$tmp/out -+ rm -f $tmp/in -+ mv $tmp/out $tmp/in -+' >>$CONFIG_STATUS -+ sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail -+ rm -f conftest.undefs -+ mv conftest.tail conftest.undefs - done --rm -f conftest.vals -+rm -f conftest.undefs - --cat >> $CONFIG_STATUS <<\EOF -- rm -f conftest.frag conftest.h -- echo "/* $ac_file. Generated automatically by configure. */" > conftest.h -- cat conftest.in >> conftest.h -- rm -f conftest.in -- if cmp -s $ac_file conftest.h 2>/dev/null; then -- echo "$ac_file is unchanged" -- rm -f conftest.h -+cat >>$CONFIG_STATUS <<\_ACEOF -+ # Let's still pretend it is `configure' which instantiates (i.e., don't -+ # use $as_me), people would be surprised to read: -+ # /* config.h. Generated by config.status. */ -+ if test x"$ac_file" = x-; then -+ echo "/* Generated by configure. */" >$tmp/config.h - else -- # Remove last slash and all that follows it. Not all systems have dirname. -- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` -- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then -- # The file is in a subdirectory. -- test ! -d "$ac_dir" && mkdir "$ac_dir" -+ echo "/* $ac_file. Generated by configure. */" >$tmp/config.h -+ fi -+ cat $tmp/in >>$tmp/config.h -+ rm -f $tmp/in -+ if test x"$ac_file" != x-; then -+ if diff $ac_file $tmp/config.h >/dev/null 2>&1; then -+ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 -+echo "$as_me: $ac_file is unchanged" >&6;} -+ else -+ ac_dir=`(dirname "$ac_file") 2>/dev/null || -+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ -+ X"$ac_file" : 'X\(//\)[^/]' \| \ -+ X"$ac_file" : 'X\(//\)$' \| \ -+ X"$ac_file" : 'X\(/\)' \| \ -+ . : '\(.\)' 2>/dev/null || -+echo X"$ac_file" | -+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } -+ /^X\(\/\/\)[^/].*/{ s//\1/; q; } -+ /^X\(\/\/\)$/{ s//\1/; q; } -+ /^X\(\/\).*/{ s//\1/; q; } -+ s/.*/./; q'` -+ { if $as_mkdir_p; then -+ mkdir -p "$ac_dir" -+ else -+ as_dir="$ac_dir" -+ as_dirs= -+ while test ! -d "$as_dir"; do -+ as_dirs="$as_dir $as_dirs" -+ as_dir=`(dirname "$as_dir") 2>/dev/null || -+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ -+ X"$as_dir" : 'X\(//\)[^/]' \| \ -+ X"$as_dir" : 'X\(//\)$' \| \ -+ X"$as_dir" : 'X\(/\)' \| \ -+ . : '\(.\)' 2>/dev/null || -+echo X"$as_dir" | -+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } -+ /^X\(\/\/\)[^/].*/{ s//\1/; q; } -+ /^X\(\/\/\)$/{ s//\1/; q; } -+ /^X\(\/\).*/{ s//\1/; q; } -+ s/.*/./; q'` -+ done -+ test ! -n "$as_dirs" || mkdir $as_dirs -+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} -+ { (exit 1); exit 1; }; }; } -+ -+ rm -f $ac_file -+ mv $tmp/config.h $ac_file - fi -- rm -f $ac_file -- mv conftest.h $ac_file -+ else -+ cat $tmp/config.h -+ rm -f $tmp/config.h - fi --fi; done -+# Compute $ac_file's index in $config_headers. -+_am_stamp_count=1 -+for _am_header in $config_headers :; do -+ case $_am_header in -+ $ac_file | $ac_file:* ) -+ break ;; -+ * ) -+ _am_stamp_count=`expr $_am_stamp_count + 1` ;; -+ esac -+done -+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null || -+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ -+ X$ac_file : 'X\(//\)[^/]' \| \ -+ X$ac_file : 'X\(//\)$' \| \ -+ X$ac_file : 'X\(/\)' \| \ -+ . : '\(.\)' 2>/dev/null || -+echo X$ac_file | -+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } -+ /^X\(\/\/\)[^/].*/{ s//\1/; q; } -+ /^X\(\/\/\)$/{ s//\1/; q; } -+ /^X\(\/\).*/{ s//\1/; q; } -+ s/.*/./; q'`/stamp-h$_am_stamp_count -+done -+_ACEOF -+cat >>$CONFIG_STATUS <<\_ACEOF - --EOF --cat >> $CONFIG_STATUS </dev/null || -+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ -+ X"$ac_dest" : 'X\(//\)[^/]' \| \ -+ X"$ac_dest" : 'X\(//\)$' \| \ -+ X"$ac_dest" : 'X\(/\)' \| \ -+ . : '\(.\)' 2>/dev/null || -+echo X"$ac_dest" | -+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } -+ /^X\(\/\/\)[^/].*/{ s//\1/; q; } -+ /^X\(\/\/\)$/{ s//\1/; q; } -+ /^X\(\/\).*/{ s//\1/; q; } -+ s/.*/./; q'` -+ ac_builddir=. - -+if test "$ac_dir" != .; then -+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` -+ # A "../" for each directory in $ac_dir_suffix. -+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -+else -+ ac_dir_suffix= ac_top_builddir= -+fi - --EOF --cat >> $CONFIG_STATUS <<\EOF --test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h -+case $srcdir in -+ .) # No --srcdir option. We are building in place. -+ ac_srcdir=. -+ if test -z "$ac_top_builddir"; then -+ ac_top_srcdir=. -+ else -+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` -+ fi ;; -+ [\\/]* | ?:[\\/]* ) # Absolute path. -+ ac_srcdir=$srcdir$ac_dir_suffix; -+ ac_top_srcdir=$srcdir ;; -+ *) # Relative path. -+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix -+ ac_top_srcdir=$ac_top_builddir$srcdir ;; -+esac -+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -+# absolute. -+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` -+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` - --exit 0 --EOF -+ -+ { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 -+echo "$as_me: executing $ac_dest commands" >&6;} -+ case $ac_dest in -+ depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do -+ # Strip MF so we end up with the name of the file. -+ mf=`echo "$mf" | sed -e 's/:.*$//'` -+ # Check whether this is an Automake generated Makefile or not. -+ # We used to match only the files named `Makefile.in', but -+ # some people rename them; so instead we look at the file content. -+ # Grep'ing the first line is not enough: some people post-process -+ # each Makefile.in and add a new line on top of each file to say so. -+ # So let's grep whole file. -+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then -+ dirpart=`(dirname "$mf") 2>/dev/null || -+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ -+ X"$mf" : 'X\(//\)[^/]' \| \ -+ X"$mf" : 'X\(//\)$' \| \ -+ X"$mf" : 'X\(/\)' \| \ -+ . : '\(.\)' 2>/dev/null || -+echo X"$mf" | -+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } -+ /^X\(\/\/\)[^/].*/{ s//\1/; q; } -+ /^X\(\/\/\)$/{ s//\1/; q; } -+ /^X\(\/\).*/{ s//\1/; q; } -+ s/.*/./; q'` -+ else -+ continue -+ fi -+ grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue -+ # Extract the definition of DEP_FILES from the Makefile without -+ # running `make'. -+ DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` -+ test -z "$DEPDIR" && continue -+ # When using ansi2knr, U may be empty or an underscore; expand it -+ U=`sed -n -e '/^U = / s///p' < "$mf"` -+ test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" -+ # We invoke sed twice because it is the simplest approach to -+ # changing $(DEPDIR) to its actual value in the expansion. -+ for file in `sed -n -e ' -+ /^DEP_FILES = .*\\\\$/ { -+ s/^DEP_FILES = // -+ :loop -+ s/\\\\$// -+ p -+ n -+ /\\\\$/ b loop -+ p -+ } -+ /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ -+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do -+ # Make sure the directory exists. -+ test -f "$dirpart/$file" && continue -+ fdir=`(dirname "$file") 2>/dev/null || -+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ -+ X"$file" : 'X\(//\)[^/]' \| \ -+ X"$file" : 'X\(//\)$' \| \ -+ X"$file" : 'X\(/\)' \| \ -+ . : '\(.\)' 2>/dev/null || -+echo X"$file" | -+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } -+ /^X\(\/\/\)[^/].*/{ s//\1/; q; } -+ /^X\(\/\/\)$/{ s//\1/; q; } -+ /^X\(\/\).*/{ s//\1/; q; } -+ s/.*/./; q'` -+ { if $as_mkdir_p; then -+ mkdir -p $dirpart/$fdir -+ else -+ as_dir=$dirpart/$fdir -+ as_dirs= -+ while test ! -d "$as_dir"; do -+ as_dirs="$as_dir $as_dirs" -+ as_dir=`(dirname "$as_dir") 2>/dev/null || -+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ -+ X"$as_dir" : 'X\(//\)[^/]' \| \ -+ X"$as_dir" : 'X\(//\)$' \| \ -+ X"$as_dir" : 'X\(/\)' \| \ -+ . : '\(.\)' 2>/dev/null || -+echo X"$as_dir" | -+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } -+ /^X\(\/\/\)[^/].*/{ s//\1/; q; } -+ /^X\(\/\/\)$/{ s//\1/; q; } -+ /^X\(\/\).*/{ s//\1/; q; } -+ s/.*/./; q'` -+ done -+ test ! -n "$as_dirs" || mkdir $as_dirs -+ fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 -+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} -+ { (exit 1); exit 1; }; }; } -+ -+ # echo "creating $dirpart/$file" -+ echo '# dummy' > "$dirpart/$file" -+ done -+done -+ ;; -+ esac -+done -+_ACEOF -+ -+cat >>$CONFIG_STATUS <<\_ACEOF -+ -+{ (exit 0); exit 0; } -+_ACEOF - chmod +x $CONFIG_STATUS --rm -fr confdefs* $ac_clean_files --test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 -+ac_clean_files=$ac_clean_files_save -+ -+ -+# configure is writing to config.log, and then calls config.status. -+# config.status does its own redirection, appending to config.log. -+# Unfortunately, on DOS this fails, as config.log is still kept open -+# by configure, so config.status won't be able to write to it; its -+# output is simply discarded. So we exec the FD to /dev/null, -+# effectively closing config.log, so it can be properly (re)opened and -+# appended to by config.status. When coming back to configure, we -+# need to make the FD available again. -+if test "$no_create" != yes; then -+ ac_cs_success=: -+ ac_config_status_args= -+ test "$silent" = yes && -+ ac_config_status_args="$ac_config_status_args --quiet" -+ exec 5>/dev/null -+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false -+ exec 5>>config.log -+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which -+ # would make configure fail if this is the last instruction. -+ $ac_cs_success || { (exit 1); exit 1; } -+fi - - - echo "---------------------------------------------------------" -@@ -6704,7 +17003,7 @@ - if test "$cf_have_gpm" = yes; then echo "GPM support: YES"; else echo "GPM support: NO"; fi - if test "$cf_have_ssl" = yes; then echo "SSL support: YES"; else echo "SSL support: NO"; fi - if test "$cf_use_javascript" = yes; then echo "Javascript enabled: YES"; else echo "Javascript enabled: NO"; fi --if test "$cf_use_graphics" = yes; then -+if test "$cf_use_graphics" = yes; then - echo "Graphics enabled: YES" - echo "Graphics drivers: `echo $drivers|sed 's/^ //'`" - echo "Image formats: $image_formats" -@@ -6718,5 +17017,5 @@ - #rm Makefile.tmp - - #if test -z "$AWK"; then --# AC_WARN([awk not found. You won't be able to rebuild code page table.]); -+# AC_MSG_WARN([awk not found. You won't be able to rebuild code page table.]); - #fi diff --git a/packages/links/links-2.1pre14/.mtn2git_empty b/packages/links/links-2.1pre14/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/links/links-2.1pre14/configure.patch b/packages/links/links-2.1pre14/configure.patch deleted file mode 100644 index 9752378977..0000000000 --- a/packages/links/links-2.1pre14/configure.patch +++ /dev/null @@ -1,258 +0,0 @@ ---- links-2.1pre14/configure.in~configure -+++ links-2.1pre14/configure.in -@@ -3,7 +3,8 @@ - # Martin 'PerM' Pergel - # This file is a part of the Links program, released under GPL. - --AC_INIT(main.c) -+AC_INIT -+AC_CONFIG_SRCDIR([main.c]) - - AM_INIT_AUTOMAKE(links, 2.1pre14) - -@@ -13,12 +14,12 @@ - AUTOHEADER="./missing autoheader" - image_formats="GIF PNG XBM" - --AM_CONFIG_HEADER(config.h) -+AC_CONFIG_HEADERS([config.h]) - - dnl Checks for programs. - AC_PROG_CC - --#AC_PROG_CXX -+AC_PROG_CXX - #AC_PROG_AWK - #AM_PROG_LEX - #AC_PROG_YACC -@@ -27,20 +28,20 @@ - #AC_CHECK_LIB(fl,main,AC_DEFINE(JS) LIBS="$LIBS -lfl",AC_MSG_WARN(You don't have libfl; you won't be able to run javascript)) - - AC_CACHE_CHECK([for EMX], ac_cv_have_emx, -- AC_TRY_COMPILE(, [#ifndef __EMX__ -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[#ifndef __EMX__ - kill me! -- #endif ], ac_cv_have_emx=yes, ac_cv_have_emx=no) -+ #endif ]])],[ac_cv_have_emx=yes],[ac_cv_have_emx=no]) - ) - test "$ac_cv_have_emx" = yes && LDFLAGS=`echo "$LDFLAGS" | sed "s/-Zexe//g" | sed "s/-Zbin-files//g"` - - AC_CACHE_CHECK([for typeof], ac_cv_have_typeof, -- AC_TRY_COMPILE(, [int a; -- typeof(a) b;], ac_cv_have_typeof=yes, ac_cv_have_typeof=no) -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[int a; -+ typeof(a) b;]])],[ac_cv_have_typeof=yes],[ac_cv_have_typeof=no]) - ) - test "$ac_cv_have_typeof" = yes && AC_DEFINE(HAVE_TYPEOF) - - AC_CACHE_CHECK([for long long], ac_cv_have_long_long, -- AC_TRY_COMPILE(, [unsigned long long a; ], ac_cv_have_long_long=yes, ac_cv_have_long_long=no) -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[unsigned long long a; ]])],[ac_cv_have_long_long=yes],[ac_cv_have_long_long=no]) - ) - test "$ac_cv_have_long_long" = yes && AC_DEFINE(HAVE_LONG_LONG) - -@@ -87,7 +88,7 @@ - AC_CHECK_SIZEOF(long, "$default_int") - AC_CHECK_SIZEOF(unsigned long, "$default_int") - AC_CACHE_CHECK([for big endian], ac_cv_big_endian, -- AC_TRY_RUN([ -+ AC_RUN_IFELSE([AC_LANG_SOURCE([[ - long l; - char *c = (char *)&l; - int main() -@@ -95,10 +96,10 @@ - l = 0x12345678L; - return !(c[[sizeof(long) - 1]] == 0x78 && c[[sizeof(long) - 2]] == 0x56 && c[[sizeof(long) - 3]] == 0x34 && c[[sizeof(long) - 4]] == 0x12); - } -- ], ac_cv_big_endian=yes, ac_cv_big_endian=no, ac_cv_big_endian=no) -+ ]])],[ac_cv_big_endian=yes],[ac_cv_big_endian=no],[ac_cv_big_endian=no]) - ) - AC_CACHE_CHECK([for little endian], ac_cv_little_endian, -- AC_TRY_RUN([ -+ AC_RUN_IFELSE([AC_LANG_SOURCE([[ - long l; - char *c = (char *)&l; - int main() -@@ -106,9 +107,12 @@ - l = 0x12345678L; - return !(c[[0]] == 0x78 && c[[1]] == 0x56 && c[[2]] == 0x34 && c[[3]] == 0x12); - } -- ], ac_cv_little_endian=yes, ac_cv_little_endian=no, ac_cv_little_endian="$ac_cv_have_emx") -+ ]])],[ac_cv_little_endian=yes],[ac_cv_little_endian=no],[ac_cv_little_endian="$ac_cv_have_emx"]) - ) - -+AC_DEFUN([AC_BIG_ENDIAN],[],[]) -+AC_DEFUN([AC_LITTLE_ENDIAN],[],[]) -+ - if test "$ac_cv_big_endian" = yes; then - AC_DEFINE(AC_BIG_ENDIAN) - else if test "$ac_cv_little_endian" = yes; then -@@ -122,19 +126,19 @@ - AC_TYPE_SIGNAL - AC_FUNC_STRFTIME - AC_FUNC_VPRINTF --AC_HAVE_FUNCS(calloc) --AC_HAVE_FUNCS(snprintf) --AC_HAVE_FUNCS(gettimeofday mkdir select strcspn strerror strstr strtol strtoul alarm chmod) --AC_HAVE_FUNCS(getpid setpgid getpgid setpgrp getpgrp) --AC_HAVE_FUNCS(popen) --AC_HAVE_FUNCS(uname) --AC_HAVE_FUNCS(strptime) --AC_HAVE_FUNCS(setlocale) --AC_HAVE_FUNCS(nl_langinfo) --dnl AC_HAVE_FUNCS(sigsetjmp siglongjmp) -+AC_CHECK_FUNCS([calloc]) -+AC_CHECK_FUNCS([snprintf]) -+AC_CHECK_FUNCS([gettimeofday mkdir select strcspn strerror strstr strtol strtoul alarm chmod]) -+AC_CHECK_FUNCS([getpid setpgid getpgid setpgrp getpgrp]) -+AC_CHECK_FUNCS([popen]) -+AC_CHECK_FUNCS([uname]) -+AC_CHECK_FUNCS([strptime]) -+AC_CHECK_FUNCS([setlocale]) -+AC_CHECK_FUNCS([nl_langinfo]) -+dnl AC_CHECK_FUNCS([sigsetjmp siglongjmp]) - - AC_CACHE_CHECK([for sigsetjmp/siglongjmp], ac_cv_have_sigsetjmp, -- AC_TRY_LINK([#include ], [sigjmp_buf env;sigsetjmp(env, 1);siglongjmp(env, 2);], ac_cv_have_sigsetjmp=yes, ac_cv_have_sigsetjmp=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[sigjmp_buf env;sigsetjmp(env, 1);siglongjmp(env, 2);]])],[ac_cv_have_sigsetjmp=yes],[ac_cv_have_sigsetjmp=no]) - ) - if test "$ac_cv_have_sigsetjmp" = yes; then - AC_DEFINE(HAVE_SIGSETJMP) -@@ -153,7 +157,7 @@ - fi - - #AC_MSG_CHECKING([for gethostbyname]) --#AC_TRY_LINK([#include ], [gethostbyname("")], cf_result=yes, cf_result=no) -+#AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[gethostbyname("")]])],[cf_result=yes],[cf_result=no]) - #AC_MSG_RESULT($cf_result) - AC_CHECK_FUNC(gethostbyname, cf_result=yes, cf_result=no) - if test "$cf_result" = no; then -@@ -168,7 +172,7 @@ - AC_CHECK_FUNC(herror, AC_DEFINE(HAVE_HERROR)) - AC_CHECK_FUNC(cfmakeraw, AC_DEFINE(HAVE_CFMAKERAW)) - --AC_HAVE_FUNCS(cygwin_conv_to_full_win32_path) -+AC_CHECK_FUNCS([cygwin_conv_to_full_win32_path]) - - AC_MSG_CHECKING([if you want to enable javascript]) - AC_ARG_ENABLE(javascript, [ --enable-javascript use javascript interpreter], cf_use_javascript=yes, cf_use_javascript=no) -@@ -192,7 +196,7 @@ - AC_CACHE_CHECK([for OS/2 threads], ac_cv_have_beginthread, - CFLAGS_X="$CFLAGS" - CFLAGS="$CFLAGS -Zmt" -- AC_TRY_LINK([#include ], [_beginthread(NULL, NULL, 0, NULL)], ac_cv_have_beginthread=yes, ac_cv_have_beginthread=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[_beginthread(NULL, NULL, 0, NULL)]])],[ac_cv_have_beginthread=yes],[ac_cv_have_beginthread=no]) - CFLAGS="$CFLAGS_X" - ) - if test "$ac_cv_have_beginthread" = yes; then -@@ -209,8 +213,8 @@ - fi - #AC_CHECK_FUNC(clone, AC_DEFINE(HAVE_CLONE)) - AC_CHECK_HEADERS(atheos/threads.h) --AC_HAVE_FUNCS(spawn_thread) --AC_HAVE_FUNCS(resume_thread) -+AC_CHECK_FUNCS([spawn_thread]) -+AC_CHECK_FUNCS([resume_thread]) - - AC_CHECK_FUNC(MouOpen, AC_DEFINE(HAVE_MOUOPEN)) - AC_CHECK_FUNC(_read_kbd, AC_DEFINE(HAVE_READ_KBD)) -@@ -222,10 +226,10 @@ - if test -n "$X11ROOT"; then - CPPFLAGS="$CPPFLAGS_X -I$X11ROOT/XFree86/include" - LIBS="$LIBS_X -L$X11ROOT/XFree86/lib -lxf86_gcc" -- AC_TRY_LINK([#include ], [struct winsize win;ptioctl(1, TIOCGWINSZ, &win)], ac_cv_have_x2=xf86_gcc, ac_cv_have_x2=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct winsize win;ptioctl(1, TIOCGWINSZ, &win)]])],[ac_cv_have_x2=xf86_gcc],[ac_cv_have_x2=no]) - if test "$ac_cv_have_x2" = no; then - LIBS="$LIBS_X -L$X11ROOT/XFree86/lib -lxf86" -- AC_TRY_LINK([#include ], [struct winsize win;ptioctl(1, TIOCGWINSZ, &win)], ac_cv_have_x2=xf86, ac_cv_have_x2=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct winsize win;ptioctl(1, TIOCGWINSZ, &win)]])],[ac_cv_have_x2=xf86],[ac_cv_have_x2=no]) - fi - fi - CPPFLAGS="$CPPFLAGS_X" -@@ -254,9 +258,9 @@ - else - LIBS="-lssl -lcrypto $LIBS_X" - fi -- AC_TRY_LINK([#include ], [OpenSSL_add_all_algorithms()], cf_result=yes, cf_result=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[OpenSSL_add_all_algorithms()]])],[cf_result=yes],[cf_result=no]) - if test "$cf_result" != yes; then -- AC_TRY_LINK([#include ], [SSLeay_add_ssl_algorithms()], cf_result=yes, cf_result=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[SSLeay_add_ssl_algorithms()]])],[cf_result=yes],[cf_result=no]) - fi - fi - done -@@ -287,14 +291,14 @@ - AC_CHECK_HEADERS(png.h libpng/png.h) - AC_CHECK_LIB(png, png_create_info_struct) - if test "$ac_cv_header_png_h" != yes && test "$ac_cv_header_libpng_png_h" != yes || test "$ac_cv_lib_png_png_create_info_struct" != yes; then -- AC_ERROR([You need libpng to compile Links in graphics mode]) -+ AC_MSG_ERROR([You need libpng to compile Links in graphics mode]) - fi - -- AC_HAVE_FUNCS(png_set_rgb_to_gray) -+ AC_CHECK_FUNCS([png_set_rgb_to_gray]) - - AC_CACHE_CHECK(if you can include both setjmp.h and png.h, ac_cv_include_setjmp_png, -- AC_TRY_COMPILE([#include -- #include ], [jmp_buf bla;], ac_cv_include_setjmp_png=yes, ac_cv_include_setjmp_png=no) -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include -+ #include ]], [[jmp_buf bla;]])],[ac_cv_include_setjmp_png=yes],[ac_cv_include_setjmp_png=no]) - ) - - if test "$ac_cv_include_setjmp_png" != yes; then -@@ -338,7 +342,7 @@ - AC_CACHE_CHECK([for svgalib], ac_cv_have_svgalib, - LIBS_X="$LIBS" - LIBS="$LIBS -lvga" -- AC_TRY_LINK([#include ], [vga_setmode(0)], ac_cv_have_svgalib=yes, ac_cv_have_svgalib=no) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[vga_setmode(0)]])],[ac_cv_have_svgalib=yes],[ac_cv_have_svgalib=no]) - LIBS="$LIBS_X" - ) - -@@ -351,9 +355,9 @@ - - dnl braine, tohle jsem predelal - dnl AC_CACHE_CHECK([for framebuffer], ac_cv_have_fb, --dnl AC_TRY_RUN([#include -+dnl AC_RUN_IFELSE([AC_LANG_SOURCE([[#include - dnl #include --dnl main(){return open("/dev/fb",O_RDWR)==-1;}], ac_cv_have_fb=yes, ac_cv_have_fb=no, ac_cv_have_fb=no) -+dnl main(){return open("/dev/fb",O_RDWR)==-1;}]])],[ac_cv_have_fb=yes],[ac_cv_have_fb=no],[ac_cv_have_fb=no]) - dnl ) - - if test "$disable_fb" != yes ; then -@@ -406,14 +410,12 @@ - - if test "$disable_pmshell" != yes ; then - AC_CACHE_CHECK([for pmshell], ac_cv_have_pmshell, -- AC_TRY_LINK([#define INCL_WIN -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define INCL_WIN - #define INCL_GPI - #include -- #include ], -- [_fmutex mutex; -+ #include ]], [[_fmutex mutex; - WinDrawText(NULLHANDLE, -1, NULL, NULL, 0, 0, 0), -- GpiSetPel(NULLHANDLE, NULL)], -- ac_cv_have_pmshell=yes, ac_cv_have_pmshell=no) -+ GpiSetPel(NULLHANDLE, NULL)]])],[ac_cv_have_pmshell=yes],[ac_cv_have_pmshell=no]) - ) - - if test "$ac_cv_have_pmshell" = yes; then -@@ -463,7 +465,8 @@ - test "$ac_cv_have_emx" = yes && LDFLAGS="$LDFLAGS -Zexe" - test "$ac_cv_have_emx" = yes && LDFLAGS=`echo "$LDFLAGS" | sed "s/-Zbin-files//g"` - --AC_OUTPUT(Makefile) -+AC_CONFIG_FILES([Makefile]) -+AC_OUTPUT - - echo "---------------------------------------------------------" - echo "Configuration results:" -@@ -485,5 +488,5 @@ - #rm Makefile.tmp - - #if test -z "$AWK"; then --# AC_WARN([awk not found. You won't be able to rebuild code page table.]); -+# AC_MSG_WARN([awk not found. You won't be able to rebuild code page table.]); - #fi diff --git a/packages/links/links-x11_2.1pre21.bb b/packages/links/links-x11_2.1pre21.bb deleted file mode 100644 index 4323b2e59a..0000000000 --- a/packages/links/links-x11_2.1pre21.bb +++ /dev/null @@ -1,21 +0,0 @@ -LICENSE = "GPL" -SECTION = "console/network" -DEPENDS = "jpeg libpng flex openssl zlib virtual/libx11" -DESCRIPTION = "Links is graphics and text mode WWW \ -browser, similar to Lynx." -RCONFLICTS = "links" - -MAINTAINER = "Graeme Gregory " - -SRC_URI = "http://links.twibright.com/download/links-${PV}.tar.bz2 \ - file://ac-prog-cxx.patch;patch=1" - -inherit autotools - -EXTRA_OECONF = "--enable-javascript --with-libfl --enable-graphics \ - --with-ssl=${STAGING_LIBDIR}/.. --with-libjpeg \ - --without-libtiff --without-svgalib --without-fb \ - --without-directfb --without-pmshell --without-atheos \ - --with-x --without-gpm --without-sdl" - -S = "${WORKDIR}/links-${PV}" diff --git a/packages/links/links-x11_2.1pre22.bb b/packages/links/links-x11_2.1pre22.bb index 4323b2e59a..9c9bb831aa 100644 --- a/packages/links/links-x11_2.1pre22.bb +++ b/packages/links/links-x11_2.1pre22.bb @@ -8,7 +8,11 @@ RCONFLICTS = "links" MAINTAINER = "Graeme Gregory " SRC_URI = "http://links.twibright.com/download/links-${PV}.tar.bz2 \ - file://ac-prog-cxx.patch;patch=1" + file://ac-prog-cxx.patch;patch=1 \ + file://cookies-save-0.96.patch;patch=1 \ + file://links-2.1pre17-fix-segfault-on-loading-cookies.patch;patch=1" + +PR = "r1" inherit autotools diff --git a/packages/links/links_2.1pre12.bb b/packages/links/links_2.1pre12.bb deleted file mode 100644 index 8ab27c6c31..0000000000 --- a/packages/links/links_2.1pre12.bb +++ /dev/null @@ -1,16 +0,0 @@ -LICENSE = "GPL" -SECTION = "console/network" -DEPENDS = "jpeg libpng gpm flex openssl zlib" -DESCRIPTION = "Links is graphics and text mode WWW \ -browser, similar to Lynx." - -SRC_URI = "http://links.twibright.com/download/links-${PV}.tar.bz2 \ - file://configure.patch;patch=1" - -inherit autotools - -EXTRA_OECONF = "--enable-javascript --with-libfl --enable-graphics \ - --with-ssl=${STAGING_LIBDIR}/.. --with-libjpeg \ - --without-libtiff --without-svgalib --without-x --with-fb \ - --without-directfb --without-pmshell --without-atheos \ - --without-x" diff --git a/packages/links/links_2.1pre14.bb b/packages/links/links_2.1pre14.bb deleted file mode 100644 index a852456ba8..0000000000 --- a/packages/links/links_2.1pre14.bb +++ /dev/null @@ -1,16 +0,0 @@ -LICENSE = "GPL" -SECTION = "console/network" -DEPENDS = "jpeg libpng gpm flex openssl zlib" -DESCRIPTION = "Links is graphics and text mode WWW \ -browser, similar to Lynx." - -SRC_URI = "http://links.twibright.com/download/links-${PV}.tar.bz2 \ - file://configure.patch;patch=1" - -inherit autotools - -EXTRA_OECONF = "--enable-javascript --with-libfl --enable-graphics \ - --with-ssl=${STAGING_LIBDIR}/.. --with-libjpeg \ - --without-libtiff --without-svgalib --with-fb \ - --without-directfb --without-pmshell --without-atheos \ - --without-x" diff --git a/packages/links/links_2.1pre21.bb b/packages/links/links_2.1pre21.bb deleted file mode 100644 index e0a991e148..0000000000 --- a/packages/links/links_2.1pre21.bb +++ /dev/null @@ -1,19 +0,0 @@ -LICENSE = "GPL" -SECTION = "console/network" -DEPENDS = "jpeg libpng gpm flex openssl zlib" -DESCRIPTION = "Links is graphics and text mode WWW \ -browser, similar to Lynx." -RCONFLICTS="links-x11" - -MAINTAINER = "Graeme Gregory " - -SRC_URI = "http://links.twibright.com/download/links-${PV}.tar.bz2 \ - file://ac-prog-cxx.patch;patch=1" - -inherit autotools - -EXTRA_OECONF = "--enable-javascript --with-libfl --enable-graphics \ - --with-ssl=${STAGING_LIBDIR}/.. --with-libjpeg \ - --without-libtiff --without-svgalib --with-fb \ - --without-directfb --without-pmshell --without-atheos \ - --without-x --without-sdl" diff --git a/packages/links/links_2.1pre22.bb b/packages/links/links_2.1pre22.bb index e0a991e148..faed366594 100644 --- a/packages/links/links_2.1pre22.bb +++ b/packages/links/links_2.1pre22.bb @@ -8,7 +8,11 @@ RCONFLICTS="links-x11" MAINTAINER = "Graeme Gregory " SRC_URI = "http://links.twibright.com/download/links-${PV}.tar.bz2 \ - file://ac-prog-cxx.patch;patch=1" + file://ac-prog-cxx.patch;patch=1 \ + file://cookies-save-0.96.patch;patch=1 \ + file://links-2.1pre17-fix-segfault-on-loading-cookies.patch;patch=1" + +PR = "r1" inherit autotools -- cgit v1.2.3 From 98928e07d9798f59e1db3d7fcd47fd2c63766be2 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 17:31:47 +0000 Subject: Add MACHINE_TASK_PROVIDER to remove hardcoded references to task-bootstrap and allow machines/distros to elect an alternative --- conf/bitbake.conf | 1 + packages/images/bootstrap-image-bootchart.bb | 4 ++-- packages/images/bootstrap-image.bb | 4 ++-- packages/images/dvb-image.bb | 2 +- packages/images/e-image-core.bb | 4 ++-- packages/images/gpe-image.bb | 4 ++-- packages/images/maemo-image.bb | 4 ++-- packages/images/mythfront-image.bb | 2 +- packages/images/opie-image.bb | 4 ++-- packages/images/sdl-image.bb | 4 ++-- packages/images/sectest-gpe-image.bb | 4 ++-- packages/images/twin-image.bb | 4 ++-- packages/images/uml-image.bb | 2 +- packages/images/xfce-image.bb | 2 +- packages/images/xterminal-image.bb | 2 +- 15 files changed, 24 insertions(+), 23 deletions(-) diff --git a/conf/bitbake.conf b/conf/bitbake.conf index 1cb03f30bd..9f94bae3f5 100644 --- a/conf/bitbake.conf +++ b/conf/bitbake.conf @@ -409,6 +409,7 @@ require conf/sanity.conf IMAGE_FSTYPES ?= "jffs2" PCMCIA_MANAGER ?= "pcmcia-cs" +MACHINE_TASK_PROVIDER ?= "task-bootstrap" ################################################################## diff --git a/packages/images/bootstrap-image-bootchart.bb b/packages/images/bootstrap-image-bootchart.bb index 68cfac7490..04b1aa299d 100644 --- a/packages/images/bootstrap-image-bootchart.bb +++ b/packages/images/bootstrap-image-bootchart.bb @@ -1,8 +1,8 @@ export IMAGE_BASENAME = "bootstrap-image-bootchart" export IMAGE_LINGUAS = "" -export IPKG_INSTALL = "task-bootstrap bootchart acct" +export IPKG_INSTALL = "${MACHINE_TASK_PROVIDER} bootchart acct" -DEPENDS = "task-bootstrap bootchart" +DEPENDS = "${MACHINE_TASK_PROVIDER} bootchart" RDEPENDS = "acct" inherit image_ipk diff --git a/packages/images/bootstrap-image.bb b/packages/images/bootstrap-image.bb index 1791dd8f56..50c1a8f354 100644 --- a/packages/images/bootstrap-image.bb +++ b/packages/images/bootstrap-image.bb @@ -1,8 +1,8 @@ export IMAGE_BASENAME = "bootstrap-image" export IMAGE_LINGUAS = "" -export IPKG_INSTALL = "task-bootstrap" +export IPKG_INSTALL = "${MACHINE_TASK_PROVIDER}" -DEPENDS = "task-bootstrap" +DEPENDS = "${MACHINE_TASK_PROVIDER}" inherit image_ipk diff --git a/packages/images/dvb-image.bb b/packages/images/dvb-image.bb index fa964b4490..b1c714c79e 100644 --- a/packages/images/dvb-image.bb +++ b/packages/images/dvb-image.bb @@ -2,7 +2,7 @@ export IMAGE_BASENAME = "dvb-image" IMAGE_LINGUAS = "" -DVB_PACKAGES = "task-bootstrap task-dvb" +DVB_PACKAGES = "${MACHINE_TASK_PROVIDER} task-dvb" export IPKG_INSTALL = "${DVB_PACKAGES}" DEPENDS = "${DVB_PACKAGES}" diff --git a/packages/images/e-image-core.bb b/packages/images/e-image-core.bb index 9a1ed51a1a..f41f04ee23 100644 --- a/packages/images/e-image-core.bb +++ b/packages/images/e-image-core.bb @@ -5,7 +5,7 @@ PR = "r1" export IMAGE_BASENAME = "e-image-core" export IMAGE_LINGUAS = "" -DEPENDS = "task-bootstrap \ +DEPENDS = "${MACHINE_TASK_PROVIDER} \ xserver-kdrive \ task-e-x11-core" @@ -16,6 +16,6 @@ PREFERRED_PROVIDER_virtual/imlib2 = "imlib2-x11" PREFERRED_PROVIDER_virtual/libxine = "libxine-x11" PREFERRED_PROVIDER_libx11 = "libx11" -export IPKG_INSTALL = "task-bootstrap task-e-x11-core xserver-kdrive-fbdev glibc-charmap-utf-8 glibc-localedata-i18n" +export IPKG_INSTALL = "${MACHINE_TASK_PROVIDER} task-e-x11-core xserver-kdrive-fbdev glibc-charmap-utf-8 glibc-localedata-i18n" inherit image_ipk diff --git a/packages/images/gpe-image.bb b/packages/images/gpe-image.bb index 92bed0dd5c..75aa14a0f4 100644 --- a/packages/images/gpe-image.bb +++ b/packages/images/gpe-image.bb @@ -24,11 +24,11 @@ GPE_EXTRA_INSTALL += ${GPE_BIGFLASH_INSTALL} XSERVER ?= "xserver-kdrive-fbdev" -DEPENDS = "task-bootstrap task-gpe" +DEPENDS = "${MACHINE_TASK_PROVIDER} task-gpe" RDEPENDS = "${IPKG_INSTALL}" export IPKG_INSTALL = "\ - task-bootstrap \ + ${MACHINE_TASK_PROVIDER} \ gpe-task-base \ gpe-task-pim \ gpe-task-settings \ diff --git a/packages/images/maemo-image.bb b/packages/images/maemo-image.bb index 2adc88b958..19157b6a5f 100644 --- a/packages/images/maemo-image.bb +++ b/packages/images/maemo-image.bb @@ -15,11 +15,11 @@ MAEMO_EXTRA_INSTALL = "osso-af-services osso-af-base-apps scap dosfstools" XSERVER ?= "xserver-kdrive-omap" -DEPENDS = "task-bootstrap \ +DEPENDS = "${MACHINE_TASK_PROVIDER} \ meta-maemo \ ${MAEMO_EXTRA_DEPENDS}" -export IPKG_INSTALL = "task-bootstrap maemo-task-base maemo-task-theme \ +export IPKG_INSTALL = "${MACHINE_TASK_PROVIDER} maemo-task-base maemo-task-theme \ maemo-task-apps ${MAEMO_EXTRA_INSTALL} \ ${XSERVER}" diff --git a/packages/images/mythfront-image.bb b/packages/images/mythfront-image.bb index 7836258940..31992e4bc8 100644 --- a/packages/images/mythfront-image.bb +++ b/packages/images/mythfront-image.bb @@ -4,7 +4,7 @@ IMAGE_ROOTFS_SIZE_ext2 = "85000" IMAGE_ROOTFS_SIZE_ext2.gz = "85000" IMAGE_LINGUAS = "" -MYTHFRONT_PACKAGES = "task-bootstrap task-mythfront" +MYTHFRONT_PACKAGES = "${MACHINE_TASK_PROVIDER} task-mythfront" export IPKG_INSTALL = "${MYTHFRONT_PACKAGES}" DEPENDS = "${MYTHFRONT_PACKAGES}" diff --git a/packages/images/opie-image.bb b/packages/images/opie-image.bb index c786f67e0b..b7c68ec505 100644 --- a/packages/images/opie-image.bb +++ b/packages/images/opie-image.bb @@ -6,12 +6,12 @@ FEED_URIS_append_familiar = " opie##http://familiar.handhelds.org/releases/${D LICENSE = "MIT" PR = "r21" -DEPENDS = "task-bootstrap task-opie" +DEPENDS = "${MACHINE_TASK_PROVIDER} task-opie" RDEPENDS = "${INSTALL_PACKAGES}" extra_stuff := '${@base_conditional("ROOT_FLASH_SIZE", "24", "", "task-opie-extra-games task-opie-extra-apps task-opie-extra-styles",d)}' -INSTALL_PACKAGES = "task-bootstrap task-opie-base task-opie-base-applets \ +INSTALL_PACKAGES = "${MACHINE_TASK_PROVIDER} task-opie-base task-opie-base-applets \ task-opie-base-inputmethods task-opie-base-apps \ task-opie-base-settings task-opie-base-decorations \ task-opie-base-styles task-opie-base-pim \ diff --git a/packages/images/sdl-image.bb b/packages/images/sdl-image.bb index 0f3254b56e..79c8094f34 100644 --- a/packages/images/sdl-image.bb +++ b/packages/images/sdl-image.bb @@ -2,8 +2,8 @@ LICENSE = MIT export IMAGE_BASENAME = "sdl-image" -DEPENDS = "task-bootstrap task-sdl" +DEPENDS = "${MACHINE_TASK_PROVIDER} task-sdl" -export IPKG_INSTALL = "task-bootstrap sdl-base" +export IPKG_INSTALL = "${MACHINE_TASK_PROVIDER} sdl-base" inherit image_ipk diff --git a/packages/images/sectest-gpe-image.bb b/packages/images/sectest-gpe-image.bb index be7f28fb91..1ddd022d08 100644 --- a/packages/images/sectest-gpe-image.bb +++ b/packages/images/sectest-gpe-image.bb @@ -21,11 +21,11 @@ GPE_EXTRA_INSTALL += "${GPE_EXTRA_INSTALL_${GUI_MACHINE_CLASS}}" XSERVER ?= "xserver-kdrive-fbdev" -DEPENDS = "task-bootstrap task-gpe" +DEPENDS = "${MACHINE_TASK_PROVIDER} task-gpe" RDEPENDS = "${IPKG_INSTALL}" export IPKG_INSTALL = "\ - task-bootstrap \ + ${MACHINE_TASK_PROVIDER} \ gpe-task-base \ gpe-task-pim \ gpe-task-settings \ diff --git a/packages/images/twin-image.bb b/packages/images/twin-image.bb index 7015f7020c..f609dfd07e 100644 --- a/packages/images/twin-image.bb +++ b/packages/images/twin-image.bb @@ -1,13 +1,13 @@ export IMAGE_BASENAME="twin-image" -DEPENDS = 'task-bootstrap \ +DEPENDS = '${MACHINE_TASK_PROVIDER} \ twin \ orpheus \ nano \ vim \ mutt' -export IPKG_INSTALL = 'task-bootstrap \ +export IPKG_INSTALL = '${MACHINE_TASK_PROVIDER} \ twin \ orpheus \ nano \ diff --git a/packages/images/uml-image.bb b/packages/images/uml-image.bb index 6ebbf04537..5b6981488e 100644 --- a/packages/images/uml-image.bb +++ b/packages/images/uml-image.bb @@ -6,7 +6,7 @@ export IMAGE_BASENAME = "uml-image" OPIE_LIBS = "qte qpf-bitstream-vera libqpe-opie libopie2" OPIE_BASE = "opie-qcop opie-quicklauncher opie-taskbar" -DEPENDS = "task-bootstrap" +DEPENDS = "${MACHINE_TASK_PROVIDER}" export IPKG_INSTALL = "${DEPENDS}" inherit image_ipk diff --git a/packages/images/xfce-image.bb b/packages/images/xfce-image.bb index 5605a6b2ee..f861b9e6dd 100644 --- a/packages/images/xfce-image.bb +++ b/packages/images/xfce-image.bb @@ -5,7 +5,7 @@ IMAGE_LINGUAS = "" X_DEPENDS = "virtual/xserver" X_RDEPENDS = "xserver-kdrive-fbdev" -XFCE_DEPENDS = "task-bootstrap task-xfce-base" +XFCE_DEPENDS = "${MACHINE_TASK_PROVIDER} task-xfce-base" XFCE_RDEPENDS = "${XFCE_DEPENDS}" export IPKG_INSTALL = "${X_RDEPENDS} ${XFCE_RDEPENDS}" diff --git a/packages/images/xterminal-image.bb b/packages/images/xterminal-image.bb index 2b98ec98fc..d6cc7b1640 100644 --- a/packages/images/xterminal-image.bb +++ b/packages/images/xterminal-image.bb @@ -2,7 +2,7 @@ export IMAGE_BASENAME = "xterminal-image" IMAGE_LINGUAS = "" -XTERMINAL_PACKAGES = "task-bootstrap task-xterminal" +XTERMINAL_PACKAGES = "${MACHINE_TASK_PROVIDER} task-xterminal" export IPKG_INSTALL = "${XTERMINAL_PACKAGES}" DEPENDS = "${XTERMINAL_PACKAGES}" -- cgit v1.2.3 From f3e5a3eab0610d378a30a5688f29e277162635c1 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 17:33:29 +0000 Subject: Switch 2.6 Zaurus models to use task-base --- conf/machine/include/poodle-2.6.conf | 40 +---------------------- conf/machine/include/tosa-2.6.conf | 4 +-- conf/machine/include/zaurus-clamshell-2.6.conf | 45 ++++++-------------------- 3 files changed, 12 insertions(+), 77 deletions(-) diff --git a/conf/machine/include/poodle-2.6.conf b/conf/machine/include/poodle-2.6.conf index 1b128ea6cb..eff0ad4c7c 100644 --- a/conf/machine/include/poodle-2.6.conf +++ b/conf/machine/include/poodle-2.6.conf @@ -1,39 +1 @@ -PREFERRED_PROVIDER_virtual/kernel = "linux-openzaurus" - -PCMCIA_MANAGER ?= "pcmciautils" - -BOOTSTRAP_EXTRA_RDEPENDS += "kernel udev sysfsutils spectrum-fw \ -${PCMCIA_MANAGER} apm wireless-tools irda-utils udev-utils keymaps hostap-utils prism3-firmware prism3-support \ -ppp ppp-dialin alsa-utils-alsactl alsa-utils-alsamixer module-init-tools alsa-conf zaurusd" - -# Ethernet modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-pcnet-cs" -# NFS Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-nfs kernel-module-lockd kernel-module-sunrpc" -# Crypto Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-des kernel-module-md5" -# SMB and CRAMFS -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-smbfs kernel-module-cramfs" -# Serial Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-8250 kernel-module-serial-cs" -# Bluetooth Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-bluetooth kernel-module-l2cap kernel-module-rfcomm kernel-module-hci-vhci \ - kernel-module-bnep kernel-module-hidp kernel-module-hci-uart kernel-module-sco \ - kernel-module-bt3c-cs kernel-module-bluecard-cs kernel-module-btuart-cs kernel-module-dtl1-cs" -# Infrared Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-pxaficp-ir kernel-module-irda kernel-module-ircomm \ - kernel-module-ircomm-tty kernel-module-irlan kernel-module-irnet kernel-module-ir-usb" - -# USB Gadget Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-gadgetfs kernel-module-g-file-storage \ - kernel-module-g-serial kernel-module-g-ether" - -# Wireless Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-hostap kernel-module-hostap-cs \ - kernel-module-hermes kernel-module-orinoco \ - kernel-module-orinoco-cs kernel-module-spectrum-cs \ - hostap-conf orinoco-conf" - -# Sound Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-snd-mixer-oss kernel-module-snd-pcm-oss" -BOOTSTRAP_EXTRA_RDEPENDS_append_poodle += " kernel-module-snd-soc-poodle " +require conf/machine/include/zaurus-clamshell-2.6.conf diff --git a/conf/machine/include/tosa-2.6.conf b/conf/machine/include/tosa-2.6.conf index c7805c36fe..6831b0ea91 100644 --- a/conf/machine/include/tosa-2.6.conf +++ b/conf/machine/include/tosa-2.6.conf @@ -1,6 +1,6 @@ include conf/machine/include/zaurus-clamshell-2.6.conf # wlan-ng Modules -BOOTSTRAP_EXTRA_RDEPENDS += "wlan-ng-modules-usb" +MACHINE_EXTRA_RDEPENDS += "wlan-ng-modules-usb" # WM97xx Modules -#BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-wm97xx-core kernel-module-wm9705 kernel-module-pxa-wm97xx" +#MACHINE_EXTRA_RRECOMMENDS += "kernel-module-wm97xx-core kernel-module-wm9705 kernel-module-pxa-wm97xx" diff --git a/conf/machine/include/zaurus-clamshell-2.6.conf b/conf/machine/include/zaurus-clamshell-2.6.conf index 2433c5a748..e0a9e38e91 100644 --- a/conf/machine/include/zaurus-clamshell-2.6.conf +++ b/conf/machine/include/zaurus-clamshell-2.6.conf @@ -6,42 +6,15 @@ PREFERRED_VERSION_wpa_supplicant = "0.4.7" PCMCIA_MANAGER ?= "pcmciautils" -BOOTSTRAP_EXTRA_RDEPENDS += "kernel udev sysfsutils spectrum-fw \ -${PCMCIA_MANAGER} apm wireless-tools irda-utils udev-utils keymaps hostap-utils prism3-firmware prism3-support \ -ppp ppp-dialin wpa-supplicant-nossl alsa-utils-alsactl alsa-utils-alsamixer module-init-tools alsa-conf zaurusd" +MACHINE_FEATURES = "kernel26 apm alsa pcmcia bluetooth irda usbgadget" +MACHINE_FEATURES_akita = "kernel26 apm alsa pcmcia bluetooth irda usbgadget usbhost" +MACHINE_FEATURES_spitz = "kernel26 apm alsa pcmcia bluetooth irda usbgadget usbhost ext2" -# Ethernet modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-pcnet-cs" -# NFS Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-nfs kernel-module-lockd kernel-module-sunrpc" -# Crypto Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-des kernel-module-md5" -# SMB and CRAMFS -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-smbfs kernel-module-cramfs" -# Serial Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-8250 kernel-module-serial-cs" -# Bluetooth Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-bluetooth kernel-module-l2cap kernel-module-rfcomm kernel-module-hci-vhci \ - kernel-module-bnep kernel-module-hidp kernel-module-hci-uart kernel-module-sco \ - kernel-module-bt3c-cs kernel-module-bluecard-cs kernel-module-btuart-cs kernel-module-dtl1-cs" -# Infrared Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-pxaficp-ir kernel-module-irda kernel-module-ircomm \ - kernel-module-ircomm-tty kernel-module-irlan kernel-module-irnet kernel-module-ir-usb" -# USB Gadget Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-gadgetfs kernel-module-g-file-storage \ - kernel-module-g-serial kernel-module-g-ether" +MACHINE_EXTRA_RDEPENDS = "zaurusd" +MACHINE_EXTRA_RRECOMMENDS_c7x0 = "kernel-module-snd-soc-corgi" +MACHINE_EXTRA_RRECOMMENDS_akita = "kernel-module-snd-soc-spitz" +MACHINE_EXTRA_RRECOMMENDS_spitz = "kernel-module-snd-soc-spitz" +MACHINE_EXTRA_RRECOMMENDS_poodle = "kernel-module-snd-soc-poodle" -# Wireless Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-hostap kernel-module-hostap-cs \ - kernel-module-hermes kernel-module-orinoco \ - kernel-module-orinoco-cs kernel-module-spectrum-cs \ - hostap-conf orinoco-conf" - -# Sound Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-snd-mixer-oss kernel-module-snd-pcm-oss" - -BOOTSTRAP_EXTRA_RDEPENDS_append_c7x0 += " kernel-module-snd-soc-corgi " -BOOTSTRAP_EXTRA_RDEPENDS_append_akita += " kernel-module-snd-soc-spitz " -BOOTSTRAP_EXTRA_RDEPENDS_append_spitz += " kernel-module-snd-soc-spitz " -BOOTSTRAP_EXTRA_RDEPENDS_append_poodle += " kernel-module-snd-soc-poodle " +MACHINE_TASK_PROVIDER = "task-base" \ No newline at end of file -- cgit v1.2.3 From ea43a6c869027d4d3b45999fa4d95d2be78e00d6 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 27 Aug 2006 17:34:21 +0000 Subject: e17 menu-convert: set package arch to all --- packages/e17/e17-gpe-menu-convert_0.2.bb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/e17/e17-gpe-menu-convert_0.2.bb b/packages/e17/e17-gpe-menu-convert_0.2.bb index a2db9f0686..1b3181fb95 100644 --- a/packages/e17/e17-gpe-menu-convert_0.2.bb +++ b/packages/e17/e17-gpe-menu-convert_0.2.bb @@ -4,7 +4,10 @@ RDEPENDS += "edje-utils e-wm" LICENSE = "MIT" SECTION = "e/apps" MAINTAINER = "Justin Patrin " -PR = "r3" +PR = "r4" + +#this is a shell script +PACKAGE_ARCH = "all" SRC_URI = "file://e17-gpe-menu-convert.sh" -- cgit v1.2.3 From 08793d9b0ed1ea32c5548152e23c252fa3f1aecd Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 21:29:41 +0000 Subject: Add DISTRO_FEATURES to angstrom, familar and openzaurus. At this moment this maintains status quo but distro maintainers are free to adjust it to their needs --- conf/distro/include/angstrom.inc | 3 +++ conf/distro/include/familiar.inc | 3 +++ conf/distro/include/openzaurus.inc | 3 +++ 3 files changed, 9 insertions(+) diff --git a/conf/distro/include/angstrom.inc b/conf/distro/include/angstrom.inc index 7e765bd925..5ff9e1c942 100644 --- a/conf/distro/include/angstrom.inc +++ b/conf/distro/include/angstrom.inc @@ -46,3 +46,6 @@ DEPLOY_DIR_IMAGE = ${DEPLOY_DIR}/images/${MACHINE} # Angstrom *always* has some form of release config, so error out if someone thinks he knows better DISTRO_CHECK := "${@bb.data.getVar("DISTRO_VERSION",d,1) or bb.fatal('Remove this line or set a dummy DISTRO_VERSION if you really want to build an unversioned distro')}" + +# We want images supporting the following features (for task-base) +DISTO_FEATURES = "nfs smbfs ipsec wifi ppp alsa bluetooth ext2 irda pcmcia usbgadget usbhost" diff --git a/conf/distro/include/familiar.inc b/conf/distro/include/familiar.inc index 2646fe78a6..c7f2a05177 100644 --- a/conf/distro/include/familiar.inc +++ b/conf/distro/include/familiar.inc @@ -15,3 +15,6 @@ PARALLEL_INSTALL_MODULES = "1" UDEV_DEVFS_RULES = "1" DISTRO_CHECK := "${@bb.data.getVar("DISTRO_VERSION",d,1) or bb.fatal('Remove this line or set a dummy DISTRO_VERSION if you really want to build an unversioned distro')}" + +# We want images supporting the following features (for task-base) +DISTO_FEATURES = "nfs smbfs ipsec wifi ppp alsa bluetooth ext2 irda pcmcia usbgadget usbhost" diff --git a/conf/distro/include/openzaurus.inc b/conf/distro/include/openzaurus.inc index 264cceecfd..01877956ed 100644 --- a/conf/distro/include/openzaurus.inc +++ b/conf/distro/include/openzaurus.inc @@ -20,3 +20,6 @@ DISTRO_CHECK := "${@bb.data.getVar("DISTRO_VERSION",d,1) or bb.fatal('Remove thi # Set minimal version of BitBake needed BB_MIN_VERSION = "1.4.4" INHERIT += "sanity" + +# We want images supporting the following features (for task-base) +DISTO_FEATURES = "nfs smbfs ipsec wifi ppp alsa bluetooth ext2 irda pcmcia usbgadget usbhost" -- cgit v1.2.3 From 880d7022165f13e50d03c97fa3299e6331989a73 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 22:22:03 +0000 Subject: qemuarm: Create common include file and convert to task-base --- conf/machine/include/qemu.conf | 10 ++++++++++ conf/machine/qemuarm.conf | 37 ++----------------------------------- 2 files changed, 12 insertions(+), 35 deletions(-) create mode 100644 conf/machine/include/qemu.conf diff --git a/conf/machine/include/qemu.conf b/conf/machine/include/qemu.conf new file mode 100644 index 0000000000..83ddf24b87 --- /dev/null +++ b/conf/machine/include/qemu.conf @@ -0,0 +1,10 @@ +PCMCIA_MANAGER = "pcmciautils" +PREFERRED_PROVIDER_xserver = "xserver-kdrive" +GUI_MACHINE_CLASS = "bigscreen" +GPE_EXTRA_INSTALL += "gaim sylpheed" + +MACHINE_FEATURES = "kernel26 apm alsa pcmcia bluetooth irda usbgadget" + +IMAGE_FSTYPES ?= "tar.bz2 ext2" + +ROOT_FLASH_SIZE = "100" diff --git a/conf/machine/qemuarm.conf b/conf/machine/qemuarm.conf index 3341efd1a7..a64a58e9a2 100644 --- a/conf/machine/qemuarm.conf +++ b/conf/machine/qemuarm.conf @@ -5,42 +5,9 @@ TARGET_ARCH = "arm" IPKG_EXTRA_ARCHS = "armv4 armv5te" -PCMCIA_MANAGER = "pcmciautils" -PREFERRED_PROVIDER_xserver = "xserver-kdrive" -GUI_MACHINE_CLASS = "bigscreen" -GPE_EXTRA_INSTALL += "gaim sylpheed" - -include conf/machine/include/handheld-common.conf -include conf/machine/include/tune-arm926ejs.conf +require conf/machine/include/qemu.conf +require conf/machine/include/tune-arm926ejs.conf SERIAL_CONSOLE = "115200 ttyAMA0" PREFERRED_PROVIDER_virtual/kernel = "linux-openzaurus" - -BOOTSTRAP_EXTRA_RDEPENDS += "kernel udev sysfsutils spectrum-fw \ -pcmciautils apm wireless-tools irda-utils udev-utils console-tools hostap-utils prism3-firmware prism3-support \ -ppp ppp-dialin openswan wpa-supplicant-nossl alsa-utils-alsactl alsa-utils-alsamixer module-init-tools alsa-conf" - -# Ethernet modules -#BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-pcnet-cs" -# NFS Modules -#BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-nfs kernel-module-lockd kernel-module-sunrpc" -# Crypto Modules -#BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-des kernel-module-md5" -# SMB and CRAMFS -#BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-smbfs kernel-module-cramfs" -# Serial Modules -#BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-8250 kernel-module-serial-cs" -# Bluetooth Modules -#BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-bluetooth kernel-module-l2cap kernel-module-rfcomm kernel-module-hci-vhci \ -# kernel-module-bnep kernel-module-hidp kernel-module-hci-uart kernel-module-sco \ -# kernel-module-bt3c-cs kernel-module-bluecard-cs kernel-module-btuart-cs kernel-module-dtl1-cs" -# Infrared Modules -#BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-irda kernel-module-ircomm \ -# kernel-module-ircomm-tty kernel-module-irlan kernel-module-irnet kernel-module-ir-usb" - -IMAGE_FSTYPES = "tar.bz2" - -ROOT_FLASH_SIZE = "100" -# actually that should really read ROOTFS_SIZE = "100", because with modern kernels, -# we boot from the built-in harddisk in C3000. ROOT_FLASH_SIZE is really 5 MegaByte -- cgit v1.2.3 From 2904613080f031ac7683b6d9cf42dafe1183dab5 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 22:23:47 +0000 Subject: nokia770: Convert machine to task-base --- conf/machine/nokia770.conf | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/conf/machine/nokia770.conf b/conf/machine/nokia770.conf index eee389faf1..7069639330 100644 --- a/conf/machine/nokia770.conf +++ b/conf/machine/nokia770.conf @@ -16,7 +16,6 @@ GUI_MACHINE_CLASS = "bigscreen" # Use tune-arm926 per default. Machine independent feeds should be built with tune-strongarm. include conf/machine/include/tune-arm926ejs.conf - #size of the root partition (yes, it is 123 MB) ROOT_FLASH_SIZE = "123" EXTRA_IMAGECMD_jffs2_nokia770 = "--pad --little-endian --eraseblock=0x20000" @@ -28,10 +27,10 @@ SERIAL_CONSOLE = "115200 ttyS0" PREFERRED_PROVIDER_virtual/kernel = "linux-nokia770" -BOOTSTRAP_EXTRA_RDEPENDS += "sysfsutils nokia770-init \ - apm ppp wireless-tools console-tools" - #use this if you are using the nokia initfs ROOTFS_POSTPROCESS_COMMAND += " remove_init_link; " +MACHINE_FEATURES = "kernel26 apm alsa bluetooth usbgadget usbhost" +MACHINE_ESSENTIAL_EXTRA_RDEPENDS = "nokia770-init" +MACHINE_TASK_PROVIDER = "task-base" \ No newline at end of file -- cgit v1.2.3 From 71c8fbd1286fef469ed33fe6dfc3747177bab34d Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 22:25:46 +0000 Subject: conf/machine: various task-base conversion misc cleanups --- conf/machine/include/zaurus-clamshell.conf | 5 +---- conf/machine/qemuarm.conf | 2 ++ conf/machine/spitz.conf | 4 ---- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/conf/machine/include/zaurus-clamshell.conf b/conf/machine/include/zaurus-clamshell.conf index 97728fa5b6..e600a4926d 100644 --- a/conf/machine/include/zaurus-clamshell.conf +++ b/conf/machine/include/zaurus-clamshell.conf @@ -16,14 +16,11 @@ EXTRA_IMAGECMD_jffs2 += "&& sumtool -i ${T}/${IMAGE_NAME}.rootfs.jffs2 \ -o ${T}/${IMAGE_NAME}.rootfs.jffs2.summary \ --eraseblock=0x4000 -l -p" IMAGE_CMD_jffs2 += "; cat ${STAGING_LIBDIR}/sharp-flash-header/header-c700.bin \ - ${T}/${IMAGE_NAME}.rootfs.jffs2.summary > ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.summary.img" - + ${T}/${IMAGE_NAME}.rootfs.jffs2.summary > ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.summary.img" GUI_MACHINE_CLASS = "bigscreen" GPE_EXTRA_INSTALL += "gaim sylpheed" -include conf/machine/include/handheld-common.conf - # Use tune-xscale per default. Machine independent feeds should be built with tune-strongarm. include conf/machine/include/tune-xscale.conf diff --git a/conf/machine/qemuarm.conf b/conf/machine/qemuarm.conf index a64a58e9a2..c32353f01e 100644 --- a/conf/machine/qemuarm.conf +++ b/conf/machine/qemuarm.conf @@ -11,3 +11,5 @@ require conf/machine/include/tune-arm926ejs.conf SERIAL_CONSOLE = "115200 ttyAMA0" PREFERRED_PROVIDER_virtual/kernel = "linux-openzaurus" + +MACHINE_TASK_PROVIDER = "task-base" \ No newline at end of file diff --git a/conf/machine/spitz.conf b/conf/machine/spitz.conf index b8851f6170..af50217e0f 100644 --- a/conf/machine/spitz.conf +++ b/conf/machine/spitz.conf @@ -6,10 +6,6 @@ include conf/machine/include/zaurus-clamshell.conf include conf/machine/include/zaurus-clamshell-2.6.conf PIVOTBOOT_EXTRA_RDEPENDS += "pivotinit ${PCMCIA_MANAGER}" -PIVOTBOOT_EXTRA_RRECOMMENDS += "" - -# Useful things for the built-in Harddisk -BOOTSTRAP_EXTRA_RDEPENDS += "hdparm e2fsprogs e2fsprogs-e2fsck e2fsprogs-mke2fs" IPKG_EXTRA_ARCHS += "iwmmxt" IMAGE_FSTYPES ?= "tar.gz" -- cgit v1.2.3 From a88d842ab1111acf0cbce08145ed5cbef0356fea Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 22:28:38 +0000 Subject: atk: 1.10.1 -> 1.10.3 (from poky) --- packages/atk/atk_1.10.1.bb | 21 --------------------- packages/atk/atk_1.10.3.bb | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 21 deletions(-) delete mode 100644 packages/atk/atk_1.10.1.bb create mode 100644 packages/atk/atk_1.10.3.bb diff --git a/packages/atk/atk_1.10.1.bb b/packages/atk/atk_1.10.1.bb deleted file mode 100644 index 6424167ca2..0000000000 --- a/packages/atk/atk_1.10.1.bb +++ /dev/null @@ -1,21 +0,0 @@ -DEPENDS = "glib-2.0 gtk-doc" -DESCRIPTION = "An accessibility toolkit for GNOME." -SECTION = "x11/libs" -PRIORITY = "optional" -MAINTAINER = "Philip Blundell " -LICENSE = "LGPL" - -SRC_URI = "ftp://ftp.gtk.org/pub/gtk/v2.8/atk-${PV}.tar.bz2" - -inherit autotools pkgconfig - -EXTRA_OECONF = "--disable-glibtest" - -CFLAGS_append = " -I${STAGING_INCDIR}/glib-2.0 \ - -I${STAGING_INCDIR}/glib-2.0/glib \ - -I${STAGING_INCDIR}/glib-2.0/gobject" - -do_stage () { - oe_libinstall -so -C atk libatk-1.0 ${STAGING_LIBDIR} - autotools_stage_includes -} diff --git a/packages/atk/atk_1.10.3.bb b/packages/atk/atk_1.10.3.bb new file mode 100644 index 0000000000..d04b943557 --- /dev/null +++ b/packages/atk/atk_1.10.3.bb @@ -0,0 +1,20 @@ +DEPENDS = "glib-2.0 gtk-doc" +DESCRIPTION = "An accessibility toolkit for GNOME." +SECTION = "x11/libs" +PRIORITY = "optional" +LICENSE = "LGPL" + +SRC_URI = "ftp://ftp.gtk.org/pub/gtk/v2.8/atk-${PV}.tar.bz2" + +inherit autotools pkgconfig + +EXTRA_OECONF = "--disable-glibtest" + +CFLAGS_append = " -I${STAGING_INCDIR}/glib-2.0 \ + -I${STAGING_INCDIR}/glib-2.0/glib \ + -I${STAGING_INCDIR}/glib-2.0/gobject" + +do_stage () { + oe_libinstall -so -C atk libatk-1.0 ${STAGING_LIBDIR} + autotools_stage_includes +} -- cgit v1.2.3 From 4301731d62f7c6331685b4fcacfb5aae86d8f243 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 22:33:06 +0000 Subject: autoconf: Drop bogus RRECOMMENDS --- packages/autoconf/autoconf-native_2.59.bb | 1 - packages/autoconf/autoconf_2.57.bb | 1 - packages/autoconf/autoconf_2.59.bb | 1 - 3 files changed, 3 deletions(-) diff --git a/packages/autoconf/autoconf-native_2.59.bb b/packages/autoconf/autoconf-native_2.59.bb index 347cd354cf..92a9257797 100644 --- a/packages/autoconf/autoconf-native_2.59.bb +++ b/packages/autoconf/autoconf-native_2.59.bb @@ -2,7 +2,6 @@ SECTION = "devel" require autoconf_${PV}.bb DEPENDS = "m4-native gnu-config-native" RDEPENDS_${PN} = "m4-native gnu-config-native" -RRECOMMENDS_${PN} = "" S = "${WORKDIR}/autoconf-${PV}" FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/autoconf-${PV}" diff --git a/packages/autoconf/autoconf_2.57.bb b/packages/autoconf/autoconf_2.57.bb index 86059aa355..48726b1605 100644 --- a/packages/autoconf/autoconf_2.57.bb +++ b/packages/autoconf/autoconf_2.57.bb @@ -5,6 +5,5 @@ DESCRIPTION = "A package of M4 macros to produce scripts to \ automatically configure sourcecode." PR = "r1" -RRECOMMENDS_${PN} = "automake" SECTION = "devel" inherit autotools diff --git a/packages/autoconf/autoconf_2.59.bb b/packages/autoconf/autoconf_2.59.bb index 505b2bec9e..3a5c220a48 100644 --- a/packages/autoconf/autoconf_2.59.bb +++ b/packages/autoconf/autoconf_2.59.bb @@ -5,7 +5,6 @@ HOMEPAGE = "http://www.gnu.org/software/autoconf/" SECTION = "devel" DEPENDS += "m4-native" RDEPENDS_${PN} = "m4 gnu-config" -RRECOMMENDS_${PN} = "automake" PR = "r5" SRC_URI = "${GNU_MIRROR}/autoconf/autoconf-${PV}.tar.bz2 \ -- cgit v1.2.3 From 7bf0dd268bab4a134d607422d7ebbae829754394 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 22:43:49 +0000 Subject: avahi: Fix postinst so we only restart dbus if its already running (it might not have started when the postinst runs) --- packages/avahi/avahi_0.6.10.bb | 10 +++++++++- packages/avahi/avahi_0.6.11.bb | 12 ++++++++++-- packages/avahi/avahi_0.6.12.bb | 11 +++++++++-- packages/avahi/avahi_0.6.13.bb | 11 +++++++++-- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/packages/avahi/avahi_0.6.10.bb b/packages/avahi/avahi_0.6.10.bb index 2b12d91c8d..803266b6b3 100644 --- a/packages/avahi/avahi_0.6.10.bb +++ b/packages/avahi/avahi_0.6.10.bb @@ -5,6 +5,7 @@ AUTHOR = "Lennart Poettering " HOMEPAGE = "http://avahi.org" MAINTAINER = "Philipp Zabel " LICENSE= "GPL" +PR = "r1" DEPENDS = "expat libdaemon dbus" RRECOMMENDS = "libnss-mdns" @@ -42,6 +43,8 @@ INITSCRIPT_PARAMS_avahi-daemon = "defaults 21 19" INITSCRIPT_NAME_avahi-dnsconfd = "avahi-dnsconfd" INITSCRIPT_PARAMS_avahi-dnsconfd = "defaults 22 19" +# At the time the postinst runs, dbus might not be setup so only restart if running + pkg_postinst_avahi-daemon () { if [ "x$D" != "x" ]; then exit 1 @@ -49,7 +52,12 @@ pkg_postinst_avahi-daemon () { grep avahi /etc/group || addgroup avahi grep avahi /etc/passwd || adduser --disabled-password --system --home /var/run/avahi-daemon --no-create-home avahi --ingroup avahi -g Avahi - /etc/init.d/dbus-1 force-reload + + DBUSPID=`pidof dbus-daemon` + + if [ "x$DBUSPID" != "x" ]; then + /etc/init.d/dbus-1 force-reload + fi } pkg_postrm_avahi-daemon () { diff --git a/packages/avahi/avahi_0.6.11.bb b/packages/avahi/avahi_0.6.11.bb index 2b12d91c8d..cc32ad883f 100644 --- a/packages/avahi/avahi_0.6.11.bb +++ b/packages/avahi/avahi_0.6.11.bb @@ -5,6 +5,7 @@ AUTHOR = "Lennart Poettering " HOMEPAGE = "http://avahi.org" MAINTAINER = "Philipp Zabel " LICENSE= "GPL" +PR="r1" DEPENDS = "expat libdaemon dbus" RRECOMMENDS = "libnss-mdns" @@ -42,6 +43,8 @@ INITSCRIPT_PARAMS_avahi-daemon = "defaults 21 19" INITSCRIPT_NAME_avahi-dnsconfd = "avahi-dnsconfd" INITSCRIPT_PARAMS_avahi-dnsconfd = "defaults 22 19" +# At the time the postinst runs, dbus might not be setup so only restart if running + pkg_postinst_avahi-daemon () { if [ "x$D" != "x" ]; then exit 1 @@ -49,10 +52,15 @@ pkg_postinst_avahi-daemon () { grep avahi /etc/group || addgroup avahi grep avahi /etc/passwd || adduser --disabled-password --system --home /var/run/avahi-daemon --no-create-home avahi --ingroup avahi -g Avahi - /etc/init.d/dbus-1 force-reload + + DBUSPID=`pidof dbus-daemon` + + if [ "x$DBUSPID" != "x" ]; then + /etc/init.d/dbus-1 force-reload + fi } -pkg_postrm_avahi-daemon () { +_postrm_avahi-daemon () { deluser avahi || true delgroup avahi || true } diff --git a/packages/avahi/avahi_0.6.12.bb b/packages/avahi/avahi_0.6.12.bb index 2072c1f6bf..44e7c543ae 100644 --- a/packages/avahi/avahi_0.6.12.bb +++ b/packages/avahi/avahi_0.6.12.bb @@ -5,7 +5,7 @@ AUTHOR = "Lennart Poettering " HOMEPAGE = "http://avahi.org" MAINTAINER = "Philipp Zabel " LICENSE= "GPL" -PR = "r1" +PR = "r2" DEPENDS = "expat libdaemon dbus" RRECOMMENDS = "libnss-mdns" @@ -48,10 +48,17 @@ INITSCRIPT_PARAMS_avahi-daemon = "defaults 21 19" INITSCRIPT_NAME_avahi-dnsconfd = "avahi-dnsconfd" INITSCRIPT_PARAMS_avahi-dnsconfd = "defaults 22 19" +# At the time the postinst runs, dbus might not be setup so only restart if running + pkg_postinst_avahi-daemon () { grep avahi /etc/group || addgroup avahi grep avahi /etc/passwd || adduser --disabled-password --system --home /var/run/avahi-daemon --no-create-home avahi --ingroup avahi -g Avahi - /etc/init.d/dbus-1 force-reload + + DBUSPID=`pidof dbus-daemon` + + if [ "x$DBUSPID" != "x" ]; then + /etc/init.d/dbus-1 force-reload + fi } pkg_postrm_avahi-daemon () { diff --git a/packages/avahi/avahi_0.6.13.bb b/packages/avahi/avahi_0.6.13.bb index 7584a02514..0898bf036c 100644 --- a/packages/avahi/avahi_0.6.13.bb +++ b/packages/avahi/avahi_0.6.13.bb @@ -5,7 +5,7 @@ AUTHOR = "Lennart Poettering " HOMEPAGE = "http://avahi.org" MAINTAINER = "Philipp Zabel " LICENSE= "GPL" -PR = "r0" +PR = "r1" DEPENDS = "expat libdaemon dbus" RRECOMMENDS = "libnss-mdns" @@ -48,6 +48,8 @@ INITSCRIPT_PARAMS_avahi-daemon = "defaults 21 19" INITSCRIPT_NAME_avahi-dnsconfd = "avahi-dnsconfd" INITSCRIPT_PARAMS_avahi-dnsconfd = "defaults 22 19" +# At the time the postinst runs, dbus might not be setup so only restart if running + pkg_postinst_avahi-daemon () { # can't do this offline if [ "x$D" != "x" ]; then @@ -55,7 +57,12 @@ pkg_postinst_avahi-daemon () { fi grep avahi /etc/group || addgroup avahi grep avahi /etc/passwd || adduser --disabled-password --system --home /var/run/avahi-daemon --no-create-home avahi --ingroup avahi -g Avahi - /etc/init.d/dbus-1 force-reload + + DBUSPID=`pidof dbus-daemon` + + if [ "x$DBUSPID" != "x" ]; then + /etc/init.d/dbus-1 force-reload + fi } pkg_postrm_avahi-daemon () { -- cgit v1.2.3 From 47f60742dc51c3d460a4a29dede426d6dd99fe26 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 22:54:43 +0000 Subject: cairo: Add 1.2.4 (including float conversion speedup) (from poky) --- packages/cairo/cairo_1.2.4.bb | 16 +++++++++++++ packages/cairo/files/.mtn2git_empty | 0 packages/cairo/files/cairo-fixed.patch | 43 ++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 packages/cairo/cairo_1.2.4.bb create mode 100644 packages/cairo/files/.mtn2git_empty create mode 100644 packages/cairo/files/cairo-fixed.patch diff --git a/packages/cairo/cairo_1.2.4.bb b/packages/cairo/cairo_1.2.4.bb new file mode 100644 index 0000000000..bad6da8bde --- /dev/null +++ b/packages/cairo/cairo_1.2.4.bb @@ -0,0 +1,16 @@ +SECTION = "libs" +PRIORITY = "optional" +MAINTAINER = "Phil Blundell " +DEPENDS = "libx11 libpng fontconfig libxrender" +DESCRIPTION = "Cairo graphics library" +LICENSE = "MPL LGPL" +PR = "r1" + +SRC_URI = "http://cairographics.org/releases/cairo-${PV}.tar.gz \ + file://cairo-fixed.patch;patch=1" + +inherit autotools pkgconfig + +do_stage () { + autotools_stage_all +} diff --git a/packages/cairo/files/.mtn2git_empty b/packages/cairo/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/cairo/files/cairo-fixed.patch b/packages/cairo/files/cairo-fixed.patch new file mode 100644 index 0000000000..8df54d9cb5 --- /dev/null +++ b/packages/cairo/files/cairo-fixed.patch @@ -0,0 +1,43 @@ +diff -ur cairo-1.2.4/src/cairo-fixed.c cairo-1.2.4-new/src/cairo-fixed.c +--- cairo-1.2.4/src/cairo-fixed.c 2006-06-10 07:07:37.000000000 +0300 ++++ cairo-1.2.4-new/src/cairo-fixed.c 2006-08-25 13:06:26.000000000 +0300 +@@ -43,12 +43,6 @@ + } + + cairo_fixed_t +-_cairo_fixed_from_double (double d) +-{ +- return (cairo_fixed_t) floor (d * 65536 + 0.5); +-} +- +-cairo_fixed_t + _cairo_fixed_from_26_6 (uint32_t i) + { + return i << 10; +diff -ur cairo-1.2.4/src/cairoint.h cairo-1.2.4-new/src/cairoint.h +--- cairo-1.2.4/src/cairoint.h 2006-08-18 17:20:16.000000000 +0300 ++++ cairo-1.2.4-new/src/cairoint.h 2006-08-25 13:14:07.000000000 +0300 +@@ -1117,8 +1117,21 @@ + + #define CAIRO_FIXED_ONE _cairo_fixed_from_int (1) + +-cairo_private cairo_fixed_t +-_cairo_fixed_from_double (double d); ++#define CAIRO_DOUBLE2FIX_MAGIC 103079215104.0 /* 2 ^ (52 - 16) * 1.5 */ ++ ++#ifdef WORDS_BIGENDIAN ++#define iman 1 ++#else ++#define iman 0 ++#endif ++ ++static inline cairo_fixed_t ++_cairo_fixed_from_double (double d) ++{ ++ d = d + CAIRO_DOUBLE2FIX_MAGIC; ++ ++ return ((cairo_fixed_t *) &d)[iman]; ++} + + cairo_private cairo_fixed_t + _cairo_fixed_from_26_6 (uint32_t i); -- cgit v1.2.3 From 94af751f34a2a2af1c0bc5c4e3aeb8c30b9dcb53 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 27 Aug 2006 22:57:00 +0000 Subject: alda-utils: speaker-test doesn't really work without alsa-conf. --- packages/alsa/alsa-utils_1.0.11.bb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/alsa/alsa-utils_1.0.11.bb b/packages/alsa/alsa-utils_1.0.11.bb index 10ebacee9b..d2acfe1995 100644 --- a/packages/alsa/alsa-utils_1.0.11.bb +++ b/packages/alsa/alsa-utils_1.0.11.bb @@ -40,7 +40,7 @@ FILES_alsa-utils-alsactl = "${sbindir}/alsactl" DESCRIPTION_alsa-utils-aplay = "play (and record) sound files via ALSA" DESCRIPTION_alsa-utils-amixer = "command-line based control for ALSA mixer and settings" DESCRIPTION_alsa-utils-alsamixer = "ncurses based control for ALSA mixer and settings" -#DESCRIPTION_alsa-utils-speaker-test= "??" +DESCRIPTION_alsa-utils-speaker-test = "speaker test tone generator for ALSA" DESCRIPTION_alsa-utils-midi = "miscalleanous MIDI utilities for ALSA" DESCRIPTION_alsa-utils-aconnect = "ALSA sequencer connection manager" DESCRIPTION_alsa-utils-aseqnet = "network client/server on ALSA sequencer" @@ -50,5 +50,6 @@ DESCRIPTION_alsa-utils-alsaconf = "a bash script that creates ALSA configura RDEPENDS_alsa-utils-aplay += "alsa-conf" RDEPENDS_alsa-utils-amixer += "alsa-conf" RDEPENDS_alsa-utils-alsamixer += "alsa-conf" +RDEPENDS_alsa-utils-speaker-test += "alsa-conf" ALLOW_EMPTY_alsa-utils = "1" -- cgit v1.2.3 From 744d31ca64a9e9177797476d3d7e86eabcc9c26d Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 27 Aug 2006 23:05:45 +0000 Subject: pango: 1.13.2 -> 1.13.3 and add missing PACKAGES_DYNAMIC (from poky). Drop some old versions. --- packages/pango/pango-1.13.2/.mtn2git_empty | 0 .../pango/pango-1.13.2/opentype-makefile.patch | 20 - packages/pango/pango-1.13.3/.mtn2git_empty | 0 .../pango/pango-1.13.3/opentype-makefile.patch | 20 + packages/pango/pango-1.2.5/ft2.patch | 391 ---------------- packages/pango/pango-1.2.5/m4.patch | 502 --------------------- packages/pango/pango_1.10.0.bb | 51 --- packages/pango/pango_1.13.2.bb | 50 -- packages/pango/pango_1.13.3.bb | 52 +++ packages/pango/pango_1.2.5.bb | 36 -- packages/pango/pango_1.4.0.bb | 37 -- packages/pango/pango_1.8.0.bb | 49 -- packages/pango/pango_1.8.1.bb | 49 -- 13 files changed, 72 insertions(+), 1185 deletions(-) delete mode 100644 packages/pango/pango-1.13.2/.mtn2git_empty delete mode 100644 packages/pango/pango-1.13.2/opentype-makefile.patch create mode 100644 packages/pango/pango-1.13.3/.mtn2git_empty create mode 100644 packages/pango/pango-1.13.3/opentype-makefile.patch delete mode 100644 packages/pango/pango-1.2.5/ft2.patch delete mode 100644 packages/pango/pango-1.2.5/m4.patch delete mode 100644 packages/pango/pango_1.10.0.bb delete mode 100644 packages/pango/pango_1.13.2.bb create mode 100644 packages/pango/pango_1.13.3.bb delete mode 100644 packages/pango/pango_1.2.5.bb delete mode 100644 packages/pango/pango_1.4.0.bb delete mode 100644 packages/pango/pango_1.8.0.bb delete mode 100644 packages/pango/pango_1.8.1.bb diff --git a/packages/pango/pango-1.13.2/.mtn2git_empty b/packages/pango/pango-1.13.2/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/pango/pango-1.13.2/opentype-makefile.patch b/packages/pango/pango-1.13.2/opentype-makefile.patch deleted file mode 100644 index 9f68420bc5..0000000000 --- a/packages/pango/pango-1.13.2/opentype-makefile.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- pango/opentype/Makefile.am~ 2006-07-05 14:49:28.000000000 +0200 -+++ pango/opentype/Makefile.am 2006-07-05 14:49:28.000000000 +0200 -@@ -5,7 +5,7 @@ - - noinst_LTLIBRARIES = libharfbuzz-1.la - --SOURCES = \ -+MAIN_SOURCES = \ - ftglue.c \ - harfbuzz-buffer.c \ - harfbuzz-dump.c \ -@@ -34,7 +34,7 @@ - harfbuzz-open-private.h - - libharfbuzz_1_la_SOURCES = \ -- $(SOURCES) \ -+ $(MAIN_SOURCES) \ - $(PUBLICHEADERS) \ - $(PRIVATEHEADERS) - diff --git a/packages/pango/pango-1.13.3/.mtn2git_empty b/packages/pango/pango-1.13.3/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/pango/pango-1.13.3/opentype-makefile.patch b/packages/pango/pango-1.13.3/opentype-makefile.patch new file mode 100644 index 0000000000..9f68420bc5 --- /dev/null +++ b/packages/pango/pango-1.13.3/opentype-makefile.patch @@ -0,0 +1,20 @@ +--- pango/opentype/Makefile.am~ 2006-07-05 14:49:28.000000000 +0200 ++++ pango/opentype/Makefile.am 2006-07-05 14:49:28.000000000 +0200 +@@ -5,7 +5,7 @@ + + noinst_LTLIBRARIES = libharfbuzz-1.la + +-SOURCES = \ ++MAIN_SOURCES = \ + ftglue.c \ + harfbuzz-buffer.c \ + harfbuzz-dump.c \ +@@ -34,7 +34,7 @@ + harfbuzz-open-private.h + + libharfbuzz_1_la_SOURCES = \ +- $(SOURCES) \ ++ $(MAIN_SOURCES) \ + $(PUBLICHEADERS) \ + $(PRIVATEHEADERS) + diff --git a/packages/pango/pango-1.2.5/ft2.patch b/packages/pango/pango-1.2.5/ft2.patch deleted file mode 100644 index 5015c8b132..0000000000 --- a/packages/pango/pango-1.2.5/ft2.patch +++ /dev/null @@ -1,391 +0,0 @@ ---- pango-1.2.5/modules/indic/indic-ot.h Fri Aug 8 12:05:01 2003 -+++ pango-1.2.5-new/modules/indic/indic-ot.h Thu Dec 18 14:38:44 2003 -@@ -9,7 +9,8 @@ - #ifndef __INDIC_OT_H__ - #define __INDIC_OT_H__ - --#include -+#include -+#include FT_FREETYPE_H - #include - #include - #include "mprefixups.h" ---- pango-1.2.5/pango/opentype/ftxopen.h Fri Aug 8 12:05:10 2003 -+++ pango-1.2.5-new/pango/opentype/ftxopen.h Thu Dec 18 14:38:41 2003 -@@ -22,7 +22,8 @@ - #ifndef FTXOPEN_H - #define FTXOPEN_H - --#include -+#include -+#include FT_FREETYPE_H - - #ifdef __cplusplus - extern "C" { ---- pango-1.2.5/pango/opentype/pango-ot-info.c Wed Apr 16 16:48:20 2003 -+++ pango-1.2.5-new/pango/opentype/pango-ot-info.c Thu Dec 18 13:48:40 2003 -@@ -21,8 +21,9 @@ - - #include "pango-ot-private.h" - #include "fterrcompat.h" -+ - #include --#include -+//#include - - static void pango_ot_info_class_init (GObjectClass *object_class); - static void pango_ot_info_finalize (GObject *object); ---- pango-1.2.5/pango/opentype/pango-ot-private.h Tue Dec 19 22:41:36 2000 -+++ pango-1.2.5-new/pango/opentype/pango-ot-private.h Wed Dec 17 20:53:02 2003 -@@ -22,7 +22,8 @@ - #ifndef __PANGO_OT_PRIVATE_H__ - #define __PANGO_OT_PRIVATE_H__ - --#include -+#include -+#include FT_FREETYPE_H - - #include - ---- pango-1.2.5/pango/pango-enum-types.c Thu Jul 24 14:12:13 2003 -+++ pango-1.2.5-new/pango/pango-enum-types.c Wed Dec 31 18:00:00 1969 -@@ -1,236 +0,0 @@ -- --/* Generated data (by glib-mkenums) */ -- --#include -- --/* enumerations from "pango-attributes.h" */ --GType --pango_attr_type_get_type (void) --{ -- static GType etype = 0; -- if (etype == 0) { -- static const GEnumValue values[] = { -- { PANGO_ATTR_INVALID, "PANGO_ATTR_INVALID", "invalid" }, -- { PANGO_ATTR_LANGUAGE, "PANGO_ATTR_LANGUAGE", "language" }, -- { PANGO_ATTR_FAMILY, "PANGO_ATTR_FAMILY", "family" }, -- { PANGO_ATTR_STYLE, "PANGO_ATTR_STYLE", "style" }, -- { PANGO_ATTR_WEIGHT, "PANGO_ATTR_WEIGHT", "weight" }, -- { PANGO_ATTR_VARIANT, "PANGO_ATTR_VARIANT", "variant" }, -- { PANGO_ATTR_STRETCH, "PANGO_ATTR_STRETCH", "stretch" }, -- { PANGO_ATTR_SIZE, "PANGO_ATTR_SIZE", "size" }, -- { PANGO_ATTR_FONT_DESC, "PANGO_ATTR_FONT_DESC", "font-desc" }, -- { PANGO_ATTR_FOREGROUND, "PANGO_ATTR_FOREGROUND", "foreground" }, -- { PANGO_ATTR_BACKGROUND, "PANGO_ATTR_BACKGROUND", "background" }, -- { PANGO_ATTR_UNDERLINE, "PANGO_ATTR_UNDERLINE", "underline" }, -- { PANGO_ATTR_STRIKETHROUGH, "PANGO_ATTR_STRIKETHROUGH", "strikethrough" }, -- { PANGO_ATTR_RISE, "PANGO_ATTR_RISE", "rise" }, -- { PANGO_ATTR_SHAPE, "PANGO_ATTR_SHAPE", "shape" }, -- { PANGO_ATTR_SCALE, "PANGO_ATTR_SCALE", "scale" }, -- { 0, NULL, NULL } -- }; -- etype = g_enum_register_static ("PangoAttrType", values); -- } -- return etype; --} -- --GType --pango_underline_get_type (void) --{ -- static GType etype = 0; -- if (etype == 0) { -- static const GEnumValue values[] = { -- { PANGO_UNDERLINE_NONE, "PANGO_UNDERLINE_NONE", "none" }, -- { PANGO_UNDERLINE_SINGLE, "PANGO_UNDERLINE_SINGLE", "single" }, -- { PANGO_UNDERLINE_DOUBLE, "PANGO_UNDERLINE_DOUBLE", "double" }, -- { PANGO_UNDERLINE_LOW, "PANGO_UNDERLINE_LOW", "low" }, -- { 0, NULL, NULL } -- }; -- etype = g_enum_register_static ("PangoUnderline", values); -- } -- return etype; --} -- -- --/* enumerations from "pango-coverage.h" */ --GType --pango_coverage_level_get_type (void) --{ -- static GType etype = 0; -- if (etype == 0) { -- static const GEnumValue values[] = { -- { PANGO_COVERAGE_NONE, "PANGO_COVERAGE_NONE", "none" }, -- { PANGO_COVERAGE_FALLBACK, "PANGO_COVERAGE_FALLBACK", "fallback" }, -- { PANGO_COVERAGE_APPROXIMATE, "PANGO_COVERAGE_APPROXIMATE", "approximate" }, -- { PANGO_COVERAGE_EXACT, "PANGO_COVERAGE_EXACT", "exact" }, -- { 0, NULL, NULL } -- }; -- etype = g_enum_register_static ("PangoCoverageLevel", values); -- } -- return etype; --} -- -- --/* enumerations from "pango-font.h" */ --GType --pango_style_get_type (void) --{ -- static GType etype = 0; -- if (etype == 0) { -- static const GEnumValue values[] = { -- { PANGO_STYLE_NORMAL, "PANGO_STYLE_NORMAL", "normal" }, -- { PANGO_STYLE_OBLIQUE, "PANGO_STYLE_OBLIQUE", "oblique" }, -- { PANGO_STYLE_ITALIC, "PANGO_STYLE_ITALIC", "italic" }, -- { 0, NULL, NULL } -- }; -- etype = g_enum_register_static ("PangoStyle", values); -- } -- return etype; --} -- --GType --pango_variant_get_type (void) --{ -- static GType etype = 0; -- if (etype == 0) { -- static const GEnumValue values[] = { -- { PANGO_VARIANT_NORMAL, "PANGO_VARIANT_NORMAL", "normal" }, -- { PANGO_VARIANT_SMALL_CAPS, "PANGO_VARIANT_SMALL_CAPS", "small-caps" }, -- { 0, NULL, NULL } -- }; -- etype = g_enum_register_static ("PangoVariant", values); -- } -- return etype; --} -- --GType --pango_weight_get_type (void) --{ -- static GType etype = 0; -- if (etype == 0) { -- static const GEnumValue values[] = { -- { PANGO_WEIGHT_ULTRALIGHT, "PANGO_WEIGHT_ULTRALIGHT", "ultralight" }, -- { PANGO_WEIGHT_LIGHT, "PANGO_WEIGHT_LIGHT", "light" }, -- { PANGO_WEIGHT_NORMAL, "PANGO_WEIGHT_NORMAL", "normal" }, -- { PANGO_WEIGHT_BOLD, "PANGO_WEIGHT_BOLD", "bold" }, -- { PANGO_WEIGHT_ULTRABOLD, "PANGO_WEIGHT_ULTRABOLD", "ultrabold" }, -- { PANGO_WEIGHT_HEAVY, "PANGO_WEIGHT_HEAVY", "heavy" }, -- { 0, NULL, NULL } -- }; -- etype = g_enum_register_static ("PangoWeight", values); -- } -- return etype; --} -- --GType --pango_stretch_get_type (void) --{ -- static GType etype = 0; -- if (etype == 0) { -- static const GEnumValue values[] = { -- { PANGO_STRETCH_ULTRA_CONDENSED, "PANGO_STRETCH_ULTRA_CONDENSED", "ultra-condensed" }, -- { PANGO_STRETCH_EXTRA_CONDENSED, "PANGO_STRETCH_EXTRA_CONDENSED", "extra-condensed" }, -- { PANGO_STRETCH_CONDENSED, "PANGO_STRETCH_CONDENSED", "condensed" }, -- { PANGO_STRETCH_SEMI_CONDENSED, "PANGO_STRETCH_SEMI_CONDENSED", "semi-condensed" }, -- { PANGO_STRETCH_NORMAL, "PANGO_STRETCH_NORMAL", "normal" }, -- { PANGO_STRETCH_SEMI_EXPANDED, "PANGO_STRETCH_SEMI_EXPANDED", "semi-expanded" }, -- { PANGO_STRETCH_EXPANDED, "PANGO_STRETCH_EXPANDED", "expanded" }, -- { PANGO_STRETCH_EXTRA_EXPANDED, "PANGO_STRETCH_EXTRA_EXPANDED", "extra-expanded" }, -- { PANGO_STRETCH_ULTRA_EXPANDED, "PANGO_STRETCH_ULTRA_EXPANDED", "ultra-expanded" }, -- { 0, NULL, NULL } -- }; -- etype = g_enum_register_static ("PangoStretch", values); -- } -- return etype; --} -- --GType --pango_font_mask_get_type (void) --{ -- static GType etype = 0; -- if (etype == 0) { -- static const GFlagsValue values[] = { -- { PANGO_FONT_MASK_FAMILY, "PANGO_FONT_MASK_FAMILY", "family" }, -- { PANGO_FONT_MASK_STYLE, "PANGO_FONT_MASK_STYLE", "style" }, -- { PANGO_FONT_MASK_VARIANT, "PANGO_FONT_MASK_VARIANT", "variant" }, -- { PANGO_FONT_MASK_WEIGHT, "PANGO_FONT_MASK_WEIGHT", "weight" }, -- { PANGO_FONT_MASK_STRETCH, "PANGO_FONT_MASK_STRETCH", "stretch" }, -- { PANGO_FONT_MASK_SIZE, "PANGO_FONT_MASK_SIZE", "size" }, -- { 0, NULL, NULL } -- }; -- etype = g_flags_register_static ("PangoFontMask", values); -- } -- return etype; --} -- -- --/* enumerations from "pango-layout.h" */ --GType --pango_alignment_get_type (void) --{ -- static GType etype = 0; -- if (etype == 0) { -- static const GEnumValue values[] = { -- { PANGO_ALIGN_LEFT, "PANGO_ALIGN_LEFT", "left" }, -- { PANGO_ALIGN_CENTER, "PANGO_ALIGN_CENTER", "center" }, -- { PANGO_ALIGN_RIGHT, "PANGO_ALIGN_RIGHT", "right" }, -- { 0, NULL, NULL } -- }; -- etype = g_enum_register_static ("PangoAlignment", values); -- } -- return etype; --} -- --GType --pango_wrap_mode_get_type (void) --{ -- static GType etype = 0; -- if (etype == 0) { -- static const GEnumValue values[] = { -- { PANGO_WRAP_WORD, "PANGO_WRAP_WORD", "word" }, -- { PANGO_WRAP_CHAR, "PANGO_WRAP_CHAR", "char" }, -- { PANGO_WRAP_WORD_CHAR, "PANGO_WRAP_WORD_CHAR", "word-char" }, -- { 0, NULL, NULL } -- }; -- etype = g_enum_register_static ("PangoWrapMode", values); -- } -- return etype; --} -- -- --/* enumerations from "pango-tabs.h" */ --GType --pango_tab_align_get_type (void) --{ -- static GType etype = 0; -- if (etype == 0) { -- static const GEnumValue values[] = { -- { PANGO_TAB_LEFT, "PANGO_TAB_LEFT", "left" }, -- { 0, NULL, NULL } -- }; -- etype = g_enum_register_static ("PangoTabAlign", values); -- } -- return etype; --} -- -- --/* enumerations from "pango-types.h" */ --GType --pango_direction_get_type (void) --{ -- static GType etype = 0; -- if (etype == 0) { -- static const GEnumValue values[] = { -- { PANGO_DIRECTION_LTR, "PANGO_DIRECTION_LTR", "ltr" }, -- { PANGO_DIRECTION_RTL, "PANGO_DIRECTION_RTL", "rtl" }, -- { PANGO_DIRECTION_TTB_LTR, "PANGO_DIRECTION_TTB_LTR", "ttb-ltr" }, -- { PANGO_DIRECTION_TTB_RTL, "PANGO_DIRECTION_TTB_RTL", "ttb-rtl" }, -- { 0, NULL, NULL } -- }; -- etype = g_enum_register_static ("PangoDirection", values); -- } -- return etype; --} -- -- --/* Generated data ends here */ -- ---- pango-1.2.5/pango/pango-enum-types.h Thu Jul 24 14:11:58 2003 -+++ pango-1.2.5-new/pango/pango-enum-types.h Wed Dec 31 18:00:00 1969 -@@ -1,64 +0,0 @@ -- --/* Generated data (by glib-mkenums) */ -- --#ifndef __PANGO_ENUM_TYPES_H__ --#define __PANGO_ENUM_TYPES_H__ -- --#include -- --G_BEGIN_DECLS -- --/* enumerations from "pango-attributes.h" */ -- --GType pango_attr_type_get_type (void); --#define PANGO_TYPE_ATTR_TYPE (pango_attr_type_get_type()) -- --GType pango_underline_get_type (void); --#define PANGO_TYPE_UNDERLINE (pango_underline_get_type()) -- --/* enumerations from "pango-coverage.h" */ -- --GType pango_coverage_level_get_type (void); --#define PANGO_TYPE_COVERAGE_LEVEL (pango_coverage_level_get_type()) -- --/* enumerations from "pango-font.h" */ -- --GType pango_style_get_type (void); --#define PANGO_TYPE_STYLE (pango_style_get_type()) -- --GType pango_variant_get_type (void); --#define PANGO_TYPE_VARIANT (pango_variant_get_type()) -- --GType pango_weight_get_type (void); --#define PANGO_TYPE_WEIGHT (pango_weight_get_type()) -- --GType pango_stretch_get_type (void); --#define PANGO_TYPE_STRETCH (pango_stretch_get_type()) -- --GType pango_font_mask_get_type (void); --#define PANGO_TYPE_FONT_MASK (pango_font_mask_get_type()) -- --/* enumerations from "pango-layout.h" */ -- --GType pango_alignment_get_type (void); --#define PANGO_TYPE_ALIGNMENT (pango_alignment_get_type()) -- --GType pango_wrap_mode_get_type (void); --#define PANGO_TYPE_WRAP_MODE (pango_wrap_mode_get_type()) -- --/* enumerations from "pango-tabs.h" */ -- --GType pango_tab_align_get_type (void); --#define PANGO_TYPE_TAB_ALIGN (pango_tab_align_get_type()) -- --/* enumerations from "pango-types.h" */ -- --GType pango_direction_get_type (void); --#define PANGO_TYPE_DIRECTION (pango_direction_get_type()) -- --G_END_DECLS -- --#endif /* __PANGO_ENUM_TYPES_H__ */ -- --/* Generated data ends here */ -- ---- pango-1.2.5/pango/pango-ot.h Mon Jun 3 19:20:47 2002 -+++ pango-1.2.5-new/pango/pango-ot.h Thu Dec 18 14:37:56 2003 -@@ -22,7 +22,8 @@ - #ifndef __PANGO_OT_H__ - #define __PANGO_OT_H__ - --#include -+#include -+#include FT_FREETYPE_H - #include - - G_BEGIN_DECLS ---- pango-1.2.5/pango/pangoft2.c Fri Aug 8 12:05:05 2003 -+++ pango-1.2.5-new/pango/pangoft2.c Thu Dec 18 14:34:50 2003 -@@ -28,7 +28,8 @@ - #include - #include - --#include -+#include -+#include FT_FREETYPE_H - - #include "pango-utils.h" - #include "pangoft2.h" ---- pango-1.2.5/pango/pangoft2.h Wed Jul 3 17:30:36 2002 -+++ pango-1.2.5-new/pango/pangoft2.h Thu Dec 18 14:36:12 2003 -@@ -23,7 +23,8 @@ - #ifndef __PANGOFT2_H__ - #define __PANGOFT2_H__ - --#include -+#include -+#include FT_FREETYPE_H - - #include - diff --git a/packages/pango/pango-1.2.5/m4.patch b/packages/pango/pango-1.2.5/m4.patch deleted file mode 100644 index ec92211199..0000000000 --- a/packages/pango/pango-1.2.5/m4.patch +++ /dev/null @@ -1,502 +0,0 @@ ---- /dev/null -+++ pango-1.2.5/m4/glib-2.0.m4 -@@ -0,0 +1,212 @@ -+# Configure paths for GLIB -+# Owen Taylor 1997-2001 -+ -+dnl AM_PATH_GLIB_2_0([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]]) -+dnl Test for GLIB, and define GLIB_CFLAGS and GLIB_LIBS, if gmodule, gobject or -+dnl gthread is specified in MODULES, pass to pkg-config -+dnl -+AC_DEFUN(AM_PATH_GLIB_2_0, -+[dnl -+dnl Get the cflags and libraries from pkg-config -+dnl -+AC_ARG_ENABLE(glibtest, [ --disable-glibtest do not try to compile and run a test GLIB program], -+ , enable_glibtest=yes) -+ -+ pkg_config_args=glib-2.0 -+ for module in . $4 -+ do -+ case "$module" in -+ gmodule) -+ pkg_config_args="$pkg_config_args gmodule-2.0" -+ ;; -+ gobject) -+ pkg_config_args="$pkg_config_args gobject-2.0" -+ ;; -+ gthread) -+ pkg_config_args="$pkg_config_args gthread-2.0" -+ ;; -+ esac -+ done -+ -+ AC_PATH_PROG(PKG_CONFIG, pkg-config, no) -+ -+ no_glib="" -+ -+ if test x$PKG_CONFIG != xno ; then -+ if $PKG_CONFIG --atleast-pkgconfig-version 0.7 ; then -+ : -+ else -+ echo *** pkg-config too old; version 0.7 or better required. -+ no_glib=yes -+ PKG_CONFIG=no -+ fi -+ else -+ no_glib=yes -+ fi -+ -+ min_glib_version=ifelse([$1], ,2.0.0,$1) -+ AC_MSG_CHECKING(for GLIB - version >= $min_glib_version) -+ -+ if test x$PKG_CONFIG != xno ; then -+ ## don't try to run the test against uninstalled libtool libs -+ if $PKG_CONFIG --uninstalled $pkg_config_args; then -+ echo "Will use uninstalled version of GLib found in PKG_CONFIG_PATH" -+ enable_glibtest=no -+ fi -+ -+ if $PKG_CONFIG --atleast-version $min_glib_version $pkg_config_args; then -+ : -+ else -+ no_glib=yes -+ fi -+ fi -+ -+ if test x"$no_glib" = x ; then -+ GLIB_GENMARSHAL=`$PKG_CONFIG --variable=glib_genmarshal glib-2.0` -+ GOBJECT_QUERY=`$PKG_CONFIG --variable=gobject_query glib-2.0` -+ GLIB_MKENUMS=`$PKG_CONFIG --variable=glib_mkenums glib-2.0` -+ -+ GLIB_CFLAGS=`$PKG_CONFIG --cflags $pkg_config_args` -+ GLIB_LIBS=`$PKG_CONFIG --libs $pkg_config_args` -+ glib_config_major_version=`$PKG_CONFIG --modversion glib-2.0 | \ -+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` -+ glib_config_minor_version=`$PKG_CONFIG --modversion glib-2.0 | \ -+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` -+ glib_config_micro_version=`$PKG_CONFIG --modversion glib-2.0 | \ -+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` -+ if test "x$enable_glibtest" = "xyes" ; then -+ ac_save_CFLAGS="$CFLAGS" -+ ac_save_LIBS="$LIBS" -+ CFLAGS="$CFLAGS $GLIB_CFLAGS" -+ LIBS="$GLIB_LIBS $LIBS" -+dnl -+dnl Now check if the installed GLIB is sufficiently new. (Also sanity -+dnl checks the results of pkg-config to some extent) -+dnl -+ rm -f conf.glibtest -+ AC_TRY_RUN([ -+#include -+#include -+#include -+ -+int -+main () -+{ -+ int major, minor, micro; -+ char *tmp_version; -+ -+ system ("touch conf.glibtest"); -+ -+ /* HP/UX 9 (%@#!) writes to sscanf strings */ -+ tmp_version = g_strdup("$min_glib_version"); -+ if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { -+ printf("%s, bad version string\n", "$min_glib_version"); -+ exit(1); -+ } -+ -+ if ((glib_major_version != $glib_config_major_version) || -+ (glib_minor_version != $glib_config_minor_version) || -+ (glib_micro_version != $glib_config_micro_version)) -+ { -+ printf("\n*** 'pkg-config --modversion glib-2.0' returned %d.%d.%d, but GLIB (%d.%d.%d)\n", -+ $glib_config_major_version, $glib_config_minor_version, $glib_config_micro_version, -+ glib_major_version, glib_minor_version, glib_micro_version); -+ printf ("*** was found! If pkg-config was correct, then it is best\n"); -+ printf ("*** to remove the old version of GLib. You may also be able to fix the error\n"); -+ printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"); -+ printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); -+ printf("*** required on your system.\n"); -+ printf("*** If pkg-config was wrong, set the environment variable PKG_CONFIG_PATH\n"); -+ printf("*** to point to the correct configuration files\n"); -+ } -+ else if ((glib_major_version != GLIB_MAJOR_VERSION) || -+ (glib_minor_version != GLIB_MINOR_VERSION) || -+ (glib_micro_version != GLIB_MICRO_VERSION)) -+ { -+ printf("*** GLIB header files (version %d.%d.%d) do not match\n", -+ GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION); -+ printf("*** library (version %d.%d.%d)\n", -+ glib_major_version, glib_minor_version, glib_micro_version); -+ } -+ else -+ { -+ if ((glib_major_version > major) || -+ ((glib_major_version == major) && (glib_minor_version > minor)) || -+ ((glib_major_version == major) && (glib_minor_version == minor) && (glib_micro_version >= micro))) -+ { -+ return 0; -+ } -+ else -+ { -+ printf("\n*** An old version of GLIB (%d.%d.%d) was found.\n", -+ glib_major_version, glib_minor_version, glib_micro_version); -+ printf("*** You need a version of GLIB newer than %d.%d.%d. The latest version of\n", -+ major, minor, micro); -+ printf("*** GLIB is always available from ftp://ftp.gtk.org.\n"); -+ printf("***\n"); -+ printf("*** If you have already installed a sufficiently new version, this error\n"); -+ printf("*** probably means that the wrong copy of the pkg-config shell script is\n"); -+ printf("*** being found. The easiest way to fix this is to remove the old version\n"); -+ printf("*** of GLIB, but you can also set the PKG_CONFIG environment to point to the\n"); -+ printf("*** correct copy of pkg-config. (In this case, you will have to\n"); -+ printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); -+ printf("*** so that the correct libraries are found at run-time))\n"); -+ } -+ } -+ return 1; -+} -+],, no_glib=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) -+ CFLAGS="$ac_save_CFLAGS" -+ LIBS="$ac_save_LIBS" -+ fi -+ fi -+ if test "x$no_glib" = x ; then -+ AC_MSG_RESULT(yes (version $glib_config_major_version.$glib_config_minor_version.$glib_config_micro_version)) -+ ifelse([$2], , :, [$2]) -+ else -+ AC_MSG_RESULT(no) -+ if test "$PKG_CONFIG" = "no" ; then -+ echo "*** A new enough version of pkg-config was not found." -+ echo "*** See http://www.freedesktop.org/software/pkgconfig/" -+ else -+ if test -f conf.glibtest ; then -+ : -+ else -+ echo "*** Could not run GLIB test program, checking why..." -+ ac_save_CFLAGS="$CFLAGS" -+ ac_save_LIBS="$LIBS" -+ CFLAGS="$CFLAGS $GLIB_CFLAGS" -+ LIBS="$LIBS $GLIB_LIBS" -+ AC_TRY_LINK([ -+#include -+#include -+], [ return ((glib_major_version) || (glib_minor_version) || (glib_micro_version)); ], -+ [ echo "*** The test program compiled, but did not run. This usually means" -+ echo "*** that the run-time linker is not finding GLIB or finding the wrong" -+ echo "*** version of GLIB. If it is not finding GLIB, you'll need to set your" -+ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" -+ echo "*** to the installed location Also, make sure you have run ldconfig if that" -+ echo "*** is required on your system" -+ echo "***" -+ echo "*** If you have an old version installed, it is best to remove it, although" -+ echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ], -+ [ echo "*** The test program failed to compile or link. See the file config.log for the" -+ echo "*** exact error that occured. This usually means GLIB is incorrectly installed."]) -+ CFLAGS="$ac_save_CFLAGS" -+ LIBS="$ac_save_LIBS" -+ fi -+ fi -+ GLIB_CFLAGS="" -+ GLIB_LIBS="" -+ GLIB_GENMARSHAL="" -+ GOBJECT_QUERY="" -+ GLIB_MKENUMS="" -+ ifelse([$3], , :, [$3]) -+ fi -+ AC_SUBST(GLIB_CFLAGS) -+ AC_SUBST(GLIB_LIBS) -+ AC_SUBST(GLIB_GENMARSHAL) -+ AC_SUBST(GOBJECT_QUERY) -+ AC_SUBST(GLIB_MKENUMS) -+ rm -f conf.glibtest -+]) ---- /dev/null -+++ pango-1.2.5/m4/glib-gettext.m4 -@@ -0,0 +1,284 @@ -+# Macro to add for using GNU gettext. -+# Ulrich Drepper , 1995, 1996 -+# -+# Modified to never use included libintl. -+# Owen Taylor , 12/15/1998 -+# -+# -+# This file can be copied and used freely without restrictions. It can -+# be used in projects which are not available under the GNU Public License -+# but which still want to provide support for the GNU gettext functionality. -+# Please note that the actual code is *not* freely available. -+# -+# -+# If you make changes to this file, you MUST update the copy in -+# acinclude.m4. [ aclocal dies on duplicate macros, so if -+# we run 'aclocal -I macros/' then we'll run into problems -+# once we've installed glib-gettext.m4 :-( ] -+# -+ -+AC_DEFUN([AM_GLIB_LC_MESSAGES], -+ [if test $ac_cv_header_locale_h = yes; then -+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, -+ [AC_TRY_LINK([#include ], [return LC_MESSAGES], -+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) -+ if test $am_cv_val_LC_MESSAGES = yes; then -+ AC_DEFINE(HAVE_LC_MESSAGES, 1, -+ [Define if your file defines LC_MESSAGES.]) -+ fi -+ fi]) -+ -+dnl AM_GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, -+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) -+AC_DEFUN([AM_GLIB_PATH_PROG_WITH_TEST], -+[# Extract the first word of "$2", so it can be a program name with args. -+set dummy $2; ac_word=[$]2 -+AC_MSG_CHECKING([for $ac_word]) -+AC_CACHE_VAL(ac_cv_path_$1, -+[case "[$]$1" in -+ /*) -+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path. -+ ;; -+ *) -+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" -+ for ac_dir in ifelse([$5], , $PATH, [$5]); do -+ test -z "$ac_dir" && ac_dir=. -+ if test -f $ac_dir/$ac_word; then -+ if [$3]; then -+ ac_cv_path_$1="$ac_dir/$ac_word" -+ break -+ fi -+ fi -+ done -+ IFS="$ac_save_ifs" -+dnl If no 4th arg is given, leave the cache variable unset, -+dnl so AC_PATH_PROGS will keep looking. -+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" -+])dnl -+ ;; -+esac])dnl -+$1="$ac_cv_path_$1" -+if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then -+ AC_MSG_RESULT([$]$1) -+else -+ AC_MSG_RESULT(no) -+fi -+AC_SUBST($1)dnl -+]) -+ -+# serial 5 -+ -+AC_DEFUN(AM_GLIB_WITH_NLS, -+ dnl NLS is obligatory -+ [USE_NLS=yes -+ AC_SUBST(USE_NLS) -+ -+ dnl Figure out what method -+ nls_cv_force_use_gnu_gettext="no" -+ -+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" -+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then -+ dnl User does not insist on using GNU NLS library. Figure out what -+ dnl to use. If gettext or catgets are available (in this order) we -+ dnl use this. Else we have to fall back to GNU NLS library. -+ dnl catgets is only used if permitted by option --with-catgets. -+ nls_cv_header_intl= -+ nls_cv_header_libgt= -+ CATOBJEXT=NONE -+ XGETTEXT=: -+ -+ AC_CHECK_HEADER(libintl.h, -+ [AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc, -+ [AC_TRY_LINK([#include ], [return (int) dgettext ("","")], -+ gt_cv_func_dgettext_libc=yes, gt_cv_func_dgettext_libc=no)]) -+ -+ gt_cv_func_dgettext_libintl="no" -+ libintl_extra_libs="" -+ -+ if test "$gt_cv_func_dgettext_libc" != "yes" ; then -+ AC_CHECK_LIB(intl, bindtextdomain, -+ [AC_CHECK_LIB(intl, dgettext, -+ gt_cv_func_dgettext_libintl=yes)]) -+ -+ if test "$gt_cv_func_dgettext_libc" != "yes" ; then -+ AC_MSG_CHECKING([if -liconv is needed to use gettext]) -+ AC_MSG_RESULT([]) -+ AC_CHECK_LIB(intl, dcgettext, -+ [gt_cv_func_dgettext_libintl=yes -+ libintl_extra_libs=-liconv], -+ :,-liconv) -+ fi -+ fi -+ -+ if test "$gt_cv_func_dgettext_libintl" = "yes"; then -+ LIBS="$LIBS -lintl $libintl_extra_libs"; -+ fi -+ -+ if test "$gt_cv_func_dgettext_libc" = "yes" \ -+ || test "$gt_cv_func_dgettext_libintl" = "yes"; then -+ AC_DEFINE(HAVE_GETTEXT,1, -+ [Define if the GNU gettext() function is already present or preinstalled.]) -+ AM_GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, -+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl -+ if test "$MSGFMT" != "no"; then -+ AC_CHECK_FUNCS(dcgettext) -+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) -+ AM_GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, -+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) -+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; -+ return _nl_msg_cat_cntr], -+ [CATOBJEXT=.gmo -+ DATADIRNAME=share], -+ [CATOBJEXT=.mo -+ DATADIRNAME=lib]) -+ INSTOBJEXT=.mo -+ fi -+ fi -+ -+ # Added by Martin Baulig 12/15/98 for libc5 systems -+ if test "$gt_cv_func_dgettext_libc" != "yes" \ -+ && test "$gt_cv_func_dgettext_libintl" = "yes"; then -+ INTLLIBS="-lintl $libintl_extra_libs" -+ LIBS=`echo $LIBS | sed -e 's/-lintl//'` -+ fi -+ ]) -+ -+ if test "$CATOBJEXT" = "NONE"; then -+ dnl Neither gettext nor catgets in included in the C library. -+ dnl Fall back on GNU gettext library. -+ nls_cv_use_gnu_gettext=yes -+ fi -+ fi -+ -+ if test "$nls_cv_use_gnu_gettext" != "yes"; then -+ AC_DEFINE(ENABLE_NLS, 1, -+ [always defined to indicate that i18n is enabled]) -+ else -+ dnl Unset this variable since we use the non-zero value as a flag. -+ CATOBJEXT= -+ fi -+ -+ dnl Test whether we really found GNU xgettext. -+ if test "$XGETTEXT" != ":"; then -+ dnl If it is no GNU xgettext we define it as : so that the -+ dnl Makefiles still can work. -+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then -+ : ; -+ else -+ AC_MSG_RESULT( -+ [found xgettext program is not GNU xgettext; ignore it]) -+ XGETTEXT=":" -+ fi -+ fi -+ -+ # We need to process the po/ directory. -+ POSUB=po -+ -+ AC_OUTPUT_COMMANDS( -+ [case "$CONFIG_FILES" in *po/Makefile.in*) -+ sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile -+ esac]) -+ -+ dnl These rules are solely for the distribution goal. While doing this -+ dnl we only have to keep exactly one list of the available catalogs -+ dnl in configure.in. -+ for lang in $ALL_LINGUAS; do -+ GMOFILES="$GMOFILES $lang.gmo" -+ POFILES="$POFILES $lang.po" -+ done -+ -+ dnl Make all variables we use known to autoconf. -+ AC_SUBST(CATALOGS) -+ AC_SUBST(CATOBJEXT) -+ AC_SUBST(DATADIRNAME) -+ AC_SUBST(GMOFILES) -+ AC_SUBST(INSTOBJEXT) -+ AC_SUBST(INTLDEPS) -+ AC_SUBST(INTLLIBS) -+ AC_SUBST(INTLOBJS) -+ AC_SUBST(POFILES) -+ AC_SUBST(POSUB) -+ ]) -+ -+AC_DEFUN(AM_GLIB_GNU_GETTEXT, -+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl -+ AC_REQUIRE([AC_PROG_CC])dnl -+ AC_REQUIRE([AC_PROG_RANLIB])dnl -+ AC_REQUIRE([AC_HEADER_STDC])dnl -+ AC_REQUIRE([AC_C_CONST])dnl -+ AC_REQUIRE([AC_C_INLINE])dnl -+ AC_REQUIRE([AC_TYPE_OFF_T])dnl -+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl -+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl -+ AC_REQUIRE([AC_FUNC_MMAP])dnl -+ -+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \ -+unistd.h sys/param.h]) -+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \ -+strdup __argz_count __argz_stringify __argz_next]) -+ -+ AM_GLIB_LC_MESSAGES -+ AM_GLIB_WITH_NLS -+ -+ if test "x$CATOBJEXT" != "x"; then -+ if test "x$ALL_LINGUAS" = "x"; then -+ LINGUAS= -+ else -+ AC_MSG_CHECKING(for catalogs to be installed) -+ NEW_LINGUAS= -+ for lang in ${LINGUAS=$ALL_LINGUAS}; do -+ case "$ALL_LINGUAS" in -+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; -+ esac -+ done -+ LINGUAS=$NEW_LINGUAS -+ AC_MSG_RESULT($LINGUAS) -+ fi -+ -+ dnl Construct list of names of catalog files to be constructed. -+ if test -n "$LINGUAS"; then -+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done -+ fi -+ fi -+ -+ dnl Determine which catalog format we have (if any is needed) -+ dnl For now we know about two different formats: -+ dnl Linux libc-5 and the normal X/Open format -+ test -d po || mkdir po -+ if test "$CATOBJEXT" = ".cat"; then -+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen) -+ -+ dnl Transform the SED scripts while copying because some dumb SEDs -+ dnl cannot handle comments. -+ sed -e '/^#/d' $srcdir/po/$msgformat-msg.sed > po/po2msg.sed -+ fi -+ -+ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly -+ dnl find the mkinstalldirs script in another subdir but ($top_srcdir). -+ dnl Try to locate is. -+ MKINSTALLDIRS= -+ if test -n "$ac_aux_dir"; then -+ MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" -+ fi -+ if test -z "$MKINSTALLDIRS"; then -+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" -+ fi -+ AC_SUBST(MKINSTALLDIRS) -+ -+ dnl Generate list of files to be processed by xgettext which will -+ dnl be included in po/Makefile. -+ test -d po || mkdir po -+ if test "x$srcdir" != "x."; then -+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then -+ posrcprefix="$srcdir/" -+ else -+ posrcprefix="../$srcdir/" -+ fi -+ else -+ posrcprefix="../" -+ fi -+ rm -f po/POTFILES -+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ -+ < $srcdir/po/POTFILES.in > po/POTFILES -+ ]) -+ diff --git a/packages/pango/pango_1.10.0.bb b/packages/pango/pango_1.10.0.bb deleted file mode 100644 index 27d57052f7..0000000000 --- a/packages/pango/pango_1.10.0.bb +++ /dev/null @@ -1,51 +0,0 @@ -LICENSE = "LGPL" -SECTION = "x11/libs" -# Xt needed to keep autoconf's check for X11 happy -DEPENDS = "glib-2.0 fontconfig freetype zlib virtual/libx11 libxft libxt gtk-doc cairo" -DESCRIPTION = "The goal of the Pango project is to provide an \ -Open Source framework for the layout and rendering of \ -internationalized text." -PR = "r0" - -RRECOMMENDS_${PN} = "pango-module-basic-x pango-module-basic-fc" - -# seems to go wrong with default cflags -FULL_OPTIMIZATION_arm = "-O2" - -SRC_URI = "ftp://ftp.gtk.org/pub/gtk/v2.8/pango-${PV}.tar.bz2 \ - file://no-tests.patch;patch=1" - -inherit autotools pkgconfig - -EXTRA_OECONF = "--disable-glibtest \ - --enable-explicit-deps=no \ - --disable-debug" - -FILES_${PN} = "/etc ${bindir} ${libdir}/libpango*.so.*" - -LIBV = "1.4.0" - -do_stage () { - for lib in pango pangox pangoft2 pangoxft pangocairo; do - oe_libinstall -so -C pango lib$lib-1.0 ${STAGING_LIBDIR}/ - done - install -d ${STAGING_INCDIR}/pango - install -m 0644 ${S}/pango/pango*.h ${STAGING_INCDIR}/pango/ -} - -postinst_prologue() { -if [ "x$D" != "x" ]; then - exit 1 -fi - -} - -PACKAGES_DYNAMIC = "pango-module-*" - -python populate_packages_prepend () { - prologue = bb.data.getVar("postinst_prologue", d, 1) - - modules_root = bb.data.expand('${libdir}/pango/${LIBV}/modules', d) - - do_split_packages(d, modules_root, '^pango-(.*)\.so$', 'pango-module-%s', 'Pango module %s', prologue + 'pango-querymodules > /etc/pango/pango.modules') -} diff --git a/packages/pango/pango_1.13.2.bb b/packages/pango/pango_1.13.2.bb deleted file mode 100644 index fb2a6a7394..0000000000 --- a/packages/pango/pango_1.13.2.bb +++ /dev/null @@ -1,50 +0,0 @@ -LICENSE = "LGPL" -SECTION = "x11/libs" -# Xt needed to keep autoconf's check for X11 happy -DEPENDS = "glib-2.0 fontconfig freetype zlib virtual/libx11 libxft xt gtk-doc cairo" -DESCRIPTION = "The goal of the Pango project is to provide an \ -Open Source framework for the layout and rendering of \ -internationalized text." -PR = "r0" - -RRECOMMENDS_${PN} = "pango-module-basic-x pango-module-basic-fc" - -# seems to go wrong with default cflags -FULL_OPTIMIZATION_arm = "-O2" - -SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/pango/1.13/pango-${PV}.tar.bz2 \ - file://no-tests.patch;patch=1 \ - file://opentype-makefile.patch;patch=1;pnum=0" - -inherit autotools pkgconfig - -EXTRA_OECONF = "--disable-glibtest \ - --enable-explicit-deps=no \ - --disable-debug" - -FILES_${PN} = "/etc ${bindir} ${libdir}/libpango*.so.*" - -LIBV = "1.5.0" - -do_stage () { - for lib in pango pangox pangoft2 pangoxft pangocairo; do - oe_libinstall -so -C pango lib$lib-1.0 ${STAGING_LIBDIR}/ - done - install -d ${STAGING_INCDIR}/pango - install -m 0644 ${S}/pango/pango*.h ${STAGING_INCDIR}/pango/ -} - -postinst_prologue() { -if [ "x$D" != "x" ]; then - exit 1 -fi - -} - -python populate_packages_prepend () { - prologue = bb.data.getVar("postinst_prologue", d, 1) - - modules_root = bb.data.expand('${libdir}/pango/${LIBV}/modules', d) - - do_split_packages(d, modules_root, '^pango-(.*)\.so$', 'pango-module-%s', 'Pango module %s', prologue + 'pango-querymodules > /etc/pango/pango.modules') -} diff --git a/packages/pango/pango_1.13.3.bb b/packages/pango/pango_1.13.3.bb new file mode 100644 index 0000000000..b882365735 --- /dev/null +++ b/packages/pango/pango_1.13.3.bb @@ -0,0 +1,52 @@ +LICENSE = "LGPL" +SECTION = "x11/libs" +# Xt needed to keep autoconf's check for X11 happy +DEPENDS = "glib-2.0 fontconfig freetype zlib virtual/libx11 libxft xt gtk-doc cairo" +DESCRIPTION = "The goal of the Pango project is to provide an \ +Open Source framework for the layout and rendering of \ +internationalized text." +PR = "r0" + +RRECOMMENDS_${PN} = "pango-module-basic-x pango-module-basic-fc" + +# seems to go wrong with default cflags +FULL_OPTIMIZATION_arm = "-O2" + +SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/pango/1.13/pango-${PV}.tar.bz2 \ + file://no-tests.patch;patch=1 \ + file://opentype-makefile.patch;patch=1;pnum=0" + +inherit autotools pkgconfig + +EXTRA_OECONF = "--disable-glibtest \ + --enable-explicit-deps=no \ + --disable-debug" + +FILES_${PN} = "/etc ${bindir} ${libdir}/libpango*.so.*" + +LIBV = "1.5.0" + +do_stage () { + for lib in pango pangox pangoft2 pangoxft pangocairo; do + oe_libinstall -so -C pango lib$lib-1.0 ${STAGING_LIBDIR}/ + done + install -d ${STAGING_INCDIR}/pango + install -m 0644 ${S}/pango/pango*.h ${STAGING_INCDIR}/pango/ +} + +postinst_prologue() { +if [ "x$D" != "x" ]; then + exit 1 +fi + +} + +PACKAGES_DYNAMIC = "pango-module-*" + +python populate_packages_prepend () { + prologue = bb.data.getVar("postinst_prologue", d, 1) + + modules_root = bb.data.expand('${libdir}/pango/${LIBV}/modules', d) + + do_split_packages(d, modules_root, '^pango-(.*)\.so$', 'pango-module-%s', 'Pango module %s', prologue + 'pango-querymodules > /etc/pango/pango.modules') +} diff --git a/packages/pango/pango_1.2.5.bb b/packages/pango/pango_1.2.5.bb deleted file mode 100644 index 5a8e3da345..0000000000 --- a/packages/pango/pango_1.2.5.bb +++ /dev/null @@ -1,36 +0,0 @@ -LICENSE = "LGPL" -SECTION = "x11/libs" -DEPENDS = "glib-2.0 fontconfig freetype zlib virtual/libx11 libxft libxt" -DESCRIPTION = "The goal of the Pango project is to provide an \ -Open Source framework for the layout and rendering of \ -internationalized text." - -SRC_URI = "http://ftp.gnome.org/pub/gnome/sources/pango/1.2/pango-${PV}.tar.bz2 \ - file://ft2.patch;patch=1 \ - file://m4.patch;patch=1 \ - file://no-tests.patch;patch=1" - -inherit autotools pkgconfig - -EXTRA_OECONF = "--disable-glibtest \ - --enable-explicit-deps=no" - -FILES_${PN} = "/etc ${bindir} ${libdir}/libpango*.so.*" - -LIBV = "1.2.0" - -do_stage () { - for lib in pango pangox pangoft2 pangoxft; do - oe_libinstall -so -C pango lib$lib-1.0 ${STAGING_LIBDIR}/ - done - install -d ${STAGING_INCDIR}/pango - install -m 0644 ${S}/pango/pango*.h ${STAGING_INCDIR}/pango/ -} - -PACKAGES_DYNAMIC = "pango-module-*" - -python populate_packages_prepend () { - modules_root = bb.data.expand('${libdir}/pango/${LIBV}/modules', d) - - do_split_packages(d, modules_root, '^pango-(.*)\.so$', 'pango-module-%s', 'Pango module %s', 'pango-querymodules > /etc/pango/pango.modules') -} diff --git a/packages/pango/pango_1.4.0.bb b/packages/pango/pango_1.4.0.bb deleted file mode 100644 index 3f2f664d21..0000000000 --- a/packages/pango/pango_1.4.0.bb +++ /dev/null @@ -1,37 +0,0 @@ -LICENSE = "LGPL" -SECTION = "x11/libs" -# Xt needed to keep autoconf's check for X11 happy -DEPENDS = "glib-2.0 fontconfig freetype zlib virtual/libx11 libxft libxt" -DESCRIPTION = "The goal of the Pango project is to provide an \ -Open Source framework for the layout and rendering of \ -internationalized text." - -SRC_URI = "ftp://ftp.gtk.org/pub/gtk/v2.4/pango-${PV}.tar.bz2 \ - file://gtk-doc.patch;patch=1 \ - file://no-tests.patch;patch=1" - -inherit autotools pkgconfig - -EXTRA_OECONF = "--disable-glibtest \ - --enable-explicit-deps=no \ - --disable-debug" - -FILES_${PN} = "/etc ${bindir} ${libdir}/libpango*.so.*" - -LIBV = "1.4.0" - -do_stage () { - for lib in pango pangox pangoft2 pangoxft; do - oe_libinstall -so -C pango lib$lib-1.0 ${STAGING_LIBDIR}/ - done - install -d ${STAGING_INCDIR}/pango - install -m 0644 ${S}/pango/pango*.h ${STAGING_INCDIR}/pango/ -} - -PACKAGES_DYNAMIC = "pango-module-*" - -python populate_packages_prepend () { - modules_root = bb.data.expand('${libdir}/pango/${LIBV}/modules', d) - - do_split_packages(d, modules_root, '^pango-(.*)\.so$', 'pango-module-%s', 'Pango module %s', 'pango-querymodules > /etc/pango/pango.modules') -} diff --git a/packages/pango/pango_1.8.0.bb b/packages/pango/pango_1.8.0.bb deleted file mode 100644 index fe9752c8bd..0000000000 --- a/packages/pango/pango_1.8.0.bb +++ /dev/null @@ -1,49 +0,0 @@ -LICENSE = "LGPL" -SECTION = "x11/libs" -# Xt needed to keep autoconf's check for X11 happy -DEPENDS = "glib-2.0 fontconfig freetype zlib virtual/libx11 libxft libxt gtk-doc" -DESCRIPTION = "The goal of the Pango project is to provide an \ -Open Source framework for the layout and rendering of \ -internationalized text." -PR = "r2" - -# seems to go wrong with default cflags -FULL_OPTIMIZATION_arm = "-O2" - -SRC_URI = "ftp://ftp.gtk.org/pub/gtk/v2.6/pango-${PV}.tar.bz2 \ - file://no-tests.patch;patch=1" - -inherit autotools pkgconfig - -EXTRA_OECONF = "--disable-glibtest \ - --enable-explicit-deps=no \ - --disable-debug" - -FILES_${PN} = "/etc ${bindir} ${libdir}/libpango*.so.*" - -LIBV = "1.4.0" - -do_stage () { - for lib in pango pangox pangoft2 pangoxft; do - oe_libinstall -so -C pango lib$lib-1.0 ${STAGING_LIBDIR}/ - done - install -d ${STAGING_INCDIR}/pango - install -m 0644 ${S}/pango/pango*.h ${STAGING_INCDIR}/pango/ -} - -postinst_prologue() { -if [ "x$D" != "x" ]; then - exit 1 -fi - -} - -PACKAGES_DYNAMIC = "pango-module-*" - -python populate_packages_prepend () { - prologue = bb.data.getVar("postinst_prologue", d, 1) - - modules_root = bb.data.expand('${libdir}/pango/${LIBV}/modules', d) - - do_split_packages(d, modules_root, '^pango-(.*)\.so$', 'pango-module-%s', 'Pango module %s', prologue + 'pango-querymodules > /etc/pango/pango.modules') -} diff --git a/packages/pango/pango_1.8.1.bb b/packages/pango/pango_1.8.1.bb deleted file mode 100644 index fe9752c8bd..0000000000 --- a/packages/pango/pango_1.8.1.bb +++ /dev/null @@ -1,49 +0,0 @@ -LICENSE = "LGPL" -SECTION = "x11/libs" -# Xt needed to keep autoconf's check for X11 happy -DEPENDS = "glib-2.0 fontconfig freetype zlib virtual/libx11 libxft libxt gtk-doc" -DESCRIPTION = "The goal of the Pango project is to provide an \ -Open Source framework for the layout and rendering of \ -internationalized text." -PR = "r2" - -# seems to go wrong with default cflags -FULL_OPTIMIZATION_arm = "-O2" - -SRC_URI = "ftp://ftp.gtk.org/pub/gtk/v2.6/pango-${PV}.tar.bz2 \ - file://no-tests.patch;patch=1" - -inherit autotools pkgconfig - -EXTRA_OECONF = "--disable-glibtest \ - --enable-explicit-deps=no \ - --disable-debug" - -FILES_${PN} = "/etc ${bindir} ${libdir}/libpango*.so.*" - -LIBV = "1.4.0" - -do_stage () { - for lib in pango pangox pangoft2 pangoxft; do - oe_libinstall -so -C pango lib$lib-1.0 ${STAGING_LIBDIR}/ - done - install -d ${STAGING_INCDIR}/pango - install -m 0644 ${S}/pango/pango*.h ${STAGING_INCDIR}/pango/ -} - -postinst_prologue() { -if [ "x$D" != "x" ]; then - exit 1 -fi - -} - -PACKAGES_DYNAMIC = "pango-module-*" - -python populate_packages_prepend () { - prologue = bb.data.getVar("postinst_prologue", d, 1) - - modules_root = bb.data.expand('${libdir}/pango/${LIBV}/modules', d) - - do_split_packages(d, modules_root, '^pango-(.*)\.so$', 'pango-module-%s', 'Pango module %s', prologue + 'pango-querymodules > /etc/pango/pango.modules') -} -- cgit v1.2.3 From 49893e2eb4392385e5cff59fc41c76be5a9e2dda Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 28 Aug 2006 07:48:20 +0000 Subject: angstrom: tidy up angstrom.inc --- conf/distro/include/angstrom.inc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/conf/distro/include/angstrom.inc b/conf/distro/include/angstrom.inc index 5ff9e1c942..3bb4028a22 100644 --- a/conf/distro/include/angstrom.inc +++ b/conf/distro/include/angstrom.inc @@ -37,9 +37,6 @@ CXXFLAGS += "-fvisibility-inlines-hidden" #ARM EABI is softfloat by default, but let's make sure :) TARGET_FPU_arm = "soft" -#Always ship these packages -BOOTSTRAP_EXTRA_RDEPENDS += "angstrom-version coreutils dropbear sysvinit" - #Name the generated images in a sane way IMAGE_NAME = "${DISTRO_NAME}-${IMAGE_BASENAME}-${DISTRO_VERSION}-${MACHINE}" DEPLOY_DIR_IMAGE = ${DEPLOY_DIR}/images/${MACHINE} @@ -48,4 +45,4 @@ DEPLOY_DIR_IMAGE = ${DEPLOY_DIR}/images/${MACHINE} DISTRO_CHECK := "${@bb.data.getVar("DISTRO_VERSION",d,1) or bb.fatal('Remove this line or set a dummy DISTRO_VERSION if you really want to build an unversioned distro')}" # We want images supporting the following features (for task-base) -DISTO_FEATURES = "nfs smbfs ipsec wifi ppp alsa bluetooth ext2 irda pcmcia usbgadget usbhost" +DISTO_FEATURES = "nfs smbfs wifi ppp alsa bluetooth ext2 irda pcmcia usbgadget usbhost" -- cgit v1.2.3 From d6da4ca0d13301c94601f28e825e6c722b84cca6 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 28 Aug 2006 07:50:47 +0000 Subject: h5xxx: add apprpriate MACHINE FEATURES --- conf/machine/h5xxx.conf | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/conf/machine/h5xxx.conf b/conf/machine/h5xxx.conf index 32e9304cdb..008bfb252f 100644 --- a/conf/machine/h5xxx.conf +++ b/conf/machine/h5xxx.conf @@ -2,8 +2,8 @@ #@NAME: Compaq iPAQ 51xx, Compaq iPAQ 54xx, Compaq iPAQ 55xx #@DESCRIPTION: Machine configuration for the Compaq iPAQ 51xx, Compaq iPAQ 54xx, and Compaq iPAQ 55xx devices -KERNEL ?= "kernel24" -#KERNEL ?= "kernel26" +#KERNEL ?= "kernel24" +KERNEL ?= "kernel26" OVERRIDES =. "${KERNEL}:" @@ -12,12 +12,14 @@ INHERIT += "linux_modules" TARGET_ARCH = "arm" IPKG_EXTRA_ARCHS = "armv4 armv4t armv5e armv5te ipaqpxa" PREFERRED_PROVIDER_xserver = "xserver-kdrive" -PREFERRED_PROVIDER_virtual/kernel_kernel24 = "handhelds-pxa" -PREFERRED_PROVIDER_virtual/kernel_kernel26 = "handhelds-pxa-2.6" +#PREFERRED_PROVIDER_virtual/kernel_kernel24 = "handhelds-pxa" +PREFERRED_PROVIDER_virtual/kernel = "handhelds-pxa-2.6" EXTRA_IMAGECMD_h5xxx_jffs2 = "-e 0x40000 -p" ROOT_FLASH_SIZE = "32" +MACHINE_FEATURES = "kernel26 apm alsa pcmcia bluetooth irda wifi usbgadget usbhost" + BOOT_MODULES = "${@linux_module_packages('${H5XXX_MODULES}', d)}" BOOTSTRAP_EXTRA_RDEPENDS = "kernel ipaq-boot-params ${BOOT_MODULES}" BOOTSTRAP_EXTRA_RDEPENDS_append_kernel24 = " at76c503a-modules" -- cgit v1.2.3 From 50507e889e337579fc0bb227648bc8216c5009aa Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 28 Aug 2006 08:01:11 +0000 Subject: ipaq-pxa270: add appropriate MACHINE FEATURES --- conf/machine/ipaq-pxa270.conf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/conf/machine/ipaq-pxa270.conf b/conf/machine/ipaq-pxa270.conf index d6281e3016..84380a49d0 100644 --- a/conf/machine/ipaq-pxa270.conf +++ b/conf/machine/ipaq-pxa270.conf @@ -21,6 +21,9 @@ EXTRA_IMAGECMD_jffs2 = "; sumtool -i ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.jf IMAGE_FSTYPES ?= "jffs2" MODUTILS = "26" + +MACHINE_FEATURES = "kernel26 apm alsa pcmcia bluetooth irda wifi usbgadget" + PCMCIA_MANAGER = "pcmciautils" BOOTSTRAP_EXTRA_RDEPENDS = "kernel ipaq-boot-params " BOOTMODULES_RRECOMMENDS = "${@linux_module_packages('${PXA270_MODULES}', d)} ${@linux_module_packages('${HX4700_MODULES}', d)}" @@ -39,10 +42,10 @@ include conf/machine/include/handheld-common.conf GUI_MACHINE_CLASS = "bigscreen" # Use tune-xscale per default. Machine independent feeds should be built with tune-strongarm. -#include conf/machine/include/tune-xscale.conf +include conf/machine/include/tune-xscale.conf # Uncomment this to use iwmmxt optimizations. Remove the above xscale stuff first -include conf/machine/include/tune-iwmmxt.conf +#include conf/machine/include/tune-iwmmxt.conf # These modules are now compiled into the kernel: -- cgit v1.2.3 From 75f70c90ab0d00a1d1d13af9e873aa2dd350210e Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 28 Aug 2006 09:42:23 +0000 Subject: tslib 1.0: use tarball instead of svn and fix packaging * CONFFILES = /etc/ts.conf has been removed --- packages/tslib/tslib_1.0.bb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/tslib/tslib_1.0.bb b/packages/tslib/tslib_1.0.bb index 660d7d5e27..ddd6c5ad6d 100644 --- a/packages/tslib/tslib_1.0.bb +++ b/packages/tslib/tslib_1.0.bb @@ -5,9 +5,8 @@ SECTION = "base" LICENSE = "LGPL" PR = "r0" -SRCDATE_tslib = "now" -SRC_URI = "svn://svn.berlios.de/svnroot/repos/tslib/tags/tslib;module=${PV};proto=http \ +SRC_URI = "http://download.berlios.de/tslib/tslib-1.0.tar.bz2 \ file://ts.conf \ file://ts-2.6.conf \ file://ts.conf-h3600-2.4 \ @@ -17,7 +16,6 @@ SRC_URI = "svn://svn.berlios.de/svnroot/repos/tslib/tags/tslib;module=${PV};prot file://tslib.sh" SRC_URI_append_mnci += " file://devfs.patch;patch=1" SRC_URI_append_mnci += " file://event1.patch;patch=1" -S = "${WORKDIR}/${PV}" inherit autotools pkgconfig @@ -71,7 +69,6 @@ do_install_append() { } SRC_URI_OVERRIDES_PACKAGE_ARCH = "0" -CONFFILES_${PN} = "${sysconfdir}/ts.conf" RDEPENDS_tslib-conf_h1940 = "detect-stylus" RDEPENDS_tslib-conf_h2200 = "detect-stylus" @@ -86,12 +83,17 @@ RDEPENDS_tslib-conf_h4000 = "detect-stylus" PACKAGE_ARCH_tslib-conf = "${MACHINE_ARCH}" PACKAGE_ARCH_mnci = "${MACHINE_ARCH}" -PACKAGES = "tslib-conf libts libts-dev tslib-tests tslib-calibrate" +PACKAGES =+ "tslib-conf libts-dev tslib-tests tslib-calibrate" +DEBIAN_NOAUTONAME_tslib-conf = "1" +DEBIAN_NOAUTONAME_tslib-tests = "1" +DEBIAN_NOAUTONAME_tslib-calibrate = "1" -RDEPENDS_libts = "tslib-conf" +RDEPENDS_${PN} = "tslib-conf" + +FILES_${PN}-dbg += "${libdir}/ts/.debug*" FILES_tslib-conf = "${sysconfdir}/ts.conf ${sysconfdir}/profile.d/tslib.sh ${datadir}/tslib" -FILES_libts = "${libdir}/*.so.* ${libdir}/ts/*.so*" +FILES_${PN} = "${libdir}/*.so.* ${libdir}/ts/*.so*" FILES_libts-dev = "${FILES_tslib-dev}" FILES_tslib-calibrate += "${bindir}/ts_calibrate" FILES_tslib-tests = "${bindir}/ts_harvest ${bindir}/ts_print ${bindir}/ts_print_raw ${bindir}/ts_test" -- cgit v1.2.3 From 9181dc0009b00b49de7c8c236427e728776ea1cb Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 28 Aug 2006 15:48:37 +0000 Subject: dbus-glib: depend on dbus to get dbus.h --- packages/dbus/dbus-glib_0.71.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dbus/dbus-glib_0.71.bb b/packages/dbus/dbus-glib_0.71.bb index 6bb69ba316..80a9ae44d6 100644 --- a/packages/dbus/dbus-glib_0.71.bb +++ b/packages/dbus/dbus-glib_0.71.bb @@ -3,7 +3,7 @@ PR = "r0" HOMEPAGE = "http://www.freedesktop.org/Software/dbus" DESCRIPTION = "message bus system for applications to talk to one another" LICENSE = "GPL" -DEPENDS = "expat glib-2.0 virtual/libintl dbus-glib-native" +DEPENDS = "expat glib-2.0 virtual/libintl dbus" SRC_URI = "http://freedesktop.org/software/dbus/releases/dbus-glib-${PV}.tar.gz \ file://cross.patch;patch=1 \ -- cgit v1.2.3 From 3a1667fe6b2aa742ab876ba5cca09670689bee96 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 28 Aug 2006 16:01:58 +0000 Subject: dbus-native-0.92: do_stage: create dir before putting files to it --- packages/dbus/dbus-native_0.92.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/dbus/dbus-native_0.92.bb b/packages/dbus/dbus-native_0.92.bb index db2d7014ef..d7823889cd 100644 --- a/packages/dbus/dbus-native_0.92.bb +++ b/packages/dbus/dbus-native_0.92.bb @@ -23,5 +23,6 @@ do_stage () { autotools_stage_all # for dbus-glib-native introspection generation + install -d ${STAGING_DATADIR}/dbus install -m 0644 bus/session.conf ${STAGING_DATADIR}/dbus/session.conf } -- cgit v1.2.3 From 02489c016be37d82961b4212bf2be7e04f9d30d1 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Mon, 28 Aug 2006 16:37:33 +0000 Subject: angstrom|familiar|openzaurus.inc: s/DISTO_FEATURES/DISTRO_FEATURES/ :D --- conf/distro/include/angstrom.inc | 2 +- conf/distro/include/familiar.inc | 2 +- conf/distro/include/openzaurus.inc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/conf/distro/include/angstrom.inc b/conf/distro/include/angstrom.inc index 3bb4028a22..d9209ad23c 100644 --- a/conf/distro/include/angstrom.inc +++ b/conf/distro/include/angstrom.inc @@ -45,4 +45,4 @@ DEPLOY_DIR_IMAGE = ${DEPLOY_DIR}/images/${MACHINE} DISTRO_CHECK := "${@bb.data.getVar("DISTRO_VERSION",d,1) or bb.fatal('Remove this line or set a dummy DISTRO_VERSION if you really want to build an unversioned distro')}" # We want images supporting the following features (for task-base) -DISTO_FEATURES = "nfs smbfs wifi ppp alsa bluetooth ext2 irda pcmcia usbgadget usbhost" +DISTRO_FEATURES = "nfs smbfs wifi ppp alsa bluetooth ext2 irda pcmcia usbgadget usbhost" diff --git a/conf/distro/include/familiar.inc b/conf/distro/include/familiar.inc index c7f2a05177..ea360f5dc5 100644 --- a/conf/distro/include/familiar.inc +++ b/conf/distro/include/familiar.inc @@ -17,4 +17,4 @@ UDEV_DEVFS_RULES = "1" DISTRO_CHECK := "${@bb.data.getVar("DISTRO_VERSION",d,1) or bb.fatal('Remove this line or set a dummy DISTRO_VERSION if you really want to build an unversioned distro')}" # We want images supporting the following features (for task-base) -DISTO_FEATURES = "nfs smbfs ipsec wifi ppp alsa bluetooth ext2 irda pcmcia usbgadget usbhost" +DISTRO_FEATURES = "nfs smbfs ipsec wifi ppp alsa bluetooth ext2 irda pcmcia usbgadget usbhost" diff --git a/conf/distro/include/openzaurus.inc b/conf/distro/include/openzaurus.inc index 01877956ed..ea408ff221 100644 --- a/conf/distro/include/openzaurus.inc +++ b/conf/distro/include/openzaurus.inc @@ -22,4 +22,4 @@ BB_MIN_VERSION = "1.4.4" INHERIT += "sanity" # We want images supporting the following features (for task-base) -DISTO_FEATURES = "nfs smbfs ipsec wifi ppp alsa bluetooth ext2 irda pcmcia usbgadget usbhost" +DISTRO_FEATURES = "nfs smbfs ipsec wifi ppp alsa bluetooth ext2 irda pcmcia usbgadget usbhost" -- cgit v1.2.3 From e862cffe7647e7b07450d5cf7c4211ebe534661e Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 28 Aug 2006 17:11:04 +0000 Subject: dbus-glib-0.71: depend on dbus-glib-native for binding header generation --- packages/dbus/dbus-glib_0.71.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dbus/dbus-glib_0.71.bb b/packages/dbus/dbus-glib_0.71.bb index 80a9ae44d6..26bc851098 100644 --- a/packages/dbus/dbus-glib_0.71.bb +++ b/packages/dbus/dbus-glib_0.71.bb @@ -3,7 +3,7 @@ PR = "r0" HOMEPAGE = "http://www.freedesktop.org/Software/dbus" DESCRIPTION = "message bus system for applications to talk to one another" LICENSE = "GPL" -DEPENDS = "expat glib-2.0 virtual/libintl dbus" +DEPENDS = "expat glib-2.0 virtual/libintl dbus-glib-native dbus" SRC_URI = "http://freedesktop.org/software/dbus/releases/dbus-glib-${PV}.tar.gz \ file://cross.patch;patch=1 \ -- cgit v1.2.3 From 537ed75a23b6d1e2ef3f8138e891b4b1b0bfbd49 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 28 Aug 2006 17:46:08 +0000 Subject: libnss-mdns: remove avahi-daemon recommendation to avoid circular dependency --- packages/libnss-mdns/libnss-mdns_0.6.bb | 2 +- packages/libnss-mdns/libnss-mdns_0.7.bb | 2 +- packages/libnss-mdns/libnss-mdns_0.8.bb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/libnss-mdns/libnss-mdns_0.6.bb b/packages/libnss-mdns/libnss-mdns_0.6.bb index fc1941fc23..5de9df567c 100644 --- a/packages/libnss-mdns/libnss-mdns_0.6.bb +++ b/packages/libnss-mdns/libnss-mdns_0.6.bb @@ -4,7 +4,7 @@ LICENSE = "GPL" SECTION = "libs" PRIORITY = "optional" -RRECOMMENDS_${PN} = "avahi-daemon zeroconf" +RRECOMMENDS_${PN} = "zeroconf" PR = "r1" EXTRA_OECONF = "--libdir=/lib" diff --git a/packages/libnss-mdns/libnss-mdns_0.7.bb b/packages/libnss-mdns/libnss-mdns_0.7.bb index 306adb0ee6..98ab50f07f 100644 --- a/packages/libnss-mdns/libnss-mdns_0.7.bb +++ b/packages/libnss-mdns/libnss-mdns_0.7.bb @@ -4,7 +4,7 @@ LICENSE = "GPL" SECTION = "libs" PRIORITY = "optional" -RRECOMMENDS_${PN} = "avahi-daemon zeroconf" +RRECOMMENDS_${PN} = "zeroconf" PR = "r0" EXTRA_OECONF = "--libdir=/lib" diff --git a/packages/libnss-mdns/libnss-mdns_0.8.bb b/packages/libnss-mdns/libnss-mdns_0.8.bb index 997daf43b0..475297cd63 100644 --- a/packages/libnss-mdns/libnss-mdns_0.8.bb +++ b/packages/libnss-mdns/libnss-mdns_0.8.bb @@ -4,7 +4,7 @@ LICENSE = "GPL" SECTION = "libs" PRIORITY = "optional" -RRECOMMENDS_${PN} = "avahi-daemon zeroconf" +RRECOMMENDS_${PN} = "zeroconf" PR = "r0" EXTRA_OECONF = "--libdir=/lib" -- cgit v1.2.3 From 8d2c295a31fce8efef397d7c4443ee9ac29eee99 Mon Sep 17 00:00:00 2001 From: Stelios Koroneos Date: Mon, 28 Aug 2006 19:28:08 +0000 Subject: Machine config for the dht-walnut (ppc) board Machine config for the dht-walnut ppc based board Machine config file for the ppc based dht-walnut board --- conf/machine/dht-walnut.conf | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 conf/machine/dht-walnut.conf diff --git a/conf/machine/dht-walnut.conf b/conf/machine/dht-walnut.conf new file mode 100644 index 0000000000..68b754f2d3 --- /dev/null +++ b/conf/machine/dht-walnut.conf @@ -0,0 +1,20 @@ +TARGET_ARCH = "powerpc" +IPKG_ARCHS = "all powerpc ${MACHINE}" + +PREFERRED_PROVIDER_virtual/kernel = "linux-dht-walnut" + +#TARGET_FPU = "soft" +TARGET_CPU = "405" +OLDEST_KERNEL = "2.6.9" + +# TARGET_VENDOR = "-oe" + +BOOTSTRAP_EXTRA_DEPENDS = "virtual/kernel pciutils udev" +BOOTSTRAP_EXTRA_RDEPENDS = "kernel pciutils udev" + +udevdir = "/dev" +OLDEST_KERNEL = "2.6.5" +# GLIBC_ADDONS = "nptl" +# GLIBC_EXTRA_OECONF = "--with-tls" + + -- cgit v1.2.3 From 7f2a9d67a3f3d0c3c4194f1790686ec219cdb82a Mon Sep 17 00:00:00 2001 From: Kristoffer Ericson Date: Mon, 28 Aug 2006 20:29:19 +0000 Subject: packages/glib-2.0/glib-2.0_2.12.0: Fixes broken URL --- packages/glib-2.0/glib-2.0_2.12.0.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/glib-2.0/glib-2.0_2.12.0.bb b/packages/glib-2.0/glib-2.0_2.12.0.bb index 2082e4ca6b..0dce9a6db7 100644 --- a/packages/glib-2.0/glib-2.0_2.12.0.bb +++ b/packages/glib-2.0/glib-2.0_2.12.0.bb @@ -17,7 +17,7 @@ FILES_glib-2.0-utils = "${bindir}/*" EXTRA_OECONF = "--disable-debug" -SRC_URI = "ftp://ftp.gtk.org/pub/gtk/v2.12/glib-${PV}.tar.bz2 \ +SRC_URI = "ftp://ftp.gtk.org/pub/glib/2.12/glib-${PV}.tar.bz2 \ file://glibconfig-sysdefs.h \ file://configure-libtool.patch;patch=1" -- cgit v1.2.3 From 395ef28947528cc4cd955ae4480c2b6b5561c892 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 28 Aug 2006 19:29:30 +0000 Subject: rm_work.bbclass: stop cleaning out before populate_staging --- classes/rm_work.bbclass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/rm_work.bbclass b/classes/rm_work.bbclass index 340446917e..7f590e1b15 100644 --- a/classes/rm_work.bbclass +++ b/classes/rm_work.bbclass @@ -19,4 +19,4 @@ do_rm_work () { } addtask rm_work before do_build -addtask rm_work after do_package +addtask rm_work after do_populate_staging -- cgit v1.2.3 From dc5ca9f451646a2cfd4708fe16fad3527b1b8e17 Mon Sep 17 00:00:00 2001 From: Stelios Koroneos Date: Mon, 28 Aug 2006 19:30:26 +0000 Subject: Machine config file for the mips based RB5XX family of boards also knows as Routerboards --- conf/machine/rb500.conf | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 conf/machine/rb500.conf diff --git a/conf/machine/rb500.conf b/conf/machine/rb500.conf new file mode 100644 index 0000000000..aec2a8f726 --- /dev/null +++ b/conf/machine/rb500.conf @@ -0,0 +1,8 @@ +#@TYPE: Machine +#@NAME: Mikrotik RB500 +#@DESCRIPTION: Machine configuration for the MIPS based Routerboard + +TARGET_ARCH = "mipsel" +TARGET_CC_ARCH = "-Os -mips2" +IPKG_ARCHS = "all mipsel ${MACHINE}" +PREFERRED_PROVIDER_virtual/kernel = "linux-rb500" -- cgit v1.2.3 From 98d2a57db6b822014361aabad9486fd426d88eaa Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 28 Aug 2006 20:26:01 +0000 Subject: linux-omap1_2.6.x+git, omap5912osk: Add bb file to build kernel from omap git * Build kernel from omap git repository, use most recent version * Change omap5912osk machine to use this kernel * The depmod command is failing at the moment --- conf/machine/omap5912osk.conf | 6 +++-- packages/linux/linux-omap1_2.6.x+git.bb | 44 +++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 packages/linux/linux-omap1_2.6.x+git.bb diff --git a/conf/machine/omap5912osk.conf b/conf/machine/omap5912osk.conf index a2c01add5d..04178166d9 100644 --- a/conf/machine/omap5912osk.conf +++ b/conf/machine/omap5912osk.conf @@ -10,8 +10,10 @@ PREFERRED_PROVIDER_virtual/kernel = "linux-omap1" PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}depmod:module-init-tools-cross" PREFERRED_VERSION_u-boot = "LABEL.2006.06.30.2020" -#PREFERRED_VERSION_linux-omap1 = "2.6.17-omap1" -PREFERRED_VERSION_linux-omap1 = "2.6.12-rc2" + +# Use current git until I can find a git tag that builds for omap5912osk +PREFERRED_VERSION_linux-omap1 = "2.6.x+git" +#PREFERRED_VERSION_linux-omap1 = "2.6.12-rc2" BOOTSTRAP_EXTRA_RDEPENDS += "modutils-collateral" diff --git a/packages/linux/linux-omap1_2.6.x+git.bb b/packages/linux/linux-omap1_2.6.x+git.bb new file mode 100644 index 0000000000..9e499c7687 --- /dev/null +++ b/packages/linux/linux-omap1_2.6.x+git.bb @@ -0,0 +1,44 @@ +PR = "r0" +SECTION = "kernel" +DESCRIPTION = "Linux kernel for OMAP processors" +LICENSE = "GPL" + +SRC_URI = "git://source.mvista.com/git/linux-omap-2.6.git;protocol=git" + +S = "${WORKDIR}/git" + +KERNEL_IMAGETYPE = "vmlinux" +KERNEL_OUTPUT = "arch/${ARCH}/boot/compressed/${KERNEL_IMAGETYPE}" +#KERNEL_CCSUFFIX = "-4.1.1" + +DEPENDS = "u-boot" + +inherit kernel + +# GIT does not have the UTS_RELEASE in version.h used to find the kernel version +KERNEL_RELEASE = "2.6.17" + +COMPATIBLE_HOST = 'arm.*-linux' + +do_configure_prepend() { + if [ "${MACHINE}" == "omap5912osk" ] ; then + make omap_osk_5912_defconfig + fi + + oe_runmake oldconfig +} + +do_deploy() { + if [ "${MACHINE}" == "omap5912osk" ]; then + install -d ${DEPLOY_DIR_IMAGE} + arm-linux-objcopy -O binary -R .note -R .comment -S arch/arm/boot/compressed/vmlinux ${DEPLOY_DIR_IMAGE}/linux.bin + gzip -f -9 ${DEPLOY_DIR_IMAGE}/linux.bin + mkimage -A arm -O linux -T kernel -C gzip -a 0x10c08000 -e 0x10c08000 -n "OE" -d ${DEPLOY_DIR_IMAGE}/linux.bin.gz ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${MACHINE}-${DATETIME}.bin + rm ${DEPLOY_DIR_IMAGE}/linux.bin.gz + fi +} + + +do_deploy[dirs] = "${S}" + +addtask deploy before do_build after do_compile -- cgit v1.2.3 From d3c0ca658f75bf8f2aa96c51126712eb8d45c875 Mon Sep 17 00:00:00 2001 From: Chris Larson Date: Mon, 28 Aug 2006 20:30:14 +0000 Subject: Merge from poky: Rework the way patches are handled. There are now two abstract base classes, initialized in patch.bbclass. One for patchset operations on a directory, and another for patch failure resolution. Currently includes 'patch' and 'quilt' concrete PatchSet classes, and a 'user' resolver class, which simply drops you into a shell in the source tree to fix the rejects. --- classes/base.bbclass | 96 +----- classes/patch.bbclass | 476 ++++++++++++++++++++++++++++ conf/bitbake.conf | 12 +- packages/gawk/gawk-native_3.1.4.bb | 4 +- packages/patcher/patcher-native_20040913.bb | 4 +- packages/quilt/quilt-native.inc | 3 +- 6 files changed, 496 insertions(+), 99 deletions(-) create mode 100644 classes/patch.bbclass diff --git a/classes/base.bbclass b/classes/base.bbclass index 670b97a72d..51b6d2111f 100644 --- a/classes/base.bbclass +++ b/classes/base.bbclass @@ -1,5 +1,4 @@ BB_DEFAULT_TASK = "build" -PATCHES_DIR="${S}" def base_dep_prepend(d): import bb; @@ -13,9 +12,11 @@ def base_dep_prepend(d): # INHIBIT_DEFAULT_DEPS doesn't apply to the patch command. Whether or not # we need that built is the responsibility of the patch function / class, not # the application. - patchdeps = bb.data.getVar("PATCH_DEPENDS", d, 1) - if patchdeps and not patchdeps in bb.data.getVar("PROVIDES", d, 1): - deps = patchdeps + patchdeps = bb.data.getVar("PATCHTOOL", d, 1) + if patchdeps: + patchdeps = "%s-native" % patchdeps + if not patchdeps in bb.data.getVar("PROVIDES", d, 1): + deps = patchdeps if not bb.data.getVar('INHIBIT_DEFAULT_DEPS', d): if (bb.data.getVar('HOST_SYS', d, 1) != @@ -451,86 +452,6 @@ python base_do_unpack() { raise bb.build.FuncFailed() } -addtask patch after do_unpack -do_patch[dirs] = "${WORKDIR}" -python base_do_patch() { - import re - import bb.fetch - - src_uri = (bb.data.getVar('SRC_URI', d, 1) or '').split() - if not src_uri: - return - - patchcleancmd = bb.data.getVar('PATCHCLEANCMD', d, 1) - if patchcleancmd: - bb.data.setVar("do_patchcleancmd", patchcleancmd, d) - bb.data.setVarFlag("do_patchcleancmd", "func", 1, d) - bb.build.exec_func("do_patchcleancmd", d) - - workdir = bb.data.getVar('WORKDIR', d, 1) - for url in src_uri: - - (type, host, path, user, pswd, parm) = bb.decodeurl(url) - if not "patch" in parm: - continue - - bb.fetch.init([url],d) - url = bb.encodeurl((type, host, path, user, pswd, [])) - local = os.path.join('/', bb.fetch.localpath(url, d)) - - # did it need to be unpacked? - dots = os.path.basename(local).split(".") - if dots[-1] in ['gz', 'bz2', 'Z']: - unpacked = os.path.join(bb.data.getVar('WORKDIR', d),'.'.join(dots[0:-1])) - else: - unpacked = local - unpacked = bb.data.expand(unpacked, d) - - if "pnum" in parm: - pnum = parm["pnum"] - else: - pnum = "1" - - if "pname" in parm: - pname = parm["pname"] - else: - pname = os.path.basename(unpacked) - - if "mindate" in parm: - mindate = parm["mindate"] - else: - mindate = 0 - - if "maxdate" in parm: - maxdate = parm["maxdate"] - else: - maxdate = "20711226" - - pn = bb.data.getVar('PN', d, 1) - srcdate = bb.data.getVar('SRCDATE_%s' % pn, d, 1) - - if not srcdate: - srcdate = bb.data.getVar('SRCDATE', d, 1) - - if srcdate == "now": - srcdate = bb.data.getVar('DATE', d, 1) - - if (maxdate < srcdate) or (mindate > srcdate): - if (maxdate < srcdate): - bb.note("Patch '%s' is outdated" % pname) - - if (mindate > srcdate): - bb.note("Patch '%s' is predated" % pname) - - continue - - bb.note("Applying patch '%s'" % pname) - bb.data.setVar("do_patchcmd", bb.data.getVar("PATCHCMD", d, 1) % (pnum, pname, unpacked), d) - bb.data.setVarFlag("do_patchcmd", "func", 1, d) - bb.data.setVarFlag("do_patchcmd", "dirs", "${WORKDIR} ${S}", d) - bb.build.exec_func("do_patchcmd", d) -} - addhandler base_eventhandler python base_eventhandler() { @@ -615,6 +536,8 @@ base_do_compile() { fi } + +addtask stage after do_compile base_do_stage () { : } @@ -759,7 +682,10 @@ python () { return } -EXPORT_FUNCTIONS do_clean do_mrproper do_fetch do_unpack do_configure do_compile do_install do_package do_patch do_populate_pkgs do_stage +# Patch handling +inherit patch + +EXPORT_FUNCTIONS do_clean do_mrproper do_fetch do_unpack do_configure do_compile do_install do_package do_populate_pkgs do_stage MIRRORS[func] = "0" MIRRORS () { diff --git a/classes/patch.bbclass b/classes/patch.bbclass new file mode 100644 index 0000000000..ea0182484e --- /dev/null +++ b/classes/patch.bbclass @@ -0,0 +1,476 @@ +# Copyright (C) 2006 OpenedHand LTD + +def patch_init(d): + import os, sys + + def md5sum(fname): + import md5, sys + + f = file(fname, 'rb') + m = md5.new() + while True: + d = f.read(8096) + if not d: + break + m.update(d) + f.close() + return m.hexdigest() + + class CmdError(Exception): + def __init__(self, exitstatus, output): + self.status = exitstatus + self.output = output + + def __str__(self): + return "Command Error: exit status: %d Output:\n%s" % (self.status, self.output) + + class NotFoundError(Exception): + def __init__(self, path): + self.path = path + def __str__(self): + return "Error: %s not found." % self.path + + def runcmd(args, dir = None): + import commands + + if dir: + olddir = os.path.abspath(os.curdir) + if not os.path.exists(dir): + raise NotFoundError(dir) + os.chdir(dir) + # print("cwd: %s -> %s" % (olddir, self.dir)) + + try: + args = [ commands.mkarg(str(arg)) for arg in args ] + cmd = " ".join(args) + # print("cmd: %s" % cmd) + (exitstatus, output) = commands.getstatusoutput(cmd) + if exitstatus != 0: + raise CmdError(exitstatus >> 8, output) + return output + + finally: + if dir: + os.chdir(olddir) + + class PatchError(Exception): + def __init__(self, msg): + self.msg = msg + + def __str__(self): + return "Patch Error: %s" % self.msg + + import bb, bb.data, bb.fetch + + class PatchSet(object): + defaults = { + "strippath": 1 + } + + def __init__(self, dir, d): + self.dir = dir + self.d = d + self.patches = [] + self._current = None + + def current(self): + return self._current + + def Clean(self): + """ + Clean out the patch set. Generally includes unapplying all + patches and wiping out all associated metadata. + """ + raise NotImplementedError() + + def Import(self, patch, force): + if not patch.get("file"): + if not patch.get("remote"): + raise PatchError("Patch file must be specified in patch import.") + else: + patch["file"] = bb.fetch.localpath(patch["remote"], self.d) + + for param in PatchSet.defaults: + if not patch.get(param): + patch[param] = PatchSet.defaults[param] + + if patch.get("remote"): + patch["file"] = bb.data.expand(bb.fetch.localpath(patch["remote"], self.d), self.d) + + patch["filemd5"] = md5sum(patch["file"]) + + def Push(self, force): + raise NotImplementedError() + + def Pop(self, force): + raise NotImplementedError() + + def Refresh(self, remote = None, all = None): + raise NotImplementedError() + + + class PatchTree(PatchSet): + def __init__(self, dir, d): + PatchSet.__init__(self, dir, d) + + def Import(self, patch, force = None): + """""" + PatchSet.Import(self, patch, force) + + self.patches.insert(self._current or 0, patch) + + def _applypatch(self, patch, force = None, reverse = None): + shellcmd = ["patch", "<", patch['file'], "-p", patch['strippath']] + if reverse: + shellcmd.append('-R') + shellcmd.append('--dry-run') + + try: + output = runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) + except CmdError: + if force: + shellcmd.pop(len(shellcmd) - 1) + output = runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) + else: + import sys + raise sys.exc_value + + return output + + def Push(self, force = None, all = None): + if all: + for i in self.patches: + if self._current is not None: + self._current = self._current + 1 + else: + self._current = 0 + self._applypatch(i, force) + else: + if self._current is not None: + self._current = self._current + 1 + else: + self._current = 0 + self._applypatch(self.patches[self._current], force) + + + def Pop(self, force = None, all = None): + if all: + for i in self.patches: + self._applypatch(i, force, True) + else: + self._applypatch(self.patches[self._current], force, True) + + def Clean(self): + """""" + + class QuiltTree(PatchSet): + def _runcmd(self, args): + runcmd(["quilt"] + args, self.dir) + + def _quiltpatchpath(self, file): + return os.path.join(self.dir, "patches", os.path.basename(file)) + + + def __init__(self, dir, d): + PatchSet.__init__(self, dir, d) + self.initialized = False + + def Clean(self): + try: + self._runcmd(["pop", "-a", "-f"]) + except CmdError: + pass + except NotFoundError: + pass + # runcmd(["rm", "-rf", os.path.join(self.dir, "patches"), os.path.join(self.dir, ".pc")]) + self.initialized = True + + def InitFromDir(self): + # read series -> self.patches + seriespath = os.path.join(self.dir, 'patches', 'series') + if not os.path.exists(self.dir): + raise Exception("Error: %s does not exist." % self.dir) + if os.path.exists(seriespath): + series = file(seriespath, 'r') + for line in series.readlines(): + patch = {} + parts = line.strip().split() + patch["quiltfile"] = self._quiltpatchpath(parts[0]) + patch["quiltfilemd5"] = md5sum(patch["quiltfile"]) + if len(parts) > 1: + patch["strippath"] = parts[1][2:] + self.patches.append(patch) + series.close() + + # determine which patches are applied -> self._current + try: + output = runcmd(["quilt", "applied"], self.dir) + except CmdError: + if sys.exc_value.output.strip() == "No patches applied": + return + else: + raise sys.exc_value + output = [val for val in output.split('\n') if not val.startswith('#')] + for patch in self.patches: + if os.path.basename(patch["quiltfile"]) == output[-1]: + self._current = self.patches.index(patch) + self.initialized = True + + def Import(self, patch, force = None): + if not self.initialized: + self.InitFromDir() + PatchSet.Import(self, patch, force) + + args = ["import", "-p", patch["strippath"]] + if force: + args.append("-f") + args.append(patch["file"]) + + self._runcmd(args) + + patch["quiltfile"] = self._quiltpatchpath(patch["file"]) + patch["quiltfilemd5"] = md5sum(patch["quiltfile"]) + + # TODO: determine if the file being imported: + # 1) is already imported, and is the same + # 2) is already imported, but differs + + self.patches.insert(self._current or 0, patch) + + + def Push(self, force = None, all = None): + # quilt push [-f] + + args = ["push"] + if force: + args.append("-f") + if all: + args.append("-a") + + self._runcmd(args) + + if self._current is not None: + self._current = self._current + 1 + else: + self._current = 0 + + def Pop(self, force = None, all = None): + # quilt pop [-f] + args = ["pop"] + if force: + args.append("-f") + if all: + args.append("-a") + + self._runcmd(args) + + if self._current == 0: + self._current = None + + if self._current is not None: + self._current = self._current - 1 + + def Refresh(self, **kwargs): + if kwargs.get("remote"): + patch = self.patches[kwargs["patch"]] + if not patch: + raise PatchError("No patch found at index %s in patchset." % kwargs["patch"]) + (type, host, path, user, pswd, parm) = bb.decodeurl(patch["remote"]) + if type == "file": + import shutil + if not patch.get("file") and patch.get("remote"): + patch["file"] = bb.fetch.localpath(patch["remote"], self.d) + + shutil.copyfile(patch["quiltfile"], patch["file"]) + else: + raise PatchError("Unable to do a remote refresh of %s, unsupported remote url scheme %s." % (os.path.basename(patch["quiltfile"]), type)) + else: + # quilt refresh + args = ["refresh"] + if kwargs.get("quiltfile"): + args.append(os.path.basename(kwargs["quiltfile"])) + elif kwargs.get("patch"): + args.append(os.path.basename(self.patches[kwargs["patch"]]["quiltfile"])) + self._runcmd(args) + + class Resolver(object): + def __init__(self, patchset): + raise NotImplementedError() + + def Resolve(self): + raise NotImplementedError() + + def Revert(self): + raise NotImplementedError() + + def Finalize(self): + raise NotImplementedError() + + # Patch resolver which relies on the user doing all the work involved in the + # resolution, with the exception of refreshing the remote copy of the patch + # files (the urls). + class UserResolver(Resolver): + def __init__(self, patchset): + self.patchset = patchset + + # Force a push in the patchset, then drop to a shell for the user to + # resolve any rejected hunks + def Resolve(self): + + olddir = os.path.abspath(os.curdir) + os.chdir(self.patchset.dir) + try: + self.patchset.Push(True) + except CmdError, v: + # Patch application failed + if sys.exc_value.output.strip() == "No patches applied": + return + print(sys.exc_value) + print('NOTE: dropping user into a shell, so that patch rejects can be fixed manually.') + + os.system('/bin/sh') + + # Construct a new PatchSet after the user's changes, compare the + # sets, checking patches for modifications, and doing a remote + # refresh on each. + oldpatchset = self.patchset + self.patchset = oldpatchset.__class__(self.patchset.dir, self.patchset.d) + + for patch in self.patchset.patches: + oldpatch = None + for opatch in oldpatchset.patches: + if opatch["quiltfile"] == patch["quiltfile"]: + oldpatch = opatch + + if oldpatch: + patch["remote"] = oldpatch["remote"] + if patch["quiltfile"] == oldpatch["quiltfile"]: + if patch["quiltfilemd5"] != oldpatch["quiltfilemd5"]: + bb.note("Patch %s has changed, updating remote url %s" % (os.path.basename(patch["quiltfile"]), patch["remote"])) + # user change? remote refresh + self.patchset.Refresh(remote=True, patch=self.patchset.patches.index(patch)) + else: + # User did not fix the problem. Abort. + raise PatchError("Patch application failed, and user did not fix and refresh the patch.") + except Exception: + os.chdir(olddir) + raise + os.chdir(olddir) + + # Throw away the changes to the patches in the patchset made by resolve() + def Revert(self): + raise NotImplementedError() + + # Apply the changes to the patches in the patchset made by resolve() + def Finalize(self): + raise NotImplementedError() + + g = globals() + g["PatchSet"] = PatchSet + g["PatchTree"] = PatchTree + g["QuiltTree"] = QuiltTree + g["Resolver"] = Resolver + g["UserResolver"] = UserResolver + g["NotFoundError"] = NotFoundError + g["CmdError"] = CmdError + +addtask patch after do_unpack +do_patch[dirs] = "${WORKDIR}" +python patch_do_patch() { + import re + import bb.fetch + + patch_init(d) + + src_uri = (bb.data.getVar('SRC_URI', d, 1) or '').split() + if not src_uri: + return + + patchsetmap = { + "patch": PatchTree, + "quilt": QuiltTree, + } + + cls = patchsetmap[bb.data.getVar('PATCHTOOL', d, 1) or 'quilt'] + + resolvermap = { + "user": UserResolver, + } + + rcls = resolvermap[bb.data.getVar('PATCHRESOLVE', d, 1) or 'user'] + + s = bb.data.getVar('S', d, 1) + + path = os.getenv('PATH') + os.putenv('PATH', bb.data.getVar('PATH', d, 1)) + patchset = cls(s, d) + patchset.Clean() + + resolver = rcls(patchset) + + workdir = bb.data.getVar('WORKDIR', d, 1) + for url in src_uri: + (type, host, path, user, pswd, parm) = bb.decodeurl(url) + if not "patch" in parm: + continue + + bb.fetch.init([url],d) + url = bb.encodeurl((type, host, path, user, pswd, [])) + local = os.path.join('/', bb.fetch.localpath(url, d)) + + # did it need to be unpacked? + dots = os.path.basename(local).split(".") + if dots[-1] in ['gz', 'bz2', 'Z']: + unpacked = os.path.join(bb.data.getVar('WORKDIR', d),'.'.join(dots[0:-1])) + else: + unpacked = local + unpacked = bb.data.expand(unpacked, d) + + if "pnum" in parm: + pnum = parm["pnum"] + else: + pnum = "1" + + if "pname" in parm: + pname = parm["pname"] + else: + pname = os.path.basename(unpacked) + + if "mindate" in parm: + mindate = parm["mindate"] + else: + mindate = 0 + + if "maxdate" in parm: + maxdate = parm["maxdate"] + else: + maxdate = "20711226" + + pn = bb.data.getVar('PN', d, 1) + srcdate = bb.data.getVar('SRCDATE_%s' % pn, d, 1) + + if not srcdate: + srcdate = bb.data.getVar('SRCDATE', d, 1) + + if srcdate == "now": + srcdate = bb.data.getVar('DATE', d, 1) + + if (maxdate < srcdate) or (mindate > srcdate): + if (maxdate < srcdate): + bb.note("Patch '%s' is outdated" % pname) + + if (mindate > srcdate): + bb.note("Patch '%s' is predated" % pname) + + continue + + bb.note("Applying patch '%s'" % pname) + try: + patchset.Import({"file":unpacked, "remote":url, "strippath": pnum}, True) + except NotFoundError: + import sys + raise bb.build.FuncFailed(str(sys.exc_value)) + resolver.Resolve() +} + +EXPORT_FUNCTIONS do_patch diff --git a/conf/bitbake.conf b/conf/bitbake.conf index 9f94bae3f5..2e3cb0f980 100644 --- a/conf/bitbake.conf +++ b/conf/bitbake.conf @@ -238,6 +238,12 @@ export BUILD_STRIP = "${BUILD_PREFIX}strip" export MAKE = "make" EXTRA_OEMAKE = "-e MAKEFLAGS=" +################################################################## +# Patch handling. +################################################################## +PATCHTOOL = 'quilt' +PATCHRESOLVE = 'user' + ################################################################## # Build flags and options. ################################################################## @@ -336,12 +342,6 @@ SRC_URI = "file://${FILE}" MKTEMPDIRCMD = "mktemp -d -q ${TMPBASE}" MKTEMPCMD = "mktemp -q ${TMPBASE}" -# Program to be used to patch sources, use 'inherit patcher' to overwrite this: - -PATCHCLEANCMD = 'if [ -n "`quilt applied`" ]; then quilt pop -a -R -f || exit 1; fi' -PATCHCMD = "pnum='%s'; name='%s'; patch='%s'; mkdir -p patches ; quilt upgrade >/dev/null 2>&1; quilt import -f -p $pnum -P $name $patch; chmod u+w patches/$name; quilt push" -PATCH_DEPENDS = "quilt-native" - # GNU patch tries to be intellgent about checking out read-only files from # a RCS, which freaks out those special folks with active Perforce clients # the following makes patch ignore RCS: diff --git a/packages/gawk/gawk-native_3.1.4.bb b/packages/gawk/gawk-native_3.1.4.bb index ba8efd1af7..0a33f71684 100644 --- a/packages/gawk/gawk-native_3.1.4.bb +++ b/packages/gawk/gawk-native_3.1.4.bb @@ -4,9 +4,7 @@ require gawk_${PV}.bb inherit native DEPENDS = "" -PATCH_DEPENDS = "" -PATCHCLEANCMD = "" -PATCHCMD = "num='%s'; name='%s'; file='%s'; patch -p "$num" -i "$file"" +PATCHTOOL = "patch" S = "${WORKDIR}/gawk-${PV}" diff --git a/packages/patcher/patcher-native_20040913.bb b/packages/patcher/patcher-native_20040913.bb index 833ca21a53..7da61e91c2 100644 --- a/packages/patcher/patcher-native_20040913.bb +++ b/packages/patcher/patcher-native_20040913.bb @@ -14,9 +14,7 @@ SRC_URI = "http://www.holgerschurig.de/files/linux/patcher-${PV}.tar.bz2" SRC_URI_append_build-freebsd = " file://freebsd_gpatch.patch;patch=1 " S = "${WORKDIR}/patcher" -PATCHCLEANCMD = "" -PATCHCMD = "num='%s'; name='%s'; file='%s'; patch -p "$num" -i "$file"" -PATCHCMD_build-freebsd = "num='%s'; name='%s'; file='%s'; gpatch -p "$num" -i "$file"" +PATCHTOOL = "patch" do_stage() { install -m 0755 patcher.py ${STAGING_BINDIR}/patcher diff --git a/packages/quilt/quilt-native.inc b/packages/quilt/quilt-native.inc index d19d864904..c8bbdc8e07 100644 --- a/packages/quilt/quilt-native.inc +++ b/packages/quilt/quilt-native.inc @@ -8,8 +8,7 @@ INHIBIT_AUTOTOOLS_DEPS = "1" inherit autotools native -PATCHCLEANCMD = "" -PATCHCMD = "num='%s'; name='%s'; file='%s'; patch -p "$num" -i "$file"" +PATCHTOOL = "patch" EXTRA_OECONF = "--disable-nls" do_configure () { -- cgit v1.2.3 From c50a5743b3273d97db8957915d084de01fef7c59 Mon Sep 17 00:00:00 2001 From: Patrick Steiner Date: Mon, 28 Aug 2006 20:56:11 +0000 Subject: gobby: add gobby + supportlibs --- packages/gobby/gobby_0.4.1.bb | 8 ++++++++ packages/gobby/gtksourceview_1.7.2.bb | 10 ++++++++++ packages/gobby/libxml++_2.14.0.bb | 10 ++++++++++ packages/gobby/net6_1.2.2.bb | 8 +++++++- packages/gobby/net6_1.3.1.bb | 15 +++++++++++++++ packages/gobby/obby_0.4.1.bb | 19 +++++++++++++++++++ 6 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 packages/gobby/gobby_0.4.1.bb create mode 100644 packages/gobby/gtksourceview_1.7.2.bb create mode 100644 packages/gobby/libxml++_2.14.0.bb create mode 100644 packages/gobby/net6_1.3.1.bb create mode 100644 packages/gobby/obby_0.4.1.bb diff --git a/packages/gobby/gobby_0.4.1.bb b/packages/gobby/gobby_0.4.1.bb new file mode 100644 index 0000000000..8b7ccad199 --- /dev/null +++ b/packages/gobby/gobby_0.4.1.bb @@ -0,0 +1,8 @@ +LICENSE = "LGPL" +HOMEPAGE = "http://darcs.0x539.de/trac/obby/cgi-bin/trac.cgi/wiki/" +MAINTAINER = "Patrick Steiner " + +DEPENDS = "net6 gtkmm obby gtksourceview libxml++" +inherit autotools pkgconfig + +SRC_URI = "http://releases.0x539.de/gobby/gobby-${PV}.tar.gz" diff --git a/packages/gobby/gtksourceview_1.7.2.bb b/packages/gobby/gtksourceview_1.7.2.bb new file mode 100644 index 0000000000..084af175f7 --- /dev/null +++ b/packages/gobby/gtksourceview_1.7.2.bb @@ -0,0 +1,10 @@ +LICENSE = "GPL" +MAINTAINER = "Patrick Steiner " + +DEPENDS = "gtk+ libgnomeprint" + +inherit gnome pkgconfig + +do_stage() { +autotools_stage_all +} diff --git a/packages/gobby/libxml++_2.14.0.bb b/packages/gobby/libxml++_2.14.0.bb new file mode 100644 index 0000000000..6eb296c8c2 --- /dev/null +++ b/packages/gobby/libxml++_2.14.0.bb @@ -0,0 +1,10 @@ +LICENSE = "GPL" +MAINTAINER = "Patrick Steiner " + +DEPENDS = "gtk+" + +inherit gnome pkgconfig + +do_stage() { +autotools_stage_all +} diff --git a/packages/gobby/net6_1.2.2.bb b/packages/gobby/net6_1.2.2.bb index daa7e9b5b9..f9154fcca9 100644 --- a/packages/gobby/net6_1.2.2.bb +++ b/packages/gobby/net6_1.2.2.bb @@ -7,4 +7,10 @@ inherit autotools pkgconfig SRC_URI = "http://releases.0x539.de/${PN}/${P}.tar.gz" - +do_stage() { + autotools_stage_all + install -d ${STAGING_LIBDIR} + install -d ${STAGING_INCDIR}/net6 + install -m 644 inc/*.hpp ${STAGING_INCDIR}/net6 + install -m 755 .libs/*so* ${STAGING_LIBDIR}/ +} diff --git a/packages/gobby/net6_1.3.1.bb b/packages/gobby/net6_1.3.1.bb new file mode 100644 index 0000000000..3bcf8811d9 --- /dev/null +++ b/packages/gobby/net6_1.3.1.bb @@ -0,0 +1,15 @@ +LICENSE = "LGPL" +HOMEPAGE = "http://darcs.0x539.de/trac/obby/cgi-bin/trac.cgi/wiki/" +MAINTAINER = "Koen Kooi " + +DEPENDS = "libsigc++-2.0 gnutls" +inherit autotools pkgconfig + +SRC_URI = "http://releases.0x539.de/${PN}/${P}.tar.gz" + +do_stage() { + install -d ${STAGING_LIBDIR} + install -d ${STAGING_INCDIR}/net6 + install -m 644 inc/*.hpp ${STAGING_INCDIR}/net6 + install -m 755 .libs/*so* ${STAGING_LIBDIR}/ +} diff --git a/packages/gobby/obby_0.4.1.bb b/packages/gobby/obby_0.4.1.bb new file mode 100644 index 0000000000..adf3a72571 --- /dev/null +++ b/packages/gobby/obby_0.4.1.bb @@ -0,0 +1,19 @@ +LICENSE = "LGPL" +HOMEPAGE = "http://darcs.0x539.de/trac/obby/cgi-bin/trac.cgi/wiki/" +MAINTAINER = "Patrick Steiner " + +DEPENDS = "net6 gtkmm gmp" +inherit autotools pkgconfig + +SRC_URI = "http://releases.0x539.de/obby/obby-${PV}.tar.gz" + +EXTRA_OECONF += " --with-libgmp-prefix=${STAGING_LIBDIR}" + +do_stage() { + install -d ${STAGING_LIBDIR} + install -d ${STAGING_INCDIR}/obby + install -d ${STAGING_INCDIR}/obby/serialise + install -m 644 inc/*.hpp ${STAGING_INCDIR}/obby + install -m 644 inc/serialise/*.hpp ${STAGING_INCDIR}/obby/serialise + install -m 755 src/.libs/*so* ${STAGING_LIBDIR}/ +} -- cgit v1.2.3 From 81b3eb8ab803587093d026de254dd40082913035 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 28 Aug 2006 21:00:03 +0000 Subject: libxml++: move to correct subdir --- packages/gobby/libxml++_2.14.0.bb | 10 ---------- packages/libxml/libxml++_2.14.0.bb | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) delete mode 100644 packages/gobby/libxml++_2.14.0.bb create mode 100644 packages/libxml/libxml++_2.14.0.bb diff --git a/packages/gobby/libxml++_2.14.0.bb b/packages/gobby/libxml++_2.14.0.bb deleted file mode 100644 index 6eb296c8c2..0000000000 --- a/packages/gobby/libxml++_2.14.0.bb +++ /dev/null @@ -1,10 +0,0 @@ -LICENSE = "GPL" -MAINTAINER = "Patrick Steiner " - -DEPENDS = "gtk+" - -inherit gnome pkgconfig - -do_stage() { -autotools_stage_all -} diff --git a/packages/libxml/libxml++_2.14.0.bb b/packages/libxml/libxml++_2.14.0.bb new file mode 100644 index 0000000000..6eb296c8c2 --- /dev/null +++ b/packages/libxml/libxml++_2.14.0.bb @@ -0,0 +1,10 @@ +LICENSE = "GPL" +MAINTAINER = "Patrick Steiner " + +DEPENDS = "gtk+" + +inherit gnome pkgconfig + +do_stage() { +autotools_stage_all +} -- cgit v1.2.3 From e46b6716b194488fc8eef47d29b1129806c3bd46 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 28 Aug 2006 21:01:31 +0000 Subject: omap5912.conf: Update required module list to match kernel config from omap5912osk_defconfig in kernel source. --- conf/machine/omap5912osk.conf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/conf/machine/omap5912osk.conf b/conf/machine/omap5912osk.conf index 04178166d9..cf9e96ce19 100644 --- a/conf/machine/omap5912osk.conf +++ b/conf/machine/omap5912osk.conf @@ -21,8 +21,8 @@ SERIAL_CONSOLE ?= "115200 ttyS0" EXTRA_IMAGECMD_jffs2 = "--pad --little-endian --eraseblock=0x40000" # PCMCIA Modules -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-pcmcia-core kernel-module-pcmcia" -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-omap-cf" +#BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-pcmcia-core kernel-module-pcmcia" +#BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-omap-cf" # IDE modules BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-ide-cs kernel-module-ide-disk" BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-ide-core" @@ -31,9 +31,9 @@ BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-msdos kernel-module-nls-iso8859-1" BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-nls-cp437 kernel-module-nls-base" BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-vfat kernel-module-fat" # Video er LCD Driver -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-fb kernel-module-cfbimgblt kernel-module-cfbcopyarea" -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-cfbfillrect kernel-module-omapfb kernel-module-softcursor" +#BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-fb kernel-module-cfbimgblt kernel-module-cfbcopyarea" +#BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-cfbfillrect kernel-module-omapfb kernel-module-softcursor" # DSP Interface -BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-dsp" +#BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-dsp" include conf/machine/include/tune-arm926ejs.conf -- cgit v1.2.3 From fe776c91a3769970513c59e4106b7e675fe92f0e Mon Sep 17 00:00:00 2001 From: Stelios Koroneos Date: Mon, 28 Aug 2006 21:15:31 +0000 Subject: New package for libesmtp 1.0.4 Closes bug #1346 --- packages/libesmtp/libesmtp_1.0.4.bb | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/libesmtp/libesmtp_1.0.4.bb b/packages/libesmtp/libesmtp_1.0.4.bb index 294333c579..baff0d8931 100644 --- a/packages/libesmtp/libesmtp_1.0.4.bb +++ b/packages/libesmtp/libesmtp_1.0.4.bb @@ -1,19 +1,22 @@ -DESCRIPTION = "LibESMTP is a library to manage posting \ -(or submission of) electronic mail using SMTP to a \ -preconfigured Mail Transport Agent (MTA) such as Exim or PostFix." LICENSE = "GPL" -SECTION = "libs/network" +SECTION = "libs" DEPENDS = "openssl" -PR = "r1" +DESCRIPTION = "LibESMTP is a library to manage posting \ +(or submission of) electronic mail using SMTP to a \ +preconfigured Mail Transport Agent (MTA) such as Exim." +FILES_libesmtp_append = " ${libdir}/esmtp-plugins" SRC_URI = "http://www.stafford.uklinux.net/libesmtp/libesmtp-${PV}.tar.bz2" -inherit autotools binconfig +inherit autotools EXTRA_OECONF = "--disable-isoc --with-openssl=${STAGING_LIBDIR}/.." -do_stage() { - autotools_stage_all -} +do_stage () { + oe_libinstall -a -so libesmtp ${STAGING_LIBDIR} -FILES_libesmtp_append = " ${libdir}/esmtp-plugins" + install -d ${STAGING_INCDIR} + install -m 644 auth-client.h ${STAGING_INCDIR} + install -m 644 auth-plugin.h ${STAGING_INCDIR} + install -m 644 libesmtp.h ${STAGING_INCDIR} +} -- cgit v1.2.3 From fef0035db932ea55dc0783e175aa6ee359bffb84 Mon Sep 17 00:00:00 2001 From: Stelios Koroneos Date: Mon, 28 Aug 2006 21:31:21 +0000 Subject: esmtp 0.5.1 patch for uclibc --- packages/esmtp/esmtp-0.5.1/.mtn2git_empty | 0 packages/esmtp/esmtp-0.5.1/configure.patch | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 packages/esmtp/esmtp-0.5.1/.mtn2git_empty create mode 100644 packages/esmtp/esmtp-0.5.1/configure.patch diff --git a/packages/esmtp/esmtp-0.5.1/.mtn2git_empty b/packages/esmtp/esmtp-0.5.1/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/esmtp/esmtp-0.5.1/configure.patch b/packages/esmtp/esmtp-0.5.1/configure.patch new file mode 100644 index 0000000000..ef6244a935 --- /dev/null +++ b/packages/esmtp/esmtp-0.5.1/configure.patch @@ -0,0 +1,22 @@ +--- /orig-configure.ac 2005-02-15 18:43:40.000000000 +0200 ++++ /configure.ac 2006-08-19 13:05:52.000000000 +0300 +@@ -29,16 +29,9 @@ + LDFLAGS="$LDFLAGS -L$with_libesmtp/lib" + AC_CHECK_HEADER(libesmtp.h, ,[AC_MSG_ERROR([libesmtp.h not found in $with_libesmtp])]) + fi +-AC_MSG_CHECKING(for libESMTP) +-if libesmtp-config --version > /dev/null 2>&1 +-then +- AC_MSG_RESULT(yes) +- CFLAGS="$CFLAGS `libesmtp-config --cflags`" +- LIBS="$LIBS `libesmtp-config --libs`" +-else +- AC_MSG_RESULT(no) +- AC_MSG_ERROR(libESMTP library not found) +-fi ++ ++ CFLAGS="$CFLAGS" ++ LIBS="$LIBS -lesmtp -lssl -lcrypto -ldl" + + AC_SUBST( sysconfdir ) + -- cgit v1.2.3 From 6346207824a03f13f4915618729814f30ecc816f Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 28 Aug 2006 21:54:46 +0000 Subject: scummvm 0.9.0: enable all engines to get rid of undefined symbols* * and be able to play more games --- packages/scummvm/scummvm_0.9.0.bb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/scummvm/scummvm_0.9.0.bb b/packages/scummvm/scummvm_0.9.0.bb index 7cfd6ac0d0..9719ee200e 100644 --- a/packages/scummvm/scummvm_0.9.0.bb +++ b/packages/scummvm/scummvm_0.9.0.bb @@ -2,6 +2,11 @@ require scummvm.inc DEPENDS = "virtual/libsdl libmad libvorbis libogg zlib libmpeg2" SRC_URI += "file://sh3-arch-0.9.0+.patch;patch=1" +EXTRA_OECONF += "--enable-lure \ + --enable-agi \ + --enable-cine \ + " + do_compile() { oe_runmake CC="${CC}" CXX="${CXX}" CFLAGS="${CFLAGS}" CXXFLAGS="${CXXFLAGS}" LDFLAGS="${LDFLAGS} -lmpeg2" \ DEFINES="-DUNIX -DSCUMM_NEED_ALIGNMENT -DUSE_MAD -DUSE_VORBIS -DUSE_ZLIB -DUSE_MPEG2" -- cgit v1.2.3 From 12cd6ac5f22b09038542f066633367bf60513bed Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 28 Aug 2006 22:04:47 +0000 Subject: scummvm.inc: remove Troll technology --- packages/scummvm/scummvm.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/scummvm/scummvm.inc b/packages/scummvm/scummvm.inc index e39397be06..313b8e3d51 100644 --- a/packages/scummvm/scummvm.inc +++ b/packages/scummvm/scummvm.inc @@ -1,4 +1,4 @@ -DESCRIPTION = "Virtual Machine for LucasArts Adventures for Qt/Embedded based palmtop environments w/ SDL." +DESCRIPTION = "Virtual Machine for LucasArts Adventures" SECTION = "games" PRIORITY = "optional" LICENSE = "GPL" -- cgit v1.2.3 From 4696a83bd6aad71f56e72afb10fbb5488d337266 Mon Sep 17 00:00:00 2001 From: Carsten Schneider Date: Tue, 29 Aug 2006 06:25:15 +0000 Subject: zsafe: added 2.1.3 - close #1370 applied changes from 26de4ae1a5a4cc78e31a35514476c8f83392d32e (.oz354x) through 704acabcb81bc6c3e644c6c18bb730c30a8d882c --- packages/zsafe/.mtn2git_empty | 0 packages/zsafe/zsafe_2.1.3.bb | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 packages/zsafe/.mtn2git_empty create mode 100644 packages/zsafe/zsafe_2.1.3.bb diff --git a/packages/zsafe/.mtn2git_empty b/packages/zsafe/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/zsafe/zsafe_2.1.3.bb b/packages/zsafe/zsafe_2.1.3.bb new file mode 100644 index 0000000000..f4b9d0c5ab --- /dev/null +++ b/packages/zsafe/zsafe_2.1.3.bb @@ -0,0 +1,27 @@ +DESCRIPTION = "Password manager" +SECTION = "opie/applications" +PRIORITY = "optional" +MAINTAINER = "Carsten Schneider " +LICENSE = "GPL" +RCONFLICTS = "opie-zsafe" +APPNAME = "zsafe" +APPTYPE = "binary" +APPDESKTOP = "${WORKDIR}" +SRC_URI = "http://z-soft.z-portal.info/zsafe/zsafe_2.1.3.tgz" +S = "${WORKDIR}" + +inherit opie + +QMAKE_PROFILES = "zsafe.pro" + +export OE_QMAKE_LINK="${CXX}" + +#FILES bin/zsafe apps/Applications/zsafe.desktop pics/zsafe/zsafe.png + +FILES_zsafe = "zsafe" + +do_install() { + install -d ${D}${palmtopdir}/pics/${APPNAME}/ + install -m 0644 ${WORKDIR}/pics/${APPNAME}/*.xpm ${D}${palmtopdir}/pics/${APPNAME}/ + install -m 0644 ${WORKDIR}/zsafe.png ${D}${palmtopdir}/pics/ +} -- cgit v1.2.3 From 309314ba7cc3c5947c897d61c06309bdb9c9efa7 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Tue, 29 Aug 2006 06:34:52 +0000 Subject: libxine: add libpng to DEPENDS - close #1357 --- packages/libxine/libxine-fb_1.0.bb | 2 +- packages/libxine/libxine-x11_1.0.bb | 2 +- packages/libxine/libxine_1.1.0.bb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/libxine/libxine-fb_1.0.bb b/packages/libxine/libxine-fb_1.0.bb index fd9baee512..d0f58303fa 100644 --- a/packages/libxine/libxine-fb_1.0.bb +++ b/packages/libxine/libxine-fb_1.0.bb @@ -3,7 +3,7 @@ This version is configured for the usage with framebuffer based environments" SECTION = "libs" PRIORITY = "optional" LICENSE = "GPL" -DEPENDS = "zlib libogg tremor libmad libmodplug" +DEPENDS = "zlib libogg tremor libmad libmodplug libpng" PROVIDES = "virtual/libxine" PR = "r1" diff --git a/packages/libxine/libxine-x11_1.0.bb b/packages/libxine/libxine-x11_1.0.bb index dfce1d32ec..692c55cf9f 100644 --- a/packages/libxine/libxine-x11_1.0.bb +++ b/packages/libxine/libxine-x11_1.0.bb @@ -3,7 +3,7 @@ This version is configued for the usage with X11" SECTION = "libs" PRIORITY = "optional" LICENSE = "GPL" -DEPENDS = "zlib libogg libvorbis tremor libmad libmodplug esound-gpe virtual/libx11 libxext" +DEPENDS = "zlib libogg libvorbis tremor libmad libmodplug esound-gpe virtual/libx11 libxext libpng" PROVIDES = "virtual/libxine" PR = "r0" diff --git a/packages/libxine/libxine_1.1.0.bb b/packages/libxine/libxine_1.1.0.bb index 8f172f23a7..b4ab063063 100644 --- a/packages/libxine/libxine_1.1.0.bb +++ b/packages/libxine/libxine_1.1.0.bb @@ -3,7 +3,7 @@ This version is configued for the usage with X11" SECTION = "libs" PRIORITY = "optional" LICENSE = "GPL" -DEPENDS = "zlib libogg libvorbis tremor libmad libmodplug esound-gpe virtual/libx11 libxext" +DEPENDS = "zlib libogg libvorbis tremor libmad libmodplug esound-gpe virtual/libx11 libxext libpng" PROVIDES = "virtual/libxine" PR = "r0" -- cgit v1.2.3 From b0915887c4f041c2004f5fcb286eba5b42e02d84 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 29 Aug 2006 08:58:56 +0000 Subject: samba: fix -dbg packaging for 3.0.14a and 3.0.20 --- packages/samba/samba_3.0.14a.bb | 3 ++- packages/samba/samba_3.0.20.bb | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/samba/samba_3.0.14a.bb b/packages/samba/samba_3.0.14a.bb index 4daf98bfc8..ddd08c80b7 100644 --- a/packages/samba/samba_3.0.14a.bb +++ b/packages/samba/samba_3.0.14a.bb @@ -1,4 +1,4 @@ -PR = "r14" +PR = "r15" SRC_URI = "http://us2.samba.org/samba/ftp/stable/samba-${PV}.tar.gz \ file://configure.patch;patch=1 \ @@ -49,6 +49,7 @@ PACKAGES =+ "swat" FILES_swat = "${sbindir}/swat ${datadir}/swat ${libdir}/*.msg" FILES_${PN} += "${libdir}/vfs/*.so ${libdir}/charset/*.so ${libdir}/*.dat" +FILES_${PN}-dbg += "${libdir}/vfs/.debug/*.so ${libdir}/charset/.debug/*.so" # # bug fix for samba.inc: FILES_cifs-doc = "${mandir}/man8/mount.cifs.8" diff --git a/packages/samba/samba_3.0.20.bb b/packages/samba/samba_3.0.20.bb index 7f5bd3dffa..088c167cb1 100644 --- a/packages/samba/samba_3.0.20.bb +++ b/packages/samba/samba_3.0.20.bb @@ -1,4 +1,4 @@ -PR = "r4" +PR = "r5" SRC_URI = "http://us2.samba.org/samba/ftp/stable/samba-${PV}.tar.gz \ file://configure.patch;patch=1 \ @@ -49,6 +49,7 @@ PACKAGES =+ "swat" FILES_swat = "${sbindir}/swat ${datadir}/swat ${libdir}/*.msg" FILES_${PN} += "${libdir}/vfs/*.so ${libdir}/charset/*.so ${libdir}/*.dat" +FILES_${PN}-dbg += "${libdir}/vfs/.debug/*.so ${libdir}/charset/.debug/*.so" # # bug fix for samba.inc: FILES_cifs-doc = "${mandir}/man8/mount.cifs.8" -- cgit v1.2.3 From 1ed378b6258e7df0a51fe7082ceded34581245a9 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Tue, 29 Aug 2006 08:59:28 +0000 Subject: libesmtp: correct damage done by previous commit --- packages/libesmtp/libesmtp_1.0.4.bb | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/packages/libesmtp/libesmtp_1.0.4.bb b/packages/libesmtp/libesmtp_1.0.4.bb index baff0d8931..294333c579 100644 --- a/packages/libesmtp/libesmtp_1.0.4.bb +++ b/packages/libesmtp/libesmtp_1.0.4.bb @@ -1,22 +1,19 @@ -LICENSE = "GPL" -SECTION = "libs" -DEPENDS = "openssl" DESCRIPTION = "LibESMTP is a library to manage posting \ (or submission of) electronic mail using SMTP to a \ -preconfigured Mail Transport Agent (MTA) such as Exim." -FILES_libesmtp_append = " ${libdir}/esmtp-plugins" +preconfigured Mail Transport Agent (MTA) such as Exim or PostFix." +LICENSE = "GPL" +SECTION = "libs/network" +DEPENDS = "openssl" +PR = "r1" SRC_URI = "http://www.stafford.uklinux.net/libesmtp/libesmtp-${PV}.tar.bz2" -inherit autotools +inherit autotools binconfig EXTRA_OECONF = "--disable-isoc --with-openssl=${STAGING_LIBDIR}/.." -do_stage () { - oe_libinstall -a -so libesmtp ${STAGING_LIBDIR} - - install -d ${STAGING_INCDIR} - install -m 644 auth-client.h ${STAGING_INCDIR} - install -m 644 auth-plugin.h ${STAGING_INCDIR} - install -m 644 libesmtp.h ${STAGING_INCDIR} +do_stage() { + autotools_stage_all } + +FILES_libesmtp_append = " ${libdir}/esmtp-plugins" -- cgit v1.2.3 From bb4b9a807fd9ff8a3dc37e26303c805a358f3085 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 29 Aug 2006 09:03:15 +0000 Subject: linux-ezx: update to ezx7 and add 2 patches for gcc4-isms --- packages/linux/linux-ezx/pxa-serial-gcc4.diff | 11 ++++++++ packages/linux/linux-ezx/sa1100-rtc-gcc4.diff | 11 ++++++++ packages/linux/linux-ezx_2.6.16.13.bb | 36 ++++++--------------------- 3 files changed, 29 insertions(+), 29 deletions(-) create mode 100644 packages/linux/linux-ezx/pxa-serial-gcc4.diff create mode 100644 packages/linux/linux-ezx/sa1100-rtc-gcc4.diff diff --git a/packages/linux/linux-ezx/pxa-serial-gcc4.diff b/packages/linux/linux-ezx/pxa-serial-gcc4.diff new file mode 100644 index 0000000000..7f827965e9 --- /dev/null +++ b/packages/linux/linux-ezx/pxa-serial-gcc4.diff @@ -0,0 +1,11 @@ +--- /tmp/pxa.c 2006-08-29 10:51:57.000000000 +0200 ++++ linux-2.6.16/drivers/serial/pxa.c 2006-08-29 10:52:38.545780000 +0200 +@@ -241,7 +241,7 @@ + /* + * This handles the interrupt from one port. + */ +-static inline irqreturn_t ++inline irqreturn_t + serial_pxa_irq(int irq, void *dev_id, struct pt_regs *regs) + { + struct uart_pxa_port *up = (struct uart_pxa_port *)dev_id; diff --git a/packages/linux/linux-ezx/sa1100-rtc-gcc4.diff b/packages/linux/linux-ezx/sa1100-rtc-gcc4.diff new file mode 100644 index 0000000000..6fd54ece3a --- /dev/null +++ b/packages/linux/linux-ezx/sa1100-rtc-gcc4.diff @@ -0,0 +1,11 @@ +--- /tmp/sa1100-rtc.c 2006-08-29 10:51:48.000000000 +0200 ++++ linux-2.6.16/drivers/char/sa1100-rtc.c 2006-08-29 10:52:14.995780000 +0200 +@@ -126,7 +126,7 @@ + tval->tm_mday = days + 1; + } + +-static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) ++irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) + { + unsigned int rtsr = RTSR; + diff --git a/packages/linux/linux-ezx_2.6.16.13.bb b/packages/linux/linux-ezx_2.6.16.13.bb index f326321217..6da8a32a21 100644 --- a/packages/linux/linux-ezx_2.6.16.13.bb +++ b/packages/linux/linux-ezx_2.6.16.13.bb @@ -5,8 +5,8 @@ HOMEPAGE = "http://www.openezx.org" MAINTAINER = "Michael 'Mickey' Lauer " LICENSE = "GPL" DEPENDS += "quilt-native" -EZX = "ezx6" -PR = "${EZX}-r13" +EZX = "ezx7" +PR = "${EZX}-r0" inherit kernel @@ -17,33 +17,12 @@ RPSRC = "http://www.rpsys.net/openzaurus/patches/archive" # source and patches # SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.16.tar.bz2 \ - http://people.openezx.org/stefan/patches/patches-2.6.16-2.6.16.13-exz6-symlink-fix.tar.bz2 \ + http://people.openezx.org/stefan/patches/patches-2.6.16-2.6.16.13-ezx7.tar.bz2 \ \ - ${RPSRC}/led_core-r15.patch;patch=1 \ - ${RPSRC}/led_triggers-r14.patch;patch=1 \ - ${RPSRC}/led_trig_timer-r8.patch;patch=1 \ - ${RPSRC}/led_trig_sharpsl_pm-r5.patch;patch=1 \ - ${RPSRC}/led_zaurus-r10.patch;patch=1 \ - ${RPSRC}/led_locomo-r7.patch;patch=1 \ - ${RPSRC}/led_ixp4xx-r2.patch;patch=1 \ - ${RPSRC}/led_tosa-r5.patch;patch=1 \ - ${RPSRC}/led_ide-r6.patch;patch=1 \ - ${RPSRC}/led_nand-r3.patch;patch=1 \ - ${RPSRC}/corgi_bl_cleanup-r3.patch;patch=1 \ - ${RPSRC}/corgi_bl_generic-r3.patch;patch=1 \ - ${RPSRC}/backlight_sysfs_fix-r0.patch;patch=1 \ - \ - file://touchscreen-fix-r0.patch;patch=1 \ - \ - file://e680-disable-boomer-HACK.patch;patch=1 \ - \ - file://e680-leds-r1.patch;patch=1 \ - file://a780-leds-r0.patch;patch=1 \ - file://ezx-backlight-r1.patch;patch=1 \ - file://e680-fix-keypad.patch;patch=1 \ - file://pxakbd-fix-directkeys.patch;patch=1 \ - \ - file://logo_linux_clut224.ppm \ + file://sa1100-rtc-gcc4.diff;patch=1 \ + file://pxa-serial-gcc4.diff;patch=1 \ + \ + file://logo_linux_clut224.ppm \ file://defconfig-a780 \ file://defconfig-e680" S = "${WORKDIR}/linux-2.6.16" @@ -79,7 +58,6 @@ do_ezxpatch() { } do_configure() { - mv ${S}/.config harald.config install -m 0644 ${WORKDIR}/logo_linux_clut224.ppm drivers/video/logo/logo_linux_clut224.ppm if [ ! -e ${WORKDIR}/defconfig-${MACHINE} ]; then -- cgit v1.2.3 From 821b2af1e0caa9464fd030dfc34841607e5863be Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 29 Aug 2006 09:13:31 +0000 Subject: linux-ezx: remove outdated patches --- packages/linux/linux-ezx/a780-leds-r0.patch | 185 ---------- .../linux/linux-ezx/e680-disable-boomer-HACK.patch | 16 - packages/linux/linux-ezx/e680-fix-keypad.patch | 152 --------- packages/linux/linux-ezx/e680-leds-r0.patch | 336 ------------------ packages/linux/linux-ezx/e680-leds-r1.patch | 374 --------------------- packages/linux/linux-ezx/ezx-backlight-r0.patch | 212 ------------ packages/linux/linux-ezx/ezx-backlight-r1.patch | 277 --------------- .../linux/linux-ezx/pxakbd-fix-directkeys.patch | 83 ----- packages/linux/linux-ezx/touchscreen-fix-r0.patch | 19 -- 9 files changed, 1654 deletions(-) delete mode 100644 packages/linux/linux-ezx/a780-leds-r0.patch delete mode 100644 packages/linux/linux-ezx/e680-disable-boomer-HACK.patch delete mode 100644 packages/linux/linux-ezx/e680-fix-keypad.patch delete mode 100644 packages/linux/linux-ezx/e680-leds-r0.patch delete mode 100644 packages/linux/linux-ezx/e680-leds-r1.patch delete mode 100644 packages/linux/linux-ezx/ezx-backlight-r0.patch delete mode 100644 packages/linux/linux-ezx/ezx-backlight-r1.patch delete mode 100644 packages/linux/linux-ezx/pxakbd-fix-directkeys.patch delete mode 100644 packages/linux/linux-ezx/touchscreen-fix-r0.patch diff --git a/packages/linux/linux-ezx/a780-leds-r0.patch b/packages/linux/linux-ezx/a780-leds-r0.patch deleted file mode 100644 index 31fdfc635b..0000000000 --- a/packages/linux/linux-ezx/a780-leds-r0.patch +++ /dev/null @@ -1,185 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- linux-2.6.16/drivers/leds/Kconfig~a780-leds-r0.patch 2006-06-05 18:05:32.000000000 +0200 -+++ linux-2.6.16/drivers/leds/Kconfig 2006-06-05 18:05:32.000000000 +0200 -@@ -66,6 +66,13 @@ - This options enables support for the LEDs on the - Motorola E680(i) GSM Phone. - -+config LEDS_A780 -+ tristate "LED Support for the Motorola A780 GSM Phone" -+ depends LEDS_CLASS && PXA_EZX_A780 -+ help -+ This option enables support for the LEDs on the -+ Motorola A780 GSM Phone. -+ - config LEDS_TRIGGER_TIMER - tristate "LED Timer Trigger" - depends LEDS_TRIGGERS ---- linux-2.6.16/drivers/leds/Makefile~a780-leds-r0.patch 2006-06-05 18:05:32.000000000 +0200 -+++ linux-2.6.16/drivers/leds/Makefile 2006-06-05 18:05:32.000000000 +0200 -@@ -11,6 +11,7 @@ - obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o - obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o - obj-$(CONFIG_LEDS_E680) += leds-e680.o -+obj-$(CONFIG_LEDS_A780) += leds-a780.o - - # LED Triggers - obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o ---- linux-2.6.16/arch/arm/mach-pxa/ezx.c~a780-leds-r0.patch 2006-06-05 18:05:32.000000000 +0200 -+++ linux-2.6.16/arch/arm/mach-pxa/ezx.c 2006-06-05 18:05:32.000000000 +0200 -@@ -367,6 +367,15 @@ - }; - #endif - -+#ifdef CONFIG_PXA_EZX_A780 -+/* -+ * A780 LEDs -+ */ -+static struct platform_device a780led_device = { -+ .name = "a780-led", -+ .id = -1, -+}; -+#endif - - /* keyboard */ - -@@ -780,6 +789,9 @@ - #ifdef CONFIG_PXA_EZX_E680 - &e680led_device, - #endif -+#ifdef CONFIG_PXA_EZX_A780 -+ &a780led_device, -+#endif - }; - - static void __init ---- /dev/null 2006-06-05 13:59:28.329930680 +0200 -+++ linux-2.6.16/drivers/leds/leds-a780.c 2006-06-05 18:27:13.000000000 +0200 -@@ -0,0 +1,123 @@ -+/* -+ * EZX Platform LED Driver for the Motorola A780 GSM Phone -+ * -+ * Copyright 2006 Vanille-Media -+ * -+ * Author: Michael Lauer -+ * -+ * Based on keylight.c by Motorola and leds-corgi.c by Richard Purdie -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static void a780led_main_set(struct led_classdev *led_cdev, enum led_brightness value) -+{ -+ if ( value > 31 ) value = 31; -+ printk( KERN_DEBUG "a780led_main_set: %d\n", value ); -+ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL0, value & 0x01); -+ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL1, value & 0x02); -+ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL2, value & 0x04); -+ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL3, value & 0x08); -+ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL4, value & 0x10); -+} -+ -+static void a780led_aux_set(struct led_classdev *led_cdev, enum led_brightness value) -+{ -+ if ( value > 31 ) value = 31; -+ printk( KERN_DEBUG "a780led_aux_set: %d\n", value ); -+ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL0, value & 0x01); -+ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL1, value & 0x02); -+ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL2, value & 0x04); -+ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL3, value & 0x08); -+ ezx_pcap_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL4, value & 0x10); -+} -+ -+static struct led_classdev a780_main_led = { -+ .name = "a780:main", -+ .default_trigger = "none", -+ .brightness_set = a780led_main_set, -+}; -+ -+static struct led_classdev a780_aux_led = { -+ .name = "a780:aux", -+ .default_trigger = "none", -+ .brightness_set = a780led_aux_set, -+}; -+ -+#ifdef CONFIG_PM -+static int a780led_suspend(struct platform_device *dev, pm_message_t state) -+{ -+ led_classdev_suspend(&a780_main_led); -+ led_classdev_suspend(&a780_aux_led); -+ return 0; -+} -+ -+static int a780led_resume(struct platform_device *dev) -+{ -+ led_classdev_resume(&a780_main_led); -+ led_classdev_resume(&a780_aux_led); -+ return 0; -+} -+#endif -+ -+static int a780led_probe(struct platform_device *pdev) -+{ -+ int ret; -+ -+ ret = led_classdev_register(&pdev->dev, &a780_main_led); -+ if (ret < 0) -+ return ret; -+ -+ ret = led_classdev_register(&pdev->dev, &a780_aux_led); -+ if (ret < 0) -+ led_classdev_unregister(&a780_main_led); -+ -+ return ret; -+} -+ -+static int a780led_remove(struct platform_device *pdev) -+{ -+ led_classdev_unregister(&a780_main_led); -+ led_classdev_unregister(&a780_aux_led); -+ return 0; -+} -+ -+static struct platform_driver a780led_driver = { -+ .probe = a780led_probe, -+ .remove = a780led_remove, -+#ifdef CONFIG_PM -+ .suspend = a780led_suspend, -+ .resume = a780led_resume, -+#endif -+ .driver = { -+ .name = "a780-led", -+ }, -+}; -+ -+static int __init a780led_init(void) -+{ -+ return platform_driver_register(&a780led_driver); -+} -+ -+static void __exit a780led_exit(void) -+{ -+ a780led_main_set( &a780_main_led, 0 ); -+ a780led_aux_set( &a780_aux_led, 0 ); -+ platform_driver_unregister(&a780led_driver); -+} -+ -+module_init(a780led_init); -+module_exit(a780led_exit); -+ -+MODULE_AUTHOR("Michael Lauer "); -+MODULE_DESCRIPTION("Motorola A780 LED driver"); -+MODULE_LICENSE("GPL"); diff --git a/packages/linux/linux-ezx/e680-disable-boomer-HACK.patch b/packages/linux/linux-ezx/e680-disable-boomer-HACK.patch deleted file mode 100644 index a0d953ddfb..0000000000 --- a/packages/linux/linux-ezx/e680-disable-boomer-HACK.patch +++ /dev/null @@ -1,16 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- linux-2.6.16/drivers/i2c/chips/Makefile~e680-disable-boomer 2006-05-31 18:52:44.000000000 +0200 -+++ linux-2.6.16/drivers/i2c/chips/Makefile 2006-05-31 18:56:38.000000000 +0200 -@@ -17,7 +17,7 @@ - - obj-$(CONFIG_I2C_ADCM2700) += e680_camera.o - obj-$(CONFIG_I2C_A780_CAMERA) += a780_camera.o --obj-$(CONFIG_PXA_EZX_E680) += boomer.o -+//obj-$(CONFIG_PXA_EZX_E680) += boomer.o - - ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) - EXTRA_CFLAGS += -DDEBUG diff --git a/packages/linux/linux-ezx/e680-fix-keypad.patch b/packages/linux/linux-ezx/e680-fix-keypad.patch deleted file mode 100644 index ca06052803..0000000000 --- a/packages/linux/linux-ezx/e680-fix-keypad.patch +++ /dev/null @@ -1,152 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- linux-2.6.16/arch/arm/mach-pxa/ezx.c~e680-fix-keypad.patch 2006-06-11 00:47:33.000000000 +0200 -+++ linux-2.6.16/arch/arm/mach-pxa/ezx.c 2006-06-12 16:13:28.000000000 +0200 -@@ -341,71 +341,25 @@ - }; - #endif - --/* keyboard */ -- --#if defined(CONFIG_PXA_EZX_V700) --#error "kbd matrix still needs to be converted to new row/col layout" --static unsigned char ezx_keycode[] = { -- /* col 0 */ -- KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, -- KEYPAD_POUND, KEY_0, KEY_9, 0, -- /* col 1 */ -- KEY_2, KEY_4, KEY_6, KEY_8, -- KEY_7, KEYPAD_SLEFT, KEYPAD_SRIGHT, 0, -- /* col 2 */ -- KEY_MENU, KEY_1, KEY_3, KEY_5, -- KEY_KPASTERISK, KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, -- /* col 3 */ -- KEY_CAMERA, KEYPAD_CLEAR, KEYPAD_CARRIER, KEYPAD_ACTIVATE, -- KEYPAD_SEND, KEYPAD_SMART, KEYPAD_VAVR, 0, --}; --static unsigned char ezx_direct_keycode[] = { -- KEYPAD_NONE, -- KEYPAD_NONE, -- KEYPAD_NONE, -- KEYPAD_NONE, -- KEYPAD_NONE, -- KEYPAD_NONE, --}; --#elif defined(CONFIG_PXA_EZX_E680_P4A) --#error "kbd matrix still needs to be converted to new row/col layout" --static unsigned char ezx_keycode[] = { -- /* col 0 */ -- KEY_UP, KEY_DOWN, KEY_LEFT, 0, 0, 0, 0, 0, -- /* col 1 */ -- KEY_RIGHT, KEY_CENTER, KEY_HOME, 0, 0, 0, 0, 0, -- /* col 2 */ -- KEYPAD_GAME_R, 0, KEYPAD_GAME_L, 0, 0, 0, 0, 0, -- /* col 3 */ -- KEY_A, KEY_B, 0, 0, 0, 0, 0, 0, --}; --static unsigned char ezx_direct_keycode[] = { -- KEY_CAMERA, -- KEYPAD_NONE, -- KEYPAD_NONE, -- KEYPAD_NONE, -- KEY_POWER, -- KEYPAD_NONE, --}; --#elif defined(CONFIG_PXA_EZX_E680) --#error "kbd matrix still needs to be converted to new row/col layout" -+/* -+ * PXA Keyboard -+ */ -+#if defined(CONFIG_PXA_EZX_E680) - static unsigned char ezx_keycode[] = { -- /* col 0 */ -- KEY_UP, KEY_DOWN, 0, 0, 0, 0, 0, 0, -- /* col 1 */ -- KEY_RIGHT, KEY_LEFT, 0, 0, 0, 0, 0, 0, -- /* col 2 */ -- 0, KEYPAD_GAME_R, 0, 0, 0, 0, 0, 0, -- /* col 3 */ -- KEYPAD_HOME, KEYPAD_GAME_L, KEYPAD_CENTER, 0, 0, 0, 0, 0, -+ /* row 0 */ -+ KEY_UP, KEY_RIGHT, KEY_RESERVED, KEY_PHONE, -+ /* row 1 */ -+ KEY_DOWN, KEY_LEFT, KEY_VOLUMEUP, KEY_VOLUMEDOWN, -+ /* row 2 */ -+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_KPENTER, - }; - static unsigned char ezx_direct_keycode[] = { - KEY_CAMERA, -- KEYPAD_NONE, -- KEYPAD_NONE, -- KEYPAD_A, -+ KEY_RESERVED, -+ KEY_RESERVED, -+ KEY_HOME, - KEY_POWER, -- KEYPAD_B, -+ KEY_MENU, - }; - #elif defined(CONFIG_PXA_EZX_A780) - static unsigned char ezx_keycode[] = { -@@ -424,22 +378,12 @@ - KEY_CAMERA, - }; - #else --#error "no EZX subarchitecture defined !?!" -+#error "no EZX subarchitecture defined" - #endif - - static int ezx_kbd_init(void) - { --#if defined(CONFIG_PXA_EZX_E680_P4A) -- pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, VR Key */ -- pxa_gpio_mode(97 | GPIO_ALT_FN_1_IN); /* KP_DKIN<4>, power key */ -- pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -- pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -- pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -- pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -- pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -- pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -- pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ --#elif defined(CONFIG_PXA_EZX_E680) -+#if defined(CONFIG_PXA_EZX_E680) - pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, VR Key */ - pxa_gpio_mode(96 | GPIO_ALT_FN_1_IN); /* KP_DKIN<3>, GAME_A */ - pxa_gpio_mode(97 | GPIO_ALT_FN_1_IN); /* KP_DKIN<4>, power key */ -@@ -455,7 +399,7 @@ - GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); - GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); - PGSR3 |= GPIO_bit(GPIO_TC_MM_EN); --#elif defined (CONFIG_PXA_EZX_A780) -+#elif defined(CONFIG_PXA_EZX_A780) - pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, voice_rec */ - pxa_gpio_mode(97 | GPIO_ALT_FN_3_IN); /* KP_MKIN<3> */ - pxa_gpio_mode(98 | GPIO_ALT_FN_3_IN); /* KP_MKIN<4> */ -@@ -476,10 +420,7 @@ - .scan_interval = HZ/40, - .matrix = { - .keycode = &ezx_keycode, --#if defined(CONFIG_ARCH_EXZ_E680_P4A) -- .cols = 4, -- .rows = 3, --#elif defined(CONFIG_PXA_EZX_E680) -+#if defined(CONFIG_PXA_EZX_E680) - .cols = 4, - .rows = 3, - #elif defined(CONFIG_PXA_EZX_A780) -@@ -489,10 +430,8 @@ - }, - .direct = { - .keycode = &ezx_direct_keycode, --#if defined(CONFIG_PXA_EZX_E680_P4A) -- .num = 4, --#elif defined(CONFIG_PXA_EZX_E680) -- .num = 5, -+#if defined(CONFIG_PXA_EZX_E680) -+ .num = 6, - #elif defined(CONFIG_PXA_EZX_A780) - .num = 1, - #endif diff --git a/packages/linux/linux-ezx/e680-leds-r0.patch b/packages/linux/linux-ezx/e680-leds-r0.patch deleted file mode 100644 index b6d2413dc1..0000000000 --- a/packages/linux/linux-ezx/e680-leds-r0.patch +++ /dev/null @@ -1,336 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- linux-2.6.16/arch/arm/mach-pxa/ezx.c~led_ezx-r0.patch 2006-06-03 15:17:43.000000000 +0200 -+++ linux-2.6.16/arch/arm/mach-pxa/ezx.c 2006-06-05 15:14:59.000000000 +0200 -@@ -357,6 +357,17 @@ - .num_resources = ARRAY_SIZE(ezx_backlight_resources), - }; - -+#ifdef CONFIG_PXA_EZX_E680 -+/* -+ * E680 LEDs -+ */ -+static struct platform_device e680led_device = { -+ .name = "e680-led", -+ .id = -1, -+}; -+#endif -+ -+ - /* keyboard */ - - #if defined(CONFIG_PXA_EZX_V700) -@@ -770,6 +781,9 @@ - - static struct platform_device *devices[] __initdata = { - &ezx_bp_device, -+#ifdef CONFIG_PXA_EZX_E680 -+ &e680led_device, -+#endif - }; - - static void __init ---- linux-2.6.16/drivers/leds/Kconfig~led_ezx-r0.patch 2006-06-03 15:17:47.000000000 +0200 -+++ linux-2.6.16/drivers/leds/Kconfig 2006-06-03 15:17:47.000000000 +0200 -@@ -59,6 +59,13 @@ - This option enables support for the LEDs on Sharp Zaurus - SL-6000 series. - -+config LEDS_E680 -+ tristate "LED Support for the Motorola E680(i) GSM Phone" -+ depends LEDS_CLASS && PXA_EZX_E680 -+ help -+ This options enables support for the LEDs on the -+ Motorola E680(i) GSM Phone. -+ - config LEDS_TRIGGER_TIMER - tristate "LED Timer Trigger" - depends LEDS_TRIGGERS ---- linux-2.6.16/drivers/leds/Makefile~led_ezx-r0.patch 2006-06-03 15:17:47.000000000 +0200 -+++ linux-2.6.16/drivers/leds/Makefile 2006-06-03 15:17:47.000000000 +0200 -@@ -10,7 +10,8 @@ - obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o - obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o - obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o -+obj-$(CONFIG_LEDS_E680) += leds-e680.o - - # LED Triggers - obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o --obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o -\ Kein Zeilenumbruch am Dateiende. -+obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o ---- /dev/null 2006-06-05 13:59:28.329930680 +0200 -+++ linux-2.6.16/drivers/leds/leds-e680.c 2006-06-05 15:11:42.000000000 +0200 -@@ -0,0 +1,269 @@ -+/* -+ * EZX Platform LED Driver for the Motorola E680(i) GSM Phone -+ * -+ * Copyright 2006 Vanille-Media -+ * -+ * Author: Michael Lauer -+ * -+ * Based on the Motorola 2.4 leds-e680.c and leds-corgi.c by Richard Purdie -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+//FIXME this belongs to somewhere else, please -+// adjust when ssp_pcap.h reached its final destination -+#include "../misc/ezx/ssp_pcap.h" -+ -+//FIXME move defines to header file -+#define IND_CNTL_R_BUL 46 -+#define IND_CNTL_G_BUL 47 -+#define SSP_PCAP_LED_MASK 0x000fffe0 -+#define SSP_PCAP_LED_SHIFT 5 -+ -+static enum led_brightness old_red; -+static enum led_brightness old_green; -+static enum led_brightness old_blue; -+ -+typedef struct { -+ unsigned char ind_GPIO_red; /*Indicator Red control GPIO 46: 0 active, 1 disactive*/ -+ unsigned char ind_GPIO_green; /*Indicator Green control GPIO 47: 0 active, 1 disactive*/ -+ unsigned char pcap_LEDR_en; /*pcap LEDR_EN bit value: 1 =Red LED(&Green) sink circuit enabled*/ -+ unsigned char pcap_LEDG_en; /*pcap LEDG_EN bit value:1 =Green(->Blue)LED sink circuit enabled*/ -+ unsigned char pcap_LEDR_CTRL; /* 4bits Sets the timing for the red(&Green) LED sink circuit*/ -+ unsigned char pcap_LEDG_CTRL; /* 4bits Sets the timing for the GREEN (->Blue) LED sink circuit*/ -+ unsigned char pcap_LEDR_I; /* 2 bits 00 3mA,01 4mA, 10 5mA, 11 9mA, sets the pulsed current level for LEDR*/ -+ unsigned char pcap_LEDG_I; /* 2 bits 00 3mA,01 4mA, 10 5mA, 11 9mA, sets the pulsed current level for LEDG*/ -+ unsigned char pcap_SKIP_on; /*1=The ON timing sequence defined by LEDx_CTRL is executed on every other cycle*/ -+} PCAP2_LED_REGISTER_VALUE; -+ -+const PCAP2_LED_REGISTER_VALUE led_register_value[]= -+{ -+ /* on/off pulsepower timing intensity */ -+ {0x1,0x1, 0x0,0x0, 0x0,0x0, 0x0,0x0,0x0}, /* OFF */ -+ {0x0,0x1, 0x1,0x0, 0xc,0x0, 0x1,0x0,0x0}, /* RED */ -+ {0x1,0x0, 0x1,0x0, 0xc,0x0, 0x1,0x0,0x0}, /* GREEN */ -+ {0x0,0x0, 0x1,0x0, 0xc,0x0, 0x1,0x0,0x0}, /* ORANGE = RED + GREEN */ -+ {0x1,0x1, 0x0,0x1, 0x0,0xc, 0x0,0x0,0x0}, /* BLUE */ -+ {0x0,0x1, 0x1,0x1, 0xc,0xc, 0x1,0x0,0x0}, /* LIGHT_RED = RED + BLUE */ -+ {0x1,0x0, 0x1,0x1, 0xc,0xc, 0x1,0x0,0x0}, /* LIGHT_GREEN = GREEN + BLUE */ -+ {0x0,0x0, 0x1,0x1, 0xc,0xc, 0x1,0x0,0x0}, /* WHITE = RED + GREEN + BLUE */ -+}; -+ -+static void e680led_led_set( enum led_brightness red, enum led_brightness green, enum led_brightness blue ) -+{ -+ printk( KERN_DEBUG "e680led_led_set: red=%d, green=%d, blue=%d", red, green, blue ); -+ unsigned int tempValue = 0; -+ unsigned int value = 0; -+ unsigned int stateIndex = 0; -+ unsigned char gpio_red, gpio_green, ledr_en, ledg_en, ledr_ctrl, ledg_ctrl, ledr_i, ledg_i,skip; -+ -+ stateIndex = ( ( blue << 2 ) | ( green << 1 ) | ( red ) ) & 0x7; -+ printk( KERN_DEBUG "LED stateIndex is %d", stateIndex ); -+ gpio_red = led_register_value[stateIndex].ind_GPIO_red & 0x1; -+ gpio_green = led_register_value[stateIndex].ind_GPIO_green & 0x1; -+ ledr_en = led_register_value[stateIndex].pcap_LEDR_en & 0x1; -+ ledg_en = led_register_value[stateIndex].pcap_LEDG_en & 0x1; -+ ledr_ctrl = led_register_value[stateIndex].pcap_LEDR_CTRL & 0xf; -+ ledg_ctrl = led_register_value[stateIndex].pcap_LEDG_CTRL & 0xf; -+ ledr_i = led_register_value[stateIndex].pcap_LEDR_I & 0x3; -+ ledg_i = led_register_value[stateIndex].pcap_LEDG_I & 0x3; -+ skip = led_register_value[stateIndex].pcap_SKIP_on & 0x1; -+ -+ /* disable LEDs */ -+ if( ezx_pcap_read(SSP_PCAP_ADJ_PERIPH_REGISTER,&tempValue) != SSP_PCAP_SUCCESS ) -+ { -+ printk( KERN_WARNING "LED PCAP Read Failed\n" ); -+ return; -+ } -+ tempValue &= (~SSP_PCAP_LED_MASK); -+ if( ezx_pcap_write(SSP_PCAP_ADJ_PERIPH_REGISTER,tempValue) != SSP_PCAP_SUCCESS ) -+ { -+ printk( KERN_WARNING "LED PCAP Write Failed (Clear Data)\n" ); -+ return; -+ } -+ -+ /* configure GPIOs as output */ -+ pxa_gpio_mode(IND_CNTL_R_BUL | GPIO_OUT); -+ pxa_gpio_mode(IND_CNTL_G_BUL | GPIO_OUT); -+ -+ //FIXME: Simplify this logic -+ if ( (gpio_green && gpio_red) ) -+ { -+ /*Disable Red & Green signal*/ -+ set_GPIO(IND_CNTL_R_BUL); /*IND_CNTL_R_BUL Low active*/ -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) | GPIO_bit(IND_CNTL_R_BUL); -+ -+ clr_GPIO(IND_CNTL_G_BUL); /*IND_CNTL_G_BUL High active*/ -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) & (~GPIO_bit(IND_CNTL_G_BUL)); -+ -+ printk( KERN_DEBUG "LED GPIO Green & Red Disable\n"); -+ } else if ( gpio_green && !gpio_red ) -+ { -+ /*Green Disable, Red Enable*/ -+ clr_GPIO(IND_CNTL_R_BUL); -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) & (~GPIO_bit(IND_CNTL_R_BUL)); -+ -+ clr_GPIO(IND_CNTL_G_BUL); -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) & (~GPIO_bit(IND_CNTL_G_BUL)); -+ -+ printk( KERN_DEBUG "LED GPIO Green Disable, Red Enable\n"); -+ } else if (gpio_red && !gpio_green ) -+ { -+ /*Red Disable, Green Enable*/ -+ set_GPIO(IND_CNTL_R_BUL); -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) | GPIO_bit(IND_CNTL_R_BUL); -+ -+ set_GPIO(IND_CNTL_G_BUL); -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) | GPIO_bit(IND_CNTL_G_BUL); -+ printk( KERN_DEBUG "LED GPIO Red Disable, Green Enable"); -+ }else -+ { -+ /*Red & Green enable*/ -+ clr_GPIO(IND_CNTL_R_BUL); -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) & (~GPIO_bit(IND_CNTL_R_BUL)); -+ -+ set_GPIO(IND_CNTL_G_BUL); -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) | GPIO_bit(IND_CNTL_G_BUL); -+ printk( KERN_DEBUG "LED GPIO Red & Green Enable\n"); -+ } -+ -+ /* Write PCAP LED Peripheral Control Register*/ -+ value = ( ledr_en | (ledg_en <<1) | (ledr_ctrl <<2) | (ledg_ctrl <<6) | -+ (ledr_i << 10) | (ledg_i <<12) | (skip <<14) ) & 0x7fff; -+ tempValue |= (value <dev, &e680_red_led); -+ if (ret < 0) -+ return ret; -+ -+ ret = led_classdev_register(&pdev->dev, &e680_green_led); -+ if (ret < 0) -+ led_classdev_unregister(&e680_red_led); -+ -+ ret = led_classdev_register(&pdev->dev, &e680_blue_led); -+ if (ret < 0) { -+ led_classdev_unregister(&e680_red_led); -+ led_classdev_unregister(&e680_green_led); -+ } -+ return ret; -+} -+ -+static int e680led_remove(struct platform_device *pdev) -+{ -+ led_classdev_unregister(&e680_red_led); -+ led_classdev_unregister(&e680_green_led); -+ led_classdev_unregister(&e680_blue_led); -+ return 0; -+} -+ -+static struct platform_driver e680led_driver = { -+ .probe = e680led_probe, -+ .remove = e680led_remove, -+#ifdef CONFIG_PM -+ .suspend = e680led_suspend, -+ .resume = e680led_resume, -+#endif -+ .driver = { -+ .name = "e680-led", -+ }, -+}; -+ -+static int __init e680led_init(void) -+{ -+ return platform_driver_register(&e680led_driver); -+} -+ -+static void __exit e680led_exit(void) -+{ -+ e680led_led_set( 0, 0, 0 ); -+ platform_driver_unregister(&e680led_driver); -+} -+ -+module_init(e680led_init); -+module_exit(e680led_exit); -+ -+MODULE_AUTHOR("Michael Lauer "); -+MODULE_DESCRIPTION("Motorola E680 LED driver"); -+MODULE_LICENSE("GPL"); diff --git a/packages/linux/linux-ezx/e680-leds-r1.patch b/packages/linux/linux-ezx/e680-leds-r1.patch deleted file mode 100644 index abbab2937d..0000000000 --- a/packages/linux/linux-ezx/e680-leds-r1.patch +++ /dev/null @@ -1,374 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- linux-2.6.16/arch/arm/mach-pxa/ezx.c~e680-leds-r0.patch 2006-06-06 17:14:06.000000000 +0200 -+++ linux-2.6.16/arch/arm/mach-pxa/ezx.c 2006-06-06 17:23:14.000000000 +0200 -@@ -357,6 +357,17 @@ - .num_resources = ARRAY_SIZE(ezx_backlight_resources), - }; - -+#ifdef CONFIG_PXA_EZX_E680 -+/* -+ * E680 LEDs -+ */ -+static struct platform_device e680led_device = { -+ .name = "e680-led", -+ .id = -1, -+}; -+#endif -+ -+ - /* keyboard */ - - #if defined(CONFIG_PXA_EZX_V700) -@@ -766,6 +777,9 @@ - - static struct platform_device *devices[] __initdata = { - &ezx_bp_device, -+#ifdef CONFIG_PXA_EZX_E680 -+ &e680led_device, -+#endif - }; - - static void __init ---- linux-2.6.16/drivers/leds/Kconfig~e680-leds-r0.patch 2006-06-06 17:14:05.000000000 +0200 -+++ linux-2.6.16/drivers/leds/Kconfig 2006-06-06 17:23:14.000000000 +0200 -@@ -59,6 +59,13 @@ - This option enables support for the LEDs on Sharp Zaurus - SL-6000 series. - -+config LEDS_E680 -+ tristate "LED Support for the Motorola E680(i) GSM Phone" -+ depends LEDS_CLASS && PXA_EZX_E680 -+ help -+ This options enables support for the LEDs on the -+ Motorola E680(i) GSM Phone. -+ - config LEDS_TRIGGER_TIMER - tristate "LED Timer Trigger" - depends LEDS_TRIGGERS ---- linux-2.6.16/drivers/leds/Makefile~e680-leds-r0.patch 2006-06-06 17:14:05.000000000 +0200 -+++ linux-2.6.16/drivers/leds/Makefile 2006-06-06 17:23:14.000000000 +0200 -@@ -10,7 +10,8 @@ - obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o - obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o - obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o -+obj-$(CONFIG_LEDS_E680) += leds-e680.o - - # LED Triggers - obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o --obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o -\ Kein Zeilenumbruch am Dateiende. -+obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o ---- /dev/null 2006-06-06 16:58:36.577045136 +0200 -+++ linux-2.6.16/drivers/leds/leds-e680.c 2006-06-06 17:55:46.000000000 +0200 -@@ -0,0 +1,307 @@ -+/* -+ * EZX Platform LED Driver for the Motorola E680(i) GSM Phone -+ * -+ * Copyright 2006 Vanille-Media -+ * -+ * Author: Michael Lauer -+ * -+ * Based on the Motorola 2.4 leds-e680.c and leds-corgi.c by Richard Purdie -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+//FIXME move defines to a common header file -+#define IND_CNTL_R_BUL 46 -+#define IND_CNTL_G_BUL 47 -+#define SSP_PCAP_LED_MASK 0x000fffe0 -+#define SSP_PCAP_LED_SHIFT 5 -+#define GPIO_TC_MM_EN 99 -+ -+static enum led_brightness old_red; -+static enum led_brightness old_green; -+static enum led_brightness old_blue; -+ -+typedef struct { -+ unsigned char ind_GPIO_red; /*Indicator Red control GPIO 46: 0 active, 1 disactive*/ -+ unsigned char ind_GPIO_green; /*Indicator Green control GPIO 47: 0 active, 1 disactive*/ -+ unsigned char pcap_LEDR_en; /*pcap LEDR_EN bit value: 1 =Red LED(&Green) sink circuit enabled*/ -+ unsigned char pcap_LEDG_en; /*pcap LEDG_EN bit value:1 =Green(->Blue)LED sink circuit enabled*/ -+ unsigned char pcap_LEDR_CTRL; /* 4bits Sets the timing for the red(&Green) LED sink circuit*/ -+ unsigned char pcap_LEDG_CTRL; /* 4bits Sets the timing for the GREEN (->Blue) LED sink circuit*/ -+ unsigned char pcap_LEDR_I; /* 2 bits 00 3mA,01 4mA, 10 5mA, 11 9mA, sets the pulsed current level for LEDR*/ -+ unsigned char pcap_LEDG_I; /* 2 bits 00 3mA,01 4mA, 10 5mA, 11 9mA, sets the pulsed current level for LEDG*/ -+ unsigned char pcap_SKIP_on; /*1=The ON timing sequence defined by LEDx_CTRL is executed on every other cycle*/ -+} PCAP2_LED_REGISTER_VALUE; -+ -+const PCAP2_LED_REGISTER_VALUE led_register_value[]= -+{ -+ /* on/off pulsepower timing intensity */ -+ {0x1,0x1, 0x0,0x0, 0x0,0x0, 0x0,0x0,0x0}, /* OFF */ -+ {0x0,0x1, 0x1,0x0, 0xc,0x0, 0x1,0x0,0x0}, /* RED */ -+ {0x1,0x0, 0x1,0x0, 0xc,0x0, 0x1,0x0,0x0}, /* GREEN */ -+ {0x0,0x0, 0x1,0x0, 0xc,0x0, 0x1,0x0,0x0}, /* ORANGE = RED + GREEN */ -+ {0x1,0x1, 0x0,0x1, 0x0,0xc, 0x0,0x0,0x0}, /* BLUE */ -+ {0x0,0x1, 0x1,0x1, 0xc,0xc, 0x1,0x0,0x0}, /* LIGHT_RED = RED + BLUE */ -+ {0x1,0x0, 0x1,0x1, 0xc,0xc, 0x1,0x0,0x0}, /* LIGHT_GREEN = GREEN + BLUE */ -+ {0x0,0x0, 0x1,0x1, 0xc,0xc, 0x1,0x0,0x0}, /* WHITE = RED + GREEN + BLUE */ -+}; -+ -+static void e680led_led_set( enum led_brightness red, enum led_brightness green, enum led_brightness blue ) -+{ -+ printk( KERN_DEBUG "e680led_led_set: red=%d, green=%d, blue=%d", red, green, blue ); -+ unsigned int tempValue = 0; -+ unsigned int value = 0; -+ unsigned int stateIndex = 0; -+ unsigned char gpio_red, gpio_green, ledr_en, ledg_en, ledr_ctrl, ledg_ctrl, ledr_i, ledg_i,skip; -+ -+ stateIndex = ( ( blue << 2 ) | ( green << 1 ) | ( red ) ) & 0x7; -+ printk( KERN_DEBUG "LED stateIndex is %d", stateIndex ); -+ gpio_red = led_register_value[stateIndex].ind_GPIO_red & 0x1; -+ gpio_green = led_register_value[stateIndex].ind_GPIO_green & 0x1; -+ ledr_en = led_register_value[stateIndex].pcap_LEDR_en & 0x1; -+ ledg_en = led_register_value[stateIndex].pcap_LEDG_en & 0x1; -+ ledr_ctrl = led_register_value[stateIndex].pcap_LEDR_CTRL & 0xf; -+ ledg_ctrl = led_register_value[stateIndex].pcap_LEDG_CTRL & 0xf; -+ ledr_i = led_register_value[stateIndex].pcap_LEDR_I & 0x3; -+ ledg_i = led_register_value[stateIndex].pcap_LEDG_I & 0x3; -+ skip = led_register_value[stateIndex].pcap_SKIP_on & 0x1; -+ -+ /* disable LEDs */ -+ if( ezx_pcap_read(SSP_PCAP_ADJ_PERIPH_REGISTER,&tempValue) != SSP_PCAP_SUCCESS ) -+ { -+ printk( KERN_WARNING "LED PCAP Read Failed\n" ); -+ return; -+ } -+ tempValue &= (~SSP_PCAP_LED_MASK); -+ if( ezx_pcap_write(SSP_PCAP_ADJ_PERIPH_REGISTER,tempValue) != SSP_PCAP_SUCCESS ) -+ { -+ printk( KERN_WARNING "LED PCAP Write Failed (Clear Data)\n" ); -+ return; -+ } -+ -+ /* configure GPIOs as output */ -+ pxa_gpio_mode(IND_CNTL_R_BUL | GPIO_OUT); -+ pxa_gpio_mode(IND_CNTL_G_BUL | GPIO_OUT); -+ -+ //FIXME: Simplify this logic -+ if ( (gpio_green && gpio_red) ) -+ { -+ /*Disable Red & Green signal*/ -+ set_GPIO(IND_CNTL_R_BUL); /*IND_CNTL_R_BUL Low active*/ -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) | GPIO_bit(IND_CNTL_R_BUL); -+ -+ clr_GPIO(IND_CNTL_G_BUL); /*IND_CNTL_G_BUL High active*/ -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) & (~GPIO_bit(IND_CNTL_G_BUL)); -+ -+ printk( KERN_DEBUG "LED GPIO Green & Red Disable\n"); -+ } else if ( gpio_green && !gpio_red ) -+ { -+ /*Green Disable, Red Enable*/ -+ clr_GPIO(IND_CNTL_R_BUL); -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) & (~GPIO_bit(IND_CNTL_R_BUL)); -+ -+ clr_GPIO(IND_CNTL_G_BUL); -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) & (~GPIO_bit(IND_CNTL_G_BUL)); -+ -+ printk( KERN_DEBUG "LED GPIO Green Disable, Red Enable\n"); -+ } else if (gpio_red && !gpio_green ) -+ { -+ /*Red Disable, Green Enable*/ -+ set_GPIO(IND_CNTL_R_BUL); -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) | GPIO_bit(IND_CNTL_R_BUL); -+ -+ set_GPIO(IND_CNTL_G_BUL); -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) | GPIO_bit(IND_CNTL_G_BUL); -+ printk( KERN_DEBUG "LED GPIO Red Disable, Green Enable"); -+ }else -+ { -+ /*Red & Green enable*/ -+ clr_GPIO(IND_CNTL_R_BUL); -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) & (~GPIO_bit(IND_CNTL_R_BUL)); -+ -+ set_GPIO(IND_CNTL_G_BUL); -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) | GPIO_bit(IND_CNTL_G_BUL); -+ printk( KERN_DEBUG "LED GPIO Red & Green Enable\n"); -+ } -+ -+ /* Write PCAP LED Peripheral Control Register*/ -+ value = ( ledr_en | (ledg_en <<1) | (ledr_ctrl <<2) | (ledg_ctrl <<6) | -+ (ledr_i << 10) | (ledg_i <<12) | (skip <<14) ) & 0x7fff; -+ tempValue |= (value <dev, &e680_red_led); -+ if (ret < 0) -+ return ret; -+ -+ ret = led_classdev_register(&pdev->dev, &e680_green_led); -+ if (ret < 0) -+ led_classdev_unregister(&e680_red_led); -+ -+ ret = led_classdev_register(&pdev->dev, &e680_blue_led); -+ if (ret < 0) { -+ led_classdev_unregister(&e680_red_led); -+ led_classdev_unregister(&e680_green_led); -+ } -+ -+ ret = led_classdev_register(&pdev->dev, &e680_keypad_led); -+ if (ret < 0) { -+ led_classdev_unregister(&e680_red_led); -+ led_classdev_unregister(&e680_green_led); -+ led_classdev_unregister(&e680_blue_led); -+ } -+ return ret; -+} -+ -+static int e680led_remove(struct platform_device *pdev) -+{ -+ led_classdev_unregister(&e680_red_led); -+ led_classdev_unregister(&e680_green_led); -+ led_classdev_unregister(&e680_blue_led); -+ led_classdev_unregister(&e680_keypad_led); -+ return 0; -+} -+ -+static struct platform_driver e680led_driver = { -+ .probe = e680led_probe, -+ .remove = e680led_remove, -+#ifdef CONFIG_PM -+ .suspend = e680led_suspend, -+ .resume = e680led_resume, -+#endif -+ .driver = { -+ .name = "e680-led", -+ }, -+}; -+ -+static int __init e680led_init(void) -+{ -+ return platform_driver_register(&e680led_driver); -+} -+ -+static void __exit e680led_exit(void) -+{ -+ e680led_led_set( 0, 0, 0 ); -+ platform_driver_unregister(&e680led_driver); -+} -+ -+module_init(e680led_init); -+module_exit(e680led_exit); -+ -+MODULE_AUTHOR("Michael Lauer "); -+MODULE_DESCRIPTION("Motorola E680 LED driver"); -+MODULE_LICENSE("GPL"); diff --git a/packages/linux/linux-ezx/ezx-backlight-r0.patch b/packages/linux/linux-ezx/ezx-backlight-r0.patch deleted file mode 100644 index db917300c2..0000000000 --- a/packages/linux/linux-ezx/ezx-backlight-r0.patch +++ /dev/null @@ -1,212 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- linux-2.6.16/arch/arm/mach-pxa/ezx.c~ezx-backlight-r0.patch 2006-06-07 16:00:29.000000000 +0200 -+++ linux-2.6.16/arch/arm/mach-pxa/ezx.c 2006-06-07 16:21:09.000000000 +0200 -@@ -344,17 +344,12 @@ - .pxafb_lcd_power = &pxafb_lcd_power, - }; - -- --/* backlight for lcd */ -- --static struct resource ezx_backlight_resources[] = { --}; -- --static struct platform_device ezx_backlight_device = { -- .name = "ezx-lcd-backlight", -+/* -+ * EZX LCD Backlight -+ */ -+static struct platform_device ezxbacklight_device = { -+ .name = "ezx-bl", - .id = -1, -- .resource = ezx_backlight_resources, -- .num_resources = ARRAY_SIZE(ezx_backlight_resources), - }; - - #ifdef CONFIG_PXA_EZX_E680 -@@ -786,6 +781,7 @@ - - static struct platform_device *devices[] __initdata = { - &ezx_bp_device, -+ &ezxbacklight_device, - #ifdef CONFIG_PXA_EZX_E680 - &e680led_device, - #endif ---- linux-2.6.16/drivers/video/backlight/Kconfig~ezx-backlight-r0.patch 2006-06-07 16:00:28.000000000 +0200 -+++ linux-2.6.16/drivers/video/backlight/Kconfig 2006-06-07 16:00:30.000000000 +0200 -@@ -58,3 +58,12 @@ - If you have a HP Jornada 680, say y to enable the - backlight driver. - -+config BACKLIGHT_EZX -+ tristate "Motorola EXZ Backlight Driver (A780/E680/E680i)" -+ depends on BACKLIGHT_DEVICE && PXA_EZX -+ default y -+ help -+ If you have a Motorola A780 or E680(i), say y to enable the -+ backlight driver. -+ -+ ---- linux-2.6.16/drivers/video/backlight/Makefile~ezx-backlight-r0.patch 2006-03-20 06:53:29.000000000 +0100 -+++ linux-2.6.16/drivers/video/backlight/Makefile 2006-06-07 16:00:30.000000000 +0200 -@@ -5,3 +5,5 @@ - obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o - obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o - obj-$(CONFIG_SHARP_LOCOMO) += locomolcd.o -+obj-$(CONFIG_BACKLIGHT_EZX) += ezx_bl.o -+ ---- /dev/null 2006-06-07 15:54:31.503752232 +0200 -+++ linux-2.6.16/drivers/video/backlight/ezx_bl.c 2006-06-07 16:51:14.000000000 +0200 -@@ -0,0 +1,148 @@ -+/* -+ * Backlight Driver for Motorola A780 and E680(i) GSM Phones. -+ * -+ * Copyright 2006 Vanille Media -+ * -+ * Author: Michael Lauer -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define EZX_MAX_INTENSITY 50 -+#define EZX_DEFAULT_INTENSITY 25 -+ -+static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; -+static struct backlight_properties ezxbl_data; -+static struct backlight_device *ezx_backlight_device; -+static int current_intensity; -+ -+static int ezx_send_intensity(struct backlight_device *bd) -+{ -+ unsigned long flags; -+ int intensity = bd->props->brightness; -+ -+ printk( KERN_DEBUG "ezx_set_intensity to %d", intensity ); -+ -+ if (bd->props->power != FB_BLANK_UNBLANK) -+ intensity = 0; -+ if (bd->props->fb_blank != FB_BLANK_UNBLANK) -+ intensity = 0; -+ -+ spin_lock_irqsave(&bl_lock, flags); -+ -+ PWM_CTRL0 = 2; /* pre-scaler */ -+ PWM_PWDUTY0 = intensity; /* duty cycle */ -+ PWM_PERVAL0 = 49; /* period */ -+ -+ if (intensity) { -+ //pxa_set_cken(CKEN0_PWM0, 1); -+ //FIXME: Set PWM0 GPIO as output -+ } else { -+ //pxa_set_cken(CKEN0_PWM0, 0); -+ //FIXME: Set PWM0 GPIO as input -+ } -+ -+ spin_unlock_irqrestore(&bl_lock, flags); -+ current_intensity = intensity; -+ return 0; -+} -+ -+static int ezx_get_intensity(struct backlight_device *bd) -+{ -+ return current_intensity; -+} -+ -+static int ezx_set_intensity(struct backlight_device *bd) -+{ -+ return ezx_send_intensity(ezx_backlight_device); -+} -+ -+#ifdef CONFIG_PM -+static int ezx_bl_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ //set suspend flag -+ ezx_set_intensity(ezx_backlight_device); -+ return 0; -+} -+ -+static int ezx_bl_resume(struct platform_device *pdev) -+{ -+ // set resume flag -+ ezx_set_intensity(ezx_backlight_device); -+ return 0; -+} -+#else -+#define ezx_bl_suspend NULL -+#define ezx_bl_resume NULL -+#endif -+ -+static struct backlight_properties ezx_bl_data = { -+ .owner = THIS_MODULE, -+ .get_brightness = ezx_get_intensity, -+ .max_brightness = EZX_MAX_INTENSITY, -+ .update_status = ezx_set_intensity, -+}; -+ -+static int __init ezx_bl_probe(struct platform_device *pdev) -+{ -+ ezx_backlight_device = backlight_device_register ("ezx-bl", -+ NULL, &ezx_bl_data); -+ if (IS_ERR (ezx_backlight_device)) -+ return PTR_ERR (ezx_backlight_device); -+ -+ //ezx_bl_data.requested_brightness = EZX_DEFAULT_INTENSITY; -+ //ezx_bl_data.requested_power = FB_BLANK_UNBLANK; -+ //ezx_set_intensity(ezx_backlight_device, ezx_bl_data.requested_brightness); -+ -+ printk("EZX Backlight Driver Initialized.\n"); -+ return 0; -+} -+ -+static int ezx_bl_remove(struct platform_device *pdev) -+{ -+ backlight_device_unregister(ezx_backlight_device); -+ -+ printk("EZX Backlight Driver Unloaded.\n"); -+ return 0; -+} -+ -+static struct platform_driver ezx_bl_driver = { -+ .probe = ezx_bl_probe, -+ .remove = ezx_bl_remove, -+ .suspend = ezx_bl_suspend, -+ .resume = ezx_bl_resume, -+ .driver = { -+ .name = "ezx-bl", -+ }, -+}; -+ -+static int __init ezx_bl_init(void) -+{ -+ return platform_driver_register(&ezx_bl_driver); -+} -+ -+static void __exit ezx_bl_exit(void) -+{ -+ platform_driver_unregister(&ezx_bl_driver); -+} -+ -+module_init(ezx_bl_init); -+module_exit(ezx_bl_exit); -+ -+MODULE_AUTHOR("Michael Lauer "); -+MODULE_DESCRIPTION("Backlight Driver for Motorola A780|E680(i)"); -+MODULE_LICENSE("GPL"); diff --git a/packages/linux/linux-ezx/ezx-backlight-r1.patch b/packages/linux/linux-ezx/ezx-backlight-r1.patch deleted file mode 100644 index a277f19344..0000000000 --- a/packages/linux/linux-ezx/ezx-backlight-r1.patch +++ /dev/null @@ -1,277 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- linux-2.6.16/arch/arm/mach-pxa/ezx.c~ezx-backlight-r1.patch 2006-06-08 19:33:36.000000000 +0200 -+++ linux-2.6.16/arch/arm/mach-pxa/ezx.c 2006-06-08 19:33:37.000000000 +0200 -@@ -274,34 +274,9 @@ - .udc_command = ezx_udc_command, - }; - --/* pxafb */ -- --#define BKLIGHT_PRESCALE 2 --#define BKLIGHT_PERIOD 49 --#define DEFAULT_DUTYCYCLE 25 --#define MAX_DUTYCYCLE (BKLIGHT_PERIOD+1) --#define MIN_DUTYCYCLE 0 -- --static void pxafb_backlight_power(int on) --{ -- if (on) { -- CKEN |= CKEN0_PWM0; -- PWM_CTRL0 = BKLIGHT_PRESCALE; -- PWM_PERVAL0 = BKLIGHT_PERIOD; -- PWM_PWDUTY0 = DEFAULT_DUTYCYCLE; -- -- GPDR0 |= 0x00010000; //PWM0 is GPIO16 -- pxa_gpio_mode(GPIO16_PWM0_MD); -- } else { -- PWM_PWDUTY0 = 0; -- GAFR0_U &= 0xfffffffc; -- GPDR0 &= 0xfffeffff; /* set gpio16 (pwm0) as input */ -- CKEN &= ~CKEN0_PWM0; -- PWM_PWDUTY0 = MIN_DUTYCYCLE; -- } --} -- --//#define mdelay(x) udelay((x)*1000) -+/* -+ * EZX PXA Framebuffer -+ */ - - static void pxafb_lcd_power(int on) - { -@@ -326,35 +301,24 @@ - .xres = 240, - .yres = 320, - .bpp = 16, -- - .hsync_len = 10, - .left_margin = 20, - .right_margin = 10, -- - .vsync_len = 2, - .upper_margin = 3, - .lower_margin = 2, -- - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, -- - .lccr0 = 0x002008F8, - .lccr3 = 0x0430FF09, -- -- .pxafb_backlight_power = &pxafb_backlight_power, -- .pxafb_lcd_power = &pxafb_lcd_power, --}; -- -- --/* backlight for lcd */ -- --static struct resource ezx_backlight_resources[] = { -+ .pxafb_lcd_power= &pxafb_lcd_power, - }; - --static struct platform_device ezx_backlight_device = { -- .name = "ezx-lcd-backlight", -+/* -+ * EZX LCD Backlight -+ */ -+static struct platform_device ezxbacklight_device = { -+ .name = "ezx-bl", - .id = -1, -- .resource = ezx_backlight_resources, -- .num_resources = ARRAY_SIZE(ezx_backlight_resources), - }; - - #ifdef CONFIG_PXA_EZX_E680 -@@ -786,6 +750,7 @@ - - static struct platform_device *devices[] __initdata = { - &ezx_bp_device, -+ &ezxbacklight_device, - #ifdef CONFIG_PXA_EZX_E680 - &e680led_device, - #endif ---- linux-2.6.16/drivers/video/backlight/Kconfig~ezx-backlight-r1.patch 2006-06-08 19:33:34.000000000 +0200 -+++ linux-2.6.16/drivers/video/backlight/Kconfig 2006-06-08 19:33:37.000000000 +0200 -@@ -58,3 +58,12 @@ - If you have a HP Jornada 680, say y to enable the - backlight driver. - -+config BACKLIGHT_EZX -+ tristate "Motorola EXZ Backlight Driver (A780/E680/E680i)" -+ depends on BACKLIGHT_DEVICE && PXA_EZX -+ default y -+ help -+ If you have a Motorola A780 or E680(i), say y to enable the -+ backlight driver. -+ -+ ---- linux-2.6.16/drivers/video/backlight/Makefile~ezx-backlight-r1.patch 2006-03-20 06:53:29.000000000 +0100 -+++ linux-2.6.16/drivers/video/backlight/Makefile 2006-06-08 19:33:37.000000000 +0200 -@@ -5,3 +5,5 @@ - obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o - obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o - obj-$(CONFIG_SHARP_LOCOMO) += locomolcd.o -+obj-$(CONFIG_BACKLIGHT_EZX) += ezx_bl.o -+ ---- /dev/null 2006-06-08 19:04:31.354926880 +0200 -+++ linux-2.6.16/drivers/video/backlight/ezx_bl.c 2006-06-08 20:52:33.000000000 +0200 -@@ -0,0 +1,156 @@ -+/* -+ * Backlight Driver for Motorola A780 and E680(i) GSM Phones. -+ * -+ * Copyright 2006 Vanille Media -+ * -+ * Author: Michael Lauer -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define EZX_MIN_INTENSITY 00 -+#define EZX_MAX_INTENSITY 50 -+#define EZX_DEFAULT_INTENSITY 25 -+ -+static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; -+static struct backlight_device *ezx_backlight_device; -+static int last_intensity; -+ -+static int ezxbl_send_intensity(struct backlight_device *bd) -+{ -+ unsigned long flags; -+ int intensity = bd->props->brightness; -+ -+ printk( KERN_DEBUG "ezx_set_intensity to %d\n", intensity ); -+ -+ if (bd->props->power != FB_BLANK_UNBLANK) -+ intensity = 0; -+ if (bd->props->fb_blank != FB_BLANK_UNBLANK) -+ intensity = 0; -+ -+ spin_lock_irqsave(&bl_lock, flags); -+ -+ printk( KERN_DEBUG "backlight last intensity was %d, new intensity is %d\n", last_intensity, intensity ); -+ -+ if ( !last_intensity && intensity ) { -+ printk( KERN_DEBUG "backlight power ON\n" ); -+ PWM_CTRL0 = 2; /* pre-scaler */ -+ PWM_PWDUTY0 = intensity; /* duty cycle */ -+ PWM_PERVAL0 = 49; /* period */ -+ pxa_gpio_mode(GPIO16_PWM0_MD); /* set GPIO16 as alternate function + output */ -+ pxa_set_cken(CKEN0_PWM0, 1); /* clock enable */ -+ } -+ else if ( last_intensity && !intensity ) { -+ printk( KERN_DEBUG "backlight power OFF\n" ); -+ PWM_PWDUTY0 = 0; -+ GAFR0_U &= 0xFFFFFFFC; /* ??? */ -+ pxa_set_cken(CKEN0_PWM0, 0); /* clock disable */ -+ pxa_gpio_mode(GPIO16_PWM0); /* set GPIO16 as input */ -+ } else if ( last_intensity && intensity ) { -+ printk( KERN_DEBUG "backlight adjusting duty cycle\n" ); -+ PWM_PWDUTY0 = intensity; /* duty cycle */ -+ } -+ spin_unlock_irqrestore(&bl_lock, flags); -+ last_intensity = intensity; -+ return 0; -+} -+ -+static int ezxbl_get_intensity(struct backlight_device *bd) -+{ -+ return last_intensity; -+} -+ -+static int ezxbl_set_intensity(struct backlight_device *bd) -+{ -+ return ezxbl_send_intensity(ezx_backlight_device); -+} -+ -+#ifdef CONFIG_PM -+static int ezxbl_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ //set suspend flag -+ ezxbl_set_intensity(ezx_backlight_device); -+ return 0; -+} -+ -+static int ezxbl_resume(struct platform_device *pdev) -+{ -+ // set resume flag -+ ezxbl_set_intensity(ezx_backlight_device); -+ return 0; -+} -+#else -+#define ezxbl_suspend NULL -+#define ezxbl_resume NULL -+#endif -+ -+static struct backlight_properties ezxbl_data = { -+ .owner = THIS_MODULE, -+ .get_brightness = ezxbl_get_intensity, -+ .max_brightness = EZX_MAX_INTENSITY, -+ .update_status = ezxbl_set_intensity, -+}; -+ -+static int __init ezxbl_probe(struct platform_device *pdev) -+{ -+ ezx_backlight_device = backlight_device_register ("ezx-bl", -+ NULL, &ezxbl_data); -+ if (IS_ERR (ezx_backlight_device)) -+ return PTR_ERR (ezx_backlight_device); -+ -+ ezxbl_data.power = FB_BLANK_UNBLANK; -+ ezxbl_data.brightness = EZX_DEFAULT_INTENSITY; -+ ezxbl_set_intensity(ezx_backlight_device); -+ -+ printk("EZX Backlight Driver Initialized.\n"); -+ return 0; -+} -+ -+static int ezxbl_remove(struct platform_device *pdev) -+{ -+ backlight_device_unregister(ezx_backlight_device); -+ -+ printk("EZX Backlight Driver Unloaded.\n"); -+ return 0; -+} -+ -+static struct platform_driver ezxbl_driver = { -+ .probe = ezxbl_probe, -+ .remove = ezxbl_remove, -+ .suspend = ezxbl_suspend, -+ .resume = ezxbl_resume, -+ .driver = { -+ .name = "ezx-bl", -+ }, -+}; -+ -+static int __init ezxbl_init(void) -+{ -+ return platform_driver_register(&ezxbl_driver); -+} -+ -+static void __exit ezxbl_exit(void) -+{ -+ platform_driver_unregister(&ezxbl_driver); -+} -+ -+module_init(ezxbl_init); -+module_exit(ezxbl_exit); -+ -+MODULE_AUTHOR("Michael Lauer "); -+MODULE_DESCRIPTION("Backlight Driver for Motorola A780|E680(i)"); -+MODULE_LICENSE("GPL"); diff --git a/packages/linux/linux-ezx/pxakbd-fix-directkeys.patch b/packages/linux/linux-ezx/pxakbd-fix-directkeys.patch deleted file mode 100644 index 1dedb981bd..0000000000 --- a/packages/linux/linux-ezx/pxakbd-fix-directkeys.patch +++ /dev/null @@ -1,83 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- linux-2.6.16/drivers/input/keyboard/pxakbd.c~pxakbd-fix-directkeys.patch 2006-06-11 00:47:25.000000000 +0200 -+++ linux-2.6.16/drivers/input/keyboard/pxakbd.c 2006-06-12 16:10:03.000000000 +0200 -@@ -20,7 +20,7 @@ - #include - #include - --#if 0 -+#if 1 - #define DEBUGP(x, args ...) printk(x, ## args) - #else - #define DEBUGP(x, args ...) -@@ -44,8 +44,7 @@ - unsigned int i; - int num_pressed = 0; - -- kpdk = KPDK & 0x0000000f; -- -+ kpdk = KPDK & 0x000000ff; - for (i = 0; i < pxakbd->pd->direct.num; i++) { - int pressed = 0; - -@@ -54,11 +53,12 @@ - num_pressed++; - DEBUGP("pxakbd: pressed: direct %u\n", i); - } -- -- input_report_key(pxakbd->input, pxakbd->pd->direct.keycode[i], -- pressed); -+ if (pxakbd->pd->direct.keycode[i] != KEY_RESERVED) { -+ DEBUGP( "pxakbd: sending to input layer: keycode = %d, pressed = %d\n", pxakbd->pd->direct.keycode[i], pressed ); -+ input_report_key(pxakbd->input, pxakbd->pd->direct.keycode[i], -+ pressed); -+ } - } -- - return num_pressed; - } - -@@ -248,16 +248,6 @@ - set_bit(pxakbd->pd->matrix.keycode[i], input_dev->keybit); - clear_bit(0, input_dev->keybit); - --#if 0 -- input_dev2->evbit[0] = ; -- input_dev2->keycode = pxakbd->pd->direct.keycode; -- input_dev2->keycodesize = sizeof(unsigned char); -- input_dev2->keycodemax = pxakbd->pd->direct.num; -- -- for (i = 0; i < input_dev2->keycodemax; i++) -- set_bit(ezxkbd->keycode[i], input_dev2->keybit); --#endif -- - if (request_irq(pxakbd->irq, pxakbd_interrupt, 0, "pxakbd", pxakbd)) { - printk(KERN_ERR "pxakbd: can't request irq %d\n", pxakbd->irq); - ret = -EBUSY; -@@ -279,6 +269,7 @@ - KPC_ME | KPC_DE | /* matrix and direct keypad enabled */ - ((pxakbd->pd->matrix.cols-1)<<23) | /* columns */ - ((pxakbd->pd->matrix.rows-1)<<26) | /* rows */ -+ ((pxakbd->pd->direct.num-1)<<6) | /* direct keys */ - KPC_MS_ALL); /* scan all columns */ - - pxa_set_cken(CKEN19_KEYPAD, 1); -@@ -375,13 +366,11 @@ - static int pxakbd_remove(struct platform_device *pdev) - { - struct pxakbd *pxakbd = platform_get_drvdata(pdev); -- -+ input_unregister_device(pxakbd->input); - platform_set_drvdata(pdev, NULL); - release_resource(pxakbd->res); - free_irq(pxakbd->irq, pxakbd); -- input_unregister_device(pxakbd->input); - kfree(pxakbd); -- - return 0; - } - diff --git a/packages/linux/linux-ezx/touchscreen-fix-r0.patch b/packages/linux/linux-ezx/touchscreen-fix-r0.patch deleted file mode 100644 index 7d19a887fc..0000000000 --- a/packages/linux/linux-ezx/touchscreen-fix-r0.patch +++ /dev/null @@ -1,19 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- linux-2.6.16/drivers/input/touchscreen/pcap_ts.c~touchscreen-fix-r0 2006-05-30 23:18:22.000000000 +0200 -+++ linux-2.6.16/drivers/input/touchscreen/pcap_ts.c 2006-05-30 23:29:34.000000000 +0200 -@@ -126,10 +126,7 @@ - if (ret < 0) - return ret; - -- if (tmp & 0x00400000) -- return -EIO; -- -- if (pcap_ts->read_state == COORDINATE) { -+ if (pcap_ts->read_state == COORDINATE && !(tmp & 0x00400000)) { - pcap_ts->x = (tmp & SSP_PCAP_ADD1_VALUE_MASK); - pcap_ts->y = (tmp & SSP_PCAP_ADD2_VALUE_MASK) - >>SSP_PCAP_ADD2_VALUE_SHIFT; -- cgit v1.2.3 From d8dcbab026f5258012dbe27bbe4f9d4b41df3762 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 29 Aug 2006 09:18:44 +0000 Subject: imagemagick: add 6.2.9, closes #336 --- packages/imagemagick/.mtn2git_empty | 0 packages/imagemagick/files/.mtn2git_empty | 0 packages/imagemagick/files/PerlMagic_MakePatch | 13 +++++++++++++ packages/imagemagick/imagemagick_6.2.9.bb | 21 +++++++++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 packages/imagemagick/.mtn2git_empty create mode 100644 packages/imagemagick/files/.mtn2git_empty create mode 100644 packages/imagemagick/files/PerlMagic_MakePatch create mode 100644 packages/imagemagick/imagemagick_6.2.9.bb diff --git a/packages/imagemagick/.mtn2git_empty b/packages/imagemagick/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/imagemagick/files/.mtn2git_empty b/packages/imagemagick/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/imagemagick/files/PerlMagic_MakePatch b/packages/imagemagick/files/PerlMagic_MakePatch new file mode 100644 index 0000000000..c87414529a --- /dev/null +++ b/packages/imagemagick/files/PerlMagic_MakePatch @@ -0,0 +1,13 @@ +Index: ImageMagick-6.2.5/PerlMagick/Makefile.PL.in +=================================================================== +--- ImageMagick-6.2.5.orig/PerlMagick/Makefile.PL.in 2005-04-21 00:27:36.000000000 +0800 ++++ ImageMagick-6.2.5/PerlMagick/Makefile.PL.in 2005-10-04 04:43:35.239036400 +0800 +@@ -72,6 +72,8 @@ + + # Use same compiler as ImageMagick + 'PERLMAINCC' => '@PERLMAINCC@', ++ 'AR' => '@AR@', ++ 'LD' => '@PERLMAINCC@', + + # Set Perl installation prefix to ImageMagick installation prefix + # 'PREFIX' => '@prefix@', diff --git a/packages/imagemagick/imagemagick_6.2.9.bb b/packages/imagemagick/imagemagick_6.2.9.bb new file mode 100644 index 0000000000..cac16329c4 --- /dev/null +++ b/packages/imagemagick/imagemagick_6.2.9.bb @@ -0,0 +1,21 @@ +LICENSE = "GPL" +SECTION = "console/utils" +DEPENDS = "tiff" +DESCRIPTION = "ImageMagick is an image convertion tools" + +SRC_URI = "ftp://ftp.nluug.nl/pub/ImageMagick/ImageMagick-${PV}-2.tar.bz2 \ + file://PerlMagic_MakePatch;patch=1" + +S = "${WORKDIR}/ImageMagick-${PV}" + +inherit autotools + +EXTRA_OECONF="-without-x " + +LEAD_SONAME="libMagick.so.*" + +FILES_${PN} += "${libdir}/ImageMagick-${PV}/modules-Q16/*/*.so \ + ${libdir}/ImageMagick-${PV}/config/ \ + ${datadir}/ImageMagick-${PV}" + +FILES_${PN}-dbg += "${libdir}/ImageMagick-${PV}/modules-Q16/*/.debug/*" -- cgit v1.2.3 From d7e75a4cf3d473ca5f611cf4a9e640ad44a1fcc5 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 29 Aug 2006 09:21:15 +0000 Subject: libgnomecanvas: fix -dbg packaging for 2.10.2 and 2.12.0 --- packages/gnome/libgnomecanvas_2.10.2.bb | 3 ++- packages/gnome/libgnomecanvas_2.12.0.bb | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/gnome/libgnomecanvas_2.10.2.bb b/packages/gnome/libgnomecanvas_2.10.2.bb index 36ee1aa67f..3c1b36ecd4 100644 --- a/packages/gnome/libgnomecanvas_2.10.2.bb +++ b/packages/gnome/libgnomecanvas_2.10.2.bb @@ -1,6 +1,6 @@ LICENSE = "GPL" SECTION = "x11/gnome/libs" -PR = "r1" +PR = "r2" DESCRIPTION = "A powerful object-oriented display" inherit gnome @@ -9,6 +9,7 @@ DEPENDS = "gnome-vfs libbonobo libglade libart-lgpl" EXTRA_OECONF = "--disable-gtk-doc" FILES_${PN} += "${libdir}/libglade/*/libcanvas.so" +FILES_${PN}-dbg += "${libdir}/libglade/*/.debug/libcanvas.so" do_stage() { gnome_stage_includes diff --git a/packages/gnome/libgnomecanvas_2.12.0.bb b/packages/gnome/libgnomecanvas_2.12.0.bb index 36ee1aa67f..3c1b36ecd4 100644 --- a/packages/gnome/libgnomecanvas_2.12.0.bb +++ b/packages/gnome/libgnomecanvas_2.12.0.bb @@ -1,6 +1,6 @@ LICENSE = "GPL" SECTION = "x11/gnome/libs" -PR = "r1" +PR = "r2" DESCRIPTION = "A powerful object-oriented display" inherit gnome @@ -9,6 +9,7 @@ DEPENDS = "gnome-vfs libbonobo libglade libart-lgpl" EXTRA_OECONF = "--disable-gtk-doc" FILES_${PN} += "${libdir}/libglade/*/libcanvas.so" +FILES_${PN}-dbg += "${libdir}/libglade/*/.debug/libcanvas.so" do_stage() { gnome_stage_includes -- cgit v1.2.3 From 64a4e89e5d40475bf5c575009c09bbfcd69722a3 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Tue, 29 Aug 2006 10:47:50 +0000 Subject: feed-browser: make all sections lowercase, really remove packages before update --- contrib/feed-browser/update.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/feed-browser/update.php b/contrib/feed-browser/update.php index 786e898494..b82b843663 100644 --- a/contrib/feed-browser/update.php +++ b/contrib/feed-browser/update.php @@ -47,7 +47,7 @@ $feeds = db_query("SELECT f_id, f_name, f_uri FROM feeds"); foreach($feeds as $feed) { print("Updating {$feed['f_name']}: "); - db_query_n("DELETE FROM packages WHERE p_feed = '{$feed['f_name']}'"); + db_query_n("DELETE FROM packages WHERE p_feed = '{$feed['f_id']}'"); $count = 0; @@ -104,7 +104,7 @@ foreach($feeds as $feed) $package_info['conflicts'] = $value; break; case 'Section': - $package_info['section'] = $value; + $package_info['section'] = strtolower($value); break; case 'Architecture': $package_info['arch'] = $value; -- cgit v1.2.3 From 6daed4e490d91d87965db48cc288edca914ce47c Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 29 Aug 2006 10:51:26 +0000 Subject: libbonoboui-2.10.0: fix -dbg packaging --- packages/gnome/libbonoboui_2.10.0.bb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/gnome/libbonoboui_2.10.0.bb b/packages/gnome/libbonoboui_2.10.0.bb index 719fe2395a..3a41ef731d 100644 --- a/packages/gnome/libbonoboui_2.10.0.bb +++ b/packages/gnome/libbonoboui_2.10.0.bb @@ -1,12 +1,13 @@ LICENSE = "GPL" SECTION = "x11/gnome/libs" -PR = "r1" +PR = "r2" inherit gnome pkgconfig FILES_${PN} += "${libdir}/libglade/2.0/*.so" FILES_${PN}-dev += "${libdir}/libglade/2.0/* ${datadir}/gnome-2.0/ui \ ${libdir}/bonobo-2.0/samples" +FILES_${PN}-dbg += "${libdir}/libglade/2.0/.debug/*.so" DEPENDS = "libgnomecanvas libbonobo libgnome glib-2.0 gtk-doc gconf libxml2 libglade" -- cgit v1.2.3 From 428dc98ac20df804f6aad345bd432f2b2dacea0a Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 29 Aug 2006 11:18:29 +0000 Subject: tune-arm926ejs: .dev uses gcc 4 by default --- conf/machine/include/tune-arm926ejs.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/machine/include/tune-arm926ejs.conf b/conf/machine/include/tune-arm926ejs.conf index ce1d4f7203..31fe8868ca 100644 --- a/conf/machine/include/tune-arm926ejs.conf +++ b/conf/machine/include/tune-arm926ejs.conf @@ -1,5 +1,5 @@ # For gcc 3.x you need: -TARGET_CC_ARCH = "-march=armv5te -mtune=arm926ejs" +#TARGET_CC_ARCH = "-march=armv5te -mtune=arm926ejs" # For gcc 4.x you need: -#TARGET_CC_ARCH = "-march=armv5te -mtune=arm926ej-s" +TARGET_CC_ARCH = "-march=armv5te -mtune=arm926ej-s" PACKAGE_ARCH = "armv5te" -- cgit v1.2.3 From f4860e4639923a4f88c48bc138cce089ae5dbf60 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Tue, 29 Aug 2006 11:40:58 +0000 Subject: python 2.4.3 add PACKAGES_DYNAMIC -- close #1366 --- packages/python/python_2.4.3.bb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/python/python_2.4.3.bb b/packages/python/python_2.4.3.bb index 4fe3ebd402..30c4ee1aee 100644 --- a/packages/python/python_2.4.3.bb +++ b/packages/python/python_2.4.3.bb @@ -6,7 +6,7 @@ PRIORITY = "optional" MAINTAINER = "Michael 'Mickey' Lauer " DEPENDS = "python-native readline zlib gdbm openssl tcl tk" DEPENDS_sharprom = "python-native readline zlib gdbm openssl" -PR = "ml4" +PR = "ml5" PYTHON_MAJMIN = "2.4" @@ -68,4 +68,5 @@ require python-${PV}-manifest.inc RPROVIDES_python-core = "python" RPROVIDES_python-curses = "python" PACKAGES =+ "libpython2" +PACKAGES_DYNAMIC = "python-* libpython2" FILES_libpython2 = "${libdir}/libpython*" -- cgit v1.2.3 From 1bfeca965f47b63f59f09785e1a43cbbc76095b2 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 29 Aug 2006 12:36:57 +0000 Subject: linux-omap1_2.6.x+git.bb: Clean up file, eliminate unecessary operations. --- packages/linux/linux-omap1_2.6.x+git.bb | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/linux/linux-omap1_2.6.x+git.bb b/packages/linux/linux-omap1_2.6.x+git.bb index 9e499c7687..7a5ff66af2 100644 --- a/packages/linux/linux-omap1_2.6.x+git.bb +++ b/packages/linux/linux-omap1_2.6.x+git.bb @@ -9,24 +9,19 @@ S = "${WORKDIR}/git" KERNEL_IMAGETYPE = "vmlinux" KERNEL_OUTPUT = "arch/${ARCH}/boot/compressed/${KERNEL_IMAGETYPE}" -#KERNEL_CCSUFFIX = "-4.1.1" DEPENDS = "u-boot" inherit kernel -# GIT does not have the UTS_RELEASE in version.h used to find the kernel version -KERNEL_RELEASE = "2.6.17" - COMPATIBLE_HOST = 'arm.*-linux' do_configure_prepend() { if [ "${MACHINE}" == "omap5912osk" ] ; then - make omap_osk_5912_defconfig + oe_runmake omap_osk_5912_defconfig fi - - oe_runmake oldconfig -} + +} do_deploy() { if [ "${MACHINE}" == "omap5912osk" ]; then -- cgit v1.2.3 From 51497027c61550d72a994ad3161e45f66e8a81bd Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Tue, 29 Aug 2006 13:42:00 +0000 Subject: feed-browser: feeds has a type now: normal/upgrades. Type is used by updater to update only 'upgrades' feeds: "php update.php upgrades" --- contrib/feed-browser/includes/config.inc | 24 ++++++++++++++++++++++++ contrib/feed-browser/includes/functions.inc | 8 +++++--- contrib/feed-browser/update.php | 9 +++++++-- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/contrib/feed-browser/includes/config.inc b/contrib/feed-browser/includes/config.inc index 0a270a8eb0..e1999b066f 100644 --- a/contrib/feed-browser/includes/config.inc +++ b/contrib/feed-browser/includes/config.inc @@ -11,50 +11,62 @@ $feeds = array( array( 'name'=>'base', 'url'=>'base', + 'type'=>'normal', ), array( 'name'=>'opie', 'url'=>'opie', + 'type'=>'normal', ), array( 'name'=>'x11', 'url'=>'x11', + 'type'=>'normal', ), array( 'name'=>'upgrades', 'url'=>'upgrades', + 'type'=>'upgrades', ), array( 'name'=>'perl', 'url'=>'perl', + 'type'=>'normal', ), array( 'name'=>'python', 'url'=>'python', + 'type'=>'normal', ), array( 'name'=>'Collie upgrades', 'url'=>'upgrades/machine/collie', + 'type'=>'upgrades', ), array( 'name'=>'Tosa upgrades', 'url'=>'upgrades/machine/tosa', + 'type'=>'upgrades', ), array( 'name'=>'Poodle upgrades', 'url'=>'upgrades/machine/poodle', + 'type'=>'upgrades', ), array( 'name'=>'Poodle', 'url'=>'machine/poodle', + 'type'=>'normal', ), array( 'name'=>'Collie', 'url'=>'machine/collie', + 'type'=>'normal', ), array( 'name'=>'Tosa', 'url'=>'machine/tosa', + 'type'=>'normal', ) ) ), @@ -66,50 +78,62 @@ $feeds = array( array( 'name'=>'base', 'url'=>'base', + 'type'=>'normal', ), array( 'name'=>'opie', 'url'=>'opie', + 'type'=>'normal', ), array( 'name'=>'perl', 'url'=>'perl', + 'type'=>'normal', ), array( 'name'=>'python', 'url'=>'python', + 'type'=>'normal', ), array( 'name'=>'upgrades', 'url'=>'upgrades', + 'type'=>'upgrades', ), array( 'name'=>'x11', 'url'=>'x11', + 'type'=>'normal', ), array( 'name'=>'C7x0', 'url'=>'machine/c7x0', + 'type'=>'normal', ), array( 'name'=>'Spitz', 'url'=>'machine/spitz', + 'type'=>'normal', ), array( 'name'=>'Akita', 'url'=>'machine/akita', + 'type'=>'normal', ), array( 'name'=>'Akita upgrades', 'url'=>'upgrades/machine/akita', + 'type'=>'upgrades', ), array( 'name'=>'C7x0 upgrades', 'url'=>'upgrades/machine/c7x0', + 'type'=>'upgrades', ), array( 'name'=>'Spitz upgrades', 'url'=>'upgrades/machine/spitz', + 'type'=>'upgrades', ) ) ) diff --git a/contrib/feed-browser/includes/functions.inc b/contrib/feed-browser/includes/functions.inc index 4745c75910..2532dd7c08 100644 --- a/contrib/feed-browser/includes/functions.inc +++ b/contrib/feed-browser/includes/functions.inc @@ -85,11 +85,12 @@ function insert_feeds ($db) { foreach($distro['feeds'] as $feed) { - sqlite_query($db, "INSERT INTO feeds (f_id, f_name, f_uri) VALUES + sqlite_query($db, "INSERT INTO feeds (f_id, f_name, f_uri, f_type) VALUES ( {$id}, '{$distro['distro_name']} {$distro['distro_version']} {$feed['name']}', - '{$distro['feed_base_url']}{$feed['url']}' + '{$distro['feed_base_url']}{$feed['url']}', + '{$feed['type']}' )"); $id++; @@ -441,7 +442,8 @@ function check_database() f_id int(8), f_name varchar(32), f_uri varchar(100), - f_comments varchar(500))"); + f_type varchar(16) + )"); insert_feeds ($db) ; } diff --git a/contrib/feed-browser/update.php b/contrib/feed-browser/update.php index b82b843663..ed67d3b78a 100644 --- a/contrib/feed-browser/update.php +++ b/contrib/feed-browser/update.php @@ -39,11 +39,16 @@ require_once 'includes/functions.inc'; check_database(); +$feeds = db_query("SELECT f_id, f_name, f_uri FROM feeds"); + +if($argc > 1 AND $argv[1] == 'upgrades') +{ + $feeds = db_query("SELECT f_id, f_name, f_uri FROM feeds WHERE f_type = 'upgrades'"); +} + $start = time(); $p_count = 0; -$feeds = db_query("SELECT f_id, f_name, f_uri FROM feeds"); - foreach($feeds as $feed) { print("Updating {$feed['f_name']}: "); -- cgit v1.2.3 From 9a45407127c761f0740f0c26a5995ee99e09a42f Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Tue, 29 Aug 2006 13:48:11 +0000 Subject: uboot cvs fix SRC_URI --- packages/uboot/uboot_cvs.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/uboot/uboot_cvs.bb b/packages/uboot/uboot_cvs.bb index 5ff012555e..0174fc0560 100644 --- a/packages/uboot/uboot_cvs.bb +++ b/packages/uboot/uboot_cvs.bb @@ -10,7 +10,7 @@ PROVIDES = "virtual/bootloader" S = "${WORKDIR}/u-boot" -SRC_URI = "cvs://anonymous@cvs.sourceforge.net/cvsroot/u-boot;module=u-boot \ +SRC_URI = "cvs://anonymous@u-boot.cvs.sourceforge.net/cvsroot/u-boot;module=u-boot \ file://arm_flags.patch;patch=1" EXTRA_OEMAKE = "CROSS_COMPILE=${TARGET_PREFIX}" -- cgit v1.2.3 From cf50f73edd866973a4117ab89293c3964cf16928 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Tue, 29 Aug 2006 13:54:22 +0000 Subject: preferred-versions.inc: fix wrong preference for pango. Guys, when you remove an old version of a package, make sure that a) no recipe directly depends on this version and b) no configuration sets PREFERRED_VERSION to this version. --- conf/distro/include/maemo-preferred.inc | 4 ++-- conf/distro/include/preferred-gpe-versions-2.6.inc | 1 + conf/distro/include/preferred-gpe-versions-2.7.inc | 2 +- conf/distro/include/preferred-gpe-versions.inc | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/conf/distro/include/maemo-preferred.inc b/conf/distro/include/maemo-preferred.inc index 943f244326..3b31837911 100644 --- a/conf/distro/include/maemo-preferred.inc +++ b/conf/distro/include/maemo-preferred.inc @@ -5,6 +5,6 @@ PREFERRED_VERSION_audiofile = "0.2.6-3osso4" PREFERRED_PROVIDER_esd = "osso-esd" PREFERRED_VERSION_gtk+ = "2.6.4-1.osso7" PREFERRED_VERSION_glib-2.0 = "2.6.4" -PREFERRED_VERSION_pango = "1.8.1" +PREFERRED_VERSION_pango = "1.8.2" PREFERRED_VERSION_atk = "1.9.0" -PREFERRED_VERSION_diet-x11 ?= "6.2.1" \ No newline at end of file +PREFERRED_VERSION_diet-x11 ?= "6.2.1" diff --git a/conf/distro/include/preferred-gpe-versions-2.6.inc b/conf/distro/include/preferred-gpe-versions-2.6.inc index 3bbc6be01a..256bc0103f 100644 --- a/conf/distro/include/preferred-gpe-versions-2.6.inc +++ b/conf/distro/include/preferred-gpe-versions-2.6.inc @@ -19,6 +19,7 @@ PREFERRED_VERSION_matchbox-desktop ?= "0.9.1" PREFERRED_VERSION_matchbox-wm ?= "0.9.3" PREFERRED_VERSION_matchbox-panel ?= "0.9.1" PREFERRED_VERSION_matchbox-applet-inputmanager ?= "0.6" +PREFERRED_VERSION_pango ?= "1.8.2" PREFERRED_VERSION_gtk+ ?= "2.6.3" PREFERRED_VERSION_gtk-engines ?= "2.6.5" PREFERRED_VERSION_libgpewidget ?= "0.97" diff --git a/conf/distro/include/preferred-gpe-versions-2.7.inc b/conf/distro/include/preferred-gpe-versions-2.7.inc index 36702025c1..56d9c5b059 100644 --- a/conf/distro/include/preferred-gpe-versions-2.7.inc +++ b/conf/distro/include/preferred-gpe-versions-2.7.inc @@ -20,9 +20,9 @@ PREFERRED_VERSION_matchbox-applet-inputmanager ?= "0.6" PREFERRED_VERSION_atk ?= "1.9.0" PREFERRED_VERSION_cairo ?= "0.5.2" PREFERRED_VERSION_glib-2.0 ?= "2.6.4" +PREFERRED_VERSION_pango ?= "1.8.2" PREFERRED_VERSION_gtk+ ?= "2.6.10" PREFERRED_VERSION_gtk-engines ?= "2.6.5" -PREFERRED_VERSION_pango ?= "1.8.1" PREFERRED_VERSION_librsvg ?= "2.6.5" PREFERRED_VERSION_libgpewidget ?= "0.109" PREFERRED_VERSION_libgpepimc ?= "0.5" diff --git a/conf/distro/include/preferred-gpe-versions.inc b/conf/distro/include/preferred-gpe-versions.inc index 180ca47b17..e78888a02c 100644 --- a/conf/distro/include/preferred-gpe-versions.inc +++ b/conf/distro/include/preferred-gpe-versions.inc @@ -17,6 +17,7 @@ PREFERRED_PROVIDER_gnome-vfs=gnome-vfs-dbus #PREFERRED_VERSION_matchbox-wm ?= "0.9.3" #PREFERRED_VERSION_matchbox-panel ?= "0.9.1" #PREFERRED_VERSION_matchbox-applet-inputmanager ?= "0.6" +#PREFERRED_VERSION_pango ?= "1.8.2" #PREFERRED_VERSION_gtk+ ?= "2.6.3" #PREFERRED_VERSION_gtk-engines ?= "2.6.5" #PREFERRED_VERSION_libgpewidget ?= "0.97" -- cgit v1.2.3 From 7c31c551449c21c4b45302fd2ade5f75b484d3dc Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Tue, 29 Aug 2006 16:06:41 +0000 Subject: omniorb-native_4.0.7.bb, omniorb_4.0.7.bb, long_double.patch : * Add bb files for omniorb-4.0.7 * Patch long_double.patch allows compilation when sizeof(long double) * is something other than 12 or 16. --- packages/omniorb/files/long_double.patch | 19 ++++++++++++++++ packages/omniorb/omniorb-native_4.0.7.bb | 21 ++++++++++++++++++ packages/omniorb/omniorb_4.0.7.bb | 37 ++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 packages/omniorb/files/long_double.patch create mode 100644 packages/omniorb/omniorb-native_4.0.7.bb create mode 100644 packages/omniorb/omniorb_4.0.7.bb diff --git a/packages/omniorb/files/long_double.patch b/packages/omniorb/files/long_double.patch new file mode 100644 index 0000000000..a34ff9807e --- /dev/null +++ b/packages/omniorb/files/long_double.patch @@ -0,0 +1,19 @@ +*** omniORB-4.0.7.old/include/omniORB4/CORBA_sysdep_auto.h 2004-10-17 16:14:28.000000000 -0400 +--- omniORB-4.0.7/include/omniORB4/CORBA_sysdep_auto.h 2006-08-29 11:29:08.000000000 -0400 +*************** +*** 85,91 **** + #endif + + +! #if defined(SIZEOF_LONG_DOUBLE) && (SIZEOF_LONG_DOUBLE == 16) + # define HAS_LongDouble + # define _CORBA_LONGDOUBLE_DECL long double + #endif +--- 85,91 ---- + #endif + + +! #if defined(SIZEOF_LONG_DOUBLE) + # define HAS_LongDouble + # define _CORBA_LONGDOUBLE_DECL long double + #endif diff --git a/packages/omniorb/omniorb-native_4.0.7.bb b/packages/omniorb/omniorb-native_4.0.7.bb new file mode 100644 index 0000000000..f9addd997d --- /dev/null +++ b/packages/omniorb/omniorb-native_4.0.7.bb @@ -0,0 +1,21 @@ +PR = "r0" +SRC_URI = "${SOURCEFORGE_MIRROR}/omniorb/omniORB-${PV}.tar.gz" +SECTION = "devel" +S = "${WORKDIR}/omniORB-${PV}" + +DEPENDS += python-native + +inherit native autotools + +do_compile () { + oe_runmake +} + + +#do_stage() { +# install -m 0755 src/bison ${STAGING_BINDIR}/ +# ln -sf ./bison ${STAGING_BINDIR}/yacc +# install -d ${STAGING_BINDIR}/../share/bison/m4sugar +# install -m 0755 data/c.m4 data/glr.c data/lalr1.cc data/yacc.c ${STAGING_BINDIR}/../share/bison/ +# install -m 0755 data/m4sugar/m4sugar.m4 ${STAGING_BINDIR}/../share/bison/m4sugar/ +#} diff --git a/packages/omniorb/omniorb_4.0.7.bb b/packages/omniorb/omniorb_4.0.7.bb new file mode 100644 index 0000000000..0ef6bdac03 --- /dev/null +++ b/packages/omniorb/omniorb_4.0.7.bb @@ -0,0 +1,37 @@ +PR = "r0" +DESCRIPTION = "OmniORB High Performance ORB" +SECTION = "devel" +PRIORITY = "optional" +MAINTAINER = "Philip Balister " +LICENSE = "LGPL" + +DEPENDS = omniorb-native + +SRC_URI = "${SOURCEFORGE_MIRROR}/omniorb/omniORB-${PV}.tar.gz \ +file://omniORB-cross.patch;patch=1 \ +file://omniORB_embedded_appl.patch;patch=1" \ +file://long_double.patch;patch=1" + +S = "${WORKDIR}/omniORB-${PV}" + +inherit autotools pkgconfig + +#do_configure () { +# oe_runconf +#} + +do_compile () { + export EmbeddedSystem=1 + export TOOLBINDIR=${STAGING_BINDIR} + oe_runmake +} + +do_stage () { + export EmbeddedSystem=1 + make DESTDIR=${STAGING_DIR}/${TARGET_SYS} install +} + +do_install () { + export EmbeddedSystem=1 + make DESTDIR=${D} install +} -- cgit v1.2.3 From 1ca3ed533e848c27025769e7d311bf2892730490 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 29 Aug 2006 16:09:16 +0000 Subject: dbus-glib-native-0.71: fix bogus DEPENDS --- packages/dbus/dbus-glib-native_0.71.bb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/dbus/dbus-glib-native_0.71.bb b/packages/dbus/dbus-glib-native_0.71.bb index 200a7133b2..1f5d71da91 100644 --- a/packages/dbus/dbus-glib-native_0.71.bb +++ b/packages/dbus/dbus-glib-native_0.71.bb @@ -3,7 +3,6 @@ PR = "r0" HOMEPAGE = "http://www.freedesktop.org/Software/dbus" DESCRIPTION = "message bus system for applications to talk to one another" LICENSE = "GPL" -DEPENDS = "expat glib-2.0 virtual/libintl dbus-native" SRC_URI = "http://freedesktop.org/software/dbus/releases/dbus-glib-${PV}.tar.gz \ file://cross.patch;patch=1 \ @@ -13,7 +12,7 @@ inherit autotools pkgconfig gettext native S = "${WORKDIR}/dbus-glib-${PV}" FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/dbus-glib" -DEPENDS = "glib-2.0-native" +DEPENDS = "glib-2.0-native dbus-native" do_stage() { oe_runmake install -- cgit v1.2.3 From 2abd2ff6f3acde37b3d13abc9b20a3d9e7f2ea65 Mon Sep 17 00:00:00 2001 From: Justin Patrin Date: Tue, 29 Aug 2006 16:20:36 +0000 Subject: mtnpatch.py: Remove unneeded script (mtn now has pluck) --- contrib/mtnpatch.py | 54 ----------------------------------------------------- 1 file changed, 54 deletions(-) delete mode 100755 contrib/mtnpatch.py diff --git a/contrib/mtnpatch.py b/contrib/mtnpatch.py deleted file mode 100755 index 73143dba69..0000000000 --- a/contrib/mtnpatch.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python -import sys, os, string, getopt, re - -mtncmd = "monotone" - -def main(argv = None): - if argv is None: - argv = sys.argv - opts, list = getopt.getopt(sys.argv[1:], ':R') - if len(list) < 1: - print "You must specify a file" - return 2 - reverse = False - for o, a in opts: - if o == "-R": - reverse = True - if os.path.exists(list[0]): - input = open(list[0], 'r') - renameFrom = "" - cmd = "" - if reverse: - print "patch -R -p0 < %s" % list[0] - else: - print "patch -p0 < %s" % list[0] - for line in input: - if len(line) > 0: - if line[0] == '#': - matches = re.search("#\s+(\w+)\s+\"(.*)\"", line) - if matches is not None: - cmd = matches.group(1) - fileName = matches.group(2) - if cmd == "delete_file": - if reverse: - print "%s add %s" % (mtncmd, fileName) - else: - print "%s drop -e %s" % (mtncmd, fileName) - elif cmd == "add_file": - if reverse: - print "%s drop -e %s" % (mtncmd, fileName) - else: - print "%s add %s" % (mtncmd, fileName) - elif cmd == "rename_file": - renameFrom = fileName - elif cmd == "to" and renameFrom != "": - if reverse: - print "%s rename -e %s %s" % (mtncmd, fileName, renameFrom) - else: - print "%s rename -e %s %s" % (mtncmd, renameFrom, fileName) - renameFrom = "" - else: - cmd = "" - -if __name__ == "__main__": - sys.exit(main()) -- cgit v1.2.3 From fa3571e0a22f896c6153949b74d3220af2d7abf8 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 29 Aug 2006 18:29:35 +0000 Subject: xserver-kdrive-git: apply the xcalibrate patch from X11R7.1 --- packages/xorg-xserver/xserver-kdrive_git.bb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/xorg-xserver/xserver-kdrive_git.bb b/packages/xorg-xserver/xserver-kdrive_git.bb index aa5784e1c7..33e15bab86 100644 --- a/packages/xorg-xserver/xserver-kdrive_git.bb +++ b/packages/xorg-xserver/xserver-kdrive_git.bb @@ -1,7 +1,7 @@ PV = "1.1.0+git${SRCDATE}" DEFAULT_PREFERENCE = "-2" -PR = "r1" +PR = "r2" LICENSE = "MIT" DEPENDS = "tslib libxkbfile xf86dgaproto xf86vidmodeproto xf86miscproto xproto libxdmcp xextproto xtrans libxau virtual/libx11 libxext libxrandr fixesproto damageproto libxfont resourceproto compositeproto xcalibrateext recordproto videoproto scrnsaverproto" @@ -35,7 +35,8 @@ SRC_URI = "git://anongit.freedesktop.org/xorg/xserver;protocol=git \ file://enable-builtin-fonts.patch;patch=1 \ file://optional-xkb.patch;patch=1 \ # file://disable-xf86-dga-xorgcfg.patch;patch=1 \ - file://enable-tslib.patch;patch=1" + file://enable-tslib.patch;patch=1 \ + file://xcalibrate.patch;patch=1" SRC_URI_append_mnci = " file://onlyfb.patch;patch=1" SRC_URI_append_poodle = " file://xserver-kdrive-poodle.patch;patch=1" -- cgit v1.2.3 From 806294f16a8f9ee061cfd99adeb2087f3538c998 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 29 Aug 2006 19:56:56 +0000 Subject: bluez-libs, bluez-utils: add 3.4 --- packages/bluez/bluez-libs_3.4.bb | 22 ++++++++++++++++ packages/bluez/bluez-utils_3.4.bb | 53 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 packages/bluez/bluez-libs_3.4.bb create mode 100644 packages/bluez/bluez-utils_3.4.bb diff --git a/packages/bluez/bluez-libs_3.4.bb b/packages/bluez/bluez-libs_3.4.bb new file mode 100644 index 0000000000..d740bd80a9 --- /dev/null +++ b/packages/bluez/bluez-libs_3.4.bb @@ -0,0 +1,22 @@ +DESCRIPTION = "Linux Bluetooth Stack Userland Libaries." +SECTION = "libs" +PRIORITY = "optional" +HOMEPAGE = "http://www.bluez.org" +LICENSE = "GPL" +PR = "r0" + +SRC_URI = "http://bluez.sourceforge.net/download/bluez-libs-${PV}.tar.gz" + +inherit autotools pkgconfig + +HEADERS = "bluetooth.h bnep.h cmtp.h hci.h hci_lib.h hidp.h l2cap.h rfcomm.h sco.h sdp.h sdp_lib.h" + +do_stage() { + oe_libinstall -a -so -C src libbluetooth ${STAGING_LIBDIR} + + install -d ${STAGING_INCDIR}/bluetooth/ + for f in ${HEADERS} + do + install -m 0644 include/$f ${STAGING_INCDIR}/bluetooth/$f + done +} diff --git a/packages/bluez/bluez-utils_3.4.bb b/packages/bluez/bluez-utils_3.4.bb new file mode 100644 index 0000000000..3b8702e997 --- /dev/null +++ b/packages/bluez/bluez-utils_3.4.bb @@ -0,0 +1,53 @@ +DESCRIPTION = "Linux Bluetooth Stack Userland Utilities." +SECTION = "console" +PRIORITY = "optional" +DEPENDS = "bluez-libs-${PV} dbus" +PROVIDES = "bluez-utils-dbus" +RPROVIDES_${PN} = "bluez-pan bluez-sdp bluez-utils-dbus" +RREPLACES = "bluez-utils-dbus" +RCONFLICTS_${PN} = "bluez-utils-nodbus" +LICENSE = "GPL" +PR = "r0" + +SRC_URI = "http://bluez.sourceforge.net/download/bluez-utils-${PV}.tar.gz \ + file://hcid.conf \ + file://02dtl1_cs.sh \ + file://hciattach-ti-bts.patch;patch=1" + +# Almost all serial CF cards w/ manfid 0x0000,0x0000 seem to use the bcs protocol +# Let's default to that instead of 'any' until further notice... +SRC_URI += " file://default-manfid-0x0-to-bcps.patch;patch=1" + +S = "${WORKDIR}/bluez-utils-${PV}" + +EXTRA_OECONF = "--enable-initscripts --enable-bcm203x" +# --enable-obex enable OBEX support +# --enable-alsa enable ALSA support +# --enable-cups install CUPS backend support +# --enable-bccmd install BCCMD interface utility +# --enable-avctrl install Audio/Video control utility +# --enable-hid2hci install HID mode switching utility +# --enable-dfutool install DFU firmware upgrade utility + +inherit autotools update-rc.d + +INITSCRIPT_NAME = "bluetooth" +INITSCRIPT_PARAMS = "defaults 23 19" + +do_install_append() { + install -d ${D}${base_sbindir} ${D}${base_bindir}/ ${D}${sysconfdir}/apm/event.d/ + mv ${D}${sbindir}/* ${D}${base_sbindir}/ + mv ${D}${bindir}/* ${D}${base_bindir}/ + rmdir ${D}${bindir} ${D}${sbindir} + chmod u+s ${D}${base_sbindir}/hciattach ${D}${base_sbindir}/hciconfig + install -m 0644 ${WORKDIR}/hcid.conf ${D}${sysconfdir}/bluetooth/ + install -m 0755 ${WORKDIR}/02dtl1_cs.sh ${D}${sysconfdir}/apm/event.d/ +} + +CONFFILES_${PN} = "${sysconfdir}/bluetooth/hcid.conf ${sysconfdir}/bluetooth/rfcomm.conf \ + ${sysconfdir}/default/bluetooth" + +PACKAGES =+ "${PN}-ciptool" +FILES_${PN}-ciptool = "/bin/ciptool" +RREPLACES_${PN}-ciptool = "bluez-utils-dbus-ciptool" +RCONFLICTS_${PN}-ciptool = "bluez-utils-dbus-ciptool bluez-utils-nodbus" -- cgit v1.2.3 From a350439c9ae71b8d437730e8659a9f5561d0b0d5 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 29 Aug 2006 21:34:04 +0000 Subject: xserver-kdrive git: remove tslib and xcalibrate patches that have been applied upstream (yay!) and enable tslib in EXTRA_OECONF --- packages/xorg-xserver/xserver-kdrive_git.bb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/xorg-xserver/xserver-kdrive_git.bb b/packages/xorg-xserver/xserver-kdrive_git.bb index 33e15bab86..bf6fd92d61 100644 --- a/packages/xorg-xserver/xserver-kdrive_git.bb +++ b/packages/xorg-xserver/xserver-kdrive_git.bb @@ -1,7 +1,7 @@ PV = "1.1.0+git${SRCDATE}" DEFAULT_PREFERENCE = "-2" -PR = "r2" +PR = "r3" LICENSE = "MIT" DEPENDS = "tslib libxkbfile xf86dgaproto xf86vidmodeproto xf86miscproto xproto libxdmcp xextproto xtrans libxau virtual/libx11 libxext libxrandr fixesproto damageproto libxfont resourceproto compositeproto xcalibrateext recordproto videoproto scrnsaverproto" @@ -35,8 +35,7 @@ SRC_URI = "git://anongit.freedesktop.org/xorg/xserver;protocol=git \ file://enable-builtin-fonts.patch;patch=1 \ file://optional-xkb.patch;patch=1 \ # file://disable-xf86-dga-xorgcfg.patch;patch=1 \ - file://enable-tslib.patch;patch=1 \ - file://xcalibrate.patch;patch=1" + " SRC_URI_append_mnci = " file://onlyfb.patch;patch=1" SRC_URI_append_poodle = " file://xserver-kdrive-poodle.patch;patch=1" @@ -54,4 +53,5 @@ EXTRA_OECONF = "--enable-composite --enable-kdrive \ --disable-xevie --disable-xprint --disable-xtrap \ --disable-dmx \ --with-default-font-path=built-ins \ + --enable-tslib \ ac_cv_file__usr_share_X11_sgml_defs_ent=no" -- cgit v1.2.3 From 4b58334866dda9b3415fee5668b2c7bc08447905 Mon Sep 17 00:00:00 2001 From: Jamie Lenehan Date: Wed, 30 Aug 2006 07:18:07 +0000 Subject: classes/patch.bbclass: Create a "patches" directory when initialising the quilt patcher class. Without this quilt will search for a patches directory - starting from the current directory up to the root directory. If it finds an existing patches directory it will use it for its patches. This causes all sorts of problems since it is not where the patches are expected to be. Prior to the recent patcher changes this directory was being created. --- classes/patch.bbclass | 3 +++ 1 file changed, 3 insertions(+) diff --git a/classes/patch.bbclass b/classes/patch.bbclass index ea0182484e..c62a8ebd76 100644 --- a/classes/patch.bbclass +++ b/classes/patch.bbclass @@ -174,6 +174,9 @@ def patch_init(d): def __init__(self, dir, d): PatchSet.__init__(self, dir, d) self.initialized = False + p = os.path.join(self.dir, 'patches') + if not os.path.exists(p): + os.mkdir(p) def Clean(self): try: -- cgit v1.2.3 From dc8d0a5f1ea8956bc4af88132472cccde4a0e7c3 Mon Sep 17 00:00:00 2001 From: Chris Larson Date: Wed, 30 Aug 2006 07:29:56 +0000 Subject: patch.bbclass: * Add NOOPResolver class, which simply passes the patch failure on up, not doing any actual patch resolution. Set PATCHRESOLVE = "noop" to make use of it. Most useful for unattended builds. --- classes/patch.bbclass | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/classes/patch.bbclass b/classes/patch.bbclass index c62a8ebd76..7bb0900f8a 100644 --- a/classes/patch.bbclass +++ b/classes/patch.bbclass @@ -309,6 +309,19 @@ def patch_init(d): def Finalize(self): raise NotImplementedError() + class NOOPResolver(Resolver): + def __init__(self, patchset): + self.patchset = patchset + + def Resolve(self): + olddir = os.path.abspath(os.curdir) + os.chdir(self.patchset.dir) + try: + self.patchset.Push() + except Exception: + os.chdir(olddir) + raise sys.exc_value + # Patch resolver which relies on the user doing all the work involved in the # resolution, with the exception of refreshing the remote copy of the patch # files (the urls). @@ -360,20 +373,13 @@ def patch_init(d): raise os.chdir(olddir) - # Throw away the changes to the patches in the patchset made by resolve() - def Revert(self): - raise NotImplementedError() - - # Apply the changes to the patches in the patchset made by resolve() - def Finalize(self): - raise NotImplementedError() - g = globals() g["PatchSet"] = PatchSet g["PatchTree"] = PatchTree g["QuiltTree"] = QuiltTree g["Resolver"] = Resolver g["UserResolver"] = UserResolver + g["NOOPResolver"] = NOOPResolver g["NotFoundError"] = NotFoundError g["CmdError"] = CmdError @@ -397,6 +403,7 @@ python patch_do_patch() { cls = patchsetmap[bb.data.getVar('PATCHTOOL', d, 1) or 'quilt'] resolvermap = { + "noop": NOOPResolver, "user": UserResolver, } -- cgit v1.2.3 From 41a995084316c3f0092a85a9047751ffb82b02bc Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 30 Aug 2006 07:37:32 +0000 Subject: calibrateproto: add git version --- packages/xorg-proto/calibrateproto_git.bb | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 packages/xorg-proto/calibrateproto_git.bb diff --git a/packages/xorg-proto/calibrateproto_git.bb b/packages/xorg-proto/calibrateproto_git.bb new file mode 100644 index 0000000000..bad54301da --- /dev/null +++ b/packages/xorg-proto/calibrateproto_git.bb @@ -0,0 +1,7 @@ +require xorg-proto-common.inc + +DESCRIPTION = " Touchscreen calibration protocol" + +SRC_URI = "git://anongit.freedesktop.org/git/xorg/proto/calibrateproto;protocol=git" +S = "${WORKDIR}/git" + -- cgit v1.2.3 From 1f466c89c6c17f37c517bda099db12ab55daad6a Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 30 Aug 2006 07:42:33 +0000 Subject: calibrateproto: add a PV --- packages/xorg-proto/calibrateproto_git.bb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/xorg-proto/calibrateproto_git.bb b/packages/xorg-proto/calibrateproto_git.bb index bad54301da..964380d943 100644 --- a/packages/xorg-proto/calibrateproto_git.bb +++ b/packages/xorg-proto/calibrateproto_git.bb @@ -2,6 +2,8 @@ require xorg-proto-common.inc DESCRIPTION = " Touchscreen calibration protocol" +PV = "0.0+git${DATE}" + SRC_URI = "git://anongit.freedesktop.org/git/xorg/proto/calibrateproto;protocol=git" S = "${WORKDIR}/git" -- cgit v1.2.3 From 342881986b13d73ee6489acf4e23afbf691deb3c Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 30 Aug 2006 07:43:30 +0000 Subject: libxcalibrate: add git version --- packages/xorg-lib/libxcalibrate_git.bb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 packages/xorg-lib/libxcalibrate_git.bb diff --git a/packages/xorg-lib/libxcalibrate_git.bb b/packages/xorg-lib/libxcalibrate_git.bb new file mode 100644 index 0000000000..df23f22b11 --- /dev/null +++ b/packages/xorg-lib/libxcalibrate_git.bb @@ -0,0 +1,19 @@ +DESCRIPTION = " Touchscreen calibration client library" +SECTION = "x11/libs" +PRIORITY = "optional" +LICENSE = "BSD-X" + +PV = "0.0+git${DATE}" + +DEPENDS = "virtual/libx11 calibrateproto libxext" + +FILES_${PN}-locale += "${datadir}/X11/locale" + +SRC_URI = "git://anongit.freedesktop.org/git/xorg/lib/libXCalibrate;protocol=git" +S = "${WORKDIR}/git" + +inherit autotools pkgconfig + +do_stage() { + autotools_stage_all +} -- cgit v1.2.3 From 86f8687c1632cb0f1b6da84589e8bc211f4b40ab Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 30 Aug 2006 08:14:51 +0000 Subject: xserver-kdrive git: adjust for new calibrate stuff, package Xsdl, enable build of epson server --- packages/xorg-xserver/xserver-kdrive/enable-epson.patch | 11 +++++++++++ packages/xorg-xserver/xserver-kdrive_git.bb | 15 ++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 packages/xorg-xserver/xserver-kdrive/enable-epson.patch diff --git a/packages/xorg-xserver/xserver-kdrive/enable-epson.patch b/packages/xorg-xserver/xserver-kdrive/enable-epson.patch new file mode 100644 index 0000000000..63b13a4511 --- /dev/null +++ b/packages/xorg-xserver/xserver-kdrive/enable-epson.patch @@ -0,0 +1,11 @@ +--- /tmp/Makefile.am 2006-08-30 09:51:21.000000000 +0200 ++++ git/hw/kdrive/Makefile.am 2006-08-30 09:51:44.425780000 +0200 +@@ -4,7 +4,7 @@ + endif + + if KDRIVEFBDEV +-FBDEV_SUBDIRS = fbdev ++FBDEV_SUBDIRS = fbdev epson + endif + + if XSDLSERVER diff --git a/packages/xorg-xserver/xserver-kdrive_git.bb b/packages/xorg-xserver/xserver-kdrive_git.bb index bf6fd92d61..9c967db254 100644 --- a/packages/xorg-xserver/xserver-kdrive_git.bb +++ b/packages/xorg-xserver/xserver-kdrive_git.bb @@ -4,26 +4,32 @@ DEFAULT_PREFERENCE = "-2" PR = "r3" LICENSE = "MIT" -DEPENDS = "tslib libxkbfile xf86dgaproto xf86vidmodeproto xf86miscproto xproto libxdmcp xextproto xtrans libxau virtual/libx11 libxext libxrandr fixesproto damageproto libxfont resourceproto compositeproto xcalibrateext recordproto videoproto scrnsaverproto" +DEPENDS = "tslib virtual/libsdl libxkbfile xf86dgaproto xf86vidmodeproto xf86miscproto xproto libxdmcp xextproto xtrans libxau virtual/libx11 libxext libxrandr fixesproto damageproto libxfont resourceproto compositeproto libxcalibrate recordproto videoproto scrnsaverproto" PROVIDES = "virtual/xserver" RPROVIDES = "virtual/xserver" -PACKAGES =+ "xserver-kdrive-fbdev xserver-kdrive-fake xserver-kdrive-xephyr ${PN}-doc ${PN}-dev ${PN}-locale" +PACKAGES =+ "xserver-kdrive-fbdev xserver-kdrive-sdl xserver-kdrive-fake xserver-kdrive-xephyr xserver-kdrive-epson ${PN}-doc ${PN}-dev ${PN}-locale" SECTION = "x11/base" DESCRIPTION = "X server from freedesktop.org" DESCRIPTION_xserver-kdrive-fbdev = "X server from freedesktop.org, supporting generic framebuffer devices" DESCRIPTION_xserver-kdrive-fake = "Fake X server" DESCRIPTION_xserver-kdrive-xephyr = "X server in an X window" +DESCRIPTION_xserver-kdrive-epson = "X server from freedesktop.org, supporting Epson S1D13806 devices" +DESCRIPTION_xserver-kdrive-epson = "X server from freedesktop.org, SDL version" FILES_${PN} += "${libdir}/xserver/SecurityPolicy" FILES_xserver-kdrive-fbdev = "${bindir}/Xfbdev" FILES_xserver-kdrive-fake = "${bindir}/Xfake" FILES_xserver-kdrive-xephyr = "${bindir}/Xephyr" +FILES_xserver-kdrive-epson = "${bindir}/Xepson" +FILES_xserver-kdrive-sdl = "${bindir}/Xsdl" RDEPENDS_xserver-kdrive-fbdev = "${PN}" RDEPENDS_xserver-kdrive-fake = "${PN}" RDEPENDS_xserver-kdrive-xephyr = "${PN}" +RDEPENDS_xserver-kdrive-epson = "${PN}" +RDEPENDS_xserver-kdrive-sdl = "${PN}" SRC_URI = "git://anongit.freedesktop.org/xorg/xserver;protocol=git \ file://kmode.patch;patch=1 \ @@ -34,6 +40,7 @@ SRC_URI = "git://anongit.freedesktop.org/xorg/xserver;protocol=git \ file://fbdev-not-fix.patch;patch=1 \ file://enable-builtin-fonts.patch;patch=1 \ file://optional-xkb.patch;patch=1 \ + file://enable-epson.patch;patch=1 \ # file://disable-xf86-dga-xorgcfg.patch;patch=1 \ " @@ -53,5 +60,7 @@ EXTRA_OECONF = "--enable-composite --enable-kdrive \ --disable-xevie --disable-xprint --disable-xtrap \ --disable-dmx \ --with-default-font-path=built-ins \ - --enable-tslib \ + --enable-tslib --enable-xcalibrate \ ac_cv_file__usr_share_X11_sgml_defs_ent=no" + + -- cgit v1.2.3 From ee5c15c58188e02db43e54b9093d9c0f73696182 Mon Sep 17 00:00:00 2001 From: Chris Larson Date: Wed, 30 Aug 2006 08:32:22 +0000 Subject: patch.bbclass: * switch os.mkdir to os.makedirs. * pass on all errors from QuiltTree.Clean(), as it can fail in ways that do not need to be reported to the user, and a failure will end up being seen again during the Import/Push of the patches. --- classes/patch.bbclass | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/classes/patch.bbclass b/classes/patch.bbclass index 7bb0900f8a..5e40b3dc0d 100644 --- a/classes/patch.bbclass +++ b/classes/patch.bbclass @@ -176,16 +176,13 @@ def patch_init(d): self.initialized = False p = os.path.join(self.dir, 'patches') if not os.path.exists(p): - os.mkdir(p) + os.makedirs(p) def Clean(self): try: self._runcmd(["pop", "-a", "-f"]) - except CmdError: - pass - except NotFoundError: + except Exception: pass - # runcmd(["rm", "-rf", os.path.join(self.dir, "patches"), os.path.join(self.dir, ".pc")]) self.initialized = True def InitFromDir(self): -- cgit v1.2.3 From 5fde101032ef0d864112eebf2731c559da00c335 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Wed, 30 Aug 2006 09:35:58 +0000 Subject: handhelds-pxa-2.6: Add defconfig for h4000. --- .../linux/handhelds-pxa-2.6/h4000/.mtn2git_empty | 0 packages/linux/handhelds-pxa-2.6/h4000/defconfig | 1343 ++++++++++++++++++++ 2 files changed, 1343 insertions(+) create mode 100644 packages/linux/handhelds-pxa-2.6/h4000/.mtn2git_empty create mode 100644 packages/linux/handhelds-pxa-2.6/h4000/defconfig diff --git a/packages/linux/handhelds-pxa-2.6/h4000/.mtn2git_empty b/packages/linux/handhelds-pxa-2.6/h4000/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/linux/handhelds-pxa-2.6/h4000/defconfig b/packages/linux/handhelds-pxa-2.6/h4000/defconfig new file mode 100644 index 0000000000..2bba0377eb --- /dev/null +++ b/packages/linux/handhelds-pxa-2.6/h4000/defconfig @@ -0,0 +1,1343 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.16-hh2 +# Sat Jun 24 13:09:54 2006 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_MTD_XIP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +# CONFIG_MINIMAL_OOPS is not set +CONFIG_IKCONFIG_PROC=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_USELIB=y +CONFIG_CORE_DUMP=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +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=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +CONFIG_MODULE_SRCVERSION_ALL=y +# CONFIG_KMOD is not set + +# +# Block layer +# + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_IOSCHED_CFQ is not set +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_AT91RM9200 is not set + +# +# Intel PXA2xx Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +# CONFIG_MACH_MAINSTONE is not set +# CONFIG_ARCH_PXA_IDP is not set +# CONFIG_ARCH_ESERIES is not set +# CONFIG_MACH_A620 is not set +# CONFIG_MACH_A716 is not set +# CONFIG_ARCH_H1900 is not set +# CONFIG_ARCH_H2200 is not set +# CONFIG_ARCH_H3900 is not set +CONFIG_MACH_H4000=y +CONFIG_IPAQ_H4000_SERIAL=m +CONFIG_IPAQ_H4000_UDC=y +CONFIG_IPAQ_H4000_LCD=y +CONFIG_IPAQ_H4000_TS=y +CONFIG_IPAQ_H4000_PCMCIA=y +CONFIG_IPAQ_H4000_BUTTONS=y +CONFIG_IPAQ_H4000_BATT=y +CONFIG_IPAQ_H4300_KBD=m +# CONFIG_MACH_H4700 is not set +# CONFIG_MACH_HX2750 is not set +# CONFIG_ARCH_H5400 is not set +# CONFIG_MACH_HIMALAYA is not set +# CONFIG_MACH_HTCUNIVERSAL is not set +# CONFIG_MACH_HTCALPINE is not set +# CONFIG_MACH_MAGICIAN is not set +# CONFIG_MACH_HTCAPACHE is not set +# CONFIG_MACH_BLUEANGEL is not set +# CONFIG_MACH_HTCBEETLES is not set +# CONFIG_ARCH_AXIMX5 is not set +# CONFIG_ARCH_AXIMX3 is not set +# CONFIG_MACH_X30 is not set +# CONFIG_ARCH_ROVERP1 is not set +# CONFIG_ARCH_ROVERP5P is not set +# CONFIG_MACH_XSCALE_PALMLD is not set +# CONFIG_MACH_T3XSCALE is not set +# CONFIG_PXA_SHARPSL is not set +CONFIG_PXA25x=y +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set + +# +# Linux As Bootloader +# +# CONFIG_LAB is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +CONFIG_XSCALE_PMU=y +CONFIG_KEXEC=y + +# +# Compaq/iPAQ Platforms +# +CONFIG_PXA_IPAQ=y + +# +# XScale-based iPAQ +# +CONFIG_IPAQ_HANDHELD=y + +# +# Compaq/iPAQ Drivers +# + +# +# Compaq/HP iPAQ Drivers +# +# CONFIG_IPAQ_SLEEVE is not set +# CONFIG_IPAQ_SAMCOP is not set +# CONFIG_IPAQ_HAMCOP is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +CONFIG_PCMCIA_DEBUG=y +CONFIG_PCMCIA=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_IOCTL=y + +# +# PC-card bridges +# +CONFIG_PCMCIA_PXA2XX=y + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_NO_IDLE_HZ=y +# CONFIG_AEABI is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +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 is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="keepinitrd" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_DEBUG=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_PXA=y +CONFIG_PXA25x_ALTERNATE_FREQS=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +CONFIG_PM_DEBUG=y +CONFIG_APM=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_IPV6_TUNNEL is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK is not set +# CONFIG_NETFILTER_XTABLES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +# CONFIG_IP_NF_CT_ACCT is not set +# CONFIG_IP_NF_CONNTRACK_MARK is not set +# CONFIG_IP_NF_CONNTRACK_EVENTS is not set +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_NETBIOS_NS is not set +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_PPTP is not set +# CONFIG_IP_NF_QUEUE is not set + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +# CONFIG_IP6_NF_QUEUE is not set + +# +# Bridge: Netfilter Configuration +# +# CONFIG_BRIDGE_NF_EBTABLES is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_BRIDGE=m +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=y + +# +# IrDA protocols +# +CONFIG_IRLAN=y +CONFIG_IRCOMM=y +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +# CONFIG_IRDA_CACHE_LAST_LSAP is not set +# CONFIG_IRDA_FAST_RR is not set +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +CONFIG_PXA_FICP=y +CONFIG_BT=y +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_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +# CONFIG_BT_HCIDTL1 is not set +# CONFIG_BT_HCIBT3C is not set +# CONFIG_BT_HCIBLUECARD is not set +# CONFIG_BT_HCIBTUART is not set +# CONFIG_BT_HCIVHCI is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=3 +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_CHAR is not set +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +# CONFIG_MTD_JEDECPROBE is not set +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 is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=m +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +CONFIG_MTD_XIP=y + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_IPAQ is not set +# CONFIG_MTD_SHARP_SL is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=m +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_PCMCIA_WAVELAN is not set +# CONFIG_PCMCIA_NETWAVE is not set + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_HERMES is not set +# CONFIG_ATMEL is not set + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_WL3501 is not set +# CONFIG_HOSTAP is not set +CONFIG_ACX=y +CONFIG_ACX_MEM=y +CONFIG_NET_WIRELESS=y + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_TSDEV=y +CONFIG_INPUT_TSDEV_SCREEN_X=240 +CONFIG_INPUT_TSDEV_SCREEN_Y=320 +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_PXA=y +CONFIG_SERIAL_PXA_CONSOLE=y +CONFIG_SERIAL_PXA_COUNT=4 +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ELV is not set +CONFIG_I2C_PXA=m +CONFIG_I2C_PXA_SLAVE=y +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCA9535 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_RTC_X1205_I2C is not set +# 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 + +# +# L3 serial bus support +# +# CONFIG_L3 is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_SA1100_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# SPI support +# +CONFIG_SPI=y +CONFIG_SPI_DEBUG=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set + +# +# SPI Protocol Masters +# + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# SoC drivers +# +# CONFIG_SOC_MQ11XX is not set +# CONFIG_SOC_T7L66XB is not set +# CONFIG_SOC_TC6387XB is not set +# CONFIG_SOC_TC6393XB is not set +# CONFIG_HTC_ASIC2 is not set +CONFIG_HTC_ASIC3=y +# CONFIG_SOC_TSC2101 is not set + +# +# Misc devices +# +CONFIG_BATTERY_MONITOR=y + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set + +# +# Multimedia Capabilities Port drivers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# 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_MODE_HELPERS is not set +CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_IMAGEON is not set +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_PXA=y +CONFIG_FB_PXA_PARAMETERS=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +CONFIG_FONT_MINI_4x6=y +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_DEVICE=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_DEVICE=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# +# CONFIG_SND_A716 is not set +# CONFIG_SND_H1910 is not set +# CONFIG_SND_H2200 is not set +# CONFIG_SND_HTCMAGICIAN is not set +# CONFIG_SND_HX4700 is not set +# CONFIG_SND_H5XXX_AK4535 is not set +# CONFIG_SND_PXA2XX_AC97 is not set + +# +# PCMCIA devices +# + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DEBUG_FILES=y +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_NET2280 is not set +CONFIG_USB_GADGET_PXA2XX=y +CONFIG_USB_PXA2XX=y +# CONFIG_USB_PXA2XX_SMALL is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_MQ11XX is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +# CONFIG_USB_ZERO is not set +CONFIG_USB_ETH=y +# CONFIG_USB_ETH_RNDIS is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_G_CHAR is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=y +# CONFIG_MMC_PXA is not set +# CONFIG_MMC_TMIO is not set +# CONFIG_MMC_SAMCOP is not set +CONFIG_MMC_ASIC3=y + +# +# LED devices +# +CONFIG_CLASS_LEDS=y + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=1 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=y +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_CODEPAGE_852=y +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +CONFIG_NLS_CODEPAGE_1250=y +CONFIG_NLS_CODEPAGE_1251=y +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_MAGIC_SYSRQ is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=15 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_VM=y +CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y -- cgit v1.2.3 From 3d7729be91fd12330e2163f4ec1cd4c756bdaaae Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Wed, 30 Aug 2006 09:43:43 +0000 Subject: handhelds-pxa-2.6_2.6.16-hh5: Recipe for the latest HH.org 2.6.16 tag. Based on handhelds-pxa-2.6_2.6.15-hh0.bb. --- packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb diff --git a/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb b/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb new file mode 100644 index 0000000000..555ec411ee --- /dev/null +++ b/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb @@ -0,0 +1,40 @@ +SECTION = "kernel" +DESCRIPTION = "handhelds.org Linux kernel for PXA based devices." +MAINTAINER = "Greg Gilbert " +LICENSE = "GPL" + +DEFAULT_PREFERENCE = "-1" + +COMPATIBLE_HOST = "arm.*-linux" +COMPATIBLE_MACHINE = '(h3900|h2200|h4000|ipaq-pxa270)' + +FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/handhelds-pxa-${PV}" + +SRC_URI = "${HANDHELDS_CVS};module=linux/kernel26;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \ + file://ide_not_removable-r0.patch;patch=1 \ + file://block-pio.patch;patch=1 \ + file://defconfig" + +S = "${WORKDIR}/kernel26" + +inherit kernel + +K_MAJOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[0]}" +K_MINOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[1]}" +K_MICRO = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[2]}" +HHV = "${@bb.data.getVar('PV',d,1).split('-')[1].split('hh')[-1]}" + +KERNEL_PRIORITY = "${@'%d' % (int(bb.data.getVar('K_MAJOR',d,1)) * 100000000 + int(bb.data.getVar('K_MINOR',d,1)) * 1000000 + int(bb.data.getVar('K_MICRO',d,1)) * 10000 + float(bb.data.getVar('HHV',d,1)))}" +do_configure() { + install -m 0644 ${WORKDIR}/defconfig ${S}/.config || die "No default configuration for ${MACHINE} available." + yes '' | oe_runmake oldconfig +} + +do_deploy() { + install -d ${DEPLOY_DIR_IMAGE} + install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${PV}-${MACHINE}-${DATETIME} +} + +do_deploy[dirs] = "${S}" + +addtask deploy before do_build after do_compile -- cgit v1.2.3 From b0e7d9796b0affcd3bf49987f4965a527cb0e5a9 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 30 Aug 2006 10:22:42 +0000 Subject: hh-pxa-2.6 2.6.16 hh5: unbreak do_configure for EABI, add proper COMPATIBLE_MACHINES and do a version check for good measure --- packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb | 43 +++++++++++++++++++++----- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb b/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb index 555ec411ee..a5cc4073e4 100644 --- a/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb +++ b/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb @@ -1,33 +1,60 @@ SECTION = "kernel" DESCRIPTION = "handhelds.org Linux kernel for PXA based devices." -MAINTAINER = "Greg Gilbert " LICENSE = "GPL" -DEFAULT_PREFERENCE = "-1" - COMPATIBLE_HOST = "arm.*-linux" -COMPATIBLE_MACHINE = '(h3900|h2200|h4000|ipaq-pxa270)' +COMPATIBLE_MACHINE = '(h3900|h2200|h4000|h5xxx|htcuniversal|ipaq-pxa270)' FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/handhelds-pxa-${PV}" SRC_URI = "${HANDHELDS_CVS};module=linux/kernel26;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \ - file://ide_not_removable-r0.patch;patch=1 \ - file://block-pio.patch;patch=1 \ file://defconfig" S = "${WORKDIR}/kernel26" inherit kernel +FILES_kernel-image_ipaq-pxa270 = "" +ALLOW_EMPTY_ipaq_pxa270 = 1 +FILES_kernel-image_htcuniversal = "" +ALLOW_EMPTY_htcuniversal = 1 + + + K_MAJOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[0]}" K_MINOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[1]}" K_MICRO = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[2]}" HHV = "${@bb.data.getVar('PV',d,1).split('-')[1].split('hh')[-1]}" KERNEL_PRIORITY = "${@'%d' % (int(bb.data.getVar('K_MAJOR',d,1)) * 100000000 + int(bb.data.getVar('K_MINOR',d,1)) * 1000000 + int(bb.data.getVar('K_MICRO',d,1)) * 10000 + float(bb.data.getVar('HHV',d,1)))}" + do_configure() { - install -m 0644 ${WORKDIR}/defconfig ${S}/.config || die "No default configuration for ${MACHINE} available." - yes '' | oe_runmake oldconfig + + if [ `grep EXTRAVERSION Makefile | grep hh | awk '{print $3}' | sed s/-hh//` != ${HHV} ]; then + die "-hh version mismatch" + fi + + rm -f ${S}/.config + + if [ ! -e ${WORKDIR}/defconfig ]; then + die "No default configuration for ${MACHINE} available." + fi + + + if [ "${TARGET_OS}" == "linux-gnueabi" ]; then + echo "CONFIG_AEABI=y" >> ${S}/.config + echo "CONFIG_OABI_COMPAT=y" >> ${S}/.config + else + echo "# CONFIG_AEABI is not set" >> ${S}/.config + echo "# CONFIG_OABI_COMPAT is not set" >> ${S}/.config + fi + + sed -e '/CONFIG_AEABI/d' \ + -e '/CONFIG_OABI_COMPAT=/d' \ + '${WORKDIR}/defconfig' >>'${S}/.config' + + yes '' | oe_runmake oldconfig + } do_deploy() { -- cgit v1.2.3 From d3be917a564f3aee7ee7ad8e09e9edab7929867a Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 30 Aug 2006 11:15:50 +0000 Subject: horizon: add cvs version of this cool sketch toy * still has /media/mmc1/horizon hardcoded --- packages/horizon/.mtn2git_empty | 0 packages/horizon/files/.mtn2git_empty | 0 packages/horizon/files/makefile.patch | 34 ++++++++++++++++++++++++++++++++++ packages/horizon/horizon_cvs.bb | 27 +++++++++++++++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 packages/horizon/.mtn2git_empty create mode 100644 packages/horizon/files/.mtn2git_empty create mode 100644 packages/horizon/files/makefile.patch create mode 100644 packages/horizon/horizon_cvs.bb diff --git a/packages/horizon/.mtn2git_empty b/packages/horizon/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/horizon/files/.mtn2git_empty b/packages/horizon/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/horizon/files/makefile.patch b/packages/horizon/files/makefile.patch new file mode 100644 index 0000000000..33f341ef08 --- /dev/null +++ b/packages/horizon/files/makefile.patch @@ -0,0 +1,34 @@ +--- /tmp/Makefile 2006-08-30 12:51:56.000000000 +0200 ++++ horizon/src/Makefile 2006-08-30 12:53:03.025780000 +0200 +@@ -2,12 +2,11 @@ + + all: .depend $(BINARY) + +-CFLAGS = -g -O2 -Wall -Werror \ +- -I/usr/X11R6/include \ ++HCFLAGS = -g -O2 -Wall -Werror \ + `sdl-config --cflags` \ + `pkg-config --cflags glib-2.0 gobject-2.0 libpng` \ + -I. +-LDFLAGS = -L/usr/X11R6/lib -lX11 \ ++HLDFLAGS = -lX11 \ + `sdl-config --libs` \ + `pkg-config --libs glib-2.0 gobject-2.0 libpng` \ + -ljpeg +@@ -16,7 +15,7 @@ + OBJS = $(CFILES:.c=.o) + + $(BINARY): $(OBJS) +- $(CC) *.o */*.o -o $@ $(LDFLAGS) ++ $(CC) *.o */*.o -o $@ $(LDFLAGS) $(HLDFLAGS) + + clean: + rm -f $(OBJS) $(BINARY) *.o *~ */*~ */*/*~ .depend +@@ -35,6 +34,6 @@ + ./$(BINARY) /tmp/horizon + + .depend: *.[ch] */*.[ch] +- $(CC) -M $(CFLAGS) */*.c *.c > .depend ++ $(CC) -M $(CFLAGS) $(HCFLAGS) */*.c *.c > .depend + + include .depend diff --git a/packages/horizon/horizon_cvs.bb b/packages/horizon/horizon_cvs.bb new file mode 100644 index 0000000000..d83fbf9868 --- /dev/null +++ b/packages/horizon/horizon_cvs.bb @@ -0,0 +1,27 @@ +DESCRIPTION = "Horizon is a sketchbook application for tablet devices." +LICENSE = "GPLv2" + +DEPENDS = "glib-2.0 libpng jpeg virtual/libsdl" + +SRC_URI = "cvs://anonymous@anoncvs.gnome.org/cvs/gnome;module=horizon \ + file://makefile.patch;patch=1" + +inherit pkgconfig binconfig + +S = "${WORKDIR}/horizon" +PV = "0.37+cvs${SRCDATE}" + +PARALLEL_MAKE = "" + +CFLAGS += " -I${STAGING_INCDIR} -I${STAGING_INCDIR}/SDL -I. -Isrc -L${STAGING_LIBDIR} `PKG_CONFIG_PATH=${STAGING_DATADIR}/pkgconfig pkg-config --cflags glib-2.0 gobject-2.0 libpng`" + +do_compile() { + #yes, this is a hack to work around a faulty makefile + oe_runmake horizon +} + +do_install() { + install -d ${D}${bindir} + install -m 755 horizon ${D}${bindir} +} + -- cgit v1.2.3 From 36b05076d6f41c4301454048929aa2c8b42718f7 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Wed, 30 Aug 2006 13:22:23 +0000 Subject: linux-openzaurus: added patches from mikearthur to fix TS on tosa --- .../linux-openzaurus-2.6.17/tosa-lcdnoise-r0.patch | 157 ++++++++++++++++ .../wm97xx-lcdnoise-r0.patch | 208 +++++++++++++++++++++ packages/linux/linux-openzaurus_2.6.17.bb | 6 +- 3 files changed, 369 insertions(+), 2 deletions(-) create mode 100644 packages/linux/linux-openzaurus-2.6.17/tosa-lcdnoise-r0.patch create mode 100644 packages/linux/linux-openzaurus-2.6.17/wm97xx-lcdnoise-r0.patch diff --git a/packages/linux/linux-openzaurus-2.6.17/tosa-lcdnoise-r0.patch b/packages/linux/linux-openzaurus-2.6.17/tosa-lcdnoise-r0.patch new file mode 100644 index 0000000000..cb014fb8bc --- /dev/null +++ b/packages/linux/linux-openzaurus-2.6.17/tosa-lcdnoise-r0.patch @@ -0,0 +1,157 @@ +Index: linux-tosa/arch/arm/mach-pxa/tosa.c +=================================================================== +--- linux-tosa.orig/arch/arm/mach-pxa/tosa.c 2006-08-29 16:52:59.000000000 +0100 ++++ linux-tosa/arch/arm/mach-pxa/tosa.c 2006-08-29 16:55:25.959706776 +0100 +@@ -2,6 +2,7 @@ + * Support for Sharp SL-C6000x PDAs + * Model: (Tosa) + * ++ * Copyright (c) 2006 Wolfson Microelectronics PLC. + * Copyright (c) 2005 Dirk Opfer + * + * Based on code written by Sharp/Lineo for 2.4 kernels +@@ -46,6 +47,8 @@ + #include + #include + ++#include ++ + #include "generic.h" + + /* +@@ -428,6 +431,16 @@ + }, + }; + ++ ++/* ++ * Tosa Touchscreen device ++ */ ++ ++static struct wm97xx_machinfo tosa_ts_machinfo = { ++ .get_hsync_time = tosa_get_hsync_time, ++ .wait_hsync = tosa_wait_hsync, ++}; ++ + /* + * Tosa Blueooth + */ +@@ -457,6 +470,7 @@ + GPSR(TOSA_GPIO_ON_RESET) = GPIO_bit(TOSA_GPIO_ON_RESET); + + mdelay(1000); ++ wm97xx_unset_machinfo(); + } + + static void tosa_restart(void) +@@ -501,6 +515,8 @@ + platform_scoop_config = &tosa_pcmcia_config; + + platform_add_devices(devices, ARRAY_SIZE(devices)); ++ ++ wm97xx_set_machinfo(&tosa_ts_machinfo); + } + + static void __init fixup_tosa(struct machine_desc *desc, +Index: linux-tosa/arch/arm/mach-pxa/tosa_lcd.c +=================================================================== +--- linux-tosa.orig/arch/arm/mach-pxa/tosa_lcd.c 2006-08-29 16:52:59.000000000 +0100 ++++ linux-tosa/arch/arm/mach-pxa/tosa_lcd.c 2006-08-29 16:55:32.818664056 +0100 +@@ -1,6 +1,7 @@ + /* + * LCD / Backlight control code for Sharp SL-6000x (tosa) + * ++ * Copyright (c) 2006 Wolfson Microelectronics PLC. + * Copyright (c) 2005 Dirk Opfer + * + * This program is free software; you can redistribute it and/or modify +@@ -59,6 +60,8 @@ + static struct ssp_dev tosa_nssp_dev; + static struct ssp_state tosa_nssp_state; + static spinlock_t tosa_nssp_lock; ++static int blanked; ++static unsigned long hsync_time; + + static unsigned short normal_i2c[] = { + DAC_BASE, +@@ -130,6 +133,17 @@ + pxa_nssp_output(TG_GPOSR,0x02); /* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */ + } + ++static unsigned long calc_hsync_time(const struct fb_videomode *mode) { ++ /* The 25 and 44 'magic numbers' are from Sharp's 2.4 patches */ ++ if (mode->yres == 640) { ++ return 25; ++ } ++ if (mode->yres == 320) { ++ return 44; ++ } ++ return 0; ++} ++ + static void tosa_lcd_tg_on(struct device *dev, const struct fb_videomode *mode) + { + const int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR; +@@ -154,6 +168,8 @@ + /* set common voltage */ + i2c_smbus_write_byte_data(tosa_i2c_dac, DAC_CH1, comadj); + ++ blanked = 0; ++ hsync_time = calc_hsync_time(mode); + } + + static void tosa_lcd_tg_off(struct device *dev) +@@ -172,6 +188,8 @@ + + /* L3V Off */ + reset_scoop_gpio( &tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC3693_L3V_ON); ++ ++ blanked = 1; + } + + static int tosa_detect_client(struct i2c_adapter* adapter, int address, int kind) { +@@ -238,6 +256,23 @@ + return 0; + } + ++unsigned long tosa_get_hsync_time(void) ++{ ++/* This method should eventually contain the correct algorithm for calculating ++ the hsync_time */ ++ if (blanked) ++ return 0; ++ else ++ return hsync_time; ++} ++ ++void tosa_wait_hsync(void) ++{ ++ /* Waits for a rising edge on the VGA line */ ++ while((GPLR(TOSA_GPIO_VGA_LINE) & GPIO_bit(TOSA_GPIO_VGA_LINE)) == 0); ++ while((GPLR(TOSA_GPIO_VGA_LINE) & GPIO_bit(TOSA_GPIO_VGA_LINE)) != 0); ++} ++ + static struct i2c_driver tosa_driver={ + .id = TOSA_LCD_I2C_DEVICEID, + .attach_adapter = tosa_attach_adapter, +Index: linux-tosa/include/asm-arm/arch-pxa/tosa.h +=================================================================== +--- linux-tosa.orig/include/asm-arm/arch-pxa/tosa.h 2006-08-29 16:52:59.000000000 +0100 ++++ linux-tosa/include/asm-arm/arch-pxa/tosa.h 2006-08-29 16:55:12.442761664 +0100 +@@ -1,6 +1,7 @@ + /* + * Hardware specific definitions for Sharp SL-C6000x series of PDAs + * ++ * Copyright (c) 2006 Wolfson Microelectronics PLC. + * Copyright (c) 2005 Dirk Opfer + * + * Based on Sharp's 2.4 kernel patches +@@ -187,4 +188,8 @@ + extern struct platform_device tosascoop_jc_device; + extern struct platform_device tosascoop_device; + extern struct platform_device tc6393_device; ++ ++unsigned long tosa_get_hsync_time(void); ++void tosa_wait_hsync(void); ++ + #endif /* _ASM_ARCH_TOSA_H_ */ diff --git a/packages/linux/linux-openzaurus-2.6.17/wm97xx-lcdnoise-r0.patch b/packages/linux/linux-openzaurus-2.6.17/wm97xx-lcdnoise-r0.patch new file mode 100644 index 0000000000..191de3af22 --- /dev/null +++ b/packages/linux/linux-openzaurus-2.6.17/wm97xx-lcdnoise-r0.patch @@ -0,0 +1,208 @@ +Index: linux-tosa/drivers/input/touchscreen/wm9712.c +=================================================================== +--- linux-tosa.orig/drivers/input/touchscreen/wm9712.c 2006-08-29 16:52:36.008543280 +0100 ++++ linux-tosa/drivers/input/touchscreen/wm9712.c 2006-08-29 16:52:50.923275896 +0100 +@@ -1,7 +1,7 @@ + /* + * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs. + * +- * Copyright 2003, 2004, 2005 Wolfson Microelectronics PLC. ++ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com + * Parts Copyright : Ian Molton +@@ -13,6 +13,12 @@ + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * ++ * Revision history ++ * 4th Jul 2005 Initial version. ++ * 29th Aug 2006 Mike Arthur ++ * Added fixes for Sharp SL-6000 (Tosa) LCD noise causing ++ * touchscreen interference. ++ * + */ + + #include +@@ -28,6 +34,10 @@ + #define WM9705_VERSION "0.60" + #define DEFAULT_PRESSURE 0xb0c0 + ++#define CCNT(a) asm volatile ("mrc p14, 0, %0, C1, C1, 0" : "=r"(a)) ++#define CCNT_ON() asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(1)) ++#define CCNT_OFF() asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(1)) ++ + /* + * Debug + */ +@@ -243,6 +253,36 @@ + return wm->dig[2] & WM9712_PDEN; + } + ++ ++#ifdef CONFIG_MACH_TOSA ++/* On the Sharp SL-6000 (Tosa), due to a noisy LCD, we need to perform a wait ++ * before sampling the Y axis of the touchscreen */ ++static inline void wm9712_lcd_sync_on(struct wm97xx* wm, int adcsel) { ++ unsigned long timer1 = 0, timer2 = 0, wait_time = 0; ++ if (adcsel == WM97XX_ADCSEL_Y) { ++ wait_time = wm97xx_calc_lcd_waittime(wm); ++ ++ CCNT_ON(); ++ ++ if (wait_time) { ++ /* wait for LCD rising edge */ ++ wm_machinfo->wait_hsync(); ++ /* get clock */ ++ CCNT(timer1); ++ CCNT(timer2); ++ ++ while ((timer2 - timer1) < wait_time) { ++ CCNT(timer2); ++ } ++ } ++ } ++} ++ ++static inline void wm9712_lcd_sync_off(void) { ++ CCNT_OFF(); ++} ++#endif ++ + /* + * Read a sample from the WM9712 adc in polling mode. + */ +@@ -260,6 +300,9 @@ + /* set up digitiser */ + if (adcsel & 0x8000) + adcsel = ((adcsel & 0x7fff) + 3) << 12; ++ #ifdef CONFIG_MACH_TOSA ++ wm9712_lcd_sync_on(wm, adcsel); ++ #endif + wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, adcsel | WM97XX_POLL | WM97XX_DELAY(delay)); + + /* wait 3 AC97 time slots + delay for conversion */ +@@ -282,6 +325,10 @@ + + *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); + ++ #ifdef CONFIG_MACH_TOSA ++ wm9712_lcd_sync_off(); ++ #endif ++ + /* check we have correct sample */ + if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) { + dbg ("adc wrong sample, read %x got %x", adcsel, +@@ -303,11 +350,12 @@ + static int wm9712_poll_touch(struct wm97xx* wm, struct wm97xx_data *data) + { + int rc; +- + if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X, &data->x)) != RC_VALID) + return rc; ++ + if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y)) != RC_VALID) + return rc; ++ + if (pil && !five_wire) { + if ((rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p)) != RC_VALID) + return rc; +Index: linux-tosa/drivers/input/touchscreen/wm97xx-core.c +=================================================================== +--- linux-tosa.orig/drivers/input/touchscreen/wm97xx-core.c 2006-08-29 16:52:36.008543280 +0100 ++++ linux-tosa/drivers/input/touchscreen/wm97xx-core.c 2006-08-29 16:52:50.924275744 +0100 +@@ -2,7 +2,7 @@ + * wm97xx-core.c -- Touch screen driver core for Wolfson WM9705, WM9712 + * and WM9713 AC97 Codecs. + * +- * Copyright 2003, 2004, 2005 Wolfson Microelectronics PLC. ++ * Copyright 2003, 2004, 2005, 2006 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com + * Parts Copyright : Ian Molton +@@ -67,6 +67,9 @@ + * GPIOs) and 2.6 power management. + * 29th Nov 2004 Added WM9713 support. + * 4th Jul 2005 Moved codec specific code out to seperate files. ++ * 29th Aug 2006 Mike Arthur ++ * Added fixes for Sharp SL-6000 (Tosa) LCD noise causing ++ * touchscreen interference. + */ + + #include +@@ -94,6 +97,7 @@ + static DECLARE_MUTEX(gpio_sem); + static LIST_HEAD(wm97xx_misc_list); + static struct wm97xx* wm_codec = NULL; ++struct wm97xx_machinfo *wm_machinfo; + + /* + * WM97xx - enable/disable AUX ADC sysfs +@@ -832,6 +836,23 @@ + mdev->remove(wm_codec); + } + ++#ifdef CONFIG_MACH_TOSA ++/* On the Sharp SL-6000 (Tosa), due to a noisy LCD, we need to perform a wait ++ * before sampling the Y axis of the touchscreen */ ++unsigned long wm97xx_calc_lcd_waittime(struct wm97xx *wm) { ++ unsigned long hsync_time = wm_machinfo->get_hsync_time(); ++ return hsync_time; ++} ++ ++void wm97xx_set_machinfo(struct wm97xx_machinfo *machinfo) { ++ wm_machinfo = machinfo; ++} ++ ++void wm97xx_unset_machinfo() { ++ wm_machinfo = NULL; ++} ++#endif ++ + static struct device_driver wm97xx_driver = { + .name = "ac97", + .bus = &ac97_bus_type, +@@ -861,6 +882,9 @@ + EXPORT_SYMBOL_GPL(wm97xx_reg_write); + EXPORT_SYMBOL_GPL(wm97xx_register_misc_dev); + EXPORT_SYMBOL_GPL(wm97xx_unregister_misc_dev); ++EXPORT_SYMBOL_GPL(wm97xx_calc_lcd_waittime); ++EXPORT_SYMBOL_GPL(wm97xx_set_machinfo); ++EXPORT_SYMBOL_GPL(wm97xx_unset_machinfo); + + module_init(wm97xx_init); + module_exit(wm97xx_exit); +Index: linux-tosa/include/linux/wm97xx.h +=================================================================== +--- linux-tosa.orig/include/linux/wm97xx.h 2006-08-29 16:52:36.008543280 +0100 ++++ linux-tosa/include/linux/wm97xx.h 2006-08-29 16:52:50.924275744 +0100 +@@ -207,6 +207,7 @@ + + struct wm97xx; + extern struct wm97xx_codec_drv wm97xx_codec; ++extern struct wm97xx_machinfo *wm_machinfo; + + /* + * Codec driver interface - allows mapping to WM9705/12/13 and newer codecs +@@ -253,6 +254,11 @@ + struct list_head list; + }; + ++struct wm97xx_machinfo { ++ unsigned long (*get_hsync_time)(void); ++ void (*wait_hsync)(void); ++}; ++ + int wm97xx_register_misc_dev(struct wm97xx_misc_dev* mdev); + void wm97xx_unregister_misc_dev(struct wm97xx_misc_dev* mdev); + +@@ -281,4 +287,9 @@ + int wm97xx_acc_startup(struct wm97xx* wm); + void wm97xx_acc_shutdown(struct wm97xx* wm); + ++ ++unsigned long wm97xx_calc_lcd_waittime(struct wm97xx *wm); ++void wm97xx_set_machinfo(struct wm97xx_machinfo *machinfo); ++void wm97xx_unset_machinfo(void); ++ + #endif diff --git a/packages/linux/linux-openzaurus_2.6.17.bb b/packages/linux/linux-openzaurus_2.6.17.bb index c7f1f21618..ef03c0e434 100644 --- a/packages/linux/linux-openzaurus_2.6.17.bb +++ b/packages/linux/linux-openzaurus_2.6.17.bb @@ -1,6 +1,6 @@ require linux-openzaurus.inc -PR = "r20" +PR = "r21" # Handy URLs # git://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git \ @@ -115,7 +115,9 @@ SRC_URI_append_tosa = "\ ${DOSRC}/sharpsl-pm-postresume-r0.patch;patch=1 \ ${DOSRC}/wm97xx-dig-restore-r0.patch;patch=1 \ ${DOSRC}/wm97xx-miscdevs-resume-r0.patch;patch=1 \ - ${DOSRC}/wm9712-reset-loop-r1.patch;patch=1" + ${DOSRC}/wm9712-reset-loop-r1.patch;patch=1 \ + file://tosa-lcdnoise-r0.patch;patch=1 \ + file://wm97xx-lcdnoise-r0.patch;patch=1 " # ${DOSRC}/tosa-asoc-r1.patch;patch=1 " S = "${WORKDIR}/linux-2.6.17" -- cgit v1.2.3 From 5c72e2e5ecf750ebd5893ccba10cc74c2ee6d1db Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 30 Aug 2006 14:09:39 +0000 Subject: libx11: bump PR to keep up with diet-x11 --- packages/xorg-lib/libx11_X11R7.1-1.0.1.bb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/xorg-lib/libx11_X11R7.1-1.0.1.bb b/packages/xorg-lib/libx11_X11R7.1-1.0.1.bb index b31ed72998..2f4a5706d5 100644 --- a/packages/xorg-lib/libx11_X11R7.1-1.0.1.bb +++ b/packages/xorg-lib/libx11_X11R7.1-1.0.1.bb @@ -1,5 +1,7 @@ require xorg-lib-common.inc +PR = "r1" + DESCRIPTION = "Base X libs." DEPENDS += " bigreqsproto xproto xextproto xtrans libxau xcmiscproto \ -- cgit v1.2.3 From 835bbbbe1609357517e6cc3f38a0a6be8e3aa450 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Wed, 30 Aug 2006 14:14:03 +0000 Subject: ltrace: add mvista-toolchain specific version, fix building w/ gnueabi --- packages/ltrace/files/.mtn2git_empty | 0 packages/ltrace/files/mvc-toolchain.patch | 32 +++++++++++++++++++++++++++++++ packages/ltrace/ltrace-mvc_0.3.36.bb | 5 +++++ packages/ltrace/ltrace_0.3.36.bb | 12 +++++++----- 4 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 packages/ltrace/files/.mtn2git_empty create mode 100644 packages/ltrace/files/mvc-toolchain.patch create mode 100644 packages/ltrace/ltrace-mvc_0.3.36.bb diff --git a/packages/ltrace/files/.mtn2git_empty b/packages/ltrace/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/ltrace/files/mvc-toolchain.patch b/packages/ltrace/files/mvc-toolchain.patch new file mode 100644 index 0000000000..886759dfbf --- /dev/null +++ b/packages/ltrace/files/mvc-toolchain.patch @@ -0,0 +1,32 @@ +diff -ru ltrace-0.3.36/sysdeps/linux-gnu/arm/arch.h ltrace-0.3.36-mvc/sysdeps/linux-gnu/arm/arch.h +--- ltrace-0.3.36/sysdeps/linux-gnu/arm/arch.h 2004-11-09 20:25:15.000000000 +0800 ++++ ltrace-0.3.36-mvc/sysdeps/linux-gnu/arm/arch.h 2005-12-17 02:00:34.000000000 +0800 +@@ -1,4 +1,5 @@ +-#define BREAKPOINT_VALUE { 0x01, 0x00, 0x9f, 0xef } ++#define BREAKPOINT_VALUE { 0xfe, 0xde, 0xff, 0xe7} ++ + #define BREAKPOINT_LENGTH 4 + #define DECR_PC_AFTER_BREAK 0 + +diff -ru ltrace-0.3.36/sysdeps/linux-gnu/arm/plt.c ltrace-0.3.36-mvc/sysdeps/linux-gnu/arm/plt.c +--- ltrace-0.3.36/sysdeps/linux-gnu/arm/plt.c 2004-11-09 20:25:15.000000000 +0800 ++++ ltrace-0.3.36-mvc/sysdeps/linux-gnu/arm/plt.c 2005-12-19 08:08:54.000000000 +0800 +@@ -5,5 +5,5 @@ + GElf_Addr + arch_plt_sym_val (struct ltelf *lte, size_t ndx, GElf_Rela *rela) + { +- return lte->plt_addr + 20 + ndx * 12; ++ return lte->plt_addr + 16 + ndx * 16; + } +diff -ru ltrace-0.3.36/wait_for_something.c ltrace-0.3.36-mvc/wait_for_something.c +--- ltrace-0.3.36/wait_for_something.c 2004-06-14 23:55:50.000000000 +0800 ++++ ltrace-0.3.36-mvc/wait_for_something.c 2005-12-17 02:21:15.000000000 +0800 +@@ -82,7 +82,7 @@ + event.thing = LT_EV_UNKNOWN; + return &event; + } +- if (WSTOPSIG(status) != SIGTRAP) { ++ if (WSTOPSIG(status) != SIGTRAP && WSTOPSIG(status) != SIGILL) { + event.thing = LT_EV_SIGNAL; + event.e_un.signum = WSTOPSIG(status); + return &event; diff --git a/packages/ltrace/ltrace-mvc_0.3.36.bb b/packages/ltrace/ltrace-mvc_0.3.36.bb new file mode 100644 index 0000000000..66a613fe2e --- /dev/null +++ b/packages/ltrace/ltrace-mvc_0.3.36.bb @@ -0,0 +1,5 @@ +require ltrace_${PV}.bb + +DEFAULT_PREFERENCE = "-1" + +SRC_URI += "file://mvc-toolchain.patch;patch=1" diff --git a/packages/ltrace/ltrace_0.3.36.bb b/packages/ltrace/ltrace_0.3.36.bb index ae2c865f72..1e2ff5394b 100644 --- a/packages/ltrace/ltrace_0.3.36.bb +++ b/packages/ltrace/ltrace_0.3.36.bb @@ -3,12 +3,10 @@ HOMEPAGE = "http://packages.debian.org/unstable/utils/ltrace.html" SECTION = "devel" DEPENDS = "libelf" LICENSE = "GPL" -PR = "r1" - -SRC_URI = "ftp://ftp.debian.org/debian/pool/main/l/ltrace/ltrace_0.3.36.orig.tar.gz\ - ftp://ftp.debian.org/debian/pool/main/l/ltrace/ltrace_0.3.36-2.diff.gz;patch=1\ - file://mvc-toolchain.patch;patch=1" +PR = "r2" +SRC_URI = "ftp://ftp.debian.org/debian/pool/main/l/ltrace/ltrace_0.3.36.orig.tar.gz \ + ftp://ftp.debian.org/debian/pool/main/l/ltrace/ltrace_0.3.36-2.diff.gz;patch=1" inherit autotools PARALLEL_MAKE = "" @@ -20,6 +18,10 @@ EXTRA_OEMAKE = "ARCH=${TARGET_ARCH} \ export TARGET_CFLAGS = "${SELECTED_OPTIMIZATION} -isystem ${STAGING_DIR}/${TARGET_SYS}/include" +do_configure_prepend() { + ln -sf ./linux-gnu sysdeps/linux-gnueabi +} + do_compile() { oe_runmake LDFLAGS=${TARGET_LDFLAGS} LIBS="-lsupc++ -liberty -Wl,-Bstatic -lelf -Wl,-Bdynamic" ${EXTRA_OEMAKE} } -- cgit v1.2.3 From f1fac8939e88ca25e8227a6e97393eb216abd738 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Wed, 30 Aug 2006 14:35:19 +0000 Subject: lsof: remove 4.74, remove 4.75, add 4.76, add gnueabi support --- packages/lsof/lsof_4.74.bb | 38 -------------------------------------- packages/lsof/lsof_4.75.bb | 38 -------------------------------------- packages/lsof/lsof_4.76.bb | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 76 deletions(-) delete mode 100644 packages/lsof/lsof_4.74.bb delete mode 100644 packages/lsof/lsof_4.75.bb create mode 100644 packages/lsof/lsof_4.76.bb diff --git a/packages/lsof/lsof_4.74.bb b/packages/lsof/lsof_4.74.bb deleted file mode 100644 index 0562a57fb1..0000000000 --- a/packages/lsof/lsof_4.74.bb +++ /dev/null @@ -1,38 +0,0 @@ -SECTION = "console/utils" -DESCRIPTION = "Lsof is a Unix-specific diagnostic \ -tool. Its name stands for LiSt Open Files, and it \ -does just that." -LICENSE = "BSD" - -SRC_URI = "ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/OLD/lsof_${PV}.tar.bz2" -LOCALSRC = "file://${WORKDIR}/lsof_${PV}/lsof_${PV}_src.tar" -S = "${WORKDIR}/lsof_${PV}_src" - -python do_unpack () { - bb.build.exec_func('base_do_unpack', d) - src_uri = bb.data.getVar('SRC_URI', d) - bb.data.setVar('SRC_URI', '${LOCALSRC}', d) - bb.build.exec_func('base_do_unpack', d) - bb.data.setVar('SRC_URI', src_uri, d) -} - -LSOF_OS = "${TARGET_OS}" -LSOF_OS_linux-uclibc = "linux" - -do_configure () { - ./Configure ${LSOF_OS} -} - -export I = "${STAGING_INCDIR}" -export L = "${STAGING_INCDIR}" -export EXTRA_OEMAKE = "" - -do_compile () { - oe_runmake 'CC=${CC}' 'CFGL=${LDFLAGS} -L./lib -llsof' 'DEBUG=' 'INCL=${CFLAGS}' -} - -do_install () { - install -d ${D}${sbindir} ${D}${mandir}/man8 - install -m 4755 lsof ${D}${sbindir}/lsof - install -m 0644 lsof.8 ${D}${mandir}/man8/lsof.8 -} diff --git a/packages/lsof/lsof_4.75.bb b/packages/lsof/lsof_4.75.bb deleted file mode 100644 index 0562a57fb1..0000000000 --- a/packages/lsof/lsof_4.75.bb +++ /dev/null @@ -1,38 +0,0 @@ -SECTION = "console/utils" -DESCRIPTION = "Lsof is a Unix-specific diagnostic \ -tool. Its name stands for LiSt Open Files, and it \ -does just that." -LICENSE = "BSD" - -SRC_URI = "ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/OLD/lsof_${PV}.tar.bz2" -LOCALSRC = "file://${WORKDIR}/lsof_${PV}/lsof_${PV}_src.tar" -S = "${WORKDIR}/lsof_${PV}_src" - -python do_unpack () { - bb.build.exec_func('base_do_unpack', d) - src_uri = bb.data.getVar('SRC_URI', d) - bb.data.setVar('SRC_URI', '${LOCALSRC}', d) - bb.build.exec_func('base_do_unpack', d) - bb.data.setVar('SRC_URI', src_uri, d) -} - -LSOF_OS = "${TARGET_OS}" -LSOF_OS_linux-uclibc = "linux" - -do_configure () { - ./Configure ${LSOF_OS} -} - -export I = "${STAGING_INCDIR}" -export L = "${STAGING_INCDIR}" -export EXTRA_OEMAKE = "" - -do_compile () { - oe_runmake 'CC=${CC}' 'CFGL=${LDFLAGS} -L./lib -llsof' 'DEBUG=' 'INCL=${CFLAGS}' -} - -do_install () { - install -d ${D}${sbindir} ${D}${mandir}/man8 - install -m 4755 lsof ${D}${sbindir}/lsof - install -m 0644 lsof.8 ${D}${mandir}/man8/lsof.8 -} diff --git a/packages/lsof/lsof_4.76.bb b/packages/lsof/lsof_4.76.bb new file mode 100644 index 0000000000..d134f38b23 --- /dev/null +++ b/packages/lsof/lsof_4.76.bb @@ -0,0 +1,39 @@ +DESCRIPTION = "Lsof is a Unix-specific diagnostic tool. \ +Its name stands for LiSt Open Files, and it does just that." +SECTION = "devel" +LICENSE = "BSD" +PR = "r0" + +SRC_URI = "ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/OLD/lsof_${PV}.tar.bz2" +LOCALSRC = "file://${WORKDIR}/lsof_${PV}/lsof_${PV}_src.tar" +S = "${WORKDIR}/lsof_${PV}_src" + +python do_unpack () { + bb.build.exec_func('base_do_unpack', d) + src_uri = bb.data.getVar('SRC_URI', d) + bb.data.setVar('SRC_URI', '${LOCALSRC}', d) + bb.build.exec_func('base_do_unpack', d) + bb.data.setVar('SRC_URI', src_uri, d) +} + +LSOF_OS = "${TARGET_OS}" +LSOF_OS_linux-uclibc = "linux" +LSOF_OS_linux-gnueabi = "linux" + +do_configure () { + ./Configure ${LSOF_OS} +} + +export I = "${STAGING_INCDIR}" +export L = "${STAGING_INCDIR}" +export EXTRA_OEMAKE = "" + +do_compile () { + oe_runmake 'CC=${CC}' 'CFGL=${LDFLAGS} -L./lib -llsof' 'DEBUG=' 'INCL=${CFLAGS}' +} + +do_install () { + install -d ${D}${sbindir} ${D}${mandir}/man8 + install -m 4755 lsof ${D}${sbindir}/lsof + install -m 0644 lsof.8 ${D}${mandir}/man8/lsof.8 +} -- cgit v1.2.3 From f9697f0df1fde19b11a0c358ceca01129526cfc6 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 30 Aug 2006 16:51:52 +0000 Subject: angsgrom: make TARET_FPU overridable * put TARGET_FPU="" in conf/machine/include/tune-.conf to build a hardfloat toolchain * mixing soft and hardfloat code is safe, BUT hardfloat binaries still don't run onf FPU-less systems --- conf/distro/include/angstrom.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conf/distro/include/angstrom.inc b/conf/distro/include/angstrom.inc index d9209ad23c..96bc33ede3 100644 --- a/conf/distro/include/angstrom.inc +++ b/conf/distro/include/angstrom.inc @@ -35,7 +35,8 @@ BUILD_OPTIMIZATION = "-Os" CXXFLAGS += "-fvisibility-inlines-hidden" #ARM EABI is softfloat by default, but let's make sure :) -TARGET_FPU_arm = "soft" +#make it overridable for platforms with FPU, like ep93xx or i.mx31 +TARGET_FPU_arm ?= "soft" #Name the generated images in a sane way IMAGE_NAME = "${DISTRO_NAME}-${IMAGE_BASENAME}-${DISTRO_VERSION}-${MACHINE}" -- cgit v1.2.3 From da39c95afb07559e58b1881bff6e6d1d232984e6 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Wed, 30 Aug 2006 19:13:19 +0000 Subject: initscripts: populate-volatile.sh: Add explicit command separators. * There was issue seen when populate-volatile.sh executed something like "mkdir chown" when configuration was not full right. This fixed it. Closes #1355. --- packages/initscripts/initscripts-1.0/populate-volatile.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/initscripts/initscripts-1.0/populate-volatile.sh b/packages/initscripts/initscripts-1.0/populate-volatile.sh index f22bf2fdfe..2c2132209f 100755 --- a/packages/initscripts/initscripts-1.0/populate-volatile.sh +++ b/packages/initscripts/initscripts-1.0/populate-volatile.sh @@ -10,7 +10,7 @@ COREDEF="00_core" create_file() { EXEC=" - touch \"$1\" + touch \"$1\"; chown ${TUSER}.${TGROUP} $1 || echo \"Failed to set owner -${TUSER}- for -$1-.\" >/dev/tty0 2>&1 chmod ${TMODE} $1 || echo \"Failed to set mode -${TMODE}- for -$1-.\" >/dev/tty0 2>&1 " @@ -21,7 +21,7 @@ create_file() { mk_dir() { EXEC=" - mkdir -p \"$1\" + mkdir -p \"$1\"; chown ${TUSER}.${TGROUP} $1 || echo \"Failed to set owner -${TUSER}- for -$1-.\" >/dev/tty0 2>&1 chmod ${TMODE} $1 || echo \"Failed to set mode -${TMODE}- for -$1-.\" >/dev/tty0 2>&1 " -- cgit v1.2.3 From b777f492ed8bfd26d409f31cfafb724f1ed62848 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Wed, 30 Aug 2006 19:17:46 +0000 Subject: handhelds-pxa-2.6_2.6.16-hh5: Add patches from handhelds-pxa-2.6_cvs . --- packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb b/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb index a5cc4073e4..f36e9d2b12 100644 --- a/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb +++ b/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb @@ -8,7 +8,10 @@ COMPATIBLE_MACHINE = '(h3900|h2200|h4000|h5xxx|htcuniversal|ipaq-pxa270)' FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/handhelds-pxa-${PV}" SRC_URI = "${HANDHELDS_CVS};module=linux/kernel26;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \ - file://defconfig" + file://24-hostap_cs_id.diff;patch=1 \ + file://hrw-pcmcia-ids-r2.patch;patch=1 \ + file://hx-iwmmxt.patch;patch=1;maxdate=20060807 \ + file://defconfig" S = "${WORKDIR}/kernel26" -- cgit v1.2.3 From 589f8b60632116adca542320de2b834642dec25f Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 30 Aug 2006 19:24:41 +0000 Subject: hh-pxa-2.6 2.6.16-hh5: remove maxdate from iwmmxt patch --- packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb b/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb index f36e9d2b12..9ddc30a916 100644 --- a/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb +++ b/packages/linux/handhelds-pxa-2.6_2.6.16-hh5.bb @@ -10,7 +10,7 @@ FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/handhelds-pxa-${PV}" SRC_URI = "${HANDHELDS_CVS};module=linux/kernel26;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \ file://24-hostap_cs_id.diff;patch=1 \ file://hrw-pcmcia-ids-r2.patch;patch=1 \ - file://hx-iwmmxt.patch;patch=1;maxdate=20060807 \ + file://hx-iwmmxt.patch;patch=1 \ file://defconfig" S = "${WORKDIR}/kernel26" -- cgit v1.2.3 From ac7135e9c90c73e8c3fab13b7209b8e2f64910e7 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 30 Aug 2006 21:52:52 +0000 Subject: Update openomap distro and omap5912osk machine file with fixes to allow the OSK to boot. Includes changes to the kernel config to add TMPFS to the kernel config. The deployed fstab may need some tweaking still. --- conf/distro/openomap.conf | 3 +- conf/machine/omap5912osk.conf | 4 +- .../linux/linux-omap1-2.6.x+git/.mtn2git_empty | 0 packages/linux/linux-omap1-2.6.x+git/defconfig | 1113 ++++++++++++++++++++ packages/linux/linux-omap1_2.6.x+git.bb | 12 +- 5 files changed, 1125 insertions(+), 7 deletions(-) create mode 100644 packages/linux/linux-omap1-2.6.x+git/.mtn2git_empty create mode 100644 packages/linux/linux-omap1-2.6.x+git/defconfig diff --git a/conf/distro/openomap.conf b/conf/distro/openomap.conf index fb06ca7f47..71690ac62f 100644 --- a/conf/distro/openomap.conf +++ b/conf/distro/openomap.conf @@ -8,10 +8,11 @@ TARGET_FPU ?= "soft" # 2.4 vs 2.6 is a distro decision. MODUTILS = "26" -BOOTSTRAP_EXTRA_RDEPENDS += "udev" PREFERRED_PROVIDER_task-bootstrap = "task-bootstrap" +PREFERRED_PROVIDER_hotplug = "udev" + PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}gcc-initial:gcc-cross-initial" PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}gcc:gcc-cross" PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}g++:gcc-cross" diff --git a/conf/machine/omap5912osk.conf b/conf/machine/omap5912osk.conf index cf9e96ce19..fc17985233 100644 --- a/conf/machine/omap5912osk.conf +++ b/conf/machine/omap5912osk.conf @@ -5,6 +5,8 @@ TARGET_ARCH = "arm" IPKG_EXTRA_ARCHS = "armv5te" +HOTPLUG = "udev" + PREFERRED_PROVIDER_xserver = "xserver-kdrive" PREFERRED_PROVIDER_virtual/kernel = "linux-omap1" PREFERRED_PROVIDERS += "virtual/${TARGET_PREFIX}depmod:module-init-tools-cross" @@ -18,7 +20,7 @@ PREFERRED_VERSION_linux-omap1 = "2.6.x+git" BOOTSTRAP_EXTRA_RDEPENDS += "modutils-collateral" SERIAL_CONSOLE ?= "115200 ttyS0" -EXTRA_IMAGECMD_jffs2 = "--pad --little-endian --eraseblock=0x40000" +EXTRA_IMAGECMD_jffs2 = "--pad --little-endian --eraseblock=0x20000 -n" # PCMCIA Modules #BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-pcmcia-core kernel-module-pcmcia" diff --git a/packages/linux/linux-omap1-2.6.x+git/.mtn2git_empty b/packages/linux/linux-omap1-2.6.x+git/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/linux/linux-omap1-2.6.x+git/defconfig b/packages/linux/linux-omap1-2.6.x+git/defconfig new file mode 100644 index 0000000000..ca2ac4ebd5 --- /dev/null +++ b/packages/linux/linux-omap1-2.6.x+git/defconfig @@ -0,0 +1,1113 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.18-rc4-omap1 +# Wed Aug 30 10:58:22 2006 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# 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" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +CONFIG_ARCH_OMAP=y + +# +# TI OMAP Implementations +# +CONFIG_ARCH_OMAP_OTG=y +CONFIG_ARCH_OMAP1=y +# CONFIG_ARCH_OMAP2 is not set + +# +# OMAP Feature Selections +# +CONFIG_OMAP_RESET_CLOCKS=y +# CONFIG_OMAP_BOOT_TAG is not set +# CONFIG_OMAP_GPIO_SWITCH is not set +CONFIG_OMAP_MUX=y +# CONFIG_OMAP_MUX_DEBUG is not set +CONFIG_OMAP_MUX_WARNINGS=y +# CONFIG_OMAP_STI is not set +CONFIG_OMAP_MCBSP=y +# CONFIG_OMAP_MPU_TIMER is not set +CONFIG_OMAP_32K_TIMER=y +CONFIG_OMAP_32K_TIMER_HZ=128 +# CONFIG_OMAP_DM_TIMER is not set +CONFIG_OMAP_LL_DEBUG_UART1=y +# CONFIG_OMAP_LL_DEBUG_UART2 is not set +# CONFIG_OMAP_LL_DEBUG_UART3 is not set +CONFIG_OMAP_SERIAL_WAKE=y + +# +# OMAP Core Type +# +# CONFIG_ARCH_OMAP730 is not set +# CONFIG_ARCH_OMAP15XX is not set +CONFIG_ARCH_OMAP16XX=y + +# +# OMAP Board Type +# +# CONFIG_MACH_OMAP_INNOVATOR is not set +# CONFIG_MACH_OMAP_H2 is not set +# CONFIG_MACH_OMAP_H3 is not set +CONFIG_MACH_OMAP_OSK=y +# CONFIG_OMAP_OSK_MISTRAL is not set +# CONFIG_MACH_NOKIA770 is not set +# CONFIG_MACH_OMAP_GENERIC is not set + +# +# OMAP CPU Speed +# +# CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER is not set +# CONFIG_OMAP_ARM_216MHZ is not set +CONFIG_OMAP_ARM_192MHZ=y +# CONFIG_OMAP_ARM_168MHZ is not set +# CONFIG_OMAP_ARM_120MHZ is not set +# CONFIG_OMAP_ARM_60MHZ is not set +# CONFIG_OMAP_ARM_30MHZ is not set +# CONFIG_OMAP_DSP is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_IOCTL=y + +# +# PC-card bridges +# +CONFIG_OMAP_CF=y + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_NO_IDLE_HZ=y +CONFIG_HZ=128 +# CONFIG_AEABI is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +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 is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x10400000,8M root=/dev/ram0 rw" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=m +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# 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=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_OMAP_NOR=y +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD_ONENAND_SYNC_READ is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=m +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y +# CONFIG_DM9000 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=y +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +# CONFIG_PPP_ASYNC is not set +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPP_MPPE is not set +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_OMAP=y +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_CS is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_OMAP=y +# CONFIG_OMAP_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_OMAP_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set +CONFIG_I2C_OMAP=y + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_ISP1301_OMAP is not set +CONFIG_TPS65010=y +# CONFIG_SENSORS_TLV320AIC23 is not set +# CONFIG_GPIOEXPANDER_OMAP is not set +# CONFIG_SENSORS_MAX6875 is not set +# 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 +# + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +CONFIG_FB=y +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_OMAP=y +# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set +# CONFIG_FB_OMAP_LCD_MIPID is not set +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set +CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2 +# CONFIG_FB_OMAP_DMA_TUNE is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# Synchronous Serial Interfaces (SSI) +# +CONFIG_OMAP_UWIRE=y +CONFIG_OMAP_TSC2101=y + +# +# CBUS support +# +# CONFIG_CBUS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# 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="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y diff --git a/packages/linux/linux-omap1_2.6.x+git.bb b/packages/linux/linux-omap1_2.6.x+git.bb index 7a5ff66af2..9bc1b7c0a9 100644 --- a/packages/linux/linux-omap1_2.6.x+git.bb +++ b/packages/linux/linux-omap1_2.6.x+git.bb @@ -3,7 +3,8 @@ SECTION = "kernel" DESCRIPTION = "Linux kernel for OMAP processors" LICENSE = "GPL" -SRC_URI = "git://source.mvista.com/git/linux-omap-2.6.git;protocol=git" +SRC_URI = "git://source.mvista.com/git/linux-omap-2.6.git;protocol=git \ + file://defconfig" S = "${WORKDIR}/git" @@ -17,10 +18,11 @@ inherit kernel COMPATIBLE_HOST = 'arm.*-linux' do_configure_prepend() { - if [ "${MACHINE}" == "omap5912osk" ] ; then - oe_runmake omap_osk_5912_defconfig - fi - +# if [ "${MACHINE}" == "omap5912osk" ] ; then +# oe_runmake omap_osk_5912_defconfig +# fi + install -m 0644 ${WORKDIR}/defconfig ${S}/.config + make oldconfig } do_deploy() { -- cgit v1.2.3 From 6d1b2218c91c330a07b02bb49d8db2c10c74aa4c Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 30 Aug 2006 22:23:03 +0000 Subject: task-angstrom-x11: mask of thcrut --- packages/angstrom/task-angstrom-x11.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angstrom/task-angstrom-x11.bb b/packages/angstrom/task-angstrom-x11.bb index 55d644bc15..2e5d55d727 100644 --- a/packages/angstrom/task-angstrom-x11.bb +++ b/packages/angstrom/task-angstrom-x11.bb @@ -113,6 +113,6 @@ RDEPENDS_angstrom-task-sectest := "\ # tcpdump \ kismet \ hydra \ - thcrut \ +# thcrut \ # driftnet \ miniclipboard" -- cgit v1.2.3 From 6bfcdbf0b05a8ea5c02321e44b1b567823e191da Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 31 Aug 2006 08:01:41 +0000 Subject: gpe-bluetooth: #include in main.h, fix for #1373 --- packages/gpe-bluetooth/files/include-sdp_lib.patch | 9 +++++++++ packages/gpe-bluetooth/gpe-bluetooth_0.54.bb | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 packages/gpe-bluetooth/files/include-sdp_lib.patch diff --git a/packages/gpe-bluetooth/files/include-sdp_lib.patch b/packages/gpe-bluetooth/files/include-sdp_lib.patch new file mode 100644 index 0000000000..8ec1ab3af3 --- /dev/null +++ b/packages/gpe-bluetooth/files/include-sdp_lib.patch @@ -0,0 +1,9 @@ +--- gpe-bluetooth-0.54/main.h.orig 2006-08-31 09:49:46.000000000 +0200 ++++ gpe-bluetooth-0.54/main.h 2006-08-31 09:49:48.000000000 +0200 +@@ -1,5 +1,6 @@ + #include + #include ++#include + + struct bt_device + { diff --git a/packages/gpe-bluetooth/gpe-bluetooth_0.54.bb b/packages/gpe-bluetooth/gpe-bluetooth_0.54.bb index b02be325e6..77cf675e21 100644 --- a/packages/gpe-bluetooth/gpe-bluetooth_0.54.bb +++ b/packages/gpe-bluetooth/gpe-bluetooth_0.54.bb @@ -11,6 +11,7 @@ RDEPENDS = "bluez-utils-dbus blueprobe" GPE_TARBALL_SUFFIX= "bz2" inherit gpe autotools -SRC_URI += "file://hciattach-bts.patch;patch=1" +SRC_URI += "file://hciattach-bts.patch;patch=1 \ + file://include-sdp_lib.patch;patch=1" FILES_${PN} += '${datadir}/bluez-pin' -- cgit v1.2.3 From 2b2bb70ca659b9923de0b92d0a9a2cca68ed5d90 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 31 Aug 2006 08:09:44 +0000 Subject: gpe-package: backport search functionality from cvs --- packages/gpe-package/files/search.patch | 313 ++++++++++++++++++++++++++++++++ packages/gpe-package/gpe-package_0.3.bb | 10 +- 2 files changed, 320 insertions(+), 3 deletions(-) create mode 100644 packages/gpe-package/files/search.patch diff --git a/packages/gpe-package/files/search.patch b/packages/gpe-package/files/search.patch new file mode 100644 index 0000000000..2a71c5339f --- /dev/null +++ b/packages/gpe-package/files/search.patch @@ -0,0 +1,313 @@ +--- /tmp/interface.c 2006-08-31 09:49:57.000000000 +0200 ++++ gpe-package-0.3/interface.c 2006-08-31 09:50:20.855780000 +0200 +@@ -27,6 +27,10 @@ + #include + #include + ++#ifdef ENABLE_PCRE ++#include ++#endif ++ + #define _(x) gettext(x) + #define N_(_x) (_x) + +@@ -55,11 +59,8 @@ + #define MI_PACKAGES_APPLY 7 + #define MI_FILTER_INST 8 + #define MI_FILTER_NOTINST 9 +-#define MI_PACKAGES_INFO 10 +- +-#define TREE_SHOW_ALL 0x00 +-#define TREE_SHOW_INST 0x01 +-#define TREE_SHOW_NOTINST 0x02 ++#define MI_FILTER_SEARCH 10 ++#define MI_PACKAGES_INFO 11 + + #define HELPMESSAGE "GPE-Package\nVersion " VERSION \ + "\nGPE frontend for ipkg\n\nflorian@handhelds.org" +@@ -79,7 +80,6 @@ + + static description_t *pkg_info = NULL; + static int pkg_count = 0; +-static int tree_filter = TREE_SHOW_ALL; + + int sock; + static pkcommand_t running_command = CMD_NONE; +@@ -91,10 +91,12 @@ + static GtkWidget *notebook; + static GtkWidget *txLog; + static GtkWidget *treeview; ++static GtkTreeModel *filter; ++static gchar *filter_term = NULL; + static GtkTreeStore *store = NULL; + static GtkToolItem *bApply; + static GtkWidget *miUpdate, *miSysUpgrade, *miSelectLocal, *miApply; +-static GtkWidget *miFilterInst, *miFilterNotInst; ++static GtkWidget *miFilterInst, *miFilterNotInst, *miFilterSearch; + static GtkWidget *sbar; + GtkWidget *fMain; + static GtkWidget *dlgAction = NULL; +@@ -102,10 +104,17 @@ + static GtkTextBuffer *infobuffer = NULL; + static GtkWidget *mMain; + ++#ifdef ENABLE_PCRE ++static gboolean is_regexp; ++#endif + + /* some forwards */ + gboolean get_pending_messages (); + void on_tree_filter_changed(GtkCheckMenuItem *menuitem, gpointer user_data); ++void on_tree_filter_search_changed (GtkCheckMenuItem *menuitem, gpointer user_data); ++gboolean filter_visible_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data); ++void set_filter_term (const gchar *text, gboolean regexp); ++void search_entry_activated (GtkEntry *entry, gpointer user_data); + void create_fMain (void); + void on_select_local(GtkButton *button, gpointer user_data); + void on_packages_update_clicked(GtkButton *button, gpointer user_data); +@@ -125,8 +134,10 @@ + { N_("/Packages/Show Insta_lled"), "", on_tree_filter_changed, MI_FILTER_INST , ""}, + { N_("/Packages/Show _Not Installed"), "", on_tree_filter_changed, MI_FILTER_NOTINST, ""}, + { N_("/_Packages/s2"), NULL , NULL, 0, ""}, +- { N_("/Packages/Show _Info"), " I", on_package_info_clicked, MI_PACKAGES_INFO , ""}, ++ { N_("/Packages/_Search"), " I", on_tree_filter_search_changed, MI_FILTER_SEARCH , ""}, + { N_("/_Packages/s3"), NULL , NULL, 0, ""}, ++ { N_("/Packages/Show _Info"), " I", on_package_info_clicked, MI_PACKAGES_INFO , ""}, ++ { N_("/_Packages/s4"), NULL , NULL, 0, ""}, + { N_("/Packages/_Update lists"), " U", on_packages_update_clicked, MI_PACKAGES_UPDATE , ""}, + { N_("/Packages/Upgrade _System"), "", on_system_update_clicked, MI_PACKAGES_UPGRADE, ""}, + { N_("/_Packages/s3"), NULL , NULL, 0, ""}, +@@ -215,10 +226,10 @@ + GtkWidget * + progress_dialog (gchar * text, GdkPixbuf * pixbuf) + { +-GtkWidget *window; +-GtkWidget *label; +-GtkWidget *image; +-GtkWidget *hbox; ++ GtkWidget *window; ++ GtkWidget *label; ++ GtkWidget *image; ++ GtkWidget *hbox; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + hbox = gtk_hbox_new (FALSE, 0); +@@ -227,6 +238,7 @@ + + gtk_window_set_type_hint (GTK_WINDOW (window), + GDK_WINDOW_TYPE_HINT_DIALOG); ++ gtk_window_set_title (GTK_WINDOW (window), _("Working")); + + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + +@@ -381,9 +393,9 @@ + + void update_tree(void) + { +-guint id; +-int i; +-GtkTreeIter iter; ++ guint id; ++ int i; ++ GtkTreeIter iter; + + id = gtk_statusbar_get_context_id(GTK_STATUSBAR(sbar),"upd"); + gtk_statusbar_push(GTK_STATUSBAR(sbar), +@@ -392,10 +404,6 @@ + gtk_tree_store_clear(GTK_TREE_STORE(store)); + + for (i=0; i= 0) { ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++ } ++#endif ++ ++ if (strstr (pkgname, filter_term)) ++ return TRUE; ++ ++ return FALSE; ++} ++ ++void set_filter_term (const gchar *text, gboolean regexp) ++{ ++ if (filter_term) { ++ g_free (filter_term); ++ } ++ ++ filter_term = g_strdup (text); ++ ++#ifdef ENABLE_PCRE ++ is_regexp = regexp; ++#endif ++ ++ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter)); ++} ++ ++void search_entry_activated (GtkEntry *entry, gpointer user_data) ++{ ++ GtkDialog *dialog = user_data; ++ ++ gtk_dialog_response (dialog, GTK_RESPONSE_ACCEPT); ++} ++ ++void on_tree_filter_search_changed (GtkCheckMenuItem *menuitem, gpointer user_data) ++{ ++ GtkWidget *dialog; ++ GtkWidget *entry; ++ const gchar *text; ++#ifdef ENABLE_PCRE ++ GtkWidget *checkbutton; ++#endif ++ ++ if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (miFilterSearch))) { ++ dialog = gtk_dialog_new_with_buttons (_("Search term:"), ++ GTK_WINDOW (fMain), ++ GTK_DIALOG_DESTROY_WITH_PARENT, ++ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, ++ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, ++ NULL); ++ entry = gtk_entry_new (); ++ g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (search_entry_activated), dialog); ++ gtk_widget_show (entry); ++ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), entry); ++#ifdef ENABLE_PCRE ++ checkbutton = gtk_check_button_new_with_label (_("Regular expression")); ++ gtk_widget_show (checkbutton); ++ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), checkbutton); ++#endif ++ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { ++ text = gtk_entry_get_text (GTK_ENTRY (entry)); ++ if (strlen (text)) { ++#ifdef ENABLE_PCRE ++ set_filter_term (text, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton))); ++#else ++ set_filter_term (text, FALSE); ++#endif ++ } else { ++ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (miFilterSearch), FALSE); ++ } ++ } else { ++ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (miFilterSearch), FALSE); ++ } ++ gtk_widget_destroy (dialog); ++ } else { ++ set_filter_term (NULL, FALSE); ++ } ++ ++ ++} + + void on_about_clicked (GtkWidget * w) + { +@@ -740,9 +871,9 @@ + + void on_package_info_clicked(GtkButton *button, gpointer user_data) + { +-GtkTreeIter iter; +-GtkTreeSelection *sel; +-char *name = NULL; ++ GtkTreeIter iter; ++ GtkTreeSelection *sel; ++ char *name = NULL; + + sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); + +@@ -848,7 +979,7 @@ + selection = gtk_tree_view_get_selection (treeview); + if (gtk_tree_selection_get_selected (selection, NULL, &iter) == FALSE) + return FALSE; +- gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COL_VERSION, &version, -1); ++ gtk_tree_model_get (GTK_TREE_MODEL (filter), &iter, COL_VERSION, &version, -1); + gtk_statusbar_push(GTK_STATUSBAR(sbar),0,version); + + return TRUE; +@@ -882,6 +1013,8 @@ + MI_FILTER_INST); + miFilterNotInst = gtk_item_factory_get_item_by_action(itemfactory, + MI_FILTER_NOTINST); ++ miFilterSearch = gtk_item_factory_get_item_by_action(itemfactory, ++ MI_FILTER_SEARCH); + + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(miFilterInst),TRUE); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(miFilterNotInst),TRUE); +@@ -984,7 +1117,9 @@ + gtk_box_pack_start(GTK_BOX(vbox), cur, TRUE, TRUE, 0); + + /* packages tree */ +- treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); ++ filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL); ++ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter), filter_visible_func, NULL, NULL); ++ treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (filter)); + gtk_tree_view_set_reorderable(GTK_TREE_VIEW(treeview),FALSE); + gtk_tree_view_set_rules_hint (GTK_TREE_VIEW(treeview),TRUE); + gtk_container_add(GTK_CONTAINER(cur),treeview); + diff --git a/packages/gpe-package/gpe-package_0.3.bb b/packages/gpe-package/gpe-package_0.3.bb index 55cc4ef2a8..a6342f4e18 100644 --- a/packages/gpe-package/gpe-package_0.3.bb +++ b/packages/gpe-package/gpe-package_0.3.bb @@ -1,18 +1,22 @@ LICENSE = "GPL" -PR = "r2" +PR = "r3" inherit gpe pkgconfig DESCRIPTION = "A package manager GUI for GPE" -DEPENDS = "ipkg libgpewidget gpe-su" +DEPENDS = "ipkg pcre libgpewidget gpe-su" RDEPENDS = "gpe-icons" SECTION = "gpe" PRIORITY = "optional" SRC_URI += " file://sbin-and-no-suid-install.patch;patch=1 \ - file://gpe-package" + file://search.patch;patch=1 \ + file://gpe-package" FILES_${PN} += " /usr/bin/gpe-package" +CFLAGS += "-DENABLE_PCRE" +LDFLAGS += "-lpcre" + do_install_append() { install -d ${D}/usr/bin install -m 0755 ${WORKDIR}/gpe-package ${D}/usr/bin -- cgit v1.2.3 From d710ae5a50fe6b2983ce2d9e41d295f79e55a7a2 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 31 Aug 2006 08:43:46 +0000 Subject: h2200-bootloader: try to make sure only h2200 machine will build and install it --- packages/h2200-bootloader/h2200-bootloader.bb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/h2200-bootloader/h2200-bootloader.bb b/packages/h2200-bootloader/h2200-bootloader.bb index eb36cd50d6..376e34d7cc 100644 --- a/packages/h2200-bootloader/h2200-bootloader.bb +++ b/packages/h2200-bootloader/h2200-bootloader.bb @@ -3,6 +3,10 @@ ALLOW_EMPTY = "1" MAINTAINER = "Koen Kooi " PR="r2" +COMPATIBLE_MACHINE = "h2200" +#it is a shell script, but lets protect the innocent some more +PACKAGE_ARCH = "h2200" + pkg_postinst() { #!/bin/sh mkdir -p /lib/firmware -- cgit v1.2.3 From 20dcec61dc2304f0500a52f93abca50abe8a970b Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Thu, 31 Aug 2006 11:43:10 +0000 Subject: ruby: added 1.8.5 --- packages/ruby/ruby-native_1.8.5.bb | 3 +++ packages/ruby/ruby_1.8.5.bb | 12 ++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 packages/ruby/ruby-native_1.8.5.bb create mode 100644 packages/ruby/ruby_1.8.5.bb diff --git a/packages/ruby/ruby-native_1.8.5.bb b/packages/ruby/ruby-native_1.8.5.bb new file mode 100644 index 0000000000..d5ccae8262 --- /dev/null +++ b/packages/ruby/ruby-native_1.8.5.bb @@ -0,0 +1,3 @@ +include ruby_${PV}.bb +inherit native +DEPENDS = "" diff --git a/packages/ruby/ruby_1.8.5.bb b/packages/ruby/ruby_1.8.5.bb new file mode 100644 index 0000000000..235c3892de --- /dev/null +++ b/packages/ruby/ruby_1.8.5.bb @@ -0,0 +1,12 @@ +DESCRIPTION = "Ruby is an interpreted scripting language \ +for quick and easy object-oriented programming." +SECTION = "devel/ruby" +DEPENDS = "ruby-native" +PRIORITY = "optional" +MAINTAINER = "Gints Polis " +LICENSE = "GPL" + +SRC_URI = "ftp://ftp.ruby-lang.org/pub/ruby/ruby-${PV}.tar.gz" +S = "${WORKDIR}/ruby-${PV}" + +inherit autotools -- cgit v1.2.3 From 7e13817fd6722787df7fb331781e779158192fec Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 31 Aug 2006 19:18:08 +0000 Subject: xorg-xserver-common.inc: fixes --- packages/xorg-xserver/xorg-xserver-common.inc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/xorg-xserver/xorg-xserver-common.inc b/packages/xorg-xserver/xorg-xserver-common.inc index 5f5f5c0dea..9455e5063c 100644 --- a/packages/xorg-xserver/xorg-xserver-common.inc +++ b/packages/xorg-xserver/xorg-xserver-common.inc @@ -15,7 +15,7 @@ resourceproto xineramaproto xtrans evieext libxkbfile libxfont libxau \ libfontenc libxdmcp libxxf86vm libxaw libxmu libxt libxpm libxext libx11 \ libxkbui libxxf86misc libxi libdmx libxtst libxres mesa" -REPENDS="rgb" +RDEPENDS="rgb" XORG_PN = "xorg-server" SRC_URI = "${XORG_MIRROR}/${@bb.data.getVar('PV', d, 1)[0:7]}/src/xserver/${XORG_PN}-${PV}.tar.bz2 \ @@ -25,6 +25,9 @@ S = "${WORKDIR}/${XORG_PN}-${PV}" inherit autotools pkgconfig + +EXTRA_OECONF = "--disable-builddocs" + PACKAGES =+ "${PN}-xprint ${PN}-xvfb ${PN}-utils" FILES_${PN}-xprint = "${libdir}/X11/xserver/*/print" -- cgit v1.2.3 From 710e35683f8d5d9bba3af6d9b396a1f9c9cf5aac Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 31 Aug 2006 19:20:44 +0000 Subject: ep93xx kernel: update defconfig --- packages/linux/ep93xx-kernel/defconfig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/linux/ep93xx-kernel/defconfig b/packages/linux/ep93xx-kernel/defconfig index f173484160..e42a804b5a 100644 --- a/packages/linux/ep93xx-kernel/defconfig +++ b/packages/linux/ep93xx-kernel/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.18-rc1-git9 -# Sat Jul 15 19:58:55 2006 +# Sat Jul 15 20:13:41 2006 # CONFIG_ARM=y CONFIG_MMU=y @@ -170,7 +170,8 @@ CONFIG_ARM_AMBA=y # CONFIG_PREEMPT is not set # CONFIG_NO_IDLE_HZ is not set CONFIG_HZ=100 -# CONFIG_AEABI is not set +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -188,7 +189,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyAM0,115200 root=/dev/nfs ip=bootp" +CONFIG_CMDLINE="console=ttyAM0,57600 root=/dev/nfs ip=bootp" # CONFIG_XIP_KERNEL is not set # @@ -208,7 +209,6 @@ CONFIG_FPE_NWFPE_XP=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_AOUT is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set # # Power management options @@ -521,7 +521,7 @@ CONFIG_NETDEVICES=y # CONFIG_NET_ETHERNET=y CONFIG_MII=y -# CONFIG_EP93XX_ETH is not set +CONFIG_EP93XX_ETH=y # CONFIG_SMC91X is not set # CONFIG_DM9000 is not set -- cgit v1.2.3 From f520a657a9d66e5e80569cb7062527913de8b942 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 31 Aug 2006 19:23:57 +0000 Subject: angstrom: prefer 2.6.16-hh5 for machines that use it --- conf/distro/angstrom-2007.1.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conf/distro/angstrom-2007.1.conf b/conf/distro/angstrom-2007.1.conf index 327d4123cc..75303d2c5c 100644 --- a/conf/distro/angstrom-2007.1.conf +++ b/conf/distro/angstrom-2007.1.conf @@ -29,6 +29,9 @@ FEED_URIS += " \ #SRCDATE = "20060630" #SRCDATE_handhelds-pxa-2.6 = "20060622" +PREFERRED_VERSION_handhelds-pxa-2.6 = "2.6.16-hh5" + + SRCDATE_gconf-dbus = "20060719" SRCDATE_gnome-vfs-dbus = "20060803" -- cgit v1.2.3 From 595160162414a8b0a1db18dfb80a457cac2b53ac Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 31 Aug 2006 19:27:54 +0000 Subject: packages/linux: set some more COMPATIBLE_MACHINES * maintainers: please add the appropriate ones to your recipes --- packages/linux/a780-kernel_2.6.bb | 1 + packages/linux/e680-kernel_2.6.bb | 1 + packages/linux/gumstix_2.6.5-gnalm1-gum0.bb | 2 ++ packages/linux/linux-amsdelta-2.6_2.6.16-omap2.bb | 2 ++ packages/linux/linux-gumstix_2.6.15.bb | 2 ++ packages/linux/linux-openzaurus.inc | 2 +- packages/linux/openzaurus-pxa_2.4.18-rmk7-pxa3-embedix20031107.inc | 1 + packages/linux/shepherd-kernel-2.4-embedix.bb | 1 + 8 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/linux/a780-kernel_2.6.bb b/packages/linux/a780-kernel_2.6.bb index d141f90b55..b60bbaa3bc 100644 --- a/packages/linux/a780-kernel_2.6.bb +++ b/packages/linux/a780-kernel_2.6.bb @@ -1,2 +1,3 @@ MACHINE = "a780" +COMPATIBLE_MACHINE = "a780" require linux-ezx_2.6.16.13.bb diff --git a/packages/linux/e680-kernel_2.6.bb b/packages/linux/e680-kernel_2.6.bb index df5624384e..b3cbfbc0bf 100644 --- a/packages/linux/e680-kernel_2.6.bb +++ b/packages/linux/e680-kernel_2.6.bb @@ -1,2 +1,3 @@ MACHINE = "e680" +COMPATIBLE_MACHINE = "(e680|a780)" require linux-ezx_2.6.16.13.bb diff --git a/packages/linux/gumstix_2.6.5-gnalm1-gum0.bb b/packages/linux/gumstix_2.6.5-gnalm1-gum0.bb index 846e5f4fa2..befb587f89 100644 --- a/packages/linux/gumstix_2.6.5-gnalm1-gum0.bb +++ b/packages/linux/gumstix_2.6.5-gnalm1-gum0.bb @@ -5,6 +5,8 @@ SECTION = "kernel" DESCRIPTION = "Linux kernel for OMAP processors" LICENSE = "GPL" +COMPATIBLE_MACHINE = "gumstix" + # NOTE: pulled local linux-2.6.5-gnalm1, since it didn't apply cleanly SRC_URI = "ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.5.tar.bz2 \ file://linux-2.6.5-gnalm1.patch;patch=1 \ diff --git a/packages/linux/linux-amsdelta-2.6_2.6.16-omap2.bb b/packages/linux/linux-amsdelta-2.6_2.6.16-omap2.bb index d2f8faa032..1948dedf65 100644 --- a/packages/linux/linux-amsdelta-2.6_2.6.16-omap2.bb +++ b/packages/linux/linux-amsdelta-2.6_2.6.16-omap2.bb @@ -3,6 +3,8 @@ DESCRIPTION = "2.6 Linux kernel for the Amstrad Delta (E3)" LICENSE = "GPL" MAINTAINER = "Jonathan McDowell " +COMPATIBLE_MACHINE = "amsdelta" + SRC_URI = "ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.16.tar.bz2 \ http://www.muru.com/linux/omap/patches/patch-2.6.16-omap2.bz2;patch=1 \ http://the.earth.li/pub/e3/2.6.16/00-ams-delta-backlight.diff;patch=1 \ diff --git a/packages/linux/linux-gumstix_2.6.15.bb b/packages/linux/linux-gumstix_2.6.15.bb index de83450964..2b98c82370 100644 --- a/packages/linux/linux-gumstix_2.6.15.bb +++ b/packages/linux/linux-gumstix_2.6.15.bb @@ -3,6 +3,8 @@ SECTION = "kernel" LICENSE = "GPL" PR = "r1" +COMPATIBLE_MACHINE = "gumstix" + SRC_URI = "ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2 \ cvs://anoncvs:anoncvs@cvs.infradead.org/home/cvs;module=mtd;date=20060223 \ file://defconfig-gumstix \ diff --git a/packages/linux/linux-openzaurus.inc b/packages/linux/linux-openzaurus.inc index bba29ac1d6..2ff70f48e3 100644 --- a/packages/linux/linux-openzaurus.inc +++ b/packages/linux/linux-openzaurus.inc @@ -23,7 +23,7 @@ ALLOW_EMPTY = 1 EXTRA_OEMAKE = "OPENZAURUS_RELEASE=-${DISTRO_VERSION}" COMPATIBLE_HOST = "arm.*-linux" -COMPATIBLE_MACHINE = '(collie|poodle|c7x0|akita|spitz|tosa|ipaq-pxa270|qemuarm)' +COMPATIBLE_MACHINE = '(collie|poodle|c7x0|akita|spitz|tosa|ipoq-pxa270|qemuarm)' CMDLINE_CON = "console=ttyS0,115200n8 console=tty1 noinitrd" CMDLINE_ROOT = "root=/dev/mtdblock2 rootfstype=jffs2" diff --git a/packages/linux/openzaurus-pxa_2.4.18-rmk7-pxa3-embedix20031107.inc b/packages/linux/openzaurus-pxa_2.4.18-rmk7-pxa3-embedix20031107.inc index 3b0024d147..04f8342165 100644 --- a/packages/linux/openzaurus-pxa_2.4.18-rmk7-pxa3-embedix20031107.inc +++ b/packages/linux/openzaurus-pxa_2.4.18-rmk7-pxa3-embedix20031107.inc @@ -8,6 +8,7 @@ KV = "2.4.18" RMKV = "7" PXAV = "3" SHARPV = "20031107" +COMPATIBLE_MACHINE = "(poodle|corgi|shepherd|husky|poodle255|tosa)" FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/openzaurus-pxa-${KV}-rmk${RMKV}-pxa${PXAV}-embedix${SHARPV}" diff --git a/packages/linux/shepherd-kernel-2.4-embedix.bb b/packages/linux/shepherd-kernel-2.4-embedix.bb index e86996d96f..874c72e432 100644 --- a/packages/linux/shepherd-kernel-2.4-embedix.bb +++ b/packages/linux/shepherd-kernel-2.4-embedix.bb @@ -1,4 +1,5 @@ MACHINE = "shepherd" +COMPATIBLE_MACHINE = "shepherd" require openzaurus-pxa_2.4.18-rmk7-pxa3-embedix20031107.inc -- cgit v1.2.3 From 2eb608702d28f25f48fc4b34cf7e1c7d5f340a45 Mon Sep 17 00:00:00 2001 From: Erik Hovland Date: Thu, 31 Aug 2006 20:47:46 +0000 Subject: Provide new recipes for the latest hh.org kernels for the h3900 and h5400 iPAQs. --- .../.mtn2git_empty | 0 .../defconfig-h3900 | 1627 ++++++++++++++++++++ .../linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh42.bb | 73 + 3 files changed, 1700 insertions(+) create mode 100644 packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh42/.mtn2git_empty create mode 100644 packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh42/defconfig-h3900 create mode 100644 packages/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh42.bb diff --git a/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh42/.mtn2git_empty b/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh42/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh42/defconfig-h3900 b/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh42/defconfig-h3900 new file mode 100644 index 0000000000..4d012c89e0 --- /dev/null +++ b/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh42/defconfig-h3900 @@ -0,0 +1,1627 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_OMAHA is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_RISCSTATION is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_AT91RM9200DK is not set +# CONFIG_MINIMAL_OOPS is not set + +# +# Linux As Bootldr support +# +# CONFIG_LAB is not set +# CONFIG_BIG_KERNEL is not set +# CONFIG_USE_DATE_CODE is not set + +# +# Archimedes/A5000 Implementations +# + +# +# Archimedes/A5000 Implementations (select only ONE) +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ACCELENT is not set +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_CONSUS is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_JORNADA56X is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SIMPUTER is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_REGISTERS is not set + +# +# Intel PXA250/210 Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +# CONFIG_ARCH_PXA_IDP is not set +# CONFIG_ARCH_PXA_CERF is not set +CONFIG_ARCH_H3900=y +CONFIG_ARCH_H1900=y +CONFIG_ARCH_H5400=y +# CONFIG_ARCH_H2200 is not set +CONFIG_ARCH_AXIM=y +CONFIG_PXA_USB=m +CONFIG_PXA_USB_NETLINK=m +CONFIG_PXA_USB_CHAR=m + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_PLD is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_SA110 is not set +# CONFIG_CPU_SA1100 is not set +CONFIG_CPU_32v5=y +CONFIG_CPU_XSCALE=y +CONFIG_XSCALE_PXA250=y +# CONFIG_XSCALE_80200_OLD is not set +# CONFIG_CPU_32v3 is not set +# CONFIG_CPU_32v4 is not set +# CONFIG_SA1100_IPAQ is not set +CONFIG_PXA_IPAQ=y +CONFIG_IPAQ_HANDHELD=y + +# +# Compaq iPAQ Handheld +# +CONFIG_IPAQ_HAL=m +# CONFIG_H3600_MICRO is not set +CONFIG_IPAQ_HAS_ROSELLA=y +CONFIG_IPAQ_HAS_ASIC3=y +CONFIG_H3600_ASIC=m +CONFIG_H3900_ASIC_DEBUG=m +CONFIG_H5400_ASIC=m +CONFIG_H1900_ASIC=m +CONFIG_H1900_TS=m +CONFIG_H3600_HARDWARE=y +CONFIG_IPAQ_SLEEVE=m +CONFIG_SLEEVE_DEBUG=y +CONFIG_SLEEVE_DEBUG_VERBOSE=0 +# CONFIG_SLEEVE_IRQ_DEMUX is not set + +# +# Dell Axim X5 +# +CONFIG_AXIM_HAL=m + +# +# Processor Features +# +# CONFIG_DISCONTIGMEM is not set + +# +# General setup +# +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CPU_FREQ=y +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +# CONFIG_PCMCIA_CLPS6700 is not set +# CONFIG_PCMCIA_SA1100 is not set +CONFIG_PCMCIA_PXA=m +# CONFIG_MERCURY_BACKPAQ is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SAMSUNG_ASIC=m +# CONFIG_MMC_S3C2410 is not set +CONFIG_MMC_H5400=m +CONFIG_MMC_ASIC3=m +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_XIP_KERNEL is not set + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_PM=y +CONFIG_APM=m +# CONFIG_HWTIMER is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="keepinitrd" +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_CML1=m +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_IDP is not set +# CONFIG_PARPORT_AMIGA is not set +# CONFIG_PARPORT_MFC3 is not set +# CONFIG_PARPORT_ATARI is not set +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_SUNBPP is not set +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=1 +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +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=y +CONFIG_MTD_MAP_BANK_WIDTH_16=y +CONFIG_MTD_MAP_BANK_WIDTH_32=y +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=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_IPAQ=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +# CONFIG_MTD_SA1100 is not set +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_LUBBOCK is not set +# CONFIG_MTD_IXP425 is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_H720X is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_CEIVA is not set +# CONFIG_MTD_NOR_TOTO is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +CONFIG_MTD_BLKMTD=m + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_DOCPROBE is not set +# CONFIG_MTD_DOCECC is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_NAND_SPIA is not set +# CONFIG_MTD_NAND_TOTO is not set +# CONFIG_MTD_NAND_AUTCPU12 is not set +# CONFIG_MTD_NAND_EDB7312 is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_NVRD=m + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +CONFIG_BLK_DEV_LVM=m +CONFIG_BLK_DEV_DM=m + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_TFTP is not set +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +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 is not set +CONFIG_IP_NF_MATCH_STATE=m +# CONFIG_IP_NF_MATCH_CONNTRACK is not set +# CONFIG_IP_NF_MATCH_UNCLEAN is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_FILTER=m +# CONFIG_IP_NF_TARGET_REJECT is not set +# CONFIG_IP_NF_TARGET_MIRROR is not set +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_NAT_LOCAL is not set +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_DSCP is not set +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_ARPTABLES is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +CONFIG_IPV6=m +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MOBILITY=m +CONFIG_IPV6_MOBILITY_MN=m +# CONFIG_IPV6_MOBILITY_HA is not set +CONFIG_IPV6_MOBILITY_DEBUG=y + +# +# IPv6: Netfilter Configuration +# +# 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 is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_HL is not set +CONFIG_IP6_NF_MATCH_MULTIPORT=m +# CONFIG_IP6_NF_MATCH_OWNER is not set +CONFIG_IP6_NF_MATCH_MARK=m +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_AHESP is not set +# CONFIG_IP6_NF_MATCH_LENGTH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +CONFIG_BRIDGE=m +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_IPSEC=m + +# +# IPSec options (FreeS/WAN) +# +CONFIG_KLIPS_AUTH_HMAC_MD5=y +CONFIG_KLIPS_AUTH_HMAC_SHA1=y +CONFIG_KLIPS_ENC_3DES=y + +# +# ESP always enabled with tunnel mode +# +CONFIG_KLIPS_IPCOMP=y +CONFIG_KLIPS_DEBUG=y + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_HERMES is not set +# CONFIG_SPECTRUM24T is not set + +# +# Wireless Pcmcia cards support +# +# CONFIG_PCMCIA_HERMES is not set +CONFIG_AIRO_CS=m +# CONFIG_WVLAN_CS is not set +# CONFIG_MWVLAN_CS is not set +# CONFIG_HOSTAP is not set +# CONFIG_HOSTAP_CS is not set +CONFIG_NET_WIRELESS=y +# CONFIG_ATMELWLAN is not set +# CONFIG_ATMELWLAN_USB_503A_RFMD is not set +# CONFIG_ATMELWLAN_PCMCIA_502A is not set +# CONFIG_ATMELWLAN_PCMCIA_3COM is not set +# CONFIG_ATMELWLAN_PCMCIA_502AD is not set +# CONFIG_ATMELWLAN_PCMCIA_502AE is not set +# CONFIG_ATMELWLAN_PCMCIA_504 is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_AXNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +# CONFIG_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +CONFIG_NET_PCMCIA_RADIO=y +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_WAVELAN=m +# CONFIG_AIRONET4500_CS is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m +CONFIG_IRPORT_SIR=m + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# 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_PXA_FIR=m + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=m + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDEFLOPPY=m +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL 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_ISAPNP is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +CONFIG_SCSI=m + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set + +# +# PCMCIA SCSI adapter support +# +CONFIG_SCSI_PCMCIA=y +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=m +CONFIG_INPUT_KEYBDEV=m +CONFIG_INPUT_MOUSEDEV=m +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_UINPUT=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL_EXTENDED=y +# CONFIG_SERIAL_MANY_PORTS is not set +# CONFIG_SERIAL_SHARE_IRQ is not set +# CONFIG_SERIAL_DETECT_IRQ is not set +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_S3C2410 is not set +# CONFIG_SERIAL_S3C2410_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +# CONFIG_SERIAL_SA1100 is not set +# CONFIG_SERIAL_SA1100_CONSOLE is not set +# CONFIG_SERIAL_SIR_PXA is not set +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +CONFIG_NEWTONKBD=m +# CONFIG_SA1100_PROFILER is not set + +# +# Compaq iPAQ H3600 support +# +CONFIG_TOUCHSCREEN_H3600=m +# CONFIG_H3600_BACKPAQ_FPGA is not set +# CONFIG_H3600_BACKPAQ_ACCEL is not set +# CONFIG_H3600_BACKPAQ_GASGAUGE is not set +# CONFIG_H3600_BACKPAQ_SRAM is not set +# CONFIG_H3600_BACKPAQ_AUDIO is not set +# CONFIG_H3600_STOWAWAY is not set +# CONFIG_H3800_MICROKBD is not set +# CONFIG_SA1100_LIRC is not set +CONFIG_H5400_BUZZER=m +CONFIG_H5400_FSI=m + +# +# I2C support +# +CONFIG_I2C=m +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_PXA_ALGO=m +CONFIG_I2C_PXA_ADAP=m +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_PROC=m +# CONFIG_I2C_DS1307 is not set + +# +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set + +# +# Other L3 adapters +# +# CONFIG_L3_S3C2410 is not set +# CONFIG_L3_SA1111 is not set +# CONFIG_L3_BACKPAQ is not set +# CONFIG_BIT_SA1100_GPIO is not set + +# +# SPI support +# +# CONFIG_SPI is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +CONFIG_MOUSE=m +# CONFIG_PSMOUSE is not set +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set +# CONFIG_MK712_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +CONFIG_INPUT_SERIO=m +CONFIG_INPUT_SERPORT=m + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_21285_WATCHDOG is not set +# CONFIG_977_WATCHDOG is not set +# CONFIG_SA1100_WATCHDOG is not set +CONFIG_PXA_WATCHDOG=m +# CONFIG_OMAHA_WATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_PXA_RTC=m +CONFIG_PXA_RTC_HACK=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +CONFIG_PCMCIA_SERIAL_CS=m +CONFIG_PCMCIA_MOBILISCAN_CS=m +# CONFIG_AXIM_TS is not set +CONFIG_AXIM_KEY=m +# CONFIG_AXIM_KEY_FIX is not set + +# +# Multimedia devices +# +CONFIG_MEDIA=m +CONFIG_VIDEO_DEV=m +CONFIG_V4L2_DEV=m + +# +# Video For Linux +# +CONFIG_VIDEO_PROC_FS=y +# CONFIG_I2C_PARPORT is not set + +# +# Video Adapters +# +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA_USB=m +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZR36120 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_CYBERPRO is not set +# CONFIG_VIDEO_H3600_BACKPAQ is not set +# CONFIG_VIDEO_HAWKEYE is not set + +# +# Video for Linux 2 (V4L2) +# +CONFIG_VIDEO_WINNOV_CS=m + +# +# Radio Adapters +# +# 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 is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI 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 + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=m +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_UMSDOS_FS=m +CONFIG_VFAT_FS=m +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_LZO is not set +# CONFIG_JFFS2_LZARI is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_PROC=y +CONFIG_CRAMFS=y +CONFIG_TMPFS=y +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=m +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DRIVERFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=m +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_SUNRPC=m +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m + +# +# Console drivers +# +CONFIG_PC_KEYMAP=y +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_ACORN is not set +# CONFIG_FB_ANAKIN is not set +# CONFIG_FB_CLPS711X is not set +# CONFIG_FB_S3C2410 is not set +# CONFIG_FB_SA1100 is not set +# CONFIG_FB_EPSON1356 is not set +# CONFIG_FB_MQ200 is not set +CONFIG_FB_PXA=y +# CONFIG_FB_PXA_8BPP is not set +CONFIG_FB_PXA_16BPP=y +CONFIG_FB_MQ1100=y +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +# CONFIG_FBCON_CFB4 is not set +# CONFIG_FBCON_CFB8 is not set +CONFIG_FBCON_CFB16=y +# CONFIG_FBCON_CFB24 is not set +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +# CONFIG_FBCON_NO_LOGO is not set +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +CONFIG_FBCON_FONTS=y +CONFIG_FONT_8x8=y +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +CONFIG_SOUND_H3900_UDA1380=m +CONFIG_SOUND_H5400=m +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_PAS_JOYSTICK is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_YMFPCI_LEGACY is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_VIDC is not set +# CONFIG_SOUND_WAVEARTIST is not set +CONFIG_SOUND_PXA_AC97=m +# CONFIG_SOUND_TVMIXER is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set +# CONFIG_MCP_UCB1400_TS is not set + +# +# Console Switches +# +# CONFIG_SWITCHES is not set + +# +# USB support +# +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_LONG_TIMEOUT is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=m +# CONFIG_USB_OHCI_SA1111 is not set +CONFIG_USB_OHCI_H5400=m +CONFIG_USB_SL811HS=m +CONFIG_USB_SL811HS_CS=m + +# +# USB Device Class drivers +# +CONFIG_USB_AUDIO=m +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=m + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=m +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_WACOM is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# +CONFIG_USB_IBMCAM=m +CONFIG_USB_OV511=m +CONFIG_USB_PWC=m +# CONFIG_USB_QC is not set +CONFIG_USB_SE401=m +CONFIG_USB_STV680=m +CONFIG_USB_VICAM=m +# CONFIG_USB_DSBR is not set +# CONFIG_USB_DABUSB is not set + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +CONFIG_USB_CDCETHER=m +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +CONFIG_USB_SERIAL_IPAQ=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_KLSI is not set +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_BRLVGER is not set + +# +# Support for USB gadgets +# +CONFIG_USB_GADGET=m +CONFIG_USB_GADGET_PXA2XX=y +# CONFIG_USB_GADGET_N9604 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_SUPERH is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_CONTROLLER is not set +CONFIG_USB_PXA2XX=m +CONFIG_USB_GADGET_CONTROLLER=m +# CONFIG_USB_GADGET_DUALSPEED is not set + +# +# USB Gadget Drivers +# +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m + +# +# Linux As Bootldr Modules +# +# CONFIG_BIG_KERNEL is not set +# CONFIG_USE_DATE_CODE is not set +# CONFIG_YMODEM is not set +# CONFIG_LAB_DUMMY is not set +# CONFIG_LAB_CRC is not set +# CONFIG_LAB_YMODEM is not set +# CONFIG_LAB_MTD is not set +# CONFIG_LAB_COPY is not set +# CONFIG_LAB_COPY_YMODEM is not set +# CONFIG_LAB_COPY_FLASH is not set +# CONFIG_LAB_COPY_FS is not set +# CONFIG_LAB_COPY_WRAPPER is not set + +# +# Bluetooth support +# +CONFIG_BLUEZ=m +CONFIG_BLUEZ_L2CAP=m +CONFIG_BLUEZ_SCO=m +CONFIG_BLUEZ_RFCOMM=m +CONFIG_BLUEZ_RFCOMM_TTY=y +CONFIG_BLUEZ_BNEP=m +CONFIG_BLUEZ_BNEP_MC_FILTER=y +CONFIG_BLUEZ_BNEP_PROTO_FILTER=y +CONFIG_BLUEZ_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BLUEZ_HCIUSB=m +# CONFIG_BLUEZ_HCIUSB_SCO is not set +CONFIG_BLUEZ_HCIUART=m +CONFIG_BLUEZ_HCIUART_H4=y +CONFIG_BLUEZ_HCIUART_BCSP=y +# CONFIG_BLUEZ_HCIUART_BCSP_TXCRC is not set +# CONFIG_BLUEZ_HCIBFUSB is not set +CONFIG_BLUEZ_HCIDTL1=m +CONFIG_BLUEZ_HCIBT3C=m +CONFIG_BLUEZ_HCIBLUECARD=m +CONFIG_BLUEZ_HCIBTUART=m +# CONFIG_BLUEZ_HCIVHCI is not set + +# +# Kernel hacking +# +# CONFIG_FRAME_POINTER is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +# CONFIG_REED_SOLOMON is not set +CONFIG_FW_LOADER=m diff --git a/packages/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh42.bb b/packages/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh42.bb new file mode 100644 index 0000000000..b39cb50835 --- /dev/null +++ b/packages/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh42.bb @@ -0,0 +1,73 @@ +SECTION = "kernel" +DESCRIPTION = "handhelds.org Linux kernel for PXA25x based devices." +MAINTAINER = "Phil Blundell " +LICENSE = "GPL" +#PR = "r1" + + +KERNEL_CCSUFFIX = "-3.3.4" +COMPATIBLE_HOST = "arm.*-linux" + +SRC_URI = "${HANDHELDS_CVS};module=linux/kernel;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \ + file://defconfig-${PACKAGE_ARCH} \ + file://ipaq-hal.init \ + file://linux-2.4-usb-gadget.patch;patch=1 \ + file://usb-gadget-ether-compat.patch;patch=1 \ + file://linux-2.4-no-short-loads.patch;patch=1 \ + file://linux-2.4-cpufreq.patch;patch=1" + +S = "${WORKDIR}/kernel" + +inherit kernel update-rc.d + +K_MAJOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[0]}" +K_MINOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[1]}" +K_MICRO = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[2]}" +RMKV = "${@bb.data.getVar('PV',d,1).split('-')[1].split('rmk')[-1]}" +PXAV = "${@bb.data.getVar('PV',d,1).split('-')[2].split('pxa')[-1]}" +HHV = "${@bb.data.getVar('PV',d,1).split('-')[3].split('hh')[-1]}" + +KERNEL_PRIORITY = "${@'%d' % (int(bb.data.getVar('K_MAJOR',d,1)) * 100000000 + int(bb.data.getVar('K_MINOR',d,1)) * 1000000 + int(bb.data.getVar('K_MICRO',d,1)) * 10000 + int(bb.data.getVar('RMKV',d,1)) * 1000 + int(bb.data.getVar('PXAV',d,1)) * 100 + float(bb.data.getVar('HHV',d,1)))}" + +module_conf_h3900_asic = "alias ipaq_hal_3900 h3900_asic" +module_conf_h5400_asic = "alias ipaq_hal_5400 h5400_asic" +module_conf_pxa_ir = "alias irda0 pxa_ir" +module_conf_i2c-algo-pxa = "options i2c-algo-pxa pxa_scan=0" +module_conf_pcmcia_core = "options pcmcia_core ignore_cis_vcc=1" +module_conf_ppp_async = "alias ppp0 ppp_async" +module_conf_orinoco_cs = "options orinoco_cs ignore_cis_vcc=1" +module_conf_hostap_cs = "options hostap_cs ignore_cis_vcc=1" +module_conf_hidp = "alias bt-prot-5 hidp" + +module_autoload_h3600_ts = "h3600_ts" +module_autoload_apm = "apm" +module_autoload_af_packet = "af_packet" +module_autoload_usb-ohci-h5400 = "usb-ohci-h5400" +module_autoload_ppp_async = "ppp_async" +module_autoload_usb-eth = "usb-eth" +module_autoload_h5400_buzzer = "h5400_buzzer" +# breaks booting on first install of h3900 handhelds +#module_autoload_mmc_asic3 = "mmc_asic3" +module_autoload_mmc_h5400 = "mmc_h5400" +module_autoload_h5400-audio = "h5400-audio" +module_autoload_h3900-uda1380 = "h3900-uda1380" +module_autoload_sa1100-rtc = "sa1100-rtc" +module_autoload_ak4535 = "ak4535" +module_autoload_i2c-adap-pxa = "i2c-adap-pxa" + +FILES_kernel += "/etc/init.d/ipaq-hal" +INITSCRIPT_NAME = "ipaq-hal" +INITSCRIPT_PARAMS = "start 21 S ." + +# extra depends +RDEPENDS_kernel-module-h5400-audio = "kernel-module-ak4535 kernel-module-i2c-adap-pxa" +RDEPENDS_kernel-module-h3900-uda1380 = "kernel-module-uda1380 kernel-module-i2c-adap-pxa" + +do_configure_prepend() { + install -m 0644 ${WORKDIR}/defconfig-${PACKAGE_ARCH} ${S}/.config +} + +do_install_append() { + install -d ${D}${sysconfdir}/init.d + install ${WORKDIR}/ipaq-hal.init ${D}${sysconfdir}/init.d/ipaq-hal +} -- cgit v1.2.3 From eb9aa42c10eccc39c3cb939c9f9dd70ed89991e4 Mon Sep 17 00:00:00 2001 From: Erik Hovland Date: Thu, 31 Aug 2006 21:10:49 +0000 Subject: Update of my earlier change to make it possible to compile glibc 2.3.5 with newer gcc compilers (4.0.2 and up). This commit changes the name of the files to weak instead of week. And updates the bb file respectfully. --- .../glibc/files/glibc-2.3.5-fix-weak-alias-arm-2.patch | 11 +++++++++++ packages/glibc/files/glibc-2.3.5-fix-weak-alias-arm.patch | 15 +++++++++++++++ .../glibc/files/glibc-2.3.5-fix-week-alias-arm-2.patch | 11 ----------- packages/glibc/files/glibc-2.3.5-fix-week-alias-arm.patch | 15 --------------- packages/glibc/glibc_2.3.5+cvs20050627.bb | 4 ++-- 5 files changed, 28 insertions(+), 28 deletions(-) create mode 100644 packages/glibc/files/glibc-2.3.5-fix-weak-alias-arm-2.patch create mode 100644 packages/glibc/files/glibc-2.3.5-fix-weak-alias-arm.patch delete mode 100644 packages/glibc/files/glibc-2.3.5-fix-week-alias-arm-2.patch delete mode 100644 packages/glibc/files/glibc-2.3.5-fix-week-alias-arm.patch diff --git a/packages/glibc/files/glibc-2.3.5-fix-weak-alias-arm-2.patch b/packages/glibc/files/glibc-2.3.5-fix-weak-alias-arm-2.patch new file mode 100644 index 0000000000..bf2f31e479 --- /dev/null +++ b/packages/glibc/files/glibc-2.3.5-fix-weak-alias-arm-2.patch @@ -0,0 +1,11 @@ +--- glibc-2.3.3/ports/sysdeps/unix/sysv/linux/arm/socket.S.orig 2006-07-12 14:38:22.208228359 -0700 ++++ glibc-2.3.3/ports/sysdeps/unix/sysv/linux/arm/socket.S 2006-07-12 14:39:56.911675066 -0700 +@@ -123,5 +123,7 @@ + #endif + + PSEUDO_END (__socket) +- ++ ++#ifndef NO_WEAK_ALIAS + weak_alias (__socket, socket) ++#endif diff --git a/packages/glibc/files/glibc-2.3.5-fix-weak-alias-arm.patch b/packages/glibc/files/glibc-2.3.5-fix-weak-alias-arm.patch new file mode 100644 index 0000000000..0097ff94d3 --- /dev/null +++ b/packages/glibc/files/glibc-2.3.5-fix-weak-alias-arm.patch @@ -0,0 +1,15 @@ +--- glibc-2.3.3/ports/sysdeps/unix/sysv/linux/arm/socket.S.orig 2006-07-12 13:57:05.990485563 -0700 ++++ glibc-2.3.3/ports/sysdeps/unix/sysv/linux/arm/socket.S 2006-07-12 13:58:41.197865230 -0700 +@@ -32,7 +32,11 @@ + The .S files for the other calls just #define socket and #include this. */ + + #ifndef __socket +-#define __socket P(__,socket) ++# ifndef NO_WEAK_ALIAS ++# define __socket P(__,socket) ++# else ++# define __socket socket ++# endif + #endif + + #define PUSHARGS_1 str a1, [sp, $-4]! diff --git a/packages/glibc/files/glibc-2.3.5-fix-week-alias-arm-2.patch b/packages/glibc/files/glibc-2.3.5-fix-week-alias-arm-2.patch deleted file mode 100644 index bf2f31e479..0000000000 --- a/packages/glibc/files/glibc-2.3.5-fix-week-alias-arm-2.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- glibc-2.3.3/ports/sysdeps/unix/sysv/linux/arm/socket.S.orig 2006-07-12 14:38:22.208228359 -0700 -+++ glibc-2.3.3/ports/sysdeps/unix/sysv/linux/arm/socket.S 2006-07-12 14:39:56.911675066 -0700 -@@ -123,5 +123,7 @@ - #endif - - PSEUDO_END (__socket) -- -+ -+#ifndef NO_WEAK_ALIAS - weak_alias (__socket, socket) -+#endif diff --git a/packages/glibc/files/glibc-2.3.5-fix-week-alias-arm.patch b/packages/glibc/files/glibc-2.3.5-fix-week-alias-arm.patch deleted file mode 100644 index 0097ff94d3..0000000000 --- a/packages/glibc/files/glibc-2.3.5-fix-week-alias-arm.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- glibc-2.3.3/ports/sysdeps/unix/sysv/linux/arm/socket.S.orig 2006-07-12 13:57:05.990485563 -0700 -+++ glibc-2.3.3/ports/sysdeps/unix/sysv/linux/arm/socket.S 2006-07-12 13:58:41.197865230 -0700 -@@ -32,7 +32,11 @@ - The .S files for the other calls just #define socket and #include this. */ - - #ifndef __socket --#define __socket P(__,socket) -+# ifndef NO_WEAK_ALIAS -+# define __socket P(__,socket) -+# else -+# define __socket socket -+# endif - #endif - - #define PUSHARGS_1 str a1, [sp, $-4]! diff --git a/packages/glibc/glibc_2.3.5+cvs20050627.bb b/packages/glibc/glibc_2.3.5+cvs20050627.bb index 31105c8adb..8943e1c565 100644 --- a/packages/glibc/glibc_2.3.5+cvs20050627.bb +++ b/packages/glibc/glibc_2.3.5+cvs20050627.bb @@ -56,8 +56,8 @@ SRC_URI = "http://familiar.handhelds.org/source/v0.8.3/stash_libc_sources.redhat file://5090_all_stubs-rule-fix.patch;patch=1 \ file://raise.patch;patch=1 \ file://zecke-sane-readelf.patch;patch=1 \ - file://glibc-2.3.3-fix-week-alias-arm.patch;patch=1 \ - file://glibc-2.3.3-fix-week-alias-arm-2.patch;patch=1 \ + file://glibc-2.3.5-fix-weak-alias-arm.patch;patch=1 \ + file://glibc-2.3.5-fix-weak-alias-arm-2.patch;patch=1 \ file://etc/ld.so.conf \ file://generate-supported.mk" -- cgit v1.2.3 From a93ce70849496660903566e819a4bf10b51641aa Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 31 Aug 2006 21:25:51 +0000 Subject: hh-pxa 2.4-hh42: really make sure it supports h5xxx --- .../defconfig-h5xxx | 1627 ++++++++++++++++++++ 1 file changed, 1627 insertions(+) create mode 100644 packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh42/defconfig-h5xxx diff --git a/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh42/defconfig-h5xxx b/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh42/defconfig-h5xxx new file mode 100644 index 0000000000..4d012c89e0 --- /dev/null +++ b/packages/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh42/defconfig-h5xxx @@ -0,0 +1,1627 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +CONFIG_ARCH_PXA=y +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_OMAHA is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_RISCSTATION is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_AT91RM9200DK is not set +# CONFIG_MINIMAL_OOPS is not set + +# +# Linux As Bootldr support +# +# CONFIG_LAB is not set +# CONFIG_BIG_KERNEL is not set +# CONFIG_USE_DATE_CODE is not set + +# +# Archimedes/A5000 Implementations +# + +# +# Archimedes/A5000 Implementations (select only ONE) +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ACCELENT is not set +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_CONSUS is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_JORNADA56X is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SIMPUTER is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_REGISTERS is not set + +# +# Intel PXA250/210 Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +# CONFIG_ARCH_PXA_IDP is not set +# CONFIG_ARCH_PXA_CERF is not set +CONFIG_ARCH_H3900=y +CONFIG_ARCH_H1900=y +CONFIG_ARCH_H5400=y +# CONFIG_ARCH_H2200 is not set +CONFIG_ARCH_AXIM=y +CONFIG_PXA_USB=m +CONFIG_PXA_USB_NETLINK=m +CONFIG_PXA_USB_CHAR=m + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_PLD is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_SA110 is not set +# CONFIG_CPU_SA1100 is not set +CONFIG_CPU_32v5=y +CONFIG_CPU_XSCALE=y +CONFIG_XSCALE_PXA250=y +# CONFIG_XSCALE_80200_OLD is not set +# CONFIG_CPU_32v3 is not set +# CONFIG_CPU_32v4 is not set +# CONFIG_SA1100_IPAQ is not set +CONFIG_PXA_IPAQ=y +CONFIG_IPAQ_HANDHELD=y + +# +# Compaq iPAQ Handheld +# +CONFIG_IPAQ_HAL=m +# CONFIG_H3600_MICRO is not set +CONFIG_IPAQ_HAS_ROSELLA=y +CONFIG_IPAQ_HAS_ASIC3=y +CONFIG_H3600_ASIC=m +CONFIG_H3900_ASIC_DEBUG=m +CONFIG_H5400_ASIC=m +CONFIG_H1900_ASIC=m +CONFIG_H1900_TS=m +CONFIG_H3600_HARDWARE=y +CONFIG_IPAQ_SLEEVE=m +CONFIG_SLEEVE_DEBUG=y +CONFIG_SLEEVE_DEBUG_VERBOSE=0 +# CONFIG_SLEEVE_IRQ_DEMUX is not set + +# +# Dell Axim X5 +# +CONFIG_AXIM_HAL=m + +# +# Processor Features +# +# CONFIG_DISCONTIGMEM is not set + +# +# General setup +# +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CPU_FREQ=y +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +# CONFIG_PCMCIA_CLPS6700 is not set +# CONFIG_PCMCIA_SA1100 is not set +CONFIG_PCMCIA_PXA=m +# CONFIG_MERCURY_BACKPAQ is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SAMSUNG_ASIC=m +# CONFIG_MMC_S3C2410 is not set +CONFIG_MMC_H5400=m +CONFIG_MMC_ASIC3=m +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_XIP_KERNEL is not set + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_PM=y +CONFIG_APM=m +# CONFIG_HWTIMER is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="keepinitrd" +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_CML1=m +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_IDP is not set +# CONFIG_PARPORT_AMIGA is not set +# CONFIG_PARPORT_MFC3 is not set +# CONFIG_PARPORT_ATARI is not set +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_SUNBPP is not set +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=1 +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +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=y +CONFIG_MTD_MAP_BANK_WIDTH_16=y +CONFIG_MTD_MAP_BANK_WIDTH_32=y +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=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_IPAQ=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +# CONFIG_MTD_SA1100 is not set +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_LUBBOCK is not set +# CONFIG_MTD_IXP425 is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_H720X is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_CEIVA is not set +# CONFIG_MTD_NOR_TOTO is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +CONFIG_MTD_BLKMTD=m + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_DOCPROBE is not set +# CONFIG_MTD_DOCECC is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_NAND_SPIA is not set +# CONFIG_MTD_NAND_TOTO is not set +# CONFIG_MTD_NAND_AUTCPU12 is not set +# CONFIG_MTD_NAND_EDB7312 is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_NVRD=m + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +CONFIG_BLK_DEV_LVM=m +CONFIG_BLK_DEV_DM=m + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_TFTP is not set +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +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 is not set +CONFIG_IP_NF_MATCH_STATE=m +# CONFIG_IP_NF_MATCH_CONNTRACK is not set +# CONFIG_IP_NF_MATCH_UNCLEAN is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_FILTER=m +# CONFIG_IP_NF_TARGET_REJECT is not set +# CONFIG_IP_NF_TARGET_MIRROR is not set +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_NAT_LOCAL is not set +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_DSCP is not set +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_ARPTABLES is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +CONFIG_IPV6=m +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MOBILITY=m +CONFIG_IPV6_MOBILITY_MN=m +# CONFIG_IPV6_MOBILITY_HA is not set +CONFIG_IPV6_MOBILITY_DEBUG=y + +# +# IPv6: Netfilter Configuration +# +# 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 is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_HL is not set +CONFIG_IP6_NF_MATCH_MULTIPORT=m +# CONFIG_IP6_NF_MATCH_OWNER is not set +CONFIG_IP6_NF_MATCH_MARK=m +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_AHESP is not set +# CONFIG_IP6_NF_MATCH_LENGTH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +CONFIG_BRIDGE=m +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_IPSEC=m + +# +# IPSec options (FreeS/WAN) +# +CONFIG_KLIPS_AUTH_HMAC_MD5=y +CONFIG_KLIPS_AUTH_HMAC_SHA1=y +CONFIG_KLIPS_ENC_3DES=y + +# +# ESP always enabled with tunnel mode +# +CONFIG_KLIPS_IPCOMP=y +CONFIG_KLIPS_DEBUG=y + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_HERMES is not set +# CONFIG_SPECTRUM24T is not set + +# +# Wireless Pcmcia cards support +# +# CONFIG_PCMCIA_HERMES is not set +CONFIG_AIRO_CS=m +# CONFIG_WVLAN_CS is not set +# CONFIG_MWVLAN_CS is not set +# CONFIG_HOSTAP is not set +# CONFIG_HOSTAP_CS is not set +CONFIG_NET_WIRELESS=y +# CONFIG_ATMELWLAN is not set +# CONFIG_ATMELWLAN_USB_503A_RFMD is not set +# CONFIG_ATMELWLAN_PCMCIA_502A is not set +# CONFIG_ATMELWLAN_PCMCIA_3COM is not set +# CONFIG_ATMELWLAN_PCMCIA_502AD is not set +# CONFIG_ATMELWLAN_PCMCIA_502AE is not set +# CONFIG_ATMELWLAN_PCMCIA_504 is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_AXNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +# CONFIG_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +CONFIG_NET_PCMCIA_RADIO=y +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_WAVELAN=m +# CONFIG_AIRONET4500_CS is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m +CONFIG_IRPORT_SIR=m + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# 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_PXA_FIR=m + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=m + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=m + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDEFLOPPY=m +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL 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_ISAPNP is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +CONFIG_SCSI=m + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set + +# +# PCMCIA SCSI adapter support +# +CONFIG_SCSI_PCMCIA=y +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=m +CONFIG_INPUT_KEYBDEV=m +CONFIG_INPUT_MOUSEDEV=m +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_UINPUT=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL_EXTENDED=y +# CONFIG_SERIAL_MANY_PORTS is not set +# CONFIG_SERIAL_SHARE_IRQ is not set +# CONFIG_SERIAL_DETECT_IRQ is not set +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_S3C2410 is not set +# CONFIG_SERIAL_S3C2410_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +# CONFIG_SERIAL_SA1100 is not set +# CONFIG_SERIAL_SA1100_CONSOLE is not set +# CONFIG_SERIAL_SIR_PXA is not set +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +CONFIG_NEWTONKBD=m +# CONFIG_SA1100_PROFILER is not set + +# +# Compaq iPAQ H3600 support +# +CONFIG_TOUCHSCREEN_H3600=m +# CONFIG_H3600_BACKPAQ_FPGA is not set +# CONFIG_H3600_BACKPAQ_ACCEL is not set +# CONFIG_H3600_BACKPAQ_GASGAUGE is not set +# CONFIG_H3600_BACKPAQ_SRAM is not set +# CONFIG_H3600_BACKPAQ_AUDIO is not set +# CONFIG_H3600_STOWAWAY is not set +# CONFIG_H3800_MICROKBD is not set +# CONFIG_SA1100_LIRC is not set +CONFIG_H5400_BUZZER=m +CONFIG_H5400_FSI=m + +# +# I2C support +# +CONFIG_I2C=m +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_PXA_ALGO=m +CONFIG_I2C_PXA_ADAP=m +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_PROC=m +# CONFIG_I2C_DS1307 is not set + +# +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set + +# +# Other L3 adapters +# +# CONFIG_L3_S3C2410 is not set +# CONFIG_L3_SA1111 is not set +# CONFIG_L3_BACKPAQ is not set +# CONFIG_BIT_SA1100_GPIO is not set + +# +# SPI support +# +# CONFIG_SPI is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +CONFIG_MOUSE=m +# CONFIG_PSMOUSE is not set +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set +# CONFIG_MK712_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +CONFIG_INPUT_SERIO=m +CONFIG_INPUT_SERPORT=m + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_21285_WATCHDOG is not set +# CONFIG_977_WATCHDOG is not set +# CONFIG_SA1100_WATCHDOG is not set +CONFIG_PXA_WATCHDOG=m +# CONFIG_OMAHA_WATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_PXA_RTC=m +CONFIG_PXA_RTC_HACK=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +CONFIG_PCMCIA_SERIAL_CS=m +CONFIG_PCMCIA_MOBILISCAN_CS=m +# CONFIG_AXIM_TS is not set +CONFIG_AXIM_KEY=m +# CONFIG_AXIM_KEY_FIX is not set + +# +# Multimedia devices +# +CONFIG_MEDIA=m +CONFIG_VIDEO_DEV=m +CONFIG_V4L2_DEV=m + +# +# Video For Linux +# +CONFIG_VIDEO_PROC_FS=y +# CONFIG_I2C_PARPORT is not set + +# +# Video Adapters +# +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA_USB=m +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZR36120 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_CYBERPRO is not set +# CONFIG_VIDEO_H3600_BACKPAQ is not set +# CONFIG_VIDEO_HAWKEYE is not set + +# +# Video for Linux 2 (V4L2) +# +CONFIG_VIDEO_WINNOV_CS=m + +# +# Radio Adapters +# +# 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 is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI 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 + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=m +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_UMSDOS_FS=m +CONFIG_VFAT_FS=m +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_LZO is not set +# CONFIG_JFFS2_LZARI is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_PROC=y +CONFIG_CRAMFS=y +CONFIG_TMPFS=y +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=m +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DRIVERFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=m +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_SUNRPC=m +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m + +# +# Console drivers +# +CONFIG_PC_KEYMAP=y +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_ACORN is not set +# CONFIG_FB_ANAKIN is not set +# CONFIG_FB_CLPS711X is not set +# CONFIG_FB_S3C2410 is not set +# CONFIG_FB_SA1100 is not set +# CONFIG_FB_EPSON1356 is not set +# CONFIG_FB_MQ200 is not set +CONFIG_FB_PXA=y +# CONFIG_FB_PXA_8BPP is not set +CONFIG_FB_PXA_16BPP=y +CONFIG_FB_MQ1100=y +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +# CONFIG_FBCON_CFB4 is not set +# CONFIG_FBCON_CFB8 is not set +CONFIG_FBCON_CFB16=y +# CONFIG_FBCON_CFB24 is not set +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +# CONFIG_FBCON_NO_LOGO is not set +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +CONFIG_FBCON_FONTS=y +CONFIG_FONT_8x8=y +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +CONFIG_SOUND_H3900_UDA1380=m +CONFIG_SOUND_H5400=m +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_PAS_JOYSTICK is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_YMFPCI_LEGACY is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_VIDC is not set +# CONFIG_SOUND_WAVEARTIST is not set +CONFIG_SOUND_PXA_AC97=m +# CONFIG_SOUND_TVMIXER is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set +# CONFIG_MCP_UCB1400_TS is not set + +# +# Console Switches +# +# CONFIG_SWITCHES is not set + +# +# USB support +# +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_LONG_TIMEOUT is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=m +# CONFIG_USB_OHCI_SA1111 is not set +CONFIG_USB_OHCI_H5400=m +CONFIG_USB_SL811HS=m +CONFIG_USB_SL811HS_CS=m + +# +# USB Device Class drivers +# +CONFIG_USB_AUDIO=m +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +CONFIG_USB_PRINTER=m + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=m +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_WACOM is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# +CONFIG_USB_IBMCAM=m +CONFIG_USB_OV511=m +CONFIG_USB_PWC=m +# CONFIG_USB_QC is not set +CONFIG_USB_SE401=m +CONFIG_USB_STV680=m +CONFIG_USB_VICAM=m +# CONFIG_USB_DSBR is not set +# CONFIG_USB_DABUSB is not set + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +CONFIG_USB_CDCETHER=m +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +CONFIG_USB_SERIAL_IPAQ=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_KLSI is not set +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_BRLVGER is not set + +# +# Support for USB gadgets +# +CONFIG_USB_GADGET=m +CONFIG_USB_GADGET_PXA2XX=y +# CONFIG_USB_GADGET_N9604 is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_SUPERH is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_CONTROLLER is not set +CONFIG_USB_PXA2XX=m +CONFIG_USB_GADGET_CONTROLLER=m +# CONFIG_USB_GADGET_DUALSPEED is not set + +# +# USB Gadget Drivers +# +CONFIG_USB_ZERO=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m + +# +# Linux As Bootldr Modules +# +# CONFIG_BIG_KERNEL is not set +# CONFIG_USE_DATE_CODE is not set +# CONFIG_YMODEM is not set +# CONFIG_LAB_DUMMY is not set +# CONFIG_LAB_CRC is not set +# CONFIG_LAB_YMODEM is not set +# CONFIG_LAB_MTD is not set +# CONFIG_LAB_COPY is not set +# CONFIG_LAB_COPY_YMODEM is not set +# CONFIG_LAB_COPY_FLASH is not set +# CONFIG_LAB_COPY_FS is not set +# CONFIG_LAB_COPY_WRAPPER is not set + +# +# Bluetooth support +# +CONFIG_BLUEZ=m +CONFIG_BLUEZ_L2CAP=m +CONFIG_BLUEZ_SCO=m +CONFIG_BLUEZ_RFCOMM=m +CONFIG_BLUEZ_RFCOMM_TTY=y +CONFIG_BLUEZ_BNEP=m +CONFIG_BLUEZ_BNEP_MC_FILTER=y +CONFIG_BLUEZ_BNEP_PROTO_FILTER=y +CONFIG_BLUEZ_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BLUEZ_HCIUSB=m +# CONFIG_BLUEZ_HCIUSB_SCO is not set +CONFIG_BLUEZ_HCIUART=m +CONFIG_BLUEZ_HCIUART_H4=y +CONFIG_BLUEZ_HCIUART_BCSP=y +# CONFIG_BLUEZ_HCIUART_BCSP_TXCRC is not set +# CONFIG_BLUEZ_HCIBFUSB is not set +CONFIG_BLUEZ_HCIDTL1=m +CONFIG_BLUEZ_HCIBT3C=m +CONFIG_BLUEZ_HCIBLUECARD=m +CONFIG_BLUEZ_HCIBTUART=m +# CONFIG_BLUEZ_HCIVHCI is not set + +# +# Kernel hacking +# +# CONFIG_FRAME_POINTER is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +# CONFIG_REED_SOLOMON is not set +CONFIG_FW_LOADER=m -- cgit v1.2.3 From 79f580d504eb7f7ebabb9ef9b53d7bda901ea312 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 31 Aug 2006 21:45:01 +0000 Subject: xserver-kdrive: apply mreimer's fix to kdrive-use-evdev.patch --- packages/xorg-xserver/xserver-kdrive/kdrive-use-evdev.patch | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/xorg-xserver/xserver-kdrive/kdrive-use-evdev.patch b/packages/xorg-xserver/xserver-kdrive/kdrive-use-evdev.patch index d4f885ee26..28d7325601 100644 --- a/packages/xorg-xserver/xserver-kdrive/kdrive-use-evdev.patch +++ b/packages/xorg-xserver/xserver-kdrive/kdrive-use-evdev.patch @@ -40,13 +40,14 @@ ErrorF("-switchCmd Command to execute on vt switch\n"); ErrorF("-nozap Don't terminate server on Ctrl+Alt+Backspace\n"); ErrorF("vtxx Use virtual terminal xx instead of the next available\n"); -@@ -796,6 +799,10 @@ +@@ -796,6 +799,11 @@ UseMsg (); return 2; } + if (!strcmp (argv[i], "-use-evdev")) + { + use_evdev = 1; ++ return 1; + } if (!strcmp (argv[i], "-keyboard")) { -- cgit v1.2.3 From abdcfacc9fd95489b2c51b0767fa46238f518cb3 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 31 Aug 2006 21:47:55 +0000 Subject: xserver-kdrive-X11R7.1: apply latest fixes from the git .bb - build Xepson and Xsdl - package SecurityPolicy --- .../xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb | 23 +++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb b/packages/xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb index cfb1294c09..78b4054232 100644 --- a/packages/xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb +++ b/packages/xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb @@ -1,18 +1,32 @@ LICENSE = "MIT" -DEPENDS = "tslib xproto libxdmcp xextproto xtrans libxau virtual/libx11 libxext libxrandr fixesproto damageproto libxfont resourceproto compositeproto xcalibrateext recordproto videoproto scrnsaverproto" +DEPENDS = "tslib virtual/libsdl xproto libxdmcp xextproto xtrans libxau virtual/libx11 libxext libxrandr fixesproto damageproto libxfont resourceproto compositeproto xcalibrateext recordproto videoproto scrnsaverproto" + +PR = "r2" PROVIDES = "virtual/xserver" RPROVIDES = "virtual/xserver" -PACKAGES = "xserver-kdrive-fbdev xserver-kdrive-fake xserver-kdrive-xephyr ${PN}-doc ${PN}-dev ${PN}-locale" +PACKAGES =+ "xserver-kdrive-fbdev xserver-kdrive-sdl xserver-kdrive-fake xserver-kdrive-xephyr xserver-kdrive-epson ${PN}-doc ${PN}-dev ${PN}-locale" SECTION = "x11/base" DESCRIPTION = "X server from freedesktop.org" DESCRIPTION_xserver-kdrive-fbdev = "X server from freedesktop.org, supporting generic framebuffer devices" DESCRIPTION_xserver-kdrive-fake = "Fake X server" DESCRIPTION_xserver-kdrive-xephyr = "X server in an X window" +DESCRIPTION_xserver-kdrive-epson = "X server from freedesktop.org, supporting Epson S1D13806 devices" +DESCRIPTION_xserver-kdrive-epson = "X server from freedesktop.org, SDL version" + +FILES_${PN} += "${libdir}/xserver/SecurityPolicy" FILES_xserver-kdrive-fbdev = "${bindir}/Xfbdev" FILES_xserver-kdrive-fake = "${bindir}/Xfake" FILES_xserver-kdrive-xephyr = "${bindir}/Xephyr" +FILES_xserver-kdrive-epson = "${bindir}/Xepson" +FILES_xserver-kdrive-sdl = "${bindir}/Xsdl" + +RDEPENDS_xserver-kdrive-fbdev = "${PN}" +RDEPENDS_xserver-kdrive-fake = "${PN}" +RDEPENDS_xserver-kdrive-xephyr = "${PN}" +RDEPENDS_xserver-kdrive-epson = "${PN}" +RDEPENDS_xserver-kdrive-sdl = "${PN}" SRC_URI = "http://ftp.x.org/pub/X11R7.1/src/xserver/xorg-server-X11R7.1-1.1.0.tar.bz2 \ file://kmode.patch;patch=1 \ @@ -23,6 +37,7 @@ SRC_URI = "http://ftp.x.org/pub/X11R7.1/src/xserver/xorg-server-X11R7.1-1.1.0.ta file://fbdev-not-fix.patch;patch=1 \ file://enable-builtin-fonts.patch;patch=1 \ file://optional-xkb.patch;patch=1 \ + file://enable-epson.patch;patch=1 \ file://disable-xf86-dga-xorgcfg.patch;patch=1 \ file://enable-tslib.patch;patch=1 \ file://xcalibrate.patch;patch=1" @@ -39,8 +54,10 @@ EXTRA_OECONF = "--enable-composite --enable-kdrive \ --disable-dga --disable-dri --disable-xinerama \ --disable-xf86misc --disable-xf86vidmode \ --disable-xorg --disable-xorgcfg \ - --disable-dmx \ --disable-xkb --disable-xnest --disable-xvfb \ --disable-xevie --disable-xprint --disable-xtrap \ + --disable-dmx \ --with-default-font-path=built-ins \ + --enable-tslib --enable-xcalibrate \ ac_cv_file__usr_share_X11_sgml_defs_ent=no" + -- cgit v1.2.3 From e64c9654dbc7319dbd9d54d5c9f2c53e02963ffb Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 31 Aug 2006 21:50:06 +0000 Subject: xserver-kdrive-git: update and apply disable-xf86-dga-xorgcfg.patch --- .../disable-xf86-dga-xorgcfg-git.patch | 39 ++++++++++++++++++++++ packages/xorg-xserver/xserver-kdrive_git.bb | 7 ++-- 2 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 packages/xorg-xserver/xserver-kdrive/disable-xf86-dga-xorgcfg-git.patch diff --git a/packages/xorg-xserver/xserver-kdrive/disable-xf86-dga-xorgcfg-git.patch b/packages/xorg-xserver/xserver-kdrive/disable-xf86-dga-xorgcfg-git.patch new file mode 100644 index 0000000000..4b7e41e3e9 --- /dev/null +++ b/packages/xorg-xserver/xserver-kdrive/disable-xf86-dga-xorgcfg-git.patch @@ -0,0 +1,39 @@ +Index: git/configure.ac +=================================================================== +--- git.orig/configure.ac 2006-08-31 22:44:06.000000000 +0200 ++++ git/configure.ac 2006-08-31 22:49:39.000000000 +0200 +@@ -513,7 +513,11 @@ + XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la' + + dnl Core modules for most extensions, et al. ++if test "$KDRIVE" = yes; then ++REQUIRED_MODULES="randrproto renderproto [fixesproto >= 4.0] damageproto xcmiscproto xextproto xproto xtrans xf86bigfontproto [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto inputproto [kbproto >= 1.0.3]" ++else + REQUIRED_MODULES="randrproto renderproto [fixesproto >= 4.0] damageproto xcmiscproto xextproto xproto xtrans xf86miscproto xf86vidmodeproto xf86bigfontproto [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto inputproto xf86dgaproto [kbproto >= 1.0.3]" ++fi + REQUIRED_LIBS="xfont xau fontenc" + + AM_CONDITIONAL(XV, [test "x$XV" = xyes]) +@@ -1540,7 +1544,9 @@ + AC_SUBST(XKB_COMPILED_DIR) + + dnl and the rest of these are generic, so they're in config.h ++if test ! x"$KDRIVE" = xyes; then + AC_DEFINE(XFreeXDGA, 1, [Build XDGA support]) ++fi + AC_DEFINE(XResExtension, 1, [Build XRes extension]) + + dnl CYGWIN does not define fd_set if _POSIX_SOURCE is defined +@@ -1560,10 +1566,12 @@ + + AC_DEFINE_DIR(PROJECTROOT, prefix, [Overall prefix]) + ++if test ! "x$KDRIVE" = xyes ; then + dnl xorgconfig CLI configuration utility + PKG_CHECK_MODULES([XORGCONFIG_DEP], [xkbfile x11]) + AC_SUBST(XORGCONFIG_DEP_CFLAGS) + AC_SUBST(XORGCONFIG_DEP_LIBS) ++fi + + dnl xorgcfg GUI configuration utility + AC_ARG_ENABLE(xorgcfg, AS_HELP_STRING([--enable-xorgcfg], diff --git a/packages/xorg-xserver/xserver-kdrive_git.bb b/packages/xorg-xserver/xserver-kdrive_git.bb index 9c967db254..bffcc4cdee 100644 --- a/packages/xorg-xserver/xserver-kdrive_git.bb +++ b/packages/xorg-xserver/xserver-kdrive_git.bb @@ -1,10 +1,10 @@ PV = "1.1.0+git${SRCDATE}" DEFAULT_PREFERENCE = "-2" -PR = "r3" +PR = "r4" LICENSE = "MIT" -DEPENDS = "tslib virtual/libsdl libxkbfile xf86dgaproto xf86vidmodeproto xf86miscproto xproto libxdmcp xextproto xtrans libxau virtual/libx11 libxext libxrandr fixesproto damageproto libxfont resourceproto compositeproto libxcalibrate recordproto videoproto scrnsaverproto" +DEPENDS = "tslib virtual/libsdl libxkbfile xproto libxdmcp xextproto xtrans libxau virtual/libx11 libxext libxrandr fixesproto damageproto libxfont resourceproto compositeproto libxcalibrate recordproto videoproto scrnsaverproto" PROVIDES = "virtual/xserver" RPROVIDES = "virtual/xserver" @@ -41,7 +41,7 @@ SRC_URI = "git://anongit.freedesktop.org/xorg/xserver;protocol=git \ file://enable-builtin-fonts.patch;patch=1 \ file://optional-xkb.patch;patch=1 \ file://enable-epson.patch;patch=1 \ -# file://disable-xf86-dga-xorgcfg.patch;patch=1 \ + file://disable-xf86-dga-xorgcfg-git.patch;patch=1 \ " SRC_URI_append_mnci = " file://onlyfb.patch;patch=1" @@ -63,4 +63,3 @@ EXTRA_OECONF = "--enable-composite --enable-kdrive \ --enable-tslib --enable-xcalibrate \ ac_cv_file__usr_share_X11_sgml_defs_ent=no" - -- cgit v1.2.3 From 2499a6a0c904d96d20ef9c416f1a35ff2b1ab79a Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 31 Aug 2006 21:52:17 +0000 Subject: xserver-kdrive: bump PR for cvs and 20060312 (use-evdev fix) --- packages/xorg-xserver/xserver-kdrive_20060312.bb | 2 +- packages/xorg-xserver/xserver-kdrive_cvs.bb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/xorg-xserver/xserver-kdrive_20060312.bb b/packages/xorg-xserver/xserver-kdrive_20060312.bb index 594b6d74ec..c5080452ae 100644 --- a/packages/xorg-xserver/xserver-kdrive_20060312.bb +++ b/packages/xorg-xserver/xserver-kdrive_20060312.bb @@ -20,7 +20,7 @@ DESCRIPTION_xserver-kdrive-epson = "X server from freedesktop.org, supporting Ep DESCRIPTION_xserver-kdrive-fake = "Fake X server" DESCRIPTION_xserver-kdrive-xephyr = "X server in an X window" -PR = "r11" +PR = "r12" FILES_xserver-kdrive-fbdev = "${bindir}/Xfbdev" FILES_xserver-kdrive-ati = "${bindir}/Xati" diff --git a/packages/xorg-xserver/xserver-kdrive_cvs.bb b/packages/xorg-xserver/xserver-kdrive_cvs.bb index c2b25973fb..e0e24065e6 100644 --- a/packages/xorg-xserver/xserver-kdrive_cvs.bb +++ b/packages/xorg-xserver/xserver-kdrive_cvs.bb @@ -19,7 +19,7 @@ DESCRIPTION_xserver-kdrive-epson = "X server from freedesktop.org, supporting Ep DESCRIPTION_xserver-kdrive-fake = "Fake X server" DESCRIPTION_xserver-kdrive-xephyr = "X server in an X window" -PR = "r11" +PR = "r12" FILES_xserver-kdrive-fbdev = "${bindir}/Xfbdev" FILES_xserver-kdrive-ati = "${bindir}/Xati" -- cgit v1.2.3 From 595bc05e18f8dc76aa07f6a59349fa7180885fd5 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Thu, 31 Aug 2006 23:43:07 +0000 Subject: initscripts-slugos: Fix extra symlinks that break do_install. Bump PR of initscripts --- packages/initscripts/initscripts-slugos_1.0.bb | 17 ++++++++++++----- packages/initscripts/initscripts_1.0.bb | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/initscripts/initscripts-slugos_1.0.bb b/packages/initscripts/initscripts-slugos_1.0.bb index dcb57e92bb..f64e11dfe4 100644 --- a/packages/initscripts/initscripts-slugos_1.0.bb +++ b/packages/initscripts/initscripts-slugos_1.0.bb @@ -4,14 +4,14 @@ # problems in the initscripts on SlugOS. The problems # mostly come down to the order the scripts are executed # in. -require initscripts_${PV}.bb +include initscripts_${PV}.bb MAINTAINER = "John Bowler " RCONFLICTS = "initscripts" # All other standard definitions inherited from initscripts # Except the PR which is hacked here. The format used is # a suffix -PR := "${PR}.9" +PR := "${PR}.10" FILESPATH = "${@base_set_filespath([ '${FILE_DIRNAME}/${P}', '${FILE_DIRNAME}/initscripts-${PV}', '${FILE_DIRNAME}/files', '${FILE_DIRNAME}' ], d)}" @@ -64,15 +64,20 @@ do_install_append() { # udev will run at S04 if installed rm ${D}${sysconfdir}/rcS.d/S03sysfs rm ${D}${sysconfdir}/rcS.d/S38devpts.sh -# rm ${D}${sysconfdir}/rcS.d/S06alignment + rm ${D}${sysconfdir}/rcS.d/S06alignment + rm ${D}${sysconfdir}/rcS.d/S37populate-volatile.sh + rm ${D}${sysconfdir}/rc0.d/S25save-rtc.sh + rm ${D}${sysconfdir}/rc6.d/S25save-rtc.sh + + # Check the result find ${D}${sysconfdir}/rc?.d ! -type d -print | { status=0 while read d do - oenote "initscripts-slugos: unexpected link $f" - status = 1 + oenote "initscripts-slugos: unexpected link $d" + status=1 done test $status -eq 0 || oefatal "initscripts-slugos: new links break do_install" @@ -102,6 +107,7 @@ do_install_append() { # base-files populate-volatile.sh runs at S37 update-rc.d -r ${D} devpts.sh start 38 S . # slugos file syslog starts here (39) + update-rc.d -r ${D} populate-volatile.sh start 37 S . # set hostname and domainname before the network script works (by # entering them at level 40), networking may reset them. @@ -138,6 +144,7 @@ do_install_append() { # This is the special, correct, slugos umountnfs.sh (it looks in # the /proc/mounts information, not /etc/fstab) update-rc.d -r ${D} umountnfs.sh start 31 0 6 . + update-rc.d -r ${D} save-rtc.sh start 25 0 6 . # portmap stops at 32 # slugos network syslog stops here (39) # networking stops at 40 (nothing else does, believe me.) diff --git a/packages/initscripts/initscripts_1.0.bb b/packages/initscripts/initscripts_1.0.bb index 29747d41c2..9cf7e47de0 100644 --- a/packages/initscripts/initscripts_1.0.bb +++ b/packages/initscripts/initscripts_1.0.bb @@ -92,7 +92,7 @@ do_install () { # Install device dependent scripts # - if [ "${DISTRO}" == "openzaurus" ]; then + if [ "${DISTRO}" = "openzaurus" ]; then cat ${WORKDIR}/checkversion | sed -e "s,VERSION,${KERNEL_VERSION}-${DISTRO_VERSION}," > ${D}${sysconfdir}/init.d/checkversion chmod 0755 ${D}${sysconfdir}/init.d/checkversion ln -sf ../init.d/checkversion ${D}${sysconfdir}/rcS.d/S01version -- cgit v1.2.3 From 17c6027f5979a73ec425199947ca1c046d0c7aa6 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Thu, 31 Aug 2006 23:50:26 +0000 Subject: busybox: Add updated slugos defconfig, remove openslug-only directory, bump busybox PR --- .../busybox/busybox-1.2.1/openslug/.mtn2git_empty | 0 .../busybox-1.2.1/openslug/udhcpscript.patch | 133 ------ .../busybox/busybox-1.2.1/slugos/.mtn2git_empty | 0 packages/busybox/busybox-1.2.1/slugos/defconfig | 444 +++++++++++++++++++++ .../busybox/busybox-1.2.1/slugos/udhcpscript.patch | 133 ++++++ packages/busybox/busybox_1.2.1.bb | 2 +- 6 files changed, 578 insertions(+), 134 deletions(-) delete mode 100644 packages/busybox/busybox-1.2.1/openslug/.mtn2git_empty delete mode 100644 packages/busybox/busybox-1.2.1/openslug/udhcpscript.patch create mode 100644 packages/busybox/busybox-1.2.1/slugos/.mtn2git_empty create mode 100644 packages/busybox/busybox-1.2.1/slugos/defconfig create mode 100644 packages/busybox/busybox-1.2.1/slugos/udhcpscript.patch diff --git a/packages/busybox/busybox-1.2.1/openslug/.mtn2git_empty b/packages/busybox/busybox-1.2.1/openslug/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/busybox/busybox-1.2.1/openslug/udhcpscript.patch b/packages/busybox/busybox-1.2.1/openslug/udhcpscript.patch deleted file mode 100644 index 010f64a53f..0000000000 --- a/packages/busybox/busybox-1.2.1/openslug/udhcpscript.patch +++ /dev/null @@ -1,133 +0,0 @@ ---- busybox-1.00/.pc/udhcpscript.patch/examples/udhcp/simple.script 2004-10-13 00:18:05.000000000 -0700 -+++ busybox-1.00/examples/udhcp/simple.script 2005-06-05 15:08:28.432605118 -0700 -@@ -1,40 +1,101 @@ - #!/bin/sh -+# openslug UDHCP client script -+# this must set the HW address (MAC) on the interface -+# -+. /etc/default/functions - --# udhcpc script edited by Tim Riker - --[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1 -+echodns(){ -+ local dns -+ if test $# -gt 0 -+ then -+ for dns in "$@" -+ do -+ echo "nameserver $dns" -+ done -+ fi -+} -+ -+# Output the correct contents for resolv.conf -+mkresolv() { -+ test -n "$domain" && echo "search $domain" -+ echodns $dns -+} -+ -+# checksum of a file (or stdin if -) -+md5strm() { -+ md5sum $1 2>/dev/null | sed -n 's/^\([0-9A-Za-z]*\).*$/\1/p' -+} -+ -+bind() { -+ local B N metric i olddomain -+ B= -+ test -n "$broadcast" && B="broadcast $broadcast" -+ N= -+ test -n "$subnet" && N="netmask $subnet" -+ ifconfig "$interface" "$ip" $B $N up -+ -+ # If given router information delete the old information and -+ # enter new stuff, routers get metrics incremented by 1 -+ # between each (this is somewhat arbitrary) -+ if test -n "$router" -+ then -+ while route del default gw 0.0.0.0 dev $interface 2>/dev/null -+ do -+ : -+ done - --RESOLV_CONF="/etc/resolv.conf" --[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast" --[ -n "$subnet" ] && NETMASK="netmask $subnet" -+ metric=0 -+ for i in $router -+ do -+ route add default gw "$i" dev "$interface" metric $((metric++)) -+ done -+ fi -+ -+ olddomain= -+ test -r /etc/defaultdomain && olddomain="$(cat /etc/defaultdomain)" -+ if test -n "$domain" -a "$domain" != "$olddomain" -+ then -+ echo "$domain" >/etc/defaultdomain -+ # and update the kernel view too -+ echo "$domain" >/proc/sys/kernel/domainname -+ fi -+ -+ # Update /etc/resolv.conf to reflect domain and dns information, -+ # this always clears resolv.conf if none is given -+ md5old="$(md5strm /etc/resolv.conf)" -+ md5new="$(mkresolv | md5strm -)" -+ test "$md5old" != "$md5new" && mkresolv >/etc/resolv.conf -+} - - case "$1" in -- deconfig) -- /sbin/ifconfig $interface 0.0.0.0 -- ;; -- -- renew|bound) -- /sbin/ifconfig $interface $ip $BROADCAST $NETMASK -- -- if [ -n "$router" ] ; then -- echo "deleting routers" -- while route del default gw 0.0.0.0 dev $interface ; do -- : -- done -- -- metric=0 -- for i in $router ; do -- route add default gw $i dev $interface metric $((metric++)) -- done -+deconfig) -+ # Bring the interface up (without inet at this point) -+ ifconfig "$interface" up;; -+ -+renew|bound) -+ bind;; -+ -+leasefail) -+ # Pull the values from the config data if (only only if) this -+ # is the config interface -+ if test "$interface" = "$(config iface)" -+ then -+ ip="$(config ip)" -+ if test -n "$ip" -+ then -+ router="$(config gateway)" -+ subnet="$(config netmask)" -+ broadcast="$(config broadcast)" -+ domain="$(config domain)" -+ dns="$(config dns)" -+ -+ bind - fi -+ fi;; - -- echo -n > $RESOLV_CONF -- [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF -- for i in $dns ; do -- echo adding dns $i -- echo nameserver $i >> $RESOLV_CONF -- done -- ;; -+*) echo "udhcpc: $*: unknown command" >&2 -+ exit 1;; - esac - - exit 0 diff --git a/packages/busybox/busybox-1.2.1/slugos/.mtn2git_empty b/packages/busybox/busybox-1.2.1/slugos/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/busybox/busybox-1.2.1/slugos/defconfig b/packages/busybox/busybox-1.2.1/slugos/defconfig new file mode 100644 index 0000000000..55aa5f3b5e --- /dev/null +++ b/packages/busybox/busybox-1.2.1/slugos/defconfig @@ -0,0 +1,444 @@ +# +# Automatically generated make config: don't edit +# +HAVE_DOT_CONFIG=y + +# +# General Configuration +# +# CONFIG_FEATURE_BUFFERS_USE_MALLOC is not set +CONFIG_FEATURE_BUFFERS_GO_ON_STACK=y +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_FEATURE_VERBOSE_USAGE=y +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_FEATURE_DEVFS is not set +CONFIG_FEATURE_DEVPTS=y +# CONFIG_FEATURE_CLEAN_UP is not set +CONFIG_FEATURE_SUID=y +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_SELINUX is not set + +# +# Build Options +# +# CONFIG_STATIC is not set +CONFIG_LFS=y +# USING_CROSS_COMPILER is not set +EXTRA_CFLAGS_OPTIONS="" + +# +# Installation Options +# +# CONFIG_INSTALL_NO_USR is not set +PREFIX="./_install" + +# +# Archival Utilities +# +CONFIG_AR=y +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +CONFIG_BUNZIP2=y +# CONFIG_CPIO is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +CONFIG_GUNZIP=y +# CONFIG_FEATURE_GUNZIP_UNCOMPRESS is not set +CONFIG_GZIP=y +# CONFIG_RPM2CPIO is not set +# CONFIG_RPM is not set +CONFIG_TAR=y +CONFIG_FEATURE_TAR_CREATE=y +CONFIG_FEATURE_TAR_BZIP2=y +CONFIG_FEATURE_TAR_FROM=y +CONFIG_FEATURE_TAR_GZIP=y +# CONFIG_FEATURE_TAR_COMPRESS is not set +CONFIG_FEATURE_TAR_OLDGNU_COMPATABILITY=y +CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_UNCOMPRESS is not set +CONFIG_UNZIP=y + +# +# Common options for cpio and tar +# +# CONFIG_FEATURE_UNARCHIVE_TAPE is not set + +# +# Coreutils +# +CONFIG_BASENAME=y +# CONFIG_CAL is not set +CONFIG_CAT=y +CONFIG_CHGRP=y +CONFIG_CHMOD=y +CONFIG_CHOWN=y +CONFIG_CHROOT=y +# CONFIG_CMP is not set +CONFIG_CP=y +CONFIG_CUT=y +CONFIG_DATE=y + +# +# date (forced enabled for use with watch) +# +# CONFIG_FEATURE_DATE_ISOFMT is not set +CONFIG_DD=y +CONFIG_DF=y +CONFIG_DIRNAME=y +# CONFIG_DOS2UNIX is not set +CONFIG_DU=y +CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K=y +CONFIG_ECHO=y +CONFIG_FEATURE_FANCY_ECHO=y +CONFIG_ENV=y +CONFIG_EXPR=y +CONFIG_FALSE=y +# CONFIG_FOLD is not set +CONFIG_HEAD=y +CONFIG_FEATURE_FANCY_HEAD=y +# CONFIG_HOSTID is not set +CONFIG_ID=y +# CONFIG_INSTALL is not set +# CONFIG_LENGTH is not set +CONFIG_LN=y +CONFIG_LOGNAME=y +CONFIG_LS=y +CONFIG_FEATURE_LS_FILETYPES=y +CONFIG_FEATURE_LS_FOLLOWLINKS=y +CONFIG_FEATURE_LS_RECURSIVE=y +CONFIG_FEATURE_LS_SORTFILES=y +CONFIG_FEATURE_LS_TIMESTAMPS=y +CONFIG_FEATURE_LS_USERNAME=y +CONFIG_FEATURE_LS_COLOR=y +CONFIG_MD5SUM=y +CONFIG_MKDIR=y +CONFIG_MKFIFO=y +CONFIG_MKNOD=y +CONFIG_MV=y +CONFIG_OD=y +CONFIG_PRINTF=y +CONFIG_PWD=y +# CONFIG_REALPATH is not set +CONFIG_RM=y +CONFIG_RMDIR=y +CONFIG_SEQ=y +# CONFIG_SHA1SUM is not set +CONFIG_SLEEP=y +# CONFIG_FEATURE_FANCY_SLEEP is not set +CONFIG_SORT=y +CONFIG_STTY=y +CONFIG_SYNC=y +CONFIG_TAIL=y +CONFIG_FEATURE_FANCY_TAIL=y +CONFIG_TEE=y +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +CONFIG_TEST=y + +# +# test (forced enabled for use with shell) +# +# CONFIG_FEATURE_TEST_64 is not set +CONFIG_TOUCH=y +CONFIG_TR=y +CONFIG_TRUE=y +CONFIG_TTY=y +CONFIG_UNAME=y +CONFIG_UNIQ=y +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_UUENCODE is not set +CONFIG_WATCH=y +CONFIG_WC=y +CONFIG_WHO=y +CONFIG_WHOAMI=y +CONFIG_YES=y + +# +# Common options for cp and mv +# +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set + +# +# Common options for ls and more +# +CONFIG_FEATURE_AUTOWIDTH=y + +# +# Common options for df, du, ls +# +CONFIG_FEATURE_HUMAN_READABLE=y + +# +# Common options for md5sum, sha1sum +# +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +CONFIG_CLEAR=y +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +CONFIG_GETKEY=y +# CONFIG_LOADFONT is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +CONFIG_RESET=y +# CONFIG_SETKEYCODES is not set + +# +# Debian Utilities +# +CONFIG_MKTEMP=y +# CONFIG_PIPE_PROGRESS is not set +CONFIG_READLINK=y +CONFIG_FEATURE_READLINK_FOLLOW=y +CONFIG_RUN_PARTS=y +CONFIG_START_STOP_DAEMON=y +CONFIG_WHICH=y + +# +# Editors +# +CONFIG_AWK=y +CONFIG_FEATURE_AWK_MATH=y +# CONFIG_PATCH is not set +CONFIG_SED=y +CONFIG_VI=y +CONFIG_FEATURE_VI_COLON=y +CONFIG_FEATURE_VI_YANKMARK=y +CONFIG_FEATURE_VI_SEARCH=y +CONFIG_FEATURE_VI_USE_SIGNALS=y +CONFIG_FEATURE_VI_DOT_CMD=y +CONFIG_FEATURE_VI_READONLY=y +CONFIG_FEATURE_VI_SETOPTS=y +CONFIG_FEATURE_VI_SET=y +CONFIG_FEATURE_VI_WIN_RESIZE=y +CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y + +# +# Finding Utilities +# +# CONFIG_FIND is not set +CONFIG_GREP=y +CONFIG_FEATURE_GREP_EGREP_ALIAS=y +CONFIG_FEATURE_GREP_FGREP_ALIAS=y +CONFIG_FEATURE_GREP_CONTEXT=y +# CONFIG_XARGS is not set + +# +# Init Utilities +# +# CONFIG_INIT is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_MESG is not set + +# +# Login/Password Management Utilities +# +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_ADDGROUP is not set +# CONFIG_DELGROUP is not set +# CONFIG_ADDUSER is not set +# CONFIG_DELUSER is not set +# CONFIG_GETTY is not set +CONFIG_FEATURE_UTMP=y +# CONFIG_LOGIN is not set +# CONFIG_PASSWD is not set +# CONFIG_SU is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_CROND is not set +# CONFIG_CRONTAB is not set +# CONFIG_DC is not set +# CONFIG_DEVFSD is not set +# CONFIG_LAST is not set +# CONFIG_HDPARM is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_MT is not set +# CONFIG_RX is not set +CONFIG_STRINGS=y +CONFIG_TIME=y +# CONFIG_WATCHDOG is not set + +# +# Linux Module Utilities +# +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_MODPROBE is not set +# CONFIG_RMMOD is not set + +# +# Networking Utilities +# +CONFIG_FEATURE_IPV6=y +# CONFIG_ARPING is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +CONFIG_HOSTNAME=y +# CONFIG_HTTPD is not set +CONFIG_IFCONFIG=y +CONFIG_FEATURE_IFCONFIG_STATUS=y +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +CONFIG_FEATURE_IFCONFIG_HW=y +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +CONFIG_IFUPDOWN=y +# CONFIG_FEATURE_IFUPDOWN_IP is not set +CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN=y +CONFIG_FEATURE_IFUPDOWN_IPV4=y +CONFIG_FEATURE_IFUPDOWN_IPV6=y +# CONFIG_FEATURE_IFUPDOWN_IPX is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_INETD is not set +# CONFIG_IP is not set +# CONFIG_IPCALC is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_NAMEIF is not set +CONFIG_NC=y +CONFIG_NETSTAT=y +CONFIG_NSLOOKUP=y +CONFIG_PING=y +CONFIG_FEATURE_FANCY_PING=y +CONFIG_PING6=y +CONFIG_FEATURE_FANCY_PING6=y +CONFIG_ROUTE=y +CONFIG_TELNET=y +CONFIG_FEATURE_TELNET_TTYPE=y +CONFIG_FEATURE_TELNET_AUTOLOGIN=y +# CONFIG_TELNETD is not set +CONFIG_TFTP=y +CONFIG_FEATURE_TFTP_GET=y +CONFIG_FEATURE_TFTP_PUT=y +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_FEATURE_TFTP_DEBUG is not set +CONFIG_TRACEROUTE=y +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_VCONFIG is not set +CONFIG_WGET=y +CONFIG_FEATURE_WGET_STATUSBAR=y +CONFIG_FEATURE_WGET_AUTHENTICATION=y +CONFIG_FEATURE_WGET_IP6_LITERAL=y + +# +# udhcp Server/Client +# +# CONFIG_UDHCPD is not set +CONFIG_UDHCPC=y +CONFIG_FEATURE_UDHCP_SYSLOG=y +# CONFIG_FEATURE_UDHCP_DEBUG is not set + +# +# Process Utilities +# +CONFIG_FREE=y +CONFIG_KILL=y +CONFIG_KILLALL=y +CONFIG_PIDOF=y +CONFIG_PS=y +CONFIG_RENICE=y +CONFIG_TOP=y +FEATURE_CPU_USAGE_PERCENTAGE=y +CONFIG_UPTIME=y +CONFIG_SYSCTL=y + +# +# Another Bourne-like Shell +# +CONFIG_FEATURE_SH_IS_ASH=y +# CONFIG_FEATURE_SH_IS_HUSH is not set +# CONFIG_FEATURE_SH_IS_LASH is not set +# CONFIG_FEATURE_SH_IS_MSH is not set +# CONFIG_FEATURE_SH_IS_NONE is not set +CONFIG_ASH=y + +# +# Ash Shell Options +# +CONFIG_ASH_JOB_CONTROL=y +CONFIG_ASH_ALIAS=y +CONFIG_ASH_MATH_SUPPORT=y +# CONFIG_ASH_MATH_SUPPORT_64 is not set +CONFIG_ASH_GETOPTS=y +# CONFIG_ASH_CMDCMD is not set +# CONFIG_ASH_MAIL is not set +CONFIG_ASH_OPTIMIZE_FOR_SIZE=y +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_HUSH is not set +# CONFIG_LASH is not set +# CONFIG_MSH is not set + +# +# Bourne Shell Options +# +CONFIG_FEATURE_SH_EXTRA_QUIET=y +# CONFIG_FEATURE_SH_STANDALONE_SHELL is not set +CONFIG_FEATURE_COMMAND_EDITING=y +CONFIG_FEATURE_COMMAND_HISTORY=63 +# CONFIG_FEATURE_COMMAND_SAVEHISTORY is not set +CONFIG_FEATURE_COMMAND_TAB_COMPLETION=y +# CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION is not set +CONFIG_FEATURE_SH_FANCY_PROMPT=y + +# +# System Logging Utilities +# +CONFIG_SYSLOGD=y +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +CONFIG_FEATURE_REMOTE_LOG=y +CONFIG_FEATURE_IPC_SYSLOG=y +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16 +CONFIG_LOGREAD=y +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +CONFIG_KLOGD=y +CONFIG_LOGGER=y + +# +# Linux System Utilities +# +CONFIG_DMESG=y +# CONFIG_FBSET is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FDFORMAT is not set +CONFIG_FDISK=y +FDISK_SUPPORT_LARGE_DISKS=y +CONFIG_FEATURE_FDISK_WRITABLE=y +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +CONFIG_FEATURE_OSF_LABEL=y +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_GETOPT is not set +CONFIG_HEXDUMP=y +CONFIG_HWCLOCK=y +CONFIG_FEATURE_HWCLOCK_LONGOPTIONS=y +# CONFIG_LOSETUP is not set +CONFIG_MKSWAP=y +CONFIG_MORE=y +CONFIG_FEATURE_USE_TERMIOS=y +CONFIG_PIVOT_ROOT=y +# CONFIG_RDATE is not set +# CONFIG_SWAPONOFF is not set +# CONFIG_MOUNT is not set +# CONFIG_UMOUNT is not set + +# +# Debugging Options +# +# CONFIG_DEBUG is not set diff --git a/packages/busybox/busybox-1.2.1/slugos/udhcpscript.patch b/packages/busybox/busybox-1.2.1/slugos/udhcpscript.patch new file mode 100644 index 0000000000..010f64a53f --- /dev/null +++ b/packages/busybox/busybox-1.2.1/slugos/udhcpscript.patch @@ -0,0 +1,133 @@ +--- busybox-1.00/.pc/udhcpscript.patch/examples/udhcp/simple.script 2004-10-13 00:18:05.000000000 -0700 ++++ busybox-1.00/examples/udhcp/simple.script 2005-06-05 15:08:28.432605118 -0700 +@@ -1,40 +1,101 @@ + #!/bin/sh ++# openslug UDHCP client script ++# this must set the HW address (MAC) on the interface ++# ++. /etc/default/functions + +-# udhcpc script edited by Tim Riker + +-[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1 ++echodns(){ ++ local dns ++ if test $# -gt 0 ++ then ++ for dns in "$@" ++ do ++ echo "nameserver $dns" ++ done ++ fi ++} ++ ++# Output the correct contents for resolv.conf ++mkresolv() { ++ test -n "$domain" && echo "search $domain" ++ echodns $dns ++} ++ ++# checksum of a file (or stdin if -) ++md5strm() { ++ md5sum $1 2>/dev/null | sed -n 's/^\([0-9A-Za-z]*\).*$/\1/p' ++} ++ ++bind() { ++ local B N metric i olddomain ++ B= ++ test -n "$broadcast" && B="broadcast $broadcast" ++ N= ++ test -n "$subnet" && N="netmask $subnet" ++ ifconfig "$interface" "$ip" $B $N up ++ ++ # If given router information delete the old information and ++ # enter new stuff, routers get metrics incremented by 1 ++ # between each (this is somewhat arbitrary) ++ if test -n "$router" ++ then ++ while route del default gw 0.0.0.0 dev $interface 2>/dev/null ++ do ++ : ++ done + +-RESOLV_CONF="/etc/resolv.conf" +-[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast" +-[ -n "$subnet" ] && NETMASK="netmask $subnet" ++ metric=0 ++ for i in $router ++ do ++ route add default gw "$i" dev "$interface" metric $((metric++)) ++ done ++ fi ++ ++ olddomain= ++ test -r /etc/defaultdomain && olddomain="$(cat /etc/defaultdomain)" ++ if test -n "$domain" -a "$domain" != "$olddomain" ++ then ++ echo "$domain" >/etc/defaultdomain ++ # and update the kernel view too ++ echo "$domain" >/proc/sys/kernel/domainname ++ fi ++ ++ # Update /etc/resolv.conf to reflect domain and dns information, ++ # this always clears resolv.conf if none is given ++ md5old="$(md5strm /etc/resolv.conf)" ++ md5new="$(mkresolv | md5strm -)" ++ test "$md5old" != "$md5new" && mkresolv >/etc/resolv.conf ++} + + case "$1" in +- deconfig) +- /sbin/ifconfig $interface 0.0.0.0 +- ;; +- +- renew|bound) +- /sbin/ifconfig $interface $ip $BROADCAST $NETMASK +- +- if [ -n "$router" ] ; then +- echo "deleting routers" +- while route del default gw 0.0.0.0 dev $interface ; do +- : +- done +- +- metric=0 +- for i in $router ; do +- route add default gw $i dev $interface metric $((metric++)) +- done ++deconfig) ++ # Bring the interface up (without inet at this point) ++ ifconfig "$interface" up;; ++ ++renew|bound) ++ bind;; ++ ++leasefail) ++ # Pull the values from the config data if (only only if) this ++ # is the config interface ++ if test "$interface" = "$(config iface)" ++ then ++ ip="$(config ip)" ++ if test -n "$ip" ++ then ++ router="$(config gateway)" ++ subnet="$(config netmask)" ++ broadcast="$(config broadcast)" ++ domain="$(config domain)" ++ dns="$(config dns)" ++ ++ bind + fi ++ fi;; + +- echo -n > $RESOLV_CONF +- [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF +- for i in $dns ; do +- echo adding dns $i +- echo nameserver $i >> $RESOLV_CONF +- done +- ;; ++*) echo "udhcpc: $*: unknown command" >&2 ++ exit 1;; + esac + + exit 0 diff --git a/packages/busybox/busybox_1.2.1.bb b/packages/busybox/busybox_1.2.1.bb index 741df3f62d..61df8a9b1c 100644 --- a/packages/busybox/busybox_1.2.1.bb +++ b/packages/busybox/busybox_1.2.1.bb @@ -10,7 +10,7 @@ HOMEPAGE = "http://www.busybox.net" LICENSE = "GPL" SECTION = "base" PRIORITY = "required" -PR = "r1" +PR = "r1.1" SRC_URI = "http://www.busybox.net/downloads/busybox-${PV}.tar.gz \ file://dhcp-hostname.patch;patch=1 \ -- cgit v1.2.3 From 0fd1a70f523a36b525055337d1963a9454b372b5 Mon Sep 17 00:00:00 2001 From: Jamie Lenehan Date: Fri, 1 Sep 2006 01:48:58 +0000 Subject: linux: Add a 2.6.17 kernel for the pcengines WRAP (Wireless Router Application Platform) boards. These boards use a 233MHz AMD Geode SC1100 CPU (i486). --- .../linux/linux-wrap-geode-2.6.17/.mtn2git_empty | 0 packages/linux/linux-wrap-geode-2.6.17/defconfig | 1554 ++++++++++++++++++++ packages/linux/linux-wrap-geode_2.6.17.bb | 24 + 3 files changed, 1578 insertions(+) create mode 100644 packages/linux/linux-wrap-geode-2.6.17/.mtn2git_empty create mode 100644 packages/linux/linux-wrap-geode-2.6.17/defconfig create mode 100644 packages/linux/linux-wrap-geode_2.6.17.bb diff --git a/packages/linux/linux-wrap-geode-2.6.17/.mtn2git_empty b/packages/linux/linux-wrap-geode-2.6.17/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/linux/linux-wrap-geode-2.6.17/defconfig b/packages/linux/linux-wrap-geode-2.6.17/defconfig new file mode 100644 index 0000000000..678c650307 --- /dev/null +++ b/packages/linux/linux-wrap-geode-2.6.17/defconfig @@ -0,0 +1,1554 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.17.1 +# Thu Aug 31 16:22:43 2006 +# +CONFIG_X86_32=y +CONFIG_SEMAPHORE_SLEEPERS=y +CONFIG_X86=y +CONFIG_MMU=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_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 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +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_SHMEM=y +CONFIG_SLAB=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Processor type and features +# +# CONFIG_SMP is not set +CONFIG_X86_PC=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 is not set +# CONFIG_X86_ES7000 is not set +# CONFIG_M386 is not set +# CONFIG_M486 is not set +# CONFIG_M586 is not set +# CONFIG_M586TSC is not set +# CONFIG_M586MMX is not set +# CONFIG_M686 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MK6 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=y +# CONFIG_MCYRIXIII is not set +# CONFIG_MVIAC3_2 is not set +# CONFIG_X86_GENERIC is not set +CONFIG_X86_CMPXCHG=y +CONFIG_X86_XADD=y +CONFIG_X86_L1_CACHE_SHIFT=5 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=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_USE_PPRO_CHECKSUM=y +CONFIG_X86_USE_3DNOW=y +CONFIG_X86_TSC=y +# CONFIG_HPET_TIMER is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_X86_UP_APIC is not set +# CONFIG_X86_MCE is not set +# CONFIG_TOSHIBA is not set +# CONFIG_I8K is not set +# CONFIG_X86_REBOOTFIXUPS is not set +# CONFIG_MICROCODE is not set +# CONFIG_X86_MSR is not set +CONFIG_X86_CPUID=m + +# +# Firmware Drivers +# +# CONFIG_EDD is not set +# CONFIG_DELL_RBU is not set +# CONFIG_DCDBAS is not set +CONFIG_NOHIGHMEM=y +# CONFIG_HIGHMEM4G is not set +# CONFIG_HIGHMEM64G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +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=4 +# CONFIG_MATH_EMULATION is not set +CONFIG_MTRR=y +# CONFIG_EFI is not set +CONFIG_REGPARM=y +# CONFIG_SECCOMP is not set +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=100 +# CONFIG_KEXEC is not set +CONFIG_PHYSICAL_START=0x100000 + +# +# Power management options (ACPI, APM) +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +# CONFIG_SOFTWARE_SUSPEND is not set + +# +# ACPI (Advanced Configuration and Power Interface) Support +# +CONFIG_ACPI=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 is not set +# CONFIG_ACPI_IBM is not set +# CONFIG_ACPI_TOSHIBA is not set +CONFIG_ACPI_BLACKLIST_YEAR=0 +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_EC=y +CONFIG_ACPI_POWER=y +CONFIG_ACPI_SYSTEM=y +CONFIG_X86_PM_TIMER=y +# CONFIG_ACPI_CONTAINER is not set + +# +# APM (Advanced Power Management) BIOS Support +# +# CONFIG_APM is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=m +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=m +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m + +# +# CPUFreq processor drivers +# +CONFIG_X86_ACPI_CPUFREQ=m +# CONFIG_X86_POWERNOW_K6 is not set +# CONFIG_X86_POWERNOW_K7 is not set +# CONFIG_X86_POWERNOW_K8 is not set +CONFIG_X86_GX_SUSPMOD=m +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +# CONFIG_X86_SPEEDSTEP_ICH is not set +# CONFIG_X86_SPEEDSTEP_SMI is not set +# CONFIG_X86_P4_CLOCKMOD is not set +# CONFIG_X86_CPUFREQ_NFORCE2 is not set +# CONFIG_X86_LONGRUN is not set + +# +# shared options +# +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +# CONFIG_X86_SPEEDSTEP_LIB 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_PCIEPORTBUS is not set +# CONFIG_PCI_DEBUG is not set +CONFIG_ISA_DMA_API=y +# CONFIG_ISA is not set +# CONFIG_MCA is not set +CONFIG_SCx200=m + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=m + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# 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 + +# +# IP: Virtual Server Configuration +# +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y + +# +# IPVS scheduler +# +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 + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IPV6=m +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +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 + +# +# 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 + +# +# 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 + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +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 + +# +# Bridge: Netfilter Configuration +# +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 + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC 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 is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +CONFIG_NET_DIVERT=y +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CLK_JIFFIES=y +# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set +# CONFIG_NET_SCH_CLK_CPU is not set + +# +# Queueing/Scheduling +# +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 + +# +# Classification +# +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=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_PEDIT=m +# CONFIG_NET_ACT_SIMP is not set +CONFIG_NET_CLS_IND=y +CONFIG_NET_ESTIMATOR=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +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 is not set +CONFIG_WIRELESS_EXT=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# 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 is not set +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 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_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_BLK_DEV_CMD640 is not set +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 is not set +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 is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_ATIIXP is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_CS5535 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +CONFIG_BLK_DEV_SC1200=y +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM 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 + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_IFB is not set +CONFIG_DUMMY=m +CONFIG_BONDING=m +CONFIG_EQUALIZER=m +CONFIG_TUN=m + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=m +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_TULIP=m +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_MMIO=y +# CONFIG_TULIP_NAPI is not set +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_ULI526X=m +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +CONFIG_NATSEMI=y +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR 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 + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_AIRO is not set +# CONFIG_HERMES is not set +# CONFIG_ATMEL is not set + +# +# 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 is not set +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTAP_PCI=m +# CONFIG_BCM43XX is not set +CONFIG_NET_WIRELESS=y + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# ATM drivers +# +CONFIG_ATM_DUMMY=m +CONFIG_ATM_TCP=m +# CONFIG_ATM_LANAI is not set +# CONFIG_ATM_ENI is not set +# CONFIG_ATM_FIRESTREAM is not set +# CONFIG_ATM_ZATM is not set +# CONFIG_ATM_NICSTAR is not set +# CONFIG_ATM_IDT77252 is not set +# CONFIG_ATM_AMBASSADOR is not set +# CONFIG_ATM_HORIZON is not set +# CONFIG_ATM_IA is not set +# CONFIG_ATM_FORE200E_MAYBE is not set +# CONFIG_ATM_HE is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +# CONFIG_SLIP_MODE_SLIP6 is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_IBMASR is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I6300ESB_WDT is not set +# CONFIG_I8XX_TCO is not set +CONFIG_SC1200_WDT=m +CONFIG_SCx200_WDT=m +# CONFIG_60XX_WDT is not set +# CONFIG_SBC8360_WDT is not set +# CONFIG_CPU5_WDT is not set +# CONFIG_W83627HF_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_W83977F_WDT is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_SBC_EPX_C3_WATCHDOG is not set + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_SONYPI is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_MWAVE is not set +CONFIG_SCx200_GPIO=m +CONFIG_CS5535_GPIO=m +# CONFIG_RAW_DRIVER is not set +# CONFIG_HPET is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +CONFIG_SCx200_I2C=m +CONFIG_SCx200_I2C_SCL=12 +CONFIG_SCx200_I2C_SDA=13 +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_EEPROM=m +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# 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 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=m +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +CONFIG_SENSORS_LM77=m +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_HDAPS is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# +# CONFIG_IBM_ASM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set +# CONFIG_VIDEO_SELECT is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# +# CONFIG_EDAC is not set + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=y +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +CONFIG_XFS_EXPORT=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y +# CONFIG_XFS_RT is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +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 is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=m + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# 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=m +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +CONFIG_CONFIGFS_FS=m + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_CRAMFS=m +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +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=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT 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 is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m + +# +# Instrumentation Support +# +# CONFIG_PROFILING is not set +# CONFIG_KPROBES is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_FRAME_POINTER is not set +# CONFIG_UNWIND_INFO is not set +# CONFIG_FORCED_INLINING is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_EARLY_PRINTK=y +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_STACK_BACKTRACE_COLS=2 +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_RODATA is not set +CONFIG_4KSTACKS=y +CONFIG_DOUBLEFAULT=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_DES=y +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 + +# +# Hardware crypto devices +# +# CONFIG_CRYPTO_DEV_PADLOCK is not set + +# +# Library routines +# +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +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_KTIME_SCALAR=y diff --git a/packages/linux/linux-wrap-geode_2.6.17.bb b/packages/linux/linux-wrap-geode_2.6.17.bb new file mode 100644 index 0000000000..d02aca79f7 --- /dev/null +++ b/packages/linux/linux-wrap-geode_2.6.17.bb @@ -0,0 +1,24 @@ +SECTION = "kernel" +DESCRIPTION = "Linux kernel for PC-Engines WRAP which are \ +Geode SC1100 (i486) based wirless router appliance boards" +LICENSE = "GPL" +MAINTAINER = "Jamie Lenehan +PR = "r0" + +SRC_URI = "ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2 \ + file://defconfig" +S = "${WORKDIR}/linux-${PV}" + +COMPATIBLE_HOST = 'i486.*-linux' +COMPATIBLE_MACHINE = "wrap" + +inherit kernel + +ARCH = "i386" +KERNEL_IMAGETYPE = "bzImage" +KERNEL_OUTPUT = "arch/${ARCH}/boot/${KERNEL_IMAGETYPE}" + +do_configure_prepend() { + install -m 0644 ${WORKDIR}/defconfig ${S}/.config + yes '' | oe_runmake oldconfig +} -- cgit v1.2.3 From 97f3f6619a1ef68599977240b181b0be205b35fb Mon Sep 17 00:00:00 2001 From: Jamie Lenehan Date: Fri, 1 Sep 2006 02:20:24 +0000 Subject: groff 1.19.2: The install task was failing because groff refuses to install into the specified prefix (${D} in this case) unless that directory already exists. So modify to manually create ${D} in the install task. Its not clear what change broke this but it appears that ${D} used to be created automatically but this is no longer occuring. --- packages/groff/groff_1.19.2.bb | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/groff/groff_1.19.2.bb b/packages/groff/groff_1.19.2.bb index 24cc5eadea..c012376c0c 100644 --- a/packages/groff/groff_1.19.2.bb +++ b/packages/groff/groff_1.19.2.bb @@ -2,7 +2,7 @@ DESCRIPTION = "GNU roff" SECTION = "base" LICENSE = "GPL" MAINTAINER = "Inge Arnesen " -PR = "r2" +PR = "r3" SRC_URI = "http://ftp.gnu.org/gnu/groff/groff-${PV}.tar.gz \ file://Makefile.in.patch;patch=1 \ @@ -15,11 +15,14 @@ PARALLEL_MAKE = "" EXTRA_OECONF="--prefix=${D} --exec-prefix=${D} --bindir=${D}${bindir} --datadir=${D}${datadir} --mandir=${D}${datadir}/man --infodir=${D}${datadir}/info" inherit autotools -do_configure () { +do_configure() { oe_runconf } -#do_install() { -# oe_runmake 'PREFIX=${D}' install -#} - +# +# The installer refuses to do anything if the prefix directory does not +# already exist, so create it manually before the standard install runs. +# +do_install_prepend() { + install -m 0755 -d ${D} +} -- cgit v1.2.3 From e84cdb4039e927ad32f7b0662b381f9ec7477e8e Mon Sep 17 00:00:00 2001 From: Jamie Lenehan Date: Fri, 1 Sep 2006 02:35:39 +0000 Subject: ebtables 2.0.6: Patch to enable compiling with gcc 4.x. Tested with gcc 4.1.1 and 3.4.4. --- packages/ebtables/ebtables-2.0.6/gcc4.patch | 67 +++++++++++++++++++++++++++++ packages/ebtables/ebtables_2.0.6.bb | 3 +- 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 packages/ebtables/ebtables-2.0.6/gcc4.patch diff --git a/packages/ebtables/ebtables-2.0.6/gcc4.patch b/packages/ebtables/ebtables-2.0.6/gcc4.patch new file mode 100644 index 0000000000..6b3688a3d9 --- /dev/null +++ b/packages/ebtables/ebtables-2.0.6/gcc4.patch @@ -0,0 +1,67 @@ +--- ebtables-v2.0.6/extensions/ebt_ip.c 2006/09/01 02:27:02 1.1 ++++ ebtables-v2.0.6/extensions/ebt_ip.c 2006/09/01 02:27:30 +@@ -313,7 +313,7 @@ + ipinfo->invflags |= EBT_IP_PROTO; + if (optind > argc) + print_error("Missing IP protocol argument"); +- (unsigned char) i = strtoul(argv[optind - 1], &end, 10); ++ i = strtoul(argv[optind - 1], &end, 10); + if (*end != '\0') { + struct protoent *pe; + +--- ebtables-v2.0.6/extensions/ebt_vlan.c 2006/09/01 02:27:38 1.1 ++++ ebtables-v2.0.6/extensions/ebt_vlan.c 2006/09/01 02:28:01 +@@ -141,7 +141,7 @@ + check_option(flags, OPT_VLAN_ID); + CHECK_INV_FLAG(EBT_VLAN_ID); + CHECK_IF_MISSING_VALUE; +- (unsigned short) local.id = ++ local.id = + strtoul(argv[optind - 1], &end, 10); + CHECK_RANGE(local.id > 4094 || *end != '\0'); + vlaninfo->id = local.id; +@@ -152,7 +152,7 @@ + check_option(flags, OPT_VLAN_PRIO); + CHECK_INV_FLAG(EBT_VLAN_PRIO); + CHECK_IF_MISSING_VALUE; +- (unsigned char) local.prio = ++ local.prio = + strtoul(argv[optind - 1], &end, 10); + CHECK_RANGE(local.prio >= 8 || *end != '\0'); + vlaninfo->prio = local.prio; +@@ -163,7 +163,7 @@ + check_option(flags, OPT_VLAN_ENCAP); + CHECK_INV_FLAG(EBT_VLAN_ENCAP); + CHECK_IF_MISSING_VALUE; +- (unsigned short) local.encap = ++ local.encap = + strtoul(argv[optind - 1], &end, 16); + if (*end != '\0') { + ethent = getethertypebyname(argv[optind - 1]); +--- ebtables-v2.0.6/extensions/ebt_limit.c 2006/09/01 02:28:09 1.1 ++++ ebtables-v2.0.6/extensions/ebt_limit.c 2006/09/01 02:30:21 +@@ -203,15 +203,15 @@ + + static struct ebt_u_match limit_match = + { +- .name EBT_LIMIT_MATCH, +- .size sizeof(struct ebt_limit_info), +- .help print_help, +- .init init, +- .parse parse, +- .final_check final_check, +- .print print, +- .compare compare, +- .extra_ops opts, ++ .name = EBT_LIMIT_MATCH, ++ .size = sizeof(struct ebt_limit_info), ++ .help = print_help, ++ .init = init, ++ .parse = parse, ++ .final_check = final_check, ++ .print = print, ++ .compare = compare, ++ .extra_ops = opts, + }; + + static void _init(void) __attribute((constructor)); diff --git a/packages/ebtables/ebtables_2.0.6.bb b/packages/ebtables/ebtables_2.0.6.bb index 3c5d17dacb..318dd664a1 100644 --- a/packages/ebtables/ebtables_2.0.6.bb +++ b/packages/ebtables/ebtables_2.0.6.bb @@ -3,10 +3,11 @@ PRIORITY = "optional" MAINTAINER = "Ned Ludd " LICENSE = "GPL" SECTION = "console/network" -PR = "r1" +PR = "r2" SRC_URI = "${SOURCEFORGE_MIRROR}/ebtables/ebtables-v${PV}.tar.gz \ file://gcc34.patch;patch=1 \ + file://gcc4.patch;patch=1 \ file://installnonroot.patch;patch=1 \ file://installcreatedirs.patch;patch=1" S = "${WORKDIR}/ebtables-v${PV}" -- cgit v1.2.3 From 21e5b78eef73e3e86a3e06820f54b1cb971c57e9 Mon Sep 17 00:00:00 2001 From: Jamie Lenehan Date: Fri, 1 Sep 2006 02:44:48 +0000 Subject: site/i486-linux: Add required entries for screen. --- site/i486-linux | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/site/i486-linux b/site/i486-linux index 1d4115be90..c21dfcd365 100644 --- a/site/i486-linux +++ b/site/i486-linux @@ -146,6 +146,17 @@ ac_cv_va_copy=${ac_cv_va_copy=no} ac_cv___va_copy=${ac_cv___va_copy=yes} racoon_cv_bug_getaddrinfo=${racoon_cv_bug_getaddrinfo=no} +# screen +screen_cv_sys_bcopy_overlap=${screen_cv_sys_bcopy_overlap=no} +screen_cv_sys_memcpy_overlap=${screen_cv_sys_memcpy_overlap=no} +screen_cv_sys_memmove_overlap=${screen_cv_sys_memmove_overlap=no} +screen_cv_sys_fifo_broken_impl=${screen_cv_sys_fifo_broken_impl=yes} +screen_cv_sys_fifo_usable=${screen_cv_sys_fifo_usable=yes} +screen_cv_sys_select_broken_retval=${screen_cv_sys_select_broken_retval=no} +screen_cv_sys_sockets_nofs=${screen_cv_sys_sockets_nofs=no} +screen_cv_sys_sockets_usable=${screen_cv_sys_sockets_usable=yes} +screen_cv_sys_terminfo_used=${screen_cv_sys_terminfo_used=yes} + # slrn slrn_cv___va_copy=${slrn_cv___va_copy=yes} slrn_cv_va_copy=${slrn_cv_va_copy=no} -- cgit v1.2.3 From 5e10324e5e797c6e20c9c2db60538de1f983a8ac Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 1 Sep 2006 12:23:14 +0000 Subject: libnss-mdns-0.8: fix the postinst script --- packages/libnss-mdns/libnss-mdns_0.8.bb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/libnss-mdns/libnss-mdns_0.8.bb b/packages/libnss-mdns/libnss-mdns_0.8.bb index 475297cd63..a4a9cd00d1 100644 --- a/packages/libnss-mdns/libnss-mdns_0.8.bb +++ b/packages/libnss-mdns/libnss-mdns_0.8.bb @@ -5,7 +5,7 @@ SECTION = "libs" PRIORITY = "optional" RRECOMMENDS_${PN} = "zeroconf" -PR = "r0" +PR = "r1" EXTRA_OECONF = "--libdir=/lib" S = "${WORKDIR}/nss-mdns-${PV}" @@ -15,6 +15,10 @@ SRC_URI = "http://0pointer.de/lennart/projects/nss-mdns/nss-mdns-${PV}.tar.gz" inherit autotools pkg_postinst () { + # can't do this offline + if [ "x$D" != "x" ]; then + exit 1 + fi cat /etc/nsswitch.conf | grep "hosts:\s*files dns$" > /dev/null && { cat /etc/nsswitch.conf | sed 's/\(hosts:\s*files \)dns/\1mdns4_minimal [NOTFOUND=return] dns mdns4/' > /tmp/nsswitch.conf mv /tmp/nsswitch.conf /etc/nsswitch.conf -- cgit v1.2.3 From 8f5586abb4a12e38c42aa2ab08f472933105c93e Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 1 Sep 2006 12:26:23 +0000 Subject: libnss-mdns: drop old versions --- packages/libnss-mdns/files/.mtn2git_empty | 0 packages/libnss-mdns/files/alignment-fix.patch | 11 ---------- packages/libnss-mdns/libnss-mdns_0.6.bb | 30 -------------------------- packages/libnss-mdns/libnss-mdns_0.7.bb | 29 ------------------------- 4 files changed, 70 deletions(-) delete mode 100644 packages/libnss-mdns/files/.mtn2git_empty delete mode 100644 packages/libnss-mdns/files/alignment-fix.patch delete mode 100644 packages/libnss-mdns/libnss-mdns_0.6.bb delete mode 100644 packages/libnss-mdns/libnss-mdns_0.7.bb diff --git a/packages/libnss-mdns/files/.mtn2git_empty b/packages/libnss-mdns/files/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/libnss-mdns/files/alignment-fix.patch b/packages/libnss-mdns/files/alignment-fix.patch deleted file mode 100644 index 11d4655e1f..0000000000 --- a/packages/libnss-mdns/files/alignment-fix.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- nss-mdns-0.6/src/nss.c.orig 2005-09-25 17:27:51 +0200 -+++ nss-mdns-0.6/src/nss.c 2005-09-25 17:28:55 +0200 -@@ -456,6 +456,8 @@ - result->h_addrtype = af; - result->h_length = address_length; - -+ idx+=(sizeof(char*)-idx%sizeof(char*)); /* Align on 32 bit boundary */ -+ - /* Check if there's enough space for the addresses */ - if (buflen < idx+u.data_len+sizeof(char*)*(u.count+1)) { - *errnop = ERANGE; diff --git a/packages/libnss-mdns/libnss-mdns_0.6.bb b/packages/libnss-mdns/libnss-mdns_0.6.bb deleted file mode 100644 index 5de9df567c..0000000000 --- a/packages/libnss-mdns/libnss-mdns_0.6.bb +++ /dev/null @@ -1,30 +0,0 @@ -DESCRIPTION = "NSS module for Multicast DNS name resolution" -HOMEPAGE = "http://0pointer.de/lennart/projects/nss-mdns/" -LICENSE = "GPL" -SECTION = "libs" -PRIORITY = "optional" - -RRECOMMENDS_${PN} = "zeroconf" -PR = "r1" - -EXTRA_OECONF = "--libdir=/lib" -S = "${WORKDIR}/nss-mdns-${PV}" - -SRC_URI = "http://0pointer.de/lennart/projects/nss-mdns/nss-mdns-${PV}.tar.gz \ - file://alignment-fix.patch;patch=1" - -inherit autotools - -pkg_postinst () { - cat /etc/nsswitch.conf | grep "hosts:\s*files dns$" > /dev/null && { - cat /etc/nsswitch.conf | sed 's/hosts:\s*files dns/& mdns/' > /tmp/nsswitch.conf - mv /tmp/nsswitch.conf /etc/nsswitch.conf - } -} - -pkg_prerm () { - cat /etc/nsswitch.conf | grep "hosts:\s*files dns mdns$" > /dev/null && { - cat /etc/nsswitch.conf | sed 's/\(hosts:\s*files dns\) mdns/\1/' > /tmp/nsswitch.conf - mv /tmp/nsswitch.conf /etc/nsswitch.conf - } -} diff --git a/packages/libnss-mdns/libnss-mdns_0.7.bb b/packages/libnss-mdns/libnss-mdns_0.7.bb deleted file mode 100644 index 98ab50f07f..0000000000 --- a/packages/libnss-mdns/libnss-mdns_0.7.bb +++ /dev/null @@ -1,29 +0,0 @@ -DESCRIPTION = "NSS module for Multicast DNS name resolution" -HOMEPAGE = "http://0pointer.de/lennart/projects/nss-mdns/" -LICENSE = "GPL" -SECTION = "libs" -PRIORITY = "optional" - -RRECOMMENDS_${PN} = "zeroconf" -PR = "r0" - -EXTRA_OECONF = "--libdir=/lib" -S = "${WORKDIR}/nss-mdns-${PV}" - -SRC_URI = "http://0pointer.de/lennart/projects/nss-mdns/nss-mdns-${PV}.tar.gz" - -inherit autotools - -pkg_postinst () { - cat /etc/nsswitch.conf | grep "hosts:\s*files dns$" > /dev/null && { - cat /etc/nsswitch.conf | sed 's/hosts:\s*files dns/& mdns4/' > /tmp/nsswitch.conf - mv /tmp/nsswitch.conf /etc/nsswitch.conf - } -} - -pkg_prerm () { - cat /etc/nsswitch.conf | grep "hosts:\s*files dns mdns$" > /dev/null && { - cat /etc/nsswitch.conf | sed 's/\(hosts:\s*files dns\) mdns4*/\1/' > /tmp/nsswitch.conf - mv /tmp/nsswitch.conf /etc/nsswitch.conf - } -} -- cgit v1.2.3 From a2ce37c9a8834aa29c6a717b045588f15b65d2eb Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Fri, 1 Sep 2006 13:05:31 +0000 Subject: busybox: Fixup missing option in slugos busybox defconfig. Bump PR --- packages/busybox/busybox-1.2.1/slugos/defconfig | 2 ++ packages/busybox/busybox_1.2.1.bb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/busybox/busybox-1.2.1/slugos/defconfig b/packages/busybox/busybox-1.2.1/slugos/defconfig index 55aa5f3b5e..b5ff84550a 100644 --- a/packages/busybox/busybox-1.2.1/slugos/defconfig +++ b/packages/busybox/busybox-1.2.1/slugos/defconfig @@ -32,6 +32,8 @@ EXTRA_CFLAGS_OPTIONS="" # # CONFIG_INSTALL_NO_USR is not set PREFIX="./_install" +CONFIG_INSTALL_APPLET_SYMLINKS=y +CONFIG_INSTALL_APPLET_HARDLINKS=n # # Archival Utilities diff --git a/packages/busybox/busybox_1.2.1.bb b/packages/busybox/busybox_1.2.1.bb index 61df8a9b1c..74c69319f4 100644 --- a/packages/busybox/busybox_1.2.1.bb +++ b/packages/busybox/busybox_1.2.1.bb @@ -10,7 +10,7 @@ HOMEPAGE = "http://www.busybox.net" LICENSE = "GPL" SECTION = "base" PRIORITY = "required" -PR = "r1.1" +PR = "r1.2" SRC_URI = "http://www.busybox.net/downloads/busybox-${PV}.tar.gz \ file://dhcp-hostname.patch;patch=1 \ -- cgit v1.2.3 From 576f0b02a7a5d19dcd3a60593bc2fde9578e3fd3 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 1 Sep 2006 16:34:24 +0000 Subject: freeciv: Add proper SECTION definition. --- packages/freeciv/freeciv_2.0.8.bb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/freeciv/freeciv_2.0.8.bb b/packages/freeciv/freeciv_2.0.8.bb index 361d8e4c20..accdc47af9 100644 --- a/packages/freeciv/freeciv_2.0.8.bb +++ b/packages/freeciv/freeciv_2.0.8.bb @@ -1,7 +1,9 @@ DESCRIPTION = "Freeciv is a free turn-based multiplayer strategy game, in which each player becomes the leader of a civilization, fighting to obtain the ultimate goal: To become the greatest civilization." +SECTION = "games" LICENSE = "GPL" MAINTAINER = "Koen Kooi " DEPENDS = "gtk+ cairo esound zlib readline" +PR = "r1" SRC_URI = "${SOURCEFORGE_MIRROR}/${PN}/${P}.tar.gz" -- cgit v1.2.3 From e10a5a9fe3bd597a58bfad33f2f313ed7d1d2898 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 1 Sep 2006 16:43:06 +0000 Subject: gpe-soundbite: Adjust SECTION to gpe/multimedia. --- packages/gpe-soundbite/gpe-soundbite_1.0.6.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gpe-soundbite/gpe-soundbite_1.0.6.bb b/packages/gpe-soundbite/gpe-soundbite_1.0.6.bb index 90a8a823a5..a38a721aa7 100644 --- a/packages/gpe-soundbite/gpe-soundbite_1.0.6.bb +++ b/packages/gpe-soundbite/gpe-soundbite_1.0.6.bb @@ -5,6 +5,6 @@ SRC_URI += "file://makefile-fix.patch;patch=1" DESCRIPTION = "GPE audio Recorder" DEPENDS = "gtk+ libgpewidget libglade libgsm gpe-soundserver" -SECTION = "gpe" +SECTION = "gpe/multimedia" PRIORITY = "optional" LDFLAGS_append = "-Wl,--export-dynamic" -- cgit v1.2.3 From dccd30d481e2e8c9361adbf0b65ac6d7ab579fe3 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 1 Sep 2006 16:46:57 +0000 Subject: xdemineur: Adjust SECTION to gpe/games. --- packages/xdemineur/xdemineur_2.1.1.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/xdemineur/xdemineur_2.1.1.bb b/packages/xdemineur/xdemineur_2.1.1.bb index 8c1e8ae206..73e3276aac 100644 --- a/packages/xdemineur/xdemineur_2.1.1.bb +++ b/packages/xdemineur/xdemineur_2.1.1.bb @@ -2,7 +2,7 @@ inherit gpe LICENSE = "BSD-X" DEPENDS = "virtual/libx11 libxpm" -SECTION = "gpe" +SECTION = "gpe/games" DESCRIPTION = "Mine-sweeper game for GPE." PRIORITY = "optional" -- cgit v1.2.3 From 5e117926153aaf95c9d08fe91037ab82b4b56d44 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 1 Sep 2006 16:48:47 +0000 Subject: gpe-othello: Adjust SECTION to gpe/games. --- packages/gpe-othello/gpe-othello_0.2-1.bb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/gpe-othello/gpe-othello_0.2-1.bb b/packages/gpe-othello/gpe-othello_0.2-1.bb index a1ceb60157..43d9a197f4 100644 --- a/packages/gpe-othello/gpe-othello_0.2-1.bb +++ b/packages/gpe-othello/gpe-othello_0.2-1.bb @@ -2,7 +2,8 @@ inherit gpe DESCRIPTION = "An Othello clone using GTK, hacked from ugothello." DEPENDS = "gtk+ libgpewidget gpe-icons" -SECTION = "gpe" +SECTION = "gpe/games" PRIORITY = "optional" +PR = "r1" SRC_URI += "file://fix-makefiles.patch;patch=1" -- cgit v1.2.3 From d609c9e162caf6a59328b5622bd64cef3ef8bc63 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 1 Sep 2006 16:51:21 +0000 Subject: gpe-lights: Adjust SECTION to gpe/games. --- packages/gpe-lights/gpe-lights_0.12.bb | 3 ++- packages/gpe-lights/gpe-lights_0.13.bb | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/gpe-lights/gpe-lights_0.12.bb b/packages/gpe-lights/gpe-lights_0.12.bb index 67f0ed60e0..4b09058565 100644 --- a/packages/gpe-lights/gpe-lights_0.12.bb +++ b/packages/gpe-lights/gpe-lights_0.12.bb @@ -3,7 +3,8 @@ LICENSE = "PD" DESCRIPTION = "A simple light puzzle." DEPENDS = "gtk+ libgpewidget gpe-icons" -SECTION = "gpe" +SECTION = "gpe/games" PRIORITY = "optional" +PR = "r1" SRC_URI += "file://fix-makefiles.patch;patch=1" diff --git a/packages/gpe-lights/gpe-lights_0.13.bb b/packages/gpe-lights/gpe-lights_0.13.bb index 67f0ed60e0..4b09058565 100644 --- a/packages/gpe-lights/gpe-lights_0.13.bb +++ b/packages/gpe-lights/gpe-lights_0.13.bb @@ -3,7 +3,8 @@ LICENSE = "PD" DESCRIPTION = "A simple light puzzle." DEPENDS = "gtk+ libgpewidget gpe-icons" -SECTION = "gpe" +SECTION = "gpe/games" PRIORITY = "optional" +PR = "r1" SRC_URI += "file://fix-makefiles.patch;patch=1" -- cgit v1.2.3 From 1b6fc7326987f24d91f939e31db89b5657145277 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 1 Sep 2006 16:53:45 +0000 Subject: gpe-life: Adjust SECTION to gpe/games. --- packages/gpe-life/gpe-life_0.2.bb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/gpe-life/gpe-life_0.2.bb b/packages/gpe-life/gpe-life_0.2.bb index c9efc27f64..82ab1b1fc4 100644 --- a/packages/gpe-life/gpe-life_0.2.bb +++ b/packages/gpe-life/gpe-life_0.2.bb @@ -2,7 +2,8 @@ DESCRIPTION = "Conway's Game of Life for GPE" LICENSE = "GPL" PRIORITY = "optional" MAINTAINER = "Rene Wagner " -SECTION = "gpe" +SECTION = "gpe/games" +PR = "r1" DEPENDS = "glib-2.0 gtk+ libglade" -- cgit v1.2.3 From bfa9cfcaf6fbf4b42eae72f407c4bdb04ed6f31e Mon Sep 17 00:00:00 2001 From: Erik Hovland Date: Fri, 1 Sep 2006 17:02:05 +0000 Subject: Provides the latest hh.org 2.4 kernel for strongarm based handhelds. --- .../.mtn2git_empty | 0 .../defconfig-h3600 | 1475 ++++++++++++++++++++ .../linux/handhelds-sa_2.4.19-rmk6-pxa1-hh42.bb | 57 + 3 files changed, 1532 insertions(+) create mode 100644 packages/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh42/.mtn2git_empty create mode 100644 packages/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh42/defconfig-h3600 create mode 100644 packages/linux/handhelds-sa_2.4.19-rmk6-pxa1-hh42.bb diff --git a/packages/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh42/.mtn2git_empty b/packages/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh42/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh42/defconfig-h3600 b/packages/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh42/defconfig-h3600 new file mode 100644 index 0000000000..ad30591336 --- /dev/null +++ b/packages/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh42/defconfig-h3600 @@ -0,0 +1,1475 @@ +# +# Automatically generated by make menuconfig: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_OBSOLETE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_OMAHA is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_MX1ADS is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_RISCSTATION is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_AT91RM9200DK is not set +# CONFIG_MINIMAL_OOPS is not set + +# +# Linux As Bootldr support +# +# CONFIG_LAB is not set +# CONFIG_BIG_KERNEL is not set +# CONFIG_USE_DATE_CODE is not set + +# +# Archimedes/A5000 Implementations +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ACCELENT is not set +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CEP is not set +# CONFIG_SA1100_CERF is not set +CONFIG_SA1100_H3100=y +CONFIG_SA1100_H3600=y +CONFIG_SA1100_H3800=y +# CONFIG_SA1100_CONSUS is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_FRODO is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_HACKKIT is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_JORNADA56X is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_SIMPUTER is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +CONFIG_SA1100_USB=m +CONFIG_SA1100_USB_NETLINK=m +CONFIG_SA1100_USB_CHAR=m +CONFIG_REGISTERS=m + +# +# Intel PXA250/210 Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +# CONFIG_ARCH_PXA_IDP is not set +# CONFIG_ARCH_PXA_CERF is not set +# CONFIG_ARCH_H3900 is not set +# CONFIG_ARCH_H1900 is not set +# CONFIG_ARCH_H5400 is not set +# CONFIG_ARCH_H2200 is not set +# CONFIG_ARCH_AXIM is not set +# CONFIG_PXA_USB is not set +# CONFIG_PXA_USB_NETLINK is not set +# CONFIG_PXA_USB_CHAR is not set + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_PLD is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_ARM1026 is not set +# CONFIG_CPU_SA110 is not set +CONFIG_CPU_SA1100=y +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y +CONFIG_SA1100_IPAQ=y +# CONFIG_PXA_IPAQ is not set +CONFIG_IPAQ_HANDHELD=y + +# +# Compaq iPAQ Handheld +# +CONFIG_IPAQ_HAL=m +CONFIG_H3600_MICRO=m +CONFIG_IPAQ_HAS_ROSELLA=y +# CONFIG_IPAQ_HAS_ASIC3 is not set +CONFIG_H3600_ASIC=m +CONFIG_H3900_ASIC_DEBUG=y +# CONFIG_H5400_ASIC is not set +# CONFIG_H1900_ASIC is not set +# CONFIG_H1900_TS is not set +CONFIG_H3600_HARDWARE=y +CONFIG_IPAQ_SLEEVE=m +CONFIG_SLEEVE_DEBUG=y +CONFIG_SLEEVE_DEBUG_VERBOSE=0 +# CONFIG_SLEEVE_IRQ_DEMUX is not set +CONFIG_DISCONTIGMEM=y + +# +# General setup +# +# CONFIG_PCI is not set +CONFIG_ISA=y +# CONFIG_ISA_DMA is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CPU_FREQ=y +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +# CONFIG_PCMCIA_CLPS6700 is not set +CONFIG_PCMCIA_SA1100=m +# CONFIG_PCMCIA_PXA is not set +CONFIG_MERCURY_BACKPAQ=m + +# +# MMC/SD Card support +# +CONFIG_MMC=m +CONFIG_MMC_DEBUG=y +CONFIG_MMC_DEBUG_VERBOSE=0 +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_PM=y +CONFIG_APM=m +CONFIG_HWTIMER=m +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="keepinitrd" +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=1 +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +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=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_IPAQ=y +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +# CONFIG_MTD_SA1100 is not set +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_LUBBOCK is not set +# CONFIG_MTD_IXP425 is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_H720X is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_CEIVA is not set +# CONFIG_MTD_NOR_TOTO is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 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=m +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_DOCPROBE is not set +# CONFIG_MTD_DOCECC is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_NAND_SPIA is not set +# CONFIG_MTD_NAND_TOTO is not set +# CONFIG_MTD_NAND_AUTCPU12 is not set +# CONFIG_MTD_NAND_EDB7312 is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_NVRD=m + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +CONFIG_BLK_DEV_LVM=m +CONFIG_BLK_DEV_DM=m + +# +# Networking options +# +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_TFTP is not set +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +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 is not set +CONFIG_IP_NF_MATCH_STATE=m +# CONFIG_IP_NF_MATCH_CONNTRACK is not set +# CONFIG_IP_NF_MATCH_UNCLEAN is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_FILTER=m +# CONFIG_IP_NF_TARGET_REJECT is not set +# CONFIG_IP_NF_TARGET_MIRROR is not set +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_NAT_LOCAL is not set +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_DSCP is not set +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_ARPTABLES is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +CONFIG_IPV6=m +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MOBILITY=m +CONFIG_IPV6_MOBILITY_MN=m +# CONFIG_IPV6_MOBILITY_HA is not set +CONFIG_IPV6_MOBILITY_DEBUG=y + +# +# IPv6: Netfilter Configuration +# +# 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 is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_HL is not set +CONFIG_IP6_NF_MATCH_MULTIPORT=m +# CONFIG_IP6_NF_MATCH_OWNER is not set +CONFIG_IP6_NF_MATCH_MARK=m +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_AHESP is not set +# CONFIG_IP6_NF_MATCH_LENGTH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +CONFIG_BRIDGE=m +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_IPSEC=m +CONFIG_KLIPS_AUTH_HMAC_MD5=y +CONFIG_KLIPS_AUTH_HMAC_SHA1=y +CONFIG_KLIPS_ENC_3DES=y +CONFIG_KLIPS_IPCOMP=y +CONFIG_KLIPS_DEBUG=y + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_AIRO is not set +# CONFIG_HERMES is not set +# CONFIG_SPECTRUM24T is not set +# CONFIG_PCMCIA_HERMES is not set +CONFIG_AIRO_CS=m +# CONFIG_WVLAN_CS is not set +# CONFIG_MWVLAN_CS is not set +# CONFIG_HOSTAP is not set +# CONFIG_HOSTAP_CS is not set +CONFIG_NET_WIRELESS=y +# CONFIG_ATMELWLAN is not set +# CONFIG_ATMELWLAN_USB_503A_RFMD is not set +# CONFIG_ATMELWLAN_PCMCIA_502A is not set +# CONFIG_ATMELWLAN_PCMCIA_3COM is not set +# CONFIG_ATMELWLAN_PCMCIA_502AD is not set +# CONFIG_ATMELWLAN_PCMCIA_502AE is not set +# CONFIG_ATMELWLAN_PCMCIA_504 is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_AXNET=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_XIRC2PS=m +# CONFIG_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +CONFIG_NET_PCMCIA_RADIO=y +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_WAVELAN=m +# CONFIG_AIRONET4500_CS is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +CONFIG_IRDA=m +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_DEBUG=y + +# +# Infrared-port device drivers +# +CONFIG_IRTTY_SIR=m +CONFIG_IRPORT_SIR=m +# CONFIG_DONGLE is not set +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# 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_SA1100_FIR=m + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=m + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=m +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=m +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDETAPE=m +CONFIG_BLK_DEV_IDEFLOPPY=m +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +CONFIG_SCSI=m +CONFIG_BLK_DEV_SD=m +CONFIG_SD_EXTRA_DEVS=40 +CONFIG_CHR_DEV_ST=m +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=m +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set + +# +# PCMCIA SCSI adapter support +# +CONFIG_SCSI_PCMCIA=y +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_QLOGIC=m + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +CONFIG_ISDN=m +CONFIG_ISDN_BOOL=y +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_MPP=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_TTY_FAX=y + +# +# ISDN feature submodules +# +CONFIG_ISDN_DRV_LOOP=m +CONFIG_ISDN_DIVERSION=m + +# +# Passive ISDN cards +# +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_HISAX=y +CONFIG_HISAX_EURO=y +# CONFIG_DE_AOC is not set +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_KEYPAD is not set +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_MAX_CARDS=8 +# CONFIG_HISAX_16_0 is not set +CONFIG_HISAX_16_3=y +# CONFIG_HISAX_TELESPCI is not set +# CONFIG_HISAX_S0BOX is not set +# CONFIG_HISAX_AVM_A1 is not set +# CONFIG_HISAX_FRITZPCI is not set +# CONFIG_HISAX_AVM_A1_PCMCIA is not set +# CONFIG_HISAX_ELSA is not set +# CONFIG_HISAX_IX1MICROR2 is not set +# CONFIG_HISAX_DIEHLDIVA is not set +# CONFIG_HISAX_ASUSCOM is not set +# CONFIG_HISAX_TELEINT is not set +# CONFIG_HISAX_HFCS is not set +# CONFIG_HISAX_SEDLBAUER is not set +# CONFIG_HISAX_SPORTSTER is not set +# CONFIG_HISAX_MIC is not set +# CONFIG_HISAX_NETJET is not set +# CONFIG_HISAX_NETJET_U is not set +# CONFIG_HISAX_NICCY is not set +# CONFIG_HISAX_ISURF is not set +# CONFIG_HISAX_HSTSAPHIR is not set +# CONFIG_HISAX_BKM_A4T is not set +# CONFIG_HISAX_SCT_QUADRO is not set +# CONFIG_HISAX_GAZEL is not set +# CONFIG_HISAX_HFC_PCI is not set +# CONFIG_HISAX_W6692 is not set +CONFIG_HISAX_HFC_SX=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ELSA_CS=m +# CONFIG_HISAX_AVM_A1_CS is not set +CONFIG_HISAX_ST5481=m +# CONFIG_HISAX_FRITZ_PCIPNP is not set + +# +# Active ISDN cards +# +# 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_EICON is not set +# CONFIG_ISDN_DRV_TPAM is not set +CONFIG_ISDN_CAPI=m +# CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON is not set +# CONFIG_ISDN_CAPI_MIDDLEWARE is not set +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIDRV=m +# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set +# CONFIG_ISDN_DRV_AVMB1_B1PCI is not set +# CONFIG_ISDN_DRV_AVMB1_B1PCIV4 is not set +# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +# CONFIG_ISDN_DRV_AVMB1_AVM_CS is not set +# CONFIG_ISDN_DRV_AVMB1_T1PCI is not set +# CONFIG_ISDN_DRV_AVMB1_C4 is not set +# CONFIG_HYSDN is not set +# CONFIG_HYSDN_CAPI is not set + +# +# Input core support +# +CONFIG_INPUT=m +CONFIG_INPUT_KEYBDEV=m +CONFIG_INPUT_MOUSEDEV=m +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_UINPUT=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=m +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_S3C2410 is not set +# CONFIG_SERIAL_S3C2410_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SA1100_DEFAULT_BAUDRATE=115200 +CONFIG_SERIAL_H3800_ASIC=m +# CONFIG_SERIAL_SIR_PXA is not set +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_HUB6 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 +CONFIG_NEWTONKBD=m +CONFIG_SA1100_PROFILER=m +CONFIG_TOUCHSCREEN_H3600=m +CONFIG_H3600_BACKPAQ_FPGA=m +CONFIG_H3600_BACKPAQ_ACCEL=m +CONFIG_H3600_BACKPAQ_GASGAUGE=m +CONFIG_H3600_BACKPAQ_SRAM=m +CONFIG_H3600_BACKPAQ_AUDIO=m +CONFIG_H3600_STOWAWAY=m +CONFIG_H3800_MICROKBD=m +CONFIG_SA1100_LIRC=m +# CONFIG_H5400_BUZZER is not set +# CONFIG_H5400_FSI is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# L3 serial bus support +# +CONFIG_L3=y +CONFIG_L3_ALGOBIT=y +CONFIG_L3_BIT_SA1100_GPIO=y +# CONFIG_L3_S3C2410 is not set +# CONFIG_L3_SA1111 is not set +CONFIG_L3_BACKPAQ=m +CONFIG_BIT_SA1100_GPIO=y + +# +# SPI support +# +# CONFIG_SPI is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +CONFIG_MOUSE=m +# CONFIG_PSMOUSE is not set +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set +# CONFIG_MK712_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +CONFIG_INPUT_SERIO=m +CONFIG_INPUT_SERPORT=m +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_21285_WATCHDOG is not set +# CONFIG_977_WATCHDOG is not set +CONFIG_SA1100_WATCHDOG=m +# CONFIG_PXA_WATCHDOG is not set +# CONFIG_OMAHA_WATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +CONFIG_SA1100_RTC=m +# CONFIG_PXA_RTC_HACK is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +CONFIG_PCMCIA_SERIAL_CS=m +CONFIG_PCMCIA_MOBILISCAN_CS=m +# CONFIG_AXIM_KEY_FIX is not set + +# +# Multimedia devices +# +CONFIG_MEDIA=m +CONFIG_VIDEO_DEV=m +CONFIG_V4L2_DEV=m + +# +# Video For Linux +# +CONFIG_VIDEO_PROC_FS=y +# CONFIG_I2C_PARPORT is not set +# CONFIG_VIDEO_PMS is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZR36120 is not set +# CONFIG_VIDEO_MEYE is not set +# CONFIG_VIDEO_CYBERPRO is not set +CONFIG_VIDEO_H3600_BACKPAQ=m +# CONFIG_VIDEO_HAWKEYE is not set +CONFIG_VIDEO_WINNOV_CS=m + +# +# Radio Adapters +# +# 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 is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set +# CONFIG_RADIO_MIROPCM20_RDS is not set +# CONFIG_RADIO_SF16FMI 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 + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=m +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_UMSDOS_FS=m +CONFIG_VFAT_FS=m +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +CONFIG_CRAMFS=y +CONFIG_TMPFS=y +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DRIVERFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=m +# CONFIG_SYSV_FS is not set +CONFIG_UDF_FS=m +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +CONFIG_CODA_FS=m +CONFIG_INTERMEZZO_FS=m +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +CONFIG_SUNRPC=m +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +CONFIG_ZISOFS_FS=m + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m + +# +# Console drivers +# +CONFIG_PC_KEYMAP=y +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_ACORN is not set +# CONFIG_FB_ANAKIN is not set +# CONFIG_FB_CLPS711X is not set +# CONFIG_FB_S3C2410 is not set +CONFIG_FB_SA1100=y +# CONFIG_FB_EPSON1356 is not set +# CONFIG_FB_MQ200 is not set +# CONFIG_FB_PXA is not set +# CONFIG_FB_MQ1100 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +CONFIG_FBCON_CFB4=y +# CONFIG_FBCON_CFB8 is not set +CONFIG_FBCON_CFB16=y +# CONFIG_FBCON_CFB24 is not set +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +# CONFIG_FBCON_NO_LOGO is not set +CONFIG_FBCON_FONTWIDTH8_ONLY=y +CONFIG_FBCON_FONTS=y +CONFIG_FONT_8x8=y +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +CONFIG_SOUND_SA1100=m +CONFIG_SOUND_UDA1341=m +# CONFIG_SOUND_SA1100_MONO is not set +# CONFIG_SOUND_ASSABET_UDA1341 is not set +CONFIG_SOUND_H3600_UDA1341=m +# CONFIG_SOUND_PANGOLIN_UDA1341 is not set +# CONFIG_SOUND_SA1111_UDA1341 is not set +# CONFIG_SOUND_SA1100SSP is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_VIDC is not set +# CONFIG_SOUND_WAVEARTIST is not set +# CONFIG_SOUND_PXA_AC97 is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set +# CONFIG_MCP_UCB1400_TS is not set + +# +# Console Switches +# +CONFIG_SWITCHES=m +CONFIG_SWITCHES_SA1100=y + +# +# USB support +# +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +CONFIG_USB_BANDWIDTH=y +# CONFIG_USB_LONG_TIMEOUT is not set +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_OHCI_SA1111 is not set +# CONFIG_USB_OHCI_H5400 is not set +CONFIG_USB_SL811HS=m +CONFIG_USB_SL811HS_CS=m +CONFIG_USB_AUDIO=m +CONFIG_USB_EMI26=m +CONFIG_USB_BLUETOOTH=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_JUMPSHOT=y +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_HID=m +CONFIG_USB_HIDINPUT=y +CONFIG_USB_HIDDEV=y +CONFIG_USB_KBD=m +CONFIG_USB_MOUSE=m +CONFIG_USB_WACOM=m +CONFIG_USB_DC2XX=m +CONFIG_USB_MDC800=m +CONFIG_USB_SCANNER=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_HPUSBSCSI=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_OV511=m +CONFIG_USB_PWC=m +CONFIG_USB_QC=m +CONFIG_USB_SE401=m +CONFIG_USB_STV680=m +CONFIG_USB_VICAM=m +CONFIG_USB_DSBR=m +CONFIG_USB_DABUSB=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_KAWETH=m +CONFIG_USB_CATC=m +CONFIG_USB_CDCETHER=m +CONFIG_USB_USBNET=m +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_GENERIC is not set +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_RIO500=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_BRLVGER=m + +# +# Linux As Bootldr Modules +# +# CONFIG_BIG_KERNEL is not set +# CONFIG_USE_DATE_CODE is not set +# CONFIG_YMODEM is not set +# CONFIG_LAB_DUMMY is not set +# CONFIG_LAB_CRC is not set +# CONFIG_LAB_YMODEM is not set +# CONFIG_LAB_MTD is not set +# CONFIG_LAB_COPY is not set +# CONFIG_LAB_COPY_YMODEM is not set +# CONFIG_LAB_COPY_FLASH is not set +# CONFIG_LAB_COPY_FS is not set +# CONFIG_LAB_COPY_WRAPPER is not set + +# +# Bluetooth support +# +CONFIG_BLUEZ=m +CONFIG_BLUEZ_L2CAP=m +CONFIG_BLUEZ_SCO=m +CONFIG_BLUEZ_RFCOMM=m +CONFIG_BLUEZ_RFCOMM_TTY=y +CONFIG_BLUEZ_BNEP=m +CONFIG_BLUEZ_BNEP_MC_FILTER=y +CONFIG_BLUEZ_BNEP_PROTO_FILTER=y +# CONFIG_BLUEZ_CMTP is not set + +# +# Bluetooth device drivers +# +# CONFIG_BLUEZ_HCIUSB is not set +CONFIG_BLUEZ_HCIUART=m +CONFIG_BLUEZ_HCIUART_H4=y +CONFIG_BLUEZ_HCIUART_BCSP=y +# CONFIG_BLUEZ_HCIUART_BCSP_TXCRC is not set +# CONFIG_BLUEZ_HCIBFUSB is not set +CONFIG_BLUEZ_HCIDTL1=m +CONFIG_BLUEZ_HCIBT3C=m +CONFIG_BLUEZ_HCIBLUECARD=m +CONFIG_BLUEZ_HCIBTUART=m +CONFIG_BLUEZ_HCIVHCI=m + +# +# Kernel hacking +# +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_NO_PGT_CACHE is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set + +# +# Library routines +# +CONFIG_CRC32=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/packages/linux/handhelds-sa_2.4.19-rmk6-pxa1-hh42.bb b/packages/linux/handhelds-sa_2.4.19-rmk6-pxa1-hh42.bb new file mode 100644 index 0000000000..a3d54d1319 --- /dev/null +++ b/packages/linux/handhelds-sa_2.4.19-rmk6-pxa1-hh42.bb @@ -0,0 +1,57 @@ +SECTION = "kernel" +DESCRIPTION = "handhelds.org Linux kernel for StrongArm processor based devices." +MAINTAINER = "Rene Wagner " +LICENSE = "GPL" +PR = "r0" +DEFAULT_PREFERENCE = "-1" + +KERNEL_CCSUFFIX = "-3.3.4" +COMPATIBLE_HOST = "arm.*-linux" +COMPATIBLE_MACHINE = '(h3600|simpad)' + +FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/handhelds-sa-${PV}" +SRC_URI = "${HANDHELDS_CVS};module=linux/kernel;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \ + file://defconfig-${PACKAGE_ARCH} \ + file://ipaq-hal.init" + +S = "${WORKDIR}/kernel" + +inherit kernel update-rc.d + +K_MAJOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[0]}" +K_MINOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[1]}" +K_MICRO = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[2]}" +RMKV = "${@bb.data.getVar('PV',d,1).split('-')[1].split('rmk')[-1]}" +PXAV = "${@bb.data.getVar('PV',d,1).split('-')[2].split('pxa')[-1]}" +HHV = "${@bb.data.getVar('PV',d,1).split('-')[3].split('hh')[-1]}" + +KERNEL_PRIORITY = "${@'%d' % (int(bb.data.getVar('K_MAJOR',d,1)) * 100000000 + int(bb.data.getVar('K_MINOR',d,1)) * 1000000 + int(bb.data.getVar('K_MICRO',d,1)) * 10000 + int(bb.data.getVar('RMKV',d,1)) * 1000 + int(bb.data.getVar('PXAV',d,1)) * 100 + float(bb.data.getVar('HHV',d,1)))}" + +module_conf_h3600_micro = "alias ipaq_hal_3600 h3600_micro" +module_conf_h3600_asic = "alias ipaq_hal_3800 h3600_asic" +module_conf_sa1100_ir = "alias irda0 sa1100_ir" +module_conf_pcmcia_core = "options pcmcia_core ignore_cis_vcc=1" +module_conf_ppp_async = "alias ppp0 ppp_async" +module_conf_orinoco_cs = "options orinoco_cs ignore_cis_vcc=1" +module_conf_hostap_cs = "options hostap_cs ignore_cis_vcc=1" +module_conf_spectrum_cs = "options spectrum_cs ignore_cis_vcc=1" + +module_autoload_h3600_ts = "h3600_ts" +module_autoload_apm = "apm" +module_autoload_h3600-uda1341 = "h3600-uda1341" +module_autoload_af_packet = "af_packet" +module_autoload_ppp_async = "ppp_async" +module_autoload_usb-eth = "usb-eth" + +FILES_kernel += "/etc/init.d/ipaq-hal" +INITSCRIPT_NAME = "ipaq-hal" +INITSCRIPT_PARAMS = "start 21 S ." + +do_configure_prepend() { + install -m 0644 ${WORKDIR}/defconfig-${PACKAGE_ARCH} ${S}/.config +} + +do_install_append() { + install -d ${D}${sysconfdir}/init.d + install ${WORKDIR}/ipaq-hal.init ${D}${sysconfdir}/init.d/ipaq-hal +} -- cgit v1.2.3 From f42a4c6fe7b0250c33335171c8534e9a3174d3da Mon Sep 17 00:00:00 2001 From: Erik Hovland Date: Fri, 1 Sep 2006 17:06:23 +0000 Subject: gpe-package: Make minor tweaks associated to familiar 0.8.4 release * Use variables instead of hard coded directory paths * Rework DEPENDS and RDEPENDS --- packages/gpe-package/gpe-package_0.3.bb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/gpe-package/gpe-package_0.3.bb b/packages/gpe-package/gpe-package_0.3.bb index a6342f4e18..4de6e056df 100644 --- a/packages/gpe-package/gpe-package_0.3.bb +++ b/packages/gpe-package/gpe-package_0.3.bb @@ -3,8 +3,8 @@ PR = "r3" inherit gpe pkgconfig DESCRIPTION = "A package manager GUI for GPE" -DEPENDS = "ipkg pcre libgpewidget gpe-su" -RDEPENDS = "gpe-icons" +DEPENDS = "ipkg pcre libgpewidget" +RDEPENDS = "gpe-icons gpe-su" SECTION = "gpe" PRIORITY = "optional" @@ -18,6 +18,6 @@ CFLAGS += "-DENABLE_PCRE" LDFLAGS += "-lpcre" do_install_append() { - install -d ${D}/usr/bin - install -m 0755 ${WORKDIR}/gpe-package ${D}/usr/bin + install -d ${D}${bindir} + install -m 0755 ${WORKDIR}/gpe-package ${D}${bindir} } -- cgit v1.2.3 From bea2e753e4dd603050387685aa8374ae88f233cf Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 1 Sep 2006 17:17:28 +0000 Subject: abiword, abiword-plugins: Add SECTION = "gnome" (or should this be "gpe"? I guess, no, until it is patched to support GPE/handhelds better). --- packages/abiword/abiword-plugins_2.4.4.bb | 3 ++- packages/abiword/abiword-plugins_2.4.5.bb | 3 ++- packages/abiword/abiword_2.4.4.bb | 3 ++- packages/abiword/abiword_2.4.5.bb | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/abiword/abiword-plugins_2.4.4.bb b/packages/abiword/abiword-plugins_2.4.4.bb index 612e81f80f..541c893471 100644 --- a/packages/abiword/abiword-plugins_2.4.4.bb +++ b/packages/abiword/abiword-plugins_2.4.4.bb @@ -1,10 +1,11 @@ DESCRIPTION ="AbiWord is free word processing program similar to Microsoft(r) Word"" +SECTION = "gnome" HOMEPAGE="http://www.abiword.org"" MAINTAINER="Koen Kooi " LICENSE="GPLv2" DEPENDS = "abiword libwpd librsvg goffice poppler" -PR="r1" +PR="r2" SRC_URI = "http://www.abiword.org/downloads/abiword/${PV}/source/abiword-${PV}.tar.gz \ file://abiword-plugin-pdf-poppler.patch;patch=1;pnum=2" diff --git a/packages/abiword/abiword-plugins_2.4.5.bb b/packages/abiword/abiword-plugins_2.4.5.bb index 75861792dd..68c6c19742 100644 --- a/packages/abiword/abiword-plugins_2.4.5.bb +++ b/packages/abiword/abiword-plugins_2.4.5.bb @@ -1,10 +1,11 @@ DESCRIPTION ="AbiWord is free word processing program similar to Microsoft(r) Word"" +SECTION = "gnome" HOMEPAGE="http://www.abiword.org"" MAINTAINER="Koen Kooi " LICENSE="GPLv2" DEPENDS = "abiword libwpd librsvg goffice poppler" -PR="r0" +PR="r1" SRC_URI = "http://www.abiword.org/downloads/abiword/${PV}/source/abiword-${PV}.tar.gz \ file://abiword-plugin-pdf-poppler.patch;patch=1;pnum=2" diff --git a/packages/abiword/abiword_2.4.4.bb b/packages/abiword/abiword_2.4.4.bb index 8f6c3adeb6..7798626b7a 100644 --- a/packages/abiword/abiword_2.4.4.bb +++ b/packages/abiword/abiword_2.4.4.bb @@ -1,4 +1,5 @@ DESCRIPTION ="AbiWord is free word processing program similar to Microsoft(r) Word"" +SECTION = "gnome" HOMEPAGE="http://www.abiword.org"" MAINTAINER="Koen Kooi " LICENSE="GPLv2" @@ -6,7 +7,7 @@ LICENSE="GPLv2" DEPENDS = "perl-native libgsf libgnomeprint libgnomeprintui libglade libfribidi enchant jpeg libpng perl glibc libxml2" RDEPENDS = "enchant glibc-gconv-ibm850 glibc-gconv-cp1252 \ glibc-gconv-iso8859-15 glibc-gconv-iso8859-1" -PR="r0" +PR="r1" SRC_URI = "http://www.abiword.org/downloads/abiword/${PV}/source/abiword-${PV}.tar.gz" S = "${WORKDIR}/abiword-${PV}/abi" diff --git a/packages/abiword/abiword_2.4.5.bb b/packages/abiword/abiword_2.4.5.bb index 8f6c3adeb6..7798626b7a 100644 --- a/packages/abiword/abiword_2.4.5.bb +++ b/packages/abiword/abiword_2.4.5.bb @@ -1,4 +1,5 @@ DESCRIPTION ="AbiWord is free word processing program similar to Microsoft(r) Word"" +SECTION = "gnome" HOMEPAGE="http://www.abiword.org"" MAINTAINER="Koen Kooi " LICENSE="GPLv2" @@ -6,7 +7,7 @@ LICENSE="GPLv2" DEPENDS = "perl-native libgsf libgnomeprint libgnomeprintui libglade libfribidi enchant jpeg libpng perl glibc libxml2" RDEPENDS = "enchant glibc-gconv-ibm850 glibc-gconv-cp1252 \ glibc-gconv-iso8859-15 glibc-gconv-iso8859-1" -PR="r0" +PR="r1" SRC_URI = "http://www.abiword.org/downloads/abiword/${PV}/source/abiword-${PV}.tar.gz" S = "${WORKDIR}/abiword-${PV}/abi" -- cgit v1.2.3 From 5d66761dcbccbcbc8b635353c341e07f6423ecff Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 1 Sep 2006 17:34:18 +0000 Subject: abiword, abiword-plugins: Setting new SECTION="gnome/office", suggested by Koen Kooi. --- packages/abiword/abiword-plugins_2.4.4.bb | 2 +- packages/abiword/abiword-plugins_2.4.5.bb | 2 +- packages/abiword/abiword_2.4.4.bb | 2 +- packages/abiword/abiword_2.4.5.bb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/abiword/abiword-plugins_2.4.4.bb b/packages/abiword/abiword-plugins_2.4.4.bb index 541c893471..3573e87089 100644 --- a/packages/abiword/abiword-plugins_2.4.4.bb +++ b/packages/abiword/abiword-plugins_2.4.4.bb @@ -1,5 +1,5 @@ DESCRIPTION ="AbiWord is free word processing program similar to Microsoft(r) Word"" -SECTION = "gnome" +SECTION = "gnome/office" HOMEPAGE="http://www.abiword.org"" MAINTAINER="Koen Kooi " LICENSE="GPLv2" diff --git a/packages/abiword/abiword-plugins_2.4.5.bb b/packages/abiword/abiword-plugins_2.4.5.bb index 68c6c19742..444b0a43c7 100644 --- a/packages/abiword/abiword-plugins_2.4.5.bb +++ b/packages/abiword/abiword-plugins_2.4.5.bb @@ -1,5 +1,5 @@ DESCRIPTION ="AbiWord is free word processing program similar to Microsoft(r) Word"" -SECTION = "gnome" +SECTION = "gnome/office" HOMEPAGE="http://www.abiword.org"" MAINTAINER="Koen Kooi " LICENSE="GPLv2" diff --git a/packages/abiword/abiword_2.4.4.bb b/packages/abiword/abiword_2.4.4.bb index 7798626b7a..1df0303634 100644 --- a/packages/abiword/abiword_2.4.4.bb +++ b/packages/abiword/abiword_2.4.4.bb @@ -1,5 +1,5 @@ DESCRIPTION ="AbiWord is free word processing program similar to Microsoft(r) Word"" -SECTION = "gnome" +SECTION = "gnome/office" HOMEPAGE="http://www.abiword.org"" MAINTAINER="Koen Kooi " LICENSE="GPLv2" diff --git a/packages/abiword/abiword_2.4.5.bb b/packages/abiword/abiword_2.4.5.bb index 7798626b7a..1df0303634 100644 --- a/packages/abiword/abiword_2.4.5.bb +++ b/packages/abiword/abiword_2.4.5.bb @@ -1,5 +1,5 @@ DESCRIPTION ="AbiWord is free word processing program similar to Microsoft(r) Word"" -SECTION = "gnome" +SECTION = "gnome/office" HOMEPAGE="http://www.abiword.org"" MAINTAINER="Koen Kooi " LICENSE="GPLv2" -- cgit v1.2.3 From dbfe597f0d9b9c8837dc6a28c0adfea4b281d46c Mon Sep 17 00:00:00 2001 From: Erik Hovland Date: Fri, 1 Sep 2006 18:26:01 +0000 Subject: busybox 1.00: Incorporate fixes from familiar 0.8.4 release * Add --oknodo argument to start-stop-daemon * df fixes * unzip and libuncompress fixes backported from 1.1.0 * bump rev to r37 since familiar 0.8.4 shipped with r36 --- packages/busybox/busybox-1.00/df.patch | 28 + .../start-stop-daemon-oknodo-support.patch | 73 ++ .../busybox/busybox-1.00/unzip-endian-fixes.patch | 54 ++ .../busybox-1.00/unzip-enhancement-and-fixes.patch | 878 +++++++++++++++++++++ packages/busybox/busybox_1.00.bb | 7 +- 5 files changed, 1039 insertions(+), 1 deletion(-) create mode 100644 packages/busybox/busybox-1.00/df.patch create mode 100644 packages/busybox/busybox-1.00/start-stop-daemon-oknodo-support.patch create mode 100644 packages/busybox/busybox-1.00/unzip-endian-fixes.patch create mode 100644 packages/busybox/busybox-1.00/unzip-enhancement-and-fixes.patch diff --git a/packages/busybox/busybox-1.00/df.patch b/packages/busybox/busybox-1.00/df.patch new file mode 100644 index 0000000000..49888293fd --- /dev/null +++ b/packages/busybox/busybox-1.00/df.patch @@ -0,0 +1,28 @@ +--- busybox-1.00/coreutils/df.c.orig 2006-07-14 09:50:47.914912750 -0400 ++++ busybox-1.00/coreutils/df.c 2006-07-14 09:52:32.613456000 -0400 +@@ -60,6 +60,7 @@ + struct statfs s; + static const char hdr_1k[] = "1k-blocks"; /* default display is kilobytes */ + const char *disp_units_hdr = hdr_1k; ++ int root_done = 0; + + #ifdef CONFIG_FEATURE_HUMAN_READABLE + bb_opt_complementaly = "h-km:k-hm:m-hk"; +@@ -125,14 +126,14 @@ + ) / (blocks_used + s.f_bavail); + } + +- if (strcmp(device, "rootfs") == 0) { +- continue; +- } else if (strcmp(device, "/dev/root") == 0) { ++ if (strcmp(device, "/dev/root") == 0 || strcmp(device, "rootfs") == 0) { ++ if (root_done) continue; + /* Adjusts device to be the real root device, + * or leaves device alone if it can't find it */ + if ((device = find_real_root_device_name()) == NULL) { + goto SET_ERROR; + } ++ root_done = 1; + } + + #ifdef CONFIG_FEATURE_HUMAN_READABLE diff --git a/packages/busybox/busybox-1.00/start-stop-daemon-oknodo-support.patch b/packages/busybox/busybox-1.00/start-stop-daemon-oknodo-support.patch new file mode 100644 index 0000000000..1b8debb021 --- /dev/null +++ b/packages/busybox/busybox-1.00/start-stop-daemon-oknodo-support.patch @@ -0,0 +1,73 @@ +--- busybox-1.00/debianutils/start_stop_daemon.c.orig 2006-07-23 00:06:14.000000000 +0200 ++++ busybox-1.00/debianutils/start_stop_daemon.c 2006-07-23 00:21:39.000000000 +0200 +@@ -160,7 +160,7 @@ + } + + +-static void ++static int + do_stop(void) + { + char what[1024]; +@@ -183,7 +183,7 @@ + if (!found) { + if (!quiet) + printf("no %s found; none killed.\n", what); +- return; ++ return -1; + } + for (p = found; p; p = p->next) { + if (kill(p->pid, signal_nr) == 0) { +@@ -200,6 +200,7 @@ + printf(" %d", -p->pid); + printf(").\n"); + } ++ return killed; + } + + +@@ -209,6 +210,7 @@ + { "background", 0, NULL, 'b' }, + { "quiet", 0, NULL, 'q' }, + { "make-pidfile", 0, NULL, 'm' }, ++ { "oknodo", 0, NULL, 'o' }, + { "startas", 1, NULL, 'a' }, + { "name", 1, NULL, 'n' }, + { "signal", 1, NULL, 's' }, +@@ -223,6 +225,7 @@ + #define SSD_OPT_BACKGROUND 4 + #define SSD_OPT_QUIET 8 + #define SSD_OPT_MAKEPID 16 ++#define SSD_OPT_OKNODO 32 + + int + start_stop_daemon_main(int argc, char **argv) +@@ -234,7 +237,7 @@ + bb_applet_long_options = ssd_long_options; + + bb_opt_complementaly = "K~S:S~K"; +- opt = bb_getopt_ulflags(argc, argv, "KSbqma:n:s:u:x:p:", ++ opt = bb_getopt_ulflags(argc, argv, "KSbqmoa:n:s:u:x:p:", + &startas, &cmdname, &signame, &userspec, &execname, &pidfile); + + /* Check one and only one context option was given */ +@@ -265,8 +268,8 @@ + user_id = my_getpwnam(userspec); + + if (opt & SSD_CTX_STOP) { +- do_stop(); +- return EXIT_SUCCESS; ++ int i = do_stop(); ++ return (opt & SSD_OPT_OKNODO) ? 0 : (i <= 0); + } + + do_procinit(); +@@ -274,7 +277,7 @@ + if (found) { + if (!quiet) + printf("%s already running.\n%d\n", execname ,found->pid); +- return EXIT_SUCCESS; ++ return (opt & SSD_OPT_OKNODO) ? EXIT_SUCCESS : EXIT_FAILURE; + } + *--argv = startas; + if (opt & SSD_OPT_BACKGROUND) { diff --git a/packages/busybox/busybox-1.00/unzip-endian-fixes.patch b/packages/busybox/busybox-1.00/unzip-endian-fixes.patch new file mode 100644 index 0000000000..56af433c30 --- /dev/null +++ b/packages/busybox/busybox-1.00/unzip-endian-fixes.patch @@ -0,0 +1,54 @@ +--- archival/unzip.c.orig 2005-03-17 18:42:45.000000000 -0500 ++++ archival/unzip.c 2005-03-17 17:46:45.000000000 -0500 +@@ -46,10 +46,28 @@ + #include "unarchive.h" + #include "busybox.h" + +-#define ZIP_FILEHEADER_MAGIC 0x04034b50 +-#define ZIP_CDS_MAGIC 0x02014b50 +-#define ZIP_CDS_END_MAGIC 0x06054b50 +-#define ZIP_DD_MAGIC 0x08074b50 ++#if (BYTE_ORDER == BIG_ENDIAN) ++static inline unsigned short ++__swap16(unsigned short x) { ++ return (((uint16_t)(x) & 0xFF) << 8) | (((uint16_t)(x) & 0xFF00) >> 8); ++} ++ ++static inline uint32_t ++__swap32(uint32_t x) { ++ return (((x & 0xFF) << 24) | ++ ((x & 0xFF00) << 8) | ++ ((x & 0xFF0000) >> 8) | ++ ((x & 0xFF000000) >> 24)); ++} ++#else ++#define __swap16(x) (x) ++#define __swap32(x) (x) ++#endif ++ ++#define ZIP_FILEHEADER_MAGIC __swap32(0x04034b50) ++#define ZIP_CDS_MAGIC __swap32(0x02014b50) ++#define ZIP_CDS_END_MAGIC __swap32(0x06054b50) ++#define ZIP_DD_MAGIC __swap32(0x08074b50) + + extern unsigned int gunzip_crc; + extern unsigned int gunzip_bytes_out; +@@ -249,6 +267,18 @@ + + /* Read the file header */ + unzip_read(src_fd, zip_header.raw, 26); ++#if (BYTE_ORDER == BIG_ENDIAN) ++ zip_header.formated.version = __swap16(zip_header.formated.version); ++ zip_header.formated.flags = __swap16(zip_header.formated.flags); ++ zip_header.formated.method = __swap16(zip_header.formated.method); ++ zip_header.formated.modtime = __swap16(zip_header.formated.modtime); ++ zip_header.formated.moddate = __swap16(zip_header.formated.moddate); ++ zip_header.formated.crc32 = __swap32(zip_header.formated.crc32); ++ zip_header.formated.cmpsize = __swap32(zip_header.formated.cmpsize); ++ zip_header.formated.ucmpsize = __swap32(zip_header.formated.ucmpsize); ++ zip_header.formated.filename_len = __swap16(zip_header.formated.filename_len); ++ zip_header.formated.extra_len = __swap16(zip_header.formated.extra_len); ++#endif + if ((zip_header.formated.method != 0) && (zip_header.formated.method != 8)) { + bb_error_msg_and_die("Unsupported compression method %d", zip_header.formated.method); + } diff --git a/packages/busybox/busybox-1.00/unzip-enhancement-and-fixes.patch b/packages/busybox/busybox-1.00/unzip-enhancement-and-fixes.patch new file mode 100644 index 0000000000..49542cab1d --- /dev/null +++ b/packages/busybox/busybox-1.00/unzip-enhancement-and-fixes.patch @@ -0,0 +1,878 @@ + +Index: archival/unzip.c +=================================================================== +RCS file: /var/cvs/busybox/archival/unzip.c,v +retrieving revision 1.8 +diff -u -r1.8 unzip.c +--- archival/unzip.c 6 Jun 2004 10:22:43 -0000 1.8 ++++ archival/unzip.c 18 Oct 2004 01:32:25 -0000 +@@ -2,7 +2,10 @@ + /* + * Mini unzip implementation for busybox + * +- * Copyright (C) 2001 by Laurence Anderson ++ * Copyright (C) 2004 by Ed Clark ++ * ++ * Loosely based on original busybox unzip applet by Laurence Anderson. ++ * All options and features should work in this version. + * + * 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 +@@ -21,17 +24,25 @@ + */ + + /* For reference see +- * http://www.pkware.com/products/enterprise/white_papers/appnote.txt ++ * http://www.pkware.com/company/standards/appnote/ + * http://www.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip + */ + +-/* TODO Endian issues, exclude, should we accept input from stdin ? */ ++/* TODO ++ * Endian issues ++ * Zip64 + other methods ++ * Improve handling of zip format, ie. ++ * - deferred CRC, comp. & uncomp. lengths (zip header flags bit 3) ++ * - unix file permissions, etc. ++ * - central directory ++ */ + + #include + #include + #include + #include + #include ++#include + #include "unarchive.h" + #include "busybox.h" + +@@ -43,205 +54,353 @@ + extern unsigned int gunzip_crc; + extern unsigned int gunzip_bytes_out; + +-static void header_list_unzip(const file_header_t *file_header) ++typedef union { ++ unsigned char raw[26]; ++ struct { ++ unsigned short version; /* 0-1 */ ++ unsigned short flags; /* 2-3 */ ++ unsigned short method; /* 4-5 */ ++ unsigned short modtime; /* 6-7 */ ++ unsigned short moddate; /* 8-9 */ ++ unsigned int crc32 __attribute__ ((packed)); /* 10-13 */ ++ unsigned int cmpsize __attribute__ ((packed)); /* 14-17 */ ++ unsigned int ucmpsize __attribute__ ((packed)); /* 18-21 */ ++ unsigned short filename_len; /* 22-23 */ ++ unsigned short extra_len; /* 24-25 */ ++ } formated __attribute__ ((packed)); ++} zip_header_t; ++ ++static void unzip_skip(int fd, off_t skip) + { +- printf(" inflating: %s\n", file_header->name); ++ if (lseek(fd, skip, SEEK_CUR) == (off_t)-1) { ++ if ((errno != ESPIPE) || (bb_copyfd_size(fd, -1, skip) != skip)) { ++ bb_error_msg_and_die("Seek failure"); ++ } ++ } + } + +-static void header_verbose_list_unzip(const file_header_t *file_header) ++static void unzip_read(int fd, void *buf, size_t count) + { +- unsigned int dostime = (unsigned int) file_header->mtime; ++ if (bb_xread(fd, buf, count) != count) { ++ bb_error_msg_and_die("Read failure"); ++ } ++} + +- /* can printf arguments cut of the decade component ? */ +- unsigned short year = 1980 + ((dostime & 0xfe000000) >> 25); +- while (year >= 100) { +- year -= 100; +- } +- +- printf("%9u %02u-%02u-%02u %02u:%02u %s\n", +- (unsigned int) file_header->size, +- (dostime & 0x01e00000) >> 21, +- (dostime & 0x001f0000) >> 16, +- year, +- (dostime & 0x0000f800) >> 11, +- (dostime & 0x000007e0) >> 5, +- file_header->name); ++static void unzip_create_leading_dirs(char *fn) ++{ ++ /* Create all leading directories */ ++ char *name = bb_xstrdup(fn); ++ if (bb_make_directory(dirname(name), 0777, FILEUTILS_RECUR)) { ++ bb_error_msg_and_die("Failed to create directory"); ++ } ++ free(name); + } + +-extern int unzip_main(int argc, char **argv) ++static void unzip_extract(zip_header_t *zip_header, int src_fd, int dst_fd) + { +- union { +- unsigned char raw[26]; +- struct { +- unsigned short version; /* 0-1 */ +- unsigned short flags; /* 2-3 */ +- unsigned short method; /* 4-5 */ +- unsigned short modtime; /* 6-7 */ +- unsigned short moddate; /* 8-9 */ +- unsigned int crc32 __attribute__ ((packed)); /* 10-13 */ +- unsigned int cmpsize __attribute__ ((packed));; /* 14-17 */ +- unsigned int ucmpsize __attribute__ ((packed));; /* 18-21 */ +- unsigned short filename_len; /* 22-23 */ +- unsigned short extra_len; /* 24-25 */ +- } formated __attribute__ ((packed)); +- } zip_header; ++ if (zip_header->formated.method == 0) { ++ /* Method 0 - stored (not compressed) */ ++ int size = zip_header->formated.ucmpsize; ++ if (size && (bb_copyfd_size(src_fd, dst_fd, size) != size)) { ++ bb_error_msg_and_die("Cannot complete extraction"); ++ } ++ ++ } else { ++ /* Method 8 - inflate */ ++ inflate_init(zip_header->formated.cmpsize); ++ inflate_unzip(src_fd, dst_fd); ++ inflate_cleanup(); ++ /* Validate decompression - crc */ ++ if (zip_header->formated.crc32 != (gunzip_crc ^ 0xffffffffL)) { ++ bb_error_msg("Invalid compressed data--crc error"); ++ } ++ /* Validate decompression - size */ ++ if (zip_header->formated.ucmpsize != gunzip_bytes_out) { ++ bb_error_msg("Invalid compressed data--length error"); ++ } ++ } ++} + +- archive_handle_t *archive_handle; ++extern int unzip_main(int argc, char **argv) ++{ ++ zip_header_t zip_header; ++ enum {v_silent, v_normal, v_list} verbosity = v_normal; ++ enum {o_prompt, o_never, o_always} overwrite = o_prompt; + unsigned int total_size = 0; + unsigned int total_entries = 0; ++ int src_fd = -1, dst_fd = -1; ++ char *src_fn = NULL, *dst_fn = NULL; ++ llist_t *accept = NULL; ++ llist_t *reject = NULL; + char *base_dir = NULL; +- int opt = 0; +- +- /* Initialise */ +- archive_handle = init_handle(); +- archive_handle->action_data = NULL; +- archive_handle->action_header = header_list_unzip; +- +- while ((opt = getopt(argc, argv, "lnopqd:")) != -1) { +- switch (opt) { +- case 'l': /* list */ +- archive_handle->action_header = header_verbose_list_unzip; +- archive_handle->action_data = data_skip; +- break; +- case 'n': /* never overwright existing files */ ++ int i, opt, opt_range = 0, list_header_done = 0; ++ char key_buf[512]; ++ struct stat stat_buf; ++ ++ while((opt = getopt(argc, argv, "-d:lnopqx")) != -1) { ++ switch(opt_range) { ++ case 0: /* Options */ ++ switch(opt) { ++ case 'l': /* List */ ++ verbosity = v_list; + break; +- case 'o': +- archive_handle->flags = ARCHIVE_EXTRACT_UNCONDITIONAL; ++ ++ case 'n': /* Never overwrite existing files */ ++ overwrite = o_never; + break; +- case 'p': /* extract files to stdout */ +- archive_handle->action_data = data_extract_to_stdout; ++ ++ case 'o': /* Always overwrite existing files */ ++ overwrite = o_always; + break; +- case 'q': /* Extract files quietly */ +- archive_handle->action_header = header_skip; ++ ++ case 'p': /* Extract files to stdout and fall through to set verbosity */ ++ dst_fd = STDOUT_FILENO; ++ ++ case 'q': /* Be quiet */ ++ verbosity = (verbosity == v_normal) ? v_silent : verbosity; + break; +- case 'd': /* Extract files to specified base directory*/ +- base_dir = optarg; +- break; +-#if 0 +- case 'x': /* Exclude the specified files */ +- archive_handle->filter = filter_accept_reject_list; ++ ++ case 1 : /* The zip file */ ++ src_fn = bb_xstrndup(optarg, strlen(optarg)+4); ++ opt_range++; + break; +-#endif ++ + default: + bb_show_usage(); ++ ++ } ++ break; ++ ++ case 1: /* Include files */ ++ if (opt == 1) { ++ accept = llist_add_to(accept, optarg); ++ ++ } else if (opt == 'd') { ++ base_dir = optarg; ++ opt_range += 2; ++ ++ } else if (opt == 'x') { ++ opt_range++; ++ ++ } else { ++ bb_show_usage(); ++ } ++ break; ++ ++ case 2 : /* Exclude files */ ++ if (opt == 1) { ++ reject = llist_add_to(reject, optarg); ++ ++ } else if (opt == 'd') { /* Extract to base directory */ ++ base_dir = optarg; ++ opt_range++; ++ ++ } else { ++ bb_show_usage(); ++ } ++ break; ++ ++ default: ++ bb_show_usage(); + } + } +- +- if (argc == optind) { ++ ++ if (src_fn == NULL) { + bb_show_usage(); + } + +- printf("Archive: %s\n", argv[optind]); +- if (archive_handle->action_header == header_verbose_list_unzip) { +- printf(" Length Date Time Name\n"); +- printf(" -------- ---- ---- ----\n"); +- } +- +- if (*argv[optind] == '-') { +- archive_handle->src_fd = STDIN_FILENO; +- archive_handle->seek = seek_by_char; ++ /* Open input file */ ++ if (strcmp("-", src_fn) == 0) { ++ src_fd = STDIN_FILENO; ++ /* Cannot use prompt mode since zip data is arriving on STDIN */ ++ overwrite = (overwrite == o_prompt) ? o_never : overwrite; ++ + } else { +- archive_handle->src_fd = bb_xopen(argv[optind++], O_RDONLY); ++ char *extn[] = {"", ".zip", ".ZIP"}; ++ int orig_src_fn_len = strlen(src_fn); ++ for(i = 0; (i < 3) && (src_fd == -1); i++) { ++ strcpy(src_fn + orig_src_fn_len, extn[i]); ++ src_fd = open(src_fn, O_RDONLY); ++ } ++ if (src_fd == -1) { ++ src_fn[orig_src_fn_len] = 0; ++ bb_error_msg_and_die("Cannot open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn); ++ } + } + +- if ((base_dir) && (chdir(base_dir))) { +- bb_perror_msg_and_die("Couldnt chdir"); ++ /* Change dir if necessary */ ++ if (base_dir && chdir(base_dir)) { ++ bb_perror_msg_and_die("Cannot chdir"); + } + +- while (optind < argc) { +- archive_handle->filter = filter_accept_list; +- archive_handle->accept = llist_add_to(archive_handle->accept, argv[optind]); +- optind++; +- } ++ if (verbosity != v_silent) ++ printf("Archive: %s\n", src_fn); + + while (1) { + unsigned int magic; +- int dst_fd; +- +- /* TODO Endian issues */ +- archive_xread_all(archive_handle, &magic, 4); +- archive_handle->offset += 4; + ++ /* Check magic number */ ++ unzip_read(src_fd, &magic, 4); + if (magic == ZIP_CDS_MAGIC) { + break; ++ } else if (magic != ZIP_FILEHEADER_MAGIC) { ++ bb_error_msg_and_die("Invalid zip magic %08X", magic); + } +- else if (magic != ZIP_FILEHEADER_MAGIC) { +- bb_error_msg_and_die("Invlaide zip magic"); +- } +- ++ + /* Read the file header */ +- archive_xread_all(archive_handle, zip_header.raw, 26); +- archive_handle->offset += 26; +- archive_handle->file_header->mode = S_IFREG | 0777; +- +- if (zip_header.formated.method != 8) { +- bb_error_msg_and_die("Unsupported compression method %d\n", zip_header.formated.method); ++ unzip_read(src_fd, zip_header.raw, 26); ++ if ((zip_header.formated.method != 0) && (zip_header.formated.method != 8)) { ++ bb_error_msg_and_die("Unsupported compression method %d", zip_header.formated.method); + } + + /* Read filename */ +- archive_handle->file_header->name = xmalloc(zip_header.formated.filename_len + 1); +- archive_xread_all(archive_handle, archive_handle->file_header->name, zip_header.formated.filename_len); +- archive_handle->offset += zip_header.formated.filename_len; +- archive_handle->file_header->name[zip_header.formated.filename_len] = '\0'; +- +- /* Skip extra header bits */ +- archive_handle->file_header->size = zip_header.formated.extra_len; +- data_skip(archive_handle); +- archive_handle->offset += zip_header.formated.extra_len; +- +- /* Handle directories */ +- archive_handle->file_header->mode = S_IFREG | 0777; +- if (last_char_is(archive_handle->file_header->name, '/')) { +- archive_handle->file_header->mode ^= S_IFREG; +- archive_handle->file_header->mode |= S_IFDIR; +- } +- +- /* Data section */ +- archive_handle->file_header->size = zip_header.formated.cmpsize; +- if (archive_handle->action_data) { +- archive_handle->action_data(archive_handle); +- } else { +- dst_fd = bb_xopen(archive_handle->file_header->name, O_WRONLY | O_CREAT); +- inflate_init(zip_header.formated.cmpsize); +- inflate_unzip(archive_handle->src_fd, dst_fd); +- close(dst_fd); +- chmod(archive_handle->file_header->name, archive_handle->file_header->mode); +- +- /* Validate decompression - crc */ +- if (zip_header.formated.crc32 != (gunzip_crc ^ 0xffffffffL)) { +- bb_error_msg("Invalid compressed data--crc error"); +- } +- +- /* Validate decompression - size */ +- if (gunzip_bytes_out != zip_header.formated.ucmpsize) { +- bb_error_msg("Invalid compressed data--length error"); +- } ++ free(dst_fn); ++ dst_fn = xmalloc(zip_header.formated.filename_len + 1); ++ unzip_read(src_fd, dst_fn, zip_header.formated.filename_len); ++ dst_fn[zip_header.formated.filename_len] = 0; ++ ++ /* Skip extra header bytes */ ++ unzip_skip(src_fd, zip_header.formated.extra_len); ++ ++ if ((verbosity == v_list) && !list_header_done){ ++ printf(" Length Date Time Name\n"); ++ printf(" -------- ---- ---- ----\n"); ++ list_header_done = 1; + } + +- /* local file descriptor section */ +- archive_handle->offset += zip_header.formated.cmpsize; +- /* This ISNT unix time */ +- archive_handle->file_header->mtime = zip_header.formated.modtime | (zip_header.formated.moddate << 16); +- archive_handle->file_header->size = zip_header.formated.ucmpsize; +- total_size += archive_handle->file_header->size; +- total_entries++; ++ /* Filter zip entries */ ++ if (find_list_entry(reject, dst_fn) || ++ (accept && !find_list_entry(accept, dst_fn))) { /* Skip entry */ ++ i = 'n'; ++ ++ } else { /* Extract entry */ ++ total_size += zip_header.formated.ucmpsize; ++ ++ if (verbosity == v_list) { /* List entry */ ++ unsigned int dostime = zip_header.formated.modtime | (zip_header.formated.moddate << 16); ++ printf("%9u %02u-%02u-%02u %02u:%02u %s\n", ++ zip_header.formated.ucmpsize, ++ (dostime & 0x01e00000) >> 21, ++ (dostime & 0x001f0000) >> 16, ++ (((dostime & 0xfe000000) >> 25) + 1980) % 100, ++ (dostime & 0x0000f800) >> 11, ++ (dostime & 0x000007e0) >> 5, ++ dst_fn); ++ total_entries++; ++ i = 'n'; ++ ++ } else if (dst_fd == STDOUT_FILENO) { /* Extracting to STDOUT */ ++ i = -1; ++ ++ } else if (last_char_is(dst_fn, '/')) { /* Extract directory */ ++ if (stat(dst_fn, &stat_buf) == -1) { ++ if (errno != ENOENT) { ++ bb_perror_msg_and_die("Cannot stat '%s'",dst_fn); ++ } ++ if (verbosity == v_normal) { ++ printf(" creating: %s\n", dst_fn); ++ } ++ unzip_create_leading_dirs(dst_fn); ++ if (bb_make_directory(dst_fn, 0777, 0)) { ++ bb_error_msg_and_die("Failed to create directory"); ++ } ++ } else { ++ if (!S_ISDIR(stat_buf.st_mode)) { ++ bb_error_msg_and_die("'%s' exists but is not directory", dst_fn); ++ } ++ } ++ i = 'n'; ++ ++ } else { /* Extract file */ ++ _check_file: ++ if (stat(dst_fn, &stat_buf) == -1) { /* File does not exist */ ++ if (errno != ENOENT) { ++ bb_perror_msg_and_die("Cannot stat '%s'",dst_fn); ++ } ++ i = 'y'; ++ ++ } else { /* File already exists */ ++ if (overwrite == o_never) { ++ i = 'n'; ++ ++ } else if (S_ISREG(stat_buf.st_mode)) { /* File is regular file */ ++ if (overwrite == o_always) { ++ i = 'y'; ++ } else { ++ printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn); ++ if (!fgets(key_buf, 512, stdin)) { ++ bb_perror_msg_and_die("Cannot read input"); ++ } ++ i = key_buf[0]; ++ } ++ ++ } else { /* File is not regular file */ ++ bb_error_msg_and_die("'%s' exists but is not regular file",dst_fn); ++ } ++ } ++ } ++ } + +- archive_handle->action_header(archive_handle->file_header); ++ switch (i) { ++ case 'A': ++ overwrite = o_always; ++ case 'y': /* Open file and fall into unzip */ ++ unzip_create_leading_dirs(dst_fn); ++ dst_fd = bb_xopen(dst_fn, O_WRONLY | O_CREAT); ++ case -1: /* Unzip */ ++ if (verbosity == v_normal) { ++ printf(" inflating: %s\n", dst_fn); ++ } ++ unzip_extract(&zip_header, src_fd, dst_fd); ++ if (dst_fd != STDOUT_FILENO) { ++ /* closing STDOUT is potentially bad for future business */ ++ close(dst_fd); ++ } ++ break; + ++ case 'N': ++ overwrite = o_never; ++ case 'n': ++ /* Skip entry data */ ++ unzip_skip(src_fd, zip_header.formated.cmpsize); ++ break; ++ ++ case 'r': ++ /* Prompt for new name */ ++ printf("new name: "); ++ if (!fgets(key_buf, 512, stdin)) { ++ bb_perror_msg_and_die("Cannot read input"); ++ } ++ free(dst_fn); ++ dst_fn = bb_xstrdup(key_buf); ++ chomp(dst_fn); ++ goto _check_file; ++ ++ default: ++ printf("error: invalid response [%c]\n",(char)i); ++ goto _check_file; ++ } ++ + /* Data descriptor section */ + if (zip_header.formated.flags & 4) { + /* skip over duplicate crc, compressed size and uncompressed size */ +- unsigned char data_description[12]; +- archive_xread_all(archive_handle, data_description, 12); +- archive_handle->offset += 12; ++ unzip_skip(src_fd, 12); + } + } +- /* Central directory section */ + +- if (archive_handle->action_header == header_verbose_list_unzip) { ++ if (verbosity == v_list) { + printf(" -------- -------\n"); + printf("%9d %d files\n", total_size, total_entries); + } +- ++ + return(EXIT_SUCCESS); + } ++ ++/* END CODE */ ++/* ++Local Variables: ++c-file-style: "linux" ++c-basic-offset: 4 ++tab-width: 4 ++End: ++*/ +Index: archival/libunarchive/decompress_unzip.c +=================================================================== +RCS file: /var/cvs/busybox/archival/libunarchive/decompress_unzip.c,v +retrieving revision 1.35 +diff -u -r1.35 decompress_unzip.c +--- archival/libunarchive/decompress_unzip.c 25 Apr 2004 05:11:13 -0000 1.35 ++++ archival/libunarchive/decompress_unzip.c 18 Oct 2004 01:32:29 -0000 +@@ -16,6 +16,11 @@ + * + * read_gz interface + associated hacking by Laurence Anderson + * ++ * Fixed huft_build() so decoding end-of-block code does not grab more bits ++ * than necessary (this is required by unzip applet), added inflate_cleanup() ++ * to free leaked bytebuffer memory (used in unzip.c), and some minor style ++ * guide cleanups by Ed Clark ++ * + * 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 +@@ -116,26 +121,26 @@ + /* Copy lengths for literal codes 257..285 */ + static const unsigned short cplens[] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, +- 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 ++ 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 + }; + + /* note: see note #13 above about the 258 in this list. */ + /* Extra bits for literal codes 257..285 */ + static const unsigned char cplext[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, +- 5, 5, 5, 0, 99, 99 ++ 5, 5, 5, 0, 99, 99 + }; /* 99==invalid */ + + /* Copy offsets for distance codes 0..29 */ + static const unsigned short cpdist[] = { + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, +- 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ++ 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 + }; + + /* Extra bits for distance codes */ + static const unsigned char cpdext[] = { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, +- 11, 11, 12, 12, 13, 13 ++ 11, 11, 12, 12, 13, 13 + }; + + /* Tables for deflate from PKZIP's appnote.txt. */ +@@ -184,8 +189,8 @@ + table_entry = (table_entry >> 1) ^ poly; + } else { + table_entry >>= 1; +- } +- } ++ } ++ } + gunzip_crc_table[i] = table_entry; + } + } +@@ -225,70 +230,59 @@ + * t: result: starting table + * m: maximum lookup bits, returns actual + */ +-static int huft_build(unsigned int *b, const unsigned int n, +- const unsigned int s, const unsigned short *d, +- const unsigned char *e, huft_t ** t, int *m) ++int huft_build(unsigned int *b, const unsigned int n, ++ const unsigned int s, const unsigned short *d, ++ const unsigned char *e, huft_t ** t, int *m) + { +- unsigned a; /* counter for codes of length k */ ++ unsigned a; /* counter for codes of length k */ + unsigned c[BMAX + 1]; /* bit length count table */ +- unsigned f; /* i repeats in table every f entries */ +- int g; /* maximum code length */ +- int h; /* table level */ ++ unsigned eob_len; /* length of end-of-block code (value 256) */ ++ unsigned f; /* i repeats in table every f entries */ ++ int g; /* maximum code length */ ++ int h; /* table level */ + register unsigned i; /* counter, current code */ + register unsigned j; /* counter */ +- register int k; /* number of bits in current code */ +- int l; /* bits per table (returned in m) */ ++ register int k; /* number of bits in current code */ + register unsigned *p; /* pointer into c[], b[], or v[] */ +- register huft_t *q; /* points to current table */ +- huft_t r; /* table entry for structure assignment */ +- huft_t *u[BMAX]; /* table stack */ +- unsigned v[N_MAX]; /* values in order of bit length */ +- register int w; /* bits before this table == (l * h) */ ++ register huft_t *q; /* points to current table */ ++ huft_t r; /* table entry for structure assignment */ ++ huft_t *u[BMAX]; /* table stack */ ++ unsigned v[N_MAX]; /* values in order of bit length */ ++ int ws[BMAX+1]; /* bits decoded stack */ ++ register int w; /* bits decoded */ + unsigned x[BMAX + 1]; /* bit offsets, then code stack */ +- unsigned *xp; /* pointer into x */ +- int y; /* number of dummy codes added */ +- unsigned z; /* number of entries in current table */ ++ unsigned *xp; /* pointer into x */ ++ int y; /* number of dummy codes added */ ++ unsigned z; /* number of entries in current table */ ++ ++ /* Length of EOB code, if any */ ++ eob_len = n > 256 ? b[256] : BMAX; + + /* Generate counts for each bit length */ +- memset((void *) (c), 0, sizeof(c)); ++ memset((void *)c, 0, sizeof(c)); + p = b; + i = n; + do { +- c[*p]++; /* assume all entries <= BMAX */ +- p++; /* Can't combine with above line (Solaris bug) */ ++ c[*p]++; /* assume all entries <= BMAX */ ++ p++; /* Can't combine with above line (Solaris bug) */ + } while (--i); +- if (c[0] == n) { /* null input--all zero length codes */ ++ if (c[0] == n) { /* null input--all zero length codes */ + *t = (huft_t *) NULL; + *m = 0; + return 0; + } + + /* Find minimum and maximum length, bound *m by those */ +- l = *m; +- for (j = 1; j <= BMAX; j++) { +- if (c[j]) { +- break; +- } +- } +- k = j; /* minimum code length */ +- if ((unsigned) l < j) { +- l = j; +- } +- for (i = BMAX; i; i--) { +- if (c[i]) { +- break; +- } +- } +- g = i; /* maximum code length */ +- if ((unsigned) l > i) { +- l = i; +- } +- *m = l; ++ for (j = 1; (c[j] == 0) && (j <= BMAX); j++); ++ k = j; /* minimum code length */ ++ for (i = BMAX; (c[i] == 0) && i; i--); ++ g = i; /* maximum code length */ ++ *m = (*m < j) ? j : ((*m > i) ? i : *m); + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) { + if ((y -= c[j]) < 0) { +- return 2; /* bad input: more codes than bits */ ++ return 2; /* bad input: more codes than bits */ + } + } + if ((y -= c[i]) < 0) { +@@ -300,7 +294,7 @@ + x[1] = j = 0; + p = c + 1; + xp = x + 2; +- while (--i) { /* note that i == g from above */ ++ while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + +@@ -314,13 +308,13 @@ + } while (++i < n); + + /* Generate the Huffman codes and for each, make the table entries */ +- x[0] = i = 0; /* first Huffman code is zero */ +- p = v; /* grab values in bit order */ +- h = -1; /* no tables yet--level -1 */ +- w = -l; /* bits decoded == (l * h) */ ++ x[0] = i = 0; /* first Huffman code is zero */ ++ p = v; /* grab values in bit order */ ++ h = -1; /* no tables yet--level -1 */ ++ w = ws[0] = 0; /* bits decoded */ + u[0] = (huft_t *) NULL; /* just to keep compilers happy */ + q = (huft_t *) NULL; /* ditto */ +- z = 0; /* ditto */ ++ z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) { +@@ -328,52 +322,52 @@ + while (a--) { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ +- while (k > w + l) { +- h++; +- w += l; /* previous table always l bits */ +- +- /* compute minimum size table less than or equal to l bits */ +- z = (z = g - w) > (unsigned) l ? l : z; /* upper limit on table size */ +- if ((f = 1 << (j = k - w)) > a + 1) { /* try a k-w bit table *//* too few codes for k-w bit table */ +- f -= a + 1; /* deduct codes from patterns left */ ++ while (k > ws[h + 1]) { ++ w = ws[++h]; ++ ++ /* compute minimum size table less than or equal to *m bits */ ++ z = (z = g - w) > *m ? *m : z; /* upper limit on table size */ ++ if ((f = 1 << (j = k - w)) > a + 1) { /* try a k-w bit table */ ++ /* too few codes for k-w bit table */ ++ f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; +- while (++j < z) { /* try smaller tables up to z bits */ ++ while (++j < z) { /* try smaller tables up to z bits */ + if ((f <<= 1) <= *++xp) { +- break; /* enough codes to use up j bits */ ++ break; /* enough codes to use up j bits */ + } +- f -= *xp; /* else deduct codes from patterns */ ++ f -= *xp; /* else deduct codes from patterns */ + } + } ++ j = (w + j > eob_len && w < eob_len) ? eob_len - w : j; /* make EOB code end at table */ + z = 1 << j; /* table entries for j-bit table */ ++ ws[h+1] = w + j; /* set bits decoded in stack */ + + /* allocate and link in new table */ + q = (huft_t *) xmalloc((z + 1) * sizeof(huft_t)); +- + *t = q + 1; /* link to list for huft_free() */ + *(t = &(q->v.t)) = NULL; + u[h] = ++q; /* table starts after link */ + + /* connect to last table, if there is one */ + if (h) { +- x[h] = i; /* save pattern for backing up */ +- r.b = (unsigned char) l; /* bits to dump before this table */ +- r.e = (unsigned char) (16 + j); /* bits in this table */ +- r.v.t = q; /* pointer to this table */ +- j = i >> (w - l); /* (get around Turbo C bug) */ +- u[h - 1][j] = r; /* connect to last table */ ++ x[h] = i; /* save pattern for backing up */ ++ r.b = (unsigned char) (w - ws[h - 1]); /* bits to dump before this table */ ++ r.e = (unsigned char) (16 + j); /* bits in this table */ ++ r.v.t = q; /* pointer to this table */ ++ j = (i & ((1 << w) - 1)) >> ws[h - 1]; ++ u[h - 1][j] = r; /* connect to last table */ + } + } +- ++ + /* set up table entry in r */ + r.b = (unsigned char) (k - w); + if (p >= v + n) { +- r.e = 99; /* out of values--invalid code */ ++ r.e = 99; /* out of values--invalid code */ + } else if (*p < s) { +- r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is end-of-block code */ +- r.v.n = (unsigned short) (*p); /* simple code is just the value */ +- p++; /* one compiler does not like *p++ */ ++ r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */ ++ r.v.n = (unsigned short) (*p++); /* simple code is just the value */ + } else { +- r.e = (unsigned char) e[*p - s]; /* non-simple--look up in lists */ ++ r.e = (unsigned char) e[*p - s]; /* non-simple--look up in lists */ + r.v.n = d[*p++ - s]; + } + +@@ -391,11 +385,14 @@ + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != x[h]) { +- h--; /* don't need to update q */ +- w -= l; ++ w = ws[--h]; + } + } + } ++ ++ /* return actual size of base table */ ++ *m = ws[1]; ++ + /* Return true (1) if we were given an incomplete table */ + return y != 0 && g != 1; + } +@@ -901,6 +898,11 @@ + bytebuffer_size = 0; + } + ++extern void inflate_cleanup(void) ++{ ++ free(bytebuffer); ++} ++ + extern int inflate_unzip(int in, int out) + { + ssize_t nwrote; +Index: include/unarchive.h +=================================================================== +RCS file: /var/cvs/busybox/include/unarchive.h,v +retrieving revision 1.23 +diff -u -r1.23 unarchive.h +--- include/unarchive.h 15 Mar 2004 08:28:38 -0000 1.23 ++++ include/unarchive.h 18 Oct 2004 01:32:30 -0000 +@@ -98,6 +98,7 @@ + + extern int uncompressStream(int src_fd, int dst_fd); + extern void inflate_init(unsigned int bufsize); ++extern void inflate_cleanup(void); + extern int inflate_unzip(int in, int out); + extern int inflate_gunzip(int in, int out); + +_________________________________________________________________ +Express yourself instantly with MSN Messenger! Download today it's FREE! +http://messenger.msn.com/ + + +--===============0046497949== +Content-Type: text/plain; charset="iso-8859-1" +MIME-Version: 1.0 +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline + +_______________________________________________ +busybox mailing list +busybox@mail.busybox.net +http://codepoet.org/mailman/listinfo/busybox + +--===============0046497949==-- diff --git a/packages/busybox/busybox_1.00.bb b/packages/busybox/busybox_1.00.bb index c0f7c87a6b..743cab0c27 100644 --- a/packages/busybox/busybox_1.00.bb +++ b/packages/busybox/busybox_1.00.bb @@ -10,7 +10,7 @@ HOMEPAGE = "http://www.busybox.net" LICENSE = "GPL" SECTION = "base" PRIORITY = "required" -PR = "r32" +PR = "r37" SRC_URI = "http://www.busybox.net/downloads/busybox-${PV}.tar.gz \ file://add-getkey-applet.patch;patch=1 \ @@ -22,6 +22,7 @@ SRC_URI = "http://www.busybox.net/downloads/busybox-${PV}.tar.gz \ file://readlink.patch;patch=1 \ file://iproute-flush-cache.patch;patch=1;pnum=0 \ file://rmmod.patch;patch=1 \ + file://df.patch;patch=1 \ file://below.patch;patch=1 \ file://fbset.patch;patch=1 \ file://mount-all-type.patch;patch=1 \ @@ -29,6 +30,9 @@ SRC_URI = "http://www.busybox.net/downloads/busybox-${PV}.tar.gz \ file://gzip-spurious-const.patch;patch=1 \ file://ifupdown-spurious-environ.patch;patch=1 \ file://uclibc_posix.patch;patch=1 \ + file://unzip-enhancement-and-fixes.patch;patch=1;pnum=0 \ + file://unzip-endian-fixes.patch;patch=1;pnum=0 \ + file://start-stop-daemon-oknodo-support.patch;patch=1 \ file://defconfig \ file://busybox-cron \ file://busybox-httpd \ @@ -146,6 +150,7 @@ pkg_prerm_${PN} () { # providing its files, this will make update-alternatives work, but the update-rc.d part # for syslog, httpd and/or udhcpd will fail if there is no other package providing sh tmpdir=`mktemp -d /tmp/busyboxrm-XXXXXX` + cp -a /bin/busybox $tmpdir/ ln -s /bin/busybox $tmpdir/[ ln -s /bin/busybox $tmpdir/test ln -s /bin/busybox $tmpdir/head -- cgit v1.2.3 From c96b9162381e8ee422db24ac641dcaecf0367813 Mon Sep 17 00:00:00 2001 From: Erik Hovland Date: Fri, 1 Sep 2006 18:27:21 +0000 Subject: familiar unstable: Peg glibc and busybox h3600 unstable: Peg handhelds-sa kernel version to hh42 --- conf/distro/familiar-unstable.conf | 6 ++++++ conf/machine/h3600.conf | 1 + 2 files changed, 7 insertions(+) diff --git a/conf/distro/familiar-unstable.conf b/conf/distro/familiar-unstable.conf index 6ae4e9ddc3..010d3b4708 100644 --- a/conf/distro/familiar-unstable.conf +++ b/conf/distro/familiar-unstable.conf @@ -55,6 +55,12 @@ PREFERRED_VERSION_binutils ?= "2.15.94.0.1" PREFERRED_PROVIDER_hostap-conf = "hostap-conf" PREFERRED_PROVIDER_task-bootstrap = "task-bootstrap" require conf/distro/include/sane-srcdates.inc +PREFERRED_VERSION_busybox ?= "1.00" + +# +# GlibC +# +PREFERRED_VERSION_glibc ?= "2.3.5+cvs20050627" # # Opie diff --git a/conf/machine/h3600.conf b/conf/machine/h3600.conf index 0261a84d64..5c7440403b 100644 --- a/conf/machine/h3600.conf +++ b/conf/machine/h3600.conf @@ -6,6 +6,7 @@ TARGET_ARCH = "arm" IPKG_EXTRA_ARCHS = "ipaqsa" PREFERRED_PROVIDER_xserver = "xserver-kdrive" PREFERRED_PROVIDER_virtual/kernel = "handhelds-sa" +PREFERRED_VERSION_handhelds-sa ?= "2.4.19-rmk6-pxa1-hh42" EXTRA_IMAGECMD_h3600_jffs2 = "-e 0x40000 -p" BOOTSTRAP_EXTRA_RDEPENDS = "alsa-driver kernel ipaq-boot-params ${@linux_module_packages('${H3600_MODULES}', d)}" -- cgit v1.2.3 From b7d82774dfae26fa96f9163fc3475ead917eecba Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 1 Sep 2006 21:13:37 +0000 Subject: hh-pxa 2.6.16hh6: add it --- packages/linux/handhelds-pxa-2.6_2.6.16-hh6.bb | 69 ++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 packages/linux/handhelds-pxa-2.6_2.6.16-hh6.bb diff --git a/packages/linux/handhelds-pxa-2.6_2.6.16-hh6.bb b/packages/linux/handhelds-pxa-2.6_2.6.16-hh6.bb new file mode 100644 index 0000000000..e8048ae641 --- /dev/null +++ b/packages/linux/handhelds-pxa-2.6_2.6.16-hh6.bb @@ -0,0 +1,69 @@ +SECTION = "kernel" +DESCRIPTION = "handhelds.org Linux kernel for PXA based devices." +LICENSE = "GPL" + +COMPATIBLE_HOST = "arm.*-linux" +COMPATIBLE_MACHINE = '(h3900|h2200|h4000|h5xxx|htcuniversal|ipaq-pxa270)' + +FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/handhelds-pxa-${PV}" + +SRC_URI = "${HANDHELDS_CVS};module=linux/kernel26;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \ + file://24-hostap_cs_id.diff;patch=1 \ + file://hrw-pcmcia-ids-r2.patch;patch=1 \ + file://defconfig" + +S = "${WORKDIR}/kernel26" + +inherit kernel + +FILES_kernel-image_ipaq-pxa270 = "" +ALLOW_EMPTY_ipaq_pxa270 = 1 +FILES_kernel-image_htcuniversal = "" +ALLOW_EMPTY_htcuniversal = 1 + + + +K_MAJOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[0]}" +K_MINOR = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[1]}" +K_MICRO = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[2]}" +HHV = "${@bb.data.getVar('PV',d,1).split('-')[1].split('hh')[-1]}" + +KERNEL_PRIORITY = "${@'%d' % (int(bb.data.getVar('K_MAJOR',d,1)) * 100000000 + int(bb.data.getVar('K_MINOR',d,1)) * 1000000 + int(bb.data.getVar('K_MICRO',d,1)) * 10000 + float(bb.data.getVar('HHV',d,1)))}" + +do_configure() { + + if [ `grep EXTRAVERSION Makefile | grep hh | awk '{print $3}' | sed s/-hh//` != ${HHV} ]; then + die "-hh version mismatch" + fi + + rm -f ${S}/.config + + if [ ! -e ${WORKDIR}/defconfig ]; then + die "No default configuration for ${MACHINE} available." + fi + + + if [ "${TARGET_OS}" == "linux-gnueabi" ]; then + echo "CONFIG_AEABI=y" >> ${S}/.config + echo "CONFIG_OABI_COMPAT=y" >> ${S}/.config + else + echo "# CONFIG_AEABI is not set" >> ${S}/.config + echo "# CONFIG_OABI_COMPAT is not set" >> ${S}/.config + fi + + sed -e '/CONFIG_AEABI/d' \ + -e '/CONFIG_OABI_COMPAT=/d' \ + '${WORKDIR}/defconfig' >>'${S}/.config' + + yes '' | oe_runmake oldconfig + +} + +do_deploy() { + install -d ${DEPLOY_DIR_IMAGE} + install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${PV}-${MACHINE}-${DATETIME} +} + +do_deploy[dirs] = "${S}" + +addtask deploy before do_build after do_compile -- cgit v1.2.3 From 70d5b55f33a0c6b0e7bfe0af67770f45c8eb3e46 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 1 Sep 2006 21:15:27 +0000 Subject: angstrom: prefer hhpxa 2.6.16hh6 --- conf/distro/angstrom-2007.1.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/distro/angstrom-2007.1.conf b/conf/distro/angstrom-2007.1.conf index 75303d2c5c..859c28b95f 100644 --- a/conf/distro/angstrom-2007.1.conf +++ b/conf/distro/angstrom-2007.1.conf @@ -29,7 +29,7 @@ FEED_URIS += " \ #SRCDATE = "20060630" #SRCDATE_handhelds-pxa-2.6 = "20060622" -PREFERRED_VERSION_handhelds-pxa-2.6 = "2.6.16-hh5" +PREFERRED_VERSION_handhelds-pxa-2.6 = "2.6.16-hh6" SRCDATE_gconf-dbus = "20060719" -- cgit v1.2.3 From d340fede1b3d8514b5d95d453da25b8a06e14c7c Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 1 Sep 2006 21:18:26 +0000 Subject: angstrom: zaprootpw happens automagically now --- conf/distro/angstrom-2007.1.conf | 2 -- 1 file changed, 2 deletions(-) diff --git a/conf/distro/angstrom-2007.1.conf b/conf/distro/angstrom-2007.1.conf index 859c28b95f..9d14345111 100644 --- a/conf/distro/angstrom-2007.1.conf +++ b/conf/distro/angstrom-2007.1.conf @@ -14,8 +14,6 @@ require conf/distro/include/sane-srcdates.inc DISTRO_TYPE = "debug" #DISTRO_TYPE = "release" -#!!!!! DON'T FORGET TO ENABLE ZAPROOTPASSWD !!!!! - FEED_URIS += " \ base##${ANGSTROM_URI}/unstable/feed/base \ -- cgit v1.2.3 From 4cf0e7ef269b8f2be828c0cc30f2fa81cf9d8474 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 1 Sep 2006 21:27:08 +0000 Subject: cairo 1.2.4: libx11 -> virtual/libx11 --- packages/cairo/cairo_1.2.4.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cairo/cairo_1.2.4.bb b/packages/cairo/cairo_1.2.4.bb index bad6da8bde..662f685fb9 100644 --- a/packages/cairo/cairo_1.2.4.bb +++ b/packages/cairo/cairo_1.2.4.bb @@ -1,7 +1,7 @@ SECTION = "libs" PRIORITY = "optional" MAINTAINER = "Phil Blundell " -DEPENDS = "libx11 libpng fontconfig libxrender" +DEPENDS = "virtual/libx11 libpng fontconfig libxrender" DESCRIPTION = "Cairo graphics library" LICENSE = "MPL LGPL" PR = "r1" -- cgit v1.2.3 From e7a5d75f170eaf4eacbaea46176026d0c7ab056f Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 1 Sep 2006 21:28:48 +0000 Subject: angstrom: prefer cairo 1.2.2 --- conf/distro/angstrom-2007.1.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conf/distro/angstrom-2007.1.conf b/conf/distro/angstrom-2007.1.conf index 9d14345111..b7350efec7 100644 --- a/conf/distro/angstrom-2007.1.conf +++ b/conf/distro/angstrom-2007.1.conf @@ -53,6 +53,8 @@ PREFERRED_PROVIDER_dbus-glib = "dbus-glib" PREFERRED_VERSION_fontconfig = "2.3.95" PREFERRED_VERSION_freetype = "2.2.1" +#fix screen corruption issues +PREFERRED_VERSION_cairo = "1.2.2" #Small machines prefer kdrive, but we might ship full Xorg in other images PREFERRED_PROVIDER_virtual/xserver ?= "xserver-kdrive" -- cgit v1.2.3 From 87ae50230b26c98c639327a6beee7bbab4012c4b Mon Sep 17 00:00:00 2001 From: Matt Reimer Date: Fri, 1 Sep 2006 21:29:45 +0000 Subject: gtk+ 2.8.16: Activate all the patches used in previous versions. For some reason several were commented out, but they apply and compile cleanly, so I've re-enabled them. --- packages/gtk+/gtk+_2.8.16.bb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/gtk+/gtk+_2.8.16.bb b/packages/gtk+/gtk+_2.8.16.bb index ef7f20e4ac..d870b0e0b1 100644 --- a/packages/gtk+/gtk+_2.8.16.bb +++ b/packages/gtk+/gtk+_2.8.16.bb @@ -18,14 +18,14 @@ SRC_URI = "ftp://ftp.gtk.org/pub/gtk/v2.8/gtk+-${PV}.tar.bz2 \ file://disable-tooltips.patch;patch=1 \ file://gtklabel-resize-patch;patch=1 \ file://gtktreeview-316689.patch;patch=1 \ -# file://menu-deactivate.patch;patch=1 \ -# file://xsettings.patch;patch=1 \ -# file://scroll-timings.patch;patch=1 \ -# file://small-gtkfilesel.patch;patch=1 \ -# file://migration.patch;patch=1;pnum=0 \ - file://no-demos.patch;patch=1" -# file://gtk+-handhelds.patch;patch=1 \ -# file://single-click.patch;patch=1" + file://menu-deactivate.patch;patch=1 \ + file://xsettings.patch;patch=1 \ + file://scroll-timings.patch;patch=1 \ + file://small-gtkfilesel.patch;patch=1 \ + file://migration.patch;patch=1;pnum=0 \ + file://no-demos.patch;patch=1" \ + file://gtk+-handhelds.patch;patch=1 \ + file://single-click.patch;patch=1" inherit autotools pkgconfig -- cgit v1.2.3 From 890d766f7d6e3c35309d0155e5751e9d76376aa8 Mon Sep 17 00:00:00 2001 From: Matt Reimer Date: Fri, 1 Sep 2006 21:32:31 +0000 Subject: familiar-unstable.conf: Specify a provider for dbus-glib, so it doesn't try to pull in a second, older version of dbus. --- conf/distro/familiar-unstable.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/distro/familiar-unstable.conf b/conf/distro/familiar-unstable.conf index 010d3b4708..8041ca8fb6 100644 --- a/conf/distro/familiar-unstable.conf +++ b/conf/distro/familiar-unstable.conf @@ -78,6 +78,7 @@ require conf/distro/include/preferred-opie-versions.inc PREFERRED_PROVIDERS += "virtual/xserver:xserver-kdrive" PREFERRED_PROVIDERS += "virtual/gconf:gconf-dbus" PREFERRED_PROVIDER_virtual/libx11 = "diet-x11" +PREFERRED_PROVIDER_dbus-glib = "dbus-glib" require conf/distro/include/preferred-gpe-versions-2.8.inc # -- cgit v1.2.3 From 0fd3efb404b5e56a2fb05c25653931b5771f58b3 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 1 Sep 2006 21:44:47 +0000 Subject: gpe-login 0.87: replace highdpi patch with one that just sets a normal theme, since the dpi issues should have been resolved --- packages/gpe-login/files/removeblue-fontsize8.patch | 14 ++++++++++++++ packages/gpe-login/gpe-login_0.87.bb | 9 ++------- 2 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 packages/gpe-login/files/removeblue-fontsize8.patch diff --git a/packages/gpe-login/files/removeblue-fontsize8.patch b/packages/gpe-login/files/removeblue-fontsize8.patch new file mode 100644 index 0000000000..4962c8401f --- /dev/null +++ b/packages/gpe-login/files/removeblue-fontsize8.patch @@ -0,0 +1,14 @@ +--- /tmp/gpe-login.gtkrc 2005-11-08 17:15:50.363302568 +0100 ++++ gpe-login-0.83/X11/gpe-login.gtkrc 2005-11-08 17:16:22.659392816 +0100 +@@ -1,9 +1,2 @@ +-gtk-font-name = "Sans 8" +-include "/usr/share/themes/Angelistic/gtk-2.0/gtkrc" +- +-style "default" +-{ +- bg[NORMAL] = "#90d8ff" +-} +- +-widget "*" style "default" ++gtk-font-name = "Sans 8" ++include "/usr/share/themes/Industrial/gtk-2.0/gtkrc" diff --git a/packages/gpe-login/gpe-login_0.87.bb b/packages/gpe-login/gpe-login_0.87.bb index 5d7f00530c..b548a1ad6b 100644 --- a/packages/gpe-login/gpe-login_0.87.bb +++ b/packages/gpe-login/gpe-login_0.87.bb @@ -7,13 +7,8 @@ PRIORITY = "optional" DEPENDS = "gtk+ libgpewidget gpe-ownerinfo xkbd" RDEPENDS = "xkbd" RPROVIDES = "gpe-session-starter" -PR = "r0" +PR = "r1" -#apply a patch to set the fontsize for bigdpi (200+) devices to 5 -SRC_URI_append_ipaq-pxa270 = " file://highdpifontfix.patch;patch=1" -SRC_URI_append_spitz = " file://highdpifontfix.patch;patch=1" -SRC_URI_append_akita = " file://highdpifontfix.patch;patch=1" -SRC_URI_append_c7x0 = " file://highdpifontfix.patch;patch=1" -SRC_URI_append_nokia770 = " file://highdpifontfix.patch;patch=1" +SRC_URI += "file://removeblue-fontsize8.patch;patch=1" SRC_URI += " file://chvt-keylaunch.patch;patch=1 " -- cgit v1.2.3 From 4c8e71488bf3b15180335d8d3adba6d497ca634f Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 1 Sep 2006 23:00:06 +0000 Subject: angstrom: tslib and/or libxcalibrate is broken in kdrive_git, so use the release for now --- conf/distro/angstrom-2007.1.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/distro/angstrom-2007.1.conf b/conf/distro/angstrom-2007.1.conf index b7350efec7..829d2f23f5 100644 --- a/conf/distro/angstrom-2007.1.conf +++ b/conf/distro/angstrom-2007.1.conf @@ -62,7 +62,7 @@ PREFERRED_PROVIDER_xserver ?= "xserver-kdrive" require conf/distro/include/preferred-xorg-versions-X11R7.1.inc -PREFERRED_VERSION_xserver-kdrive = "1.1.0+git${SRCDATE}" +PREFERRED_VERSION_xserver-kdrive = "X11R7.1-1.1.0" #zap extra stuff taking place in $MACHINE.conf GPE_EXTRA_INSTALL = "" -- cgit v1.2.3 From 6a06d9f694239db1a178f6b36fff7a6fa98f9f8c Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 1 Sep 2006 23:16:04 +0000 Subject: angstrom: hh6 has broken dependencies due to version mismatch, switch back to hh5 --- conf/distro/angstrom-2007.1.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/distro/angstrom-2007.1.conf b/conf/distro/angstrom-2007.1.conf index 829d2f23f5..f3ad52beca 100644 --- a/conf/distro/angstrom-2007.1.conf +++ b/conf/distro/angstrom-2007.1.conf @@ -27,7 +27,7 @@ FEED_URIS += " \ #SRCDATE = "20060630" #SRCDATE_handhelds-pxa-2.6 = "20060622" -PREFERRED_VERSION_handhelds-pxa-2.6 = "2.6.16-hh6" +PREFERRED_VERSION_handhelds-pxa-2.6 = "2.6.16-hh5" SRCDATE_gconf-dbus = "20060719" -- cgit v1.2.3 From 4db47cb621b73ca6b178152846c0d52eb3ce50ca Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Sat, 2 Sep 2006 00:10:57 +0000 Subject: ixp4xx-kernel: Match 2.6.16 defconfig with svn repo --- packages/linux/ixp4xx-kernel/2.6.16/defconfig | 2 +- packages/linux/ixp4xx-kernel_2.6.16.bb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/linux/ixp4xx-kernel/2.6.16/defconfig b/packages/linux/ixp4xx-kernel/2.6.16/defconfig index 441d382c4f..c3b711f9c9 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/defconfig +++ b/packages/linux/ixp4xx-kernel/2.6.16/defconfig @@ -1167,7 +1167,7 @@ CONFIG_VIDEO_CX88_ALSA=m # CONFIG_VIDEO_EM28XX is not set CONFIG_VIDEO_OVCAMCHIP=m CONFIG_VIDEO_AUDIO_DECODER=m -# CONFIG_VIDEO_DECODER is not set +CONFIG_VIDEO_DECODER=m # # Radio Adapters diff --git a/packages/linux/ixp4xx-kernel_2.6.16.bb b/packages/linux/ixp4xx-kernel_2.6.16.bb index b7354755ef..be8855cc57 100644 --- a/packages/linux/ixp4xx-kernel_2.6.16.bb +++ b/packages/linux/ixp4xx-kernel_2.6.16.bb @@ -3,7 +3,7 @@ # Increment PR_CONFIG for changes to the ixp4xx-kernel specific # defconfig (do *NOT* increment anything in here for changes # to other kernel configs!) -PR_CONFIG = "4" +PR_CONFIG = "5" # # Increment the number below (i.e. the digits after PR) when # making changes within this file or for changes to the patches -- cgit v1.2.3 From 07f7ad8d3c04026aad55f1d808e0a9d7769dbce3 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Sat, 2 Sep 2006 00:16:13 +0000 Subject: ixp4xx-kernel: Add YEALINK module --- packages/linux/ixp4xx-kernel/2.6.16/defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/linux/ixp4xx-kernel/2.6.16/defconfig b/packages/linux/ixp4xx-kernel/2.6.16/defconfig index c3b711f9c9..dda2e790b0 100644 --- a/packages/linux/ixp4xx-kernel/2.6.16/defconfig +++ b/packages/linux/ixp4xx-kernel/2.6.16/defconfig @@ -1361,7 +1361,7 @@ CONFIG_USB_KBD=m # CONFIG_USB_MTOUCH is not set # CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set -# CONFIG_USB_YEALINK is not set +CONFIG_USB_YEALINK=m # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set # CONFIG_USB_ATI_REMOTE2 is not set -- cgit v1.2.3 From e5ac50ad59a9b404eabbc287ad0df03a68002405 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Sat, 2 Sep 2006 00:25:45 +0000 Subject: ixp4xx-kernel: bump PR to force rebuild from svn --- packages/linux/ixp4xx-kernel_2.6.17.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/linux/ixp4xx-kernel_2.6.17.bb b/packages/linux/ixp4xx-kernel_2.6.17.bb index 9025cca893..b08129799a 100644 --- a/packages/linux/ixp4xx-kernel_2.6.17.bb +++ b/packages/linux/ixp4xx-kernel_2.6.17.bb @@ -3,7 +3,7 @@ # Increment PR_CONFIG for changes to the ixp4xx-kernel specific # defconfig (do *NOT* increment anything in here for changes # to other kernel configs!) -PR_CONFIG = "2" +PR_CONFIG = "3" # # Increment the number below (i.e. the digits after PR) when # making changes within this file or for changes to the patches -- cgit v1.2.3 From d676aacf9d7461fc140131ad65a6871689e66f38 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sat, 2 Sep 2006 10:19:20 +0000 Subject: xserver-kdrive: w100 accelerated kdrive for people to play with - enable compilation of Xw100 and package it as xserver-kdrive-w100 - thanks to Mardy, RP, sirfred, Spyro and XorA! --- packages/xorg-xserver/xserver-kdrive/w100.patch | 6385 ++++++++++++++++++++ .../xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb | 12 +- packages/xorg-xserver/xserver-kdrive_git.bb | 12 +- 3 files changed, 6401 insertions(+), 8 deletions(-) create mode 100644 packages/xorg-xserver/xserver-kdrive/w100.patch diff --git a/packages/xorg-xserver/xserver-kdrive/w100.patch b/packages/xorg-xserver/xserver-kdrive/w100.patch new file mode 100644 index 0000000000..2ff1639b9a --- /dev/null +++ b/packages/xorg-xserver/xserver-kdrive/w100.patch @@ -0,0 +1,6385 @@ +Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati.c 2006-09-02 11:47:21.000000000 +0200 +@@ -0,0 +1,434 @@ ++/* ++ * Copyright © 2006 Alberto Mardegan ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and its ++ * documentation for any purpose is hereby granted without fee, provided that ++ * the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of Alberto Mardegan not be used in ++ * advertising or publicity pertaining to distribution of the software without ++ * specific, written prior permission. Alberto Mardegan makes no ++ * representations about the suitability of this software for any purpose. It ++ * is provided "as is" without express or implied warranty. ++ * ++ * ALBERTO MARDEGAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO ++ * EVENT SHALL ALBERTO MARDEGAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR ++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, ++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER ++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++#include "ati.h" ++#include "w100_regs.h" ++ ++ ++struct pci_id_entry ati_pci_ids[] = { ++ {0x1002, 0x5644, 0, "ATI Imageon 3200"}, ++ {0x1002, 0x5741, 0, "ATI Imageon 100"}, ++ {0x1002, 0x5744, 0, "ATI Imageon 3220"}, ++ {0, 0, 0, NULL} ++}; ++ ++ ++static Bool ++ATICardInit(KdCardInfo * card) ++{ ++ ATICardInfo *atic; ++ int i; ++ Bool initialized = FALSE; ++ ++ atic = xcalloc(sizeof(ATICardInfo), 1); ++ if (atic == NULL) ++ return FALSE; ++ ++#ifdef KDRIVEFBDEV ++ if (!initialized && fbdevInitialize(card, &atic->backend_priv.fbdev)) { ++ atic->use_fbdev = TRUE; ++ initialized = TRUE; ++ atic->backend_funcs.cardfini = fbdevCardFini; ++ atic->backend_funcs.scrfini = fbdevScreenFini; ++ atic->backend_funcs.initScreen = fbdevInitScreen; ++ atic->backend_funcs.finishInitScreen = fbdevFinishInitScreen; ++ atic->backend_funcs.createRes = fbdevCreateResources; ++ atic->backend_funcs.preserve = fbdevPreserve; ++ atic->backend_funcs.restore = fbdevRestore; ++ atic->backend_funcs.dpms = fbdevDPMS; ++ atic->backend_funcs.enable = fbdevEnable; ++ atic->backend_funcs.disable = fbdevDisable; ++ atic->backend_funcs.getColors = fbdevGetColors; ++ atic->backend_funcs.putColors = fbdevPutColors; ++#ifdef RANDR ++ atic->backend_funcs.randrSetConfig = fbdevRandRSetConfig; ++#endif ++ } ++#endif ++#ifdef KDRIVEVESA ++ if (!initialized && vesaInitialize(card, &atic->backend_priv.vesa)) { ++ atic->use_vesa = TRUE; ++ initialized = TRUE; ++ atic->backend_funcs.cardfini = vesaCardFini; ++ atic->backend_funcs.scrfini = vesaScreenFini; ++ atic->backend_funcs.initScreen = vesaInitScreen; ++ atic->backend_funcs.finishInitScreen = vesaFinishInitScreen; ++ atic->backend_funcs.createRes = vesaCreateResources; ++ atic->backend_funcs.preserve = vesaPreserve; ++ atic->backend_funcs.restore = vesaRestore; ++ atic->backend_funcs.dpms = vesaDPMS; ++ atic->backend_funcs.enable = vesaEnable; ++ atic->backend_funcs.disable = vesaDisable; ++ atic->backend_funcs.getColors = vesaGetColors; ++ atic->backend_funcs.putColors = vesaPutColors; ++#ifdef RANDR ++ atic->backend_funcs.randrSetConfig = vesaRandRSetConfig; ++#endif ++ } ++#endif ++ ++ if (!initialized || !ATIMap(card, atic)) { ++ xfree(atic); ++ return FALSE; ++ } ++ ++ card->driver = atic; ++ ++ for (i = 0; ati_pci_ids[i].name != NULL; i++) { ++ if (ati_pci_ids[i].device == card->attr.deviceID) { ++ atic->pci_id = &ati_pci_ids[i]; ++ break; ++ } ++ } ++ ++ ErrorF("Using ATI card: %s\n", atic->pci_id->name); ++ ++ return TRUE; ++} ++ ++static void ++ATICardFini(KdCardInfo * card) ++{ ++ ATICardInfo *atic = (ATICardInfo *) card->driver; ++ ++ ATIUnmap(card, atic); ++ atic->backend_funcs.cardfini(card); ++} ++ ++/* ++ * Once screen->off_screen_base is set, this function ++ * allocates the remaining memory appropriately ++ */ ++ ++static void ++ATISetOffscreen(KdScreenInfo * screen) ++{ ++ ATICardInfo(screen); ++ int screen_size; ++ char *mmio = atic->reg_base; ++ ++ /* check (and adjust) pitch */ ++ if (mmio) { ++ int byteStride = screen->fb[0].byteStride; ++ int bitStride; ++ int pixelStride; ++ int bpp = screen->fb[0].bitsPerPixel; ++ ++ /* ++ * Ensure frame buffer is correctly aligned ++ */ ++ if (byteStride & 0x3f) { ++ byteStride = (byteStride + 0x3f) & ~0x3f; ++ bitStride = byteStride * 8; ++ pixelStride = bitStride / bpp; ++ ++ screen->fb[0].byteStride = byteStride; ++ screen->fb[0].pixelStride = pixelStride; ++ } ++ } ++ ++ screen_size = screen->fb[0].byteStride * screen->height; ++ ++ screen->off_screen_base = screen_size; ++ ++} ++ ++static Bool ++ATIScreenInit(KdScreenInfo * screen) ++{ ++ ATIScreenInfo *atis; ++ ATICardInfo(screen); ++ Bool success = FALSE; ++ ++ atis = xcalloc(sizeof(ATIScreenInfo), 1); ++ if (atis == NULL) ++ return FALSE; ++ ++ atis->atic = atic; ++ atis->screen = screen; ++ screen->driver = atis; ++ ++ if (screen->fb[0].depth == 0) ++ screen->fb[0].depth = 16; ++#ifdef KDRIVEFBDEV ++ if (atic->use_fbdev) { ++ success = fbdevScreenInitialize(screen, &atis->backend_priv.fbdev); ++ } ++#endif ++#ifdef KDRIVEVESA ++ if (atic->use_vesa) { ++ success = vesaScreenInitialize(screen, &atis->backend_priv.vesa); ++ } ++#endif ++ ++ if (!success) { ++ screen->driver = NULL; ++ xfree(atis); ++ return FALSE; ++ } ++ ++ ErrorF ++ ("Offscreen memory at offset %08x, memory base %08x, size %08x\n", ++ screen->off_screen_base, screen->memory_base, ++ screen->memory_size); ++ ATISetOffscreen(screen); ++ ++ return TRUE; ++} ++ ++#ifdef RANDR ++static Bool ++ATIRandRSetConfig(ScreenPtr pScreen, ++ Rotation randr, int rate, RRScreenSizePtr pSize) ++{ ++ KdScreenPriv(pScreen); ++ KdScreenInfo *screen = pScreenPriv->screen; ++ ATICardInfo *atic = screen->card->driver; ++ Bool ret; ++ ++ ATIDrawDisable(pScreen); ++ ret = atic->backend_funcs.randrSetConfig(pScreen, randr, rate, pSize); ++ ATISetOffscreen(screen); ++ /* ++ * Set frame buffer mapping ++ */ ++ (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap(pScreen), ++ pScreen->width, ++ pScreen->height, ++ screen->fb[0].depth, ++ screen->fb[0].bitsPerPixel, ++ screen->fb[0].byteStride, ++ screen->fb[0].frameBuffer); ++ ++ ATIDrawEnable(pScreen); ++ return ret; ++} ++ ++static Bool ++ATIRandRInit(ScreenPtr pScreen) ++{ ++ rrScrPrivPtr pScrPriv; ++ ++ pScrPriv = rrGetScrPriv(pScreen); ++ pScrPriv->rrSetConfig = ATIRandRSetConfig; ++ return TRUE; ++} ++#endif ++ ++static void ++ATIScreenFini(KdScreenInfo * screen) ++{ ++ ATIScreenInfo *atis = (ATIScreenInfo *) screen->driver; ++ ATICardInfo *atic = screen->card->driver; ++ ++ atic->backend_funcs.scrfini(screen); ++ xfree(atis); ++ screen->driver = 0; ++} ++ ++Bool ++ATIMap(KdCardInfo * card, ATICardInfo * atic) ++{ ++ atic->mem_base = (CARD8 *) KdMapDevice(ATI_MEM_BASE(card), ++ ATI_MEM_SIZE(card)); ++ ++ if (atic->mem_base == NULL) ++ return FALSE; ++ atic->reg_base = atic->mem_base + 0x10000; /* XXX */ ++ ++ KdSetMappedMode(ATI_MEM_BASE(card), ATI_MEM_SIZE(card), ++ KD_MAPPED_MODE_REGISTERS); ++ ++ return TRUE; ++} ++ ++void ++ATIUnmap(KdCardInfo * card, ATICardInfo * atic) ++{ ++ if (atic->reg_base) { ++ KdResetMappedMode(ATI_REG_BASE(card), ATI_REG_SIZE(card), ++ KD_MAPPED_MODE_REGISTERS); ++ KdUnmapDevice((void *) atic->reg_base, ATI_REG_SIZE(card)); ++ atic->reg_base = 0; ++ } ++} ++ ++static Bool ++ATIInitScreen(ScreenPtr pScreen) ++{ ++ KdScreenPriv(pScreen); ++ ATICardInfo(pScreenPriv); ++ ++ return atic->backend_funcs.initScreen(pScreen); ++} ++ ++static Bool ++ATIFinishInitScreen(ScreenPtr pScreen) ++{ ++ KdScreenPriv(pScreen); ++ ATICardInfo(pScreenPriv); ++ ++ if (!atic->backend_funcs.finishInitScreen(pScreen)) ++ return FALSE; ++#ifdef RANDR ++ if (!ATIRandRInit(pScreen)) ++ return FALSE; ++#endif ++ return TRUE; ++} ++ ++static Bool ++ATICreateResources(ScreenPtr pScreen) ++{ ++ KdScreenPriv(pScreen); ++ ATICardInfo(pScreenPriv); ++ ++ return atic->backend_funcs.createRes(pScreen); ++} ++ ++static void ++ATIPreserve(KdCardInfo * card) ++{ ++ ATICardInfo *atic = card->driver; ++ ++ atic->backend_funcs.preserve(card); ++} ++ ++static void ++ATIRestore(KdCardInfo * card) ++{ ++ ATICardInfo *atic = card->driver; ++ ++ ATIUnmap(card, atic); ++ ++ atic->backend_funcs.restore(card); ++} ++ ++static Bool ++ATIDPMS(ScreenPtr pScreen, int mode) ++{ ++ KdScreenPriv(pScreen); ++ ATICardInfo(pScreenPriv); ++ ++ return atic->backend_funcs.dpms(pScreen, mode); ++} ++ ++static Bool ++ATIEnable(ScreenPtr pScreen) ++{ ++ KdScreenPriv(pScreen); ++ ATICardInfo(pScreenPriv); ++ mc_ext_mem_location_u eml; ++ char *mmio; ++ ++ if (!atic->backend_funcs.enable(pScreen)) ++ return FALSE; ++ ++ if ((atic->reg_base == NULL) ++ && !ATIMap(pScreenPriv->screen->card, atic)) ++ return FALSE; ++ ++ mmio = atic->reg_base; ++ eml.val = MMIO_IN32(mmio, mmMC_EXT_MEM_LOCATION); ++ atic->ext_mem_location = eml.f.mc_ext_mem_start << 8; ++ ATISetOffscreen(pScreenPriv->screen); ++ ++ return TRUE; ++} ++ ++static void ++ATIDisable(ScreenPtr pScreen) ++{ ++ KdScreenPriv(pScreen); ++ ATICardInfo(pScreenPriv); ++ ++ ATIUnmap(pScreenPriv->card, atic); ++ ++ atic->backend_funcs.disable(pScreen); ++} ++ ++static void ++ATIGetColors(ScreenPtr pScreen, int fb, int n, xColorItem * pdefs) ++{ ++ KdScreenPriv(pScreen); ++ ATICardInfo(pScreenPriv); ++ ++ atic->backend_funcs.getColors(pScreen, fb, n, pdefs); ++} ++ ++static void ++ATIPutColors(ScreenPtr pScreen, int fb, int n, xColorItem * pdefs) ++{ ++ KdScreenPriv(pScreen); ++ ATICardInfo(pScreenPriv); ++ ++ atic->backend_funcs.putColors(pScreen, fb, n, pdefs); ++} ++ ++/* Compute log base 2 of val. */ ++int ++ATILog2(int val) ++{ ++ int bits; ++ ++ for (bits = 0; val != 0; val >>= 1, ++bits); ++ return bits - 1; ++} ++ ++ ++ ++KdCardFuncs ATIFuncs = { ++ ATICardInit, /* cardinit */ ++ ATIScreenInit, /* scrinit */ ++ ATIInitScreen, /* initScreen */ ++ ATIFinishInitScreen, /* finishInitScreen */ ++ ATICreateResources, /* createRes */ ++ ATIPreserve, /* preserve */ ++ ATIEnable, /* enable */ ++ ATIDPMS, /* dpms */ ++ ATIDisable, /* disable */ ++ ATIRestore, /* restore */ ++ ATIScreenFini, /* scrfini */ ++ ATICardFini, /* cardfini */ ++ ++#define ATICursorInit 0 ++#define ATICursorEnable 0 ++#define ATICursorDisable 0 ++#define ATICursorFini 0 ++#define ATIRecolorCursor 0 ++ ATICursorInit, /* initCursor */ ++ ATICursorEnable, /* enableCursor */ ++ ATICursorDisable, /* disableCursor */ ++ ATICursorFini, /* finiCursor */ ++ ATIRecolorCursor, /* recolorCursor */ ++ ++ ATIDrawInit, /* initAccel */ ++ ATIDrawEnable, /* enableAccel */ ++ ATIDrawDisable, /* disableAccel */ ++ ATIDrawFini, /* finiAccel */ ++ ++ ATIGetColors, /* getColors */ ++ ATIPutColors, /* putColors */ ++}; +Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_cursor.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_cursor.c 2006-09-02 11:47:21.000000000 +0200 +@@ -0,0 +1,93 @@ ++/* ++ * Copyright © 2006 Alberto Mardegan ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and its ++ * documentation for any purpose is hereby granted without fee, provided that ++ * the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of Alberto Mardegan not be used in ++ * advertising or publicity pertaining to distribution of the software without ++ * specific, written prior permission. Alberto Mardegan makes no ++ * representations about the suitability of this software for any purpose. It ++ * is provided "as is" without express or implied warranty. ++ * ++ * ALBERTO MARDEGAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO ++ * EVENT SHALL ALBERTO MARDEGAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR ++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, ++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER ++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++#include "ati.h" ++#include "cursorstr.h" ++#include "ati_draw.h" ++ ++static void ++ATIMoveCursor(ScreenPtr pScreen, int x, int y) ++{ ++} ++ ++ ++static Bool ++ATIRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) ++{ ++ return FALSE; ++} ++ ++ ++static Bool ++ATIUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) ++{ ++ return TRUE; ++} ++ ++ ++static void ++ATISetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y) ++{ ++} ++ ++ ++miPointerSpriteFuncRec ATIPointerSpriteFuncs = { ++ ATIRealizeCursor, ++ ATIUnrealizeCursor, ++ ATISetCursor, ++ ATIMoveCursor, ++}; ++ ++ ++void ++ATICursorEnable(ScreenPtr pScreen) ++{ ++} ++ ++ ++void ++ATICursorDisable(ScreenPtr pScreen) ++{ ++} ++ ++ ++Bool ++ATICursorInit(ScreenPtr pScreen) ++{ ++ return FALSE; ++} ++ ++ ++void ++ATIRecolorCursor(ScreenPtr pScreen, int ndef, xColorItem * pdef) ++{ ++ return; ++} ++ ++ ++void ++ATICursorFini(ScreenPtr pScreen) ++{ ++} +Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_dma.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_dma.c 2006-09-02 11:47:21.000000000 +0200 +@@ -0,0 +1,333 @@ ++/* ++ * Copyright © 2006 Alberto Mardegan ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and its ++ * documentation for any purpose is hereby granted without fee, provided that ++ * the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of Alberto Mardegan not be used in ++ * advertising or publicity pertaining to distribution of the software without ++ * specific, written prior permission. Alberto Mardegan makes no ++ * representations about the suitability of this software for any purpose. It ++ * is provided "as is" without express or implied warranty. ++ * ++ * ALBERTO MARDEGAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO ++ * EVENT SHALL ALBERTO MARDEGAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR ++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, ++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER ++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include ++ ++#include "ati.h" ++#include "w100_regs.h" ++#include "w100_const.h" ++#include "ati_dma.h" ++#include "ati_draw.h" ++ ++ ++#define DEBUG_FIFO 0 ++ ++extern CARD32 w100_microcode[][2]; ++ ++#if DEBUG_FIFO ++static void ++ATIDebugFifo(ATIScreenInfo * atis) ++{ ++ ATICardInfo *atic = atis->atic; ++ char *mmio = atic->reg_base; ++ ++ ErrorF("mmCP_CSQ_CNTL: 0x%08x\n", MMIO_IN32(mmio, mmCP_CSQ_CNTL)); ++ ErrorF("mmCP_CSQ_STAT: 0x%08x\n", MMIO_IN32(mmio, mmCP_CSQ_STAT)); ++ ErrorF("mmRBBM_STATUS: 0x%08x\n", MMIO_IN32(mmio, mmRBBM_STATUS)); ++} ++#endif ++ ++static void ++ATIUploadMicrocode(ATIScreenInfo * atis) ++{ ++ ATICardInfo *atic = atis->atic; ++ char *mmio = atic->reg_base; ++ int i; ++ ++ MMIO_OUT32(mmio, mmCP_ME_RAM_ADDR, 0); ++ for (i = 0; i < 256; i++) { ++ MMIO_OUT32(mmio, mmCP_ME_RAM_DATAH, w100_microcode[i][1]); ++ MMIO_OUT32(mmio, mmCP_ME_RAM_DATAL, w100_microcode[i][0]); ++ } ++} ++ ++/* Required when reading from video memory after acceleration to make sure all ++ * data has been flushed to video memory from the pixel cache. ++ */ ++static void ++ATIFlushPixelCache(ATIScreenInfo * atis) ++{ ++ ATICardInfo *atic = atis->atic; ++ char *mmio = atic->reg_base; ++ rbbm_status_u rs; ++ TIMEOUT_LOCALS; ++ ++ WHILE_NOT_TIMEOUT(.2) { ++ rs.val = MMIO_IN32(mmio, mmRBBM_STATUS); ++ if (!rs.f.gui_active) ++ break; ++ } ++ if (TIMEDOUT()) ++ ErrorF("Timeout flushing pixel cache.\n"); ++} ++ ++static void ++ATIEngineReset(ATIScreenInfo * atis) ++{ ++ ATICardInfo *atic = atis->atic; ++ char *mmio = atic->reg_base; ++ CARD32 sclk_cntl; ++ sclk_cntl_u sc; ++ rbbm_soft_reset_u rsr; ++ ++#if DEBUG_FIFO ++ ErrorF("Engine Reset!\n"); ++ ATIDebugFifo(atis); ++#endif ++ ++ ATIFlushPixelCache(atis); ++ ++ sc.val = sclk_cntl = MMIO_IN32(mmio, mmSCLK_CNTL); ++ sc.f.sclk_force_e2 = sc.f.sclk_force_e3 = sc.f.sclk_force_idct = 1; ++ MMIO_OUT32(mmio, mmSCLK_CNTL, sc.val); ++ ++ rsr.val = 0; ++ rsr.f.soft_reset_e2 = 1; ++ MMIO_OUT32(mmio, mmRBBM_SOFT_RESET, rsr.val); ++ MMIO_OUT32(mmio, mmRBBM_SOFT_RESET, 0); ++ ++ MMIO_OUT32(mmio, mmSCLK_CNTL, sclk_cntl); ++} ++ ++inline void ++ATIWaitAvailMMIO(ATIScreenInfo * atis, int n) ++{ ++ ATICardInfo *atic = atis->atic; ++ char *mmio = atic->reg_base; ++ rbbm_status_u rs; ++ TIMEOUT_LOCALS; ++ ++ if (atis->mmio_avail >= n) { ++ atis->mmio_avail -= n; ++ return; ++ } ++ WHILE_NOT_TIMEOUT(.2) { ++ rs.val = MMIO_IN32(mmio, mmRBBM_STATUS); ++ atis->mmio_avail = rs.f.cmdfifo_avail; ++ if (atis->mmio_avail >= n) ++ break; ++ ErrorF("Available %d slots.\n", atis->mmio_avail); ++ } ++ if (TIMEDOUT()) { ++ ErrorF("Timeout waiting for %d MMIO slots.\n", n); ++ ATIEngineReset(atis); ++ ATIDrawSetup(atis->screen->pScreen); ++ } ++ atis->mmio_avail -= n; ++} ++ ++ ++void ++ATIWaitIdle(ATIScreenInfo * atis) ++{ ++ ATICardInfo *atic = atis->atic; ++ char *mmio = atic->reg_base; ++ rbbm_status_u rs; ++ TIMEOUT_LOCALS; ++ ++ /* Empty the fifo */ ++ ATIWaitAvailMMIO(atis, 16); ++ ++ WHILE_NOT_TIMEOUT(.2) { ++ rs.val = MMIO_IN32(mmio, mmRBBM_STATUS); ++ if (!rs.f.gui_active) ++ break; ++#if DEBUG_FIFO ++ ATIDebugFifo(atis); ++#endif ++ /* don't know if this is needed, but it's in aticore */ ++ MMIO_IN32(mmio, mmCP_RB_RPTR); ++ } ++ if (TIMEDOUT()) { ++ ErrorF("Timeout idling accelerator, resetting...\n"); ++ ATIEngineReset(atis); ++ ATIDrawSetup(atis->screen->pScreen); ++ } ++ ++ ATIFlushPixelCache(atis); ++ ++#if DEBUG_FIFO ++ ErrorF("Idle?\n"); ++ ATIDebugFifo(atis); ++#endif ++} ++ ++ ++static Bool ++ATIDMAInit(ScreenPtr pScreen, Bool use_agp) ++{ ++ KdScreenPriv(pScreen); ++ ATIScreenInfo(pScreenPriv); ++ ATICardInfo(pScreenPriv); ++ char *mmio = atic->reg_base; ++ int dma_offset, rbsize = 10; ++ wrap_start_dir_u wsd; ++ wrap_buf_a_u wba; ++ cp_rb_cntl_u rc; ++ cp_csq_cntl_u cc; ++ CARD32 mem_offset; ++ ++ /* with rbsize = 10, DMA buffer will be of 0x2000 (8192) bytes */ ++ atis->ring_count = 1 << (rbsize + 1); ++ atis->ring_mask = atis->ring_count - 1; ++ atis->ring_len = atis->ring_count * 4; ++ atis->dma_space = KdOffscreenAlloc(pScreen, atis->ring_len, ++ 16, TRUE, NULL, NULL); ++ if (atis->dma_space == NULL) ++ return FALSE; ++ ++ wsd.val = MMIO_IN32(mmio, mmWRAP_START_DIR); ++ atis->ring_addr = ++ (CARD32 *) (atic->mem_base + (wsd.f.start_addr << 1)); ++ dma_offset = atis->dma_space->offset; ++ ++ ATIUploadMicrocode(atis); ++ ATIEngineReset(atis); ++ ++ atis->ring_read = 0; ++ atis->ring_write = 0; ++ atis->ring_free = atis->ring_count; ++ ++ mem_offset = atic->ext_mem_location + atis->dma_space->offset; ++ MMIO_OUT32(mmio, mmCP_RB_BASE, mem_offset); ++ MMIO_OUT32(mmio, mmCP_RB_WPTR, atis->ring_write); ++ MMIO_OUT32(mmio, mmCP_RB_RPTR, atis->ring_read); ++ MMIO_OUT32(mmio, mmCP_RB_RPTR_ADDR, 0); ++ ++ wba.val = 0; ++ wba.f.offset_addr_a = mem_offset; ++ switch (rbsize) { ++ case 9: ++ wba.f.block_size_a = WB_BLOCK_SIZE_A_0; ++ break; ++ case 10: ++ wba.f.block_size_a = WB_BLOCK_SIZE_A_1; ++ break; ++ case 11: ++ wba.f.block_size_a = WB_BLOCK_SIZE_A_2; ++ break; ++ case 12: ++ wba.f.block_size_a = WB_BLOCK_SIZE_A_3; ++ break; ++ case 13: ++ wba.f.block_size_a = WB_BLOCK_SIZE_A_4; ++ break; ++ } ++ MMIO_OUT32(mmio, mmWRAP_BUF_A, wba.val); ++ ++ rc.val = 0; ++ rc.f.rb_no_update = 1; ++ rc.f.rb_bufsz = rbsize; ++ MMIO_OUT32(mmio, mmCP_RB_CNTL, rc.val); ++ ++ cc.val = 0; ++ cc.f.csq_mode = CSQ_CNTL_MODE_FREERUN; ++ MMIO_OUT32(mmio, mmCP_CSQ_CNTL, cc.val); ++ ++ return TRUE; ++} ++ ++static Bool ++ATIDMAFini(ScreenPtr pScreen) ++{ ++ KdScreenPriv(pScreen); ++ ATIScreenInfo(pScreenPriv); ++ ATICardInfo(pScreenPriv); ++ char *mmio = atic->reg_base; ++ ++ MMIO_OUT32(mmio, mmCP_CSQ_CNTL, 0); ++ ++ ATIEngineReset(atis); ++ ++ //KdOffscreenFree(pScreen, atis->dma_space); ++ ++ return TRUE; ++} ++ ++void ++ATIDMASetup(ScreenPtr pScreen) ++{ ++ KdScreenPriv(pScreen); ++ ATIScreenInfo(pScreenPriv); ++ ++ atis->using_dma = FALSE; ++ atis->using_pio = FALSE; ++ if (ATIDMAInit(pScreen, FALSE)) ++ atis->using_dma = TRUE; ++ ++ if (atis->using_dma) ++ ErrorF("Initialized DMA\n"); ++} ++ ++void ++ATIDMATeardown(ScreenPtr pScreen) ++{ ++ KdScreenPriv(pScreen); ++ ATIScreenInfo(pScreenPriv); ++ ++ ATIWaitIdle(atis); ++ ++ if (atis->using_dma) ++ ATIDMAFini(pScreen); ++ ++ atis->using_pio = FALSE; ++ atis->using_dma = FALSE; ++} ++ ++ ++CARD32 * ++ATIRequestEntries(ATIScreenInfo * atis, int n) ++{ ++ char *mmio = atis->atic->reg_base; ++ CARD32 *ptr; ++ TIMEOUT_LOCALS; ++ ++ WHILE_NOT_TIMEOUT(1) { ++ if (atis->ring_free > n) { ++ ptr = atis->ring_addr + atis->ring_write; ++ return ptr; ++ } ++ atis->ring_read = MMIO_IN32(mmio, mmCP_RB_RPTR); ++ atis->ring_write = MMIO_IN32(mmio, mmCP_RB_WPTR); ++ ++ if (atis->ring_read == atis->ring_write) { ++ atis->ring_free = atis->ring_count; ++ } else { ++ atis->ring_free = ++ (atis->ring_count + ++ atis->ring_read - atis->ring_write) & atis->ring_mask; ++ } ++ } ++ if (TIMEDOUT()) ++ ErrorF("Timeout waiting for %d entries.\n", n); ++ return NULL; ++} ++ ++void ++ATISubmitEntries(ATIScreenInfo * atis, int n) ++{ ++ char *mmio = atis->atic->reg_base; ++ atis->ring_free -= n; ++ atis->ring_write += n; ++ atis->ring_write &= atis->ring_mask; ++ MMIO_OUT32(mmio, mmCP_RB_WPTR, atis->ring_write); ++} +Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_dma.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_dma.h 2006-09-02 11:47:21.000000000 +0200 +@@ -0,0 +1,176 @@ ++/* ++ * Copyright © 2004 Eric Anholt ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and its ++ * documentation for any purpose is hereby granted without fee, provided that ++ * the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of Eric Anholt not be used in ++ * advertising or publicity pertaining to distribution of the software without ++ * specific, written prior permission. Eric Anholt makes no ++ * representations about the suitability of this software for any purpose. It ++ * is provided "as is" without express or implied warranty. ++ * ++ * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO ++ * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR ++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, ++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER ++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ */ ++/* $Header: /cvs/xserver/xserver/hw/kdrive/ati/ati_dma.h,v 1.5 2005-01-27 05:25:57 anholt Exp $ */ ++ ++#ifndef _ATI_DMA_H_ ++#define _ATI_DMA_H_ ++ ++#define CCE_DEBUG 1 ++ ++/* CCE packet defines */ ++ ++#define ATI_CCE_PACKETTYPE_MASK 0xc0000000 ++#define ATI_CCE_PACKET0 0x00000000 ++#define ATI_CCE_PACKET0_COUNT_MASK 0x3fff0000 ++#define ATI_CCE_PACKET0_ONE_REG_WR 0x00008000 ++#define ATI_CCE_PACKET0_REG_MASK 0x000007ff ++#define ATI_CCE_PACKET1 0x40000000 ++#define ATI_CCE_PACKET1_REG_1 0x000007ff ++#define ATI_CCE_PACKET1_REG_2 0x003ff800 ++#define ATI_CCE_PACKET1_REG_2_SHIFT 10 ++#define ATI_CCE_PACKET2 0x80000000 ++#define ATI_CCE_PACKET3 0xc0000000 ++#define ATI_CCE_PACKET3_COUNT_MASK 0x3fff0000 ++#define ATI_CCE_PACKET3_IT_OPCODE_MASK 0x0000ff00 ++ ++ ++#if !CCE_DEBUG ++#define DMA_PACKET0(reg, count) \ ++ (ATI_CCE_PACKET0 | (((count) - 1) << 16) | ((reg) >> 2)) ++#else ++#define DMA_PACKET0(reg, count) \ ++ (__packet0count = (count), __reg = (reg), \ ++ ATI_CCE_PACKET0 | (((count) - 1) << 16) | ((reg) >> 2)) ++#endif ++#define DMA_PACKET1(reg1, reg2) \ ++ (ATI_CCE_PACKET1 | \ ++ (((reg2) >> 2) << ATI_CCE_PACKET1_REG_2_SHIFT) | ((reg1) >> 2)) ++#define DMA_PACKET3(type, count) \ ++ ((type) | (((count) - 1) << 16)) ++ ++ ++ ++#ifdef USE_DMA ++ ++#if !CCE_DEBUG ++ ++#define RING_LOCALS \ ++ CARD32 *__head; int __count ++#define BEGIN_DMA(n) \ ++do { \ ++ __head = ATIRequestEntries(atis, n); \ ++ __count = 0; \ ++} while (0) ++#define END_DMA() do { \ ++ ATISubmitEntries(atis, __count); \ ++} while (0) ++ ++#else /* CCE_DEBUG */ ++#define RING_LOCALS \ ++ CARD32 *__head; int __count, __total, __reg, __packet0count ++#define BEGIN_DMA(n) \ ++do { \ ++ __head = ATIRequestEntries(atis, n); \ ++ __count = 0; \ ++ __total = n; \ ++ __reg = 0; \ ++ __packet0count = 0; \ ++} while (0) ++#define END_DMA() do { \ ++ if (__count != __total) \ ++ FatalError("count != total (%d vs %d) at %s:%d\n", \ ++ __count, __total, __FILE__, __LINE__); \ ++ ATISubmitEntries(atis, __count); \ ++} while (0) ++ ++#endif /* CCE_DEBUG */ ++ ++#define BEGIN_DMA_REG(n) BEGIN_DMA(n * 2) ++#define END_DMA_REG() END_DMA() ++ ++#define OUT_REG(reg, val) \ ++do { \ ++ OUT_RING(DMA_PACKET0(reg, 1)); \ ++ OUT_RING(val); \ ++} while (0) ++ ++ ++#else /* USE_DMA */ ++ ++ ++#define RING_LOCALS char *__mmio = atis->atic->reg_base ++#define BEGIN_DMA_REG(n) \ ++do { \ ++ ATIWaitAvailMMIO(atis, n); \ ++} while (0) ++#define END_DMA_REG() do {} while (0) ++#define OUT_REG(reg, val) MMIO_OUT32(__mmio, reg, val) ++#endif /* USE_DMA */ ++ ++ ++#define OUT_RING(val) do { \ ++ __head[__count++] = (val); \ ++} while (0) ++ ++#define OUT_RING_REG(reg, val) do { \ ++ if (__reg != reg) \ ++ FatalError("unexpected reg (0x%x vs 0x%x) at %s:%d\n", \ ++ reg, __reg, __FILE__, __LINE__); \ ++ if (__packet0count-- <= 0) \ ++ FatalError("overrun of packet0 at %s:%d\n", \ ++ __FILE__, __LINE__); \ ++ __head[__count++] = (val); \ ++ __reg += 4; \ ++} while (0) ++ ++#define OUT_RING_F(x) OUT_RING(GET_FLOAT_BITS(x)) ++ ++#define TIMEOUT_LOCALS struct timeval _target, _curtime ++ ++static inline Bool ++tv_le(struct timeval *tv1, struct timeval *tv2) ++{ ++ if (tv1->tv_sec < tv2->tv_sec || ++ (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec < tv2->tv_usec)) ++ return TRUE; ++ else ++ return FALSE; ++} ++ ++#define WHILE_NOT_TIMEOUT(_timeout) \ ++ gettimeofday(&_target, NULL); \ ++ _target.tv_usec += ((_timeout) * 1000000); \ ++ _target.tv_sec += _target.tv_usec / 1000000; \ ++ _target.tv_usec = _target.tv_usec % 1000000; \ ++ while (gettimeofday(&_curtime, NULL), tv_le(&_curtime, &_target)) ++ ++#define TIMEDOUT() (!tv_le(&_curtime, &_target)) ++ ++ ++void ++ATIFlushIndirect(ATIScreenInfo *atis, Bool discard); ++ ++void ++ATIDMASetup(ScreenPtr pScreen); ++ ++void ++ATIDMATeardown(ScreenPtr pScreen); ++ ++CARD32 * ++ATIRequestEntries(ATIScreenInfo *atis, int n); ++ ++void ++ATISubmitEntries(ATIScreenInfo *atis, int n); ++ ++inline void ++ATIWaitAvailMMIO(ATIScreenInfo *atis, int n); ++#endif /* _ATI_DMA_H_ */ +Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_draw.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_draw.c 2006-09-02 11:47:21.000000000 +0200 +@@ -0,0 +1,477 @@ ++/* ++ * Copyright © 2006 Alberto Mardegan ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and its ++ * documentation for any purpose is hereby granted without fee, provided that ++ * the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of Alberto Mardegan not be used in ++ * advertising or publicity pertaining to distribution of the software without ++ * specific, written prior permission. Alberto Mardegan makes no ++ * representations about the suitability of this software for any purpose. It ++ * is provided "as is" without express or implied warranty. ++ * ++ * ALBERTO MARDEGAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO ++ * EVENT SHALL ALBERTO MARDEGAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR ++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, ++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER ++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#define USE_DMA ++#define DRAW_USING_PACKET3 ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++#include "ati.h" ++#include "w100_regs.h" ++#include "w100_const.h" ++#include "ati_dma.h" ++#include "ati_draw.h" ++#include "kaa.h" ++ ++ ++CARD8 ATISolidRop[16] = { ++ /* GXclear */ 0x00, ++ /* 0 */ ++ /* GXand */ 0xa0, ++ /* src AND dst */ ++ /* GXandReverse */ 0x50, ++ /* src AND NOT dst */ ++ /* GXcopy */ 0xf0, ++ /* src */ ++ /* GXandInverted */ 0x0a, ++ /* NOT src AND dst */ ++ /* GXnoop */ 0xaa, ++ /* dst */ ++ /* GXxor */ 0x5a, ++ /* src XOR dst */ ++ /* GXor */ 0xfa, ++ /* src OR dst */ ++ /* GXnor */ 0x05, ++ /* NOT src AND NOT dst */ ++ /* GXequiv */ 0xa5, ++ /* NOT src XOR dst */ ++ /* GXinvert */ 0x55, ++ /* NOT dst */ ++ /* GXorReverse */ 0xf5, ++ /* src OR NOT dst */ ++ /* GXcopyInverted */ 0x0f, ++ /* NOT src */ ++ /* GXorInverted */ 0xaf, ++ /* NOT src OR dst */ ++ /* GXnand */ 0x5f, ++ /* NOT src OR NOT dst */ ++ /* GXset */ 0xff, ++ /* 1 */ ++}; ++ ++CARD8 ATIBltRop[16] = { ++ /* GXclear */ 0x00, ++ /* 0 */ ++ /* GXand */ 0x88, ++ /* src AND dst */ ++ /* GXandReverse */ 0x44, ++ /* src AND NOT dst */ ++ /* GXcopy */ 0xcc, ++ /* src */ ++ /* GXandInverted */ 0x22, ++ /* NOT src AND dst */ ++ /* GXnoop */ 0xaa, ++ /* dst */ ++ /* GXxor */ 0x66, ++ /* src XOR dst */ ++ /* GXor */ 0xee, ++ /* src OR dst */ ++ /* GXnor */ 0x11, ++ /* NOT src AND NOT dst */ ++ /* GXequiv */ 0x99, ++ /* NOT src XOR dst */ ++ /* GXinvert */ 0x55, ++ /* NOT dst */ ++ /* GXorReverse */ 0xdd, ++ /* src OR NOT dst */ ++ /* GXcopyInverted */ 0x33, ++ /* NOT src */ ++ /* GXorInverted */ 0xbb, ++ /* NOT src OR dst */ ++ /* GXnand */ 0x77, ++ /* NOT src OR NOT dst */ ++ /* GXset */ 0xff, ++ /* 1 */ ++}; ++ ++static int copydx, copydy; ++static ATIScreenInfo *accel_atis; ++static char *accel_mmio; ++ ++ ++void ++ATIDrawSetup(ScreenPtr pScreen) ++{ ++ KdScreenPriv(pScreen); ++ ATIScreenInfo(pScreenPriv); ++ default_sc_bottom_right_u dsbr; ++ RING_LOCALS; ++ ++ dsbr.val = 0; ++ dsbr.f.default_sc_right = dsbr.f.default_sc_bottom = W100_MAXINT; ++ ++ BEGIN_DMA_REG(2); ++ OUT_REG(mmDEFAULT_SC_BOTTOM_RIGHT, dsbr.val); ++ OUT_REG(mmSRC_SC_BOTTOM_RIGHT, dsbr.val); ++ END_DMA_REG(); ++} ++ ++static void ++ATIWaitMarker(ScreenPtr pScreen, int marker) ++{ ++ KdScreenPriv(pScreen); ++ ATIScreenInfo(pScreenPriv); ++ ++ ENTER_DRAW(0); ++ ATIWaitIdle(atis); ++ LEAVE_DRAW(0); ++} ++ ++ ++#if ATI_TRACE_DRAW ++void ++ATIEnterDraw(PixmapPtr pPix, const char *function) ++{ ++ if (pPix != NULL) { ++ KdScreenPriv(pPix->drawable.pScreen); ++ CARD32 offset; ++ ++ offset = ((CARD8 *) pPix->devPrivate.ptr - ++ pScreenPriv->screen->memory_base); ++ ++ ErrorF("Enter %s 0x%x (%dx%dx%d/%d)\n", function, offset, ++ pPix->drawable.width, pPix->drawable.height, ++ pPix->drawable.depth, pPix->drawable.bitsPerPixel); ++ } else ++ ErrorF("Enter %s\n", function); ++} ++ ++void ++ATILeaveDraw(PixmapPtr pPix, const char *function) ++{ ++ if (pPix != NULL) { ++ KdScreenPriv(pPix->drawable.pScreen); ++ CARD32 offset; ++ ++ offset = ((CARD8 *) pPix->devPrivate.ptr - ++ pScreenPriv->screen->memory_base); ++ ++ ErrorF("Leave %s 0x%x\n", function, offset); ++ } else ++ ErrorF("Leave %s\n", function); ++} ++#endif ++ ++/* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we ++ * require src and dest datatypes to be equal. ++ */ ++static Bool ++ATIGetDatatypeBpp(int bpp, CARD32 * type) ++{ ++ switch (bpp) { ++ case 8: ++ *type = DATATYPE_8BPP; ++ return TRUE; ++ case 16: ++ *type = DATATYPE_ARGB1555; ++ return TRUE; ++ default: ++ ATI_FALLBACK(("Unsupported bpp: %d\n", bpp)); ++ return FALSE; ++ } ++} ++ ++ ++Bool ++ATIGetPixmapOffsetPitch(PixmapPtr pPix, CARD32 * pitch, CARD32 * offset) ++{ ++ KdScreenPriv(pPix->drawable.pScreen); ++ ATICardInfo(pScreenPriv); ++ ++ /* XXX this only works for surfaces allocated in external memory */ ++ *offset = ((CARD8 *) pPix->devPrivate.ptr - ++ pScreenPriv->screen->memory_base) + atic->ext_mem_location; ++ *pitch = pPix->devKind >> 1; ++ ++ return TRUE; ++} ++ ++ ++static Bool ++ATIPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) ++{ ++ KdScreenPriv(pPix->drawable.pScreen); ++ ATIScreenInfo(pScreenPriv); ++ ATICardInfo(pScreenPriv); ++ CARD32 datatype, dst_pitch, dst_offset; ++ dp_gui_master_cntl_u gmc; ++ dp_cntl_u dp_cntl; ++ RING_LOCALS; ++ ++ accel_atis = atis; ++ accel_mmio = atic->reg_base; ++ ++ if (!ATIGetDatatypeBpp(pPix->drawable.bitsPerPixel, &datatype)) ++ return FALSE; ++ if (!ATIGetPixmapOffsetPitch(pPix, &dst_pitch, &dst_offset)) ++ return FALSE; ++ ++ ENTER_DRAW(pPix); ++ ++ gmc.val = 0; ++ gmc.f.gmc_dst_pitch_offset_cntl = 1; ++ gmc.f.gmc_dst_clipping = 1; ++ gmc.f.gmc_brush_datatype = BRUSH_SOLIDCOLOR; ++ gmc.f.gmc_dst_datatype = datatype; ++ gmc.f.gmc_src_datatype = datatype; ++ gmc.f.gmc_byte_pix_order = 1; ++ gmc.f.gmc_rop3 = ATISolidRop[alu]; ++ gmc.f.gmc_dp_src_source = SOURCE_MEM_RECTANGULAR; ++ gmc.f.gmc_clr_cmp_fcn_dis = 1; ++ gmc.f.gmc_dp_op = OP_ROP; ++ ++ dp_cntl.val = 0; ++ dp_cntl.f.dst_x_dir = 1; ++ dp_cntl.f.dst_y_dir = 1; ++ ++ BEGIN_DMA_REG(6); ++ OUT_REG(mmDST_PITCH, dst_pitch); ++ OUT_REG(mmDST_OFFSET, dst_offset); ++ OUT_REG(mmDP_GUI_MASTER_CNTL, gmc.val); ++ OUT_REG(mmDP_BRUSH_FRGD_CLR, fg); ++ OUT_REG(mmDP_WRITE_MSK, pm); ++ OUT_REG(mmDP_CNTL, dp_cntl.val); ++ END_DMA_REG(); ++ ++ LEAVE_DRAW(pPix); ++ return TRUE; ++} ++ ++static void ++ATISolid(int x1, int y1, int x2, int y2) ++{ ++ ENTER_DRAW(0); ++ ATIScreenInfo *atis = accel_atis; ++ RING_LOCALS; ++ ++#ifdef DRAW_USING_PACKET3 ++ BEGIN_DMA(3); ++ OUT_RING(DMA_PACKET3(W100_CCE_PACKET3_PAINT_MULTI, 2)); ++ OUT_RING((x1 << 16) | y1); ++ OUT_RING(((x2 - x1) << 16) | (y2 - y1)); ++ END_DMA(); ++#elif defined DRAW_USING_PACKET0 ++ BEGIN_DMA(3); ++ OUT_RING(DMA_PACKET0(mmDST_Y_X, 2)); ++ OUT_RING_REG(mmDST_Y_X, (y1 << 16) | x1); ++ OUT_RING_REG(mmDST_HEIGHT_WIDTH, ((y2 - y1) << 16) | (x2 - x1)); ++ END_DMA(); ++#else ++ BEGIN_DMA_REG(2); ++ OUT_REG(mmDST_Y_X, (y1 << 16) | x1); ++ OUT_REG(mmDST_HEIGHT_WIDTH, ((y2 - y1) << 16) | (x2 - x1)); ++ END_DMA_REG(); ++#endif ++ LEAVE_DRAW(0); ++} ++ ++ ++static void ++ATIDoneSolid(void) ++{ ++ ENTER_DRAW(0); ++ LEAVE_DRAW(0); ++} ++ ++ ++static Bool ++ATIPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, ++ Pixel pm) ++{ ++ KdScreenPriv(pDst->drawable.pScreen); ++ ATIScreenInfo(pScreenPriv); ++ ATICardInfo(pScreenPriv); ++ CARD32 datatype, src_pitch, src_offset, dst_pitch, dst_offset; ++ dp_gui_master_cntl_u gmc; ++ dp_cntl_u dp_cntl; ++ dp_datatype_u dpdt; ++ RING_LOCALS; ++ ++ accel_mmio = atic->reg_base; ++ copydx = dx; ++ copydy = dy; ++ accel_atis = atis; ++ ++ if (!ATIGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype)) ++ return FALSE; ++ if (!ATIGetPixmapOffsetPitch(pSrc, &src_pitch, &src_offset)) ++ return FALSE; ++ if (!ATIGetPixmapOffsetPitch(pDst, &dst_pitch, &dst_offset)) ++ return FALSE; ++ ++ ENTER_DRAW(pDst); ++ ++ gmc.val = 0; ++ gmc.f.gmc_src_pitch_offset_cntl = 1; ++ gmc.f.gmc_dst_pitch_offset_cntl = 1; ++ gmc.f.gmc_src_clipping = 1; ++ gmc.f.gmc_dst_clipping = 1; ++ gmc.f.gmc_brush_datatype = BRUSH_NONE; ++ gmc.f.gmc_dst_datatype = datatype; ++ gmc.f.gmc_src_datatype = datatype; ++ gmc.f.gmc_byte_pix_order = 1; ++ gmc.f.gmc_rop3 = ATIBltRop[alu]; ++ gmc.f.gmc_dp_src_source = SOURCE_MEM_RECTANGULAR; ++ gmc.f.gmc_clr_cmp_fcn_dis = 1; ++ gmc.f.gmc_dp_op = OP_ROP; ++ ++ dp_cntl.val = 0; ++ if (dx >= 0) ++ dp_cntl.f.dst_x_dir = 1; ++ if (dy >= 0) ++ dp_cntl.f.dst_y_dir = 1; ++ ++ dpdt.val = 0; ++ dpdt.f.dp_dst_datatype = datatype; ++ dpdt.f.dp_src_datatype = datatype; ++ dpdt.f.dp_byte_pix_order = 1; ++ ++ BEGIN_DMA_REG(8); ++ OUT_REG(mmSRC_PITCH, src_pitch); ++ OUT_REG(mmSRC_OFFSET, src_offset); ++ OUT_REG(mmDST_PITCH, dst_pitch); ++ OUT_REG(mmDST_OFFSET, dst_offset); ++ OUT_REG(mmDP_GUI_MASTER_CNTL, gmc.val); ++ OUT_REG(mmDP_WRITE_MSK, pm); ++ OUT_REG(mmDP_CNTL, dp_cntl.val); ++ OUT_REG(mmDP_DATATYPE, dpdt.val); ++ END_DMA_REG(); ++ ++ LEAVE_DRAW(pDst); ++ return TRUE; ++} ++ ++static void ++ATICopy(int srcX, int srcY, int dstX, int dstY, int w, int h) ++{ ++ ATIScreenInfo *atis = accel_atis; ++ RING_LOCALS; ++ ++ ENTER_DRAW(0); ++#ifndef DRAW_USING_PACKET3 ++ if (copydx < 0) { ++ srcX += w - 1; ++ dstX += w - 1; ++ } ++ if (copydy < 0) { ++ srcY += h - 1; ++ dstY += h - 1; ++ } ++#endif ++ ++#ifdef DRAW_USING_PACKET3 ++ BEGIN_DMA(4); ++ OUT_RING(DMA_PACKET3(W100_CCE_PACKET3_BITBLT_MULTI, 3)); ++ OUT_RING((srcX << 16) | srcY); ++ OUT_RING((dstX << 16) | dstY); ++ OUT_RING((w << 16) | h); ++ END_DMA(); ++#elif defined DRAW_USING_PACKET0 ++ BEGIN_DMA(4); ++ OUT_RING(DMA_PACKET0(mmSRC_Y_X, 3)); ++ OUT_RING_REG(mmSRC_Y_X, (srcY << 16) | srcX); ++ OUT_RING_REG(mmDST_Y_X, (dstY << 16) | dstX); ++ OUT_RING_REG(mmDST_HEIGHT_WIDTH, (h << 16) | w); ++ END_DMA(); ++#else ++ BEGIN_DMA_REG(3); ++ OUT_REG(mmSRC_Y_X, (srcY << 16) | srcX); ++ OUT_REG(mmDST_Y_X, (dstY << 16) | dstX); ++ OUT_REG(mmDST_HEIGHT_WIDTH, (h << 16) | w); ++ END_DMA_REG(); ++#endif ++ LEAVE_DRAW(0); ++} ++ ++ ++static void ++ATIDoneCopy(void) ++{ ++ ENTER_DRAW(0); ++ LEAVE_DRAW(0); ++} ++ ++ ++Bool ++ATIDrawInit(ScreenPtr pScreen) ++{ ++ KdScreenPriv(pScreen); ++ ATIScreenInfo(pScreenPriv); ++ ++ ErrorF("Screen: %d/%d depth/bpp\n", pScreenPriv->screen->fb[0].depth, ++ pScreenPriv->screen->fb[0].bitsPerPixel); ++ ++ memset(&atis->kaa, 0, sizeof(KaaScreenInfoRec)); ++ atis->kaa.waitMarker = ATIWaitMarker; ++ atis->kaa.PrepareSolid = ATIPrepareSolid; ++ atis->kaa.Solid = ATISolid; ++ atis->kaa.DoneSolid = ATIDoneSolid; ++ atis->kaa.PrepareCopy = ATIPrepareCopy; ++ atis->kaa.Copy = ATICopy; ++ atis->kaa.DoneCopy = ATIDoneCopy; ++ /* XXX if this flag isn't specified, Kdrive crashes in kaaPixmapUseMemory ++ * or kaaPixmapUseScreen. But this is probably caused by some bug in this ++ * driver... */ ++ atis->kaa.flags |= KAA_OFFSCREEN_PIXMAPS; ++ if (!kaaDrawInit(pScreen, &atis->kaa)) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++ ++void ++ATIDrawEnable(ScreenPtr pScreen) ++{ ++ KdScreenPriv(pScreen); ++ ATIScreenInfo(pScreenPriv); ++ ++ ATIDMASetup(pScreen); ++ ATIDrawSetup(pScreen); ++ ++ atis->scratch_area = NULL; ++ atis->kaa.PrepareBlend = NULL; ++ atis->kaa.Blend = NULL; ++ atis->kaa.DoneBlend = NULL; ++ atis->kaa.CheckComposite = NULL; ++ atis->kaa.PrepareComposite = NULL; ++ atis->kaa.Composite = NULL; ++ atis->kaa.DoneComposite = NULL; ++ atis->kaa.UploadToScreen = NULL; ++ atis->kaa.UploadToScratch = NULL; ++ ++ ++ kaaMarkSync(pScreen); ++} ++ ++void ++ATIDrawDisable(ScreenPtr pScreen) ++{ ++ ATIDMATeardown(pScreen); ++} ++ ++void ++ATIDrawFini(ScreenPtr pScreen) ++{ ++ kaaDrawFini(pScreen); ++} +Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_draw.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_draw.h 2006-09-02 11:47:21.000000000 +0200 +@@ -0,0 +1,107 @@ ++/* ++ * Copyright © 2004 Eric Anholt ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and its ++ * documentation for any purpose is hereby granted without fee, provided that ++ * the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of Eric Anholt not be used in ++ * advertising or publicity pertaining to distribution of the software without ++ * specific, written prior permission. Eric Anholt makes no ++ * representations about the suitability of this software for any purpose. It ++ * is provided "as is" without express or implied warranty. ++ * ++ * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO ++ * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR ++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, ++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER ++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ */ ++/* $Header: /cvs/xserver/xserver/hw/kdrive/ati/ati_draw.h,v 1.9 2005-02-21 03:44:10 anholt Exp $ */ ++ ++#ifndef _ATI_DRAW_H_ ++#define _ATI_DRAW_H_ ++ ++Bool ATIGetOffsetPitch(ATIScreenInfo *atis, int bpp, CARD32 *pitch_offset, ++ int offset, int pitch); ++Bool ATIGetPixmapOffsetPitch(PixmapPtr pPix, CARD32 *pitch, CARD32 *offset); ++ ++Bool R128CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, ++ PicturePtr pDstPicture); ++Bool R128PrepareComposite(int op, PicturePtr pSrcPicture, ++ PicturePtr pMaskPicture, PicturePtr pDstPicture, PixmapPtr pSrc, ++ PixmapPtr pMask, PixmapPtr pDst); ++void R128Composite(int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, ++ int w, int h); ++void R128DoneComposite(void); ++ ++Bool R128PrepareTrapezoids(PicturePtr pDstPicture, PixmapPtr pDst); ++void R128Trapezoids(KaaTrapezoid *traps, int ntraps); ++void R128DoneTrapezoids(void); ++ ++Bool R100CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, ++ PicturePtr pDstPicture); ++Bool R100PrepareComposite(int op, PicturePtr pSrcPicture, ++ PicturePtr pMaskPicture, PicturePtr pDstPicture, PixmapPtr pSrc, ++ PixmapPtr pMask, PixmapPtr pDst); ++Bool R200CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, ++ PicturePtr pDstPicture); ++Bool R200PrepareComposite(int op, PicturePtr pSrcPicture, ++ PicturePtr pMaskPicture, PicturePtr pDstPicture, PixmapPtr pSrc, ++ PixmapPtr pMask, PixmapPtr pDst); ++void RadeonComposite(int srcX, int srcY, int maskX, int maskY, int dstX, ++ int dstY, int w, int h); ++void RadeonDoneComposite(void); ++ ++Bool RadeonPrepareTrapezoids(PicturePtr pDstPicture, PixmapPtr pDst); ++void RadeonTrapezoids(KaaTrapezoid *traps, int ntraps); ++void RadeonDoneTrapezoids(void); ++ ++void RadeonSwitchTo2D(ATIScreenInfo *atis); ++void RadeonSwitchTo3D(ATIScreenInfo *atis); ++void ATIWaitIdle(ATIScreenInfo *atis); ++ ++#define ATI_TRACE_FALL 0 ++#define ATI_TRACE_DRAW 1 ++ ++#if ATI_TRACE_FALL ++#define ATI_FALLBACK(x) \ ++do { \ ++ ErrorF("%s: ", __FUNCTION__); \ ++ ErrorF x; \ ++ return FALSE; \ ++} while (0) ++#else ++#define ATI_FALLBACK(x) return FALSE ++#endif ++ ++#if ATI_TRACE_DRAW ++#define ENTER_DRAW(pix) ATIEnterDraw(pix, __FUNCTION__) ++#define LEAVE_DRAW(pix) ATILeaveDraw(pix, __FUNCTION__) ++ ++void ++ATIEnterDraw (PixmapPtr pPixmap, const char *function); ++ ++void ++ATILeaveDraw (PixmapPtr pPixmap, const char *function); ++#else /* ATI_TRACE */ ++#define ENTER_DRAW(pix) ++#define LEAVE_DRAW(pix) ++#endif /* !ATI_TRACE */ ++ ++#ifndef USE_DMA ++/* if DMA is not going to be used, drawing using PACKET3 or PACKET0 won't ++ * be possible */ ++#ifdef DRAW_USING_PACKET3 ++#undef DRAW_USING_PACKET3 ++#endif ++ ++#ifdef DRAW_USING_PACKET0 ++#undef DRAW_USING_PACKET0 ++#endif ++ ++#endif /* USE_DMA */ ++ ++#endif /* _ATI_DRAW_H_ */ +Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati.h 2006-09-02 11:47:21.000000000 +0200 +@@ -0,0 +1,256 @@ ++/* ++ * $Id: ati.h,v 1.18 2005-06-10 02:14:44 anholt Exp $ ++ * ++ * Copyright © 2003 Eric Anholt ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and its ++ * documentation for any purpose is hereby granted without fee, provided that ++ * the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of Eric Anholt not be used in ++ * advertising or publicity pertaining to distribution of the software without ++ * specific, written prior permission. Eric Anholt makes no ++ * representations about the suitability of this software for any purpose. It ++ * is provided "as is" without express or implied warranty. ++ * ++ * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO ++ * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR ++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, ++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER ++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ */ ++/* $Header: /cvs/xserver/xserver/hw/kdrive/ati/ati.h,v 1.18 2005-06-10 02:14:44 anholt Exp $ */ ++ ++#ifndef _ATI_H_ ++#define _ATI_H_ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#ifdef KDRIVEFBDEV ++#include ++#endif ++#ifdef KDRIVEVESA ++#include ++#endif ++ ++#include "kxv.h" ++ ++ ++#define ATI_MEM_BASE(c) (0x08000000) ++#define ATI_MEM_SIZE(c) (0x01000000) ++#define ATI_REG_BASE(c) (ATI_MEM_BASE(c) + 0x10000) /* the 0x08000000 must be obtained from /proc/iomem, the 0x10000 from ReadCfgReg(cfgREG_BASE) << 16) & 0xff0000 */ ++#define ATI_REG_SIZE(c) (0x2000) ++ ++#ifdef __powerpc__ ++ ++static __inline__ void ++MMIO_OUT32(__volatile__ void *base, const unsigned long offset, ++ const unsigned int val) ++{ ++ __asm__ __volatile__( ++ "stwbrx %1,%2,%3\n\t" ++ "eieio" ++ : "=m" (*((volatile unsigned char *)base+offset)) ++ : "r" (val), "b" (base), "r" (offset)); ++} ++ ++static __inline__ CARD32 ++MMIO_IN32(__volatile__ void *base, const unsigned long offset) ++{ ++ register unsigned int val; ++ __asm__ __volatile__( ++ "lwbrx %0,%1,%2\n\t" ++ "eieio" ++ : "=r" (val) ++ : "b" (base), "r" (offset), ++ "m" (*((volatile unsigned char *)base+offset))); ++ return val; ++} ++ ++#else ++ ++#define MMIO_OUT32(mmio, a, v) (*(VOL32 *)((mmio) + (a)) = (v)) ++#define MMIO_IN32(mmio, a) (*(VOL32 *)((mmio) + (a))) ++ ++#endif ++ ++#define MMIO_OUT8(mmio, a, v) (*(VOL8 *)((mmio) + (a)) = (v)) ++#define MMIO_IN8(mmio, a, v) (*(VOL8 *)((mmio) + (a))) ++ ++ ++typedef volatile CARD8 VOL8; ++typedef volatile CARD16 VOL16; ++typedef volatile CARD32 VOL32; ++ ++struct pci_id_entry { ++ CARD16 vendor; ++ CARD16 device; ++ CARD8 caps; ++ char *name; ++}; ++ ++struct backend_funcs { ++ void (*cardfini)(KdCardInfo *); ++ void (*scrfini)(KdScreenInfo *); ++ Bool (*initScreen)(ScreenPtr); ++ Bool (*finishInitScreen)(ScreenPtr pScreen); ++ Bool (*createRes)(ScreenPtr); ++ void (*preserve)(KdCardInfo *); ++ void (*restore)(KdCardInfo *); ++ Bool (*dpms)(ScreenPtr, int); ++ Bool (*enable)(ScreenPtr); ++ void (*disable)(ScreenPtr); ++ void (*getColors)(ScreenPtr, int, int, xColorItem *); ++ void (*putColors)(ScreenPtr, int, int, xColorItem *); ++#ifdef RANDR ++ Bool (*randrSetConfig) (ScreenPtr, Rotation, int, RRScreenSizePtr); ++#endif ++}; ++ ++typedef struct _ATICardInfo { ++ union { ++#ifdef KDRIVEFBDEV ++ FbdevPriv fbdev; ++#endif ++#ifdef KDRIVEVESA ++ VesaCardPrivRec vesa; ++#endif ++ } backend_priv; ++ struct backend_funcs backend_funcs; ++ ++ struct pci_id_entry *pci_id; ++ CARD8 *mem_base; ++ CARD8 *reg_base; ++ CARD32 fb_location; ++ CARD32 ext_mem_location; ++ Bool use_fbdev, use_vesa; ++} ATICardInfo; ++ ++#define getATICardInfo(kd) ((ATICardInfo *) ((kd)->card->driver)) ++#define ATICardInfo(kd) ATICardInfo *atic = getATICardInfo(kd) ++ ++typedef struct _ATICursor { ++ int width, height; ++ int xhot, yhot; ++ ++ Bool has_cursor; ++ CursorPtr pCursor; ++ Pixel source, mask; ++ KdOffscreenArea *area; ++} ATICursor; ++ ++typedef struct _ATIPortPriv { ++ int brightness; ++ int saturation; ++ RegionRec clip; ++ CARD32 size; ++ KdOffscreenArea *off_screen; ++ DrawablePtr pDraw; ++ PixmapPtr pPixmap; ++ ++ CARD32 src_offset; ++ CARD32 src_pitch; ++ CARD8 *src_addr; ++ ++ int id; ++ int src_x1, src_y1, src_x2, src_y2; ++ int dst_x1, dst_y1, dst_x2, dst_y2; ++ int src_w, src_h, dst_w, dst_h; ++} ATIPortPrivRec, *ATIPortPrivPtr; ++ ++typedef struct _ATIScreenInfo { ++ union { ++#ifdef KDRIVEFBDEV ++ FbdevScrPriv fbdev; ++#endif ++#ifdef KDRIVEVESA ++ VesaScreenPrivRec vesa; ++#endif ++ } backend_priv; ++ KaaScreenInfoRec kaa; ++ ++ ATICardInfo *atic; ++ KdScreenInfo *screen; ++ ++ int scratch_offset; ++ int scratch_next; ++ KdOffscreenArea *scratch_area; ++ ++ ATICursor cursor; ++ ++ KdVideoAdaptorPtr pAdaptor; ++ int num_texture_ports; ++ ++ Bool using_pio; /* If we use decode DMA packets to MMIO. */ ++ Bool using_dma; /* If we use non-DRI DMA to submit packets. */ ++ ++ KdOffscreenArea *dma_space; /* For "DMA" from framebuffer. */ ++ CARD32 *ring_addr; /* Beginning of ring buffer. */ ++ int ring_write; /* Index of write ptr in ring. */ ++ int ring_read; /* Index of read ptr in ring. */ ++ int ring_len; ++ int ring_mask; ++ int ring_count; ++ int ring_free; ++ ++ ++ int mmio_avail; ++} ATIScreenInfo; ++ ++#define getATIScreenInfo(kd) ((ATIScreenInfo *) ((kd)->screen->driver)) ++#define ATIScreenInfo(kd) ATIScreenInfo *atis = getATIScreenInfo(kd) ++ ++typedef union { float f; CARD32 i; } fi_type; ++ ++ ++/* ati.c */ ++Bool ++ATIMap(KdCardInfo *card, ATICardInfo *atic); ++ ++void ++ATIUnmap(KdCardInfo *card, ATICardInfo *atic); ++ ++/* ati_draw.c */ ++void ++ATIDrawSetup(ScreenPtr pScreen); ++ ++Bool ++ATIDrawInit(ScreenPtr pScreen); ++ ++void ++ATIDrawEnable(ScreenPtr pScreen); ++ ++void ++ATIDrawDisable(ScreenPtr pScreen); ++ ++void ++ATIDrawFini(ScreenPtr pScreen); ++ ++ ++/* ati_cursor.c */ ++Bool ++ATICursorInit(ScreenPtr pScreen); ++ ++void ++ATICursorEnable(ScreenPtr pScreen); ++ ++void ++ATICursorDisable(ScreenPtr pScreen); ++ ++void ++ATICursorFini(ScreenPtr pScreen); ++ ++void ++ATIRecolorCursor(ScreenPtr pScreen, int ndef, xColorItem *pdef); ++ ++int ++ATILog2(int val); ++ ++ ++extern KdCardFuncs ATIFuncs; ++ ++#endif /* _ATI_H_ */ +Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_microcode.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_microcode.c 2006-09-02 11:47:21.000000000 +0200 +@@ -0,0 +1,412 @@ ++/* ++ * Copyright © 2006 Alberto Mardegan ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and its ++ * documentation for any purpose is hereby granted without fee, provided that ++ * the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of Alberto Mardegan not be used in ++ * advertising or publicity pertaining to distribution of the software without ++ * specific, written prior permission. Alberto Mardegan makes no ++ * representations about the suitability of this software for any purpose. It ++ * is provided "as is" without express or implied warranty. ++ * ++ * ALBERTO MARDEGAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO ++ * EVENT SHALL ALBERTO MARDEGAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR ++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, ++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER ++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++/* CCE microcode (from ATI) */ ++ ++#include "ati.h" ++ ++ ++CARD32 w100_microcode[][2] = { ++ {0x21007000, 0x00000000} ++ , ++ {0x20007000, 0x00000000} ++ , ++ {0x00000098, 0x00000004} ++ , ++ {0x0000009c, 0x00000004} ++ , ++ {0x66544a49, 0x00000000} ++ , ++ {0x49494174, 0x00000000} ++ , ++ {0x54517d83, 0x00000000} ++ , ++ {0x498d8b64, 0x00000000} ++ , ++ {0x49494949, 0x00000000} ++ , ++ {0x49b6493c, 0x00000000} ++ , ++ {0x49494949, 0x00000000} ++ , ++ {0x49494949, 0x00000000} ++ , ++ {0x49490d10, 0x00000000} ++ , ++ {0x000f0000, 0x00000016} ++ , ++ {0x30292027, 0x00000000} ++ , ++ {0x00000012, 0x00000004} ++ , ++ {0x000f0000, 0x00000016} ++ , ++ {0x30292427, 0x00000000} ++ , ++ {0x0000730f, 0x00000002} ++ , /* mmIDCT_CONTROL */ ++ {0x00061000, 0x00000002} ++ , ++ {0x0000001d, 0x0000001a} ++ , ++ {0x00004000, 0x0000001e} ++ , ++ {0x00061000, 0x00000002} ++ , ++ {0x0000001d, 0x0000001a} ++ , ++ {0x00004000, 0x0000001e} ++ , ++ {0x00061000, 0x00000002} ++ , ++ {0x0000001d, 0x0000001a} ++ , ++ {0x00004000, 0x0000001e} ++ , ++ {0x00000013, 0x00000004} ++ , ++ {0x0003803a, 0x00000002} ++ , ++ {0x04006300, 0x00000002} ++ , /* mmIDCT_RUNS */ ++ {0x00000013, 0x00000004} ++ , ++ {0x00007300, 0x00000002} ++ , /* mmIDCT_RUNS */ ++ {0x00065000, 0x00000002} ++ , ++ {0x00003301, 0x00000002} ++ , /* mmIDCT_LEVELS */ ++ {0x04006301, 0x00000006} ++ , /* mmIDCT_LEVELS */ ++ {0x00007300, 0x00000002} ++ , /* mmIDCT_RUNS */ ++ {0x00007301, 0x00000002} ++ , /* mmIDCT_LEVELS */ ++ {0x00007301, 0x00000006} ++ , /* mmIDCT_LEVELS */ ++ {0x0003803a, 0x00000002} ++ , ++ {0x04006300, 0x00000006} ++ , /* mmIDCT_RUNS */ ++ {0x00a05000, 0x00000002} ++ , ++ {0x00000039, 0x0000000c} ++ , ++ {0x00000000, 0x00000002} ++ , ++ {0x00007300, 0x00000002} ++ , /* mmIDCT_RUNS */ ++ {0x00007301, 0x00000002} ++ , /* mmIDCT_LEVELS */ ++ {0x00007301, 0x00000002} ++ , /* mmIDCT_LEVELS */ ++ {0x0060002a, 0x00000004} ++ , ++ {0x00007488, 0x00000002} ++ , /* mmE2_ARITHMETIC_CNTL */ ++ {0x0003803b, 0x00000002} ++ , ++ {0x00098000, 0x00000002} ++ , ++ {0x00200000, 0x00000002} ++ , ++ {0x00000039, 0x0000000c} ++ , ++ {0x00007465, 0x00000002} ++ , /* mmDST_X_Y */ ++ {0x00007464, 0x00000002} ++ , /* mmSRC_X_Y */ ++ {0x00007478, 0x00000002} ++ , /* mmMVC_CNTL_START */ ++ {0x00600034, 0x00000004} ++ , ++ {0x00000000, 0x00000006} ++ , ++ {0xffffffff, 0x00000000} ++ , ++ {0x00000006, 0x00000000} ++ , ++ {0x01605000, 0x00000002} ++ , ++ {0x00065000, 0x00000002} ++ , ++ {0x00098000, 0x00000002} ++ , ++ {0x00061000, 0x00000002} ++ , ++ {0x64c0603d, 0x00000004} ++ , ++ {0x00080000, 0x00000016} ++ , ++ {0x00000000, 0x00000000} ++ , ++ {0x0400241d, 0x00000002} ++ , /* mmBRUSH_Y_X */ ++ {0x00007424, 0x00000002} ++ , /* mmDST_LINE_START */ ++ {0x00067425, 0x00000002} ++ , /* mmDST_LINE_END */ ++ {0x04002424, 0x00000002} ++ , /* mmDST_LINE_START */ ++ {0x00067425, 0x00000002} ++ , /* mmDST_LINE_END */ ++ {0x00000046, 0x00000004} ++ , ++ {0x00005000, 0x00000000} ++ , ++ {0x00061000, 0x00000002} ++ , ++ {0x0000740e, 0x00000002} ++ , /* mmDST_Y_X */ ++ {0x00019000, 0x00000002} ++ , ++ {0x00011050, 0x00000014} ++ , ++ {0x00000050, 0x00000012} ++ , ++ {0x0400240f, 0x00000002} ++ , /* mmDST_HEIGHT_WIDTH */ ++ {0x0000504a, 0x00000004} ++ , ++ {0x00007465, 0x00000002} ++ , /* mmDST_X_Y */ ++ {0x00007466, 0x00000002} ++ , /* mmDST_WIDTH_HEIGHT */ ++ {0x00000051, 0x00000004} ++ , ++ {0x01e65473, 0x00000002} ++ , /* mmDP_CNTL_DST_DIR */ ++ {0x4401b0b9, 0x00000002} ++ , ++ {0x01c110b9, 0x00000002} ++ , ++ {0x2666705d, 0x00000018} ++ , ++ {0x040c2465, 0x00000002} ++ , /* mmDST_X_Y */ ++ {0x0000005d, 0x00000018} ++ , ++ {0x04002464, 0x00000002} ++ , /* mmSRC_X_Y */ ++ {0x00007466, 0x00000002} ++ , /* mmDST_WIDTH_HEIGHT */ ++ {0x00000054, 0x00000004} ++ , ++ {0x00401060, 0x00000008} ++ , ++ {0x00101000, 0x00000002} ++ , ++ {0x000d80ff, 0x00000002} ++ , ++ {0x00800063, 0x00000008} ++ , ++ {0x000f9000, 0x00000002} ++ , ++ {0x000e00ff, 0x00000002} ++ , ++ {0x00000000, 0x00000006} ++ , ++ {0x00000080, 0x00000018} ++ , ++ {0x00000054, 0x00000004} ++ , ++ {0x00007490, 0x00000002} ++ , /* mmDP_SRC_FRGD_CLR */ ++ {0x00065000, 0x00000002} ++ , ++ {0x00009000, 0x00000002} ++ , ++ {0x00041000, 0x00000002} ++ , ++ {0x0c00340e, 0x00000002} ++ , /* mmDST_Y_X */ ++ {0x00049000, 0x00000002} ++ , ++ {0x00051000, 0x00000002} ++ , ++ {0x01e784f8, 0x00000002} ++ , ++ {0x00200000, 0x00000002} ++ , ++ {0x00600073, 0x0000000c} ++ , ++ {0x00007463, 0x00000002} ++ , /* mmDST_HEIGHT_WIDTH_8 */ ++ {0x006074f0, 0x00000021} ++ , /* mmHOST_DATA0 */ ++ {0x20007068, 0x00000004} ++ , ++ {0x00005068, 0x00000004} ++ , ++ {0x00007490, 0x00000002} ++ , /* mmDP_SRC_FRGD_CLR */ ++ {0x00007491, 0x00000002} ++ , /* mmDP_SRC_BKGD_CLR */ ++ {0x0000740e, 0x00000002} ++ , /* mmDST_Y_X */ ++ {0x0000740f, 0x00000002} ++ , /* mmDST_HEIGHT_WIDTH */ ++ {0x00a05000, 0x00000002} ++ , ++ {0x00600076, 0x0000000c} ++ , ++ {0x006074f0, 0x00000021} ++ , /* mmHOST_DATA0 */ ++ {0x000074f8, 0x00000002} ++ , /* mmHOST_DATA_LAST */ ++ {0x00000076, 0x00000004} ++ , ++ {0x000a740e, 0x00000002} ++ , /* mmDST_Y_X */ ++ {0x0020740f, 0x00000002} ++ , /* mmDST_HEIGHT_WIDTH */ ++ {0x00600079, 0x00000004} ++ , ++ {0x0000748c, 0x00000002} ++ , /* mmCLR_CMP_CNTL */ ++ {0x0000748d, 0x00000002} ++ , /* mmCLR_CMP_CLR_SRC */ ++ {0x0000748e, 0x00000006} ++ , /* mmCLR_CMP_CLR_DST */ ++ {0x00005000, 0x00000002} ++ , ++ {0x00a05000, 0x00000002} ++ , ++ {0x00007468, 0x00000002} ++ , /* mmDST_HEIGHT_Y */ ++ {0x00061000, 0x00000002} ++ , ++ {0x00000084, 0x0000000c} ++ , ++ {0x00058000, 0x00000002} ++ , ++ {0x0c607462, 0x00000002} ++ , /* mmDST_WIDTH_X */ ++ {0x00000086, 0x00000004} ++ , ++ {0x00600085, 0x00000004} ++ , ++ {0x400070ba, 0x00000000} ++ , ++ {0x000380ba, 0x00000002} ++ , ++ {0x00000093, 0x0000001c} ++ , ++ {0x00065095, 0x00000018} ++ , ++ {0x0400246f, 0x00000002} ++ , /* mmSC_TOP_LEFT */ ++ {0x00061096, 0x00000018} ++ , ++ {0x04007470, 0x00000000} ++ , /* mmSC_BOTTOM_RIGHT */ ++ {0x0000746f, 0x00000002} ++ , /* mmSC_TOP_LEFT */ ++ {0x00007470, 0x00000000} ++ , /* mmSC_BOTTOM_RIGHT */ ++ {0x00090000, 0x00000006} ++ , ++ {0x00090000, 0x00000002} ++ , ++ {0x000d8002, 0x00000006} ++ , ++ {0x01200000, 0x00000002} ++ , ++ {0x20077000, 0x00000002} ++ , ++ {0x01200000, 0x00000002} ++ , ++ {0x20007000, 0x00000002} ++ , ++ {0x00061000, 0x00000002} ++ , ++ {0x0120741b, 0x00000002} ++ , /* mmDP_GUI_MASTER_CNTL */ ++ {0x8040740a, 0x00000002} ++ , /* mmSRC_PITCH_OFFSET */ ++ {0x8040740b, 0x00000002} ++ , /* mmDST_PITCH_OFFSET */ ++ {0x00110000, 0x00000002} ++ , ++ {0x000380ba, 0x00000002} ++ , ++ {0x000000aa, 0x0000001c} ++ , ++ {0x00061096, 0x00000018} ++ , ++ {0x84407471, 0x00000002} ++ , /* mmSRC_SC_BOTTOM_RIGHT */ ++ {0x00061095, 0x00000018} ++ , ++ {0x8400746f, 0x00000002} ++ , /* mmSC_TOP_LEFT */ ++ {0x00061096, 0x00000018} ++ , ++ {0x84407470, 0x00000002} ++ , /* mmSC_BOTTOM_RIGHT */ ++ {0x000000ad, 0x00000004} ++ , ++ {0x80407471, 0x00000002} ++ , /* mmSRC_SC_BOTTOM_RIGHT */ ++ {0x8000746f, 0x00000002} ++ , /* mmSC_TOP_LEFT */ ++ {0x80407470, 0x00000002} ++ , /* mmSC_BOTTOM_RIGHT */ ++ {0x00108000, 0x00000002} ++ , ++ {0x01400000, 0x00000002} ++ , ++ {0x006000b1, 0x0000000c} ++ , ++ {0x20c07000, 0x00000020} ++ , ++ {0x000000b3, 0x00000012} ++ , ++ {0x00800000, 0x00000006} ++ , ++ {0x0080741d, 0x00000006} ++ , /* mmBRUSH_Y_X */ ++ {0x00000000, 0x00000000} ++ , ++ {0x00000001, 0x00000000} ++ , ++ {0x000380b5, 0x00000002} ++ , ++ {0x04002054, 0x00000002} ++ , /* mmNQWAIT_UNTIL */ ++ {0x00005000, 0x00000000} ++ , ++ {0x00000000, 0x00000000} ++ , ++ {0x00000000, 0x00000000} ++ , ++ {0x00000000, 0x00000000} ++ , ++ {0x00000000, 0x00000000} ++ , ++ {0x00000000, 0x00000000} ++ , ++ {0x00000000, 0x00000000} ++ , ++ {0x00000000, 0x00000000} ++}; +Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_stub.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_stub.c 2006-09-02 11:47:21.000000000 +0200 +@@ -0,0 +1,103 @@ ++/* ++ * Copyright © 2006 Alberto Mardegan ++ * ++ * Permission to use, copy, modify, distribute, and sell this software and its ++ * documentation for any purpose is hereby granted without fee, provided that ++ * the above copyright notice appear in all copies and that both that ++ * copyright notice and this permission notice appear in supporting ++ * documentation, and that the name of Alberto Mardegan not be used in ++ * advertising or publicity pertaining to distribution of the software without ++ * specific, written prior permission. Alberto Mardegan makes no ++ * representations about the suitability of this software for any purpose. It ++ * is provided "as is" without express or implied warranty. ++ * ++ * ALBERTO MARDEGAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO ++ * EVENT SHALL ALBERTO MARDEGAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR ++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, ++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER ++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++ * PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++#include "ati.h" ++#include "w100_regs.h" ++#include "klinux.h" ++ ++extern struct pci_id_entry ati_pci_ids[]; ++ ++static Bool ++FindW100(CARD16 vendor, CARD16 device, CARD32 count, KdCardAttr * attr) ++{ ++ char *mmio; ++ CARD32 chip_id; ++ Bool found = FALSE; ++ ++ mmio = KdMapDevice(ATI_REG_BASE(0), ATI_REG_SIZE(0)); ++ KdSetMappedMode((CARD32) mmio, ATI_REG_SIZE(0), ++ KD_MAPPED_MODE_REGISTERS); ++ ++ chip_id = MMIO_IN32(mmio, mmCHIP_ID); ++ if ((vendor | (device << 16)) == chip_id) { ++ ErrorF("Found Chip ID: %08x\n\n", chip_id); ++ attr->deviceID = device; ++ attr->vendorID = vendor; ++ found = TRUE; ++ } ++ KdUnmapDevice(mmio, ATI_REG_SIZE(0)); ++ return found; ++} ++ ++ ++void ++InitCard(char *name) ++{ ++ struct pci_id_entry *id; ++ KdCardAttr attr; ++ ++ for (id = ati_pci_ids; id->name != NULL; id++) { ++ int j = 0; ++ if (FindW100(id->vendor, id->device, j++, &attr)) ++ KdCardInfoAdd(&ATIFuncs, &attr, 0); ++ } ++} ++ ++void ++InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) ++{ ++ KdInitOutput(pScreenInfo, argc, argv); ++} ++ ++void ++InitInput(int argc, char **argv) ++{ ++ KdInitInput(&LinuxMouseFuncs, &LinuxKeyboardFuncs); ++#ifdef TOUCHSCREEN ++ KdAddMouseDriver(&TsFuncs); ++#endif ++} ++ ++void ++ddxUseMsg(void) ++{ ++ KdUseMsg(); ++#ifdef KDRIVEVESA ++ vesaUseMsg(); ++#endif ++} ++ ++int ++ddxProcessArgument(int argc, char **argv, int i) ++{ ++ int ret; ++ ++#ifdef KDRIVEVESA ++ if (!(ret = vesaProcessArgument(argc, argv, i))) ++#endif ++ ret = KdProcessArgument(argc, argv, i); ++ ++ return ret; ++} +Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/Makefile.am +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/Makefile.am 2006-09-02 11:47:21.000000000 +0200 +@@ -0,0 +1,53 @@ ++if KDRIVEFBDEV ++FBDEV_INCLUDES =-I$(top_srcdir)/hw/kdrive/fbdev ++FBDEV_LIBS = $(top_builddir)/hw/kdrive/fbdev/libfbdev.a ++endif ++ ++if KDRIVEVESA ++VESA_INCLUDES = -I$(top_srcdir)/hw/kdrive/vesa ++VESA_LIBS = $(top_builddir)/hw/kdrive/vesa/libvesa.a ++endif ++ ++INCLUDES = \ ++ @KDRIVE_INCS@ \ ++ $(FBDEV_INCLUDES) \ ++ $(VESA_INCLUDES) \ ++ @KDRIVE_CFLAGS@ ++ ++bin_PROGRAMS = Xw100 ++ ++if TSLIB ++TSLIB_FLAG = -lts ++endif ++ ++noinst_LIBRARIES = libw100.a ++ ++libw100_a_SOURCES = \ ++ ati_cursor.c \ ++ ati_dma.c \ ++ ati_dma.h \ ++ ati_draw.c \ ++ ati_draw.h \ ++ ati_microcode.c \ ++ ati.c \ ++ ati.h \ ++ w100_regs.h \ ++ w100_const.h ++ ++Xw100_SOURCES = \ ++ ati_stub.c ++ ++W100_LIBS = \ ++ libw100.a \ ++ $(FBDEV_LIBS) \ ++ $(VESA_LIBS) \ ++ $(DRI_LIBS) \ ++ @KDRIVE_LIBS@ ++ ++Xw100_LDADD = \ ++ $(W100_LIBS) \ ++ @XSERVER_LIBS@ \ ++ $(TSLIB_FLAG) ++ ++ ++Xw100_DEPENDENCIES = $(W100_LIBS) @KDRIVE_LIBS@ +Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/w100_const.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/w100_const.h 2006-09-02 11:47:21.000000000 +0200 +@@ -0,0 +1,25 @@ ++#define CSQ_CNTL_MODE_FREERUN 0x8 ++ ++#define WB_BLOCK_SIZE_A_0 0 ++#define WB_BLOCK_SIZE_A_1 1 ++#define WB_BLOCK_SIZE_A_2 2 ++#define WB_BLOCK_SIZE_A_3 3 ++#define WB_BLOCK_SIZE_A_4 4 ++ ++#define DATATYPE_8BPP 2 ++#define DATATYPE_ARGB1555 3 ++#define DATATYPE_ARGB4444 5 ++ ++#define BRUSH_SOLIDCOLOR 13 ++#define BRUSH_NONE 15 ++ ++#define OP_ROP 0 ++#define OP_ARITHMETIC 1 ++ ++#define SOURCE_MEM_RECTANGULAR 2 ++ ++#define W100_MAXINT 0x1fff ++ ++#define W100_CCE_PACKET3_PAINT_MULTI 0xc0001a00 ++#define W100_CCE_PACKET3_BITBLT_MULTI 0xc0001b00 ++ +Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/w100_regs.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/w100_regs.h 2006-09-02 11:47:21.000000000 +0200 +@@ -0,0 +1,3802 @@ ++#ifndef _W100_REGS_H_ ++#define _W100_REGS_H_ ++ ++/* Block CIF Start: */ ++#define mmCHIP_ID 0x0000 ++#define mmREVISION_ID 0x0004 ++#define mmWRAP_BUF_A 0x0008 ++#define mmWRAP_BUF_B 0x000C ++#define mmWRAP_TOP_DIR 0x0010 ++#define mmWRAP_START_DIR 0x0014 ++#define mmCIF_CNTL 0x0018 ++#define mmCFGREG_BASE 0x001C ++#define mmCIF_IO 0x0020 ++#define mmCIF_READ_DBG 0x0024 ++#define mmCIF_WRITE_DBG 0x0028 ++#define cfgIND_ADDR_A_0 0x0000 ++#define cfgIND_ADDR_A_1 0x0001 ++#define cfgIND_ADDR_A_2 0x0002 ++#define cfgIND_DATA_A 0x0003 ++#define cfgREG_BASE 0x0004 ++#define cfgINTF_CNTL 0x0005 ++#define cfgSTATUS 0x0006 ++#define cfgCPU_DEFAULTS 0x0007 ++#define cfgIND_ADDR_B_0 0x0008 ++#define cfgIND_ADDR_B_1 0x0009 ++#define cfgIND_ADDR_B_2 0x000A ++#define cfgIND_DATA_B 0x000B ++#define cfgPM4_RPTR 0x000C ++#define cfgSCRATCH 0x000D ++#define cfgPM4_WRPTR_0 0x000E ++#define cfgPM4_WRPTR_1 0x000F ++/* Block CIF End: */ ++ ++/* Block CP Start: */ ++#define mmCP_RB_CNTL 0x0210 ++#define mmCP_RB_BASE 0x0214 ++#define mmCP_RB_RPTR_ADDR 0x0218 ++#define mmCP_RB_RPTR 0x021C ++#define mmCP_RB_RPTR_WR 0x02F8 ++#define mmCP_RB_WPTR 0x0220 ++#define mmCP_IB_BASE 0x0228 ++#define mmCP_IB_BUFSZ 0x022C ++#define mmCP_CSQ_CNTL 0x0230 ++#define mmCP_CSQ_APER_PRIMARY 0x0300 ++#define mmCP_CSQ_APER_INDIRECT 0x0340 ++#define mmCP_ME_CNTL 0x0240 ++#define mmCP_ME_RAM_ADDR 0x0244 ++#define mmCP_ME_RAM_RADDR 0x0248 ++#define mmCP_ME_RAM_DATAH 0x024C ++#define mmCP_ME_RAM_DATAL 0x0250 ++#define mmCP_DEBUG 0x025C ++#define mmSCRATCH_REG0 0x0260 ++#define mmSCRATCH_REG1 0x0264 ++#define mmSCRATCH_REG2 0x0268 ++#define mmSCRATCH_REG3 0x026C ++#define mmSCRATCH_REG4 0x0270 ++#define mmSCRATCH_REG5 0x0274 ++#define mmSCRATCH_UMSK 0x0280 ++#define mmSCRATCH_ADDR 0x0284 ++#define mmCP_CSQ_ADDR 0x02E4 ++#define mmCP_CSQ_DATA 0x02E8 ++#define mmCP_CSQ_STAT 0x02EC ++#define mmCP_STAT 0x02F0 ++#define mmGEN_INT_CNTL 0x0200 ++#define mmGEN_INT_STATUS 0x0204 ++/* Block CP End: */ ++ ++/* Block DISPLAY Start: */ ++#define mmLCD_FORMAT 0x0410 ++#define mmGRAPHIC_CTRL 0x0414 ++#define mmGRAPHIC_OFFSET 0x0418 ++#define mmGRAPHIC_PITCH 0x041C ++#define mmCRTC_TOTAL 0x0420 ++#define mmACTIVE_H_DISP 0x0424 ++#define mmACTIVE_V_DISP 0x0428 ++#define mmGRAPHIC_H_DISP 0x042C ++#define mmGRAPHIC_V_DISP 0x0430 ++#define mmVIDEO_CTRL 0x0434 ++#define mmGRAPHIC_KEY 0x0438 ++#define mmVIDEO_Y_OFFSET 0x043C ++#define mmVIDEO_Y_PITCH 0x0440 ++#define mmVIDEO_U_OFFSET 0x0444 ++#define mmVIDEO_U_PITCH 0x0448 ++#define mmVIDEO_V_OFFSET 0x044C ++#define mmVIDEO_V_PITCH 0x0450 ++#define mmVIDEO_H_POS 0x0454 ++#define mmVIDEO_V_POS 0x0458 ++#define mmBRIGHTNESS_CNTL 0x045C ++#define mmCURSOR1_OFFSET 0x0460 ++#define mmCURSOR1_H_POS 0x0464 ++#define mmCURSOR1_V_POS 0x0468 ++#define mmCURSOR1_COLOR0 0x046C ++#define mmCURSOR1_COLOR1 0x0470 ++#define mmCURSOR2_OFFSET 0x0474 ++#define mmCURSOR2_H_POS 0x0478 ++#define mmCURSOR2_V_POS 0x047C ++#define mmCURSOR2_COLOR0 0x0480 ++#define mmCURSOR2_COLOR1 0x0484 ++#define mmDISP_INT_CNTL 0x0488 ++#define mmCRTC_SS 0x048C ++#define mmCRTC_LS 0x0490 ++#define mmCRTC_REV 0x0494 ++#define mmCRTC_DCLK 0x049C ++#define mmCRTC_GS 0x04A0 ++#define mmCRTC_VPOS_GS 0x04A4 ++#define mmCRTC_GCLK 0x04A8 ++#define mmCRTC_GOE 0x04AC ++#define mmCRTC_FRAME 0x04B0 ++#define mmCRTC_FRAME_VPOS 0x04B4 ++#define mmGPIO_DATA 0x04B8 ++#define mmGPIO_CNTL1 0x04BC ++#define mmGPIO_CNTL2 0x04C0 ++#define mmLCDD_CNTL1 0x04C4 ++#define mmLCDD_CNTL2 0x04C8 ++#define mmGENLCD_CNTL1 0x04CC ++#define mmGENLCD_CNTL2 0x04D0 ++#define mmDISP_DEBUG 0x04D4 ++#define mmDISP_DB_BUF_CNTL 0x04D8 ++#define mmDISP_CRC_SIG 0x04DC ++#define mmCRTC_DEFAULT_COUNT 0x04E0 ++#define mmLCD_BACKGROUND_COLOR 0x04E4 ++#define mmCRTC_PS2 0x04E8 ++#define mmCRTC_PS2_VPOS 0x04EC ++#define mmCRTC_PS1_ACTIVE 0x04F0 ++#define mmCRTC_PS1_NACTIVE 0x04F4 ++#define mmCRTC_GCLK_EXT 0x04F8 ++#define mmCRTC_ALW 0x04FC ++#define mmCRTC_ALW_VPOS 0x0500 ++#define mmCRTC_PSK 0x0504 ++#define mmCRTC_PSK_HPOS 0x0508 ++#define mmCRTC_CV4_START 0x050C ++#define mmCRTC_CV4_END 0x0510 ++#define mmCRTC_CV4_HPOS 0x0514 ++#define mmCRTC_ECK 0x051C ++#define mmREFRESH_CNTL 0x0520 ++#define mmGENLCD_CNTL3 0x0524 ++#define mmGPIO_DATA2 0x0528 ++#define mmGPIO_CNTL3 0x052C ++#define mmGPIO_CNTL4 0x0530 ++#define mmCHIP_STRAP 0x0534 ++#define mmDISP_DEBUG2 0x0538 ++#define mmDEBUG_BUS_CNTL 0x053C ++#define mmGAMMA_VALUE1 0x0540 ++#define mmGAMMA_VALUE2 0x0544 ++#define mmGAMMA_SLOPE 0x0548 ++#define mmGEN_STATUS 0x054C ++#define mmHW_INT 0x0550 ++/* Block DISPLAY End: */ ++ ++/* Block GFX Start: */ ++#define mmDST_OFFSET 0x1004 ++#define mmDST_PITCH 0x1008 ++#define mmDST_PITCH_OFFSET 0x102C ++#define mmDST_X 0x101C ++#define mmDST_Y 0x1020 ++#define mmDST_X_Y 0x1194 ++#define mmDST_Y_X 0x1038 ++#define mmDST_WIDTH 0x100C ++#define mmDST_HEIGHT 0x1010 ++#define mmDST_WIDTH_HEIGHT 0x1198 ++#define mmDST_HEIGHT_WIDTH 0x103C ++#define mmDST_HEIGHT_WIDTH_8 0x118C ++#define mmDST_HEIGHT_Y 0x11A0 ++#define mmDST_WIDTH_X 0x1188 ++#define mmDST_WIDTH_X_INCY 0x119C ++#define mmDST_LINE_START 0x1090 ++#define mmDST_LINE_END 0x1094 ++#define mmBRUSH_OFFSET 0x108C ++#define mmBRUSH_Y_X 0x1074 ++#define mmDP_BRUSH_FRGD_CLR 0x107C ++#define mmDP_BRUSH_BKGD_CLR 0x1078 ++#define mmSRC2_OFFSET 0x1060 ++#define mmSRC2_PITCH 0x1064 ++#define mmSRC2_PITCH_OFFSET 0x1068 ++#define mmSRC2_X 0x1050 ++#define mmSRC2_Y 0x1054 ++#define mmSRC2_X_Y 0x1058 ++#define mmSRC2_WIDTH 0x1080 ++#define mmSRC2_HEIGHT 0x1084 ++#define mmSRC2_INC 0x1088 ++#define mmSRC_OFFSET 0x11AC ++#define mmSRC_PITCH 0x11B0 ++#define mmSRC_PITCH_OFFSET 0x1028 ++#define mmSRC_X 0x1014 ++#define mmSRC_Y 0x1018 ++#define mmSRC_X_Y 0x1190 ++#define mmSRC_Y_X 0x1034 ++#define mmSRC_WIDTH 0x1040 ++#define mmSRC_HEIGHT 0x1044 ++#define mmSRC_INC 0x1048 ++#define mmHOST_DATA0 0x13C0 ++#define mmHOST_DATA1 0x13C4 ++#define mmHOST_DATA2 0x13C8 ++#define mmHOST_DATA3 0x13CC ++#define mmHOST_DATA4 0x13D0 ++#define mmHOST_DATA5 0x13D4 ++#define mmHOST_DATA6 0x13D8 ++#define mmHOST_DATA7 0x13DC ++#define mmHOST_DATA_LAST 0x13E0 ++#define mmDP_SRC_FRGD_CLR 0x1240 ++#define mmDP_SRC_BKGD_CLR 0x1244 ++#define mmSC_LEFT 0x1140 ++#define mmSC_RIGHT 0x1144 ++#define mmSC_TOP 0x1148 ++#define mmSC_BOTTOM 0x114C ++#define mmSRC_SC_RIGHT 0x1154 ++#define mmSRC_SC_BOTTOM 0x115C ++#define mmDP_CNTL 0x11C8 ++#define mmDP_CNTL_DST_DIR 0x11CC ++#define mmDP_DATATYPE 0x12C4 ++#define mmDP_MIX 0x12C8 ++#define mmDP_WRITE_MSK 0x12CC ++#define mmCLR_CMP_CLR_SRC 0x1234 ++#define mmCLR_CMP_CLR_DST 0x1238 ++#define mmCLR_CMP_CNTL 0x1230 ++#define mmCLR_CMP_MSK 0x123C ++#define mmDEFAULT_PITCH_OFFSET 0x10A0 ++#define mmDEFAULT_SC_BOTTOM_RIGHT 0x10A8 ++#define mmDEFAULT2_SC_BOTTOM_RIGHT 0x10AC ++#define mmREF1_PITCH_OFFSET 0x10B8 ++#define mmREF2_PITCH_OFFSET 0x10BC ++#define mmREF3_PITCH_OFFSET 0x10C0 ++#define mmREF4_PITCH_OFFSET 0x10C4 ++#define mmREF5_PITCH_OFFSET 0x10C8 ++#define mmREF6_PITCH_OFFSET 0x10CC ++#define mmDP_GUI_MASTER_CNTL 0x106C ++#define mmSC_TOP_LEFT 0x11BC ++#define mmSC_BOTTOM_RIGHT 0x11C0 ++#define mmSRC_SC_BOTTOM_RIGHT 0x11C4 ++#define mmGLOBAL_ALPHA 0x1210 ++#define mmFILTER_COEF 0x1214 ++#define mmMVC_CNTL_START 0x11E0 ++#define mmE2_ARITHMETIC_CNTL 0x1220 ++#define mmDEBUG0 0x1280 ++#define mmDEBUG1 0x1284 ++#define mmDEBUG2 0x1288 ++#define mmDEBUG3 0x128C ++#define mmDEBUG4 0x1290 ++#define mmDEBUG5 0x1294 ++#define mmDEBUG6 0x1298 ++#define mmDEBUG7 0x129C ++#define mmDEBUG8 0x12A0 ++#define mmDEBUG9 0x12A4 ++#define mmDEBUG10 0x12A8 ++#define mmDEBUG11 0x12AC ++#define mmDEBUG12 0x12B0 ++#define mmDEBUG13 0x12B4 ++#define mmDEBUG14 0x12B8 ++#define mmDEBUG15 0x12BC ++#define mmENG_CNTL 0x13E8 ++#define mmENG_PERF_CNT 0x13F0 ++/* Block GFX End: */ ++ ++/* Block IDCT Start: */ ++#define mmIDCT_RUNS 0x0C00 ++#define mmIDCT_LEVELS 0x0C04 ++#define mmIDCT_CONTROL 0x0C3C ++#define mmIDCT_AUTH_CONTROL 0x0C08 ++#define mmIDCT_AUTH 0x0C0C ++/* Block IDCT End: */ ++ ++/* Block MC Start: */ ++#define mmMEM_CNTL 0x0180 ++#define mmMEM_ARB 0x0184 ++#define mmMC_FB_LOCATION 0x0188 ++#define mmMEM_EXT_CNTL 0x018C ++#define mmMC_EXT_MEM_LOCATION 0x0190 ++#define mmMEM_EXT_TIMING_CNTL 0x0194 ++#define mmMEM_SDRAM_MODE_REG 0x0198 ++#define mmMEM_IO_CNTL 0x019C ++#define mmMC_DEBUG 0x01A0 ++#define mmMC_BIST_CTRL 0x01A4 ++#define mmMC_BIST_COLLAR_READ 0x01A8 ++#define mmTC_MISMATCH 0x01AC ++#define mmMC_PERF_MON_CNTL 0x01B0 ++#define mmMC_PERF_COUNTERS 0x01B4 ++/* Block MC End: */ ++ ++/* Block RBBM Start: */ ++#define mmWAIT_UNTIL 0x1400 ++#define mmISYNC_CNTL 0x1404 ++#define mmRBBM_GUICNTL 0x1408 ++#define mmRBBM_STATUS 0x0140 ++#define mmRBBM_STATUS_alt_1 0x140C ++#define mmRBBM_CNTL 0x0144 ++#define mmRBBM_SOFT_RESET 0x0148 ++#define mmNQWAIT_UNTIL 0x0150 ++#define mmRBBM_DEBUG 0x016C ++#define mmRBBM_CMDFIFO_ADDR 0x0170 ++#define mmRBBM_CMDFIFO_DATAL 0x0174 ++#define mmRBBM_CMDFIFO_DATAH 0x0178 ++#define mmRBBM_CMDFIFO_STAT 0x017C ++/* Block RBBM End: */ ++ ++/* Block CG Start: */ ++#define mmCLK_PIN_CNTL 0x0080 ++#define mmPLL_REF_FB_DIV 0x0084 ++#define mmPLL_CNTL 0x0088 ++#define mmSCLK_CNTL 0x008C ++#define mmPCLK_CNTL 0x0090 ++#define mmCLK_TEST_CNTL 0x0094 ++#define mmPWRMGT_CNTL 0x0098 ++#define mmPWRMGT_STATUS 0x009C ++/* Block CG End: */ ++ ++ ++/* data structure definitions */ ++ ++typedef struct _chip_id_t { ++ unsigned long vendor_id : 16; ++ unsigned long device_id : 16; ++ } chip_id_t; ++ ++typedef union { ++ unsigned long val : 32; ++ chip_id_t f; ++} chip_id_u; ++ ++typedef struct _revision_id_t { ++ unsigned long minor_rev_id : 4; ++ unsigned long major_rev_id : 4; ++ unsigned long : 24; ++ } revision_id_t; ++ ++typedef union { ++ unsigned long val : 32; ++ revision_id_t f; ++} revision_id_u; ++ ++typedef struct _wrap_buf_a_t { ++ unsigned long offset_addr_a : 24; ++ unsigned long block_size_a : 3; ++ unsigned long : 5; ++ } wrap_buf_a_t; ++ ++typedef union { ++ unsigned long val : 32; ++ wrap_buf_a_t f; ++} wrap_buf_a_u; ++ ++typedef struct _wrap_buf_b_t { ++ unsigned long offset_addr_b : 24; ++ unsigned long block_size_b : 3; ++ unsigned long : 5; ++ } wrap_buf_b_t; ++ ++typedef union { ++ unsigned long val : 32; ++ wrap_buf_b_t f; ++} wrap_buf_b_u; ++ ++typedef struct _wrap_top_dir_t { ++ unsigned long top_addr : 23; ++ unsigned long : 9; ++ } wrap_top_dir_t; ++ ++typedef union { ++ unsigned long val : 32; ++ wrap_top_dir_t f; ++} wrap_top_dir_u; ++ ++typedef struct _wrap_start_dir_t { ++ unsigned long start_addr : 23; ++ unsigned long : 9; ++ } wrap_start_dir_t; ++ ++typedef union { ++ unsigned long val : 32; ++ wrap_start_dir_t f; ++} wrap_start_dir_u; ++ ++typedef struct _cif_cntl_t { ++ unsigned long swap_reg : 2; ++ unsigned long swap_fbuf_1 : 2; ++ unsigned long swap_fbuf_2 : 2; ++ unsigned long swap_fbuf_3 : 2; ++ unsigned long pmi_int_disable : 1; ++ unsigned long pmi_schmen_disable : 1; ++ unsigned long intb_oe : 1; ++ unsigned long en_wait_to_compensate_dq_prop_dly : 1; ++ unsigned long compensate_wait_rd_size : 2; ++ unsigned long wait_asserted_timeout_val : 2; ++ unsigned long wait_masked_val : 2; ++ unsigned long en_wait_timeout : 1; ++ unsigned long en_one_clk_setup_before_wait : 1; ++ unsigned long interrupt_active_high : 1; ++ unsigned long en_overwrite_straps : 1; ++ unsigned long strap_wait_active_hi : 1; ++ unsigned long lat_busy_count : 2; ++ unsigned long lat_rd_pm4_sclk_busy : 1; ++ unsigned long dis_system_bits : 1; ++ unsigned long dis_mr : 1; ++ unsigned long cif_spare_1 : 4; ++ } cif_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cif_cntl_t f; ++} cif_cntl_u; ++ ++typedef struct _cfgreg_base_t { ++ unsigned long cfgreg_base : 24; ++ unsigned long : 8; ++ } cfgreg_base_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cfgreg_base_t f; ++} cfgreg_base_u; ++ ++typedef struct _cif_io_t { ++ unsigned long dq_srp : 1; ++ unsigned long dq_srn : 1; ++ unsigned long dq_sp : 4; ++ unsigned long dq_sn : 4; ++ unsigned long waitb_srp : 1; ++ unsigned long waitb_srn : 1; ++ unsigned long waitb_sp : 4; ++ unsigned long waitb_sn : 4; ++ unsigned long intb_srp : 1; ++ unsigned long intb_srn : 1; ++ unsigned long intb_sp : 4; ++ unsigned long intb_sn : 4; ++ unsigned long : 2; ++ } cif_io_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cif_io_t f; ++} cif_io_u; ++ ++typedef struct _cif_read_dbg_t { ++ unsigned long unpacker_pre_fetch_trig_gen : 2; ++ unsigned long dly_second_rd_fetch_trig : 1; ++ unsigned long rst_rd_burst_id : 1; ++ unsigned long dis_rd_burst_id : 1; ++ unsigned long en_block_rd_when_packer_is_not_emp : 1; ++ unsigned long dis_pre_fetch_cntl_sm : 1; ++ unsigned long rbbm_chrncy_dis : 1; ++ unsigned long rbbm_rd_after_wr_lat : 2; ++ unsigned long dis_be_during_rd : 1; ++ unsigned long one_clk_invalidate_pulse : 1; ++ unsigned long dis_chnl_priority : 1; ++ unsigned long rst_read_path_a_pls : 1; ++ unsigned long rst_read_path_b_pls : 1; ++ unsigned long dis_reg_rd_fetch_trig : 1; ++ unsigned long dis_rd_fetch_trig_from_ind_addr : 1; ++ unsigned long dis_rd_same_byte_to_trig_fetch : 1; ++ unsigned long dis_dir_wrap : 1; ++ unsigned long dis_ring_buf_to_force_dec : 1; ++ unsigned long dis_addr_comp_in_16bit : 1; ++ unsigned long clr_w : 1; ++ unsigned long err_rd_tag_is_3 : 1; ++ unsigned long err_load_when_ful_a : 1; ++ unsigned long err_load_when_ful_b : 1; ++ unsigned long : 7; ++ } cif_read_dbg_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cif_read_dbg_t f; ++} cif_read_dbg_u; ++ ++typedef struct _cif_write_dbg_t { ++ unsigned long packer_timeout_count : 2; ++ unsigned long en_upper_load_cond : 1; ++ unsigned long en_chnl_change_cond : 1; ++ unsigned long dis_addr_comp_cond : 1; ++ unsigned long dis_load_same_byte_addr_cond : 1; ++ unsigned long dis_timeout_cond : 1; ++ unsigned long dis_timeout_during_rbbm : 1; ++ unsigned long dis_packer_ful_during_rbbm_timeout : 1; ++ unsigned long en_dword_split_to_rbbm : 1; ++ unsigned long en_dummy_val : 1; ++ unsigned long dummy_val_sel : 1; ++ unsigned long mask_pm4_wrptr_dec : 1; ++ unsigned long dis_mc_clean_cond : 1; ++ unsigned long err_two_reqi_during_ful : 1; ++ unsigned long err_reqi_during_idle_clk : 1; ++ unsigned long err_global : 1; ++ unsigned long en_wr_buf_dbg_load : 1; ++ unsigned long en_wr_buf_dbg_path : 1; ++ unsigned long sel_wr_buf_byte : 3; ++ unsigned long dis_rd_flush_wr : 1; ++ unsigned long dis_packer_ful_cond : 1; ++ unsigned long dis_invalidate_by_ops_chnl : 1; ++ unsigned long en_halt_when_reqi_err : 1; ++ unsigned long cif_spare_2 : 5; ++ unsigned long : 1; ++ } cif_write_dbg_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cif_write_dbg_t f; ++} cif_write_dbg_u; ++ ++typedef struct _ind_addr_a_0_t { ++ unsigned char ind_addr_a_0 : 8; ++ } ind_addr_a_0_t; ++ ++typedef union { ++ unsigned char val : 8; ++ ind_addr_a_0_t f; ++} ind_addr_a_0_u; ++ ++typedef struct _ind_addr_a_1_t { ++ unsigned char ind_addr_a_1 : 8; ++ } ind_addr_a_1_t; ++ ++typedef union { ++ unsigned char val : 8; ++ ind_addr_a_1_t f; ++} ind_addr_a_1_u; ++ ++typedef struct _ind_addr_a_2_t { ++ unsigned char ind_addr_a_2 : 8; ++ } ind_addr_a_2_t; ++ ++typedef union { ++ unsigned char val : 8; ++ ind_addr_a_2_t f; ++} ind_addr_a_2_u; ++ ++typedef struct _ind_data_a_t { ++ unsigned char ind_data_a : 8; ++ } ind_data_a_t; ++ ++typedef union { ++ unsigned char val : 8; ++ ind_data_a_t f; ++} ind_data_a_u; ++ ++typedef struct _reg_base_t { ++ unsigned char reg_base : 8; ++ } reg_base_t; ++ ++typedef union { ++ unsigned char val : 8; ++ reg_base_t f; ++} reg_base_u; ++ ++typedef struct _intf_cntl_t { ++ unsigned char ad_inc_a : 1; ++ unsigned char ring_buf_a : 1; ++ unsigned char rd_fetch_trigger_a : 1; ++ unsigned char rd_data_rdy_a : 1; ++ unsigned char ad_inc_b : 1; ++ unsigned char ring_buf_b : 1; ++ unsigned char rd_fetch_trigger_b : 1; ++ unsigned char rd_data_rdy_b : 1; ++ } intf_cntl_t; ++ ++typedef union { ++ unsigned char val : 8; ++ intf_cntl_t f; ++} intf_cntl_u; ++ ++typedef struct _status_t { ++ unsigned char wr_fifo_available_space : 2; ++ unsigned char fbuf_wr_pipe_emp : 1; ++ unsigned char soft_reset : 1; ++ unsigned char system_pwm_mode : 2; ++ unsigned char mem_access_dis : 1; ++ unsigned char en_pre_fetch : 1; ++ } status_t; ++ ++typedef union { ++ unsigned char val : 8; ++ status_t f; ++} status_u; ++ ++typedef struct _cpu_defaults_t { ++ unsigned char unpack_rd_data : 1; ++ unsigned char access_ind_addr_a : 1; ++ unsigned char access_ind_addr_b : 1; ++ unsigned char access_scratch_reg : 1; ++ unsigned char pack_wr_data : 1; ++ unsigned char transition_size : 1; ++ unsigned char en_read_buf_mode : 1; ++ unsigned char rd_fetch_scratch : 1; ++ } cpu_defaults_t; ++ ++typedef union { ++ unsigned char val : 8; ++ cpu_defaults_t f; ++} cpu_defaults_u; ++ ++typedef struct _ind_addr_b_0_t { ++ unsigned char ind_addr_b_0 : 8; ++ } ind_addr_b_0_t; ++ ++typedef union { ++ unsigned char val : 8; ++ ind_addr_b_0_t f; ++} ind_addr_b_0_u; ++ ++typedef struct _ind_addr_b_1_t { ++ unsigned char ind_addr_b_1 : 8; ++ } ind_addr_b_1_t; ++ ++typedef union { ++ unsigned char val : 8; ++ ind_addr_b_1_t f; ++} ind_addr_b_1_u; ++ ++typedef struct _ind_addr_b_2_t { ++ unsigned char ind_addr_b_2 : 8; ++ } ind_addr_b_2_t; ++ ++typedef union { ++ unsigned char val : 8; ++ ind_addr_b_2_t f; ++} ind_addr_b_2_u; ++ ++typedef struct _ind_data_b_t { ++ unsigned char ind_data_b : 8; ++ } ind_data_b_t; ++ ++typedef union { ++ unsigned char val : 8; ++ ind_data_b_t f; ++} ind_data_b_u; ++ ++typedef struct _pm4_rptr_t { ++ unsigned char pm4_rptr : 8; ++ } pm4_rptr_t; ++ ++typedef union { ++ unsigned char val : 8; ++ pm4_rptr_t f; ++} pm4_rptr_u; ++ ++typedef struct _scratch_t { ++ unsigned char scratch : 8; ++ } scratch_t; ++ ++typedef union { ++ unsigned char val : 8; ++ scratch_t f; ++} scratch_u; ++ ++typedef struct _pm4_wrptr_0_t { ++ unsigned char pm4_wrptr_0 : 8; ++ } pm4_wrptr_0_t; ++ ++typedef union { ++ unsigned char val : 8; ++ pm4_wrptr_0_t f; ++} pm4_wrptr_0_u; ++ ++typedef struct _pm4_wrptr_1_t { ++ unsigned char pm4_wrptr_1 : 6; ++ unsigned char rd_fetch_pm4_rptr : 1; ++ unsigned char wrptr_atomic_update_w : 1; ++ } pm4_wrptr_1_t; ++ ++typedef union { ++ unsigned char val : 8; ++ pm4_wrptr_1_t f; ++} pm4_wrptr_1_u; ++ ++typedef struct _cp_rb_cntl_t { ++ unsigned long rb_bufsz : 6; ++ unsigned long : 2; ++ unsigned long rb_blksz : 6; ++ unsigned long : 2; ++ unsigned long buf_swap : 2; ++ unsigned long max_fetch : 2; ++ unsigned long : 7; ++ unsigned long rb_no_update : 1; ++ unsigned long : 3; ++ unsigned long rb_rptr_wr_ena : 1; ++ } cp_rb_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_rb_cntl_t f; ++} cp_rb_cntl_u; ++ ++typedef struct _cp_rb_base_t { ++ unsigned long : 2; ++ unsigned long rb_base : 22; ++ unsigned long : 8; ++ } cp_rb_base_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_rb_base_t f; ++} cp_rb_base_u; ++ ++typedef struct _cp_rb_rptr_addr_t { ++ unsigned long rb_rptr_swap : 2; ++ unsigned long rb_rptr_addr : 22; ++ unsigned long : 8; ++ } cp_rb_rptr_addr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_rb_rptr_addr_t f; ++} cp_rb_rptr_addr_u; ++ ++typedef struct _cp_rb_rptr_t { ++ unsigned long rb_rptr : 23; ++ unsigned long : 9; ++ } cp_rb_rptr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_rb_rptr_t f; ++} cp_rb_rptr_u; ++ ++typedef struct _cp_rb_rptr_wr_t { ++ unsigned long rb_rptr_wr : 23; ++ unsigned long : 9; ++ } cp_rb_rptr_wr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_rb_rptr_wr_t f; ++} cp_rb_rptr_wr_u; ++ ++typedef struct _cp_rb_wptr_t { ++ unsigned long rb_wptr : 23; ++ unsigned long : 9; ++ } cp_rb_wptr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_rb_wptr_t f; ++} cp_rb_wptr_u; ++ ++typedef struct _cp_ib_base_t { ++ unsigned long : 2; ++ unsigned long ib_base : 22; ++ unsigned long : 8; ++ } cp_ib_base_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_ib_base_t f; ++} cp_ib_base_u; ++ ++typedef struct _cp_ib_bufsz_t { ++ unsigned long ib_bufsz : 23; ++ unsigned long : 9; ++ } cp_ib_bufsz_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_ib_bufsz_t f; ++} cp_ib_bufsz_u; ++ ++typedef struct _cp_csq_cntl_t { ++ unsigned long csq_cnt_primary : 8; ++ unsigned long csq_cnt_indirect : 8; ++ unsigned long : 12; ++ unsigned long csq_mode : 4; ++ } cp_csq_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_csq_cntl_t f; ++} cp_csq_cntl_u; ++ ++typedef struct _cp_csq_aper_primary_t { ++ unsigned long cp_csq_aper_primary : 32; ++ } cp_csq_aper_primary_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_csq_aper_primary_t f; ++} cp_csq_aper_primary_u; ++ ++typedef struct _cp_csq_aper_indirect_t { ++ unsigned long cp_csq_aper_indirect : 32; ++ } cp_csq_aper_indirect_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_csq_aper_indirect_t f; ++} cp_csq_aper_indirect_u; ++ ++typedef struct _cp_me_cntl_t { ++ unsigned long me_stat : 16; ++ unsigned long me_statmux : 5; ++ unsigned long : 8; ++ unsigned long me_busy : 1; ++ unsigned long me_mode : 1; ++ unsigned long me_step : 1; ++ } cp_me_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_me_cntl_t f; ++} cp_me_cntl_u; ++ ++typedef struct _cp_me_ram_addr_t { ++ unsigned long me_ram_addr : 8; ++ unsigned long : 24; ++ } cp_me_ram_addr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_me_ram_addr_t f; ++} cp_me_ram_addr_u; ++ ++typedef struct _cp_me_ram_raddr_t { ++ unsigned long me_ram_raddr : 8; ++ unsigned long : 24; ++ } cp_me_ram_raddr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_me_ram_raddr_t f; ++} cp_me_ram_raddr_u; ++ ++typedef struct _cp_me_ram_datah_t { ++ unsigned long me_ram_datah : 6; ++ unsigned long : 26; ++ } cp_me_ram_datah_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_me_ram_datah_t f; ++} cp_me_ram_datah_u; ++ ++typedef struct _cp_me_ram_datal_t { ++ unsigned long me_ram_datal : 32; ++ } cp_me_ram_datal_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_me_ram_datal_t f; ++} cp_me_ram_datal_u; ++ ++typedef struct _cp_debug_t { ++ unsigned long cp_debug : 32; ++ } cp_debug_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_debug_t f; ++} cp_debug_u; ++ ++typedef struct _scratch_reg0_t { ++ unsigned long scratch_reg0 : 32; ++ } scratch_reg0_t; ++ ++typedef union { ++ unsigned long val : 32; ++ scratch_reg0_t f; ++} scratch_reg0_u; ++ ++typedef struct _scratch_reg1_t { ++ unsigned long scratch_reg1 : 32; ++ } scratch_reg1_t; ++ ++typedef union { ++ unsigned long val : 32; ++ scratch_reg1_t f; ++} scratch_reg1_u; ++ ++typedef struct _scratch_reg2_t { ++ unsigned long scratch_reg2 : 32; ++ } scratch_reg2_t; ++ ++typedef union { ++ unsigned long val : 32; ++ scratch_reg2_t f; ++} scratch_reg2_u; ++ ++typedef struct _scratch_reg3_t { ++ unsigned long scratch_reg3 : 32; ++ } scratch_reg3_t; ++ ++typedef union { ++ unsigned long val : 32; ++ scratch_reg3_t f; ++} scratch_reg3_u; ++ ++typedef struct _scratch_reg4_t { ++ unsigned long scratch_reg4 : 32; ++ } scratch_reg4_t; ++ ++typedef union { ++ unsigned long val : 32; ++ scratch_reg4_t f; ++} scratch_reg4_u; ++ ++typedef struct _scratch_reg5_t { ++ unsigned long scratch_reg5 : 32; ++ } scratch_reg5_t; ++ ++typedef union { ++ unsigned long val : 32; ++ scratch_reg5_t f; ++} scratch_reg5_u; ++ ++typedef struct _scratch_umsk_t { ++ unsigned long scratch_umsk : 6; ++ unsigned long : 10; ++ unsigned long scratch_swap : 2; ++ unsigned long : 14; ++ } scratch_umsk_t; ++ ++typedef union { ++ unsigned long val : 32; ++ scratch_umsk_t f; ++} scratch_umsk_u; ++ ++typedef struct _scratch_addr_t { ++ unsigned long : 5; ++ unsigned long scratch_addr : 27; ++ } scratch_addr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ scratch_addr_t f; ++} scratch_addr_u; ++ ++typedef struct _cp_csq_addr_t { ++ unsigned long : 2; ++ unsigned long csq_addr : 8; ++ unsigned long : 22; ++ } cp_csq_addr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_csq_addr_t f; ++} cp_csq_addr_u; ++ ++typedef struct _cp_csq_data_t { ++ unsigned long csq_data : 32; ++ } cp_csq_data_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_csq_data_t f; ++} cp_csq_data_u; ++ ++typedef struct _cp_csq_stat_t { ++ unsigned long csq_rptr_primary : 8; ++ unsigned long csq_wptr_primary : 8; ++ unsigned long csq_rptr_indirect : 8; ++ unsigned long csq_wptr_indirect : 8; ++ } cp_csq_stat_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_csq_stat_t f; ++} cp_csq_stat_u; ++ ++typedef struct _cp_stat_t { ++ unsigned long mru_busy : 1; ++ unsigned long mwu_busy : 1; ++ unsigned long rsiu_busy : 1; ++ unsigned long rciu_busy : 1; ++ unsigned long : 5; ++ unsigned long csf_primary_busy : 1; ++ unsigned long csf_indirect_busy : 1; ++ unsigned long csq_primary_busy : 1; ++ unsigned long csq_indirect_busy : 1; ++ unsigned long csi_busy : 1; ++ unsigned long : 14; ++ unsigned long guidma_busy : 1; ++ unsigned long viddma_busy : 1; ++ unsigned long cmdstrm_busy : 1; ++ unsigned long cp_busy : 1; ++ } cp_stat_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cp_stat_t f; ++} cp_stat_u; ++ ++typedef struct _gen_int_cntl_t { ++ unsigned long crtc_vblank_mask : 1; ++ unsigned long crtc_vline_mask : 1; ++ unsigned long crtc_hwint1_mask : 1; ++ unsigned long crtc_hwint2_mask : 1; ++ unsigned long : 15; ++ unsigned long gui_idle_mask : 1; ++ unsigned long : 8; ++ unsigned long pm4_idle_int_mask : 1; ++ unsigned long dvi_i2c_int_mask : 1; ++ unsigned long : 2; ++ } gen_int_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ gen_int_cntl_t f; ++} gen_int_cntl_u; ++ ++typedef struct _gen_int_status_rd_t { ++ unsigned long crtc_vblank_stat : 1; ++ unsigned long crtc_vline_stat : 1; ++ unsigned long crtc_hwint1_stat : 1; ++ unsigned long crtc_hwint2_stat : 1; ++ unsigned long : 15; ++ unsigned long gui_idle_stat : 1; ++ unsigned long : 8; ++ unsigned long pm4_idle_int_stat : 1; ++ unsigned long dvi_i2c_int_stat : 1; ++ unsigned long : 2; ++ } gen_int_status_rd_t; ++ ++typedef union { ++ unsigned long val : 32; ++ gen_int_status_rd_t f; ++} gen_int_status_rd_u; ++ ++typedef struct _gen_int_status_wr_t { ++ unsigned long crtc_vblank_stat_ak : 1; ++ unsigned long crtc_vline_stat_ak : 1; ++ unsigned long crtc_hwint1_stat_ak : 1; ++ unsigned long crtc_hwint2_stat_ak : 1; ++ unsigned long : 15; ++ unsigned long gui_idle_stat_ak : 1; ++ unsigned long : 8; ++ unsigned long pm4_idle_int_ak : 1; ++ unsigned long dvi_i2c_int_ak : 1; ++ unsigned long : 2; ++ } gen_int_status_wr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ gen_int_status_wr_t f; ++} gen_int_status_wr_u; ++ ++typedef struct _lcd_format_t { ++ unsigned long lcd_type : 4; ++ unsigned long color_to_mono : 1; ++ unsigned long data_inv : 1; ++ unsigned long stn_fm : 2; ++ unsigned long tft_fm : 2; ++ unsigned long scan_lr_en : 1; ++ unsigned long scan_ud_en : 1; ++ unsigned long pol_inv : 1; ++ unsigned long rst_fm : 1; ++ unsigned long yuv_to_rgb : 1; ++ unsigned long hr_tft : 1; ++ unsigned long ulc_panel : 1; ++ unsigned long : 15; ++ } lcd_format_t; ++ ++typedef union { ++ unsigned long val : 32; ++ lcd_format_t f; ++} lcd_format_u; ++ ++typedef struct _graphic_ctrl_t { ++ unsigned long color_depth : 3; ++ unsigned long portrait_mode : 2; ++ unsigned long low_power_on : 1; ++ unsigned long req_freq : 4; ++ unsigned long en_crtc : 1; ++ unsigned long en_graphic_req : 1; ++ unsigned long en_graphic_crtc : 1; ++ unsigned long total_req_graphic : 9; ++ unsigned long lcd_pclk_on : 1; ++ unsigned long lcd_sclk_on : 1; ++ unsigned long pclk_running : 1; ++ unsigned long sclk_running : 1; ++ unsigned long : 6; ++ } graphic_ctrl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ graphic_ctrl_t f; ++} graphic_ctrl_u; ++ ++typedef struct _graphic_offset_t { ++ unsigned long graphic_offset : 24; ++ unsigned long : 8; ++ } graphic_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ graphic_offset_t f; ++} graphic_offset_u; ++ ++typedef struct _graphic_pitch_t { ++ unsigned long graphic_pitch : 11; ++ unsigned long : 21; ++ } graphic_pitch_t; ++ ++typedef union { ++ unsigned long val : 32; ++ graphic_pitch_t f; ++} graphic_pitch_u; ++ ++typedef struct _crtc_total_t { ++ unsigned long crtc_h_total : 10; ++ unsigned long : 6; ++ unsigned long crtc_v_total : 10; ++ unsigned long : 6; ++ } crtc_total_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_total_t f; ++} crtc_total_u; ++ ++typedef struct _active_h_disp_t { ++ unsigned long active_h_start : 10; ++ unsigned long : 6; ++ unsigned long active_h_end : 10; ++ unsigned long : 6; ++ } active_h_disp_t; ++ ++typedef union { ++ unsigned long val : 32; ++ active_h_disp_t f; ++} active_h_disp_u; ++ ++typedef struct _active_v_disp_t { ++ unsigned long active_v_start : 10; ++ unsigned long : 6; ++ unsigned long active_v_end : 10; ++ unsigned long : 6; ++ } active_v_disp_t; ++ ++typedef union { ++ unsigned long val : 32; ++ active_v_disp_t f; ++} active_v_disp_u; ++ ++typedef struct _graphic_h_disp_t { ++ unsigned long graphic_h_start : 10; ++ unsigned long : 6; ++ unsigned long graphic_h_end : 10; ++ unsigned long : 6; ++ } graphic_h_disp_t; ++ ++typedef union { ++ unsigned long val : 32; ++ graphic_h_disp_t f; ++} graphic_h_disp_u; ++ ++typedef struct _graphic_v_disp_t { ++ unsigned long graphic_v_start : 10; ++ unsigned long : 6; ++ unsigned long graphic_v_end : 10; ++ unsigned long : 6; ++ } graphic_v_disp_t; ++ ++typedef union { ++ unsigned long val : 32; ++ graphic_v_disp_t f; ++} graphic_v_disp_u; ++ ++typedef struct _video_ctrl_t { ++ unsigned long video_mode : 1; ++ unsigned long keyer_en : 1; ++ unsigned long en_video_req : 1; ++ unsigned long en_graphic_req_video : 1; ++ unsigned long en_video_crtc : 1; ++ unsigned long video_hor_exp : 2; ++ unsigned long video_ver_exp : 2; ++ unsigned long uv_combine : 1; ++ unsigned long total_req_video : 9; ++ unsigned long video_ch_sel : 1; ++ unsigned long video_portrait : 2; ++ unsigned long yuv2rgb_en : 1; ++ unsigned long yuv2rgb_option : 1; ++ unsigned long video_inv_hor : 1; ++ unsigned long video_inv_ver : 1; ++ unsigned long gamma_sel : 2; ++ unsigned long dis_limit : 1; ++ unsigned long en_uv_hblend : 1; ++ unsigned long rgb_gamma_sel : 2; ++ } video_ctrl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ video_ctrl_t f; ++} video_ctrl_u; ++ ++typedef struct _graphic_key_t { ++ unsigned long keyer_color : 16; ++ unsigned long keyer_mask : 16; ++ } graphic_key_t; ++ ++typedef union { ++ unsigned long val : 32; ++ graphic_key_t f; ++} graphic_key_u; ++ ++typedef struct _video_y_offset_t { ++ unsigned long y_offset : 24; ++ unsigned long : 8; ++ } video_y_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ video_y_offset_t f; ++} video_y_offset_u; ++ ++typedef struct _video_y_pitch_t { ++ unsigned long y_pitch : 11; ++ unsigned long : 21; ++ } video_y_pitch_t; ++ ++typedef union { ++ unsigned long val : 32; ++ video_y_pitch_t f; ++} video_y_pitch_u; ++ ++typedef struct _video_u_offset_t { ++ unsigned long u_offset : 24; ++ unsigned long : 8; ++ } video_u_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ video_u_offset_t f; ++} video_u_offset_u; ++ ++typedef struct _video_u_pitch_t { ++ unsigned long u_pitch : 11; ++ unsigned long : 21; ++ } video_u_pitch_t; ++ ++typedef union { ++ unsigned long val : 32; ++ video_u_pitch_t f; ++} video_u_pitch_u; ++ ++typedef struct _video_v_offset_t { ++ unsigned long v_offset : 24; ++ unsigned long : 8; ++ } video_v_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ video_v_offset_t f; ++} video_v_offset_u; ++ ++typedef struct _video_v_pitch_t { ++ unsigned long v_pitch : 11; ++ unsigned long : 21; ++ } video_v_pitch_t; ++ ++typedef union { ++ unsigned long val : 32; ++ video_v_pitch_t f; ++} video_v_pitch_u; ++ ++typedef struct _video_h_pos_t { ++ unsigned long video_h_start : 10; ++ unsigned long : 6; ++ unsigned long video_h_end : 10; ++ unsigned long : 6; ++ } video_h_pos_t; ++ ++typedef union { ++ unsigned long val : 32; ++ video_h_pos_t f; ++} video_h_pos_u; ++ ++typedef struct _video_v_pos_t { ++ unsigned long video_v_start : 10; ++ unsigned long : 6; ++ unsigned long video_v_end : 10; ++ unsigned long : 6; ++ } video_v_pos_t; ++ ++typedef union { ++ unsigned long val : 32; ++ video_v_pos_t f; ++} video_v_pos_u; ++ ++typedef struct _brightness_cntl_t { ++ unsigned long brightness : 7; ++ unsigned long : 25; ++ } brightness_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ brightness_cntl_t f; ++} brightness_cntl_u; ++ ++typedef struct _cursor1_offset_t { ++ unsigned long cur1_offset : 24; ++ unsigned long cur1_x_offset : 4; ++ unsigned long cur1_y_offset : 4; ++ } cursor1_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cursor1_offset_t f; ++} cursor1_offset_u; ++ ++typedef struct _cursor1_h_pos_t { ++ unsigned long cur1_h_start : 10; ++ unsigned long : 6; ++ unsigned long cur1_h_end : 10; ++ unsigned long : 5; ++ unsigned long cur1_en : 1; ++ } cursor1_h_pos_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cursor1_h_pos_t f; ++} cursor1_h_pos_u; ++ ++typedef struct _cursor1_v_pos_t { ++ unsigned long cur1_v_start : 10; ++ unsigned long : 6; ++ unsigned long cur1_v_end : 10; ++ unsigned long : 6; ++ } cursor1_v_pos_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cursor1_v_pos_t f; ++} cursor1_v_pos_u; ++ ++typedef struct _cursor1_color0_t { ++ unsigned long cur1_color0_r : 8; ++ unsigned long cur1_color0_g : 8; ++ unsigned long cur1_color0_b : 8; ++ unsigned long : 8; ++ } cursor1_color0_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cursor1_color0_t f; ++} cursor1_color0_u; ++ ++typedef struct _cursor1_color1_t { ++ unsigned long cur1_color1_r : 8; ++ unsigned long cur1_color1_g : 8; ++ unsigned long cur1_color1_b : 8; ++ unsigned long : 8; ++ } cursor1_color1_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cursor1_color1_t f; ++} cursor1_color1_u; ++ ++typedef struct _cursor2_offset_t { ++ unsigned long cur2_offset : 24; ++ unsigned long cur2_x_offset : 4; ++ unsigned long cur2_y_offset : 4; ++ } cursor2_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cursor2_offset_t f; ++} cursor2_offset_u; ++ ++typedef struct _cursor2_h_pos_t { ++ unsigned long cur2_h_start : 10; ++ unsigned long : 6; ++ unsigned long cur2_h_end : 10; ++ unsigned long : 5; ++ unsigned long cur2_en : 1; ++ } cursor2_h_pos_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cursor2_h_pos_t f; ++} cursor2_h_pos_u; ++ ++typedef struct _cursor2_v_pos_t { ++ unsigned long cur2_v_start : 10; ++ unsigned long : 6; ++ unsigned long cur2_v_end : 10; ++ unsigned long : 6; ++ } cursor2_v_pos_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cursor2_v_pos_t f; ++} cursor2_v_pos_u; ++ ++typedef struct _cursor2_color0_t { ++ unsigned long cur2_color0_r : 8; ++ unsigned long cur2_color0_g : 8; ++ unsigned long cur2_color0_b : 8; ++ unsigned long : 8; ++ } cursor2_color0_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cursor2_color0_t f; ++} cursor2_color0_u; ++ ++typedef struct _cursor2_color1_t { ++ unsigned long cur2_color1_r : 8; ++ unsigned long cur2_color1_g : 8; ++ unsigned long cur2_color1_b : 8; ++ unsigned long : 8; ++ } cursor2_color1_t; ++ ++typedef union { ++ unsigned long val : 32; ++ cursor2_color1_t f; ++} cursor2_color1_u; ++ ++typedef struct _disp_int_cntl_t { ++ unsigned long vline_int_pos : 10; ++ unsigned long : 6; ++ unsigned long hpos_int_pos : 10; ++ unsigned long : 4; ++ unsigned long vblank_int_pol : 1; ++ unsigned long frame_int_pol : 1; ++ } disp_int_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ disp_int_cntl_t f; ++} disp_int_cntl_u; ++ ++typedef struct _crtc_ss_t { ++ unsigned long ss_start : 10; ++ unsigned long : 6; ++ unsigned long ss_end : 10; ++ unsigned long : 2; ++ unsigned long ss_align : 1; ++ unsigned long ss_pol : 1; ++ unsigned long ss_run_mode : 1; ++ unsigned long ss_en : 1; ++ } crtc_ss_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_ss_t f; ++} crtc_ss_u; ++ ++typedef struct _crtc_ls_t { ++ unsigned long ls_start : 10; ++ unsigned long : 6; ++ unsigned long ls_end : 10; ++ unsigned long : 2; ++ unsigned long ls_align : 1; ++ unsigned long ls_pol : 1; ++ unsigned long ls_run_mode : 1; ++ unsigned long ls_en : 1; ++ } crtc_ls_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_ls_t f; ++} crtc_ls_u; ++ ++typedef struct _crtc_rev_t { ++ unsigned long rev_pos : 10; ++ unsigned long : 6; ++ unsigned long rev_align : 1; ++ unsigned long rev_freq_nref : 5; ++ unsigned long rev_en : 1; ++ unsigned long : 9; ++ } crtc_rev_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_rev_t f; ++} crtc_rev_u; ++ ++typedef struct _crtc_dclk_t { ++ unsigned long dclk_start : 10; ++ unsigned long : 6; ++ unsigned long dclk_end : 10; ++ unsigned long : 1; ++ unsigned long dclk_run_mode : 2; ++ unsigned long dclk_pol : 1; ++ unsigned long dclk_align : 1; ++ unsigned long dclk_en : 1; ++ } crtc_dclk_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_dclk_t f; ++} crtc_dclk_u; ++ ++typedef struct _crtc_gs_t { ++ unsigned long gs_start : 10; ++ unsigned long : 6; ++ unsigned long gs_end : 10; ++ unsigned long : 3; ++ unsigned long gs_align : 1; ++ unsigned long gs_pol : 1; ++ unsigned long gs_en : 1; ++ } crtc_gs_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_gs_t f; ++} crtc_gs_u; ++ ++typedef struct _crtc_vpos_gs_t { ++ unsigned long gs_vpos_start : 10; ++ unsigned long : 6; ++ unsigned long gs_vpos_end : 10; ++ unsigned long : 6; ++ } crtc_vpos_gs_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_vpos_gs_t f; ++} crtc_vpos_gs_u; ++ ++typedef struct _crtc_gclk_t { ++ unsigned long gclk_start : 10; ++ unsigned long : 6; ++ unsigned long gclk_end : 10; ++ unsigned long : 3; ++ unsigned long gclk_align : 1; ++ unsigned long gclk_pol : 1; ++ unsigned long gclk_en : 1; ++ } crtc_gclk_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_gclk_t f; ++} crtc_gclk_u; ++ ++typedef struct _crtc_goe_t { ++ unsigned long goe_start : 10; ++ unsigned long : 6; ++ unsigned long goe_end : 10; ++ unsigned long : 3; ++ unsigned long goe_align : 1; ++ unsigned long goe_pol : 1; ++ unsigned long goe_en : 1; ++ } crtc_goe_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_goe_t f; ++} crtc_goe_u; ++ ++typedef struct _crtc_frame_t { ++ unsigned long crtc_fr_start : 10; ++ unsigned long : 6; ++ unsigned long crtc_fr_end : 10; ++ unsigned long : 4; ++ unsigned long crtc_frame_en : 1; ++ unsigned long crtc_frame_align : 1; ++ } crtc_frame_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_frame_t f; ++} crtc_frame_u; ++ ++typedef struct _crtc_frame_vpos_t { ++ unsigned long crtc_fr_vpos : 10; ++ unsigned long : 22; ++ } crtc_frame_vpos_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_frame_vpos_t f; ++} crtc_frame_vpos_u; ++ ++typedef struct _gpio_data_t { ++ unsigned long gio_out : 16; ++ unsigned long gio_in : 16; ++ } gpio_data_t; ++ ++typedef union { ++ unsigned long val : 32; ++ gpio_data_t f; ++} gpio_data_u; ++ ++typedef struct _gpio_cntl1_t { ++ unsigned long gio_pd : 16; ++ unsigned long gio_schmen : 16; ++ } gpio_cntl1_t; ++ ++typedef union { ++ unsigned long val : 32; ++ gpio_cntl1_t f; ++} gpio_cntl1_u; ++ ++typedef struct _gpio_cntl2_t { ++ unsigned long gio_oe : 16; ++ unsigned long gio_srp : 1; ++ unsigned long gio_srn : 1; ++ unsigned long gio_sp : 4; ++ unsigned long gio_sn : 4; ++ unsigned long : 6; ++ } gpio_cntl2_t; ++ ++typedef union { ++ unsigned long val : 32; ++ gpio_cntl2_t f; ++} gpio_cntl2_u; ++ ++typedef struct _lcdd_cntl1_t { ++ unsigned long lcdd_pd : 18; ++ unsigned long lcdd_srp : 1; ++ unsigned long lcdd_srn : 1; ++ unsigned long lcdd_sp : 4; ++ unsigned long lcdd_sn : 4; ++ unsigned long lcdd_align : 1; ++ unsigned long : 3; ++ } lcdd_cntl1_t; ++ ++typedef union { ++ unsigned long val : 32; ++ lcdd_cntl1_t f; ++} lcdd_cntl1_u; ++ ++typedef struct _lcdd_cntl2_t { ++ unsigned long lcdd_oe : 18; ++ unsigned long : 14; ++ } lcdd_cntl2_t; ++ ++typedef union { ++ unsigned long val : 32; ++ lcdd_cntl2_t f; ++} lcdd_cntl2_u; ++ ++typedef struct _genlcd_cntl1_t { ++ unsigned long dclk_oe : 1; ++ unsigned long dclk_pd : 1; ++ unsigned long dclk_srp : 1; ++ unsigned long dclk_srn : 1; ++ unsigned long dclk_sp : 4; ++ unsigned long dclk_sn : 4; ++ unsigned long ss_oe : 1; ++ unsigned long ss_pd : 1; ++ unsigned long ls_oe : 1; ++ unsigned long ls_pd : 1; ++ unsigned long gs_oe : 1; ++ unsigned long gs_pd : 1; ++ unsigned long goe_oe : 1; ++ unsigned long goe_pd : 1; ++ unsigned long rev_oe : 1; ++ unsigned long rev_pd : 1; ++ unsigned long frame_oe : 1; ++ unsigned long frame_pd : 1; ++ unsigned long : 8; ++ } genlcd_cntl1_t; ++ ++typedef union { ++ unsigned long val : 32; ++ genlcd_cntl1_t f; ++} genlcd_cntl1_u; ++ ++typedef struct _genlcd_cntl2_t { ++ unsigned long gclk_oe : 1; ++ unsigned long gclk_pd : 1; ++ unsigned long gclk_srp : 1; ++ unsigned long gclk_srn : 1; ++ unsigned long gclk_sp : 4; ++ unsigned long gclk_sn : 4; ++ unsigned long genlcd_srp : 1; ++ unsigned long genlcd_srn : 1; ++ unsigned long genlcd_sp : 4; ++ unsigned long genlcd_sn : 4; ++ unsigned long : 10; ++ } genlcd_cntl2_t; ++ ++typedef union { ++ unsigned long val : 32; ++ genlcd_cntl2_t f; ++} genlcd_cntl2_u; ++ ++typedef struct _disp_debug_t { ++ unsigned long disp_debug : 32; ++ } disp_debug_t; ++ ++typedef union { ++ unsigned long val : 32; ++ disp_debug_t f; ++} disp_debug_u; ++ ++typedef struct _disp_db_buf_cntl_rd_t { ++ unsigned long en_db_buf : 1; ++ unsigned long update_db_buf_done : 1; ++ unsigned long db_buf_cntl : 6; ++ unsigned long : 24; ++ } disp_db_buf_cntl_rd_t; ++ ++typedef union { ++ unsigned long val : 32; ++ disp_db_buf_cntl_rd_t f; ++} disp_db_buf_cntl_rd_u; ++ ++typedef struct _disp_db_buf_cntl_wr_t { ++ unsigned long en_db_buf : 1; ++ unsigned long update_db_buf : 1; ++ unsigned long db_buf_cntl : 6; ++ unsigned long : 24; ++ } disp_db_buf_cntl_wr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ disp_db_buf_cntl_wr_t f; ++} disp_db_buf_cntl_wr_u; ++ ++typedef struct _disp_crc_sig_t { ++ unsigned long crc_sig_r : 6; ++ unsigned long crc_sig_g : 6; ++ unsigned long crc_sig_b : 6; ++ unsigned long crc_cont_en : 1; ++ unsigned long crc_en : 1; ++ unsigned long crc_mask_en : 1; ++ unsigned long crc_sig_cntl : 6; ++ unsigned long : 5; ++ } disp_crc_sig_t; ++ ++typedef union { ++ unsigned long val : 32; ++ disp_crc_sig_t f; ++} disp_crc_sig_u; ++ ++typedef struct _crtc_default_count_t { ++ unsigned long crtc_hcount_def : 10; ++ unsigned long : 6; ++ unsigned long crtc_vcount_def : 10; ++ unsigned long : 6; ++ } crtc_default_count_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_default_count_t f; ++} crtc_default_count_u; ++ ++typedef struct _lcd_background_color_t { ++ unsigned long lcd_bg_red : 8; ++ unsigned long lcd_bg_green : 8; ++ unsigned long lcd_bg_blue : 8; ++ unsigned long : 8; ++ } lcd_background_color_t; ++ ++typedef union { ++ unsigned long val : 32; ++ lcd_background_color_t f; ++} lcd_background_color_u; ++ ++typedef struct _crtc_ps2_t { ++ unsigned long ps2_start : 10; ++ unsigned long : 6; ++ unsigned long ps2_end : 10; ++ unsigned long : 4; ++ unsigned long ps2_pol : 1; ++ unsigned long ps2_en : 1; ++ } crtc_ps2_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_ps2_t f; ++} crtc_ps2_u; ++ ++typedef struct _crtc_ps2_vpos_t { ++ unsigned long ps2_vpos_start : 10; ++ unsigned long : 6; ++ unsigned long ps2_vpos_end : 10; ++ unsigned long : 6; ++ } crtc_ps2_vpos_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_ps2_vpos_t f; ++} crtc_ps2_vpos_u; ++ ++typedef struct _crtc_ps1_active_t { ++ unsigned long ps1_h_start : 10; ++ unsigned long : 6; ++ unsigned long ps1_h_end : 10; ++ unsigned long : 3; ++ unsigned long ps1_pol : 1; ++ unsigned long ps1_en : 1; ++ unsigned long ps1_use_nactive : 1; ++ } crtc_ps1_active_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_ps1_active_t f; ++} crtc_ps1_active_u; ++ ++typedef struct _crtc_ps1_nactive_t { ++ unsigned long ps1_h_start_na : 10; ++ unsigned long : 6; ++ unsigned long ps1_h_end_na : 10; ++ unsigned long : 5; ++ unsigned long ps1_en_na : 1; ++ } crtc_ps1_nactive_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_ps1_nactive_t f; ++} crtc_ps1_nactive_u; ++ ++typedef struct _crtc_gclk_ext_t { ++ unsigned long gclk_alter_start : 10; ++ unsigned long : 6; ++ unsigned long gclk_alter_width : 2; ++ unsigned long gclk_en_alter : 1; ++ unsigned long gclk_db_width : 2; ++ unsigned long : 11; ++ } crtc_gclk_ext_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_gclk_ext_t f; ++} crtc_gclk_ext_u; ++ ++typedef struct _crtc_alw_t { ++ unsigned long alw_hstart : 10; ++ unsigned long : 6; ++ unsigned long alw_hend : 10; ++ unsigned long : 4; ++ unsigned long alw_delay : 1; ++ unsigned long alw_en : 1; ++ } crtc_alw_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_alw_t f; ++} crtc_alw_u; ++ ++typedef struct _crtc_alw_vpos_t { ++ unsigned long alw_vstart : 10; ++ unsigned long : 6; ++ unsigned long alw_vend : 10; ++ unsigned long : 6; ++ } crtc_alw_vpos_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_alw_vpos_t f; ++} crtc_alw_vpos_u; ++ ++typedef struct _crtc_psk_t { ++ unsigned long psk_vstart : 10; ++ unsigned long : 6; ++ unsigned long psk_vend : 10; ++ unsigned long : 4; ++ unsigned long psk_pol : 1; ++ unsigned long psk_en : 1; ++ } crtc_psk_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_psk_t f; ++} crtc_psk_u; ++ ++typedef struct _crtc_psk_hpos_t { ++ unsigned long psk_hstart : 10; ++ unsigned long : 6; ++ unsigned long psk_hend : 10; ++ unsigned long : 6; ++ } crtc_psk_hpos_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_psk_hpos_t f; ++} crtc_psk_hpos_u; ++ ++typedef struct _crtc_cv4_start_t { ++ unsigned long cv4_vstart : 10; ++ unsigned long : 20; ++ unsigned long cv4_pol : 1; ++ unsigned long cv4_en : 1; ++ } crtc_cv4_start_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_cv4_start_t f; ++} crtc_cv4_start_u; ++ ++typedef struct _crtc_cv4_end_t { ++ unsigned long cv4_vend1 : 10; ++ unsigned long : 6; ++ unsigned long cv4_vend2 : 10; ++ unsigned long : 6; ++ } crtc_cv4_end_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_cv4_end_t f; ++} crtc_cv4_end_u; ++ ++typedef struct _crtc_cv4_hpos_t { ++ unsigned long cv4_hstart : 10; ++ unsigned long : 6; ++ unsigned long cv4_hend : 10; ++ unsigned long : 6; ++ } crtc_cv4_hpos_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_cv4_hpos_t f; ++} crtc_cv4_hpos_u; ++ ++typedef struct _crtc_eck_t { ++ unsigned long eck_freq1 : 3; ++ unsigned long eck_en : 1; ++ unsigned long : 28; ++ } crtc_eck_t; ++ ++typedef union { ++ unsigned long val : 32; ++ crtc_eck_t f; ++} crtc_eck_u; ++ ++typedef struct _refresh_cntl_t { ++ unsigned long ref_frame : 3; ++ unsigned long nref_frame : 5; ++ unsigned long ref_cntl : 1; ++ unsigned long stop_sm_nref : 1; ++ unsigned long stop_req_nref : 1; ++ unsigned long : 21; ++ } refresh_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ refresh_cntl_t f; ++} refresh_cntl_u; ++ ++typedef struct _genlcd_cntl3_t { ++ unsigned long ps1_oe : 1; ++ unsigned long ps1_pd : 1; ++ unsigned long ps2_oe : 1; ++ unsigned long ps2_pd : 1; ++ unsigned long rev2_oe : 1; ++ unsigned long rev2_pd : 1; ++ unsigned long awl_oe : 1; ++ unsigned long awl_pd : 1; ++ unsigned long dinv_oe : 1; ++ unsigned long dinv_pd : 1; ++ unsigned long psk_out : 1; ++ unsigned long psd_out : 1; ++ unsigned long eck_out : 1; ++ unsigned long cv4_out : 1; ++ unsigned long ps1_out : 1; ++ unsigned long ps2_out : 1; ++ unsigned long rev_out : 1; ++ unsigned long rev2_out : 1; ++ unsigned long : 14; ++ } genlcd_cntl3_t; ++ ++typedef union { ++ unsigned long val : 32; ++ genlcd_cntl3_t f; ++} genlcd_cntl3_u; ++ ++typedef struct _gpio_data2_t { ++ unsigned long gio2_out : 16; ++ unsigned long gio2_in : 16; ++ } gpio_data2_t; ++ ++typedef union { ++ unsigned long val : 32; ++ gpio_data2_t f; ++} gpio_data2_u; ++ ++typedef struct _gpio_cntl3_t { ++ unsigned long gio2_pd : 16; ++ unsigned long gio2_schmen : 16; ++ } gpio_cntl3_t; ++ ++typedef union { ++ unsigned long val : 32; ++ gpio_cntl3_t f; ++} gpio_cntl3_u; ++ ++typedef struct _gpio_cntl4_t { ++ unsigned long gio2_oe : 16; ++ unsigned long : 16; ++ } gpio_cntl4_t; ++ ++typedef union { ++ unsigned long val : 32; ++ gpio_cntl4_t f; ++} gpio_cntl4_u; ++ ++typedef struct _chip_strap_t { ++ unsigned long config_strap : 8; ++ unsigned long pkg_strap : 1; ++ unsigned long : 23; ++ } chip_strap_t; ++ ++typedef union { ++ unsigned long val : 32; ++ chip_strap_t f; ++} chip_strap_u; ++ ++typedef struct _disp_debug2_t { ++ unsigned long disp_debug2 : 32; ++ } disp_debug2_t; ++ ++typedef union { ++ unsigned long val : 32; ++ disp_debug2_t f; ++} disp_debug2_u; ++ ++typedef struct _debug_bus_cntl_t { ++ unsigned long debug_testmux : 4; ++ unsigned long debug_testsel : 4; ++ unsigned long debug_gioa_sel : 2; ++ unsigned long debug_giob_sel : 2; ++ unsigned long debug_clk_sel : 1; ++ unsigned long debug_clk_inv : 1; ++ unsigned long : 2; ++ unsigned long debug_bus : 16; ++ } debug_bus_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug_bus_cntl_t f; ++} debug_bus_cntl_u; ++ ++typedef struct _gamma_value1_t { ++ unsigned long gamma1 : 8; ++ unsigned long gamma2 : 8; ++ unsigned long gamma3 : 8; ++ unsigned long gamma4 : 8; ++ } gamma_value1_t; ++ ++typedef union { ++ unsigned long val : 32; ++ gamma_value1_t f; ++} gamma_value1_u; ++ ++typedef struct _gamma_value2_t { ++ unsigned long gamma5 : 8; ++ unsigned long gamma6 : 8; ++ unsigned long gamma7 : 8; ++ unsigned long gamma8 : 8; ++ } gamma_value2_t; ++ ++typedef union { ++ unsigned long val : 32; ++ gamma_value2_t f; ++} gamma_value2_u; ++ ++typedef struct _gamma_slope_t { ++ unsigned long slope1 : 3; ++ unsigned long slope2 : 3; ++ unsigned long slope3 : 3; ++ unsigned long slope4 : 3; ++ unsigned long slope5 : 3; ++ unsigned long slope6 : 3; ++ unsigned long slope7 : 3; ++ unsigned long slope8 : 3; ++ unsigned long : 8; ++ } gamma_slope_t; ++ ++typedef union { ++ unsigned long val : 32; ++ gamma_slope_t f; ++} gamma_slope_u; ++ ++typedef struct _gen_status_t { ++ unsigned long status : 16; ++ unsigned long : 16; ++ } gen_status_t; ++ ++typedef union { ++ unsigned long val : 32; ++ gen_status_t f; ++} gen_status_u; ++ ++typedef struct _hw_int_t { ++ unsigned long hwint1_pos : 5; ++ unsigned long hwint2_pos : 5; ++ unsigned long hwint1_pol : 1; ++ unsigned long hwint2_pol : 1; ++ unsigned long hwint1_en_db : 1; ++ unsigned long hwint2_en_db : 1; ++ unsigned long : 18; ++ } hw_int_t; ++ ++typedef union { ++ unsigned long val : 32; ++ hw_int_t f; ++} hw_int_u; ++ ++typedef struct _dst_offset_t { ++ unsigned long dst_offset : 24; ++ unsigned long : 8; ++ } dst_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_offset_t f; ++} dst_offset_u; ++ ++typedef struct _dst_pitch_t { ++ unsigned long dst_pitch : 14; ++ unsigned long mc_dst_pitch_mul : 2; ++ unsigned long : 16; ++ } dst_pitch_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_pitch_t f; ++} dst_pitch_u; ++ ++typedef struct _dst_pitch_offset_t { ++ unsigned long dst_offset : 20; ++ unsigned long dst_pitch : 10; ++ unsigned long mc_dst_pitch_mul : 2; ++ } dst_pitch_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_pitch_offset_t f; ++} dst_pitch_offset_u; ++ ++typedef struct _dst_x_t { ++ unsigned long dst_x : 14; ++ unsigned long : 18; ++ } dst_x_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_x_t f; ++} dst_x_u; ++ ++typedef struct _dst_y_t { ++ unsigned long dst_y : 14; ++ unsigned long : 18; ++ } dst_y_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_y_t f; ++} dst_y_u; ++ ++typedef struct _dst_x_y_t { ++ unsigned long dst_y : 14; ++ unsigned long : 2; ++ unsigned long dst_x : 14; ++ unsigned long : 2; ++ } dst_x_y_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_x_y_t f; ++} dst_x_y_u; ++ ++typedef struct _dst_y_x_t { ++ unsigned long dst_x : 14; ++ unsigned long : 2; ++ unsigned long dst_y : 14; ++ unsigned long : 2; ++ } dst_y_x_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_y_x_t f; ++} dst_y_x_u; ++ ++typedef struct _dst_width_t { ++ unsigned long dst_width_b0 : 8; ++ unsigned long dst_width_b1 : 6; ++ unsigned long : 18; ++ } dst_width_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_width_t f; ++} dst_width_u; ++ ++typedef struct _dst_height_t { ++ unsigned long dst_height : 14; ++ unsigned long : 18; ++ } dst_height_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_height_t f; ++} dst_height_u; ++ ++typedef struct _dst_width_height_t { ++ unsigned long dst_height : 14; ++ unsigned long : 2; ++ unsigned long dst_width_b0 : 8; ++ unsigned long dst_width_b1 : 6; ++ unsigned long : 2; ++ } dst_width_height_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_width_height_t f; ++} dst_width_height_u; ++ ++typedef struct _dst_height_width_t { ++ unsigned long dst_width_b0 : 8; ++ unsigned long dst_width_b1 : 6; ++ unsigned long : 2; ++ unsigned long dst_height : 14; ++ unsigned long : 2; ++ } dst_height_width_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_height_width_t f; ++} dst_height_width_u; ++ ++typedef struct _dst_height_width_8_t { ++ unsigned long : 16; ++ unsigned long dst_width_b0 : 8; ++ unsigned long dst_height : 8; ++ } dst_height_width_8_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_height_width_8_t f; ++} dst_height_width_8_u; ++ ++typedef struct _dst_height_y_t { ++ unsigned long dst_y : 14; ++ unsigned long : 2; ++ unsigned long dst_height : 14; ++ unsigned long : 2; ++ } dst_height_y_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_height_y_t f; ++} dst_height_y_u; ++ ++typedef struct _dst_width_x_t { ++ unsigned long dst_x : 14; ++ unsigned long : 2; ++ unsigned long dst_width_b0 : 8; ++ unsigned long dst_width_b1 : 6; ++ unsigned long : 2; ++ } dst_width_x_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_width_x_t f; ++} dst_width_x_u; ++ ++typedef struct _dst_width_x_incy_t { ++ unsigned long dst_x : 14; ++ unsigned long : 2; ++ unsigned long dst_width_b0 : 8; ++ unsigned long dst_width_b1 : 6; ++ unsigned long : 2; ++ } dst_width_x_incy_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_width_x_incy_t f; ++} dst_width_x_incy_u; ++ ++typedef struct _dst_line_start_t { ++ unsigned long dst_start_x : 14; ++ unsigned long : 2; ++ unsigned long dst_start_y : 14; ++ unsigned long : 2; ++ } dst_line_start_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_line_start_t f; ++} dst_line_start_u; ++ ++typedef struct _dst_line_end_t { ++ unsigned long dst_end_x : 14; ++ unsigned long : 2; ++ unsigned long dst_end_y_b0 : 8; ++ unsigned long dst_end_y_b1 : 6; ++ unsigned long : 2; ++ } dst_line_end_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dst_line_end_t f; ++} dst_line_end_u; ++ ++typedef struct _brush_offset_t { ++ unsigned long brush_offset : 24; ++ unsigned long : 8; ++ } brush_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ brush_offset_t f; ++} brush_offset_u; ++ ++typedef struct _brush_y_x_t { ++ unsigned long brush_x : 5; ++ unsigned long : 3; ++ unsigned long brush_y : 3; ++ unsigned long : 21; ++ } brush_y_x_t; ++ ++typedef union { ++ unsigned long val : 32; ++ brush_y_x_t f; ++} brush_y_x_u; ++ ++typedef struct _dp_brush_frgd_clr_t { ++ unsigned long dp_brush_frgd_clr : 32; ++ } dp_brush_frgd_clr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dp_brush_frgd_clr_t f; ++} dp_brush_frgd_clr_u; ++ ++typedef struct _dp_brush_bkgd_clr_t { ++ unsigned long dp_brush_bkgd_clr : 32; ++ } dp_brush_bkgd_clr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dp_brush_bkgd_clr_t f; ++} dp_brush_bkgd_clr_u; ++ ++typedef struct _src2_offset_t { ++ unsigned long src2_offset : 24; ++ unsigned long : 8; ++ } src2_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src2_offset_t f; ++} src2_offset_u; ++ ++typedef struct _src2_pitch_t { ++ unsigned long src2_pitch : 14; ++ unsigned long src2_pitch_mul : 2; ++ unsigned long : 16; ++ } src2_pitch_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src2_pitch_t f; ++} src2_pitch_u; ++ ++typedef struct _src2_pitch_offset_t { ++ unsigned long src2_offset : 20; ++ unsigned long : 2; ++ unsigned long src2_pitch : 8; ++ unsigned long src2_pitch_mul : 2; ++ } src2_pitch_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src2_pitch_offset_t f; ++} src2_pitch_offset_u; ++ ++typedef struct _src2_x_t { ++ unsigned long src_x : 14; ++ unsigned long : 18; ++ } src2_x_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src2_x_t f; ++} src2_x_u; ++ ++typedef struct _src2_y_t { ++ unsigned long src_y : 14; ++ unsigned long : 18; ++ } src2_y_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src2_y_t f; ++} src2_y_u; ++ ++typedef struct _src2_x_y_t { ++ unsigned long src_y : 14; ++ unsigned long : 2; ++ unsigned long src_x : 14; ++ unsigned long : 2; ++ } src2_x_y_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src2_x_y_t f; ++} src2_x_y_u; ++ ++typedef struct _src2_width_t { ++ unsigned long src2_width : 14; ++ unsigned long : 18; ++ } src2_width_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src2_width_t f; ++} src2_width_u; ++ ++typedef struct _src2_height_t { ++ unsigned long src2_height : 14; ++ unsigned long : 18; ++ } src2_height_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src2_height_t f; ++} src2_height_u; ++ ++typedef struct _src2_inc_t { ++ unsigned long src2_xinc : 6; ++ unsigned long : 2; ++ unsigned long src2_yinc : 6; ++ unsigned long : 18; ++ } src2_inc_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src2_inc_t f; ++} src2_inc_u; ++ ++typedef struct _src_offset_t { ++ unsigned long src_offset : 24; ++ unsigned long : 8; ++ } src_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_offset_t f; ++} src_offset_u; ++ ++typedef struct _src_pitch_t { ++ unsigned long src_pitch : 14; ++ unsigned long src_pitch_mul : 2; ++ unsigned long : 16; ++ } src_pitch_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_pitch_t f; ++} src_pitch_u; ++ ++typedef struct _src_pitch_offset_t { ++ unsigned long src_offset : 20; ++ unsigned long src_pitch : 10; ++ unsigned long src_pitch_mul : 2; ++ } src_pitch_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_pitch_offset_t f; ++} src_pitch_offset_u; ++ ++typedef struct _src_x_t { ++ unsigned long src_x : 14; ++ unsigned long : 18; ++ } src_x_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_x_t f; ++} src_x_u; ++ ++typedef struct _src_y_t { ++ unsigned long src_y : 14; ++ unsigned long : 18; ++ } src_y_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_y_t f; ++} src_y_u; ++ ++typedef struct _src_x_y_t { ++ unsigned long src_y : 14; ++ unsigned long : 2; ++ unsigned long src_x : 14; ++ unsigned long : 2; ++ } src_x_y_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_x_y_t f; ++} src_x_y_u; ++ ++typedef struct _src_y_x_t { ++ unsigned long src_x : 14; ++ unsigned long : 2; ++ unsigned long src_y : 14; ++ unsigned long : 2; ++ } src_y_x_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_y_x_t f; ++} src_y_x_u; ++ ++typedef struct _src_width_t { ++ unsigned long src_width : 14; ++ unsigned long : 18; ++ } src_width_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_width_t f; ++} src_width_u; ++ ++typedef struct _src_height_t { ++ unsigned long src_height : 14; ++ unsigned long : 18; ++ } src_height_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_height_t f; ++} src_height_u; ++ ++typedef struct _src_inc_t { ++ unsigned long src_xinc : 6; ++ unsigned long : 2; ++ unsigned long src_yinc : 6; ++ unsigned long : 18; ++ } src_inc_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_inc_t f; ++} src_inc_u; ++ ++typedef struct _host_data0_t { ++ unsigned long host_data : 32; ++ } host_data0_t; ++ ++typedef union { ++ unsigned long val : 32; ++ host_data0_t f; ++} host_data0_u; ++ ++typedef struct _host_data1_t { ++ unsigned long host_data : 32; ++ } host_data1_t; ++ ++typedef union { ++ unsigned long val : 32; ++ host_data1_t f; ++} host_data1_u; ++ ++typedef struct _host_data2_t { ++ unsigned long host_data : 32; ++ } host_data2_t; ++ ++typedef union { ++ unsigned long val : 32; ++ host_data2_t f; ++} host_data2_u; ++ ++typedef struct _host_data3_t { ++ unsigned long host_data : 32; ++ } host_data3_t; ++ ++typedef union { ++ unsigned long val : 32; ++ host_data3_t f; ++} host_data3_u; ++ ++typedef struct _host_data4_t { ++ unsigned long host_data : 32; ++ } host_data4_t; ++ ++typedef union { ++ unsigned long val : 32; ++ host_data4_t f; ++} host_data4_u; ++ ++typedef struct _host_data5_t { ++ unsigned long host_data : 32; ++ } host_data5_t; ++ ++typedef union { ++ unsigned long val : 32; ++ host_data5_t f; ++} host_data5_u; ++ ++typedef struct _host_data6_t { ++ unsigned long host_data : 32; ++ } host_data6_t; ++ ++typedef union { ++ unsigned long val : 32; ++ host_data6_t f; ++} host_data6_u; ++ ++typedef struct _host_data7_t { ++ unsigned long host_data : 32; ++ } host_data7_t; ++ ++typedef union { ++ unsigned long val : 32; ++ host_data7_t f; ++} host_data7_u; ++ ++typedef struct _host_data_last_t { ++ unsigned long host_data_last : 32; ++ } host_data_last_t; ++ ++typedef union { ++ unsigned long val : 32; ++ host_data_last_t f; ++} host_data_last_u; ++ ++typedef struct _dp_src_frgd_clr_t { ++ unsigned long dp_src_frgd_clr : 32; ++ } dp_src_frgd_clr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dp_src_frgd_clr_t f; ++} dp_src_frgd_clr_u; ++ ++typedef struct _dp_src_bkgd_clr_t { ++ unsigned long dp_src_bkgd_clr : 32; ++ } dp_src_bkgd_clr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dp_src_bkgd_clr_t f; ++} dp_src_bkgd_clr_u; ++ ++typedef struct _sc_left_t { ++ unsigned long sc_left : 14; ++ unsigned long : 18; ++ } sc_left_t; ++ ++typedef union { ++ unsigned long val : 32; ++ sc_left_t f; ++} sc_left_u; ++ ++typedef struct _sc_right_t { ++ unsigned long sc_right : 14; ++ unsigned long : 18; ++ } sc_right_t; ++ ++typedef union { ++ unsigned long val : 32; ++ sc_right_t f; ++} sc_right_u; ++ ++typedef struct _sc_top_t { ++ unsigned long sc_top : 14; ++ unsigned long : 18; ++ } sc_top_t; ++ ++typedef union { ++ unsigned long val : 32; ++ sc_top_t f; ++} sc_top_u; ++ ++typedef struct _sc_bottom_t { ++ unsigned long sc_bottom : 14; ++ unsigned long : 18; ++ } sc_bottom_t; ++ ++typedef union { ++ unsigned long val : 32; ++ sc_bottom_t f; ++} sc_bottom_u; ++ ++typedef struct _src_sc_right_t { ++ unsigned long sc_right : 14; ++ unsigned long : 18; ++ } src_sc_right_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_sc_right_t f; ++} src_sc_right_u; ++ ++typedef struct _src_sc_bottom_t { ++ unsigned long sc_bottom : 14; ++ unsigned long : 18; ++ } src_sc_bottom_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_sc_bottom_t f; ++} src_sc_bottom_u; ++ ++typedef struct _dp_cntl_t { ++ unsigned long dst_x_dir : 1; ++ unsigned long dst_y_dir : 1; ++ unsigned long src_x_dir : 1; ++ unsigned long src_y_dir : 1; ++ unsigned long dst_major_x : 1; ++ unsigned long src_major_x : 1; ++ unsigned long : 26; ++ } dp_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dp_cntl_t f; ++} dp_cntl_u; ++ ++typedef struct _dp_cntl_dst_dir_t { ++ unsigned long : 15; ++ unsigned long dst_y_dir : 1; ++ unsigned long : 15; ++ unsigned long dst_x_dir : 1; ++ } dp_cntl_dst_dir_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dp_cntl_dst_dir_t f; ++} dp_cntl_dst_dir_u; ++ ++typedef struct _dp_datatype_t { ++ unsigned long dp_dst_datatype : 4; ++ unsigned long : 4; ++ unsigned long dp_brush_datatype : 4; ++ unsigned long dp_src2_type : 1; ++ unsigned long dp_src2_datatype : 3; ++ unsigned long dp_src_datatype : 3; ++ unsigned long : 11; ++ unsigned long dp_byte_pix_order : 1; ++ unsigned long : 1; ++ } dp_datatype_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dp_datatype_t f; ++} dp_datatype_u; ++ ++typedef struct _dp_mix_t { ++ unsigned long : 8; ++ unsigned long dp_src_source : 3; ++ unsigned long dp_src2_source : 3; ++ unsigned long : 2; ++ unsigned long dp_rop3 : 8; ++ unsigned long dp_op : 1; ++ unsigned long : 7; ++ } dp_mix_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dp_mix_t f; ++} dp_mix_u; ++ ++typedef struct _dp_write_msk_t { ++ unsigned long dp_write_msk : 32; ++ } dp_write_msk_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dp_write_msk_t f; ++} dp_write_msk_u; ++ ++typedef struct _clr_cmp_clr_src_t { ++ unsigned long clr_cmp_clr_src : 32; ++ } clr_cmp_clr_src_t; ++ ++typedef union { ++ unsigned long val : 32; ++ clr_cmp_clr_src_t f; ++} clr_cmp_clr_src_u; ++ ++typedef struct _clr_cmp_clr_dst_t { ++ unsigned long clr_cmp_clr_dst : 32; ++ } clr_cmp_clr_dst_t; ++ ++typedef union { ++ unsigned long val : 32; ++ clr_cmp_clr_dst_t f; ++} clr_cmp_clr_dst_u; ++ ++typedef struct _clr_cmp_cntl_t { ++ unsigned long clr_cmp_fcn_src : 3; ++ unsigned long : 5; ++ unsigned long clr_cmp_fcn_dst : 3; ++ unsigned long : 13; ++ unsigned long clr_cmp_src : 2; ++ unsigned long : 6; ++ } clr_cmp_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ clr_cmp_cntl_t f; ++} clr_cmp_cntl_u; ++ ++typedef struct _clr_cmp_msk_t { ++ unsigned long clr_cmp_msk : 32; ++ } clr_cmp_msk_t; ++ ++typedef union { ++ unsigned long val : 32; ++ clr_cmp_msk_t f; ++} clr_cmp_msk_u; ++ ++typedef struct _default_pitch_offset_t { ++ unsigned long default_offset : 20; ++ unsigned long default_pitch : 10; ++ unsigned long : 2; ++ } default_pitch_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ default_pitch_offset_t f; ++} default_pitch_offset_u; ++ ++typedef struct _default_sc_bottom_right_t { ++ unsigned long default_sc_right : 14; ++ unsigned long : 2; ++ unsigned long default_sc_bottom : 14; ++ unsigned long : 2; ++ } default_sc_bottom_right_t; ++ ++typedef union { ++ unsigned long val : 32; ++ default_sc_bottom_right_t f; ++} default_sc_bottom_right_u; ++ ++typedef struct _default2_sc_bottom_right_t { ++ unsigned long default_sc_right : 14; ++ unsigned long : 2; ++ unsigned long default_sc_bottom : 14; ++ unsigned long : 2; ++ } default2_sc_bottom_right_t; ++ ++typedef union { ++ unsigned long val : 32; ++ default2_sc_bottom_right_t f; ++} default2_sc_bottom_right_u; ++ ++typedef struct _ref1_pitch_offset_t { ++ unsigned long offset : 20; ++ unsigned long : 2; ++ unsigned long pitch : 8; ++ unsigned long : 2; ++ } ref1_pitch_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ ref1_pitch_offset_t f; ++} ref1_pitch_offset_u; ++ ++typedef struct _ref2_pitch_offset_t { ++ unsigned long offset : 20; ++ unsigned long : 2; ++ unsigned long pitch : 8; ++ unsigned long : 2; ++ } ref2_pitch_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ ref2_pitch_offset_t f; ++} ref2_pitch_offset_u; ++ ++typedef struct _ref3_pitch_offset_t { ++ unsigned long offset : 20; ++ unsigned long : 2; ++ unsigned long pitch : 8; ++ unsigned long : 2; ++ } ref3_pitch_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ ref3_pitch_offset_t f; ++} ref3_pitch_offset_u; ++ ++typedef struct _ref4_pitch_offset_t { ++ unsigned long offset : 20; ++ unsigned long : 2; ++ unsigned long pitch : 8; ++ unsigned long : 2; ++ } ref4_pitch_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ ref4_pitch_offset_t f; ++} ref4_pitch_offset_u; ++ ++typedef struct _ref5_pitch_offset_t { ++ unsigned long offset : 20; ++ unsigned long : 2; ++ unsigned long pitch : 8; ++ unsigned long : 2; ++ } ref5_pitch_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ ref5_pitch_offset_t f; ++} ref5_pitch_offset_u; ++ ++typedef struct _ref6_pitch_offset_t { ++ unsigned long offset : 20; ++ unsigned long : 2; ++ unsigned long pitch : 8; ++ unsigned long : 2; ++ } ref6_pitch_offset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ ref6_pitch_offset_t f; ++} ref6_pitch_offset_u; ++ ++typedef struct _dp_gui_master_cntl_t { ++ unsigned long gmc_src_pitch_offset_cntl : 1; ++ unsigned long gmc_dst_pitch_offset_cntl : 1; ++ unsigned long gmc_src_clipping : 1; ++ unsigned long gmc_dst_clipping : 1; ++ unsigned long gmc_brush_datatype : 4; ++ unsigned long gmc_dst_datatype : 4; ++ unsigned long gmc_src_datatype : 3; ++ unsigned long gmc_byte_pix_order : 1; ++ unsigned long gmc_default_sel : 1; ++ unsigned long gmc_rop3 : 8; ++ unsigned long gmc_dp_src_source : 3; ++ unsigned long gmc_clr_cmp_fcn_dis : 1; ++ unsigned long : 1; ++ unsigned long gmc_wr_msk_dis : 1; ++ unsigned long gmc_dp_op : 1; ++ } dp_gui_master_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ dp_gui_master_cntl_t f; ++} dp_gui_master_cntl_u; ++ ++typedef struct _sc_top_left_t { ++ unsigned long sc_left : 14; ++ unsigned long : 2; ++ unsigned long sc_top : 14; ++ unsigned long : 2; ++ } sc_top_left_t; ++ ++typedef union { ++ unsigned long val : 32; ++ sc_top_left_t f; ++} sc_top_left_u; ++ ++typedef struct _sc_bottom_right_t { ++ unsigned long sc_right : 14; ++ unsigned long : 2; ++ unsigned long sc_bottom : 14; ++ unsigned long : 2; ++ } sc_bottom_right_t; ++ ++typedef union { ++ unsigned long val : 32; ++ sc_bottom_right_t f; ++} sc_bottom_right_u; ++ ++typedef struct _src_sc_top_left_t { ++ unsigned short sc_left; ++ unsigned short sc_top; ++} src_sc_top_left_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_sc_top_left_t f; ++} src_sc_top_left_u; ++ ++typedef struct _src_sc_bottom_right_t { ++ unsigned long sc_right : 14; ++ unsigned long : 2; ++ unsigned long sc_bottom : 14; ++ unsigned long : 2; ++ } src_sc_bottom_right_t; ++ ++typedef union { ++ unsigned long val : 32; ++ src_sc_bottom_right_t f; ++} src_sc_bottom_right_u; ++ ++typedef struct _global_alpha_t { ++ unsigned long alpha_r : 8; ++ unsigned long alpha_g : 8; ++ unsigned long alpha_b : 8; ++ unsigned long alpha_a : 8; ++} global_alpha_t; ++ ++typedef union { ++ unsigned long val : 32; ++ global_alpha_t f; ++} global_alpha_u; ++ ++typedef struct _filter_coef_t { ++ unsigned long c_4 : 4; ++ unsigned long c_3 : 4; ++ unsigned long c_2 : 4; ++ unsigned long c_1 : 4; ++ unsigned long c1 : 4; ++ unsigned long c2 : 4; ++ unsigned long c3 : 4; ++ unsigned long c4 : 4; ++} filter_coef_t; ++ ++typedef union { ++ unsigned long val : 32; ++ filter_coef_t f; ++} filter_coef_u; ++ ++typedef struct _mvc_cntl_start_t { ++ unsigned long mc_cntl_src_1_index : 4; ++ unsigned long mc_cntl_dst_offset : 20; ++ unsigned long mc_dst_pitch_mul : 2; ++ unsigned long mc_cntl_src_2_index : 3; ++ unsigned long mc_cntl_width_height_sel : 3; ++} mvc_cntl_start_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mvc_cntl_start_t f; ++} mvc_cntl_start_u; ++ ++typedef struct _e2_arithmetic_cntl_t { ++ unsigned long opcode : 5; ++ unsigned long shiftright : 4; ++ unsigned long clamp : 1; ++ unsigned long rounding : 2; ++ unsigned long filter_n : 3; ++ unsigned long : 1; ++ unsigned long srcblend_inv : 1; ++ unsigned long srcblend : 4; ++ unsigned long : 3; ++ unsigned long dstblend_inv : 1; ++ unsigned long dstblend : 4; ++ unsigned long dst_signed : 1; ++ unsigned long autoinc : 1; ++ unsigned long : 1; ++} e2_arithmetic_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ e2_arithmetic_cntl_t f; ++} e2_arithmetic_cntl_u; ++ ++typedef struct _debug0_t { ++ unsigned long debug0_r : 8; ++ unsigned long : 8; ++ unsigned long debug0_rw : 8; ++ unsigned long : 8; ++} debug0_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug0_t f; ++} debug0_u; ++ ++typedef struct _debug1_t { ++ unsigned long debug1_r : 8; ++ unsigned long : 8; ++ unsigned long debug1_rw : 8; ++ unsigned long : 8; ++} debug1_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug1_t f; ++} debug1_u; ++ ++typedef struct _debug2_t { ++ unsigned long debug2_r : 8; ++ unsigned long : 8; ++ unsigned long debug2_rw : 8; ++ unsigned long : 8; ++} debug2_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug2_t f; ++} debug2_u; ++ ++typedef struct _debug3_t { ++ unsigned long : 32; ++} debug3_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug3_t f; ++} debug3_u; ++ ++typedef struct _debug4_t { ++ unsigned long : 32; ++} debug4_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug4_t f; ++} debug4_u; ++ ++typedef struct _debug5_t { ++ unsigned long : 32; ++} debug5_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug5_t f; ++} debug5_u; ++ ++typedef struct _debug6_t { ++ unsigned long : 32; ++} debug6_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug6_t f; ++} debug6_u; ++ ++typedef struct _debug7_t { ++ unsigned long : 32; ++} debug7_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug7_t f; ++} debug7_u; ++ ++typedef struct _debug8_t { ++ unsigned long : 32; ++} debug8_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug8_t f; ++} debug8_u; ++ ++typedef struct _debug9_t { ++ unsigned long : 32; ++} debug9_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug9_t f; ++} debug9_u; ++ ++typedef struct _debug10_t { ++ unsigned long : 32; ++ } debug10_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug10_t f; ++} debug10_u; ++ ++typedef struct _debug11_t { ++ unsigned long : 32; ++ } debug11_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug11_t f; ++} debug11_u; ++ ++typedef struct _debug12_t { ++ unsigned long : 32; ++ } debug12_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug12_t f; ++} debug12_u; ++ ++typedef struct _debug13_t { ++ unsigned long : 32; ++ } debug13_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug13_t f; ++} debug13_u; ++ ++typedef struct _debug14_t { ++ unsigned long : 32; ++ } debug14_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug14_t f; ++} debug14_u; ++ ++typedef struct _debug15_t { ++ unsigned long : 32; ++ } debug15_t; ++ ++typedef union { ++ unsigned long val : 32; ++ debug15_t f; ++} debug15_u; ++ ++typedef struct _eng_cntl_t { ++ unsigned long erc_reg_rd_ws : 1; ++ unsigned long erc_reg_wr_ws : 1; ++ unsigned long erc_idle_reg_wr : 1; ++ unsigned long dis_engine_triggers : 1; ++ unsigned long dis_rop_src_uses_dst_w_h : 1; ++ unsigned long dis_src_uses_dst_dirmaj : 1; ++ unsigned long : 6; ++ unsigned long force_3dclk_when_2dclk : 1; ++ unsigned long : 19; ++ } eng_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ eng_cntl_t f; ++} eng_cntl_u; ++ ++typedef struct _eng_perf_cnt_t { ++ unsigned long perf_cnt : 20; ++ unsigned long perf_sel : 4; ++ unsigned long perf_en : 1; ++ unsigned long : 3; ++ unsigned long perf_clr : 1; ++ unsigned long : 3; ++ } eng_perf_cnt_t; ++ ++typedef union { ++ unsigned long val : 32; ++ eng_perf_cnt_t f; ++} eng_perf_cnt_u; ++ ++typedef struct _idct_runs_t { ++ unsigned long idct_runs_3 : 8; ++ unsigned long idct_runs_2 : 8; ++ unsigned long idct_runs_1 : 8; ++ unsigned long idct_runs_0 : 8; ++ } idct_runs_t; ++ ++typedef union { ++ unsigned long val : 32; ++ idct_runs_t f; ++} idct_runs_u; ++ ++typedef struct _idct_levels_t { ++ unsigned long idct_level_hi : 16; ++ unsigned long idct_level_lo : 16; ++ } idct_levels_t; ++ ++typedef union { ++ unsigned long val : 32; ++ idct_levels_t f; ++} idct_levels_u; ++ ++typedef struct _idct_control_t { ++ unsigned long idct_ctl_luma_rd_format : 2; ++ unsigned long idct_ctl_chroma_rd_format : 2; ++ unsigned long idct_ctl_scan_pattern : 1; ++ unsigned long idct_ctl_intra : 1; ++ unsigned long idct_ctl_flush : 1; ++ unsigned long idct_ctl_passthru : 1; ++ unsigned long idct_ctl_sw_reset : 1; ++ unsigned long idct_ctl_constreq : 1; ++ unsigned long idct_ctl_scramble : 1; ++ unsigned long idct_ctl_alt_scan : 1; ++ unsigned long : 20; ++ } idct_control_t; ++ ++typedef union { ++ unsigned long val : 32; ++ idct_control_t f; ++} idct_control_u; ++ ++typedef struct _idct_auth_control_t { ++ unsigned long control_bits : 32; ++ } idct_auth_control_t; ++ ++typedef union { ++ unsigned long val : 32; ++ idct_auth_control_t f; ++} idct_auth_control_u; ++ ++typedef struct _idct_auth_t { ++ unsigned long auth : 32; ++ } idct_auth_t; ++ ++typedef union { ++ unsigned long val : 32; ++ idct_auth_t f; ++} idct_auth_u; ++ ++typedef struct _mem_cntl_t { ++ unsigned long : 1; ++ unsigned long en_mem_ch1 : 1; ++ unsigned long en_mem_ch2 : 1; ++ unsigned long int_mem_mapping : 1; ++ unsigned long : 28; ++ } mem_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mem_cntl_t f; ++} mem_cntl_u; ++ ++typedef struct _mem_arb_t { ++ unsigned long disp_time_slot : 4; ++ unsigned long disp_timer : 4; ++ unsigned long arb_option : 1; ++ unsigned long : 23; ++ } mem_arb_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mem_arb_t f; ++} mem_arb_u; ++ ++typedef struct _mc_fb_location_t { ++ unsigned long mc_fb_start : 16; ++ unsigned long mc_fb_top : 16; ++ } mc_fb_location_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mc_fb_location_t f; ++} mc_fb_location_u; ++ ++typedef struct _mem_ext_cntl_t { ++ unsigned long mem_ext_enable : 1; ++ unsigned long mem_ap_enable : 1; ++ unsigned long mem_addr_mapping : 2; ++ unsigned long mem_wdoe_cntl : 2; ++ unsigned long mem_wdoe_extend : 1; ++ unsigned long : 1; ++ unsigned long mem_page_timer : 8; ++ unsigned long mem_dynamic_cke : 1; ++ unsigned long mem_sdram_tri_en : 1; ++ unsigned long mem_self_refresh_en : 1; ++ unsigned long mem_power_down : 1; ++ unsigned long mem_hw_power_down_en : 1; ++ unsigned long mem_power_down_stat : 1; ++ unsigned long : 3; ++ unsigned long mem_pd_mck : 1; ++ unsigned long mem_pd_ma : 1; ++ unsigned long mem_pd_mdq : 1; ++ unsigned long mem_tristate_mck : 1; ++ unsigned long mem_tristate_ma : 1; ++ unsigned long mem_tristate_mcke : 1; ++ unsigned long mem_invert_mck : 1; ++ } mem_ext_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mem_ext_cntl_t f; ++} mem_ext_cntl_u; ++ ++typedef struct _mc_ext_mem_location_t { ++ unsigned long mc_ext_mem_start : 16; ++ unsigned long mc_ext_mem_top : 16; ++ } mc_ext_mem_location_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mc_ext_mem_location_t f; ++} mc_ext_mem_location_u; ++ ++typedef struct _mem_ext_timing_cntl_t { ++ unsigned long mem_trp : 2; ++ unsigned long mem_trcd : 2; ++ unsigned long mem_tras : 3; ++ unsigned long : 1; ++ unsigned long mem_trrd : 2; ++ unsigned long mem_tr2w : 2; ++ unsigned long mem_twr : 2; ++ unsigned long : 4; ++ unsigned long mem_twr_mode : 1; ++ unsigned long : 1; ++ unsigned long mem_refresh_dis : 1; ++ unsigned long : 3; ++ unsigned long mem_refresh_rate : 8; ++ } mem_ext_timing_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mem_ext_timing_cntl_t f; ++} mem_ext_timing_cntl_u; ++ ++typedef struct _mem_sdram_mode_reg_t { ++ unsigned long mem_mode_reg : 14; ++ unsigned long : 2; ++ unsigned long mem_read_latency : 2; ++ unsigned long mem_schmen_latency : 2; ++ unsigned long mem_cas_latency : 2; ++ unsigned long mem_schmen_extend : 1; ++ unsigned long : 8; ++ unsigned long mem_sdram_reset : 1; ++ } mem_sdram_mode_reg_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mem_sdram_mode_reg_t f; ++} mem_sdram_mode_reg_u; ++ ++typedef struct _mem_io_cntl_t { ++ unsigned long mem_sn_mck : 4; ++ unsigned long mem_sn_ma : 4; ++ unsigned long mem_sn_mdq : 4; ++ unsigned long mem_srn_mck : 1; ++ unsigned long mem_srn_ma : 1; ++ unsigned long mem_srn_mdq : 1; ++ unsigned long : 1; ++ unsigned long mem_sp_mck : 4; ++ unsigned long mem_sp_ma : 4; ++ unsigned long mem_sp_mdq : 4; ++ unsigned long mem_srp_mck : 1; ++ unsigned long mem_srp_ma : 1; ++ unsigned long mem_srp_mdq : 1; ++ unsigned long : 1; ++ } mem_io_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mem_io_cntl_t f; ++} mem_io_cntl_u; ++ ++typedef struct _mc_debug_t { ++ unsigned long mc_debug : 32; ++ } mc_debug_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mc_debug_t f; ++} mc_debug_u; ++ ++typedef struct _mc_bist_ctrl_t { ++ unsigned long mc_bist_ctrl : 32; ++ } mc_bist_ctrl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mc_bist_ctrl_t f; ++} mc_bist_ctrl_u; ++ ++typedef struct _mc_bist_collar_read_t { ++ unsigned long mc_bist_collar_read : 32; ++ } mc_bist_collar_read_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mc_bist_collar_read_t f; ++} mc_bist_collar_read_u; ++ ++typedef struct _tc_mismatch_t { ++ unsigned long tc_mismatch : 24; ++ unsigned long : 8; ++ } tc_mismatch_t; ++ ++typedef union { ++ unsigned long val : 32; ++ tc_mismatch_t f; ++} tc_mismatch_u; ++ ++typedef struct _mc_perf_mon_cntl_t { ++ unsigned long clr_perf : 1; ++ unsigned long en_perf : 1; ++ unsigned long : 2; ++ unsigned long perf_op_a : 2; ++ unsigned long perf_op_b : 2; ++ unsigned long : 8; ++ unsigned long monitor_period : 8; ++ unsigned long perf_count_a_overflow : 1; ++ unsigned long perf_count_b_overflow : 1; ++ unsigned long : 6; ++ } mc_perf_mon_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mc_perf_mon_cntl_t f; ++} mc_perf_mon_cntl_u; ++ ++typedef struct _mc_perf_counters_t { ++ unsigned long mc_perf_counter_a : 16; ++ unsigned long mc_perf_counter_b : 16; ++ } mc_perf_counters_t; ++ ++typedef union { ++ unsigned long val : 32; ++ mc_perf_counters_t f; ++} mc_perf_counters_u; ++ ++typedef struct _wait_until_t { ++ unsigned long wait_crtc_pflip : 1; ++ unsigned long wait_re_crtc_vline : 1; ++ unsigned long wait_fe_crtc_vline : 1; ++ unsigned long wait_crtc_vline : 1; ++ unsigned long wait_dma_viph0_idle : 1; ++ unsigned long wait_dma_viph1_idle : 1; ++ unsigned long wait_dma_viph2_idle : 1; ++ unsigned long wait_dma_viph3_idle : 1; ++ unsigned long wait_dma_vid_idle : 1; ++ unsigned long wait_dma_gui_idle : 1; ++ unsigned long wait_cmdfifo : 1; ++ unsigned long wait_ov0_flip : 1; ++ unsigned long wait_ov0_slicedone : 1; ++ unsigned long : 1; ++ unsigned long wait_2d_idle : 1; ++ unsigned long wait_3d_idle : 1; ++ unsigned long wait_2d_idleclean : 1; ++ unsigned long wait_3d_idleclean : 1; ++ unsigned long wait_host_idleclean : 1; ++ unsigned long wait_extern_sig : 1; ++ unsigned long cmdfifo_entries : 7; ++ unsigned long : 3; ++ unsigned long wait_both_crtc_pflip : 1; ++ unsigned long eng_display_select : 1; ++ } wait_until_t; ++ ++typedef union { ++ unsigned long val : 32; ++ wait_until_t f; ++} wait_until_u; ++ ++typedef struct _isync_cntl_t { ++ unsigned long isync_any2d_idle3d : 1; ++ unsigned long isync_any3d_idle2d : 1; ++ unsigned long isync_trig2d_idle3d : 1; ++ unsigned long isync_trig3d_idle2d : 1; ++ unsigned long isync_wait_idlegui : 1; ++ unsigned long isync_cpscratch_idlegui : 1; ++ unsigned long : 26; ++ } isync_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ isync_cntl_t f; ++} isync_cntl_u; ++ ++typedef struct _rbbm_guicntl_t { ++ unsigned long host_data_swap : 2; ++ unsigned long : 30; ++ } rbbm_guicntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ rbbm_guicntl_t f; ++} rbbm_guicntl_u; ++ ++typedef struct _rbbm_status_t { ++ unsigned long cmdfifo_avail : 7; ++ unsigned long : 1; ++ unsigned long hirq_on_rbb : 1; ++ unsigned long cprq_on_rbb : 1; ++ unsigned long cfrq_on_rbb : 1; ++ unsigned long hirq_in_rtbuf : 1; ++ unsigned long cprq_in_rtbuf : 1; ++ unsigned long cfrq_in_rtbuf : 1; ++ unsigned long cf_pipe_busy : 1; ++ unsigned long eng_ev_busy : 1; ++ unsigned long cp_cmdstrm_busy : 1; ++ unsigned long e2_busy : 1; ++ unsigned long rb2d_busy : 1; ++ unsigned long rb3d_busy : 1; ++ unsigned long se_busy : 1; ++ unsigned long re_busy : 1; ++ unsigned long tam_busy : 1; ++ unsigned long tdm_busy : 1; ++ unsigned long pb_busy : 1; ++ unsigned long : 6; ++ unsigned long gui_active : 1; ++ } rbbm_status_t; ++ ++typedef union { ++ unsigned long val : 32; ++ rbbm_status_t f; ++} rbbm_status_u; ++ ++typedef struct _rbbm_cntl_t { ++ unsigned long rb_settle : 4; ++ unsigned long abortclks_hi : 3; ++ unsigned long : 1; ++ unsigned long abortclks_cp : 3; ++ unsigned long : 1; ++ unsigned long abortclks_cfifo : 3; ++ unsigned long : 2; ++ unsigned long cpq_data_swap : 1; ++ unsigned long : 3; ++ unsigned long no_abort_idct : 1; ++ unsigned long no_abort_bios : 1; ++ unsigned long no_abort_fb : 1; ++ unsigned long no_abort_cp : 1; ++ unsigned long no_abort_hi : 1; ++ unsigned long no_abort_hdp : 1; ++ unsigned long no_abort_mc : 1; ++ unsigned long no_abort_aic : 1; ++ unsigned long no_abort_vip : 1; ++ unsigned long no_abort_disp : 1; ++ unsigned long no_abort_cg : 1; ++ } rbbm_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ rbbm_cntl_t f; ++} rbbm_cntl_u; ++ ++typedef struct _rbbm_soft_reset_t { ++ unsigned long soft_reset_cp : 1; ++ unsigned long soft_reset_hi : 1; ++ unsigned long reserved3 : 3; ++ unsigned long soft_reset_e2 : 1; ++ unsigned long reserved2 : 2; ++ unsigned long soft_reset_mc : 1; ++ unsigned long reserved1 : 2; ++ unsigned long soft_reset_disp : 1; ++ unsigned long soft_reset_cg : 1; ++ unsigned long : 19; ++ } rbbm_soft_reset_t; ++ ++typedef union { ++ unsigned long val : 32; ++ rbbm_soft_reset_t f; ++} rbbm_soft_reset_u; ++ ++typedef struct _nqwait_until_t { ++ unsigned long wait_gui_idle : 1; ++ unsigned long : 31; ++ } nqwait_until_t; ++ ++typedef union { ++ unsigned long val : 32; ++ nqwait_until_t f; ++} nqwait_until_u; ++ ++typedef struct _rbbm_debug_t { ++ unsigned long rbbm_debug : 32; ++ } rbbm_debug_t; ++ ++typedef union { ++ unsigned long val : 32; ++ rbbm_debug_t f; ++} rbbm_debug_u; ++ ++typedef struct _rbbm_cmdfifo_addr_t { ++ unsigned long cmdfifo_addr : 6; ++ unsigned long : 26; ++ } rbbm_cmdfifo_addr_t; ++ ++typedef union { ++ unsigned long val : 32; ++ rbbm_cmdfifo_addr_t f; ++} rbbm_cmdfifo_addr_u; ++ ++typedef struct _rbbm_cmdfifo_datal_t { ++ unsigned long cmdfifo_datal : 32; ++ } rbbm_cmdfifo_datal_t; ++ ++typedef union { ++ unsigned long val : 32; ++ rbbm_cmdfifo_datal_t f; ++} rbbm_cmdfifo_datal_u; ++ ++typedef struct _rbbm_cmdfifo_datah_t { ++ unsigned long cmdfifo_datah : 12; ++ unsigned long : 20; ++ } rbbm_cmdfifo_datah_t; ++ ++typedef union { ++ unsigned long val : 32; ++ rbbm_cmdfifo_datah_t f; ++} rbbm_cmdfifo_datah_u; ++ ++typedef struct _rbbm_cmdfifo_stat_t { ++ unsigned long cmdfifo_rptr : 6; ++ unsigned long : 2; ++ unsigned long cmdfifo_wptr : 6; ++ unsigned long : 18; ++ } rbbm_cmdfifo_stat_t; ++ ++typedef union { ++ unsigned long val : 32; ++ rbbm_cmdfifo_stat_t f; ++} rbbm_cmdfifo_stat_u; ++ ++typedef struct _clk_pin_cntl_t { ++ unsigned long osc_en : 1; ++ unsigned long osc_gain : 5; ++ unsigned long dont_use_xtalin : 1; ++ unsigned long xtalin_pm_en : 1; ++ unsigned long xtalin_dbl_en : 1; ++ unsigned long : 7; ++ unsigned long cg_debug : 16; ++ } clk_pin_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ clk_pin_cntl_t f; ++} clk_pin_cntl_u; ++ ++typedef struct _pll_ref_fb_div_t { ++ unsigned long pll_ref_div : 4; ++ unsigned long : 4; ++ unsigned long pll_fb_div_int : 6; ++ unsigned long : 2; ++ unsigned long pll_fb_div_frac : 3; ++ unsigned long : 1; ++ unsigned long pll_reset_time : 4; ++ unsigned long pll_lock_time : 8; ++ } pll_ref_fb_div_t; ++ ++typedef union { ++ unsigned long val : 32; ++ pll_ref_fb_div_t f; ++} pll_ref_fb_div_u; ++ ++typedef struct _pll_cntl_t { ++ unsigned long pll_pwdn : 1; ++ unsigned long pll_reset : 1; ++ unsigned long pll_pm_en : 1; ++ unsigned long pll_mode : 1; ++ unsigned long pll_refclk_sel : 1; ++ unsigned long pll_fbclk_sel : 1; ++ unsigned long pll_tcpoff : 1; ++ unsigned long pll_pcp : 3; ++ unsigned long pll_pvg : 3; ++ unsigned long pll_vcofr : 1; ++ unsigned long pll_ioffset : 2; ++ unsigned long pll_pecc_mode : 2; ++ unsigned long pll_pecc_scon : 2; ++ unsigned long pll_dactal : 4; ++ unsigned long pll_cp_clip : 2; ++ unsigned long pll_conf : 3; ++ unsigned long pll_mbctrl : 2; ++ unsigned long pll_ring_off : 1; ++ } pll_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ pll_cntl_t f; ++} pll_cntl_u; ++ ++typedef struct _sclk_cntl_t { ++ unsigned long sclk_src_sel : 2; ++ unsigned long : 2; ++ unsigned long sclk_post_div_fast : 4; ++ unsigned long sclk_clkon_hys : 3; ++ unsigned long sclk_post_div_slow : 4; ++ unsigned long disp_cg_ok2switch_en : 1; ++ unsigned long sclk_force_reg : 1; ++ unsigned long sclk_force_disp : 1; ++ unsigned long sclk_force_mc : 1; ++ unsigned long sclk_force_extmc : 1; ++ unsigned long sclk_force_cp : 1; ++ unsigned long sclk_force_e2 : 1; ++ unsigned long sclk_force_e3 : 1; ++ unsigned long sclk_force_idct : 1; ++ unsigned long sclk_force_bist : 1; ++ unsigned long busy_extend_cp : 1; ++ unsigned long busy_extend_e2 : 1; ++ unsigned long busy_extend_e3 : 1; ++ unsigned long busy_extend_idct : 1; ++ unsigned long : 3; ++ } sclk_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ sclk_cntl_t f; ++} sclk_cntl_u; ++ ++typedef struct _pclk_cntl_t { ++ unsigned long pclk_src_sel : 2; ++ unsigned long : 2; ++ unsigned long pclk_post_div : 4; ++ unsigned long : 8; ++ unsigned long pclk_force_disp : 1; ++ unsigned long : 15; ++ } pclk_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ pclk_cntl_t f; ++} pclk_cntl_u; ++ ++typedef struct _clk_test_cntl_t { ++ unsigned long testclk_sel : 4; ++ unsigned long : 3; ++ unsigned long start_check_freq : 1; ++ unsigned long tstcount_rst : 1; ++ unsigned long : 15; ++ unsigned long test_count : 8; ++ } clk_test_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ clk_test_cntl_t f; ++} clk_test_cntl_u; ++ ++typedef struct _pwrmgt_cntl_t { ++ unsigned long pwm_enable : 1; ++ unsigned long : 1; ++ unsigned long pwm_mode_req : 2; ++ unsigned long pwm_wakeup_cond : 2; ++ unsigned long pwm_fast_noml_hw_en : 1; ++ unsigned long pwm_noml_fast_hw_en : 1; ++ unsigned long pwm_fast_noml_cond : 4; ++ unsigned long pwm_noml_fast_cond : 4; ++ unsigned long pwm_idle_timer : 8; ++ unsigned long pwm_busy_timer : 8; ++ } pwrmgt_cntl_t; ++ ++typedef union { ++ unsigned long val : 32; ++ pwrmgt_cntl_t f; ++} pwrmgt_cntl_u; ++ ++typedef struct _pwrmgt_status_t { ++ unsigned long pwm_mode : 2; ++ unsigned long : 30; ++ } pwrmgt_status_t; ++ ++typedef union { ++ unsigned long val : 32; ++ pwrmgt_status_t f; ++} pwrmgt_status_u; ++ ++ ++#endif //_W100_REGS_H_ +Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/Makefile.am +=================================================================== +--- xorg-server-X11R7.1-1.1.0.orig/hw/kdrive/Makefile.am 2006-09-02 11:47:21.000000000 +0200 ++++ xorg-server-X11R7.1-1.1.0/hw/kdrive/Makefile.am 2006-09-02 11:47:21.000000000 +0200 +@@ -7,6 +7,10 @@ + FBDEV_SUBDIRS = fbdev epson + endif + ++if KDRIVEW100 ++W100_SUBDIRS = w100 ++endif ++ + if XSDLSERVER + XSDL_SUBDIRS = sdl + endif +@@ -20,6 +24,7 @@ + linux \ + $(XSDL_SUBDIRS) \ + $(FBDEV_SUBDIRS) \ ++ $(W100_SUBDIRS) \ + $(VESA_SUBDIRS) \ + $(XEPHYR_SUBDIRS) \ + fake +Index: xorg-server-X11R7.1-1.1.0/configure.ac +=================================================================== +--- xorg-server-X11R7.1-1.1.0.orig/configure.ac 2006-09-02 11:47:21.000000000 +0200 ++++ xorg-server-X11R7.1-1.1.0/configure.ac 2006-09-02 11:51:56.000000000 +0200 +@@ -434,6 +434,7 @@ + AC_ARG_ENABLE(kdrive, AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no]) + AC_ARG_ENABLE(xephyr, AS_HELP_STRING([--enable-xephyr], [Build the kdrive Xephyr server (default: auto)]), [XEPHYR=$enableval], [XEPHYR=auto]) + AC_ARG_ENABLE(xsdl, AS_HELP_STRING([--enable-xsdl], [Build the kdrive Xsdl server (default: auto)]), [XSDL=$enableval], [XSDL=auto]) ++AC_ARG_ENABLE(w100, AS_HELP_STRING([--enable-w100], [Build the kdrive Xw100 server (default: no)]), [KDRIVEW100=$enableval], [KDRIVEW100=no]) + dnl xprint + AC_ARG_ENABLE(freetype, AS_HELP_STRING([ --enable-freetype], [Build Xprint FreeType backend (default: yes)]), [XP_USE_FREETYPE=$enableval],[XP_USE_FREETYPE=no]) + AC_ARG_WITH(freetype-config, AS_HELP_STRING([ --with-freetype-config=PROG], [Use FreeType configuration program PROG (default: auto)]), freetype_config=$withval, freetype_config=auto) +@@ -1497,6 +1498,10 @@ + AC_SUBST([XSDL_LIBS]) + AC_SUBST([XSDL_INCS]) + ++AM_CONDITIONAL(KDRIVEW100, [test "x$KDRIVEW100" = xyes]) ++if test "x$KDRIVEW100" = xyes; then ++ AC_DEFINE(KDRIVEW100, 1, [Build Xw100 server]) ++fi + + dnl these only go in xkb-config.h (which is shared by the Xorg and Xnest servers) + AC_DEFINE(__XKBDEFRULES__, "xorg", [Default XKB rules]) +@@ -1739,6 +1744,7 @@ + hw/kdrive/epson/Makefile + hw/kdrive/fake/Makefile + hw/kdrive/fbdev/Makefile ++hw/kdrive/w100/Makefile + hw/kdrive/i810/Makefile + hw/kdrive/linux/Makefile + hw/kdrive/mach64/Makefile diff --git a/packages/xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb b/packages/xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb index 78b4054232..7ba53b7a73 100644 --- a/packages/xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb +++ b/packages/xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb @@ -1,18 +1,19 @@ LICENSE = "MIT" DEPENDS = "tslib virtual/libsdl xproto libxdmcp xextproto xtrans libxau virtual/libx11 libxext libxrandr fixesproto damageproto libxfont resourceproto compositeproto xcalibrateext recordproto videoproto scrnsaverproto" -PR = "r2" +PR = "r3" PROVIDES = "virtual/xserver" RPROVIDES = "virtual/xserver" -PACKAGES =+ "xserver-kdrive-fbdev xserver-kdrive-sdl xserver-kdrive-fake xserver-kdrive-xephyr xserver-kdrive-epson ${PN}-doc ${PN}-dev ${PN}-locale" +PACKAGES =+ "xserver-kdrive-fbdev xserver-kdrive-sdl xserver-kdrive-fake xserver-kdrive-xephyr xserver-kdrive-epson xserver-kdrive-w100 ${PN}-doc ${PN}-dev ${PN}-locale" SECTION = "x11/base" DESCRIPTION = "X server from freedesktop.org" DESCRIPTION_xserver-kdrive-fbdev = "X server from freedesktop.org, supporting generic framebuffer devices" DESCRIPTION_xserver-kdrive-fake = "Fake X server" DESCRIPTION_xserver-kdrive-xephyr = "X server in an X window" DESCRIPTION_xserver-kdrive-epson = "X server from freedesktop.org, supporting Epson S1D13806 devices" -DESCRIPTION_xserver-kdrive-epson = "X server from freedesktop.org, SDL version" +DESCRIPTION_xserver-kdrive-sdl = "X server from freedesktop.org, SDL version" +DESCRIPTION_xserver-kdrive-w100 = "X server from freedesktop.org, w100 version" FILES_${PN} += "${libdir}/xserver/SecurityPolicy" @@ -21,12 +22,14 @@ FILES_xserver-kdrive-fake = "${bindir}/Xfake" FILES_xserver-kdrive-xephyr = "${bindir}/Xephyr" FILES_xserver-kdrive-epson = "${bindir}/Xepson" FILES_xserver-kdrive-sdl = "${bindir}/Xsdl" +FILES_xserver-kdrive-w100 = "${bindir}/Xw100" RDEPENDS_xserver-kdrive-fbdev = "${PN}" RDEPENDS_xserver-kdrive-fake = "${PN}" RDEPENDS_xserver-kdrive-xephyr = "${PN}" RDEPENDS_xserver-kdrive-epson = "${PN}" RDEPENDS_xserver-kdrive-sdl = "${PN}" +RDEPENDS_xserver-kdrive-w100 = "${PN}" SRC_URI = "http://ftp.x.org/pub/X11R7.1/src/xserver/xorg-server-X11R7.1-1.1.0.tar.bz2 \ file://kmode.patch;patch=1 \ @@ -39,6 +42,7 @@ SRC_URI = "http://ftp.x.org/pub/X11R7.1/src/xserver/xorg-server-X11R7.1-1.1.0.ta file://optional-xkb.patch;patch=1 \ file://enable-epson.patch;patch=1 \ file://disable-xf86-dga-xorgcfg.patch;patch=1 \ + file://w100.patch;patch=1 \ file://enable-tslib.patch;patch=1 \ file://xcalibrate.patch;patch=1" @@ -56,7 +60,7 @@ EXTRA_OECONF = "--enable-composite --enable-kdrive \ --disable-xorg --disable-xorgcfg \ --disable-xkb --disable-xnest --disable-xvfb \ --disable-xevie --disable-xprint --disable-xtrap \ - --disable-dmx \ + --disable-dmx --enable-w100 \ --with-default-font-path=built-ins \ --enable-tslib --enable-xcalibrate \ ac_cv_file__usr_share_X11_sgml_defs_ent=no" diff --git a/packages/xorg-xserver/xserver-kdrive_git.bb b/packages/xorg-xserver/xserver-kdrive_git.bb index bffcc4cdee..5fb8d10822 100644 --- a/packages/xorg-xserver/xserver-kdrive_git.bb +++ b/packages/xorg-xserver/xserver-kdrive_git.bb @@ -1,21 +1,22 @@ PV = "1.1.0+git${SRCDATE}" DEFAULT_PREFERENCE = "-2" -PR = "r4" +PR = "r5" LICENSE = "MIT" DEPENDS = "tslib virtual/libsdl libxkbfile xproto libxdmcp xextproto xtrans libxau virtual/libx11 libxext libxrandr fixesproto damageproto libxfont resourceproto compositeproto libxcalibrate recordproto videoproto scrnsaverproto" PROVIDES = "virtual/xserver" RPROVIDES = "virtual/xserver" -PACKAGES =+ "xserver-kdrive-fbdev xserver-kdrive-sdl xserver-kdrive-fake xserver-kdrive-xephyr xserver-kdrive-epson ${PN}-doc ${PN}-dev ${PN}-locale" +PACKAGES =+ "xserver-kdrive-fbdev xserver-kdrive-sdl xserver-kdrive-fake xserver-kdrive-xephyr xserver-kdrive-epson xserver-kdrive-w100 ${PN}-doc ${PN}-dev ${PN}-locale" SECTION = "x11/base" DESCRIPTION = "X server from freedesktop.org" DESCRIPTION_xserver-kdrive-fbdev = "X server from freedesktop.org, supporting generic framebuffer devices" DESCRIPTION_xserver-kdrive-fake = "Fake X server" DESCRIPTION_xserver-kdrive-xephyr = "X server in an X window" DESCRIPTION_xserver-kdrive-epson = "X server from freedesktop.org, supporting Epson S1D13806 devices" -DESCRIPTION_xserver-kdrive-epson = "X server from freedesktop.org, SDL version" +DESCRIPTION_xserver-kdrive-sdl = "X server from freedesktop.org, SDL version" +DESCRIPTION_xserver-kdrive-w100 = "X server from freedesktop.org, w100 version" FILES_${PN} += "${libdir}/xserver/SecurityPolicy" @@ -24,12 +25,14 @@ FILES_xserver-kdrive-fake = "${bindir}/Xfake" FILES_xserver-kdrive-xephyr = "${bindir}/Xephyr" FILES_xserver-kdrive-epson = "${bindir}/Xepson" FILES_xserver-kdrive-sdl = "${bindir}/Xsdl" +FILES_xserver-kdrive-w100 = "${bindir}/Xw100" RDEPENDS_xserver-kdrive-fbdev = "${PN}" RDEPENDS_xserver-kdrive-fake = "${PN}" RDEPENDS_xserver-kdrive-xephyr = "${PN}" RDEPENDS_xserver-kdrive-epson = "${PN}" RDEPENDS_xserver-kdrive-sdl = "${PN}" +RDEPENDS_xserver-kdrive-w100 = "${PN}" SRC_URI = "git://anongit.freedesktop.org/xorg/xserver;protocol=git \ file://kmode.patch;patch=1 \ @@ -42,6 +45,7 @@ SRC_URI = "git://anongit.freedesktop.org/xorg/xserver;protocol=git \ file://optional-xkb.patch;patch=1 \ file://enable-epson.patch;patch=1 \ file://disable-xf86-dga-xorgcfg-git.patch;patch=1 \ + file://w100.patch;patch=1 \ " SRC_URI_append_mnci = " file://onlyfb.patch;patch=1" @@ -58,7 +62,7 @@ EXTRA_OECONF = "--enable-composite --enable-kdrive \ --disable-xorg --disable-xorgcfg \ --disable-xkb --disable-xnest --disable-xvfb \ --disable-xevie --disable-xprint --disable-xtrap \ - --disable-dmx \ + --disable-dmx --enable-w100 \ --with-default-font-path=built-ins \ --enable-tslib --enable-xcalibrate \ ac_cv_file__usr_share_X11_sgml_defs_ent=no" -- cgit v1.2.3 From 1889b0da866ccdf181791654958f8f0b593f0eb0 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 2 Sep 2006 11:03:51 +0000 Subject: imlib: add 1.9.15 --- packages/imlib/.mtn2git_empty | 0 packages/imlib/files/.mtn2git_empty | 0 packages/imlib/files/configure.patch | 31 +++++++++++++++++++++++++++++++ packages/imlib/imlib_1.9.15.bb | 20 ++++++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 packages/imlib/.mtn2git_empty create mode 100644 packages/imlib/files/.mtn2git_empty create mode 100644 packages/imlib/files/configure.patch create mode 100644 packages/imlib/imlib_1.9.15.bb diff --git a/packages/imlib/.mtn2git_empty b/packages/imlib/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/imlib/files/.mtn2git_empty b/packages/imlib/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/imlib/files/configure.patch b/packages/imlib/files/configure.patch new file mode 100644 index 0000000000..90879c15ee --- /dev/null +++ b/packages/imlib/files/configure.patch @@ -0,0 +1,31 @@ +--- /tmp/configure.in 2006-09-02 12:44:16.000000000 +0200 ++++ imlib-1.9.15/configure.in 2006-09-02 12:44:22.975780000 +0200 +@@ -43,19 +43,6 @@ + oCFLAGS="$CFLAGS" + LIBS="$LIBS `glib-config --libs gmodule`" + CFLAGS="$CFLAGS `glib-config --cflags gmodule`" +- AC_TRY_RUN([ +-#include +-#include +-main () +-{ +- if (g_module_supported ()) +- exit (0); +- else +- exit (1); +-} +-], dynworks=true) +- LIBS="$oLIBS" +- CFLAGS="$oCFLAGS" + fi + + dnl Now we check to see if our libtool supports shared lib deps +@@ -141,7 +128,7 @@ + fi + AC_SUBST(GX_LIBS) + +-CPPFLAGS="$CPPFLAGS -I$includedir -I$prefix/include" ++CPPFLAGS="$CPPFLAGS" + + SUPPORT_LIBS="" + diff --git a/packages/imlib/imlib_1.9.15.bb b/packages/imlib/imlib_1.9.15.bb new file mode 100644 index 0000000000..da96736958 --- /dev/null +++ b/packages/imlib/imlib_1.9.15.bb @@ -0,0 +1,20 @@ +DESCRIPTION = "Image loading library" +LICENSE = "GPLv2" +DEPENDS = "gtk+-1.2 jpeg tiff libpng libungif" + +inherit gnome binconfig + +SRC_URI += "file://configure.patch;patch=1" + +EXTRA_OECONF = " --enable-modules \ + --disable-gtktest \ + ac_cv_dynworks=true \ + " + +do_stage() { + install -m 644 Imlib/*.h ${STAGING_INCDIR} + install -m 644 gdk_imlib/*.h ${STAGING_INCDIR} + oe_libinstall -a -so -C Imlib libImlib ${STAGING_LIBDIR} + oe_libinstall -a -so -C gdk_imlib libgdk_imlib ${STAGING_LIBDIR} +} + -- cgit v1.2.3 From 887642656edc1a144139e805ea22376000ad016e Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 2 Sep 2006 11:24:19 +0000 Subject: qiv: add 1.9 --- packages/qiv/.mtn2git_empty | 0 packages/qiv/files/.mtn2git_empty | 0 packages/qiv/files/makefile.patch | 22 ++++++++++++++++++++++ packages/qiv/qiv_1.9.bb | 16 ++++++++++++++++ 4 files changed, 38 insertions(+) create mode 100644 packages/qiv/.mtn2git_empty create mode 100644 packages/qiv/files/.mtn2git_empty create mode 100644 packages/qiv/files/makefile.patch create mode 100644 packages/qiv/qiv_1.9.bb diff --git a/packages/qiv/.mtn2git_empty b/packages/qiv/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/qiv/files/.mtn2git_empty b/packages/qiv/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/qiv/files/makefile.patch b/packages/qiv/files/makefile.patch new file mode 100644 index 0000000000..42707be9b9 --- /dev/null +++ b/packages/qiv/files/makefile.patch @@ -0,0 +1,22 @@ +--- /tmp/Makefile 2006-09-02 13:04:25.000000000 +0200 ++++ qiv-1.9/Makefile 2006-09-02 13:05:05.255780000 +0200 +@@ -4,7 +4,7 @@ + ###################################################################### + + # Directory where qiv will be installed under. +-PREFIX = /usr/local ++PREFIX = /usr/ + + # Font to use for statusbar in fullscreen mode + STATUSBAR_FONT = "fixed" +@@ -53,10 +53,6 @@ + # Do not edit below here! + ###################################################################### + +-CC = gcc +-CFLAGS = -O2 -Wall -fomit-frame-pointer -finline-functions \ +- -fcaller-saves -ffast-math -fno-strength-reduce \ +- -fthread-jumps #-march=pentium #-DSTAT_MACROS_BROKEN + + INCLUDES = `imlib-config --cflags-gdk` + LIBS = `imlib-config --libs-gdk` diff --git a/packages/qiv/qiv_1.9.bb b/packages/qiv/qiv_1.9.bb new file mode 100644 index 0000000000..f6e96adddb --- /dev/null +++ b/packages/qiv/qiv_1.9.bb @@ -0,0 +1,16 @@ +DESCRIPTION = "Qiv is a very small and pretty fast gdk/Imlib image viewer." +LICENSE = "GPLv2" + +DEPENDS = "gtk+-1.2 imlib" + +SRC_URI = "http://www.klografx.net/qiv/download/qiv-1.9-src.tgz \ + file://makefile.patch;patch=1 \ + " +inherit pkgconfig binconfig + +CFLAGS += " -lSM -lICE -lXdmcp" + +do_install() { + install -s -m 0755 qiv ${D}${bindir}/qiv + install -m 0644 qiv.1 ${D}${mandir}/man1/qiv.1 +} -- cgit v1.2.3 From 661fd8d6ae89b7a4f963f57ccd2d9a404653c467 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sat, 2 Sep 2006 11:25:01 +0000 Subject: xserver-kdrive: git build fix, better w100 description --- packages/xorg-xserver/xserver-kdrive/w100.patch | 73 +++++++++++----------- .../xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb | 2 +- packages/xorg-xserver/xserver-kdrive_git.bb | 2 +- 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/packages/xorg-xserver/xserver-kdrive/w100.patch b/packages/xorg-xserver/xserver-kdrive/w100.patch index 2ff1639b9a..9a20fa1f1e 100644 --- a/packages/xorg-xserver/xserver-kdrive/w100.patch +++ b/packages/xorg-xserver/xserver-kdrive/w100.patch @@ -1,7 +1,7 @@ -Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati.c +Index: git/hw/kdrive/w100/ati.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati.c 2006-09-02 11:47:21.000000000 +0200 ++++ git/hw/kdrive/w100/ati.c 2006-09-02 12:12:14.000000000 +0200 @@ -0,0 +1,434 @@ +/* + * Copyright © 2006 Alberto Mardegan @@ -437,10 +437,10 @@ Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati.c + ATIGetColors, /* getColors */ + ATIPutColors, /* putColors */ +}; -Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_cursor.c +Index: git/hw/kdrive/w100/ati_cursor.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_cursor.c 2006-09-02 11:47:21.000000000 +0200 ++++ git/hw/kdrive/w100/ati_cursor.c 2006-09-02 12:12:14.000000000 +0200 @@ -0,0 +1,93 @@ +/* + * Copyright © 2006 Alberto Mardegan @@ -535,10 +535,10 @@ Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_cursor.c +ATICursorFini(ScreenPtr pScreen) +{ +} -Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_dma.c +Index: git/hw/kdrive/w100/ati_dma.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_dma.c 2006-09-02 11:47:21.000000000 +0200 ++++ git/hw/kdrive/w100/ati_dma.c 2006-09-02 12:12:14.000000000 +0200 @@ -0,0 +1,333 @@ +/* + * Copyright © 2006 Alberto Mardegan @@ -873,10 +873,10 @@ Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_dma.c + atis->ring_write &= atis->ring_mask; + MMIO_OUT32(mmio, mmCP_RB_WPTR, atis->ring_write); +} -Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_dma.h +Index: git/hw/kdrive/w100/ati_dma.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_dma.h 2006-09-02 11:47:21.000000000 +0200 ++++ git/hw/kdrive/w100/ati_dma.h 2006-09-02 12:12:14.000000000 +0200 @@ -0,0 +1,176 @@ +/* + * Copyright © 2004 Eric Anholt @@ -1054,10 +1054,10 @@ Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_dma.h +inline void +ATIWaitAvailMMIO(ATIScreenInfo *atis, int n); +#endif /* _ATI_DMA_H_ */ -Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_draw.c +Index: git/hw/kdrive/w100/ati_draw.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_draw.c 2006-09-02 11:47:21.000000000 +0200 ++++ git/hw/kdrive/w100/ati_draw.c 2006-09-02 12:12:14.000000000 +0200 @@ -0,0 +1,477 @@ +/* + * Copyright © 2006 Alberto Mardegan @@ -1536,10 +1536,10 @@ Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_draw.c +{ + kaaDrawFini(pScreen); +} -Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_draw.h +Index: git/hw/kdrive/w100/ati_draw.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_draw.h 2006-09-02 11:47:21.000000000 +0200 ++++ git/hw/kdrive/w100/ati_draw.h 2006-09-02 12:12:14.000000000 +0200 @@ -0,0 +1,107 @@ +/* + * Copyright © 2004 Eric Anholt @@ -1648,10 +1648,10 @@ Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_draw.h +#endif /* USE_DMA */ + +#endif /* _ATI_DRAW_H_ */ -Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati.h +Index: git/hw/kdrive/w100/ati.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati.h 2006-09-02 11:47:21.000000000 +0200 ++++ git/hw/kdrive/w100/ati.h 2006-09-02 12:12:14.000000000 +0200 @@ -0,0 +1,256 @@ +/* + * $Id: ati.h,v 1.18 2005-06-10 02:14:44 anholt Exp $ @@ -1909,10 +1909,10 @@ Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati.h +extern KdCardFuncs ATIFuncs; + +#endif /* _ATI_H_ */ -Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_microcode.c +Index: git/hw/kdrive/w100/ati_microcode.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_microcode.c 2006-09-02 11:47:21.000000000 +0200 ++++ git/hw/kdrive/w100/ati_microcode.c 2006-09-02 12:12:14.000000000 +0200 @@ -0,0 +1,412 @@ +/* + * Copyright © 2006 Alberto Mardegan @@ -2326,10 +2326,10 @@ Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_microcode.c + , + {0x00000000, 0x00000000} +}; -Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_stub.c +Index: git/hw/kdrive/w100/ati_stub.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_stub.c 2006-09-02 11:47:21.000000000 +0200 ++++ git/hw/kdrive/w100/ati_stub.c 2006-09-02 12:12:14.000000000 +0200 @@ -0,0 +1,103 @@ +/* + * Copyright © 2006 Alberto Mardegan @@ -2434,11 +2434,11 @@ Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/ati_stub.c + + return ret; +} -Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/Makefile.am +Index: git/hw/kdrive/w100/Makefile.am =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/Makefile.am 2006-09-02 11:47:21.000000000 +0200 -@@ -0,0 +1,53 @@ ++++ git/hw/kdrive/w100/Makefile.am 2006-09-02 12:42:38.000000000 +0200 +@@ -0,0 +1,56 @@ +if KDRIVEFBDEV +FBDEV_INCLUDES =-I$(top_srcdir)/hw/kdrive/fbdev +FBDEV_LIBS = $(top_builddir)/hw/kdrive/fbdev/libfbdev.a @@ -2491,11 +2491,14 @@ Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/Makefile.am + $(TSLIB_FLAG) + + -+Xw100_DEPENDENCIES = $(W100_LIBS) @KDRIVE_LIBS@ -Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/w100_const.h ++Xw100_DEPENDENCIES = \ ++ libw100.a \ ++ $(FBDEV_LIBS) \ ++ $(VESA_LIBS) +Index: git/hw/kdrive/w100/w100_const.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/w100_const.h 2006-09-02 11:47:21.000000000 +0200 ++++ git/hw/kdrive/w100/w100_const.h 2006-09-02 12:12:14.000000000 +0200 @@ -0,0 +1,25 @@ +#define CSQ_CNTL_MODE_FREERUN 0x8 + @@ -2522,10 +2525,10 @@ Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/w100_const.h +#define W100_CCE_PACKET3_PAINT_MULTI 0xc0001a00 +#define W100_CCE_PACKET3_BITBLT_MULTI 0xc0001b00 + -Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/w100_regs.h +Index: git/hw/kdrive/w100/w100_regs.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/w100_regs.h 2006-09-02 11:47:21.000000000 +0200 ++++ git/hw/kdrive/w100/w100_regs.h 2006-09-02 12:12:14.000000000 +0200 @@ -0,0 +1,3802 @@ +#ifndef _W100_REGS_H_ +#define _W100_REGS_H_ @@ -6329,10 +6332,10 @@ Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/w100/w100_regs.h + + +#endif //_W100_REGS_H_ -Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/Makefile.am +Index: git/hw/kdrive/Makefile.am =================================================================== ---- xorg-server-X11R7.1-1.1.0.orig/hw/kdrive/Makefile.am 2006-09-02 11:47:21.000000000 +0200 -+++ xorg-server-X11R7.1-1.1.0/hw/kdrive/Makefile.am 2006-09-02 11:47:21.000000000 +0200 +--- git.orig/hw/kdrive/Makefile.am 2006-09-02 12:12:13.000000000 +0200 ++++ git/hw/kdrive/Makefile.am 2006-09-02 12:12:14.000000000 +0200 @@ -7,6 +7,10 @@ FBDEV_SUBDIRS = fbdev epson endif @@ -6352,11 +6355,11 @@ Index: xorg-server-X11R7.1-1.1.0/hw/kdrive/Makefile.am $(VESA_SUBDIRS) \ $(XEPHYR_SUBDIRS) \ fake -Index: xorg-server-X11R7.1-1.1.0/configure.ac +Index: git/configure.ac =================================================================== ---- xorg-server-X11R7.1-1.1.0.orig/configure.ac 2006-09-02 11:47:21.000000000 +0200 -+++ xorg-server-X11R7.1-1.1.0/configure.ac 2006-09-02 11:51:56.000000000 +0200 -@@ -434,6 +434,7 @@ +--- git.orig/configure.ac 2006-09-02 12:12:14.000000000 +0200 ++++ git/configure.ac 2006-09-02 12:12:14.000000000 +0200 +@@ -442,6 +442,7 @@ AC_ARG_ENABLE(kdrive, AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no]) AC_ARG_ENABLE(xephyr, AS_HELP_STRING([--enable-xephyr], [Build the kdrive Xephyr server (default: auto)]), [XEPHYR=$enableval], [XEPHYR=auto]) AC_ARG_ENABLE(xsdl, AS_HELP_STRING([--enable-xsdl], [Build the kdrive Xsdl server (default: auto)]), [XSDL=$enableval], [XSDL=auto]) @@ -6364,7 +6367,7 @@ Index: xorg-server-X11R7.1-1.1.0/configure.ac dnl xprint AC_ARG_ENABLE(freetype, AS_HELP_STRING([ --enable-freetype], [Build Xprint FreeType backend (default: yes)]), [XP_USE_FREETYPE=$enableval],[XP_USE_FREETYPE=no]) AC_ARG_WITH(freetype-config, AS_HELP_STRING([ --with-freetype-config=PROG], [Use FreeType configuration program PROG (default: auto)]), freetype_config=$withval, freetype_config=auto) -@@ -1497,6 +1498,10 @@ +@@ -1519,6 +1520,10 @@ AC_SUBST([XSDL_LIBS]) AC_SUBST([XSDL_INCS]) @@ -6375,7 +6378,7 @@ Index: xorg-server-X11R7.1-1.1.0/configure.ac dnl these only go in xkb-config.h (which is shared by the Xorg and Xnest servers) AC_DEFINE(__XKBDEFRULES__, "xorg", [Default XKB rules]) -@@ -1739,6 +1744,7 @@ +@@ -1753,6 +1758,7 @@ hw/kdrive/epson/Makefile hw/kdrive/fake/Makefile hw/kdrive/fbdev/Makefile diff --git a/packages/xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb b/packages/xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb index 7ba53b7a73..47225ff5b0 100644 --- a/packages/xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb +++ b/packages/xorg-xserver/xserver-kdrive_X11R7.1-1.1.0.bb @@ -13,7 +13,7 @@ DESCRIPTION_xserver-kdrive-fake = "Fake X server" DESCRIPTION_xserver-kdrive-xephyr = "X server in an X window" DESCRIPTION_xserver-kdrive-epson = "X server from freedesktop.org, supporting Epson S1D13806 devices" DESCRIPTION_xserver-kdrive-sdl = "X server from freedesktop.org, SDL version" -DESCRIPTION_xserver-kdrive-w100 = "X server from freedesktop.org, w100 version" +DESCRIPTION_xserver-kdrive-w100 = "X server from freedesktop.org, supporting the ATI imageon w100 chipset" FILES_${PN} += "${libdir}/xserver/SecurityPolicy" diff --git a/packages/xorg-xserver/xserver-kdrive_git.bb b/packages/xorg-xserver/xserver-kdrive_git.bb index 5fb8d10822..96364c09d8 100644 --- a/packages/xorg-xserver/xserver-kdrive_git.bb +++ b/packages/xorg-xserver/xserver-kdrive_git.bb @@ -16,7 +16,7 @@ DESCRIPTION_xserver-kdrive-fake = "Fake X server" DESCRIPTION_xserver-kdrive-xephyr = "X server in an X window" DESCRIPTION_xserver-kdrive-epson = "X server from freedesktop.org, supporting Epson S1D13806 devices" DESCRIPTION_xserver-kdrive-sdl = "X server from freedesktop.org, SDL version" -DESCRIPTION_xserver-kdrive-w100 = "X server from freedesktop.org, w100 version" +DESCRIPTION_xserver-kdrive-w100 = "X server from freedesktop.org, supporting the ATI imageon w100 chipset" FILES_${PN} += "${libdir}/xserver/SecurityPolicy" -- cgit v1.2.3 From 703f0544e914ff348fe794b7df21fe9ce512d796 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 2 Sep 2006 11:30:26 +0000 Subject: wxbase cvs: fix SRC_URI --- packages/wxbase/wxbase_2.7+cvs.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wxbase/wxbase_2.7+cvs.bb b/packages/wxbase/wxbase_2.7+cvs.bb index a813788eee..05aeb6c08e 100644 --- a/packages/wxbase/wxbase_2.7+cvs.bb +++ b/packages/wxbase/wxbase_2.7+cvs.bb @@ -7,7 +7,7 @@ PRIORITY = "optional" DEPENDS = "jpeg libpng zlib" -SRC_URI = "http://biolpc22.york.ac.uk/pub/CVS_HEAD/wx-cvs-Gtk.tar.bz2" +SRC_URI = "http://biolpc22.york.ac.uk/pub/CVS_HEAD/v1/wx-cvs-Gtk.tar.bz2" #SRC_URI = "${SOURCEFORGE_MIRROR}/wxwindows/wxBase-${PV}.tar.bz2" S = "${WORKDIR}/wxGTK" -- cgit v1.2.3 From 8f2755bcfe2318ab67491d2611c500ecc3609a6b Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 2 Sep 2006 11:55:53 +0000 Subject: openntpd: don't pickup unwanted ssl libs, closes #1378 --- packages/openntpd/openntpd_3.7p1.bb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/openntpd/openntpd_3.7p1.bb b/packages/openntpd/openntpd_3.7p1.bb index 43c419ae24..6649361fd4 100644 --- a/packages/openntpd/openntpd_3.7p1.bb +++ b/packages/openntpd/openntpd_3.7p1.bb @@ -6,7 +6,7 @@ LICENSE = "BSD" SECTION = "console/network" MAINTAINER = "Oyvind Repvik " DEPENDS = "timezones" -PR="r11" +PR="r12" SRC_URI = "http://www.zip.com.au/~dtucker/openntpd/release/openntpd-${PV}.tar.gz \ file://autofoo.patch;patch=1 \ @@ -23,7 +23,10 @@ inherit autotools update-rc.d EXTRA_OECONF += "CFLAGS=-DUSE_ADJTIMEX --disable-strip --prefix=/usr \ --sysconfdir=/etc --with-privsep-path=/${localstatedir}/shared/empty \ - --with-privsep-user=ntpd" + --with-privsep-user=ntpd \ + --with-builtin-arc4random \ + --without-ssl-dir \ + " do_install_prepend() { install -d ${D}${sysconfdir}/init.d -- cgit v1.2.3 From 115fb071f3b122307a4599902f6ab195b69ac6d2 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 2 Sep 2006 12:01:47 +0000 Subject: nfs-utils: fix #1378 and fix RDEPENDS on a kernel-module * NEVER (R)DEPEND on a kernel-module, since those can be built-in, use RRECOMMENDS instead --- packages/nfs-utils/files/nfs-utils-1.0.6-uclibc.patch | 18 ++++++++++++++++++ packages/nfs-utils/nfs-utils_1.0.6.bb | 8 +++++--- 2 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 packages/nfs-utils/files/nfs-utils-1.0.6-uclibc.patch diff --git a/packages/nfs-utils/files/nfs-utils-1.0.6-uclibc.patch b/packages/nfs-utils/files/nfs-utils-1.0.6-uclibc.patch new file mode 100644 index 0000000000..ebd3276be2 --- /dev/null +++ b/packages/nfs-utils/files/nfs-utils-1.0.6-uclibc.patch @@ -0,0 +1,18 @@ +--- ./support/nfs/svc_socket.c.orig 2004-12-12 06:43:52.000000000 +0000 ++++ ./support/nfs/svc_socket.c 2004-12-12 06:50:04.000000000 +0000 +@@ -66,6 +66,7 @@ + __bzero ((char *) &addr, sizeof (addr)); + addr.sin_family = AF_INET; + ++#ifndef __UCLIBC__ /* neither getrpcbynumber() nor getrpcbynumber_r() is SuSv3 */ + ret = getrpcbynumber_r (number, &rpcbuf, rpcdata, sizeof rpcdata, + &rpcp); + if (ret == 0 && rpcp != NULL) +@@ -99,6 +100,7 @@ + } + } + else ++#endif + { + if (bindresvport (sock, &addr)) + { diff --git a/packages/nfs-utils/nfs-utils_1.0.6.bb b/packages/nfs-utils/nfs-utils_1.0.6.bb index 4f5e64b352..076ef4cff1 100644 --- a/packages/nfs-utils/nfs-utils_1.0.6.bb +++ b/packages/nfs-utils/nfs-utils_1.0.6.bb @@ -3,12 +3,13 @@ PRIORITY = "optional" SECTION = "console/network" MAINTAINER = "dyoung " LICENSE = "GPL" -PR = "r6" +PR = "r7" SRC_URI = "${SOURCEFORGE_MIRROR}/nfs/nfs-utils-${PV}.tar.gz \ file://acinclude-lossage.patch;patch=1 \ file://rpcgen-lossage.patch;patch=1 \ file://stat-include.patch;patch=1 \ + file://nfs-utils-1.0.6-uclibc.patch;patch=1 \ file://nfsserver \ file://forgotten-defines" @@ -16,9 +17,10 @@ S = ${WORKDIR}/nfs-utils-${PV}/ PARALLEL_MAKE = "" -# Only kernel-module-nfsd is required here - the nfsd module will +# Only kernel-module-nfsd is required here (but can be built-in) - the nfsd module will # pull in the remainder of the dependencies. -RDEPENDS = "portmap kernel-module-nfsd" +RDEPENDS = "portmap" +RRECOMMENDS = "kernel-module-nfsd" INITSCRIPT_NAME = "nfsserver" # The server has no dependencies at the user run levels, so just put -- cgit v1.2.3 From 774c7e10391a462b905f9d0f776878d373d4fd1b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sat, 2 Sep 2006 12:06:31 +0000 Subject: xserver-common: move recipes back into their own dir, xserver-common is not part of xorg --- packages/xorg-xserver/xserver-common_1.10.bb | 19 ------------------- packages/xorg-xserver/xserver-common_1.3.bb | 12 ------------ packages/xorg-xserver/xserver-common_1.8.bb | 18 ------------------ packages/xorg-xserver/xserver-common_1.9.bb | 19 ------------------- packages/xserver-common/.mtn2git_empty | 0 packages/xserver-common/xserver-common_1.10.bb | 19 +++++++++++++++++++ packages/xserver-common/xserver-common_1.3.bb | 12 ++++++++++++ packages/xserver-common/xserver-common_1.8.bb | 18 ++++++++++++++++++ packages/xserver-common/xserver-common_1.9.bb | 19 +++++++++++++++++++ 9 files changed, 68 insertions(+), 68 deletions(-) delete mode 100644 packages/xorg-xserver/xserver-common_1.10.bb delete mode 100644 packages/xorg-xserver/xserver-common_1.3.bb delete mode 100644 packages/xorg-xserver/xserver-common_1.8.bb delete mode 100644 packages/xorg-xserver/xserver-common_1.9.bb create mode 100644 packages/xserver-common/.mtn2git_empty create mode 100644 packages/xserver-common/xserver-common_1.10.bb create mode 100644 packages/xserver-common/xserver-common_1.3.bb create mode 100644 packages/xserver-common/xserver-common_1.8.bb create mode 100644 packages/xserver-common/xserver-common_1.9.bb diff --git a/packages/xorg-xserver/xserver-common_1.10.bb b/packages/xorg-xserver/xserver-common_1.10.bb deleted file mode 100644 index de81537f99..0000000000 --- a/packages/xorg-xserver/xserver-common_1.10.bb +++ /dev/null @@ -1,19 +0,0 @@ -MAINTAINER = "Florian Boor " -DESCRIPTION = "Common X11 scripts and support files" -LICENSE = "GPL" -SECTION = "x11" -RDEPENDS_${PN} = "xmodmap xrandr xdpyinfo xtscal" -PR = "r1" - -PACKAGE_ARCH = "all" - -# we are using a gpe-style Makefile -inherit gpe - -SRC_URI_append = " file://setDPI.sh \ - file://calibrate_zaurusd.patch;patch=1 \ - file://poodle-xmodmap-2.6.patch;patch=1" - -do_install_append() { - install -m 0755 "${WORKDIR}/setDPI.sh" "${D}/etc/X11/Xinit.d/50setdpi" -} diff --git a/packages/xorg-xserver/xserver-common_1.3.bb b/packages/xorg-xserver/xserver-common_1.3.bb deleted file mode 100644 index ea3fab6654..0000000000 --- a/packages/xorg-xserver/xserver-common_1.3.bb +++ /dev/null @@ -1,12 +0,0 @@ -MAINTAINER = "Florian Boor " -DESCRIPTION = "Common X11 scripts and support files" -LICENSE = "GPL" -SECTION = "x11" -RDEPENDS_${PN} = "xmodmap xrandr xdpyinfo xtscal" -PR = "r1" - -PACKAGE_ARCH = "all" - -# we are using a gpe-style Makefile -inherit gpe - diff --git a/packages/xorg-xserver/xserver-common_1.8.bb b/packages/xorg-xserver/xserver-common_1.8.bb deleted file mode 100644 index b7b3f554f3..0000000000 --- a/packages/xorg-xserver/xserver-common_1.8.bb +++ /dev/null @@ -1,18 +0,0 @@ -MAINTAINER = "Florian Boor " -DESCRIPTION = "Common X11 scripts and support files" -LICENSE = "GPL" -SECTION = "x11" -RDEPENDS_${PN} = "xmodmap xrandr xdpyinfo xtscal" -PR = "r2" - -PACKAGE_ARCH = "all" - -# we are using a gpe-style Makefile -inherit gpe - -SRC_URI_append = " file://setDPI.sh \ - file://calibrate_zaurusd.patch;patch=1" - -do_install_append() { - install -m 0755 "${WORKDIR}/setDPI.sh" "${D}/etc/X11/Xinit.d/50setdpi" -} diff --git a/packages/xorg-xserver/xserver-common_1.9.bb b/packages/xorg-xserver/xserver-common_1.9.bb deleted file mode 100644 index de81537f99..0000000000 --- a/packages/xorg-xserver/xserver-common_1.9.bb +++ /dev/null @@ -1,19 +0,0 @@ -MAINTAINER = "Florian Boor " -DESCRIPTION = "Common X11 scripts and support files" -LICENSE = "GPL" -SECTION = "x11" -RDEPENDS_${PN} = "xmodmap xrandr xdpyinfo xtscal" -PR = "r1" - -PACKAGE_ARCH = "all" - -# we are using a gpe-style Makefile -inherit gpe - -SRC_URI_append = " file://setDPI.sh \ - file://calibrate_zaurusd.patch;patch=1 \ - file://poodle-xmodmap-2.6.patch;patch=1" - -do_install_append() { - install -m 0755 "${WORKDIR}/setDPI.sh" "${D}/etc/X11/Xinit.d/50setdpi" -} diff --git a/packages/xserver-common/.mtn2git_empty b/packages/xserver-common/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/xserver-common/xserver-common_1.10.bb b/packages/xserver-common/xserver-common_1.10.bb new file mode 100644 index 0000000000..de81537f99 --- /dev/null +++ b/packages/xserver-common/xserver-common_1.10.bb @@ -0,0 +1,19 @@ +MAINTAINER = "Florian Boor " +DESCRIPTION = "Common X11 scripts and support files" +LICENSE = "GPL" +SECTION = "x11" +RDEPENDS_${PN} = "xmodmap xrandr xdpyinfo xtscal" +PR = "r1" + +PACKAGE_ARCH = "all" + +# we are using a gpe-style Makefile +inherit gpe + +SRC_URI_append = " file://setDPI.sh \ + file://calibrate_zaurusd.patch;patch=1 \ + file://poodle-xmodmap-2.6.patch;patch=1" + +do_install_append() { + install -m 0755 "${WORKDIR}/setDPI.sh" "${D}/etc/X11/Xinit.d/50setdpi" +} diff --git a/packages/xserver-common/xserver-common_1.3.bb b/packages/xserver-common/xserver-common_1.3.bb new file mode 100644 index 0000000000..ea3fab6654 --- /dev/null +++ b/packages/xserver-common/xserver-common_1.3.bb @@ -0,0 +1,12 @@ +MAINTAINER = "Florian Boor " +DESCRIPTION = "Common X11 scripts and support files" +LICENSE = "GPL" +SECTION = "x11" +RDEPENDS_${PN} = "xmodmap xrandr xdpyinfo xtscal" +PR = "r1" + +PACKAGE_ARCH = "all" + +# we are using a gpe-style Makefile +inherit gpe + diff --git a/packages/xserver-common/xserver-common_1.8.bb b/packages/xserver-common/xserver-common_1.8.bb new file mode 100644 index 0000000000..b7b3f554f3 --- /dev/null +++ b/packages/xserver-common/xserver-common_1.8.bb @@ -0,0 +1,18 @@ +MAINTAINER = "Florian Boor " +DESCRIPTION = "Common X11 scripts and support files" +LICENSE = "GPL" +SECTION = "x11" +RDEPENDS_${PN} = "xmodmap xrandr xdpyinfo xtscal" +PR = "r2" + +PACKAGE_ARCH = "all" + +# we are using a gpe-style Makefile +inherit gpe + +SRC_URI_append = " file://setDPI.sh \ + file://calibrate_zaurusd.patch;patch=1" + +do_install_append() { + install -m 0755 "${WORKDIR}/setDPI.sh" "${D}/etc/X11/Xinit.d/50setdpi" +} diff --git a/packages/xserver-common/xserver-common_1.9.bb b/packages/xserver-common/xserver-common_1.9.bb new file mode 100644 index 0000000000..de81537f99 --- /dev/null +++ b/packages/xserver-common/xserver-common_1.9.bb @@ -0,0 +1,19 @@ +MAINTAINER = "Florian Boor " +DESCRIPTION = "Common X11 scripts and support files" +LICENSE = "GPL" +SECTION = "x11" +RDEPENDS_${PN} = "xmodmap xrandr xdpyinfo xtscal" +PR = "r1" + +PACKAGE_ARCH = "all" + +# we are using a gpe-style Makefile +inherit gpe + +SRC_URI_append = " file://setDPI.sh \ + file://calibrate_zaurusd.patch;patch=1 \ + file://poodle-xmodmap-2.6.patch;patch=1" + +do_install_append() { + install -m 0755 "${WORKDIR}/setDPI.sh" "${D}/etc/X11/Xinit.d/50setdpi" +} -- cgit v1.2.3 From f317b85a70280478bdd281cacafcaf2cda1fc81f Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sat, 2 Sep 2006 12:12:11 +0000 Subject: xserver-common: move patches back into their own dir, xserver-common is not part of xorg --- packages/xorg-xserver/files/.mtn2git_empty | 0 .../xorg-xserver/files/calibrate_zaurusd.patch | 12 --- .../xorg-xserver/files/poodle-xmodmap-2.6.patch | 42 ---------- packages/xorg-xserver/files/setDPI.sh | 92 ---------------------- packages/xserver-common/files/.mtn2git_empty | 0 .../xserver-common/files/calibrate_zaurusd.patch | 12 +++ .../xserver-common/files/poodle-xmodmap-2.6.patch | 42 ++++++++++ packages/xserver-common/files/setDPI.sh | 92 ++++++++++++++++++++++ 8 files changed, 146 insertions(+), 146 deletions(-) delete mode 100644 packages/xorg-xserver/files/.mtn2git_empty delete mode 100644 packages/xorg-xserver/files/calibrate_zaurusd.patch delete mode 100644 packages/xorg-xserver/files/poodle-xmodmap-2.6.patch delete mode 100644 packages/xorg-xserver/files/setDPI.sh create mode 100644 packages/xserver-common/files/.mtn2git_empty create mode 100644 packages/xserver-common/files/calibrate_zaurusd.patch create mode 100644 packages/xserver-common/files/poodle-xmodmap-2.6.patch create mode 100644 packages/xserver-common/files/setDPI.sh diff --git a/packages/xorg-xserver/files/.mtn2git_empty b/packages/xorg-xserver/files/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/xorg-xserver/files/calibrate_zaurusd.patch b/packages/xorg-xserver/files/calibrate_zaurusd.patch deleted file mode 100644 index 6a7e3b02b7..0000000000 --- a/packages/xorg-xserver/files/calibrate_zaurusd.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- xserver-common-1.8/X11/Xinit.d/30xTs_Calibrate.orig 2006-04-09 15:12:16.167950472 +0200 -+++ xserver-common-1.8/X11/Xinit.d/30xTs_Calibrate 2006-04-09 15:14:51.511334688 +0200 -@@ -2,4 +2,9 @@ - - if [ ! -f /etc/pointercal ]; then - /usr/bin/run-calibrate.sh -+ -+ if [ -x /etc/init.d/zaurusd ]; then -+ /etc/init.d/zaurusd stop -+ /etc/init.d/zaurusd start -+ fi - fi diff --git a/packages/xorg-xserver/files/poodle-xmodmap-2.6.patch b/packages/xorg-xserver/files/poodle-xmodmap-2.6.patch deleted file mode 100644 index 73cf3f6ffb..0000000000 --- a/packages/xorg-xserver/files/poodle-xmodmap-2.6.patch +++ /dev/null @@ -1,42 +0,0 @@ -diff -Nur xserver-common-1.8.orig/X11/Xinit.d/12keymap xserver-common-1.8/X11/Xinit.d/12keymap ---- xserver-common-1.8.orig/X11/Xinit.d/12keymap 2006-05-17 12:02:52.645201000 +0200 -+++ xserver-common-1.8/X11/Xinit.d/12keymap 2006-05-17 12:03:49.401573648 +0200 -@@ -9,6 +9,9 @@ - "SHARP Akita" | "SHARP Borzoi" | "SHARP Spitz") - xmodmap - < /etc/X11/slcXXXX.xmodmap - ;; -+ "SHARP Poodle") -+ xmodmap - < /etc/X11/poodle.xmodmap -+ ;; - "Sharp-Collie") - xmodmap - < /etc/X11/collie.xmodmap - ;; -diff -Nur xserver-common-1.8.orig/X11/poodle.xmodmap xserver-common-1.8/X11/poodle.xmodmap ---- xserver-common-1.8.orig/X11/poodle.xmodmap 1970-01-01 01:00:00.000000000 +0100 -+++ xserver-common-1.8/X11/poodle.xmodmap 2006-05-18 13:42:45.711264920 +0200 -@@ -0,0 +1,25 @@ -+keycode 37 = Control_L -+keycode 64 = Alt_L -+ -+ -+keycode 50 = Shift_L -+keycode 62 = Shift_R -+keycode 75 = Mode_switch -+ -+ -+ -+clear control -+clear shift -+clear lock -+clear mod4 -+clear mod1 -+ -+add control = Control_L -+add shift = Shift_L Shift_R -+add lock = Caps_Lock -+ -+! This is AltGr -+add mod4 = Mode_switch -+ -+add mod1 = Alt_L -+ diff --git a/packages/xorg-xserver/files/setDPI.sh b/packages/xorg-xserver/files/setDPI.sh deleted file mode 100644 index 04a2edd6c6..0000000000 --- a/packages/xorg-xserver/files/setDPI.sh +++ /dev/null @@ -1,92 +0,0 @@ -#! /bin/sh -# -# Copyright Matthias Hentges (c) 2006 -# License: GPL (see http://www.gnu.org/licenses/gpl.txt for a copy of the license) -# -# Filename: setDPI.sh -# Date: 09-Apr-06 - -# This script configures Xft.dpi dependent on your screens DPI. This insures that the same font-size -# setting of 7 can be used on all machines. - - -XDEFAULTS="/etc/X11/Xdefaults" - - - -set_dpi() { - - CURRENT_SETTING="`cat ${XDEFAULTS} | sed -n "/Xft.dpi\:/s/.*\:\(.*\)/\1/p" | sed -n "s/\ //p"`" - - if test "$CURRENT_SETTING" != "$1" - then - echo "Using Xft.dpi of $SET_SCREEN_DPI for your $SCREEN_DPI DPI screen" - - if grep -q "Xft.dpi" "$XDEFAULTS" - then - cat "${XDEFAULTS}" | sed "s/^Xft.dpi\:.*/Xft.dpi\: $SET_SCREEN_DPI/" > "${XDEFAULTS}_" - mv "${XDEFAULTS}_" "${XDEFAULTS}" - else - echo -e "Xft.dpi: $SET_SCREEN_DPI\n" >> "$XDEFAULTS" - fi - else - echo "Your $SCREEN_DPI DPI screen is already configured." - fi -} - -set_rxvt_font() { - - CURRENT_SETTING="`cat ${XDEFAULTS} | sed -n "/Rxvt\*font/s/\(.*\pixelsize=\)\(.*\)/\2/p"`" - - if test "$1" -gt 100 - then - - # Configure the rxvt font-size for your screen here: - test "$1" -gt 180 -a "$1" -lt "221" && RXVT_FONT_SIZE=16 - - if test -z "$RXVT_FONT_SIZE" - then - echo "WARNING: No rxvt font-size configured for a $SCREEN_DPI DPI screen!" - echo "Defaulting to size 9" - RXVT_FONT_SIZE=9 - fi - - if test "$CURRENT_SETTING" != "$RXVT_FONT_SIZE" - then - echo "Using a rxvt font-size of $RXVT_FONT_SIZE" - cat ${XDEFAULTS} | sed "/Rxvt\*font/s/\(.*\pixelsize\)\(=*.*\)/\1=$RXVT_FONT_SIZE/" > ${XDEFAULTS}_ - mv ${XDEFAULTS}_ ${XDEFAULTS} - else - echo "The rxvt font-size is already configured" - fi - fi -} - -if test -z "$DISPLAY" -then - echo "DISPLAY is not set, aborting..." - exit 0 -fi - -SCREEN_DPI="`/usr/bin/xdpyinfo | grep "dots per inch" | awk '{print $2}'| sed -n "s/\(.*\)x\(.*\)/\2/p"`" - -if test -z "$SCREEN_DPI" -then - echo "WARNING: Couldn't read your screens DPI, defaulting to 100" - SCREEN_DPI=100 -fi - -# Configure your screen here: -test "$SCREEN_DPI" -gt 180 -a "$SCREEN_DPI" -lt "221" && SET_SCREEN_DPI=160 -test "$SCREEN_DPI" -gt 90 -a "$SCREEN_DPI" -lt "121" && SET_SCREEN_DPI=100 - - -if test -z "$SET_SCREEN_DPI" -then - echo "WARNING: No default configuration found for your $SCREEN_DPI DPI screen!" - echo "Using 100 DPI" - SET_SCREEN_DPI=100 -fi - -set_dpi "$SET_SCREEN_DPI" -set_rxvt_font "$SCREEN_DPI" diff --git a/packages/xserver-common/files/.mtn2git_empty b/packages/xserver-common/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/xserver-common/files/calibrate_zaurusd.patch b/packages/xserver-common/files/calibrate_zaurusd.patch new file mode 100644 index 0000000000..6a7e3b02b7 --- /dev/null +++ b/packages/xserver-common/files/calibrate_zaurusd.patch @@ -0,0 +1,12 @@ +--- xserver-common-1.8/X11/Xinit.d/30xTs_Calibrate.orig 2006-04-09 15:12:16.167950472 +0200 ++++ xserver-common-1.8/X11/Xinit.d/30xTs_Calibrate 2006-04-09 15:14:51.511334688 +0200 +@@ -2,4 +2,9 @@ + + if [ ! -f /etc/pointercal ]; then + /usr/bin/run-calibrate.sh ++ ++ if [ -x /etc/init.d/zaurusd ]; then ++ /etc/init.d/zaurusd stop ++ /etc/init.d/zaurusd start ++ fi + fi diff --git a/packages/xserver-common/files/poodle-xmodmap-2.6.patch b/packages/xserver-common/files/poodle-xmodmap-2.6.patch new file mode 100644 index 0000000000..73cf3f6ffb --- /dev/null +++ b/packages/xserver-common/files/poodle-xmodmap-2.6.patch @@ -0,0 +1,42 @@ +diff -Nur xserver-common-1.8.orig/X11/Xinit.d/12keymap xserver-common-1.8/X11/Xinit.d/12keymap +--- xserver-common-1.8.orig/X11/Xinit.d/12keymap 2006-05-17 12:02:52.645201000 +0200 ++++ xserver-common-1.8/X11/Xinit.d/12keymap 2006-05-17 12:03:49.401573648 +0200 +@@ -9,6 +9,9 @@ + "SHARP Akita" | "SHARP Borzoi" | "SHARP Spitz") + xmodmap - < /etc/X11/slcXXXX.xmodmap + ;; ++ "SHARP Poodle") ++ xmodmap - < /etc/X11/poodle.xmodmap ++ ;; + "Sharp-Collie") + xmodmap - < /etc/X11/collie.xmodmap + ;; +diff -Nur xserver-common-1.8.orig/X11/poodle.xmodmap xserver-common-1.8/X11/poodle.xmodmap +--- xserver-common-1.8.orig/X11/poodle.xmodmap 1970-01-01 01:00:00.000000000 +0100 ++++ xserver-common-1.8/X11/poodle.xmodmap 2006-05-18 13:42:45.711264920 +0200 +@@ -0,0 +1,25 @@ ++keycode 37 = Control_L ++keycode 64 = Alt_L ++ ++ ++keycode 50 = Shift_L ++keycode 62 = Shift_R ++keycode 75 = Mode_switch ++ ++ ++ ++clear control ++clear shift ++clear lock ++clear mod4 ++clear mod1 ++ ++add control = Control_L ++add shift = Shift_L Shift_R ++add lock = Caps_Lock ++ ++! This is AltGr ++add mod4 = Mode_switch ++ ++add mod1 = Alt_L ++ diff --git a/packages/xserver-common/files/setDPI.sh b/packages/xserver-common/files/setDPI.sh new file mode 100644 index 0000000000..04a2edd6c6 --- /dev/null +++ b/packages/xserver-common/files/setDPI.sh @@ -0,0 +1,92 @@ +#! /bin/sh +# +# Copyright Matthias Hentges (c) 2006 +# License: GPL (see http://www.gnu.org/licenses/gpl.txt for a copy of the license) +# +# Filename: setDPI.sh +# Date: 09-Apr-06 + +# This script configures Xft.dpi dependent on your screens DPI. This insures that the same font-size +# setting of 7 can be used on all machines. + + +XDEFAULTS="/etc/X11/Xdefaults" + + + +set_dpi() { + + CURRENT_SETTING="`cat ${XDEFAULTS} | sed -n "/Xft.dpi\:/s/.*\:\(.*\)/\1/p" | sed -n "s/\ //p"`" + + if test "$CURRENT_SETTING" != "$1" + then + echo "Using Xft.dpi of $SET_SCREEN_DPI for your $SCREEN_DPI DPI screen" + + if grep -q "Xft.dpi" "$XDEFAULTS" + then + cat "${XDEFAULTS}" | sed "s/^Xft.dpi\:.*/Xft.dpi\: $SET_SCREEN_DPI/" > "${XDEFAULTS}_" + mv "${XDEFAULTS}_" "${XDEFAULTS}" + else + echo -e "Xft.dpi: $SET_SCREEN_DPI\n" >> "$XDEFAULTS" + fi + else + echo "Your $SCREEN_DPI DPI screen is already configured." + fi +} + +set_rxvt_font() { + + CURRENT_SETTING="`cat ${XDEFAULTS} | sed -n "/Rxvt\*font/s/\(.*\pixelsize=\)\(.*\)/\2/p"`" + + if test "$1" -gt 100 + then + + # Configure the rxvt font-size for your screen here: + test "$1" -gt 180 -a "$1" -lt "221" && RXVT_FONT_SIZE=16 + + if test -z "$RXVT_FONT_SIZE" + then + echo "WARNING: No rxvt font-size configured for a $SCREEN_DPI DPI screen!" + echo "Defaulting to size 9" + RXVT_FONT_SIZE=9 + fi + + if test "$CURRENT_SETTING" != "$RXVT_FONT_SIZE" + then + echo "Using a rxvt font-size of $RXVT_FONT_SIZE" + cat ${XDEFAULTS} | sed "/Rxvt\*font/s/\(.*\pixelsize\)\(=*.*\)/\1=$RXVT_FONT_SIZE/" > ${XDEFAULTS}_ + mv ${XDEFAULTS}_ ${XDEFAULTS} + else + echo "The rxvt font-size is already configured" + fi + fi +} + +if test -z "$DISPLAY" +then + echo "DISPLAY is not set, aborting..." + exit 0 +fi + +SCREEN_DPI="`/usr/bin/xdpyinfo | grep "dots per inch" | awk '{print $2}'| sed -n "s/\(.*\)x\(.*\)/\2/p"`" + +if test -z "$SCREEN_DPI" +then + echo "WARNING: Couldn't read your screens DPI, defaulting to 100" + SCREEN_DPI=100 +fi + +# Configure your screen here: +test "$SCREEN_DPI" -gt 180 -a "$SCREEN_DPI" -lt "221" && SET_SCREEN_DPI=160 +test "$SCREEN_DPI" -gt 90 -a "$SCREEN_DPI" -lt "121" && SET_SCREEN_DPI=100 + + +if test -z "$SET_SCREEN_DPI" +then + echo "WARNING: No default configuration found for your $SCREEN_DPI DPI screen!" + echo "Using 100 DPI" + SET_SCREEN_DPI=100 +fi + +set_dpi "$SET_SCREEN_DPI" +set_rxvt_font "$SCREEN_DPI" -- cgit v1.2.3 From cd40986a93e3d0c01a4c506ef2540878741ae0ca Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sat, 2 Sep 2006 12:14:36 +0000 Subject: xserver-common: use Xw100 if available --- packages/xserver-common/files/w100.patch | 12 ++++++++++++ packages/xserver-common/xserver-common_1.10.bb | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 packages/xserver-common/files/w100.patch diff --git a/packages/xserver-common/files/w100.patch b/packages/xserver-common/files/w100.patch new file mode 100644 index 0000000000..ca908850e2 --- /dev/null +++ b/packages/xserver-common/files/w100.patch @@ -0,0 +1,12 @@ +--- xserver-common-1.10/X11/Xserver.orig 2006-09-02 13:54:30.000000000 +0200 ++++ xserver-common-1.10/X11/Xserver 2006-09-02 14:00:22.000000000 +0200 +@@ -14,6 +14,9 @@ + if [ -f /usr/bin/Xomap ]; then + XSERVER=Xomap + fi ++if [ -f /usr/bin/Xw100 ]; then ++ XSERVER=Xw100 ++fi + + . /etc/profile + diff --git a/packages/xserver-common/xserver-common_1.10.bb b/packages/xserver-common/xserver-common_1.10.bb index de81537f99..64c223f109 100644 --- a/packages/xserver-common/xserver-common_1.10.bb +++ b/packages/xserver-common/xserver-common_1.10.bb @@ -3,7 +3,7 @@ DESCRIPTION = "Common X11 scripts and support files" LICENSE = "GPL" SECTION = "x11" RDEPENDS_${PN} = "xmodmap xrandr xdpyinfo xtscal" -PR = "r1" +PR = "r2" PACKAGE_ARCH = "all" @@ -12,6 +12,7 @@ inherit gpe SRC_URI_append = " file://setDPI.sh \ file://calibrate_zaurusd.patch;patch=1 \ + file://w100.patch;patch=1 \ file://poodle-xmodmap-2.6.patch;patch=1" do_install_append() { -- cgit v1.2.3 From d3e9d5b3b92c0f04dc1c73ea94758ed974e3d8b9 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Sat, 2 Sep 2006 14:09:04 +0000 Subject: zd1211: Remove deprecated versions, update to rev83 --- packages/zd1211/zd1211-r59/.mtn2git_empty | 0 packages/zd1211/zd1211-r59/makefile-unslung.patch | 48 ---------------------- packages/zd1211/zd1211-r59/makefile.patch | 47 --------------------- packages/zd1211/zd1211-r67/.mtn2git_empty | 0 packages/zd1211/zd1211-r67/makefile-unslung.patch | 48 ---------------------- packages/zd1211/zd1211-r67/makefile.patch | 47 --------------------- packages/zd1211/zd1211-r74/.mtn2git_empty | 0 packages/zd1211/zd1211-r74/makefile-unslung.patch | 48 ---------------------- packages/zd1211/zd1211-r74/makefile.patch | 47 --------------------- .../zd1211/zd1211-r74/unslung-iwpriv-hack.patch | 19 --------- .../zd1211/zd1211-r74/unslung-writel-logging.patch | 14 ------- packages/zd1211/zd1211-r74/zd1211-endian-fix.patch | 11 ----- packages/zd1211/zd1211-r83/.mtn2git_empty | 0 packages/zd1211/zd1211-r83/makefile-unslung.patch | 48 ++++++++++++++++++++++ packages/zd1211/zd1211-r83/makefile.patch | 47 +++++++++++++++++++++ .../zd1211/zd1211-r83/unslung-iwpriv-hack.patch | 19 +++++++++ .../zd1211/zd1211-r83/unslung-writel-logging.patch | 14 +++++++ packages/zd1211/zd1211_r83.bb | 36 ++++++++++++++++ 18 files changed, 164 insertions(+), 329 deletions(-) delete mode 100644 packages/zd1211/zd1211-r59/.mtn2git_empty delete mode 100644 packages/zd1211/zd1211-r59/makefile-unslung.patch delete mode 100644 packages/zd1211/zd1211-r59/makefile.patch delete mode 100644 packages/zd1211/zd1211-r67/.mtn2git_empty delete mode 100644 packages/zd1211/zd1211-r67/makefile-unslung.patch delete mode 100644 packages/zd1211/zd1211-r67/makefile.patch delete mode 100644 packages/zd1211/zd1211-r74/.mtn2git_empty delete mode 100644 packages/zd1211/zd1211-r74/makefile-unslung.patch delete mode 100644 packages/zd1211/zd1211-r74/makefile.patch delete mode 100644 packages/zd1211/zd1211-r74/unslung-iwpriv-hack.patch delete mode 100644 packages/zd1211/zd1211-r74/unslung-writel-logging.patch delete mode 100644 packages/zd1211/zd1211-r74/zd1211-endian-fix.patch create mode 100644 packages/zd1211/zd1211-r83/.mtn2git_empty create mode 100644 packages/zd1211/zd1211-r83/makefile-unslung.patch create mode 100644 packages/zd1211/zd1211-r83/makefile.patch create mode 100644 packages/zd1211/zd1211-r83/unslung-iwpriv-hack.patch create mode 100644 packages/zd1211/zd1211-r83/unslung-writel-logging.patch create mode 100644 packages/zd1211/zd1211_r83.bb diff --git a/packages/zd1211/zd1211-r59/.mtn2git_empty b/packages/zd1211/zd1211-r59/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/zd1211/zd1211-r59/makefile-unslung.patch b/packages/zd1211/zd1211-r59/makefile-unslung.patch deleted file mode 100644 index 3ad1e24424..0000000000 --- a/packages/zd1211/zd1211-r59/makefile-unslung.patch +++ /dev/null @@ -1,48 +0,0 @@ ---- zd1211-driver-r59/Makefile.orig 2006-02-25 16:04:26.000000000 +0100 -+++ zd1211-driver-r59/Makefile 2006-02-25 17:11:27.000000000 +0100 -@@ -4,24 +4,23 @@ - # - # - --CC=gcc --CPP=g++ --LD=ld --rM=rm -f -r -+CC ?= gcc -+CPP ?= g++ -+LD ?= ld - --MODPATH := /lib/modules/$(shell uname -r) -+MODPATH ?= /lib/modules/$(shell uname -r) - - # if the kernel is 2.6.x, turn on this --KERN_26=y -+#KERN_26=y - --KERNEL_SOURCE=$(MODPATH)/source -+KERNEL_SOURCE ?= $(MODPATH)/source - #KERNEL_SOURCE=/usr/src/linux - - # set to 1 for zd1211b - ZD1211REV_B=0 - --SRC_DIR=src --DEFINES=-D__KERNEL__ -DMODULE=1 -+SRC_DIR=src -+DEFINES ?=-D__KERNEL__ -DMODULE=1 - - - -@@ -227,9 +226,9 @@ - depmod -a - - #for apdbg -- gcc -o apdbg apdbg.c -- chmod +x apdbg -- cp ./apdbg /sbin/apdbg -+# gcc -o apdbg apdbg.c -+# chmod +x apdbg -+# cp ./apdbg /sbin/apdbg - - clean: - rm -rf .tmp_versions .*.cmd *.ko *.mod.c *.mod.o *.o $(SRC_DIR)/*.o $(SRC_DIR)/.*.o.cmd diff --git a/packages/zd1211/zd1211-r59/makefile.patch b/packages/zd1211/zd1211-r59/makefile.patch deleted file mode 100644 index 5c575faece..0000000000 --- a/packages/zd1211/zd1211-r59/makefile.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- zd1211-driver-r59/Makefile.orig 2006-02-25 16:04:26.000000000 +0100 -+++ zd1211-driver-r59/Makefile 2006-02-25 17:11:27.000000000 +0100 -@@ -4,24 +4,23 @@ - # - # - --CC=gcc --CPP=g++ --LD=ld --rM=rm -f -r -+CC ?= gcc -+CPP ?= g++ -+LD ?= ld - --MODPATH := /lib/modules/$(shell uname -r) -+MODPATH ?= /lib/modules/$(shell uname -r) - - # if the kernel is 2.6.x, turn on this - KERN_26=y - --KERNEL_SOURCE=$(MODPATH)/source -+KERNEL_SOURCE ?= $(MODPATH)/source - #KERNEL_SOURCE=/usr/src/linux - - # set to 1 for zd1211b - ZD1211REV_B=0 - --SRC_DIR=src --DEFINES=-D__KERNEL__ -DMODULE=1 -+SRC_DIR=src -+DEFINES ?=-D__KERNEL__ -DMODULE=1 - - - -@@ -227,9 +226,9 @@ - depmod -a - - #for apdbg -- gcc -o apdbg apdbg.c -- chmod +x apdbg -- cp ./apdbg /sbin/apdbg -+# gcc -o apdbg apdbg.c -+# chmod +x apdbg -+# cp ./apdbg /sbin/apdbg - - clean: - rm -rf .tmp_versions .*.cmd *.ko *.mod.c *.mod.o *.o $(SRC_DIR)/*.o $(SRC_DIR)/.*.o.cmd diff --git a/packages/zd1211/zd1211-r67/.mtn2git_empty b/packages/zd1211/zd1211-r67/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/zd1211/zd1211-r67/makefile-unslung.patch b/packages/zd1211/zd1211-r67/makefile-unslung.patch deleted file mode 100644 index 3ad1e24424..0000000000 --- a/packages/zd1211/zd1211-r67/makefile-unslung.patch +++ /dev/null @@ -1,48 +0,0 @@ ---- zd1211-driver-r59/Makefile.orig 2006-02-25 16:04:26.000000000 +0100 -+++ zd1211-driver-r59/Makefile 2006-02-25 17:11:27.000000000 +0100 -@@ -4,24 +4,23 @@ - # - # - --CC=gcc --CPP=g++ --LD=ld --rM=rm -f -r -+CC ?= gcc -+CPP ?= g++ -+LD ?= ld - --MODPATH := /lib/modules/$(shell uname -r) -+MODPATH ?= /lib/modules/$(shell uname -r) - - # if the kernel is 2.6.x, turn on this --KERN_26=y -+#KERN_26=y - --KERNEL_SOURCE=$(MODPATH)/source -+KERNEL_SOURCE ?= $(MODPATH)/source - #KERNEL_SOURCE=/usr/src/linux - - # set to 1 for zd1211b - ZD1211REV_B=0 - --SRC_DIR=src --DEFINES=-D__KERNEL__ -DMODULE=1 -+SRC_DIR=src -+DEFINES ?=-D__KERNEL__ -DMODULE=1 - - - -@@ -227,9 +226,9 @@ - depmod -a - - #for apdbg -- gcc -o apdbg apdbg.c -- chmod +x apdbg -- cp ./apdbg /sbin/apdbg -+# gcc -o apdbg apdbg.c -+# chmod +x apdbg -+# cp ./apdbg /sbin/apdbg - - clean: - rm -rf .tmp_versions .*.cmd *.ko *.mod.c *.mod.o *.o $(SRC_DIR)/*.o $(SRC_DIR)/.*.o.cmd diff --git a/packages/zd1211/zd1211-r67/makefile.patch b/packages/zd1211/zd1211-r67/makefile.patch deleted file mode 100644 index 5c575faece..0000000000 --- a/packages/zd1211/zd1211-r67/makefile.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- zd1211-driver-r59/Makefile.orig 2006-02-25 16:04:26.000000000 +0100 -+++ zd1211-driver-r59/Makefile 2006-02-25 17:11:27.000000000 +0100 -@@ -4,24 +4,23 @@ - # - # - --CC=gcc --CPP=g++ --LD=ld --rM=rm -f -r -+CC ?= gcc -+CPP ?= g++ -+LD ?= ld - --MODPATH := /lib/modules/$(shell uname -r) -+MODPATH ?= /lib/modules/$(shell uname -r) - - # if the kernel is 2.6.x, turn on this - KERN_26=y - --KERNEL_SOURCE=$(MODPATH)/source -+KERNEL_SOURCE ?= $(MODPATH)/source - #KERNEL_SOURCE=/usr/src/linux - - # set to 1 for zd1211b - ZD1211REV_B=0 - --SRC_DIR=src --DEFINES=-D__KERNEL__ -DMODULE=1 -+SRC_DIR=src -+DEFINES ?=-D__KERNEL__ -DMODULE=1 - - - -@@ -227,9 +226,9 @@ - depmod -a - - #for apdbg -- gcc -o apdbg apdbg.c -- chmod +x apdbg -- cp ./apdbg /sbin/apdbg -+# gcc -o apdbg apdbg.c -+# chmod +x apdbg -+# cp ./apdbg /sbin/apdbg - - clean: - rm -rf .tmp_versions .*.cmd *.ko *.mod.c *.mod.o *.o $(SRC_DIR)/*.o $(SRC_DIR)/.*.o.cmd diff --git a/packages/zd1211/zd1211-r74/.mtn2git_empty b/packages/zd1211/zd1211-r74/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/zd1211/zd1211-r74/makefile-unslung.patch b/packages/zd1211/zd1211-r74/makefile-unslung.patch deleted file mode 100644 index 3ad1e24424..0000000000 --- a/packages/zd1211/zd1211-r74/makefile-unslung.patch +++ /dev/null @@ -1,48 +0,0 @@ ---- zd1211-driver-r59/Makefile.orig 2006-02-25 16:04:26.000000000 +0100 -+++ zd1211-driver-r59/Makefile 2006-02-25 17:11:27.000000000 +0100 -@@ -4,24 +4,23 @@ - # - # - --CC=gcc --CPP=g++ --LD=ld --rM=rm -f -r -+CC ?= gcc -+CPP ?= g++ -+LD ?= ld - --MODPATH := /lib/modules/$(shell uname -r) -+MODPATH ?= /lib/modules/$(shell uname -r) - - # if the kernel is 2.6.x, turn on this --KERN_26=y -+#KERN_26=y - --KERNEL_SOURCE=$(MODPATH)/source -+KERNEL_SOURCE ?= $(MODPATH)/source - #KERNEL_SOURCE=/usr/src/linux - - # set to 1 for zd1211b - ZD1211REV_B=0 - --SRC_DIR=src --DEFINES=-D__KERNEL__ -DMODULE=1 -+SRC_DIR=src -+DEFINES ?=-D__KERNEL__ -DMODULE=1 - - - -@@ -227,9 +226,9 @@ - depmod -a - - #for apdbg -- gcc -o apdbg apdbg.c -- chmod +x apdbg -- cp ./apdbg /sbin/apdbg -+# gcc -o apdbg apdbg.c -+# chmod +x apdbg -+# cp ./apdbg /sbin/apdbg - - clean: - rm -rf .tmp_versions .*.cmd *.ko *.mod.c *.mod.o *.o $(SRC_DIR)/*.o $(SRC_DIR)/.*.o.cmd diff --git a/packages/zd1211/zd1211-r74/makefile.patch b/packages/zd1211/zd1211-r74/makefile.patch deleted file mode 100644 index 5c575faece..0000000000 --- a/packages/zd1211/zd1211-r74/makefile.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- zd1211-driver-r59/Makefile.orig 2006-02-25 16:04:26.000000000 +0100 -+++ zd1211-driver-r59/Makefile 2006-02-25 17:11:27.000000000 +0100 -@@ -4,24 +4,23 @@ - # - # - --CC=gcc --CPP=g++ --LD=ld --rM=rm -f -r -+CC ?= gcc -+CPP ?= g++ -+LD ?= ld - --MODPATH := /lib/modules/$(shell uname -r) -+MODPATH ?= /lib/modules/$(shell uname -r) - - # if the kernel is 2.6.x, turn on this - KERN_26=y - --KERNEL_SOURCE=$(MODPATH)/source -+KERNEL_SOURCE ?= $(MODPATH)/source - #KERNEL_SOURCE=/usr/src/linux - - # set to 1 for zd1211b - ZD1211REV_B=0 - --SRC_DIR=src --DEFINES=-D__KERNEL__ -DMODULE=1 -+SRC_DIR=src -+DEFINES ?=-D__KERNEL__ -DMODULE=1 - - - -@@ -227,9 +226,9 @@ - depmod -a - - #for apdbg -- gcc -o apdbg apdbg.c -- chmod +x apdbg -- cp ./apdbg /sbin/apdbg -+# gcc -o apdbg apdbg.c -+# chmod +x apdbg -+# cp ./apdbg /sbin/apdbg - - clean: - rm -rf .tmp_versions .*.cmd *.ko *.mod.c *.mod.o *.o $(SRC_DIR)/*.o $(SRC_DIR)/.*.o.cmd diff --git a/packages/zd1211/zd1211-r74/unslung-iwpriv-hack.patch b/packages/zd1211/zd1211-r74/unslung-iwpriv-hack.patch deleted file mode 100644 index 64f3806140..0000000000 --- a/packages/zd1211/zd1211-r74/unslung-iwpriv-hack.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- zd1211-driver-r74/src/zd1205.c~ 2006-04-16 09:42:15.000000000 -0500 -+++ zd1211-driver-r74/src/zd1205.c 2006-04-27 12:29:03.000000000 -0500 -@@ -349,8 +349,14 @@ - { SIOCIWFIRSTPRIV + 0xA, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "connect" }, - { SIOCIWFIRSTPRIV + 0xB, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_mac_mode" }, - { SIOCIWFIRSTPRIV + 0xC, 0, IW_PRIV_TYPE_CHAR | 12, "get_mac_mode" }, -- { SIOCIWFIRSTPRIV + 0xD, 0, 0, "save_conf" /* has been removed */ }, -- { SIOCIWFIRSTPRIV + 0xE, 0, 0, "load_conf" /* has been removed */ }, -+// HACK HACK HACK - The following two lines are commented out in order to make -+// iwpriv work on Unslung (2.4.22 kernel) - this kernel's Wireless Extensions -+// can only handle up to 16 iwpriv entries in this structure. Yes, the correct -+// fix is to patch the Wireless Extensions in the Unslung kernel. This hack -+// should be removed when that's actually done. ~mwester 27APR2006 -+// { SIOCIWFIRSTPRIV + 0xD, 0, 0, "save_conf" /* has been removed */ }, -+// { SIOCIWFIRSTPRIV + 0xE, 0, 0, "load_conf" /* has been removed */ }, -+// End of HACK - { SIOCIWFIRSTPRIV + 0xF, 0, IW_PRIV_TYPE_CHAR | 14, "get_Region" }, - { SIOCIWFIRSTPRIV + 0x9,IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_Region" }, - }; diff --git a/packages/zd1211/zd1211-r74/unslung-writel-logging.patch b/packages/zd1211/zd1211-r74/unslung-writel-logging.patch deleted file mode 100644 index 00d54d7d68..0000000000 --- a/packages/zd1211/zd1211-r74/unslung-writel-logging.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- zd1211-driver-r74/src/zd1211.c~ 2006-04-09 12:28:06.000000000 -0500 -+++ zd1211-driver-r74/src/zd1211.c 2006-04-27 12:38:55.000000000 -0500 -@@ -652,7 +652,10 @@ - count++; - - if (count > 5) { -- printk(KERN_ERR "1211_readl failed for 5 attempts...Very Serious"); -+// You are going to see this often enough on Unslung that we might as well put it in -+// the syslog and fix it so it has a nl on the end. Sigh. ~mwester, 27APR06 -+// -+ printk(KERN_ERR "1211_readl failed for 5 attempts...Very Serious\n"); - break; - } - } diff --git a/packages/zd1211/zd1211-r74/zd1211-endian-fix.patch b/packages/zd1211/zd1211-r74/zd1211-endian-fix.patch deleted file mode 100644 index c694174fee..0000000000 --- a/packages/zd1211/zd1211-r74/zd1211-endian-fix.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- zd1211-driver-r67/src/zd1211.c~ 2006-02-16 15:33:51.000000000 -0600 -+++ zd1211-driver-r67/src/zd1211.c 2006-04-30 22:47:13.000000000 -0500 -@@ -2228,7 +2228,7 @@ - - if (CurFrmLen & 0x03) - tmpLen += 4; -- rfd->ActualCount += macp->rxOffset; -+ rfd->ActualCount = cpu_to_le32(CurFrmLen + macp->rxOffset); - } - } else { - // last_pkt_len = 509, 510, 511 diff --git a/packages/zd1211/zd1211-r83/.mtn2git_empty b/packages/zd1211/zd1211-r83/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/zd1211/zd1211-r83/makefile-unslung.patch b/packages/zd1211/zd1211-r83/makefile-unslung.patch new file mode 100644 index 0000000000..4edcbb7a9d --- /dev/null +++ b/packages/zd1211/zd1211-r83/makefile-unslung.patch @@ -0,0 +1,48 @@ +--- zd1211-driver-r77/Makefile.orig 2006-02-25 16:04:26.000000000 +0100 ++++ zd1211-driver-r77/Makefile 2006-02-25 17:11:27.000000000 +0100 +@@ -4,24 +4,23 @@ + # + # + +-CC=gcc +-CPP=g++ +-LD=ld +-rM=rm -f -r ++CC ?= gcc ++CPP ?= g++ ++LD ?= ld + +-MODPATH := /lib/modules/$(shell uname -r) ++MODPATH ?= /lib/modules/$(shell uname -r) + + # if the kernel is 2.6.x, turn on this +-KERN_26=y ++#KERN_26=y + +-KERNEL_SOURCE=$(MODPATH)/source ++KERNEL_SOURCE ?= $(MODPATH)/source + #KERNEL_SOURCE=/usr/src/linux + + # set to 1 for zd1211b + ZD1211REV_B=0 + +-SRC_DIR=src +-DEFINES=-D__KERNEL__ -DMODULE=1 ++SRC_DIR=src ++DEFINES ?=-D__KERNEL__ -DMODULE=1 + + + +@@ -227,9 +226,9 @@ + depmod -a + + #for apdbg +- gcc -o apdbg apdbg.c +- chmod +x apdbg +- cp ./apdbg /sbin/apdbg ++# gcc -o apdbg apdbg.c ++# chmod +x apdbg ++# cp ./apdbg /sbin/apdbg + + clean: + rm -rf .tmp_versions .*.cmd *.ko *.mod.c *.mod.o *.o $(SRC_DIR)/*.o $(SRC_DIR)/.*.o.cmd diff --git a/packages/zd1211/zd1211-r83/makefile.patch b/packages/zd1211/zd1211-r83/makefile.patch new file mode 100644 index 0000000000..adc2bd416d --- /dev/null +++ b/packages/zd1211/zd1211-r83/makefile.patch @@ -0,0 +1,47 @@ +--- zd1211-driver-r83/Makefile.orig 2006-09-02 16:00:00.000000000 +0200 ++++ zd1211-driver-r83/Makefile 2006-09-02 16:01:57.000000000 +0200 +@@ -4,10 +4,10 @@ + # + # + +-CC=gcc +-CPP=g++ +-LD=ld +-rM=rm -f -r ++#CC=gcc ++#CPP=g++ ++#LD=ld ++#rM=rm -f -r + + VERSION := $(shell uname -r) + MODPATH := /lib/modules/$(VERSION) +@@ -15,14 +15,14 @@ + # if the kernel is 2.6.x, turn on this + KERN_26=y + +-KERNEL_SOURCE=$(MODPATH)/source ++KERNEL_SOURCE ?= $(MODPATH)/source + #KERNEL_SOURCE=/usr/src/linux + + # set to 1 for zd1211b + ZD1211REV_B=0 + + SRC_DIR=src +-DEFINES=-D__KERNEL__ -DMODULE=1 ++DEFINES ?= -D__KERNEL__ -DMODULE=1 + + + +@@ -228,9 +228,9 @@ + depmod -a $(VERSION) + + #for apdbg +- gcc -o apdbg apdbg.c +- chmod +x apdbg +- cp ./apdbg /sbin/apdbg ++# gcc -o apdbg apdbg.c ++# chmod +x apdbg ++# cp ./apdbg /sbin/apdbg + + clean: + rm -rf .tmp_versions .*.cmd *.ko *.mod.c *.mod.o *.o $(SRC_DIR)/*.o $(SRC_DIR)/.*.o.cmd diff --git a/packages/zd1211/zd1211-r83/unslung-iwpriv-hack.patch b/packages/zd1211/zd1211-r83/unslung-iwpriv-hack.patch new file mode 100644 index 0000000000..64f3806140 --- /dev/null +++ b/packages/zd1211/zd1211-r83/unslung-iwpriv-hack.patch @@ -0,0 +1,19 @@ +--- zd1211-driver-r74/src/zd1205.c~ 2006-04-16 09:42:15.000000000 -0500 ++++ zd1211-driver-r74/src/zd1205.c 2006-04-27 12:29:03.000000000 -0500 +@@ -349,8 +349,14 @@ + { SIOCIWFIRSTPRIV + 0xA, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "connect" }, + { SIOCIWFIRSTPRIV + 0xB, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_mac_mode" }, + { SIOCIWFIRSTPRIV + 0xC, 0, IW_PRIV_TYPE_CHAR | 12, "get_mac_mode" }, +- { SIOCIWFIRSTPRIV + 0xD, 0, 0, "save_conf" /* has been removed */ }, +- { SIOCIWFIRSTPRIV + 0xE, 0, 0, "load_conf" /* has been removed */ }, ++// HACK HACK HACK - The following two lines are commented out in order to make ++// iwpriv work on Unslung (2.4.22 kernel) - this kernel's Wireless Extensions ++// can only handle up to 16 iwpriv entries in this structure. Yes, the correct ++// fix is to patch the Wireless Extensions in the Unslung kernel. This hack ++// should be removed when that's actually done. ~mwester 27APR2006 ++// { SIOCIWFIRSTPRIV + 0xD, 0, 0, "save_conf" /* has been removed */ }, ++// { SIOCIWFIRSTPRIV + 0xE, 0, 0, "load_conf" /* has been removed */ }, ++// End of HACK + { SIOCIWFIRSTPRIV + 0xF, 0, IW_PRIV_TYPE_CHAR | 14, "get_Region" }, + { SIOCIWFIRSTPRIV + 0x9,IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_Region" }, + }; diff --git a/packages/zd1211/zd1211-r83/unslung-writel-logging.patch b/packages/zd1211/zd1211-r83/unslung-writel-logging.patch new file mode 100644 index 0000000000..00d54d7d68 --- /dev/null +++ b/packages/zd1211/zd1211-r83/unslung-writel-logging.patch @@ -0,0 +1,14 @@ +--- zd1211-driver-r74/src/zd1211.c~ 2006-04-09 12:28:06.000000000 -0500 ++++ zd1211-driver-r74/src/zd1211.c 2006-04-27 12:38:55.000000000 -0500 +@@ -652,7 +652,10 @@ + count++; + + if (count > 5) { +- printk(KERN_ERR "1211_readl failed for 5 attempts...Very Serious"); ++// You are going to see this often enough on Unslung that we might as well put it in ++// the syslog and fix it so it has a nl on the end. Sigh. ~mwester, 27APR06 ++// ++ printk(KERN_ERR "1211_readl failed for 5 attempts...Very Serious\n"); + break; + } + } diff --git a/packages/zd1211/zd1211_r83.bb b/packages/zd1211/zd1211_r83.bb new file mode 100644 index 0000000000..398d516372 --- /dev/null +++ b/packages/zd1211/zd1211_r83.bb @@ -0,0 +1,36 @@ +DESCRIPTION = "Driver for zd1211 family of wireless USB Dongles" +PRIORITY = "optional" +SECTION = "kernel/modules" +MAINTAINER = "Oyvind Repvik " +LICENSE = "GPL" +PR = "r1" +RDEPENDS = "wireless-tools" + +SRC_URI = "http://zd1211.ath.cx/download/zd1211-driver-${PV}.tgz \ + file://makefile.patch;patch=1 \ + " + +SRC_URI_unslung = "http://zd1211.ath.cx/download/zd1211-driver-${PV}.tgz \ + file://makefile-unslung.patch;patch=1 \ + file://unslung-iwpriv-hack.patch;patch=1 \ + file://unslung-writel-logging.patch;patch=1 \ + " + +S = "${WORKDIR}/zd1211-driver-${PV}" + +inherit module + +do_compile () { + unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS CC LD CPP + oe_runmake 'MODPATH={D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net' \ + 'KERNEL_SOURCE=${STAGING_KERNEL_DIR}' \ + 'KDIR=${STAGING_KERNEL_DIR}' \ + 'KERNEL_VERSION=${KERNEL_VERSION}' \ + 'CC=${KERNEL_CC}' \ + 'LD=${KERNEL_LD}' +} + +do_install() { + install -d ${D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net + install -m 0644 ${S}/zd1211*${KERNEL_OBJECT_SUFFIX} ${D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net +} -- cgit v1.2.3 From 59ddae46040775c9ad7514adc1d72a9cb6bb83ea Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Sat, 2 Sep 2006 17:31:10 +0000 Subject: feed-browser: add search functionality --- contrib/feed-browser/index.php | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/contrib/feed-browser/index.php b/contrib/feed-browser/index.php index df7282db7d..1c902ac66e 100644 --- a/contrib/feed-browser/index.php +++ b/contrib/feed-browser/index.php @@ -35,6 +35,13 @@ require_once 'includes/functions.inc'; check_database(); +$name = ''; + +if(isset($_GET['name'])) +{ + $name = $_GET['name']; +} + $action = ''; if(isset($_GET['action'])) @@ -48,10 +55,8 @@ switch($action) $ipkgoutput = pkgdetails ($_GET['pnm']); break; - case "package": - $edit = $_POST['edit']; - $searchword = $edit['searchword']; - $ipkgoutput = searchpkg ("%$searchword%"); + case "search": + $ipkgoutput = searchpkg ("%{$name}%"); break; case "section": @@ -78,7 +83,18 @@ switch($action) - +

Sections list

-- cgit v1.2.3 From 358f48301ec25e4f35daf798eb41cfd767f2cab8 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Sat, 2 Sep 2006 17:55:23 +0000 Subject: samba: upstream upgrade to 3.0.23c. Add MAINTAINER and LICENCE fields --- packages/samba/samba-3.0.23c/.mtn2git_empty | 0 packages/samba/samba-3.0.23c/Managing-Samba.txt | 40 +++++ packages/samba/samba-3.0.23c/cifs.patch | 10 ++ packages/samba/samba-3.0.23c/config-lfs.patch | 47 ++++++ packages/samba/samba-3.0.23c/configure.patch | 170 +++++++++++++++++++++ packages/samba/samba-3.0.23c/init | 58 +++++++ packages/samba/samba-3.0.23c/init-essential | 68 +++++++++ packages/samba/samba-3.0.23c/quota.patch | 11 ++ .../samba-3.0.23c/smb-essential-inactive.conf | 34 +++++ packages/samba/samba-3.0.23c/smb-essential.conf | 82 ++++++++++ packages/samba/samba_3.0.23c.bb | 55 +++++++ 11 files changed, 575 insertions(+) create mode 100644 packages/samba/samba-3.0.23c/.mtn2git_empty create mode 100644 packages/samba/samba-3.0.23c/Managing-Samba.txt create mode 100644 packages/samba/samba-3.0.23c/cifs.patch create mode 100644 packages/samba/samba-3.0.23c/config-lfs.patch create mode 100644 packages/samba/samba-3.0.23c/configure.patch create mode 100644 packages/samba/samba-3.0.23c/init create mode 100644 packages/samba/samba-3.0.23c/init-essential create mode 100644 packages/samba/samba-3.0.23c/quota.patch create mode 100644 packages/samba/samba-3.0.23c/smb-essential-inactive.conf create mode 100644 packages/samba/samba-3.0.23c/smb-essential.conf create mode 100644 packages/samba/samba_3.0.23c.bb diff --git a/packages/samba/samba-3.0.23c/.mtn2git_empty b/packages/samba/samba-3.0.23c/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/samba/samba-3.0.23c/Managing-Samba.txt b/packages/samba/samba-3.0.23c/Managing-Samba.txt new file mode 100644 index 0000000000..01f7592824 --- /dev/null +++ b/packages/samba/samba-3.0.23c/Managing-Samba.txt @@ -0,0 +1,40 @@ +This device is running a bare-bone Samba server which allows easy +transfer of files and directories between any networked desktop PC and +your networked PDA. + +Since it is generally a bad idea to allow everyone read and write access +to your PDA, you will have to configure at least one user to get access to +any shared folder. + +How to create a Samba user with password: + +- If you haven't already created a non-root user, do so now: + root@poodle:/usr/bin# adduser testuser + Changing password for testuser + Enter the new password (minimum of 5, maximum of 8 characters) + Please use a combination of upper and lower case letters and numbers. + Enter new password: + Bad password: too short. + + Warning: weak password (continuing). + Re-enter new password: + Password changed. + root@poodle:/usr/bin# + +- Note that the password you entered will _not_ be your samba password. + Samba uses its own password database. + +- Add a Samba password for your user: + root@poodle:/usr/bin# smbpasswd -a testuser + New SMB password: + Retype new SMB password: + Added user testuser. + root@poodle:/usr/bin# + +- After you have added your new samba user, you'll have to restart the samba + server by running "/etc/init.d/samba restart" or by rebooting the device + +- Use the newly created username / password combination to access your network + shares. Please note the the Samba username must also exist as a unix username! + + diff --git a/packages/samba/samba-3.0.23c/cifs.patch b/packages/samba/samba-3.0.23c/cifs.patch new file mode 100644 index 0000000000..ee6dab567f --- /dev/null +++ b/packages/samba/samba-3.0.23c/cifs.patch @@ -0,0 +1,10 @@ +--- source/client/mount.cifs.c.old 2004-11-28 02:33:52.000000000 +1030 ++++ source/client/mount.cifs.c 2004-11-28 02:33:59.000000000 +1030 +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + #define MOUNT_CIFS_VERSION_MAJOR "1" + #define MOUNT_CIFS_VERSION_MINOR "2" diff --git a/packages/samba/samba-3.0.23c/config-lfs.patch b/packages/samba/samba-3.0.23c/config-lfs.patch new file mode 100644 index 0000000000..b37ed690ce --- /dev/null +++ b/packages/samba/samba-3.0.23c/config-lfs.patch @@ -0,0 +1,47 @@ +Cache the check for Linux LFS support, so it can be prepopulated from +the site cache for configure variables for cross-compiling. Without this, +samba gets the idea that it can use dirent64 and friends without defining +the flags it needs to get it, such as _GNU_SOURCE and _LARGEFILE64_SOURCE. + +Symptoms of getting the configuration wrong on cross-compile inculde +warnings such as + + smbd/trans2.c: In function `get_lanman2_dir_entry': + smbd/trans2.c:1065: warning: right shift count >= width of type + +and errors like + + smbd/vfs.c:630: error: dereferencing pointer to incomplete type + +(when trying to dereference dirent64.) + +--- source/configure.in.orig 2005-05-29 14:46:18.000000000 -0700 ++++ source/configure.in 2005-05-29 14:51:57.000000000 -0700 +@@ -588,7 +588,7 @@ + # Tests for linux LFS support. Need kernel 2.4 and glibc2.2 or greater support. + # + *linux*) +- AC_MSG_CHECKING([for LFS support]) ++ AC_CACHE_CHECK([for LFS support], samba_cv_LINUX_LFS_SUPPORT,[ + old_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS" + AC_TRY_RUN([ +@@ -627,15 +627,14 @@ + exit(1); + #endif + } +-], [LINUX_LFS_SUPPORT=yes], [LINUX_LFS_SUPPORT=no], [LINUX_LFS_SUPPORT=cross]) +- CPPFLAGS="$old_CPPFLAGS" +- if test x$LINUX_LFS_SUPPORT = xyes ; then ++], [samba_cv_LINUX_LFS_SUPPORT=yes], [samba_cv_LINUX_LFS_SUPPORT=no], [samba_cv_LINUX_LFS_SUPPORT=cross]) ++ CPPFLAGS="$old_CPPFLAGS"]) ++ if test x"$samba_cv_LINUX_LFS_SUPPORT" = x"yes" ; then + CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS" + AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to enable large file support]) + AC_DEFINE(_FILE_OFFSET_BITS, 64, [File offset bits]) + AC_DEFINE(_GNU_SOURCE, 1, [Whether to use GNU libc extensions]) + fi +- AC_MSG_RESULT([$LINUX_LFS_SUPPORT]) + ;; + + # diff --git a/packages/samba/samba-3.0.23c/configure.patch b/packages/samba/samba-3.0.23c/configure.patch new file mode 100644 index 0000000000..0366efb314 --- /dev/null +++ b/packages/samba/samba-3.0.23c/configure.patch @@ -0,0 +1,170 @@ + +# +# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher +# + +--- source/configure.in~configure 2003-12-14 22:36:25.000000000 -0500 ++++ source/configure.in 2004-01-26 14:33:15.000000000 -0500 +@@ -959,7 +959,7 @@ + #endif + exit(0); + } +-], [linux_getgrouplist_ok=yes], [linux_getgrouplist_ok=no]) ++], [linux_getgrouplist_ok=yes], [linux_getgrouplist_ok=no], [linux_getgrouplist_ok=cross]) + if test x"$linux_getgrouplist_ok" = x"yes"; then + AC_DEFINE(HAVE_GETGROUPLIST, 1, [Have good getgrouplist]) + fi +--- source/aclocal.m4~configure 2004-01-26 14:33:15.000000000 -0500 ++++ source/aclocal.m4 2004-01-26 17:34:28.000000000 -0500 +@@ -2,7 +2,7 @@ + dnl if the cache file is inconsistent with the current host, + dnl target and build system types, execute CMD or print a default + dnl error message. +-AC_DEFUN(AC_VALIDATE_CACHE_SYSTEM_TYPE, [ ++AC_DEFUN([AC_VALIDATE_CACHE_SYSTEM_TYPE], [ + AC_REQUIRE([AC_CANONICAL_SYSTEM]) + AC_MSG_CHECKING([config.cache system type]) + if { test x"${ac_cv_host_system_type+set}" = x"set" && +@@ -24,7 +24,7 @@ + + + dnl test whether dirent has a d_off member +-AC_DEFUN(AC_DIRENT_D_OFF, ++AC_DEFUN([AC_DIRENT_D_OFF], + [AC_CACHE_CHECK([for d_off in dirent], ac_cv_dirent_d_off, + [AC_TRY_COMPILE([ + #include +@@ -38,7 +38,7 @@ + + dnl Mark specified module as shared + dnl SMB_MODULE(name,static_files,shared_files,subsystem,whatif-static,whatif-shared) +-AC_DEFUN(SMB_MODULE, ++AC_DEFUN([SMB_MODULE], + [ + AC_MSG_CHECKING([how to build $1]) + if test "$[MODULE_][$1]"; then +@@ -68,7 +68,7 @@ + fi + ]) + +-AC_DEFUN(SMB_SUBSYSTEM, ++AC_DEFUN([SMB_SUBSYSTEM], + [ + AC_SUBST($1_STATIC) + AC_SUBST($1_MODULES) +@@ -77,7 +77,7 @@ + ]) + + dnl AC_PROG_CC_FLAG(flag) +-AC_DEFUN(AC_PROG_CC_FLAG, ++AC_DEFUN([AC_PROG_CC_FLAG], + [AC_CACHE_CHECK(whether ${CC-cc} accepts -$1, ac_cv_prog_cc_$1, + [echo 'void f(){}' > conftest.c + if test -z "`${CC-cc} -$1 -c conftest.c 2>&1`"; then +@@ -91,7 +91,7 @@ + dnl see if a declaration exists for a function or variable + dnl defines HAVE_function_DECL if it exists + dnl AC_HAVE_DECL(var, includes) +-AC_DEFUN(AC_HAVE_DECL, ++AC_DEFUN([AC_HAVE_DECL], + [ + AC_CACHE_CHECK([for $1 declaration],ac_cv_have_$1_decl,[ + AC_TRY_COMPILE([$2],[int i = (int)$1], +@@ -223,7 +223,7 @@ + + dnl Define an AC_DEFINE with ifndef guard. + dnl AC_N_DEFINE(VARIABLE [, VALUE]) +-define(AC_N_DEFINE, ++define([AC_N_DEFINE], + [cat >> confdefs.h <<\EOF + [#ifndef] $1 + [#define] $1 ifelse($#, 2, [$2], $#, 3, [$2], 1) +@@ -233,14 +233,14 @@ + + dnl Add an #include + dnl AC_ADD_INCLUDE(VARIABLE) +-define(AC_ADD_INCLUDE, ++define([AC_ADD_INCLUDE], + [cat >> confdefs.h <<\EOF + [#include] $1 + EOF + ]) + + dnl Copied from libtool.m4 +-AC_DEFUN(AC_PROG_LD_GNU, ++AC_DEFUN([AC_PROG_LD_GNU], + [AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld, + [# I'd rather use --version here, but apparently some GNU ld's only accept -v. + if $LD -v 2>&1 &5; then +@@ -259,7 +259,7 @@ + dnl AM_PATH_XML2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) + dnl Test for XML, and define XML_CFLAGS and XML_LIBS + dnl +-AC_DEFUN(AM_PATH_XML2,[ ++AC_DEFUN([AM_PATH_XML2],[ + AC_ARG_WITH(xml-prefix, + [ --with-xml-prefix=PFX Prefix where libxml is installed (optional)], + xml_config_prefix="$withval", xml_config_prefix="") +@@ -443,7 +443,7 @@ + dnl AM_PATH_MYSQL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) + dnl Test for MYSQL, and define MYSQL_CFLAGS and MYSQL_LIBS + dnl +-AC_DEFUN(AM_PATH_MYSQL, ++AC_DEFUN([AM_PATH_MYSQL], + [dnl + dnl Get the cflags and libraries from the mysql_config script + dnl +@@ -485,7 +485,7 @@ + ]) + + dnl Removes -I/usr/include/? from given variable +-AC_DEFUN(CFLAGS_REMOVE_USR_INCLUDE,[ ++AC_DEFUN([CFLAGS_REMOVE_USR_INCLUDE],[ + ac_new_flags="" + for i in [$]$1; do + case [$]i in +@@ -497,7 +497,7 @@ + ]) + + dnl Removes -L/usr/lib/? from given variable +-AC_DEFUN(LIB_REMOVE_USR_LIB,[ ++AC_DEFUN([LIB_REMOVE_USR_LIB],[ + ac_new_flags="" + for i in [$]$1; do + case [$]i in +@@ -510,7 +510,7 @@ + + dnl From Bruno Haible. + +-AC_DEFUN(jm_ICONV, ++AC_DEFUN([jm_ICONV], + [ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable libiconv installed). +@@ -607,7 +607,7 @@ + fi + ]) + +-AC_DEFUN(rjs_CHARSET,[ ++AC_DEFUN([rjs_CHARSET],[ + dnl Find out if we can convert from $1 to UCS2-LE + AC_MSG_CHECKING([can we convert from $1 to UCS2-LE?]) + AC_TRY_RUN([ +@@ -625,7 +625,7 @@ + + dnl CFLAGS_ADD_DIR(CFLAGS, $INCDIR) + dnl This function doesn't add -I/usr/include into CFLAGS +-AC_DEFUN(CFLAGS_ADD_DIR,[ ++AC_DEFUN([CFLAGS_ADD_DIR],[ + if test "$2" != "/usr/include" ; then + $1="$$1 -I$2" + fi +@@ -633,7 +633,7 @@ + + dnl LIB_ADD_DIR(LDFLAGS, $LIBDIR) + dnl This function doesn't add -L/usr/lib into LDFLAGS +-AC_DEFUN(LIB_ADD_DIR,[ ++AC_DEFUN([LIB_ADD_DIR],[ + if test "$2" != "/usr/lib" ; then + $1="$$1 -L$2" + fi diff --git a/packages/samba/samba-3.0.23c/init b/packages/samba/samba-3.0.23c/init new file mode 100644 index 0000000000..cb57b17de4 --- /dev/null +++ b/packages/samba/samba-3.0.23c/init @@ -0,0 +1,58 @@ +#! /bin/sh +# +# This is an init script for openembedded +# Copy it to /etc/init.d/samba and type +# > update-rc.d samba defaults 60 +# + + +smbd=/usr/sbin/smbd +test -x "$smbd" || exit 0 +nmbd=/usr/sbin/nmbd +test -x "$nmbd" || exit 0 + + +case "$1" in + start) + echo -n "Starting Samba: smbd" + start-stop-daemon --start --quiet --exec $smbd + echo -n " nmbd" + start-stop-daemon --start --quiet --exec $nmbd + echo "." + ;; + stop) + echo -n "Stopping Samba: smbd" + start-stop-daemon --stop --quiet --pidfile /var/run/smbd.pid + echo -n " nmbd" + start-stop-daemon --stop --quiet --pidfile /var/run/nmbd.pid + echo "." + ;; + reload|force-reload) + start-stop-daemon --stop --quiet --signal 1 --exec $smbd + start-stop-daemon --stop --quiet --signal 1 --exec $nmbd + ;; + restart) + echo -n "Stopping Samba: smbd" + start-stop-daemon --stop --quiet --pidfile /var/run/smbd.pid + echo -n " nmbd" + start-stop-daemon --stop --quiet --pidfile /var/run/nmbd.pid + echo "" + echo -n "Waiting for samba processes to die off" + for i in 1 2 3 ; + do + sleep 1 + echo -n "." + done + echo "" + echo -n "Starting Samba: smbd" + start-stop-daemon --start --quiet --exec $smbd + echo -n " nmbd" + start-stop-daemon --start --quiet --exec $nmbd + echo "." + ;; + *) + echo "Usage: /etc/init.d/samba {start|stop|reload|restart|force-reload}" + exit 1 +esac + +exit 0 \ No newline at end of file diff --git a/packages/samba/samba-3.0.23c/init-essential b/packages/samba/samba-3.0.23c/init-essential new file mode 100644 index 0000000000..59184ce733 --- /dev/null +++ b/packages/samba/samba-3.0.23c/init-essential @@ -0,0 +1,68 @@ +#! /bin/sh +# +# This is an init script for openembedded +# Copy it to /etc/init.d/samba and type +# > update-rc.d samba defaults 60 +# + + +smbd=/usr/sbin/smbd +test -x "$smbd" || exit 0 +nmbd=/usr/sbin/nmbd +test -x "$nmbd" || exit 0 + + +if test -e /etc/samba/private/smbpasswd +then + if test -n "`cat /etc/samba/private/smbpasswd`" + then + CONFIG_FILE="/etc/samba/smb.conf" + fi +fi + +test -z "$CONFIG_FILE" && CONFIG_FILE="/etc/samba/smb-essential-inactive.conf" + +case "$1" in + start) + echo -n "Starting Samba: smbd" + start-stop-daemon --start --quiet --exec $smbd -- -s $CONFIG_FILE + echo -n " nmbd" + start-stop-daemon --start --quiet --exec $nmbd -- -s $CONFIG_FILE + echo "." + ;; + stop) + echo -n "Stopping Samba: smbd" + start-stop-daemon --stop --quiet --pidfile /var/run/smbd.pid + echo -n " nmbd" + start-stop-daemon --stop --quiet --pidfile /var/run/nmbd.pid + echo "." + ;; + reload|force-reload) + start-stop-daemon --stop --quiet --signal 1 --exec $smbd -- -s $CONFIG_FILE + start-stop-daemon --stop --quiet --signal 1 --exec $nmbd -- -s $CONFIG_FILE + ;; + restart) + echo -n "Stopping Samba: smbd" + start-stop-daemon --stop --quiet --pidfile /var/run/smbd.pid + echo -n " nmbd" + start-stop-daemon --stop --quiet --pidfile /var/run/nmbd.pid + echo "" + echo -n "Waiting for samba processes to die off" + for i in 1 2 3 ; + do + sleep 1 + echo -n "." + done + echo "" + echo -n "Starting Samba: smbd" + start-stop-daemon --start --quiet --exec $smbd -- -s $CONFIG_FILE + echo -n " nmbd" + start-stop-daemon --start --quiet --exec $nmbd -- -s $CONFIG_FILE + echo "." + ;; + *) + echo "Usage: /etc/init.d/samba {start|stop|reload|restart|force-reload}" + exit 1 +esac + +exit 0 diff --git a/packages/samba/samba-3.0.23c/quota.patch b/packages/samba/samba-3.0.23c/quota.patch new file mode 100644 index 0000000000..6f42ff868f --- /dev/null +++ b/packages/samba/samba-3.0.23c/quota.patch @@ -0,0 +1,11 @@ +--- lib/sysquotas_4A.c.old 2005-07-03 17:16:00.000000000 +0200 ++++ lib/sysquotas_4A.c 2005-07-03 17:10:09.000000000 +0200 +@@ -28,6 +28,8 @@ + /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */ + /* this is used by: HPUX,IRIX */ + ++ #define _LINUX_QUOTA_VERSION 1 ++ + #ifdef HAVE_SYS_TYPES_H + #include + #endif diff --git a/packages/samba/samba-3.0.23c/smb-essential-inactive.conf b/packages/samba/samba-3.0.23c/smb-essential-inactive.conf new file mode 100644 index 0000000000..d42d63cb9a --- /dev/null +++ b/packages/samba/samba-3.0.23c/smb-essential-inactive.conf @@ -0,0 +1,34 @@ + + +[global] + workgroup = MYWORKGROUP + server string = OpenZaurus Samba Server + + netbios name = %L-INACTIVE + + security = share + + load printers = no + + socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192 + + dns proxy = yes + + +#============================ Share Definitions ============================== + +[Samba-Help] + comment = How to enable Samba + path = /usr/share/samba/help + writable = no + public = yes + printable = no + +[printers] + comment = All Printers + path = /usr/spool/samba + guest ok = no + writable = no + printable = yes + browseable = no + diff --git a/packages/samba/samba-3.0.23c/smb-essential.conf b/packages/samba/samba-3.0.23c/smb-essential.conf new file mode 100644 index 0000000000..24cb2a56cb --- /dev/null +++ b/packages/samba/samba-3.0.23c/smb-essential.conf @@ -0,0 +1,82 @@ + + +[global] + workgroup = MYWORKGROUP + server string = OpenZaurus Samba Server + + security = user + + load printers = no + +; guest account = pcguest + + log file = /var/log.%m + + max log size = 50 + + socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192 + + dns proxy = yes + + +#============================ Share Definitions ============================== +[homes] + comment = Home Directory for %U + browseable = no + writable = yes + follow symlinks = yes + include = /etc/test.%U + +# This one is useful for people to share files +;[tmp] +; comment = Temporary file space +; path = /tmp +; read only = no +; public = yes + +[printers] + comment = All Printers + path = /usr/spool/samba + guest ok = no + writable = no + printable = yes + browseable = no + +[CompactFlash] + comment = Compact Flash Storage + path = /media/cf + writable = yes + printable = no + public = no + +[SD-MMC] + comment = SD & MMC Storage + path = /media/card + writable = yes + printable = no + public = no + +[RootFS] + comment = Zaurus Rootfs + path = / + writable = yes + printable = no + public = no + follow symlinks = yes + +[Home] + comment = "User Home Directories" + path = /home + writable = yes + printable = no + public = no + follow symlinks = yes + +[Samba-Help] + comment = How to configure Samba + path = /usr/share/samba/help + writable = no + public = yes + printable = no + + diff --git a/packages/samba/samba_3.0.23c.bb b/packages/samba/samba_3.0.23c.bb new file mode 100644 index 0000000000..e129b241b3 --- /dev/null +++ b/packages/samba/samba_3.0.23c.bb @@ -0,0 +1,55 @@ +LICENCE="GPL-2" +MAINTAINER="Oyvind Repvik " +PR = "r0" + +SRC_URI = "http://us2.samba.org/samba/ftp/stable/samba-${PV}.tar.gz \ + file://configure.patch;patch=1 \ + file://cifs.patch;patch=1 \ + file://config-lfs.patch;patch=1 \ + file://init \ + file://quota.patch;patch=1;pnum=0 \ + " +S = ${WORKDIR}/${P}/source + +include samba.inc +inherit update-rc.d + +INITSCRIPT_NAME = "samba" +# No dependencies, goes in at level 20 (NOTE: take care with the +# level, later levels put the shutdown later too - see the links +# in rc6.d, the shutdown must precede network shutdown). +INITSCRIPT_PARAMS = "defaults" +CONFFILES_${PN} = "${sysconfdir}/samba/smb.conf" + +# The file system settings --foodir=dirfoo and overridden unconditionally +# in the samba config by --with-foodir=dirfoo - even if the --with is not +# specified! Fix that here. Set the privatedir to /etc/samba/private. +EXTRA_OECONF += "\ + samba_cv_struct_timespec=yes \ + --with-configdir=${sysconfdir}/samba \ + --with-privatedir=${sysconfdir}/samba/private \ + --with-lockdir=${localstatedir}/lock \ + --with-piddir=${localstatedir}/run \ + --with-logfilebase=${localstatedir}/log \ + --with-libdir=${libdir} \ + --with-mandir=${mandir} \ + --with-swatdir=${datadir}/swat \ + " + +do_install_append() { + install -d "${D}${localstatedir}/log" + rm -f ${D}/sbin/mount.smbfs + ln -sf smbmount ${D}${sbindir}/mount.smbfs + install -d "${D}${sysconfdir}/init.d" + install -c -m 755 ${WORKDIR}/init ${D}${sysconfdir}/init.d/samba + install -d "${D}${sysconfdir}/samba" + install -c -m 644 ../examples/smb.conf.default ${D}${sysconfdir}/samba/smb.conf +} + +PACKAGES =+ "swat" + +FILES_swat = "${sbindir}/swat ${datadir}/swat ${libdir}/*.msg" +FILES_${PN} += "${libdir}/vfs/*.so ${libdir}/charset/*.so ${libdir}/*.dat ${libdir}/auth/*.so" +# +# bug fix for samba.inc: +FILES_cifs-doc = "${mandir}/man8/mount.cifs.8" -- cgit v1.2.3 From db39c0f2f3257233b415fa9443eae90a471e29af Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Sat, 2 Sep 2006 17:57:34 +0000 Subject: samba: Remove duplicate files --- packages/samba/samba-3.0.23c/Managing-Samba.txt | 40 ----------- packages/samba/samba-3.0.23c/cifs.patch | 10 --- packages/samba/samba-3.0.23c/config-lfs.patch | 47 ------------- packages/samba/samba-3.0.23c/init | 58 --------------- packages/samba/samba-3.0.23c/init-essential | 68 ------------------ packages/samba/samba-3.0.23c/quota.patch | 11 --- .../samba-3.0.23c/smb-essential-inactive.conf | 34 --------- packages/samba/samba-3.0.23c/smb-essential.conf | 82 ---------------------- 8 files changed, 350 deletions(-) delete mode 100644 packages/samba/samba-3.0.23c/Managing-Samba.txt delete mode 100644 packages/samba/samba-3.0.23c/cifs.patch delete mode 100644 packages/samba/samba-3.0.23c/config-lfs.patch delete mode 100644 packages/samba/samba-3.0.23c/init delete mode 100644 packages/samba/samba-3.0.23c/init-essential delete mode 100644 packages/samba/samba-3.0.23c/quota.patch delete mode 100644 packages/samba/samba-3.0.23c/smb-essential-inactive.conf delete mode 100644 packages/samba/samba-3.0.23c/smb-essential.conf diff --git a/packages/samba/samba-3.0.23c/Managing-Samba.txt b/packages/samba/samba-3.0.23c/Managing-Samba.txt deleted file mode 100644 index 01f7592824..0000000000 --- a/packages/samba/samba-3.0.23c/Managing-Samba.txt +++ /dev/null @@ -1,40 +0,0 @@ -This device is running a bare-bone Samba server which allows easy -transfer of files and directories between any networked desktop PC and -your networked PDA. - -Since it is generally a bad idea to allow everyone read and write access -to your PDA, you will have to configure at least one user to get access to -any shared folder. - -How to create a Samba user with password: - -- If you haven't already created a non-root user, do so now: - root@poodle:/usr/bin# adduser testuser - Changing password for testuser - Enter the new password (minimum of 5, maximum of 8 characters) - Please use a combination of upper and lower case letters and numbers. - Enter new password: - Bad password: too short. - - Warning: weak password (continuing). - Re-enter new password: - Password changed. - root@poodle:/usr/bin# - -- Note that the password you entered will _not_ be your samba password. - Samba uses its own password database. - -- Add a Samba password for your user: - root@poodle:/usr/bin# smbpasswd -a testuser - New SMB password: - Retype new SMB password: - Added user testuser. - root@poodle:/usr/bin# - -- After you have added your new samba user, you'll have to restart the samba - server by running "/etc/init.d/samba restart" or by rebooting the device - -- Use the newly created username / password combination to access your network - shares. Please note the the Samba username must also exist as a unix username! - - diff --git a/packages/samba/samba-3.0.23c/cifs.patch b/packages/samba/samba-3.0.23c/cifs.patch deleted file mode 100644 index ee6dab567f..0000000000 --- a/packages/samba/samba-3.0.23c/cifs.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- source/client/mount.cifs.c.old 2004-11-28 02:33:52.000000000 +1030 -+++ source/client/mount.cifs.c 2004-11-28 02:33:59.000000000 +1030 -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - #define MOUNT_CIFS_VERSION_MAJOR "1" - #define MOUNT_CIFS_VERSION_MINOR "2" diff --git a/packages/samba/samba-3.0.23c/config-lfs.patch b/packages/samba/samba-3.0.23c/config-lfs.patch deleted file mode 100644 index b37ed690ce..0000000000 --- a/packages/samba/samba-3.0.23c/config-lfs.patch +++ /dev/null @@ -1,47 +0,0 @@ -Cache the check for Linux LFS support, so it can be prepopulated from -the site cache for configure variables for cross-compiling. Without this, -samba gets the idea that it can use dirent64 and friends without defining -the flags it needs to get it, such as _GNU_SOURCE and _LARGEFILE64_SOURCE. - -Symptoms of getting the configuration wrong on cross-compile inculde -warnings such as - - smbd/trans2.c: In function `get_lanman2_dir_entry': - smbd/trans2.c:1065: warning: right shift count >= width of type - -and errors like - - smbd/vfs.c:630: error: dereferencing pointer to incomplete type - -(when trying to dereference dirent64.) - ---- source/configure.in.orig 2005-05-29 14:46:18.000000000 -0700 -+++ source/configure.in 2005-05-29 14:51:57.000000000 -0700 -@@ -588,7 +588,7 @@ - # Tests for linux LFS support. Need kernel 2.4 and glibc2.2 or greater support. - # - *linux*) -- AC_MSG_CHECKING([for LFS support]) -+ AC_CACHE_CHECK([for LFS support], samba_cv_LINUX_LFS_SUPPORT,[ - old_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS" - AC_TRY_RUN([ -@@ -627,15 +627,14 @@ - exit(1); - #endif - } --], [LINUX_LFS_SUPPORT=yes], [LINUX_LFS_SUPPORT=no], [LINUX_LFS_SUPPORT=cross]) -- CPPFLAGS="$old_CPPFLAGS" -- if test x$LINUX_LFS_SUPPORT = xyes ; then -+], [samba_cv_LINUX_LFS_SUPPORT=yes], [samba_cv_LINUX_LFS_SUPPORT=no], [samba_cv_LINUX_LFS_SUPPORT=cross]) -+ CPPFLAGS="$old_CPPFLAGS"]) -+ if test x"$samba_cv_LINUX_LFS_SUPPORT" = x"yes" ; then - CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS" - AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to enable large file support]) - AC_DEFINE(_FILE_OFFSET_BITS, 64, [File offset bits]) - AC_DEFINE(_GNU_SOURCE, 1, [Whether to use GNU libc extensions]) - fi -- AC_MSG_RESULT([$LINUX_LFS_SUPPORT]) - ;; - - # diff --git a/packages/samba/samba-3.0.23c/init b/packages/samba/samba-3.0.23c/init deleted file mode 100644 index cb57b17de4..0000000000 --- a/packages/samba/samba-3.0.23c/init +++ /dev/null @@ -1,58 +0,0 @@ -#! /bin/sh -# -# This is an init script for openembedded -# Copy it to /etc/init.d/samba and type -# > update-rc.d samba defaults 60 -# - - -smbd=/usr/sbin/smbd -test -x "$smbd" || exit 0 -nmbd=/usr/sbin/nmbd -test -x "$nmbd" || exit 0 - - -case "$1" in - start) - echo -n "Starting Samba: smbd" - start-stop-daemon --start --quiet --exec $smbd - echo -n " nmbd" - start-stop-daemon --start --quiet --exec $nmbd - echo "." - ;; - stop) - echo -n "Stopping Samba: smbd" - start-stop-daemon --stop --quiet --pidfile /var/run/smbd.pid - echo -n " nmbd" - start-stop-daemon --stop --quiet --pidfile /var/run/nmbd.pid - echo "." - ;; - reload|force-reload) - start-stop-daemon --stop --quiet --signal 1 --exec $smbd - start-stop-daemon --stop --quiet --signal 1 --exec $nmbd - ;; - restart) - echo -n "Stopping Samba: smbd" - start-stop-daemon --stop --quiet --pidfile /var/run/smbd.pid - echo -n " nmbd" - start-stop-daemon --stop --quiet --pidfile /var/run/nmbd.pid - echo "" - echo -n "Waiting for samba processes to die off" - for i in 1 2 3 ; - do - sleep 1 - echo -n "." - done - echo "" - echo -n "Starting Samba: smbd" - start-stop-daemon --start --quiet --exec $smbd - echo -n " nmbd" - start-stop-daemon --start --quiet --exec $nmbd - echo "." - ;; - *) - echo "Usage: /etc/init.d/samba {start|stop|reload|restart|force-reload}" - exit 1 -esac - -exit 0 \ No newline at end of file diff --git a/packages/samba/samba-3.0.23c/init-essential b/packages/samba/samba-3.0.23c/init-essential deleted file mode 100644 index 59184ce733..0000000000 --- a/packages/samba/samba-3.0.23c/init-essential +++ /dev/null @@ -1,68 +0,0 @@ -#! /bin/sh -# -# This is an init script for openembedded -# Copy it to /etc/init.d/samba and type -# > update-rc.d samba defaults 60 -# - - -smbd=/usr/sbin/smbd -test -x "$smbd" || exit 0 -nmbd=/usr/sbin/nmbd -test -x "$nmbd" || exit 0 - - -if test -e /etc/samba/private/smbpasswd -then - if test -n "`cat /etc/samba/private/smbpasswd`" - then - CONFIG_FILE="/etc/samba/smb.conf" - fi -fi - -test -z "$CONFIG_FILE" && CONFIG_FILE="/etc/samba/smb-essential-inactive.conf" - -case "$1" in - start) - echo -n "Starting Samba: smbd" - start-stop-daemon --start --quiet --exec $smbd -- -s $CONFIG_FILE - echo -n " nmbd" - start-stop-daemon --start --quiet --exec $nmbd -- -s $CONFIG_FILE - echo "." - ;; - stop) - echo -n "Stopping Samba: smbd" - start-stop-daemon --stop --quiet --pidfile /var/run/smbd.pid - echo -n " nmbd" - start-stop-daemon --stop --quiet --pidfile /var/run/nmbd.pid - echo "." - ;; - reload|force-reload) - start-stop-daemon --stop --quiet --signal 1 --exec $smbd -- -s $CONFIG_FILE - start-stop-daemon --stop --quiet --signal 1 --exec $nmbd -- -s $CONFIG_FILE - ;; - restart) - echo -n "Stopping Samba: smbd" - start-stop-daemon --stop --quiet --pidfile /var/run/smbd.pid - echo -n " nmbd" - start-stop-daemon --stop --quiet --pidfile /var/run/nmbd.pid - echo "" - echo -n "Waiting for samba processes to die off" - for i in 1 2 3 ; - do - sleep 1 - echo -n "." - done - echo "" - echo -n "Starting Samba: smbd" - start-stop-daemon --start --quiet --exec $smbd -- -s $CONFIG_FILE - echo -n " nmbd" - start-stop-daemon --start --quiet --exec $nmbd -- -s $CONFIG_FILE - echo "." - ;; - *) - echo "Usage: /etc/init.d/samba {start|stop|reload|restart|force-reload}" - exit 1 -esac - -exit 0 diff --git a/packages/samba/samba-3.0.23c/quota.patch b/packages/samba/samba-3.0.23c/quota.patch deleted file mode 100644 index 6f42ff868f..0000000000 --- a/packages/samba/samba-3.0.23c/quota.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- lib/sysquotas_4A.c.old 2005-07-03 17:16:00.000000000 +0200 -+++ lib/sysquotas_4A.c 2005-07-03 17:10:09.000000000 +0200 -@@ -28,6 +28,8 @@ - /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */ - /* this is used by: HPUX,IRIX */ - -+ #define _LINUX_QUOTA_VERSION 1 -+ - #ifdef HAVE_SYS_TYPES_H - #include - #endif diff --git a/packages/samba/samba-3.0.23c/smb-essential-inactive.conf b/packages/samba/samba-3.0.23c/smb-essential-inactive.conf deleted file mode 100644 index d42d63cb9a..0000000000 --- a/packages/samba/samba-3.0.23c/smb-essential-inactive.conf +++ /dev/null @@ -1,34 +0,0 @@ - - -[global] - workgroup = MYWORKGROUP - server string = OpenZaurus Samba Server - - netbios name = %L-INACTIVE - - security = share - - load printers = no - - socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192 - - dns proxy = yes - - -#============================ Share Definitions ============================== - -[Samba-Help] - comment = How to enable Samba - path = /usr/share/samba/help - writable = no - public = yes - printable = no - -[printers] - comment = All Printers - path = /usr/spool/samba - guest ok = no - writable = no - printable = yes - browseable = no - diff --git a/packages/samba/samba-3.0.23c/smb-essential.conf b/packages/samba/samba-3.0.23c/smb-essential.conf deleted file mode 100644 index 24cb2a56cb..0000000000 --- a/packages/samba/samba-3.0.23c/smb-essential.conf +++ /dev/null @@ -1,82 +0,0 @@ - - -[global] - workgroup = MYWORKGROUP - server string = OpenZaurus Samba Server - - security = user - - load printers = no - -; guest account = pcguest - - log file = /var/log.%m - - max log size = 50 - - socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192 - - dns proxy = yes - - -#============================ Share Definitions ============================== -[homes] - comment = Home Directory for %U - browseable = no - writable = yes - follow symlinks = yes - include = /etc/test.%U - -# This one is useful for people to share files -;[tmp] -; comment = Temporary file space -; path = /tmp -; read only = no -; public = yes - -[printers] - comment = All Printers - path = /usr/spool/samba - guest ok = no - writable = no - printable = yes - browseable = no - -[CompactFlash] - comment = Compact Flash Storage - path = /media/cf - writable = yes - printable = no - public = no - -[SD-MMC] - comment = SD & MMC Storage - path = /media/card - writable = yes - printable = no - public = no - -[RootFS] - comment = Zaurus Rootfs - path = / - writable = yes - printable = no - public = no - follow symlinks = yes - -[Home] - comment = "User Home Directories" - path = /home - writable = yes - printable = no - public = no - follow symlinks = yes - -[Samba-Help] - comment = How to configure Samba - path = /usr/share/samba/help - writable = no - public = yes - printable = no - - -- cgit v1.2.3 From 5deb71f87262364ed86132f969fadd076e20fd5b Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Sat, 2 Sep 2006 18:17:22 +0000 Subject: zd1211: Clean up duplicate files --- packages/zd1211/files/.mtn2git_empty | 0 packages/zd1211/files/makefile-unslung.patch | 48 ++++++++++++++++++++++ packages/zd1211/files/unslung-iwpriv-hack.patch | 19 +++++++++ packages/zd1211/files/unslung-writel-logging.patch | 14 +++++++ packages/zd1211/zd1211-r83/makefile-unslung.patch | 48 ---------------------- .../zd1211/zd1211-r83/unslung-iwpriv-hack.patch | 19 --------- .../zd1211/zd1211-r83/unslung-writel-logging.patch | 14 ------- packages/zd1211/zd1211_r59.bb | 35 ---------------- packages/zd1211/zd1211_r67.bb | 35 ---------------- packages/zd1211/zd1211_r74.bb | 38 ----------------- 10 files changed, 81 insertions(+), 189 deletions(-) create mode 100644 packages/zd1211/files/.mtn2git_empty create mode 100644 packages/zd1211/files/makefile-unslung.patch create mode 100644 packages/zd1211/files/unslung-iwpriv-hack.patch create mode 100644 packages/zd1211/files/unslung-writel-logging.patch delete mode 100644 packages/zd1211/zd1211-r83/makefile-unslung.patch delete mode 100644 packages/zd1211/zd1211-r83/unslung-iwpriv-hack.patch delete mode 100644 packages/zd1211/zd1211-r83/unslung-writel-logging.patch delete mode 100644 packages/zd1211/zd1211_r59.bb delete mode 100644 packages/zd1211/zd1211_r67.bb delete mode 100644 packages/zd1211/zd1211_r74.bb diff --git a/packages/zd1211/files/.mtn2git_empty b/packages/zd1211/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/zd1211/files/makefile-unslung.patch b/packages/zd1211/files/makefile-unslung.patch new file mode 100644 index 0000000000..4edcbb7a9d --- /dev/null +++ b/packages/zd1211/files/makefile-unslung.patch @@ -0,0 +1,48 @@ +--- zd1211-driver-r77/Makefile.orig 2006-02-25 16:04:26.000000000 +0100 ++++ zd1211-driver-r77/Makefile 2006-02-25 17:11:27.000000000 +0100 +@@ -4,24 +4,23 @@ + # + # + +-CC=gcc +-CPP=g++ +-LD=ld +-rM=rm -f -r ++CC ?= gcc ++CPP ?= g++ ++LD ?= ld + +-MODPATH := /lib/modules/$(shell uname -r) ++MODPATH ?= /lib/modules/$(shell uname -r) + + # if the kernel is 2.6.x, turn on this +-KERN_26=y ++#KERN_26=y + +-KERNEL_SOURCE=$(MODPATH)/source ++KERNEL_SOURCE ?= $(MODPATH)/source + #KERNEL_SOURCE=/usr/src/linux + + # set to 1 for zd1211b + ZD1211REV_B=0 + +-SRC_DIR=src +-DEFINES=-D__KERNEL__ -DMODULE=1 ++SRC_DIR=src ++DEFINES ?=-D__KERNEL__ -DMODULE=1 + + + +@@ -227,9 +226,9 @@ + depmod -a + + #for apdbg +- gcc -o apdbg apdbg.c +- chmod +x apdbg +- cp ./apdbg /sbin/apdbg ++# gcc -o apdbg apdbg.c ++# chmod +x apdbg ++# cp ./apdbg /sbin/apdbg + + clean: + rm -rf .tmp_versions .*.cmd *.ko *.mod.c *.mod.o *.o $(SRC_DIR)/*.o $(SRC_DIR)/.*.o.cmd diff --git a/packages/zd1211/files/unslung-iwpriv-hack.patch b/packages/zd1211/files/unslung-iwpriv-hack.patch new file mode 100644 index 0000000000..64f3806140 --- /dev/null +++ b/packages/zd1211/files/unslung-iwpriv-hack.patch @@ -0,0 +1,19 @@ +--- zd1211-driver-r74/src/zd1205.c~ 2006-04-16 09:42:15.000000000 -0500 ++++ zd1211-driver-r74/src/zd1205.c 2006-04-27 12:29:03.000000000 -0500 +@@ -349,8 +349,14 @@ + { SIOCIWFIRSTPRIV + 0xA, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "connect" }, + { SIOCIWFIRSTPRIV + 0xB, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_mac_mode" }, + { SIOCIWFIRSTPRIV + 0xC, 0, IW_PRIV_TYPE_CHAR | 12, "get_mac_mode" }, +- { SIOCIWFIRSTPRIV + 0xD, 0, 0, "save_conf" /* has been removed */ }, +- { SIOCIWFIRSTPRIV + 0xE, 0, 0, "load_conf" /* has been removed */ }, ++// HACK HACK HACK - The following two lines are commented out in order to make ++// iwpriv work on Unslung (2.4.22 kernel) - this kernel's Wireless Extensions ++// can only handle up to 16 iwpriv entries in this structure. Yes, the correct ++// fix is to patch the Wireless Extensions in the Unslung kernel. This hack ++// should be removed when that's actually done. ~mwester 27APR2006 ++// { SIOCIWFIRSTPRIV + 0xD, 0, 0, "save_conf" /* has been removed */ }, ++// { SIOCIWFIRSTPRIV + 0xE, 0, 0, "load_conf" /* has been removed */ }, ++// End of HACK + { SIOCIWFIRSTPRIV + 0xF, 0, IW_PRIV_TYPE_CHAR | 14, "get_Region" }, + { SIOCIWFIRSTPRIV + 0x9,IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_Region" }, + }; diff --git a/packages/zd1211/files/unslung-writel-logging.patch b/packages/zd1211/files/unslung-writel-logging.patch new file mode 100644 index 0000000000..00d54d7d68 --- /dev/null +++ b/packages/zd1211/files/unslung-writel-logging.patch @@ -0,0 +1,14 @@ +--- zd1211-driver-r74/src/zd1211.c~ 2006-04-09 12:28:06.000000000 -0500 ++++ zd1211-driver-r74/src/zd1211.c 2006-04-27 12:38:55.000000000 -0500 +@@ -652,7 +652,10 @@ + count++; + + if (count > 5) { +- printk(KERN_ERR "1211_readl failed for 5 attempts...Very Serious"); ++// You are going to see this often enough on Unslung that we might as well put it in ++// the syslog and fix it so it has a nl on the end. Sigh. ~mwester, 27APR06 ++// ++ printk(KERN_ERR "1211_readl failed for 5 attempts...Very Serious\n"); + break; + } + } diff --git a/packages/zd1211/zd1211-r83/makefile-unslung.patch b/packages/zd1211/zd1211-r83/makefile-unslung.patch deleted file mode 100644 index 4edcbb7a9d..0000000000 --- a/packages/zd1211/zd1211-r83/makefile-unslung.patch +++ /dev/null @@ -1,48 +0,0 @@ ---- zd1211-driver-r77/Makefile.orig 2006-02-25 16:04:26.000000000 +0100 -+++ zd1211-driver-r77/Makefile 2006-02-25 17:11:27.000000000 +0100 -@@ -4,24 +4,23 @@ - # - # - --CC=gcc --CPP=g++ --LD=ld --rM=rm -f -r -+CC ?= gcc -+CPP ?= g++ -+LD ?= ld - --MODPATH := /lib/modules/$(shell uname -r) -+MODPATH ?= /lib/modules/$(shell uname -r) - - # if the kernel is 2.6.x, turn on this --KERN_26=y -+#KERN_26=y - --KERNEL_SOURCE=$(MODPATH)/source -+KERNEL_SOURCE ?= $(MODPATH)/source - #KERNEL_SOURCE=/usr/src/linux - - # set to 1 for zd1211b - ZD1211REV_B=0 - --SRC_DIR=src --DEFINES=-D__KERNEL__ -DMODULE=1 -+SRC_DIR=src -+DEFINES ?=-D__KERNEL__ -DMODULE=1 - - - -@@ -227,9 +226,9 @@ - depmod -a - - #for apdbg -- gcc -o apdbg apdbg.c -- chmod +x apdbg -- cp ./apdbg /sbin/apdbg -+# gcc -o apdbg apdbg.c -+# chmod +x apdbg -+# cp ./apdbg /sbin/apdbg - - clean: - rm -rf .tmp_versions .*.cmd *.ko *.mod.c *.mod.o *.o $(SRC_DIR)/*.o $(SRC_DIR)/.*.o.cmd diff --git a/packages/zd1211/zd1211-r83/unslung-iwpriv-hack.patch b/packages/zd1211/zd1211-r83/unslung-iwpriv-hack.patch deleted file mode 100644 index 64f3806140..0000000000 --- a/packages/zd1211/zd1211-r83/unslung-iwpriv-hack.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- zd1211-driver-r74/src/zd1205.c~ 2006-04-16 09:42:15.000000000 -0500 -+++ zd1211-driver-r74/src/zd1205.c 2006-04-27 12:29:03.000000000 -0500 -@@ -349,8 +349,14 @@ - { SIOCIWFIRSTPRIV + 0xA, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "connect" }, - { SIOCIWFIRSTPRIV + 0xB, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_mac_mode" }, - { SIOCIWFIRSTPRIV + 0xC, 0, IW_PRIV_TYPE_CHAR | 12, "get_mac_mode" }, -- { SIOCIWFIRSTPRIV + 0xD, 0, 0, "save_conf" /* has been removed */ }, -- { SIOCIWFIRSTPRIV + 0xE, 0, 0, "load_conf" /* has been removed */ }, -+// HACK HACK HACK - The following two lines are commented out in order to make -+// iwpriv work on Unslung (2.4.22 kernel) - this kernel's Wireless Extensions -+// can only handle up to 16 iwpriv entries in this structure. Yes, the correct -+// fix is to patch the Wireless Extensions in the Unslung kernel. This hack -+// should be removed when that's actually done. ~mwester 27APR2006 -+// { SIOCIWFIRSTPRIV + 0xD, 0, 0, "save_conf" /* has been removed */ }, -+// { SIOCIWFIRSTPRIV + 0xE, 0, 0, "load_conf" /* has been removed */ }, -+// End of HACK - { SIOCIWFIRSTPRIV + 0xF, 0, IW_PRIV_TYPE_CHAR | 14, "get_Region" }, - { SIOCIWFIRSTPRIV + 0x9,IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_Region" }, - }; diff --git a/packages/zd1211/zd1211-r83/unslung-writel-logging.patch b/packages/zd1211/zd1211-r83/unslung-writel-logging.patch deleted file mode 100644 index 00d54d7d68..0000000000 --- a/packages/zd1211/zd1211-r83/unslung-writel-logging.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- zd1211-driver-r74/src/zd1211.c~ 2006-04-09 12:28:06.000000000 -0500 -+++ zd1211-driver-r74/src/zd1211.c 2006-04-27 12:38:55.000000000 -0500 -@@ -652,7 +652,10 @@ - count++; - - if (count > 5) { -- printk(KERN_ERR "1211_readl failed for 5 attempts...Very Serious"); -+// You are going to see this often enough on Unslung that we might as well put it in -+// the syslog and fix it so it has a nl on the end. Sigh. ~mwester, 27APR06 -+// -+ printk(KERN_ERR "1211_readl failed for 5 attempts...Very Serious\n"); - break; - } - } diff --git a/packages/zd1211/zd1211_r59.bb b/packages/zd1211/zd1211_r59.bb deleted file mode 100644 index 2ab0f2c5b2..0000000000 --- a/packages/zd1211/zd1211_r59.bb +++ /dev/null @@ -1,35 +0,0 @@ -DESCRIPTION = "Driver for zd1211 family of wireless USB Dongles" -PRIORITY = "optional" -SECTION = "kernel/modules" -MAINTAINER = "Oyvind Repvik " -LICENSE = "GPL" -PR = "r3" -RDEPENDS = "wireless-tools" - -SRC_URI = "http://zd1211.ath.cx/download/zd1211-driver-${PV}.tgz \ - file://makefile.patch;patch=1 \ - " - -SRC_URI_unslung = "http://zd1211.ath.cx/download/zd1211-driver-${PV}.tgz \ - file://makefile-unslung.patch;patch=1 \ - " - -S = "${WORKDIR}/zd1211-driver-${PV}" - -inherit module - -do_compile () { - unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS CC LD CPP - oe_runmake 'MODPATH=${D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net' \ - 'KERNEL_SOURCE=${STAGING_KERNEL_DIR}' \ - 'KDIR=${STAGING_KERNEL_DIR}' \ - 'KERNEL_VERSION=${KERNEL_VERSION}' \ - 'CC=${KERNEL_CC}' \ - 'LD=${KERNEL_LD}' -} - -do_install() { - install -d ${D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net - install -m 0644 ${S}/zd1211*${KERNEL_OBJECT_SUFFIX} ${D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net -} - diff --git a/packages/zd1211/zd1211_r67.bb b/packages/zd1211/zd1211_r67.bb deleted file mode 100644 index 2ab0f2c5b2..0000000000 --- a/packages/zd1211/zd1211_r67.bb +++ /dev/null @@ -1,35 +0,0 @@ -DESCRIPTION = "Driver for zd1211 family of wireless USB Dongles" -PRIORITY = "optional" -SECTION = "kernel/modules" -MAINTAINER = "Oyvind Repvik " -LICENSE = "GPL" -PR = "r3" -RDEPENDS = "wireless-tools" - -SRC_URI = "http://zd1211.ath.cx/download/zd1211-driver-${PV}.tgz \ - file://makefile.patch;patch=1 \ - " - -SRC_URI_unslung = "http://zd1211.ath.cx/download/zd1211-driver-${PV}.tgz \ - file://makefile-unslung.patch;patch=1 \ - " - -S = "${WORKDIR}/zd1211-driver-${PV}" - -inherit module - -do_compile () { - unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS CC LD CPP - oe_runmake 'MODPATH=${D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net' \ - 'KERNEL_SOURCE=${STAGING_KERNEL_DIR}' \ - 'KDIR=${STAGING_KERNEL_DIR}' \ - 'KERNEL_VERSION=${KERNEL_VERSION}' \ - 'CC=${KERNEL_CC}' \ - 'LD=${KERNEL_LD}' -} - -do_install() { - install -d ${D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net - install -m 0644 ${S}/zd1211*${KERNEL_OBJECT_SUFFIX} ${D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net -} - diff --git a/packages/zd1211/zd1211_r74.bb b/packages/zd1211/zd1211_r74.bb deleted file mode 100644 index bb23071835..0000000000 --- a/packages/zd1211/zd1211_r74.bb +++ /dev/null @@ -1,38 +0,0 @@ -DESCRIPTION = "Driver for zd1211 family of wireless USB Dongles" -PRIORITY = "optional" -SECTION = "kernel/modules" -MAINTAINER = "Oyvind Repvik " -LICENSE = "GPL" -PR = "r2" -RDEPENDS = "wireless-tools" - -SRC_URI = "http://zd1211.ath.cx/download/zd1211-driver-${PV}.tgz \ - file://makefile.patch;patch=1 \ - file://zd1211-endian-fix.patch;patch=1 \ - " - -SRC_URI_unslung = "http://zd1211.ath.cx/download/zd1211-driver-${PV}.tgz \ - file://makefile-unslung.patch;patch=1 \ - file://zd1211-endian-fix.patch;patch=1 \ - file://unslung-iwpriv-hack.patch;patch=1 \ - file://unslung-writel-logging.patch;patch=1 \ - " - -S = "${WORKDIR}/zd1211-driver-${PV}" - -inherit module - -do_compile () { - unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS CC LD CPP - oe_runmake 'MODPATH=${D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net' \ - 'KERNEL_SOURCE=${STAGING_KERNEL_DIR}' \ - 'KDIR=${STAGING_KERNEL_DIR}' \ - 'KERNEL_VERSION=${KERNEL_VERSION}' \ - 'CC=${KERNEL_CC}' \ - 'LD=${KERNEL_LD}' -} - -do_install() { - install -d ${D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net - install -m 0644 ${S}/zd1211*${KERNEL_OBJECT_SUFFIX} ${D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net -} -- cgit v1.2.3 From cb5dffee80ac91dea81e10d42727269a73d186b1 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Sat, 2 Sep 2006 18:20:49 +0000 Subject: samba: Move MAINTAINER/LICENCE to .inc --- packages/samba/samba.inc | 1 + packages/samba/samba_3.0.23c.bb | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/samba/samba.inc b/packages/samba/samba.inc index 1f38f131e2..b5995c1b2e 100644 --- a/packages/samba/samba.inc +++ b/packages/samba/samba.inc @@ -1,6 +1,7 @@ SECTION = "console/network" DEPENDS = readline LICENSE = "GPL" +MAINTAINER = "Oyvind Repvik " PACKAGES =+ "libsmbclient libsmbclient-dev cifs cifs-doc" FILES_cifs = "${bindir}/mount.cifs" diff --git a/packages/samba/samba_3.0.23c.bb b/packages/samba/samba_3.0.23c.bb index e129b241b3..4425449345 100644 --- a/packages/samba/samba_3.0.23c.bb +++ b/packages/samba/samba_3.0.23c.bb @@ -1,5 +1,3 @@ -LICENCE="GPL-2" -MAINTAINER="Oyvind Repvik " PR = "r0" SRC_URI = "http://us2.samba.org/samba/ftp/stable/samba-${PV}.tar.gz \ -- cgit v1.2.3 From fb5cfbd9b510692852e9276d0ee99039338d66cf Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Sat, 2 Sep 2006 18:37:49 +0000 Subject: initscripts-slugos: Fix S06alignment link removal --- packages/initscripts/initscripts-slugos_1.0.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/initscripts/initscripts-slugos_1.0.bb b/packages/initscripts/initscripts-slugos_1.0.bb index f64e11dfe4..4fb6926490 100644 --- a/packages/initscripts/initscripts-slugos_1.0.bb +++ b/packages/initscripts/initscripts-slugos_1.0.bb @@ -11,7 +11,7 @@ RCONFLICTS = "initscripts" # All other standard definitions inherited from initscripts # Except the PR which is hacked here. The format used is # a suffix -PR := "${PR}.10" +PR := "${PR}.11" FILESPATH = "${@base_set_filespath([ '${FILE_DIRNAME}/${P}', '${FILE_DIRNAME}/initscripts-${PV}', '${FILE_DIRNAME}/files', '${FILE_DIRNAME}' ], d)}" @@ -64,7 +64,7 @@ do_install_append() { # udev will run at S04 if installed rm ${D}${sysconfdir}/rcS.d/S03sysfs rm ${D}${sysconfdir}/rcS.d/S38devpts.sh - rm ${D}${sysconfdir}/rcS.d/S06alignment + rm -f ${D}${sysconfdir}/rcS.d/S06alignment rm ${D}${sysconfdir}/rcS.d/S37populate-volatile.sh rm ${D}${sysconfdir}/rc0.d/S25save-rtc.sh rm ${D}${sysconfdir}/rc6.d/S25save-rtc.sh -- cgit v1.2.3 From 99b80b8615c8e5662827252cf6cb7fc12144f8c2 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sat, 2 Sep 2006 18:44:19 +0000 Subject: qemu-native: Create qemu-native.bbclass so all versions have the gcc 3.x detection code --- packages/qemu/qemu-native.inc | 13 +++++++++++++ packages/qemu/qemu-native_0.7.0.bb | 3 +-- packages/qemu/qemu-native_0.8.0.bb | 3 +-- packages/qemu/qemu-native_0.8.1.bb | 2 +- packages/qemu/qemu-native_0.8.2.bb | 3 +-- packages/qemu/qemu-native_cvs.bb | 13 +------------ 6 files changed, 18 insertions(+), 19 deletions(-) create mode 100644 packages/qemu/qemu-native.inc diff --git a/packages/qemu/qemu-native.inc b/packages/qemu/qemu-native.inc new file mode 100644 index 0000000000..049aa675f8 --- /dev/null +++ b/packages/qemu/qemu-native.inc @@ -0,0 +1,13 @@ +FILESPATH =. "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/qemu-${PV}:" +prefix = "${STAGING_DIR}/${BUILD_SYS}" + +python __anonymous() { + from bb import which, data + + path = data.getVar('PATH', d) + if len(which(path, 'gcc-3.4')) != 0: + data.setVar('EXTRA_OECONF', " --cc=gcc-3.4", d) + elif len(which(path, 'gcc-3.3')) != 0: + data.setVar('EXTRA_OECONF', " --cc=gcc-3.3", d) + +} diff --git a/packages/qemu/qemu-native_0.7.0.bb b/packages/qemu/qemu-native_0.7.0.bb index acb5543a90..bad8bd7bf4 100644 --- a/packages/qemu/qemu-native_0.7.0.bb +++ b/packages/qemu/qemu-native_0.7.0.bb @@ -1,5 +1,4 @@ require qemu_${PV}.bb inherit native S = "${WORKDIR}/qemu-${PV}" -prefix = "${STAGING_DIR}/${BUILD_SYS}" - +require qemu-native.inc diff --git a/packages/qemu/qemu-native_0.8.0.bb b/packages/qemu/qemu-native_0.8.0.bb index 2b143bdc0f..9613f7d614 100644 --- a/packages/qemu/qemu-native_0.8.0.bb +++ b/packages/qemu/qemu-native_0.8.0.bb @@ -1,6 +1,5 @@ require qemu_${PV}.bb inherit native -FILESPATH =. "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/qemu-${PV}:" +require qemu-native.inc S = "${WORKDIR}/qemu-${PV}" -prefix = "${STAGING_DIR}/${BUILD_SYS}" diff --git a/packages/qemu/qemu-native_0.8.1.bb b/packages/qemu/qemu-native_0.8.1.bb index acb5543a90..9613f7d614 100644 --- a/packages/qemu/qemu-native_0.8.1.bb +++ b/packages/qemu/qemu-native_0.8.1.bb @@ -1,5 +1,5 @@ require qemu_${PV}.bb inherit native +require qemu-native.inc S = "${WORKDIR}/qemu-${PV}" -prefix = "${STAGING_DIR}/${BUILD_SYS}" diff --git a/packages/qemu/qemu-native_0.8.2.bb b/packages/qemu/qemu-native_0.8.2.bb index e064723e4e..c0b1cd4ee3 100644 --- a/packages/qemu/qemu-native_0.8.2.bb +++ b/packages/qemu/qemu-native_0.8.2.bb @@ -1,7 +1,6 @@ require qemu_${PV}.bb EXTRA_OECONF = "" inherit native -FILESPATH =. "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/qemu-${PV}:" +require qemu-native.inc S = "${WORKDIR}/qemu-${PV}" -prefix = "${STAGING_DIR}/${BUILD_SYS}" diff --git a/packages/qemu/qemu-native_cvs.bb b/packages/qemu/qemu-native_cvs.bb index 49d6c17b64..639f9a6a7c 100644 --- a/packages/qemu/qemu-native_cvs.bb +++ b/packages/qemu/qemu-native_cvs.bb @@ -1,14 +1,3 @@ require qemu_cvs.bb inherit native -prefix = "${STAGING_DIR}/${BUILD_SYS}" - -python __anonymous() { - from bb import which, data - - path = data.getVar('PATH', d) - if len(which(path, 'gcc-3.4')) != 0: - data.setVar('EXTRA_OECONF', " --cc=gcc-3.4", d) - elif len(which(path, 'gcc-3.3')) != 0: - data.setVar('EXTRA_OECONF', " --cc=gcc-3.3", d) - -} +require qemu-native.inc -- cgit v1.2.3 From 9a18fe9bb13d36dd189043cb9b4467596e78c5a2 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Sat, 2 Sep 2006 20:41:04 +0000 Subject: lcdproc: Split off driver packages (large). Change MAINTAINER --- packages/lcdproc/lcdproc_0.5.0.bb | 65 +++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/packages/lcdproc/lcdproc_0.5.0.bb b/packages/lcdproc/lcdproc_0.5.0.bb index 4d933fc064..c5ac8a2ddb 100644 --- a/packages/lcdproc/lcdproc_0.5.0.bb +++ b/packages/lcdproc/lcdproc_0.5.0.bb @@ -3,36 +3,89 @@ shipped with this package can be used to acquire various kinds of system stats." HOMEPAGE = "http://lcdproc.org" LICENSE = "GPL" PRIORITY = "optional" -MAINTAINER = "Rene Wagner " +MAINTAINER = "Oyvind Repvik " SECTION = "utils" +PR="r1" -DEPENDS = "${@((bb.data.getVar('LCDPROC_DRIVERS',d) or 'all').find('curses') != -1) and 'ncurses' or ''}" +DEPENDS = "libusb ncurses" RRECOMMENDS_lcdproc = "lcdd" SRC_URI = "${SOURCEFORGE_MIRROR}/lcdproc/lcdproc-${PV}.tar.gz" inherit autotools update-rc.d -PACKAGES =+ "lcdd" +PACKAGES =+ "lcdd lcdd-driver-cfontz lcdd-driver-bayrad lcdd-driver-hd44780nousb \ + lcdd-driver-hd44780 lcdd-driver-mtxorb lcdd-driver-serialvfd \ + lcdd-driver-curses lcdd-driver-text \ + lcdd-driver-sed lcdd-driver-cwlnx lcdd-driver-glk lcdd-driver-icp-a106 \ + lcdd-driver-imon lcdd-driver-joy lcdd-driver-lb216 lcdd-driver-lcdm001 \ + lcdd-driver-lcterm lcdd-driver-ms6931 lcdd-driver-mtc-s16209x \ + lcdd-driver-noritakevfd lcdd-driver-pyramid lcdd-driver-sli \ + lcdd-driver-stv5730 lcdd-driver-t6963 lcdd-driver-tyan" CONFFILES_lcdd = "${sysconfdir}/LCDd.conf" CONFFILES_lcdproc = "${sysconfdir}/lcdproc.conf" FILES_lcdd = "${CONFFILES_lcdd} \ ${sbindir}/LCDd \ - ${sysconfdir}/init.d/lcdd \ - ${libdir}/lcdproc/" + ${sysconfdir}/init.d/lcdd" + FILES_lcdproc = "${CONFFILES_lcdproc} \ ${bindir}/lcdproc \ ${sysconfdir}/init.d/lcdproc" +# Driver packages + +FILES_lcdd-driver-cfontz = "${libdir}/lcdproc/CFontz*.so" +FILES_lcdd-driver-bayrad = "${libdir}/lcdproc/bayrad.so" +FILES_lcdd-driver-hd44780nousb = "${libdir}/lcdproc/hd44780nousb.so" +FILES_lcdd-driver-hd44780 = "${libdir}/lcdproc/hd44780.so" +FILES_lcdd-driver-mtxorb = "${libdir}/lcdproc/MtxOrb.so" +FILES_lcdd-driver-serialvfd = "${libdir}/lcdproc/serialVFD.so" +FILES_lcdd-driver-curses = "${libdir}/lcdproc/curses.so" +FILES_lcdd-driver-text = "${libdir}/lcdproc/text.so" +FILES_lcdd-driver-sed = "${libdir}/lcdproc/sed*.so" +FILES_lcdd-driver-cwlnx = "${libdir}/lcdproc/CwLnx.so" +FILES_lcdd-driver-glk = "${libdir}/lcdproc/glk.so" +FILES_lcdd-driver-icp-a106 = "${libdir}/lcdproc/icp_a106.so" +FILES_lcdd-driver-imon = "${libdir}/lcdproc/imon.so" +FILES_lcdd-driver-joy = "${libdir}/lcdproc/joy.so" +FILES_lcdd-driver-lb216 = "${libdir}/lcdproc/lb216.so" +FILES_lcdd-driver-lcdm001 = "${libdir}/lcdproc/lcdm001.so" +FILES_lcdd-driver-lcterm = "${libdir}/lcdproc/lcterm.so" +FILES_lcdd-driver-ms6931 = "${libdir}/lcdproc/ms6931.so" +FILES_lcdd-driver-mtc-s16209x = "${libdir}/lcdproc/mtc_s16209x.so" +FILES_lcdd-driver-noritakevfd = "${libdir}/lcdproc/NoritakeVFD.so" +FILES_lcdd-driver-pyramid = "${libdir}/lcdproc/pyramid.so" +FILES_lcdd-driver-sli = "${libdir}/lcdproc/sli.so" +FILES_lcdd-driver-stv5730 = "${libdir}/lcdproc/stv5730.so" +FILES_lcdd-driver-t6963 = "${libdir}/lcdproc/t6963.so" +FILES_lcdd-driver-tyan = "${libdir}/lcdproc/tyan.so" + + +# Install-all-drivers-hack: + +DEPENDS_lcdd-driver-all = "lcdd-driver-cfontz lcdd-driver-bayrad lcdd-driver-hd44780nousb \ + lcdd-driver-hd44780 lcdd-driver-mtxorb lcdd-driver-serialvfd \ + lcdd-driver-curses lcdd-driver-text \ + lcdd-driver-sed lcdd-driver-cwlnx lcdd-driver-glk lcdd-driver-icp-a106 \ + lcdd-driver-imon lcdd-driver-joy lcdd-driver-lb216 lcdd-driver-lcdm001 \ + lcdd-driver-lcterm lcdd-driver-ms6931 lcdd-driver-mtc-s16209x \ + lcdd-driver-noritakevfd lcdd-driver-pyramid lcdd-driver-sli \ + lcdd-driver-stv5730 lcdd-driver-t6963 lcdd-driver-tyan" + +# USB / no USB trickery + +CONFLICTS_lcdd-driver-hd47780nousb = "lcdd-driver-hd44780" +CONFLICTS_lcdd-driver-hd47780 = "lcdd-driver-hd44780nousb" + INITSCRIPT_PACKAGES = "lcdd lcdproc" INITSCRIPT_NAME_lcdd = "lcdd" INITSCRIPT_NAME_lcdproc = "lcdproc" INITSCRIPT_PARAMS_lcdd = "defaults 70 21" INITSCRIPT_PARAMS_lcdproc = "defaults 71 20" -EXTRA_OECONF = "${@'--enable-drivers=' + (bb.data.getVar('LCDPROC_DRIVERS',d) or 'all')}" +EXTRA_OECONF = "--enable-drivers=all" do_install () { # binaries -- cgit v1.2.3 From 64610d0e500cafc177e74555ea38ecdc3ede5a17 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Sat, 2 Sep 2006 20:42:55 +0000 Subject: lcdproc: Add forgotten --enable-libusb --- packages/lcdproc/lcdproc_0.5.0.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/lcdproc/lcdproc_0.5.0.bb b/packages/lcdproc/lcdproc_0.5.0.bb index c5ac8a2ddb..8c7c53d17b 100644 --- a/packages/lcdproc/lcdproc_0.5.0.bb +++ b/packages/lcdproc/lcdproc_0.5.0.bb @@ -5,7 +5,7 @@ LICENSE = "GPL" PRIORITY = "optional" MAINTAINER = "Oyvind Repvik " SECTION = "utils" -PR="r1" +PR="r2" DEPENDS = "libusb ncurses" RRECOMMENDS_lcdproc = "lcdd" @@ -85,7 +85,7 @@ INITSCRIPT_NAME_lcdproc = "lcdproc" INITSCRIPT_PARAMS_lcdd = "defaults 70 21" INITSCRIPT_PARAMS_lcdproc = "defaults 71 20" -EXTRA_OECONF = "--enable-drivers=all" +EXTRA_OECONF = "--enable-drivers=all --enable-libusb" do_install () { # binaries -- cgit v1.2.3 From c489f4ed0a4776ecae5f852baf159ca0750d3f3d Mon Sep 17 00:00:00 2001 From: Mike Westerhof Date: Sun, 3 Sep 2006 02:11:15 +0000 Subject: DSM-G600A support added (Artop IDE and Via velocity patches) --- packages/linux/ixp4xx-kernel_2.6.17.bb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/linux/ixp4xx-kernel_2.6.17.bb b/packages/linux/ixp4xx-kernel_2.6.17.bb index b08129799a..c27f73330b 100644 --- a/packages/linux/ixp4xx-kernel_2.6.17.bb +++ b/packages/linux/ixp4xx-kernel_2.6.17.bb @@ -3,12 +3,12 @@ # Increment PR_CONFIG for changes to the ixp4xx-kernel specific # defconfig (do *NOT* increment anything in here for changes # to other kernel configs!) -PR_CONFIG = "3" +PR_CONFIG = "4" # # Increment the number below (i.e. the digits after PR) when # making changes within this file or for changes to the patches # applied to the kernel. -PR = "r2.${PR_CONFIG}" +PR = "r3.${PR_CONFIG}" require ixp4xx-kernel.inc @@ -20,6 +20,7 @@ IXP4XX_PATCHES = "" SVN_SRC = "http://svn.nslu2-linux.org/svnroot/kernel/trunk/patches/2.6.17" # IXP4XX_PATCHES += "file://06-remove-extraversion.patch;patch=1" +IXP4XX_PATCHES += "${SVN_SRC}/patch-2.6.17-ide1;patch=1" IXP4XX_PATCHES += "${SVN_SRC}/01-nas100d-leds.patch;patch=1" IXP4XX_PATCHES += "${SVN_SRC}/02-nas100d-mac-addr.patch;patch=1" IXP4XX_PATCHES += "${SVN_SRC}/03-nslu2-leds.patch;patch=1" @@ -33,3 +34,5 @@ IXP4XX_PATCHES += "${SVN_SRC}/20-nslu2-cmdline-fixup.patch;patch=1" IXP4XX_PATCHES += "${SVN_SRC}/50-leds-arm-cpu-activity.patch;patch=1" IXP4XX_PATCHES += "${SVN_SRC}/75-dsmg600.patch;patch=1" IXP4XX_PATCHES += "${SVN_SRC}/76-dsmg600-pwrbtn.patch;patch=1" +IXP4XX_PATCHES += "${SVN_SRC}/77-velocity-module.patch;patch=1" +IXP4XX_PATCHES += "${SVN_SRC}/78-velocity-BE.patch;patch=1" -- cgit v1.2.3 From b834da52b954c6c48a5fdf6f46b22b7d54a4afdc Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sun, 3 Sep 2006 13:32:14 +0000 Subject: cairo 1.2.4: Drop broken patch pending a rethink --- packages/cairo/cairo_1.2.4.bb | 3 +-- packages/cairo/files/cairo-fixed.patch | 43 ---------------------------------- 2 files changed, 1 insertion(+), 45 deletions(-) delete mode 100644 packages/cairo/files/cairo-fixed.patch diff --git a/packages/cairo/cairo_1.2.4.bb b/packages/cairo/cairo_1.2.4.bb index 662f685fb9..9f8425c03f 100644 --- a/packages/cairo/cairo_1.2.4.bb +++ b/packages/cairo/cairo_1.2.4.bb @@ -6,8 +6,7 @@ DESCRIPTION = "Cairo graphics library" LICENSE = "MPL LGPL" PR = "r1" -SRC_URI = "http://cairographics.org/releases/cairo-${PV}.tar.gz \ - file://cairo-fixed.patch;patch=1" +SRC_URI = "http://cairographics.org/releases/cairo-${PV}.tar.gz" inherit autotools pkgconfig diff --git a/packages/cairo/files/cairo-fixed.patch b/packages/cairo/files/cairo-fixed.patch deleted file mode 100644 index 8df54d9cb5..0000000000 --- a/packages/cairo/files/cairo-fixed.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff -ur cairo-1.2.4/src/cairo-fixed.c cairo-1.2.4-new/src/cairo-fixed.c ---- cairo-1.2.4/src/cairo-fixed.c 2006-06-10 07:07:37.000000000 +0300 -+++ cairo-1.2.4-new/src/cairo-fixed.c 2006-08-25 13:06:26.000000000 +0300 -@@ -43,12 +43,6 @@ - } - - cairo_fixed_t --_cairo_fixed_from_double (double d) --{ -- return (cairo_fixed_t) floor (d * 65536 + 0.5); --} -- --cairo_fixed_t - _cairo_fixed_from_26_6 (uint32_t i) - { - return i << 10; -diff -ur cairo-1.2.4/src/cairoint.h cairo-1.2.4-new/src/cairoint.h ---- cairo-1.2.4/src/cairoint.h 2006-08-18 17:20:16.000000000 +0300 -+++ cairo-1.2.4-new/src/cairoint.h 2006-08-25 13:14:07.000000000 +0300 -@@ -1117,8 +1117,21 @@ - - #define CAIRO_FIXED_ONE _cairo_fixed_from_int (1) - --cairo_private cairo_fixed_t --_cairo_fixed_from_double (double d); -+#define CAIRO_DOUBLE2FIX_MAGIC 103079215104.0 /* 2 ^ (52 - 16) * 1.5 */ -+ -+#ifdef WORDS_BIGENDIAN -+#define iman 1 -+#else -+#define iman 0 -+#endif -+ -+static inline cairo_fixed_t -+_cairo_fixed_from_double (double d) -+{ -+ d = d + CAIRO_DOUBLE2FIX_MAGIC; -+ -+ return ((cairo_fixed_t *) &d)[iman]; -+} - - cairo_private cairo_fixed_t - _cairo_fixed_from_26_6 (uint32_t i); -- cgit v1.2.3 From 4a7d637ba7ff97733a37d50927475c75c86f6e43 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 3 Sep 2006 13:56:02 +0000 Subject: networkmanager: RDEPEND on iproute2 --- packages/networkmanager/networkmanager_0.6.4.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/networkmanager/networkmanager_0.6.4.bb b/packages/networkmanager/networkmanager_0.6.4.bb index e9c02ba3dd..80a88d384e 100644 --- a/packages/networkmanager/networkmanager_0.6.4.bb +++ b/packages/networkmanager/networkmanager_0.6.4.bb @@ -5,9 +5,9 @@ HOMEPAGE = "http://www.gnome.org" MAINTAINER = "Milan Plzik " PRIORITY = "optional" DEPENDS = "libnl dbus dbus-glib libhal-nm libgpewidget gnome-keyring gconf-dbus wireless-tools libglade" -RDEPENDS = "wpa-supplicant dhcdbd gnome-keyring hicolor-icon-theme" +RDEPENDS = "wpa-supplicant iproute2 dhcdbd gnome-keyring hicolor-icon-theme" -PR = "r1" +PR = "r2" SRC_URI="http://www.handhelds.org/~mmp/files/NetworkManager-${PV}-gpe.tar.gz \ file://dbus-api-fix.patch;patch=1 \ -- cgit v1.2.3 From d5920d9869e2c5d3ef23242537b09664b2144bfc Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sun, 3 Sep 2006 19:11:46 +0000 Subject: libsndfile: slightly improve packaging --- packages/libsndfile/libsndfile1_1.0.16.bb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/libsndfile/libsndfile1_1.0.16.bb b/packages/libsndfile/libsndfile1_1.0.16.bb index e103b6636f..fb3ed30f38 100644 --- a/packages/libsndfile/libsndfile1_1.0.16.bb +++ b/packages/libsndfile/libsndfile1_1.0.16.bb @@ -4,7 +4,7 @@ AUTHOR = "Erik de Castro Lopo" MAINTAINER = "Michael 'Mickey' Lauer " SECTION = "libs/multimedia" LICENSE = "LGPL" -PR = "r0" +PR = "r1" SRC_URI = "http://www.mega-nerd.com/libsndfile/libsndfile-${PV}.tar.gz" S = "${WORKDIR}/libsndfile-${PV}" @@ -17,5 +17,4 @@ do_stage() { } #FIXME package the rest -PACKAGES = "${PN}" FILES_${PN} = "${libdir}/libsndfile.so*" -- cgit v1.2.3 From 7bca1f212429a1ec73847091de287afdae90dbb6 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Sun, 3 Sep 2006 19:13:45 +0000 Subject: libpcap: remove 0.7.2 and 0.8.3 --- packages/libpcap/libpcap-0.7.2/.mtn2git_empty | 0 packages/libpcap/libpcap-0.7.2/configure.patch | 43 -- packages/libpcap/libpcap-0.7.2/ldflags.patch | 27 -- .../libpcap/libpcap-0.7.2/libpcap-shared.patch | 526 --------------------- packages/libpcap/libpcap-0.8.3/.mtn2git_empty | 0 packages/libpcap/libpcap-0.8.3/shared.patch | 118 ----- packages/libpcap/libpcap_0.7.2.bb | 30 -- packages/libpcap/libpcap_0.8.3.bb | 30 -- 8 files changed, 774 deletions(-) delete mode 100644 packages/libpcap/libpcap-0.7.2/.mtn2git_empty delete mode 100644 packages/libpcap/libpcap-0.7.2/configure.patch delete mode 100644 packages/libpcap/libpcap-0.7.2/ldflags.patch delete mode 100644 packages/libpcap/libpcap-0.7.2/libpcap-shared.patch delete mode 100644 packages/libpcap/libpcap-0.8.3/.mtn2git_empty delete mode 100644 packages/libpcap/libpcap-0.8.3/shared.patch delete mode 100644 packages/libpcap/libpcap_0.7.2.bb delete mode 100644 packages/libpcap/libpcap_0.8.3.bb diff --git a/packages/libpcap/libpcap-0.7.2/.mtn2git_empty b/packages/libpcap/libpcap-0.7.2/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/libpcap/libpcap-0.7.2/configure.patch b/packages/libpcap/libpcap-0.7.2/configure.patch deleted file mode 100644 index d9275b561b..0000000000 --- a/packages/libpcap/libpcap-0.7.2/configure.patch +++ /dev/null @@ -1,43 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- libpcap-0.7.2/./configure.in~configure -+++ libpcap-0.7.2/./configure.in -@@ -7,9 +7,10 @@ - dnl - - AC_REVISION($Revision: 1.94.2.1 $) --AC_INIT(pcap.c) -+AC_INIT -+AC_CONFIG_SRCDIR([pcap.c]) - --AC_CANONICAL_SYSTEM -+AC_CANONICAL_TARGET([]) - - AC_LBL_C_INIT(V_CCOPT, V_INCLS) - AC_LBL_C_INLINE -@@ -210,11 +211,7 @@ - sinix*) - AC_MSG_CHECKING(if SINIX compiler defines sinix) - AC_CACHE_VAL(ac_cv_cc_sinix_defined, -- AC_TRY_COMPILE( -- [], -- [int i = sinix;], -- ac_cv_cc_sinix_defined=yes, -- ac_cv_cc_sinix_defined=no)) -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[int i = sinix;]])],[ac_cv_cc_sinix_defined=yes],[ac_cv_cc_sinix_defined=no])) - AC_MSG_RESULT($ac_cv_cc_sinix_defined) - if test $ac_cv_cc_sinix_defined = no ; then - AC_DEFINE(sinix,1,[on sinix]) -@@ -250,7 +247,8 @@ - - AC_CONFIG_HEADER(config.h) - --AC_OUTPUT(Makefile) -+AC_CONFIG_FILES([Makefile]) -+AC_OUTPUT - - if test -f .devel ; then - make depend diff --git a/packages/libpcap/libpcap-0.7.2/ldflags.patch b/packages/libpcap/libpcap-0.7.2/ldflags.patch deleted file mode 100644 index 8802a7e073..0000000000 --- a/packages/libpcap/libpcap-0.7.2/ldflags.patch +++ /dev/null @@ -1,27 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- libpcap-0.7.2/Makefile.in~ldflags -+++ libpcap-0.7.2/Makefile.in -@@ -59,6 +59,10 @@ - CFLAGS = $(CCOPT) $(INCLS) $(DEFS) - CFLAGS_SHARED = -shared -Wl,-soname,$(SOLIBRARY).$(MAJ) - -+# Standard LDFLAGS -+LDFLAGS = @LDFLAGS@ -+LIBS = -lc -+ - INSTALL = @INSTALL@ - INSTALL_PROGRAM = @INSTALL_PROGRAM@ - INSTALL_DATA = @INSTALL_DATA@ -@@ -118,7 +122,7 @@ - $(SHAREDLIB): $(OBJ_PIC) - -@rm -f $@ - -@rm -f $(SOLIBRARY) $(SOLIBRARY).$(MAJ) -- $(CC) $(CFLAGS_SHARED) -o $(SHAREDLIB) $(OBJ_PIC) -lc -+ $(CC) $(CFLAGS_SHARED) -o $(SHAREDLIB) $(OBJ_PIC) $(LIBS) $(LDFLAGS) - ln -s $(SHAREDLIB) $(SOLIBRARY).$(MAJ) - ln -s $(SOLIBRARY).$(MAJ) $(SOLIBRARY) - diff --git a/packages/libpcap/libpcap-0.7.2/libpcap-shared.patch b/packages/libpcap/libpcap-0.7.2/libpcap-shared.patch deleted file mode 100644 index 18b0250c16..0000000000 --- a/packages/libpcap/libpcap-0.7.2/libpcap-shared.patch +++ /dev/null @@ -1,526 +0,0 @@ ---- libpcap-0.7.2.orig/nametoaddr.c -+++ libpcap-0.7.2/nametoaddr.c -@@ -310,7 +310,7 @@ - e = ep = (u_char *)malloc(6); - - while (*s) { -- if (*s == ':') -+ if (*s == ':' || *s == '.') - s += 1; - d = xdtoi(*s++); - if (isxdigit((unsigned char)*s)) { ---- libpcap-0.7.2.orig/debian/libpcap0.postinst -+++ libpcap-0.7.2/debian/libpcap0.postinst -@@ -0,0 +1,7 @@ -+#! /bin/sh -+ -+if [ "$1" = "configure" ]; then -+ ldconfig -+fi -+ -+#DEBHELPER# ---- libpcap-0.7.2.orig/debian/copyright -+++ libpcap-0.7.2/debian/copyright -@@ -0,0 +1,37 @@ -+This package was debianized by Anand Kumria on -+Sun, 12 Nov 2000 03:19:44 +1100. -+ -+It was downloaded from http://www.tcpdump.org/ -+ -+Upstream Author(s): patches@tcpdump.org -+ -+Copyright: -+ -+The licence-style of this software is BSD. However this version (0.5) -+fails to include a file containing the licence. A similar version -+of the licence is available in /usr/share/common-licenses/BSD. -+Future versions of libpcap will contain the licence located at -+ -+which is what I describe below. -+ -+The differences are: -+ - Item 3, replace "University" with "Authors" -+ - The LEGALESE (uppercase portion) ends after -+ the words "A PARTICULAR PURPOSE" -+ - The copyright holders are listed below (the CREDITS -+ file is canonical, this is merely a convienent listing) -+ -+people who contributed to libpcap or tcpdump: -+ Bill Fenner -+ Assar Westerlund -+ Alexei -+ Jun-ichiro itojun Hagino -+ Guy Harris -+ Torsten Landschoff -+ Michael Richardson -+ -+The original LBL crew: -+ Steve McCanne -+ Craig Leres -+ Van Jacobson -+ ---- libpcap-0.7.2.orig/debian/libpcap0.postrm -+++ libpcap-0.7.2/debian/libpcap0.postrm -@@ -0,0 +1,7 @@ -+#! /bin/sh -+ -+if [ "$1" = "remove" ]; then -+ ldconfig -+fi -+ -+#DEBHELPER# ---- libpcap-0.7.2.orig/debian/libpcap-dev.dirs -+++ libpcap-0.7.2/debian/libpcap-dev.dirs -@@ -0,0 +1,4 @@ -+usr/lib -+usr/include -+usr/include/net -+usr/share/man/man3 ---- libpcap-0.7.2.orig/debian/README.Debian -+++ libpcap-0.7.2/debian/README.Debian -@@ -0,0 +1,13 @@ -+libpcap for Debian -+------------------ -+ -+ If you receive messages telling you the packet type is not supported -+ or is deprecated check that CONFIG_PACKET is set to either `Y' or `M'. -+ -+ You should also check that /etc/modules.conf has the line -+ -+ alias net-pf-17 af_packet -+ -+ Feel free to report bugs. -+ -+ -- Anand Kumria , Tue, 28 Nov 2000 02:04:28 EST ---- libpcap-0.7.2.orig/debian/libpcap0.docs -+++ libpcap-0.7.2/debian/libpcap0.docs -@@ -0,0 +1,2 @@ -+README -+CREDITS ---- libpcap-0.7.2.orig/debian/libpcap0.7.postinst -+++ libpcap-0.7.2/debian/libpcap0.7.postinst -@@ -0,0 +1,8 @@ -+#! /bin/sh -+ -+if [ "$1" = "configure" ]; then -+ ldconfig -+fi -+ -+#DEBHELPER# -+ ---- libpcap-0.7.2.orig/debian/libpcap0.7.postrm -+++ libpcap-0.7.2/debian/libpcap0.7.postrm -@@ -0,0 +1,8 @@ -+#! /bin/sh -+ -+if [ "$1" = "remove" ]; then -+ ldconfig -+fi -+ -+#DEBHELPER# -+ ---- libpcap-0.7.2.orig/debian/changelog -+++ libpcap-0.7.2/debian/changelog -@@ -0,0 +1,135 @@ -+libpcap (0.7.2-1) unstable; urgency=low -+ -+ * New upstream release (closes: #145538). -+ * debian/rules: Build the library with _FILE_OFFSET_BITS set to 64 -+ to allow for files bigger than 2GB (closes: #129213). -+ * Rename the library package to libpcap0.7 and change the SONAME so that we -+ can account for interface changes (closes: #132359). -+ * Run ldconfig as appropriate (lintian). -+ * Remove watch.ex template and the silly symlink from libpcap-dev's -+ documentation to libpcap0 (lintian). -+ -+ -- Torsten Landschoff Sat, 3 Aug 2002 23:33:56 +0200 -+ -+libpcap (0.6.2-2) unstable; urgency=low -+ -+ * debian/control: Change section of libpcap0 from net to libs -+ (Debian installer message). -+ * aclocal.m4: Treat the ia64 as a cpu which can't handle unaligned -+ memory access (closes: #112152). Thanks for the report go to -+ John R. Daily. -+ -+ -- Torsten Landschoff Fri, 14 Sep 2001 10:15:52 +0200 -+ -+libpcap (0.6.2-1) unstable; urgency=medium -+ -+ * New upstream release. -+ * debian/control: Removed Build-Depends already satisfied by the -+ build-essential package. -+ * gencode.c (gen_scode): Add the missing default branch of the protocol -+ family switch (closes: 88688). -+ * debian/libpcap.post{rm,inst}: Run ldconfig (lintian). -+ * debian/copyright: Fix the "similiar" typo (lintian). -+ -+ -- Torsten Landschoff Tue, 6 Mar 2001 04:27:27 +0100 -+ -+libpcap (0.6.1-2) unstable; urgency=low -+ -+ * debian/rules: Changed the shlibs info so that only pcap 0.6 -+ is okay for packages linked against this version. -+ -+ -- Torsten Landschoff Thu, 18 Jan 2001 01:13:20 +0100 -+ -+libpcap (0.6.1-1) unstable; urgency=low -+ -+ * Taking back the package. Kudos to Anand for helping out. -+ * debian/rules: Pass --enable-ipv6 to configure (closes: #80223). -+ -+ -- Torsten Landschoff Tue, 16 Jan 2001 15:40:37 +0100 -+ -+libpcap (0.5.2-2) unstable; urgency=low -+ -+ * Update config.guess and config.sub (Closes #26031) -+ * Source builds would not always work. Fix that. -+ * Kernel interface problem is really a module not loaded problem. -+ Note this in README.Debian. (Closes #21356) -+ -+ -- Anand Kumria Tue, 28 Nov 2000 02:03:25 +1100 -+ -+libpcap (0.5.2-1) unstable; urgency=low -+ -+ * New upstream release -+ * New maintainer -+ * Migrate to Debhelper and insert Build-Depends -+ -+ -- Anand Kumria Sun, 12 Nov 2000 03:19:44 +1100 -+ -+libpcap (0.4a6-3) unstable; urgency=low -+ -+ * New maintainer. -+ * scanner.l: Allow a 12 digit hex number as ether address as well as -+ BB.BB.BB.BB.BB.BB (closes: #48735) -+ * nametoaddr.c (pcap_ether_aton): Adjust for change in scanner.l -+ -+ -- Torsten Landschoff Mon, 22 Nov 1999 02:39:45 +0100 -+ -+libpcap (0.4a6-2.1) unstable; urgency=low -+ -+ * Non maintainer upload. -+ config.{guess,sub} changed to recognize a Arm architecture. -+ -+ -- Turbo Fredriksson Thu, 20 Aug 1998 23:12:36 -0400 -+ -+libpcap (0.4a6-2) frozen unstable; urgency=low -+ -+ * renamed /usr/doc/libpcap to /usr/doc/libpcap0 (should fix several -+ lintian warnings) -+ * updated standards-version -+ * rebuild with latest debmake -+ -+ -- Peter Tobias Mon, 30 Mar 1998 00:46:44 +0200 -+ -+ -+libpcap (0.4a6-1) unstable; urgency=low -+ -+ * upgraded to latest upstream version, fixes: Bug#17164 -+ * added patch from Michael Alan Dorman -+ for building libpcap on alpha systems, fixes: Bug#15556 -+ * fixed aclocal.m4 script -+ -+ -- Peter Tobias Sat, 31 Jan 1998 23:19:42 +0100 -+ -+ -+libpcap (0.4a2-2) unstable; urgency=low -+ -+ * fixed detection of IFF_LOOPBACK for linux systems -+ * link shared library with -l -+ -+ -- Peter Tobias Wed, 19 Nov 1997 23:44:34 +0100 -+ -+ -+libpcap (0.4a2-1) unstable; urgency=low -+ -+ * new maintainer -+ * latest upstream release -+ * libc6 version -+ * compiled with _REENTRANT -+ -+ -- Peter Tobias Wed, 17 Sep 1997 20:40:01 +0200 -+ -+ -+libpcap (0.3.1a3-1) unstable; urgency=low -+ -+ * Latest upstream release. Fixes bug #6670. -+ -+ -- Karl Sackett Wed, 2 Apr 1997 10:19:28 -0600 -+ -+ -+libpcap (0.3-1) unstable; urgency=low -+ -+ * First Debian release. -+ * Makefile.in: supports libpcap.so target. -+ -+ -- Karl Sackett Wed, 8 Jan 1997 09:38:31 -0600 -+ -+ ---- libpcap-0.7.2.orig/debian/rules -+++ libpcap-0.7.2/debian/rules -@@ -0,0 +1,87 @@ -+#!/usr/bin/make -f -+# Sample debian/rules that uses debhelper. -+# GNU copyright 1997 to 1999 by Joey Hess. -+ -+# Uncomment this to turn on verbose mode. -+#export DH_VERBOSE=1 -+ -+# This is the debhelper compatability version to use. -+export DH_COMPAT=2 -+ -+# shared library versions, option 1 -+version=0.7.2 -+major=0.7 -+# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so -+#version=`ls src/.libs/lib*.so.* | \ -+# awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'` -+#major=`ls src/.libs/lib*.so.* | \ -+# awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'` -+ -+build: build-stamp -+build-stamp: -+ dh_testdir -+ -+ CFLAGS=-D_FILE_OFFSET_BITS=64 ./configure --prefix=/usr --mandir=\$${prefix}/share/man \ -+ --enable-ipv6 --infodir=\$${prefix}/share/info -+ # Add here commands to compile the package. -+ $(MAKE) -+ -+ touch build-stamp -+ -+clean: -+ dh_testdir -+ dh_testroot -+ rm -f build-stamp -+ -+ # Add here commands to clean up after the build process. -+ -$(MAKE) distclean -+ -+ rm -f net/net -+ -+ dh_clean -+ -+install: build -+ dh_testdir -+ dh_testroot -+ dh_clean -k -+ dh_installdirs -+ -+ $(MAKE) install prefix=`pwd`/debian/libpcap-dev/usr -+ -+# Build architecture-independent files here. -+binary-indep: build install -+# We have nothing to do by default. -+ -+# Build architecture-dependent files here. -+binary-arch: build install -+# dh_testversion -+ dh_testdir -+ dh_testroot -+ # -+ # build libpcap${major} package by moving files from libpcap-dev -+ # -+ dh_movefiles -plibpcap$(major) --sourcedir=debian/libpcap-dev \ -+ usr/lib/libpcap.so.$(major) \ -+ usr/lib/libpcap.so.$(version) -+ -+# dh_installdebconf -+ dh_installdocs -+ dh_installexamples -+ dh_installmenu -+ dh_installmanpages -plibpcap-dev -+ dh_installinfo -+# dh_undocumented -+ dh_installchangelogs CHANGES -+ dh_link -plibpcap-dev -+ dh_strip -+ dh_compress -+ dh_fixperms -+ dh_makeshlibs -+ dh_installdeb -+ dh_shlibdeps -+ dh_gencontrol -+ dh_md5sums -+ dh_builddeb -+ -+binary: binary-indep binary-arch -+.PHONY: build clean binary-indep binary-arch binary install ---- libpcap-0.7.2.orig/debian/control -+++ libpcap-0.7.2/debian/control -@@ -0,0 +1,30 @@ -+Source: libpcap -+Section: devel -+Priority: optional -+Maintainer: Torsten Landschoff -+Build-Depends: debhelper, flex, bison -+Standards-Version: 3.0.1 -+ -+Package: libpcap-dev -+Section: devel -+Architecture: any -+Depends: libpcap0.7 (= ${Source-Version}), libc6-dev -+Description: Development library for libpcap. -+ Includes headers, static libraries, and documentation. -+ -+Package: libpcap0.7 -+Section: libs -+Architecture: any -+Depends: ${shlibs:Depends} -+Description: System interface for user-level packet capture. -+ libpcap (Packet CAPture) provides a portable framework for low-level -+ network monitoring. Applications include network statistics collection, -+ security monitoring, network debugging, etc. -+ . -+ Since almost every system vendor provides a different interface for -+ packet capture, and since there are several tools that require this -+ functionality, we've created this system-independent API to ease in -+ porting and to alleviate the need for several system-dependent packet -+ capture modules in each application. -+ . -+ Further information is available at ---- libpcap-0.7.2.orig/scanner.l -+++ libpcap-0.7.2/scanner.l -@@ -75,6 +75,7 @@ - N ([0-9]+|(0X|0x)[0-9A-Fa-f]+) - B ([0-9A-Fa-f][0-9A-Fa-f]?) - W ([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?) -+X [0-9A-Fa-f] - - %a 15000 - %o 17000 -@@ -261,7 +262,7 @@ - {N} { yylval.i = stoi((char *)yytext); return NUM; } - ({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) { - yylval.s = sdup((char *)yytext); return HID; } --{B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char *)yytext); -+({B}:{B}:{B}:{B}:{B}:{B})|({B}\.{B}\.{B}\.{B}\.{B}\.{B}) { yylval.e = pcap_ether_aton((char *)yytext); - return EID; } - {V6} { - #ifdef INET6 -@@ -279,6 +280,8 @@ - #endif /*INET6*/ - } - {B}:+({B}:+)+ { bpf_error("bogus ethernet address %s", yytext); } -+{X}{12} { yylval.e = pcap_ether_aton((char *)yytext); return EID;} -+ - icmptype { yylval.i = 0; return NUM; } - icmpcode { yylval.i = 1; return NUM; } - icmp-echoreply { yylval.i = 0; return NUM; } ---- libpcap-0.7.2.orig/Makefile.in -+++ libpcap-0.7.2/Makefile.in -@@ -37,6 +37,15 @@ - srcdir = @srcdir@ - VPATH = @srcdir@ - -+# some defines for shared library compilation - FIXME -+MAJ=0.7 -+MIN=2 -+VERSION=$(MAJ).$(MIN) -+LIBNAME=pcap -+LIBRARY=lib$(LIBNAME).a -+SOLIBRARY=lib$(LIBNAME).so -+SHAREDLIB=$(SOLIBRARY).$(VERSION) -+ - # - # You shouldn't need to edit anything below. - # -@@ -48,6 +57,7 @@ - - # Standard CFLAGS - CFLAGS = $(CCOPT) $(INCLS) $(DEFS) -+CFLAGS_SHARED = -shared -Wl,-soname,$(SOLIBRARY).$(MAJ) - - INSTALL = @INSTALL@ - INSTALL_PROGRAM = @INSTALL_PROGRAM@ -@@ -67,7 +77,11 @@ - # problem if you don't own the file but can write to the directory. - .c.o: - @rm -f $@ -- $(CC) $(CFLAGS) -c $(srcdir)/$*.c -+ $(CC) $(CFLAGS) -c -o $@ $(srcdir)/$*.c -+ -+%_pic.o: %.c -+ @rm -f $@ -+ $(CC) -fPIC $(CFLAGS) -c -o $@ $(srcdir)/$*.c - - PSRC = pcap-@V_PCAP@.c - CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c \ -@@ -80,6 +94,7 @@ - # We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot - # hack the extra indirection - OBJ = $(PSRC:.c=.o) $(CSRC:.c=.o) $(GENSRC:.c=.o) # $(LIBOBJS) -+OBJ_PIC = $(PSRC:.c=_pic.o) $(CSRC:.c=_pic.o) $(GENSRC:.c=_pic.o) - HDR = pcap.h pcap-int.h pcap-namedb.h pcap-nit.h pcap-pf.h \ - ethertype.h gencode.h gnuc.h - GENHDR = \ -@@ -91,15 +106,22 @@ - TAGFILES = \ - $(SRC) $(HDR) $(TAGHDR) - --CLEANFILES = $(OBJ) libpcap.a $(GENSRC) $(GENHDR) lex.yy.c -+CLEANFILES = $(OBJ) $(OBJ_PIC) libpcap.a $(GENSRC) $(GENHDR) lex.yy.c libpcap.so* - --all: libpcap.a -+all: libpcap.a $(SHAREDLIB) - - libpcap.a: $(OBJ) - @rm -f $@ - ar rc $@ $(OBJ) - $(RANLIB) $@ - -+$(SHAREDLIB): $(OBJ_PIC) -+ -@rm -f $@ -+ -@rm -f $(SOLIBRARY) $(SOLIBRARY).$(MAJ) -+ $(CC) $(CFLAGS_SHARED) -o $(SHAREDLIB) $(OBJ_PIC) -lc -+ ln -s $(SHAREDLIB) $(SOLIBRARY).$(MAJ) -+ ln -s $(SOLIBRARY).$(MAJ) $(SOLIBRARY) -+ - scanner.c: $(srcdir)/scanner.l - @rm -f $@ - $(LEX) -t $< > $$$$.$@; mv $$$$.$@ $@ -@@ -107,6 +129,9 @@ - scanner.o: scanner.c tokdefs.h - $(CC) $(CFLAGS) -c scanner.c - -+scanner_pic.o: scanner.c tokdefs.h -+ $(CC) -fPIC $(CFLAGS) -o $@ -c scanner.c -+ - tokdefs.h: grammar.c - grammar.c: $(srcdir)/grammar.y - @rm -f grammar.c tokdefs.h -@@ -118,9 +143,16 @@ - @rm -f $@ - $(CC) $(CFLAGS) -Dyylval=pcap_lval -c grammar.c - -+grammar_pic.o: grammar.c -+ @rm -f $@ -+ $(CC) -fPIC $(CFLAGS) -Dyylval=pcap_lval -o $@ -c grammar.c -+ - version.o: version.c - $(CC) $(CFLAGS) -c version.c - -+version_pic.o: version.c -+ $(CC) -fPIC $(CFLAGS) -c version.c -o $@ -+ - snprintf.o: $(srcdir)/../tcpdump/missing/snprintf.c - $(CC) $(CFLAGS) -o $@ -c $(srcdir)/../tcpdump/missing/snprintf.c - -@@ -135,10 +167,16 @@ - bpf_filter.o: bpf_filter.c - $(CC) $(CFLAGS) -c bpf_filter.c - -+bpf_filter_pic.o: bpf_filter.c -+ $(CC) -fPIC $(CFLAGS) -c bpf_filter.c -o $@ -+ - install: - [ -d $(DESTDIR)$(libdir) ] || \ - (mkdir -p $(DESTDIR)$(libdir); chmod 755 $(DESTDIR)$(libdir)) - $(INSTALL_DATA) libpcap.a $(DESTDIR)$(libdir)/libpcap.a -+ $(INSTALL_DATA) $(SHAREDLIB) $(DESTDIR)$(libdir)/ -+ ln -sf $(SHAREDLIB) $(DESTDIR)$(libdir)/$(SOLIBRARY).$(MAJ) -+ ln -sf $(SOLIBRARY).$(MAJ) $(DESTDIR)$(libdir)/$(SOLIBRARY) - $(RANLIB) $(DESTDIR)$(libdir)/libpcap.a - [ -d $(DESTDIR)$(includedir) ] || \ - (mkdir -p $(DESTDIR)$(includedir); chmod 755 $(DESTDIR)$(includedir)) diff --git a/packages/libpcap/libpcap-0.8.3/.mtn2git_empty b/packages/libpcap/libpcap-0.8.3/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/libpcap/libpcap-0.8.3/shared.patch b/packages/libpcap/libpcap-0.8.3/shared.patch deleted file mode 100644 index 4d654417c0..0000000000 --- a/packages/libpcap/libpcap-0.8.3/shared.patch +++ /dev/null @@ -1,118 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- libpcap-0.8.1/Makefile.in~shared 2003-12-15 02:42:23.000000000 +0100 -+++ libpcap-0.8.1/Makefile.in 2004-01-02 14:46:18.000000000 +0100 -@@ -37,6 +37,15 @@ - srcdir = @srcdir@ - VPATH = @srcdir@ - -+# some defines for shared library compilation - FIXME, if not matching -+MAJ=0.8 -+MIN=3 -+VERSION=$(MAJ).$(MIN) -+LIBNAME=pcap -+LIBRARY=lib$(LIBNAME).a -+SOLIBRARY=lib$(LIBNAME).so -+SHAREDLIB=$(SOLIBRARY).$(VERSION) -+ - # - # You shouldn't need to edit anything below. - # -@@ -49,6 +58,7 @@ - - # Standard CFLAGS - CFLAGS = $(CCOPT) $(INCLS) $(DEFS) -+CFLAGS_SHARED = -shared -Wl,-soname,$(SOLIBRARY).$(MAJ) - - INSTALL = @INSTALL@ - INSTALL_PROGRAM = @INSTALL_PROGRAM@ -@@ -69,6 +79,9 @@ - .c.o: - @rm -f $@ - $(CC) $(CFLAGS) -c $(srcdir)/$*.c -+%_pic.o: %.c -+ @rm -f $@ -+ $(CC) -fPIC $(CFLAGS) -c -o $@ $(srcdir)/$*.c - - PSRC = pcap-@V_PCAP@.c - FSRC = fad-@V_FINDALLDEVS@.c -@@ -83,6 +96,7 @@ - # We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot - # hack the extra indirection - OBJ = $(PSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(GENSRC:.c=.o) $(LIBOBJS) -+OBJ_PIC = $(PSRC:.c=_pic.o) $(FSRC:.c=.o) $(CSRC:.c=_pic.o) $(GENSRC:.c=_pic.o) - HDR = pcap.h pcap-int.h pcap-namedb.h pcap-nit.h pcap-pf.h \ - ethertype.h gencode.h gnuc.h - GENHDR = \ -@@ -94,15 +108,22 @@ - TAGFILES = \ - $(SRC) $(HDR) $(TAGHDR) - --CLEANFILES = $(OBJ) libpcap.a $(GENSRC) $(GENHDR) lex.yy.c -+CLEANFILES = $(OBJ) libpcap.a $(GENSRC) $(GENHDR) lex.yy.c libpcap.so* - --all: libpcap.a -+all: libpcap.a $(SHAREDLIB) - - libpcap.a: $(OBJ) - @rm -f $@ - ar rc $@ $(OBJ) $(LIBS) - $(RANLIB) $@ - -+$(SHAREDLIB): $(OBJ_PIC) -+ -@rm -f $@ -+ -@rm -f $(SOLIBRARY) $(SOLIBRARY).$(MAJ) -+ $(CC) $(CFLAGS_SHARED) -o $(SHAREDLIB) $(OBJ_PIC) -lc -+ ln -s $(SHAREDLIB) $(SOLIBRARY).$(MAJ) -+ ln -s $(SOLIBRARY).$(MAJ) $(SOLIBRARY) -+ - scanner.c: $(srcdir)/scanner.l - @rm -f $@ - $(LEX) -t $< > $$$$.$@; mv $$$$.$@ $@ -@@ -110,6 +131,9 @@ - scanner.o: scanner.c tokdefs.h - $(CC) $(CFLAGS) -c scanner.c - -+scanner_pic.o: scanner.c tokdefs.h -+ $(CC) -fPIC $(CFLAGS) -o $@ -c scanner.c -+ - pcap.o: version.h - - tokdefs.h: grammar.c -@@ -123,9 +147,16 @@ - @rm -f $@ - $(CC) $(CFLAGS) -Dyylval=pcap_lval -c grammar.c - -+grammer_pic.o: grammar.c -+ @rm -f $@ -+ $(CC) -fPIC $(CFLAGS) -Dyylval=pcap_lval -o $@ -c grammar.c -+ - version.o: version.c - $(CC) $(CFLAGS) -c version.c - -+version_pic.o: version.c -+ $(CC) -fPIC $(CFLAGS) -c version.c -o $@ -+ - snprintf.o: $(srcdir)/missing/snprintf.c - $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c - -@@ -151,10 +182,16 @@ - bpf_filter.o: bpf_filter.c - $(CC) $(CFLAGS) -c bpf_filter.c - -+bpf_filter_pic.o: bpf_filter.c -+ $(CC) -fPIC $(CFLAGS) -c bpf_filter.c -o $@ -+ - install: - [ -d $(DESTDIR)$(libdir) ] || \ - (mkdir -p $(DESTDIR)$(libdir); chmod 755 $(DESTDIR)$(libdir)) - $(INSTALL_DATA) libpcap.a $(DESTDIR)$(libdir)/libpcap.a -+ $(INSTALL_DATA) $(SHAREDLIB) $(DESTDIR)$(libdir)/ -+ ln -sf $(SHAREDLIB) $(DESTDIR)$(libdir)/$(SOLIBRARY).$(MAJ) -+ ln -sf $(SOLIBRARY).$(MAJ) $(DESTDIR)$(libdir)/$(SOLIBRARY) - $(RANLIB) $(DESTDIR)$(libdir)/libpcap.a - [ -d $(DESTDIR)$(includedir) ] || \ - (mkdir -p $(DESTDIR)$(includedir); chmod 755 $(DESTDIR)$(includedir)) diff --git a/packages/libpcap/libpcap_0.7.2.bb b/packages/libpcap/libpcap_0.7.2.bb deleted file mode 100644 index 1b430c7ece..0000000000 --- a/packages/libpcap/libpcap_0.7.2.bb +++ /dev/null @@ -1,30 +0,0 @@ -DESCRIPTION = "Network Packet Capture Library" -SECTION = "libs" -PRIORITY = "required" -MAINTAINER = "Greg Gilbert " -LICENSE = "BSD" -SRC_URI = "http://www.tcpdump.org/release/libpcap-${PV}.tar.gz;" -SRC_URI_append = " file://libpcap-shared.patch;patch=1" -SRC_URI_append = " file://configure.patch;patch=1" -SRC_URI_append = " file://ldflags.patch;patch=1" - -inherit autotools - -EXTRA_OECONF = "--with-pcap=linux" -CPPFLAGS_prepend = "-I${S} " -CFLAGS_prepend = "-I${S} " -CXXFLAGS_prepend = "-I${S} " - -do_configure_prepend () { - if [ ! -e acinclude.m4 ]; then - cat aclocal.m4 > acinclude.m4 - fi -} - -do_stage () { - install -d ${STAGING_INCDIR}/net - install -m 0644 net/bpf.h ${STAGING_INCDIR}/net/bpf.h - install -m 0644 pcap.h ${STAGING_INCDIR}/pcap.h - install -m 0644 pcap-namedb.h ${STAGING_INCDIR}/pcap-namedb.h - oe_libinstall -a -so libpcap ${STAGING_LIBDIR} -} diff --git a/packages/libpcap/libpcap_0.8.3.bb b/packages/libpcap/libpcap_0.8.3.bb deleted file mode 100644 index bdf68e8d3f..0000000000 --- a/packages/libpcap/libpcap_0.8.3.bb +++ /dev/null @@ -1,30 +0,0 @@ -DESCRIPTION = "Network Packet Capture Library" -HOMEPAGE = "http://www.tcpdump.org/" -LICENSE = "BSD" -SECTION = "libs" -PR = "r1" - -SRC_URI = "http://www.tcpdump.org/release/libpcap-${PV}.tar.gz; \ - file://shared.patch;patch=1" - -inherit autotools - -EXTRA_OECONF = "--with-pcap=linux" -CPPFLAGS_prepend = "-I${S} " -CFLAGS_prepend = "-I${S} " -CXXFLAGS_prepend = "-I${S} " - -do_configure_prepend () { - if [ ! -e acinclude.m4 ]; then - cat aclocal.m4 > acinclude.m4 - fi -} - -do_stage () { - install -m 0644 pcap.h ${STAGING_INCDIR}/pcap.h - install -m 0644 pcap-namedb.h ${STAGING_INCDIR}/pcap-namedb.h - install -m 0644 pcap-bpf.h ${STAGING_INCDIR}/pcap-bpf.h - oe_libinstall -a -so libpcap ${STAGING_LIBDIR} - install -d ${STAGING_INCDIR}/net - ln -sf ${STAGING_INCDIR}/pcap-bpf.h ${STAGING_INCDIR}/net/bpf.h -} -- cgit v1.2.3 From a00c3736cc87257bb0fc7feea1463322236c0d4f Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Sun, 3 Sep 2006 19:38:18 +0000 Subject: tcpdump: remove 3.8.3; reinstatiate -O2 patch for 3.9.3; remove using local includes --- packages/tcpdump/tcpdump_3.8.3.bb | 17 ----------------- packages/tcpdump/tcpdump_3.9.3.bb | 10 +++++++--- 2 files changed, 7 insertions(+), 20 deletions(-) delete mode 100644 packages/tcpdump/tcpdump_3.8.3.bb diff --git a/packages/tcpdump/tcpdump_3.8.3.bb b/packages/tcpdump/tcpdump_3.8.3.bb deleted file mode 100644 index f0274b4e86..0000000000 --- a/packages/tcpdump/tcpdump_3.8.3.bb +++ /dev/null @@ -1,17 +0,0 @@ -DESCRIPTION = "A sophisticated network protocol dumper" -HOMEPAGE = "http://www.tcpdump.org/" -LICENSE = "BSD" -SECTION = "console/network" -PRIORITY = "optional" -DEPENDS = "libpcap-0.8.3" -PR = "r1" - -SRC_URI = "http://www.tcpdump.org/release/tcpdump-${PV}.tar.gz \ - file://fix-paths.patch;patch=1" - -inherit autotools - -do_configure() { - gnu-configize - oe_runconf -} diff --git a/packages/tcpdump/tcpdump_3.9.3.bb b/packages/tcpdump/tcpdump_3.9.3.bb index d3422539ce..2caaa3ab98 100644 --- a/packages/tcpdump/tcpdump_3.9.3.bb +++ b/packages/tcpdump/tcpdump_3.9.3.bb @@ -4,14 +4,18 @@ LICENSE = "BSD" SECTION = "console/network" PRIORITY = "optional" DEPENDS = "libpcap-0.9.3 openssl" -PR = "r0" +PR = "r1" -SRC_URI = "http://www.tcpdump.org/release/tcpdump-${PV}.tar.gz" +SRC_URI = "http://www.tcpdump.org/release/tcpdump-${PV}.tar.gz \ + file://tcpdump_configure_no_-O2.patch;patch=1" inherit autotools +EXTRA_OECONF = "--without-crypto" + do_configure() { gnu-configize oe_runconf + sed -i 's:/usr/lib:${STAGING_LIBDIR}:' ./Makefile + sed -i 's:/usr/include:${STAGING_INCDIR}:' ./Makefile } - -- cgit v1.2.3 From 88ddfa8fba208fc9c874480f9a8889bd65225e43 Mon Sep 17 00:00:00 2001 From: Kristoffer Ericson Date: Sun, 3 Sep 2006 22:43:59 +0000 Subject: conf/distro/jlime-donkey.conf : GTK related versions remove, bugfix * Removed all GTK, GLIB related stuff so we start bugtrack why osb-jscore doeesnt build. * Added PREFERRED_PROVIDER for glibc-intermediate so it grabs 2.4. Had to set specific defines for both archs due to some bitbake bug when using {ARCH} in define line. --- conf/distro/jlime-donkey.conf | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/conf/distro/jlime-donkey.conf b/conf/distro/jlime-donkey.conf index e668c3ce38..76e68fcc08 100644 --- a/conf/distro/jlime-donkey.conf +++ b/conf/distro/jlime-donkey.conf @@ -53,19 +53,13 @@ PREFERRED_VERSION_linux-libc-headers = "2.6.15.99" PREFERRED_VERSION_glibc = "2.4" PREFERRED_VERSION_glibc-intermediate = "2.4" - -#<>------------------------------------------------------------------> -#<>Setting Preferred glib, dbus, db-native -#<>------------------------------------------------------------------< -PREFERRED_VERSION_glib-2.0-native = "2.6.5" -PREFERRED_VERSION_glib-1.2-native = "1.2.10" -PREFERRED_VERSION_glib-2.0 = "2.12.0" -PREFERRED_VERSION_glib-1.2 = "1.2.10" -PREFERRED_VERSION_pango = "1.12.0" -PREFERRED_VERSION_dbus = "0.61" -PREFERRED_VERSION_dbus-native = "0.61" -PREFERRED_PROVIDER_dbus-glib = "dbus" -PREFERRED_PROVIDER_virtual/db-native = "db-native" +#<>-----------------------------------------------------------------> +#<>Patch for bitbake bug: +#<>Due to bitbake not grabbing glibc 2.4 properly +#<>we need to override it to be sure. Do it for both supported archs +#<>-----------------------------------------------------------------< +PREFERRED_PROVIDER_virtual/sh3-linux-libc-for-gcc = "glibc-intermediate" +PREFERRED_PROVIDER_virtual/arm-linux-libc-for-gcc = "glibc-intermediate" #<>------------------------------------------------------------------> @@ -109,17 +103,6 @@ OPIE_VERSION = "1.2.2" require conf/distro/include/preferred-opie-versions.inc -#<>------------------------------------------------------------------> -#<> Lets decide on a GPE versipns -#<> And lets override GTK to something that builds -#<>------------------------------------------------------------------< -require conf/distro/include/preferred-gpe-versions-2.7.inc -PREFERRED_VERSION_gtk+ = "2.8.16" -PREFERRED_VERSION_pango = "1.12.0" -PREFERRED_VERSION_cairo = "1.2.2" -PREFERRED_VERSION_gtk-engines = "2.7.4" - - #<>------------------------------------------------------------------> #<> We want pcmciautils, not pcmcia-cs #<>------------------------------------------------------------------< -- cgit v1.2.3 From dc05d36fb3e799566cb1325f4d1f0ca018207f57 Mon Sep 17 00:00:00 2001 From: Holger Freyther Date: Sun, 3 Sep 2006 21:51:36 +0000 Subject: classes/sanity.bbclass: Check for bzip2 in the path as well --- classes/sanity.bbclass | 3 +++ 1 file changed, 3 insertions(+) diff --git a/classes/sanity.bbclass b/classes/sanity.bbclass index 91ca9865fd..23a8f656b2 100644 --- a/classes/sanity.bbclass +++ b/classes/sanity.bbclass @@ -97,6 +97,9 @@ def check_sanity(e): if not check_app_exists('svn', e.data): raise_sanity_error('Please install the svn utility') + if not check_app_exists('bzip2', e.data): + raise_sanity_error('Please install the bzip2 utility') + oes_bb_conf = data.getVar( 'OES_BITBAKE_CONF', e.data, True ) if not oes_bb_conf: raise_sanity_error('You do not include OpenEmbeddeds version of conf/bitbake.conf') -- cgit v1.2.3 From 9e256efb9fc1f6df7049927c359fea00ffaf5b51 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Mon, 4 Sep 2006 01:27:27 +0000 Subject: litestream: Add package. litestream is a shoutcast-compatible streamer, but tiny and a lot less dependencies --- packages/litestream/.mtn2git_empty | 0 packages/litestream/litestream_1.3RC3.bb | 17 +++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 packages/litestream/.mtn2git_empty create mode 100644 packages/litestream/litestream_1.3RC3.bb diff --git a/packages/litestream/.mtn2git_empty b/packages/litestream/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/litestream/litestream_1.3RC3.bb b/packages/litestream/litestream_1.3RC3.bb new file mode 100644 index 0000000000..6c83266764 --- /dev/null +++ b/packages/litestream/litestream_1.3RC3.bb @@ -0,0 +1,17 @@ +LICENSE = "GPL" +MAINTAINER = "Oyvind Repvik " +DESCRIPTION = "ShoutCast-compatible streamer" +PR = "r0" + +SRC_URI = "http://www.litestream.org/litestream/${PN}-${PV}.tar.gz" + +inherit autotools + +do_install () { + mkdir -p ${D}${bindir} + install -m 755 litestream ${D}${bindir} + install -m 755 literestream ${D}${bindir} + install -m 755 source ${D}${bindir} + install -m 755 client ${D}${bindir} + install -m 755 server ${D}${bindir} +} \ No newline at end of file -- cgit v1.2.3 From 8cfa5694cf3f491e71109e6684a26d740499880a Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Mon, 4 Sep 2006 01:29:27 +0000 Subject: icecast: Move to nonworking --- packages/icecast/.mtn2git_empty | 0 packages/icecast/icecast_2.2.0.bb | 18 ------------------ packages/nonworking/icecast/.mtn2git_empty | 0 packages/nonworking/icecast/icecast_2.2.0.bb | 18 ++++++++++++++++++ 4 files changed, 18 insertions(+), 18 deletions(-) delete mode 100644 packages/icecast/.mtn2git_empty delete mode 100644 packages/icecast/icecast_2.2.0.bb create mode 100644 packages/nonworking/icecast/.mtn2git_empty create mode 100644 packages/nonworking/icecast/icecast_2.2.0.bb diff --git a/packages/icecast/.mtn2git_empty b/packages/icecast/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/icecast/icecast_2.2.0.bb b/packages/icecast/icecast_2.2.0.bb deleted file mode 100644 index 7322af3087..0000000000 --- a/packages/icecast/icecast_2.2.0.bb +++ /dev/null @@ -1,18 +0,0 @@ -PR = "r4" -MAINTAINER = "Oyvind Repvik Date: Mon, 4 Sep 2006 01:30:19 +0000 Subject: slugos-packages: Add litestream to feeds --- packages/meta/slugos-packages.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/meta/slugos-packages.bb b/packages/meta/slugos-packages.bb index 241f999999..3b1ffb306c 100644 --- a/packages/meta/slugos-packages.bb +++ b/packages/meta/slugos-packages.bb @@ -99,6 +99,7 @@ SLUGOS_PACKAGES = "\ libvorbis \ libxml2 \ lirc \ + litestream \ lrzsz \ lsof \ lvm2 \ -- cgit v1.2.3 From df688a4ab663c85fc93171fc022529826828e644 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 4 Sep 2006 01:51:22 +0000 Subject: rocksndiamonds: New package, a game, Boulderdash/Emerald Mine/Supaplex/Sokoban clone. * Initial draft recipe version, but already works. * Too big even for VGA devices (window size is hardcoded in game). * Data storage formats are non-optimal (pcx/uncompressed level files). * Packaging crude, need to be split up. * Nice game. --- packages/rocksndiamonds/.mtn2git_empty | 0 packages/rocksndiamonds/files/.mtn2git_empty | 0 packages/rocksndiamonds/files/rocksndiamonds.png | Bin 0 -> 1114 bytes packages/rocksndiamonds/rocksndiamonds_3.2.0.bb | 28 +++++++++++++++++++++++ 4 files changed, 28 insertions(+) create mode 100644 packages/rocksndiamonds/.mtn2git_empty create mode 100644 packages/rocksndiamonds/files/.mtn2git_empty create mode 100644 packages/rocksndiamonds/files/rocksndiamonds.png create mode 100644 packages/rocksndiamonds/rocksndiamonds_3.2.0.bb diff --git a/packages/rocksndiamonds/.mtn2git_empty b/packages/rocksndiamonds/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/rocksndiamonds/files/.mtn2git_empty b/packages/rocksndiamonds/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/rocksndiamonds/files/rocksndiamonds.png b/packages/rocksndiamonds/files/rocksndiamonds.png new file mode 100644 index 0000000000..a93d6d4e73 Binary files /dev/null and b/packages/rocksndiamonds/files/rocksndiamonds.png differ diff --git a/packages/rocksndiamonds/rocksndiamonds_3.2.0.bb b/packages/rocksndiamonds/rocksndiamonds_3.2.0.bb new file mode 100644 index 0000000000..ab5a5c8932 --- /dev/null +++ b/packages/rocksndiamonds/rocksndiamonds_3.2.0.bb @@ -0,0 +1,28 @@ +DESCRIPTION = "Rocks'n'Diamonds - Boulderdash/Emerald Mine/Supaplex/Sokoban clone." +SECTION = "games" +LICENSE = "GPL" +HOMEPAGE = "http://www.artsoft.org/rocksndiamonds/" +AUTHOR = "Holger Schemel " +MAINTAINER = "Paul Sokolovsky " + +DEFAULT_PREFERENCE = "-1" + +SRC_URI = "http://artsoft.org/RELEASES/unix/rocksndiamonds/rocksndiamonds-${PV}.tar.gz \ + file://rocksndiamonds.png" + +DEPENDS += "libsdl-net smpeg" + +APPIMAGE = "../rocksndiamonds.png" +EXTRA_OEMAKE = "CC='${CC}' RO_GAME_DIR='${datadir}/${PN}' RW_GAME_DIR='${datadir}/${PN}'" + +inherit sdl + +do_install() { + install -d ${D}${bindir} + install -m 755 ${PN} ${D}${bindir} + install -d ${D}${datadir}/${PN} + cp -r graphics levels music scores sounds ${D}${datadir}/${PN}/ +} + + +FILES_${PN} += "${bindir}/${PN} ${datadir}/${PN}" -- cgit v1.2.3 From 337c4e16e80b06c66b7b02d364d54acce543ad49 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 4 Sep 2006 09:45:19 +0000 Subject: abiword-plugins_2.4.4.bb, abiword_2.4.4.bb : drop old versions --- packages/abiword/abiword-plugins_2.4.4.bb | 27 ------------------- packages/abiword/abiword_2.4.4.bb | 43 ------------------------------- 2 files changed, 70 deletions(-) delete mode 100644 packages/abiword/abiword-plugins_2.4.4.bb delete mode 100644 packages/abiword/abiword_2.4.4.bb diff --git a/packages/abiword/abiword-plugins_2.4.4.bb b/packages/abiword/abiword-plugins_2.4.4.bb deleted file mode 100644 index 3573e87089..0000000000 --- a/packages/abiword/abiword-plugins_2.4.4.bb +++ /dev/null @@ -1,27 +0,0 @@ -DESCRIPTION ="AbiWord is free word processing program similar to Microsoft(r) Word"" -SECTION = "gnome/office" -HOMEPAGE="http://www.abiword.org"" -MAINTAINER="Koen Kooi " -LICENSE="GPLv2" - -DEPENDS = "abiword libwpd librsvg goffice poppler" -PR="r2" - -SRC_URI = "http://www.abiword.org/downloads/abiword/${PV}/source/abiword-${PV}.tar.gz \ - file://abiword-plugin-pdf-poppler.patch;patch=1;pnum=2" -S = "${WORKDIR}/abiword-${PV}/abiword-plugins" - -inherit autotools - -PARALLEL_MAKE="" - -EXTRA_OECONF = "--without-libwmf" - -PACKAGES_DYNAMIC = "abiword-plugin-*" - -python populate_packages_prepend () { - abiword_libdir = bb.data.expand('${libdir}/AbiWord-2.4/plugins', d) - - do_split_packages(d, abiword_libdir, '^libAbi(.*)\.so$', 'abiword-plugin-%s', 'Abiword plugin for %s', extra_depends='') -} - diff --git a/packages/abiword/abiword_2.4.4.bb b/packages/abiword/abiword_2.4.4.bb deleted file mode 100644 index 1df0303634..0000000000 --- a/packages/abiword/abiword_2.4.4.bb +++ /dev/null @@ -1,43 +0,0 @@ -DESCRIPTION ="AbiWord is free word processing program similar to Microsoft(r) Word"" -SECTION = "gnome/office" -HOMEPAGE="http://www.abiword.org"" -MAINTAINER="Koen Kooi " -LICENSE="GPLv2" - -DEPENDS = "perl-native libgsf libgnomeprint libgnomeprintui libglade libfribidi enchant jpeg libpng perl glibc libxml2" -RDEPENDS = "enchant glibc-gconv-ibm850 glibc-gconv-cp1252 \ - glibc-gconv-iso8859-15 glibc-gconv-iso8859-1" -PR="r1" - -SRC_URI = "http://www.abiword.org/downloads/abiword/${PV}/source/abiword-${PV}.tar.gz" -S = "${WORKDIR}/abiword-${PV}/abi" - -FILES_${PN} += " ${datadir}/icons/* \ -${datadir}/AbiSuite-2.4/AbiWord/glade \ -${datadir}/AbiSuite-2.4/AbiWord/scripts \ -${datadir}/AbiSuite-2.4/AbiWord/system.profile-en \ -${datadir}/AbiSuite-2.4/AbiWord/system.profile-en_GB \ -#${datadir}/AbiSuite-2.4/templates/A4.awt \ -#${datadir}/AbiSuite-2.4/templates/US-Letter.awt \ -${datadir}/AbiSuite-2.4/templates/normal.awt \ -${datadir}/AbiSuite-2.4/templates/normal.awt-en_GB \ -${datadir}/AbiSuite-2.4/templates/Employee-Directory.awt \ -${datadir}/AbiSuite-2.4/templates/Business-Report.awt \ -${datadir}/AbiSuite-2.4/templates/Fax-Coversheet.awt \ -${datadir}/AbiSuite-2.4/templates/Resume.awt \ -${datadir}/AbiSuite-2.4/templates/Two-Columns.awt \ -${datadir}/AbiSuite-2.4/templates/Memo.awt \ -${datadir}/AbiSuite-2.4/templates/Press-Release.awt " - -inherit autotools - -PARALLEL_MAKE="" - -EXTRA_OECONF = "--disable-pspell --enable-enchant" - -do_install_append() { - install -d ${D}${datadir}/pixmaps/ - mv ${D}${datadir}/icons/* ${D}${datadir}/pixmaps/ -} - - -- cgit v1.2.3 From 470ea3658bea7dabd656a8644bc7aa841f12faf6 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 4 Sep 2006 09:51:04 +0000 Subject: abiword-embedded_2.4.5.bb, abiword_2.4.5.bb : add abiword-embedded package which adds a version of abiword more suited for small screen devices. main abiword stuff moved into a .inc file. --- packages/abiword/abiword-embedded_2.4.5.bb | 11 ++++++++ packages/abiword/abiword.inc | 43 ++++++++++++++++++++++++++++++ packages/abiword/abiword_2.4.5.bb | 43 ++---------------------------- 3 files changed, 56 insertions(+), 41 deletions(-) create mode 100644 packages/abiword/abiword-embedded_2.4.5.bb create mode 100644 packages/abiword/abiword.inc diff --git a/packages/abiword/abiword-embedded_2.4.5.bb b/packages/abiword/abiword-embedded_2.4.5.bb new file mode 100644 index 0000000000..59a3455ccd --- /dev/null +++ b/packages/abiword/abiword-embedded_2.4.5.bb @@ -0,0 +1,11 @@ +require abiword.inc + +EXTRA_OECONF += "--enable-embedded" + +RCONFLICTS = "abiword" + +do_compile_prepend() { + cp ${S}/src/af/xap/unix/hildon/xap_EmbeddedFeatures.h ${S}/src/af/xap/unix/ + cp ${S}/src/wp/ap/unix/hildon/ap_EmbeddedFeatures.h ${S}/src/wp/ap/unix/ +} + diff --git a/packages/abiword/abiword.inc b/packages/abiword/abiword.inc new file mode 100644 index 0000000000..1df0303634 --- /dev/null +++ b/packages/abiword/abiword.inc @@ -0,0 +1,43 @@ +DESCRIPTION ="AbiWord is free word processing program similar to Microsoft(r) Word"" +SECTION = "gnome/office" +HOMEPAGE="http://www.abiword.org"" +MAINTAINER="Koen Kooi " +LICENSE="GPLv2" + +DEPENDS = "perl-native libgsf libgnomeprint libgnomeprintui libglade libfribidi enchant jpeg libpng perl glibc libxml2" +RDEPENDS = "enchant glibc-gconv-ibm850 glibc-gconv-cp1252 \ + glibc-gconv-iso8859-15 glibc-gconv-iso8859-1" +PR="r1" + +SRC_URI = "http://www.abiword.org/downloads/abiword/${PV}/source/abiword-${PV}.tar.gz" +S = "${WORKDIR}/abiword-${PV}/abi" + +FILES_${PN} += " ${datadir}/icons/* \ +${datadir}/AbiSuite-2.4/AbiWord/glade \ +${datadir}/AbiSuite-2.4/AbiWord/scripts \ +${datadir}/AbiSuite-2.4/AbiWord/system.profile-en \ +${datadir}/AbiSuite-2.4/AbiWord/system.profile-en_GB \ +#${datadir}/AbiSuite-2.4/templates/A4.awt \ +#${datadir}/AbiSuite-2.4/templates/US-Letter.awt \ +${datadir}/AbiSuite-2.4/templates/normal.awt \ +${datadir}/AbiSuite-2.4/templates/normal.awt-en_GB \ +${datadir}/AbiSuite-2.4/templates/Employee-Directory.awt \ +${datadir}/AbiSuite-2.4/templates/Business-Report.awt \ +${datadir}/AbiSuite-2.4/templates/Fax-Coversheet.awt \ +${datadir}/AbiSuite-2.4/templates/Resume.awt \ +${datadir}/AbiSuite-2.4/templates/Two-Columns.awt \ +${datadir}/AbiSuite-2.4/templates/Memo.awt \ +${datadir}/AbiSuite-2.4/templates/Press-Release.awt " + +inherit autotools + +PARALLEL_MAKE="" + +EXTRA_OECONF = "--disable-pspell --enable-enchant" + +do_install_append() { + install -d ${D}${datadir}/pixmaps/ + mv ${D}${datadir}/icons/* ${D}${datadir}/pixmaps/ +} + + diff --git a/packages/abiword/abiword_2.4.5.bb b/packages/abiword/abiword_2.4.5.bb index 1df0303634..b97556b735 100644 --- a/packages/abiword/abiword_2.4.5.bb +++ b/packages/abiword/abiword_2.4.5.bb @@ -1,43 +1,4 @@ -DESCRIPTION ="AbiWord is free word processing program similar to Microsoft(r) Word"" -SECTION = "gnome/office" -HOMEPAGE="http://www.abiword.org"" -MAINTAINER="Koen Kooi " -LICENSE="GPLv2" - -DEPENDS = "perl-native libgsf libgnomeprint libgnomeprintui libglade libfribidi enchant jpeg libpng perl glibc libxml2" -RDEPENDS = "enchant glibc-gconv-ibm850 glibc-gconv-cp1252 \ - glibc-gconv-iso8859-15 glibc-gconv-iso8859-1" -PR="r1" - -SRC_URI = "http://www.abiword.org/downloads/abiword/${PV}/source/abiword-${PV}.tar.gz" -S = "${WORKDIR}/abiword-${PV}/abi" - -FILES_${PN} += " ${datadir}/icons/* \ -${datadir}/AbiSuite-2.4/AbiWord/glade \ -${datadir}/AbiSuite-2.4/AbiWord/scripts \ -${datadir}/AbiSuite-2.4/AbiWord/system.profile-en \ -${datadir}/AbiSuite-2.4/AbiWord/system.profile-en_GB \ -#${datadir}/AbiSuite-2.4/templates/A4.awt \ -#${datadir}/AbiSuite-2.4/templates/US-Letter.awt \ -${datadir}/AbiSuite-2.4/templates/normal.awt \ -${datadir}/AbiSuite-2.4/templates/normal.awt-en_GB \ -${datadir}/AbiSuite-2.4/templates/Employee-Directory.awt \ -${datadir}/AbiSuite-2.4/templates/Business-Report.awt \ -${datadir}/AbiSuite-2.4/templates/Fax-Coversheet.awt \ -${datadir}/AbiSuite-2.4/templates/Resume.awt \ -${datadir}/AbiSuite-2.4/templates/Two-Columns.awt \ -${datadir}/AbiSuite-2.4/templates/Memo.awt \ -${datadir}/AbiSuite-2.4/templates/Press-Release.awt " - -inherit autotools - -PARALLEL_MAKE="" - -EXTRA_OECONF = "--disable-pspell --enable-enchant" - -do_install_append() { - install -d ${D}${datadir}/pixmaps/ - mv ${D}${datadir}/icons/* ${D}${datadir}/pixmaps/ -} +require abiword.inc +RCONFLICTS = "abiword-embedded" -- cgit v1.2.3 From 96a81259628f148f9c7543a8d84b44ee05df539b Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 4 Sep 2006 09:53:59 +0000 Subject: libbonobo_2.14.0.bb : new version --- packages/gnome/libbonobo_2.14.0.bb | 60 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 packages/gnome/libbonobo_2.14.0.bb diff --git a/packages/gnome/libbonobo_2.14.0.bb b/packages/gnome/libbonobo_2.14.0.bb new file mode 100644 index 0000000000..d3cdc3a1c8 --- /dev/null +++ b/packages/gnome/libbonobo_2.14.0.bb @@ -0,0 +1,60 @@ +LICENSE = "GPL" +PR = "r0" +SECTION = "x11/gnome/libs" +DESCRIPTION = "Bonobo CORBA interfaces library" + +inherit gnome + +SRC_URI += "file://configure-gthread.patch;patch=1 \ + file://gtk-doc.m4 \ + file://gtk-doc.make" +DEPENDS = "glib-2.0 orbit2 intltool-native libxml2" +ORBIT_IDL_SRC = "${STAGING_BINDIR}/orbit-idl-2" + +FILES_${PN} += "${libdir}/orbit-2.0/*.so ${libdir}/bonobo/monikers/*.so" +FILES_${PN}-dev += "${libdir}/orbit-2.0/* ${libdir}/bonobo/monikers/* \ + ${libdir}/bonobo-2.0/samples" + +PARALLEL_MAKE = "" + +do_configure_prepend() { + install -d m4 + install ${WORKDIR}/gtk-doc.m4 m4/ + install ${WORKDIR}/gtk-doc.make ./ +} + +ACTIVATION_HEADERS = "Bonobo_Unknown.h Bonobo_GenericFactory.h Bonobo_Activation_types.h \ + bonobo-activation.h bonobo-activation-async.h bonobo-activation-activate.h \ + bonobo-activation-init.h bonobo-activation-shlib.h bonobo-activation-register.h \ + bonobo-activation-server-info.h bonobo-activation-version.h" + +BONOBO_HEADERS = "Bonobo.h bonobo-arg.h bonobo-context.h bonobo-event-source.h bonobo-exception.h \ + bonobo-generic-factory.h bonobo-item-container.h bonobo-item-handler.h \ + bonobo-listener.h bonobo-main.h bonobo-macros.h bonobo-moniker-extender.h \ + bonobo-moniker-simple.h bonobo-moniker-util.h bonobo-moniker.h bonobo-object.h \ + bonobo-foreign-object.h bonobo-persist-file.h bonobo-persist-stream.h \ + bonobo-persist.h bonobo-persist-client.h bonobo-property-bag.h \ + bonobo-property-bag-client.h bonobo-shlib-factory.h bonobo-storage.h \ + bonobo-stream.h bonobo-stream-client.h bonobo-stream-memory.h \ + bonobo-storage-memory.h bonobo-xobject.h bonobo-i18n.h bonobo-types.h \ + bonobo-app-client.h bonobo-application.h" + +do_compile() { + oe_runmake ORBIT_IDL="${ORBIT_IDL_SRC}" +} + +do_stage() { + install -d ${STAGING_INCDIR}/bonobo-activation-2.0/bonobo-activation + for i in ${ACTIVATION_HEADERS}; do install -m 0644 bonobo-activation/$i ${STAGING_INCDIR}/bonobo-activation-2.0/bonobo-activation/; done + install -d ${STAGING_INCDIR}/libbonobo-2.0/bonobo + for i in ${BONOBO_HEADERS}; do install -m 0644 bonobo/$i ${STAGING_INCDIR}/libbonobo-2.0/bonobo/; done + install -m 0644 libbonobo.h ${STAGING_INCDIR}/libbonobo-2.0/ + install -d ${STAGING_DATADIR}/idl/bonobo-activation-2.0/ + install idl/*.idl ${STAGING_DATADIR}/idl/bonobo-activation-2.0/ + oe_libinstall -so -C bonobo libbonobo-2 ${STAGING_LIBDIR} + oe_libinstall -so -C bonobo-activation libbonobo-activation ${STAGING_LIBDIR} +} + +do_install() { + oe_runmake ORBIT_IDL="${ORBIT_IDL_SRC}" DESTDIR="${D}" install +} -- cgit v1.2.3 From 3db8d2e4c418d898668d3fe1c7323570e366b8e5 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 4 Sep 2006 09:56:36 +0000 Subject: libbonobo/configure-gthread.patch : forgot the patch --- packages/gnome/libbonobo/.mtn2git_empty | 0 packages/gnome/libbonobo/configure-gthread.patch | 11 +++++++++++ 2 files changed, 11 insertions(+) create mode 100644 packages/gnome/libbonobo/.mtn2git_empty create mode 100644 packages/gnome/libbonobo/configure-gthread.patch diff --git a/packages/gnome/libbonobo/.mtn2git_empty b/packages/gnome/libbonobo/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/gnome/libbonobo/configure-gthread.patch b/packages/gnome/libbonobo/configure-gthread.patch new file mode 100644 index 0000000000..005fa6760a --- /dev/null +++ b/packages/gnome/libbonobo/configure-gthread.patch @@ -0,0 +1,11 @@ +--- libbonobo-2.14.0/configure.in.orig 2006-09-04 09:21:54.000000000 +0100 ++++ libbonobo-2.14.0/configure.in 2006-09-04 09:22:58.000000000 +0100 +@@ -166,7 +166,7 @@ + AC_MSG_RESULT(no) + AC_MSG_ERROR( + [No working gthread-2.0 support found, using --disable-threads IS DISCOURAGED]) +- ] ++ ],[AC_MSG_RESULT(yes)] + ) + CFLAGS=$libbonobo_save_CFLAGS + LIBS=$libbonobo_save_LIBS -- cgit v1.2.3 From dd6915b00393feb4830a4435f13b505f838bf7e9 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 4 Sep 2006 10:06:27 +0000 Subject: abiword-embedded: RPROVIDE abiword --- packages/abiword/abiword-embedded_2.4.5.bb | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/abiword/abiword-embedded_2.4.5.bb b/packages/abiword/abiword-embedded_2.4.5.bb index 59a3455ccd..9381bbd8a7 100644 --- a/packages/abiword/abiword-embedded_2.4.5.bb +++ b/packages/abiword/abiword-embedded_2.4.5.bb @@ -3,6 +3,7 @@ require abiword.inc EXTRA_OECONF += "--enable-embedded" RCONFLICTS = "abiword" +RPROVIDES += "abiword" do_compile_prepend() { cp ${S}/src/af/xap/unix/hildon/xap_EmbeddedFeatures.h ${S}/src/af/xap/unix/ -- cgit v1.2.3 From da241cb72a4d49335420bf122f4f8eb1ce82419f Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 4 Sep 2006 11:07:14 +0000 Subject: abiword-plugins_2.4.5.bb : remove DEPENDS on abiword as it doesnt require it to build. Add RDEPENDS on abiword as plugins require it to be useful. --- packages/abiword/abiword-plugins_2.4.5.bb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/abiword/abiword-plugins_2.4.5.bb b/packages/abiword/abiword-plugins_2.4.5.bb index 444b0a43c7..567cc3a414 100644 --- a/packages/abiword/abiword-plugins_2.4.5.bb +++ b/packages/abiword/abiword-plugins_2.4.5.bb @@ -4,12 +4,13 @@ HOMEPAGE="http://www.abiword.org"" MAINTAINER="Koen Kooi " LICENSE="GPLv2" -DEPENDS = "abiword libwpd librsvg goffice poppler" +DEPENDS = "libwpd librsvg goffice poppler" PR="r1" SRC_URI = "http://www.abiword.org/downloads/abiword/${PV}/source/abiword-${PV}.tar.gz \ file://abiword-plugin-pdf-poppler.patch;patch=1;pnum=2" S = "${WORKDIR}/abiword-${PV}/abiword-plugins" +RDEPENDS='abiword' inherit autotools -- cgit v1.2.3 From b15cd814c4d59a858beee25a329a6e29a0b3989b Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 4 Sep 2006 11:24:07 +0000 Subject: libbonoboui_2.14.0.bb : new version --- packages/gnome/libbonoboui_2.14.0.bb | 58 ++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 packages/gnome/libbonoboui_2.14.0.bb diff --git a/packages/gnome/libbonoboui_2.14.0.bb b/packages/gnome/libbonoboui_2.14.0.bb new file mode 100644 index 0000000000..049eb135ad --- /dev/null +++ b/packages/gnome/libbonoboui_2.14.0.bb @@ -0,0 +1,58 @@ +LICENSE = "GPL" +SECTION = "x11/gnome/libs" +PR = "r0" + +inherit gnome pkgconfig + +FILES_${PN} += "${libdir}/libglade/2.0/*.so" +FILES_${PN}-dev += "${libdir}/libglade/2.0/* ${datadir}/gnome-2.0/ui \ + ${libdir}/bonobo-2.0/samples" +FILES_${PN}-dbg += "${libdir}/libglade/2.0/.debug/*.so" + +DEPENDS = "libgnomecanvas libbonobo libgnome glib-2.0 gtk-doc gconf libxml2 libglade" + +EXTRA_OECONF = "--disable-gtk-doc" + +HEADERS = " \ +bonobo/bonobo-zoomable.h \ +bonobo/bonobo-ui-component.h \ +bonobo/bonobo-dock-layout.h \ +bonobo/bonobo-ui-type-builtins.h \ +bonobo/bonobo-canvas-component.h \ +bonobo/bonobo-widget.h \ +bonobo/bonobo-ui-engine.h \ +bonobo/bonobo-window.h \ +bonobo/bonobo-ui-toolbar.h \ +bonobo/bonobo-dock-band.h \ +bonobo/bonobo-ui-toolbar-item.h \ +bonobo/bonobo-control.h \ +bonobo/bonobo-dock-item.h \ +bonobo/bonobo-ui-config-widget.h \ +bonobo/bonobo-zoomable-frame.h \ +bonobo/bonobo-control-frame.h \ +bonobo/bonobo-dock.h \ +bonobo/bonobo-ui-main.h \ +bonobo/bonobo-canvas-item.h \ +bonobo/bonobo-ui-node.h \ +bonobo/bonobo-socket.h \ +bonobo/bonobo-selector.h \ +bonobo/bonobo-ui-sync.h \ +bonobo/bonobo-ui-util.h \ +bonobo/bonobo-plug.h \ +bonobo/bonobo-ui-toolbar-button-item.h \ +bonobo/bonobo-ui-toolbar-toggle-button-item.h \ +bonobo/bonobo-ui-container.h \ +bonobo/bonobo-file-selector-util.h \ +bonobo/bonobo-property-control.h \ +bonobo/bonobo-selector-widget.h \ +libbonoboui.h \ +bonobo.h \ +" + +do_stage() { + install -d ${STAGING_INCDIR}/libbonoboui-2.0/bonobo + for i in ${HEADERS}; do + install -m 0644 $i ${STAGING_INCDIR}/libbonoboui-2.0/$i + done + oe_libinstall -C bonobo -a -so libbonoboui-2 ${STAGING_LIBDIR} +} -- cgit v1.2.3 From 608ae24505e28e6212904851c39cc51de41bf037 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 4 Sep 2006 11:32:03 +0000 Subject: libgnome_2.14.1.bb : new version --- packages/gnome/libgnome_2.14.1.bb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 packages/gnome/libgnome_2.14.1.bb diff --git a/packages/gnome/libgnome_2.14.1.bb b/packages/gnome/libgnome_2.14.1.bb new file mode 100644 index 0000000000..e5a681ab54 --- /dev/null +++ b/packages/gnome/libgnome_2.14.1.bb @@ -0,0 +1,14 @@ +DESCRIPTION = "Gnome application programming libraries" +LICENSE = "GPL" +SECTION = "x11/gnome/libs" +PR = "r0" + +inherit gnome + +DEPENDS = "gconf-native gnome-vfs libbonobo" + +EXTRA_OECONF = "--disable-gtk-doc" + +do_stage() { +autotools_stage_all +} -- cgit v1.2.3 From dff14fe743df2fbdf4b934bd8721b4302c942e4d Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 4 Sep 2006 11:39:20 +0000 Subject: libgnomeui_2.15.2.bb : new version had to use unstable as this fixes a compile bug with gtk+ recent. --- packages/gnome/libgnomeui_2.15.2.bb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 packages/gnome/libgnomeui_2.15.2.bb diff --git a/packages/gnome/libgnomeui_2.15.2.bb b/packages/gnome/libgnomeui_2.15.2.bb new file mode 100644 index 0000000000..8f3e0a725c --- /dev/null +++ b/packages/gnome/libgnomeui_2.15.2.bb @@ -0,0 +1,22 @@ +LICENSE = "GPL" +SECTION = "x11/gnome/libs" +PR = "r0" +DEPENDS = "libgnome libgnomecanvas libbonoboui gnome-keyring" +DESCRIPTION = "GNOME User Interface Library" + +FILES_${PN} += "${libdir}/gtk-2.0/*/filesystems/lib*.so \ + ${libdir}/libglade/*/lib*.so" + +inherit gnome + +SRC_URI += "file://gnome-stock-pixbufs.h file://no-pixbuf-csource.patch;patch=1" + +EXTRA_OECONF = "--disable-gtk-doc" + +do_configure_prepend() { + install -m 0644 ${WORKDIR}/gnome-stock-pixbufs.h ${S}/libgnomeui/pixmaps/gnome-stock-pixbufs.h +} + +do_stage() { +autotools_stage_all +} -- cgit v1.2.3 From 9763a2f7bf9620ef6a3743fcc4caff4f1c19a916 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 4 Sep 2006 13:13:28 +0000 Subject: abiword.inc: fix DESCRIPTION --- packages/abiword/abiword.inc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/abiword/abiword.inc b/packages/abiword/abiword.inc index 1df0303634..657ed618c9 100644 --- a/packages/abiword/abiword.inc +++ b/packages/abiword/abiword.inc @@ -1,8 +1,8 @@ -DESCRIPTION ="AbiWord is free word processing program similar to Microsoft(r) Word"" +DESCRIPTION = "AbiWord is free word processing program similar to Microsoft(r) Word" SECTION = "gnome/office" -HOMEPAGE="http://www.abiword.org"" -MAINTAINER="Koen Kooi " -LICENSE="GPLv2" +HOMEPAGE = "http://www.abiword.org"" +MAINTAINER = "Koen Kooi " +LICENSE = "GPLv2" DEPENDS = "perl-native libgsf libgnomeprint libgnomeprintui libglade libfribidi enchant jpeg libpng perl glibc libxml2" RDEPENDS = "enchant glibc-gconv-ibm850 glibc-gconv-cp1252 \ -- cgit v1.2.3 From 11a24487c132a7d80c69d98b48945d0242912320 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 4 Sep 2006 15:15:08 +0000 Subject: links-x11_2.1pre23.bb : new version Added a .desktop and icon. --- packages/links/files/links2.desktop | 14 ++++++++++++++ packages/links/links-x11_2.1pre22.bb | 25 ------------------------- packages/links/links-x11_2.1pre23.bb | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 packages/links/files/links2.desktop delete mode 100644 packages/links/links-x11_2.1pre22.bb create mode 100644 packages/links/links-x11_2.1pre23.bb diff --git a/packages/links/files/links2.desktop b/packages/links/files/links2.desktop new file mode 100644 index 0000000000..a05bce1b2b --- /dev/null +++ b/packages/links/files/links2.desktop @@ -0,0 +1,14 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Links +Comment=Links is a browser very similar to lynx +Comment[es]=El links es un browser para modo texto, similar a lynx +Comment[pl]=Links jest przeglÄ…darkÄ… podobnÄ… do lynksa +Comment[pt]=O links é um browser para modo texto, similar ao lynx +Comment[pt_BR]=O links é um browser para modo texto, similar ao lynx +Exec=links -g +Terminal=true +Icon=links2 +Type=Application +Categories=Application;ConsoleOnly;Network;WebBrowser; +# vi: encoding=utf-8 diff --git a/packages/links/links-x11_2.1pre22.bb b/packages/links/links-x11_2.1pre22.bb deleted file mode 100644 index 9c9bb831aa..0000000000 --- a/packages/links/links-x11_2.1pre22.bb +++ /dev/null @@ -1,25 +0,0 @@ -LICENSE = "GPL" -SECTION = "console/network" -DEPENDS = "jpeg libpng flex openssl zlib virtual/libx11" -DESCRIPTION = "Links is graphics and text mode WWW \ -browser, similar to Lynx." -RCONFLICTS = "links" - -MAINTAINER = "Graeme Gregory " - -SRC_URI = "http://links.twibright.com/download/links-${PV}.tar.bz2 \ - file://ac-prog-cxx.patch;patch=1 \ - file://cookies-save-0.96.patch;patch=1 \ - file://links-2.1pre17-fix-segfault-on-loading-cookies.patch;patch=1" - -PR = "r1" - -inherit autotools - -EXTRA_OECONF = "--enable-javascript --with-libfl --enable-graphics \ - --with-ssl=${STAGING_LIBDIR}/.. --with-libjpeg \ - --without-libtiff --without-svgalib --without-fb \ - --without-directfb --without-pmshell --without-atheos \ - --with-x --without-gpm --without-sdl" - -S = "${WORKDIR}/links-${PV}" diff --git a/packages/links/links-x11_2.1pre23.bb b/packages/links/links-x11_2.1pre23.bb new file mode 100644 index 0000000000..c68a94565b --- /dev/null +++ b/packages/links/links-x11_2.1pre23.bb @@ -0,0 +1,32 @@ +DESCRIPTION = "Links is graphics and text mode WWW \ +browser, similar to Lynx." +HOMEPAGE = "http://links.twibright.com/" +SECTION = "console/network" +MAINTAINER = "Graeme Gregory " +LICENSE = "GPL" +DEPENDS = "jpeg libpng flex openssl zlib virtual/libx11" +RCONFLICTS = "links" +PR = "r0" +SRC_URI = "http://links.twibright.com/download/links-${PV}.tar.bz2 \ + file://ac-prog-cxx.patch;patch=1 \ + file://cookies-save-0.96.patch;patch=1 \ + file://links-2.1pre17-fix-segfault-on-loading-cookies.patch;patch=1 \ + file://links2.desktop \ + http://www.xora.org.uk/oe/links2.png" +S = "${WORKDIR}/links-${PV}" + +inherit autotools + +EXTRA_OECONF = "--enable-javascript --with-libfl --enable-graphics \ + --with-ssl=${STAGING_LIBDIR}/.. --with-libjpeg \ + --without-libtiff --without-svgalib --without-fb \ + --without-directfb --without-pmshell --without-atheos \ + --with-x --without-gpm --without-sdl" + +do_install_append() { + install -d ${D}/${datadir}/applications + install -m 0644 ${WORKDIR}/links2.desktop ${D}/${datadir}/applications + install -d ${D}/${datadir}/pixmaps + install -m 0644 ${WORKDIR}/links2.png ${D}/${datadir}/pixmaps +} + -- cgit v1.2.3 From 40cd6d1cb5e34f32bb91be5b80bcdc48e1ee1480 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 4 Sep 2006 15:30:51 +0000 Subject: links_2.1pre23.bb : new version --- packages/links/links_2.1pre22.bb | 23 ----------------------- packages/links/links_2.1pre23.bb | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 23 deletions(-) delete mode 100644 packages/links/links_2.1pre22.bb create mode 100644 packages/links/links_2.1pre23.bb diff --git a/packages/links/links_2.1pre22.bb b/packages/links/links_2.1pre22.bb deleted file mode 100644 index faed366594..0000000000 --- a/packages/links/links_2.1pre22.bb +++ /dev/null @@ -1,23 +0,0 @@ -LICENSE = "GPL" -SECTION = "console/network" -DEPENDS = "jpeg libpng gpm flex openssl zlib" -DESCRIPTION = "Links is graphics and text mode WWW \ -browser, similar to Lynx." -RCONFLICTS="links-x11" - -MAINTAINER = "Graeme Gregory " - -SRC_URI = "http://links.twibright.com/download/links-${PV}.tar.bz2 \ - file://ac-prog-cxx.patch;patch=1 \ - file://cookies-save-0.96.patch;patch=1 \ - file://links-2.1pre17-fix-segfault-on-loading-cookies.patch;patch=1" - -PR = "r1" - -inherit autotools - -EXTRA_OECONF = "--enable-javascript --with-libfl --enable-graphics \ - --with-ssl=${STAGING_LIBDIR}/.. --with-libjpeg \ - --without-libtiff --without-svgalib --with-fb \ - --without-directfb --without-pmshell --without-atheos \ - --without-x --without-sdl" diff --git a/packages/links/links_2.1pre23.bb b/packages/links/links_2.1pre23.bb new file mode 100644 index 0000000000..4838ce37c0 --- /dev/null +++ b/packages/links/links_2.1pre23.bb @@ -0,0 +1,21 @@ +DESCRIPTION = "Links is graphics and text mode WWW \ +browser, similar to Lynx." +HOMEPAGE = "http://links.twibright.com/" +SECTION = "console/network" +MAINTAINER = "Graeme Gregory " +LICENSE = "GPL" +DEPENDS = "jpeg libpng gpm flex openssl zlib" +RCONFLICTS="links-x11" +PR = "r0" +SRC_URI = "http://links.twibright.com/download/links-${PV}.tar.bz2 \ + file://ac-prog-cxx.patch;patch=1 \ + file://cookies-save-0.96.patch;patch=1 \ + file://links-2.1pre17-fix-segfault-on-loading-cookies.patch;patch=1" + +inherit autotools + +EXTRA_OECONF = "--enable-javascript --with-libfl --enable-graphics \ + --with-ssl=${STAGING_LIBDIR}/.. --with-libjpeg \ + --without-libtiff --without-svgalib --with-fb \ + --without-directfb --without-pmshell --without-atheos \ + --without-x --without-sdl" -- cgit v1.2.3 From f297767ec9755b4406368867eef6e9344d730d70 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 4 Sep 2006 19:00:35 +0000 Subject: povray: add 3.6.1 (from 2004), since the povray dudes haven;t released the source for 3.7.0beta yet * scrary license, $MAINTAINER gets compiled into the binary --- packages/povray/.mtn2git_empty | 0 packages/povray/files/.mtn2git_empty | 0 packages/povray/files/configure-cross-hack.patch | 94 ++++++++++++++++++++++++ packages/povray/povray_3.6.1.bb | 45 ++++++++++++ 4 files changed, 139 insertions(+) create mode 100644 packages/povray/.mtn2git_empty create mode 100644 packages/povray/files/.mtn2git_empty create mode 100644 packages/povray/files/configure-cross-hack.patch create mode 100644 packages/povray/povray_3.6.1.bb diff --git a/packages/povray/.mtn2git_empty b/packages/povray/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/povray/files/.mtn2git_empty b/packages/povray/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/povray/files/configure-cross-hack.patch b/packages/povray/files/configure-cross-hack.patch new file mode 100644 index 0000000000..550eac9323 --- /dev/null +++ b/packages/povray/files/configure-cross-hack.patch @@ -0,0 +1,94 @@ +--- /tmp/configure 2006-09-04 20:44:50.000000000 +0200 ++++ povray-3.6.1/configure 2006-09-04 20:44:58.085780000 +0200 +@@ -10287,7 +10287,7 @@ + # check library version, update LIBS + echo "$as_me:$LINENO: checking for libz version >= $required_libz_version" >&5 + echo $ECHO_N "checking for libz version >= $required_libz_version... $ECHO_C" >&6 +- if test "$cross_compiling" = yes; then ++ if test "$cross_compilingi" = yes; then + echo "$as_me:$LINENO: result: cross-compiling, forced" >&5 + echo "${ECHO_T}cross-compiling, forced" >&6 + +@@ -10338,7 +10338,7 @@ + ( exit $ac_status ) + + if test "$ac_status" != "1" || ! test -s conftest$ac_exeext ; then +- pov_check_lib="unknown" ++ pov_check_lib="ok" + echo "$as_me:$LINENO: result: $pov_check_lib" >&5 + echo "${ECHO_T}$pov_check_lib" >&6 + else +@@ -10632,7 +10632,7 @@ + # check library version, update LIBS + echo "$as_me:$LINENO: checking for libpng version >= $required_libpng_version" >&5 + echo $ECHO_N "checking for libpng version >= $required_libpng_version... $ECHO_C" >&6 +- if test "$cross_compiling" = yes; then ++ if test "$cross_compilingi" = yes; then + echo "$as_me:$LINENO: result: cross-compiling, forced" >&5 + echo "${ECHO_T}cross-compiling, forced" >&6 + +@@ -10683,7 +10683,7 @@ + ( exit $ac_status ) + + if test "$ac_status" != "1" || ! test -s conftest$ac_exeext ; then +- pov_check_lib="unknown" ++ pov_check_lib="ok" + echo "$as_me:$LINENO: result: $pov_check_lib" >&5 + echo "${ECHO_T}$pov_check_lib" >&6 + else +@@ -10989,7 +10989,7 @@ + # check library version, update LIBS + echo "$as_me:$LINENO: checking for libjpeg version >= $required_libjpeg_version" >&5 + echo $ECHO_N "checking for libjpeg version >= $required_libjpeg_version... $ECHO_C" >&6 +- if test "$cross_compiling" = yes; then ++ if test "$cross_compilings" = yes; then + echo "$as_me:$LINENO: result: cross-compiling, forced" >&5 + echo "${ECHO_T}cross-compiling, forced" >&6 + +@@ -11041,12 +11041,12 @@ + ( exit $ac_status ) + + if test "$ac_status" != "1" || ! test -s conftest$ac_exeext ; then +- pov_check_libjpeg="unknown" ++ pov_check_libjpeg="ok" + echo "$as_me:$LINENO: result: $pov_check_libjpeg" >&5 + echo "${ECHO_T}$pov_check_libjpeg" >&6 + else + pov_check_libjpeg_version=`eval $ac_try 2>&1` +- pov_check_libjpeg="bad" ++ pov_check_libjpeg="ok" + echo "$as_me:$LINENO: result: $pov_check_libjpeg_version, $pov_check_libjpeg" >&5 + echo "${ECHO_T}$pov_check_libjpeg_version, $pov_check_libjpeg" >&6 + fi +@@ -11079,7 +11079,7 @@ + + subdirs="$subdirs libraries/jpeg" + +- if test "$ac_cv_search_jpeg_std_error"; then ++ if test "$ac_cv_search_jpeg_std_errort"; then + LIBS=`echo $LIBS | sed s,$ac_cv_search_jpeg_std_error,,g` + fi + INCJPEG="-I\$(top_srcdir)/libraries/jpeg" +@@ -11341,7 +11341,7 @@ + # check library version, update LIBS + echo "$as_me:$LINENO: checking for libtiff version >= $required_libtiff_version" >&5 + echo $ECHO_N "checking for libtiff version >= $required_libtiff_version... $ECHO_C" >&6 +- if test "$cross_compiling" = yes; then ++ if test "$cross_compilingi" = yes; then + echo "$as_me:$LINENO: result: cross-compiling, forced" >&5 + echo "${ECHO_T}cross-compiling, forced" >&6 + +@@ -11398,11 +11398,11 @@ + ( exit $ac_status ) + + if test "$ac_status" != "1" || ! test -s conftest$ac_exeext ; then +- pov_check_libtiff="unknown" ++ pov_check_libtiff="ok" + echo "$as_me:$LINENO: result: $pov_check_libtiff" >&5 + echo "${ECHO_T}$pov_check_libtiff" >&6 + else +- pov_check_libtiff_version=`eval $ac_try 2>&1` ++ pov_check_libtiff_version="3.6.1" + pov_check_libtiff="bad" + echo "$as_me:$LINENO: result: $pov_check_libtiff_version, $pov_check_libtiff" >&5 + echo "${ECHO_T}$pov_check_libtiff_version, $pov_check_libtiff" >&6 diff --git a/packages/povray/povray_3.6.1.bb b/packages/povray/povray_3.6.1.bb new file mode 100644 index 0000000000..ee4876324e --- /dev/null +++ b/packages/povray/povray_3.6.1.bb @@ -0,0 +1,45 @@ +DESCRIPTION = "The Persistence of Vision Raytracer is a high-quality, totally free tool for creating stunning three-dimensional graphics. " +HOMEPAGE = "http://www.povray.org" +SECTION = "foo/bar" +#Make this a weak assigment to allow branding of the povray binary +MAINTAINER ?= "Koen Kooi " +LICENSE = "povray" + +DEPENDS = "virtual/libx11 libz jpeg libpng tiff" +RDEPENDS = "" + +PR = "r0" + +#We apply a patch that subverts the checks for jpeg, zlib, png and tiff because we know OE has the required versions, but it is still a hack. +SRC_URI = "http://www.povray.org/redirect/www.povray.org/ftp/pub/povray/Official/Unix/${P}.tar.bz2 \ + file://configure-cross-hack.patch;patch=1" + +inherit autotools pkgconfig + +EXTRA_OECONF = "--with-x COMPILED_BY=${MAINTAINER}" +PARALLEL_MAKE = "" + +#autoreconf breaks, so we'll skip that. The added advantage is that the patch to ./configure actually has effect +do_configure() { + oe_runconf +} + +PACKAGES += "${PN}-scenes ${PN}-ini ${PN}-icons ${PN}-scripts ${PN}-includes" + +PACKAGE_ARCH_${PN}-doc = "all" + +PACKAGE_ARCH_${PN}-scenes = "all" +FILES_${PN}-scenes = "${datadir}/povray-3.6/scenes" + +PACKAGE_ARCH_${PN}-ini = "all" +FILES_${PN}-ini = "${datadir}/povray-3.6/ini" + +PACKAGE_ARCH_${PN}-icons = "all" +FILES_${PN}-icons = "${datadir}/povray-3.6/icons" + +PACKAGE_ARCH_${PN}-scripts = "all" +FILES_${PN}-scripts = "${datadir}/povray-3.6/scripts" + +PACKAGE_ARCH_${PN}-includes = "all" +FILES_${PN}-includes = "${datadir}/povray-3.6/include" + -- cgit v1.2.3 From c93538264b82fde2e70c3d059e04128ade1e5092 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Mon, 4 Sep 2006 20:24:10 +0000 Subject: rox-filer: add 2.5 * compiles, packages, but not tested on device --- packages/rox/.mtn2git_empty | 0 packages/rox/files/.mtn2git_empty | 0 packages/rox/files/no-strip-objcopy.patch | 13 +++++++++++++ packages/rox/rox-filer_2.5.bb | 21 +++++++++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 packages/rox/.mtn2git_empty create mode 100644 packages/rox/files/.mtn2git_empty create mode 100644 packages/rox/files/no-strip-objcopy.patch create mode 100644 packages/rox/rox-filer_2.5.bb diff --git a/packages/rox/.mtn2git_empty b/packages/rox/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/rox/files/.mtn2git_empty b/packages/rox/files/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/rox/files/no-strip-objcopy.patch b/packages/rox/files/no-strip-objcopy.patch new file mode 100644 index 0000000000..181dccc436 --- /dev/null +++ b/packages/rox/files/no-strip-objcopy.patch @@ -0,0 +1,13 @@ +--- /tmp/Makefile.in 2006-09-04 22:08:51.000000000 +0200 ++++ rox-filer-2.5/ROX-Filer/src/Makefile.in 2006-09-04 22:09:00.275780000 +0200 +@@ -51,10 +51,6 @@ + ${PROG}: ${OBJECTS} + ${CC} -o "${PROG}" ${OBJECTS} ${LDFLAGS} + mv "${PROG}" "${PLATFORM_DIR}" +- -(cd "${PLATFORM_DIR}" && \ +- objcopy --only-keep-debug ROX-Filer ROX-Filer.dbg && \ +- strip ROX-Filer && \ +- objcopy --add-gnu-debuglink=ROX-Filer.dbg ROX-Filer) + + clean: + rm -f *.o Makefile.bak diff --git a/packages/rox/rox-filer_2.5.bb b/packages/rox/rox-filer_2.5.bb new file mode 100644 index 0000000000..87552ddfc2 --- /dev/null +++ b/packages/rox/rox-filer_2.5.bb @@ -0,0 +1,21 @@ +DESCRIPTION = "the file manager at the core of the ROX desktop" +HOMEPAGE = "http://rox.sf.net" +LICENSE = "GPL" +DEPENDS = "gtk+" + +SRC_URI = "${SOURCEFORGE_MIRROR}/rox/${P}.tar.bz2 \ + file://no-strip-objcopy.patch;patch=1;pnum=3" + +inherit pkgconfig + +S = "${WORKDIR}/${P}/ROX-Filer/src/" + +do_compile() { + ../AppRun --compile +} + +do_install() { + install -d ${D}${bindir} + install -m 755 ../ROX-Filer ${D}${bindir} +} + -- cgit v1.2.3 From b52975a224a8824cdcff83d5c1e5b4120091d975 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 5 Sep 2006 07:44:59 +0000 Subject: povray: remove bogus section --- packages/povray/povray_3.6.1.bb | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/povray/povray_3.6.1.bb b/packages/povray/povray_3.6.1.bb index ee4876324e..58ff33cbc4 100644 --- a/packages/povray/povray_3.6.1.bb +++ b/packages/povray/povray_3.6.1.bb @@ -1,6 +1,5 @@ DESCRIPTION = "The Persistence of Vision Raytracer is a high-quality, totally free tool for creating stunning three-dimensional graphics. " HOMEPAGE = "http://www.povray.org" -SECTION = "foo/bar" #Make this a weak assigment to allow branding of the povray binary MAINTAINER ?= "Koen Kooi " LICENSE = "povray" -- cgit v1.2.3 From 76abf1c2b1388f76d700b9ab16f238346d5170bf Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Tue, 5 Sep 2006 08:10:02 +0000 Subject: rox-filer: package ALL needed infos. do_install() taken from Debian package which I maintained years ago --- packages/rox/rox-filer_2.5.bb | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/packages/rox/rox-filer_2.5.bb b/packages/rox/rox-filer_2.5.bb index 87552ddfc2..868720da12 100644 --- a/packages/rox/rox-filer_2.5.bb +++ b/packages/rox/rox-filer_2.5.bb @@ -2,6 +2,8 @@ DESCRIPTION = "the file manager at the core of the ROX desktop" HOMEPAGE = "http://rox.sf.net" LICENSE = "GPL" DEPENDS = "gtk+" +RDEPENDS = "shared-mime-info" +PR = "r1" SRC_URI = "${SOURCEFORGE_MIRROR}/rox/${P}.tar.bz2 \ file://no-strip-objcopy.patch;patch=1;pnum=3" @@ -17,5 +19,37 @@ do_compile() { do_install() { install -d ${D}${bindir} install -m 755 ../ROX-Filer ${D}${bindir} -} + install -d ${D}${datadir}/rox/Choices + install -d ${D}${datadir}/rox/images + install -d ${D}${datadir}/mime/packages + install -d ${D}${datadir}/doc/rox/html + install -d ${D}${mandir}/man1 + + gzip -c9 ${WORKDIR}/${P}/rox.1 >${D}${mandir}/man1/rox.1.gz + + cp -r ${WORKDIR}/${P}/Choices ${D}${datadir}/rox + rm -rf ${D}${datadir}rox/Choices/MIME-info/ + cp ${WORKDIR}/${P}/ROX-Filer/*.xml ${D}${datadir}/rox + + cp ${WORKDIR}/${P}/ROX-Filer/Help/{Changes,README*,TODO} ${D}${datadir}/doc/rox + cp ${WORKDIR}/${P}/ROX-Filer/Help/*html ${D}${datadir}/doc/rox/html + cp ${WORKDIR}/${P}/ROX-Filer/style.css ${D}${datadir}/doc/rox/html + cp -r ${WORKDIR}/${P}/ROX-Filer/images ${D}${datadir}/rox + cp -r ${WORKDIR}/${P}/ROX-Filer/ROX ${D}${datadir}/rox + +# cp ROX-Filer/ROX-Filer ${D}/usr/bin/rox + cp ${WORKDIR}/${P}/ROX-Filer/.DirIcon ${D}${datadir}/rox/.DirIcon + cp ${WORKDIR}/${P}/rox.xml ${D}${datadir}/mime/packages + + for $f in ${WORKDIR}/${P}/ROX-Filer/Messages/*.gmo; do + export ROXTMP=`basename $f .gmo` ; + if [ $ROXTMP == "sp" ]; then + export ROXTMP="es" ; + fi + install -d ${D}${datadir}/locale/$ROXTMP/LC_MESSAGES; + cp $f debian/rox-filer/usr/share/locale/$ROXTMP/LC_MESSAGES/rox.mo; + done + + +FILES_${PN} += "${datadir}/rox/ ${datadir}/mime/" -- cgit v1.2.3 From 966d545b994dc7a6831a181f273cdfb77b9a78f6 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 5 Sep 2006 08:11:19 +0000 Subject: libgnomeui 2.15.2: lower default pref since it need gtk 2.10, which also has a negative default-pref --- packages/gnome/libgnomeui_2.15.2.bb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/gnome/libgnomeui_2.15.2.bb b/packages/gnome/libgnomeui_2.15.2.bb index 8f3e0a725c..a6700434c3 100644 --- a/packages/gnome/libgnomeui_2.15.2.bb +++ b/packages/gnome/libgnomeui_2.15.2.bb @@ -4,6 +4,8 @@ PR = "r0" DEPENDS = "libgnome libgnomecanvas libbonoboui gnome-keyring" DESCRIPTION = "GNOME User Interface Library" +DEFAULT_PREFERENCE = "-1" + FILES_${PN} += "${libdir}/gtk-2.0/*/filesystems/lib*.so \ ${libdir}/libglade/*/lib*.so" -- cgit v1.2.3 From 1ecb6418e1fbf8736bb5901b8a5f17052c241bd7 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Tue, 5 Sep 2006 08:20:45 +0000 Subject: rox-filer: fixed do_install() typos --- packages/rox/rox-filer_2.5.bb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/rox/rox-filer_2.5.bb b/packages/rox/rox-filer_2.5.bb index 868720da12..1a510f2bcd 100644 --- a/packages/rox/rox-filer_2.5.bb +++ b/packages/rox/rox-filer_2.5.bb @@ -42,14 +42,14 @@ do_install() { cp ${WORKDIR}/${P}/ROX-Filer/.DirIcon ${D}${datadir}/rox/.DirIcon cp ${WORKDIR}/${P}/rox.xml ${D}${datadir}/mime/packages - for $f in ${WORKDIR}/${P}/ROX-Filer/Messages/*.gmo; do + for f in ${WORKDIR}/${P}/ROX-Filer/Messages/*.gmo; do export ROXTMP=`basename $f .gmo` ; if [ $ROXTMP == "sp" ]; then export ROXTMP="es" ; fi install -d ${D}${datadir}/locale/$ROXTMP/LC_MESSAGES; - cp $f debian/rox-filer/usr/share/locale/$ROXTMP/LC_MESSAGES/rox.mo; + cp $f ${D}${datadir}/locale/$ROXTMP/LC_MESSAGES/rox.mo; done - +} FILES_${PN} += "${datadir}/rox/ ${datadir}/mime/" -- cgit v1.2.3 From 56d150793b1615a72905657bbeaf49ed1b54d959 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 5 Sep 2006 09:00:55 +0000 Subject: tesseract: add 1.0, tesseract is a OCR engine --- packages/tesseract/.mtn2git_empty | 0 packages/tesseract/tesseract_1.0.bb | 11 +++++++++++ 2 files changed, 11 insertions(+) create mode 100644 packages/tesseract/.mtn2git_empty create mode 100644 packages/tesseract/tesseract_1.0.bb diff --git a/packages/tesseract/.mtn2git_empty b/packages/tesseract/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/tesseract/tesseract_1.0.bb b/packages/tesseract/tesseract_1.0.bb new file mode 100644 index 0000000000..8543add52f --- /dev/null +++ b/packages/tesseract/tesseract_1.0.bb @@ -0,0 +1,11 @@ +DESCRIPTION = "A commercial quality OCR engine " +LICENSE = "APL + others" + +DEPENDS = "tiff" + +SRC_URI = "${SOURCEFORGE_MIRROR}/${PN}-ocr/${P}.tar.gz" + +inherit autotools pkgconfig + + + -- cgit v1.2.3 From 203293cfb151dbd7eab7bc797b7b949afa8a3ba1 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 5 Sep 2006 09:08:31 +0000 Subject: angstrom: set correct mail address --- conf/distro/include/angstrom.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/distro/include/angstrom.inc b/conf/distro/include/angstrom.inc index 96bc33ede3..7d125ae25b 100644 --- a/conf/distro/include/angstrom.inc +++ b/conf/distro/include/angstrom.inc @@ -9,7 +9,7 @@ DISTRO_NAME = "Angstrom" ANGSTROM_URI = "http://www.angstrom-distribution.org" #Set the default maintainer to angstrom-dev -MAINTAINER = "Angstrom Developers " +MAINTAINER = "Angstrom Developers " #use ipkg package format with debian style naming #use multimachine buildrules -- cgit v1.2.3 From 331ec17a16ea8be41fe2a0e5c4fa272b568f319b Mon Sep 17 00:00:00 2001 From: Chris Larson Date: Tue, 5 Sep 2006 11:32:08 +0000 Subject: patch.bbclass: fix issue encountered by zecke, where PatchTree was only doing a --dry-run, never actually applying the patch. Only quilt-native in oe was using that. --- classes/patch.bbclass | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/classes/patch.bbclass b/classes/patch.bbclass index 5e40b3dc0d..f0232adf1e 100644 --- a/classes/patch.bbclass +++ b/classes/patch.bbclass @@ -120,21 +120,20 @@ def patch_init(d): self.patches.insert(self._current or 0, patch) def _applypatch(self, patch, force = None, reverse = None): - shellcmd = ["patch", "<", patch['file'], "-p", patch['strippath']] + shellcmd = ["cat", patch['file'], "|", "patch", "-p", patch['strippath']] if reverse: shellcmd.append('-R') - shellcmd.append('--dry-run') - try: - output = runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) - except CmdError: - if force: - shellcmd.pop(len(shellcmd) - 1) - output = runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) - else: - import sys - raise sys.exc_value + if not force: + shellcmd.append('--dry-run') + + output = runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) + + if force: + return + shellcmd.pop(len(shellcmd) - 1) + output = runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) return output def Push(self, force = None, all = None): -- cgit v1.2.3 From ae4f8efa3e3985d529df6371a1152b454be36674 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Tue, 5 Sep 2006 14:00:38 +0000 Subject: add hnb, a nice text-mode outliner --- packages/hnb/.mtn2git_empty | 0 packages/hnb/hnb_1.9.17+1.9.18pre7.bb | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 packages/hnb/.mtn2git_empty create mode 100644 packages/hnb/hnb_1.9.17+1.9.18pre7.bb diff --git a/packages/hnb/.mtn2git_empty b/packages/hnb/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/hnb/hnb_1.9.17+1.9.18pre7.bb b/packages/hnb/hnb_1.9.17+1.9.18pre7.bb new file mode 100644 index 0000000000..b907665bc8 --- /dev/null +++ b/packages/hnb/hnb_1.9.17+1.9.18pre7.bb @@ -0,0 +1,19 @@ +DESCRIPTION = "hnb is a text-mode hierarchical outliner" +SECTION = "console/pim" +HOMEPAGE = "http://hnb.sf.net" +LICENSE = "GPL" +DEPENDS = "ncurses" +MAINTAINER = "Michael 'Mickey' Lauer " + +SRC_URI = "http://hnb.sourceforge.net/.files/hnb-1.9.18.pre7.tar.gz" +S = "${WORKDIR}/hnb-1.9.18.pre7" + +EXTRA_OEMAKE = '"LIBS=-L${STAGING_LIBDIR} -lncurses libcli/libcli.a"' + +do_install() { + install -d ${D}${bindir} + install -m 0755 src/hnb ${D}${bindir} + install -d ${D}${mandir}/man1 + install -m 0644 doc/hnb.1 ${D}${mandir}/man1/ +} + -- cgit v1.2.3 From dbae8df533dc665215286adb3d8dfd99085b5d84 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Tue, 5 Sep 2006 15:07:52 +0000 Subject: added alsa support to generic device table --- packages/initscripts/initscripts-1.0/device_table.txt | 18 ++++++++++++++++++ packages/initscripts/initscripts-1.0/devices | 1 + 2 files changed, 19 insertions(+) diff --git a/packages/initscripts/initscripts-1.0/device_table.txt b/packages/initscripts/initscripts-1.0/device_table.txt index 35560b4025..a302c5aca3 100644 --- a/packages/initscripts/initscripts-1.0/device_table.txt +++ b/packages/initscripts/initscripts-1.0/device_table.txt @@ -160,6 +160,24 @@ /dev/smtpe2 c 640 0 0 35 130 - - - /dev/smtpe3 c 640 0 0 35 131 - - - /dev/sndstat c 660 0 29 14 6 - - - +/dev/snd/seq c 660 0 0 116 1 - - - +/dev/snd/timer c 660 0 0 116 33 - - - +/dev/snd/controlC0 c 660 0 0 116 0 - - - +/dev/snd/controlC1 c 660 0 0 116 32 - - - +/dev/snd/controlC2 c 660 0 0 116 64 - - - +/dev/snd/controlC3 c 660 0 0 116 96 - - - +/dev/snd/hwC0D0 c 660 0 0 116 4 - - - +/dev/snd/hwC0D1 c 660 0 0 116 5 - - - +/dev/snd/hwC0D2 c 660 0 0 116 6 - - - +/dev/snd/hwC0D3 c 660 0 0 116 7 - - - +/dev/snd/pcmC0D0c c 660 0 0 116 24 - - - +/dev/snd/pcmC0D0p c 660 0 0 116 16 - - - +/dev/snd/pcmC0D1c c 660 0 0 116 25 - - - +/dev/snd/pcmC0D1p c 660 0 0 116 17 - - - +/dev/snd/pcmC0D2c c 660 0 0 116 26 - - - +/dev/snd/pcmC0D2p c 660 0 0 116 18 - - - +/dev/snd/pcmC0D3c c 660 0 0 116 27 - - - +/dev/snd/pcmC0D3p c 660 0 0 116 19 - - - /dev/st0 c 660 0 11 9 0 - - - /dev/st0a c 660 0 11 9 96 - - - /dev/st0l c 660 0 11 9 32 - - - diff --git a/packages/initscripts/initscripts-1.0/devices b/packages/initscripts/initscripts-1.0/devices index fb0f851d16..67a2ec8092 100755 --- a/packages/initscripts/initscripts-1.0/devices +++ b/packages/initscripts/initscripts-1.0/devices @@ -50,6 +50,7 @@ else mkdir -p dev/msys mkdir -p dev/pts mkdir -p dev/vc + mkdir -p dev/snd for i in 0 1 2 3 4 5 6 7 8 9; do ln -s /dev/tty$i /dev/vc/$i done -- cgit v1.2.3 From e435f8ed32d3a89586827267af7f1ce6142a889d Mon Sep 17 00:00:00 2001 From: Justin Patrin Date: Tue, 5 Sep 2006 16:28:02 +0000 Subject: mtnpatch: resurrect mtnpatch --- contrib/mtnpatch.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100755 contrib/mtnpatch.py diff --git a/contrib/mtnpatch.py b/contrib/mtnpatch.py new file mode 100755 index 0000000000..73143dba69 --- /dev/null +++ b/contrib/mtnpatch.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +import sys, os, string, getopt, re + +mtncmd = "monotone" + +def main(argv = None): + if argv is None: + argv = sys.argv + opts, list = getopt.getopt(sys.argv[1:], ':R') + if len(list) < 1: + print "You must specify a file" + return 2 + reverse = False + for o, a in opts: + if o == "-R": + reverse = True + if os.path.exists(list[0]): + input = open(list[0], 'r') + renameFrom = "" + cmd = "" + if reverse: + print "patch -R -p0 < %s" % list[0] + else: + print "patch -p0 < %s" % list[0] + for line in input: + if len(line) > 0: + if line[0] == '#': + matches = re.search("#\s+(\w+)\s+\"(.*)\"", line) + if matches is not None: + cmd = matches.group(1) + fileName = matches.group(2) + if cmd == "delete_file": + if reverse: + print "%s add %s" % (mtncmd, fileName) + else: + print "%s drop -e %s" % (mtncmd, fileName) + elif cmd == "add_file": + if reverse: + print "%s drop -e %s" % (mtncmd, fileName) + else: + print "%s add %s" % (mtncmd, fileName) + elif cmd == "rename_file": + renameFrom = fileName + elif cmd == "to" and renameFrom != "": + if reverse: + print "%s rename -e %s %s" % (mtncmd, fileName, renameFrom) + else: + print "%s rename -e %s %s" % (mtncmd, renameFrom, fileName) + renameFrom = "" + else: + cmd = "" + +if __name__ == "__main__": + sys.exit(main()) -- cgit v1.2.3 From 54f6e2623012b4ac6bd1b87523e6981bbed14dfb Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 5 Sep 2006 17:21:09 +0000 Subject: gpe-shield: test run of Cyril's sanitizer and drop obsolete versions --- packages/gpe-shield/gpe-shield-0.2/.mtn2git_empty | 0 packages/gpe-shield/gpe-shield-0.2/makefile.patch | 79 ---------------------- packages/gpe-shield/gpe-shield-0.6/.mtn2git_empty | 0 .../gpe-shield-0.6/backend-iptables.patch | 71 ------------------- .../gpe-shield/gpe-shield-0.6/desktop-name.patch | 15 ---- packages/gpe-shield/gpe-shield-0.7/.mtn2git_empty | 0 packages/gpe-shield/gpe-shield-0.7/nostropts.patch | 34 ---------- packages/gpe-shield/gpe-shield_0.2.bb | 15 ---- packages/gpe-shield/gpe-shield_0.3.bb | 14 ---- packages/gpe-shield/gpe-shield_0.4.bb | 15 ---- packages/gpe-shield/gpe-shield_0.6.bb | 15 ---- packages/gpe-shield/gpe-shield_0.7.bb | 10 --- packages/gpe-shield/gpe-shield_0.8.bb | 11 --- packages/gpe-shield/gpe-shield_0.9.bb | 11 +-- 14 files changed, 7 insertions(+), 283 deletions(-) delete mode 100644 packages/gpe-shield/gpe-shield-0.2/.mtn2git_empty delete mode 100644 packages/gpe-shield/gpe-shield-0.2/makefile.patch delete mode 100644 packages/gpe-shield/gpe-shield-0.6/.mtn2git_empty delete mode 100644 packages/gpe-shield/gpe-shield-0.6/backend-iptables.patch delete mode 100644 packages/gpe-shield/gpe-shield-0.6/desktop-name.patch delete mode 100644 packages/gpe-shield/gpe-shield-0.7/.mtn2git_empty delete mode 100644 packages/gpe-shield/gpe-shield-0.7/nostropts.patch delete mode 100644 packages/gpe-shield/gpe-shield_0.2.bb delete mode 100644 packages/gpe-shield/gpe-shield_0.3.bb delete mode 100644 packages/gpe-shield/gpe-shield_0.4.bb delete mode 100644 packages/gpe-shield/gpe-shield_0.6.bb delete mode 100644 packages/gpe-shield/gpe-shield_0.7.bb delete mode 100644 packages/gpe-shield/gpe-shield_0.8.bb diff --git a/packages/gpe-shield/gpe-shield-0.2/.mtn2git_empty b/packages/gpe-shield/gpe-shield-0.2/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/gpe-shield/gpe-shield-0.2/makefile.patch b/packages/gpe-shield/gpe-shield-0.2/makefile.patch deleted file mode 100644 index 58c4c0bd00..0000000000 --- a/packages/gpe-shield/gpe-shield-0.2/makefile.patch +++ /dev/null @@ -1,79 +0,0 @@ -? .tm_project.cache -? gpe-shield -? gpe-shield.desktop -? gpe-shield_0.2.batch -? gpe-shield_0.2_arm.ipk -? gpe-shield_0.2_arm.ipk.asc -? gpe-shield_0.2_arm.ipk.upload.html -? makefile.patch -? po -Index: Makefile -=================================================================== -RCS file: /cvs/gpe/base/gpe-shield/Makefile,v -retrieving revision 1.2 -diff -r1.2 Makefile -14a15,17 -> GTKCFLAGS = `pkg-config --cflags gtk+-2.0 gdk-2.0` -> GTKLDFLAGS = `pkg-config --libs gtk+-2.0 gdk-2.0` -> -16,17c19,20 -< GTKLDFLAGS += -L../libgpewidget -L. -< CFLAGS += -Wall -I../libgpewidget -I. ---- -> PACKAGE_LDFLAGS += -L../libgpewidget -L. -> PACKAGE_CFLAGS += -I../libgpewidget -I. -20d22 -< GTKCFLAGS += -I$(PREFIX)/include/gpe -23a26,30 -> PACKAGE_CPPFLAGS = $(STANDARD_CPPFLAGS) -> PACKAGE_CFLAGS += $(STANDARD_CFLAGS) $(GTKCFLAGS) $(GPECFLAGS) -> PACKAGE_LDFLAGS += $(STANDARD_LDFLAGS) $(GPELIBS) $(GTKLDFLAGS) -> -> -27c34 -< CFLAGS += -g -DDEBUG ---- -> PACKAGE_CFLAGS += -g -DDEBUG -29c36 -< CFLAGS += -Os -fomit-frame-pointer ---- -> PACKAGE_CFLAGS += -Os -fomit-frame-pointer -32,58c39,40 -< CFLAGS += -DVERSION=\"$(VERSION)\" -DPREFIX=\"$(PREFIX)\" -D_GNU_SOURCE -< CFLAGS += -DPACKAGE=\"$(PACKAGE)\" -DPACKAGE_LOCALE_DIR=\"$(PREFIX)/share/locale\" -< -< GTKCFLAGS += `pkg-config --cflags gtk+-2.0 gdk-pixbuf-2.0` -< GTKLDFLAGS += `pkg-config --libs gtk+-2.0 gdk-2.0 gdk-pixbuf-2.0` -< -< # setup how to compile -< ifeq ($(NATIVE),yes) -< -< STRIP=strip -< CC=gcc -< -< CFLAGS += $(GTKCFLAGS) -Wall -< LDFLAGS += -lgpewidget $(GTKLDFLAGS) -< -< else # we do cross-compile... -< -< CC=arm-linux-gcc -< STRIP=arm-linux-strip -< -< CFLAGS += -march=armv4 -mtune=strongarm -< CFLAGS += $(GTKCFLAGS) -Wall -< LDFLAGS += -lgpewidget $(GTKLDFLAGS) -Wall -< LDFLAGS += -lXinerama -< -< endif #native or cross-compile -< ---- -> PACKAGE_CFLAGS += -DVERSION=\"$(VERSION)\" -DPREFIX=\"$(PREFIX)\" -D_GNU_SOURCE -> PACKAGE_CFLAGS += -DPACKAGE=\"$(PACKAGE)\" -DPACKAGE_LOCALE_DIR=\"$(PREFIX)/share/locale\" -70c52 -< $(CC) -g -o $@ $(OBJS) $(LDFLAGS) -lgpewidget $(GTKLDFLAGS) ---- -> $(CC) -g -o $@ $(OBJS) $(LDFLAGS) $(PACKAGE_LDFLAGS) -80c62 -< for i in $(PIXMAPS); do install -m 644 -D pixmaps/$$i $(DESTDIR)$(PREFIX)/share/pixmaps/$$i; done ---- -> for i in $(PIXMAPS); do install -m 4755 -D pixmaps/$$i $(DESTDIR)$(PREFIX)/share/pixmaps/$$i; done diff --git a/packages/gpe-shield/gpe-shield-0.6/.mtn2git_empty b/packages/gpe-shield/gpe-shield-0.6/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/gpe-shield/gpe-shield-0.6/backend-iptables.patch b/packages/gpe-shield/gpe-shield-0.6/backend-iptables.patch deleted file mode 100644 index 5c306be02f..0000000000 --- a/packages/gpe-shield/gpe-shield-0.6/backend-iptables.patch +++ /dev/null @@ -1,71 +0,0 @@ -Index: backend.c -=================================================================== -RCS file: /cvs/gpe/base/gpe-shield/backend.c,v -retrieving revision 1.8 -diff -u -r1.8 backend.c ---- backend.c 21 Jun 2004 08:54:53 -0000 1.8 -+++ backend.c 16 Aug 2004 12:17:54 -0000 -@@ -41,6 +41,7 @@ - #define IPTABLES_CMD1 "/usr/sbin/iptables" - #define IPTABLES_CMD2 "/sbin/iptables" - #define IPTABLES_CMD3 "/usr/local/sbin/iptables" -+#define IPTABLES_CMD4 "/usr/bin/iptables" - - static const char* IPTABLES_CMD = NULL; - -@@ -144,13 +145,17 @@ - void - do_clear(void) - { -- char* cmd = g_strdup_printf("%s %s",IPTABLES_CMD,"--flush"); -+ char* cmd; -+ -+ cmd = g_strdup_printf("%s %s",IPTABLES_CMD,"--flush"); - system(cmd); -+ - g_free(cmd); - cmd = g_strdup_printf("%s %s",IPTABLES_CMD,"-P INPUT ACCEPT"); /* reset input policy */ - system(cmd); - g_free(cmd); - g_free(rule_info); -+ - rule_info = NULL; - rule_count = 0; - } -@@ -387,6 +392,7 @@ - - pfd[0].fd = sock; - pfd[0].events = (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI); -+ - while (poll (pfd, 1, -1) > 0) - { - if ((pfd[0].revents & POLLERR) || (pfd[0].revents & POLLHUP)) -@@ -497,7 +503,8 @@ - IPTABLES_CMD = IPTABLES_CMD2; - else if (!access(IPTABLES_CMD3,X_OK)) - IPTABLES_CMD = IPTABLES_CMD3; -- -+ else if (!access(IPTABLES_CMD4,X_OK)) -+ IPTABLES_CMD = IPTABLES_CMD4; - } - - /* app mainloop */ -@@ -505,8 +512,16 @@ - int - suidloop (int csock) - { -- find_iptables(); -- -+ find_iptables(); -+ -+ if (IPTABLES_CMD == NULL) -+ { -+ fprintf(stderr, "Iptables not found, exiting.\n"); -+ close (sock); -+ unlink (PK_SOCKET); -+ exit (2); -+ } -+ - sock = csock; - - while (wait_message ()) ; diff --git a/packages/gpe-shield/gpe-shield-0.6/desktop-name.patch b/packages/gpe-shield/gpe-shield-0.6/desktop-name.patch deleted file mode 100644 index c2afd3907e..0000000000 --- a/packages/gpe-shield/gpe-shield-0.6/desktop-name.patch +++ /dev/null @@ -1,15 +0,0 @@ -Index: gpe-shield.desktop.in -=================================================================== -RCS file: /cvs/gpe/base/gpe-shield/gpe-shield.desktop.in,v -retrieving revision 1.1 -retrieving revision 1.2 -diff -u -r1.1 -r1.2 ---- gpe-shield.desktop.in 4 Jun 2004 14:51:41 -0000 1.1 -+++ gpe-shield.desktop.in 2 Sep 2004 22:16:43 -0000 1.2 -@@ -1,5 +1,5 @@ - [Desktop Entry] --_Name=Desktop Firewall -+_Name=Network Shield - _Comment=Change security settings and access control - Exec=gpe-shield - Terminal=0 diff --git a/packages/gpe-shield/gpe-shield-0.7/.mtn2git_empty b/packages/gpe-shield/gpe-shield-0.7/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/gpe-shield/gpe-shield-0.7/nostropts.patch b/packages/gpe-shield/gpe-shield-0.7/nostropts.patch deleted file mode 100644 index 83740c7a8f..0000000000 --- a/packages/gpe-shield/gpe-shield-0.7/nostropts.patch +++ /dev/null @@ -1,34 +0,0 @@ - -# -# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher -# - ---- gpe-shield-0.7/interface.c~nostropts.patch 2004-09-21 12:35:30.000000000 -0400 -+++ gpe-shield-0.7/interface.c 2005-01-04 15:43:49.604380608 -0500 -@@ -18,26 +18,6 @@ - #include - #include - #include --#include --#include --#include --#include --#include --#include -- --#include --#include --#define _(x) gettext(x) -- --#include -- --#include --#include --#include --#include --#include --#include --#include - #include - #include - #include diff --git a/packages/gpe-shield/gpe-shield_0.2.bb b/packages/gpe-shield/gpe-shield_0.2.bb deleted file mode 100644 index f5766871bc..0000000000 --- a/packages/gpe-shield/gpe-shield_0.2.bb +++ /dev/null @@ -1,15 +0,0 @@ -PR = "r1" -LICENSE = "GPL" -inherit gpe pkgconfig - -DEPENDS = "libgpewidget iptables" -SECTION = "gpe" -MAINTAINER = "Florian Boor " - -DESCRIPTION = "GPE network security tool" -export CVSBUILD = "no" - -SRC_URI = "${GPE_MIRROR}/${PN}-${PV}.tar.gz \ - file://${FILESDIR}/makefile.patch;patch=1;pnum=0" - - diff --git a/packages/gpe-shield/gpe-shield_0.3.bb b/packages/gpe-shield/gpe-shield_0.3.bb deleted file mode 100644 index 7fe229e35d..0000000000 --- a/packages/gpe-shield/gpe-shield_0.3.bb +++ /dev/null @@ -1,14 +0,0 @@ -PR = "r0" -LICENSE = "GPL" -inherit gpe pkgconfig - -DEPENDS = "libgpewidget iptables" -SECTION = "gpe" -MAINTAINER = "Florian Boor " - -DESCRIPTION = "GPE network security tool" -export CVSBUILD = "no" - -SRC_URI = "${GPE_MIRROR}/${PN}-${PV}.tar.gz" - - diff --git a/packages/gpe-shield/gpe-shield_0.4.bb b/packages/gpe-shield/gpe-shield_0.4.bb deleted file mode 100644 index 8a9d5b693c..0000000000 --- a/packages/gpe-shield/gpe-shield_0.4.bb +++ /dev/null @@ -1,15 +0,0 @@ -PR = "r0" -LICENSE = "GPL" -inherit gpe pkgconfig - -DEPENDS = "libgpewidget iptables" -RDEPENDS = "iptables" -SECTION = "gpe" -MAINTAINER = "Florian Boor " - -DESCRIPTION = "GPE network security tool" -export CVSBUILD = "no" - -SRC_URI = "${GPE_MIRROR}/${PN}-${PV}.tar.gz" - - diff --git a/packages/gpe-shield/gpe-shield_0.6.bb b/packages/gpe-shield/gpe-shield_0.6.bb deleted file mode 100644 index eff82cb38d..0000000000 --- a/packages/gpe-shield/gpe-shield_0.6.bb +++ /dev/null @@ -1,15 +0,0 @@ -PR = "r2" -LICENSE = "GPL" -inherit gpe pkgconfig - -DEPENDS = "libgpewidget iptables" -RDEPENDS = "iptables" -SECTION = "gpe" -MAINTAINER = "Florian Boor " - -DESCRIPTION = "GPE network security tool" -export CVSBUILD = "no" - -SRC_URI = "${GPE_MIRROR}/${PN}-${PV}.tar.gz \ - file://backend-iptables.patch;patch=1;pnum=0 \ - file://desktop-name.patch;patch=1;pnum=0" diff --git a/packages/gpe-shield/gpe-shield_0.7.bb b/packages/gpe-shield/gpe-shield_0.7.bb deleted file mode 100644 index fdce8c91c2..0000000000 --- a/packages/gpe-shield/gpe-shield_0.7.bb +++ /dev/null @@ -1,10 +0,0 @@ -PR = "r1" -inherit gpe pkgconfig -LICENSE = "GPL" -DEPENDS = "libgpewidget iptables" -RDEPENDS = "iptables" -SECTION = "gpe" -MAINTAINER = "Florian Boor " - -DESCRIPTION = "GPE network security tool" -SRC_URI += "file://nostropts.patch;patch=1" diff --git a/packages/gpe-shield/gpe-shield_0.8.bb b/packages/gpe-shield/gpe-shield_0.8.bb deleted file mode 100644 index ce6843a468..0000000000 --- a/packages/gpe-shield/gpe-shield_0.8.bb +++ /dev/null @@ -1,11 +0,0 @@ -PR = "r1" -inherit gpe pkgconfig -LICENSE = "GPL" -DEPENDS = "libgpewidget iptables virtual/kernel" -RDEPENDS = "iptables" -RRECOMMENDS = "kernel-module-ipt-state" -SECTION = "gpe" -MAINTAINER = "Florian Boor " - -DESCRIPTION = "GPE network security tool" - diff --git a/packages/gpe-shield/gpe-shield_0.9.bb b/packages/gpe-shield/gpe-shield_0.9.bb index fd1d2c4a17..898d67a181 100644 --- a/packages/gpe-shield/gpe-shield_0.9.bb +++ b/packages/gpe-shield/gpe-shield_0.9.bb @@ -1,11 +1,14 @@ -PR = "r0" +DESCRIPTION = "GPE network security tool" +SECTION = "gpe" +MAINTAINER = "Florian Boor " LICENSE = "GPL" + DEPENDS = "libgpewidget iptables virtual/kernel" RDEPENDS = "iptables" RRECOMMENDS = "kernel-module-ipt-state" -SECTION = "gpe" -MAINTAINER = "Florian Boor " -DESCRIPTION = "GPE network security tool" +PR = "r0" inherit gpe pkgconfig + + -- cgit v1.2.3 From df4ea569ef7a9c2b0498fa924280acbd580de94a Mon Sep 17 00:00:00 2001 From: Chris Larson Date: Tue, 5 Sep 2006 19:23:39 +0000 Subject: patch.bbclass: Fix bug in PatchTree.Import resulting in new patches being imported -before- the current patch rather than -after-. --- classes/patch.bbclass | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/classes/patch.bbclass b/classes/patch.bbclass index f0232adf1e..e3b89ba4f9 100644 --- a/classes/patch.bbclass +++ b/classes/patch.bbclass @@ -117,7 +117,11 @@ def patch_init(d): """""" PatchSet.Import(self, patch, force) - self.patches.insert(self._current or 0, patch) + if self._current is not None: + i = self._current + 1 + else: + i = 0 + self.patches.insert(i, patch) def _applypatch(self, patch, force = None, reverse = None): shellcmd = ["cat", patch['file'], "|", "patch", "-p", patch['strippath']] @@ -137,18 +141,22 @@ def patch_init(d): return output def Push(self, force = None, all = None): + bb.note("self._current is %s" % self._current) + bb.note("patches is %s" % self.patches) if all: for i in self.patches: if self._current is not None: self._current = self._current + 1 else: self._current = 0 + bb.note("applying patch %s" % i) self._applypatch(i, force) else: if self._current is not None: self._current = self._current + 1 else: self._current = 0 + bb.note("applying patch %s" % self.patches[self._current]) self._applypatch(self.patches[self._current], force) -- cgit v1.2.3 From fe5bfb0d15b118e0c590e752ed320593604b5094 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 5 Sep 2006 19:52:45 +0000 Subject: fuse: fix RRECOMMEND(S) --- packages/fuse/fuse-module_2.4.2.bb | 33 --------------------------------- packages/fuse/fuse-module_2.5.3.bb | 4 +++- packages/fuse/fuse_2.4.2.bb | 23 ----------------------- packages/fuse/fuse_2.5.3.bb | 4 +++- 4 files changed, 6 insertions(+), 58 deletions(-) delete mode 100644 packages/fuse/fuse-module_2.4.2.bb delete mode 100644 packages/fuse/fuse_2.4.2.bb diff --git a/packages/fuse/fuse-module_2.4.2.bb b/packages/fuse/fuse-module_2.4.2.bb deleted file mode 100644 index 512f0453a1..0000000000 --- a/packages/fuse/fuse-module_2.4.2.bb +++ /dev/null @@ -1,33 +0,0 @@ -HOMEPAGE = "http://fuse.sf.net" -DESCRIPTION = "With FUSE it is possible to implement a fully functional filesystem in a userspace program" -MAINTAINER = "Koen Kooi " - -LICENSE = "GPL" - - -DEPENDS = "fakeroot-native" -RRECOMMEND = "fuse" - -SRC_URI="${SOURCEFORGE_MIRROR}/fuse/fuse-${PV}.tar.gz" -S = "${WORKDIR}/fuse-${PV}" - -inherit autotools pkgconfig module -EXTRA_OECONF = " --with-kernel=${STAGING_KERNEL_DIR}" - -do_configure() { -cd ${S} ; oe_runconf -} - -do_compile(){ -LDFLAGS="" -cd ${S}/kernel -oe_runmake -} - -fakeroot do_install() { -LDFLAGS="" -cd ${S}/kernel -oe_runmake install DESTDIR=${D} -} - -FILES_${PN} = "/dev /lib/modules" diff --git a/packages/fuse/fuse-module_2.5.3.bb b/packages/fuse/fuse-module_2.5.3.bb index 94cd87c603..0b887ba4bc 100644 --- a/packages/fuse/fuse-module_2.5.3.bb +++ b/packages/fuse/fuse-module_2.5.3.bb @@ -6,7 +6,9 @@ LICENSE = "GPL" DEPENDS = "fakeroot-native" -RRECOMMEND = "fuse" +RRECOMMENDS = "fuse" + +PR = "r1" SRC_URI="${SOURCEFORGE_MIRROR}/fuse/fuse-${PV}.tar.gz" S = "${WORKDIR}/fuse-${PV}" diff --git a/packages/fuse/fuse_2.4.2.bb b/packages/fuse/fuse_2.4.2.bb deleted file mode 100644 index a51c659153..0000000000 --- a/packages/fuse/fuse_2.4.2.bb +++ /dev/null @@ -1,23 +0,0 @@ -HOMEPAGE = "http://fuse.sf.net" -DESCRIPTION = "With FUSE it is possible to implement a fully functional filesystem in a userspace program" -MAINTAINER = "Koen Kooi " - -LICENSE_${PN} = "LGPL" - -DEPENDS = "fakeroot-native" -RRECOMMENDS_${PN} = "fuse-module" - -SRC_URI="${SOURCEFORGE_MIRROR}/fuse/${P}.tar.gz" - -inherit autotools pkgconfig -EXTRA_OECONF = " --disable-kernel-module" - -fakeroot do_install() { -oe_runmake install DESTDIR=${D} -} - -fakeroot do_stage() { -autotools_stage_all -} - - diff --git a/packages/fuse/fuse_2.5.3.bb b/packages/fuse/fuse_2.5.3.bb index 8aa1f3578d..2f893d5192 100644 --- a/packages/fuse/fuse_2.5.3.bb +++ b/packages/fuse/fuse_2.5.3.bb @@ -4,8 +4,10 @@ MAINTAINER = "Koen Kooi " LICENSE_${PN} = "LGPL" +PR = "r1" + DEPENDS = "fakeroot-native" -RRECOMMENDS_${PN} = "fuse-module" +RRECOMMENDS_${PN} = "fuse-module kernel-module-fuse" #package utils in a sperate package and stop debian.bbclass renaming it to libfuse-utils, we want it to be fuse-utils PACKAGES += "fuse-utils" -- cgit v1.2.3 From 3991d9efe92fa183899a15fdf928582f53044bbe Mon Sep 17 00:00:00 2001 From: Chris Larson Date: Tue, 5 Sep 2006 20:09:10 +0000 Subject: Add 'rebuild' task to base.bbclass, as it's quite useful and simple to add. --- classes/base.bbclass | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/classes/base.bbclass b/classes/base.bbclass index 51b6d2111f..80e0b82198 100644 --- a/classes/base.bbclass +++ b/classes/base.bbclass @@ -324,6 +324,16 @@ python base_do_clean() { os.system('rm -f '+ dir) } +addtask rebuild +do_rebuild[dirs] = "${TOPDIR}" +do_rebuild[nostamp] = "1" +do_rebuild[bbdepcmd] = "" +python base_do_rebuild() { + """rebuild a package""" + bb.build.exec_task('do_clean', d) + bb.build.exec_task('do_' + bb.data.getVar('BB_DEFAULT_TASK', d, 1), d) +} + addtask mrproper do_mrproper[dirs] = "${TOPDIR}" do_mrproper[nostamp] = "1" @@ -685,7 +695,7 @@ python () { # Patch handling inherit patch -EXPORT_FUNCTIONS do_clean do_mrproper do_fetch do_unpack do_configure do_compile do_install do_package do_populate_pkgs do_stage +EXPORT_FUNCTIONS do_clean do_mrproper do_fetch do_unpack do_configure do_compile do_install do_package do_populate_pkgs do_stage do_rebuild MIRRORS[func] = "0" MIRRORS () { -- cgit v1.2.3 From c2255f38d6a6c4a2bab571ab2cf547d7493891cd Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Tue, 5 Sep 2006 20:10:35 +0000 Subject: gpe-buttonbox: fix embarrasing typos --- packages/gpe-buttonbox/gpe-buttonbox_0.5.bb | 2 +- packages/gpe-buttonbox/gpe-buttonbox_cvs.bb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/gpe-buttonbox/gpe-buttonbox_0.5.bb b/packages/gpe-buttonbox/gpe-buttonbox_0.5.bb index dcf8640611..ed69f01df1 100644 --- a/packages/gpe-buttonbox/gpe-buttonbox_0.5.bb +++ b/packages/gpe-buttonbox/gpe-buttonbox_0.5.bb @@ -1,5 +1,5 @@ LICENSE = "GPL" -DESCIPTION = "Buttonbox for gpe" +DESCRIPTION = "Buttonbox for gpe" MAINTAINER = "Koen Kooi " DEPENDS = "libgpewidget libgpelaunch" diff --git a/packages/gpe-buttonbox/gpe-buttonbox_cvs.bb b/packages/gpe-buttonbox/gpe-buttonbox_cvs.bb index 86e5cabcf0..f982c4517f 100644 --- a/packages/gpe-buttonbox/gpe-buttonbox_cvs.bb +++ b/packages/gpe-buttonbox/gpe-buttonbox_cvs.bb @@ -1,6 +1,6 @@ DEFAULT_PREFERENCE = "-1" LICENSE = "GPL" -DESCIPTION = "Buttonbox for gpe" +DESCRIPTION = "Buttonbox for gpe" SRC_URI = "${HANDHELDS_CVS};module=gpe/base/gpe-buttonbox" -- cgit v1.2.3 From 4826bc3766e6e70e5d2bcaade7a5b1a3f58c92a2 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 6 Sep 2006 11:40:27 +0000 Subject: various: correct typos spotted by Cyril Romain --- packages/otpkeygen/otpkeygen_1.3.0.bb | 2 +- packages/sn9c102/sn9c102_1.32.bb | 2 +- packages/tcp-wrappers/tcp-wrappers_7.6.bb | 2 +- packages/xorg-app/xprop_cvs.bb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/otpkeygen/otpkeygen_1.3.0.bb b/packages/otpkeygen/otpkeygen_1.3.0.bb index b679b4c380..786c5ab835 100644 --- a/packages/otpkeygen/otpkeygen_1.3.0.bb +++ b/packages/otpkeygen/otpkeygen_1.3.0.bb @@ -2,7 +2,7 @@ DESCRIPTION = "OTP S/Key password generator" SECTION = "opie/applications" HOMEPAGE = "http://www.bitrot.de/pda_otpkeygen.html" AUTHOR = "Thomas Driemeyer " -MAINTANER = "Marcin Juszkiewicz " +MAINTAINER = "Marcin Juszkiewicz " LICENSE = "GPL" APPTYPE="binary" PR = "r2" diff --git a/packages/sn9c102/sn9c102_1.32.bb b/packages/sn9c102/sn9c102_1.32.bb index bc2d9d9aa2..fae68d0473 100644 --- a/packages/sn9c102/sn9c102_1.32.bb +++ b/packages/sn9c102/sn9c102_1.32.bb @@ -1,4 +1,4 @@ -DESRIPTION = "Drivers for sn9c10x webcams" +DESCRIPTION = "Drivers for sn9c10x webcams" LICENSE = "GPL" HOMEPAGE = "http://www.linux-projects.org/" SRC_URI = "http://www.linux-projects.org/downloads/${P}.tar.gz" diff --git a/packages/tcp-wrappers/tcp-wrappers_7.6.bb b/packages/tcp-wrappers/tcp-wrappers_7.6.bb index 3531f43463..bff4d720df 100644 --- a/packages/tcp-wrappers/tcp-wrappers_7.6.bb +++ b/packages/tcp-wrappers/tcp-wrappers_7.6.bb @@ -1,4 +1,4 @@ -DESRIPTION = "Tools for monitoring and filtering incoming requests for tcp \ +DESCRIPTION = "Tools for monitoring and filtering incoming requests for tcp \ services." LICENSE = "tcp-wrappers" MAINTAINER = "Chris Larson " diff --git a/packages/xorg-app/xprop_cvs.bb b/packages/xorg-app/xprop_cvs.bb index 1079d6a591..6fb3cf4c59 100644 --- a/packages/xorg-app/xprop_cvs.bb +++ b/packages/xorg-app/xprop_cvs.bb @@ -2,7 +2,7 @@ PV = "0.0+cvs${SRCDATE}" LICENSE = "MIT" DEPENDS = "virtual/libx11 libxmu libxext" DESCRIPTION = "property displayer for X" -MAINTER = "Rene Wagner " +MAINTAINER = "Rene Wagner " SECTION = "x11/base" PR = "r2" -- cgit v1.2.3 From 7d28cdcfb4f95216437f163c891b00dd25a4f7ae Mon Sep 17 00:00:00 2001 From: Cyril Romain Date: Wed, 6 Sep 2006 17:35:43 +0000 Subject: sanitize.py: add a script that does the heavy lifting for making recipes conform to the styleguide in the wiki --- contrib/sanitize.py | 369 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 contrib/sanitize.py diff --git a/contrib/sanitize.py b/contrib/sanitize.py new file mode 100644 index 0000000000..6327653053 --- /dev/null +++ b/contrib/sanitize.py @@ -0,0 +1,369 @@ +#!/usr/bin/env python + +# sanitize a bitbake file following the OpenEmbedded style guidelines +# see http://openembedded.org/wiki/StyleGuide +# (C) 2006 Cyril Romain +# MIT license + +# TODO: +# - add the others OpenEmbedded variables commonly used +# ./ handle comments in .bb files +# - parse command arguments and print usage on misuse +# . prevent giving more than one .bb file in arguments +# - write result to a file +# - backup the original .bb file +# - make a diff and ask confirmation for patching ? +# - /!\ startswith('SOMETHING') is not taken into account due to the previous startswith('S'). +# - count rule breaks and displays them in the order frequence + +from odict import OrderedDict +import fileinput +import string +import re + +__author__ = "Cyril Romain " +__version__ = "$Revision: 0.3 $" + +# The ordered list of OpenEmbedded variables +OE_vars = OrderedDict([ + ('DESCRIPTION', []), + ('AUTHOR', []), + ('HOMEPAGE', []), + ('SECTION', []), + ('PRIORITY', []), + ('MAINTAINER', []), + ('LICENSE', []), + ('DEPENDS', []), + ('RDEPENDS', []), + ('RRECOMMENDS', []), + ('RSUGGESTS', []), + ('PROVIDES', []), + ('RPROVIDES', []), + ('RCONFLICTS', []), + ('SRCDATE', []), + ('PV', []), + ('PR', []), + ('SRC_URI', []), + ('S', []), + ('inherit', []), + ('EXTRA_', []), + ('do_fetch', []), + ('do_unpack', []), + ('do_patch', []), + ('do_configure', []), + ('do_compile', []), + ('do_install', []), + ('do_package', []), + ('do_stage', []), + ('PACKAGE_ARCH', []), + ('PACKAGES', []), + ('FILES', []), + ('WORKDIR', []), + ('acpaths', []), + ('addhandler', []), + ('addtask', []), + ('bindir', []), + ('export', []), + ('headers', []), + ('include', []), + ('includedir', []), + ('python', []), + ('qtopiadir', []), + ('pkg_postins', []), + ('pkg_postrm', []), + ('require', []), + ('sbindir', []), + ('basesysconfdir', []), + ('sysconfdir', []), + ('ALLOW_EMPTY', []), + ('ALTERNATIVE_LINK', []), + ('ALTERNATIVE_NAME', []), + ('ALTERNATIVE_PATH', []), + ('ALTERNATIVE_PRIORITY', []), + ('ALTNAME', []), + ('AMD_DRIVER_LABEL', []), + ('AMD_DRIVER_VERSION', []), + ('ANGSTROM_EXTRA_INSTALL', []), + ('APPDESKTOP', []), + ('APPIMAGE', []), + ('APPNAME', []), + ('APPTYPE', []), + ('APPWEB_BUILD', []), + ('APPWEB_HOST', []), + ('AR', []), + ('ARCH', []), + ('ARM_INSTRUCTION_SET', []), + ('ARM_MUTEX', []), + ('ART_CONFIG', []), + ('B', []), + ('BJAM_OPTS', []), + ('BJAM_TOOLS', []), + ('BONOBO_HEADERS', []), + ('BOOTSCRIPTS', []), + ('BROKEN', []), + ('BUILD_ALL_DEPS', []), + ('BUILD_CPPFLAGS', []), + ('CFLAGS', []), + ('CCFLAGS', []), + ('CMDLINE', []), + ('COLLIE_MEMORY_SIZE', []), + ('COMPATIBLE_HOST', []), + ('COMPATIBLE_MACHINE', []), + ('COMPILE_HERMES', []), + ('CONFFILES', []), + ('CONFLICTS', []), + ('CORE_EXTRA_D', []), + ('CORE_PACKAGES_D', []), + ('CORE_PACKAGES_RD', []), + ('CPPFLAGS', []), + ('CVSDATE', []), + ('CXXFLAGS', []), + ('DEBIAN_NOAUTONAME', []), + ('DEBUG_APPS', []), + ('DEFAULT_PREFERENCE', []), + ('DB4_CONFIG', []), + ('EXCLUDE_FROM_SHLIBS', []), + ('EXCLUDE_FROM_WORLD', []), + ('FIXEDSRCDATE', []), + ('GLIBC_ADDONS', []), + ('GLIBC_EXTRA_OECONF', []), + ('GNOME_VFS_HEADERS', []), + ('GPE_TARBALL_SUFFIX', []), + ('HEADERS', []), + ('INHIBIT_DEFAULT_DEPS', []), + ('INITSCRIPT_NAME', []), + ('INITSCRIPT_PACKAGES', []), + ('INITSCRIPT_PARAMS', []), + ('IPKG_INSTALL', []), + ('KERNEL_IMAGETYPE', []), + ('KERNEL_IMAGEDEST', []), + ('KERNEL_OUTPUT', []), + ('KERNEL_RELEASE', []), + ('KERNEL_PRIORITY', []), + ('KERNEL_SOURCE', []), + ('KERNEL_SUFFIX', []), + ('KERNEL_VERSION', []), + ('K_MAJOR', []), + ('K_MICRO', []), + ('K_MINOR', []), + ('HHV', []), + ('KV', []), + ('LDFLAGS', []), + ('LD', []), + ('LD_SO', []), + ('LDLIBS', []), + ('LEAD_SONAME', []), + ('LIBTOOL', []), + ('LIBBDB_EXTRA', []), + ('LIBV', []), + ('MACHINE', []), + ('MACHINE_ESSENTIAL_EXTRA_RDEPENDS', []), + ('MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS', []), + ('MACHINE_EXTRA_RDEPENDS', []), + ('MACHINE_EXTRA_RRECOMMENDS', []), + ('MACHINE_FEATURES', []), + ('MACHINE_TASKS', []), + ('MACHTYPE', []), + ('MAKE_TARGETS', []), + ('MESSAGEUSER', []), + ('MESSAGEHOME', []), + ('MIRRORS', []), + ('MUTEX', []), + ('OE_QMAKE_INCDIR_QT', []), + ('OE_QMAKE_CXXFLAGS', []), + ('ORBIT_IDL_SRC', []), + ('PARALLEL_MAKE', []), + ('PAKCAGE_ARCH', []), + ('PCMCIA_MANAGER', []), + ('PKG_BASENAME', []), + ('QEMU', []), + ('QMAKE_PROFILES', []), + ('QPEDIR', []), + ('QPF_DESCRIPTION', []), + ('QPF_PKGPATTERN', []), + ('QT_CONFIG_FLAGS', []), + ('QT_LIBRARY', []), + ('ROOTFS_POSTPROCESS_COMMAND', []), + ('RREPLACES', []), + ('TARGET_CFLAGS', []), + ('TARGET_CPPFLAGS', []), + ('TARGET_LDFLAGS', []), + ('UBOOT_MACHINE', []), + ('UCLIBC_BASE', []), + ('UCLIBC_PATCHES', []), + ('UNSLUNG_PACKAGES', []), + ('VIRTUAL_NAME', []), + ('XORG_PN', []), + ('XSERVER', []), + ('others', []) +]) + +varRegexp = r'^([A-Z_0-9]*)([ \t]*?)([+.:]?=[+.]?)([ \t]*?)("[^"]*["\\]?)' +routineRegexp = r'^([a-zA-Z0-9_ -]+?)\(' + +# Style guideline #0: No spaces are allowed at the beginning of lines that define a variable or a do_ routine +def check_rule0(line): + return line.lstrip()==line +def follow_rule0(line): + return line.lstrip() + +# Style guideline #1: No spaces are allowed behind the line continuation symbol '\' +def check_rule1(line): + if line.rstrip().endswith('\\'): + return line.endswith('\\') + else: + return True +def follow_rule1(line): + return line.rstrip() + +# Style guideline #2: Tabs should not be used (use spaces instead). +def check_rule2(line): + return line.count('\t')==0 +def follow_rule2(line): + return line.expandtabs() + +# Style guideline #3: Comments inside bb files are allowed using the '#' character at the beginning of a line. +def check_rule3(line): + if line.lstrip().startswith('#'): + return line.startswith('#') + else: + return True +def follow_rule3(line): + return line.lstrip() + +# Style guideline #4: Use quotes on the right hand side of assignments: FOO = "BAR" +def check_rule4(line): + return re.match(varRegexp, line) is not None +def follow_rule4(line): + return follow_rule5(line) + +# Style guideline #5: The correct spacing for a variable is FOO = "BAR". +def check_rule5(line): + r = re.search(varRegexp, line) + return r is not None and r.group(2)==" " and r.group(4)==" " +def follow_rule5(line): + r = re.search(varRegexp, line) + return ''.join([r.group(1), ' ', r.group(3), ' ', r.group(5)]) + +# Style guideline #6: Don't use spaces or tabs on empty lines +def check_rule6(line): + return not line.isspace() or line=="\n" +def follow_rule6(line): + return "" + +# Style guideline #7: Indentation of multiline variables such as SRC_URI is desireable. +def check_rule7(line): + return True +def follow_rule7(line): + return line + +rules = ( + (check_rule0, follow_rule0, "No spaces are allowed at the beginning of lines that define a variable or a do_ routine"), + (check_rule1, follow_rule1, "No spaces are allowed behind the line continuation symbol '\\'"), + (check_rule2, follow_rule2, "Tabs should not be used (use spaces instead)"), + (check_rule3, follow_rule3, "Comments inside bb files are allowed using the '#' character at the beginning of a line"), + (check_rule4, follow_rule4, "Use quotes on the right hand side of assignments: FOO = \"BAR\""), + (check_rule5, follow_rule5, "The correct spacing for a variable is FOO = \"BAR\""), + (check_rule6, follow_rule6, "Don't use spaces or tabs on empty lines"), + (check_rule7, follow_rule7, "Indentation of multiline variables such as SRC_URI is desireable"), +) + +def follow_rule(i, line): + oldline = line + if not rules[i][0](line): + line = rules[i][1](line) + if not rules[i][0](line): + print "## Rule %d disgression: on this line: " % i, line + print "## Warning: ", rules[i][2] + else: + print "## Reminder: ", rules[i][2], " in :", oldline + return line + + +if __name__ == "__main__": + + # -- retrieves lines of the .bb file -- + lines = [] + for line in fileinput.input(): + if True: + lines.append(line) + else: + # expandtabs on each line so that rule2 is always respected + # rstrip each line so that rule1 is always respected + line = line.expandtabs().rstrip() + # ignore empty lines (or line filled with spaces or tabs only) + # so that rule6 is always respected + if line is not '': + lines.append(line) + + # -- parse the file -- + var = "" + in_routine = False + commentBloc = [] + olines = [] + unknownVar = set() + for line in lines: + line = line.rstrip() + line = follow_rule(2, line) + line = follow_rule(1, line) + line = follow_rule(6, line) + # ignore empty lines + if line.isspace() or line is '': + # flush comments into the olines + for c in commentBloc: olines.append(c) + commentBloc = [] + continue + + if line.startswith('}'): in_routine=False + keep = line.endswith('\\') or in_routine + + # handles commented lines + if line.lstrip().startswith('#'): + # check and follow rule3 if not in a variables or routines + if not in_routine: + line = follow_rule(3, line) + commentBloc.append(line) + continue + + if OE_vars.has_key(var): + for c in commentBloc: + OE_vars[var].append(c) + commentBloc = [] + OE_vars[var].append(line) + else: + varexist = False + for k in OE_vars: + if line.startswith(k): + line = follow_rule(0, line) + varexist = True + if re.match(routineRegexp, line) is not None: + in_routine=True + elif re.match(varRegexp, line) is not None: + line = follow_rule(4, line) + line = follow_rule(5, line) + for c in commentBloc: + OE_vars[k].append(c) + commentBloc = [] + OE_vars[k].append(line) + var = (keep==True or in_routine==True) and k or "" + break + if not varexist: + s = string.split(line)[0].rstrip().lstrip() + if s not in unknownVar: + unknownVar.add(s) + if not in_routine: + print "## Warning: unknown variable/routine \"%s\"" % line + OE_vars['others'].append(line) + if not keep and not in_routine: var = "" + + # -- prepare the sanitized .bb file -- + #for k in OE_vars: print k, OE_vars[k] + addEmptyLine = False + for k in OE_vars: + if k=='SRC_URI': addEmptyLine = True + if OE_vars[k] != []: + if addEmptyLine: olines.append("") + for l in OE_vars[k]: + olines.append(l) + for line in olines: print line + #for i in unknownVar: print i, '\n' \ No newline at end of file -- cgit v1.2.3 From f4c5bad2b962336d79ac962e4f5cb014b311c584 Mon Sep 17 00:00:00 2001 From: Frans Meulenbroeks Date: Wed, 6 Sep 2006 19:21:00 +0000 Subject: puvrusb2-mci: added 20090903 snapshot; made bb file style guide compliant --- .../pvrusb2-mci-20060903/.mtn2git_empty | 0 .../pvrusb2-mci-20060903/Makefile.patch | 25 +++++++++++ packages/pvrusb2-mci/pvrusb2-mci_20060903.bb | 49 ++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 packages/pvrusb2-mci/pvrusb2-mci-20060903/.mtn2git_empty create mode 100644 packages/pvrusb2-mci/pvrusb2-mci-20060903/Makefile.patch create mode 100644 packages/pvrusb2-mci/pvrusb2-mci_20060903.bb diff --git a/packages/pvrusb2-mci/pvrusb2-mci-20060903/.mtn2git_empty b/packages/pvrusb2-mci/pvrusb2-mci-20060903/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/pvrusb2-mci/pvrusb2-mci-20060903/Makefile.patch b/packages/pvrusb2-mci/pvrusb2-mci-20060903/Makefile.patch new file mode 100644 index 0000000000..3db0b2c9d6 --- /dev/null +++ b/packages/pvrusb2-mci/pvrusb2-mci-20060903/Makefile.patch @@ -0,0 +1,25 @@ +*** driver/Makefile.orig 2006-04-02 03:40:31.000000000 +0200 +--- driver/Makefile 2006-04-26 21:56:46.000000000 +0200 +*************** +*** 57,66 **** + CONFIG_VARS+= CONFIG_VIDEO_PVRUSB2_DEBUGIFC=y + + modules modules_install clean: +! $(MAKE) INSTALL_MOD_DIR=$(INSTALL_MOD_DIR) -C $(KDIR) M=$(M) $(CONFIG_VARS) $@ + + install: +! $(MAKE) INSTALL_MOD_DIR=$(INSTALL_MOD_DIR) -C $(KDIR) M=$(M) $(CONFIG_VARS) modules_install + + else + +--- 57,66 ---- + CONFIG_VARS+= CONFIG_VIDEO_PVRUSB2_DEBUGIFC=y + + modules modules_install clean: +! $(MAKE) INSTALL_MOD_DIR=$(INSTALL_MOD_DIR) -C $(KDIR) CFLAGS="$(CFLAGS)" M=$(M) $(CONFIG_VARS) $@ + + install: +! $(MAKE) INSTALL_MOD_DIR=$(INSTALL_MOD_DIR) -C $(KDIR) CFLAGS="$(CFLAGS)" M=$(M) $(CONFIG_VARS) modules_install + + else + diff --git a/packages/pvrusb2-mci/pvrusb2-mci_20060903.bb b/packages/pvrusb2-mci/pvrusb2-mci_20060903.bb new file mode 100644 index 0000000000..c06b34251e --- /dev/null +++ b/packages/pvrusb2-mci/pvrusb2-mci_20060903.bb @@ -0,0 +1,49 @@ +DESCRIPTION = "Driver for the Hauppauge WinTV PVR USB2" +AUTHOR = Mike Isely +HOMEPAGE = "http://www.isely.net/pvrusb2.html" +SECTION = "kernel/modules" +PRIORITY = "optional" +MAINTAINER = "Frans Meulenbroeks " +LICENSE = "GPL" +RRECOMMENDS = "kernel-module-tveeprom \ + kernel-module-firmware-class \ + kernel-module-tuner \ + kernel-module-msp3400 \ + kernel-module-saa7115 \ + kernel-module-tda9887 \ + kernel-module-v4l1-compat \ + kernel-module-v4l2-common \ + kernel-module-videodev" +PR = "r0" + +SRC_URI = "http://www.isely.net/downloads/pvrusb2-mci-${PV}.tar.bz2 \ + file://hotplug.functions \ + file://firmware.hotplug \ + file://Makefile.patch;patch=1" + +S = "${WORKDIR}/pvrusb2-mci-${PV}/driver" + +inherit module + +CFLAGS = "'-I${KERNEL_SOURCE}/include' \ + '-I${KERNEL_SOURCE}/drivers/media/video' " + +CFLAGS_append_arm = " '-D__LINUX_ARM_ARCH__=5' " + +CFLAGS_append_armeb = " '-D__LINUX_ARM_ARCH__=5' " + +EXTRA_OEMAKE = "'V=1' 'CFLAGS=${CFLAGS}' \ + 'CC=${KERNEL_CC}' \ + 'LD=${KERNEL_LD}' \ + 'KDIR=${STAGING_KERNEL_DIR}'" + +export TARGET_LDFLAGS = "-L${STAGING_DIR}/${TARGET_SYS}/lib \ + -Wl,-rpath-link,${STAGING_DIR}/${TARGET_SYS}/lib" + +do_install() { + install -d ${D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/usb/media + install -m 0644 *${KERNEL_OBJECT_SUFFIX} ${D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/usb/media + mkdir -p ${D}/etc/hotplug.d/firmware + cp ${WORKDIR}/hotplug.functions ${D}/etc/hotplug.d/firmware + cp ${WORKDIR}/firmware.hotplug ${D}/etc/hotplug.d/firmware +} -- cgit v1.2.3 From 2ca0a4e92903aff560061711b91d4f0c62795fd9 Mon Sep 17 00:00:00 2001 From: Michael Lauer Date: Wed, 6 Sep 2006 20:28:59 +0000 Subject: calibrateproto: s/DATE/SRCDATE/ --- packages/xorg-proto/calibrateproto_git.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/xorg-proto/calibrateproto_git.bb b/packages/xorg-proto/calibrateproto_git.bb index 964380d943..8c61f3c0a4 100644 --- a/packages/xorg-proto/calibrateproto_git.bb +++ b/packages/xorg-proto/calibrateproto_git.bb @@ -2,7 +2,7 @@ require xorg-proto-common.inc DESCRIPTION = " Touchscreen calibration protocol" -PV = "0.0+git${DATE}" +PV = "0.0+git${SRCDATE}" SRC_URI = "git://anongit.freedesktop.org/git/xorg/proto/calibrateproto;protocol=git" S = "${WORKDIR}/git" -- cgit v1.2.3 From 6c6348e86054763e3f29828d37813a6731460e49 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Thu, 7 Sep 2006 00:44:27 +0000 Subject: sanitize.py: Fix line-endings (dos->unix). --- contrib/sanitize.py | 738 ++++++++++++++++++++++++++-------------------------- 1 file changed, 369 insertions(+), 369 deletions(-) diff --git a/contrib/sanitize.py b/contrib/sanitize.py index 6327653053..3d329730b1 100644 --- a/contrib/sanitize.py +++ b/contrib/sanitize.py @@ -1,369 +1,369 @@ -#!/usr/bin/env python - -# sanitize a bitbake file following the OpenEmbedded style guidelines -# see http://openembedded.org/wiki/StyleGuide -# (C) 2006 Cyril Romain -# MIT license - -# TODO: -# - add the others OpenEmbedded variables commonly used -# ./ handle comments in .bb files -# - parse command arguments and print usage on misuse -# . prevent giving more than one .bb file in arguments -# - write result to a file -# - backup the original .bb file -# - make a diff and ask confirmation for patching ? -# - /!\ startswith('SOMETHING') is not taken into account due to the previous startswith('S'). -# - count rule breaks and displays them in the order frequence - -from odict import OrderedDict -import fileinput -import string -import re - -__author__ = "Cyril Romain " -__version__ = "$Revision: 0.3 $" - -# The ordered list of OpenEmbedded variables -OE_vars = OrderedDict([ - ('DESCRIPTION', []), - ('AUTHOR', []), - ('HOMEPAGE', []), - ('SECTION', []), - ('PRIORITY', []), - ('MAINTAINER', []), - ('LICENSE', []), - ('DEPENDS', []), - ('RDEPENDS', []), - ('RRECOMMENDS', []), - ('RSUGGESTS', []), - ('PROVIDES', []), - ('RPROVIDES', []), - ('RCONFLICTS', []), - ('SRCDATE', []), - ('PV', []), - ('PR', []), - ('SRC_URI', []), - ('S', []), - ('inherit', []), - ('EXTRA_', []), - ('do_fetch', []), - ('do_unpack', []), - ('do_patch', []), - ('do_configure', []), - ('do_compile', []), - ('do_install', []), - ('do_package', []), - ('do_stage', []), - ('PACKAGE_ARCH', []), - ('PACKAGES', []), - ('FILES', []), - ('WORKDIR', []), - ('acpaths', []), - ('addhandler', []), - ('addtask', []), - ('bindir', []), - ('export', []), - ('headers', []), - ('include', []), - ('includedir', []), - ('python', []), - ('qtopiadir', []), - ('pkg_postins', []), - ('pkg_postrm', []), - ('require', []), - ('sbindir', []), - ('basesysconfdir', []), - ('sysconfdir', []), - ('ALLOW_EMPTY', []), - ('ALTERNATIVE_LINK', []), - ('ALTERNATIVE_NAME', []), - ('ALTERNATIVE_PATH', []), - ('ALTERNATIVE_PRIORITY', []), - ('ALTNAME', []), - ('AMD_DRIVER_LABEL', []), - ('AMD_DRIVER_VERSION', []), - ('ANGSTROM_EXTRA_INSTALL', []), - ('APPDESKTOP', []), - ('APPIMAGE', []), - ('APPNAME', []), - ('APPTYPE', []), - ('APPWEB_BUILD', []), - ('APPWEB_HOST', []), - ('AR', []), - ('ARCH', []), - ('ARM_INSTRUCTION_SET', []), - ('ARM_MUTEX', []), - ('ART_CONFIG', []), - ('B', []), - ('BJAM_OPTS', []), - ('BJAM_TOOLS', []), - ('BONOBO_HEADERS', []), - ('BOOTSCRIPTS', []), - ('BROKEN', []), - ('BUILD_ALL_DEPS', []), - ('BUILD_CPPFLAGS', []), - ('CFLAGS', []), - ('CCFLAGS', []), - ('CMDLINE', []), - ('COLLIE_MEMORY_SIZE', []), - ('COMPATIBLE_HOST', []), - ('COMPATIBLE_MACHINE', []), - ('COMPILE_HERMES', []), - ('CONFFILES', []), - ('CONFLICTS', []), - ('CORE_EXTRA_D', []), - ('CORE_PACKAGES_D', []), - ('CORE_PACKAGES_RD', []), - ('CPPFLAGS', []), - ('CVSDATE', []), - ('CXXFLAGS', []), - ('DEBIAN_NOAUTONAME', []), - ('DEBUG_APPS', []), - ('DEFAULT_PREFERENCE', []), - ('DB4_CONFIG', []), - ('EXCLUDE_FROM_SHLIBS', []), - ('EXCLUDE_FROM_WORLD', []), - ('FIXEDSRCDATE', []), - ('GLIBC_ADDONS', []), - ('GLIBC_EXTRA_OECONF', []), - ('GNOME_VFS_HEADERS', []), - ('GPE_TARBALL_SUFFIX', []), - ('HEADERS', []), - ('INHIBIT_DEFAULT_DEPS', []), - ('INITSCRIPT_NAME', []), - ('INITSCRIPT_PACKAGES', []), - ('INITSCRIPT_PARAMS', []), - ('IPKG_INSTALL', []), - ('KERNEL_IMAGETYPE', []), - ('KERNEL_IMAGEDEST', []), - ('KERNEL_OUTPUT', []), - ('KERNEL_RELEASE', []), - ('KERNEL_PRIORITY', []), - ('KERNEL_SOURCE', []), - ('KERNEL_SUFFIX', []), - ('KERNEL_VERSION', []), - ('K_MAJOR', []), - ('K_MICRO', []), - ('K_MINOR', []), - ('HHV', []), - ('KV', []), - ('LDFLAGS', []), - ('LD', []), - ('LD_SO', []), - ('LDLIBS', []), - ('LEAD_SONAME', []), - ('LIBTOOL', []), - ('LIBBDB_EXTRA', []), - ('LIBV', []), - ('MACHINE', []), - ('MACHINE_ESSENTIAL_EXTRA_RDEPENDS', []), - ('MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS', []), - ('MACHINE_EXTRA_RDEPENDS', []), - ('MACHINE_EXTRA_RRECOMMENDS', []), - ('MACHINE_FEATURES', []), - ('MACHINE_TASKS', []), - ('MACHTYPE', []), - ('MAKE_TARGETS', []), - ('MESSAGEUSER', []), - ('MESSAGEHOME', []), - ('MIRRORS', []), - ('MUTEX', []), - ('OE_QMAKE_INCDIR_QT', []), - ('OE_QMAKE_CXXFLAGS', []), - ('ORBIT_IDL_SRC', []), - ('PARALLEL_MAKE', []), - ('PAKCAGE_ARCH', []), - ('PCMCIA_MANAGER', []), - ('PKG_BASENAME', []), - ('QEMU', []), - ('QMAKE_PROFILES', []), - ('QPEDIR', []), - ('QPF_DESCRIPTION', []), - ('QPF_PKGPATTERN', []), - ('QT_CONFIG_FLAGS', []), - ('QT_LIBRARY', []), - ('ROOTFS_POSTPROCESS_COMMAND', []), - ('RREPLACES', []), - ('TARGET_CFLAGS', []), - ('TARGET_CPPFLAGS', []), - ('TARGET_LDFLAGS', []), - ('UBOOT_MACHINE', []), - ('UCLIBC_BASE', []), - ('UCLIBC_PATCHES', []), - ('UNSLUNG_PACKAGES', []), - ('VIRTUAL_NAME', []), - ('XORG_PN', []), - ('XSERVER', []), - ('others', []) -]) - -varRegexp = r'^([A-Z_0-9]*)([ \t]*?)([+.:]?=[+.]?)([ \t]*?)("[^"]*["\\]?)' -routineRegexp = r'^([a-zA-Z0-9_ -]+?)\(' - -# Style guideline #0: No spaces are allowed at the beginning of lines that define a variable or a do_ routine -def check_rule0(line): - return line.lstrip()==line -def follow_rule0(line): - return line.lstrip() - -# Style guideline #1: No spaces are allowed behind the line continuation symbol '\' -def check_rule1(line): - if line.rstrip().endswith('\\'): - return line.endswith('\\') - else: - return True -def follow_rule1(line): - return line.rstrip() - -# Style guideline #2: Tabs should not be used (use spaces instead). -def check_rule2(line): - return line.count('\t')==0 -def follow_rule2(line): - return line.expandtabs() - -# Style guideline #3: Comments inside bb files are allowed using the '#' character at the beginning of a line. -def check_rule3(line): - if line.lstrip().startswith('#'): - return line.startswith('#') - else: - return True -def follow_rule3(line): - return line.lstrip() - -# Style guideline #4: Use quotes on the right hand side of assignments: FOO = "BAR" -def check_rule4(line): - return re.match(varRegexp, line) is not None -def follow_rule4(line): - return follow_rule5(line) - -# Style guideline #5: The correct spacing for a variable is FOO = "BAR". -def check_rule5(line): - r = re.search(varRegexp, line) - return r is not None and r.group(2)==" " and r.group(4)==" " -def follow_rule5(line): - r = re.search(varRegexp, line) - return ''.join([r.group(1), ' ', r.group(3), ' ', r.group(5)]) - -# Style guideline #6: Don't use spaces or tabs on empty lines -def check_rule6(line): - return not line.isspace() or line=="\n" -def follow_rule6(line): - return "" - -# Style guideline #7: Indentation of multiline variables such as SRC_URI is desireable. -def check_rule7(line): - return True -def follow_rule7(line): - return line - -rules = ( - (check_rule0, follow_rule0, "No spaces are allowed at the beginning of lines that define a variable or a do_ routine"), - (check_rule1, follow_rule1, "No spaces are allowed behind the line continuation symbol '\\'"), - (check_rule2, follow_rule2, "Tabs should not be used (use spaces instead)"), - (check_rule3, follow_rule3, "Comments inside bb files are allowed using the '#' character at the beginning of a line"), - (check_rule4, follow_rule4, "Use quotes on the right hand side of assignments: FOO = \"BAR\""), - (check_rule5, follow_rule5, "The correct spacing for a variable is FOO = \"BAR\""), - (check_rule6, follow_rule6, "Don't use spaces or tabs on empty lines"), - (check_rule7, follow_rule7, "Indentation of multiline variables such as SRC_URI is desireable"), -) - -def follow_rule(i, line): - oldline = line - if not rules[i][0](line): - line = rules[i][1](line) - if not rules[i][0](line): - print "## Rule %d disgression: on this line: " % i, line - print "## Warning: ", rules[i][2] - else: - print "## Reminder: ", rules[i][2], " in :", oldline - return line - - -if __name__ == "__main__": - - # -- retrieves lines of the .bb file -- - lines = [] - for line in fileinput.input(): - if True: - lines.append(line) - else: - # expandtabs on each line so that rule2 is always respected - # rstrip each line so that rule1 is always respected - line = line.expandtabs().rstrip() - # ignore empty lines (or line filled with spaces or tabs only) - # so that rule6 is always respected - if line is not '': - lines.append(line) - - # -- parse the file -- - var = "" - in_routine = False - commentBloc = [] - olines = [] - unknownVar = set() - for line in lines: - line = line.rstrip() - line = follow_rule(2, line) - line = follow_rule(1, line) - line = follow_rule(6, line) - # ignore empty lines - if line.isspace() or line is '': - # flush comments into the olines - for c in commentBloc: olines.append(c) - commentBloc = [] - continue - - if line.startswith('}'): in_routine=False - keep = line.endswith('\\') or in_routine - - # handles commented lines - if line.lstrip().startswith('#'): - # check and follow rule3 if not in a variables or routines - if not in_routine: - line = follow_rule(3, line) - commentBloc.append(line) - continue - - if OE_vars.has_key(var): - for c in commentBloc: - OE_vars[var].append(c) - commentBloc = [] - OE_vars[var].append(line) - else: - varexist = False - for k in OE_vars: - if line.startswith(k): - line = follow_rule(0, line) - varexist = True - if re.match(routineRegexp, line) is not None: - in_routine=True - elif re.match(varRegexp, line) is not None: - line = follow_rule(4, line) - line = follow_rule(5, line) - for c in commentBloc: - OE_vars[k].append(c) - commentBloc = [] - OE_vars[k].append(line) - var = (keep==True or in_routine==True) and k or "" - break - if not varexist: - s = string.split(line)[0].rstrip().lstrip() - if s not in unknownVar: - unknownVar.add(s) - if not in_routine: - print "## Warning: unknown variable/routine \"%s\"" % line - OE_vars['others'].append(line) - if not keep and not in_routine: var = "" - - # -- prepare the sanitized .bb file -- - #for k in OE_vars: print k, OE_vars[k] - addEmptyLine = False - for k in OE_vars: - if k=='SRC_URI': addEmptyLine = True - if OE_vars[k] != []: - if addEmptyLine: olines.append("") - for l in OE_vars[k]: - olines.append(l) - for line in olines: print line - #for i in unknownVar: print i, '\n' \ No newline at end of file +#!/usr/bin/env python + +# sanitize a bitbake file following the OpenEmbedded style guidelines +# see http://openembedded.org/wiki/StyleGuide +# (C) 2006 Cyril Romain +# MIT license + +# TODO: +# - add the others OpenEmbedded variables commonly used +# ./ handle comments in .bb files +# - parse command arguments and print usage on misuse +# . prevent giving more than one .bb file in arguments +# - write result to a file +# - backup the original .bb file +# - make a diff and ask confirmation for patching ? +# - /!\ startswith('SOMETHING') is not taken into account due to the previous startswith('S'). +# - count rule breaks and displays them in the order frequence + +from odict import OrderedDict +import fileinput +import string +import re + +__author__ = "Cyril Romain " +__version__ = "$Revision: 0.3 $" + +# The ordered list of OpenEmbedded variables +OE_vars = OrderedDict([ + ('DESCRIPTION', []), + ('AUTHOR', []), + ('HOMEPAGE', []), + ('SECTION', []), + ('PRIORITY', []), + ('MAINTAINER', []), + ('LICENSE', []), + ('DEPENDS', []), + ('RDEPENDS', []), + ('RRECOMMENDS', []), + ('RSUGGESTS', []), + ('PROVIDES', []), + ('RPROVIDES', []), + ('RCONFLICTS', []), + ('SRCDATE', []), + ('PV', []), + ('PR', []), + ('SRC_URI', []), + ('S', []), + ('inherit', []), + ('EXTRA_', []), + ('do_fetch', []), + ('do_unpack', []), + ('do_patch', []), + ('do_configure', []), + ('do_compile', []), + ('do_install', []), + ('do_package', []), + ('do_stage', []), + ('PACKAGE_ARCH', []), + ('PACKAGES', []), + ('FILES', []), + ('WORKDIR', []), + ('acpaths', []), + ('addhandler', []), + ('addtask', []), + ('bindir', []), + ('export', []), + ('headers', []), + ('include', []), + ('includedir', []), + ('python', []), + ('qtopiadir', []), + ('pkg_postins', []), + ('pkg_postrm', []), + ('require', []), + ('sbindir', []), + ('basesysconfdir', []), + ('sysconfdir', []), + ('ALLOW_EMPTY', []), + ('ALTERNATIVE_LINK', []), + ('ALTERNATIVE_NAME', []), + ('ALTERNATIVE_PATH', []), + ('ALTERNATIVE_PRIORITY', []), + ('ALTNAME', []), + ('AMD_DRIVER_LABEL', []), + ('AMD_DRIVER_VERSION', []), + ('ANGSTROM_EXTRA_INSTALL', []), + ('APPDESKTOP', []), + ('APPIMAGE', []), + ('APPNAME', []), + ('APPTYPE', []), + ('APPWEB_BUILD', []), + ('APPWEB_HOST', []), + ('AR', []), + ('ARCH', []), + ('ARM_INSTRUCTION_SET', []), + ('ARM_MUTEX', []), + ('ART_CONFIG', []), + ('B', []), + ('BJAM_OPTS', []), + ('BJAM_TOOLS', []), + ('BONOBO_HEADERS', []), + ('BOOTSCRIPTS', []), + ('BROKEN', []), + ('BUILD_ALL_DEPS', []), + ('BUILD_CPPFLAGS', []), + ('CFLAGS', []), + ('CCFLAGS', []), + ('CMDLINE', []), + ('COLLIE_MEMORY_SIZE', []), + ('COMPATIBLE_HOST', []), + ('COMPATIBLE_MACHINE', []), + ('COMPILE_HERMES', []), + ('CONFFILES', []), + ('CONFLICTS', []), + ('CORE_EXTRA_D', []), + ('CORE_PACKAGES_D', []), + ('CORE_PACKAGES_RD', []), + ('CPPFLAGS', []), + ('CVSDATE', []), + ('CXXFLAGS', []), + ('DEBIAN_NOAUTONAME', []), + ('DEBUG_APPS', []), + ('DEFAULT_PREFERENCE', []), + ('DB4_CONFIG', []), + ('EXCLUDE_FROM_SHLIBS', []), + ('EXCLUDE_FROM_WORLD', []), + ('FIXEDSRCDATE', []), + ('GLIBC_ADDONS', []), + ('GLIBC_EXTRA_OECONF', []), + ('GNOME_VFS_HEADERS', []), + ('GPE_TARBALL_SUFFIX', []), + ('HEADERS', []), + ('INHIBIT_DEFAULT_DEPS', []), + ('INITSCRIPT_NAME', []), + ('INITSCRIPT_PACKAGES', []), + ('INITSCRIPT_PARAMS', []), + ('IPKG_INSTALL', []), + ('KERNEL_IMAGETYPE', []), + ('KERNEL_IMAGEDEST', []), + ('KERNEL_OUTPUT', []), + ('KERNEL_RELEASE', []), + ('KERNEL_PRIORITY', []), + ('KERNEL_SOURCE', []), + ('KERNEL_SUFFIX', []), + ('KERNEL_VERSION', []), + ('K_MAJOR', []), + ('K_MICRO', []), + ('K_MINOR', []), + ('HHV', []), + ('KV', []), + ('LDFLAGS', []), + ('LD', []), + ('LD_SO', []), + ('LDLIBS', []), + ('LEAD_SONAME', []), + ('LIBTOOL', []), + ('LIBBDB_EXTRA', []), + ('LIBV', []), + ('MACHINE', []), + ('MACHINE_ESSENTIAL_EXTRA_RDEPENDS', []), + ('MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS', []), + ('MACHINE_EXTRA_RDEPENDS', []), + ('MACHINE_EXTRA_RRECOMMENDS', []), + ('MACHINE_FEATURES', []), + ('MACHINE_TASKS', []), + ('MACHTYPE', []), + ('MAKE_TARGETS', []), + ('MESSAGEUSER', []), + ('MESSAGEHOME', []), + ('MIRRORS', []), + ('MUTEX', []), + ('OE_QMAKE_INCDIR_QT', []), + ('OE_QMAKE_CXXFLAGS', []), + ('ORBIT_IDL_SRC', []), + ('PARALLEL_MAKE', []), + ('PAKCAGE_ARCH', []), + ('PCMCIA_MANAGER', []), + ('PKG_BASENAME', []), + ('QEMU', []), + ('QMAKE_PROFILES', []), + ('QPEDIR', []), + ('QPF_DESCRIPTION', []), + ('QPF_PKGPATTERN', []), + ('QT_CONFIG_FLAGS', []), + ('QT_LIBRARY', []), + ('ROOTFS_POSTPROCESS_COMMAND', []), + ('RREPLACES', []), + ('TARGET_CFLAGS', []), + ('TARGET_CPPFLAGS', []), + ('TARGET_LDFLAGS', []), + ('UBOOT_MACHINE', []), + ('UCLIBC_BASE', []), + ('UCLIBC_PATCHES', []), + ('UNSLUNG_PACKAGES', []), + ('VIRTUAL_NAME', []), + ('XORG_PN', []), + ('XSERVER', []), + ('others', []) +]) + +varRegexp = r'^([A-Z_0-9]*)([ \t]*?)([+.:]?=[+.]?)([ \t]*?)("[^"]*["\\]?)' +routineRegexp = r'^([a-zA-Z0-9_ -]+?)\(' + +# Style guideline #0: No spaces are allowed at the beginning of lines that define a variable or a do_ routine +def check_rule0(line): + return line.lstrip()==line +def follow_rule0(line): + return line.lstrip() + +# Style guideline #1: No spaces are allowed behind the line continuation symbol '\' +def check_rule1(line): + if line.rstrip().endswith('\\'): + return line.endswith('\\') + else: + return True +def follow_rule1(line): + return line.rstrip() + +# Style guideline #2: Tabs should not be used (use spaces instead). +def check_rule2(line): + return line.count('\t')==0 +def follow_rule2(line): + return line.expandtabs() + +# Style guideline #3: Comments inside bb files are allowed using the '#' character at the beginning of a line. +def check_rule3(line): + if line.lstrip().startswith('#'): + return line.startswith('#') + else: + return True +def follow_rule3(line): + return line.lstrip() + +# Style guideline #4: Use quotes on the right hand side of assignments: FOO = "BAR" +def check_rule4(line): + return re.match(varRegexp, line) is not None +def follow_rule4(line): + return follow_rule5(line) + +# Style guideline #5: The correct spacing for a variable is FOO = "BAR". +def check_rule5(line): + r = re.search(varRegexp, line) + return r is not None and r.group(2)==" " and r.group(4)==" " +def follow_rule5(line): + r = re.search(varRegexp, line) + return ''.join([r.group(1), ' ', r.group(3), ' ', r.group(5)]) + +# Style guideline #6: Don't use spaces or tabs on empty lines +def check_rule6(line): + return not line.isspace() or line=="\n" +def follow_rule6(line): + return "" + +# Style guideline #7: Indentation of multiline variables such as SRC_URI is desireable. +def check_rule7(line): + return True +def follow_rule7(line): + return line + +rules = ( + (check_rule0, follow_rule0, "No spaces are allowed at the beginning of lines that define a variable or a do_ routine"), + (check_rule1, follow_rule1, "No spaces are allowed behind the line continuation symbol '\\'"), + (check_rule2, follow_rule2, "Tabs should not be used (use spaces instead)"), + (check_rule3, follow_rule3, "Comments inside bb files are allowed using the '#' character at the beginning of a line"), + (check_rule4, follow_rule4, "Use quotes on the right hand side of assignments: FOO = \"BAR\""), + (check_rule5, follow_rule5, "The correct spacing for a variable is FOO = \"BAR\""), + (check_rule6, follow_rule6, "Don't use spaces or tabs on empty lines"), + (check_rule7, follow_rule7, "Indentation of multiline variables such as SRC_URI is desireable"), +) + +def follow_rule(i, line): + oldline = line + if not rules[i][0](line): + line = rules[i][1](line) + if not rules[i][0](line): + print "## Rule %d disgression: on this line: " % i, line + print "## Warning: ", rules[i][2] + else: + print "## Reminder: ", rules[i][2], " in :", oldline + return line + + +if __name__ == "__main__": + + # -- retrieves lines of the .bb file -- + lines = [] + for line in fileinput.input(): + if True: + lines.append(line) + else: + # expandtabs on each line so that rule2 is always respected + # rstrip each line so that rule1 is always respected + line = line.expandtabs().rstrip() + # ignore empty lines (or line filled with spaces or tabs only) + # so that rule6 is always respected + if line is not '': + lines.append(line) + + # -- parse the file -- + var = "" + in_routine = False + commentBloc = [] + olines = [] + unknownVar = set() + for line in lines: + line = line.rstrip() + line = follow_rule(2, line) + line = follow_rule(1, line) + line = follow_rule(6, line) + # ignore empty lines + if line.isspace() or line is '': + # flush comments into the olines + for c in commentBloc: olines.append(c) + commentBloc = [] + continue + + if line.startswith('}'): in_routine=False + keep = line.endswith('\\') or in_routine + + # handles commented lines + if line.lstrip().startswith('#'): + # check and follow rule3 if not in a variables or routines + if not in_routine: + line = follow_rule(3, line) + commentBloc.append(line) + continue + + if OE_vars.has_key(var): + for c in commentBloc: + OE_vars[var].append(c) + commentBloc = [] + OE_vars[var].append(line) + else: + varexist = False + for k in OE_vars: + if line.startswith(k): + line = follow_rule(0, line) + varexist = True + if re.match(routineRegexp, line) is not None: + in_routine=True + elif re.match(varRegexp, line) is not None: + line = follow_rule(4, line) + line = follow_rule(5, line) + for c in commentBloc: + OE_vars[k].append(c) + commentBloc = [] + OE_vars[k].append(line) + var = (keep==True or in_routine==True) and k or "" + break + if not varexist: + s = string.split(line)[0].rstrip().lstrip() + if s not in unknownVar: + unknownVar.add(s) + if not in_routine: + print "## Warning: unknown variable/routine \"%s\"" % line + OE_vars['others'].append(line) + if not keep and not in_routine: var = "" + + # -- prepare the sanitized .bb file -- + #for k in OE_vars: print k, OE_vars[k] + addEmptyLine = False + for k in OE_vars: + if k=='SRC_URI': addEmptyLine = True + if OE_vars[k] != []: + if addEmptyLine: olines.append("") + for l in OE_vars[k]: + olines.append(l) + for line in olines: print line + #for i in unknownVar: print i, '\n' -- cgit v1.2.3 From 049910b3b1f2a33daf0bdc1e7de536edb1f60b78 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Thu, 7 Sep 2006 00:52:34 +0000 Subject: sanitize.py: Make executable. --- contrib/sanitize.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 contrib/sanitize.py diff --git a/contrib/sanitize.py b/contrib/sanitize.py old mode 100644 new mode 100755 -- cgit v1.2.3 From ec0b02d7c11c785bf3c594d7be3cc4b03fe984b0 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Thu, 7 Sep 2006 01:39:24 +0000 Subject: sanitize.py: Drop unimportant Python 2.4 dependency. --- contrib/sanitize.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/sanitize.py b/contrib/sanitize.py index 3d329730b1..e38c28c13f 100755 --- a/contrib/sanitize.py +++ b/contrib/sanitize.py @@ -301,7 +301,7 @@ if __name__ == "__main__": in_routine = False commentBloc = [] olines = [] - unknownVar = set() + unknownVar = [] for line in lines: line = line.rstrip() line = follow_rule(2, line) @@ -350,7 +350,7 @@ if __name__ == "__main__": if not varexist: s = string.split(line)[0].rstrip().lstrip() if s not in unknownVar: - unknownVar.add(s) + unknownVar.append(s) if not in_routine: print "## Warning: unknown variable/routine \"%s\"" % line OE_vars['others'].append(line) -- cgit v1.2.3 From 68369bccea960e60a01570fff3da7789b1e2b452 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Thu, 7 Sep 2006 12:30:16 +0000 Subject: busybox: Update slugos-specific defconfig --- packages/busybox/busybox-1.2.1/slugos/defconfig | 332 ++++++++++++++++++------ packages/busybox/busybox_1.2.1.bb | 2 +- 2 files changed, 249 insertions(+), 85 deletions(-) diff --git a/packages/busybox/busybox-1.2.1/slugos/defconfig b/packages/busybox/busybox-1.2.1/slugos/defconfig index b5ff84550a..c35b4f7f70 100644 --- a/packages/busybox/busybox-1.2.1/slugos/defconfig +++ b/packages/busybox/busybox-1.2.1/slugos/defconfig @@ -3,37 +3,70 @@ # HAVE_DOT_CONFIG=y +# +# Busybox Settings +# + # # General Configuration # +# CONFIG_NITPICK is not set # CONFIG_FEATURE_BUFFERS_USE_MALLOC is not set CONFIG_FEATURE_BUFFERS_GO_ON_STACK=y # CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_SHOW_USAGE=y CONFIG_FEATURE_VERBOSE_USAGE=y +# CONFIG_FEATURE_COMPRESS_USAGE is not set # CONFIG_FEATURE_INSTALLER is not set -# CONFIG_LOCALE_SUPPORT is not set -# CONFIG_FEATURE_DEVFS is not set +CONFIG_LOCALE_SUPPORT=y +CONFIG_GETOPT_LONG=y CONFIG_FEATURE_DEVPTS=y # CONFIG_FEATURE_CLEAN_UP is not set CONFIG_FEATURE_SUID=y # CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set # CONFIG_SELINUX is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" # # Build Options # # CONFIG_STATIC is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_FULL_LIBBUSYBOX is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set CONFIG_LFS=y -# USING_CROSS_COMPILER is not set -EXTRA_CFLAGS_OPTIONS="" +USING_CROSS_COMPILER=y +CROSS_COMPILER_PREFIX="arm-angstrom-linux-gnueabi-" +CONFIG_BUILD_AT_ONCE=y + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_NO_DEBUG_LIB is not set +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set +CONFIG_DEBUG_YANK_SUSv2=y # # Installation Options # # CONFIG_INSTALL_NO_USR is not set -PREFIX="./_install" CONFIG_INSTALL_APPLET_SYMLINKS=y -CONFIG_INSTALL_APPLET_HARDLINKS=n +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +PREFIX="./_install" + +# +# Busybox Library Tuning +# +CONFIG_MD5_SIZE_VS_SPEED=2 + +# +# Applets +# # # Archival Utilities @@ -44,6 +77,7 @@ CONFIG_BUNZIP2=y # CONFIG_CPIO is not set # CONFIG_DPKG is not set # CONFIG_DPKG_DEB is not set +# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set CONFIG_GUNZIP=y # CONFIG_FEATURE_GUNZIP_UNCOMPRESS is not set CONFIG_GZIP=y @@ -52,19 +86,25 @@ CONFIG_GZIP=y CONFIG_TAR=y CONFIG_FEATURE_TAR_CREATE=y CONFIG_FEATURE_TAR_BZIP2=y +# CONFIG_FEATURE_TAR_LZMA is not set CONFIG_FEATURE_TAR_FROM=y CONFIG_FEATURE_TAR_GZIP=y # CONFIG_FEATURE_TAR_COMPRESS is not set -CONFIG_FEATURE_TAR_OLDGNU_COMPATABILITY=y +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y # CONFIG_FEATURE_TAR_LONG_OPTIONS is not set # CONFIG_UNCOMPRESS is not set +# CONFIG_UNLZMA is not set +# CONFIG_FEATURE_LZMA_FAST is not set CONFIG_UNZIP=y # # Common options for cpio and tar # # CONFIG_FEATURE_UNARCHIVE_TAPE is not set +# CONFIG_FEATURE_DEB_TAR_GZ is not set +# CONFIG_FEATURE_DEB_TAR_BZ2 is not set +# CONFIG_FEATURE_DEB_TAR_LZMA is not set # # Coreutils @@ -72,29 +112,37 @@ CONFIG_UNZIP=y CONFIG_BASENAME=y # CONFIG_CAL is not set CONFIG_CAT=y +# CONFIG_CATV is not set CONFIG_CHGRP=y CONFIG_CHMOD=y CONFIG_CHOWN=y CONFIG_CHROOT=y +# CONFIG_CKSUM is not set # CONFIG_CMP is not set +# CONFIG_COMM is not set CONFIG_CP=y CONFIG_CUT=y CONFIG_DATE=y - -# -# date (forced enabled for use with watch) -# # CONFIG_FEATURE_DATE_ISOFMT is not set CONFIG_DD=y +CONFIG_FEATURE_DD_SIGNAL_HANDLING=y +# CONFIG_FEATURE_DD_IBS_OBS is not set CONFIG_DF=y +CONFIG_DIFF=y +CONFIG_FEATURE_DIFF_BINARY=y +CONFIG_FEATURE_DIFF_DIR=y +# CONFIG_FEATURE_DIFF_MINIMAL is not set CONFIG_DIRNAME=y # CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set CONFIG_DU=y -CONFIG_FEATURE_DU_DEFALT_BLOCKSIZE_1K=y +CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y CONFIG_ECHO=y CONFIG_FEATURE_FANCY_ECHO=y CONFIG_ENV=y +CONFIG_FEATURE_ENV_LONG_OPTIONS=y CONFIG_EXPR=y +# CONFIG_EXPR_MATH_SUPPORT_64 is not set CONFIG_FALSE=y # CONFIG_FOLD is not set CONFIG_HEAD=y @@ -102,6 +150,7 @@ CONFIG_FEATURE_FANCY_HEAD=y # CONFIG_HOSTID is not set CONFIG_ID=y # CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set # CONFIG_LENGTH is not set CONFIG_LN=y CONFIG_LOGNAME=y @@ -113,41 +162,49 @@ CONFIG_FEATURE_LS_SORTFILES=y CONFIG_FEATURE_LS_TIMESTAMPS=y CONFIG_FEATURE_LS_USERNAME=y CONFIG_FEATURE_LS_COLOR=y +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set CONFIG_MD5SUM=y CONFIG_MKDIR=y +CONFIG_FEATURE_MKDIR_LONG_OPTIONS=y CONFIG_MKFIFO=y CONFIG_MKNOD=y CONFIG_MV=y +# CONFIG_FEATURE_MV_LONG_OPTIONS is not set +# CONFIG_NICE is not set +# CONFIG_NOHUP is not set CONFIG_OD=y +# CONFIG_PRINTENV is not set CONFIG_PRINTF=y CONFIG_PWD=y -# CONFIG_REALPATH is not set +CONFIG_REALPATH=y CONFIG_RM=y CONFIG_RMDIR=y CONFIG_SEQ=y # CONFIG_SHA1SUM is not set CONFIG_SLEEP=y -# CONFIG_FEATURE_FANCY_SLEEP is not set +CONFIG_FEATURE_FANCY_SLEEP=y CONFIG_SORT=y +CONFIG_FEATURE_SORT_BIG=y +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set CONFIG_STTY=y +# CONFIG_SUM is not set CONFIG_SYNC=y CONFIG_TAIL=y CONFIG_FEATURE_FANCY_TAIL=y CONFIG_TEE=y # CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set CONFIG_TEST=y - -# -# test (forced enabled for use with shell) -# # CONFIG_FEATURE_TEST_64 is not set CONFIG_TOUCH=y CONFIG_TR=y +CONFIG_FEATURE_TR_CLASSES=y +# CONFIG_FEATURE_TR_EQUIV is not set CONFIG_TRUE=y CONFIG_TTY=y CONFIG_UNAME=y CONFIG_UNIQ=y -# CONFIG_USLEEP is not set +CONFIG_USLEEP=y # CONFIG_UUDECODE is not set # CONFIG_UUENCODE is not set CONFIG_WATCH=y @@ -162,7 +219,7 @@ CONFIG_YES=y # CONFIG_FEATURE_PRESERVE_HARDLINKS is not set # -# Common options for ls and more +# Common options for ls, more and telnet # CONFIG_FEATURE_AUTOWIDTH=y @@ -174,7 +231,7 @@ CONFIG_FEATURE_HUMAN_READABLE=y # # Common options for md5sum, sha1sum # -# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y # # Console Utilities @@ -183,12 +240,14 @@ CONFIG_FEATURE_HUMAN_READABLE=y CONFIG_CLEAR=y # CONFIG_DEALLOCVT is not set # CONFIG_DUMPKMAP is not set -CONFIG_GETKEY=y # CONFIG_LOADFONT is not set # CONFIG_LOADKMAP is not set # CONFIG_OPENVT is not set CONFIG_RESET=y +CONFIG_SETCONSOLE=y +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set # CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set # # Debian Utilities @@ -198,7 +257,10 @@ CONFIG_MKTEMP=y CONFIG_READLINK=y CONFIG_FEATURE_READLINK_FOLLOW=y CONFIG_RUN_PARTS=y +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set CONFIG_START_STOP_DAEMON=y +CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y +CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS=y CONFIG_WHICH=y # @@ -206,7 +268,8 @@ CONFIG_WHICH=y # CONFIG_AWK=y CONFIG_FEATURE_AWK_MATH=y -# CONFIG_PATCH is not set +# CONFIG_ED is not set +CONFIG_PATCH=y CONFIG_SED=y CONFIG_VI=y CONFIG_FEATURE_VI_COLON=y @@ -224,6 +287,7 @@ CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y # Finding Utilities # # CONFIG_FIND is not set +CONFIG_FEATURE_FIND_EXEC=y CONFIG_GREP=y CONFIG_FEATURE_GREP_EGREP_ALIAS=y CONFIG_FEATURE_GREP_FGREP_ALIAS=y @@ -234,14 +298,20 @@ CONFIG_FEATURE_GREP_CONTEXT=y # Init Utilities # # CONFIG_INIT is not set +# CONFIG_DEBUG_INIT is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_EXTRA_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +# CONFIG_FEATURE_INITRD is not set # CONFIG_HALT is not set -# CONFIG_POWEROFF is not set -# CONFIG_REBOOT is not set # CONFIG_MESG is not set # # Login/Password Management Utilities # +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_SHADOW is not set # CONFIG_USE_BB_PWD_GRP is not set # CONFIG_ADDGROUP is not set # CONFIG_DELGROUP is not set @@ -249,46 +319,152 @@ CONFIG_FEATURE_GREP_CONTEXT=y # CONFIG_DELUSER is not set # CONFIG_GETTY is not set CONFIG_FEATURE_UTMP=y +# CONFIG_FEATURE_WTMP is not set # CONFIG_LOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set # CONFIG_PASSWD is not set # CONFIG_SU is not set # CONFIG_SULOGIN is not set # CONFIG_VLOCK is not set +# +# Linux Ext2 FS Progs +# +CONFIG_CHATTR=y +CONFIG_E2FSCK=y +CONFIG_FSCK=y +# CONFIG_LSATTR is not set +CONFIG_MKE2FS=y +# CONFIG_TUNE2FS is not set +# CONFIG_E2LABEL is not set +# CONFIG_FINDFS is not set + +# +# Linux Module Utilities +# +# CONFIG_INSMOD is not set +# CONFIG_RMMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_MODPROBE is not set + +# +# Options common to multiple modutils +# +CONFIG_FEATURE_CHECK_TAINTED_MODULE=y +# CONFIG_FEATURE_2_4_MODULES is not set +CONFIG_FEATURE_2_6_MODULES=y +# CONFIG_FEATURE_QUERY_MODULE_INTERFACE is not set + +# +# Linux System Utilities +# +CONFIG_DMESG=y +# CONFIG_FBSET is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FDFORMAT is not set +CONFIG_FDISK=y +FDISK_SUPPORT_LARGE_DISKS=y +CONFIG_FEATURE_FDISK_WRITABLE=y +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +CONFIG_FEATURE_OSF_LABEL=y +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_GETOPT is not set +CONFIG_HEXDUMP=y +CONFIG_HWCLOCK=y +CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS=y +CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS=y +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LOSETUP is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +CONFIG_MKSWAP=y +# CONFIG_FEATURE_MKSWAP_V0 is not set +CONFIG_MORE=y +CONFIG_FEATURE_USE_TERMIOS=y +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +CONFIG_PIVOT_ROOT=y +CONFIG_RDATE=y +# CONFIG_READPROFILE is not set +# CONFIG_SETARCH is not set +# CONFIG_SWAPONOFF is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set + # # Miscellaneous Utilities # # CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set # CONFIG_CROND is not set +# CONFIG_DEBUG_CROND_OPTION is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set # CONFIG_CRONTAB is not set # CONFIG_DC is not set # CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_EJECT is not set # CONFIG_LAST is not set +CONFIG_LESS=y +CONFIG_FEATURE_LESS_BRACKETS=y +CONFIG_FEATURE_LESS_FLAGS=y +# CONFIG_FEATURE_LESS_FLAGCS is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set # CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set # CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MOUNTPOINT is not set # CONFIG_MT is not set +# CONFIG_RUNLEVEL is not set # CONFIG_RX is not set CONFIG_STRINGS=y +# CONFIG_SETSID is not set +# CONFIG_TASKSET is not set CONFIG_TIME=y # CONFIG_WATCHDOG is not set -# -# Linux Module Utilities -# -# CONFIG_INSMOD is not set -# CONFIG_LSMOD is not set -# CONFIG_MODPROBE is not set -# CONFIG_RMMOD is not set - # # Networking Utilities # CONFIG_FEATURE_IPV6=y # CONFIG_ARPING is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FAKEIDENTD is not set # CONFIG_FTPGET is not set # CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set CONFIG_HOSTNAME=y # CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_WITHOUT_INETD is not set +# CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set CONFIG_IFCONFIG=y CONFIG_FEATURE_IFCONFIG_STATUS=y # CONFIG_FEATURE_IFCONFIG_SLIP is not set @@ -303,14 +479,23 @@ CONFIG_FEATURE_IFUPDOWN_IPV6=y # CONFIG_FEATURE_IFUPDOWN_IPX is not set # CONFIG_FEATURE_IFUPDOWN_MAPPING is not set # CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set # CONFIG_IP is not set -# CONFIG_IPCALC is not set # CONFIG_IPADDR is not set # CONFIG_IPLINK is not set # CONFIG_IPROUTE is not set # CONFIG_IPTUNNEL is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set # CONFIG_NAMEIF is not set CONFIG_NC=y +# CONFIG_NC_GAPING_SECURITY_HOLE is not set CONFIG_NETSTAT=y CONFIG_NSLOOKUP=y CONFIG_PING=y @@ -322,43 +507,53 @@ CONFIG_TELNET=y CONFIG_FEATURE_TELNET_TTYPE=y CONFIG_FEATURE_TELNET_AUTOLOGIN=y # CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_INETD is not set CONFIG_TFTP=y CONFIG_FEATURE_TFTP_GET=y CONFIG_FEATURE_TFTP_PUT=y # CONFIG_FEATURE_TFTP_BLOCKSIZE is not set -# CONFIG_FEATURE_TFTP_DEBUG is not set +# CONFIG_DEBUG_TFTP is not set CONFIG_TRACEROUTE=y # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set -# CONFIG_VCONFIG is not set -CONFIG_WGET=y -CONFIG_FEATURE_WGET_STATUSBAR=y -CONFIG_FEATURE_WGET_AUTHENTICATION=y -CONFIG_FEATURE_WGET_IP6_LITERAL=y +# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set # # udhcp Server/Client # -# CONFIG_UDHCPD is not set -CONFIG_UDHCPC=y +# CONFIG_APP_UDHCPD is not set +CONFIG_APP_UDHCPC=y +CONFIG_APP_DUMPLEASES=y CONFIG_FEATURE_UDHCP_SYSLOG=y # CONFIG_FEATURE_UDHCP_DEBUG is not set +# CONFIG_VCONFIG is not set +CONFIG_WGET=y +CONFIG_FEATURE_WGET_STATUSBAR=y +CONFIG_FEATURE_WGET_AUTHENTICATION=y +CONFIG_FEATURE_WGET_IP6_LITERAL=y +CONFIG_FEATURE_WGET_LONG_OPTIONS=y +# CONFIG_ZCIP is not set # # Process Utilities # CONFIG_FREE=y +CONFIG_FUSER=y CONFIG_KILL=y CONFIG_KILLALL=y CONFIG_PIDOF=y +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set CONFIG_PS=y +CONFIG_FEATURE_PS_WIDE=y CONFIG_RENICE=y +CONFIG_BB_SYSCTL=y CONFIG_TOP=y -FEATURE_CPU_USAGE_PERCENTAGE=y +CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y CONFIG_UPTIME=y -CONFIG_SYSCTL=y # -# Another Bourne-like Shell +# Shells # CONFIG_FEATURE_SH_IS_ASH=y # CONFIG_FEATURE_SH_IS_HUSH is not set @@ -371,14 +566,19 @@ CONFIG_ASH=y # Ash Shell Options # CONFIG_ASH_JOB_CONTROL=y +# CONFIG_ASH_READ_NCHARS is not set +# CONFIG_ASH_READ_TIMEOUT is not set CONFIG_ASH_ALIAS=y CONFIG_ASH_MATH_SUPPORT=y # CONFIG_ASH_MATH_SUPPORT_64 is not set CONFIG_ASH_GETOPTS=y +# CONFIG_ASH_BUILTIN_ECHO is not set +CONFIG_ASH_BUILTIN_TEST=y # CONFIG_ASH_CMDCMD is not set # CONFIG_ASH_MAIL is not set CONFIG_ASH_OPTIMIZE_FOR_SIZE=y # CONFIG_ASH_RANDOM_SUPPORT is not set +CONFIG_ASH_EXPAND_PRMT=y # CONFIG_HUSH is not set # CONFIG_LASH is not set # CONFIG_MSH is not set @@ -389,6 +589,7 @@ CONFIG_ASH_OPTIMIZE_FOR_SIZE=y CONFIG_FEATURE_SH_EXTRA_QUIET=y # CONFIG_FEATURE_SH_STANDALONE_SHELL is not set CONFIG_FEATURE_COMMAND_EDITING=y +# CONFIG_FEATURE_COMMAND_EDITING_VI is not set CONFIG_FEATURE_COMMAND_HISTORY=63 # CONFIG_FEATURE_COMMAND_SAVEHISTORY is not set CONFIG_FEATURE_COMMAND_TAB_COMPLETION=y @@ -399,48 +600,11 @@ CONFIG_FEATURE_SH_FANCY_PROMPT=y # System Logging Utilities # CONFIG_SYSLOGD=y -# CONFIG_FEATURE_ROTATE_LOGFILE is not set +CONFIG_FEATURE_ROTATE_LOGFILE=y CONFIG_FEATURE_REMOTE_LOG=y CONFIG_FEATURE_IPC_SYSLOG=y CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16 CONFIG_LOGREAD=y -# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING=y CONFIG_KLOGD=y CONFIG_LOGGER=y - -# -# Linux System Utilities -# -CONFIG_DMESG=y -# CONFIG_FBSET is not set -# CONFIG_FDFLUSH is not set -# CONFIG_FDFORMAT is not set -CONFIG_FDISK=y -FDISK_SUPPORT_LARGE_DISKS=y -CONFIG_FEATURE_FDISK_WRITABLE=y -# CONFIG_FEATURE_AIX_LABEL is not set -# CONFIG_FEATURE_SGI_LABEL is not set -# CONFIG_FEATURE_SUN_LABEL is not set -CONFIG_FEATURE_OSF_LABEL=y -# CONFIG_FEATURE_FDISK_ADVANCED is not set -# CONFIG_FREERAMDISK is not set -# CONFIG_FSCK_MINIX is not set -# CONFIG_MKFS_MINIX is not set -# CONFIG_GETOPT is not set -CONFIG_HEXDUMP=y -CONFIG_HWCLOCK=y -CONFIG_FEATURE_HWCLOCK_LONGOPTIONS=y -# CONFIG_LOSETUP is not set -CONFIG_MKSWAP=y -CONFIG_MORE=y -CONFIG_FEATURE_USE_TERMIOS=y -CONFIG_PIVOT_ROOT=y -# CONFIG_RDATE is not set -# CONFIG_SWAPONOFF is not set -# CONFIG_MOUNT is not set -# CONFIG_UMOUNT is not set - -# -# Debugging Options -# -# CONFIG_DEBUG is not set diff --git a/packages/busybox/busybox_1.2.1.bb b/packages/busybox/busybox_1.2.1.bb index 74c69319f4..ee71f37fa8 100644 --- a/packages/busybox/busybox_1.2.1.bb +++ b/packages/busybox/busybox_1.2.1.bb @@ -10,7 +10,7 @@ HOMEPAGE = "http://www.busybox.net" LICENSE = "GPL" SECTION = "base" PRIORITY = "required" -PR = "r1.2" +PR = "r1.3" SRC_URI = "http://www.busybox.net/downloads/busybox-${PV}.tar.gz \ file://dhcp-hostname.patch;patch=1 \ -- cgit v1.2.3 From aaad1c8c596a0568435bf72ebcbfc1a19f012112 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Thu, 7 Sep 2006 12:34:00 +0000 Subject: openntpd: Fix initscript and reformat .bb to match OE style guidelines --- packages/openntpd/files/init | 2 +- packages/openntpd/openntpd_3.7p1.bb | 38 ++++++++++++++++++------------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/packages/openntpd/files/init b/packages/openntpd/files/init index d35c65299d..745f1701aa 100644 --- a/packages/openntpd/files/init +++ b/packages/openntpd/files/init @@ -7,7 +7,7 @@ ntpd=/usr/sbin/ntpd test -x "$ntpd" || exit 0 -[ ! -d /var/shared/empty ] && mkdir /var/shared/empty +[ ! -d /var/shared/empty ] && mkdir -p /var/shared/empty case "$1" in start) diff --git a/packages/openntpd/openntpd_3.7p1.bb b/packages/openntpd/openntpd_3.7p1.bb index 6649361fd4..4001eb7dae 100644 --- a/packages/openntpd/openntpd_3.7p1.bb +++ b/packages/openntpd/openntpd_3.7p1.bb @@ -6,43 +6,41 @@ LICENSE = "BSD" SECTION = "console/network" MAINTAINER = "Oyvind Repvik " DEPENDS = "timezones" -PR="r12" +PR="r13" SRC_URI = "http://www.zip.com.au/~dtucker/openntpd/release/openntpd-${PV}.tar.gz \ - file://autofoo.patch;patch=1 \ - file://adjtimex-${PV}.patch;patch=1 \ - file://makefile-install.patch;patch=1 \ - file://init" -S = "${WORKDIR}/openntpd-${PV}" - -INITSCRIPT_NAME = "openntpd" -INITSCRIPT_PARAMS = "defaults" + file://autofoo.patch;patch=1 \ + file://adjtimex-${PV}.patch;patch=1 \ + file://makefile-install.patch;patch=1 \ + file://init" +S = "${WORKDIR}/openntpd-${PV}" inherit autotools update-rc.d +INITSCRIPT_NAME = "openntpd" +INITSCRIPT_PARAMS = "defaults" + EXTRA_OECONF += "CFLAGS=-DUSE_ADJTIMEX --disable-strip --prefix=/usr \ - --sysconfdir=/etc --with-privsep-path=/${localstatedir}/shared/empty \ - --with-privsep-user=ntpd \ - --with-builtin-arc4random \ - --without-ssl-dir \ - " + --sysconfdir=/etc --with-privsep-path=/${localstatedir}/shared/empty \ + --with-privsep-user=ntpd \ + --with-builtin-arc4random \ + --without-ssl-dir" do_install_prepend() { install -d ${D}${sysconfdir}/init.d } do_install_append() { - install -c -m 755 ${WORKDIR}/init ${D}${sysconfdir}/init.d/openntpd + install -c -m 755 ${WORKDIR}/init ${D}${sysconfdir}/init.d/openntpd } pkg_postrm () { - grep ntpd ${sysconfdir}/passwd && deluser ntpd + grep ntpd ${sysconfdir}/passwd && deluser ntpd } pkg_postinst () { - [ ! -d ${localstatedir}/shared ] && mkdir -p ${localstatedir}/shared - grep ntpd ${sysconfdir}/passwd || adduser --disabled-password --home=${localstatedir}/shared/empty --ingroup nogroup ntpd - chown root:root ${localstatedir}/shared/empty + [ ! -d ${localstatedir}/shared ] && mkdir -p ${localstatedir}/shared + grep ntpd ${sysconfdir}/passwd || adduser --disabled-password --home=${localstatedir}/shared/empty --ingroup nogroup ntpd + chown root:root ${localstatedir}/shared/empty } - -- cgit v1.2.3 From 2ac7f43dd9df8854c55690fb5e820cf5c3d9514b Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Thu, 7 Sep 2006 12:35:39 +0000 Subject: zd1211: Reformat .bb --- packages/zd1211/zd1211_r83.bb | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/zd1211/zd1211_r83.bb b/packages/zd1211/zd1211_r83.bb index 398d516372..5f0c6a0d0a 100644 --- a/packages/zd1211/zd1211_r83.bb +++ b/packages/zd1211/zd1211_r83.bb @@ -7,14 +7,12 @@ PR = "r1" RDEPENDS = "wireless-tools" SRC_URI = "http://zd1211.ath.cx/download/zd1211-driver-${PV}.tgz \ - file://makefile.patch;patch=1 \ - " + file://makefile.patch;patch=1" SRC_URI_unslung = "http://zd1211.ath.cx/download/zd1211-driver-${PV}.tgz \ file://makefile-unslung.patch;patch=1 \ - file://unslung-iwpriv-hack.patch;patch=1 \ - file://unslung-writel-logging.patch;patch=1 \ - " + file://unslung-iwpriv-hack.patch;patch=1 \ + file://unslung-writel-logging.patch;patch=1" S = "${WORKDIR}/zd1211-driver-${PV}" @@ -23,9 +21,9 @@ inherit module do_compile () { unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS CC LD CPP oe_runmake 'MODPATH={D}${base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net' \ - 'KERNEL_SOURCE=${STAGING_KERNEL_DIR}' \ - 'KDIR=${STAGING_KERNEL_DIR}' \ - 'KERNEL_VERSION=${KERNEL_VERSION}' \ + 'KERNEL_SOURCE=${STAGING_KERNEL_DIR}' \ + 'KDIR=${STAGING_KERNEL_DIR}' \ + 'KERNEL_VERSION=${KERNEL_VERSION}' \ 'CC=${KERNEL_CC}' \ 'LD=${KERNEL_LD}' } -- cgit v1.2.3 From 3d426fa9cd242cc650e7163277ff3c958b907fb3 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Thu, 7 Sep 2006 12:36:31 +0000 Subject: litestream: Reformat .bb --- packages/litestream/litestream_1.3RC3.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/litestream/litestream_1.3RC3.bb b/packages/litestream/litestream_1.3RC3.bb index 6c83266764..4de9bc8327 100644 --- a/packages/litestream/litestream_1.3RC3.bb +++ b/packages/litestream/litestream_1.3RC3.bb @@ -8,10 +8,10 @@ SRC_URI = "http://www.litestream.org/litestream/${PN}-${PV}.tar.gz" inherit autotools do_install () { - mkdir -p ${D}${bindir} + install -d ${D}${bindir} install -m 755 litestream ${D}${bindir} install -m 755 literestream ${D}${bindir} install -m 755 source ${D}${bindir} install -m 755 client ${D}${bindir} - install -m 755 server ${D}${bindir} + install -m 755 server ${D}${bindir} } \ No newline at end of file -- cgit v1.2.3 From 566fe1804ed01b7cc89a3d2eea1d278ce1536394 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Thu, 7 Sep 2006 12:37:50 +0000 Subject: ssmtp: Reformat .bb --- packages/ssmtp/ssmtp_2.61.bb | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/ssmtp/ssmtp_2.61.bb b/packages/ssmtp/ssmtp_2.61.bb index 6a4a94a0e3..25d1aa2d66 100644 --- a/packages/ssmtp/ssmtp_2.61.bb +++ b/packages/ssmtp/ssmtp_2.61.bb @@ -9,32 +9,31 @@ SRC_URI = "${DEBIAN_MIRROR}/main/s/ssmtp/ssmtp_${PV}.orig.tar.gz \ file://ldflags.patch;patch=1 \ file://configure.patch;patch=1 \ file://libs-lcrypto.patch;patch=1 \ - file://dont-strip.patch;patch=1 \ file://ssmtp.conf" -S = "${WORKDIR}/${PN}-2.61" -LICENSE = "GPL" -CONFFILES_${PN} = "${sysconfdir}/ssmtp/ssmtp.conf ${sysconfdir}/ssmtp/revaliases" +S = "${WORKDIR}/${PN}-${PV}" + inherit autotools +CONFFILES_${PN} = "${sysconfdir}/ssmtp/ssmtp.conf ${sysconfdir}/ssmtp/revaliases" EXTRA_OECONF = "--enable-ssl" +INHIBIT_AUTO_STAGE = "1" + do_compile () { - oe_runmake 'LDFLAGS=${LDFLAGS}' + oe_runmake 'LDFLAGS=${LDFLAGS}' } -INHIBIT_AUTO_STAGE = "1" - do_install () { - oe_runmake 'prefix=${D}${prefix}' 'exec_prefix=${D}${exec_prefix}' \ - 'bindir=${D}${bindir}' 'mandir=${D}${mandir}' \ - 'etcdir=${D}${sysconfdir}' GEN_CONFIG="`which echo`" install - install -d ${D}${sysconfdir}/ssmtp - install -m 0644 ${WORKDIR}/ssmtp.conf ${D}${sysconfdir}/ssmtp/ssmtp.conf + oe_runmake 'prefix=${D}${prefix}' 'exec_prefix=${D}${exec_prefix}' \ + 'bindir=${D}${bindir}' 'mandir=${D}${mandir}' \ + 'etcdir=${D}${sysconfdir}' GEN_CONFIG="`which echo`" install + install -d ${D}${sysconfdir}/ssmtp + install -m 0644 ${WORKDIR}/ssmtp.conf ${D}${sysconfdir}/ssmtp/ssmtp.conf } pkg_postinst () { - update-alternatives --install ${sbindir}/sendmail sendmail ${bindir}/ssmtp 30 + update-alternatives --install ${sbindir}/sendmail sendmail ${bindir}/ssmtp 30 } pkg_postrm () { - update-alternatives --remove ${sbindir}/sendmail sendmail + update-alternatives --remove ${sbindir}/sendmail sendmail } -- cgit v1.2.3 From d38cd863bfa830afbde586ad7478bfd8ae6b2987 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 7 Sep 2006 12:54:16 +0000 Subject: gpe-calendar: reformat according to styleguide and drop obsolete versions --- packages/gpe-calendar/gpe-calendar_0.66.bb | 12 ------------ packages/gpe-calendar/gpe-calendar_0.67.bb | 11 ----------- packages/gpe-calendar/gpe-calendar_0.68.bb | 12 ------------ packages/gpe-calendar/gpe-calendar_0.69.bb | 12 ------------ packages/gpe-calendar/gpe-calendar_0.70.bb | 15 --------------- packages/gpe-calendar/gpe-calendar_0.71.bb | 15 --------------- packages/gpe-calendar/gpe-calendar_0.72.bb | 20 ++++++++++++-------- packages/gpe-calendar/gpe-calendar_cvs.bb | 21 ++++++++++++--------- 8 files changed, 24 insertions(+), 94 deletions(-) delete mode 100644 packages/gpe-calendar/gpe-calendar_0.66.bb delete mode 100644 packages/gpe-calendar/gpe-calendar_0.67.bb delete mode 100644 packages/gpe-calendar/gpe-calendar_0.68.bb delete mode 100644 packages/gpe-calendar/gpe-calendar_0.69.bb delete mode 100644 packages/gpe-calendar/gpe-calendar_0.70.bb delete mode 100644 packages/gpe-calendar/gpe-calendar_0.71.bb diff --git a/packages/gpe-calendar/gpe-calendar_0.66.bb b/packages/gpe-calendar/gpe-calendar_0.66.bb deleted file mode 100644 index d3741787ea..0000000000 --- a/packages/gpe-calendar/gpe-calendar_0.66.bb +++ /dev/null @@ -1,12 +0,0 @@ -LICENSE = "GPL" -PR = "r0" -GPE_TARBALL_SUFFIX = "bz2" -MAINTAINER = "Florian Boor " - -inherit autotools gpe - -DEPENDS = "libeventdb libschedule libxsettings libxsettings-client libgpepimc libdisplaymigration libgpevtype" -SECTION = "gpe" -RDEPENDS = "gpe-icons" -DESCRIPTION = "GPE calendar" - diff --git a/packages/gpe-calendar/gpe-calendar_0.67.bb b/packages/gpe-calendar/gpe-calendar_0.67.bb deleted file mode 100644 index da50299bcd..0000000000 --- a/packages/gpe-calendar/gpe-calendar_0.67.bb +++ /dev/null @@ -1,11 +0,0 @@ -LICENSE = "GPL" -PR = "r0" -GPE_TARBALL_SUFFIX = "bz2" - -inherit autotools gpe - -DEPENDS = "libeventdb libschedule libxsettings libxsettings-client libgpepimc libdisplaymigration libgpevtype" -SECTION = "gpe" -RDEPENDS = "gpe-icons" -DESCRIPTION = "GPE calendar" - diff --git a/packages/gpe-calendar/gpe-calendar_0.68.bb b/packages/gpe-calendar/gpe-calendar_0.68.bb deleted file mode 100644 index 3c8fbbc148..0000000000 --- a/packages/gpe-calendar/gpe-calendar_0.68.bb +++ /dev/null @@ -1,12 +0,0 @@ -LICENSE = "GPL" -PR = "r0" -GPE_TARBALL_SUFFIX = "bz2" -MAINTAINER = "Florian Boor " - -inherit autotools gpe - -DEPENDS = "libeventdb libschedule libxsettings-client libgpepimc libgpevtype" -SECTION = "gpe" -RDEPENDS = "gpe-icons" -DESCRIPTION = "GPE calendar" - diff --git a/packages/gpe-calendar/gpe-calendar_0.69.bb b/packages/gpe-calendar/gpe-calendar_0.69.bb deleted file mode 100644 index 3c8fbbc148..0000000000 --- a/packages/gpe-calendar/gpe-calendar_0.69.bb +++ /dev/null @@ -1,12 +0,0 @@ -LICENSE = "GPL" -PR = "r0" -GPE_TARBALL_SUFFIX = "bz2" -MAINTAINER = "Florian Boor " - -inherit autotools gpe - -DEPENDS = "libeventdb libschedule libxsettings-client libgpepimc libgpevtype" -SECTION = "gpe" -RDEPENDS = "gpe-icons" -DESCRIPTION = "GPE calendar" - diff --git a/packages/gpe-calendar/gpe-calendar_0.70.bb b/packages/gpe-calendar/gpe-calendar_0.70.bb deleted file mode 100644 index d88c8c3930..0000000000 --- a/packages/gpe-calendar/gpe-calendar_0.70.bb +++ /dev/null @@ -1,15 +0,0 @@ -LICENSE = "GPL" -PR = "r0" -GPE_TARBALL_SUFFIX = "bz2" -MAINTAINER = "Florian Boor " - -inherit autotools gpe - -DEPENDS = "dbus-glib libeventdb libschedule libxsettings-client libgpepimc libgpevtype" -SECTION = "gpe" -RDEPENDS = "gpe-icons" -DESCRIPTION = "GPE calendar is the calendar application of the GPE PIM suite." - -do_configure () { - autotools_do_configure -} diff --git a/packages/gpe-calendar/gpe-calendar_0.71.bb b/packages/gpe-calendar/gpe-calendar_0.71.bb deleted file mode 100644 index d88c8c3930..0000000000 --- a/packages/gpe-calendar/gpe-calendar_0.71.bb +++ /dev/null @@ -1,15 +0,0 @@ -LICENSE = "GPL" -PR = "r0" -GPE_TARBALL_SUFFIX = "bz2" -MAINTAINER = "Florian Boor " - -inherit autotools gpe - -DEPENDS = "dbus-glib libeventdb libschedule libxsettings-client libgpepimc libgpevtype" -SECTION = "gpe" -RDEPENDS = "gpe-icons" -DESCRIPTION = "GPE calendar is the calendar application of the GPE PIM suite." - -do_configure () { - autotools_do_configure -} diff --git a/packages/gpe-calendar/gpe-calendar_0.72.bb b/packages/gpe-calendar/gpe-calendar_0.72.bb index d88c8c3930..10bb221ff2 100644 --- a/packages/gpe-calendar/gpe-calendar_0.72.bb +++ b/packages/gpe-calendar/gpe-calendar_0.72.bb @@ -1,15 +1,19 @@ -LICENSE = "GPL" -PR = "r0" -GPE_TARBALL_SUFFIX = "bz2" +DESCRIPTION = "GPE calendar is the calendar application of the GPE PIM suite." +SECTION = "gpe" MAINTAINER = "Florian Boor " - -inherit autotools gpe +LICENSE = "GPL" DEPENDS = "dbus-glib libeventdb libschedule libxsettings-client libgpepimc libgpevtype" -SECTION = "gpe" RDEPENDS = "gpe-icons" -DESCRIPTION = "GPE calendar is the calendar application of the GPE PIM suite." + +PR = "r0" + +GPE_TARBALL_SUFFIX = "bz2" + +inherit autotools gpe do_configure () { - autotools_do_configure + autotools_do_configure } + + diff --git a/packages/gpe-calendar/gpe-calendar_cvs.bb b/packages/gpe-calendar/gpe-calendar_cvs.bb index 228d701fec..f93f9d1fae 100644 --- a/packages/gpe-calendar/gpe-calendar_cvs.bb +++ b/packages/gpe-calendar/gpe-calendar_cvs.bb @@ -1,17 +1,20 @@ -LICENSE = "GPL" DEFAULT_PREFERENCE = "-1" +DESCRIPTION = "GPE calendar" +SECTION = "gpe" +LICENSE = "GPL" + +DEPENDS = "libhandoff libsoup libeventdb libschedule libxsettings libxsettings-client libgpepimc libdisplaymigration libgpevtype" +RDEPENDS = "gpe-icons" + +PV = "0.73+cvs${SRCDATE}" +PR = "r0" + +SRC_URI = "${HANDHELDS_CVS};module=gpe/base/${PN}" S = "${WORKDIR}/${PN}" -PV = "0.72+cvs${SRCDATE}" -PR = "r1" -PARALLEL_MAKE = "" inherit autotools gpe -SRC_URI = "${HANDHELDS_CVS};module=gpe/base/${PN}" +PARALLEL_MAKE = "" -DEPENDS = "libhandoff libsoup libeventdb libschedule libxsettings libxsettings-client libgpepimc libdisplaymigration libgpevtype" -SECTION = "gpe" -RDEPENDS = "gpe-icons" -DESCRIPTION = "GPE calendar" -- cgit v1.2.3 From d7c5504299f2215ad653fb4352e196405a2dd3dd Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 7 Sep 2006 13:04:32 +0000 Subject: gpe-conf: reformat according to styleguide and drop obsolete versions --- packages/gpe-conf/files/.mtn2git_empty | 0 packages/gpe-conf/files/Makefile.dpkg_ipkg | 114 --------------------- packages/gpe-conf/files/Makefile.translation | 107 ------------------- packages/gpe-conf/files/desktop-categories.patch | 10 -- packages/gpe-conf/files/fixsegfault.patch | 44 -------- .../gpe-conf/files/ipaq-sleep-configName.patch | 20 ---- packages/gpe-conf/gpe-conf_0.1.30.bb | 28 ----- packages/gpe-conf/gpe-conf_0.2.1.bb | 24 ----- packages/gpe-conf/gpe-conf_0.2.2.bb | 10 +- packages/gpe-conf/gpe-conf_cvs.bb | 28 ++--- 10 files changed, 20 insertions(+), 365 deletions(-) delete mode 100644 packages/gpe-conf/files/.mtn2git_empty delete mode 100644 packages/gpe-conf/files/Makefile.dpkg_ipkg delete mode 100644 packages/gpe-conf/files/Makefile.translation delete mode 100644 packages/gpe-conf/files/desktop-categories.patch delete mode 100644 packages/gpe-conf/files/fixsegfault.patch delete mode 100644 packages/gpe-conf/files/ipaq-sleep-configName.patch delete mode 100644 packages/gpe-conf/gpe-conf_0.1.30.bb delete mode 100644 packages/gpe-conf/gpe-conf_0.2.1.bb diff --git a/packages/gpe-conf/files/.mtn2git_empty b/packages/gpe-conf/files/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/gpe-conf/files/Makefile.dpkg_ipkg b/packages/gpe-conf/files/Makefile.dpkg_ipkg deleted file mode 100644 index 978b08d91a..0000000000 --- a/packages/gpe-conf/files/Makefile.dpkg_ipkg +++ /dev/null @@ -1,114 +0,0 @@ -## Please read the README in this directory to see how to use this -## Makefile snippet - -# Let's use whatever clean target the specific app provides - -CONTROL = `if test -e familiar/control1; then echo control1; else echo control; fi` - -# URL to source tarball -SOURCE = ftp://gpe.handhelds.org/projects/gpe/source/$(PACKAGE)-$(VERSION).tar.gz - -# can change this to e.g. /var/tmp/deb -DEB_PATH = ../deb - -ifeq ($(CVSBUILD),yes) -LIBGPEWIDGET_PC = libgpewidget-uninstalled -PC_EXTRA=PKG_CONFIG_PATH=../../base/libgpewidget -else -LIBGPEWIDGET_PC = libgpewidget -endif - -ifeq ($(IN_LIBGPEWIDGET),) -GPECFLAGS = $(shell $(PC_EXTRA) pkg-config --cflags $(LIBGPEWIDGET_PC)) -GPELIBS = $(shell $(PC_EXTRA) pkg-config --libs $(LIBGPEWIDGET_PC)) -endif - -GTKCFLAGS = $(shell pkg-config --cflags gtk+-2.0) -GTKLIBS = $(shell pkg-config --libs gtk+-2.0) - -STANDARD_CPPFLAGS = -D_GNU_SOURCE -DPACKAGE=\"$(PACKAGE)\" -DPREFIX=\"$(PREFIX)\" -DPACKAGE_LOCALE_DIR=\"$(PREFIX)/share/locale\" -STANDARD_CFLAGS = -MD -Wall - -ifeq ($(DEBUG),yes) -CFLAGS += -O2 -g -LDFLAGS = -g -else -CFLAGS += -Os -fomit-frame-pointer -endif - -dist: check-source clean dist-prep - rm -rf ../$(PACKAGE)-$(VERSION) - mkdir ../$(PACKAGE)-$(VERSION) - ( tar cf - --exclude "*/CVS" --exclude CVS --exclude "*~" --exclude "#*#" --exclude "debian" --exclude ".*" --exclude "*.ipk" --exclude "*.ipk.*" --exclude "*.mo" --exclude "*.batch" --exclude "translation-ipkgs.txt" * ) | (cd ../$(PACKAGE)-$(VERSION); tar xf -) - ( if [ -f linguas ]; then LINGUAS=`cat linguas`; PATCH_LINGUAS="s:^LINGUAS =.*:LINGUAS = $${LINGUAS}:"; fi; cd ../$(PACKAGE)-$(VERSION) && mkdir build && cp $(BUILD)/Makefile.dpkg_ipkg $(BUILD)/Makefile.translation build/ && sed "s:^CVSBUILD =.*:CVSBUILD = no:;s:^DEBUG =.*:DEBUG = no:;s:Makefile.translation-auto-linguas:Makefile.translation:;$${PATCH_LINGUAS}" < Makefile > Makefile.new && mv Makefile.new Makefile ) - ( cd .. ; tar cf - $(PACKAGE)-$(VERSION) | gzip -9 >$(PACKAGE)-$(VERSION).tar.gz ) - rm -rf ../$(PACKAGE)-$(VERSION) - $(MAKE) printinfo - -dist-upload: dist - scp ../$(PACKAGE)-$(VERSION).tar.gz $(USER)@handhelds.org:/home/ftp/projects/gpe/source/ - -dist-prep: -ipkg-prep: -install-mo: -# empty, can be filled in Makefile.translation - -install: install-program install-mo - -clean-dist: - rm -rf familiar/dist familiar/dist.list - -clean: clean-dist - -check-source: - @if [ -f familiar/$(CONTROL) ] && ! grep -q '^Source:' familiar/$(CONTROL); then echo -e "\nNo Source: field in control file. Aborting.\n"; exit 1; fi - -ipkg: check-source ipkg-prep clean - rm -rf familiar/dist - mkdir -p familiar/dist/CONTROL - sed 's:VERSION:$(VERSION):;s$$SOURCE$$$(SOURCE)$$' < familiar/$(CONTROL) > familiar/dist/CONTROL/control - if test -e familiar/conffiles; then install -m 644 familiar/conffiles familiar/dist/CONTROL; fi - if test -e familiar/preinst; then install familiar/preinst familiar/dist/CONTROL; fi - if test -e familiar/postinst; then install familiar/postinst familiar/dist/CONTROL; fi - if test -e familiar/prerm; then install familiar/prerm familiar/dist/CONTROL; fi - if test -e familiar/postrm; then install familiar/postrm familiar/dist/CONTROL; fi - $(MAKE) DESTDIR=`pwd`/familiar/dist PREFIX=/usr prefix=/usr DEBUG=no install-program - rm -rf familiar/dist.list - ipkg-build -o 0 -g 0 familiar/dist | sed 's/^Packaged .*into //; t 1; d; : 1; s:.*/::' >> familiar/dist.list - if [ "x$(LINGUAS)" != "x" ]; then make translation-ipkg; tr ' ' '\n' < translation-ipkgs.txt >> familiar/dist.list; fi - md5sum `cat familiar/dist.list` > $(PACKAGE)_$(VERSION).batch - rm -rf familiar/dist familiar/dist.list - $(MAKE) printinfo - -dpkg: dist - mkdir -p $(DEB_PATH) - ( olddir=`pwd`; cd $(DEB_PATH); rm -rf $(PACKAGE)-$(VERSION); ln -s $$olddir/../$(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)_$(VERSION).orig.tar.gz ; tar xzf $(PACKAGE)_$(VERSION).orig.tar.gz ) - mkdir -p $(DEB_PATH)/$(PACKAGE)-$(VERSION)/debian - for i in debian/*; do if test -f $$i; then cp $$i $(DEB_PATH)/$(PACKAGE)-$(VERSION)/debian/; fi; done - -CVSTAG := $(shell echo $(PACKAGE)-$(VERSION) | tr [a-z.] [A-Z_]) -printinfo: - @printf '-------------------------------------------------------------------------------\n' - @printf "If this becomes a package release, please add a CVS tag.\n" - @printf "You can use 'make tag' for that, it will execute\n" - @printf " cvs tag %s\n" $(CVSTAG) - @printf "Please upload a tarball (created with 'make dist') to\n" - @printf " ftp://ftp.handhelds.org/pub/projects/gpe/\n" - @printf " (handhelds.org:~ftp/pub/projects/gpe/source)\n" - @printf "You can use 'make dist-upload' to do that.\n" - @printf "You are currently known as USER %s.\n" $(USER) - @printf '-------------------------------------------------------------------------------\n' - -tag: check-source - cvs tag $(CVSTAG) - -retag: check-source - cvs tag -F $(CVSTAG) - -source: tag dist-upload - -%.pc: %.pc.in - sed 's:PREFIX:$(PREFIX):;s:BUILDDIR:$(shell pwd):;s:VERSION:$(VERSION):' < $< > $@ - -.c.o:; - $(CC) $(CFLAGS) $(CPPFLAGS) $(PACKAGE_CFLAGS) $(PACKAGE_CPPFLAGS) -c $< -o $@ diff --git a/packages/gpe-conf/files/Makefile.translation b/packages/gpe-conf/files/Makefile.translation deleted file mode 100644 index 1ca7d648fd..0000000000 --- a/packages/gpe-conf/files/Makefile.translation +++ /dev/null @@ -1,107 +0,0 @@ -.SUFFIXES: .mo .po .pot .po8 - -CONTROL = `if test -e familiar/control1; then echo control1; else echo control; fi` - -# use ipkg-build or ipkg-deb-build -IPKG_BUILD := ipkg-build - -TRANSLATION_SITE := http://www.iro.umontreal.ca/~gnutra/maint - -ifeq ($(DIR_PO),) -DIR_PO := po -endif - -ifeq ($(BINPACKAGE),) -BINPACKAGE := $(PACKAGE) -endif - -mo-files = $(patsubst %,$(DIR_PO)/%.mo,$(LINGUAS)) -po-files = $(patsubst %,$(DIR_PO)/%.po,$(LINGUAS)) - -ifeq ($(shell if [ -f $(PACKAGE).desktop.in ]; then echo present; fi;),present) -desktop-files += $(PACKAGE).desktop -endif - -ifneq ($(EXTRA_DESKTOPS),) -desktop-files += $(patsubst %.desktop.in,%.desktop,$(EXTRA_DESKTOPS)) -endif - -all-mo: $(mo-files) - -all-desktop: $(desktop-files) - -install-mo: all-mo - if [ "$(ENABLE_NLS)" != "no" ]; then \ - if [ "x$(LINGUAS)" != "x" ]; then \ - for i in $(LINGUAS); do mkdir -p $(DESTDIR)$(PREFIX)/share/locale/$$i/LC_MESSAGES; install -m 644 $(DIR_PO)/$$i.mo $(DESTDIR)$(PREFIX)/share/locale/$$i/LC_MESSAGES/$(PACKAGE).mo; done \ - fi; \ - fi; - -.po8.mo:; - if [ "$(ENABLE_NLS)" != "no" ]; then \ - msgfmt -o $@ $<; \ - fi; - -.po.po8:; - CTYPE=`grep "^\"Content-Type:" $< | sed 's/^.*charset=//;s/\\\\.*//'`; sed "s/\(Content-Type: .*=\)$$CTYPE/\1UTF-8/" < $< | iconv -f $${CTYPE} -t UTF-8 >$@ - -update-po: $(po-files) extract-po - -dist-prep: update-po freshen-po -# empty - -ifeq ($(CVSBUILD),yes) -ipkg-prep: freshen-po -# empty -endif - -extract-po: - mkdir -p $(DIR_PO) - ( SOURCES="$(SOURCES)"; for DESK in $(PACKAGE).desktop.in $(EXTRA_DESKTOPS); do if [ -f $$DESK ]; then intltool-extract --type=gettext/ini $$DESK; SOURCES="$$SOURCES $${DESK}.h"; fi; done; if [ "x$$SOURCES" != "x" ]; then xgettext --add-comments=TRANSLATORS: -k_ -kN_ -o $(DIR_PO)/$(PACKAGE).pot.new $$SOURCES; fi ) - if [ -f $(DIR_PO)/$(PACKAGE).pot.new ]; then if cmp -s $(DIR_PO)/$(PACKAGE).pot.new $(PACKAGE).pot; then rm $(DIR_PO)/$(PACKAGE).pot.new; else mv $(DIR_PO)/$(PACKAGE).pot.new $(DIR_PO)/$(PACKAGE).pot; fi; fi - -clean: clean-po clean-dist-translation - -clean-po: - rm -rf $(DIR_PO)/*.mo - for i in $(desktop-files); do if [ -f $$i.in ]; then rm -f $$i; rm -f $$i.in.h; fi; done - -%.desktop: %.desktop.in $(patsubst %,$(DIR_PO)/%.po,$(LINGUAS)) - intltool-merge -u -d $(DIR_PO) $< $@ - -freshen-po: - rm -rf tmp-po - mkdir tmp-po - cd tmp-po; for LANG in $(LINGUAS); do wget $(TRANSLATION_SITE)/$(PACKAGE)/$$LANG.po; done - for LANG in $(LINGUAS); do if [ ! -f $(DIR_PO)/$$LANG.po ] || ! cmp -s $(DIR_PO)/$$LANG.po tmp-po/$$LANG.po ; then mv tmp-po/$$LANG.po $(DIR_PO)/$$LANG.po; echo "Updated $$LANG translation"; fi; done - rm -rf tmp-po - -# ------------------------------------------------------------------------ - -MAINTAINER = $(shell grep 'Maintainer: ' familiar/$(CONTROL) | cut -d ' ' -f 2-) - -ifndef BUILD -BUILD = ../build -endif - -transdist := familiar/dist-translation -templates := $(BUILD)/familiar -ipkglist := translation-ipkgs.txt - -clean-dist-translation: - rm -rf $(transdist) $(ipkglist) - -real-translation-package: all-mo - rm -rf $(transdist) $(ipkglist) - for LINGUA in $(LINGUAS); do \ - i=$$(echo $$LINGUA | tr '[A-Z_]' '[a-z+]'); \ - mkdir -p $(transdist)/$$i/CONTROL; \ - mkdir -p $(transdist)/$$i$(PREFIX)/share/locale/$$LINGUA/LC_MESSAGES; \ - install -m 644 po/$$LINGUA.mo $(transdist)/$$i$(PREFIX)/share/locale/$$LINGUA/LC_MESSAGES/$(PACKAGE).mo; \ - sed -e "s//$(MAINTAINER)/;s//$(BINPACKAGE)/;s//$(VERSION)/;s//$$i/;s!!$(SOURCE)!" $(templates)/control.translation > $(transdist)/$$i/CONTROL/control; \ - install $(templates)/postinst.translation $(transdist)/$$i/CONTROL/postinst; \ - $(IPKG_BUILD) -g 0 -o 0 $(transdist)/$$i | sed 's/^Packaged .*into //; t 1; d; : 1; s:.*/::' >> $(ipkglist); \ - done - -translation-ipkg: - make PREFIX=/usr real-translation-package diff --git a/packages/gpe-conf/files/desktop-categories.patch b/packages/gpe-conf/files/desktop-categories.patch deleted file mode 100644 index 57215aae6b..0000000000 --- a/packages/gpe-conf/files/desktop-categories.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- gpe-conf-0.1.22/gpe-conf.desktop.in.old 2004-11-29 19:54:23.000000000 +0000 -+++ gpe-conf-0.1.22/gpe-conf.desktop.in 2004-11-29 19:54:35.000000000 +0000 -@@ -5,6 +5,6 @@ - Terminal=0 - Type=Application - Icon=gpe-config.png --Categories=Application;SystemSettings;GPE -+Categories=Application;GPE; - StartupNotify=True - SingleInstance=True diff --git a/packages/gpe-conf/files/fixsegfault.patch b/packages/gpe-conf/files/fixsegfault.patch deleted file mode 100644 index 7f1ccbe432..0000000000 --- a/packages/gpe-conf/files/fixsegfault.patch +++ /dev/null @@ -1,44 +0,0 @@ -Index: network.c -=================================================================== -RCS file: /cvs/gpe/base/gpe-conf/network.c,v -retrieving revision 1.55.2.2 -retrieving revision 1.55.2.3 -diff -u -r1.55.2.2 -r1.55.2.3 ---- network.c 16 Feb 2006 22:32:30 -0000 1.55.2.2 -+++ network.c 20 Feb 2006 01:34:44 -0000 1.55.2.3 -@@ -289,19 +289,23 @@ - i = iflen-1; - - fd = fopen(_PATH_PROCNET_WIRELESS, "r"); -- fgets(buffer, 256, fd); // chuck first two lines; -- fgets(buffer, 256, fd); -- while (!feof(fd)) { -- if (fgets(buffer, 256, fd) == NULL) -- break; -- name = buffer; -- sep = strrchr(buffer, ':'); -- if (sep) *sep = 0; -- while(*name == ' ') name++; -- if (!strcmp(name, ifname)) -- iflist[iflen - 1].iswireless = TRUE; -- } -+ if (fd != NULL) -+ { -+ fgets(buffer, 256, fd); // chuck first two lines; -+ fgets(buffer, 256, fd); -+ while (!feof(fd)) -+ { -+ if (fgets(buffer, 256, fd) == NULL) -+ break; -+ name = buffer; -+ sep = strrchr(buffer, ':'); -+ if (sep) *sep = 0; -+ while(*name == ' ') name++; -+ if (!strcmp(name, ifname)) -+ iflist[iflen - 1].iswireless = TRUE; -+ } - fclose(fd); -+ } - } - else - i = existing; diff --git a/packages/gpe-conf/files/ipaq-sleep-configName.patch b/packages/gpe-conf/files/ipaq-sleep-configName.patch deleted file mode 100644 index 34f22094ad..0000000000 --- a/packages/gpe-conf/files/ipaq-sleep-configName.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- gpe-conf-0.1.30/sleep/main.c.orig 2006-06-05 12:23:34.458994776 +0200 -+++ gpe-conf-0.1.30/sleep/main.c 2006-06-05 12:23:40.216119560 +0200 -@@ -23,7 +23,7 @@ - g_spawn_command_line_sync (cmd, NULL, NULL, NULL, NULL); - if(save_ISconf(ISconf, ISconf->confName)) { - char homeConf[MAXPATHLEN]; -- sprintf(homeConf, "%s/ipaq-sleep.conf", getenv("HOME")); -+ sprintf(homeConf, "%s/.sleep.conf", getenv("HOME")); - if(!save_ISconf(ISconf, homeConf)) - strcpy(ISconf->confName, homeConf); - } -@@ -42,7 +42,7 @@ - char cname[MAXPATHLEN]; - GtkWidget *GPE_Config_Sleep; - -- sprintf(cname,"%s/ipaq-sleep.conf",g_get_home_dir()); -+ sprintf(cname,"%s/.sleep.conf",g_get_home_dir()); - ISconf = load_ISconf(cname); - if(ISconf == NULL) { - strcpy(cname, "/etc/ipaq-sleep.conf"); diff --git a/packages/gpe-conf/gpe-conf_0.1.30.bb b/packages/gpe-conf/gpe-conf_0.1.30.bb deleted file mode 100644 index 5588420e45..0000000000 --- a/packages/gpe-conf/gpe-conf_0.1.30.bb +++ /dev/null @@ -1,28 +0,0 @@ -PACKAGES = "gpe-conf gpe-conf-panel" -LICENSE = "GPL" -SECTION = "gpe" -PRIORITY = "optional" -MAINTAINER = "Florian Boor " -PR="r2" - -inherit gpe - -SRC_URI += " file://fixsegfault.patch;patch=1;pnum=0 \ - file://ipaq-sleep-configName.patch;patch=1" - -DEPENDS = "gtk+ libgpewidget libxsettings libxsettings-client pcmcia-cs xst xset ipaq-sleep ntp gpe-login gpe-icons" -RDEPENDS_${PN} = "xst xset ipaq-sleep ntpdate gpe-login gpe-icons" -RDEPENDS_gpe-conf-panel = "gpe-conf" -FILES_${PN} = "${sysconfdir} ${bindir} ${datadir}/pixmaps \ - ${datadir}/applications/gpe-conf-* ${datadir}/gpe/pixmaps \ - ${datadir}/gpe-conf" -FILES_gpe-conf-panel = "${datadir}/applications/gpe-conf.desktop" - -do_compile () { - oe_runmake PREFIX=${prefix} - oe_runmake all-desktop PREFIX=${prefix} -} - -do_install () { - oe_runmake MACHINE=${MACHINE} PREFIX=${prefix} DESTDIR=${D} install-program -} diff --git a/packages/gpe-conf/gpe-conf_0.2.1.bb b/packages/gpe-conf/gpe-conf_0.2.1.bb deleted file mode 100644 index 9cb5b6b059..0000000000 --- a/packages/gpe-conf/gpe-conf_0.2.1.bb +++ /dev/null @@ -1,24 +0,0 @@ -LICENSE = "GPL" -SECTION = "gpe" -PRIORITY = "optional" - -DEPENDS = "gtk+ esound audiofile libgpewidget libxsettings libxsettings-client" -RDEPENDS_${PN} = "xst xset ipaq-sleep ntpdate gpe-login gpe-icons timezones" -RDEPENDS_gpe-conf-panel = "gpe-conf" - -MAINTAINER = "Florian Boor " -PR="r0" - -GPE_TARBALL_SUFFIX = "bz2" - -inherit gpe autotools pkgconfig - -PACKAGES += "gpe-conf-panel" - -FILES_${PN} = "${sysconfdir} ${bindir} ${datadir}/pixmaps \ - ${datadir}/applications/gpe-conf-* ${datadir}/gpe/pixmaps \ - ${datadir}/gpe-conf" - -FILES_gpe-conf-panel = "${datadir}/applications/gpe-conf.desktop" - - diff --git a/packages/gpe-conf/gpe-conf_0.2.2.bb b/packages/gpe-conf/gpe-conf_0.2.2.bb index 9cb5b6b059..995a42f621 100644 --- a/packages/gpe-conf/gpe-conf_0.2.2.bb +++ b/packages/gpe-conf/gpe-conf_0.2.2.bb @@ -1,13 +1,14 @@ -LICENSE = "GPL" -SECTION = "gpe" +DESCRIPTION = "Configuration applets for GPE" +SECTION = "gpe" PRIORITY = "optional" +MAINTAINER = "Florian Boor " +LICENSE = "GPL" DEPENDS = "gtk+ esound audiofile libgpewidget libxsettings libxsettings-client" RDEPENDS_${PN} = "xst xset ipaq-sleep ntpdate gpe-login gpe-icons timezones" RDEPENDS_gpe-conf-panel = "gpe-conf" -MAINTAINER = "Florian Boor " -PR="r0" +PR = "r0" GPE_TARBALL_SUFFIX = "bz2" @@ -18,7 +19,6 @@ PACKAGES += "gpe-conf-panel" FILES_${PN} = "${sysconfdir} ${bindir} ${datadir}/pixmaps \ ${datadir}/applications/gpe-conf-* ${datadir}/gpe/pixmaps \ ${datadir}/gpe-conf" - FILES_gpe-conf-panel = "${datadir}/applications/gpe-conf.desktop" diff --git a/packages/gpe-conf/gpe-conf_cvs.bb b/packages/gpe-conf/gpe-conf_cvs.bb index a0bec2b70f..e8da8a2646 100644 --- a/packages/gpe-conf/gpe-conf_cvs.bb +++ b/packages/gpe-conf/gpe-conf_cvs.bb @@ -1,25 +1,27 @@ DEFAULT_PREFERENCE = "-1" -S = "${WORKDIR}/${PN}" -PV = "0.1.29+cvs${SRCDATE}" -PR = "r2" - -inherit autotools gpe - -SRC_URI = "${HANDHELDS_CVS};module=gpe/base/${PN}" - -PACKAGES = "gpe-conf gpe-conf-panel" -LICENSE = "GPL" +DESCRIPTION = "Configuration applets for GPE" SECTION = "gpe" PRIORITY = "optional" MAINTAINER = "Florian Boor " - +LICENSE = "GPL" DEPENDS = "gtk+ libgpewidget libxsettings libxsettings-client pcmcia-cs xst xset ipaq-sleep ntp gpe-login gpe-icons" RDEPENDS_${PN} = "xst xset ipaq-sleep ntpdate gpe-login gpe-icons" RDEPENDS_gpe-conf-panel = "gpe-conf" + +PV = "0.2.2+cvs${SRCDATE}" +PR = "r0" + +SRC_URI = "${HANDHELDS_CVS};module=gpe/base/${PN}" +S = "${WORKDIR}/${PN}" + +inherit autotools gpe + +PACKAGES = "gpe-conf gpe-conf-panel" + FILES_${PN} = "${sysconfdir} ${bindir} ${datadir}/pixmaps \ - ${datadir}/applications/gpe-conf-* ${datadir}/gpe/pixmaps \ - ${datadir}/gpe-conf" + ${datadir}/applications/gpe-conf-* ${datadir}/gpe/pixmaps \ + ${datadir}/gpe-conf" FILES_gpe-conf-panel = "${datadir}/applications/gpe-conf.desktop" -- cgit v1.2.3 From 3428d0098febbb8553df208dafffb8400db9c566 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 7 Sep 2006 13:54:35 +0000 Subject: openocd: unbreak build --- packages/openocd/openocd_svn.bb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/openocd/openocd_svn.bb b/packages/openocd/openocd_svn.bb index 2652e15eae..26ab365b0e 100644 --- a/packages/openocd/openocd_svn.bb +++ b/packages/openocd/openocd_svn.bb @@ -2,11 +2,13 @@ HOMEPAGE = "http://openocd.berlios.de/" DESCRIPTION = "Free and Open On-Chip Debugging, In-System Programming and Boundary-Scan Testing" LICENSE = "GPL" +PV = "0.0+svn${SRCDATE}" + inherit autotools SRC_URI = "svn://svn.berlios.de/;module=${PN}" -S = "${WORKDIR}/${PN}" +S = "${WORKDIR}/${PN}/trunk" EXTRA_OECONF = " --disable-ftdi2232 --disable-ftd2xx" -- cgit v1.2.3 From 6f5ad23ff4f0e08383a18355330ceb7b2f79f4a6 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 7 Sep 2006 14:27:25 +0000 Subject: gimp: add 2.3.10 --- packages/gimp/gimp_2.3.10.bb | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/gimp/gimp_2.3.10.bb b/packages/gimp/gimp_2.3.10.bb index eb760ec9d8..f28ff7d52d 100644 --- a/packages/gimp/gimp_2.3.10.bb +++ b/packages/gimp/gimp_2.3.10.bb @@ -1,23 +1,23 @@ -DESCRIPTION = "The GIMP is the GNU Image Manipulation Program." -HOMEPAGE = "http://www.gimp.org" -LICENSE = "GPL" -MAINTAINER = "Koen Kooi " +DESCRIPTION = "The GIMP is the GNU Image Manipulation Program." +HOMEPAGE = "http://www.gimp.org" +MAINTAINER = "Koen Kooi " +LICENSE = "GPL" -SRC_URI = "ftp://ftp.gimp.org/pub/gimp/v2.3/gimp-${PV}.tar.bz2 \ - file://configure-libwmf.patch;patch=1" - -DEPENDS = "sed-native libart-lgpl gtk+ jpeg libpng libexif tiff" +DEPENDS = "sed-native libart-lgpl gtk+ jpeg libpng libexif tiff" -DEFAULT_PREFERENCE = "-1" +SRC_URI = "ftp://ftp.gimp.org/pub/gimp/v2.3/gimp-${PV}.tar.bz2 \ + file://configure-libwmf.patch;patch=1" inherit autotools pkgconfig + #Don't laugh, this just builds a threaded gimp -EXTRA_OECONF = " --disable-gtktest \ - --disable-print \ - --disable-python \ - --enable-mp \ - --without-libwmf" +EXTRA_OECONF = " --disable-gtktest \ + --disable-print \ + --disable-python \ + --enable-mp \ + --without-libwmf" do_configure_append() { - find ${S} -name Makefile | xargs sed -i s:'-I$(includedir)':'-I.':g + find ${S} -name Makefile | xargs sed -i s:'-I$(includedir)':'-I.':g } + -- cgit v1.2.3 From 1cd49843e337ea08e4f35facc77f62a11c272fd7 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Thu, 7 Sep 2006 23:02:42 +0000 Subject: linux-oz-2.6.17: Update to latest ASoC (and disable 32bit audio to get cxx00 working, include mmc conflict fix). Add cxx00 overlay support. Update poodle patches preparing patch for mainline. --- .../linux/linux-openzaurus-2.6.17/defconfig-spitz | 107 +++++++++++++-------- packages/linux/linux-openzaurus_2.6.17.bb | 14 +-- 2 files changed, 76 insertions(+), 45 deletions(-) diff --git a/packages/linux/linux-openzaurus-2.6.17/defconfig-spitz b/packages/linux/linux-openzaurus-2.6.17/defconfig-spitz index 22a544f1b4..1fbf999473 100644 --- a/packages/linux/linux-openzaurus-2.6.17/defconfig-spitz +++ b/packages/linux/linux-openzaurus-2.6.17/defconfig-spitz @@ -1,13 +1,15 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16 -# Thu Mar 23 22:11:12 2006 +# Linux kernel version: 2.6.17 +# Sun Sep 3 23:29:17 2006 # CONFIG_ARM=y CONFIG_MMU=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 # # Code maturity level options @@ -30,6 +32,7 @@ CONFIG_BSD_PROCESS_ACCT=y CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_UID16=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -45,10 +48,6 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -60,7 +59,6 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -68,6 +66,7 @@ CONFIG_KMOD=y # # Block layer # +# CONFIG_BLK_DEV_IO_TRACE is not set # # IO Schedulers @@ -89,11 +88,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set CONFIG_ARCH_PXA=y # CONFIG_ARCH_RPC is not set @@ -113,6 +114,7 @@ CONFIG_ARCH_PXA=y # Intel PXA2xx Implementations # # CONFIG_ARCH_LUBBOCK is not set +# CONFIG_MACH_LOGICPD_PXA270 is not set # CONFIG_MACH_MAINSTONE is not set # CONFIG_ARCH_PXA_IDP is not set CONFIG_PXA_SHARPSL=y @@ -171,6 +173,7 @@ CONFIG_PCMCIA_PXA2XX=y # CONFIG_PREEMPT=y CONFIG_NO_IDLE_HZ=y +CONFIG_HZ=100 # CONFIG_AEABI is not set # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set CONFIG_SELECT_MEMORY_MODEL=y @@ -188,6 +191,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/hda1 rootfstype=ext3 rw fbcon=rotate:1 dyntick=enable debug" # CONFIG_XIP_KERNEL is not set # @@ -249,6 +253,7 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set CONFIG_INET_DIAG=m CONFIG_INET_TCP_DIAG=m @@ -261,9 +266,11 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IP_VS is not set CONFIG_IPV6=m # CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set 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 @@ -289,6 +296,7 @@ CONFIG_IP_NF_IRC=m CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m # CONFIG_IP_NF_PPTP is not set +# CONFIG_IP_NF_H323 is not set CONFIG_IP_NF_QUEUE=m # @@ -409,6 +417,8 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m +# CONFIG_IEEE80211_SOFTMAC is not set +CONFIG_WIRELESS_EXT=y # # Device Drivers @@ -481,7 +491,6 @@ CONFIG_MTD_SHARP_SL=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -525,7 +534,7 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set # CONFIG_BLK_DEV_RAM is not set -CONFIG_BLK_DEV_RAM_COUNT=16 +# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -662,6 +671,7 @@ CONFIG_MII=m # Wireless LAN (non-hamradio) # CONFIG_NET_RADIO=y +# CONFIG_NET_WIRELESS_RTNETLINK is not set # # Obsolete Wireless cards support (pre-802.11) @@ -893,10 +903,6 @@ CONFIG_I2C_PXA=y # Misc devices # -# -# Multimedia Capabilities Port drivers -# - # # Multi-Function Devices # @@ -906,9 +912,17 @@ CONFIG_I2C_PXA=y # CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y -CONFIG_LEDS_TRIGGERS=y + +# +# LED drivers +# CONFIG_LEDS_SPITZ=y # CONFIG_LEDS_TOSA is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_IDE_DISK=y @@ -916,11 +930,13 @@ CONFIG_LEDS_TRIGGER_IDE_DISK=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices # # CONFIG_DVB is not set +CONFIG_USB_DABUSB=m # # Graphics support @@ -930,10 +946,14 @@ 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=y # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_S1D13XXX is not set CONFIG_FB_PXA=y +CONFIG_FB_PXA_LCD_QVGA=y +# CONFIG_FB_PXA_LCD_VGA is not set +CONFIG_FB_PXA_OVERLAY=y # CONFIG_FB_PXA_PARAMETERS is not set # CONFIG_FB_W100 is not set # CONFIG_FB_VIRTUAL is not set @@ -960,14 +980,20 @@ CONFIG_FONT_8x16=y # # Logo configuration # -# CONFIG_LOGO is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +# CONFIG_LOGO_LINUX_CLUT224 is not set +# CONFIG_LOGO_OHAND_CLUT224 is not set +# CONFIG_LOGO_OZ240_CLUT224 is not set +# CONFIG_LOGO_OZ480_CLUT224 is not set +CONFIG_LOGO_OZ640_CLUT224=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_DEVICE=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_DEVICE=y CONFIG_BACKLIGHT_CORGI=y -# CONFIG_BACKLIGHT_HP680 is not set # # Sound @@ -980,17 +1006,22 @@ CONFIG_SOUND=m CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m CONFIG_SND_SEQUENCER=m # CONFIG_SND_SEQ_DUMMY is not set CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y # CONFIG_SND_SEQUENCER_OSS is not set # CONFIG_SND_DYNAMIC_MINORS is not set CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y CONFIG_SND_VERBOSE_PRINTK=y CONFIG_SND_DEBUG=y # CONFIG_SND_DEBUG_DETECT is not set +# CONFIG_SND_PCM_XRUN_DEBUG is not set # # Generic devices @@ -1017,6 +1048,8 @@ CONFIG_SND_USB_AUDIO=m # # PCMCIA devices # +# CONFIG_SND_VXPOCKET is not set +# CONFIG_SND_PDAUDIOCF is not set # # SoC audio support @@ -1032,13 +1065,15 @@ CONFIG_SND_SOC=m # CONFIG_SND_PXA2xx_SOC=m CONFIG_SND_PXA2xx_SOC_I2S=m -# CONFIG_SND_PXA2xx_SOC_MAINSTONE is not set -# CONFIG_SND_PXA2xx_SOC_MAINSTONE_WM8753 is not set -# CONFIG_SND_PXA2xx_SOC_MAINSTONE_WM9713 is not set -# CONFIG_SND_PXA2xx_SOC_MAINSTONE_WM9712 is not set -# CONFIG_SND_PXA2xx_SOC_CORGI is not set CONFIG_SND_PXA2xx_SOC_SPITZ=m -# CONFIG_SND_PXA2xx_SOC_TOSA is not set + +# +# SoC Audio for the Atmel AT91 +# + +# +# SoC Audio for the Freescale i.MX +# # # Soc Codecs @@ -1049,6 +1084,7 @@ CONFIG_SND_SOC_WM8750=m # CONFIG_SND_SOC_WM8753 is not set # CONFIG_SND_SOC_WM8772 is not set # CONFIG_SND_SOC_WM8971 is not set +# CONFIG_SND_SOC_WM8974 is not set # CONFIG_SND_SOC_WM9713 is not set # CONFIG_SND_SOC_WM9712 is not set # CONFIG_SND_SOC_UDA1380 is not set @@ -1064,6 +1100,7 @@ CONFIG_SND_SOC_WM8750=m # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set CONFIG_USB=m # CONFIG_USB_DEBUG is not set @@ -1089,7 +1126,6 @@ CONFIG_USB_SL811_CS=m # # USB Device Class drivers # -# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m @@ -1132,9 +1168,7 @@ CONFIG_USB_WACOM=m # CONFIG_USB_ACECAD is not set CONFIG_USB_KBTAB=m CONFIG_USB_POWERMATE=m -CONFIG_USB_MTOUCH=m -# CONFIG_USB_ITMTOUCH is not set -CONFIG_USB_EGALAX=m +# CONFIG_USB_TOUCHSCREEN is not set # CONFIG_USB_YEALINK is not set CONFIG_USB_XPAD=m CONFIG_USB_ATI_REMOTE=m @@ -1148,15 +1182,6 @@ CONFIG_USB_ATI_REMOTE=m CONFIG_USB_MDC800=m CONFIG_USB_MICROTEK=m -# -# USB Multimedia devices -# -CONFIG_USB_DABUSB=m - -# -# Video4Linux support is needed for USB Multimedia device support -# - # # USB Network Adapters # @@ -1187,6 +1212,7 @@ CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y # CONFIG_USB_SERIAL_AIRPRIME is not set # CONFIG_USB_SERIAL_ANYDATA is not set +# CONFIG_USB_SERIAL_ARK3116 is not set CONFIG_USB_SERIAL_BELKIN=m # CONFIG_USB_SERIAL_WHITEHEAT is not set CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m @@ -1194,6 +1220,7 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_CYPRESS_M8=m CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m +# CONFIG_USB_SERIAL_FUNSOFT is not set CONFIG_USB_SERIAL_VISOR=m CONFIG_USB_SERIAL_IPAQ=m CONFIG_USB_SERIAL_IR=m @@ -1218,6 +1245,7 @@ CONFIG_USB_SERIAL_KEYSPAN=m CONFIG_USB_SERIAL_KLSI=m CONFIG_USB_SERIAL_KOBIL_SCT=m CONFIG_USB_SERIAL_MCT_U232=m +# CONFIG_USB_SERIAL_NAVMAN is not set CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_SERIAL_HP4X is not set CONFIG_USB_SERIAL_SAFE=m @@ -1263,6 +1291,7 @@ CONFIG_USB_PXA27X=m # CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_AT91 is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set # CONFIG_USB_GADGET_DUALSPEED is not set CONFIG_USB_ZERO=m @@ -1284,6 +1313,7 @@ CONFIG_MMC_PXA=y # # Real Time Clock # +CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" @@ -1302,6 +1332,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_M48T86 is not set CONFIG_RTC_DRV_SA1100=y # CONFIG_RTC_DRV_TEST is not set @@ -1353,7 +1384,6 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set # CONFIG_CONFIGFS_FS is not set # @@ -1508,6 +1538,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set # CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set @@ -1561,5 +1592,5 @@ CONFIG_CRC_CCITT=y # CONFIG_CRC16 is not set CONFIG_CRC32=y CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff --git a/packages/linux/linux-openzaurus_2.6.17.bb b/packages/linux/linux-openzaurus_2.6.17.bb index ef03c0e434..a1bcec9b86 100644 --- a/packages/linux/linux-openzaurus_2.6.17.bb +++ b/packages/linux/linux-openzaurus_2.6.17.bb @@ -1,6 +1,6 @@ require linux-openzaurus.inc -PR = "r21" +PR = "r22" # Handy URLs # git://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git \ @@ -28,10 +28,9 @@ SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.17.tar.bz2 \ ${RPSRC}/spectrumcs_fix-r0.patch;patch=1 \ file://00-hostap.patch;patch=1;status=merged \ file://10-pcnet.patch;patch=1;status=merged \ - ${RPSRC}/alsa/asoc-v0.11pre12.patch;patch=1 \ + ${RPSRC}/alsa/asoc-v0.11.3.patch;patch=1 \ + ${RPSRC}/alsa/asoc_zaurus_fixups-r0.patch;patch=1 \ ${RPSRC}/asoc_makefile-r0.patch;patch=1 \ - ${RPSRC}/alsa/asoc_platform_dev_fix-r0.patch;patch=1 \ - ${RPSRC}/asoc_poodle_morehack-r0.patch;patch=1 \ ${RPSRC}/hx2750_base-r27.patch;patch=1 \ ${RPSRC}/hx2750_bl-r7.patch;patch=1 \ ${RPSRC}/hx2750_pcmcia-r2.patch;patch=1 \ @@ -46,10 +45,11 @@ SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.17.tar.bz2 \ ${RPSRC}/usb_pxa27x_udc-r0.patch;patch=1 \ ${RPSRC}/usb_add_epalloc-r1.patch;patch=1 \ ${DOSRC}/kexec-arm-r3.patch;patch=1 \ - ${RPSRC}/locomo_kbd_tweak-r0.patch;patch=1 \ - ${RPSRC}/poodle_pm-r1.patch;patch=1 \ + ${RPSRC}/locomo_kbd_tweak-r1.patch;patch=1 \ + ${RPSRC}/poodle_pm-r2.patch;patch=1 \ ${RPSRC}/pxafb_changeres-r0.patch;patch=1 \ - ${RPSRC}/poodle_audio-r1.patch;patch=1 \ + ${RPSRC}/poodle_audio-r2.patch;patch=1 \ + ${RPSRC}/pxa27x_overlay-r1.patch;patch=1 \ file://serial-add-support-for-non-standard-xtals-to-16c950-driver.patch;patch=1 \ file://hrw-pcmcia-ids-r4.patch;patch=1 \ ${RPSRC}/logo_oh-r0.patch.bz2;patch=1;status=unmergable \ -- cgit v1.2.3 From 93c40996e9da30e39a06cffd85b3fdc403d71c47 Mon Sep 17 00:00:00 2001 From: Chris Larson Date: Fri, 8 Sep 2006 08:08:58 +0000 Subject: package.bbclass: Make legitimize_package_name also convert style encoding of unicode codepoints into their utf-8 representation, as in glibc locale files. --- classes/package.bbclass | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/classes/package.bbclass b/classes/package.bbclass index 9b913ecf82..03999a54ef 100644 --- a/classes/package.bbclass +++ b/classes/package.bbclass @@ -1,4 +1,15 @@ def legitimize_package_name(s): + import re + + def fixutf(m): + cp = m.group(1) + if cp: + return ('\u%s' % cp).decode('unicode_escape').encode('utf-8') + + # Handle unicode codepoints encoded as , as in glibc locale files. + s = re.sub('', fixutf, s) + + # Remaining package name validity fixes return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-') STAGING_PKGMAPS_DIR ?= "${STAGING_DIR}/pkgmaps" -- cgit v1.2.3 From 85a2bb4f66cf3ccd6307d65491995118366b2b36 Mon Sep 17 00:00:00 2001 From: Leon Zhang Date: Fri, 8 Sep 2006 09:10:16 +0000 Subject: opie-eye: fix install --- packages/opie-eye/opie-eye.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/opie-eye/opie-eye.inc b/packages/opie-eye/opie-eye.inc index 71b41b56b0..d78acfc167 100644 --- a/packages/opie-eye/opie-eye.inc +++ b/packages/opie-eye/opie-eye.inc @@ -20,6 +20,7 @@ do_compile_append() { } do_install() { + install -d ${D}${palmtopdir}/bin install -m 0755 opie-eye_slave ${D}${palmtopdir}/bin/ install -d ${D}${palmtopdir}/pics/${APPNAME}/ install -m 0644 ${WORKDIR}/pics/${APPNAME}/*.png ${D}${palmtopdir}/pics/${APPNAME}/ -- cgit v1.2.3 From 8a3aeeb6e7a3ba86cf130dbc34474c0b7be23369 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 8 Sep 2006 09:27:55 +0000 Subject: minimo: check in stuff from #1391 (various authors) to make it easier for people to test --- packages/mozilla/files/minimo.desktop | 13 +- packages/mozilla/minimo/minimo | 4 + packages/mozilla/minimo/minimo.patch | 567 ++++++++++++++++++++++++++++++++++ packages/mozilla/minimo/minimo.png | Bin 0 -> 4323 bytes packages/mozilla/minimo/mozconfig | 43 ++- packages/mozilla/minimo_0.016+cvs.bb | 144 +++++++++ 6 files changed, 750 insertions(+), 21 deletions(-) create mode 100644 packages/mozilla/minimo/minimo create mode 100644 packages/mozilla/minimo/minimo.patch create mode 100644 packages/mozilla/minimo/minimo.png create mode 100644 packages/mozilla/minimo_0.016+cvs.bb diff --git a/packages/mozilla/files/minimo.desktop b/packages/mozilla/files/minimo.desktop index 5ef0f2075a..7120ee5202 100644 --- a/packages/mozilla/files/minimo.desktop +++ b/packages/mozilla/files/minimo.desktop @@ -1,9 +1,10 @@ [Desktop Entry] -Name=Minimo -Comment=Minimo web browser -Exec=minimo http://www.mozilla.org/projects/minimo/home.html -Terminal=0 Type=Application +Name=Minimo +GenericName=Web Browser +Comment=Browse the web Icon=minimo.png -Categories=Application;Network; -StartupNotify=True +Exec=minimo +Terminal=false +Categories=Network;WebBrowser; +StartupNotify=true diff --git a/packages/mozilla/minimo/minimo b/packages/mozilla/minimo/minimo new file mode 100644 index 0000000000..d130173adf --- /dev/null +++ b/packages/mozilla/minimo/minimo @@ -0,0 +1,4 @@ +#!/bin/sh +export MOZILLA_FIVE_HOME=/usr/lib/mozilla-minimo +export LD_LIBRARY_PATH=${MOZILLA_FIVE_HOME} +exec ${MOZILLA_FIVE_HOME}/minimo "$@" diff --git a/packages/mozilla/minimo/minimo.patch b/packages/mozilla/minimo/minimo.patch new file mode 100644 index 0000000000..a1f9291167 --- /dev/null +++ b/packages/mozilla/minimo/minimo.patch @@ -0,0 +1,567 @@ +Index: mozilla/content/html/content/src/nsFormSubmission.cpp +=================================================================== +RCS file: /cvsroot/mozilla/content/html/content/src/nsFormSubmission.cpp,v +retrieving revision 1.46 +diff --context=3 -r1.46 nsFormSubmission.cpp +*** mozilla/content/html/content/src/nsFormSubmission.cpp 13 Jul 2005 16:55:59 -0000 1.46 +--- mozilla/content/html/content/src/nsFormSubmission.cpp 21 Jul 2006 00:27:14 -0000 +*************** +*** 1315,1325 **** + nsresult rv = NS_OK; + + nsCAutoString charset(aCharset); +- // canonical name is passed so that we just have to check against +- // *our* canonical names listed in charsetaliases.properties +- if (charset.EqualsLiteral("ISO-8859-1")) { +- charset.AssignLiteral("windows-1252"); +- } + + // use UTF-8 for UTF-16* and UTF-32* (per WHATWG and existing practice of + // MS IE/Opera). +--- 1315,1320 ---- +Index: mozilla/embedding/base/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/embedding/base/Makefile.in,v +retrieving revision 1.34.8.2 +diff --context=3 -r1.34.8.2 Makefile.in +*** mozilla/embedding/base/Makefile.in 14 Feb 2006 05:28:31 -0000 1.34.8.2 +--- mozilla/embedding/base/Makefile.in 21 Jul 2006 00:27:14 -0000 +*************** +*** 43,48 **** +--- 43,49 ---- + + MODULE = embed_base + LIBRARY_NAME = embed_base_s ++ EXPORT_LIBRARY = 1 + XPIDL_MODULE = embed_base + + include $(DEPTH)/config/autoconf.mk +Index: mozilla/js/src/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/js/src/Makefile.in,v +retrieving revision 3.95.4.4 +diff --context=3 -r3.95.4.4 Makefile.in +*** mozilla/js/src/Makefile.in 7 Jul 2006 02:12:02 -0000 3.95.4.4 +--- mozilla/js/src/Makefile.in 21 Jul 2006 00:27:14 -0000 +*************** +*** 46,51 **** +--- 46,52 ---- + + MODULE = js + LIBRARY_NAME = mozjs ++ EXPORT_LIBRARY = 1 + LIB_IS_C_ONLY = 1 + GRE_MODULE = 1 + +Index: mozilla/minimo/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/minimo/Makefile.in,v +retrieving revision 1.1.2.2 +diff --context=3 -r1.1.2.2 Makefile.in +*** mozilla/minimo/Makefile.in 29 Jun 2006 06:11:30 -0000 1.1.2.2 +--- mozilla/minimo/Makefile.in 21 Jul 2006 00:27:14 -0000 +*************** +*** 41,46 **** + + include $(DEPTH)/config/autoconf.mk + +! DIRS = config components chrome locales customization base + + include $(topsrcdir)/config/rules.mk +--- 41,46 ---- + + include $(DEPTH)/config/autoconf.mk + +! DIRS = config chrome locales customization base + + include $(topsrcdir)/config/rules.mk +Index: mozilla/minimo/base/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/minimo/base/Makefile.in,v +retrieving revision 1.3.2.7 +diff --context=3 -r1.3.2.7 Makefile.in +*** mozilla/minimo/base/Makefile.in 18 Apr 2006 21:04:38 -0000 1.3.2.7 +--- mozilla/minimo/base/Makefile.in 21 Jul 2006 00:27:14 -0000 +*************** +*** 95,101 **** + + # this should move into the toolkit! + LOCAL_INCLUDES = -I$(srcdir) -I$(topsrcdir)/xpfe/browser/src/ +- CPPSRCS += nsBrowserStatusFilter.cpp nsBrowserInstance.cpp + + ifdef WINCE + RCINCLUDE = wince/SplashScreen.rc +--- 95,100 ---- +*************** +*** 139,148 **** + endif + + +- FINAL_LINK_COMPS=$(topsrcdir)/minimo/base/$(FINAL_PLATFORM)/minimo-link-comps +- FINAL_LINK_COMP_NAMES=$(topsrcdir)/minimo/base/$(FINAL_PLATFORM)/minimo-link-names +- FINAL_LINK_LIBS=$(topsrcdir)/minimo/base/$(FINAL_PLATFORM)/minimo-link-libs +- + include $(topsrcdir)/config/static-config.mk + + EXTRA_DEPS += $(STATIC_EXTRA_DEPS) +--- 138,143 ---- +*************** +*** 176,189 **** + # (same as in mozilla/js/src/Makefile.in) + ifdef WINCE + LDFLAGS += -OPT:NOICF + endif + +- export:: +- $(NSINSTALL) $(topsrcdir)/xpfe/browser/src/nsBrowserStatusFilter.cpp . +- $(NSINSTALL) $(topsrcdir)/xpfe/browser/src/nsBrowserInstance.cpp . +- +- +- GARBAGE += nsBrowserStatusFilter.cpp nsBrowserInstance.cpp + + ifdef WINCE + package:: +--- 171,181 ---- + # (same as in mozilla/js/src/Makefile.in) + ifdef WINCE + LDFLAGS += -OPT:NOICF ++ else ++ # Hack to work around libxpcom_core.a / libunicharutil_s.a link order problem. ++ LDFLAGS += -u NS_StringGetData_P -u NS_StringGetMutableData_P + endif + + + ifdef WINCE + package:: +Index: mozilla/minimo/base/Minimo.cpp +=================================================================== +RCS file: /cvsroot/mozilla/minimo/base/Minimo.cpp,v +retrieving revision 1.1.2.11 +diff --context=3 -r1.1.2.11 Minimo.cpp +*** mozilla/minimo/base/Minimo.cpp 11 Jul 2006 19:37:05 -0000 1.1.2.11 +--- mozilla/minimo/base/Minimo.cpp 21 Jul 2006 00:27:15 -0000 +*************** +*** 781,789 **** + CreateListenerWindow(); + #endif + +! #ifdef MOZ_WIDGET_GTK2 + gtk_set_locale(); + gtk_init(&argc, &argv); + #endif + + #ifdef HACKY_PRE_LOAD_LIBRARY +--- 781,794 ---- + CreateListenerWindow(); + #endif + +! #if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_GTK2) +! #if defined(MOZ_WIDGET_GTK) + gtk_set_locale(); ++ #endif + gtk_init(&argc, &argv); ++ ++ gtk_widget_set_default_visual(gdk_rgb_get_visual()); ++ gtk_widget_set_default_colormap(gdk_rgb_get_cmap()); + #endif + + #ifdef HACKY_PRE_LOAD_LIBRARY +Index: mozilla/minimo/base/SplashScreen.cpp +=================================================================== +RCS file: /cvsroot/mozilla/minimo/base/SplashScreen.cpp,v +retrieving revision 1.1.2.3 +diff --context=3 -r1.1.2.3 SplashScreen.cpp +*** mozilla/minimo/base/SplashScreen.cpp 11 Jul 2006 18:44:17 -0000 1.1.2.3 +--- mozilla/minimo/base/SplashScreen.cpp 21 Jul 2006 00:27:15 -0000 +*************** +*** 180,188 **** +--- 180,203 ---- + void KillSplashScreen() {} + void GetScreenSize(unsigned long* x, unsigned long* y) + { ++ #ifdef MOZ_WIDGET_GTK2 ++ GdkDisplay* display = gdk_display_get_default(); ++ if (display != NULL) ++ { ++ GdkScreen *screen; ++ screen = gdk_display_get_default_screen(display); ++ *x = gdk_screen_get_width(screen); ++ *y = gdk_screen_get_height(screen); ++ } ++ else ++ { ++ #endif + // we need to figure this out. + *x = 240; + *y = 320; ++ #ifdef MOZ_WIDGET_GTK2 ++ } ++ #endif + } + + +Index: mozilla/minimo/chrome/content/minimo.js +=================================================================== +RCS file: /cvsroot/mozilla/minimo/chrome/content/minimo.js,v +retrieving revision 1.9.2.90 +diff --context=3 -r1.9.2.90 minimo.js +*** mozilla/minimo/chrome/content/minimo.js 11 Jul 2006 19:37:04 -0000 1.9.2.90 +--- mozilla/minimo/chrome/content/minimo.js 21 Jul 2006 00:27:16 -0000 +*************** +*** 1313,1319 **** + 43 const FIND_LINKS = 2; + http://lxr.mozilla.org/mozilla/source/toolkit/components/typeaheadfind/content/findBar.js + */ +! gBrowser.fastFind.find(vQuery,0); + } + } catch (e) { + onErrorHandler(e); +--- 1313,1319 ---- + 43 const FIND_LINKS = 2; + http://lxr.mozilla.org/mozilla/source/toolkit/components/typeaheadfind/content/findBar.js + */ +! gBrowser.fastFind.find(vQuery,0,this.mHasFocus); + } + } catch (e) { + onErrorHandler(e); +*************** +*** 1324,1330 **** + + function DoBrowserFindNext() { + try { +! gBrowser.fastFind.findNext(); + } catch (e) { + onErrorHandler(e); + } +--- 1324,1330 ---- + + function DoBrowserFindNext() { + try { +! gBrowser.fastFind.findNext(this.mHasFocus); + } catch (e) { + onErrorHandler(e); + } +Index: mozilla/minimo/config/linux_package.sh +=================================================================== +RCS file: /cvsroot/mozilla/minimo/config/linux_package.sh,v +retrieving revision 1.8.2.3 +diff --context=3 -r1.8.2.3 linux_package.sh +*** mozilla/minimo/config/linux_package.sh 30 Jun 2006 16:35:19 -0000 1.8.2.3 +--- mozilla/minimo/config/linux_package.sh 21 Jul 2006 00:27:16 -0000 +*************** +*** 29,37 **** + cp -pRL bin/libnssckbi.so minimo + cp -pRL bin/libsmime3.so minimo + cp -pRL bin/libsoftokn3.so minimo +- cp -pRL bin/libsoftokn3.chk minimo + cp -pRL bin/libfreebl3.so minimo +- cp -pRL bin/libfreebl3.chk minimo + cp -pRL bin/libssl3.so minimo + + mkdir -p minimo/chrome +--- 29,35 ---- +*************** +*** 62,69 **** + cp -pRL bin/components/nsHelperAppDlg.js minimo/components + cp -pRL bin/components/nsProgressDialog.js minimo/components + +- cp -pRL bin/extensions/spatial-navigation@extensions.mozilla.org/components/* minimo/components +- + mkdir -p minimo/greprefs + cp -pRL bin/greprefs/* minimo/greprefs + +--- 60,65 ---- +*************** +*** 80,86 **** + + echo Linking XPT files. + +! bin/xpt_link minimo/components/all.xpt bin/components/*.xpt + + echo Chewing on chrome + +--- 76,82 ---- + + echo Linking XPT files. + +! host/bin/host_xpt_link minimo/components/all.xpt bin/components/*.xpt + + echo Chewing on chrome + +Index: mozilla/profile/dirserviceprovider/src/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/profile/dirserviceprovider/src/Makefile.in,v +retrieving revision 1.7 +diff --context=3 -r1.7 Makefile.in +*** mozilla/profile/dirserviceprovider/src/Makefile.in 6 Apr 2005 03:35:21 -0000 1.7 +--- mozilla/profile/dirserviceprovider/src/Makefile.in 21 Jul 2006 00:27:16 -0000 +*************** +*** 44,49 **** +--- 44,50 ---- + + MODULE = profdirserviceprovider + LIBRARY_NAME = profdirserviceprovider_s ++ EXPORT_LIBRARY = 1 + MOZILLA_INTERNAL_API = 1 + + REQUIRES = xpcom \ +Index: mozilla/security/coreconf/Linux.mk +=================================================================== +RCS file: /cvsroot/mozilla/security/coreconf/Linux.mk,v +retrieving revision 1.18.18.1 +diff --context=3 -r1.18.18.1 Linux.mk +*** mozilla/security/coreconf/Linux.mk 3 Feb 2006 22:26:36 -0000 1.18.18.1 +--- mozilla/security/coreconf/Linux.mk 21 Jul 2006 00:27:16 -0000 +*************** +*** 117,122 **** +--- 117,126 ---- + OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE + CPU_ARCH = mips + else ++ ifeq ($(OS_TEST),arm) ++ OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE ++ CPU_ARCH = arm ++ else + OS_REL_CFLAGS = -DLINUX1_2 -Di386 -D_XOPEN_SOURCE + CPU_ARCH = x86 + endif +*************** +*** 133,138 **** +--- 137,143 ---- + endif + endif + endif ++ endif + + + LIBC_TAG = _glibc +Index: mozilla/security/coreconf/arch.mk +=================================================================== +RCS file: /cvsroot/mozilla/security/coreconf/arch.mk,v +retrieving revision 1.17.14.2 +diff --context=3 -r1.17.14.2 arch.mk +*** mozilla/security/coreconf/arch.mk 3 Feb 2006 22:26:36 -0000 1.17.14.2 +--- mozilla/security/coreconf/arch.mk 21 Jul 2006 00:27:16 -0000 +*************** +*** 60,77 **** + 64BIT_TAG= + endif + +! OS_ARCH := $(subst /,_,$(shell uname -s)) + + # + # Attempt to differentiate between sparc and x86 Solaris + # + +! OS_TEST := $(shell uname -m) +! ifeq ($(OS_TEST),i86pc) +! OS_RELEASE := $(shell uname -r)_$(OS_TEST) +! else +! OS_RELEASE := $(shell uname -r) +! endif + + # + # Force the IRIX64 machines to use IRIX. +--- 60,73 ---- + 64BIT_TAG= + endif + +! OS_ARCH := Linux + + # + # Attempt to differentiate between sparc and x86 Solaris + # + +! OS_TEST := arm +! OS_RELEASE := 2.6 + + # + # Force the IRIX64 machines to use IRIX. +Index: mozilla/toolkit/components/build/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/toolkit/components/build/Makefile.in,v +retrieving revision 1.24.2.10 +diff --context=3 -r1.24.2.10 Makefile.in +*** mozilla/toolkit/components/build/Makefile.in 13 Jul 2006 20:08:29 -0000 1.24.2.10 +--- mozilla/toolkit/components/build/Makefile.in 21 Jul 2006 00:27:17 -0000 +*************** +*** 112,118 **** + $(NULL) + + SHARED_LIBRARY_LIBS = \ +- ../startup/src/$(LIB_PREFIX)appstartup_s.$(LIB_SUFFIX) \ + $(NULL) + + ifdef MOZ_XPINSTALL +--- 112,117 ---- +Index: mozilla/toolkit/components/startup/src/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/toolkit/components/startup/src/Makefile.in,v +retrieving revision 1.7 +diff --context=3 -r1.7 Makefile.in +*** mozilla/toolkit/components/startup/src/Makefile.in 27 Jul 2005 20:42:44 -0000 1.7 +--- mozilla/toolkit/components/startup/src/Makefile.in 21 Jul 2006 00:27:17 -0000 +*************** +*** 43,48 **** +--- 43,49 ---- + + MODULE = toolkitcomps + LIBRARY_NAME = appstartup_s ++ EXPORT_LIBRARY = 1 + FORCE_STATIC_LIB = 1 + LIBXUL_LIBRARY = 1 + +Index: mozilla/toolkit/xre/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/toolkit/xre/Makefile.in,v +retrieving revision 1.48.2.3 +diff --context=3 -r1.48.2.3 Makefile.in +*** mozilla/toolkit/xre/Makefile.in 30 Sep 2005 19:52:44 -0000 1.48.2.3 +--- mozilla/toolkit/xre/Makefile.in 21 Jul 2006 00:27:17 -0000 +*************** +*** 45,51 **** + + MODULE = xulapp + LIBRARY_NAME = xulapp_s +- EXPORT_LIBRARY = 1 + LIBXUL_LIBRARY = 1 + + REQUIRES = \ +--- 45,50 ---- +*************** +*** 176,189 **** + + include $(topsrcdir)/config/rules.mk + +- ifdef BUILD_STATIC_LIBS +- export:: +- @$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_LINK_COMP_NAMES) Apprunner +- # embedding/browser/gtk/src/Makefile.in sucks! we need to add an empty line to +- # FINAL_LINK_COMPS to keep the two lists in sync :-( +- @$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_LINK_COMPS) "" +- endif +- + LOCAL_INCLUDES += \ + -I$(srcdir) \ + -I$(topsrcdir)/xpfe/bootstrap \ +--- 175,180 ---- +Index: mozilla/xpcom/build/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/xpcom/build/Makefile.in,v +retrieving revision 1.90.2.2 +diff --context=3 -r1.90.2.2 Makefile.in +*** mozilla/xpcom/build/Makefile.in 29 Jan 2006 16:51:02 -0000 1.90.2.2 +--- mozilla/xpcom/build/Makefile.in 21 Jul 2006 00:27:17 -0000 +*************** +*** 61,67 **** + endif + + # Do not set EXPORT_LIBRARY as we do not want xpcom in the static libs list +! #EXPORT_LIBRARY = 1 + GRE_MODULE = 1 + MOZILLA_INTERNAL_API = 1 + +--- 61,67 ---- + endif + + # Do not set EXPORT_LIBRARY as we do not want xpcom in the static libs list +! EXPORT_LIBRARY = 1 + GRE_MODULE = 1 + MOZILLA_INTERNAL_API = 1 + +Index: mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm.cpp +=================================================================== +RCS file: /cvsroot/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm.cpp,v +retrieving revision 1.7 +diff --context=3 -r1.7 xptcstubs_arm.cpp +*** mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm.cpp 18 Apr 2004 14:18:18 -0000 1.7 +--- mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_arm.cpp 21 Jul 2006 00:27:17 -0000 +*************** +*** 45,53 **** + #endif + + /* Specify explicitly a symbol for this function, don't try to guess the c++ mangled symbol. */ +! static nsresult PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint32* args) asm("_PrepareAndDispatch"); + +! static nsresult + PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint32* args) + { + #define PARAM_BUFFER_COUNT 16 +--- 45,53 ---- + #endif + + /* Specify explicitly a symbol for this function, don't try to guess the c++ mangled symbol. */ +! nsresult PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint32* args) asm("_PrepareAndDispatch"); + +! nsresult + PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint32* args) + { + #define PARAM_BUFFER_COUNT 16 +Index: mozilla/xpfe/browser/src/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/xpfe/browser/src/Makefile.in,v +retrieving revision 1.70 +diff --context=3 -r1.70 Makefile.in +*** mozilla/xpfe/browser/src/Makefile.in 18 Mar 2005 21:23:45 -0000 1.70 +--- mozilla/xpfe/browser/src/Makefile.in 21 Jul 2006 00:27:17 -0000 +*************** +*** 44,49 **** +--- 44,50 ---- + + MODULE = browser + LIBRARY_NAME = mozbrwsr_s ++ EXPORT_LIBRARY = 1 + FORCE_STATIC_LIB = 1 + LIBXUL_LIBRARY = 1 + MODULE_NAME = nsBrowserModule +Index: mozilla/xpfe/components/build/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/xpfe/components/build/Makefile.in,v +retrieving revision 1.69.8.1 +diff --context=3 -r1.69.8.1 Makefile.in +*** mozilla/xpfe/components/build/Makefile.in 27 Sep 2005 00:15:25 -0000 1.69.8.1 +--- mozilla/xpfe/components/build/Makefile.in 21 Jul 2006 00:27:17 -0000 +*************** +*** 44,50 **** + + MODULE = appcomps + LIBRARY_NAME = appcomps +- EXPORT_LIBRARY = 1 + IS_COMPONENT = 1 + MODULE_NAME = application + LIBXUL_LIBRARY = 1 +--- 44,49 ---- +Index: mozilla/xpfe/components/filepicker/src/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/xpfe/components/filepicker/src/Makefile.in,v +retrieving revision 1.9.8.1 +diff --context=3 -r1.9.8.1 Makefile.in +*** mozilla/xpfe/components/filepicker/src/Makefile.in 22 May 2006 16:29:32 -0000 1.9.8.1 +--- mozilla/xpfe/components/filepicker/src/Makefile.in 21 Jul 2006 00:27:17 -0000 +*************** +*** 47,53 **** + MODULE = filepicker + LIBRARY_NAME = fileview + SHORT_LIBNAME = fileview +- EXPORT_LIBRARY = 1 + IS_COMPONENT = 1 + MODULE_NAME = nsFileViewModule + MOZILLA_INTERNAL_API = 1 +--- 47,52 ---- +Index: mozilla/xpfe/components/find/src/Makefile.in +=================================================================== +RCS file: /cvsroot/mozilla/xpfe/components/find/src/Makefile.in,v +retrieving revision 1.37 +diff --context=3 -r1.37 Makefile.in +*** mozilla/xpfe/components/find/src/Makefile.in 18 Mar 2005 21:23:46 -0000 1.37 +--- mozilla/xpfe/components/find/src/Makefile.in 21 Jul 2006 00:27:17 -0000 +*************** +*** 45,51 **** + MODULE = appcomps + XPIDL_MODULE = mozfind + LIBRARY_NAME = mozfind +- EXPORT_LIBRARY = 1 + IS_COMPONENT = 1 + MODULE_NAME = nsFindComponent + LIBXUL_LIBRARY = 1 +--- 45,50 ---- diff --git a/packages/mozilla/minimo/minimo.png b/packages/mozilla/minimo/minimo.png new file mode 100644 index 0000000000..f8b2e2192b Binary files /dev/null and b/packages/mozilla/minimo/minimo.png differ diff --git a/packages/mozilla/minimo/mozconfig b/packages/mozilla/minimo/mozconfig index 59cf8c77fb..393981e9fa 100644 --- a/packages/mozilla/minimo/mozconfig +++ b/packages/mozilla/minimo/mozconfig @@ -1,23 +1,36 @@ -mk_add_options MOZ_CO_PROJECT=minimo -ac_add_options --enable-application=minimo - +# mozilla/configure: Features and packages: -# use GTK+-2 widget set with XFT font rendering +ac_add_options --enable-application=minimo ac_add_options --enable-default-toolkit=gtk2 -ac_add_options --enable-xft ac_add_options --disable-freetype2 -ac_add_options --disable-plugins - +ac_add_options --enable-xft +ac_add_options --disable-postscript +ac_add_options --disable-xprint +ac_add_options --disable-gnomevfs +ac_add_options --disable-gnomeui +ac_add_options --disable-jsd +ac_add_options --disable-plugins +ac_add_options --disable-view-source +ac_add_options --disable-accessibility +ac_add_options --disable-xpinstall +ac_add_options --enable-single-profile +ac_add_options --disable-jsloader +ac_add_options --disable-printing +ac_add_options --enable-native-uconv +ac_add_options --enable-plaintext-editor-only +ac_add_options --disable-xpcom-obsolete +ac_add_options --disable-pref-extensions +ac_add_options --disable-extensions +ac_add_options --enable-image-decoders=png,gif,jpeg +ac_add_options --disable-mathml +ac_add_options --disable-installer +ac_add_options --disable-updater +ac_add_options --disable-tests ac_add_options --enable-optimize=-Os +ac_add_options --disable-logging ac_add_options --enable-strip -ac_add_options --disable-debug -ac_add_options --enable-reorder ac_add_options --enable-elf-dynstr-gc - -# enable static build ac_add_options --disable-shared ac_add_options --enable-static - -# remove link dependency on libstdc++.so -LIBS=-lsupc++ - +ac_add_options --disable-profilesharing +ac_add_options --disable-profilelocking diff --git a/packages/mozilla/minimo_0.016+cvs.bb b/packages/mozilla/minimo_0.016+cvs.bb new file mode 100644 index 0000000000..4505a1f63e --- /dev/null +++ b/packages/mozilla/minimo_0.016+cvs.bb @@ -0,0 +1,144 @@ +DESCRIPTION = "A minimal version of the Mozilla web browser for mobile devices" +SECTION = "x11/network" +LICENSE = "MPL/GPL/LGPL" +HOMEPAGE = "http://www.mozilla.org/projects/minimo/" +PRIORITY = "optional" + +DEPENDS = "libxrender xt xft fontconfig freetype libidl dbus-glib pango atk gtk+" + +CVSSVR="cvs-mirror.mozilla.org" +BRTAG = "MOZILLA_1_8_BRANCH" +MOZDATE = "20060720" + +PV = "0.016+cvs${MOZDATE}" +PR = r0 + +SRC_URI = "cvs://anonymous@${CVSSVR}/cvsroot;module=mozilla;tag=${BRTAG};date=${MOZDATE} \ + file://minimo.patch;patch=1 \ + file://mozconfig file://minimo \ + file://minimo.desktop file://minimo.png" + +inherit autotools + +S = "${WORKDIR}/mozilla" + +export MOZCONFIG = "${WORKDIR}/mozconfig" + +export CROSS_COMPILE="1" +export ac_cv_prog_HOST_CC="${BUILD_CC}" +export ac_cv_prog_HOST_CFLAGS="${BUILD_CFLAGS}" +export ac_cv_prog_HOST_CXX="${BUILD_CXX}" +export ac_cv_prog_HOST_CXXFLAGS="${BUILD_CXXFLAGS}" + +mozdir="${D}${libdir}/mozilla-minimo" + +EXTRA_OECONF += "--build=${BUILD_SYS} --host=${BUILD_SYS} --target=${TARGET_SYS} " + +do_configure() { + cd ${S} + oe_runmake -f client.mk CONFIGURE_ARGS="${EXTRA_OECONF}" configure +} + +do_compile() { + cd ${S} + oe_runmake -f client.mk build +} + +do_install() { + cd ${WORKDIR} + + install -d ${D}${bindir} + install -m 0755 minimo ${D}${bindir} + + install -d ${D}${datadir}/applications + install -m 0644 minimo.desktop ${D}${datadir}/applications + + install -d ${D}/${datadir}/pixmaps + install -m 0644 minimo.png ${D}${datadir}/pixmaps + + cd ${S} + + ./minimo/config/linux_package.sh ${S} ${S}/minimo/config + + cd dist/minimo + + install -d ${D}${mozdir} + install -m 0755 minimo ${D}${mozdir} + install -m 0755 libfreebl3.so ${D}${mozdir} + install -m 0755 libnspr4.so ${D}${mozdir} + install -m 0755 libnss3.so ${D}${mozdir} + install -m 0755 libnssckbi.so ${D}${mozdir} + install -m 0755 libplc4.so ${D}${mozdir} + install -m 0755 libplds4.so ${D}${mozdir} + install -m 0755 libsmime3.so ${D}${mozdir} + install -m 0755 libsoftokn3.so ${D}${mozdir} + install -m 0755 libssl3.so ${D}${mozdir} + + install -d ${D}${mozdir}/chrome + install -m 0644 chrome/classic.jar ${D}${mozdir}/chrome + install -m 0644 chrome/classic.manifest ${D}${mozdir}/chrome + install -m 0644 chrome/en-US.jar ${D}${mozdir}/chrome + install -m 0644 chrome/en-US.manifest ${D}${mozdir}/chrome + install -m 0644 chrome/minimo-skin-vga.jar ${D}${mozdir}/chrome + install -m 0644 chrome/minimo-skin-vga.manifest ${D}${mozdir}/chrome + install -m 0644 chrome/minimo-skin.jar ${D}${mozdir}/chrome + install -m 0644 chrome/minimo-skin.manifest ${D}${mozdir}/chrome + install -m 0644 chrome/minimo.jar ${D}${mozdir}/chrome + install -m 0644 chrome/minimo.manifest ${D}${mozdir}/chrome + install -m 0644 chrome/pippki.jar ${D}${mozdir}/chrome + install -m 0644 chrome/pippki.manifest ${D}${mozdir}/chrome + install -m 0644 chrome/toolkit.jar ${D}${mozdir}/chrome + install -m 0644 chrome/toolkit.manifest ${D}${mozdir}/chrome + + install -d ${D}${mozdir}/components + install -m 0644 components/all.xpt ${D}${mozdir}/components + install -m 0644 components/nsHelperAppDlg.js ${D}${mozdir}/components + install -m 0644 components/nsProgressDialog.js ${D}${mozdir}/components + + install -d ${D}${mozdir}/greprefs + install -m 0644 greprefs/all.js ${D}${mozdir}/greprefs + install -m 0644 greprefs/security-prefs.js ${D}${mozdir}/greprefs + + install -d ${D}${mozdir}/res + install -m 0644 res/forms.css ${D}${mozdir}/res + install -m 0644 res/html.css ${D}${mozdir}/res + install -m 0644 res/quirk.css ${D}${mozdir}/res + install -m 0644 res/ua.css ${D}${mozdir}/res + install -m 0644 res/arrow.gif ${D}${mozdir}/res + install -m 0644 res/arrowd.gif ${D}${mozdir}/res + install -m 0644 res/broken-image.gif ${D}${mozdir}/res + install -m 0644 res/loading-image.gif ${D}${mozdir}/res + install -m 0644 res/charsetData.properties ${D}${mozdir}/res + install -m 0644 res/charsetalias.properties ${D}${mozdir}/res + install -m 0644 res/langGroups.properties ${D}${mozdir}/res + install -m 0644 res/language.properties ${D}${mozdir}/res + install -m 0644 res/unixcharset.properties ${D}${mozdir}/res + + install -d ${D}${mozdir}/res/dtd + install -m 0644 res/dtd/xhtml11.dtd ${D}${mozdir}/res/dtd + + install -d ${D}${mozdir}/res/entityTables + install -m 0644 res/entityTables/html40Latin1.properties ${D}${mozdir}/res/entityTables + install -m 0644 res/entityTables/html40Special.properties ${D}${mozdir}/res/entityTables + install -m 0644 res/entityTables/html40Symbols.properties ${D}${mozdir}/res/entityTables + install -m 0644 res/entityTables/htmlEntityVersions.properties ${D}${mozdir}/res/entityTables + install -m 0644 res/entityTables/transliterate.properties ${D}${mozdir}/res/entityTables + + install -d ${D}${mozdir}/res/fonts + install -m 0644 res/fonts/fontEncoding.properties ${D}${mozdir}/res/fonts + install -m 0644 res/fonts/pangoFontEncoding.properties ${D}${mozdir}/res/fonts + + install -d ${D}${mozdir}/res/html + install -m 0644 res/html/gopher-audio.gif ${D}${mozdir}/res/html + install -m 0644 res/html/gopher-binary.gif ${D}${mozdir}/res/html + install -m 0644 res/html/gopher-find.gif ${D}${mozdir}/res/html + install -m 0644 res/html/gopher-image.gif ${D}${mozdir}/res/html + install -m 0644 res/html/gopher-menu.gif ${D}${mozdir}/res/html + install -m 0644 res/html/gopher-movie.gif ${D}${mozdir}/res/html + install -m 0644 res/html/gopher-sound.gif ${D}${mozdir}/res/html + install -m 0644 res/html/gopher-telnet.gif ${D}${mozdir}/res/html + install -m 0644 res/html/gopher-text.gif ${D}${mozdir}/res/html + install -m 0644 res/html/gopher-unknown.gif ${D}${mozdir}/res/html +} + +FILES_${PN} += "${mozdir}" -- cgit v1.2.3 From eb79f18a31b65ba137cfaeb7e121e134b2b20d87 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 8 Sep 2006 11:21:15 +0000 Subject: udev: add 0.100, default preference = -1 --- packages/udev/udev-100/.mtn2git_empty | 0 packages/udev/udev-100/flags.patch | 51 +++++++ packages/udev/udev-100/init | 242 +++++++++++++++++++++++++++++++ packages/udev/udev-100/links.conf | 20 +++ packages/udev/udev-100/local.rules | 31 ++++ packages/udev/udev-100/permissions.rules | 109 ++++++++++++++ packages/udev/udev-100/udev.rules | 98 +++++++++++++ packages/udev/udev_100.bb | 63 ++++++++ 8 files changed, 614 insertions(+) create mode 100644 packages/udev/udev-100/.mtn2git_empty create mode 100644 packages/udev/udev-100/flags.patch create mode 100644 packages/udev/udev-100/init create mode 100644 packages/udev/udev-100/links.conf create mode 100644 packages/udev/udev-100/local.rules create mode 100644 packages/udev/udev-100/permissions.rules create mode 100644 packages/udev/udev-100/udev.rules create mode 100644 packages/udev/udev_100.bb diff --git a/packages/udev/udev-100/.mtn2git_empty b/packages/udev/udev-100/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/udev/udev-100/flags.patch b/packages/udev/udev-100/flags.patch new file mode 100644 index 0000000000..492a39881c --- /dev/null +++ b/packages/udev/udev-100/flags.patch @@ -0,0 +1,51 @@ +--- udev-089/Makefile.orig 2006-04-08 13:32:53.000000000 +0200 ++++ udev-089/Makefile 2006-04-08 13:34:27.000000000 +0200 +@@ -117,28 +117,28 @@ + AR = $(CROSS_COMPILE)ar + RANLIB = $(CROSS_COMPILE)ranlib + +-CFLAGS = -g -Wall -pipe -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 ++override CFLAGS = -g -Wall -pipe -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 + WARNINGS = -Wstrict-prototypes -Wsign-compare -Wshadow \ + -Wchar-subscripts -Wmissing-declarations -Wnested-externs \ + -Wpointer-arith -Wcast-align -Wsign-compare -Wmissing-prototypes +-CFLAGS += $(WARNINGS) ++override CFLAGS += $(WARNINGS) + + LDFLAGS = -Wl,-warn-common + + OPTFLAGS = -Os +-CFLAGS += $(OPTFLAGS) ++override CFLAGS += $(OPTFLAGS) + + ifeq ($(strip $(USE_LOG)),true) +- CFLAGS += -DUSE_LOG ++ override CFLAGS += -DUSE_LOG + endif + + # if DEBUG is enabled, then we do not strip + ifeq ($(strip $(DEBUG)),true) +- CFLAGS += -DDEBUG ++ override CFLAGS += -DDEBUG + endif + + ifeq ($(strip $(USE_GCOV)),true) +- CFLAGS += -fprofile-arcs -ftest-coverage ++ override CFLAGS += -fprofile-arcs -ftest-coverage + LDFLAGS += -fprofile-arcs + endif + +@@ -151,11 +151,11 @@ + ifeq ($(strip $(USE_SELINUX)),true) + UDEV_OBJS += udev_selinux.o + LIB_OBJS += -lselinux -lsepol +- CFLAGS += -DUSE_SELINUX ++ override CFLAGS += -DUSE_SELINUX + endif + + ifeq ($(strip $(USE_STATIC)),true) +- CFLAGS += -DUSE_STATIC ++ override CFLAGS += -DUSE_STATIC + LDFLAGS += -static + endif + diff --git a/packages/udev/udev-100/init b/packages/udev/udev-100/init new file mode 100644 index 0000000000..cc25c026a3 --- /dev/null +++ b/packages/udev/udev-100/init @@ -0,0 +1,242 @@ +#!/bin/sh -e +### BEGIN INIT INFO +# Provides: udev +# Required-Start: mountvirtfs +# Required-Stop: +# Default-Start: S +# Default-Stop: +# Short-Description: Start udevd, populate /dev and load drivers. +### END INIT INFO + +# we need to unmount /dev/pts/ and remount it later over the tmpfs +unmount_devpts() { + if mountpoint -q /dev/pts/; then + umount -l /dev/pts/ + fi + + if mountpoint -q /dev/shm/; then + umount -l /dev/shm/ + fi +} + +# mount a tmpfs over /dev, if somebody did not already do it +mount_tmpfs() { + if grep -E -q "^[^[:space:]]+ /dev tmpfs" /proc/mounts; then + return + fi + + # /dev/.static/dev/ is used by MAKEDEV to access the real /dev/ directory. + # /etc/udev/ is recycled as a temporary mount point because it's the only + # directory which is guaranteed to be available. + mount -n -o bind /dev /etc/udev + + if ! mount -n -o size=$tmpfs_size,mode=0755 -t tmpfs tmpfs /dev; then + umount /etc/udev + echo "udev requires tmpfs support, not started." + exit 1 + fi + + mkdir -p /dev/.static/dev + chmod 700 /dev/.static/ + # The mount options in busybox are non-standard... + if test -x /bin/mount.util-linux + then + /bin/mount.util-linux --move /etc/udev /dev/.static/dev + elif test -x /bin/busybox + then + busybox mount -n -o move /etc/udev /dev/.static/dev + else + echo "udev requires an identifiable mount command, not started." + umount /etc/udev + umount /dev + exit 1 + fi +} + +create_dev_makedev() { + if [ -e /sbin/MAKEDEV ]; then + [ ! -e /dev/MAKEDEV ] || ln -s /sbin/MAKEDEV /dev/MAKEDEV + else + ln -s /bin/true /dev/MAKEDEV + fi +} + +# I hate this hack. -- Md +make_extra_nodes() { + if [ "$(echo /lib/udev/devices/*)" != "/lib/udev/devices/*" ]; then + cp -a /lib/udev/devices/* /dev/ + fi + + [ -e /etc/udev/links.conf ] || return 0 + grep '^[^#]' /etc/udev/links.conf | \ + while read type name arg1; do + [ "$type" -a "$name" -a ! -e "/dev/$name" -a ! -L "/dev/$name" ] ||continue + case "$type" in + L) ln -s $arg1 /dev/$name ;; + D) mkdir -p /dev/$name ;; + M) mknod -m 600 /dev/$name $arg1 ;; + *) echo "links.conf: unparseable line ($type $name $arg1)" ;; + esac + done +} + +supported_kernel() { + case "$(uname -r)" in + 2.[012345].*|2.6.[0-9]|2.6.[0-9][!0-9]*) return 1 ;; + 2.6.1[0-4]|2.6.1[0-4][!0-9]*) return 1 ;; + esac + return 0 +} + +load_input_modules() { + case "$(uname -r)" in + 2.6.1[0-5]|2.6.1[0-5][!0-9]*) ;; # <= 2.6.15 + *) return 0 + esac + + for module in mousedev evdev joydev; do + modprobe -q $module || true + done +} + +# shell version of /usr/bin/tty +my_tty() { + [ -x /bin/readlink ] || return 0 + [ -e /proc/self/fd/0 ] || return 0 + readlink --silent /proc/self/fd/0 || true +} + +warn_if_interactive() { + if [ "$RUNLEVEL" = "S" -a "$PREVLEVEL" = "N" ]; then + return + fi + + TTY=$(my_tty) + if [ -z "$TTY" -o "$TTY" = "/dev/console" ]; then + return + fi + + printf "\n\n\nIt has been detected that the command\n\n\t$0 $*\n\n" + printf "has been run from an interactive shell.\n" + printf "It will probably not do what you expect, so this script will wait\n" + printf "60 seconds before continuing. Press ^C to stop it.\n" + printf "RUNNING THIS COMMAND IS HIGHLY DISCOURAGED!\n\n\n\n" + sleep 60 +} + +############################################################################## + +[ -x /sbin/udevd ] || exit 0 + +PATH="/sbin:/bin:/usr/bin" + +# defaults +tmpfs_size="10M" +udev_root="/dev" + +if [ -e /etc/udev/udev.conf ]; then + . /etc/udev/udev.conf +fi + +if ! supported_kernel; then + echo "udev requires a kernel >= 2.6.15, not started." + exit 1 +fi + +if [ ! -e /proc/filesystems ]; then + echo "udev requires a mounted procfs, not started." + exit 1 +fi + +if ! grep -q '[[:space:]]tmpfs$' /proc/filesystems; then + echo "udev requires tmpfs support, not started." + exit 1 +fi + +if [ ! -d /sys/class/ ]; then + echo "udev requires a mounted sysfs, not started." + exit 1 +fi + +if [ ! -e /proc/sys/kernel/hotplug ]; then + echo "udev requires hotplug support, not started." + exit 1 +fi + +############################################################################## + +# When modifying this script, do not forget that between the time that +# the new /dev has been mounted and udevsynthesize has been run there will be +# no /dev/null. This also means that you cannot use the "&" shell command. + +udev_root=${udev_root%/} + +case "$1" in + start) + if [ -e "$udev_root/.udev/" ]; then + if mountpoint -q $udev_root/; then + TMPFS_MOUNTED=1 + else + echo ".udev/ already exists on the static $udev_root!" + fi + else + warn_if_interactive + fi + + echo > /proc/sys/kernel/hotplug + + if [ -z "$TMPFS_MOUNTED" ]; then + unmount_devpts + mount_tmpfs + [ -d /proc/1 ] || mount -n /proc + fi + + # /dev/null must be created before udevd is started + make_extra_nodes + + echo "Starting the hotplug events dispatcher" "udevd" + udevd --daemon + + # if this directory is not present /dev will not be updated by udev + mkdir -p /dev/.udev/db/ /dev/.udev/queue/ + + echo "Synthesizing the initial hotplug events" + udevtrigger + + load_input_modules + create_dev_makedev + + # wait for the udevd childs to finish + echo "Waiting for /dev to be fully populated" + if ! udevsettle; then + echo 'timeout' + fi + ;; + + stop) + echo "Stopping the hotplug events dispatcher" "udevd" + start-stop-daemon --stop --name udevd --quiet + ;; + + restart) + echo "Stopping the hotplug events dispatcher" "udevd" + if start-stop-daemon --stop --name udevd --quiet ; then + exit 1 + fi + + echo "Starting the hotplug events dispatcher" "udevd" + udevd --daemon + ;; + + reload) + udevcontrol reload_rules + ;; + + *) + echo "Usage: /etc/init.d/udev {start|stop|restart|reload}" + exit 1 + ;; +esac + +exit 0 + diff --git a/packages/udev/udev-100/links.conf b/packages/udev/udev-100/links.conf new file mode 100644 index 0000000000..ee26012039 --- /dev/null +++ b/packages/udev/udev-100/links.conf @@ -0,0 +1,20 @@ +# This file does not exist. Please do not ask the debian maintainer about it. +# You may use it to do strange and wonderful things, at your risk. + +L fd /proc/self/fd +L stdin /proc/self/fd/0 +L stdout /proc/self/fd/1 +L stderr /proc/self/fd/2 +L core /proc/kcore +L sndstat /proc/asound/oss/sndstat + +D pts +D shm + +# Hic sunt leones. +M ppp c 108 0 +D loop +M loop/0 b 7 0 +D net +M net/tun c 10 200 + diff --git a/packages/udev/udev-100/local.rules b/packages/udev/udev-100/local.rules new file mode 100644 index 0000000000..2308b52c4a --- /dev/null +++ b/packages/udev/udev-100/local.rules @@ -0,0 +1,31 @@ +# There are a number of modifiers that are allowed to be used in some +# of the different fields. They provide the following subsitutions: +# +# %n the "kernel number" of the device. +# For example, 'sda3' has a "kernel number" of '3' +# %e the smallest number for that name which does not matches an existing node +# %k the kernel name for the device +# %M the kernel major number for the device +# %m the kernel minor number for the device +# %b the bus id for the device +# %c the string returned by the PROGRAM +# %s{filename} the content of a sysfs attribute +# %% the '%' char itself +# + +# Media automounting +SUBSYSTEM=="block", ACTION=="add" RUN+="/etc/udev/scripts/mount.sh" +SUBSYSTEM=="block", ACTION=="remove" RUN+="/etc/udev/scripts/mount.sh" + +# Handle network interface setup +SUBSYSTEM=="net", ACTION=="add" RUN+="/etc/udev/scripts/network.sh" +SUBSYSTEM=="net", ACTION=="remove" RUN+="/etc/udev/scripts/network.sh" + +# The first rtc device is symlinked to /dev/rtc +KERNEL=="rtc0", SYMLINK+="rtc" + +# Try and modprobe for drivers for new hardware +ACTION=="add", DEVPATH=="/devices/*", ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe $env{MODALIAS}" + +# Create a symlink to any touchscreen input device +SUBSYSTEM=="input", KERNEL=="event[0-9]*", SYSFS{modalias}=="input:*-e0,1*,3,*a0,1,*18,*", SYMLINK+="input/touchscreen0" diff --git a/packages/udev/udev-100/permissions.rules b/packages/udev/udev-100/permissions.rules new file mode 100644 index 0000000000..8da35c3090 --- /dev/null +++ b/packages/udev/udev-100/permissions.rules @@ -0,0 +1,109 @@ +ACTION!="add", GOTO="permissions_end" + +# workarounds needed to synchronize with sysfs +DEVPATH=="/devices/*", ENV{PHYSDEVBUS}=="?*", WAIT_FOR_SYSFS="bus" +SUBSYSTEM=="scsi", WAIT_FOR_SYSFS="ioerr_cnt" +# only needed for kernels < 2.6.16 +SUBSYSTEM=="net", WAIT_FOR_SYSFS="address" +# only needed for kernels < 2.6.17 +SUBSYSTEM=="net", ENV{PHYSDEVDRIVER}=="?*", WAIT_FOR_SYSFS="device/driver" + +# default permissions for block devices +SUBSYSTEM=="block", GROUP="disk" +SUBSYSTEM=="block", SYSFS{removable}=="1", GROUP="floppy" + +# IDE devices +BUS=="ide", KERNEL=="hd[a-z]|pcd[0-9]*", DRIVER=="ide-cdrom|pcd", \ + IMPORT{program}="cdrom_id --export $tempnode" +ENV{ID_CDROM}=="?*", GROUP="cdrom" +BUS=="ide", KERNEL=="ht[0-9]*", GROUP="tape" +BUS=="ide", KERNEL=="nht[0-9]*", GROUP="tape" + +# SCSI devices +BUS=="scsi", SYSFS{type}=="1", GROUP="tape" +BUS=="scsi", SYSFS{type}=="3", SYSFS{vendor}=="HP", GROUP="scanner" +BUS=="scsi", SYSFS{type}=="5", GROUP="cdrom" +BUS=="scsi", SYSFS{type}=="6", GROUP="scanner" + +# USB devices +BUS=="usb", KERNEL=="legousbtower*", MODE="0666" +BUS=="usb", KERNEL=="lp[0-9]*", GROUP="lp" + +# usbfs-like devices +SUBSYSTEM=="usb_device", MODE="0664" + +# iRiver music players +SUBSYSTEM=="usb_device", GROUP="plugdev", \ + SYSFS{idVendor}=="4102", SYSFS{idProduct}=="10[01][135789]" + +# serial devices +SUBSYSTEM=="tty", GROUP="dialout" +SUBSYSTEM=="capi", GROUP="dialout" +SUBSYSTEM=="slamr", GROUP="dialout" +SUBSYSTEM=="zaptel", GROUP="dialout" + +# vc devices (all members of the tty subsystem) +KERNEL=="ptmx", MODE="0666", GROUP="root" +KERNEL=="console", MODE="0600", GROUP="root" +KERNEL=="tty", MODE="0666", GROUP="root" +KERNEL=="tty[0-9]*", GROUP="root" +KERNEL=="pty*", MODE="0666", GROUP="tty" + +# video devices +SUBSYSTEM=="video4linux", GROUP="video" +SUBSYSTEM=="drm", GROUP="video" +SUBSYSTEM=="dvb", GROUP="video" +SUBSYSTEM=="em8300", GROUP="video" +SUBSYSTEM=="graphics", GROUP="video" +SUBSYSTEM=="nvidia", GROUP="video" + +# misc devices +KERNEL=="random", MODE="0666" +KERNEL=="urandom", MODE="0666" +KERNEL=="mem", MODE="0640", GROUP="kmem" +KERNEL=="kmem", MODE="0640", GROUP="kmem" +KERNEL=="port", MODE="0640", GROUP="kmem" +KERNEL=="full", MODE="0666" +KERNEL=="null", MODE="0666" +KERNEL=="zero", MODE="0666" +KERNEL=="inotify", MODE="0666" +KERNEL=="sgi_fetchop", MODE="0666" +KERNEL=="sonypi", MODE="0666" +KERNEL=="agpgart", GROUP="video" +KERNEL=="nvram", GROUP="nvram" +KERNEL=="rtc", GROUP="audio" +KERNEL=="tpm*", MODE="0600", OWNER="tss", GROUP="tss" +KERNEL=="fuse", GROUP="fuse" + +KERNEL=="cdemu[0-9]*", GROUP="cdrom" +KERNEL=="pktcdvd[0-9]*", GROUP="cdrom" +KERNEL=="pktcdvd", MODE="0644" + +KERNEL=="uverbs*", GROUP="rdma" +KERNEL=="ucm*", GROUP="rdma" + +# printers and parallel devices +SUBSYSTEM=="printer", GROUP="lp" +SUBSYSTEM=="ppdev", GROUP="lp" +KERNEL=="pt[0-9]*", GROUP="tape" +KERNEL=="pht[0-9]*", GROUP="tape" + +# sound devices +SUBSYSTEM=="sound", GROUP="audio" + +# ieee1394 devices +KERNEL=="raw1394", GROUP="disk" +KERNEL=="dv1394*", GROUP="video" +KERNEL=="video1394*", GROUP="video" + +# input devices +KERNEL=="event[0-9]*", SYSFS{name}=="*dvb*|*DVB*|* IR *" \ + MODE="0664", GROUP="video" +KERNEL=="js[0-9]*", MODE="0664" + +# AOE character devices +SUBSYSTEM=="aoe", MODE="0220", GROUP="disk" +SUBSYSTEM=="aoe", KERNEL=="err", MODE="0440" + +LABEL="permissions_end" + diff --git a/packages/udev/udev-100/udev.rules b/packages/udev/udev-100/udev.rules new file mode 100644 index 0000000000..9c4ea4214d --- /dev/null +++ b/packages/udev/udev-100/udev.rules @@ -0,0 +1,98 @@ +# There are a number of modifiers that are allowed to be used in some +# of the different fields. They provide the following subsitutions: +# +# %n the "kernel number" of the device. +# For example, 'sda3' has a "kernel number" of '3' +# %e the smallest number for that name which does not matches an existing node +# %k the kernel name for the device +# %M the kernel major number for the device +# %m the kernel minor number for the device +# %b the bus id for the device +# %c the string returned by the PROGRAM +# %s{filename} the content of a sysfs attribute +# %% the '%' char itself +# + +# SCSI devices +BUS=="scsi", KERNEL=="sr[0-9]*", NAME="scd%n", SYMLINK+="sr%n" + +# USB devices +BUS=="usb", KERNEL=="auer[0-9]*", NAME="usb/%k" +BUS=="usb", KERNEL=="cpad[0-9]*", NAME="usb/%k" +BUS=="usb", KERNEL=="dabusb*", NAME="usb/%k" +BUS=="usb", KERNEL=="hiddev*", NAME="usb/%k" +BUS=="usb", KERNEL=="legousbtower*", NAME="usb/%k" +BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k" +BUS=="usb", KERNEL=="ttyUSB*", SYSFS{product}=="Palm Handheld*", \ + SYMLINK+="pilot" + +# usbfs-like devices +SUBSYSTEM=="usb_device", \ + PROGRAM="/bin/sh -c 'export X=%k; export X=$${X#usbdev}; export B=$${X%%%%.*}; export D=$${X#*.}; echo bus/usb/$$B/$$D'", SYMLINK+="%c" + +# serial devices +KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20" +KERNEL=="capi[0-9]*", NAME="capi/%n" + +# video devices +KERNEL=="card[0-9]*", NAME="dri/%k" + +# misc devices +KERNEL=="hw_random", NAME="hwrng" +KERNEL=="tun", NAME="net/%k" + +KERNEL=="cdemu[0-9]*", NAME="cdemu/%n" +KERNEL=="pktcdvd[0-9]*", NAME="pktcdvd/%n" +KERNEL=="pktcdvd", NAME="pktcdvd/control" + +KERNEL=="cpu[0-9]*", NAME="cpu/%n/cpuid" +KERNEL=="msr[0-9]*", NAME="cpu/%n/msr" +KERNEL=="microcode", NAME="cpu/microcode" + +KERNEL=="umad*", NAME="infiniband/%k" +KERNEL=="issm*", NAME="infiniband/%k" +KERNEL=="uverbs*", NAME="infiniband/%k" +KERNEL=="ucm", NAME="infiniband/%k" + +KERNEL=="buzzer", NAME="misc/buzzer" + +# ALSA devices +KERNEL=="controlC[0-9]*", NAME="snd/%k" +KERNEL=="hwC[D0-9]*", NAME="snd/%k" +KERNEL=="pcmC[D0-9cp]*", NAME="snd/%k" +KERNEL=="midiC[D0-9]*", NAME="snd/%k" +KERNEL=="timer", NAME="snd/%k" +KERNEL=="seq", NAME="snd/%k" + +# ieee1394 devices +KERNEL=="dv1394*", NAME="dv1394/%n" +KERNEL=="video1394*", NAME="video1394/%n" + +# input devices +KERNEL=="mice", NAME="input/%k" +KERNEL=="mouse[0-9]*", NAME="input/%k" +KERNEL=="event[0-9]*", NAME="input/%k" +KERNEL=="js[0-9]*", NAME="input/%k" +KERNEL=="ts[0-9]*", NAME="input/%k" +KERNEL=="uinput", NAME="input/%k" + +# Zaptel +KERNEL=="zapctl", NAME="zap/ctl" +KERNEL=="zaptimer", NAME="zap/timer" +KERNEL=="zapchannel", NAME="zap/channel" +KERNEL=="zappseudo", NAME="zap/pseudo" +KERNEL=="zap[0-9]*", NAME="zap/%n" + +# AOE character devices +SUBSYSTEM=="aoe", KERNEL=="discover", NAME="etherd/%k" +SUBSYSTEM=="aoe", KERNEL=="err", NAME="etherd/%k" +SUBSYSTEM=="aoe", KERNEL=="interfaces", NAME="etherd/%k" + +# device mapper creates its own device nodes, so ignore these +KERNEL=="dm-[0-9]*", OPTIONS+="ignore_device" +KERNEL=="device-mapper", NAME="mapper/control" + +KERNEL=="rfcomm[0-9]*", NAME="%k", GROUP="users", MODE="0660" + +# Firmware Helper +ACTION=="add", SUBSYSTEM=="firmware", RUN+="/lib/udev/firmware_helper" diff --git a/packages/udev/udev_100.bb b/packages/udev/udev_100.bb new file mode 100644 index 0000000000..2e9e8d500f --- /dev/null +++ b/packages/udev/udev_100.bb @@ -0,0 +1,63 @@ +DEFAULT_PREFERENCE = "-1" + +DESCRIPTION = "udev is a daemon which dynamically creates and removes device nodes from \ +/dev/, handles hotplug events and loads drivers at boot time. It replaces \ +the hotplug package and requires a kernel not older than 2.6.15." +DESCRIPTION_libvolume-id = "libvolume_id shared library, \ +used to detect the type of a file system and read its metadata." +DESCRIPTION_libvolume-id-dev = "libvolume_id development headers, \ +needed to link programs with libvolume_id." + +PR = "r0" + +SRC_URI = "http://kernel.org/pub/linux/utils/kernel/hotplug/udev-${PV}.tar.gz \ + file://noasmlinkage.patch;patch=1 \ + file://flags.patch;patch=1 \ + file://mount.blacklist \ + " + +require udev.inc + +SRC_URI_append_h2200 = " file://50-hostap_cs.rules " +PACKAGE_ARCH_h2200 = "h2200" + +INITSCRIPT_PARAMS = "start 03 S ." + +PACKAGES =+ "libvolume-id-dev libvolume-id" +PKG_libvolume-id-dev = "libvolume-id-dev" +FILES_libvolume-id-dev = "${includedir}/libvolume_id.h ${libdir}/libvolume_id.a ${libdir}/libvolume_id.so ${libdir}/pkgconfig/libvolume_id.pc" +FILES_libvolume-id = "${base_libdir}/libvolume_id.so.*" +FILES_${PN} += "${base_libdir}/udev/*" +FILES_${PN}-dbg += "${base_libdir}/udev/.debug" +UDEV_EXTRAS = "extras/firmware/ extras/scsi_id/ extras/volume_id/ extras/run_directory/" +EXTRA_OEMAKE += "libudevdir=/lib/udev libdir=${base_libdir} prefix=" + +do_install () { + install -d ${D}${usrsbindir} \ + ${D}${sbindir} + oe_runmake 'DESTDIR=${D}' INSTALL=install install + install -d ${D}${sysconfdir}/init.d + install -m 0755 ${WORKDIR}/init ${D}${sysconfdir}/init.d/udev + + install -d ${D}${sysconfdir}/udev/rules.d/ + + install -m 0644 ${WORKDIR}/mount.blacklist ${D}${sysconfdir}/udev/ + install -m 0644 ${WORKDIR}/local.rules ${D}${sysconfdir}/udev/rules.d/local.rules + install -m 0644 ${WORKDIR}/permissions.rules ${D}${sysconfdir}/udev/rules.d/permissions.rules + install -m 0644 ${WORKDIR}/udev.rules ${D}${sysconfdir}/udev/rules.d/udev.rules + install -m 0644 ${WORKDIR}/links.conf ${D}${sysconfdir}/udev/links.conf + if [ "${UDEV_DEVFS_RULES}" = "1" ]; then + install -m 0644 ${WORKDIR}/devfs-udev.rules ${D}${sysconfdir}/udev/rules.d/devfs-udev.rules + fi + + install -d ${D}${sysconfdir}/udev/scripts/ + + install -m 0755 ${WORKDIR}/mount.sh ${D}${sysconfdir}/udev/scripts/mount.sh + install -m 0755 ${WORKDIR}/network.sh ${D}${sysconfdir}/udev/scripts + + install -d ${D}${base_libdir}/udev/ +} + +do_install_append_h2200() { + install -m 0644 ${WORKDIR}/50-hostap_cs.rules ${D}${sysconfdir}/udev/rules.d/50-hostap_cs.rules +} -- cgit v1.2.3 From 067b1c71f57fabc6c8abba4cc2e3420637b06228 Mon Sep 17 00:00:00 2001 From: Frans Meulenbroeks Date: Fri, 8 Sep 2006 11:27:02 +0000 Subject: uclibc: chaned do_stage to do_install_prepend to resolve order issue --- packages/uclibc/uclibc.inc | 2 +- packages/uclibc/uclibc_0.9.28.bb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/uclibc/uclibc.inc b/packages/uclibc/uclibc.inc index e48c6d734d..2064489ec6 100644 --- a/packages/uclibc/uclibc.inc +++ b/packages/uclibc/uclibc.inc @@ -113,7 +113,7 @@ do_configure() { oe_runmake oldconfig } -do_stage() { +do_install_prepend() { # Install into the cross dir (this MUST be done first because we # will install crt1.o in the install_dev stage and gcc needs it) oe_runmake PREFIX= DEVEL_PREFIX=${UCLIBC_PREFIX}/ \ diff --git a/packages/uclibc/uclibc_0.9.28.bb b/packages/uclibc/uclibc_0.9.28.bb index 0a0fe100cd..807fcb8a67 100644 --- a/packages/uclibc/uclibc_0.9.28.bb +++ b/packages/uclibc/uclibc_0.9.28.bb @@ -1,5 +1,5 @@ DEFAULT_PREFERENCE = "1" -PR = "r6" +PR = "r7" require uclibc.inc -- cgit v1.2.3 From 1849c7146319438853e3b6c932003bde1a14b32f Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 8 Sep 2006 11:59:04 +0000 Subject: angstrom: clean up preferred_providers a bit --- conf/distro/angstrom-2007.1.conf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/conf/distro/angstrom-2007.1.conf b/conf/distro/angstrom-2007.1.conf index f3ad52beca..876975b875 100644 --- a/conf/distro/angstrom-2007.1.conf +++ b/conf/distro/angstrom-2007.1.conf @@ -93,9 +93,10 @@ PREFERRED_PROVIDER_virtual/xserver ?= xserver-kdrive # Others: PREFERRED_PROVIDER_virtual/libx11 ?= "diet-x11" -PREFERRED_PROVIDER_gconf ?= gconf-dbus -PREFERRED_PROVIDER_gnome-vfs ?= gnome-vfs -PREFERRED_PROVIDER_tslib ?= tslib +PREFERRED_PROVIDER_gconf ?= "gconf-dbus" +PREFERRED_PROVIDER_gnome-vfs ?= "gnome-vfs" +PREFERRED_PROVIDER_tslib ?= "tslib" +PREFERRED_PROVIDER_tslib-conf ?= "tslib" PREFERRED_PROVIDER_libgpewidget ?= "libgpewidget" PREFERRED_PROVIDER_ntp = "ntp" PREFERRED_PROVIDER_hotplug = "udev" -- cgit v1.2.3 From 6f4455ad4fe9f67a9b2cc316663b69f085af4031 Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 12:32:25 +0000 Subject: configuration: merged in changes to nylon/mtx from 4G repository * added mtx-2 machine (4G Surfbox II) * updated several defaults --- conf/distro/nylon.conf | 10 ++++++---- conf/machine/mtx-1.conf | 15 +++++++++++---- conf/machine/mtx-2.conf | 27 +++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 conf/machine/mtx-2.conf diff --git a/conf/distro/nylon.conf b/conf/distro/nylon.conf index a1d81e336f..b68d82ced6 100644 --- a/conf/distro/nylon.conf +++ b/conf/distro/nylon.conf @@ -19,7 +19,9 @@ PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc:gcc-cross" PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}g++:gcc-cross" PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}libc-for-gcc:glibc" -#SRCDATE = 20040916 +TARGET_FPU = "soft" + +SRCDATE := "20050527" PREFERRED_VERSION_glibc = "2.3.3" PREFERRED_VERSION_gcc-cross-initial = "3.3.4" @@ -28,11 +30,11 @@ PREFERRED_VERSION_gcc-cross-sdk = "3.3.4" PREFERRED_VERSION_gcc = "3.3.4" PREFERRED_VERSION_binutils-cross = "2.14.90.0.7" PREFERRED_VERSION_binutils-cross-sdk = "2.14.90.0.7" -PREFERRED_VERSION_binutils = "2.14.90.0.7" +PREFERRED_VERSION_binutils = "2.16" +PREFERRED_VERSION_shorewall = "2.0.9-monolithic" +PREFERRED_VERSION_ppp-dsl = "0.1-monolithic" -PREFERRED_VERSION_olsrd = "0.4.8" PREFERRED_VERSION_prism54-firmware = "1.0.3.0" -PREFERRED_VERSION_usbutils = "0.11" # usually overrrided from local.conf NYLON_RELEASE = "unstable" diff --git a/conf/machine/mtx-1.conf b/conf/machine/mtx-1.conf index 3a5f047ae0..73500b501d 100644 --- a/conf/machine/mtx-1.conf +++ b/conf/machine/mtx-1.conf @@ -3,11 +3,13 @@ #@DESCRIPTION: Machine configuration for the mtx-1 (aka MeshCube) TARGET_ARCH = "mipsel" +IPKG_ARCHS = "all mipsel ${MACHINE}" PREFERRED_PROVIDER_virtual/kernel = "linux-mtx-1" -#PREFERRED_VERSION_linux-mtx-1 = "2.4.24" -EXTRA_IMAGECMD_jffs2 = "--pad=0x1c00000 --little-endian --eraseblock=0x20000 -n" +# md: is the --pad=.. necessary? I believe not. +# EXTRA_IMAGECMD_jffs2 = "--pad=0x1c00000 --little-endian --eraseblock=0x20000 -n" +EXTRA_IMAGECMD_jffs2 = "--little-endian --eraseblock=0x20000 -n" # does not gain any speed and just creates problems: # TARGET_CC_ARCH = "-march=mips32" @@ -18,5 +20,10 @@ SERIAL_CONSOLE = "115200 tts/0 vt100" BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-usb-storage kernel-module-scsi-mod kernel-module-sd-mod kernel-module-fat kernel-module-vfat kernel-module-usbnet kernel-module-mii" -# also create a srec file -IMAGE_POSTPROCESS_COMMAND = "${TARGET_PREFIX}objcopy -O srec -I binary --adjust-vma 0xbe000000 ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.${type} ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.srec" \ No newline at end of file +PREFERRED_VERSION_yamon = "2.17" + +# create srec files +IMAGE_POSTPROCESS_COMMAND += "\ + ${TARGET_PREFIX}objcopy -O srec -I binary --adjust-vma 0xbe000000 ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.${type} ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.srec; \ + grep -v S7 ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.srec > ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.srec; \ + grep -v S0 ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGE_NAME}.flash.srec >> ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.srec; " diff --git a/conf/machine/mtx-2.conf b/conf/machine/mtx-2.conf new file mode 100644 index 0000000000..d3e15afc9e --- /dev/null +++ b/conf/machine/mtx-2.conf @@ -0,0 +1,27 @@ +#@TYPE: Machine +#@NAME: 4G Systems mtx-2 +#@DESCRIPTION: Machine configuration for the mtx-2 (aka SurfBox 2nd generation) + +TARGET_ARCH = "mipsel" +IPKG_ARCHS = "all mipsel ${MACHINE}" + +PREFERRED_PROVIDER_virtual/kernel = "linux-mtx-2" + +EXTRA_IMAGECMD_jffs2 = "--little-endian --eraseblock=0x20000 -n" + +# does not gain any speed and just creates problems: +# TARGET_CC_ARCH = "-march=mips32" + +USE_DEVFS = "1" +USE_VT = "0" +SERIAL_CONSOLE = "115200 tts/0 vt100" + +BOOTSTRAP_EXTRA_RDEPENDS += "kernel-module-usb-storage kernel-module-scsi-mod kernel-module-sd-mod kernel-module-fat kernel-module-vfat kernel-module-usbnet kernel-module-mii" + +PREFERRED_VERSION_yamon = "2.24" + +# create srec files +IMAGE_POSTPROCESS_COMMAND += "\ + ${TARGET_PREFIX}objcopy -O srec -I binary --adjust-vma 0xbe000000 ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.${type} ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.srec; \ + grep -v S7 ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.srec > ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.srec; \ + grep -v S0 ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGE_NAME}.flash.srec >> ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.srec; " -- cgit v1.2.3 From 03b3579813b72ea73f9961105c598581e3f073e0 Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 12:41:48 +0000 Subject: linux kernels: updated kernels plus patches for nylon/mtx * linux-mtx-1-2.4.27: the standard kernel used for the 4G access cube * linux-mtx-1u-2.4.27: the customized kernel for the 4G Surfbox I * linux-mtx-2-2.4.27: the customized kernel for the 4G Surfbox II --- .../15-au1000-pci-fixup-non-coherent-pre-ac.diff | 19 - packages/linux/linux-mtx-1-2.4.27/22-umts.diff | 28 + .../linux/linux-mtx-1-2.4.27/28-idsel-cardbus.diff | 67 + .../linux/linux-mtx-1-2.4.27/30-mtx-1-sysled.diff | 446 + .../linux-mtx-1-2.4.27/31-mtx-1u-led-init.diff | 16 + .../32-usbserial-stalled-hack.diff | 22 + .../33-usbserial-bulk_in_size-4096.diff | 140 + .../linux/linux-mtx-1-2.4.27/39-mppe-mpc.patch | 1665 + .../linux/linux-mtx-1-2.4.27/40-option-hsdpa.patch | 2961 + .../linux-mtx-1-2.4.27/42-usb-ohci-fixes.patch | 42 + packages/linux/linux-mtx-1-2.4.27/defconfig-mtx-1 | 34 +- packages/linux/linux-mtx-1_2.4.27.bb | 13 +- packages/linux/linux-mtx-1u_2.4.27.bb | 21 + packages/linux/linux-mtx-2-2.4.27/.mtn2git_empty | 0 packages/linux/linux-mtx-2-2.4.27/00-mtx-2.diff | 3032 + .../linux/linux-mtx-2-2.4.27/01-mtd-mtx-2.diff | 51784 ++++++++++++++++ .../03-mtd-erase-compiler-bug.diff | 21 + .../04-mtd-yamonenv-readwrite.diff | 20 + .../linux/linux-mtx-2-2.4.27/05-mtx-2-pci-irq.diff | 18 + .../linux/linux-mtx-2-2.4.27/06-zboot-2.4.26.patch | 5308 ++ .../07-zboot-zimage-flash-bin.diff | 11 + .../linux-mtx-2-2.4.27/08-usb-nonpci-2.4.24.patch | 3185 + .../linux/linux-mtx-2-2.4.27/10-iw-max-spy-32.diff | 11 + .../11-mtd-proc-partition-rw.diff | 173 + .../12-openswan-2.2.0-nat-t.diff | 143 + .../linux-mtx-2-2.4.27/13-openswan-2.2.0.patch | 61293 +++++++++++++++++++ packages/linux/linux-mtx-2-2.4.27/16-i2c.patch | 7482 +++ .../linux-mtx-2-2.4.27/17-lmsensors.2.8.8.patch | 40940 +++++++++++++ .../linux-mtx-2-2.4.27/18-i2c-au1x00gpio.patch | 466 + .../linux-mtx-2-2.4.27/19-kernel-make-depend.diff | 11 + packages/linux/linux-mtx-2-2.4.27/22-umts.diff | 28 + .../linux/linux-mtx-2-2.4.27/27-idsel-cardbus.diff | 115 + .../linux-mtx-2-2.4.27/28-surfbox2-idsel.diff | 47 + .../29-au1000-pci-config-clear-errors.diff | 15 + .../32-usbserial-stalled-hack.diff | 22 + .../33-usbserial-bulk_in_size-4096.diff | 140 + .../linux/linux-mtx-2-2.4.27/35-sb2-slic.patch | 761 + packages/linux/linux-mtx-2-2.4.27/36-sb2-lcd.patch | 465 + .../linux/linux-mtx-2-2.4.27/37-sb2-sysbtn.patch | 246 + .../linux/linux-mtx-2-2.4.27/39-mppe-mpc.patch | 1665 + .../linux/linux-mtx-2-2.4.27/40-option-hsdpa.patch | 2961 + .../linux-mtx-2-2.4.27/42-usb-ohci-fixes.patch | 42 + .../43-usbserial-27-32-backport.diff | 33 + .../44-dbdma-and-au1550_psc.diff | 1491 + packages/linux/linux-mtx-2-2.4.27/45-acm-tty.patch | 252 + packages/linux/linux-mtx-2-2.4.27/defconfig-mtx-2 | 1347 + packages/linux/linux-mtx-2_2.4.27.bb | 94 + 47 files changed, 189056 insertions(+), 40 deletions(-) delete mode 100644 packages/linux/linux-mtx-1-2.4.27/15-au1000-pci-fixup-non-coherent-pre-ac.diff create mode 100644 packages/linux/linux-mtx-1-2.4.27/22-umts.diff create mode 100644 packages/linux/linux-mtx-1-2.4.27/28-idsel-cardbus.diff create mode 100644 packages/linux/linux-mtx-1-2.4.27/30-mtx-1-sysled.diff create mode 100644 packages/linux/linux-mtx-1-2.4.27/31-mtx-1u-led-init.diff create mode 100644 packages/linux/linux-mtx-1-2.4.27/32-usbserial-stalled-hack.diff create mode 100644 packages/linux/linux-mtx-1-2.4.27/33-usbserial-bulk_in_size-4096.diff create mode 100644 packages/linux/linux-mtx-1-2.4.27/39-mppe-mpc.patch create mode 100644 packages/linux/linux-mtx-1-2.4.27/40-option-hsdpa.patch create mode 100644 packages/linux/linux-mtx-1-2.4.27/42-usb-ohci-fixes.patch create mode 100644 packages/linux/linux-mtx-1u_2.4.27.bb create mode 100644 packages/linux/linux-mtx-2-2.4.27/.mtn2git_empty create mode 100644 packages/linux/linux-mtx-2-2.4.27/00-mtx-2.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/01-mtd-mtx-2.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/03-mtd-erase-compiler-bug.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/04-mtd-yamonenv-readwrite.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/05-mtx-2-pci-irq.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/06-zboot-2.4.26.patch create mode 100644 packages/linux/linux-mtx-2-2.4.27/07-zboot-zimage-flash-bin.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/08-usb-nonpci-2.4.24.patch create mode 100644 packages/linux/linux-mtx-2-2.4.27/10-iw-max-spy-32.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/11-mtd-proc-partition-rw.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/12-openswan-2.2.0-nat-t.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/13-openswan-2.2.0.patch create mode 100644 packages/linux/linux-mtx-2-2.4.27/16-i2c.patch create mode 100644 packages/linux/linux-mtx-2-2.4.27/17-lmsensors.2.8.8.patch create mode 100644 packages/linux/linux-mtx-2-2.4.27/18-i2c-au1x00gpio.patch create mode 100644 packages/linux/linux-mtx-2-2.4.27/19-kernel-make-depend.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/22-umts.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/27-idsel-cardbus.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/28-surfbox2-idsel.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/29-au1000-pci-config-clear-errors.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/32-usbserial-stalled-hack.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/33-usbserial-bulk_in_size-4096.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/35-sb2-slic.patch create mode 100644 packages/linux/linux-mtx-2-2.4.27/36-sb2-lcd.patch create mode 100644 packages/linux/linux-mtx-2-2.4.27/37-sb2-sysbtn.patch create mode 100644 packages/linux/linux-mtx-2-2.4.27/39-mppe-mpc.patch create mode 100644 packages/linux/linux-mtx-2-2.4.27/40-option-hsdpa.patch create mode 100644 packages/linux/linux-mtx-2-2.4.27/42-usb-ohci-fixes.patch create mode 100644 packages/linux/linux-mtx-2-2.4.27/43-usbserial-27-32-backport.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/44-dbdma-and-au1550_psc.diff create mode 100644 packages/linux/linux-mtx-2-2.4.27/45-acm-tty.patch create mode 100644 packages/linux/linux-mtx-2-2.4.27/defconfig-mtx-2 create mode 100644 packages/linux/linux-mtx-2_2.4.27.bb diff --git a/packages/linux/linux-mtx-1-2.4.27/15-au1000-pci-fixup-non-coherent-pre-ac.diff b/packages/linux/linux-mtx-1-2.4.27/15-au1000-pci-fixup-non-coherent-pre-ac.diff deleted file mode 100644 index 0a3896433a..0000000000 --- a/packages/linux/linux-mtx-1-2.4.27/15-au1000-pci-fixup-non-coherent-pre-ac.diff +++ /dev/null @@ -1,19 +0,0 @@ ---- linux/arch/mips/au1000/common/pci_fixup.c.orig 2004-11-25 20:14:24.907902616 +0100 -+++ linux/arch/mips/au1000/common/pci_fixup.c 2004-11-25 20:27:08.842766864 +0100 -@@ -75,10 +75,13 @@ - - #ifdef CONFIG_NONCOHERENT_IO - /* -- * Set the NC bit in controller for pre-AC silicon -+ * Set the NC bit in controller for Au1500 pre-AC silicon - */ -- au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG); -- printk("Non-coherent PCI accesses enabled\n"); -+ u32 prid = read_c0_prid(); -+ if ( (prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) { -+ au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG); -+ printk("Non-coherent PCI accesses enabled\n"); -+ } - #endif - - set_io_port_base(virt_io_addr); diff --git a/packages/linux/linux-mtx-1-2.4.27/22-umts.diff b/packages/linux/linux-mtx-1-2.4.27/22-umts.diff new file mode 100644 index 0000000000..8bf2f80236 --- /dev/null +++ b/packages/linux/linux-mtx-1-2.4.27/22-umts.diff @@ -0,0 +1,28 @@ +diff -Nurb linux-2.4.27-mtx1/drivers/usb/serial/usbserial.c linux-2.4.27-mtx1-umts/drivers/usb/serial/usbserial.c +--- linux-2.4.27-mtx1/drivers/usb/serial/usbserial.c 2004-08-14 20:38:57.000000000 +0200 ++++ linux-2.4.27-mtx1-umts/drivers/usb/serial/usbserial.c 2005-06-07 10:53:03.000000000 +0200 +@@ -332,7 +332,7 @@ + static __u16 vendor = 0x05f9; + static __u16 product = 0xffff; + +-static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ ++static struct usb_device_id generic_device_ids[5]; /* Initially all zeroes. */ + + /* All of the device info needed for the Generic Serial Converter */ + static struct usb_serial_device_type generic_device = { +@@ -1773,6 +1773,15 @@ + generic_device_ids[0].idVendor = vendor; + generic_device_ids[0].idProduct = product; + generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; ++ generic_device_ids[1].idVendor = 0xaf0; ++ generic_device_ids[1].idProduct = 0x5000; ++ generic_device_ids[1].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; ++ generic_device_ids[2].idVendor = 0xaf0; ++ generic_device_ids[2].idProduct = 0x6000; ++ generic_device_ids[2].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; ++ generic_device_ids[3].idVendor = 0xaf0; ++ generic_device_ids[3].idProduct = 0x6300; ++ generic_device_ids[3].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; + /* register our generic driver with ourselves */ + usb_serial_register (&generic_device); + #endif diff --git a/packages/linux/linux-mtx-1-2.4.27/28-idsel-cardbus.diff b/packages/linux/linux-mtx-1-2.4.27/28-idsel-cardbus.diff new file mode 100644 index 0000000000..aff210bb54 --- /dev/null +++ b/packages/linux/linux-mtx-1-2.4.27/28-idsel-cardbus.diff @@ -0,0 +1,67 @@ +diff -Nurb linux/arch/mips/au1000/mtx-1/board_setup.c /home/br1/linux-idsel/arch/mips/au1000/mtx-1/board_setup.c +--- linux/arch/mips/au1000/mtx-1/board_setup.c 2005-08-18 18:23:59.000000000 +0200 ++++ /home/br1/linux-idsel/arch/mips/au1000/mtx-1/board_setup.c 2005-08-18 18:19:48.000000000 +0200 +@@ -48,6 +48,10 @@ + + extern struct rtc_ops no_rtc_ops; + ++extern int (*board_pci_idsel)(unsigned int devsel, int assert); ++int mtx1_pci_idsel(unsigned int devsel, int assert); ++ ++ + void board_reset (void) + { + /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ +@@ -85,11 +89,39 @@ + au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR ); + au_writel( 0x00000001, SYS_OUTPUTCLR ); // set M66EN (PCI 66MHz) to OFF + au_writel( 0x00000008, SYS_OUTPUTSET ); // set PCI CLKRUN# to OFF ++ au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON + au_writel( 0x00000020, SYS_OUTPUTCLR ); // set eth PHY TX_ER to OFF + + // enable LED and set it to green + au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR ); + au_writel( 0x18000800, GPIO2_OUTPUT ); + ++ board_pci_idsel = mtx1_pci_idsel; ++ + printk("4G Systems MTX-1 Board\n"); + } ++ ++ ++/* ++ */ ++int ++mtx1_pci_idsel(unsigned int devsel, int assert) ++{ ++#define MTX_IDSEL_ONLY_0_AND_3 0 ++#if MTX_IDSEL_ONLY_0_AND_3 ++ if (devsel != 0 && devsel != 3) { ++ printk("*** not 0 or 3\n"); ++ return 0; ++ } ++#endif ++ ++ if (assert && devsel != 0) { ++ // supress signal to cardbus ++ au_writel( 0x00000002, SYS_OUTPUTCLR ); // set EXT_IO3 OFF ++ } ++ else { ++ au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON ++ } ++ au_sync_udelay(1); ++ return 1; ++} +diff -Nurb linux/arch/mips/au1000/mtx-1/irqmap.c /home/br1/linux-idsel/arch/mips/au1000/mtx-1/irqmap.c +--- linux/arch/mips/au1000/mtx-1/irqmap.c 2005-08-18 18:24:05.000000000 +0200 ++++ /home/br1/linux-idsel/arch/mips/au1000/mtx-1/irqmap.c 2005-08-16 16:37:39.000000000 +0200 +@@ -73,7 +73,7 @@ + * A B C D + */ + { +- {INTA, INTB, INTX, INTX}, /* IDSEL 0 */ ++ {INTA, INTA, INTX, INTX}, /* IDSEL 0 */ + {INTB, INTA, INTX, INTX}, /* IDSEL 1 */ + {INTC, INTD, INTX, INTX}, /* IDSEL 2 */ + {INTD, INTC, INTX, INTX}, /* IDSEL 3 */ + diff --git a/packages/linux/linux-mtx-1-2.4.27/30-mtx-1-sysled.diff b/packages/linux/linux-mtx-1-2.4.27/30-mtx-1-sysled.diff new file mode 100644 index 0000000000..283b7af451 --- /dev/null +++ b/packages/linux/linux-mtx-1-2.4.27/30-mtx-1-sysled.diff @@ -0,0 +1,446 @@ +--- /dev/null 1970-01-01 01:00:00.000000000 +0100 ++++ linux/arch/mips/au1000/mtx-1/mtx-1_sysled.c 2005-08-27 15:30:51.000000000 +0200 +@@ -0,0 +1,398 @@ ++/* ++ * Driver for the MTX-1 System LEDs. ++ * ++ * (c) Copyright 2005 4G Systems , All Rights Reserved. ++ * http://www.4g-systems.biz ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ * ++ * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide ++ * warranty for any of this software. This material is provided ++ * "AS-IS" and at no charge. ++ * ++ * (c) Copyright 2005 4G Systems ++ * ++ * Release 0.01. ++ * ++ * Author: Michael Stickel michael.stickel@4g-systems.biz ++ * ++ * ++ * After the module is loaded there will be a device /dev/misc/leds ++ * that can be written to. There are two bits, each represents one LED ++ * ++ * ++ */ ++ ++static int errno; ++#define __KERNEL_SYSCALLS__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++ ++#include ++ ++ ++#include "mtx-1_sysled.h" ++ ++ ++#ifndef FALSE ++# define FALSE (0) ++#endif ++ ++#ifndef TRUE ++# define TRUE (!FALSE) ++#endif ++ ++ ++/* handle up_and_exit confusion */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9) ++typedef struct semaphore THREAD_SEM; ++#define THREAD_SEM_EXIT(c,l) up_and_exit(c,l) ++#define THREAD_SEM_DECLARE(c) DECLARE_MUTEX_LOCKED(c) ++#define THREAD_SEM_INIT(c) init_MUTEX_LOCKED(c) ++#define THREAD_SEM_WAIT_COMPLETE(c) {down(c);up(c);} ++ ++#else ++#include ++typedef struct completion THREAD_SEM; ++#define THREAD_SEM_EXIT(c,l) complete_and_exit(c,l) ++#define THREAD_SEM_DECLARE(c) DECLARE_COMPLETION(c) ++#define THREAD_SEM_INIT(c) init_completion(c) ++#define THREAD_SEM_WAIT_COMPLETE(c) wait_for_completion(c) ++#endif ++ ++ ++//---------[ Hardware Functions ]----------------- ++ ++ ++ ++static unsigned char sysled_gpios[10] = ++{ ++ 211, // Power = GPIO211 ++ 212, // Status = GPIO212 ++ ++#if 1 ++ 12, // LEDBar1 Blue = GPIO12 0 ++ 13, // LEDBar1 Red = GPIO13 ++ ++ 26, // LEDBar3 Blue = GPIO27 1 ++ 27, // LEDBar3 Red = GPIO26 ++ ++ 10, // LEDBar0 Blue = GPIO10 2 ++ 11, // LEDBar0 Red = GPIO11 ++ ++ 14, // LEDBar2 Blue = GPIO14 3 ++ 25, // LEDBar2 Red = GPIO28 ++#else ++ 7, // IOCTRL0 ++ 8, // IOCTRL1 ++ ++ 15, // IOCTRL2 ++ 205, // IOCTRL3 ++ ++ 206, // IOCTRL4 ++ 208, // LEDBar2 Blue = GPIO14 ++ ++ 255, ++ 255 ++#endif ++}; ++static int num_sysled_gpios = sizeof(sysled_gpios) / sizeof(sysled_gpios[0]); ++ ++ ++static void mtx1_setled (int ledno, char on) ++{ ++ if (ledno >= 0 && ledno < num_sysled_gpios) ++ { ++ if (sysled_gpios[ledno] >= 200 && sysled_gpios[ledno] < 231) ++ { ++ unsigned long pinmask = 1 << (sysled_gpios[ledno] - 200); ++ au_writel((pinmask<<16) | (on ? pinmask : 0), GPIO2_OUTPUT); ++ } ++ else if (sysled_gpios[ledno] < 32) ++ { ++ unsigned long pinmask = 1 << sysled_gpios[ledno]; ++ if (on) ++ au_writel(pinmask, SYS_OUTPUTSET); ++ else ++ au_writel(pinmask, SYS_OUTPUTCLR); ++ } ++ } ++} ++ ++ ++//---------[ LED Precalculation ]----------------- ++ ++typedef struct current_led_config_s ++{ ++ unsigned char period; ++ unsigned long pattern[8]; /* bit-pattern: up to 3.2*8 seconds. 25.6 seconds at 10 Hz */ ++ short current_value; ++ unsigned char led_state; /* 0 = off, 1 = on */ ++} current_led_config_t; ++ ++static current_led_config_t current_led_config[10]; ++static THREAD_SEM mtx1_ledthread_exited; ++static int mtx1_ledthread_pid; ++ ++static int mtx1_led_thread (void *user_data) ++{ ++ int last_jiffies = jiffies - HZ/10; /* initialize with meaningfull value */ ++ ++ lock_kernel(); ++ ++ daemonize (); ++ spin_lock_irq (¤t->sigmask_lock); ++ sigemptyset (¤t->blocked); ++ recalc_sigpending (current); ++ spin_unlock_irq (¤t->sigmask_lock); ++ ++ strncpy (current->comm, "mtx1led", sizeof(current->comm) - 1); ++ current->comm[sizeof(current->comm) - 1] = '\0'; ++ ++ do { ++ int i; ++ ++ // missed_values = (jiffies - last_jiffies) / (HZ/10); ++ last_jiffies = jiffies; ++ ++ // 1/10 second later. ++ for (i=0; i < num_sysled_gpios; i++) ++ { ++ int index = current_led_config[i].current_value; ++ if (current_led_config[i].period > 0 && index < 256) ++ { ++ char led_on = (current_led_config[i].pattern[(index>>5)&7] >> (index&0x1f)) & 1; ++ ++ if (led_on != current_led_config[i].led_state) ++ mtx1_setled (i, led_on); ++ current_led_config[i].led_state = led_on; ++ ++ current_led_config[i].current_value++; ++ if (current_led_config[i].current_value > current_led_config[i].period) ++ current_led_config[i].current_value = 0; ++ } ++ } ++ ++ current->state = TASK_INTERRUPTIBLE; ++ /* long timeout = */ schedule_timeout(HZ / 10); ++ } while (!signal_pending(current)); ++ ++ THREAD_SEM_EXIT (&mtx1_ledthread_exited, 0); ++ return 0; ++} ++ ++ ++static int mtx1_start_ledthread (void) ++{ ++ THREAD_SEM_INIT (&mtx1_ledthread_exited); ++ ++ printk ("starting mtx1 ledthread\n"); ++ mtx1_ledthread_pid = kernel_thread(mtx1_led_thread, ++ NULL, ++ CLONE_FS | CLONE_FILES | CLONE_SIGHAND); ++ if (mtx1_ledthread_pid >= 0) ++ return 0; ++ return -1; ++} ++ ++ ++static void mtx1_stop_ledthread (void) ++{ ++ int waitpid_result = 0; ++ if (mtx1_ledthread_pid > 0) { ++ int ret = kill_proc(mtx1_ledthread_pid, SIGTERM, 1); ++ if (ret==0) ++ { ++ THREAD_SEM_WAIT_COMPLETE(&mtx1_ledthread_exited); ++ waitpid_result = waitpid (mtx1_ledthread_pid, NULL, __WCLONE|WNOHANG); ++ mtx1_ledthread_pid = 0; ++ } ++ } ++// return waitpid_result; ++} ++ ++//---------[ File Functions ]----------------- ++ ++static int mtx1sysled_minor = -1; ++ ++static int mtx1sysled_open (struct inode *inode, struct file *file) ++{ ++ if (MINOR(inode->i_rdev)!=mtx1sysled_minor) return -ENODEV; ++ MOD_INC_USE_COUNT; ++ ++ return 0; ++} ++ ++ ++static int mtx1sysled_release (struct inode *inode, struct file *file) { ++ if (MINOR(inode->i_rdev)==mtx1sysled_minor) { ++ } ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++ ++static ssize_t mtx1sysled_write (struct file *file, const char *buf, size_t count, loff_t *ppos) { ++ led_control_t ctrl_entry; ++ size_t buflen; ++ ++ if (ppos != &file->f_pos) ++ return -ESPIPE; ++ ++ if (count < 1) ++ return -EINVAL; ++ ++ if (copy_from_user (&ctrl_entry, buf, sizeof(unsigned char))) ++ return -EFAULT; ++ ++ if ((ctrl_entry.flags & 0x1f) <= 0) ++ return -EINVAL; ++ ++ buflen = (count < sizeof(led_control_t)) ? count : sizeof(led_control_t); ++ if (copy_from_user (&ctrl_entry, buf, buflen)) ++ return -EFAULT; ++ ++ int numentries = (buflen-1) / sizeof(led_control_entry_t); ++ ++ if ((ctrl_entry.flags & 0x1f) < numentries) ++ numentries = ctrl_entry.flags & 0x1f; ++ ++ int i; ++ for (i=0; i < numentries; i++) { ++ unsigned short led_id = ctrl_entry.led[i].led_id; ++ if (led_id < num_sysled_gpios) { ++ current_led_config[led_id].period = ctrl_entry.led[i].period; ++ memcpy (current_led_config[led_id].pattern, ctrl_entry.led[i].pattern, sizeof(unsigned long)*8); ++ current_led_config[led_id].current_value = 0; ++ ++ // may update the led output (if the led should be set to 1 or 0). ++ } ++ } ++ return count; ++} ++ ++ ++ ++static struct file_operations mtx1sysled_fops = { ++ .owner = THIS_MODULE, ++ .llseek = NULL, ++ .read = NULL, ++ .write = mtx1sysled_write, ++ .readdir = NULL, ++ .poll = NULL, ++ .ioctl = NULL, ++ .mmap = NULL, ++ .open = mtx1sysled_open, ++ .flush = NULL, ++ .release = mtx1sysled_release ++}; ++ ++ ++static struct miscdevice mtx1sysled_miscdev = { ++ MISC_DYNAMIC_MINOR /* SYSLED_MINOR */ , ++ "leds", ++ &mtx1sysled_fops ++}; ++ ++ ++ ++//---------[ Module Functions ]----------------- ++ ++ ++void __exit cleanup_mtx1_sysled (void) ++{ ++ mtx1_stop_ledthread (); ++ misc_deregister(&mtx1sysled_miscdev); ++} ++ ++ ++int __init init_mtx1_sysled (void) ++{ ++ printk("MTX-1 System LED driver\n"); ++ ++ ++ unsigned long gpio_mask = 0L; ++ unsigned long gpio2_mask = 0L; ++ int i; ++ for (i=0; i < num_sysled_gpios; i++) ++ { ++ if (sysled_gpios[i] < 32) /* GPIO00..xx */ ++ gpio2_mask |= 1<= 200 && sysled_gpios[i] < 216) /* GPIO200..231 */ ++ gpio2_mask |= 1 << (sysled_gpios[i] - 200); ++ } ++ ++ if (gpio2_mask) { ++ au_writel(au_readl(GPIO2_DIR) | gpio2_mask, GPIO2_DIR); ++ au_writel(gpio2_mask<<16, GPIO2_OUTPUT); ++ } ++ ++ if (gpio_mask) { ++ au_writel(gpio_mask, SYS_OUTPUTCLR); ++ } ++ ++ // Clear SYS_LED#10 = U910-OE# ++ au_writel(1<<28, SYS_OUTPUTCLR); ++ ++ ++ if (misc_register (&mtx1sysled_miscdev) < 0) ++ { ++ return 1; ++ } ++ mtx1sysled_minor = mtx1sysled_miscdev.minor; ++ ++ for (i=0; i < num_sysled_gpios; i++) { ++ current_led_config[i].period = 32; ++ current_led_config[i].pattern[0] = 0x0; ++ current_led_config[i].current_value = 0; ++ current_led_config[i].led_state = 0; ++ mtx1_setled (i, 0); ++ } ++ current_led_config[2].period = 31; ++ current_led_config[2].pattern[0] = 0xFFFFFFFF; ++ current_led_config[3].period = 31; ++ current_led_config[3].pattern[0] = 0xFFFFFFFF; ++ current_led_config[4].period = 31; ++ current_led_config[4].pattern[0] = 0xFFFFFFFF; ++ current_led_config[5].period = 31; ++ current_led_config[5].pattern[0] = 0xFFFFFFFF; ++ current_led_config[6].period = 31; ++ current_led_config[6].pattern[0] = 0xFFFFFFFF; ++ current_led_config[7].period = 31; ++ current_led_config[7].pattern[0] = 0xFFFFFFFF; ++ ++ ++ if (mtx1_start_ledthread ()) ++ { ++ // Error ++ } ++ ++ return 0; ++} ++ ++__initcall(init_mtx1_sysled); ++__exitcall(cleanup_mtx1_sysled); ++ ++MODULE_AUTHOR("Michael Stickel"); ++MODULE_DESCRIPTION("Driver for the MTX-1 system LEDs"); ++MODULE_LICENSE("GPL"); ++EXPORT_NO_SYMBOLS; +--- /dev/null 1970-01-01 01:00:00.000000000 +0100 ++++ linux/arch/mips/au1000/mtx-1/mtx-1_sysled.h 2005-08-27 15:00:41.000000000 +0200 +@@ -0,0 +1,32 @@ ++#ifndef __MTX1_SYSLED_H__ ++#define __MTX1_SYSLED_H__ ++ /* ++ * flags: ++ * Bit Function ++ * 7 set to 0 ++ * 6 set to 0 ++ * 5 set to 0 ++ * 4..0 The number of led-control records. 1 means one record, 15 means records. ++ * ++ */ ++ ++ ++typedef struct led_control_entry_s ++{ ++ unsigned short led_id; ++ unsigned char period; /* 0..0xff unit is 1/10 of a second */ ++ unsigned long pattern[8]; /* bit-pattern: up to 3.2*8 seconds. 25.6 seconds at 10 Hz */ ++} led_control_entry_t; ++ ++ ++typedef struct led_control_s ++{ ++ unsigned char flags; ++ led_control_entry_t led[31]; ++} led_control_t; ++ ++#define MTX1SYSLED_CONTROL_SIZE(x) (sizeof(unsigned char)+(x)*sizeof(led_control_entry_t)) ++ ++#define MTX1SYSLED_FLAGS_NUMENTRIES(n) ((n)&0x1f) ++ ++#endif +--- linux/arch/mips/au1000/mtx-1/Makefile.orig 2005-08-27 15:59:31.000000000 +0200 ++++ linux/arch/mips/au1000/mtx-1/Makefile 2005-08-27 15:59:45.000000000 +0200 +@@ -15,6 +15,6 @@ + + O_TARGET := mtx-1.o + +-obj-y := init.o board_setup.o irqmap.o mtx-1_watchdog.o mtx-1_sysbtn.o ++obj-y := init.o board_setup.o irqmap.o mtx-1_watchdog.o mtx-1_sysbtn.o mtx-1_sysled.o + + include $(TOPDIR)/Rules.make diff --git a/packages/linux/linux-mtx-1-2.4.27/31-mtx-1u-led-init.diff b/packages/linux/linux-mtx-1-2.4.27/31-mtx-1u-led-init.diff new file mode 100644 index 0000000000..53e17e48bb --- /dev/null +++ b/packages/linux/linux-mtx-1-2.4.27/31-mtx-1u-led-init.diff @@ -0,0 +1,16 @@ +--- linux/arch/mips/au1000/mtx-1/board_setup.c.pre 2005-08-27 17:09:39.000000000 +0200 ++++ linux/arch/mips/au1000/mtx-1/board_setup.c 2005-08-27 17:38:56.000000000 +0200 +@@ -91,9 +91,12 @@ + au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON + au_writel( 0x00000020, SYS_OUTPUTCLR ); // set eth PHY TX_ER to OFF + ++ au_writel( 0x0c003000, SYS_OUTPUTSET ); ++ au_writel( 0x12004c00, SYS_OUTPUTCLR ); ++ + // enable LED and set it to green + au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR ); +- au_writel( 0x18000800, GPIO2_OUTPUT ); ++ au_writel( 0x18000000, GPIO2_OUTPUT ); + + board_pci_idsel = mtx1_pci_idsel; + diff --git a/packages/linux/linux-mtx-1-2.4.27/32-usbserial-stalled-hack.diff b/packages/linux/linux-mtx-1-2.4.27/32-usbserial-stalled-hack.diff new file mode 100644 index 0000000000..bfc1af9db9 --- /dev/null +++ b/packages/linux/linux-mtx-1-2.4.27/32-usbserial-stalled-hack.diff @@ -0,0 +1,22 @@ +--- linux-2.4.27-mtx1/drivers/usb/serial/usbserial.c 2005-08-28 20:23:40.000000000 +0200 ++++ linux-2.4.27-mtx1/drivers/usb/serial/usbserial.c 2005-08-28 20:23:12.000000000 +0200 +@@ -499,6 +499,19 @@ + /* get_usb_serial checks port->tty, so cannot be used */ + serial = port->serial; + if (port->write_busy) { ++ ++ /*-- how is the status of the outgoing urb? --*/ ++ /*-- did we miss a callback? --*/ ++ /*-- problem with the hack below is that we may */ ++ /* corrup structures we currently walk thru */ ++ if (port->write_urb && port->write_urb->status != -EINPROGRESS) { ++ if (port->write_urb->complete) ++ port->write_urb->complete(port->write_urb); ++ else ++ dbg("%s: URB %p has no complete function\n", __FUNCTION__, port->write_urb); ++ } ++ ++ + dbg("%s - port %d busy", __FUNCTION__, port->number); + pos = pos->next; + continue; diff --git a/packages/linux/linux-mtx-1-2.4.27/33-usbserial-bulk_in_size-4096.diff b/packages/linux/linux-mtx-1-2.4.27/33-usbserial-bulk_in_size-4096.diff new file mode 100644 index 0000000000..e615a92fa4 --- /dev/null +++ b/packages/linux/linux-mtx-1-2.4.27/33-usbserial-bulk_in_size-4096.diff @@ -0,0 +1,140 @@ +--- linux/drivers/usb/serial/usbserial.c~33-usbserial-bulk_in_size-4096.diff 2006-03-31 15:05:46.674445000 +0200 ++++ linux/drivers/usb/serial/usbserial.c 2006-04-07 12:23:56.970400500 +0200 +@@ -332,6 +332,9 @@ + static __u16 vendor = 0x05f9; + static __u16 product = 0xffff; + ++static int count_smaller64 = 0; ++static int count_bigger64 = 0; ++ + static struct usb_device_id generic_device_ids[5]; /* Initially all zeroes. */ + + /* All of the device info needed for the Generic Serial Converter */ +@@ -396,6 +399,10 @@ + drivers depend on it. + */ + ++/* global params controlling max sizes for read, write, control */ ++static int maxszr = 0; ++static int maxszw = 0; ++static int maxszc = 0; + + static int serial_refcount; + static struct tty_driver serial_tty_driver; +@@ -1272,6 +1279,14 @@ + tty_flip_buffer_push(tty); + } + ++ if (urb->actual_length>64) { ++ count_bigger64++; ++ } else { ++ count_smaller64++; ++ } ++ ++ /*printk("*** %d\n", urb->actual_length);*/ ++ + /* Continue trying to always read */ + usb_fill_bulk_urb (port->read_urb, serial->dev, + usb_rcvbulkpipe (serial->dev, +@@ -1505,7 +1520,8 @@ + err("No free urbs available"); + goto probe_error; + } +- buffer_size = endpoint->wMaxPacketSize; ++ buffer_size = (endpoint->wMaxPacketSize > maxszr)? ++ endpoint->wMaxPacketSize: maxszr; + port->bulk_in_endpointAddress = endpoint->bEndpointAddress; + port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); + if (!port->bulk_in_buffer) { +@@ -1530,7 +1546,8 @@ + err("No free urbs available"); + goto probe_error; + } +- buffer_size = endpoint->wMaxPacketSize; ++ buffer_size = (endpoint->wMaxPacketSize > maxszw)? ++ endpoint->wMaxPacketSize: maxszw; + port->bulk_out_size = buffer_size; + port->bulk_out_endpointAddress = endpoint->bEndpointAddress; + port->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL); +@@ -1556,7 +1573,8 @@ + err("No free urbs available"); + goto probe_error; + } +- buffer_size = endpoint->wMaxPacketSize; ++ buffer_size = (endpoint->wMaxPacketSize > maxszc)? ++ endpoint->wMaxPacketSize: maxszc; + port->interrupt_in_endpointAddress = endpoint->bEndpointAddress; + port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL); + if (!port->interrupt_in_buffer) { +@@ -1807,6 +1825,7 @@ + + static void __exit usb_serial_exit(void) + { ++ printk("*** received packets\n< 64: %d\n> 64: %d\n", count_smaller64, count_bigger64); + + #ifdef CONFIG_USB_SERIAL_GENERIC + /* remove our generic driver */ +@@ -1874,6 +1893,15 @@ + MODULE_PARM(debug, "i"); + MODULE_PARM_DESC(debug, "Debug enabled or not"); + ++MODULE_PARM(maxszr, "i"); ++MODULE_PARM_DESC(maxszr, "User specified USB endpoint read size"); ++ ++MODULE_PARM(maxszw, "i"); ++MODULE_PARM_DESC(maxszw, "User specified USB endpoint write size"); ++ ++MODULE_PARM(maxszc, "i"); ++MODULE_PARM_DESC(maxszc, "User specified USB endpoint control size"); ++ + #ifdef CONFIG_USB_SERIAL_GENERIC + MODULE_PARM(vendor, "h"); + MODULE_PARM_DESC(vendor, "User specified USB idVendor"); +--- linux/drivers/usb/acm.c.orig 2006-04-07 13:56:33.837683000 +0200 ++++ linux/drivers/usb/acm.c 2006-04-07 12:14:37.995466750 +0200 +@@ -155,6 +155,11 @@ + unsigned char clocal; /* termios CLOCAL */ + }; + ++/* global params controlling max sizes for read, write, control */ ++static int maxszr = 0; ++static int maxszw = 0; ++static int maxszc = 0; ++ + static struct usb_driver acm_driver; + static struct tty_driver acm_tty_driver; + static struct acm *acm_table[ACM_TTY_MINORS]; +@@ -573,9 +578,13 @@ + } + memset(acm, 0, sizeof(struct acm)); + +- ctrlsize = epctrl->wMaxPacketSize; +- readsize = epread->wMaxPacketSize; +- acm->writesize = epwrite->wMaxPacketSize; ++ ctrlsize = (epctrl->wMaxPacketSize > maxszc)? ++ epctrl->wMaxPacketSize: maxszc; ++ readsize = (epread->wMaxPacketSize > maxszr)? ++ epread->wMaxPacketSize: maxszr; ++ acm->writesize = (epwrite->wMaxPacketSize > maxszw)? ++ epwrite->wMaxPacketSize: maxszw; ++ + acm->iface = cfacm->interface + j; + acm->minor = minor; + acm->dev = dev; +@@ -740,6 +749,16 @@ + module_init(acm_init); + module_exit(acm_exit); + ++ ++MODULE_PARM(maxszr, "i"); ++MODULE_PARM_DESC(maxszr, "User specified USB endpoint read size"); ++ ++MODULE_PARM(maxszw, "i"); ++MODULE_PARM_DESC(maxszw, "User specified USB endpoint write size"); ++ ++MODULE_PARM(maxszc, "i"); ++MODULE_PARM_DESC(maxszc, "User specified USB endpoint control size"); ++ + MODULE_AUTHOR( DRIVER_AUTHOR ); + MODULE_DESCRIPTION( DRIVER_DESC ); + MODULE_LICENSE("GPL"); diff --git a/packages/linux/linux-mtx-1-2.4.27/39-mppe-mpc.patch b/packages/linux/linux-mtx-1-2.4.27/39-mppe-mpc.patch new file mode 100644 index 0000000000..28ce19d467 --- /dev/null +++ b/packages/linux/linux-mtx-1-2.4.27/39-mppe-mpc.patch @@ -0,0 +1,1665 @@ +diff -ruN linux.orig/Documentation/Configure.help linux/Documentation/Configure.help +--- linux.orig/Documentation/Configure.help 2004-08-08 12:14:49.000000000 +0200 ++++ linux/Documentation/Configure.help 2004-08-15 09:22:18.000000000 +0200 +@@ -9905,6 +9905,28 @@ + module; it is called bsd_comp.o and will show up in the directory + modules once you have said "make modules". If unsure, say N. + ++Microsoft PPP compression/encryption (MPPC/MPPE) ++CONFIG_PPP_MPPE_MPPC ++ Support for the Microsoft Point-To-Point Compression (RFC2118) and ++ Microsoft Point-To-Point Encryption (RFC3078). These protocols are ++ supported by Microsoft Windows and wide range of "hardware" access ++ servers. MPPE is common protocol in Virtual Private Networks. According ++ to RFC3078, MPPE supports 40, 56 and 128-bit key lengths. Depending on ++ PPP daemon configuration on both ends of the link, following scenarios ++ are possible: ++ - only compression (MPPC) is used, ++ - only encryption (MPPE) is used, ++ - compression and encryption (MPPC+MPPE) are used. ++ ++ Please note that Hi/Fn (http://www.hifn.com) holds patent on MPPC so ++ you should check if this patent is valid in your country in order to ++ avoid legal problems. ++ ++ For more information please visit http://free.polbox.pl/h/hs001 ++ ++ To compile this driver as a module, choose M here. The module will ++ be called ppp_mppe_mppc.o. ++ + PPP over Ethernet + CONFIG_PPPOE + Support for PPP over Ethernet. +diff -ruN linux.orig/crypto/Config.in linux/crypto/Config.in +--- linux.orig/crypto/Config.in 2004-08-08 12:14:50.000000000 +0200 ++++ linux/crypto/Config.in 2004-08-15 11:36:18.000000000 +0200 +@@ -11,7 +11,9 @@ + "$CONFIG_INET6_AH" = "y" -o \ + "$CONFIG_INET6_AH" = "m" -o \ + "$CONFIG_INET6_ESP" = "y" -o \ +- "$CONFIG_INET6_ESP" = "m" ]; then ++ "$CONFIG_INET6_ESP" = "m" -o \ ++ "$CONFIG_PPP_MPPE_MPPC" = "y" -o \ ++ "$CONFIG_PPP_MPPE_MPPC" = "m" ]; then + define_bool CONFIG_CRYPTO y + else + bool 'Cryptographic API' CONFIG_CRYPTO +@@ -44,6 +46,7 @@ + else + tristate ' MD5 digest algorithm' CONFIG_CRYPTO_MD5 + fi ++ + if [ "$CONFIG_INET_AH" = "y" -o \ + "$CONFIG_INET_AH" = "m" -o \ + "$CONFIG_INET_ESP" = "y" -o \ +@@ -51,11 +54,24 @@ + "$CONFIG_INET6_AH" = "y" -o \ + "$CONFIG_INET6_AH" = "m" -o \ + "$CONFIG_INET6_ESP" = "y" -o \ +- "$CONFIG_INET6_ESP" = "m" ]; then +- define_bool CONFIG_CRYPTO_SHA1 y +- else +- tristate ' SHA1 digest algorithm' CONFIG_CRYPTO_SHA1 ++ "$CONFIG_INET6_ESP" = "m" -o \ ++ "$CONFIG_PPP_MPPE_MPPC" = "y" -o \ ++ "$CONFIG_PPP_MPPE_MPPC" = "m" ]; then ++ if [ "$CONFIG_INET_AH" = "y" -o \ ++ "$CONFIG_INET_ESP" = "y" -o \ ++ "$CONFIG_INET6_AH" = "y" -o \ ++ "$CONFIG_INET6_ESP" = "y" -o \ ++ "$CONFIG_PPP_MPPE_MPPC" = "y" ]; then ++ define_tristate CONFIG_CRYPTO_SHA1 y ++ else ++ if [ "$CONFIG_CRYPTO_SHA1" != "y" -a \ ++ "$CONFIG_CRYPTO_SHA1" != "m" ]; then ++ define_tristate CONFIG_CRYPTO_SHA1 m ++ fi ++ fi + fi ++ tristate ' SHA1 digest algorithm' CONFIG_CRYPTO_SHA1 ++ + tristate ' SHA256 digest algorithm' CONFIG_CRYPTO_SHA256 + tristate ' SHA384 and SHA512 digest algorithms' CONFIG_CRYPTO_SHA512 + if [ "$CONFIG_INET_ESP" = "y" -o \ +@@ -73,7 +89,20 @@ + tristate ' CAST5 (CAST-128) cipher algorithm' CONFIG_CRYPTO_CAST5 + tristate ' CAST6 (CAST-256) cipher algorithm' CONFIG_CRYPTO_CAST6 + tristate ' TEA and XTEA cipher algorithms' CONFIG_CRYPTO_TEA ++ ++ if [ "$CONFIG_PPP_MPPE_MPPC" = "y" -o \ ++ "$CONFIG_PPP_MPPE_MPPC" = "m" ]; then ++ if [ "$CONFIG_PPP_MPPE_MPPC" = "y" ]; then ++ define_tristate CONFIG_CRYPTO_ARC4 y ++ else ++ if [ "$CONFIG_CRYPTO_ARC4" != "y" -a \ ++ "$CONFIG_CRYPTO_ARC4" != "m" ]; then ++ define_tristate CONFIG_CRYPTO_ARC4 m ++ fi ++ fi ++ fi + tristate ' ARC4 cipher algorithm' CONFIG_CRYPTO_ARC4 ++ + if [ "$CONFIG_INET_IPCOMP" = "y" -o \ + "$CONFIG_INET_IPCOMP" = "m" -o \ + "$CONFIG_INET6_IPCOMP" = "y" -o \ +diff -ruN linux.orig/drivers/net/Config.in linux/drivers/net/Config.in +--- linux.orig/drivers/net/Config.in 2004-08-08 12:14:52.000000000 +0200 ++++ linux/drivers/net/Config.in 2004-08-08 12:17:43.000000000 +0200 +@@ -325,6 +325,7 @@ + dep_tristate ' PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP + dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP + dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP ++ dep_tristate ' Microsoft PPP compression/encryption (MPPC/MPPE)' CONFIG_PPP_MPPE_MPPC $CONFIG_PPP + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP + fi +diff -ruN linux.orig/drivers/net/Makefile linux/drivers/net/Makefile +--- linux.orig/drivers/net/Makefile 2004-08-08 12:14:52.000000000 +0200 ++++ linux/drivers/net/Makefile 2004-08-08 12:17:43.000000000 +0200 +@@ -161,6 +161,7 @@ + obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o + obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o + obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o ++obj-$(CONFIG_PPP_MPPE_MPPC) += ppp_mppe_mppc.o + obj-$(CONFIG_PPPOE) += pppox.o pppoe.o + + obj-$(CONFIG_SLIP) += slip.o +diff -ruN linux.orig/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c +--- linux.orig/drivers/net/ppp_generic.c 2003-08-25 13:44:42.000000000 +0200 ++++ linux/drivers/net/ppp_generic.c 2004-08-08 12:17:43.000000000 +0200 +@@ -19,7 +19,7 @@ + * PPP driver, written by Michael Callahan and Al Longyear, and + * subsequently hacked by Paul Mackerras. + * +- * ==FILEVERSION 20020217== ++ * ==FILEVERSION 20040509== + */ + + #include +@@ -102,6 +102,7 @@ + spinlock_t rlock; /* lock for receive side 58 */ + spinlock_t wlock; /* lock for transmit side 5c */ + int mru; /* max receive unit 60 */ ++ int mru_alloc; /* MAX(1500,MRU) for dev_alloc_skb() */ + unsigned int flags; /* control bits 64 */ + unsigned int xstate; /* transmit state bits 68 */ + unsigned int rstate; /* receive state bits 6c */ +@@ -552,7 +553,9 @@ + case PPPIOCSMRU: + if (get_user(val, (int *) arg)) + break; +- ppp->mru = val; ++ ppp->mru_alloc = ppp->mru = val; ++ if (ppp->mru_alloc < PPP_MRU) ++ ppp->mru_alloc = PPP_MRU; /* increase for broken peers */ + err = 0; + break; + +@@ -1025,14 +1028,37 @@ + case PPP_CCP: + /* peek at outbound CCP frames */ + ppp_ccp_peek(ppp, skb, 0); ++ /* ++ * When LZS or MPPE/MPPC has been negotiated we don't send ++ * CCP_RESETACK after receiving CCP_RESETREQ; in fact pppd ++ * sends such a packet but we silently discard it here ++ */ ++ if (CCP_CODE(skb->data+2) == CCP_RESETACK ++ && (ppp->xcomp->compress_proto == CI_MPPE ++ || ppp->xcomp->compress_proto == CI_LZS)) { ++ --ppp->stats.tx_packets; ++ ppp->stats.tx_bytes -= skb->len - 2; ++ kfree_skb(skb); ++ return; ++ } + break; + } + + /* try to do packet compression */ + if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0 + && proto != PPP_LCP && proto != PPP_CCP) { +- new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len, +- GFP_ATOMIC); ++ int comp_ovhd = 0; ++ /* ++ * because of possible data expansion when MPPC or LZS ++ * is used, allocate compressor's buffer 12.5% bigger ++ * than MTU ++ */ ++ if (ppp->xcomp->compress_proto == CI_MPPE) ++ comp_ovhd = ((ppp->dev->mtu * 9) / 8) + 1 + MPPE_OVHD; ++ else if (ppp->xcomp->compress_proto == CI_LZS) ++ comp_ovhd = ((ppp->dev->mtu * 9) / 8) + 1 + LZS_OVHD; ++ new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len ++ + comp_ovhd, GFP_ATOMIC); + if (new_skb == 0) { + printk(KERN_ERR "PPP: no memory (comp pkt)\n"); + goto drop; +@@ -1050,9 +1076,21 @@ + skb = new_skb; + skb_put(skb, len); + skb_pull(skb, 2); /* pull off A/C bytes */ +- } else { ++ } else if (len == 0) { + /* didn't compress, or CCP not up yet */ + kfree_skb(new_skb); ++ } else { ++ /* ++ * (len < 0) ++ * MPPE requires that we do not send unencrypted ++ * frames. The compressor will return -1 if we ++ * should drop the frame. We cannot simply test ++ * the compress_proto because MPPE and MPPC share ++ * the same number. ++ */ ++ printk(KERN_ERR "ppp: compressor dropped pkt\n"); ++ kfree_skb(new_skb); ++ goto drop; + } + } + +@@ -1540,14 +1578,15 @@ + int len; + + if (proto == PPP_COMP) { +- ns = dev_alloc_skb(ppp->mru + PPP_HDRLEN); ++ ns = dev_alloc_skb(ppp->mru_alloc + PPP_HDRLEN); + if (ns == 0) { + printk(KERN_ERR "ppp_decompress_frame: no memory\n"); + goto err; + } + /* the decompressor still expects the A/C bytes in the hdr */ + len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2, +- skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN); ++ skb->len + 2, ns->data, ++ ppp->mru_alloc + PPP_HDRLEN); + if (len < 0) { + /* Pass the compressed frame to pppd as an + error indication. */ +@@ -1573,7 +1612,14 @@ + return skb; + + err: +- ppp->rstate |= SC_DC_ERROR; ++ if (ppp->rcomp->compress_proto != CI_MPPE ++ && ppp->rcomp->compress_proto != CI_LZS) { ++ /* ++ * If decompression protocol isn't MPPE/MPPC or LZS, we set ++ * SC_DC_ERROR flag and wait for CCP_RESETACK ++ */ ++ ppp->rstate |= SC_DC_ERROR; ++ } + ppp_receive_error(ppp); + return skb; + } +@@ -2253,6 +2299,7 @@ + /* Initialize the new ppp unit */ + ppp->file.index = unit; + ppp->mru = PPP_MRU; ++ ppp->mru_alloc = PPP_MRU; + init_ppp_file(&ppp->file, INTERFACE); + ppp->file.hdrlen = PPP_HDRLEN - 2; /* don't count proto bytes */ + for (i = 0; i < NUM_NP; ++i) +diff -ruN linux.orig/drivers/net/ppp_mppe_mppc.c linux/drivers/net/ppp_mppe_mppc.c +--- linux.orig/drivers/net/ppp_mppe_mppc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/net/ppp_mppe_mppc.c 2004-08-15 10:12:23.000000000 +0200 +@@ -0,0 +1,1269 @@ ++/* ++ * ppp_mppe_mppc.c - MPPC/MPPE "compressor/decompressor" module. ++ * ++ * Copyright (c) 1994 Árpád Magosányi ++ * Copyright (c) 1999 Tim Hockin, Cobalt Networks Inc. ++ * Copyright (c) 2002-2004 Jan Dubiec ++ * ++ * Permission to use, copy, modify, and distribute this software and its ++ * documentation is hereby granted, provided that the above copyright ++ * notice appears in all copies. This software is provided without any ++ * warranty, express or implied. ++ * ++ * The code is based on MPPE kernel module written by Árpád Magosányi and ++ * Tim Hockin which can be found on http://planetmirror.com/pub/mppe/. ++ * I have added MPPC and 56 bit session keys support in MPPE. ++ * ++ * WARNING! Although this is open source code, its usage in some countries ++ * (in particular in the USA) may violate Stac Inc. patent for MPPC. ++ * ++ * ==FILEVERSION 20040815== ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* ++ * In 2.4.x kernels macro offset_in_page() is not defined in linux/mm.h so ++ * we define it here; PAGE_MASK is defined in asm/page.h which is included ++ * by linux/mm.h. ++ */ ++#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) ++ ++/* ++ * State for a mppc/mppe "(de)compressor". ++ */ ++struct ppp_mppe_state { ++ struct crypto_tfm *arc4_tfm; ++ struct crypto_tfm *sha1_tfm; ++ u8 master_key[MPPE_MAX_KEY_LEN]; ++ u8 session_key[MPPE_MAX_KEY_LEN]; ++ u8 mppc; /* do we use compression (MPPC)? */ ++ u8 mppe; /* do we use encryption (MPPE)? */ ++ u8 keylen; /* key length in bytes */ ++ u8 bitkeylen; /* key length in bits */ ++ u16 ccount; /* coherency counter */ ++ u16 bits; /* MPPC/MPPE control bits */ ++ u8 stateless; /* do we use stateless mode? */ ++ u8 nextflushed; /* set A bit in the next outgoing packet; ++ used only by compressor*/ ++ u8 flushexpected; /* drop packets until A bit is received; ++ used only by decompressor*/ ++ u8 *hist; /* MPPC history */ ++ u16 *hash; /* Hash table; used only by compressor */ ++ u16 histptr; /* history "cursor" */ ++ int unit; ++ int debug; ++ int mru; ++ struct compstat stats; ++}; ++ ++#define MPPE_HIST_LEN 8192 /* MPPC history size */ ++#define MPPE_MAX_CCOUNT 0x0FFF /* max. coherency counter value */ ++ ++#define MPPE_BIT_FLUSHED 0x80 /* bit A */ ++#define MPPE_BIT_RESET 0x40 /* bit B */ ++#define MPPE_BIT_COMP 0x20 /* bit C */ ++#define MPPE_BIT_ENCRYPTED 0x10 /* bit D */ ++ ++#define MPPE_SALT0 0xD1 /* values used in MPPE key derivation */ ++#define MPPE_SALT1 0x26 /* according to RFC3079 */ ++#define MPPE_SALT2 0x9E ++ ++#define MPPE_CCOUNT(x) ((((x)[4] & 0x0f) << 8) + (x)[5]) ++#define MPPE_BITS(x) ((x)[4] & 0xf0) ++#define MPPE_CTRLHI(x) ((((x)->ccount & 0xf00)>>8)|((x)->bits)) ++#define MPPE_CTRLLO(x) ((x)->ccount & 0xff) ++ ++static inline void ++setup_sg(struct scatterlist *sg, const void *address, unsigned int length) ++{ ++ sg[0].page = virt_to_page(address); ++ sg[0].offset = offset_in_page(address); ++ sg[0].length = length; ++} ++ ++static inline void ++arc4_setkey(struct ppp_mppe_state *state, const unsigned char *key, ++ const unsigned int keylen) ++{ ++ crypto_cipher_setkey(state->arc4_tfm, key, keylen); ++} ++ ++static inline void ++arc4_encrypt(struct ppp_mppe_state *state, const unsigned char *in, ++ const unsigned int len, unsigned char *out) ++{ ++ struct scatterlist sgin[4], sgout[4]; ++ ++ setup_sg(sgin, in, len); ++ setup_sg(sgout, out, len); ++ crypto_cipher_encrypt(state->arc4_tfm, sgout, sgin, len); ++} ++ ++#define arc4_decrypt arc4_encrypt ++ ++/* ++ * Key Derivation, from RFC 3078, RFC 3079. ++ * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079. ++ */ ++static void ++GetNewKeyFromSHA(struct ppp_mppe_state *state, unsigned char *MasterKey, ++ unsigned char *SessionKey, unsigned long SessionKeyLength, ++ unsigned char *InterimKey) ++{ ++ /*Pads used in key derivation */ ++ static const unsigned char SHAPad1[40] = { ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ }; ++ ++ static const unsigned char SHAPad2[40] = { ++ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, ++ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, ++ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, ++ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 ++ }; ++ ++ unsigned char Digest[20]; /* SHA1_DIGEST_SIZE = 20 */ ++ struct scatterlist sg[2]; ++ ++ crypto_digest_init(state->sha1_tfm); ++ ++ setup_sg(sg, MasterKey, SessionKeyLength); ++ crypto_digest_update(state->sha1_tfm, sg, 1); ++ ++ setup_sg(sg, SHAPad1, sizeof(SHAPad1)); ++ crypto_digest_update(state->sha1_tfm, sg, 1); ++ ++ setup_sg(sg, SessionKey, SessionKeyLength); ++ crypto_digest_update(state->sha1_tfm, sg, 1); ++ ++ setup_sg(sg, SHAPad2, sizeof(SHAPad2)); ++ crypto_digest_update(state->sha1_tfm, sg, 1); ++ ++ crypto_digest_final(state->sha1_tfm, Digest); ++ ++ memcpy(InterimKey, Digest, SessionKeyLength); ++} ++ ++static void ++mppe_change_key(struct ppp_mppe_state *state, int initialize) ++{ ++ unsigned char InterimKey[MPPE_MAX_KEY_LEN]; ++ ++ GetNewKeyFromSHA(state, state->master_key, state->session_key, ++ state->keylen, InterimKey); ++ if (initialize) { ++ memcpy(state->session_key, InterimKey, state->keylen); ++ } else { ++ arc4_setkey(state, InterimKey, state->keylen); ++ arc4_encrypt(state, InterimKey, state->keylen, state->session_key); ++ } ++ if (state->keylen == 8) { ++ if (state->bitkeylen == 40) { ++ state->session_key[0] = MPPE_SALT0; ++ state->session_key[1] = MPPE_SALT1; ++ state->session_key[2] = MPPE_SALT2; ++ } else { ++ state->session_key[0] = MPPE_SALT0; ++ } ++ } ++ arc4_setkey(state, state->session_key, state->keylen); ++} ++ ++/* increase 12-bit coherency counter */ ++static inline void ++mppe_increase_ccount(struct ppp_mppe_state *state) ++{ ++ state->ccount = (state->ccount + 1) & MPPE_MAX_CCOUNT; ++ if (state->mppe) { ++ if (state->stateless) { ++ mppe_change_key(state, 0); ++ state->nextflushed = 1; ++ } else { ++ if ((state->ccount & 0xff) == 0xff) { ++ mppe_change_key(state, 0); ++ } ++ } ++ } ++} ++ ++/* allocate space for a MPPE/MPPC (de)compressor. */ ++/* comp != 0 -> init compressor */ ++/* comp = 0 -> init decompressor */ ++static void * ++mppe_alloc(unsigned char *options, int opt_len, int comp) ++{ ++ struct ppp_mppe_state *state; ++ u8* fname; ++ ++ fname = comp ? "mppe_comp_alloc" : "mppe_decomp_alloc"; ++ ++ /* ++ * Hack warning - additionally to the standard MPPC/MPPE configuration ++ * options, pppd passes to the (de)copressor 8 or 16 byte session key. ++ * Therefore options[1] contains MPPC/MPPE configuration option length ++ * (CILEN_MPPE = 6), but the real options length, depending on the key ++ * length, is 6+8 or 6+16. ++ */ ++ if (opt_len < CILEN_MPPE) { ++ printk(KERN_WARNING "%s: wrong options length: %u\n", fname, opt_len); ++ return NULL; ++ } ++ ++ if (options[0] != CI_MPPE || options[1] != CILEN_MPPE || ++ (options[2] & ~MPPE_STATELESS) != 0 || ++ options[3] != 0 || options[4] != 0 || ++ (options[5] & ~(MPPE_128BIT|MPPE_56BIT|MPPE_40BIT|MPPE_MPPC)) != 0 || ++ (options[5] & (MPPE_128BIT|MPPE_56BIT|MPPE_40BIT|MPPE_MPPC)) == 0) { ++ printk(KERN_WARNING "%s: options rejected: o[0]=%02x, o[1]=%02x, " ++ "o[2]=%02x, o[3]=%02x, o[4]=%02x, o[5]=%02x\n", fname, options[0], ++ options[1], options[2], options[3], options[4], options[5]); ++ return NULL; ++ } ++ ++ state = (struct ppp_mppe_state *)kmalloc(sizeof(*state), GFP_KERNEL); ++ if (state == NULL) { ++ printk(KERN_ERR "%s: cannot allocate space for %scompressor\n", fname, ++ comp ? "" : "de"); ++ return NULL; ++ } ++ memset(state, 0, sizeof(struct ppp_mppe_state)); ++ ++ state->mppc = options[5] & MPPE_MPPC; /* Do we use MPPC? */ ++ state->mppe = options[5] & (MPPE_128BIT | MPPE_56BIT | ++ MPPE_40BIT); /* Do we use MPPE? */ ++ ++ if (state->mppc) { ++ /* allocate MPPC history */ ++ state->hist = (u8*)vmalloc(2*MPPE_HIST_LEN*sizeof(u8)); ++ if (state->hist == NULL) { ++ kfree(state); ++ printk(KERN_ERR "%s: cannot allocate space for MPPC history\n", ++ fname); ++ return NULL; ++ } ++ ++ /* allocate hashtable for MPPC compressor */ ++ if (comp) { ++ state->hash = (u16*)vmalloc(MPPE_HIST_LEN*sizeof(u16)); ++ if (state->hash == NULL) { ++ vfree(state->hist); ++ kfree(state); ++ printk(KERN_ERR "%s: cannot allocate space for MPPC history\n", ++ fname); ++ return NULL; ++ } ++ } ++ } ++ ++ if (state->mppe) { /* specific for MPPE */ ++ /* Load SHA1 algorithm */ ++ state->sha1_tfm = crypto_alloc_tfm("sha1", 0); ++ if (state->sha1_tfm == NULL) { ++ vfree(state->hash); ++ vfree(state->hist); ++ kfree(state); ++ printk(KERN_ERR "%s: cannot load SHA1 module\n", fname); ++ return NULL; ++ } ++ ++ /* Load ARC4 algorithm */ ++ state->arc4_tfm = crypto_alloc_tfm("arc4", 0); ++ if (state->arc4_tfm == NULL) { ++ crypto_free_tfm(state->sha1_tfm); ++ vfree(state->hash); ++ vfree(state->hist); ++ kfree(state); ++ printk(KERN_ERR "%s: cannot load ARC4 module\n", fname); ++ return NULL; ++ } ++ ++ memcpy(state->master_key, options+CILEN_MPPE, MPPE_MAX_KEY_LEN); ++ memcpy(state->session_key, state->master_key, MPPE_MAX_KEY_LEN); ++ /* initial key generation is done in mppe_init() */ ++ } ++ ++ MOD_INC_USE_COUNT; ++ ++ return (void *) state; ++} ++ ++static void * ++mppe_comp_alloc(unsigned char *options, int opt_len) ++{ ++ return mppe_alloc(options, opt_len, 1); ++} ++ ++static void * ++mppe_decomp_alloc(unsigned char *options, int opt_len) ++{ ++ return mppe_alloc(options, opt_len, 0); ++} ++ ++/* cleanup the (de)compressor */ ++static void ++mppe_comp_free(void *arg) ++{ ++ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; ++ ++ if (state != NULL) { ++ if (state->mppe) { ++ if (state->sha1_tfm != NULL) ++ crypto_free_tfm(state->sha1_tfm); ++ if (state->arc4_tfm != NULL) ++ crypto_free_tfm(state->arc4_tfm); ++ } ++ if (state->hist != NULL) ++ vfree(state->hist); ++ if (state->hash != NULL) ++ vfree(state->hash); ++ kfree(state); ++ } ++ ++ MOD_DEC_USE_COUNT; ++} ++ ++/* init MPPC/MPPE (de)compresor */ ++/* comp != 0 -> init compressor */ ++/* comp = 0 -> init decompressor */ ++static int ++mppe_init(void *arg, unsigned char *options, int opt_len, int unit, ++ int hdrlen, int mru, int debug, int comp) ++{ ++ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; ++ u8* fname; ++ ++ fname = comp ? "mppe_comp_init" : "mppe_decomp_init"; ++ ++ if (opt_len < CILEN_MPPE) { ++ if (debug) ++ printk(KERN_WARNING "%s: wrong options length: %u\n", ++ fname, opt_len); ++ return 0; ++ } ++ ++ if (options[0] != CI_MPPE || options[1] != CILEN_MPPE || ++ (options[2] & ~MPPE_STATELESS) != 0 || ++ options[3] != 0 || options[4] != 0 || ++ (options[5] & ~(MPPE_56BIT|MPPE_128BIT|MPPE_40BIT|MPPE_MPPC)) != 0 || ++ (options[5] & (MPPE_56BIT|MPPE_128BIT|MPPE_40BIT|MPPE_MPPC)) == 0) { ++ if (debug) ++ printk(KERN_WARNING "%s: options rejected: o[0]=%02x, o[1]=%02x, " ++ "o[2]=%02x, o[3]=%02x, o[4]=%02x, o[5]=%02x\n", fname, ++ options[0], options[1], options[2], options[3], options[4], ++ options[5]); ++ return 0; ++ } ++ ++ if ((options[5] & ~MPPE_MPPC) != MPPE_128BIT && ++ (options[5] & ~MPPE_MPPC) != MPPE_56BIT && ++ (options[5] & ~MPPE_MPPC) != MPPE_40BIT && ++ (options[5] & MPPE_MPPC) != MPPE_MPPC) { ++ if (debug) ++ printk(KERN_WARNING "%s: don't know what to do: o[5]=%02x\n", ++ fname, options[5]); ++ return 0; ++ } ++ ++ state->mppc = options[5] & MPPE_MPPC; /* Do we use MPPC? */ ++ state->mppe = options[5] & (MPPE_128BIT | MPPE_56BIT | ++ MPPE_40BIT); /* Do we use MPPE? */ ++ state->stateless = options[2] & MPPE_STATELESS; /* Do we use stateless mode? */ ++ ++ switch (state->mppe) { ++ case MPPE_40BIT: /* 40 bit key */ ++ state->keylen = 8; ++ state->bitkeylen = 40; ++ break; ++ case MPPE_56BIT: /* 56 bit key */ ++ state->keylen = 8; ++ state->bitkeylen = 56; ++ break; ++ case MPPE_128BIT: /* 128 bit key */ ++ state->keylen = 16; ++ state->bitkeylen = 128; ++ break; ++ default: ++ state->keylen = 0; ++ state->bitkeylen = 0; ++ } ++ ++ state->ccount = MPPE_MAX_CCOUNT; ++ state->bits = 0; ++ state->unit = unit; ++ state->debug = debug; ++ state->histptr = MPPE_HIST_LEN; ++ if (state->mppc) { /* reset history if MPPC was negotiated */ ++ memset(state->hist, 0, 2*MPPE_HIST_LEN*sizeof(u8)); ++ } ++ ++ if (state->mppe) { /* generate initial session keys */ ++ mppe_change_key(state, 1); ++ } ++ ++ if (comp) { /* specific for compressor */ ++ state->nextflushed = 1; ++ } else { /* specific for decompressor */ ++ state->mru = mru; ++ state->flushexpected = 1; ++ } ++ ++ return 1; ++} ++ ++static int ++mppe_comp_init(void *arg, unsigned char *options, int opt_len, int unit, ++ int hdrlen, int debug) ++{ ++ return mppe_init(arg, options, opt_len, unit, hdrlen, 0, debug, 1); ++} ++ ++ ++static int ++mppe_decomp_init(void *arg, unsigned char *options, int opt_len, int unit, ++ int hdrlen, int mru, int debug) ++{ ++ return mppe_init(arg, options, opt_len, unit, hdrlen, mru, debug, 0); ++} ++ ++static void ++mppe_comp_reset(void *arg) ++{ ++ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg; ++ ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: resetting MPPC/MPPE compressor\n", ++ __FUNCTION__, state->unit); ++ ++ state->nextflushed = 1; ++ if (state->mppe) ++ arc4_setkey(state, state->session_key, state->keylen); ++} ++ ++static void ++mppe_decomp_reset(void *arg) ++{ ++ /* When MPPC/MPPE is in use, we shouldn't receive any CCP Reset-Ack. ++ But when we receive such a packet, we just ignore it. */ ++ return; ++} ++ ++static void ++mppe_stats(void *arg, struct compstat *stats) ++{ ++ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg; ++ ++ *stats = state->stats; ++} ++ ++/***************************/ ++/**** Compression stuff ****/ ++/***************************/ ++/* inserts 1 to 8 bits into the output buffer */ ++static inline void putbits8(u8 *buf, u32 val, const u32 n, u32 *i, u32 *l) ++{ ++ buf += *i; ++ if (*l >= n) { ++ *l = (*l) - n; ++ val <<= *l; ++ *buf = *buf | (val & 0xff); ++ if (*l == 0) { ++ *l = 8; ++ (*i)++; ++ *(++buf) = 0; ++ } ++ } else { ++ (*i)++; ++ *l = 8 - n + (*l); ++ val <<= *l; ++ *buf = *buf | ((val >> 8) & 0xff); ++ *(++buf) = val & 0xff; ++ } ++} ++ ++/* inserts 9 to 16 bits into the output buffer */ ++static inline void putbits16(u8 *buf, u32 val, const u32 n, u32 *i, u32 *l) ++{ ++ buf += *i; ++ if (*l >= n - 8) { ++ (*i)++; ++ *l = 8 - n + (*l); ++ val <<= *l; ++ *buf = *buf | ((val >> 8) & 0xff); ++ *(++buf) = val & 0xff; ++ if (*l == 0) { ++ *l = 8; ++ (*i)++; ++ *(++buf) = 0; ++ } ++ } else { ++ (*i)++; (*i)++; ++ *l = 16 - n + (*l); ++ val <<= *l; ++ *buf = *buf | ((val >> 16) & 0xff); ++ *(++buf) = (val >> 8) & 0xff; ++ *(++buf) = val & 0xff; ++ } ++} ++ ++/* inserts 17 to 24 bits into the output buffer */ ++static inline void putbits24(u8 *buf, u32 val, const u32 n, u32 *i, u32 *l) ++{ ++ buf += *i; ++ if (*l >= n - 16) { ++ (*i)++; (*i)++; ++ *l = 16 - n + (*l); ++ val <<= *l; ++ *buf = *buf | ((val >> 16) & 0xff); ++ *(++buf) = (val >> 8) & 0xff; ++ *(++buf) = val & 0xff; ++ if (*l == 0) { ++ *l = 8; ++ (*i)++; ++ *(++buf) = 0; ++ } ++ } else { ++ (*i)++; (*i)++; (*i)++; ++ *l = 24 - n + (*l); ++ val <<= *l; ++ *buf = *buf | ((val >> 24) & 0xff); ++ *(++buf) = (val >> 16) & 0xff; ++ *(++buf) = (val >> 8) & 0xff; ++ *(++buf) = val & 0xff; ++ } ++} ++ ++static int ++mppc_compress(struct ppp_mppe_state *state, unsigned char *ibuf, ++ unsigned char *obuf, int isize, int osize) ++{ ++ u32 olen, off, len, idx, i, l; ++ u8 *hist, *sbuf, *p, *q, *r, *s; ++ ++ /* ++ At this point, to avoid possible buffer overflow caused by packet ++ expansion during/after compression, we should make sure that ++ osize >= (((isize*9)/8)+1)+2, but we don't do that because in ++ ppp_generic.c we simply allocate bigger obuf. ++ ++ Maximum MPPC packet expansion is 12.5%. This is the worst case when ++ all octets in the input buffer are >= 0x80 and we cannot find any ++ repeated tokens. Additionally we have to reserve 2 bytes for MPPE/MPPC ++ status bits and coherency counter. ++ */ ++ ++ hist = state->hist + MPPE_HIST_LEN; ++ /* check if there is enough room at the end of the history */ ++ if (state->histptr + isize >= 2*MPPE_HIST_LEN) { ++ state->bits |= MPPE_BIT_RESET; ++ state->histptr = MPPE_HIST_LEN; ++ memcpy(state->hist, hist, MPPE_HIST_LEN); ++ } ++ /* add packet to the history; isize must be <= MPPE_HIST_LEN */ ++ sbuf = state->hist + state->histptr; ++ memcpy(sbuf, ibuf, isize); ++ state->histptr += isize; ++ ++ /* compress data */ ++ r = sbuf + isize; ++ *obuf = olen = i = 0; ++ l = 8; ++ while (i < isize - 2) { ++ s = q = sbuf + i; ++ idx = ((40543*((((s[0]<<4)^s[1])<<4)^s[2]))>>4) & 0x1fff; ++ p = hist + state->hash[idx]; ++ state->hash[idx] = (u16) (s - hist); ++ off = s - p; ++ if (off > MPPE_HIST_LEN - 1 || off < 1 || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++) { ++ /* no match found; encode literal byte */ ++ if (ibuf[i] < 0x80) { /* literal byte < 0x80 */ ++ putbits8(obuf, (u32) ibuf[i], 8, &olen, &l); ++ } else { /* literal byte >= 0x80 */ ++ putbits16(obuf, (u32) (0x100|(ibuf[i]&0x7f)), 9, &olen, &l); ++ } ++ ++i; ++ continue; ++ } ++ if (r - q >= 64) { ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++; ++ if (s - q == 64) { ++ p--; s--; ++ while((*p++ == *s++) && (s < r) && (p < q)); ++ } ++ } else { ++ while((*p++ == *s++) && (s < r) && (p < q)); ++ } ++ len = s - q - 1; ++ i += len; ++ ++ /* at least 3 character match found; code data */ ++ /* encode offset */ ++ if (off < 64) { /* 10-bit offset; 0 <= offset < 64 */ ++ putbits16(obuf, 0x3c0|off, 10, &olen, &l); ++ } else if (off < 320) { /* 12-bit offset; 64 <= offset < 320 */ ++ putbits16(obuf, 0xe00|(off-64), 12, &olen, &l); ++ } else if (off < 8192) { /* 16-bit offset; 320 <= offset < 8192 */ ++ putbits16(obuf, 0xc000|(off-320), 16, &olen, &l); ++ } else { ++ /* This shouldn't happen; we return 0 what means "packet expands", ++ and we send packet uncompressed. */ ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: wrong offset value: %d\n", ++ __FUNCTION__, state->unit, off); ++ return 0; ++ } ++ /* encode length of match */ ++ if (len < 4) { /* length = 3 */ ++ putbits8(obuf, 0, 1, &olen, &l); ++ } else if (len < 8) { /* 4 <= length < 8 */ ++ putbits8(obuf, 0x08|(len&0x03), 4, &olen, &l); ++ } else if (len < 16) { /* 8 <= length < 16 */ ++ putbits8(obuf, 0x30|(len&0x07), 6, &olen, &l); ++ } else if (len < 32) { /* 16 <= length < 32 */ ++ putbits8(obuf, 0xe0|(len&0x0f), 8, &olen, &l); ++ } else if (len < 64) { /* 32 <= length < 64 */ ++ putbits16(obuf, 0x3c0|(len&0x1f), 10, &olen, &l); ++ } else if (len < 128) { /* 64 <= length < 128 */ ++ putbits16(obuf, 0xf80|(len&0x3f), 12, &olen, &l); ++ } else if (len < 256) { /* 128 <= length < 256 */ ++ putbits16(obuf, 0x3f00|(len&0x7f), 14, &olen, &l); ++ } else if (len < 512) { /* 256 <= length < 512 */ ++ putbits16(obuf, 0xfe00|(len&0xff), 16, &olen, &l); ++ } else if (len < 1024) { /* 512 <= length < 1024 */ ++ putbits24(obuf, 0x3fc00|(len&0x1ff), 18, &olen, &l); ++ } else if (len < 2048) { /* 1024 <= length < 2048 */ ++ putbits24(obuf, 0xff800|(len&0x3ff), 20, &olen, &l); ++ } else if (len < 4096) { /* 2048 <= length < 4096 */ ++ putbits24(obuf, 0x3ff000|(len&0x7ff), 22, &olen, &l); ++ } else if (len < 8192) { /* 4096 <= length < 8192 */ ++ putbits24(obuf, 0xffe000|(len&0xfff), 24, &olen, &l); ++ } else { ++ /* This shouldn't happen; we return 0 what means "packet expands", ++ and send packet uncompressed. */ ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: wrong length of match value: %d\n", ++ __FUNCTION__, state->unit, len); ++ return 0; ++ } ++ } ++ ++ /* Add remaining octets to the output */ ++ while(isize - i > 0) { ++ if (ibuf[i] < 0x80) { /* literal byte < 0x80 */ ++ putbits8(obuf, (u32) ibuf[i++], 8, &olen, &l); ++ } else { /* literal byte >= 0x80 */ ++ putbits16(obuf, (u32) (0x100|(ibuf[i++]&0x7f)), 9, &olen, &l); ++ } ++ } ++ /* Reset unused bits of the last output octet */ ++ if ((l != 0) && (l != 8)) { ++ putbits8(obuf, 0, l, &olen, &l); ++ } ++ ++ return (int) olen; ++} ++ ++int ++mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf, ++ int isize, int osize) ++{ ++ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; ++ int proto, olen, complen, off; ++ unsigned char *wptr; ++ ++ /* Check that the protocol is in the range we handle. */ ++ proto = PPP_PROTOCOL(ibuf); ++ if (proto < 0x0021 || proto > 0x00fa) ++ return 0; ++ ++ wptr = obuf; ++ /* Copy over the PPP header */ ++ wptr[0] = PPP_ADDRESS(ibuf); ++ wptr[1] = PPP_CONTROL(ibuf); ++ wptr[2] = PPP_COMP >> 8; ++ wptr[3] = PPP_COMP; ++ wptr += PPP_HDRLEN + (MPPE_OVHD / 2); /* Leave two octets for MPPE/MPPC bits */ ++ ++ /* ++ * In ver. 0.99 protocol field was compressed. Deflate and BSD compress ++ * do PFC before actual compression, RCF2118 and RFC3078 are not precise ++ * on this topic so I decided to do PFC. Unfortunately this change caused ++ * incompatibility with older/other MPPE/MPPC modules. I have received ++ * a lot of complaints from unexperienced users so I have decided to revert ++ * to previous state, i.e. the protocol field is sent uncompressed now. ++ * Although this may be changed in the future. ++ * ++ * Receiving side (mppe_decompress()) still accepts packets with compressed ++ * and uncompressed protocol field so you shouldn't get "Unsupported protocol ++ * 0x2145 received" messages anymore. ++ */ ++ //off = (proto > 0xff) ? 2 : 3; /* PFC - skip first protocol byte if 0 */ ++ off = 2; ++ ++ ibuf += off; ++ ++ mppe_increase_ccount(state); ++ ++ if (state->nextflushed) { ++ state->bits |= MPPE_BIT_FLUSHED; ++ state->nextflushed = 0; ++ if (state->mppe && !state->stateless) { ++ /* ++ * If this is the flag packet, the key has been already changed in ++ * mppe_increase_ccount() so we dont't do it once again. ++ */ ++ if ((state->ccount & 0xff) != 0xff) { ++ arc4_setkey(state, state->session_key, state->keylen); ++ } ++ } ++ if (state->mppc) { /* reset history */ ++ state->bits |= MPPE_BIT_RESET; ++ state->histptr = MPPE_HIST_LEN; ++ memset(state->hist + MPPE_HIST_LEN, 0, MPPE_HIST_LEN*sizeof(u8)); ++ } ++ } ++ ++ if (state->mppc && !state->mppe) { /* Do only compression */ ++ complen = mppc_compress(state, ibuf, wptr, isize - off, ++ osize - PPP_HDRLEN - (MPPE_OVHD / 2)); ++ /* ++ * TODO: Implement an heuristics to handle packet expansion in a smart ++ * way. Now, when a packet expands, we send it as uncompressed and ++ * when next packet is sent we have to reset compressor's history. ++ * Maybe it would be better to send such packet as compressed in order ++ * to keep history's continuity. ++ */ ++ if ((complen > isize) || (complen > osize - PPP_HDRLEN) || ++ (complen == 0)) { ++ /* packet expands */ ++ state->nextflushed = 1; ++ memcpy(wptr, ibuf, isize - off); ++ olen = isize - (off - 2) + MPPE_OVHD; ++ (state->stats).inc_bytes += olen; ++ (state->stats).inc_packets++; ++ } else { ++ state->bits |= MPPE_BIT_COMP; ++ olen = complen + PPP_HDRLEN + (MPPE_OVHD / 2); ++ (state->stats).comp_bytes += olen; ++ (state->stats).comp_packets++; ++ } ++ } else { /* Do encryption with or without compression */ ++ state->bits |= MPPE_BIT_ENCRYPTED; ++ if (!state->mppc && state->mppe) { /* Do only encryption */ ++ /* read from ibuf, write to wptr, adjust for PPP_HDRLEN */ ++ arc4_encrypt(state, ibuf, isize - off, wptr); ++ olen = isize - (off - 2) + MPPE_OVHD; ++ (state->stats).inc_bytes += olen; ++ (state->stats).inc_packets++; ++ } else { /* Do compression and then encryption - RFC3078 */ ++ complen = mppc_compress(state, ibuf, wptr, isize - off, ++ osize - PPP_HDRLEN - (MPPE_OVHD / 2)); ++ /* ++ * TODO: Implement an heuristics to handle packet expansion in a smart ++ * way. Now, when a packet expands, we send it as uncompressed and ++ * when next packet is sent we have to reset compressor's history. ++ * Maybe it would be good to send such packet as compressed in order ++ * to keep history's continuity. ++ */ ++ if ((complen > isize) || (complen > osize - PPP_HDRLEN) || ++ (complen == 0)) { ++ /* packet expands */ ++ state->nextflushed = 1; ++ arc4_encrypt(state, ibuf, isize - off, wptr); ++ olen = isize - (off - 2) + MPPE_OVHD; ++ (state->stats).inc_bytes += olen; ++ (state->stats).inc_packets++; ++ } else { ++ state->bits |= MPPE_BIT_COMP; ++ /* Hack warning !!! RC4 implementation which we use does ++ encryption "in place" - it means that input and output ++ buffers can be *the same* memory area. Therefore we don't ++ need to use a temporary buffer. But be careful - other ++ implementations don't have to be so nice. ++ I used to use ibuf as temporary buffer here, but it led ++ packet sniffers into error. Thanks to Wilfried Weissmann ++ for pointing that. */ ++ arc4_encrypt(state, wptr, complen, wptr); ++ olen = complen + PPP_HDRLEN + (MPPE_OVHD / 2); ++ (state->stats).comp_bytes += olen; ++ (state->stats).comp_packets++; ++ } ++ } ++ } ++ ++ /* write status bits and coherency counter into the output buffer */ ++ wptr = obuf + PPP_HDRLEN; ++ wptr[0] = MPPE_CTRLHI(state); ++ wptr[1] = MPPE_CTRLLO(state); ++ ++ state->bits = 0; ++ ++ (state->stats).unc_bytes += isize; ++ (state->stats).unc_packets++; ++ ++ return olen; ++} ++ ++/***************************/ ++/*** Decompression stuff ***/ ++/***************************/ ++static inline u32 getbits(const u8 *buf, const u32 n, u32 *i, u32 *l) ++{ ++ static const u32 m[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; ++ u32 res, ol; ++ ++ ol = *l; ++ if (*l >= n) { ++ *l = (*l) - n; ++ res = (buf[*i] & m[ol]) >> (*l); ++ if (*l == 0) { ++ *l = 8; ++ (*i)++; ++ } ++ } else { ++ *l = 8 - n + (*l); ++ res = (buf[(*i)++] & m[ol]) << 8; ++ res = (res | buf[*i]) >> (*l); ++ } ++ ++ return res; ++} ++ ++static inline u32 getbyte(const u8 *buf, const u32 i, const u32 l) ++{ ++ if (l == 8) { ++ return buf[i]; ++ } else { ++ return (((buf[i] << 8) | buf[i+1]) >> l) & 0xff; ++ } ++} ++ ++static inline void lamecopy(u8 *dst, u8 *src, u32 len) ++{ ++ while (len--) ++ *dst++ = *src++; ++} ++ ++static int ++mppc_decompress(struct ppp_mppe_state *state, unsigned char *ibuf, ++ unsigned char *obuf, int isize, int osize) ++{ ++ u32 olen, off, len, bits, val, sig, i, l; ++ u8 *history, *s; ++ ++ history = state->hist + state->histptr; ++ olen = len = i = 0; ++ l = 8; ++ bits = isize * 8; ++ while (bits >= 8) { ++ val = getbyte(ibuf, i++, l); ++ if (val < 0x80) { /* literal byte < 0x80 */ ++ if (state->histptr < 2*MPPE_HIST_LEN) { ++ /* copy uncompressed byte to the history */ ++ (state->hist)[(state->histptr)++] = (u8) val; ++ } else { ++ /* buffer overflow; drop packet */ ++ if (state->debug) ++ printk(KERN_ERR "%s%d: trying to write outside history " ++ "buffer\n", __FUNCTION__, state->unit); ++ return DECOMP_ERROR; ++ } ++ olen++; ++ bits -= 8; ++ continue; ++ } ++ ++ sig = val & 0xc0; ++ if (sig == 0x80) { /* literal byte >= 0x80 */ ++ if (state->histptr < 2*MPPE_HIST_LEN) { ++ /* copy uncompressed byte to the history */ ++ (state->hist)[(state->histptr)++] = ++ (u8) (0x80|((val&0x3f)<<1)|getbits(ibuf, 1 , &i ,&l)); ++ } else { ++ /* buffer overflow; drop packet */ ++ if (state->debug) ++ printk(KERN_ERR "%s%d: trying to write outside history " ++ "buffer\n", __FUNCTION__, state->unit); ++ return DECOMP_ERROR; ++ } ++ olen++; ++ bits -= 9; ++ continue; ++ } ++ ++ /* Not a literal byte so it must be an (offset,length) pair */ ++ /* decode offset */ ++ sig = val & 0xf0; ++ if (sig == 0xf0) { /* 10-bit offset; 0 <= offset < 64 */ ++ off = (((val&0x0f)<<2)|getbits(ibuf, 2 , &i ,&l)); ++ bits -= 10; ++ } else { ++ if (sig == 0xe0) { /* 12-bit offset; 64 <= offset < 320 */ ++ off = ((((val&0x0f)<<4)|getbits(ibuf, 4 , &i ,&l))+64); ++ bits -= 12; ++ } else { ++ if ((sig&0xe0) == 0xc0) {/* 16-bit offset; 320 <= offset < 8192 */ ++ off = ((((val&0x1f)<<8)|getbyte(ibuf, i++, l))+320); ++ bits -= 16; ++ if (off > MPPE_HIST_LEN - 1) { ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: too big offset value: %d\n", ++ __FUNCTION__, state->unit, off); ++ return DECOMP_ERROR; ++ } ++ } else { /* this shouldn't happen */ ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: cannot decode offset value\n", ++ __FUNCTION__, state->unit); ++ return DECOMP_ERROR; ++ } ++ } ++ } ++ /* decode length of match */ ++ val = getbyte(ibuf, i, l); ++ if ((val & 0x80) == 0x00) { /* len = 3 */ ++ len = 3; ++ bits--; ++ getbits(ibuf, 1 , &i ,&l); ++ } else if ((val & 0xc0) == 0x80) { /* 4 <= len < 8 */ ++ len = 0x04 | ((val>>4) & 0x03); ++ bits -= 4; ++ getbits(ibuf, 4 , &i ,&l); ++ } else if ((val & 0xe0) == 0xc0) { /* 8 <= len < 16 */ ++ len = 0x08 | ((val>>2) & 0x07); ++ bits -= 6; ++ getbits(ibuf, 6 , &i ,&l); ++ } else if ((val & 0xf0) == 0xe0) { /* 16 <= len < 32 */ ++ len = 0x10 | (val & 0x0f); ++ bits -= 8; ++ i++; ++ } else { ++ bits -= 8; ++ val = (val << 8) | getbyte(ibuf, ++i, l); ++ if ((val & 0xf800) == 0xf000) { /* 32 <= len < 64 */ ++ len = 0x0020 | ((val >> 6) & 0x001f); ++ bits -= 2; ++ getbits(ibuf, 2 , &i ,&l); ++ } else if ((val & 0xfc00) == 0xf800) { /* 64 <= len < 128 */ ++ len = 0x0040 | ((val >> 4) & 0x003f); ++ bits -= 4; ++ getbits(ibuf, 4 , &i ,&l); ++ } else if ((val & 0xfe00) == 0xfc00) { /* 128 <= len < 256 */ ++ len = 0x0080 | ((val >> 2) & 0x007f); ++ bits -= 6; ++ getbits(ibuf, 6 , &i ,&l); ++ } else if ((val & 0xff00) == 0xfe00) { /* 256 <= len < 512 */ ++ len = 0x0100 | (val & 0x00ff); ++ bits -= 8; ++ i++; ++ } else { ++ bits -= 8; ++ val = (val << 8) | getbyte(ibuf, ++i, l); ++ if ((val & 0xff8000) == 0xff0000) { /* 512 <= len < 1024 */ ++ len = 0x000200 | ((val >> 6) & 0x0001ff); ++ bits -= 2; ++ getbits(ibuf, 2 , &i ,&l); ++ } else if ((val & 0xffc000) == 0xff8000) {/* 1024 <= len < 2048 */ ++ len = 0x000400 | ((val >> 4) & 0x0003ff); ++ bits -= 4; ++ getbits(ibuf, 4 , &i ,&l); ++ } else if ((val & 0xffe000) == 0xffc000) {/* 2048 <= len < 4096 */ ++ len = 0x000800 | ((val >> 2) & 0x0007ff); ++ bits -= 6; ++ getbits(ibuf, 6 , &i ,&l); ++ } else if ((val & 0xfff000) == 0xffe000) {/* 4096 <= len < 8192 */ ++ len = 0x001000 | (val & 0x000fff); ++ bits -= 8; ++ i++; ++ } else { /* this shouldn't happen */ ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: wrong length code: 0x%X\n", ++ __FUNCTION__, state->unit, val); ++ return DECOMP_ERROR; ++ } ++ } ++ } ++ s = state->hist + state->histptr; ++ state->histptr += len; ++ olen += len; ++ if (state->histptr < 2*MPPE_HIST_LEN) { ++ /* copy uncompressed bytes to the history */ ++ ++ /* In some cases len may be greater than off. It means that memory ++ * areas pointed by s and s-off overlap. I had used memmove() here ++ * because I thought that it acts as libc's version. Unfortunately, ++ * I was wrong. :-) I got strange errors sometimes. Wilfried suggested ++ * using of byte by byte copying here and strange errors disappeared. ++ */ ++ lamecopy(s, s - off, len); ++ } else { ++ /* buffer overflow; drop packet */ ++ if (state->debug) ++ printk(KERN_ERR "%s%d: trying to write outside history " ++ "buffer\n", __FUNCTION__, state->unit); ++ return DECOMP_ERROR; ++ } ++ } ++ ++ /* Do PFC decompression */ ++ len = olen; ++ if ((history[0] & 0x01) != 0) { ++ obuf[0] = 0; ++ obuf++; ++ len++; ++ } ++ ++ if (len <= osize) { ++ /* copy uncompressed packet to the output buffer */ ++ memcpy(obuf, history, olen); ++ } else { ++ /* buffer overflow; drop packet */ ++ if (state->debug) ++ printk(KERN_ERR "%s%d: too big uncompressed packet: %d\n", ++ __FUNCTION__, state->unit, len + (PPP_HDRLEN / 2)); ++ return DECOMP_ERROR; ++ } ++ ++ return (int) len; ++} ++ ++int ++mppe_decompress(void *arg, unsigned char *ibuf, int isize, ++ unsigned char *obuf, int osize) ++{ ++ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg; ++ int seq, bits, uncomplen; ++ ++ if (isize <= PPP_HDRLEN + MPPE_OVHD) { ++ if (state->debug) { ++ printk(KERN_DEBUG "%s%d: short packet (len=%d)\n", __FUNCTION__, ++ state->unit, isize); ++ } ++ return DECOMP_ERROR; ++ } ++ ++ /* Get coherency counter and control bits from input buffer */ ++ seq = MPPE_CCOUNT(ibuf); ++ bits = MPPE_BITS(ibuf); ++ ++ if (state->stateless) { ++ /* RFC 3078, sec 8.1. */ ++ mppe_increase_ccount(state); ++ if ((seq != state->ccount) && state->debug) ++ printk(KERN_DEBUG "%s%d: bad sequence number: %d, expected: %d\n", ++ __FUNCTION__, state->unit, seq, state->ccount); ++ while (seq != state->ccount) ++ mppe_increase_ccount(state); ++ } else { ++ /* RFC 3078, sec 8.2. */ ++ if (state->flushexpected) { /* discard state */ ++ if ((bits & MPPE_BIT_FLUSHED)) { /* we received expected FLUSH bit */ ++ while (seq != state->ccount) ++ mppe_increase_ccount(state); ++ state->flushexpected = 0; ++ } else /* drop packet*/ ++ return DECOMP_ERROR; ++ } else { /* normal state */ ++ mppe_increase_ccount(state); ++ if (seq != state->ccount) { ++ /* Packet loss detected, enter the discard state. */ ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: bad sequence number: %d, expected: %d\n", ++ __FUNCTION__, state->unit, seq, state->ccount); ++ state->flushexpected = 1; ++ return DECOMP_ERROR; ++ } ++ } ++ if (state->mppe && (bits & MPPE_BIT_FLUSHED)) { ++ arc4_setkey(state, state->session_key, state->keylen); ++ } ++ } ++ ++ if (state->mppc && (bits & (MPPE_BIT_FLUSHED | MPPE_BIT_RESET))) { ++ state->histptr = MPPE_HIST_LEN; ++ if ((bits & MPPE_BIT_FLUSHED)) { ++ memset(state->hist + MPPE_HIST_LEN, 0, MPPE_HIST_LEN*sizeof(u8)); ++ } else ++ if ((bits & MPPE_BIT_RESET)) { ++ memcpy(state->hist, state->hist + MPPE_HIST_LEN, MPPE_HIST_LEN); ++ } ++ } ++ ++ /* Fill in the first part of the PPP header. The protocol field ++ comes from the decompressed data. */ ++ obuf[0] = PPP_ADDRESS(ibuf); ++ obuf[1] = PPP_CONTROL(ibuf); ++ obuf += PPP_HDRLEN / 2; ++ ++ if (state->mppe) { /* process encrypted packet */ ++ if ((bits & MPPE_BIT_ENCRYPTED)) { ++ /* OK, packet encrypted, so decrypt it */ ++ if (state->mppc && (bits & MPPE_BIT_COMP)) { ++ /* Hack warning !!! RC4 implementation which we use does ++ decryption "in place" - it means that input and output ++ buffers can be *the same* memory area. Therefore we don't ++ need to use a temporary buffer. But be careful - other ++ implementations don't have to be so nice. */ ++ arc4_decrypt(state, ibuf + PPP_HDRLEN + (MPPE_OVHD / 2), isize - ++ PPP_HDRLEN - (MPPE_OVHD / 2), ibuf + PPP_HDRLEN + ++ (MPPE_OVHD / 2)); ++ uncomplen = mppc_decompress(state, ibuf + PPP_HDRLEN + ++ (MPPE_OVHD / 2), obuf, isize - ++ PPP_HDRLEN - (MPPE_OVHD / 2), ++ osize - (PPP_HDRLEN / 2)); ++ if (uncomplen == DECOMP_ERROR) { ++ state->flushexpected = 1; ++ return DECOMP_ERROR; ++ } ++ uncomplen += PPP_HDRLEN / 2; ++ (state->stats).comp_bytes += isize; ++ (state->stats).comp_packets++; ++ } else { ++ uncomplen = isize - MPPE_OVHD; ++ /* Decrypt the first byte in order to check if it is ++ compressed or uncompressed protocol field */ ++ arc4_decrypt(state, ibuf + PPP_HDRLEN + (MPPE_OVHD / 2), 1, obuf); ++ /* Do PFC decompression */ ++ if ((obuf[0] & 0x01) != 0) { ++ obuf[1] = obuf[0]; ++ obuf[0] = 0; ++ obuf++; ++ uncomplen++; ++ } ++ /* And finally, decrypt the rest of the frame. */ ++ arc4_decrypt(state, ibuf + PPP_HDRLEN + (MPPE_OVHD / 2) + 1, ++ isize - PPP_HDRLEN - (MPPE_OVHD / 2) - 1, obuf + 1); ++ (state->stats).inc_bytes += isize; ++ (state->stats).inc_packets++; ++ } ++ } else { /* this shouldn't happen */ ++ if (state->debug) ++ printk(KERN_ERR "%s%d: encryption negotiated but not an " ++ "encrypted packet received\n", __FUNCTION__, state->unit); ++ mppe_change_key(state, 0); ++ state->flushexpected = 1; ++ return DECOMP_ERROR; ++ } ++ } else { ++ if (state->mppc) { /* no MPPE, only MPPC */ ++ if ((bits & MPPE_BIT_COMP)) { ++ uncomplen = mppc_decompress(state, ibuf + PPP_HDRLEN + ++ (MPPE_OVHD / 2), obuf, isize - ++ PPP_HDRLEN - (MPPE_OVHD / 2), ++ osize - (PPP_HDRLEN / 2)); ++ if (uncomplen == DECOMP_ERROR) { ++ state->flushexpected = 1; ++ return DECOMP_ERROR; ++ } ++ uncomplen += PPP_HDRLEN / 2; ++ (state->stats).comp_bytes += isize; ++ (state->stats).comp_packets++; ++ } else { ++ memcpy(obuf, ibuf + PPP_HDRLEN + (MPPE_OVHD / 2), isize - ++ PPP_HDRLEN - (MPPE_OVHD / 2)); ++ uncomplen = isize - MPPE_OVHD; ++ (state->stats).inc_bytes += isize; ++ (state->stats).inc_packets++; ++ } ++ } else { /* this shouldn't happen */ ++ if (state->debug) ++ printk(KERN_ERR "%s%d: error - not an MPPC or MPPE frame " ++ "received\n", __FUNCTION__, state->unit); ++ state->flushexpected = 1; ++ return DECOMP_ERROR; ++ } ++ } ++ ++ (state->stats).unc_bytes += uncomplen; ++ (state->stats).unc_packets++; ++ ++ return uncomplen; ++} ++ ++ ++/************************************************************ ++ * Module interface table ++ ************************************************************/ ++ ++/* These are in ppp_generic.c */ ++extern int ppp_register_compressor (struct compressor *cp); ++extern void ppp_unregister_compressor (struct compressor *cp); ++ ++/* ++ * Functions exported to ppp_generic.c. ++ * ++ * In case of MPPC/MPPE there is no need to process incompressible data ++ * because such a data is sent in MPPC/MPPE frame. Therefore the (*incomp) ++ * callback function isn't needed. ++ */ ++struct compressor ppp_mppe = { ++ CI_MPPE, /* compress_proto */ ++ mppe_comp_alloc, /* comp_alloc */ ++ mppe_comp_free, /* comp_free */ ++ mppe_comp_init, /* comp_init */ ++ mppe_comp_reset, /* comp_reset */ ++ mppe_compress, /* compress */ ++ mppe_stats, /* comp_stat */ ++ mppe_decomp_alloc, /* decomp_alloc */ ++ mppe_comp_free, /* decomp_free */ ++ mppe_decomp_init, /* decomp_init */ ++ mppe_decomp_reset, /* decomp_reset */ ++ mppe_decompress, /* decompress */ ++ NULL, /* incomp */ ++ mppe_stats, /* decomp_stat */ ++}; ++ ++/************************************************************ ++ * Module support routines ++ ************************************************************/ ++ ++int __init mppe_module_init(void) ++{ ++ int answer = ppp_register_compressor(&ppp_mppe); ++ if (answer == 0) { ++ printk(KERN_INFO "MPPE/MPPC encryption/compression module registered\n"); ++ } ++ return answer; ++} ++ ++void __exit mppe_module_cleanup(void) ++{ ++ ppp_unregister_compressor(&ppp_mppe); ++ printk(KERN_INFO "MPPE/MPPC encryption/compression module unregistered\n"); ++} ++ ++module_init(mppe_module_init); ++module_exit(mppe_module_cleanup); ++ ++MODULE_AUTHOR("Jan Dubiec "); ++MODULE_DESCRIPTION("MPPE/MPPC encryption/compression module for Linux"); ++MODULE_LICENSE("Dual BSD/GPL"); +diff -ruN linux.orig/include/linux/ppp-comp.h linux/include/linux/ppp-comp.h +--- linux.orig/include/linux/ppp-comp.h 1999-08-06 19:44:11.000000000 +0200 ++++ linux/include/linux/ppp-comp.h 2004-08-08 12:17:43.000000000 +0200 +@@ -1,34 +1,42 @@ + /* + * ppp-comp.h - Definitions for doing PPP packet compression. + * +- * Copyright (c) 1994 The Australian National University. +- * All rights reserved. ++ * Copyright (c) 1984 Paul Mackerras. All rights reserved. + * +- * Permission to use, copy, modify, and distribute this software and its +- * documentation is hereby granted, provided that the above copyright +- * notice appears in all copies. This software is provided without any +- * warranty, express or implied. The Australian National University +- * makes no representations about the suitability of this software for +- * any purpose. +- * +- * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY +- * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF +- * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY +- * OF SUCH DAMAGE. +- * +- * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, +- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +- * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO +- * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, +- * OR MODIFICATIONS. ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: + * +- * $Id: ppp-comp.h,v 1.6 1997/11/27 06:04:44 paulus Exp $ ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. The name(s) of the authors of this software must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. ++ * ++ * 4. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by Paul Mackerras ++ * ". ++ * ++ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO ++ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ++ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY ++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN ++ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING ++ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * $Id: ppp-comp.h,v 1.10 2002/12/06 09:49:15 paulus Exp $ + */ + + /* +- * ==FILEVERSION 980319== ++ * ==FILEVERSION 20040509== + * + * NOTE TO MAINTAINERS: + * If you modify this file at all, please set the above date. +@@ -78,7 +86,7 @@ + + /* Compress a packet */ + int (*compress) (void *state, unsigned char *rptr, +- unsigned char *obuf, int isize, int osize); ++ unsigned char *obuf, int isize, int osize); + + /* Return compression statistics */ + void (*comp_stat) (void *state, struct compstat *stats); +@@ -99,7 +107,7 @@ + + /* Decompress a packet. */ + int (*decompress) (void *state, unsigned char *ibuf, int isize, +- unsigned char *obuf, int osize); ++ unsigned char *obuf, int osize); + + /* Update state for an incompressible packet received */ + void (*incomp) (void *state, unsigned char *ibuf, int icnt); +@@ -187,6 +195,42 @@ + #define DEFLATE_CHK_SEQUENCE 0 + + /* ++ * Definitions for MPPE/MPPC. ++ */ ++ ++#define CI_MPPE 18 /* config option for MPPE */ ++#define CILEN_MPPE 6 /* length of config option */ ++ ++#define MPPE_OVHD 4 /* MPPE overhead */ ++#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */ ++ ++#define MPPE_STATELESS 0x01 /* configuration bit H */ ++#define MPPE_40BIT 0x20 /* configuration bit L */ ++#define MPPE_56BIT 0x80 /* configuration bit M */ ++#define MPPE_128BIT 0x40 /* configuration bit S */ ++#define MPPE_MPPC 0x01 /* configuration bit C */ ++ ++/* ++ * Definitions for Stac LZS. ++ */ ++ ++#define CI_LZS 17 /* config option for Stac LZS */ ++#define CILEN_LZS 5 /* length of config option */ ++ ++#define LZS_OVHD 4 /* max. LZS overhead */ ++#define LZS_HIST_LEN 2048 /* LZS history size */ ++#define LZS_MAX_CCOUNT 0x0FFF /* max. coherency counter value */ ++ ++#define LZS_MODE_NONE 0 ++#define LZS_MODE_LCB 1 ++#define LZS_MODE_CRC 2 ++#define LZS_MODE_SEQ 3 ++#define LZS_MODE_EXT 4 ++ ++#define LZS_EXT_BIT_FLUSHED 0x80 /* bit A */ ++#define LZS_EXT_BIT_COMP 0x20 /* bit C */ ++ ++/* + * Definitions for other, as yet unsupported, compression methods. + */ + diff --git a/packages/linux/linux-mtx-1-2.4.27/40-option-hsdpa.patch b/packages/linux/linux-mtx-1-2.4.27/40-option-hsdpa.patch new file mode 100644 index 0000000000..2055f72312 --- /dev/null +++ b/packages/linux/linux-mtx-1-2.4.27/40-option-hsdpa.patch @@ -0,0 +1,2961 @@ +diff -uNr linux-org/Documentation/Configure.help linux/Documentation/Configure.help +--- linux-org/Documentation/Configure.help 2006-02-06 14:01:32.375955928 +0100 ++++ linux/Documentation/Configure.help 2006-02-06 15:51:13.332498464 +0100 +@@ -4057,6 +4057,9 @@ + The module will be called synclinkmp.o. If you want to do that, say M + here. + ++Option HSDPA card support ++CONFIG_NOZOMI ++ + ACP Modem (Mwave) support + CONFIG_MWAVE + The ACP modem (Mwave) for Linux is a WinModem. It is composed of a +diff -uNr linux-org/drivers/char/Config.in linux/drivers/char/Config.in +--- linux-org/drivers/char/Config.in 2006-02-06 14:01:55.767399888 +0100 ++++ linux/drivers/char/Config.in 2006-02-06 15:51:07.574373832 +0100 +@@ -388,6 +388,8 @@ + + endmenu + ++tristate ' Option HSDPA card support' CONFIG_NOZOMI ++ + if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then + source drivers/char/pcmcia/Config.in + fi +diff -uNr linux-org/drivers/char/Makefile linux/drivers/char/Makefile +--- linux-org/drivers/char/Makefile 2006-02-06 14:01:55.782397608 +0100 ++++ linux/drivers/char/Makefile 2006-02-06 15:30:37.949305256 +0100 +@@ -331,6 +331,11 @@ + obj-$(CONFIG_INDYDOG) += indydog.o + obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o + ++subdir-$(CONFIG_NOZOMI) += nozomi ++ifeq ($(CONFIG_NOZOMI),y) ++ obj-y += nozomi/noz.o ++endif ++ + subdir-$(CONFIG_MWAVE) += mwave + ifeq ($(CONFIG_MWAVE),y) + obj-y += mwave/mwave.o +diff -uNr linux-org/drivers/char/nozomi/CHANGELOG linux/drivers/char/nozomi/CHANGELOG +--- linux-org/drivers/char/nozomi/CHANGELOG 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/CHANGELOG 2006-02-06 15:30:07.370953872 +0100 +@@ -0,0 +1,7 @@ ++/* ++ * Version 1.0 ++ * ++ * First version of driver, only tested with card of type F32_2. ++ * Works fine with 2.4 and 2.6 kernels. ++ * Driver also support big endian architecture. ++ */ +diff -uNr linux-org/drivers/char/nozomi/COPYING linux/drivers/char/nozomi/COPYING +--- linux-org/drivers/char/nozomi/COPYING 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/COPYING 2006-02-06 15:30:07.371953720 +0100 +@@ -0,0 +1,340 @@ ++ GNU GENERAL PUBLIC LICENSE ++ Version 2, June 1991 ++ ++ Copyright (C) 1989, 1991 Free Software Foundation, Inc. ++ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ Everyone is permitted to copy and distribute verbatim copies ++ of this license document, but changing it is not allowed. ++ ++ Preamble ++ ++ The licenses for most software are designed to take away your ++freedom to share and change it. By contrast, the GNU General Public ++License is intended to guarantee your freedom to share and change free ++software--to make sure the software is free for all its users. This ++General Public License applies to most of the Free Software ++Foundation's software and to any other program whose authors commit to ++using it. (Some other Free Software Foundation software is covered by ++the GNU Library General Public License instead.) You can apply it to ++your programs, too. ++ ++ When we speak of free software, we are referring to freedom, not ++price. Our General Public Licenses are designed to make sure that you ++have the freedom to distribute copies of free software (and charge for ++this service if you wish), that you receive source code or can get it ++if you want it, that you can change the software or use pieces of it ++in new free programs; and that you know you can do these things. ++ ++ To protect your rights, we need to make restrictions that forbid ++anyone to deny you these rights or to ask you to surrender the rights. ++These restrictions translate to certain responsibilities for you if you ++distribute copies of the software, or if you modify it. ++ ++ For example, if you distribute copies of such a program, whether ++gratis or for a fee, you must give the recipients all the rights that ++you have. You must make sure that they, too, receive or can get the ++source code. And you must show them these terms so they know their ++rights. ++ ++ We protect your rights with two steps: (1) copyright the software, and ++(2) offer you this license which gives you legal permission to copy, ++distribute and/or modify the software. ++ ++ Also, for each author's protection and ours, we want to make certain ++that everyone understands that there is no warranty for this free ++software. If the software is modified by someone else and passed on, we ++want its recipients to know that what they have is not the original, so ++that any problems introduced by others will not reflect on the original ++authors' reputations. ++ ++ Finally, any free program is threatened constantly by software ++patents. We wish to avoid the danger that redistributors of a free ++program will individually obtain patent licenses, in effect making the ++program proprietary. To prevent this, we have made it clear that any ++patent must be licensed for everyone's free use or not licensed at all. ++ ++ The precise terms and conditions for copying, distribution and ++modification follow. ++ ++ GNU GENERAL PUBLIC LICENSE ++ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION ++ ++ 0. This License applies to any program or other work which contains ++a notice placed by the copyright holder saying it may be distributed ++under the terms of this General Public License. The "Program", below, ++refers to any such program or work, and a "work based on the Program" ++means either the Program or any derivative work under copyright law: ++that is to say, a work containing the Program or a portion of it, ++either verbatim or with modifications and/or translated into another ++language. (Hereinafter, translation is included without limitation in ++the term "modification".) Each licensee is addressed as "you". ++ ++Activities other than copying, distribution and modification are not ++covered by this License; they are outside its scope. The act of ++running the Program is not restricted, and the output from the Program ++is covered only if its contents constitute a work based on the ++Program (independent of having been made by running the Program). ++Whether that is true depends on what the Program does. ++ ++ 1. You may copy and distribute verbatim copies of the Program's ++source code as you receive it, in any medium, provided that you ++conspicuously and appropriately publish on each copy an appropriate ++copyright notice and disclaimer of warranty; keep intact all the ++notices that refer to this License and to the absence of any warranty; ++and give any other recipients of the Program a copy of this License ++along with the Program. ++ ++You may charge a fee for the physical act of transferring a copy, and ++you may at your option offer warranty protection in exchange for a fee. ++ ++ 2. You may modify your copy or copies of the Program or any portion ++of it, thus forming a work based on the Program, and copy and ++distribute such modifications or work under the terms of Section 1 ++above, provided that you also meet all of these conditions: ++ ++ a) You must cause the modified files to carry prominent notices ++ stating that you changed the files and the date of any change. ++ ++ b) You must cause any work that you distribute or publish, that in ++ whole or in part contains or is derived from the Program or any ++ part thereof, to be licensed as a whole at no charge to all third ++ parties under the terms of this License. ++ ++ c) If the modified program normally reads commands interactively ++ when run, you must cause it, when started running for such ++ interactive use in the most ordinary way, to print or display an ++ announcement including an appropriate copyright notice and a ++ notice that there is no warranty (or else, saying that you provide ++ a warranty) and that users may redistribute the program under ++ these conditions, and telling the user how to view a copy of this ++ License. (Exception: if the Program itself is interactive but ++ does not normally print such an announcement, your work based on ++ the Program is not required to print an announcement.) ++ ++These requirements apply to the modified work as a whole. If ++identifiable sections of that work are not derived from the Program, ++and can be reasonably considered independent and separate works in ++themselves, then this License, and its terms, do not apply to those ++sections when you distribute them as separate works. But when you ++distribute the same sections as part of a whole which is a work based ++on the Program, the distribution of the whole must be on the terms of ++this License, whose permissions for other licensees extend to the ++entire whole, and thus to each and every part regardless of who wrote it. ++ ++Thus, it is not the intent of this section to claim rights or contest ++your rights to work written entirely by you; rather, the intent is to ++exercise the right to control the distribution of derivative or ++collective works based on the Program. ++ ++In addition, mere aggregation of another work not based on the Program ++with the Program (or with a work based on the Program) on a volume of ++a storage or distribution medium does not bring the other work under ++the scope of this License. ++ ++ 3. You may copy and distribute the Program (or a work based on it, ++under Section 2) in object code or executable form under the terms of ++Sections 1 and 2 above provided that you also do one of the following: ++ ++ a) Accompany it with the complete corresponding machine-readable ++ source code, which must be distributed under the terms of Sections ++ 1 and 2 above on a medium customarily used for software interchange; or, ++ ++ b) Accompany it with a written offer, valid for at least three ++ years, to give any third party, for a charge no more than your ++ cost of physically performing source distribution, a complete ++ machine-readable copy of the corresponding source code, to be ++ distributed under the terms of Sections 1 and 2 above on a medium ++ customarily used for software interchange; or, ++ ++ c) Accompany it with the information you received as to the offer ++ to distribute corresponding source code. (This alternative is ++ allowed only for noncommercial distribution and only if you ++ received the program in object code or executable form with such ++ an offer, in accord with Subsection b above.) ++ ++The source code for a work means the preferred form of the work for ++making modifications to it. For an executable work, complete source ++code means all the source code for all modules it contains, plus any ++associated interface definition files, plus the scripts used to ++control compilation and installation of the executable. However, as a ++special exception, the source code distributed need not include ++anything that is normally distributed (in either source or binary ++form) with the major components (compiler, kernel, and so on) of the ++operating system on which the executable runs, unless that component ++itself accompanies the executable. ++ ++If distribution of executable or object code is made by offering ++access to copy from a designated place, then offering equivalent ++access to copy the source code from the same place counts as ++distribution of the source code, even though third parties are not ++compelled to copy the source along with the object code. ++ ++ 4. You may not copy, modify, sublicense, or distribute the Program ++except as expressly provided under this License. Any attempt ++otherwise to copy, modify, sublicense or distribute the Program is ++void, and will automatically terminate your rights under this License. ++However, parties who have received copies, or rights, from you under ++this License will not have their licenses terminated so long as such ++parties remain in full compliance. ++ ++ 5. You are not required to accept this License, since you have not ++signed it. However, nothing else grants you permission to modify or ++distribute the Program or its derivative works. These actions are ++prohibited by law if you do not accept this License. Therefore, by ++modifying or distributing the Program (or any work based on the ++Program), you indicate your acceptance of this License to do so, and ++all its terms and conditions for copying, distributing or modifying ++the Program or works based on it. ++ ++ 6. Each time you redistribute the Program (or any work based on the ++Program), the recipient automatically receives a license from the ++original licensor to copy, distribute or modify the Program subject to ++these terms and conditions. You may not impose any further ++restrictions on the recipients' exercise of the rights granted herein. ++You are not responsible for enforcing compliance by third parties to ++this License. ++ ++ 7. If, as a consequence of a court judgment or allegation of patent ++infringement or for any other reason (not limited to patent issues), ++conditions are imposed on you (whether by court order, agreement or ++otherwise) that contradict the conditions of this License, they do not ++excuse you from the conditions of this License. If you cannot ++distribute so as to satisfy simultaneously your obligations under this ++License and any other pertinent obligations, then as a consequence you ++may not distribute the Program at all. For example, if a patent ++license would not permit royalty-free redistribution of the Program by ++all those who receive copies directly or indirectly through you, then ++the only way you could satisfy both it and this License would be to ++refrain entirely from distribution of the Program. ++ ++If any portion of this section is held invalid or unenforceable under ++any particular circumstance, the balance of the section is intended to ++apply and the section as a whole is intended to apply in other ++circumstances. ++ ++It is not the purpose of this section to induce you to infringe any ++patents or other property right claims or to contest validity of any ++such claims; this section has the sole purpose of protecting the ++integrity of the free software distribution system, which is ++implemented by public license practices. Many people have made ++generous contributions to the wide range of software distributed ++through that system in reliance on consistent application of that ++system; it is up to the author/donor to decide if he or she is willing ++to distribute software through any other system and a licensee cannot ++impose that choice. ++ ++This section is intended to make thoroughly clear what is believed to ++be a consequence of the rest of this License. ++ ++ 8. If the distribution and/or use of the Program is restricted in ++certain countries either by patents or by copyrighted interfaces, the ++original copyright holder who places the Program under this License ++may add an explicit geographical distribution limitation excluding ++those countries, so that distribution is permitted only in or among ++countries not thus excluded. In such case, this License incorporates ++the limitation as if written in the body of this License. ++ ++ 9. The Free Software Foundation may publish revised and/or new versions ++of the General Public License from time to time. Such new versions will ++be similar in spirit to the present version, but may differ in detail to ++address new problems or concerns. ++ ++Each version is given a distinguishing version number. If the Program ++specifies a version number of this License which applies to it and "any ++later version", you have the option of following the terms and conditions ++either of that version or of any later version published by the Free ++Software Foundation. If the Program does not specify a version number of ++this License, you may choose any version ever published by the Free Software ++Foundation. ++ ++ 10. If you wish to incorporate parts of the Program into other free ++programs whose distribution conditions are different, write to the author ++to ask for permission. For software which is copyrighted by the Free ++Software Foundation, write to the Free Software Foundation; we sometimes ++make exceptions for this. Our decision will be guided by the two goals ++of preserving the free status of all derivatives of our free software and ++of promoting the sharing and reuse of software generally. ++ ++ NO WARRANTY ++ ++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY ++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN ++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES ++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED ++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS ++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE ++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, ++REPAIR OR CORRECTION. ++ ++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING ++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR ++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, ++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING ++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED ++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY ++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER ++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE ++POSSIBILITY OF SUCH DAMAGES. ++ ++ END OF TERMS AND CONDITIONS ++ ++ How to Apply These Terms to Your New Programs ++ ++ If you develop a new program, and you want it to be of the greatest ++possible use to the public, the best way to achieve this is to make it ++free software which everyone can redistribute and change under these terms. ++ ++ To do so, attach the following notices to the program. It is safest ++to attach them to the start of each source file to most effectively ++convey the exclusion of warranty; and each file should have at least ++the "copyright" line and a pointer to where the full notice is found. ++ ++ ++ Copyright (C) ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ ++ ++Also add information on how to contact you by electronic and paper mail. ++ ++If the program is interactive, make it output a short notice like this ++when it starts in an interactive mode: ++ ++ Gnomovision version 69, Copyright (C) year name of author ++ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. ++ This is free software, and you are welcome to redistribute it ++ under certain conditions; type `show c' for details. ++ ++The hypothetical commands `show w' and `show c' should show the appropriate ++parts of the General Public License. Of course, the commands you use may ++be called something other than `show w' and `show c'; they could even be ++mouse-clicks or menu items--whatever suits your program. ++ ++You should also get your employer (if you work as a programmer) or your ++school, if any, to sign a "copyright disclaimer" for the program, if ++necessary. Here is a sample; alter the names: ++ ++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program ++ `Gnomovision' (which makes passes at compilers) written by James Hacker. ++ ++ , 1 April 1989 ++ Ty Coon, President of Vice ++ ++This General Public License does not permit incorporating your program into ++proprietary programs. If your program is a subroutine library, you may ++consider it more useful to permit linking proprietary applications with the ++library. If this is what you want to do, use the GNU Library General ++Public License instead of this License. +diff -uNr linux-org/drivers/char/nozomi/Makefile linux/drivers/char/nozomi/Makefile +--- linux-org/drivers/char/nozomi/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/Makefile 2006-02-06 15:30:07.379952504 +0100 +@@ -0,0 +1,25 @@ ++# ++# Makefile for ACP Modem (Mwave). ++# ++# See the README file in this directory for more info. ++# ++# Note! Dependencies are done automagically by 'make dep', which also ++# removes any old dependencies. DON'T put your own dependencies here ++# unless it's something special (ie not a .c file). ++# ++# Note 2! The CFLAGS definitions are now inherited from the ++# parent makes.. ++# ++ ++# To compile in lots (~20 KiB) of run-time enablable printk()s for debugging: ++#EXTRA_CFLAGS += -DMW_TRACE ++ ++# To have the mwave driver disable other uarts if necessary ++# EXTRA_CFLAGS += -DMWAVE_FUTZ_WITH_OTHER_DEVICES ++ ++O_TARGET := noz.o ++ ++obj-y := nozomi.o kfifo.o ++obj-m := $(O_TARGET) ++ ++include $(TOPDIR)/Rules.make +diff -uNr linux-org/drivers/char/nozomi/README linux/drivers/char/nozomi/README +--- linux-org/drivers/char/nozomi/README 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/README 2006-02-06 15:30:07.380952352 +0100 +@@ -0,0 +1,17 @@ ++To build this driver for your kernel, please check: ++ ++For kernel 2.6 ++--------------- ++Check the Makefile and run 'make'. ++ ++For kernel 2.4 ++---------- ++make HW=PC_24 ++ ++If you have troubles: ++1) Have proper kernel headers/source as your running kernel. ++2) Make sure this variable in Makefile is correct KERNELDIR = -I/path/to/kernel ++3) If the /dev/noz[0-3] will not be created automatically, do: ++mknod /dev/noz0 c 241 0; mknod /dev/noz1 c 241 1; ++mknod /dev/noz2 c 241 2; mknod /dev/noz3 c 241 3 ++ +diff -uNr linux-org/drivers/char/nozomi/TODO linux/drivers/char/nozomi/TODO +--- linux-org/drivers/char/nozomi/TODO 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/TODO 2006-02-06 15:30:07.361955240 +0100 +@@ -0,0 +1,6 @@ ++* When having a noz* open and rmmod module or removing card, ++ the driver core dumps. ++ ++* Does not yet support multiple cards. ++ ++* Add a helpful description. +diff -uNr linux-org/drivers/char/nozomi/kfifo.c linux/drivers/char/nozomi/kfifo.c +--- linux-org/drivers/char/nozomi/kfifo.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/kfifo.c 2006-02-06 15:30:07.361955240 +0100 +@@ -0,0 +1,189 @@ ++/* ++ * A simple kernel FIFO implementation. ++ * ++ * Copyright (C) 2004 Stelian Pop ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include "kfifo.h" ++ ++ ++/** ++ * kfifo_init - allocates a new FIFO using a preallocated buffer ++ * @buffer: the preallocated buffer to be used. ++ * @size: the size of the internal buffer, this have to be a power of 2. ++ * @gfp_mask: get_free_pages mask, passed to kmalloc() ++ * @lock: the lock to be used to protect the fifo buffer ++ * ++ * Do NOT pass the kfifo to kfifo_free() after use ! Simply free the ++ * struct kfifo with kfree(). ++ */ ++struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size, ++ unsigned int gfp_mask, void *lock) ++{ ++ struct kfifo *fifo; ++ ++ /* size must be a power of 2 */ ++ BUG_ON(size & (size - 1)); ++ ++ fifo = kmalloc(sizeof(struct kfifo), gfp_mask); ++ if (!fifo) ++ return ERR_PTR(-ENOMEM); ++ ++ fifo->buffer = buffer; ++ fifo->size = size; ++ fifo->in = fifo->out = 0; ++ ++ return fifo; ++} ++ ++/** ++ * kfifo_alloc - allocates a new FIFO and its internal buffer ++ * @size: the size of the internal buffer to be allocated. ++ * @gfp_mask: get_free_pages mask, passed to kmalloc() ++ * @lock: the lock to be used to protect the fifo buffer ++ * ++ * The size will be rounded-up to a power of 2. ++ */ ++struct kfifo *kfifo_alloc(unsigned int size, unsigned int gfp_mask, void *lock) ++{ ++ unsigned char *buffer; ++ struct kfifo *ret; ++ ++ /* ++ * round up to the next power of 2, since our 'let the indices ++ * wrap' tachnique works only in this case. ++ */ ++ if (size & (size - 1)) { ++ BUG_ON(size > 0x80000000); ++ printk("Do not support no power of two!\n"); ++ //size = roundup_pow_of_two(size); ++ } ++ ++ buffer = kmalloc(size, gfp_mask); ++ if (!buffer) ++ return ERR_PTR(-ENOMEM); ++ ++ ret = kfifo_init(buffer, size, gfp_mask, lock); ++ ++ if (IS_ERR(ret)) ++ kfree(buffer); ++ ++ return ret; ++} ++ ++/** ++ * kfifo_free - frees the FIFO ++ * @fifo: the fifo to be freed. ++ */ ++void kfifo_free(struct kfifo *fifo) ++{ ++ kfree(fifo->buffer); ++ kfree(fifo); ++} ++ ++/** ++ * __kfifo_put - puts some data into the FIFO, no locking version ++ * @fifo: the fifo to be used. ++ * @buffer: the data to be added. ++ * @len: the length of the data to be added. ++ * ++ * This function copies at most 'len' bytes from the 'buffer' into ++ * the FIFO depending on the free space, and returns the number of ++ * bytes copied. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these functions. ++ */ ++unsigned int __kfifo_put(struct kfifo *fifo, ++ unsigned char *buffer, unsigned int len) ++{ ++ unsigned int l; ++ ++ len = min(len, fifo->size - fifo->in + fifo->out); ++ ++ /* first put the data starting from fifo->in to buffer end */ ++ l = min(len, fifo->size - (fifo->in & (fifo->size - 1))); ++ memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l); ++ ++ /* then put the rest (if any) at the beginning of the buffer */ ++ memcpy(fifo->buffer, buffer + l, len - l); ++ ++ fifo->in += len; ++ ++ return len; ++} ++ ++/** __kfifio_put_user works like __kfifo_put, but copies data from ++ * user space. ++ */ ++ ++unsigned int __kfifo_put_user(struct kfifo *fifo, ++ unsigned char *buffer, unsigned int len) ++{ ++ unsigned int l; ++ ++ len = min(len, fifo->size - fifo->in + fifo->out); ++ ++ /* first put the data starting from fifo->in to buffer end */ ++ l = min(len, fifo->size - (fifo->in & (fifo->size - 1))); ++ copy_from_user(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l); ++ ++ /* then put the rest (if any) at the beginning of the buffer */ ++ copy_from_user(fifo->buffer, buffer + l, len - l); ++ ++ fifo->in += len; ++ ++ return len; ++} ++ ++ ++ ++/** ++ * __kfifo_get - gets some data from the FIFO, no locking version ++ * @fifo: the fifo to be used. ++ * @buffer: where the data must be copied. ++ * @len: the size of the destination buffer. ++ * ++ * This function copies at most 'len' bytes from the FIFO into the ++ * 'buffer' and returns the number of copied bytes. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these functions. ++ */ ++unsigned int __kfifo_get(struct kfifo *fifo, ++ unsigned char *buffer, unsigned int len) ++{ ++ unsigned int l; ++ ++ len = min(len, fifo->in - fifo->out); ++ ++ /* first get the data from fifo->out until the end of the buffer */ ++ l = min(len, fifo->size - (fifo->out & (fifo->size - 1))); ++ memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l); ++ ++ /* then get the rest (if any) from the beginning of the buffer */ ++ memcpy(buffer + l, fifo->buffer, len - l); ++ ++ fifo->out += len; ++ ++ return len; ++} +diff -uNr linux-org/drivers/char/nozomi/kfifo.h linux/drivers/char/nozomi/kfifo.h +--- linux-org/drivers/char/nozomi/kfifo.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/kfifo.h 2006-02-06 15:30:07.361955240 +0100 +@@ -0,0 +1,67 @@ ++/* ++ * A simple kernel FIFO implementation. ++ * ++ * Copyright (C) 2004 Stelian Pop ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++#ifndef _LINUX_KFIFO_H ++#define _LINUX_KFIFO_H ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++#warning "Don't include this header in 2.6, use header supplied with kernel" ++#endif ++ ++struct kfifo { ++ unsigned char *buffer; /* the buffer holding the data */ ++ unsigned int size; /* the size of the allocated buffer */ ++ unsigned int in; /* data is added at offset (in % size) */ ++ unsigned int out; /* data is extracted from off. (out % size) */ ++}; ++ ++extern struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size, unsigned int gfp_mask, void *lock); ++extern struct kfifo *kfifo_alloc(unsigned int size, unsigned int gfp_mask, void *lock); ++extern void kfifo_free(struct kfifo *fifo); ++extern unsigned int __kfifo_put(struct kfifo *fifo, unsigned char *buffer, unsigned int len); ++extern unsigned int __kfifo_put_user(struct kfifo *fifo, unsigned char *buffer, unsigned int len); ++extern unsigned int __kfifo_get(struct kfifo *fifo, unsigned char *buffer, unsigned int len); ++ ++/** ++ * __kfifo_reset - removes the entire FIFO contents, no locking version ++ * @fifo: the fifo to be emptied. ++ */ ++static inline void __kfifo_reset(struct kfifo *fifo) ++{ ++ fifo->in = fifo->out = 0; ++} ++ ++/** ++ * __kfifo_len - returns the number of bytes available in the FIFO, no locking version ++ * @fifo: the fifo to be used. ++ */ ++static inline unsigned int __kfifo_len(struct kfifo *fifo) ++{ ++ return fifo->in - fifo->out; ++} ++ ++#else ++#warning "don't include kernel headers in userspace" ++#endif /* __KERNEL__ */ ++#endif +diff -uNr linux-org/drivers/char/nozomi/nozomi.c linux/drivers/char/nozomi/nozomi.c +--- linux-org/drivers/char/nozomi/nozomi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/nozomi.c 2006-02-06 15:30:07.379952504 +0100 +@@ -0,0 +1,2238 @@ ++ ++/* nozomi.c -- HSDPA driver Broadband Wireless Data Card - Globe Trotter ++ * ++ * Written by: Ulf Jakobsson, ++ * Jan Åkerfeldt, ++ * Stefan Thomasson, ++ * ++ * Maintained by: Paul Hardwick, p.hardwick@option.com ++ * ++ * Source has been ported from an implementation made by Filip Aben, f.aben@option.com ++ * ++ * -------------------------------------------------------------------------- ++ ++ Copyright (c) 2005 Option Wireless Sweden AB ++ All rights Reserved. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ ++ * -------------------------------------------------------------------------- ++ */ ++ ++/* CHANGELOG ++ * ++ * See CHANGELOG in this package ++ */ ++ ++/* TODO ++ * ++ * See TODO file in this package ++ */ ++ ++ ++/* ++ * TODO2 fix the send_reset_token() routine not to use the fixed start address ++ */ ++ ++ ++ ++#include ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++#define KERNEL_2_6 ++#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0) ++#define KERNEL_2_4 ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define VERSION_STRING DRIVER_DESC " (build date: " __DATE__ " " __TIME__ ")" ++ ++#ifdef KERNEL_2_6 ++#include ++#else ++#include "kfifo.h" ++#endif ++ ++#ifdef KERNEL_2_4 ++#ifndef IRQ_NONE ++#define IRQ_NONE ++#endif ++#ifndef IRQ_HANDLED ++#define IRQ_HANDLED ++typedef void irqreturn_t; ++#endif ++#endif ++ ++#ifndef CONFIG_PCI ++#error "This driver needs PCI support to be available" ++#endif ++ ++/* Macros definitions */ ++ ++/* Enable this to have a lot of debug printouts */ ++/*#define NOZOMI_DEBUG */ ++ ++/* Default debug printout level */ ++#define NOZOMI_DEBUG_LEVEL 0xffff ++ ++#define P_BUF_SIZE 128 ++#define NFO( _err_flag_, args...) \ ++ do{ \ ++ char t_m_p_[P_BUF_SIZE]; \ ++ snprintf(t_m_p_, sizeof(t_m_p_), ##args); \ ++ printk( _err_flag_ "[%d] %s(): %s\n", __LINE__, __FUNCTION__, t_m_p_); \ ++} while(0) ++ ++#define INFO(args...) NFO(KERN_INFO, ##args) ++#define ERR(args...) NFO( KERN_ERR, ##args) ++ ++#define D1(args...) D_(0x01, ##args) ++#define D2(args...) D_(0x02, ##args) ++#define D3(args...) D_(0x04, ##args) ++#define D4(args...) D_(0x08, ##args) ++#define D5(args...) D_(0x10, ##args) ++#define D6(args...) D_(0x20, ##args) ++#define D7(args...) D_(0x40, ##args) ++#define D8(args...) D_(0x80, ##args) ++ ++ ++#ifdef NOZOMI_DEBUG ++#define D_(lvl, args...) D(lvl, ##args) ++ /* Do we need this settable at runtime? */ ++static int nzdebug = NOZOMI_DEBUG_LEVEL; ++ ++#define D(lvl, args...) do{if(lvl & nzdebug) NFO(KERN_INFO, ##args );}while(0) ++#define D_(lvl, args...) D(lvl, ##args) ++ ++/* These printouts are always printed */ ++ ++#else ++ static const int nzdebug = 0; ++#define D_(lvl, args...) ++#endif ++ ++/* TODO: rewrite to optimize macros... */ ++#define SET_FCR(value__) \ ++ do { \ ++ writew((value__), (void*) (dc->REG_FCR )); \ ++} while(0) ++ ++#define SET_IER(value__, mask__) \ ++ do { \ ++ dc->ier_last_written = (dc->ier_last_written & ~mask__) | (value__ & mask__ );\ ++ writew( dc->ier_last_written, (void*) (dc->REG_IER));\ ++} while(0) ++ ++#define GET_IER(read_val__) \ ++ do { \ ++ (read_val__) = readw((void*) (dc->REG_IER));\ ++} while(0) ++ ++#define GET_IIR(read_val__) \ ++ do { \ ++ (read_val__) = readw((void*) (dc->REG_IIR));\ ++} while(0) ++ ++#define GET_MEM(value__, addr__, length__) \ ++ do { \ ++ read_mem32( (u32*) (value__), (u32) (addr__), (length__));\ ++} while(0) ++ ++#define GET_MEM_BUF(value__, addr__, length__) \ ++ do { \ ++ read_mem32_buf( (u32*) (value__), (u32) (addr__), (length__));\ ++} while(0) ++ ++#define SET_MEM(addr__, value__, length__) \ ++ do { \ ++ write_mem32( (addr__), (u32*) (value__), (length__));\ ++} while(0) ++ ++#define SET_MEM_BUF(addr__, value__, length__) \ ++ do { \ ++ write_mem32_buf( (addr__), (u32*) (value__), (length__));\ ++} while(0) ++ ++ ++#define TMP_BUF_MAX 256 ++ ++#define DUMP(buf__,len__) \ ++ do { \ ++ char tbuf[TMP_BUF_MAX]={0};\ ++ if (len__>1) {\ ++ snprintf(tbuf, len__ > TMP_BUF_MAX ? TMP_BUF_MAX : len__, "%s",buf__);\ ++ if(tbuf[len__-2] == '\r') {\ ++ tbuf[len__-2] = 'r';\ ++ }\ ++ D1( "SENDING: '%s' (%d+n)", tbuf, len__);\ ++ } else {\ ++ D1( "SENDING: '%s' (%d)", tbuf, len__);\ ++ }\ ++} while(0) ++ ++#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) ++ ++ ++/* Defines */ ++#define NOZOMI_NAME "nozomi" ++#define NOZOMI_NAME_TTY "nozomi_tty" ++#define DRIVER_DESC "Nozomi driver" ++ ++#define NTTY_TTY_MAJOR 241 ++#define NTTY_TTY_MINORS MAX_PORT ++#define NTTY_FIFO_BUFFER_SIZE 8192 ++ ++/* Must be power of 2 */ ++#define FIFO_BUFFER_SIZE_UL 8192 ++ ++/* Size of tmp send buffer to card */ ++#define SEND_BUF_MAX 1024 ++#define RECEIVE_BUF_MAX 4 ++ ++/* Our fake UART values */ ++#define MCR_DTR 0x01 ++#define MCR_RTS 0x02 ++#define MCR_LOOP 0x04 ++#define MSR_CTS 0x08 ++#define MSR_CD 0x10 ++#define MSR_RI 0x20 ++#define MSR_DSR 0x40 ++ ++/* Define all types of vendors and devices to support */ ++#define VENDOR1 0x1931 /* Vendor Option */ ++#define DEVICE1 0x000c /* HSDPA card */ ++ ++#define R_IIR 0x0000 /* Interrupt Identity Register */ ++#define R_FCR 0x0000 /* Flow Control Register */ ++#define R_IER 0x0004 /* Interrupt Enable Register */ ++ ++#define CONFIG_MAGIC 0xEFEFFEFE ++#define TOGGLE_VALID 0x0000 ++ ++/* Definition of interrupt tokens */ ++#define MDM_DL1 0x0001 ++#define MDM_UL1 0x0002 ++#define MDM_DL2 0x0004 ++#define MDM_UL2 0x0008 ++#define DIAG_DL1 0x0010 ++#define DIAG_DL2 0x0020 ++#define DIAG_UL 0x0040 ++#define APP1_DL 0x0080 ++#define APP1_UL 0x0100 ++#define APP2_DL 0x0200 ++#define APP2_UL 0x0400 ++#define CTRL_DL 0x0800 ++#define CTRL_UL 0x1000 ++#define RESET 0x8000 ++ ++#define MDM_DL (MDM_DL1 | MDM_DL2) ++#define MDM_UL (MDM_UL1 | MDM_UL2) ++#define DIAG_DL (DIAG_DL1 | DIAG_DL2) ++ ++/* modem signal definition */ ++#define CTRL_DSR 0x0001 ++#define CTRL_DCD 0x0002 ++#define CTRL_RI 0x0004 ++#define CTRL_CTS 0x0008 ++ ++#define CTRL_DTR 0x0001 ++#define CTRL_RTS 0x0002 ++ ++#define MAX_PORT 4 ++#define NOZOMI_MAX_PORTS 5 ++ ++/* Type definitions */ ++ ++/* There are two types of nozomi cards, one with 2048 memory and with 8192 memory */ ++typedef enum { ++ F32_2 = 2048, /* Has 512 bytes downlink and uplink * 2 -> 2048 */ ++ F32_8 = 9192, /* Has 3072 bytes downlink and 1024 bytes uplink * 2 -> 8192 */ ++} card_type_t; ++ ++/* Two different toggle channels exist */ ++typedef enum { ++ CH_A=0, ++ CH_B=1, ++} channel_t; ++ ++/* Port definition for the card regarding flow control */ ++typedef enum { ++ CTRL_CMD = 0x00, ++ CTRL_MDM = 0x01, ++ CTRL_DIAG = 0x02, ++ CTRL_APP1 = 0x03, ++ CTRL_APP2 = 0x04, ++ CTRL_ERROR = -1, ++} ctrl_port_t; ++ ++/* Ports that the nozomi has */ ++typedef enum { ++ PORT_MDM = 0, ++ PORT_DIAG= 1, ++ PORT_APP1= 2, ++ PORT_APP2= 3, ++ PORT_CTRL= 4, ++ PORT_ERROR=-1, ++} port_type_t; ++ ++#ifdef __ARMEB__ ++/* Big endian */ ++ ++typedef struct { ++ unsigned enabled : 5; /* Toggle fields are valid if enabled is 0, else A-channels ++ must always be used. */ ++ unsigned diag_dl : 1; ++ unsigned mdm_dl : 1; ++ unsigned mdm_ul : 1; ++} __attribute__ ((packed)) toggles_t; ++ ++/* Configuration table to read at startup of card */ ++/* Is for now only needed during initialization phase */ ++typedef struct { ++ u32 signature; ++ u16 product_information; ++ u16 version; ++ u8 pad3[3]; ++ toggles_t toggle; ++ u8 pad1[4]; ++ u16 dl_mdm_len1; /* If this is 64, it can hold 60 bytes + 4 that is length field */ ++ u16 dl_start; ++ ++ u16 dl_diag_len1; ++ u16 dl_mdm_len2; /* If this is 64, it can hold 60 bytes + 4 that is length field */ ++ u16 dl_app1_len; ++ ++ u16 dl_diag_len2; ++ u16 dl_ctrl_len; ++ u16 dl_app2_len; ++ u8 pad2[16]; ++ u16 ul_mdm_len1; ++ u16 ul_start; ++ u16 ul_diag_len; ++ u16 ul_mdm_len2; ++ u16 ul_app1_len; ++ u16 ul_app2_len; ++ u16 ul_ctrl_len; ++} __attribute__((packed)) config_table_t; ++ ++/* This stores all control downlink flags */ ++typedef struct { ++ u8 port; ++ unsigned reserved : 4; ++ unsigned CTS : 1; ++ unsigned RI : 1; ++ unsigned DCD : 1; ++ unsigned DSR : 1; ++} __attribute__ ((packed)) ctrl_dl_t; ++ ++/* This stores all control uplink flags */ ++typedef struct { ++ u8 port; ++ unsigned reserved : 6; ++ unsigned RTS : 1; ++ unsigned DTR : 1; ++} __attribute__ ((packed)) ctrl_ul_t; ++ ++#else ++/* Little endian */ ++ ++/* This represents the toggle information */ ++typedef struct { ++ unsigned mdm_ul : 1; ++ unsigned mdm_dl : 1; ++ unsigned diag_dl : 1; ++ unsigned enabled : 5; /* Toggle fields are valid if enabled is 0, else A-channels ++ must always be used. */ ++} __attribute__ ((packed)) toggles_t; ++ ++/* Configuration table to read at startup of card */ ++typedef struct { ++ u32 signature; ++ u16 version; ++ u16 product_information; ++ toggles_t toggle; ++ u8 pad1[7]; ++ u16 dl_start; ++ u16 dl_mdm_len1; /* If this is 64, it can hold 60 bytes + 4 that is length field */ ++ u16 dl_mdm_len2; ++ u16 dl_diag_len1; ++ u16 dl_diag_len2; ++ u16 dl_app1_len; ++ u16 dl_app2_len; ++ u16 dl_ctrl_len; ++ u8 pad2[16]; ++ u16 ul_start; ++ u16 ul_mdm_len2; ++ u16 ul_mdm_len1; ++ u16 ul_diag_len; ++ u16 ul_app1_len; ++ u16 ul_app2_len; ++ u16 ul_ctrl_len; ++} __attribute__((packed)) config_table_t; ++ ++/* This stores all control downlink flags */ ++typedef struct { ++ unsigned DSR : 1; ++ unsigned DCD : 1; ++ unsigned RI : 1; ++ unsigned CTS : 1; ++ unsigned reserverd : 4; ++ u8 port; ++} __attribute__ ((packed)) ctrl_dl_t; ++ ++/* This stores all control uplink flags */ ++typedef struct { ++ unsigned DTR : 1; ++ unsigned RTS : 1; ++ unsigned reserved : 6; ++ u8 port; ++} __attribute__ ((packed)) ctrl_ul_t; ++#endif ++ ++/* This holds all information that is needed regarding a port */ ++typedef struct { ++ u8 update_flow_control; ++ ctrl_ul_t ctrl_ul; ++ ctrl_dl_t ctrl_dl; ++ struct kfifo *fifo_ul; ++ u32 dl_addr[2]; ++ u32 dl_size[2]; ++ u8 toggle_dl; ++ u32 ul_addr[2]; ++ u32 ul_size[2]; ++ u8 toggle_ul; ++ u16 token_dl; ++ ++ struct tty_struct *tty; ++ int tty_open_count; ++ struct semaphore tty_sem; ++ wait_queue_head_t tty_wait; ++ struct async_icount tty_icount; ++ int tty_index; ++ u32 rx_data, tx_data; ++ u8 tty_dont_flip; ++ ++} port_t; ++ ++/* Private data one for each card in the system */ ++typedef struct { ++ u32 base_addr; ++ u8 closing; ++ ++ /* Register addresses */ ++ u32 REG_IIR; ++ u32 REG_FCR; ++ u32 REG_IER; ++ ++ volatile u16 ier_last_written; ++ card_type_t card_type; ++ config_table_t config_table; /* Configuration table */ ++ struct pci_dev *pdev; ++ port_t port[NOZOMI_MAX_PORTS]; ++ u8 *send_buf; ++ ++ struct tty_driver tty_driver; ++ ++#ifdef KERNEL_2_4 ++ struct tty_struct *tty_table[NTTY_TTY_MINORS]; ++ struct tq_struct tty_flip_queue; ++ s32 tty_refcount; ++#endif ++#ifdef KERNEL_2_6 ++ struct workqueue_struct *tty_flip_wq; ++ struct work_struct tty_flip_wq_struct; ++#endif ++ ++ struct termios *tty_termios[NTTY_TTY_MINORS]; ++ struct termios *tty_termios_locked[NTTY_TTY_MINORS]; ++ spinlock_t spin_mutex; ++ ++ u32 open_ttys; ++ struct proc_dir_entry *proc_entry; ++ ++} dc_t; ++ ++/* This is a data packet that is read or written to/from card */ ++typedef struct { ++ u32 size; /* size is the length of the data buffer */ ++ u8 *data; ++} __attribute__ ((packed)) buf_t; ++ ++/* Function declarations */ ++static int ntty_tty_init(dc_t *dc); ++ ++static void tty_flip_queue_function(void *tmp_dc); ++ ++/* Global variables */ ++static struct pci_device_id nozomi_pci_tbl[] __devinitdata = { ++ {VENDOR1, DEVICE1}, ++ {0, } ++}; ++ ++/* Used to store interrupt variables */ ++typedef struct { ++ volatile u16 read_iir; /* Holds current interrupt tokens */ ++} irq_t; ++ ++MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl); ++ ++/* Representing the pci device of interest */ ++static int cards_found = 0; ++static int cards_initialized = 0; ++dc_t* my_dev = NULL; ++struct pci_dev *my_pdev = NULL; ++irq_t my_irq; ++ ++#define CARD_CHECK(rval) { \ ++ if (cards_found == 0 || cards_found != cards_initialized) { \ ++ ERR("Operation requested on uninitialized nozomi card."); \ ++ return rval; \ ++ } } ++ ++ ++static inline dc_t* get_dc_by_pdev(struct pci_dev* pdev) { ++ return my_dev; ++} ++ ++static inline dc_t* get_dc_by_index(s32 index ) { ++ return my_dev; ++} ++ ++static inline s32 get_index(struct tty_struct *tty) { ++#ifdef KERNEL_2_6 ++ return tty->index; ++#else ++ return MINOR(tty->device) - tty->driver.minor_start; ++#endif ++} ++ ++static inline port_t* get_port_by_tty(struct tty_struct *tty) { ++ return &my_dev->port[ get_index(tty) ]; ++} ++ ++static inline dc_t* get_dc_by_tty(struct tty_struct *tty ) { ++ return my_dev; ++} ++ ++ ++/* TODO: */ ++/* -Optimize */ ++/* -Rewrite cleaner */ ++static void read_mem32(u32 *buf, u32 mem_addr_start, u32 size_bytes) { ++ u32 i = 0; ++ u32* ptr = (u32*) mem_addr_start; ++ u16* buf16; ++ ++ /* 2 bytes */ ++ if (size_bytes == 2) { ++ buf16 = (u16*) buf; ++ *buf16 = readw( ptr ); ++ return; ++ } ++ ++ while (i < size_bytes) { ++ if ( size_bytes - i == 2) { ++ /* Handle 2 bytes in the end */ ++ buf16 = (u16*) buf; ++ *(buf16) = readw( ptr ); ++ i+=2; ++ } else { ++ /* Read 4 bytes */ ++ *(buf) = readl( ptr ); ++ i+=4; ++ } ++ buf++; ptr++; ++ } ++} ++ ++/* TODO: */ ++/* - Rewrite cleaner */ ++/* - merge with read_mem32() */ ++static void read_mem32_buf(u32 *buf, u32 mem_addr_start, u32 size_bytes) { ++#ifdef __ARMEB__ ++ u32 i = 0; ++ u32* ptr = (u32*) mem_addr_start; ++ u16* buf16; ++ ++ /* 2 bytes */ ++ if (size_bytes == 2) { ++ buf16 = (u16*) buf; ++ *buf16 = __le16_to_cpu( readw( ptr )); ++ return; ++ } ++ ++ while (i < size_bytes) { ++ if ( size_bytes - i == 2) { ++ /* Handle 2 bytes in the end */ ++ buf16 = (u16*) buf; ++ *(buf16) = __le16_to_cpu( readw( ptr )); ++ i+=2; ++ } else { ++ /* Read 4 bytes */ ++ *(buf) = __le32_to_cpu( readl( ptr )); ++ i+=4; ++ } ++ buf++; ptr++; ++ } ++#else ++ read_mem32(buf, mem_addr_start, size_bytes); ++#endif ++} ++ ++/* TODO: */ ++/* -Optimize */ ++/* -Rewrite cleaner */ ++static u32 write_mem32(u32 mem_addr_start, u32 *buf, u32 size_bytes) { ++ u32 i = 0; ++ u32* ptr = (u32*) mem_addr_start; ++ u16* buf16; ++ ++ /* 2 bytes */ ++ if (size_bytes == 2) { ++ buf16 = (u16*) buf; ++ writew( *buf16, ptr); ++ return 2; ++ } ++ ++ while (i < size_bytes) { ++ if ( size_bytes - i == 2) { ++ /* 2 bytes */ ++ buf16 = (u16*) buf; ++ writew( *buf16, ptr); ++ i+=2; ++ } else { ++ /* 4 bytes */ ++ writel( *buf, ptr ); ++ i += 4; ++ } ++ buf++; ptr++; ++ } ++ return size_bytes; ++} ++ ++/* Todo: */ ++/* - Merge with write_mem32() */ ++static u32 write_mem32_buf(u32 mem_addr_start, u32 *buf, u32 size_bytes) { ++#ifdef __ARMEB__ ++ u32 i = 0; ++ u32* ptr = (u32*) mem_addr_start; ++ u16* buf16; ++ ++ /* 2 bytes */ ++ if (size_bytes == 2) { ++ buf16 = (u16*) buf; ++ writew( __le16_to_cpu(*buf16), ptr); ++ return 2; ++ } ++ ++ while (i < size_bytes) { ++ if ( size_bytes - i == 2) { ++ /* 2 bytes */ ++ buf16 = (u16*) buf; ++ writew( __le16_to_cpu(*buf16), ptr); ++ i+=2; ++ } else { ++ /* 4 bytes */ ++ writel( __cpu_to_le32( *buf ), ptr ); ++ i += 4; ++ } ++ buf++; ptr++; ++ } ++ return size_bytes; ++#else ++ return write_mem32(mem_addr_start, buf, size_bytes); ++#endif ++} ++ ++/* Setup pointers to different channels and also setup buffer sizes. */ ++static void setup_memory(dc_t *dc) { ++ ++ u32 offset = dc->base_addr + dc->config_table.dl_start; ++ /* The length reported is including the length field of 4 bytes, hence subtract with 4. */ ++ u16 buff_offset = 4; ++ ++ /* Modem port dl configuration */ ++ dc->port[PORT_MDM].dl_addr[CH_A] = offset; ++ dc->port[PORT_MDM].dl_addr[CH_B] = (offset += dc->config_table.dl_mdm_len1); ++ dc->port[PORT_MDM].dl_size[CH_A] = dc->config_table.dl_mdm_len1 - buff_offset; ++ dc->port[PORT_MDM].dl_size[CH_B] = dc->config_table.dl_mdm_len2 - buff_offset; ++ ++ /* Diag port dl configuration */ ++ dc->port[PORT_DIAG].dl_addr[CH_A] = (offset += dc->config_table.dl_mdm_len2); ++ dc->port[PORT_DIAG].dl_size[CH_A] = dc->config_table.dl_diag_len1 - buff_offset; ++ dc->port[PORT_DIAG].dl_addr[CH_B] = (offset += dc->config_table.dl_diag_len1); ++ dc->port[PORT_DIAG].dl_size[CH_B] = dc->config_table.dl_diag_len2 - buff_offset; ++ ++ /* App1 port dl configuration */ ++ dc->port[PORT_APP1].dl_addr[CH_A] = (offset += dc->config_table.dl_diag_len2); ++ dc->port[PORT_APP1].dl_size[CH_A] = dc->config_table.dl_app1_len - buff_offset; ++ ++ /* App2 port dl configuration */ ++ dc->port[PORT_APP2].dl_addr[CH_A] = (offset += dc->config_table.dl_app1_len); ++ dc->port[PORT_APP2].dl_size[CH_A] = dc->config_table.dl_app2_len - buff_offset; ++ ++ /* Ctrl dl configuration */ ++ dc->port[PORT_CTRL].dl_addr[CH_A] = (offset += dc->config_table.dl_app2_len); ++ dc->port[PORT_CTRL].dl_size[CH_A] = dc->config_table.dl_ctrl_len - buff_offset; ++ ++ ++ /* Modem Port ul configuration */ ++ dc->port[PORT_MDM].ul_addr[CH_A] = (offset = dc->base_addr + dc->config_table.ul_start); ++ dc->port[PORT_MDM].ul_size[CH_A] = dc->config_table.ul_mdm_len1 - buff_offset; ++ dc->port[PORT_MDM].ul_addr[CH_B] = (offset += dc->config_table.ul_mdm_len1); ++ dc->port[PORT_MDM].ul_size[CH_B] = dc->config_table.ul_mdm_len2 - buff_offset; ++ ++ /* Diag port ul configuration */ ++ dc->port[PORT_DIAG].ul_addr[CH_A] = (offset += dc->config_table.ul_mdm_len2); ++ dc->port[PORT_DIAG].ul_size[CH_A] = dc->config_table.ul_diag_len - buff_offset; ++ ++ /* App1 port ul configuration */ ++ dc->port[PORT_APP1].ul_addr[CH_A] = (offset += dc->config_table.ul_diag_len); ++ dc->port[PORT_APP1].ul_size[CH_A] = dc->config_table.ul_app1_len - buff_offset; ++ ++ /* App2 port ul configuration */ ++ dc->port[PORT_APP2].ul_addr[CH_A] = (offset += dc->config_table.ul_app1_len); ++ dc->port[PORT_APP2].ul_size[CH_A] = dc->config_table.ul_app2_len - buff_offset; ++ ++ /* Ctrl ul configuration */ ++ dc->port[PORT_CTRL].ul_addr[CH_A] = (offset += dc->config_table.ul_app2_len); ++ dc->port[PORT_CTRL].ul_size[CH_A] = dc->config_table.ul_ctrl_len - buff_offset; ++ offset = dc->config_table.ul_start; ++} ++ ++/* Dump config table under initalization phase */ ++#ifdef NOZOMI_DEBUG ++static void dump_table(dc_t *dc) { ++ D3("signature: 0x%08X", dc->config_table.signature); ++ D3("version: 0x%04X", dc->config_table.version); ++ D3("product_information: 0x%04X", dc->config_table.product_information); ++ D3("toggle enabled: %d", dc->config_table.toggle.enabled); ++ D3("toggle up_mdm: %d", dc->config_table.toggle.mdm_ul); ++ D3("toggle dl_mdm: %d", dc->config_table.toggle.mdm_dl); ++ D3("toggle dl_dbg: %d", dc->config_table.toggle.diag_dl); ++ ++ D3("dl_start: 0x%04X", dc->config_table.dl_start); ++ D3("dl_mdm_len0: 0x%04X, %d", dc->config_table.dl_mdm_len1, dc->config_table.dl_mdm_len1); ++ D3("dl_mdm_len1: 0x%04X, %d", dc->config_table.dl_mdm_len2, dc->config_table.dl_mdm_len2); ++ D3("dl_diag_len0: 0x%04X, %d", dc->config_table.dl_diag_len1, dc->config_table.dl_diag_len1); ++ D3("dl_diag_len1: 0x%04X, %d", dc->config_table.dl_diag_len2, dc->config_table.dl_diag_len2); ++ D3("dl_app1_len: 0x%04X, %d", dc->config_table.dl_app1_len, dc->config_table.dl_app1_len); ++ D3("dl_app2_len: 0x%04X, %d", dc->config_table.dl_app2_len, dc->config_table.dl_app2_len); ++ D3("dl_ctrl_len: 0x%04X, %d", dc->config_table.dl_ctrl_len, dc->config_table.dl_ctrl_len); ++ D3("ul_start: 0x%04X, %d", dc->config_table.ul_start, dc->config_table.ul_start); ++ D3("ul_mdm_len[0]: 0x%04X, %d", dc->config_table.ul_mdm_len1, dc->config_table.ul_mdm_len1); ++ D3("ul_mdm_len[1]: 0x%04X, %d", dc->config_table.ul_mdm_len2, dc->config_table.ul_mdm_len2); ++ D3("ul_diag_len: 0x%04X, %d", dc->config_table.ul_diag_len, dc->config_table.ul_diag_len); ++ D3("ul_app1_len: 0x%04X, %d", dc->config_table.ul_app1_len, dc->config_table.ul_app1_len); ++ D3("ul_app2_len: 0x%04X, %d", dc->config_table.ul_app2_len, dc->config_table.ul_app2_len); ++ D3("ul_ctrl_len: 0x%04X, %d", dc->config_table.ul_ctrl_len, dc->config_table.ul_ctrl_len); ++} ++#endif ++ ++/* Read configuration table from card under intalization phase */ ++/* Returns 1 if ok, else 0 */ ++static int nozomi_read_config_table(dc_t *dc) { ++ ++ if (cards_found > 0 && cards_found == cards_initialized) { ++ return 1; ++ } ++ ++ GET_MEM( &dc->config_table, dc->base_addr + 0, sizeof(config_table_t)); ++ ++ /* D1( "0x%08X == 0x%08X ", dc->config_table.signature, CONFIG_MAGIC); */ ++ ++ if( dc->config_table.signature != CONFIG_MAGIC ) { ++ ERR("ConfigTable Bad! 0x%08X != 0x%08X", dc->config_table.signature, CONFIG_MAGIC); ++ return 0; ++ } ++ ++ if( (dc->config_table.version == 0) || (dc->config_table.toggle.enabled == TOGGLE_VALID) ) { ++ int i; ++ INFO( "Second phase, configuring card"); ++ ++ setup_memory(dc); ++ ++ dc->port[PORT_MDM].toggle_ul = dc->config_table.toggle.mdm_ul; ++ dc->port[PORT_MDM].toggle_dl = dc->config_table.toggle.mdm_dl; ++ dc->port[PORT_DIAG].toggle_dl = dc->config_table.toggle.diag_dl; ++ D1( "toggle ports: MDM UL:%d MDM DL:%d, DIAG DL:%d", ++ dc->port[PORT_MDM].toggle_ul, ++ dc->port[PORT_MDM].toggle_dl, ++ dc->port[PORT_DIAG].toggle_dl); ++ ++#ifdef NOZOMI_DEBUG ++ dump_table(dc); ++#endif ++ for (i=PORT_MDM; i< MAX_PORT;i++) { ++ dc->port[i].fifo_ul = kfifo_alloc( FIFO_BUFFER_SIZE_UL, GFP_ATOMIC , NULL); ++ memset( &dc->port[i].ctrl_dl, 0, sizeof (ctrl_dl_t)); ++ memset( &dc->port[i].ctrl_ul, 0, sizeof (ctrl_ul_t)); ++ } ++ ++ /* Enable control channel */ ++ SET_IER( CTRL_DL, CTRL_DL ); ++ ++ INFO("Initialization OK!"); ++ cards_initialized++; ++ return 1; ++ } ++ ++ if( (dc->config_table.version > 0) && (dc->config_table.toggle.enabled != TOGGLE_VALID ) ) { ++ u32 offset = 0; ++ INFO( "First phase: pushing upload buffers, clearing download"); ++ ++ INFO("Version of card: %d", dc->config_table.version); ++ ++ /* Here we should disable all I/O over F32. */ ++ setup_memory(dc); ++ ++ /* We should send ALL channel pair tokens back along with reset token */ ++ ++ /* push upload modem buffers */ ++ SET_MEM( dc->port[PORT_MDM].ul_addr[CH_A], &offset, 4); ++ SET_MEM( dc->port[PORT_MDM].ul_addr[CH_B], &offset, 4); ++ ++ SET_FCR( MDM_UL | DIAG_DL | MDM_DL ); ++ ++ D1( "First phase done"); ++ } ++ ++ return 1; ++} ++ ++/* Enable uplink interrupts */ ++static void enable_transmit_ul( port_type_t port , dc_t *dc ) { ++ ++ switch( port ) { ++ case PORT_MDM: SET_IER( MDM_UL , MDM_UL ); break; ++ case PORT_DIAG: SET_IER( DIAG_UL, DIAG_UL ); break; ++ case PORT_APP1: SET_IER( APP1_UL, APP1_UL ); break; ++ case PORT_APP2: SET_IER( APP2_UL, APP2_UL ); break; ++ case PORT_CTRL: SET_IER( CTRL_UL, CTRL_UL ); break; ++ default: ++ ERR("Called with wrong port?"); ++ break; ++ }; ++} ++ ++/* Disable uplink interrupts */ ++static void disable_transmit_ul( port_type_t port , dc_t *dc ) { ++ ++ switch( port ) { ++ case PORT_MDM: SET_IER( 0 ,MDM_UL ); break; ++ case PORT_DIAG: SET_IER( 0, DIAG_UL ); break; ++ case PORT_APP1: SET_IER( 0, APP1_UL ); break; ++ case PORT_APP2: SET_IER( 0, APP2_UL ); break; ++ case PORT_CTRL: SET_IER( 0, CTRL_UL ); break; ++ default: ++ ERR("Called with wrong port?"); ++ break; ++ }; ++} ++ ++/* Enable downlink interrupts */ ++static void enable_transmit_dl( port_type_t port , dc_t *dc ) { ++ ++ switch( port ) { ++ case PORT_MDM: SET_IER( MDM_DL , MDM_DL ); break; ++ case PORT_DIAG: SET_IER( DIAG_DL, DIAG_DL ); break; ++ case PORT_APP1: SET_IER( APP1_DL, APP1_DL ); break; ++ case PORT_APP2: SET_IER( APP2_DL, APP2_DL ); break; ++ case PORT_CTRL: SET_IER( CTRL_DL, CTRL_DL ); break; ++ default: ++ ERR("Called with wrong port?"); ++ break; ++ }; ++} ++ ++/* Disable downlink interrupts */ ++static void disable_transmit_dl( port_type_t port , dc_t *dc ) { ++ ++ switch( port ) { ++ case PORT_MDM: SET_IER( 0 ,MDM_DL ); break; ++ case PORT_DIAG: SET_IER( 0, DIAG_DL ); break; ++ case PORT_APP1: SET_IER( 0, APP1_DL ); break; ++ case PORT_APP2: SET_IER( 0, APP2_DL ); break; ++ case PORT_CTRL: SET_IER( 0, CTRL_DL ); break; ++ default: ++ ERR("Called with wrong port?"); ++ break; ++ }; ++} ++ ++/* Return 1 - send buffer to card and ack. */ ++/* Return 0 - don't ack, don't send buffer to card. */ ++int send_data( port_type_t index, dc_t *dc ) { ++ u32 size = 0; ++ port_t *port = &dc->port[index]; ++ u8 toggle = port->toggle_ul; ++ u32 addr = port->ul_addr[toggle]; ++ u32 ul_size = port->ul_size[toggle]; ++ struct tty_struct *tty = port->tty; ++ ++ if (index >= NTTY_TTY_MINORS) { ++ ERR("Called with wrong index?"); ++ return 0; ++ } ++ ++ /* Get data from tty and place in buf for now */ ++ size = __kfifo_get( port->fifo_ul, dc->send_buf, ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX ); ++ ++ if (size == 0) { ++ D4("No more data to send, disable link:"); ++ return 0; ++ } ++ ++ port->tx_data += size; ++ ++ /* DUMP(buf, size); */ ++ ++ /* Write length + data */ ++ SET_MEM( addr, &size, 4 ); ++ SET_MEM_BUF( addr + 4, dc->send_buf, size); ++ ++ if (port->tty) { ++ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { ++ tty->ldisc.write_wakeup(tty); ++ } ++ wake_up_interruptible(&tty->write_wait); ++ } ++ ++ return 1; ++} ++ ++/* If all data has been read, return 1, else 0 */ ++static int receive_data( port_type_t index, dc_t* dc ) { ++ u8 buf[RECEIVE_BUF_MAX] = {0}; ++ int size; ++ u32 offset = 4; ++ port_t *port = &dc->port[index]; ++ u8 toggle = port->toggle_dl; ++ u32 addr = port->dl_addr[toggle]; ++ struct tty_struct *tty = port->tty; ++ int i; ++ ++ if ( !tty ) { ++ D1("tty not open for port: %d?", index); ++ return 1; ++ } ++ ++ if (test_bit(TTY_DONT_FLIP, &tty->flags)) { ++ D6("TTY_DONT_FLIP set!! %d", index); ++ /* Here we disable interrupt for that port and schedule */ ++/* task. Task wakes up a little bit later and enables interrupt.. */ ++ port->tty_dont_flip = 1; ++ disable_transmit_dl(index, dc); ++#ifdef KERNEL_2_4 ++ schedule_task(&dc->tty_flip_queue); ++#endif ++#ifdef KERNEL_2_6 ++ if (!queue_work(dc->tty_flip_wq, &dc->tty_flip_wq_struct)) { ++ ERR("Call to queue_work() failed."); ++ } ++#endif ++ return 0; ++ } ++ ++ GET_MEM( &size, addr, 4 ); ++ /* D1( "%d bytes port: %d", size, index); */ ++ ++ if ( test_bit( TTY_THROTTLED, & tty->flags) ) { ++ D1("No room in tty, don't read data, don't ack interrupt, disable interrupt"); ++ ++ /* disable interrupt in downlink... */ ++ disable_transmit_dl(index, dc); ++ return 0; ++ } ++ ++ if (size == 0) { ++ ERR("size == 0?"); ++ return 1; ++ } ++ ++ while( size > 0 ) { ++ GET_MEM_BUF(buf, addr + offset, 4); ++ ++ i = 0; ++ while (i < 4 && size > 0) { ++ if (tty->flip.count >= TTY_FLIPBUF_SIZE) { ++ tty_flip_buffer_push(tty); ++ } ++ tty_insert_flip_char(tty, buf[i], TTY_NORMAL); ++ port->rx_data++; ++ i++; ++ size--; ++ } ++ ++ offset += 4; ++ } ++ ++ tty_flip_buffer_push(tty); ++ ++ return 1; ++} ++ ++/* Debug for interrupts */ ++#ifdef NOZOMI_DEBUG ++static char* interrupt2str( u16 interrupt) { ++ static char buf[TMP_BUF_MAX]; ++ char *p = buf; ++ ++ interrupt & MDM_DL1 ? p += snprintf(p, TMP_BUF_MAX, "MDM_DL1 "):0; ++ interrupt & MDM_DL2 ? p += snprintf(p, TMP_BUF_MAX, "MDM_DL2 "):0; ++ ++ interrupt & MDM_UL1 ? p += snprintf(p, TMP_BUF_MAX, "MDM_UL1 "):0; ++ interrupt & MDM_UL2 ? p += snprintf(p, TMP_BUF_MAX, "MDM_UL2 "):0; ++ ++ interrupt & DIAG_DL1 ? p += snprintf(p, TMP_BUF_MAX, "DIAG_DL1 "):0; ++ interrupt & DIAG_DL2 ? p += snprintf(p, TMP_BUF_MAX, "DIAG_DL2 "):0; ++ ++ interrupt & DIAG_UL ? p += snprintf(p, TMP_BUF_MAX, "DIAG_UL "):0; ++ ++ interrupt & APP1_DL ? p += snprintf(p, TMP_BUF_MAX, "APP1_DL "):0; ++ interrupt & APP2_DL ? p += snprintf(p, TMP_BUF_MAX, "APP2_DL "):0; ++ ++ interrupt & APP1_UL ? p += snprintf(p, TMP_BUF_MAX, "APP1_UL "):0; ++ interrupt & APP2_UL ? p += snprintf(p, TMP_BUF_MAX, "APP2_UL "):0; ++ ++ interrupt & CTRL_DL ? p += snprintf(p, TMP_BUF_MAX, "CTRL_DL "):0; ++ interrupt & CTRL_UL ? p += snprintf(p, TMP_BUF_MAX, "CTRL_UL "):0; ++ ++ interrupt & RESET ? p += snprintf(p, TMP_BUF_MAX, "RESET "):0; ++ ++ return buf; ++} ++#endif ++ ++/* Receive flow control */ ++/* Return 1 - If ok, else 0 */ ++static int receive_flow_control( dc_t *dc, irq_t *m) { ++ port_type_t port = PORT_MDM; ++ ctrl_dl_t ctrl_dl; ++ ctrl_dl_t old_ctrl; ++ u16 enable_ier = 0; ++ ++ GET_MEM( &ctrl_dl, dc->port[PORT_CTRL].dl_addr[CH_A], 2); ++ ++ switch( ctrl_dl.port ) { ++ case CTRL_CMD: ++ D1( "The Base Band sends this value as a response to a request for IMSI detach sent" ++ " over the control channel uplink (see section 7.6.1)."); ++ break; ++ case CTRL_MDM: port = PORT_MDM; enable_ier = MDM_DL; break; ++ case CTRL_DIAG: port = PORT_DIAG; enable_ier = DIAG_DL; break; ++ case CTRL_APP1: port = PORT_APP1; enable_ier = APP1_DL; break; ++ case CTRL_APP2: port = PORT_APP2; enable_ier = APP2_DL; break; ++ default: ++ ERR("ERROR: flow control received for non-existing port"); ++ return 0; ++ }; ++ ++ D1( "0x%04X->0x%04X", *((u16*) &dc->port[port].ctrl_dl), *((u16*)&ctrl_dl)); ++ ++ old_ctrl = dc->port[port].ctrl_dl; ++ dc->port[port].ctrl_dl = ctrl_dl; ++ ++ if ( old_ctrl.CTS == 1 && ctrl_dl.CTS == 0 ) { ++ D1( "Disable interrupt (0x%04X) on port: %d", enable_ier, port); ++ disable_transmit_ul(port, dc); ++ ++ } else if ( old_ctrl.CTS == 0 && ctrl_dl.CTS == 1 ) { ++ ++ if ( __kfifo_len(dc->port[port].fifo_ul) ) { ++ D1( "Enable interrupt (0x%04X) on port: %d", enable_ier, port); ++ D1( "Data in buffer [%d], enable transmit! ", __kfifo_len(dc->port[port].fifo_ul) ); ++ enable_transmit_ul( port, dc ); ++ } else { ++ D1( "No data in buffer..."); ++ } ++ } ++ ++ if(*(u16*)&old_ctrl == *(u16*)&ctrl_dl) ++ { ++ D1( " No change in mctrl"); ++ return 1; ++ } ++ /* Update statistics */ ++ if(old_ctrl.CTS != ctrl_dl.CTS) { ++ dc->port[port].tty_icount.cts++; ++ } ++ if(old_ctrl.DSR != ctrl_dl.DSR) { ++ dc->port[port].tty_icount.dsr++; ++ } ++ if(old_ctrl.RI != ctrl_dl.RI) { ++ dc->port[port].tty_icount.rng++; ++ } ++ if(old_ctrl.DCD != ctrl_dl.DCD) { ++ dc->port[port].tty_icount.dcd++; ++ } ++ D1("port: %d DCD(%d), CTS(%d), RI(%d), DSR(%d)", ++ port, ++ dc->port[port].tty_icount.dcd, dc->port[port].tty_icount.cts, ++ dc->port[port].tty_icount.rng, dc->port[port].tty_icount.dsr); ++ ++ return 1; ++} ++ ++/* TODO: */ ++/* - return ctrl_port_t */ ++static u8 port2ctrl(port_type_t port) { ++ switch( port ) { ++ case PORT_MDM: ++ return CTRL_MDM; ++ case PORT_DIAG: ++ return CTRL_DIAG; ++ case PORT_APP1: ++ return CTRL_APP1; ++ case PORT_APP2: ++ return CTRL_APP2; ++ default: ++ ERR("ERROR: send flow control received for non-existing port"); ++ return -1; ++ }; ++ return -1; ++} ++ ++/* Send flow control, can only update one channel at a time */ ++/* Return 0 - If we have updated all flow control */ ++/* Return 1 - If we need to update more flow control, ack current enable more */ ++static int send_flow_control( dc_t *dc ) { ++ u32 i, more_flow_control_to_be_updated = 0; ++ u16* ctrl; ++ ++ for( i=PORT_MDM; iport[i].update_flow_control ) { ++ if ( more_flow_control_to_be_updated ) { ++ /* We have more flow control to be updated */ ++ return 1; ++ } ++ dc->port[i].ctrl_ul.port = port2ctrl(i); ++ ctrl = (u16*) &dc->port[i].ctrl_ul; ++ /* D1( "sending flow control 0x%04X for port %d, %d", (u16) *ctrl, i, dc->port[i].ctrl_ul.port ); */ ++ SET_MEM( dc->port[PORT_CTRL].ul_addr[0], (u32*) ctrl, 2 ); ++ dc->port[i].update_flow_control = 0; ++ more_flow_control_to_be_updated = 1; ++ } ++ } ++ return 0; ++} ++ ++/* Handle donlink data, ports that are handled are modem and diagnostics */ ++/* Return 1 - ok */ ++/* Return 0 - toggle fields are out of sync */ ++static int handle_data_dl(dc_t *dc, irq_t *m, port_type_t port, u8 *toggle, u16 mask1, u16 mask2) { ++ ++ if ( *toggle == 0 && m->read_iir & mask1 ) { ++ if (receive_data( port, dc )) { ++ SET_FCR( mask1 ); ++ *toggle = !(*toggle); ++ } ++ ++ if ( m->read_iir & mask2 ) { ++ if (receive_data( port, dc )) { ++ SET_FCR( mask2 ); ++ *toggle = !(*toggle); ++ } ++ } ++ } else if ( *toggle == 1 && m->read_iir & mask2 ) { ++ if (receive_data( port, dc )) { ++ SET_FCR( mask2 ); ++ *toggle = !(*toggle); ++ } ++ ++ if ( m->read_iir & mask1 ) { ++ if (receive_data( port, dc )) { ++ SET_FCR( mask1 ); ++ *toggle = !(*toggle); ++ } ++ } ++ } else { ++ ERR("port out of sync!, toggle:%d", *toggle); ++ return 0; ++ } ++ return 1; ++} ++ ++/* Handle uplink data, this is currently for the modem port */ ++/* Return 1 - ok */ ++/* Return 0 - toggle field are out of sync */ ++static int handle_data_ul(dc_t *dc, irq_t *m, port_type_t port) { ++ ++ u8 *toggle = &(dc->port[port].toggle_ul); ++ ++ if ( *toggle==0 && m->read_iir & MDM_UL1 ) { ++ SET_IER( 0, MDM_UL ); ++ if (send_data(port, dc)) { ++ SET_FCR( MDM_UL1 ); ++ SET_IER( MDM_UL, MDM_UL); ++ *toggle = !*toggle; ++ } ++ ++ if ( m->read_iir & MDM_UL2 ) { ++ SET_IER( 0, MDM_UL ); ++ if (send_data(port, dc)) { ++ SET_FCR( MDM_UL2 ); ++ SET_IER( MDM_UL, MDM_UL); ++ *toggle = !*toggle; ++ } ++ } ++ ++ } else if ( *toggle==1 && m->read_iir & MDM_UL2 ) { ++ SET_IER( 0, MDM_UL ); ++ if (send_data(port, dc)) { ++ SET_FCR( MDM_UL2 ); ++ SET_IER( MDM_UL, MDM_UL); ++ *toggle = !*toggle; ++ } ++ ++ if ( m->read_iir & MDM_UL1 ) { ++ SET_IER( 0, MDM_UL ); ++ if (send_data(port, dc)) { ++ SET_FCR( MDM_UL1 ); ++ SET_IER( MDM_UL, MDM_UL); ++ *toggle = !*toggle; ++ } ++ } ++ } else { ++ SET_FCR( m->read_iir & MDM_UL ); ++ ERR("port out of sync!"); ++ return 0; ++ } ++ return 1; ++} ++ ++static irqreturn_t interrupt_handler(int irq, void *dev_id, struct pt_regs *regs) { ++ dc_t *dc = NULL; ++ irq_t* m = &my_irq; ++ ++ if (my_dev && my_dev->pdev != dev_id) { ++ return IRQ_NONE; ++ } ++ ++ if ( !(dc = get_dc_by_pdev(dev_id)) ) { ++ ERR("Could not find device context from pci_dev: %d", (u32) dev_id); ++ return IRQ_NONE; ++ } ++ ++ GET_IIR( m->read_iir ); ++ ++ /* Just handle interrupt enabled in IER (by masking with dc->ier_last_written) */ ++ m->read_iir &= dc->ier_last_written; ++ ++ if (m->read_iir == 0) { ++ return IRQ_NONE; ++ } ++ ++ if (dc == NULL ) { ++ ERR("ERROR!!"); ++ return IRQ_NONE; ++ } ++ ++ spin_lock(&dc->spin_mutex); ++ ++ D4( "%s irq:0x%04X, prev:0x%04X", interrupt2str(m->read_iir), m->read_iir, dc->ier_last_written); ++ ++ if ( m->read_iir & RESET) { ++ if( !nozomi_read_config_table(dc) ) { ++ SET_IER( 0, 0xFFFF); ++ ERR("ERR: Could not read status from card, we should disable interface"); ++ } else { ++ SET_FCR( RESET ); ++ } ++ goto exit_handler; /* No more useful info if this was the reset interrupt. */ ++ } ++ if ( m->read_iir & CTRL_UL ) { ++ D1( "CTRL_UL"); ++ SET_IER( 0, CTRL_UL ); ++ if ( send_flow_control(dc) ) { ++ SET_FCR( CTRL_UL ); ++ SET_IER( CTRL_UL, CTRL_UL ); ++ } ++ } ++ if ( m->read_iir & CTRL_DL ) { ++ receive_flow_control(dc, m); ++ SET_FCR( CTRL_DL ); ++ } ++ if ( m->read_iir & MDM_DL ) { ++ if ( !(handle_data_dl(dc, m, PORT_MDM, &(dc->port[PORT_MDM].toggle_dl), MDM_DL1, MDM_DL2)) ) { ++ ERR("MDM_DL out of sync!"); ++ goto exit_handler; ++ } ++ } ++ if ( m->read_iir & MDM_UL ) { ++ if ( !handle_data_ul(dc, m, PORT_MDM ) ) { ++ ERR("MDM_UL out of sync!"); ++ goto exit_handler; ++ } ++ } ++ if ( m->read_iir & DIAG_DL ) { ++ if ( !(handle_data_dl(dc, m, PORT_DIAG, &(dc->port[PORT_DIAG].toggle_dl), DIAG_DL1, DIAG_DL2)) ) { ++ ERR("DIAG_DL out of sync!"); ++ goto exit_handler; ++ } ++ } ++ if ( m->read_iir & DIAG_UL ) { ++ SET_IER( 0, DIAG_UL ); ++ if( send_data( PORT_DIAG, dc ) ) { ++ SET_FCR( DIAG_UL ); ++ SET_IER( DIAG_UL, DIAG_UL ); ++ } ++ } ++ if ( m->read_iir & APP1_DL ) { ++ if (receive_data( PORT_APP1, dc ) ) { ++ SET_FCR( APP1_DL ); ++ } ++ } ++ if ( m->read_iir & APP1_UL ) { ++ SET_IER( 0, APP1_UL ); ++ if(send_data( PORT_APP1, dc )) { ++ SET_FCR( APP1_UL ); ++ SET_IER( APP1_UL, APP1_UL ); ++ } ++ } ++ if ( m->read_iir & APP2_DL ) { ++ if (receive_data( PORT_APP2, dc )) { ++ SET_FCR( APP2_DL ); ++ } ++ } ++ if ( m->read_iir & APP2_UL ) { ++ SET_IER( 0, APP2_UL ); ++ if(send_data( PORT_APP2, dc )) { ++ SET_FCR( APP2_UL ); ++ SET_IER( APP2_UL, APP2_UL ); ++ } ++ } ++ ++ exit_handler: ++ spin_unlock(&dc->spin_mutex); ++ return IRQ_HANDLED; ++} ++ ++/* Request a shared IRQ from system */ ++static int nozomi_setup_interrupt(struct pci_dev *pdev) { ++ ++ int rval = 0; ++ ++ if ( (rval = request_irq( pdev->irq, &interrupt_handler, SA_SHIRQ, NOZOMI_NAME, pdev )) ) { ++ ERR("Cannot open because IRQ %d is already in use.", pdev->irq ); ++ return rval; ++ } ++ ++ return rval; ++} ++ ++static void nozomi_get_card_type(dc_t *dc) { ++ u32 i, size=0; ++ for(i=0;i<6;i++) { ++ size += pci_resource_len(dc->pdev, i); ++ } ++ ++ /* Assume card type F32_8 if no match */ ++ dc->card_type = size == 2048 ? F32_2 : F32_8; ++ ++ INFO("Card type is: %d", dc->card_type ); ++} ++ ++void nozomi_setup_private_data(dc_t *dc) { ++ u32 offset = dc->base_addr + dc->card_type/2; ++ int i; ++ ++ dc->REG_FCR = offset + R_FCR; ++ dc->REG_IIR = offset + R_IIR; ++ dc->REG_IER = offset + R_IER; ++ dc->ier_last_written = 0; ++ dc->closing = 0; ++ ++ dc->port[PORT_MDM ].token_dl = MDM_DL; ++ dc->port[PORT_DIAG].token_dl = DIAG_DL; ++ dc->port[PORT_APP1].token_dl = APP1_DL; ++ dc->port[PORT_APP2].token_dl = APP2_DL; ++ ++ for(i=PORT_MDM;iport[i].rx_data = dc->port[i].tx_data = 0; ++ dc->port[i].tty_dont_flip = 0; ++ } ++} ++ ++ ++static void tty_flip_queue_function(void *tmp_dc) { ++ dc_t *dc = (dc_t*) tmp_dc; ++ int i; ++ ++ /* Enable interrupt for that port */ ++ for(i=0;iport[i].tty_dont_flip) { ++ D6("Enable for port: %d", i); ++ dc->port[i].tty_dont_flip = 0; ++ enable_transmit_dl(dc->port[i].tty_index, dc); ++ } ++ } ++} ++ ++static int read_proc_card_type(char *buf, char **start, off_t offset, int len) { ++ dc_t *dc = get_dc_by_index(0); ++ len = 0; ++ ++ len += sprintf(buf+len,"%d\n", dc->card_type); ++ return len; ++} ++ ++static int read_proc_open_ttys(char *buf, char **start, off_t offset, int len) { ++ dc_t *dc = get_dc_by_index(0); ++ len = 0; ++ ++ len += sprintf(buf+len,"%d\n", dc->open_ttys); ++ return len; ++} ++ ++static int read_proc_version(char *buf, char **start, off_t offset, int len) { ++ len = 0; ++ ++ len += sprintf(buf+len, "%s\n", VERSION_STRING); ++ return len; ++} ++ ++static int read_proc_rtx(char *buf, char **start, off_t offset, int len) { ++ dc_t *dc = get_dc_by_index(0); ++ int i; ++ ++ len = 0; ++ ++ ++ for(i=PORT_MDM;iport[i].rx_data, dc->port[i].tx_data); ++ } ++ return len; ++} ++ ++static void make_proc_dirs(void) { ++ dc_t *dc = get_dc_by_index(0); ++ ++ dc->proc_entry = proc_mkdir("nozomi", &proc_root); ++ ++ /* Register the read_proc */ ++ if ( !create_proc_info_entry("card_type",0,dc->proc_entry,read_proc_card_type) ) { ++ ERR("ERROR: failed to register read_procmem"); ++ } ++ if ( !create_proc_info_entry("open_ttys",0,dc->proc_entry,read_proc_open_ttys) ) { ++ ERR("ERROR: failed to register read_procmem"); ++ } ++ if ( !create_proc_info_entry("rtx",0,dc->proc_entry,read_proc_rtx) ) { ++ ERR("ERROR: failed to register read_procmem"); ++ } ++ if ( !create_proc_info_entry("version",0,dc->proc_entry,read_proc_version) ) { ++ ERR("ERROR: failed to register read_procmem"); ++ } ++} ++ ++static void remove_proc_dirs(void) { ++ dc_t *dc = get_dc_by_index(0); ++ ++ remove_proc_entry("card_type", dc->proc_entry); ++ remove_proc_entry("open_ttys", dc->proc_entry); ++ remove_proc_entry("rtx", dc->proc_entry); ++ remove_proc_entry("version", dc->proc_entry); ++ remove_proc_entry("nozomi", &proc_root); ++} ++ ++static void send_reset_token(dc_t *dc) { ++ ++ ctrl_ul_t ctrl; ++ ++ /* Send 0x0001, command card to resend the reset token. */ ++ /* This is to get the reset when the module is reloaded. */ ++ ctrl.port = 0x00; ctrl.reserved = 0; ctrl.RTS=0; ctrl.DTR=1; ++ D1( "sending flow control 0x%04X", * ((u16*) &ctrl) ); ++ ++ ++ /*SET_MEM( dc->port[PORT_CTRL].ul_addr[0], (u32*) &ctrl, 2 );*/ ++ /* hack alert :D (fixed address determined experimentally) */ ++ SET_MEM( dc->base_addr + 0x000002FC, (u32*) &ctrl, 2 ); ++ SET_FCR( CTRL_UL ); /* push the token to the card. */ ++ D1( "sent flow control 0x%04X", * ((u16*) &ctrl) ); ++} ++ ++/* Allocate memory for one device */ ++static int __devinit nozomi_card_init(struct pci_dev *pdev, const struct pci_device_id *ent) { ++ int ret = -EIO; ++ dc_t *dc=NULL; ++ ++ cards_found++; ++ INFO("Init, cards_found: %d", cards_found); ++ ++ if (!(my_dev = kmalloc(sizeof(dc_t), GFP_KERNEL))) { ++ D1( "Could not allocate memory"); ++ return -EIO; ++ } ++ ++ memset(my_dev, 0, sizeof( dc_t )); ++ ++ if (cards_found > 1) { ++ ERR("This driver only supports 1 device"); ++ return -ENODEV; ++ } ++ ++ my_dev->pdev = pdev; ++ dc = my_dev; ++ ++ /* Find out what card type it is */ ++ nozomi_get_card_type(dc); ++ ++ if (pci_enable_device(dc->pdev)) { ++ ERR("Not possible to enable PCI Device"); ++ return -ENODEV; ++ } ++ ++ if ( (dc->base_addr = pci_resource_start(dc->pdev, 0)) == 0x0000) { ++ ERR("No I/O-Address for card detected"); ++ ret = -ENODEV; ++ goto err_disable_device; ++ } ++ ++ if (!(dc->base_addr = (u32) ioremap(dc->base_addr, dc->card_type))) { ++ ERR("No I/O-Address for card detected"); ++ ret = -ENODEV; ++ goto err_disable_device; ++ } ++ ++ dc->open_ttys=0; ++ ++ nozomi_setup_private_data(dc); ++ ++ if (pci_request_regions(dc->pdev, NOZOMI_NAME)) { ++ ERR("I/O address 0x%04x already in use", ++ (int) /* nozomi_private.io_addr */ 0); ++ ret = -EIO; ++ goto err_disable_regions; ++ } ++ ++ if ( !(dc->send_buf = kmalloc(SEND_BUF_MAX, GFP_KERNEL))) { ++ ERR("Could not allocate send buffer?"); ++ goto err_disable_regions; ++ } ++ ++ /* Disable all interrupts */ ++ SET_IER( 0 , 0xFFFF ); ++ ++ /* Setup interrupt handler */ ++ if (nozomi_setup_interrupt(dc->pdev)) { ++ ret = -EIO; ++ goto err_disable_regions; ++ } ++ ++ D1( "base_addr: 0x%08X", dc->base_addr); ++ ++#ifdef KERNEL_2_4 ++ dc->tty_flip_queue.list.next = NULL; ++ dc->tty_flip_queue.list.prev = NULL; ++ dc->tty_flip_queue.sync = 0; ++ dc->tty_flip_queue.data = dc; ++ dc->tty_flip_queue.routine = tty_flip_queue_function; ++#endif ++#ifdef KERNEL_2_6 ++ if ( !(dc->tty_flip_wq = create_singlethread_workqueue(NOZOMI_NAME )) ) { ++ ERR("Could not create workqueue?"); ++ BUG_ON(!dc->tty_flip_wq); ++ return -ENOMEM; ++ } ++ INIT_WORK( &dc->tty_flip_wq_struct, tty_flip_queue_function, (void*) dc); ++#endif ++ ++ spin_lock_init(&dc->spin_mutex); ++ ++ make_proc_dirs(); ++ ++ ntty_tty_init(dc); ++#if 0 ++ if (!nozomi_read_config_table(dc)) { ++ ERR("Could not read config table (pass 1)"); ++ return -ENODEV; ++ } ++ if (!nozomi_read_config_table(dc)) { ++ ERR("Could not read config table (pass 2)"); ++ return -ENODEV; ++ } ++#endif ++ send_reset_token(dc); ++ ++ /* Enable RESET interrupt. */ ++ SET_IER( RESET, 0xFFFF ); ++ ++ return 0; ++ ++err_disable_regions: ++ pci_release_regions(pdev); ++ iounmap((void *)dc->base_addr ); ++ dc->base_addr = 0; ++ ++err_disable_device: ++ pci_disable_device(pdev); ++ if(my_dev) { ++ kfree( my_dev ); ++ } ++ return ret; ++} ++ ++static void tty_do_close(dc_t *dc, port_t *port) { ++ ++ down(&port->tty_sem); ++ ++ if ( !port->tty_open_count ) { ++ goto exit; ++ } ++ ++ dc->open_ttys--; ++ port->tty_open_count--; ++#ifdef KERNEL_2_4 ++ MOD_DEC_USE_COUNT; ++#endif ++ ++ if ( port->tty_open_count == 0) { ++ D1("close: %d", port->token_dl ); ++ SET_IER( 0, port->token_dl ); ++ } ++ ++exit: ++ up(&port->tty_sem); ++} ++ ++static void __exit tty_exit(void) { ++ int i; ++ dc_t *dc = my_dev; ++ ++ D1( " "); ++ ++#ifdef KERNEL_2_6 ++ for (i = 0; i < NTTY_TTY_MINORS; ++i) ++ tty_unregister_device(&dc->tty_driver, i); ++#endif ++ ++ tty_unregister_driver(&dc->tty_driver); ++ ++ for (i = 0; i < NTTY_TTY_MINORS; i++) { ++ while (dc->port[i].tty_open_count) { ++ tty_do_close(dc, &dc->port[i]); ++ } ++ ++ dc->port[i].tty = NULL; ++ } ++} ++ ++/* Deallocate memory for one device */ ++static void __devexit nozomi_card_exit(struct pci_dev *pdev) { ++ int i; ++ dc_t *dc = get_dc_by_pdev(pdev); ++ ++ /* Disable all interrupts */ ++ SET_IER( 0, 0xFFFF); ++ ++ /* Setup dc->reg addresses to we can use defines here */ ++ nozomi_setup_private_data(dc); ++ send_reset_token(dc); ++ ++ D1( "pci_release_regions"); ++ pci_release_regions(pdev); ++ ++ if(dc->base_addr) ++ iounmap((void *)dc->base_addr); ++ ++ D1( "pci_disable_device"); ++ pci_disable_device(pdev); ++ ++ free_irq( pdev->irq, pdev ); ++ ++ for (i=PORT_MDM; i< MAX_PORT;i++) { ++ kfree ( dc->port[i].fifo_ul ); ++ } ++ ++ kfree( dc->send_buf ); ++ ++ tty_exit(); ++ ++ remove_proc_dirs(); ++ ++#ifdef KERNEL_2_6 ++ destroy_workqueue(dc->tty_flip_wq); ++#endif ++ ++ if (my_dev) { ++ kfree( my_dev ); ++ } ++ ++ cards_found--; ++ cards_initialized--; ++} ++ ++static void set_rts(int index, int rts) { ++ dc_t *dc = get_dc_by_index(index); ++ ++ dc->port[index].ctrl_ul.RTS = rts; ++ dc->port[index].update_flow_control = 1; ++ enable_transmit_ul(PORT_CTRL, dc); ++} ++ ++static void set_dtr(int index, int dtr) { ++ dc_t *dc = get_dc_by_index(index); ++ ++ D1("SETTING DTR index: %d, dtr: %d", index, dtr); ++ ++ dc->port[index].ctrl_ul.DTR = dtr; ++ dc->port[index].update_flow_control = 1; ++ enable_transmit_ul(PORT_CTRL, dc); ++} ++ ++ ++/* --------------------------------------------------------------------------------------------------- ++ TTY code ++ ---------------------------------------------------------------------------------------------------*/ ++ ++ ++/* Called when the userspace process opens the tty, /dev/noz*. */ ++static int ntty_open(struct tty_struct *tty, struct file *file) { ++ ++ s32 index = get_index(tty); ++ port_t *port = get_port_by_tty(tty); ++ dc_t *dc = get_dc_by_tty(tty); ++ ++ CARD_CHECK(-ENODEV); ++ ++ down(&port->tty_sem); ++ ++ tty->low_latency = 1; ++ tty->driver_data = port; ++ port->tty = tty; ++ port->tty_index = index; ++ ++ port->tty_open_count++; ++ dc->open_ttys++; ++ ++#ifdef KERNEL_2_4 ++ MOD_INC_USE_COUNT; ++#endif ++ ++ /* Enable interrupt downlink for channel */ ++ if ( port->tty_open_count == 1) { ++ port->rx_data = port->tx_data = 0; ++ D1("open: %d", port->token_dl ); ++ SET_IER( port->token_dl, port->token_dl ); ++ } ++ ++ up(&port->tty_sem); ++ ++ return 0; ++} ++ ++/* Called when the userspace process close the tty, /dev/noz*. */ ++static void ntty_close(struct tty_struct *tty, struct file *file) { ++ dc_t *dc; ++ CARD_CHECK(); ++ dc = get_dc_by_tty(tty); ++ tty_do_close(dc, (port_t *) tty->driver_data); ++} ++ ++/* called when the userspace process writes to the tty (/dev/noz*). */ ++/* Data is inserted into a fifo, which is then read and transfered to the modem. */ ++#ifdef KERNEL_2_6 ++static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, int count) { ++#else ++static s32 ntty_write(struct tty_struct *tty, s32 from_user, const u8 *buffer, s32 count) { ++#endif ++ int rval = -EINVAL; ++ dc_t *dc = get_dc_by_tty(tty); ++ port_t *port = (port_t *) tty->driver_data; ++ ++ CARD_CHECK(rval); ++ ++ /* D1( "WRITEx: %d, index = %d", count, index); */ ++ ++ if (! port) { ++ return -ENODEV; ++ } ++ ++ down(&port->tty_sem); ++ ++ if (! port->tty_open_count) { ++ D1( " "); ++ goto exit; ++ } ++ ++#ifdef KERNEL_2_4 ++ if (from_user) { ++ rval = __kfifo_put_user(port->fifo_ul, (unsigned char *) buffer, count); ++ } else { ++ rval = __kfifo_put(port->fifo_ul, (unsigned char *) buffer, count); ++ } ++#else ++ rval = __kfifo_put(port->fifo_ul, (unsigned char *) buffer, count); ++#endif ++ ++ /* notify card */ ++ if ( dc == NULL) { ++ D1( "No device context?"); ++ goto exit; ++ } ++ ++ // CTS is only valid on the modem channel ++ if ( port == &(dc->port[PORT_MDM]) ) { ++ if ( port->ctrl_dl.CTS ) { ++ D4( "Enable interrupt"); ++ enable_transmit_ul(port->tty_index, dc ); ++ } else { ++ ERR("CTS not active on modem port?"); ++ } ++ } else { ++ enable_transmit_ul(port->tty_index, dc ); ++ } ++ ++exit: ++ up(&port->tty_sem); ++ return rval; ++} ++ ++/* Calculate how much is left in device */ ++/* This method is called by the upper tty layer. */ ++/* #according to sources N_TTY.c it expects a value >= 0 and does not check for negative values. */ ++static int ntty_write_room(struct tty_struct *tty) { ++ port_t *port = (port_t *) tty->driver_data; ++ int room = 0; ++/* u32 flags = 0; */ ++/* dc_t *dc = get_dc_by_tty(tty); */ ++ ++ CARD_CHECK(-ENODEV); ++ ++ if (! port) { ++ return 0; ++ } ++ ++ down(&port->tty_sem); ++ ++ if (! port->tty_open_count) { ++ goto exit; ++ } ++ ++ room = port->fifo_ul->size - __kfifo_len(port->fifo_ul); ++ ++exit: ++ up(&port->tty_sem); ++ return room; ++} ++ ++/* Sets termios flags, called by the tty layer. */ ++static void ntty_set_termios(struct tty_struct *tty, struct termios *old_termios) { ++ unsigned int cflag; ++ ++ CARD_CHECK(); ++ ++ cflag = tty->termios->c_cflag; ++ ++ if (old_termios) { ++ if ((cflag == old_termios->c_cflag) && ++ (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) { ++ D1( " - nothing to change..."); ++ goto exit_termios; ++ } ++ } ++ ++ /* get the byte size */ ++ switch (cflag & CSIZE) { ++ case CS5: ++ D1( " - data bits = 5"); ++ break; ++ case CS6: ++ D1( " - data bits = 6"); ++ break; ++ case CS7: ++ D1( " - data bits = 7"); ++ break; ++ default: ++ case CS8: ++ D1( " - data bits = 8"); ++ break; ++ } ++ ++ /* determine the parity */ ++ if (cflag & PARENB) { ++ if (cflag & PARODD) { ++ D1( " - parity = odd"); ++ } else { ++ D1( " - parity = even"); ++ } ++ } else { ++ D1( " - parity = none"); ++ } ++ ++ /* figure out the stop bits requested */ ++ if (cflag & CSTOPB) { ++ D1( " - stop bits = 2"); ++ } else { ++ D1( " - stop bits = 1"); ++ } ++ ++ /* figure out the hardware flow control settings */ ++ if (cflag & CRTSCTS) { ++ D1( " - RTS/CTS is enabled"); ++ } else { ++ D1( " - RTS/CTS is disabled"); ++ } ++ ++ /* determine software flow control */ ++ /* if we are implementing XON/XOFF, set the start and ++ * stop character in the device */ ++ if (I_IXOFF(tty) || I_IXON(tty)) { ++#ifdef NOZOMI_DEBUG ++ unsigned char stop_char = STOP_CHAR(tty); ++ unsigned char start_char = START_CHAR(tty); ++#endif ++ /* if we are implementing INBOUND XON/XOFF */ ++ if (I_IXOFF(tty)) { ++ D1( " - INBOUND XON/XOFF is enabled, " ++ "XON = %2x, XOFF = %2x", start_char, stop_char); ++ } else { ++ D1( " - INBOUND XON/XOFF is disabled"); ++ } ++ ++ /* if we are implementing OUTBOUND XON/XOFF */ ++ if (I_IXON(tty)) { ++ D1( " - OUTBOUND XON/XOFF is enabled, " ++ "XON = %2x, XOFF = %2x", start_char, stop_char); ++ } else { ++ D1( " - OUTBOUND XON/XOFF is disabled"); ++ } ++ } ++ ++ exit_termios: ++ return; ++} ++ ++/* Gets io control parameters */ ++static int ntty_tiocmget(struct tty_struct *tty, struct file *file) { ++ port_t *port = (port_t *) tty->driver_data; ++ ctrl_dl_t *ctrl_dl = &port->ctrl_dl; ++ ctrl_ul_t *ctrl_ul = &port->ctrl_ul; ++ ++ return 0 ++ | (ctrl_ul->RTS ? TIOCM_RTS : 0) ++ | (ctrl_ul->DTR ? TIOCM_DTR : 0) ++ | (ctrl_dl->DCD ? TIOCM_CAR : 0) ++ | (ctrl_dl->RI ? TIOCM_RNG : 0) ++ | (ctrl_dl->DSR ? TIOCM_DSR : 0) ++ | (ctrl_dl->CTS ? TIOCM_CTS : 0); ++} ++ ++/* Sets io controls parameters */ ++static int ntty_tiocmset(struct tty_struct *tty, struct file *file, u32 arg) { ++ port_t *port = (port_t *) tty->driver_data; ++ ++ set_rts(port->tty_index, (arg & TIOCM_RTS) ? 1 : 0); ++ set_dtr(port->tty_index, (arg & TIOCM_DTR) ? 1 : 0); ++ ++ return 0; ++} ++ ++static int ntty_ioctl_tiocmiwait(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { ++ port_t *port = (port_t *) tty->driver_data; ++ ++ if (cmd == TIOCMIWAIT) { ++ DECLARE_WAITQUEUE(wait, current); ++ struct async_icount cnow; ++ struct async_icount cprev; ++ ++ cprev = port->tty_icount; ++ while (1) { ++ add_wait_queue(&port->tty_wait, &wait); ++ set_current_state(TASK_INTERRUPTIBLE); ++ schedule(); ++ remove_wait_queue(&port->tty_wait, &wait); ++ ++ /* see if a signal woke us up */ ++ if (signal_pending(current)) ++ return -ERESTARTSYS; ++ ++ cnow = port->tty_icount; ++ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && ++ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) ++ return -EIO; /* no change => error */ ++ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ++ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || ++ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || ++ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { ++ return 0; ++ } ++ cprev = cnow; ++ } ++ ++ } ++ return -ENOIOCTLCMD; ++} ++ ++static int ntty_ioctl_tiocgicount(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { ++ port_t *port = (port_t *) tty->driver_data; ++ ++ if (cmd == TIOCGICOUNT) { ++ struct async_icount cnow = port->tty_icount; ++ struct serial_icounter_struct icount; ++ ++ icount.cts = cnow.cts; ++ icount.dsr = cnow.dsr; ++ icount.rng = cnow.rng; ++ icount.dcd = cnow.dcd; ++ icount.rx = cnow.rx; ++ icount.tx = cnow.tx; ++ icount.frame = cnow.frame; ++ icount.overrun = cnow.overrun; ++ icount.parity = cnow.parity; ++ icount.brk = cnow.brk; ++ icount.buf_overrun = cnow.buf_overrun; ++ ++ if (copy_to_user((void *)arg, &icount, sizeof(icount))) ++ return -EFAULT; ++ return 0; ++ } ++ return -ENOIOCTLCMD; ++} ++ ++static int ntty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { ++ port_t *port = (port_t *) tty->driver_data; ++ int mask; ++ int rval = -ENOIOCTLCMD; ++ ++ CARD_CHECK(rval); ++ ++ D1("******** IOCTL, cmd: %d", cmd); ++ ++ ++ switch (cmd) { ++ case TCGETS: ++ D1( "IOCTL TCGETS ..."); ++ rval = -ENOIOCTLCMD; ++ break; ++ case TCSETS: ++ D1( "IOCTL TCSETS ..."); ++ rval = -ENOIOCTLCMD; ++ break; ++ case TIOCMIWAIT: ++ rval = ntty_ioctl_tiocmiwait(tty, file, cmd, arg); ++ break; ++ case TIOCGICOUNT: ++ rval = ntty_ioctl_tiocgicount(tty, file, cmd, arg); ++ break; ++ case TIOCMGET: ++ rval = ntty_tiocmget(tty, file); ++ break; ++ case TIOCMSET: ++ rval = ntty_tiocmset(tty, file, arg); ++ break; ++ case TIOCMBIC: ++ if (get_user(mask, (unsigned long *) arg)) ++ return -EFAULT; ++ ++ if (mask & TIOCM_RTS) ++ set_rts(port->tty_index, 0); ++ if (mask & TIOCM_DTR) ++ set_dtr(port->tty_index, 0); ++ rval = 0; ++ break; ++ case TIOCMBIS: ++ if (get_user(mask, (unsigned long *) arg)) ++ return -EFAULT; ++ ++ if (mask & TIOCM_RTS) ++ set_rts(port->tty_index, 1); ++ if (mask & TIOCM_DTR) ++ set_dtr(port->tty_index, 1); ++ rval = 0; ++ break; ++ case TCFLSH: ++ D1( "IOCTL TCFLSH ..."); ++ rval = -ENOIOCTLCMD; ++ break; ++ ++ default: ++ D1( "ERR: 0x%08X, %d", cmd, cmd); ++ break; ++ }; ++ ++ return rval; ++} ++ ++/* Called by the upper tty layer when tty buffers are ready */ ++/* to receive data again after a call to throttle. */ ++static void ntty_unthrottle(struct tty_struct *tty) { ++ port_t *port = (port_t *) tty->driver_data; ++ dc_t *dc = get_dc_by_tty(tty); ++ u32 flags; ++ ++ CARD_CHECK(); ++ ++ D1( "UNTHROTTLE"); ++ spin_lock_irqsave(&dc->spin_mutex, flags); ++ enable_transmit_dl(port->tty_index, dc); ++ set_rts(port->tty_index, 1); ++ ++ spin_unlock_irqrestore(&dc->spin_mutex, flags); ++} ++ ++/* Called by the upper tty layer when the tty buffers are almost full. */ ++/* The driver should stop send more data. */ ++static void ntty_throttle(struct tty_struct *tty) { ++ port_t *port = (port_t *) tty->driver_data; ++ dc_t *dc = get_dc_by_tty(tty); ++ u32 flags; ++ ++ CARD_CHECK(); ++ ++ D1( "THROTTLE"); ++ spin_lock_irqsave(&dc->spin_mutex, flags); ++ set_rts(port->tty_index, 0); ++ spin_unlock_irqrestore(&dc->spin_mutex, flags); ++} ++ ++static void ntty_put_char(struct tty_struct *tty, unsigned char c) { ++ CARD_CHECK(); ++ D2("PUT CHAR Function: %c", c); ++} ++ ++/* Returns number of chars in buffer, called by tty layer */ ++static s32 ntty_chars_in_buffer(struct tty_struct *tty) { ++ port_t *port = (port_t *) tty->driver_data; ++ s32 rval; ++ ++ CARD_CHECK(-ENODEV); ++ ++ if (! port) { ++ rval = -ENODEV; ++ goto exit_in_buffer; ++ } ++ ++ if (! port->tty_open_count) { ++ ERR("No tty open?"); ++ rval = -ENODEV; ++ goto exit_in_buffer; ++ } ++ ++ rval = __kfifo_len(port->fifo_ul); ++ ++ exit_in_buffer: ++ return rval; ++} ++ ++/* Initializes the tty */ ++static int ntty_tty_init(dc_t *dc) { ++ struct tty_driver *td = &dc->tty_driver; ++ int rval; ++ int i; ++ ++ memset(td, 0, sizeof(struct tty_driver)); ++ ++ td->magic = TTY_DRIVER_MAGIC; ++ td->driver_name = NOZOMI_NAME_TTY; ++ td->name = "noz"; ++ td->major = NTTY_TTY_MAJOR, ++ td->type = TTY_DRIVER_TYPE_SERIAL, ++ td->subtype = SERIAL_TYPE_NORMAL, ++ td->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, ++ td->init_termios = tty_std_termios; ++ td->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL; ++ ++ td->num = MAX_PORT; ++ td->name_base = 0; ++ td->minor_start = 0; ++ ++#ifdef KERNEL_2_4 ++ td->table = dc->tty_table; ++ td->refcount = &dc->tty_refcount; ++#endif ++ ++ td->termios = dc->tty_termios; ++ td->termios_locked = dc->tty_termios_locked; ++ ++ td->ioctl = ntty_ioctl; ++ td->open = ntty_open; ++ td->close = ntty_close; ++ td->write = ntty_write; ++ td->write_room = ntty_write_room; ++ td->unthrottle = ntty_unthrottle; ++ td->throttle = ntty_throttle; ++ td->set_termios = ntty_set_termios; ++ td->chars_in_buffer = ntty_chars_in_buffer; ++ td->put_char = ntty_put_char; ++ ++ rval = tty_register_driver(td); ++ ++ if (rval) { ++ printk(KERN_ERR "failed to register ntty tty driver"); ++ D1( "failed to register ntty tty driver"); ++ return rval; ++ } ++ ++ for (i = 0; i < NTTY_TTY_MINORS; i++) { ++ init_MUTEX(&dc->port[i].tty_sem); ++ dc->port[i].tty_open_count = 0; ++ dc->port[i].tty = NULL; ++ ++#ifdef KERNEL_2_6 ++ tty_register_device(td, i, NULL); ++#endif ++ } ++ ++ printk(KERN_INFO DRIVER_DESC " " NOZOMI_NAME_TTY); ++ D1( " "); ++ return rval; ++} ++ ++/* Module initialization */ ++static struct pci_driver nozomi_driver = { ++ .name = NOZOMI_NAME, ++ .id_table = nozomi_pci_tbl, ++ .probe = nozomi_card_init, ++ .remove = __devexit_p(nozomi_card_exit), ++}; ++ ++static int __init nozomi_init(void) { ++ int rval = 0; ++ ++ rval = pci_module_init(&nozomi_driver); ++ printk(KERN_INFO "Initializing %s\n", VERSION_STRING); ++ return rval; ++} ++ ++static void nozomi_exit(void) { ++ printk(KERN_INFO "Unloading %s", DRIVER_DESC); ++ ++ pci_unregister_driver(&nozomi_driver); ++} ++ ++module_init(nozomi_init); ++module_exit(nozomi_exit); ++ ++#ifdef NOZOMI_DEBUG ++ MODULE_PARM(nzdebug, "i"); ++#endif ++ ++MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_DESCRIPTION( DRIVER_DESC ); diff --git a/packages/linux/linux-mtx-1-2.4.27/42-usb-ohci-fixes.patch b/packages/linux/linux-mtx-1-2.4.27/42-usb-ohci-fixes.patch new file mode 100644 index 0000000000..4c3058ce00 --- /dev/null +++ b/packages/linux/linux-mtx-1-2.4.27/42-usb-ohci-fixes.patch @@ -0,0 +1,42 @@ +--- linux/drivers/usb/host/usb-ohci.c.orig 2006-03-30 11:38:08.972225500 +0200 ++++ linux/drivers/usb/host/usb-ohci.c 2006-03-30 11:39:46.858343000 +0200 +@@ -104,6 +104,10 @@ + + #define OHCI_UNLINK_TIMEOUT (HZ / 10) + ++static int ohci_delay = 3000; ++MODULE_PARM(ohci_delay, "i"); ++MODULE_PARM_DESC(ohci_delay, "Wait time [ms] for OHCI to come up"); ++ + /*-------------------------------------------------------------------------*/ + + /* AMD-756 (D2 rev) reports corrupt register contents in some cases. +@@ -2587,12 +2591,12 @@ + hc_release_ohci (ohci); + return -ENODEV; + } +- ++#if 0 + /* FIXME this is a second HC reset; why?? */ + writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control); + (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ + wait_ms (10); +- ++#endif + usb_register_bus (ohci->bus); + + if (request_irq (irq, hc_interrupt, SA_SHIRQ, +@@ -2668,6 +2672,13 @@ + void *mem_base; + int status; + ++ printk ("waiting for ohci to come up\n"); ++ mdelay(ohci_delay); ++ /* We have to wait for about four seconds for some devices to be available. ++ * This may only be a matter of the Option Globetrotter Fusion, ++ * that may need to much time to start up correctly. */ ++ printk ("ohci should be up\n"); ++ + if (pci_enable_device(dev) < 0) + return -ENODEV; + diff --git a/packages/linux/linux-mtx-1-2.4.27/defconfig-mtx-1 b/packages/linux/linux-mtx-1-2.4.27/defconfig-mtx-1 index d31e979829..5c189749fd 100644 --- a/packages/linux/linux-mtx-1-2.4.27/defconfig-mtx-1 +++ b/packages/linux/linux-mtx-1-2.4.27/defconfig-mtx-1 @@ -311,13 +311,13 @@ CONFIG_SYN_COOKIES=y # # IP: Netfilter Configuration # -CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_CONNTRACK=y CONFIG_IP_NF_FTP=m CONFIG_IP_NF_AMANDA=m CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_IRC=m CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_IPTABLES=y CONFIG_IP_NF_MATCH_LIMIT=m CONFIG_IP_NF_MATCH_MAC=m CONFIG_IP_NF_MATCH_PKTTYPE=m @@ -332,29 +332,29 @@ 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_STATE=y +CONFIG_IP_NF_MATCH_CONNTRACK=y CONFIG_IP_NF_MATCH_UNCLEAN=m CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y CONFIG_IP_NF_TARGET_MIRROR=m -CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT=y CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_REDIRECT=y CONFIG_IP_NF_NAT_AMANDA=m # CONFIG_IP_NF_NAT_LOCAL is not set 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_MANGLE=m +CONFIG_IP_NF_MANGLE=y 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_LOG=m +CONFIG_IP_NF_TARGET_MARK=y +CONFIG_IP_NF_TARGET_LOG=y CONFIG_IP_NF_TARGET_ULOG=m CONFIG_IP_NF_TARGET_TCPMSS=m CONFIG_IP_NF_ARPTABLES=m @@ -636,13 +636,14 @@ CONFIG_MIPS_AU1X00_ENET=y # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set -CONFIG_PPP=m +CONFIG_PPP=y CONFIG_PPP_MULTILINK=y CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m +CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=m CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE_MPPC=y CONFIG_PPPOE=m # CONFIG_SLIP is not set @@ -749,6 +750,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y # CONFIG_MIPS_HYDROGEN3_BUTTONS is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 +CONFIG_NOZOMI=m # # I2C support @@ -1059,7 +1061,7 @@ CONFIG_SOUND=m # CONFIG_SOUND_ICH is not set # CONFIG_SOUND_RME96XX is not set # CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_AU1X00 is not set +CONFIG_SOUND_AU1X00=m # CONFIG_SOUND_AU1550_PSC is not set # CONFIG_SOUND_AU1550_I2S is not set # CONFIG_SOUND_TRIDENT is not set @@ -1113,7 +1115,7 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_EHCI_HCD is not set # CONFIG_USB_UHCI is not set # CONFIG_USB_UHCI_ALT is not set -CONFIG_USB_OHCI=y +CONFIG_USB_OHCI=m CONFIG_USB_AUDIO=m CONFIG_USB_EMI26=m CONFIG_USB_MIDI=m diff --git a/packages/linux/linux-mtx-1_2.4.27.bb b/packages/linux/linux-mtx-1_2.4.27.bb index cce3b3c30c..0c907d6427 100644 --- a/packages/linux/linux-mtx-1_2.4.27.bb +++ b/packages/linux/linux-mtx-1_2.4.27.bb @@ -9,7 +9,7 @@ inherit module-base kernel PROVIDES = "virtual/kernel" RDEPENDS = "mtd-utils" -SRC_URI = "cvs://cvs@ftp.linux-mips.org/home/cvs;module=linux;tag=linux_2_4_27 \ +SRC_URI = "cvs://cvs:cvs@ftp.linux-mips.org/home/cvs;module=linux;tag=linux_2_4_27 \ file://01-mtd-2004-01-27.diff;patch=1 \ file://02-mtd-mtx-1-map.diff;patch=1 \ file://03-mtd-erase-compiler-bug.diff;patch=1 \ @@ -36,10 +36,13 @@ SRC_URI = "cvs://cvs@ftp.linux-mips.org/home/cvs;module=linux;tag=linux_2_4_27 \ file://26-usbd-amd-pb1x00-kit-23may2003-update.diff;patch=1 \ file://27-usbd-amd-pb1x00-kit-23may2003-usbd.diff;patch=1 \ file://29-au1000-pci-config-clear-errors.diff;patch=1 \ + file://42-usb-ohci-fixes.patch;patch=1 \ file://defconfig-mtx-1" S = "${WORKDIR}/linux" +inherit kernel + COMPATIBLE_HOST = "mipsel.*-linux" ARCH = "mips" KERNEL_OUTPUT = "arch/mips/zboot/images/mtx-1.flash.bin" @@ -70,10 +73,10 @@ fi FILES_kernel += " /tmp" do_deploy() { - install -d ${DEPLOY_DIR_IMAGE} - install -m 0644 arch/mips/zboot/images/mtx-1.flash.bin ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGE_NAME}.flash.bin - install -m 0644 arch/mips/zboot/images/mtx-1.flash.srec ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGE_NAME}.flash.srec - install -m 0644 arch/mips/zboot/images/mtx-1.srec ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGE_NAME}.ram.srec + install -d ${DEPLOY_DIR}/images + install -m 0644 arch/mips/zboot/images/mtx-1.flash.bin ${DEPLOY_DIR}/images/${KERNEL_IMAGE_NAME}.flash.bin + install -m 0644 arch/mips/zboot/images/mtx-1.flash.srec ${DEPLOY_DIR}/images/${KERNEL_IMAGE_NAME}.flash.srec + install -m 0644 arch/mips/zboot/images/mtx-1.srec ${DEPLOY_DIR}/images/${KERNEL_IMAGE_NAME}.ram.srec } do_deploy[dirs] = "${S}" diff --git a/packages/linux/linux-mtx-1u_2.4.27.bb b/packages/linux/linux-mtx-1u_2.4.27.bb new file mode 100644 index 0000000000..8ab1c5bbd1 --- /dev/null +++ b/packages/linux/linux-mtx-1u_2.4.27.bb @@ -0,0 +1,21 @@ +include linux-mtx-1_2.4.27.bb + +PR = "r11" + +SRC_URI += "\ + file://22-umts.diff;patch=1 \ + file://28-idsel-cardbus.diff;patch=1 \ + file://30-mtx-1-sysled.diff;patch=1 \ + file://31-mtx-1u-led-init.diff;patch=1 \ + file://32-usbserial-stalled-hack.diff;patch=1 \ + file://33-usbserial-bulk_in_size-4096.diff;patch=1 \ + file://39-mppe-mpc.patch;patch=1 \ + file://40-option-hsdpa.patch;patch=1" + +FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/linux-mtx-1-${PV}" + +KERNEL_IMAGE_NAME = "kernel-${KV}-${MACHINE}u_${BUILDNAME}" + +MTX_KERNEL_NON_PCI_OHCI = "no" + +PACKAGE_ARCH = "mtx-1u" diff --git a/packages/linux/linux-mtx-2-2.4.27/.mtn2git_empty b/packages/linux/linux-mtx-2-2.4.27/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/linux/linux-mtx-2-2.4.27/00-mtx-2.diff b/packages/linux/linux-mtx-2-2.4.27/00-mtx-2.diff new file mode 100644 index 0000000000..589446c2e9 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/00-mtx-2.diff @@ -0,0 +1,3032 @@ +diff -uNr linux-old/arch/mips/Makefile linux/arch/mips/Makefile +--- linux-old/arch/mips/Makefile 2004-11-24 12:11:50.000000000 +0100 ++++ linux/arch/mips/Makefile 2006-04-30 18:50:41.679294000 +0200 +@@ -306,6 +306,13 @@ + LOADADDR += 0x80100000 + endif + ++ifdef CONFIG_MIPS_MTX2 ++LIBS += arch/mips/au1000/mtx-2/mtx-2.o \ ++ arch/mips/au1000/common/au1000.o ++SUBDIRS += arch/mips/au1000/mtx-2 arch/mips/au1000/common ++LOADADDR += 0x80100000 ++endif ++ + ifdef CONFIG_MIPS_PB1550 + LIBS += arch/mips/au1000/pb1550/pb1550.o \ + arch/mips/au1000/common/au1000.o +diff -uNr linux-old/arch/mips/au1000/mtx-2/Makefile linux/arch/mips/au1000/mtx-2/Makefile +--- linux-old/arch/mips/au1000/mtx-2/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux/arch/mips/au1000/mtx-2/Makefile 2006-04-30 18:52:46.383087500 +0200 +@@ -0,0 +1,20 @@ ++# ++# Copyright 2003 MontaVista Software Inc. ++# Author: MontaVista Software, Inc. ++# ppopov@mvista.com or source@mvista.com ++# Bruno Randolf ++# ++# Makefile for 4G Systems MTX-2 board. ++# ++# Note! Dependencies are done automagically by 'make dep', which also ++# removes any old dependencies. DON'T put your own dependencies here ++# unless it's something special (ie not a .c file). ++# ++ ++USE_STANDARD_AS_RULE := true ++ ++O_TARGET := mtx-2.o ++ ++obj-y := init.o board_setup.o irqmap.o ++ ++include $(TOPDIR)/Rules.make +diff -uNr linux-old/arch/mips/au1000/mtx-2/board_setup.c linux/arch/mips/au1000/mtx-2/board_setup.c +--- linux-old/arch/mips/au1000/mtx-2/board_setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/arch/mips/au1000/mtx-2/board_setup.c 2006-04-30 18:52:50.967374000 +0200 +@@ -0,0 +1,90 @@ ++/* ++ * ++ * BRIEF MODULE DESCRIPTION ++ * 4G Systems MTX-2 board setup. ++ * ++ * Copyright 2003 MontaVista Software Inc. ++ * Author: MontaVista Software, Inc. ++ * ppopov@mvista.com or source@mvista.com ++ * Bruno Randolf ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern struct rtc_ops no_rtc_ops; ++ ++void __init board_setup(void) ++{ ++ rtc_ops = &no_rtc_ops; ++ ++#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) ++#ifdef CONFIG_AU1X00_USB_DEVICE ++ // 2nd USB port is USB device ++ au_writel(au_readl(SYS_PINFUNC) & (u32)(~0x8000), SYS_PINFUNC); ++#endif ++ // enable USB power switch ++ au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR ); ++ au_writel( 0x100000, GPIO2_OUTPUT ); ++#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) ++ ++#ifdef CONFIG_PCI ++#if defined(__MIPSEB__) ++ au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); ++#else ++ au_writel(0xf, Au1500_PCI_CFG); ++#endif ++#endif ++ ++ // initialize sys_pinfunc: ++ // disable second ethernet port (SYS_PF_NI2) ++ // set U3/GPIO23 to GPIO23 (SYS_PF_U3) ++ au_writel( SYS_PF_NI2 | SYS_PF_U3, SYS_PINFUNC ); ++ ++ // initialize GPIO ++ au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR ); ++ au_writel( 0x00000001, SYS_OUTPUTCLR ); // set M66EN (PCI 66MHz) to OFF ++ au_writel( 0x00000008, SYS_OUTPUTSET ); // set PCI CLKRUN# to OFF ++ au_writel( 0x00000020, SYS_OUTPUTCLR ); // set eth PHY TX_ER to OFF ++ au_writel( 0x00010000, SYS_OUTPUTSET ); // set ETH_RESET# to get PHY out of reset. ++ ++ // enable LED and set it to green ++ au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR ); ++ au_writel( 0x18000800, GPIO2_OUTPUT ); ++ ++ printk("4G Systems MTX-2 Board\n"); ++} +diff -uNr linux-old/arch/mips/au1000/mtx-2/init.c linux/arch/mips/au1000/mtx-2/init.c +--- linux-old/arch/mips/au1000/mtx-2/init.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/arch/mips/au1000/mtx-2/init.c 2006-04-30 18:52:58.171824250 +0200 +@@ -0,0 +1,74 @@ ++/* ++ * ++ * BRIEF MODULE DESCRIPTION ++ * 4G Systems MTX-2 board setup+ ++ * ++ * Copyright 2003 MontaVista Software Inc. ++ * Author: MontaVista Software, Inc. ++ * ppopov@mvista.com or source@mvista.com ++ * Bruno Randolf ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++int prom_argc; ++char **prom_argv, **prom_envp; ++extern void __init prom_init_cmdline(void); ++extern char *prom_getenv(char *envname); ++ ++const char *get_system_type(void) ++{ ++ return "MTX-2"; ++} ++ ++int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) ++{ ++ unsigned char *memsize_str; ++ unsigned long memsize; ++ ++ prom_argc = argc; ++ prom_argv = argv; ++ prom_envp = envp; ++ ++ mips_machgroup = MACH_GROUP_ALCHEMY; ++ mips_machtype = MACH_MTX2; /* set the platform # */ ++ prom_init_cmdline(); ++ ++ memsize_str = prom_getenv("memsize"); ++ if (!memsize_str) { ++ memsize = 0x04000000; ++ } else { ++ memsize = simple_strtol(memsize_str, NULL, 0); ++ } ++ add_memory_region(0, memsize, BOOT_MEM_RAM); ++ return 0; ++} +diff -uNr linux-old/arch/mips/au1000/mtx-2/irqmap.c linux/arch/mips/au1000/mtx-2/irqmap.c +--- linux-old/arch/mips/au1000/mtx-2/irqmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/arch/mips/au1000/mtx-2/irqmap.c 2006-04-30 18:52:11.892932000 +0200 +@@ -0,0 +1,83 @@ ++/* ++ * BRIEF MODULE DESCRIPTION ++ * Au1xxx irq map table ++ * ++ * Copyright 2003 Embedded Edge, LLC ++ * dan@embeddededge.com ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Need to define this. ++*/ ++au1xxx_irq_map_t au1xxx_irq_map[] = { ++ { 0, 0, 0} ++}; ++ ++int au1xxx_nr_irqs = 0; ++ ++#ifdef CONFIG_PCI ++ ++#define INTA AU1000_PCI_INTA ++#define INTB AU1000_PCI_INTB ++#define INTC AU1000_PCI_INTC ++#define INTD AU1000_PCI_INTD ++#define INTX 0xFF /* not valid */ ++ ++int __init ++au1xxx_pci_irqmap(struct pci_dev *dev, unsigned char idsel, unsigned char pin) ++{ ++ static char pci_irq_table[][4] = ++ /* ++ * PCI IDSEL/INTPIN->INTLINE ++ * A B C D ++ */ ++ { ++ {INTA, INTB, INTC, INTD}, /* IDSEL 0 */ ++ {INTA, INTB, INTC, INTD}, /* IDSEL 1 */ ++ {INTA, INTB, INTC, INTD}, /* IDSEL 2 */ ++ {INTA, INTB, INTC, INTD}, /* IDSEL 3 */ ++ }; ++ const long min_idsel = 0, max_idsel = 3, irqs_per_slot = 4; ++ return PCI_IRQ_TABLE_LOOKUP; ++}; ++#endif +diff -uNr linux-old/arch/mips/config-shared.in linux/arch/mips/config-shared.in +--- linux-old/arch/mips/config-shared.in 2004-11-24 12:11:50.000000000 +0100 ++++ linux/arch/mips/config-shared.in 2006-04-30 18:54:03.599913250 +0200 +@@ -33,6 +33,7 @@ + dep_bool 'Support for Alchemy PB1550 board' CONFIG_MIPS_PB1550 $CONFIG_MIPS32 + dep_bool 'Support for MyCable XXS1500 board' CONFIG_MIPS_XXS1500 $CONFIG_MIPS32 + dep_bool 'Support for 4G Systems MTX-1 board' CONFIG_MIPS_MTX1 $CONFIG_MIPS32 ++dep_bool 'Support for 4G Systems MTX-2 board' CONFIG_MIPS_MTX2 $CONFIG_MIPS32 + dep_bool 'Support for Cogent CSB250 board' CONFIG_COGENT_CSB250 $CONFIG_MIPS32 + dep_bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS $CONFIG_MIPS32 $CONFIG_EXPERIMENTAL + bool 'Support for CASIO CASSIOPEIA E-10/15/55/65' CONFIG_CASIO_E55 +@@ -321,6 +322,11 @@ + define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_NONCOHERENT_IO y + fi ++if [ "$CONFIG_MIPS_MTX2" = "y" ]; then ++ define_bool CONFIG_SOC_AU1X00 y ++ define_bool CONFIG_SOC_AU1550 y ++ define_bool CONFIG_NONCOHERENT_IO y ++fi + if [ "$CONFIG_COGENT_CSB250" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y +diff -uNr linux-old/arch/mips/defconfig linux/arch/mips/defconfig +--- linux-old/arch/mips/defconfig 2004-11-24 12:11:50.000000000 +0100 ++++ linux/arch/mips/defconfig 2006-04-30 18:54:08.200200750 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-atlas linux/arch/mips/defconfig-atlas +--- linux-old/arch/mips/defconfig-atlas 2004-11-24 12:11:50.000000000 +0100 ++++ linux/arch/mips/defconfig-atlas 2006-04-30 18:54:12.896494250 +0200 +@@ -32,6 +32,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-bosporus linux/arch/mips/defconfig-bosporus +--- linux-old/arch/mips/defconfig-bosporus 2004-11-24 12:11:50.000000000 +0100 ++++ linux/arch/mips/defconfig-bosporus 2006-04-30 18:54:21.893056500 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -208,6 +209,7 @@ + CONFIG_MTD_BOSPORUS=y + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + # CONFIG_MTD_DB1X00 is not set + # CONFIG_MTD_PB1550 is not set + # CONFIG_MTD_HYDROGEN3 is not set +diff -uNr linux-old/arch/mips/defconfig-capcella linux/arch/mips/defconfig-capcella +--- linux-old/arch/mips/defconfig-capcella 2004-11-24 12:11:50.000000000 +0100 ++++ linux/arch/mips/defconfig-capcella 2006-04-30 18:54:26.265329750 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-cobalt linux/arch/mips/defconfig-cobalt +--- linux-old/arch/mips/defconfig-cobalt 2004-11-24 12:11:50.000000000 +0100 ++++ linux/arch/mips/defconfig-cobalt 2006-04-30 18:54:30.161573250 +0200 +@@ -32,6 +32,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-csb250 linux/arch/mips/defconfig-csb250 +--- linux-old/arch/mips/defconfig-csb250 2004-11-24 12:11:50.000000000 +0100 ++++ linux/arch/mips/defconfig-csb250 2006-04-30 18:54:34.969873750 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + CONFIG_COGENT_CSB250=y + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-db1000 linux/arch/mips/defconfig-db1000 +--- linux-old/arch/mips/defconfig-db1000 2004-11-24 12:11:50.000000000 +0100 ++++ linux/arch/mips/defconfig-db1000 2006-04-30 18:54:42.246328500 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -214,6 +215,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + CONFIG_MTD_DB1X00=y + CONFIG_MTD_DB1X00_BOOT=y + CONFIG_MTD_DB1X00_USER=y +diff -uNr linux-old/arch/mips/defconfig-db1100 linux/arch/mips/defconfig-db1100 +--- linux-old/arch/mips/defconfig-db1100 2004-11-24 12:11:50.000000000 +0100 ++++ linux/arch/mips/defconfig-db1100 2006-04-30 18:54:50.098819250 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -214,6 +215,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + CONFIG_MTD_DB1X00=y + # CONFIG_MTD_DB1X00_BOOT is not set + CONFIG_MTD_DB1X00_USER=y +diff -uNr linux-old/arch/mips/defconfig-db1500 linux/arch/mips/defconfig-db1500 +--- linux-old/arch/mips/defconfig-db1500 2004-11-24 12:11:50.000000000 +0100 ++++ linux/arch/mips/defconfig-db1500 2006-04-30 18:54:53.499031750 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-db1550 linux/arch/mips/defconfig-db1550 +--- linux-old/arch/mips/defconfig-db1550 2004-10-20 02:00:40.000000000 +0200 ++++ linux/arch/mips/defconfig-db1550 2006-04-30 18:58:13.603537500 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -213,6 +214,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + # CONFIG_MTD_DB1X00 is not set + CONFIG_MTD_PB1550=y + CONFIG_MTD_PB1550_BOOT=y +diff -uNr linux-old/arch/mips/defconfig-ddb5476 linux/arch/mips/defconfig-ddb5476 +--- linux-old/arch/mips/defconfig-ddb5476 2004-11-24 12:11:50.000000000 +0100 ++++ linux/arch/mips/defconfig-ddb5476 2006-04-30 18:54:56.835240250 +0200 +@@ -32,6 +32,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-ddb5477 linux/arch/mips/defconfig-ddb5477 +--- linux-old/arch/mips/defconfig-ddb5477 2004-11-24 12:11:50.000000000 +0100 ++++ linux/arch/mips/defconfig-ddb5477 2006-04-30 18:55:00.011438750 +0200 +@@ -32,6 +32,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-decstation linux/arch/mips/defconfig-decstation +--- linux-old/arch/mips/defconfig-decstation 2004-11-24 12:11:51.000000000 +0100 ++++ linux/arch/mips/defconfig-decstation 2006-04-30 18:55:02.803613250 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-e55 linux/arch/mips/defconfig-e55 +--- linux-old/arch/mips/defconfig-e55 2004-11-24 12:11:51.000000000 +0100 ++++ linux/arch/mips/defconfig-e55 2006-04-30 18:55:05.687793500 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + CONFIG_CASIO_E55=y +diff -uNr linux-old/arch/mips/defconfig-eagle linux/arch/mips/defconfig-eagle +--- linux-old/arch/mips/defconfig-eagle 2004-11-24 12:11:51.000000000 +0100 ++++ linux/arch/mips/defconfig-eagle 2006-04-30 18:55:11.956185250 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -217,6 +218,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + # CONFIG_MTD_DB1X00 is not set + # CONFIG_MTD_PB1550 is not set + # CONFIG_MTD_HYDROGEN3 is not set +diff -uNr linux-old/arch/mips/defconfig-ev64120 linux/arch/mips/defconfig-ev64120 +--- linux-old/arch/mips/defconfig-ev64120 2004-11-24 12:11:51.000000000 +0100 ++++ linux/arch/mips/defconfig-ev64120 2006-04-30 18:55:14.956372750 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-ev96100 linux/arch/mips/defconfig-ev96100 +--- linux-old/arch/mips/defconfig-ev96100 2004-11-24 12:11:51.000000000 +0100 ++++ linux/arch/mips/defconfig-ev96100 2006-04-30 18:55:18.712607500 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-hp-lj linux/arch/mips/defconfig-hp-lj +--- linux-old/arch/mips/defconfig-hp-lj 2004-11-24 12:11:51.000000000 +0100 ++++ linux/arch/mips/defconfig-hp-lj 2006-04-30 18:55:28.065192000 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -193,6 +194,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + # CONFIG_MTD_DB1X00 is not set + # CONFIG_MTD_PB1550 is not set + # CONFIG_MTD_HYDROGEN3 is not set +diff -uNr linux-old/arch/mips/defconfig-hydrogen3 linux/arch/mips/defconfig-hydrogen3 +--- linux-old/arch/mips/defconfig-hydrogen3 2004-11-24 12:11:51.000000000 +0100 ++++ linux/arch/mips/defconfig-hydrogen3 2006-04-30 18:55:34.601600500 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -214,6 +215,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + # CONFIG_MTD_DB1X00 is not set + # CONFIG_MTD_PB1550 is not set + CONFIG_MTD_HYDROGEN3=y +diff -uNr linux-old/arch/mips/defconfig-ip22 linux/arch/mips/defconfig-ip22 +--- linux-old/arch/mips/defconfig-ip22 2004-11-24 12:11:51.000000000 +0100 ++++ linux/arch/mips/defconfig-ip22 2006-04-30 18:55:37.781799250 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-it8172 linux/arch/mips/defconfig-it8172 +--- linux-old/arch/mips/defconfig-it8172 2004-11-24 12:11:51.000000000 +0100 ++++ linux/arch/mips/defconfig-it8172 2006-04-30 18:55:44.362210500 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -195,6 +196,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + # CONFIG_MTD_DB1X00 is not set + # CONFIG_MTD_PB1550 is not set + # CONFIG_MTD_HYDROGEN3 is not set +diff -uNr linux-old/arch/mips/defconfig-ivr linux/arch/mips/defconfig-ivr +--- linux-old/arch/mips/defconfig-ivr 2004-11-24 12:11:51.000000000 +0100 ++++ linux/arch/mips/defconfig-ivr 2006-04-30 18:55:47.746422000 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-jmr3927 linux/arch/mips/defconfig-jmr3927 +--- linux-old/arch/mips/defconfig-jmr3927 2004-11-24 12:11:51.000000000 +0100 ++++ linux/arch/mips/defconfig-jmr3927 2006-04-30 18:55:51.314645000 +0200 +@@ -32,6 +32,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-lasat linux/arch/mips/defconfig-lasat +--- linux-old/arch/mips/defconfig-lasat 2004-11-24 12:11:51.000000000 +0100 ++++ linux/arch/mips/defconfig-lasat 2006-04-30 18:55:56.730983500 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -198,6 +199,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + # CONFIG_MTD_DB1X00 is not set + # CONFIG_MTD_PB1550 is not set + # CONFIG_MTD_HYDROGEN3 is not set +diff -uNr linux-old/arch/mips/defconfig-malta linux/arch/mips/defconfig-malta +--- linux-old/arch/mips/defconfig-malta 2004-11-24 12:11:51.000000000 +0100 ++++ linux/arch/mips/defconfig-malta 2006-04-30 18:55:59.771173500 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-mirage linux/arch/mips/defconfig-mirage +--- linux-old/arch/mips/defconfig-mirage 2004-11-24 12:11:52.000000000 +0100 ++++ linux/arch/mips/defconfig-mirage 2006-04-30 18:56:06.291581000 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -209,6 +210,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + # CONFIG_MTD_DB1X00 is not set + # CONFIG_MTD_PB1550 is not set + # CONFIG_MTD_HYDROGEN3 is not set +diff -uNr linux-old/arch/mips/defconfig-mpc30x linux/arch/mips/defconfig-mpc30x +--- linux-old/arch/mips/defconfig-mpc30x 2004-11-24 12:11:52.000000000 +0100 ++++ linux/arch/mips/defconfig-mpc30x 2006-04-30 18:56:09.391774750 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-mtx-1 linux/arch/mips/defconfig-mtx-1 +--- linux-old/arch/mips/defconfig-mtx-1 2004-11-24 12:11:52.000000000 +0100 ++++ linux/arch/mips/defconfig-mtx-1 2006-04-30 18:56:26.612851000 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + CONFIG_MIPS_MTX1=y ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-nino linux/arch/mips/defconfig-nino +--- linux-old/arch/mips/defconfig-nino 2004-11-24 12:11:52.000000000 +0100 ++++ linux/arch/mips/defconfig-nino 2006-04-30 18:56:33.605288000 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-ocelot linux/arch/mips/defconfig-ocelot +--- linux-old/arch/mips/defconfig-ocelot 2004-11-24 12:11:52.000000000 +0100 ++++ linux/arch/mips/defconfig-ocelot 2006-04-30 18:56:41.721795250 +0200 +@@ -32,6 +32,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -194,6 +195,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + # CONFIG_MTD_DB1X00 is not set + # CONFIG_MTD_PB1550 is not set + # CONFIG_MTD_HYDROGEN3 is not set +diff -uNr linux-old/arch/mips/defconfig-osprey linux/arch/mips/defconfig-osprey +--- linux-old/arch/mips/defconfig-osprey 2004-11-24 12:11:52.000000000 +0100 ++++ linux/arch/mips/defconfig-osprey 2006-04-30 18:56:45.994062250 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/arch/mips/defconfig-pb1000 linux/arch/mips/defconfig-pb1000 +--- linux-old/arch/mips/defconfig-pb1000 2004-11-24 12:11:52.000000000 +0100 ++++ linux/arch/mips/defconfig-pb1000 2006-04-30 18:56:53.594537250 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -215,6 +216,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + # CONFIG_MTD_DB1X00 is not set + # CONFIG_MTD_PB1550 is not set + # CONFIG_MTD_HYDROGEN3 is not set +diff -uNr linux-old/garch/mips/defconfig-pb1100 linux/arch/mips/defconfig-pb1100 +--- linux-old/arch/mips/defconfig-pb1100 2004-11-24 12:11:52.000000000 +0100 ++++ linux/arch/mips/defconfig-pb1100 2006-04-30 18:56:59.990937000 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -196,6 +197,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + CONFIG_MTD_PB1500_BOOT=y + CONFIG_MTD_PB1500_USER=y + # CONFIG_MTD_DB1X00 is not set +diff -uNr linux-old/garch/mips/defconfig-pb1500 linux/arch/mips/defconfig-pb1500 +--- linux-old/arch/mips/defconfig-pb1500 2004-11-24 12:11:52.000000000 +0100 ++++ linux/arch/mips/defconfig-pb1500 2006-04-30 18:57:06.155322250 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -213,6 +214,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + CONFIG_MTD_PB1500_BOOT=y + # CONFIG_MTD_PB1500_USER is not set + # CONFIG_MTD_DB1X00 is not set +diff -uNr linux-old/garch/mips/defconfig-pb1550 linux/arch/mips/defconfig-pb1550 +--- linux-old/arch/mips/defconfig-pb1550 2004-11-24 12:11:52.000000000 +0100 ++++ linux/arch/mips/defconfig-pb1550 2006-04-30 18:57:12.627726750 +0200 +@@ -34,6 +34,7 @@ + CONFIG_MIPS_PB1550=y + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -213,6 +214,7 @@ + # CONFIG_MTD_BOSPORUS is not set + # CONFIG_MTD_XXS1500 is not set + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + # CONFIG_MTD_DB1X00 is not set + CONFIG_MTD_PB1550=y + CONFIG_MTD_PB1550_BOOT=y +diff -uNr linux-old/garch/mips/defconfig-rbtx4927 linux/arch/mips/defconfig-rbtx4927 +--- linux-old/arch/mips/defconfig-rbtx4927 2004-11-24 12:11:52.000000000 +0100 ++++ linux/arch/mips/defconfig-rbtx4927 2006-04-30 18:57:15.871929500 +0200 +@@ -32,6 +32,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips/defconfig-rm200 linux/arch/mips/defconfig-rm200 +--- linux-old/arch/mips/defconfig-rm200 2004-11-24 12:11:52.000000000 +0100 ++++ linux/arch/mips/defconfig-rm200 2006-04-30 18:57:19.128133000 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips/defconfig-sb1250-swarm linux/arch/mips/defconfig-sb1250-swarm +--- linux-old/arch/mips/defconfig-sb1250-swarm 2004-11-24 12:11:53.000000000 +0100 ++++ linux/arch/mips/defconfig-sb1250-swarm 2006-04-30 18:57:22.820363750 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips/defconfig-sead linux/arch/mips/defconfig-sead +--- linux-old/arch/mips/defconfig-sead 2004-11-24 12:11:53.000000000 +0100 ++++ linux/arch/mips/defconfig-sead 2006-04-30 18:57:28.392712000 +0200 +@@ -32,6 +32,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips/defconfig-stretch linux/arch/mips/defconfig-stretch +--- linux-old/arch/mips/defconfig-stretch 2004-11-10 02:32:57.000000000 +0100 ++++ linux/arch/mips/defconfig-stretch 2006-04-30 18:58:16.823738750 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips/defconfig-tb0226 linux/arch/mips/defconfig-tb0226 +--- linux-old/arch/mips/defconfig-tb0226 2004-11-24 12:11:53.000000000 +0100 ++++ linux/arch/mips/defconfig-tb0226 2006-04-30 18:57:32.156947250 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips/defconfig-tb0229 linux/arch/mips/defconfig-tb0229 +--- linux-old/arch/mips/defconfig-tb0229 2004-11-24 12:11:53.000000000 +0100 ++++ linux/arch/mips/defconfig-tb0229 2006-04-30 18:57:35.369148000 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips/defconfig-ti1500 linux/arch/mips/defconfig-ti1500 +--- linux-old/arch/mips/defconfig-ti1500 2004-11-24 12:11:53.000000000 +0100 ++++ linux/arch/mips/defconfig-ti1500 2006-04-30 18:57:42.681605000 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + CONFIG_MIPS_XXS1500=y + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -213,6 +214,7 @@ + # CONFIG_MTD_BOSPORUS is not set + CONFIG_MTD_XXS1500=y + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + # CONFIG_MTD_DB1X00 is not set + # CONFIG_MTD_PB1550 is not set + # CONFIG_MTD_HYDROGEN3 is not set +diff -uNr linux-old/garch/mips/defconfig-workpad linux/arch/mips/defconfig-workpad +--- linux-old/arch/mips/defconfig-workpad 2004-11-24 12:11:53.000000000 +0100 ++++ linux/arch/mips/defconfig-workpad 2006-04-30 18:57:46.913869500 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips/defconfig-xxs1500 linux/arch/mips/defconfig-xxs1500 +--- linux-old/arch/mips/defconfig-xxs1500 2004-11-24 12:11:53.000000000 +0100 ++++ linux/arch/mips/defconfig-xxs1500 2006-04-30 18:57:56.206450250 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + CONFIG_MIPS_XXS1500=y + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +@@ -213,6 +214,7 @@ + # CONFIG_MTD_BOSPORUS is not set + CONFIG_MTD_XXS1500=y + # CONFIG_MTD_MTX1 is not set ++# CONFIG_MTD_MTX2 is not set + # CONFIG_MTD_DB1X00 is not set + # CONFIG_MTD_PB1550 is not set + # CONFIG_MTD_HYDROGEN3 is not set +diff -uNr linux-old/garch/mips/defconfig-yosemite linux/arch/mips/defconfig-yosemite +--- linux-old/arch/mips/defconfig-yosemite 2004-11-24 12:11:53.000000000 +0100 ++++ linux/arch/mips/defconfig-yosemite 2006-04-30 18:57:59.338646000 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips64/defconfig linux/arch/mips64/defconfig +--- linux-old/arch/mips64/defconfig 2004-11-24 12:11:59.000000000 +0100 ++++ linux/arch/mips64/defconfig 2006-04-30 18:58:19.915932000 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips64/defconfig-atlas linux/arch/mips64/defconfig-atlas +--- linux-old/arch/mips64/defconfig-atlas 2004-11-24 12:11:59.000000000 +0100 ++++ linux/arch/mips64/defconfig-atlas 2006-04-30 18:58:25.160259750 +0200 +@@ -32,6 +32,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips64/defconfig-decstation linux/arch/mips64/defconfig-decstation +--- linux-old/arch/mips64/defconfig-decstation 2004-11-24 12:11:59.000000000 +0100 ++++ linux/arch/mips64/defconfig-decstation 2006-04-30 18:58:31.416650750 +0200 +@@ -32,6 +32,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips64/defconfig-ip22 linux/arch/mips64/defconfig-ip22 +--- linux-old/arch/mips64/defconfig-ip22 2004-11-24 12:11:59.000000000 +0100 ++++ linux/arch/mips64/defconfig-ip22 2006-04-30 18:58:34.396837000 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips64/defconfig-ip27 linux/arch/mips64/defconfig-ip27 +--- linux-old/arch/mips64/defconfig-ip27 2004-11-24 12:11:59.000000000 +0100 ++++ linux/arch/mips64/defconfig-ip27 2006-04-30 18:58:37.477029500 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips64/defconfig-jaguar linux/arch/mips64/defconfig-jaguar +--- linux-old/arch/mips64/defconfig-jaguar 2004-11-24 12:11:59.000000000 +0100 ++++ linux/arch/mips64/defconfig-jaguar 2006-04-30 18:58:40.977248250 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips64/defconfig-malta linux/arch/mips64/defconfig-malta +--- linux-old/arch/mips64/defconfig-malta 2004-11-24 12:11:59.000000000 +0100 ++++ linux/arch/mips64/defconfig-malta 2006-04-30 18:58:44.281454750 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips64/defconfig-ocelotc linux/arch/mips64/defconfig-ocelotc +--- linux-old/arch/mips64/defconfig-ocelotc 2004-11-24 12:11:59.000000000 +0100 ++++ linux/arch/mips64/defconfig-ocelotc 2006-04-30 18:58:47.137633250 +0200 +@@ -33,7 +33,7 @@ + # CONFIG_MIPS_HYDROGEN3 is not set + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set +-# CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips64/defconfig-sb1250-swarm linux/arch/mips64/defconfig-sb1250-swarm +--- linux-old/arch/mips64/defconfig-sb1250-swarm 2004-11-24 12:11:59.000000000 +0100 ++++ linux/arch/mips64/defconfig-sb1250-swarm 2006-04-30 18:58:50.077817000 +0200 +@@ -34,6 +34,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/garch/mips64/defconfig-sead linux/arch/mips64/defconfig-sead +--- linux-old/arch/mips64/defconfig-sead 2004-11-24 12:11:59.000000000 +0100 ++++ linux/arch/mips64/defconfig-sead 2006-04-30 18:58:52.893993000 +0200 +@@ -32,6 +32,7 @@ + # CONFIG_MIPS_PB1550 is not set + # CONFIG_MIPS_XXS1500 is not set + # CONFIG_MIPS_MTX1 is not set ++# CONFIG_MIPS_MTX2 is not set + # CONFIG_COGENT_CSB250 is not set + # CONFIG_BAGET_MIPS is not set + # CONFIG_CASIO_E55 is not set +diff -uNr linux-old/gdrivers/mtd/maps/Config.in linux/drivers/mtd/maps/Config.in +--- linux-old/drivers/mtd/maps/Config.in 2004-11-24 12:12:41.000000000 +0100 ++++ linux/drivers/mtd/maps/Config.in 2006-04-30 18:59:02.642602250 +0200 +@@ -54,6 +54,7 @@ + dep_tristate ' Bosporus MTD support' CONFIG_MTD_BOSPORUS $CONFIG_MIPS_BOSPORUS + dep_tristate ' XXS1500 boot flash device' CONFIG_MTD_XXS1500 $CONFIG_MIPS_XXS1500 + dep_tristate ' MTX-1 flash device' CONFIG_MTD_MTX1 $CONFIG_MIPS_MTX1 ++ dep_tristate ' MTX-2 flash device' CONFIG_MTD_MTX2 $CONFIG_MIPS_MTX2 + if [ "$CONFIG_MTD_PB1500" = "y" -o "$CONFIG_MTD_PB1500" = "m" \ + -o "$CONFIG_MTD_PB1100" = "y" -o "$CONFIG_MTD_PB1100" = "m" ]; then + bool ' Pb[15]00 boot flash device' CONFIG_MTD_PB1500_BOOT +diff -uNr linux-old/gdrivers/mtd/maps/Makefile linux/drivers/mtd/maps/Makefile +--- linux-old/drivers/mtd/maps/Makefile 2004-11-24 12:12:41.000000000 +0100 ++++ linux/drivers/mtd/maps/Makefile 2006-04-30 18:51:08.540972750 +0200 +@@ -54,6 +54,7 @@ + obj-$(CONFIG_MTD_PB1500) += pb1xxx-flash.o + obj-$(CONFIG_MTD_XXS1500) += xxs1500.o + obj-$(CONFIG_MTD_MTX1) += mtx-1.o ++obj-$(CONFIG_MTD_MTX2) += mtx-2.o + obj-$(CONFIG_MTD_LASAT) += lasat.o + obj-$(CONFIG_MTD_DB1X00) += db1x00-flash.o + obj-$(CONFIG_MTD_PB1550) += pb1550-flash.o +diff -Nur linux-old/Documentation/Configure.help linux/Documentation/Configure.help +--- linux-old/Documentation/Configure.help 2006-03-21 19:18:40.000000000 +0100 ++++ linux/Documentation/Configure.help 2006-04-27 18:10:01.000000000 +0200 +@@ -2631,6 +2631,16 @@ + kernel built with this option will not run on any other type of + processor or vice versa. + ++4G-Systems MTX-1 ++CONFIG_MIPS_MTX1 ++ Select this if you intend to compile the kernel for use in a ++ 4G-Systems Access Cube or SurfBoxI. ++ ++4G-Systems MTX-2 ++CONFIG_MIPS_MTX2 ++ Select this if you intend to compile the kernel for use in a ++ 4G-Systems SurfBoxII ++ + CPU feature configuration + CONFIG_CPU_ADVANCED + Saying yes here allows you to select support for various features +--- linux-old/arch/mips/defconfig-mtx-2 1970-01-01 01:00:00.000000000 +0100 ++++ linux/arch/mips/defconfig-mtx-2 2006-04-30 20:35:58.000000000 +0200 +@@ -0,0 +1,1456 @@ ++# ++# Automatically generated make config: don't edit ++# ++CONFIG_MIPS=y ++CONFIG_MIPS32=y ++# CONFIG_MIPS64 is not set ++ ++# ++# Code maturity level options ++# ++CONFIG_EXPERIMENTAL=y ++ ++# ++# Loadable module support ++# ++CONFIG_MODULES=y ++# CONFIG_MODVERSIONS is not set ++CONFIG_KMOD=y ++ ++# ++# Machine selection ++# ++# CONFIG_ACER_PICA_61 is not set ++# CONFIG_MIPS_BOSPORUS is not set ++# CONFIG_MIPS_MIRAGE is not set ++# CONFIG_MIPS_DB1000 is not set ++# CONFIG_MIPS_DB1100 is not set ++# CONFIG_MIPS_DB1500 is not set ++# CONFIG_MIPS_DB1550 is not set ++# CONFIG_MIPS_PB1000 is not set ++# CONFIG_MIPS_PB1100 is not set ++# CONFIG_MIPS_PB1500 is not set ++# CONFIG_MIPS_HYDROGEN3 is not set ++# CONFIG_MIPS_PB1550 is not set ++# CONFIG_MIPS_XXS1500 is not set ++CONFIG_MIPS_MTX1=y ++# CONFIG_COGENT_CSB250 is not set ++# CONFIG_BAGET_MIPS is not set ++# CONFIG_CASIO_E55 is not set ++# CONFIG_MIPS_COBALT is not set ++# CONFIG_DECSTATION is not set ++# CONFIG_MIPS_EV64120 is not set ++# CONFIG_MIPS_EV96100 is not set ++# CONFIG_MIPS_IVR is not set ++# CONFIG_HP_LASERJET is not set ++# CONFIG_IBM_WORKPAD is not set ++# CONFIG_LASAT is not set ++# CONFIG_MIPS_ITE8172 is not set ++# CONFIG_MIPS_ATLAS is not set ++# CONFIG_MIPS_MAGNUM_4000 is not set ++# CONFIG_MIPS_MALTA is not set ++# CONFIG_MIPS_SEAD is not set ++# CONFIG_MOMENCO_OCELOT is not set ++# CONFIG_MOMENCO_OCELOT_G is not set ++# CONFIG_MOMENCO_OCELOT_C is not set ++# CONFIG_MOMENCO_JAGUAR_ATX is not set ++# CONFIG_PMC_BIG_SUR is not set ++# CONFIG_PMC_STRETCH is not set ++# CONFIG_PMC_YOSEMITE is not set ++# CONFIG_DDB5074 is not set ++# CONFIG_DDB5476 is not set ++# CONFIG_DDB5477 is not set ++# CONFIG_NEC_OSPREY is not set ++# CONFIG_NEC_EAGLE is not set ++# CONFIG_OLIVETTI_M700 is not set ++# CONFIG_NINO is not set ++# CONFIG_SGI_IP22 is not set ++# CONFIG_SGI_IP27 is not set ++# CONFIG_SIBYTE_SB1xxx_SOC is not set ++# CONFIG_SNI_RM200_PCI is not set ++# CONFIG_TANBAC_TB0226 is not set ++# CONFIG_TANBAC_TB0229 is not set ++# CONFIG_TOSHIBA_JMR3927 is not set ++# CONFIG_TOSHIBA_RBTX4927 is not set ++# CONFIG_VICTOR_MPC30X is not set ++# CONFIG_ZAO_CAPCELLA is not set ++# CONFIG_HIGHMEM is not set ++CONFIG_RWSEM_GENERIC_SPINLOCK=y ++# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set ++CONFIG_SOC_AU1X00=y ++CONFIG_SOC_AU1500=y ++CONFIG_NONCOHERENT_IO=y ++# CONFIG_MIPS_AU1000 is not set ++ ++# ++# CPU selection ++# ++CONFIG_CPU_MIPS32=y ++# CONFIG_CPU_MIPS64 is not set ++# CONFIG_CPU_R3000 is not set ++# CONFIG_CPU_TX39XX is not set ++# CONFIG_CPU_VR41XX is not set ++# CONFIG_CPU_R4300 is not set ++# CONFIG_CPU_R4X00 is not set ++# CONFIG_CPU_TX49XX is not set ++# CONFIG_CPU_R5000 is not set ++# CONFIG_CPU_R5432 is not set ++# CONFIG_CPU_R6000 is not set ++# CONFIG_CPU_NEVADA is not set ++# CONFIG_CPU_R8000 is not set ++# CONFIG_CPU_R10000 is not set ++# CONFIG_CPU_RM7000 is not set ++# CONFIG_CPU_RM9000 is not set ++# CONFIG_CPU_SB1 is not set ++CONFIG_PAGE_SIZE_4KB=y ++# CONFIG_PAGE_SIZE_16KB is not set ++# CONFIG_PAGE_SIZE_64KB is not set ++CONFIG_CPU_HAS_PREFETCH=y ++# CONFIG_VTAG_ICACHE is not set ++CONFIG_64BIT_PHYS_ADDR=y ++# CONFIG_CPU_ADVANCED is not set ++CONFIG_CPU_HAS_LLSC=y ++# CONFIG_CPU_HAS_LLDSCD is not set ++# CONFIG_CPU_HAS_WB is not set ++CONFIG_CPU_HAS_SYNC=y ++ ++# ++# General setup ++# ++CONFIG_CPU_LITTLE_ENDIAN=y ++# CONFIG_BUILD_ELF64 is not set ++CONFIG_NET=y ++CONFIG_PCI=y ++CONFIG_PCI_NEW=y ++CONFIG_PCI_AUTO=y ++CONFIG_PCI_NAMES=y ++# CONFIG_ISA is not set ++# CONFIG_TC is not set ++# CONFIG_MCA is not set ++# CONFIG_SBUS is not set ++CONFIG_HOTPLUG=y ++ ++# ++# PCMCIA/CardBus support ++# ++CONFIG_PCMCIA=m ++CONFIG_CARDBUS=y ++# CONFIG_TCIC is not set ++# CONFIG_I82092 is not set ++# CONFIG_I82365 is not set ++# CONFIG_PCMCIA_AU1X00 is not set ++ ++# ++# PCI Hotplug Support ++# ++# CONFIG_HOTPLUG_PCI is not set ++# CONFIG_HOTPLUG_PCI_COMPAQ is not set ++# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set ++# CONFIG_HOTPLUG_PCI_SHPC is not set ++# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set ++# CONFIG_HOTPLUG_PCI_PCIE is not set ++# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set ++CONFIG_SYSVIPC=y ++# CONFIG_BSD_PROCESS_ACCT is not set ++CONFIG_SYSCTL=y ++CONFIG_KCORE_ELF=y ++# CONFIG_KCORE_AOUT is not set ++# CONFIG_BINFMT_AOUT is not set ++CONFIG_BINFMT_ELF=y ++# CONFIG_MIPS32_COMPAT is not set ++# CONFIG_MIPS32_O32 is not set ++# CONFIG_MIPS32_N32 is not set ++# CONFIG_BINFMT_ELF32 is not set ++CONFIG_BINFMT_MISC=y ++# CONFIG_OOM_KILLER is not set ++# CONFIG_CMDLINE_BOOL is not set ++# CONFIG_PM is not set ++ ++# ++# Memory Technology Devices (MTD) ++# ++CONFIG_MTD=y ++# CONFIG_MTD_DEBUG is not set ++CONFIG_MTD_PARTITIONS=y ++# CONFIG_MTD_CONCAT is not set ++# CONFIG_MTD_REDBOOT_PARTS is not set ++# CONFIG_MTD_CMDLINE_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_CHAR=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++CONFIG_MTD_CFI=y ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_GEN_PROBE=y ++# CONFIG_MTD_CFI_ADV_OPTIONS is not set ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_AMDSTD_RETRY=y ++CONFIG_MTD_CFI_AMDSTD_RETRY_MAX=5 ++# CONFIG_MTD_CFI_STAA is not set ++CONFIG_MTD_CFI_UTIL=y ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++# CONFIG_MTD_OBSOLETE_CHIPS is not set ++# CONFIG_MTD_AMDSTD is not set ++# CONFIG_MTD_SHARP is not set ++# CONFIG_MTD_JEDEC is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_PHYSMAP is not set ++# CONFIG_MTD_DB1X00 is not set ++CONFIG_MTD_MTX1=y ++# CONFIG_MTD_CSTM_MIPS_IXX is not set ++# CONFIG_MTD_OCELOT is not set ++# CONFIG_MTD_LASAT is not set ++# CONFIG_MTD_PCI is not set ++# CONFIG_MTD_PCMCIA is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_PMC551 is not set ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLKMTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOC2000 is not set ++# CONFIG_MTD_DOC2001 is not set ++# CONFIG_MTD_DOC2001PLUS is not set ++# CONFIG_MTD_DOCPROBE is not set ++ ++# ++# NAND Flash Device Drivers ++# ++# CONFIG_MTD_NAND is not set ++ ++# ++# Parallel port support ++# ++# CONFIG_PARPORT is not set ++ ++# ++# Plug and Play configuration ++# ++# CONFIG_PNP is not set ++# CONFIG_ISAPNP is not set ++ ++# ++# Block devices ++# ++# CONFIG_BLK_DEV_FD is not set ++# CONFIG_BLK_DEV_XD is not set ++# CONFIG_PARIDE is not set ++# CONFIG_BLK_CPQ_DA is not set ++# CONFIG_BLK_CPQ_CISS_DA is not set ++# CONFIG_CISS_SCSI_TAPE is not set ++# CONFIG_CISS_MONITOR_THREAD is not set ++# CONFIG_BLK_DEV_DAC960 is not set ++# CONFIG_BLK_DEV_UMEM is not set ++# CONFIG_BLK_DEV_SX8 is not set ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=m ++CONFIG_BLK_DEV_RAM_SIZE=4096 ++# CONFIG_BLK_DEV_INITRD is not set ++# CONFIG_BLK_STATS is not set ++ ++# ++# Multi-device support (RAID and LVM) ++# ++# CONFIG_MD is not set ++# CONFIG_BLK_DEV_MD is not set ++# CONFIG_MD_LINEAR is not set ++# CONFIG_MD_RAID0 is not set ++# CONFIG_MD_RAID1 is not set ++# CONFIG_MD_RAID5 is not set ++# CONFIG_MD_MULTIPATH is not set ++# CONFIG_BLK_DEV_LVM is not set ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++CONFIG_PACKET_MMAP=y ++CONFIG_NETLINK_DEV=m ++CONFIG_NETFILTER=y ++# CONFIG_NETFILTER_DEBUG is not set ++CONFIG_FILTER=y ++CONFIG_UNIX=y ++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=y ++CONFIG_IP_PNP_DHCP=y ++# CONFIG_IP_PNP_BOOTP is not set ++# CONFIG_IP_PNP_RARP 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_INET_ECN is not set ++CONFIG_SYN_COOKIES=y ++ ++# ++# IP: Netfilter Configuration ++# ++CONFIG_IP_NF_CONNTRACK=y ++CONFIG_IP_NF_FTP=m ++CONFIG_IP_NF_AMANDA=m ++CONFIG_IP_NF_TFTP=m ++CONFIG_IP_NF_IRC=m ++CONFIG_IP_NF_QUEUE=m ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_LIMIT=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=y ++CONFIG_IP_NF_MATCH_CONNTRACK=y ++CONFIG_IP_NF_MATCH_UNCLEAN=m ++CONFIG_IP_NF_MATCH_OWNER=m ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_TARGET_MIRROR=m ++CONFIG_IP_NF_NAT=y ++CONFIG_IP_NF_NAT_NEEDED=y ++CONFIG_IP_NF_TARGET_MASQUERADE=y ++CONFIG_IP_NF_TARGET_REDIRECT=y ++CONFIG_IP_NF_NAT_AMANDA=m ++# CONFIG_IP_NF_NAT_LOCAL is not set ++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_MANGLE=y ++CONFIG_IP_NF_TARGET_TOS=m ++CONFIG_IP_NF_TARGET_ECN=m ++CONFIG_IP_NF_TARGET_DSCP=m ++CONFIG_IP_NF_TARGET_MARK=y ++CONFIG_IP_NF_TARGET_LOG=y ++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 ++ ++# ++# IP: Virtual Server Configuration ++# ++# CONFIG_IP_VS is not set ++CONFIG_IPV6=m ++ ++# ++# IPv6: Netfilter Configuration ++# ++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_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_KHTTPD is not set ++ ++# ++# SCTP Configuration (EXPERIMENTAL) ++# ++# CONFIG_IP_SCTP is not set ++# CONFIG_ATM is not set ++CONFIG_VLAN_8021Q=m ++ ++# ++# ++# ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++ ++# ++# Appletalk devices ++# ++# CONFIG_DEV_APPLETALK is not set ++# CONFIG_DECNET is not set ++CONFIG_BRIDGE=m ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_LLC is not set ++# CONFIG_NET_DIVERT is not set ++# CONFIG_ECONET is not set ++# CONFIG_WAN_ROUTER is not set ++# CONFIG_NET_FASTROUTE is not set ++# CONFIG_NET_HW_FLOWCONTROL 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_HFSC is not set ++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_NETEM is not set ++CONFIG_NET_SCH_DSMARK=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 ++ ++# ++# Network testing ++# ++CONFIG_NET_PKTGEN=m ++CONFIG_IPSEC_NAT_TRAVERSAL=y ++CONFIG_IPSEC=m ++ ++# ++# IPSec options (Openswan) ++# ++CONFIG_IPSEC_IPIP=y ++CONFIG_IPSEC_AH=y ++CONFIG_IPSEC_AUTH_HMAC_MD5=y ++CONFIG_IPSEC_AUTH_HMAC_SHA1=y ++CONFIG_IPSEC_ESP=y ++CONFIG_IPSEC_ENC_3DES=y ++CONFIG_IPSEC_ENC_AES=y ++CONFIG_IPSEC_ALG=y ++CONFIG_IPSEC_ALG_AES=m ++CONFIG_IPSEC_ALG_CRYPTOAPI=m ++CONFIG_IPSEC_ALG_NON_LIBRE=y ++CONFIG_IPSEC_IPCOMP=y ++CONFIG_IPSEC_DEBUG=y ++ ++# ++# Telephony Support ++# ++# CONFIG_PHONE is not set ++# CONFIG_PHONE_IXJ is not set ++# CONFIG_PHONE_IXJ_PCMCIA is not set ++ ++# ++# ATA/IDE/MFM/RLL support ++# ++# CONFIG_IDE is not set ++# CONFIG_BLK_DEV_HD is not set ++ ++# ++# SCSI support ++# ++CONFIG_SCSI=m ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=m ++CONFIG_SD_EXTRA_DEVS=40 ++# CONFIG_CHR_DEV_ST is not set ++# CONFIG_CHR_DEV_OSST is not set ++CONFIG_BLK_DEV_SR=m ++# CONFIG_BLK_DEV_SR_VENDOR is not set ++CONFIG_SR_EXTRA_DEVS=2 ++# CONFIG_CHR_DEV_SG is not set ++ ++# ++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs ++# ++# CONFIG_SCSI_DEBUG_QUEUES is not set ++# CONFIG_SCSI_MULTI_LUN is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_LOGGING is not set ++ ++# ++# SCSI low-level drivers ++# ++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set ++# CONFIG_SCSI_7000FASST is not set ++# CONFIG_SCSI_ACARD is not set ++# CONFIG_SCSI_AHA152X is not set ++# CONFIG_SCSI_AHA1542 is not set ++# CONFIG_SCSI_AHA1740 is not set ++# CONFIG_SCSI_AACRAID is not set ++# CONFIG_SCSI_AIC7XXX is not set ++# CONFIG_SCSI_AIC79XX is not set ++# CONFIG_SCSI_AIC7XXX_OLD is not set ++# CONFIG_SCSI_DPT_I2O is not set ++# CONFIG_SCSI_ADVANSYS is not set ++# CONFIG_SCSI_IN2000 is not set ++# CONFIG_SCSI_AM53C974 is not set ++# CONFIG_SCSI_MEGARAID is not set ++# CONFIG_SCSI_MEGARAID2 is not set ++# CONFIG_SCSI_SATA is not set ++# CONFIG_SCSI_SATA_SVW is not set ++# CONFIG_SCSI_SATA_PROMISE is not set ++# CONFIG_SCSI_SATA_SX4 is not set ++# CONFIG_SCSI_SATA_SIL is not set ++# CONFIG_SCSI_SATA_SIS is not set ++# CONFIG_SCSI_SATA_VIA is not set ++# CONFIG_SCSI_SATA_VITESSE is not set ++# CONFIG_SCSI_BUSLOGIC 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_DMA is not set ++# CONFIG_SCSI_EATA_PIO is not set ++# CONFIG_SCSI_FUTURE_DOMAIN is not set ++# CONFIG_SCSI_GDTH is not set ++# CONFIG_SCSI_GENERIC_NCR5380 is not set ++# CONFIG_SCSI_INITIO is not set ++# CONFIG_SCSI_INIA100 is not set ++# CONFIG_SCSI_NCR53C406A is not set ++# CONFIG_SCSI_NCR53C7xx is not set ++# CONFIG_SCSI_SYM53C8XX_2 is not set ++# CONFIG_SCSI_NCR53C8XX is not set ++# CONFIG_SCSI_SYM53C8XX is not set ++# CONFIG_SCSI_PAS16 is not set ++# CONFIG_SCSI_PCI2000 is not set ++# CONFIG_SCSI_PCI2220I is not set ++# CONFIG_SCSI_PSI240I is not set ++# CONFIG_SCSI_QLOGIC_FAS is not set ++# CONFIG_SCSI_QLOGIC_ISP is not set ++# CONFIG_SCSI_QLOGIC_FC is not set ++# CONFIG_SCSI_QLOGIC_1280 is not set ++# CONFIG_SCSI_SIM710 is not set ++# CONFIG_SCSI_SYM53C416 is not set ++# CONFIG_SCSI_DC390T is not set ++# CONFIG_SCSI_T128 is not set ++# CONFIG_SCSI_U14_34F is not set ++# CONFIG_SCSI_NSP32 is not set ++# CONFIG_SCSI_DEBUG is not set ++ ++# ++# PCMCIA SCSI adapter support ++# ++# CONFIG_SCSI_PCMCIA is not set ++ ++# ++# Fusion MPT device support ++# ++# CONFIG_FUSION is not set ++# CONFIG_FUSION_BOOT is not set ++# CONFIG_FUSION_ISENSE is not set ++# CONFIG_FUSION_CTL is not set ++# CONFIG_FUSION_LAN is not set ++ ++# ++# IEEE 1394 (FireWire) support (EXPERIMENTAL) ++# ++# CONFIG_IEEE1394 is not set ++ ++# ++# I2O device support ++# ++# CONFIG_I2O is not set ++# CONFIG_I2O_PCI is not set ++# CONFIG_I2O_BLOCK is not set ++# CONFIG_I2O_LAN is not set ++# CONFIG_I2O_SCSI is not set ++# CONFIG_I2O_PROC is not set ++ ++# ++# Network device support ++# ++CONFIG_NETDEVICES=y ++ ++# ++# ARCnet devices ++# ++# CONFIG_ARCNET is not set ++CONFIG_DUMMY=m ++CONFIG_BONDING=m ++# CONFIG_EQUALIZER is not set ++CONFIG_TUN=m ++# CONFIG_ETHERTAP is not set ++ ++# ++# Ethernet (10 or 100Mbit) ++# ++CONFIG_NET_ETHERNET=y ++CONFIG_MIPS_AU1X00_ENET=y ++# CONFIG_BCM5222_DUAL_PHY is not set ++# CONFIG_SUNLANCE is not set ++# CONFIG_HAPPYMEAL is not set ++# CONFIG_SUNBMAC is not set ++# CONFIG_SUNQE is not set ++# CONFIG_SUNGEM is not set ++# CONFIG_NET_VENDOR_3COM is not set ++# CONFIG_LANCE is not set ++# CONFIG_NET_VENDOR_SMC is not set ++# CONFIG_NET_VENDOR_RACAL is not set ++# CONFIG_HP100 is not set ++# CONFIG_NET_ISA is not set ++# CONFIG_NET_PCI is not set ++# CONFIG_NET_POCKET is not set ++ ++# ++# Ethernet (1000 Mbit) ++# ++# CONFIG_ACENIC is not set ++# CONFIG_DL2K is not set ++# CONFIG_E1000 is not set ++# CONFIG_MYRI_SBUS is not set ++# CONFIG_NS83820 is not set ++# CONFIG_HAMACHI is not set ++# CONFIG_YELLOWFIN is not set ++# CONFIG_R8169 is not set ++# CONFIG_SK98LIN is not set ++# CONFIG_TIGON3 is not set ++# CONFIG_FDDI is not set ++# CONFIG_HIPPI is not set ++# CONFIG_PLIP is not set ++CONFIG_PPP=y ++CONFIG_PPP_MULTILINK=y ++CONFIG_PPP_FILTER=y ++CONFIG_PPP_ASYNC=y ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_PPPOE=m ++# CONFIG_SLIP is not set ++ ++# ++# Wireless LAN (non-hamradio) ++# ++CONFIG_NET_RADIO=y ++# CONFIG_STRIP is not set ++# CONFIG_WAVELAN is not set ++# CONFIG_ARLAN is not set ++CONFIG_AIRONET4500=m ++CONFIG_AIRONET4500_NONCS=m ++# CONFIG_AIRONET4500_PNP is not set ++CONFIG_AIRONET4500_PCI=y ++# CONFIG_AIRONET4500_ISA is not set ++# CONFIG_AIRONET4500_I365 is not set ++CONFIG_AIRONET4500_PROC=m ++CONFIG_AIRO=m ++# CONFIG_HERMES is not set ++# CONFIG_PLX_HERMES is not set ++# CONFIG_TMD_HERMES is not set ++# CONFIG_PCI_HERMES is not set ++ ++# ++# Wireless Pcmcia cards support ++# ++# CONFIG_PCMCIA_HERMES is not set ++# CONFIG_AIRO_CS is not set ++# CONFIG_PCMCIA_ATMEL is not set ++CONFIG_NET_WIRELESS=y ++ ++# ++# Token Ring devices ++# ++# CONFIG_TR is not set ++# CONFIG_NET_FC is not set ++# CONFIG_RCPCI is not set ++CONFIG_SHAPER=m ++ ++# ++# Wan interfaces ++# ++# CONFIG_WAN is not set ++ ++# ++# PCMCIA network device support ++# ++# CONFIG_NET_PCMCIA is not set ++ ++# ++# Amateur Radio support ++# ++# CONFIG_HAMRADIO is not set ++ ++# ++# IrDA (infrared) support ++# ++# CONFIG_IRDA is not set ++ ++# ++# ISDN subsystem ++# ++# CONFIG_ISDN is not set ++ ++# ++# Input core support ++# ++# CONFIG_INPUT is not set ++# CONFIG_INPUT_KEYBDEV is not set ++# CONFIG_INPUT_MOUSEDEV is not set ++# CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_EVDEV is not set ++# CONFIG_INPUT_UINPUT is not set ++ ++# ++# Character devices ++# ++# CONFIG_VT is not set ++# CONFIG_SERIAL is not set ++# CONFIG_SERIAL_EXTENDED is not set ++CONFIG_SERIAL_NONSTANDARD=y ++# CONFIG_COMPUTONE is not set ++# CONFIG_ROCKETPORT 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_ISI is not set ++# CONFIG_SYNCLINK is not set ++# CONFIG_SYNCLINKMP is not set ++# CONFIG_N_HDLC is not set ++# 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 ++# CONFIG_SERIAL_TX3912 is not set ++# CONFIG_SERIAL_TX3912_CONSOLE is not set ++# CONFIG_SERIAL_TXX9 is not set ++# CONFIG_SERIAL_TXX9_CONSOLE is not set ++CONFIG_AU1X00_UART=y ++CONFIG_AU1X00_SERIAL_CONSOLE=y ++# CONFIG_TXX927_SERIAL is not set ++# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set ++CONFIG_UNIX98_PTYS=y ++CONFIG_UNIX98_PTY_COUNT=256 ++ ++# ++# I2C support ++# ++CONFIG_I2C=m ++CONFIG_I2C_ALGOBIT=m ++# CONFIG_I2C_PHILIPSPAR is not set ++# CONFIG_I2C_ELV is not set ++# CONFIG_I2C_VELLEMAN is not set ++# CONFIG_SCx200_I2C is not set ++CONFIG_I2C_AU1X00GPIO=m ++CONFIG_I2C_AU1X00GPIO_SCL=206 ++CONFIG_I2C_AU1X00GPIO_SDA=207 ++# CONFIG_SCx200_ACB is not set ++# CONFIG_I2C_ALGOPCF is not set ++# CONFIG_I2C_MAINBOARD is not set ++CONFIG_I2C_CHARDEV=m ++CONFIG_I2C_PROC=m ++ ++# ++# Hardware sensors support ++# ++CONFIG_SENSORS=y ++# CONFIG_SENSORS_ADM1021 is not set ++# CONFIG_SENSORS_ADM1024 is not set ++# CONFIG_SENSORS_ADM1025 is not set ++# CONFIG_SENSORS_ADM1026 is not set ++# CONFIG_SENSORS_ADM9240 is not set ++# CONFIG_SENSORS_ASB100 is not set ++# CONFIG_SENSORS_DS1621 is not set ++# CONFIG_SENSORS_FSCPOS is not set ++# CONFIG_SENSORS_FSCSCY is not set ++# CONFIG_SENSORS_GL518SM is not set ++# CONFIG_SENSORS_GL520SM is not set ++# CONFIG_SENSORS_MAXILIFE is not set ++# CONFIG_SENSORS_XEONTEMP is not set ++# CONFIG_SENSORS_IT87 is not set ++# CONFIG_SENSORS_MAX6650 is not set ++# CONFIG_SENSORS_MTP008 is not set ++CONFIG_SENSORS_LM75=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_PC87360=m ++# CONFIG_SENSORS_SIS5595 is not set ++# CONFIG_SENSORS_SMSC47M1 is not set ++# CONFIG_SENSORS_THMC50 is not set ++# CONFIG_SENSORS_VIA686A is not set ++# CONFIG_SENSORS_VT1211 is not set ++# CONFIG_SENSORS_VT8231 is not set ++# CONFIG_SENSORS_W83781D is not set ++# CONFIG_SENSORS_W83627HF is not set ++# CONFIG_SENSORS_W83L785TS is not set ++CONFIG_SENSORS_OTHER=y ++CONFIG_SENSORS_BT869=m ++CONFIG_SENSORS_DDCMON=m ++CONFIG_SENSORS_EEPROM=m ++CONFIG_SENSORS_MATORB=m ++CONFIG_SENSORS_PCF8574=m ++CONFIG_SENSORS_PCF8591=m ++ ++# ++# Mice ++# ++# CONFIG_BUSMOUSE is not set ++# CONFIG_MOUSE is not set ++ ++# ++# Joysticks ++# ++# CONFIG_INPUT_GAMEPORT is not set ++ ++# ++# Input core support is needed for gameports ++# ++ ++# ++# Input core support is needed for joysticks ++# ++# CONFIG_QIC02_TAPE is not set ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_IPMI_PANIC_EVENT is not set ++# CONFIG_IPMI_DEVICE_INTERFACE is not set ++# CONFIG_IPMI_KCS is not set ++# CONFIG_IPMI_WATCHDOG is not set ++ ++# ++# Watchdog Cards ++# ++# CONFIG_WATCHDOG is not set ++# CONFIG_SCx200 is not set ++# CONFIG_SCx200_GPIO is not set ++# CONFIG_AMD_PM768 is not set ++# CONFIG_NVRAM is not set ++# CONFIG_RTC is not set ++# CONFIG_DTLK is not set ++# CONFIG_R3964 is not set ++# CONFIG_APPLICOM is not set ++ ++# ++# Ftape, the floppy tape device driver ++# ++# CONFIG_FTAPE is not set ++# CONFIG_AGP is not set ++ ++# ++# Direct Rendering Manager (XFree86 DRI support) ++# ++# CONFIG_DRM is not set ++ ++# ++# PCMCIA character devices ++# ++# CONFIG_PCMCIA_SERIAL_CS is not set ++# CONFIG_SYNCLINK_CS is not set ++CONFIG_AU1X00_GPIO=m ++# CONFIG_TS_AU1X00_ADS7846 is not set ++ ++# ++# File systems ++# ++# CONFIG_QUOTA is not set ++# CONFIG_QFMT_V2 is not set ++# CONFIG_AUTOFS_FS is not set ++# CONFIG_AUTOFS4_FS is not set ++CONFIG_REISERFS_FS=m ++# CONFIG_REISERFS_CHECK is not set ++# CONFIG_REISERFS_PROC_INFO is not set ++# CONFIG_ADFS_FS is not set ++# CONFIG_ADFS_FS_RW is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BEFS_DEBUG is not set ++# CONFIG_BFS_FS is not set ++CONFIG_EXT3_FS=m ++CONFIG_JBD=m ++# CONFIG_JBD_DEBUG is not set ++CONFIG_FAT_FS=m ++CONFIG_MSDOS_FS=m ++# CONFIG_UMSDOS_FS is not set ++CONFIG_VFAT_FS=m ++# CONFIG_EFS_FS is not set ++# CONFIG_JFFS_FS is not set ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++# CONFIG_JFFS2_FS_NAND is not set ++# CONFIG_CRAMFS is not set ++CONFIG_TMPFS=y ++CONFIG_RAMFS=y ++CONFIG_ISO9660_FS=m ++CONFIG_JOLIET=y ++CONFIG_ZISOFS=y ++# CONFIG_JFS_FS is not set ++# CONFIG_JFS_DEBUG is not set ++# CONFIG_JFS_STATISTICS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_VXFS_FS is not set ++CONFIG_NTFS_FS=m ++# CONFIG_NTFS_RW is not set ++# CONFIG_HPFS_FS is not set ++CONFIG_PROC_FS=y ++CONFIG_DEVFS_FS=y ++CONFIG_DEVFS_MOUNT=y ++# CONFIG_DEVFS_DEBUG is not set ++CONFIG_DEVPTS_FS=y ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX4FS_RW is not set ++# CONFIG_ROMFS_FS is not set ++CONFIG_EXT2_FS=m ++# CONFIG_SYSV_FS is not set ++# CONFIG_UDF_FS is not set ++# CONFIG_UDF_RW is not set ++# CONFIG_UFS_FS is not set ++# CONFIG_UFS_FS_WRITE is not set ++# CONFIG_XFS_FS is not set ++# CONFIG_XFS_QUOTA is not set ++# CONFIG_XFS_RT is not set ++# CONFIG_XFS_TRACE is not set ++# CONFIG_XFS_DEBUG is not set ++ ++# ++# Network File Systems ++# ++# CONFIG_CODA_FS is not set ++# CONFIG_INTERMEZZO_FS is not set ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++# CONFIG_NFS_DIRECTIO is not set ++CONFIG_ROOT_NFS=y ++CONFIG_NFSD=y ++CONFIG_NFSD_V3=y ++# CONFIG_NFSD_TCP is not set ++CONFIG_SUNRPC=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_SMB_FS=m ++# CONFIG_SMB_NLS_DEFAULT is not set ++# CONFIG_SMB_UNIX is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_NCPFS_PACKET_SIGNING is not set ++# CONFIG_NCPFS_IOCTL_LOCKING is not set ++# CONFIG_NCPFS_STRONG is not set ++# CONFIG_NCPFS_NFS_NS is not set ++# CONFIG_NCPFS_OS2_NS is not set ++# CONFIG_NCPFS_SMALLDOS is not set ++# CONFIG_NCPFS_NLS is not set ++# CONFIG_NCPFS_EXTRAS is not set ++CONFIG_ZISOFS_FS=m ++ ++# ++# Partition Types ++# ++# CONFIG_PARTITION_ADVANCED is not set ++CONFIG_MSDOS_PARTITION=y ++CONFIG_SMB_NLS=y ++CONFIG_NLS=y ++ ++# ++# Native Language Support ++# ++CONFIG_NLS_DEFAULT="iso8859-15" ++CONFIG_NLS_CODEPAGE_437=m ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++CONFIG_NLS_CODEPAGE_850=m ++# CONFIG_NLS_CODEPAGE_852 is not set ++# CONFIG_NLS_CODEPAGE_855 is not set ++# CONFIG_NLS_CODEPAGE_857 is not set ++# CONFIG_NLS_CODEPAGE_860 is not set ++# CONFIG_NLS_CODEPAGE_861 is not set ++# CONFIG_NLS_CODEPAGE_862 is not set ++# CONFIG_NLS_CODEPAGE_863 is not set ++# CONFIG_NLS_CODEPAGE_864 is not set ++# CONFIG_NLS_CODEPAGE_865 is not set ++# CONFIG_NLS_CODEPAGE_866 is not set ++# CONFIG_NLS_CODEPAGE_869 is not set ++# CONFIG_NLS_CODEPAGE_936 is not set ++# CONFIG_NLS_CODEPAGE_950 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# CONFIG_NLS_CODEPAGE_949 is not set ++# CONFIG_NLS_CODEPAGE_874 is not set ++# CONFIG_NLS_ISO8859_8 is not set ++# CONFIG_NLS_CODEPAGE_1250 is not set ++# CONFIG_NLS_CODEPAGE_1251 is not set ++CONFIG_NLS_ISO8859_1=m ++# CONFIG_NLS_ISO8859_2 is not set ++# CONFIG_NLS_ISO8859_3 is not set ++# CONFIG_NLS_ISO8859_4 is not set ++# CONFIG_NLS_ISO8859_5 is not set ++# CONFIG_NLS_ISO8859_6 is not set ++# CONFIG_NLS_ISO8859_7 is not set ++# CONFIG_NLS_ISO8859_9 is not set ++# CONFIG_NLS_ISO8859_13 is not set ++# CONFIG_NLS_ISO8859_14 is not set ++CONFIG_NLS_ISO8859_15=m ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++CONFIG_NLS_UTF8=m ++ ++# ++# Multimedia devices ++# ++CONFIG_VIDEO_DEV=m ++ ++# ++# Video For Linux ++# ++CONFIG_VIDEO_PROC_FS=y ++# CONFIG_I2C_PARPORT is not set ++ ++# ++# Video Adapters ++# ++# CONFIG_VIDEO_BT848 is not set ++# CONFIG_VIDEO_PMS is not set ++CONFIG_VIDEO_CPIA=m ++# CONFIG_VIDEO_CPIA_PP is not set ++CONFIG_VIDEO_CPIA_USB=m ++# CONFIG_VIDEO_SAA5249 is not set ++# CONFIG_TUNER_3036 is not set ++# CONFIG_VIDEO_STRADIS is not set ++# CONFIG_VIDEO_ZORAN is not set ++# CONFIG_VIDEO_ZORAN_BUZ is not set ++# CONFIG_VIDEO_ZORAN_DC10 is not set ++# CONFIG_VIDEO_ZORAN_LML33 is not set ++# CONFIG_VIDEO_ZR36120 is not set ++# CONFIG_VIDEO_MEYE is not set ++ ++# ++# Radio Adapters ++# ++# CONFIG_RADIO_GEMTEK_PCI is not set ++# CONFIG_RADIO_MAXIRADIO is not set ++# CONFIG_RADIO_MAESTRO is not set ++# CONFIG_RADIO_MIROPCM20 is not set ++ ++# ++# Sound ++# ++CONFIG_SOUND=m ++# CONFIG_SOUND_ALI5455 is not set ++# CONFIG_SOUND_BT878 is not set ++# CONFIG_SOUND_CMPCI is not set ++# CONFIG_SOUND_EMU10K1 is not set ++# CONFIG_MIDI_EMU10K1 is not set ++# CONFIG_SOUND_FUSION is not set ++# CONFIG_SOUND_CS4281 is not set ++# CONFIG_SOUND_ES1370 is not set ++# CONFIG_SOUND_ES1371 is not set ++# CONFIG_SOUND_ESSSOLO1 is not set ++# CONFIG_SOUND_MAESTRO is not set ++# CONFIG_SOUND_MAESTRO3 is not set ++# CONFIG_SOUND_FORTE is not set ++# CONFIG_SOUND_ICH is not set ++# CONFIG_SOUND_RME96XX is not set ++# CONFIG_SOUND_SONICVIBES is not set ++# CONFIG_SOUND_AU1X00 is not set ++# CONFIG_SOUND_AU1550_PSC is not set ++# CONFIG_SOUND_AU1550_I2S is not set ++# CONFIG_SOUND_TRIDENT is not set ++# CONFIG_SOUND_MSNDCLAS is not set ++# CONFIG_SOUND_MSNDPIN is not set ++# CONFIG_SOUND_VIA82CXXX is not set ++# CONFIG_MIDI_VIA82CXXX is not set ++CONFIG_SOUND_OSS=m ++# CONFIG_SOUND_TRACEINIT is not set ++# CONFIG_SOUND_DMAP is not set ++# CONFIG_SOUND_AD1816 is not set ++# CONFIG_SOUND_AD1889 is not set ++# CONFIG_SOUND_SGALAXY is not set ++# CONFIG_SOUND_ADLIB is not set ++# CONFIG_SOUND_ACI_MIXER is not set ++# CONFIG_SOUND_CS4232 is not set ++# CONFIG_SOUND_SSCAPE is not set ++# CONFIG_SOUND_GUS is not set ++# CONFIG_SOUND_VMIDI is not set ++# CONFIG_SOUND_TRIX is not set ++# CONFIG_SOUND_MSS is not set ++# CONFIG_SOUND_MPU401 is not set ++# CONFIG_SOUND_NM256 is not set ++# CONFIG_SOUND_MAD16 is not set ++# CONFIG_SOUND_PAS is not set ++# CONFIG_PAS_JOYSTICK is not set ++# CONFIG_SOUND_PSS is not set ++# CONFIG_SOUND_SB is not set ++# CONFIG_SOUND_AWE32_SYNTH is not set ++# CONFIG_SOUND_KAHLUA is not set ++# CONFIG_SOUND_WAVEFRONT is not set ++# CONFIG_SOUND_MAUI is not set ++# CONFIG_SOUND_YM3812 is not set ++# CONFIG_SOUND_OPL3SA1 is not set ++# CONFIG_SOUND_OPL3SA2 is not set ++# CONFIG_SOUND_YMFPCI is not set ++# CONFIG_SOUND_YMFPCI_LEGACY is not set ++# CONFIG_SOUND_UART6850 is not set ++# CONFIG_SOUND_AEDSP16 is not set ++# CONFIG_SOUND_TVMIXER is not set ++# CONFIG_SOUND_AD1980 is not set ++# CONFIG_SOUND_WM97XX is not set ++ ++# ++# USB support ++# ++CONFIG_USB=y ++# CONFIG_USB_DEBUG is not set ++ ++# ++# Miscellaneous USB options ++# ++CONFIG_USB_DEVICEFS=y ++# CONFIG_USB_BANDWIDTH is not set ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_EHCI_HCD is not set ++# CONFIG_USB_UHCI is not set ++# CONFIG_USB_UHCI_ALT is not set ++CONFIG_USB_OHCI=m ++CONFIG_USB_NON_PCI_OHCI=m ++ ++# ++# USB Device Class drivers ++# ++CONFIG_USB_AUDIO=m ++CONFIG_USB_EMI26=m ++ ++# ++# USB Bluetooth can only be used with disabled Bluetooth subsystem ++# ++CONFIG_USB_MIDI=m ++CONFIG_USB_STORAGE=m ++CONFIG_USB_STORAGE_DEBUG=y ++CONFIG_USB_STORAGE_DATAFAB=y ++CONFIG_USB_STORAGE_FREECOM=y ++# CONFIG_USB_STORAGE_ISD200 is not set ++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_ACM=m ++CONFIG_USB_PRINTER=m ++ ++# ++# USB Human Interface Devices (HID) ++# ++# CONFIG_USB_HID is not set ++ ++# ++# Input core support is needed for USB HID input layer or HIDBP support ++# ++# CONFIG_USB_HIDINPUT is not set ++# CONFIG_USB_HIDDEV is not set ++# CONFIG_USB_KBD is not set ++# CONFIG_USB_MOUSE is not set ++# CONFIG_USB_AIPTEK is not set ++# CONFIG_USB_WACOM is not set ++# CONFIG_USB_KBTAB is not set ++# CONFIG_USB_POWERMATE is not set ++ ++# ++# USB Imaging devices ++# ++CONFIG_USB_DC2XX=m ++CONFIG_USB_MDC800=m ++CONFIG_USB_SCANNER=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USB_HPUSBSCSI=m ++ ++# ++# USB Multimedia devices ++# ++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_W9968CF is not set ++CONFIG_USB_VICAM=m ++CONFIG_USB_DSBR=m ++CONFIG_USB_DABUSB=m ++ ++# ++# USB Network adaptors ++# ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_CATC=m ++CONFIG_USB_CDCETHER=m ++CONFIG_USB_USBNET=m ++ ++# ++# USB port drivers ++# ++# CONFIG_USB_USS720 is not set ++ ++# ++# USB Serial Converter support ++# ++CONFIG_USB_SERIAL=m ++# CONFIG_USB_SERIAL_DEBUG is not set ++CONFIG_USB_SERIAL_GENERIC=y ++CONFIG_USB_SERIAL_BELKIN=m ++CONFIG_USB_SERIAL_WHITEHEAT=m ++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m ++CONFIG_USB_SERIAL_EMPEG=m ++CONFIG_USB_SERIAL_FTDI_SIO=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_KEYSPAN_PDA=m ++CONFIG_USB_SERIAL_KEYSPAN=m ++CONFIG_USB_SERIAL_KEYSPAN_USA28=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28X=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19=y ++CONFIG_USB_SERIAL_KEYSPAN_USA18X=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19W=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y ++CONFIG_USB_SERIAL_KEYSPAN_MPR=y ++CONFIG_USB_SERIAL_KEYSPAN_USA49W=y ++CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y ++CONFIG_USB_SERIAL_MCT_U232=m ++CONFIG_USB_SERIAL_KLSI=m ++CONFIG_USB_SERIAL_KOBIL_SCT=m ++CONFIG_USB_SERIAL_PL2303=m ++CONFIG_USB_SERIAL_CYBERJACK=m ++CONFIG_USB_SERIAL_XIRCOM=m ++CONFIG_USB_SERIAL_OMNINET=m ++ ++# ++# USB Miscellaneous drivers ++# ++CONFIG_USB_RIO500=m ++CONFIG_USB_AUERSWALD=m ++CONFIG_USB_TIGL=m ++CONFIG_USB_BRLVGER=m ++CONFIG_USB_LCD=m ++ ++# ++# Support for USB gadgets ++# ++# CONFIG_USB_GADGET is not set ++ ++# ++# USB clients (devices, not hosts) ++# ++CONFIG_USBD=m ++ ++# ++# ++# ++# CONFIG_USBD_HIGH_SPEED is not set ++# CONFIG_USBD_NO_SERIAL_NUMBER is not set ++CONFIG_USBD_SERIAL_NUMBER_STR="" ++CONFIG_USBD_MAXPOWER=0 ++ ++# ++# ++# ++CONFIG_USBD_PROCFS=y ++CONFIG_USBD_PROCFSM=m ++ ++# ++# Function Drivers ++# ++ ++# ++# Network Function ++# ++CONFIG_USBD_NETWORK=m ++CONFIG_USBD_NETWORK_VENDORID=12b9 ++CONFIG_USBD_NETWORK_PRODUCTID=f001 ++CONFIG_USBD_NETWORK_BCDDEVICE=0100 ++CONFIG_USBD_NETWORK_MANUFACTURER="Belcarra" ++CONFIG_USBD_NETWORK_PRODUCT_NAME="Belcarra BLAN Device" ++ ++# ++# ++# ++# CONFIG_USBD_NETWORK_BLAN is not set ++CONFIG_USBD_NETWORK_SAFE=y ++CONFIG_USBD_NETWORK_SAFE_DESC="SAFE Net Cfg" ++CONFIG_USBD_NETWORK_SAFE_INTF="Data Intf" ++# CONFIG_USBD_NETWORK_SAFE_DO_NOT_SETTIME is not set ++# CONFIG_USBD_NETWORK_SAFE_CRC is not set ++CONFIG_USBD_NETWORK_SAFE_NOBRIDGE=y ++ ++# ++# ++# ++# CONFIG_USBD_NETWORK_CDC is not set ++# CONFIG_USBD_NETWORK_BASIC is not set ++# CONFIG_USBD_NETWORK_BASIC2 is not set ++ ++# ++# ++# ++# CONFIG_USBD_NETWORK_START_SINGLE is not set ++# CONFIG_USBD_NETWORK_EP0TEST is not set ++ ++# ++# CDC ACM Function ++# ++CONFIG_USBD_ACM=m ++CONFIG_USBD_ACM_VENDORID=12b9 ++CONFIG_USBD_ACM_PRODUCTID=f002 ++CONFIG_USBD_ACM_BCDDEVICE=0100 ++CONFIG_USBD_ACM_MANUFACTURER="Belcarra" ++CONFIG_USBD_ACM_PRODUCT_NAME="Belcarra ACM Device" ++CONFIG_USBD_ACM_DESC="Acm Cfg" ++CONFIG_USBD_ACM_COMM_INTF="Comm Intf" ++CONFIG_USBD_ACM_DATA_INTF="Data Intf" ++# CONFIG_USBD_ACM_TRACE is not set ++ ++# ++# ++# ++ ++# ++# Random Mouse Function ++# ++# CONFIG_USBD_MOUSE is not set ++ ++# ++# Bus Interface ++# ++ ++# ++# AMD AU1X000 Bus Interface ++# ++CONFIG_USBD_AU1X00_BUS=m ++CONFIG_USBD_AU1X00_SCLOCK=400 ++CONFIG_AU1000_USB_DEVICE=y ++CONFIG_AU1X00_USB_DEVICE=y ++# CONFIG_USBD_BI_REGISTER_TRACE is not set ++ ++# ++# Bluetooth support ++# ++CONFIG_BLUEZ=m ++CONFIG_BLUEZ_L2CAP=m ++CONFIG_BLUEZ_SCO=m ++CONFIG_BLUEZ_RFCOMM=m ++CONFIG_BLUEZ_RFCOMM_TTY=y ++CONFIG_BLUEZ_BNEP=m ++CONFIG_BLUEZ_BNEP_MC_FILTER=y ++CONFIG_BLUEZ_BNEP_PROTO_FILTER=y ++ ++# ++# Bluetooth device drivers ++# ++CONFIG_BLUEZ_HCIUSB=m ++CONFIG_BLUEZ_HCIUSB_SCO=y ++CONFIG_BLUEZ_HCIUART=m ++CONFIG_BLUEZ_HCIUART_H4=y ++CONFIG_BLUEZ_HCIUART_BCSP=y ++CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y ++CONFIG_BLUEZ_HCIBFUSB=m ++# CONFIG_BLUEZ_HCIDTL1 is not set ++# CONFIG_BLUEZ_HCIBT3C is not set ++# CONFIG_BLUEZ_HCIBLUECARD is not set ++# CONFIG_BLUEZ_HCIBTUART is not set ++CONFIG_BLUEZ_HCIVHCI=m ++ ++# ++# Kernel hacking ++# ++CONFIG_CROSSCOMPILE=y ++# CONFIG_RUNTIME_DEBUG is not set ++# CONFIG_KGDB is not set ++# CONFIG_GDB_CONSOLE is not set ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_MAGIC_SYSRQ is not set ++# CONFIG_MIPS_UNCACHED is not set ++CONFIG_LOG_BUF_SHIFT=0 ++ ++# ++# Cryptographic options ++# ++CONFIG_CRYPTO=y ++CONFIG_CRYPTO_HMAC=y ++CONFIG_CRYPTO_NULL=m ++CONFIG_CRYPTO_MD4=m ++CONFIG_CRYPTO_MD5=m ++CONFIG_CRYPTO_SHA1=m ++CONFIG_CRYPTO_SHA256=m ++CONFIG_CRYPTO_SHA512=m ++CONFIG_CRYPTO_DES=m ++CONFIG_CRYPTO_BLOWFISH=m ++CONFIG_CRYPTO_TWOFISH=m ++CONFIG_CRYPTO_SERPENT=m ++CONFIG_CRYPTO_AES=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_CAST6=m ++CONFIG_CRYPTO_TEA=m ++CONFIG_CRYPTO_ARC4=m ++CONFIG_CRYPTO_DEFLATE=m ++CONFIG_CRYPTO_MICHAEL_MIC=m ++CONFIG_CRYPTO_TEST=m ++ ++# ++# Library routines ++# ++CONFIG_CRC32=m ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_FW_LOADER=m +--- linux-old/drivers/i2c/Makefile 2006-05-01 10:20:41.922591250 +0200 ++++ linux/drivers/i2c/Makefile 2006-04-30 20:35:58.000000000 +0200 +@@ -6,7 +6,7 @@ + + export-objs := i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o \ + i2c-algo-ite.o i2c-algo-sibyte.o i2c-algo-sgi.o \ +- i2c-algo-au1550.o i2c-proc.o ++ i2c-algo-au1550.o i2c-proc.o i2c-au1550.o + + obj-$(CONFIG_I2C) += i2c-core.o + obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o +--- linux-old/drivers/i2c/i2c-au1550.c 2004-09-19 00:07:37.000000000 +0200 ++++ linux/drivers/i2c/i2c-au1550.c 2006-04-30 20:35:58.000000000 +0200 +@@ -34,6 +34,8 @@ + #include + #include + ++#include ++ + static int + pb1550_reg(struct i2c_client *client) + { +@@ -116,6 +118,7 @@ + return pb1550_board_adapter.algo->master_xfer(&pb1550_board_adapter, &wm_i2c_msg, 1); + } + ++EXPORT_SYMBOL(pb1550_wm_codec_write); + + MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC."); + MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550"); +--- linux/drivers/net/au1000_eth.c~00-mtx-2.diff 2006-06-10 14:01:44.602796000 +0200 ++++ linux/drivers/net/au1000_eth.c 2006-06-10 13:56:07.353719250 +0200 +@@ -6,7 +6,9 @@ + * Copyright 2002 TimeSys Corp. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com +- * ++ * Bjoern Riemer 2004 ++ * riemer@fokus.fraunhofer.de or riemer@riemer-nt.de ++ * // fixed the link beat detection with ioctls (SIOCGMIIPHY) + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it +@@ -83,7 +85,7 @@ + static int au1000_set_config(struct net_device *dev, struct ifmap *map); + static void set_rx_mode(struct net_device *); + static struct net_device_stats *au1000_get_stats(struct net_device *); +-static inline void update_tx_stats(struct net_device *, u32, u32); ++static inline void update_tx_stats(struct net_device *, u32); + static inline void update_rx_stats(struct net_device *, u32); + static void au1000_timer(unsigned long); + static int au1000_ioctl(struct net_device *, struct ifreq *, int); +@@ -656,6 +658,7 @@ + ks8995m_status, + }; + ++ + #ifdef CONFIG_MIPS_BOSPORUS + struct phy_ops stub_ops = { + stub_init, +@@ -674,6 +677,7 @@ + {"Broadcom BCM5201 10/100 BaseT PHY",0x0040,0x6212, &bcm_5201_ops,0}, + {"Broadcom BCM5221 10/100 BaseT PHY",0x0040,0x61e4, &bcm_5201_ops,0}, + {"Broadcom BCM5222 10/100 BaseT PHY",0x0040,0x6322, &bcm_5201_ops,1}, ++ {"Broadcom BCM5241 10/100 BaseT PHY",0x0143,0xBC31, &bcm_5201_ops,1}, + {"AMD 79C901 HomePNA PHY",0x0000,0x35c8, &am79c901_ops,0}, + {"AMD 79C874 10/100 BaseT PHY",0x0022,0x561b, &am79c874_ops,0}, + {"LSI 80227 10/100 BaseT PHY",0x0016,0xf840, &lsi_80227_ops,0}, +@@ -810,28 +814,39 @@ + int phy_found=0; + #endif + ++#if 0 ++ if (aup && aup->mii) ++ aup->mii->chip_info = NULL; ++#endif ++ ++ + /* search for total of 32 possible mii phy addresses */ + for (phy_addr = 0; phy_addr < 32; phy_addr++) { + u16 mii_status; + u16 phy_id0, phy_id1; + int i; + +- #ifdef CONFIG_BCM5222_DUAL_PHY ++#ifdef CONFIG_BCM5222_DUAL_PHY + /* Mask the already found phy, try next one */ + if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) { + if (au_macs[0]->phy_addr == phy_addr) + continue; + } +- #endif ++#endif + + mii_status = mdio_read(dev, phy_addr, MII_STATUS); + if (mii_status == 0xffff || mii_status == 0x0000) + /* the mii is not accessable, try next one */ + continue; + ++ + phy_id0 = mdio_read(dev, phy_addr, MII_PHY_ID0); + phy_id1 = mdio_read(dev, phy_addr, MII_PHY_ID1); + ++ /*printk ("mii_probe: found PHY at address 0x%X : %04X/%04X\n", phy_addr, ++ phy_id0, phy_id1 ++ ); */ ++ + /* search our mii table for the current mii */ + for (i = 0; mii_chip_table[i].phy_id1; i++) { + if (phy_id0 == mii_chip_table[i].phy_id0 && +@@ -853,7 +868,7 @@ + // values and set indicators. We need to do + // this now since mdio_{read,write} need the + // control and data register addresses. +- #ifdef CONFIG_BCM5222_DUAL_PHY ++#ifdef CONFIG_BCM5222_DUAL_PHY + if ( mii_chip_table[i].dual_phy) { + + /* assume both phys are controlled +@@ -867,11 +882,13 @@ + aup->mii->mii_data_reg = (u32 *) + &au_macs[0]->mac->mii_data; + } +- #endif ++#endif + goto found; + } + } + } ++ return -1; ++ + found: + + #ifdef CONFIG_MIPS_BOSPORUS +@@ -1027,24 +1044,26 @@ + struct au1000_private *aup = (struct au1000_private *) dev->priv; + + if (au1000_debug > 4) +- printk(KERN_INFO "%s: reset mac, aup %x\n", +- dev->name, (unsigned)aup); ++ printk(KERN_INFO "%s: reset mac, aup %x, macid %d\n", ++ dev->name, (unsigned)aup, aup->mac_id); ++ ++ return; + + spin_lock_irqsave(&aup->lock, flags); + del_timer(&aup->timer); + hard_stop(dev); +- #ifdef CONFIG_BCM5222_DUAL_PHY ++#ifdef CONFIG_BCM5222_DUAL_PHY + if (aup->mac_id != 0) { +- #endif ++#endif + /* If BCM5222, we can't leave MAC0 in reset because then + * we can't access the dual phy for ETH1 */ + *aup->enable = MAC_EN_CLOCK_ENABLE; + au_sync_delay(2); + *aup->enable = 0; + au_sync_delay(2); +- #ifdef CONFIG_BCM5222_DUAL_PHY ++#ifdef CONFIG_BCM5222_DUAL_PHY + } +- #endif ++#endif + aup->tx_full = 0; + for (i = 0; i < NUM_RX_DMA; i++) { + /* reset control bits */ +@@ -1140,17 +1159,39 @@ + iflist[1].macen_addr = AU1550_MAC1_ENABLE; + iflist[0].irq = AU1550_MAC0_DMA_INT; + iflist[1].irq = AU1550_MAC1_DMA_INT; ++ /*printk ("***** Au1550 Ethernet *****\n");*/ + break; + #endif + default: + num_ifs = 0; + } ++ ++ { ++ unsigned long pf = au_readl(SYS_PINFUNC); ++ pf &= ~1; ++ ++ au_writel (pf, SYS_PINFUNC); ++ au_writel (0x10000, SYS_OUTPUTSET); ++ ++ } ++ ++ ++ + for(i = 0; i < num_ifs; i++) { ++ /*printk ("*** calling au1000_probe(0x%08lX, %d, %d)\n", iflist[i].base_addr, iflist[i].irq, i);*/ + dev = au1000_probe(iflist[i].base_addr, iflist[i].irq, i); ++ /*printk ("*** left au1000_probe\n");*/ ++ + iflist[i].dev = dev; ++ ++ /*printk ("*** 1\n");*/ ++ + if (dev) + found_one++; + } ++ ++ printk("Au1x Ethernet found %d ethernet devices\n", found_one); ++ + if (!found_one) + return -ENODEV; + return 0; +@@ -1194,6 +1235,7 @@ + /* Allocate the data buffers */ + aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * + (NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr); ++ + if (!aup->vaddr) { + kfree(dev); + release_region(ioaddr, MAC_IOSIZE); +@@ -1227,6 +1269,7 @@ + setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); + aup->mac_id = 0; + au_macs[0] = aup; ++ + } + else + if (ioaddr == iflist[1].base_addr) +@@ -1257,6 +1300,8 @@ + printk(KERN_ERR "%s: out of memory\n", dev->name); + goto err_out; + } ++ ++ aup->mii->chip_info = NULL; + aup->mii->mii_control_reg = 0; + aup->mii->mii_data_reg = 0; + +@@ -1284,6 +1329,7 @@ + aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; + aup->rx_db_inuse[i] = pDB; + } ++ + for (i = 0; i < NUM_TX_DMA; i++) { + pDB = GetFreeDB(aup); + if (!pDB) { +@@ -1383,12 +1429,17 @@ + aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed); + control = MAC_DISABLE_RX_OWN | MAC_RX_ENABLE | MAC_TX_ENABLE; + #ifndef CONFIG_CPU_LITTLE_ENDIAN ++ /*riemer: fix for startup without cable */ ++ if (!link) ++ dev->flags &= ~IFF_RUNNING; ++ + control |= MAC_BIG_ENDIAN; + #endif + if (link && (dev->if_port == IF_PORT_100BASEFX)) { + control |= MAC_FULL_DUPLEX; + } + aup->mac->control = control; ++ aup->mac->vlan1_tag = 0x8100; /* activate vlan support */ + au_sync(); + + spin_unlock_irqrestore(&aup->lock, flags); +@@ -1541,14 +1592,11 @@ + + + static inline void +-update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len) ++update_tx_stats(struct net_device *dev, u32 status) + { + struct au1000_private *aup = (struct au1000_private *) dev->priv; + struct net_device_stats *ps = &aup->stats; + +- ps->tx_packets++; +- ps->tx_bytes += pkt_len; +- + if (status & TX_FRAME_ABORTED) { + if (dev->if_port == IF_PORT_100BASEFX) { + if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) { +@@ -1581,7 +1629,7 @@ + ptxd = aup->tx_dma_ring[aup->tx_tail]; + + while (ptxd->buff_stat & TX_T_DONE) { +- update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff); ++ update_tx_stats(dev, ptxd->status); + ptxd->buff_stat &= ~TX_T_DONE; + ptxd->len = 0; + au_sync(); +@@ -1603,6 +1651,7 @@ + static int au1000_tx(struct sk_buff *skb, struct net_device *dev) + { + struct au1000_private *aup = (struct au1000_private *) dev->priv; ++ struct net_device_stats *ps = &aup->stats; + volatile tx_dma_t *ptxd; + u32 buff_stat; + db_dest_t *pDB; +@@ -1622,7 +1671,7 @@ + return 1; + } + else if (buff_stat & TX_T_DONE) { +- update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff); ++ update_tx_stats(dev, ptxd->status); + ptxd->len = 0; + } + +@@ -1642,6 +1691,9 @@ + else + ptxd->len = skb->len; + ++ ps->tx_packets++; ++ ps->tx_bytes += ptxd->len; ++ + ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE; + au_sync(); + dev_kfree_skb(skb); +@@ -1840,17 +1892,35 @@ + + static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) + { +- //u16 *data = (u16 *)&rq->ifr_data; ++/* ++// This structure is used in all SIOCxMIIxxx ioctl calls ++struct mii_ioctl_data { ++ 0 u16 phy_id; ++ 1 u16 reg_num; ++ 2 u16 val_in; ++ 3 u16 val_out; ++};*/ ++ u16 *data = (u16 *)&rq->ifr_data; ++ struct au1000_private *aup = (struct au1000_private *) dev->priv; ++ //struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data; + + /* fixme */ + switch(cmd) { + case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ +- //data[0] = PHY_ADDRESS; ++ case SIOCGMIIPHY: ++ if (!netif_running(dev)) ++ return -EINVAL; ++ data[0] = aup->phy_addr; + case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ +- //data[3] = mdio_read(ioaddr, data[0], data[1]); ++ case SIOCGMIIREG: ++ data[3] = mdio_read(dev, data[0], data[1]); ++ //data->val_out = mdio_read(dev,data->phy_id,data->reg_num); + return 0; + case SIOCDEVPRIVATE+2: /* Write the specified MII register */ +- //mdio_write(ioaddr, data[0], data[1], data[2]); ++ case SIOCSMIIREG: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ mdio_write(dev, data[0], data[1],data[2]); + return 0; + default: + return -EOPNOTSUPP; +--- linux-old/drivers/sound/au1550_psc.c 2004-09-19 00:07:37.000000000 +0200 ++++ linux/drivers/sound/au1550_psc.c 2006-04-30 20:35:58.000000000 +0200 +@@ -55,14 +55,15 @@ + #include + #include + +-#ifdef CONFIG_MIPS_PB1550 ++#if defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_MTX2) + #include + #endif + +-#ifdef CONFIG_MIPS_DB1550 ++#ifdef CONFIG_MIPS_PB1550 + #include + #endif + ++ + #undef OSS_DOCUMENTED_MIXER_SEMANTICS + + #define AU1550_MODULE_NAME "Au1550 psc audio" +@@ -626,10 +627,13 @@ + { + struct dmabuf *db = &s->dma_adc; + int i; ++ unsigned long flags; + + if (!db->stopped) + return; + ++ spin_lock_irqsave(&s->lock, flags); ++ + /* Put two buffers on the ring to get things started. + */ + for (i=0; i<2; i++) { +@@ -648,6 +652,7 @@ + au_sync(); + + db->stopped = 0; ++ spin_unlock_irqrestore(&s->lock, flags); + } + + static int +--- linux-old/include/asm-mips/db1x00.h 2004-11-24 12:13:39.000000000 +0100 ++++ linux/include/asm-mips/db1x00.h 2006-04-30 20:35:58.000000000 +0200 +@@ -27,7 +27,7 @@ + #ifndef __ASM_DB1X00_H + #define __ASM_DB1X00_H + +-#ifdef CONFIG_MIPS_DB1550 ++#if defined(CONFIG_MIPS_DB1550) || defined(CONFIG_MIPS_MTX2) + #define BCSR_KSEG1_ADDR 0xAF000000 + #define NAND_PHYS_ADDR 0x20000000 + #define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX +--- linux-old/include/asm-mips/bootinfo.h 2006-05-01 11:55:50.363346500 +0200 ++++ linux/include/asm-mips/bootinfo.h 2006-05-01 12:25:54.932125000 +0200 +@@ -180,6 +180,7 @@ + #define MACH_MTX1 7 /* 4G MTX-1 Au1500-based board */ + #define MACH_CSB250 8 /* Cogent Au1500 */ + #define MACH_PB1550 9 /* Au1550-based eval board */ ++#define MACH_MTX2 10 /* 4G MTX-2 Au1550-based board */ + + /* + * Valid machtype for group NEC_VR41XX +--- linux-old/include/asm-mips64/bootinfo.h 2006-05-01 11:56:02.584110250 +0200 ++++ linux/include/asm-mips64/bootinfo.h 2006-05-01 12:26:42.047069500 +0200 +@@ -179,6 +179,7 @@ + #define MACH_XXS1500 6 /* Au1500-based eval board */ + #define MACH_MTX1 7 /* 4G MTX-1 Au1500-based board */ + #define MACH_CSB250 8 /* Cogent Au1500 */ ++#define MACH_MTX2 10 /* 4G MTX-2 Au1550-based board */ + + /* + * Valid machtype for group NEC_VR41XX +--- linux-old/arch/mips/au1000/common/dbdma.c 2004-07-14 08:27:07.000000000 +0200 ++++ linux/arch/mips/au1000/common/dbdma.c 2006-04-30 20:35:58.000000000 +0200 +@@ -41,7 +41,9 @@ + #include + #include + +-#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) ++#include ++ ++#if 1 // defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) + + /* + * The Descriptor Based DMA supports up to 16 channels. +@@ -830,5 +832,18 @@ + } while (dp != ctp->chan_desc_base); + } + ++ ++EXPORT_SYMBOL(au1xxx_dbdma_dump); ++EXPORT_SYMBOL(au1xxx_dbdma_put_source); ++EXPORT_SYMBOL(au1xxx_dbdma_put_dest); ++EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc); ++EXPORT_SYMBOL(au1xxx_dbdma_start); ++EXPORT_SYMBOL(au1xxx_dbdma_get_dest); ++EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc); ++EXPORT_SYMBOL(au1xxx_get_dma_residue); ++EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth); ++EXPORT_SYMBOL(au1xxx_dbdma_chan_free); ++EXPORT_SYMBOL(au1xxx_dbdma_reset); ++ + #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ + diff --git a/packages/linux/linux-mtx-2-2.4.27/01-mtd-mtx-2.diff b/packages/linux/linux-mtx-2-2.4.27/01-mtd-mtx-2.diff new file mode 100644 index 0000000000..8b07114f12 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/01-mtd-mtx-2.diff @@ -0,0 +1,51784 @@ +diff -Nurb linux-mips-2.4.27/drivers/mtd/Config.in linux/drivers/mtd/Config.in +--- linux-mips-2.4.27/drivers/mtd/Config.in 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/Config.in 2004-11-19 10:25:11.607244176 +0100 +@@ -1,5 +1,5 @@ + +-# $Id: Config.in,v 1.74 2002/04/23 13:52:14 mag Exp $ ++# $Id: Config.in,v 1.75 2003/05/23 11:38:29 dwmw2 Exp $ + + mainmenu_option next_comment + comment 'Memory Technology Devices (MTD)' +@@ -30,6 +30,7 @@ + if [ "$CONFIG_NFTL" = "y" -o "$CONFIG_NFTL" = "m" ]; then + bool ' Write support for NFTL (BETA)' CONFIG_NFTL_RW + fi ++ dep_tristate ' INFTL (Inverse NAND Flash Translation Layer) support' CONFIG_INFTL $CONFIG_MTD + + source drivers/mtd/chips/Config.in + +diff -Nurb linux-mips-2.4.27/drivers/mtd/Makefile linux/drivers/mtd/Makefile +--- linux-mips-2.4.27/drivers/mtd/Makefile 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/Makefile 2004-11-19 10:25:11.608244024 +0100 +@@ -1,30 +1,7 @@ + # + # Makefile for the memory technology device drivers. + # +-# Note! Dependencies are done automagically by 'make dep', which also +-# removes any old dependencies. DON'T put your own dependencies here +-# unless it's something special (ie not a .c file). +-# +-# Note 2! The CFLAGS definitions are now inherited from the +-# parent makes.. +-# +-# $Id: Makefile,v 1.65 2002/03/22 07:10:34 dwmw2 Exp $ +- +- +-obj-y += chips/chipslink.o maps/mapslink.o \ +- devices/devlink.o nand/nandlink.o +-obj-m := +-obj-n := +-obj- := +- +-O_TARGET := mtdlink.o +- +-export-objs := mtdcore.o mtdpart.o redboot.o cmdlinepart.o afs.o mtdconcat.o +-list-multi := nftl.o +- +-mod-subdirs := +-subdir-y := chips maps devices nand +-subdir-m := $(subdir-y) ++# $Id: Makefile.common,v 1.2 2003/05/23 11:38:29 dwmw2 Exp $ + + # *** BIG UGLY NOTE *** + # +@@ -52,15 +29,44 @@ + + # 'Users' - code which presents functionality to userspace. + obj-$(CONFIG_MTD_CHAR) += mtdchar.o +-obj-$(CONFIG_MTD_BLOCK) += mtdblock.o +-obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o +-obj-$(CONFIG_FTL) += ftl.o +-obj-$(CONFIG_NFTL) += nftl.o ++obj-$(CONFIG_MTD_BLOCK) += mtdblock.o mtd_blkdevs.o ++obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o mtd_blkdevs.o ++obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs.o ++obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o ++obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o + + nftl-objs := nftlcore.o nftlmount.o ++inftl-objs := inftlcore.o inftlmount.o ++ ++ifeq ($(PATCHLEVEL),4) ++ ++export-objs := mtdcore.o mtdpart.o redboot.o cmdlinepart.o afs.o \ ++ mtdconcat.o mtd_blkdevs-24.o ++ ++mtd_blkdevs-objs := mtd_blkdevs-24.o ++ ++obj-y += chips/chipslink.o maps/mapslink.o \ ++ devices/devlink.o nand/nandlink.o ++ ++O_TARGET := mtdlink.o ++ ++list-multi := nftl.o inftl.o mtd_blkdevs.o ++ ++mod-subdirs := ++subdir-y := chips maps devices nand ++subdir-m := $(subdir-y) + + include $(TOPDIR)/Rules.make + + nftl.o: $(nftl-objs) + $(LD) -r -o $@ $(nftl-objs) + ++inftl.o: $(inftl-objs) ++ $(LD) -r -o $@ $(inftl-objs) ++ ++mtd_blkdevs.o: $(mtd_blkdevs-objs) ++ $(LD) -r -o $@ $(mtd_blkdevs-objs) ++ ++else ++obj-y += chips/ maps/ devices/ nand/ ++endif +diff -Nurb linux-mips-2.4.27/drivers/mtd/afs.c linux/drivers/mtd/afs.c +--- linux-mips-2.4.27/drivers/mtd/afs.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/afs.c 2004-11-19 10:25:11.610243720 +0100 +@@ -21,7 +21,7 @@ + This is access code for flashes using ARM's flash partitioning + standards. + +- $Id: afs.c,v 1.8 2002/05/04 08:49:09 rmk Exp $ ++ $Id: afs.c,v 1.12 2003/06/13 15:31:06 rmk Exp $ + + ======================================================================*/ + +@@ -76,17 +76,19 @@ + return ret; + } + ++ ret = 1; ++ + /* + * Does it contain the magic number? + */ + if (fs.signature != 0xa0ffff9f) +- ret = 1; ++ ret = 0; + + /* + * Don't touch the SIB. + */ + if (fs.type == 2) +- ret = 1; ++ ret = 0; + + *iis_start = fs.image_info_base & mask; + *img_start = fs.image_start & mask; +@@ -96,14 +98,14 @@ + * be located after the footer structure. + */ + if (*iis_start >= ptr) +- ret = 1; ++ ret = 0; + + /* + * Check the start of this image. The image + * data can not be located after this block. + */ + if (*img_start > off) +- ret = 1; ++ ret = 0; + + return ret; + } +@@ -125,7 +127,9 @@ + return ret; + } + +-int parse_afs_partitions(struct mtd_info *mtd, struct mtd_partition **pparts) ++static int parse_afs_partitions(struct mtd_info *mtd, ++ struct mtd_partition **pparts, ++ unsigned long origin) + { + struct mtd_partition *parts; + u_int mask, off, idx, sz; +@@ -150,7 +154,7 @@ + ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); + if (ret < 0) + break; +- if (ret == 1) ++ if (ret == 0) + continue; + + ret = afs_read_iis(mtd, &iis, iis_ptr); +@@ -183,7 +187,7 @@ + ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); + if (ret < 0) + break; +- if (ret == 1) ++ if (ret == 0) + continue; + + /* Read the image info block */ +@@ -227,7 +231,25 @@ + return idx ? idx : ret; + } + +-EXPORT_SYMBOL(parse_afs_partitions); ++static struct mtd_part_parser afs_parser = { ++ .owner = THIS_MODULE, ++ .parse_fn = parse_afs_partitions, ++ .name = "afs", ++}; ++ ++static int __init afs_parser_init(void) ++{ ++ return register_mtd_parser(&afs_parser); ++} ++ ++static void __exit afs_parser_exit(void) ++{ ++ deregister_mtd_parser(&afs_parser); ++} ++ ++module_init(afs_parser_init); ++module_exit(afs_parser_exit); ++ + + MODULE_AUTHOR("ARM Ltd"); + MODULE_DESCRIPTION("ARM Firmware Suite partition parser"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/Config.in linux/drivers/mtd/chips/Config.in +--- linux-mips-2.4.27/drivers/mtd/chips/Config.in 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/chips/Config.in 2004-11-19 10:25:11.712228216 +0100 +@@ -1,6 +1,6 @@ + # drivers/mtd/chips/Config.in + +-# $Id: Config.in,v 1.16 2002/09/03 13:30:43 joern Exp $ ++# $Id: Config.in,v 1.17 2003/09/25 14:40:34 thayne Exp $ + + mainmenu_option next_comment + +@@ -11,13 +11,12 @@ + + if [ "$CONFIG_MTD_CFI" = "y" -o "$CONFIG_MTD_JEDECPROBE" = "y" ]; then + define_bool CONFIG_MTD_GEN_PROBE y +-else +- if [ "$CONFIG_MTD_CFI" = "m" -o "$CONFIG_MTD_JEDECPROBE" = "m" ]; then ++elif [ "$CONFIG_MTD_CFI" = "m" -o "$CONFIG_MTD_JEDECPROBE" = "m" ]; then + define_bool CONFIG_MTD_GEN_PROBE m +- else ++else + define_bool CONFIG_MTD_GEN_PROBE n +- fi + fi ++ + if [ "$CONFIG_MTD_GEN_PROBE" = "y" -o "$CONFIG_MTD_GEN_PROBE" = "m" ]; then + bool ' Flash chip driver advanced configuration options' CONFIG_MTD_CFI_ADV_OPTIONS + if [ "$CONFIG_MTD_CFI_ADV_OPTIONS" = "y" ]; then +@@ -44,8 +43,27 @@ + fi + dep_tristate ' Support for Intel/Sharp flash chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_GEN_PROBE + dep_tristate ' Support for AMD/Fujitsu flash chips' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_GEN_PROBE ++if [ "$CONFIG_MTD_CFI_AMDSTD" = "y" -o "$CONFIG_MTD_CFI_AMDSTD" = "m" ]; then ++ bool ' Retry failed commands (erase/program)' CONFIG_MTD_CFI_AMDSTD_RETRY n ++ if [ "$CONFIG_MTD_CFI_AMDSTD_RETRY" = "y" ]; then ++ int ' Max retries of failed commands (erase/program)' CONFIG_MTD_CFI_AMDSTD_RETRY_MAX 0 ++ fi ++fi ++ + dep_tristate ' Support for ST (Advanced Architecture) flash chips' CONFIG_MTD_CFI_STAA $CONFIG_MTD_GEN_PROBE + ++if [ "$CONFIG_MTD_CFI_INTELEXT" = "y" \ ++ -o "$CONFIG_MTD_CFI_AMDSTD" = "y" \ ++ -o "$CONFIG_MTD_CFI_STAA" = "y" ]; then ++ define_bool CONFIG_MTD_CFI_UTIL y ++elif [ "$CONFIG_MTD_CFI_INTELEXT" = "m" \ ++ -o "$CONFIG_MTD_CFI_AMDSTD" = "m" \ ++ -o "$CONFIG_MTD_CFI_STAA" = "m" ]; then ++ define_bool CONFIG_MTD_CFI_UTIL m ++else ++ define_bool CONFIG_MTD_CFI_UTIL n ++fi ++ + dep_tristate ' Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONFIG_MTD + dep_tristate ' Support for ROM chips in bus mapping' CONFIG_MTD_ROM $CONFIG_MTD + dep_tristate ' Support for absent chips in bus mapping' CONFIG_MTD_ABSENT $CONFIG_MTD +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/Makefile linux/drivers/mtd/chips/Makefile +--- linux-mips-2.4.27/drivers/mtd/chips/Makefile 2003-07-05 05:23:38.000000000 +0200 ++++ linux/drivers/mtd/chips/Makefile 2004-11-19 10:25:11.714227912 +0100 +@@ -1,11 +1,12 @@ + # + # linux/drivers/chips/Makefile + # +-# $Id: Makefile,v 1.8 2002/01/10 20:27:40 eric Exp $ ++# $Id: Makefile.common,v 1.3 2003/09/25 14:40:34 thayne Exp $ + ++ifeq ($(PATCHLEVEL),4) + O_TARGET := chipslink.o +- +-export-objs := chipreg.o gen_probe.o ++export-objs := chipreg.o gen_probe.o cfi_util.o ++endif + + # *** BIG UGLY NOTE *** + # +@@ -17,6 +18,7 @@ + obj-$(CONFIG_MTD) += chipreg.o + obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o + obj-$(CONFIG_MTD_CFI) += cfi_probe.o ++obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o + obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o + obj-$(CONFIG_MTD_CFI_AMDSTD) += cfi_cmdset_0002.o + obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o +@@ -28,4 +30,4 @@ + obj-$(CONFIG_MTD_SHARP) += sharp.o + obj-$(CONFIG_MTD_ABSENT) += map_absent.o + +-include $(TOPDIR)/Rules.make ++-include $(TOPDIR)/Rules.make +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/amd_flash.c linux/drivers/mtd/chips/amd_flash.c +--- linux-mips-2.4.27/drivers/mtd/chips/amd_flash.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/chips/amd_flash.c 2004-11-19 10:25:11.722226696 +0100 +@@ -3,7 +3,7 @@ + * + * Author: Jonas Holmberg + * +- * $Id: amd_flash.c,v 1.19 2003/01/24 13:30:11 dwmw2 Exp $ ++ * $Id: amd_flash.c,v 1.23 2003/06/12 09:24:13 dwmw2 Exp $ + * + * Copyright (c) 2001 Axis Communications AB + * +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -125,10 +126,10 @@ + + + static struct mtd_chip_driver amd_flash_chipdrv = { +- probe: amd_flash_probe, +- destroy: amd_flash_destroy, +- name: "amd_flash", +- module: THIS_MODULE ++ .probe = amd_flash_probe, ++ .destroy = amd_flash_destroy, ++ .name = "amd_flash", ++ .module = THIS_MODULE + }; + + +@@ -140,11 +141,11 @@ + static inline __u32 wide_read(struct map_info *map, __u32 addr) + { + if (map->buswidth == 1) { +- return map->read8(map, addr); ++ return map_read8(map, addr); + } else if (map->buswidth == 2) { +- return map->read16(map, addr); ++ return map_read16(map, addr); + } else if (map->buswidth == 4) { +- return map->read32(map, addr); ++ return map_read32(map, addr); + } + + return 0; +@@ -153,11 +154,11 @@ + static inline void wide_write(struct map_info *map, __u32 val, __u32 addr) + { + if (map->buswidth == 1) { +- map->write8(map, val, addr); ++ map_write8(map, val, addr); + } else if (map->buswidth == 2) { +- map->write16(map, val, addr); ++ map_write16(map, val, addr); + } else if (map->buswidth == 4) { +- map->write32(map, val, addr); ++ map_write32(map, val, addr); + } + } + +@@ -424,231 +425,228 @@ + + static struct mtd_info *amd_flash_probe(struct map_info *map) + { +- /* Keep this table on the stack so that it gets deallocated after the +- * probe is done. +- */ +- const struct amd_flash_info table[] = { ++ static const struct amd_flash_info table[] = { + { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29LV160DT, +- name: "AMD AM29LV160DT", +- size: 0x00200000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 }, +- { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 } ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29LV160DT, ++ .name = "AMD AM29LV160DT", ++ .size = 0x00200000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, ++ { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 } + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29LV160DB, +- name: "AMD AM29LV160DB", +- size: 0x00200000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, +- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 } ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29LV160DB, ++ .name = "AMD AM29LV160DB", ++ .size = 0x00200000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, ++ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } + } + }, { +- mfr_id: MANUFACTURER_TOSHIBA, +- dev_id: TC58FVT160, +- name: "Toshiba TC58FVT160", +- size: 0x00200000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 }, +- { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 } ++ .mfr_id = MANUFACTURER_TOSHIBA, ++ .dev_id = TC58FVT160, ++ .name = "Toshiba TC58FVT160", ++ .size = 0x00200000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, ++ { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 } + } + }, { +- mfr_id: MANUFACTURER_FUJITSU, +- dev_id: MBM29LV160TE, +- name: "Fujitsu MBM29LV160TE", +- size: 0x00200000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 }, +- { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 } ++ .mfr_id = MANUFACTURER_FUJITSU, ++ .dev_id = MBM29LV160TE, ++ .name = "Fujitsu MBM29LV160TE", ++ .size = 0x00200000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, ++ { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 } + } + }, { +- mfr_id: MANUFACTURER_TOSHIBA, +- dev_id: TC58FVB160, +- name: "Toshiba TC58FVB160", +- size: 0x00200000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, +- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 } ++ .mfr_id = MANUFACTURER_TOSHIBA, ++ .dev_id = TC58FVB160, ++ .name = "Toshiba TC58FVB160", ++ .size = 0x00200000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, ++ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } + } + }, { +- mfr_id: MANUFACTURER_FUJITSU, +- dev_id: MBM29LV160BE, +- name: "Fujitsu MBM29LV160BE", +- size: 0x00200000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, +- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 } ++ .mfr_id = MANUFACTURER_FUJITSU, ++ .dev_id = MBM29LV160BE, ++ .name = "Fujitsu MBM29LV160BE", ++ .size = 0x00200000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, ++ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29LV800BB, +- name: "AMD AM29LV800BB", +- size: 0x00100000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, +- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x010000, erasesize: 0x10000, numblocks: 15 } ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29LV800BB, ++ .name = "AMD AM29LV800BB", ++ .size = 0x00100000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, ++ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 } + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29F800BB, +- name: "AMD AM29F800BB", +- size: 0x00100000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, +- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x010000, erasesize: 0x10000, numblocks: 15 } ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29F800BB, ++ .name = "AMD AM29F800BB", ++ .size = 0x00100000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, ++ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 } + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29LV800BT, +- name: "AMD AM29LV800BT", +- size: 0x00100000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x10000, numblocks: 15 }, +- { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 } ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29LV800BT, ++ .name = "AMD AM29LV800BT", ++ .size = 0x00100000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 }, ++ { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 } + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29F800BT, +- name: "AMD AM29F800BT", +- size: 0x00100000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x10000, numblocks: 15 }, +- { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 } ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29F800BT, ++ .name = "AMD AM29F800BT", ++ .size = 0x00100000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 }, ++ { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 } + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29LV800BB, +- name: "AMD AM29LV800BB", +- size: 0x00100000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x10000, numblocks: 15 }, +- { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 } ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29LV800BB, ++ .name = "AMD AM29LV800BB", ++ .size = 0x00100000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 }, ++ { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 } + } + }, { +- mfr_id: MANUFACTURER_FUJITSU, +- dev_id: MBM29LV800BB, +- name: "Fujitsu MBM29LV800BB", +- size: 0x00100000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, +- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x010000, erasesize: 0x10000, numblocks: 15 } ++ .mfr_id = MANUFACTURER_FUJITSU, ++ .dev_id = MBM29LV800BB, ++ .name = "Fujitsu MBM29LV800BB", ++ .size = 0x00100000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, ++ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 } + } + }, { +- mfr_id: MANUFACTURER_ST, +- dev_id: M29W800T, +- name: "ST M29W800T", +- size: 0x00100000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x10000, numblocks: 15 }, +- { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 } ++ .mfr_id = MANUFACTURER_ST, ++ .dev_id = M29W800T, ++ .name = "ST M29W800T", ++ .size = 0x00100000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 }, ++ { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 } + } + }, { +- mfr_id: MANUFACTURER_ST, +- dev_id: M29W160DT, +- name: "ST M29W160DT", +- size: 0x00200000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 }, +- { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 } ++ .mfr_id = MANUFACTURER_ST, ++ .dev_id = M29W160DT, ++ .name = "ST M29W160DT", ++ .size = 0x00200000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, ++ { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 } + } + }, { +- mfr_id: MANUFACTURER_ST, +- dev_id: M29W160DB, +- name: "ST M29W160DB", +- size: 0x00200000, +- numeraseregions: 4, +- regions: { +- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 }, +- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 }, +- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 }, +- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 } ++ .mfr_id = MANUFACTURER_ST, ++ .dev_id = M29W160DB, ++ .name = "ST M29W160DB", ++ .size = 0x00200000, ++ .numeraseregions = 4, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 }, ++ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 }, ++ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 }, ++ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29BDS323D, +- name: "AMD AM29BDS323D", +- size: 0x00400000, +- numeraseregions: 3, +- regions: { +- { offset: 0x000000, erasesize: 0x10000, numblocks: 48 }, +- { offset: 0x300000, erasesize: 0x10000, numblocks: 15 }, +- { offset: 0x3f0000, erasesize: 0x02000, numblocks: 8 }, ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29BDS323D, ++ .name = "AMD AM29BDS323D", ++ .size = 0x00400000, ++ .numeraseregions = 3, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 48 }, ++ { .offset = 0x300000, .erasesize = 0x10000, .numblocks = 15 }, ++ { .offset = 0x3f0000, .erasesize = 0x02000, .numblocks = 8 }, + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29BDS643D, +- name: "AMD AM29BDS643D", +- size: 0x00800000, +- numeraseregions: 3, +- regions: { +- { offset: 0x000000, erasesize: 0x10000, numblocks: 96 }, +- { offset: 0x600000, erasesize: 0x10000, numblocks: 31 }, +- { offset: 0x7f0000, erasesize: 0x02000, numblocks: 8 }, ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29BDS643D, ++ .name = "AMD AM29BDS643D", ++ .size = 0x00800000, ++ .numeraseregions = 3, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 96 }, ++ { .offset = 0x600000, .erasesize = 0x10000, .numblocks = 31 }, ++ { .offset = 0x7f0000, .erasesize = 0x02000, .numblocks = 8 }, + } + }, { +- mfr_id: MANUFACTURER_ATMEL, +- dev_id: AT49xV16x, +- name: "Atmel AT49xV16x", +- size: 0x00200000, +- numeraseregions: 2, +- regions: { +- { offset: 0x000000, erasesize: 0x02000, numblocks: 8 }, +- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 } ++ .mfr_id = MANUFACTURER_ATMEL, ++ .dev_id = AT49xV16x, ++ .name = "Atmel AT49xV16x", ++ .size = 0x00200000, ++ .numeraseregions = 2, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x02000, .numblocks = 8 }, ++ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 } + } + }, { +- mfr_id: MANUFACTURER_ATMEL, +- dev_id: AT49xV16xT, +- name: "Atmel AT49xV16xT", +- size: 0x00200000, +- numeraseregions: 2, +- regions: { +- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 }, +- { offset: 0x1F0000, erasesize: 0x02000, numblocks: 8 } ++ .mfr_id = MANUFACTURER_ATMEL, ++ .dev_id = AT49xV16xT, ++ .name = "Atmel AT49xV16xT", ++ .size = 0x00200000, ++ .numeraseregions = 2, ++ .regions = { ++ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, ++ { .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 } + } + } + }; +@@ -822,7 +820,7 @@ + + chip->state = FL_READY; + +- map->copy_from(map, buf, adr, len); ++ map_copy_from(map, buf, adr, len); + + wake_up(&chip->wq); + spin_unlock_bh(chip->mutex); +@@ -984,7 +982,7 @@ + u_char tmp_buf[4]; + __u32 datum; + +- map->copy_from(map, tmp_buf, ++ map_copy_from(map, tmp_buf, + bus_ofs + private->chips[chipnum].start, + map->buswidth); + while (len && i < map->buswidth) +@@ -1057,7 +1055,7 @@ + u_char tmp_buf[2]; + __u32 datum; + +- map->copy_from(map, tmp_buf, ++ map_copy_from(map, tmp_buf, + ofs + private->chips[chipnum].start, + map->buswidth); + while (len--) { +@@ -1178,7 +1176,7 @@ + __u8 verify; + + for (address = adr; address < (adr + size); address++) { +- if ((verify = map->read8(map, address)) != 0xFF) { ++ if ((verify = map_read8(map, address)) != 0xFF) { + error = 1; + break; + } +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/cfi_cmdset_0001.c linux/drivers/mtd/chips/cfi_cmdset_0001.c +--- linux-mips-2.4.27/drivers/mtd/chips/cfi_cmdset_0001.c 2003-07-05 05:23:38.000000000 +0200 ++++ linux/drivers/mtd/chips/cfi_cmdset_0001.c 2004-11-19 10:25:11.733225024 +0100 +@@ -4,7 +4,7 @@ + * + * (C) 2000 Red Hat. GPL'd + * +- * $Id: cfi_cmdset_0001.c,v 1.114 2003/03/18 12:28:40 dwmw2 Exp $ ++ * $Id: cfi_cmdset_0001.c,v 1.132 2003/11/04 19:34:22 thayne Exp $ + * + * + * 10/10/2000 Nicolas Pitre +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -29,10 +30,14 @@ + #include + #include + #include +-#include ++#include + #include ++#include ++ ++/* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */ + +-// debugging, turns off buffer write mode #define FORCE_WORD_WRITE ++// debugging, turns off buffer write mode if set to 1 ++#define FORCE_WORD_WRITE 0 + + static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); + static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *); +@@ -52,16 +57,21 @@ + + static struct mtd_info *cfi_intelext_setup (struct map_info *); + +-static int do_point (struct mtd_info *mtd, loff_t from, size_t len, ++static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char **mtdbuf); +-static void do_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, ++static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, + size_t len); + ++ ++/* ++ * *********** SETUP AND PROBE BITS *********** ++ */ ++ + static struct mtd_chip_driver cfi_intelext_chipdrv = { +- probe: NULL, /* Not usable directly */ +- destroy: cfi_intelext_destroy, +- name: "cfi_cmdset_0001", +- module: THIS_MODULE ++ .probe = NULL, /* Not usable directly */ ++ .destroy = cfi_intelext_destroy, ++ .name = "cfi_cmdset_0001", ++ .module = THIS_MODULE + }; + + /* #define DEBUG_LOCK_BITS */ +@@ -102,13 +112,63 @@ + } + + printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", +- extp->VccOptimal >> 8, extp->VccOptimal & 0xf); ++ extp->VccOptimal >> 4, extp->VccOptimal & 0xf); + if (extp->VppOptimal) + printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", +- extp->VppOptimal >> 8, extp->VppOptimal & 0xf); ++ extp->VppOptimal >> 4, extp->VppOptimal & 0xf); + } + #endif + ++#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE ++/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ ++static void fixup_intel_strataflash(struct map_info *map, void* param) ++{ ++ struct cfi_private *cfi = map->fldrv_priv; ++ struct cfi_pri_amdstd *extp = cfi->cmdset_priv; ++ ++ printk(KERN_WARNING "cfi_cmdset_0001: Suspend " ++ "erase on write disabled.\n"); ++ extp->SuspendCmdSupport &= ~1; ++} ++#endif ++ ++static void fixup_st_m28w320ct(struct map_info *map, void* param) ++{ ++ struct cfi_private *cfi = map->fldrv_priv; ++ ++ cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */ ++ cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ ++} ++ ++static void fixup_st_m28w320cb(struct map_info *map, void* param) ++{ ++ struct cfi_private *cfi = map->fldrv_priv; ++ ++ /* Note this is done after the region info is endian swapped */ ++ cfi->cfiq->EraseRegionInfo[1] = ++ (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; ++}; ++ ++static struct cfi_fixup fixup_table[] = { ++#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE ++ { ++ CFI_MFR_ANY, CFI_ID_ANY, ++ fixup_intel_strataflash, NULL ++ }, ++#endif ++ { ++ 0x0020, /* STMicroelectronics */ ++ 0x00ba, /* M28W320CT */ ++ fixup_st_m28w320ct, NULL ++ }, { ++ 0x0020, /* STMicroelectronics */ ++ 0x00bb, /* M28W320CB */ ++ fixup_st_m28w320cb, NULL ++ }, { ++ 0, 0, NULL, NULL ++ } ++}; ++ + /* This routine is made available to other mtd code via + * inter_module_register. It must only be accessed through + * inter_module_get which will bump the use count of this module. The +@@ -120,7 +180,6 @@ + { + struct cfi_private *cfi = map->fldrv_priv; + int i; +- __u32 base = cfi->chips[0].start; + + if (cfi->cfi_mode == CFI_MODE_CFI) { + /* +@@ -130,59 +189,29 @@ + */ + __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; + struct cfi_pri_intelext *extp; +- int ofs_factor = cfi->interleave * cfi->device_type; +- +- //printk(" Intel/Sharp Extended Query Table at 0x%4.4X\n", adr); +- if (!adr) +- return NULL; + +- /* Switch it into Query Mode */ +- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); +- +- extp = kmalloc(sizeof(*extp), GFP_KERNEL); +- if (!extp) { +- printk(KERN_ERR "Failed to allocate memory\n"); ++ extp = (struct cfi_pri_intelext*)cfi_read_pri(map, adr, sizeof(*extp), "Intel/Sharp"); ++ if (!extp) + return NULL; +- } +- +- /* Read in the Extended Query Table */ +- for (i=0; iMajorVersion != '1' || +- (extp->MinorVersion < '0' || extp->MinorVersion > '3')) { +- printk(KERN_WARNING " Unknown IntelExt Extended Query " +- "version %c.%c.\n", extp->MajorVersion, +- extp->MinorVersion); +- kfree(extp); +- return NULL; +- } + + /* Do some byteswapping if necessary */ + extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport); + extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask); + extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr); + ++ /* Install our own private info structure */ ++ cfi->cmdset_priv = extp; ++ ++ cfi_fixup(map, fixup_table); ++ + #ifdef DEBUG_CFI_FEATURES + /* Tell the user about it in lots of lovely detail */ + cfi_tell_features(extp); + #endif + + if(extp->SuspendCmdSupport & 1) { +-//#define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE +-#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE +-/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ +- printk(KERN_WARNING "cfi_cmdset_0001: Suspend " +- "erase on write disabled.\n"); +- extp->SuspendCmdSupport &= ~1; +-#else + printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n"); +-#endif + } +- /* Install our own private info structure */ +- cfi->cmdset_priv = extp; + } + + for (i=0; i< cfi->numchips; i++) { +@@ -194,8 +223,6 @@ + + map->fldrv = &cfi_intelext_chipdrv; + +- /* Make sure it's in read mode */ +- cfi_send_gen_cmd(0xff, 0x55, base, map, cfi, cfi->device_type, NULL); + return cfi_intelext_setup(map); + } + +@@ -261,20 +288,16 @@ + mtd->erase = cfi_intelext_erase_varsize; + mtd->read = cfi_intelext_read; + +- if(map->point && map->unpoint){ +- mtd->point = do_point; +- mtd->unpoint = do_unpoint; ++ if (map_is_linear(map)) { ++ mtd->point = cfi_intelext_point; ++ mtd->unpoint = cfi_intelext_unpoint; + } + +-#ifndef FORCE_WORD_WRITE +- if ( cfi->cfiq->BufWriteTimeoutTyp ) { +- printk("Using buffer write method\n" ); ++ if ( cfi->cfiq->BufWriteTimeoutTyp && !FORCE_WORD_WRITE) { ++ printk(KERN_INFO "Using buffer write method\n" ); + mtd->write = cfi_intelext_write_buffers; + } else { +-#else +- { +-#endif +- printk("Using word write method\n" ); ++ printk(KERN_INFO "Using word write method\n" ); + mtd->write = cfi_intelext_write_words; + } + mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg; +@@ -286,8 +309,8 @@ + mtd->resume = cfi_intelext_resume; + mtd->flags = MTD_CAP_NORFLASH; + map->fldrv = &cfi_intelext_chipdrv; +- MOD_INC_USE_COUNT; + mtd->name = map->name; ++ __module_get(THIS_MODULE); + return mtd; + + setup_err: +@@ -301,78 +324,170 @@ + return NULL; + } + +-static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) ++/* ++ * *********** CHIP ACCESS FUNCTIONS *********** ++ */ ++ ++static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) + { +- cfi_word status, status_OK; +- unsigned long timeo; + DECLARE_WAITQUEUE(wait, current); +- unsigned long cmd_addr; + struct cfi_private *cfi = map->fldrv_priv; ++ cfi_word status, status_OK = CMD(0x80); ++ unsigned long timeo; ++ struct cfi_pri_intelext *cfip = (struct cfi_pri_intelext *)cfi->cmdset_priv; + +- adr += chip->start; +- +- /* Ensure cmd read/writes are aligned. */ +- cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1); +- +- /* Let's determine this according to the interleave only once */ +- status_OK = CMD(0x80); +- ++ resettime: + timeo = jiffies + HZ; + retry: +- spin_lock(chip->mutex); +- +- /* Check that the chip's ready to talk to us. +- * If it's in FL_ERASING state, suspend it and make it talk now. +- */ + switch (chip->state) { + +- case FL_READY: +- case FL_POINT: ++ case FL_STATUS: ++ for (;;) { ++ status = cfi_read(map, adr); ++ if ((status & status_OK) == status_OK) + break; + ++ if (time_after(jiffies, timeo)) { ++ printk(KERN_ERR "Waiting for chip to be ready timed out. Status %llx\n", ++ (long long)status); ++ spin_unlock(chip->mutex); ++ return -EIO; ++ } ++ spin_unlock(chip->mutex); ++ cfi_udelay(1); ++ spin_lock(chip->mutex); ++ /* Someone else might have been playing with it. */ ++ goto retry; ++ } ++ ++ case FL_READY: + case FL_CFI_QUERY: + case FL_JEDEC_QUERY: +- cfi_write(map, CMD(0x70), cmd_addr); +- chip->state = FL_STATUS; ++ return 0; + +- case FL_STATUS: +- status = cfi_read(map, cmd_addr); +- if ((status & status_OK) == status_OK) { +- cfi_write(map, CMD(0xff), cmd_addr); +- chip->state = FL_READY; ++ case FL_ERASING: ++ if (!(cfip->FeatureSupport & 2) || ++ !(mode == FL_READY || mode == FL_POINT || ++ (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1)))) ++ goto sleep; ++ ++ ++ /* Erase suspend */ ++ cfi_write(map, CMD(0xB0), adr); ++ ++ /* If the flash has finished erasing, then 'erase suspend' ++ * appears to make some (28F320) flash devices switch to ++ * 'read' mode. Make sure that we switch to 'read status' ++ * mode so we get the right data. --rmk ++ */ ++ cfi_write(map, CMD(0x70), adr); ++ chip->oldstate = FL_ERASING; ++ chip->state = FL_ERASE_SUSPENDING; ++ chip->erase_suspended = 1; ++ for (;;) { ++ status = cfi_read(map, adr); ++ if ((status & status_OK) == status_OK) + break; +- } + +- /* Urgh. Chip not yet ready to talk to us. */ + if (time_after(jiffies, timeo)) { +- spin_unlock(chip->mutex); +- printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %llx\n", (__u64)status); ++ /* Urgh. Resume and pretend we weren't here. */ ++ cfi_write(map, CMD(0xd0), adr); ++ /* Make sure we're in 'read status' mode if it had finished */ ++ cfi_write(map, CMD(0x70), adr); ++ chip->state = FL_ERASING; ++ chip->oldstate = FL_READY; ++ printk(KERN_ERR "Chip not ready after erase " ++ "suspended: status = 0x%x\n", status); + return -EIO; + } + +- /* Latency issues. Drop the lock, wait a while and retry */ + spin_unlock(chip->mutex); + cfi_udelay(1); +- goto retry; ++ spin_lock(chip->mutex); ++ /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING. ++ So we can just loop here. */ ++ } ++ chip->state = FL_STATUS; ++ return 0; ++ ++ case FL_POINT: ++ /* Only if there's no operation suspended... */ ++ if (mode == FL_READY && chip->oldstate == FL_READY) ++ return 0; + + default: +- /* Stick ourselves on a wait queue to be woken when +- someone changes the status */ ++ sleep: + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + spin_unlock(chip->mutex); + schedule(); + remove_wait_queue(&chip->wq, &wait); +- timeo = jiffies + HZ; +- goto retry; ++ spin_lock(chip->mutex); ++ goto resettime; + } ++} ++ ++static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr) ++{ ++ struct cfi_private *cfi = map->fldrv_priv; ++ ++ switch(chip->oldstate) { ++ case FL_ERASING: ++ chip->state = chip->oldstate; ++ /* What if one interleaved chip has finished and the ++ other hasn't? The old code would leave the finished ++ one in READY mode. That's bad, and caused -EROFS ++ errors to be returned from do_erase_oneblock because ++ that's the only bit it checked for at the time. ++ As the state machine appears to explicitly allow ++ sending the 0x70 (Read Status) command to an erasing ++ chip and expecting it to be ignored, that's what we ++ do. */ ++ cfi_write(map, CMD(0xd0), adr); ++ cfi_write(map, CMD(0x70), adr); ++ chip->oldstate = FL_READY; ++ chip->state = FL_ERASING; ++ break; ++ ++ case FL_READY: ++ case FL_STATUS: ++ /* We should really make set_vpp() count, rather than doing this */ ++ DISABLE_VPP(map); ++ break; ++ default: ++ printk(KERN_ERR "put_chip() called with oldstate %d!!\n", chip->oldstate); ++ } ++ wake_up(&chip->wq); ++} ++ ++static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) ++{ ++ unsigned long cmd_addr; ++ struct cfi_private *cfi = map->fldrv_priv; ++ int ret = 0; ++ ++ adr += chip->start; ++ ++ /* Ensure cmd read/writes are aligned. */ ++ cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1); ++ ++ spin_lock(chip->mutex); ++ ++ ret = get_chip(map, chip, cmd_addr, FL_POINT); ++ ++ if (!ret) { ++ if (chip->state != FL_POINT && chip->state != FL_READY) ++ cfi_write(map, CMD(0xff), cmd_addr); + + chip->state = FL_POINT; + chip->ref_point_counter++; ++ } + spin_unlock(chip->mutex); +- return 0; ++ ++ return ret; + } +-static int do_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) ++ ++static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) + { + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; +@@ -380,12 +495,10 @@ + int chipnum; + int ret = 0; + +- if (from + len > mtd->size) ++ if (!map->virt || (from + len > mtd->size)) + return -EINVAL; + +- *mtdbuf = map->point(map, from, len); +- if(*mtdbuf == NULL) +- return -EINVAL; /* can not point this region */ ++ *mtdbuf = (void *)map->virt + from; + *retlen = 0; + + /* Now lock the chip(s) to POINT state */ +@@ -418,14 +531,13 @@ + return 0; + } + +-static void do_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) ++static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) + { + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + unsigned long ofs; + int chipnum; + +- map->unpoint(map, addr, from, len); + /* Now unlock the chip(s) POINT state */ + + /* ofs: offset within the first chip that the first read should start */ +@@ -446,13 +558,14 @@ + thislen = len; + + spin_lock(chip->mutex); +- if(chip->state == FL_POINT){ ++ if (chip->state == FL_POINT) { + chip->ref_point_counter--; + if(chip->ref_point_counter == 0) + chip->state = FL_READY; + } else +- printk("Warning: unpoint called on non pointed region\n"); /* Should this give an error? */ +- wake_up(&chip->wq); ++ printk(KERN_ERR "Warning: unpoint called on non pointed region\n"); /* Should this give an error? */ ++ ++ put_chip(map, chip, chip->start); + spin_unlock(chip->mutex); + + len -= thislen; +@@ -463,136 +576,32 @@ + + static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) + { +- cfi_word status, status_OK; +- unsigned long timeo; +- DECLARE_WAITQUEUE(wait, current); +- int suspended = 0; + unsigned long cmd_addr; + struct cfi_private *cfi = map->fldrv_priv; ++ int ret; + + adr += chip->start; + + /* Ensure cmd read/writes are aligned. */ + cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1); + +- /* Let's determine this according to the interleave only once */ +- status_OK = CMD(0x80); +- +- timeo = jiffies + HZ; +- retry: + spin_lock(chip->mutex); +- +- /* Check that the chip's ready to talk to us. +- * If it's in FL_ERASING state, suspend it and make it talk now. +- */ +- switch (chip->state) { +- case FL_ERASING: +- if (!cfi->cmdset_priv || +- !(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) +- goto sleep; /* We don't support erase suspend */ +- +- cfi_write (map, CMD(0xb0), cmd_addr); +- /* If the flash has finished erasing, then 'erase suspend' +- * appears to make some (28F320) flash devices switch to +- * 'read' mode. Make sure that we switch to 'read status' +- * mode so we get the right data. --rmk +- */ +- cfi_write(map, CMD(0x70), cmd_addr); +- chip->oldstate = FL_ERASING; +- chip->state = FL_ERASE_SUSPENDING; +- // printk("Erase suspending at 0x%lx\n", cmd_addr); +- for (;;) { +- status = cfi_read(map, cmd_addr); +- if ((status & status_OK) == status_OK) +- break; +- +- if (time_after(jiffies, timeo)) { +- /* Urgh */ +- cfi_write(map, CMD(0xd0), cmd_addr); +- /* make sure we're in 'read status' mode */ +- cfi_write(map, CMD(0x70), cmd_addr); +- chip->state = FL_ERASING; +- spin_unlock(chip->mutex); +- printk(KERN_ERR "Chip not ready after erase " +- "suspended: status = 0x%llx\n", (__u64)status); +- return -EIO; +- } +- ++ ret = get_chip(map, chip, cmd_addr, FL_READY); ++ if (ret) { + spin_unlock(chip->mutex); +- cfi_udelay(1); +- spin_lock(chip->mutex); ++ return ret; + } + +- suspended = 1; ++ if (chip->state != FL_POINT && chip->state != FL_READY) { + cfi_write(map, CMD(0xff), cmd_addr); +- chip->state = FL_READY; +- break; +- +-#if 0 +- case FL_WRITING: +- /* Not quite yet */ +-#endif +- +- case FL_READY: +- case FL_POINT: +- break; +- +- case FL_CFI_QUERY: +- case FL_JEDEC_QUERY: +- cfi_write(map, CMD(0x70), cmd_addr); +- chip->state = FL_STATUS; + +- case FL_STATUS: +- status = cfi_read(map, cmd_addr); +- if ((status & status_OK) == status_OK) { +- cfi_write(map, CMD(0xff), cmd_addr); + chip->state = FL_READY; +- break; + } + +- /* Urgh. Chip not yet ready to talk to us. */ +- if (time_after(jiffies, timeo)) { +- spin_unlock(chip->mutex); +- printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %llx\n", (__u64)status); +- return -EIO; +- } ++ map_copy_from(map, buf, adr, len); + +- /* Latency issues. Drop the lock, wait a while and retry */ +- spin_unlock(chip->mutex); +- cfi_udelay(1); +- goto retry; ++ put_chip(map, chip, cmd_addr); + +- default: +- sleep: +- /* Stick ourselves on a wait queue to be woken when +- someone changes the status */ +- set_current_state(TASK_UNINTERRUPTIBLE); +- add_wait_queue(&chip->wq, &wait); +- spin_unlock(chip->mutex); +- schedule(); +- remove_wait_queue(&chip->wq, &wait); +- timeo = jiffies + HZ; +- goto retry; +- } +- +- map->copy_from(map, buf, adr, len); +- +- if (suspended) { +- chip->state = chip->oldstate; +- /* What if one interleaved chip has finished and the +- other hasn't? The old code would leave the finished +- one in READY mode. That's bad, and caused -EROFS +- errors to be returned from do_erase_oneblock because +- that's the only bit it checked for at the time. +- As the state machine appears to explicitly allow +- sending the 0x70 (Read Status) command to an erasing +- chip and expecting it to be ignored, that's what we +- do. */ +- cfi_write(map, CMD(0xd0), cmd_addr); +- cfi_write(map, CMD(0x70), cmd_addr); +- } +- +- wake_up(&chip->wq); + spin_unlock(chip->mutex); + return 0; + } +@@ -640,70 +649,52 @@ + { + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; +- struct cfi_pri_intelext *extp=cfi->cmdset_priv; +- int ofs_factor = cfi->interleave * cfi->device_type; +- int count=len; ++ struct cfi_pri_intelext *extp = cfi->cmdset_priv; + struct flchip *chip; +- int chip_num,offst; +- unsigned long timeo; +- DECLARE_WAITQUEUE(wait, current); ++ int ofs_factor = cfi->interleave * cfi->device_type; ++ int count = len; ++ int chip_num, offst; ++ int ret; + +- chip=0; +- /* Calculate which chip & protection register offset we need */ +- chip_num=((unsigned int)from/reg_sz); +- offst=from-(reg_sz*chip_num)+base_offst; ++ chip_num = ((unsigned int)from/reg_sz); ++ offst = from - (reg_sz*chip_num)+base_offst; + +- while(count){ ++ while (count) { ++ /* Calculate which chip & protection register offset we need */ + +- if(chip_num>=cfi->numchips) ++ if (chip_num >= cfi->numchips) + goto out; + +- /* Make sure that the chip is in the right state */ ++ chip = &cfi->chips[chip_num]; + +- timeo = jiffies + HZ; +- chip=&cfi->chips[chip_num]; +- retry: + spin_lock(chip->mutex); +- +- switch (chip->state) { +- case FL_READY: +- case FL_STATUS: +- case FL_CFI_QUERY: +- case FL_JEDEC_QUERY: +- break; +- +- default: +- /* Stick ourselves on a wait queue to be woken when +- someone changes the status */ +- set_current_state(TASK_UNINTERRUPTIBLE); +- add_wait_queue(&chip->wq, &wait); ++ ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY); ++ if (ret) { + spin_unlock(chip->mutex); +- schedule(); +- remove_wait_queue(&chip->wq, &wait); +- timeo = jiffies + HZ; +- goto retry; ++ return (len-count)?:ret; + } + +- /* Now read the data required from this flash */ ++ if (chip->state != FL_JEDEC_QUERY) { ++ cfi_write(map, CMD(0x90), chip->start); ++ chip->state = FL_JEDEC_QUERY; ++ } + +- cfi_send_gen_cmd(0x90, 0x55,chip->start, map, cfi, cfi->device_type, NULL); +- while(count && ((offst-base_offst)read8(map,(chip->start+((extp->ProtRegAddr+1)*ofs_factor)+offst)); ++ while (count && ((offst-base_offst) < reg_sz)) { ++ *buf = map_read8(map,(chip->start+((extp->ProtRegAddr+1)*ofs_factor)+offst)); + buf++; + offst++; + count--; + } + +- chip->state=FL_CFI_QUERY; ++ put_chip(map, chip, chip->start); + spin_unlock(chip->mutex); ++ + /* Move on to the next chip */ + chip_num++; +- offst=base_offst; +- ++ offst = base_offst; + } + + out: +- wake_up(&chip->wq); + return len-count; + } + +@@ -749,103 +740,20 @@ + static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, cfi_word datum) + { + struct cfi_private *cfi = map->fldrv_priv; +- struct cfi_pri_intelext *extp = cfi->cmdset_priv; +- cfi_word status, status_OK; +- unsigned long timeo; +- DECLARE_WAITQUEUE(wait, current); +- int z, suspended=0, ret=0; +- +- adr += chip->start; +- +- /* Let's determine this according to the interleave only once */ +- status_OK = CMD(0x80); +- +- timeo = jiffies + HZ; +- retry: +- spin_lock(chip->mutex); +- +- /* Check that the chip's ready to talk to us. +- * Later, we can actually think about interrupting it +- * if it's in FL_ERASING state. +- * Not just yet, though. +- */ +- switch (chip->state) { +- case FL_READY: +- break; +- +- case FL_CFI_QUERY: +- case FL_JEDEC_QUERY: +- cfi_write(map, CMD(0x70), adr); +- chip->state = FL_STATUS; +- +- case FL_STATUS: +- status = cfi_read(map, adr); +- if ((status & status_OK) == status_OK) +- break; +- +- /* Urgh. Chip not yet ready to talk to us. */ +- if (time_after(jiffies, timeo)) { +- spin_unlock(chip->mutex); +- printk(KERN_ERR "waiting for chip to be ready timed out in read\n"); +- return -EIO; +- } +- +- /* Latency issues. Drop the lock, wait a while and retry */ +- spin_unlock(chip->mutex); +- cfi_udelay(1); +- goto retry; +- +- case FL_ERASING: +- if (!extp || +- !((extp->FeatureSupport & 2) && (extp->SuspendCmdSupport & 1))) +- goto sleep; /* We don't support erase suspend */ +- +- cfi_write (map, CMD(0xb0), adr); +- +- /* If the flash has finished erasing, then 'erase suspend' +- * appears to make some (28F320) flash devices switch to +- * 'read' mode. Make sure that we switch to 'read status' +- * mode so we get the right data. --rmk +- */ +- cfi_write(map, CMD(0x70), adr); +- chip->oldstate = FL_ERASING; +- chip->state = FL_ERASE_SUSPENDING; +- for (;;) { +- status = cfi_read(map, adr); +- if ((status & status_OK) == status_OK) +- break; ++ cfi_word status, status_OK; ++ unsigned long timeo; ++ int z, ret=0; + +- if (time_after(jiffies, timeo)) { +- /* Urgh */ +- cfi_write(map, CMD(0xd0), adr); +- /* make sure we're in 'read status' mode */ +- cfi_write(map, CMD(0x70), adr); +- chip->state = FL_ERASING; +- spin_unlock(chip->mutex); +- printk(KERN_ERR "Chip not ready after erase " +- "suspended: status = 0x%x\n", status); +- return -EIO; +- } ++ adr += chip->start; + +- spin_unlock(chip->mutex); +- cfi_udelay(1); +- spin_lock(chip->mutex); +- } +- suspended = 1; +- chip->state = FL_STATUS; +- break; ++ /* Let's determine this according to the interleave only once */ ++ status_OK = CMD(0x80); + +- default: +- sleep: +- /* Stick ourselves on a wait queue to be woken when +- someone changes the status */ +- set_current_state(TASK_UNINTERRUPTIBLE); +- add_wait_queue(&chip->wq, &wait); ++ spin_lock(chip->mutex); ++ ret = get_chip(map, chip, adr, FL_WRITING); ++ if (ret) { + spin_unlock(chip->mutex); +- schedule(); +- remove_wait_queue(&chip->wq, &wait); +- timeo = jiffies + HZ; +- goto retry; ++ return ret; + } + + ENABLE_VPP(map); +@@ -862,6 +770,8 @@ + for (;;) { + if (chip->state != FL_WRITING) { + /* Someone's suspended the write. Sleep */ ++ DECLARE_WAITQUEUE(wait, current); ++ + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + spin_unlock(chip->mutex); +@@ -879,7 +789,6 @@ + /* OK Still waiting */ + if (time_after(jiffies, timeo)) { + chip->state = FL_STATUS; +- DISABLE_VPP(map); + printk(KERN_ERR "waiting for chip to be ready timed out in word write\n"); + ret = -EIO; + goto out; +@@ -908,27 +817,11 @@ + /* put back into read status register mode */ + cfi_write(map, CMD(0x70), adr); + ret = -EROFS; +- goto out; + } + out: +- if (suspended) { +- chip->state = chip->oldstate; +- /* What if one interleaved chip has finished and the +- other hasn't? The old code would leave the finished +- one in READY mode. That's bad, and caused -EROFS +- errors to be returned from do_erase_oneblock because +- that's the only bit it checked for at the time. +- As the state machine appears to explicitly allow +- sending the 0x70 (Read Status) command to an erasing +- chip and expecting it to be ignored, that's what we +- do. */ +- cfi_write(map, CMD(0xd0), adr); +- cfi_write(map, CMD(0x70), adr); +- } else +- DISABLE_VPP(map); /* must not clear the VPP if there is a suspended erase to be resumed */ +- +- wake_up(&chip->wq); ++ put_chip(map, chip, adr); + spin_unlock(chip->mutex); ++ + return ret; + } + +@@ -1059,11 +952,9 @@ + unsigned long adr, const u_char *buf, int len) + { + struct cfi_private *cfi = map->fldrv_priv; +- struct cfi_pri_intelext *extp = cfi->cmdset_priv; + cfi_word status, status_OK; + unsigned long cmd_adr, timeo; +- DECLARE_WAITQUEUE(wait, current); +- int wbufsize, z, suspended=0, ret=0; ++ int wbufsize, z, ret=0, bytes, words; + + wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize; + adr += chip->start; +@@ -1072,91 +963,18 @@ + /* Let's determine this according to the interleave only once */ + status_OK = CMD(0x80); + +- timeo = jiffies + HZ; +- retry: + spin_lock(chip->mutex); +- +- /* Check that the chip's ready to talk to us. +- * Later, we can actually think about interrupting it +- * if it's in FL_ERASING state. +- * Not just yet, though. +- */ +- switch (chip->state) { +- case FL_READY: +- case FL_CFI_QUERY: +- case FL_JEDEC_QUERY: +- cfi_write(map, CMD(0x70), cmd_adr); +- chip->state = FL_STATUS; +- +- case FL_STATUS: +- status = cfi_read(map, cmd_adr); +- if ((status & status_OK) == status_OK) +- break; +- /* Urgh. Chip not yet ready to talk to us. */ +- if (time_after(jiffies, timeo)) { ++ ret = get_chip(map, chip, cmd_adr, FL_WRITING); ++ if (ret) { + spin_unlock(chip->mutex); +- printk(KERN_ERR "waiting for chip to be ready timed out in buffer write\n"); +- return -EIO; ++ return ret; + } + +- /* Latency issues. Drop the lock, wait a while and retry */ +- spin_unlock(chip->mutex); +- cfi_udelay(1); +- goto retry; +- +- case FL_ERASING: +- if (!extp || +- !((extp->FeatureSupport & 2) && (extp->SuspendCmdSupport & 1))) +- goto sleep; /* We don't support erase suspend */ +- +- cfi_write (map, CMD(0xb0), adr); +- +- /* If the flash has finished erasing, then 'erase suspend' +- * appears to make some (28F320) flash devices switch to +- * 'read' mode. Make sure that we switch to 'read status' +- * mode so we get the right data. --rmk +- */ +- cfi_write(map, CMD(0x70), adr); +- chip->oldstate = FL_ERASING; +- chip->state = FL_ERASE_SUSPENDING; +- for (;;) { +- status = cfi_read(map, adr); +- if ((status & status_OK) == status_OK) +- break; +- +- if (time_after(jiffies, timeo)) { +- /* Urgh */ +- cfi_write(map, CMD(0xd0), adr); +- /* make sure we're in 'read status' mode */ +- cfi_write(map, CMD(0x70), adr); +- chip->state = FL_ERASING; +- spin_unlock(chip->mutex); +- printk(KERN_ERR "Chip not ready after erase " +- "suspended: status = 0x%x\n", status); +- return -EIO; +- } ++ if (chip->state != FL_STATUS) ++ cfi_write(map, CMD(0x70), cmd_adr); + +- spin_unlock(chip->mutex); +- cfi_udelay(1); +- spin_lock(chip->mutex); +- } +- suspended = 1; +- chip->state = FL_STATUS; +- break; ++ status = cfi_read(map, cmd_adr); + +- default: +- sleep: +- /* Stick ourselves on a wait queue to be woken when +- someone changes the status */ +- set_current_state(TASK_UNINTERRUPTIBLE); +- add_wait_queue(&chip->wq, &wait); +- spin_unlock(chip->mutex); +- schedule(); +- remove_wait_queue(&chip->wq, &wait); +- timeo = jiffies + HZ; +- goto retry; +- } +- /* We know we're now in FL_STATUS mode, and 'status' is current */ + /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set + [...], the device will not accept any more Write to Buffer commands". + So we must check here and reset those bits if they're set. Otherwise +@@ -1185,7 +1003,6 @@ + /* Argh. Not ready for write to buffer */ + cfi_write(map, CMD(0x70), cmd_adr); + chip->state = FL_STATUS; +- DISABLE_VPP(map); + printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %llx, status = %llx\n", (__u64)status, (__u64)cfi_read(map, cmd_adr)); + /* Odd. Clear status bits */ + cfi_write(map, CMD(0x50), cmd_adr); +@@ -1196,20 +1013,42 @@ + } + + /* Write length of data to come */ +- cfi_write(map, CMD(len/CFIDEV_BUSWIDTH-1), cmd_adr ); ++ bytes = len & (CFIDEV_BUSWIDTH-1); ++ words = len / CFIDEV_BUSWIDTH; ++ cfi_write(map, CMD(words - !bytes), cmd_adr ); + + /* Write data */ +- for (z = 0; z < len; z += CFIDEV_BUSWIDTH) { ++ z = 0; ++ while(z < words * CFIDEV_BUSWIDTH) { + if (cfi_buswidth_is_1()) { +- map->write8 (map, *((__u8*)buf)++, adr+z); ++ map_write8 (map, *((__u8*)buf)++, adr+z); + } else if (cfi_buswidth_is_2()) { +- map->write16 (map, *((__u16*)buf)++, adr+z); ++ map_write16 (map, *((__u16*)buf)++, adr+z); + } else if (cfi_buswidth_is_4()) { +- map->write32 (map, *((__u32*)buf)++, adr+z); ++ map_write32 (map, *((__u32*)buf)++, adr+z); + } else if (cfi_buswidth_is_8()) { +- map->write64 (map, *((__u64*)buf)++, adr+z); ++ map_write64 (map, *((__u64*)buf)++, adr+z); ++ } else { ++ ret = -EINVAL; ++ goto out; ++ } ++ z += CFIDEV_BUSWIDTH; ++ } ++ if (bytes) { ++ int i = 0, n = 0; ++ u_char tmp_buf[8], *tmp_p = tmp_buf; ++ ++ while (bytes--) ++ tmp_buf[i++] = buf[n++]; ++ while (i < CFIDEV_BUSWIDTH) ++ tmp_buf[i++] = 0xff; ++ if (cfi_buswidth_is_2()) { ++ map_write16 (map, *((__u16*)tmp_p)++, adr+z); ++ } else if (cfi_buswidth_is_4()) { ++ map_write32 (map, *((__u32*)tmp_p)++, adr+z); ++ } else if (cfi_buswidth_is_8()) { ++ map_write64 (map, *((__u64*)tmp_p)++, adr+z); + } else { +- DISABLE_VPP(map); + ret = -EINVAL; + goto out; + } +@@ -1227,6 +1066,7 @@ + for (;;) { + if (chip->state != FL_WRITING) { + /* Someone's suspended the write. Sleep */ ++ DECLARE_WAITQUEUE(wait, current); + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + spin_unlock(chip->mutex); +@@ -1244,7 +1084,6 @@ + /* OK Still waiting */ + if (time_after(jiffies, timeo)) { + chip->state = FL_STATUS; +- DISABLE_VPP(map); + printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); + ret = -EIO; + goto out; +@@ -1266,6 +1105,7 @@ + + /* Done and happy. */ + chip->state = FL_STATUS; ++ + /* check for lock bit */ + if (status & CMD(0x02)) { + /* clear status */ +@@ -1273,26 +1113,10 @@ + /* put back into read status register mode */ + cfi_write(map, CMD(0x70), adr); + ret = -EROFS; +- goto out; + } +- out: +- if (suspended) { +- chip->state = chip->oldstate; +- /* What if one interleaved chip has finished and the +- other hasn't? The old code would leave the finished +- one in READY mode. That's bad, and caused -EROFS +- errors to be returned from do_erase_oneblock because +- that's the only bit it checked for at the time. +- As the state machine appears to explicitly allow +- sending the 0x70 (Read Status) command to an erasing +- chip and expecting it to be ignored, that's what we +- do. */ +- cfi_write(map, CMD(0xd0), adr); +- cfi_write(map, CMD(0x70), adr); +- } else +- DISABLE_VPP(map); /* must not clear the VPP if there is a suspended erase to be resumed */ + +- wake_up(&chip->wq); ++ out: ++ put_chip(map, chip, cmd_adr); + spin_unlock(chip->mutex); + return ret; + } +@@ -1336,12 +1160,12 @@ + } + + /* Write buffer is worth it only if more than one word to write... */ +- while(len > CFIDEV_BUSWIDTH) { ++ while(len) { + /* We must not cross write block boundaries */ + int size = wbufsize - (ofs & (wbufsize-1)); + + if (size > len) +- size = len & ~(CFIDEV_BUSWIDTH-1); ++ size = len; + ret = do_write_buffer(map, &cfi->chips[chipnum], + ofs, buf, size); + if (ret) +@@ -1359,17 +1183,6 @@ + return 0; + } + } +- +- /* ... and write the remaining bytes */ +- if (len > 0) { +- size_t local_retlen; +- ret = cfi_intelext_write_words(mtd, ofs + (chipnum << cfi->chipshift), +- len, &local_retlen, buf); +- if (ret) +- return ret; +- (*retlen) += local_retlen; +- } +- + return 0; + } + +@@ -1479,45 +1292,12 @@ + /* Let's determine this according to the interleave only once */ + status_OK = CMD(0x80); + +- timeo = jiffies + HZ; +-retry: ++ retry: + spin_lock(chip->mutex); +- +- /* Check that the chip's ready to talk to us. */ +- switch (chip->state) { +- case FL_CFI_QUERY: +- case FL_JEDEC_QUERY: +- case FL_READY: +- cfi_write(map, CMD(0x70), adr); +- chip->state = FL_STATUS; +- +- case FL_STATUS: +- status = cfi_read(map, adr); +- if ((status & status_OK) == status_OK) +- break; +- +- /* Urgh. Chip not yet ready to talk to us. */ +- if (time_after(jiffies, timeo)) { +- spin_unlock(chip->mutex); +- printk(KERN_ERR "waiting for chip to be ready timed out in erase\n"); +- return -EIO; +- } +- +- /* Latency issues. Drop the lock, wait a while and retry */ +- spin_unlock(chip->mutex); +- cfi_udelay(1); +- goto retry; +- +- default: +- /* Stick ourselves on a wait queue to be woken when +- someone changes the status */ +- set_current_state(TASK_UNINTERRUPTIBLE); +- add_wait_queue(&chip->wq, &wait); ++ ret = get_chip(map, chip, adr, FL_ERASING); ++ if (ret) { + spin_unlock(chip->mutex); +- schedule(); +- remove_wait_queue(&chip->wq, &wait); +- timeo = jiffies + HZ; +- goto retry; ++ return ret; + } + + ENABLE_VPP(map); +@@ -1528,7 +1308,7 @@ + cfi_write(map, CMD(0x20), adr); + cfi_write(map, CMD(0xD0), adr); + chip->state = FL_ERASING; +- chip->oldstate = 0; ++ chip->erase_suspended = 0; + + spin_unlock(chip->mutex); + set_current_state(TASK_UNINTERRUPTIBLE); +@@ -1550,11 +1330,11 @@ + spin_lock(chip->mutex); + continue; + } +- if (chip->oldstate) { ++ if (chip->erase_suspended) { + /* This erase was suspended and resumed. + Adjust the timeout */ + timeo = jiffies + (HZ*20); /* FIXME */ +- chip->oldstate = 0; ++ chip->erase_suspended = 0; + } + + status = cfi_read(map, adr); +@@ -1658,39 +1438,22 @@ + int i; + struct flchip *chip; + int ret = 0; +- DECLARE_WAITQUEUE(wait, current); + + for (i=0; !ret && inumchips; i++) { + chip = &cfi->chips[i]; + +- retry: + spin_lock(chip->mutex); ++ ret = get_chip(map, chip, chip->start, FL_SYNCING); + +- switch(chip->state) { +- case FL_READY: +- case FL_STATUS: +- case FL_CFI_QUERY: +- case FL_JEDEC_QUERY: ++ if (!ret) { + chip->oldstate = chip->state; + chip->state = FL_SYNCING; + /* No need to wake_up() on this state change - + * as the whole point is that nobody can do anything + * with the chip now anyway. + */ +- case FL_SYNCING: +- spin_unlock(chip->mutex); +- break; +- +- default: +- /* Not an idle state */ +- add_wait_queue(&chip->wq, &wait); +- +- spin_unlock(chip->mutex); +- schedule(); +- remove_wait_queue(&chip->wq, &wait); +- +- goto retry; + } ++ spin_unlock(chip->mutex); + } + + /* Unlock the chips again */ +@@ -1731,52 +1494,18 @@ + struct cfi_private *cfi = map->fldrv_priv; + cfi_word status, status_OK; + unsigned long timeo = jiffies + HZ; +- DECLARE_WAITQUEUE(wait, current); ++ int ret; + + adr += chip->start; + + /* Let's determine this according to the interleave only once */ + status_OK = CMD(0x80); + +- timeo = jiffies + HZ; +-retry: + spin_lock(chip->mutex); +- +- /* Check that the chip's ready to talk to us. */ +- switch (chip->state) { +- case FL_CFI_QUERY: +- case FL_JEDEC_QUERY: +- case FL_READY: +- cfi_write(map, CMD(0x70), adr); +- chip->state = FL_STATUS; +- +- case FL_STATUS: +- status = cfi_read(map, adr); +- if ((status & status_OK) == status_OK) +- break; +- +- /* Urgh. Chip not yet ready to talk to us. */ +- if (time_after(jiffies, timeo)) { +- spin_unlock(chip->mutex); +- printk(KERN_ERR "%s: waiting for chip to be ready timed out\n", __FUNCTION__); +- return -EIO; +- } +- +- /* Latency issues. Drop the lock, wait a while and retry */ +- spin_unlock(chip->mutex); +- cfi_udelay(1); +- goto retry; +- +- default: +- /* Stick ourselves on a wait queue to be woken when +- someone changes the status */ +- set_current_state(TASK_UNINTERRUPTIBLE); +- add_wait_queue(&chip->wq, &wait); ++ ret = get_chip(map, chip, adr, FL_LOCKING); ++ if (ret) { + spin_unlock(chip->mutex); +- schedule(); +- remove_wait_queue(&chip->wq, &wait); +- timeo = jiffies + HZ; +- goto retry; ++ return ret; + } + + ENABLE_VPP(map); +@@ -1823,8 +1552,7 @@ + + /* Done and happy. */ + chip->state = FL_STATUS; +- DISABLE_VPP(map); +- wake_up(&chip->wq); ++ put_chip(map, chip, adr); + spin_unlock(chip->mutex); + return 0; + } +@@ -1889,22 +1617,23 @@ + + spin_lock(chip->mutex); + +- switch(chip->state) { ++ switch (chip->state) { + case FL_READY: + case FL_STATUS: + case FL_CFI_QUERY: + case FL_JEDEC_QUERY: ++ if (chip->oldstate == FL_READY) { + chip->oldstate = chip->state; + chip->state = FL_PM_SUSPENDED; + /* No need to wake_up() on this state change - + * as the whole point is that nobody can do anything + * with the chip now anyway. + */ +- case FL_PM_SUSPENDED: ++ } + break; +- + default: + ret = -EAGAIN; ++ case FL_PM_SUSPENDED: + break; + } + spin_unlock(chip->mutex); +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/cfi_cmdset_0002.c linux/drivers/mtd/chips/cfi_cmdset_0002.c +--- linux-mips-2.4.27/drivers/mtd/chips/cfi_cmdset_0002.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/chips/cfi_cmdset_0002.c 2004-11-19 10:25:11.745223200 +0100 +@@ -6,16 +6,22 @@ + * + * 2_by_8 routines added by Simon Munton + * ++ * 4_by_16 work by Carolyn J. Smith ++ * ++ * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com ++ * + * This code is GPL + * +- * $Id: cfi_cmdset_0002.c,v 1.62 2003/01/24 23:30:13 dwmw2 Exp $ ++ * $Id: cfi_cmdset_0002.c,v 1.94 2004/01/27 10:16:20 dvrabel Exp $ + * + */ + ++#include + #include + #include + #include + #include ++#include + #include + #include + +@@ -23,16 +29,50 @@ + #include + #include + #include ++#include + #include ++#include + #include + + #define AMD_BOOTLOC_BUG ++#define FORCE_WORD_WRITE 0 ++ ++ ++/* ++ * This is an attempt to coalesce the retry logic in one place - that way ++ * there aren't #ifdefs scattered throughout. ++ */ ++#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY ++ ++#ifndef CONFIG_MTD_CFI_AMDSTD_RETRY_MAX ++#define CONFIG_MTD_CFI_AMDSTD_RETRY_MAX 0 ++#endif ++ ++#define RETRY_CMD_LABEL retry_cmd: do {} while (0) ++#define HANDLE_WACKY_STATE() handle_wacky_state(__func__, retry_cmd_cnt, adr, datum, prev_oldstatus, prev_status, oldstatus, status) ++static int retry_cmd_max = CONFIG_MTD_CFI_AMDSTD_RETRY_MAX; ++#define DECLARE_RETRY_CMD_CNT() int retry_cmd_cnt = 0 ++#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY ++#define CHECK_RETRIES() do { if (++retry_cmd_cnt <= retry_cmd_max) goto retry_cmd; } while (0) ++#endif ++ ++#else ++ ++#define RETRY_CMD_LABEL do {} while (0) ++#define HANDLE_WACKY_STATE() handle_wacky_state(__func__, adr, datum, prev_oldstatus, prev_status, oldstatus, status) ++#define DECLARE_RETRY_CMD_CNT() ++#define CHECK_RETRIES() ++ ++#endif /* !defined(CONFIG_MTD_CFI_AMDSTD_RETRY) */ ++ + + static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); +-static int cfi_amdstd_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); ++static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); ++static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); + static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *); +-static int cfi_amdstd_erase_onesize(struct mtd_info *, struct erase_info *); + static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *); ++static int cfi_amdstd_lock_varsize(struct mtd_info *, loff_t, size_t); ++static int cfi_amdstd_unlock_varsize(struct mtd_info *, loff_t, size_t); + static void cfi_amdstd_sync (struct mtd_info *); + static int cfi_amdstd_suspend (struct mtd_info *); + static void cfi_amdstd_resume (struct mtd_info *); +@@ -45,55 +85,136 @@ + + + static struct mtd_chip_driver cfi_amdstd_chipdrv = { +- probe: NULL, /* Not usable directly */ +- destroy: cfi_amdstd_destroy, +- name: "cfi_cmdset_0002", +- module: THIS_MODULE ++ .probe = NULL, /* Not usable directly */ ++ .destroy = cfi_amdstd_destroy, ++ .name = "cfi_cmdset_0002", ++ .module = THIS_MODULE + }; + +-struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) ++ ++/* #define DEBUG_LOCK_BITS */ ++/* #define DEBUG_CFI_FEATURES */ ++ ++ ++#ifdef DEBUG_CFI_FEATURES ++static void cfi_tell_features(struct cfi_pri_amdstd *extp) + { +- struct cfi_private *cfi = map->fldrv_priv; +- unsigned char bootloc; +- int ofs_factor = cfi->interleave * cfi->device_type; +- int i; +- __u8 major, minor; +- __u32 base = cfi->chips[0].start; ++ const char* erase_suspend[3] = { ++ "Not supported", "Read only", "Read/write" ++ }; ++ const char* top_bottom[6] = { ++ "No WP", "8x8KiB sectors at top & bottom, no WP", ++ "Bottom boot", "Top boot", ++ "Uniform, Bottom WP", "Uniform, Top WP" ++ }; ++ ++ printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1); ++ printk(" Address sensitive unlock: %s\n", ++ (extp->SiliconRevision & 1) ? "Not required" : "Required"); + +- if (cfi->cfi_mode==CFI_MODE_CFI){ +- __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; ++ if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend)) ++ printk(" Erase Suspend: %s\n", erase_suspend[extp->EraseSuspend]); ++ else ++ printk(" Erase Suspend: Unknown value %d\n", extp->EraseSuspend); + +- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); ++ if (extp->BlkProt == 0) ++ printk(" Block protection: Not supported\n"); ++ else ++ printk(" Block protection: %d sectors per group\n", extp->BlkProt); ++ ++ ++ printk(" Temporary block unprotect: %s\n", ++ extp->TmpBlkUnprotect ? "Supported" : "Not supported"); ++ printk(" Block protect/unprotect scheme: %d\n", extp->BlkProtUnprot); ++ printk(" Number of simultaneous operations: %d\n", extp->SimultaneousOps); ++ printk(" Burst mode: %s\n", ++ extp->BurstMode ? "Supported" : "Not supported"); ++ if (extp->PageMode == 0) ++ printk(" Page mode: Not supported\n"); ++ else ++ printk(" Page mode: %d word page\n", extp->PageMode << 2); + +- major = cfi_read_query(map, base + (adr+3)*ofs_factor); +- minor = cfi_read_query(map, base + (adr+4)*ofs_factor); ++ printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n", ++ extp->VppMin >> 4, extp->VppMin & 0xf); ++ printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n", ++ extp->VppMax >> 4, extp->VppMax & 0xf); + +- printk(KERN_NOTICE " Amd/Fujitsu Extended Query Table v%c.%c at 0x%4.4X\n", +- major, minor, adr); +- cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL); +- +- cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL); +- cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL); +- cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL); +- cfi->mfr = cfi_read_query(map, base); +- cfi->id = cfi_read_query(map, base + ofs_factor); ++ if (extp->TopBottom < ARRAY_SIZE(top_bottom)) ++ printk(" Top/Bottom Boot Block: %s\n", top_bottom[extp->TopBottom]); ++ else ++ printk(" Top/Bottom Boot Block: Unknown value %d\n", extp->TopBottom); ++} ++#endif + +- /* Wheee. Bring me the head of someone at AMD. */ + #ifdef AMD_BOOTLOC_BUG ++/* Wheee. Bring me the head of someone at AMD. */ ++static void fixup_amd_bootblock(struct map_info *map, void* param) ++{ ++ struct cfi_private *cfi = map->fldrv_priv; ++ struct cfi_pri_amdstd *extp = cfi->cmdset_priv; ++ __u8 major = extp->MajorVersion; ++ __u8 minor = extp->MinorVersion; ++ + if (((major << 8) | minor) < 0x3131) { + /* CFI version 1.0 => don't trust bootloc */ + if (cfi->id & 0x80) { + printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id); +- bootloc = 3; /* top boot */ ++ extp->TopBottom = 3; /* top boot */ + } else { +- bootloc = 2; /* bottom boot */ ++ extp->TopBottom = 2; /* bottom boot */ + } +- } else ++ } ++} + #endif ++ ++static struct cfi_fixup fixup_table[] = { ++#ifdef AMD_BOOTLOC_BUG + { +- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); +- bootloc = cfi_read_query(map, base + (adr+15)*ofs_factor); ++ 0x0001, /* AMD */ ++ CFI_ID_ANY, ++ fixup_amd_bootblock, NULL ++ }, ++#endif ++ { 0, 0, NULL, NULL } ++}; ++ ++ ++struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) ++{ ++ struct cfi_private *cfi = map->fldrv_priv; ++ unsigned char bootloc; ++ int i; ++ ++ if (cfi->cfi_mode==CFI_MODE_CFI){ ++ /* ++ * It's a real CFI chip, not one for which the probe ++ * routine faked a CFI structure. So we read the feature ++ * table from it. ++ */ ++ __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; ++ struct cfi_pri_amdstd *extp; ++ ++ extp = (struct cfi_pri_amdstd*)cfi_read_pri(map, adr, sizeof(*extp), "Amd/Fujitsu"); ++ if (!extp) ++ return NULL; ++ ++ /* Install our own private info structure */ ++ cfi->cmdset_priv = extp; ++ ++ cfi_fixup(map, fixup_table); ++ ++#ifdef DEBUG_CFI_FEATURES ++ /* Tell the user about it in lots of lovely detail */ ++ cfi_tell_features(extp); ++#endif ++ ++ bootloc = extp->TopBottom; ++ if ((bootloc != 2) && (bootloc != 3)) { ++ printk(KERN_WARNING "%s: CFI does not contain boot " ++ "bank location. Assuming top.\n", map->name); ++ bootloc = 2; + } ++ + if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) { + printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name); + +@@ -106,6 +227,11 @@ + cfi->cfiq->EraseRegionInfo[j] = swap; + } + } ++ /* ++ * These might already be setup (more correctly) by ++ * jedec_probe.c - still need it for cfi_probe.c path. ++ */ ++ if ( ! (cfi->addr_unlock1 && cfi->addr_unlock2) ) { + switch (cfi->device_type) { + case CFI_DEVICETYPE_X8: + cfi->addr_unlock1 = 0x555; +@@ -125,9 +251,13 @@ + cfi->addr_unlock2 = 0xaaa; + break; + default: +- printk(KERN_NOTICE "Eep. Unknown cfi_cmdset_0002 device type %d\n", cfi->device_type); ++ printk(KERN_WARNING ++ "MTD %s(): Unsupported device type %d\n", ++ __func__, cfi->device_type); + return NULL; + } ++ } ++ + } /* CFI mode */ + + for (i=0; i< cfi->numchips; i++) { +@@ -138,15 +268,17 @@ + + map->fldrv = &cfi_amdstd_chipdrv; + +- cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL); + return cfi_amdstd_setup(map); + } + ++ + static struct mtd_info *cfi_amdstd_setup(struct map_info *map) + { + struct cfi_private *cfi = map->fldrv_priv; + struct mtd_info *mtd; + unsigned long devsize = (1<cfiq->DevSize) * cfi->interleave; ++ unsigned long offset = 0; ++ int i,j; + + mtd = kmalloc(sizeof(*mtd), GFP_KERNEL); + printk(KERN_NOTICE "number of %s chips: %d\n", +@@ -163,15 +295,9 @@ + /* Also select the correct geometry setup too */ + mtd->size = devsize * cfi->numchips; + +- if (cfi->cfiq->NumEraseRegions == 1) { +- /* No need to muck about with multiple erase sizes */ +- mtd->erasesize = ((cfi->cfiq->EraseRegionInfo[0] >> 8) & ~0xff) * cfi->interleave; +- } else { +- unsigned long offset = 0; +- int i,j; +- + mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; +- mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * mtd->numeraseregions, GFP_KERNEL); ++ mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) ++ * mtd->numeraseregions, GFP_KERNEL); + if (!mtd->eraseregions) { + printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n"); + goto setup_err; +@@ -206,39 +332,52 @@ + mtd->eraseregions[i].numblocks); + } + #endif +- } + + switch (CFIDEV_BUSWIDTH) + { + case 1: + case 2: + case 4: +-#if 1 +- if (mtd->numeraseregions > 1) +- mtd->erase = cfi_amdstd_erase_varsize; +- else ++#ifdef CFI_WORD_64 ++ case 8: + #endif +- if (((cfi->cfiq->EraseRegionInfo[0] & 0xffff) + 1) == 1) ++ if (mtd->numeraseregions == 1 ++ && ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) + 1) == 1) { + mtd->erase = cfi_amdstd_erase_chip; +- else +- mtd->erase = cfi_amdstd_erase_onesize; ++ } else { ++ mtd->erase = cfi_amdstd_erase_varsize; ++ mtd->lock = cfi_amdstd_lock_varsize; ++ mtd->unlock = cfi_amdstd_unlock_varsize; ++ } ++ ++ if ( cfi->cfiq->BufWriteTimeoutTyp && !FORCE_WORD_WRITE) { ++ DEBUG(MTD_DEBUG_LEVEL1, "Using buffer write method\n" ); ++ mtd->write = cfi_amdstd_write_buffers; ++ } else { ++ DEBUG(MTD_DEBUG_LEVEL1, "Using word write method\n" ); ++ mtd->write = cfi_amdstd_write_words; ++ } ++ + mtd->read = cfi_amdstd_read; +- mtd->write = cfi_amdstd_write; + break; + + default: +- printk(KERN_WARNING "Unsupported buswidth\n"); ++ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n", ++ __func__, CFIDEV_BUSWIDTH); + goto setup_err; + break; + } + if (cfi->fast_prog) { +- /* In cfi_amdstd_write() we frob the protection stuff ++ /* In cfi_amdstd_write_words() we frob the protection stuff + without paying any attention to the state machine. + This upsets in-progress erases. So we turn this flag + off for now till the code gets fixed. */ + printk(KERN_NOTICE "cfi_cmdset_0002: Disabling fast programming due to code brokenness.\n"); + cfi->fast_prog = 0; + } ++ /* FIXME: erase-suspend-program is broken. See ++ http://lists.infradead.org/pipermail/linux-mtd/2003-December/009001.html */ ++ printk(KERN_NOTICE "cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.\n"); + + + /* does this chip have a secsi area? */ +@@ -266,7 +405,7 @@ + mtd->flags = MTD_CAP_NORFLASH; + map->fldrv = &cfi_amdstd_chipdrv; + mtd->name = map->name; +- MOD_INC_USE_COUNT; ++ __module_get(THIS_MODULE); + return mtd; + + setup_err: +@@ -280,46 +419,210 @@ + return NULL; + } + +-static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) ++ ++/* This is more work to coalesce the retry #ifdefs in one location */ ++static inline void handle_wacky_state(const char *func, ++#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY ++ int retry_cmd_cnt, ++#endif ++ unsigned long adr, ++ cfi_word datum, ++ cfi_word prev_oldstatus, ++ cfi_word prev_status, ++ cfi_word oldstatus, ++ cfi_word status) ++{ ++#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY ++ if ( retry_cmd_cnt == retry_cmd_max ) { ++#endif ++ printk(KERN_WARNING ++ "MTD %s(): Wacky! Unable to decode failure status\n" ++ "Possible buggy device - try " ++#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY ++ "increasing retry_cmd_max from %d\n" ++#else ++ "enabling CONFIG_MTD_CFI_AMDSTD_RETRY\n" ++ "in your kernel config and setting driver retry_cmd_max\n" ++#endif ++ , func ++#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY ++ , retry_cmd_max ++#endif ++ ); ++ ++ printk(KERN_WARNING ++ "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", ++ func, adr, datum, ++ prev_oldstatus, prev_status, ++ oldstatus, status); ++#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY ++ } ++#endif ++} ++ ++ ++static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) + { + DECLARE_WAITQUEUE(wait, current); +- unsigned long timeo = jiffies + HZ; ++ struct cfi_private *cfi = map->fldrv_priv; ++ cfi_word status, oldstatus; ++ cfi_word dq6 = CMD(1<<6); ++ cfi_word dq2 = CMD(1<<2); ++ unsigned long timeo; ++ struct cfi_pri_amdstd *cfip = (struct cfi_pri_amdstd *)cfi->cmdset_priv; + ++ resettime: ++ timeo = jiffies + HZ; + retry: ++ switch (chip->state) { ++ ++ case FL_STATUS: ++ for (;;) { ++ oldstatus = cfi_read(map, adr); ++ status = cfi_read(map, adr); ++ if (((oldstatus ^ status) & (dq6 | dq2)) == 0) ++ break; ++ ++ if (time_after(jiffies, timeo)) { ++ printk(KERN_ERR "Waiting for chip to be ready timed out. Status %llx\n", ++ (long long)status); ++ cfi_spin_unlock(chip->mutex); ++ return -EIO; ++ } ++ cfi_spin_unlock(chip->mutex); ++ cfi_udelay(1); + cfi_spin_lock(chip->mutex); ++ /* Someone else might have been playing with it. */ ++ goto retry; ++ } + +- if (chip->state != FL_READY){ +-#if 0 +- printk(KERN_DEBUG "Waiting for chip to read, status = %d\n", chip->state); +-#endif +- set_current_state(TASK_UNINTERRUPTIBLE); +- add_wait_queue(&chip->wq, &wait); ++ case FL_READY: ++ case FL_CFI_QUERY: ++ case FL_JEDEC_QUERY: ++ return 0; ++ ++ case FL_ERASING: ++ if (mode == FL_WRITING) /* FIXME: Erase-suspend-program appears broken. */ ++ goto sleep; ++ ++ if (!(mode == FL_READY || mode == FL_POINT ++ || (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)) ++ || (mode == FL_WRITING && (cfip->EraseSuspend & 0x1)))) ++ goto sleep; ++ ++ oldstatus = cfi_read(map, adr); ++ status = cfi_read(map, adr); ++ if ((oldstatus ^ status) & dq2) { ++ printk(KERN_ERR "Can't suspend erase -- block in progress\n"); ++ goto sleep; ++ } ++ ++ /* Erase suspend */ ++ /* FIXME - is there a way to verify suspend? */ ++ cfi_write(map, CMD(0xB0), chip->in_progress_block_addr); ++ chip->oldstate = FL_ERASING; ++ chip->state = FL_ERASE_SUSPENDING; ++ chip->erase_suspended = 1; ++ for (;;) { ++ oldstatus = cfi_read(map, chip->in_progress_block_addr); ++ status = cfi_read(map, chip->in_progress_block_addr); ++ if (((oldstatus ^ status) & dq6) == 0) ++ break; ++ ++ if (time_after(jiffies, timeo)) { ++ /* Urgh. Resume and pretend we weren't here. */ ++ /* FIXME - is there a way to verify resume? */ ++ cfi_write(map, CMD(0x30), chip->in_progress_block_addr); ++ chip->state = FL_ERASING; ++ chip->oldstate = FL_READY; ++ printk(KERN_ERR "Chip not ready after erase " ++ "suspended: status = 0x%x\n", status); ++ return -EIO; ++ } + + cfi_spin_unlock(chip->mutex); ++ cfi_udelay(1); ++ cfi_spin_lock(chip->mutex); ++ /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING. ++ So we can just loop here. */ ++ } ++ chip->state = FL_READY; ++ return 0; ++ ++ case FL_POINT: ++ /* Only if there's no operation suspended... */ ++ if (mode == FL_READY && chip->oldstate == FL_READY) ++ return 0; + ++ default: ++ sleep: ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ add_wait_queue(&chip->wq, &wait); ++ cfi_spin_unlock(chip->mutex); + schedule(); + remove_wait_queue(&chip->wq, &wait); +-#if 0 +- if(signal_pending(current)) +- return -EINTR; +-#endif +- timeo = jiffies + HZ; ++ cfi_spin_lock(chip->mutex); ++ goto resettime; ++ } ++} + +- goto retry; ++ ++static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr) ++{ ++ struct cfi_private *cfi = map->fldrv_priv; ++ ++ switch(chip->oldstate) { ++ case FL_ERASING: ++ chip->state = chip->oldstate; ++ cfi_write(map, CMD(0x30), chip->in_progress_block_addr); ++ chip->oldstate = FL_READY; ++ chip->state = FL_ERASING; ++ break; ++ ++ case FL_READY: ++ case FL_STATUS: ++ /* We should really make set_vpp() count, rather than doing this */ ++ DISABLE_VPP(map); ++ break; ++ default: ++ printk(KERN_ERR "MTD: put_chip() called with oldstate %d!!\n", chip->oldstate); + } ++ wake_up(&chip->wq); ++} ++ ++ ++static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) ++{ ++ unsigned long cmd_addr; ++ struct cfi_private *cfi = map->fldrv_priv; ++ int ret; + + adr += chip->start; + ++ /* Ensure cmd read/writes are aligned. */ ++ cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1); ++ ++ cfi_spin_lock(chip->mutex); ++ ret = get_chip(map, chip, cmd_addr, FL_READY); ++ if (ret) { ++ cfi_spin_unlock(chip->mutex); ++ return ret; ++ } ++ ++ if (chip->state != FL_POINT && chip->state != FL_READY) { ++ cfi_write(map, CMD(0xf0), cmd_addr); + chip->state = FL_READY; ++ } + +- map->copy_from(map, buf, adr, len); ++ map_copy_from(map, buf, adr, len); + +- wake_up(&chip->wq); +- cfi_spin_unlock(chip->mutex); ++ put_chip(map, chip, cmd_addr); + ++ cfi_spin_unlock(chip->mutex); + return 0; + } + ++ + static int cfi_amdstd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) + { + struct map_info *map = mtd->priv; +@@ -361,6 +664,7 @@ + return ret; + } + ++ + static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) + { + DECLARE_WAITQUEUE(wait, current); +@@ -394,12 +698,14 @@ + + chip->state = FL_READY; + ++ /* should these be CFI_DEVICETYPE_X8 instead of cfi->device_type? */ + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + +- map->copy_from(map, buf, adr, len); ++ map_copy_from(map, buf, adr, len); + ++ /* should these be CFI_DEVICETYPE_X8 instead of cfi->device_type? */ + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); +@@ -454,125 +760,241 @@ + return ret; + } + +-static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum, int fast) ++ ++static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, cfi_word datum, int fast) + { +- unsigned long timeo = jiffies + HZ; +- unsigned int oldstatus, status; +- unsigned int dq6, dq5; + struct cfi_private *cfi = map->fldrv_priv; +- DECLARE_WAITQUEUE(wait, current); ++ unsigned long timeo = jiffies + HZ; ++ cfi_word oldstatus, status, prev_oldstatus, prev_status; ++ cfi_word dq6 = CMD(1<<6); ++ /* ++ * We use a 1ms + 1 jiffies generic timeout for writes (most devices ++ * have a max write time of a few hundreds usec). However, we should ++ * use the maximum timeout value given by the chip at probe time ++ * instead. Unfortunately, struct flchip does have a field for ++ * maximum timeout, only for typical which can be far too short ++ * depending of the conditions. The ' + 1' is to avoid having a ++ * timeout of 0 jiffies if HZ is smaller than 1000. ++ */ ++ unsigned long uWriteTimeout = ( HZ / 1000 ) + 1; + int ret = 0; ++ int ta = 0; ++ DECLARE_RETRY_CMD_CNT(); + +- retry: +- cfi_spin_lock(chip->mutex); +- +- if (chip->state != FL_READY) { +-#if 0 +- printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", chip->state); +-#endif +- set_current_state(TASK_UNINTERRUPTIBLE); +- add_wait_queue(&chip->wq, &wait); ++ adr += chip->start; + ++ cfi_spin_lock(chip->mutex); ++ ret = get_chip(map, chip, adr, FL_WRITING); ++ if (ret) { + cfi_spin_unlock(chip->mutex); +- +- schedule(); +- remove_wait_queue(&chip->wq, &wait); +-#if 0 +- printk(KERN_DEBUG "Wake up to write:\n"); +- if(signal_pending(current)) +- return -EINTR; +-#endif +- timeo = jiffies + HZ; +- +- goto retry; ++ return ret; + } + +- chip->state = FL_WRITING; ++ RETRY_CMD_LABEL; ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8x)\n", ++ __func__, adr, datum ); ++ ++ /* ++ * Check for a NOP for the case when the datum to write is already ++ * present - it saves time and works around buggy chips that corrupt ++ * data at other locations when 0xff is written to a location that ++ * already contains 0xff. ++ */ ++ status = cfi_read(map, adr); ++ if (status == datum) { ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): NOP 0x%.8x == 0x%.8x\n", ++ __func__, status, datum ); ++ goto op_done; ++ } + +- adr += chip->start; + ENABLE_VPP(map); + if (fast) { /* Unlock bypass */ + cfi_send_gen_cmd(0xA0, 0, chip->start, map, cfi, cfi->device_type, NULL); +- } +- else { ++ } else { ++ /* ++ * The CFI_DEVICETYPE_X8 argument is needed even when ++ * cfi->device_type != CFI_DEVICETYPE_X8. The addresses for ++ * command sequences don't scale even when the device is ++ * wider. This is the case for many of the cfi_send_gen_cmd() ++ * below. I'm not sure, however, why some use ++ * cfi->device_type. ++ */ + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); + cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); + } +- + cfi_write(map, datum, adr); ++ chip->state = FL_WRITING; + + cfi_spin_unlock(chip->mutex); + cfi_udelay(chip->word_write_time); + cfi_spin_lock(chip->mutex); + +- /* Polling toggle bits instead of reading back many times +- This ensures that write operation is really completed, +- or tells us why it failed. */ +- dq6 = CMD(1<<6); +- dq5 = CMD(1<<5); +- timeo = jiffies + (HZ/1000); /* setting timeout to 1ms for now */ ++ /* ++ * Polling toggle bits instead of reading back many times This ensures ++ * that write operation is really completed, or tells us why it ++ * failed. ++ * ++ * It may appear that the polling and decoding of error state might be ++ * simplified. Don't do it unless you really know what you are doing. ++ * ++ * You must remember that JESD21-C 3.5.3 states that the status must ++ * be read back an _additional_ two times before a failure is ++ * determined. This is because these devices have internal state ++ * machines that are asynchronous to the external data bus. During an ++ * erase or write the read-back status of the polling bits might be ++ * transitioning internaly when the external read-back occurs. This ++ * means that the bits aren't in the final state and they might appear ++ * to report an error as they are in a transient state: dq7 is ++ * asynchronous with dq6 and other status bits. ++ * ++ * This asynchronous behaviour can cause infrequent errors that will ++ * usually disappear the next time an erase or write happens (Try ++ * tracking those errors down!). To ensure that the bits are not in ++ * transition, the location must be read-back two more times and ++ * compared against what was written - BOTH reads MUST match what was ++ * written. Don't think this can be simplified to only the last read ++ * matching the datum written: status bits *can* match the datum ++ * written. ++ * ++ * If the final comparison fails, error state can *then* be decoded. ++ * ++ * - Thayne Harbaugh ++ */ ++ /* See comment above for timeout value. */ ++ timeo = jiffies + uWriteTimeout; ++ for (;;) { ++ if (chip->state != FL_WRITING) { ++ /* Someone's suspended the write. Sleep */ ++ DECLARE_WAITQUEUE(wait, current); ++ ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ add_wait_queue(&chip->wq, &wait); ++ cfi_spin_unlock(chip->mutex); ++ schedule(); ++ remove_wait_queue(&chip->wq, &wait); ++ timeo = jiffies + (HZ / 2); /* FIXME */ ++ cfi_spin_lock(chip->mutex); ++ continue; ++ } + + oldstatus = cfi_read(map, adr); + status = cfi_read(map, adr); ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n", ++ __func__, oldstatus, status ); + +- while( (status & dq6) != (oldstatus & dq6) && +- (status & dq5) != dq5 && +- !time_after(jiffies, timeo) ) { ++ /* ++ * This only checks if dq6 is still toggling and that our ++ * timer hasn't expired. We purposefully ignore the chip's ++ * internal timer that will assert dq5 and leave dq6 toggling. ++ * This is done for a variety of reasons: ++ * ++ * 1) Not all chips support dq5. ++ * ++ * 2) Dealing with asynchronous status bit and data updates ++ * and reading a device two more times creates _messy_ logic ++ * when trying to deal with interleaved devices - some may be ++ * changing while others are still busy. ++ * ++ * 3) Checking dq5 only helps to optimize an error case that ++ * should at worst be infrequent and at best non-existent. ++ * ++ * If our timeout occurs _then_ we will check dq5 to see if ++ * the device also had an internal timeout. ++ */ ++ if ( (((status ^ oldstatus) & dq6) == 0) ++ || ( ta = time_after(jiffies, timeo)) ) ++ break; + +- if (need_resched()) { ++ /* Latency issues. Drop the lock, wait a while and retry */ + cfi_spin_unlock(chip->mutex); +- yield(); ++ cfi_udelay(1); + cfi_spin_lock(chip->mutex); +- } else +- udelay(1); +- +- oldstatus = cfi_read( map, adr ); +- status = cfi_read( map, adr ); + } + +- if( (status & dq6) != (oldstatus & dq6) ) { +- /* The erasing didn't stop?? */ +- if( (status & dq5) == dq5 ) { +- /* When DQ5 raises, we must check once again +- if DQ6 is toggling. If not, the erase has been +- completed OK. If not, reset chip. */ ++ /* ++ * Something kicked us out of the read-back loop. We'll check success ++ * befor checking failure. Even though dq6 might be true data, it is ++ * unkown if all of the other bits have changed to true data due to ++ * the asynchronous nature of the internal state machine. We will ++ * read two more times and use this to either verify that the write ++ * completed successfully or that something really went wrong. BOTH ++ * reads must match what was written - this certifies that bits aren't ++ * still changing and that the status bits erroneously match the datum ++ * that was written. ++ */ ++ prev_oldstatus = oldstatus; ++ prev_status = status; + oldstatus = cfi_read(map, adr); + status = cfi_read(map, adr); ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n", ++ __func__, oldstatus, status ); + +- if ( (oldstatus & 0x00FF) == (status & 0x00FF) ) { +- printk(KERN_WARNING "Warning: DQ5 raised while program operation was in progress, however operation completed OK\n" ); ++ if ( oldstatus == datum && status == datum ) { ++ /* success - do nothing */ ++ goto op_done; ++ } ++ ++ if ( ta ) { ++ /* Only check dq5 on the chips that are still toggling. */ ++ cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1; ++ if ( status & dq5mask ) { ++ /* dq5 asserted - decode interleave chips */ ++ printk( KERN_WARNING ++ "MTD %s(): FLASH internal timeout: 0x%.8x 0x%.8x 0x%8x\n", ++ __func__, ++ status & dq5mask, status, datum ); + } else { +- /* DQ5 is active so we can do a reset and stop the erase */ +- cfi_write(map, CMD(0xF0), chip->start); +- printk(KERN_WARNING "Internal flash device timeout occurred or write operation was performed while flash was programming.\n" ); ++ printk( KERN_WARNING ++ "MTD %s(): Software timed out during write.\n", ++ __func__ ); ++ } ++ goto op_failed; + } +- } else { +- printk(KERN_WARNING "Waiting for write to complete timed out in do_write_oneword."); + ++ /* ++ * If we get to here then it means that something ++ * is wrong and it's not a timeout. Something ++ * is seriously wacky! Dump some debug info. ++ */ ++ /* ++ * Found a clue about the chips that reach this state. ++ * Some flash chips (SST >cough<) ++ * are horribly broken. They do not ignore traffic that is ++ * destined to other devices. This happens because some solutions ++ * are on shared busses, the erase and program sequences have ++ * have multiple commands, and the sequence is interspersed with ++ * commands destined to other devices. A good flash chip will ++ * examine the command and destination address and will ignore ++ * commands that are for other devices. ++ */ ++ HANDLE_WACKY_STATE(); ++ ++ op_failed: ++ /* reset on all failures. */ ++ cfi_write( map, CMD(0xF0), chip->start ); ++ /* FIXME - should have reset delay before continuing */ ++ CHECK_RETRIES(); ++ ret = -EIO; ++ ++ op_done: + chip->state = FL_READY; +- wake_up(&chip->wq); +- cfi_spin_unlock(chip->mutex); +- DISABLE_VPP(map); +- ret = -EIO; +- } +- } +- +- DISABLE_VPP(map); +- chip->state = FL_READY; +- wake_up(&chip->wq); ++ put_chip(map, chip, adr); + cfi_spin_unlock(chip->mutex); + + return ret; + } + +-static int cfi_amdstd_write (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf) ++ ++static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf) + { + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + int ret = 0; + int chipnum; + unsigned long ofs, chipstart; ++ DECLARE_WAITQUEUE(wait, current); + + *retlen = 0; + if (!len) +@@ -587,19 +1009,52 @@ + unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1); + int i = ofs - bus_ofs; + int n = 0; +- u_char tmp_buf[4]; +- __u32 datum; ++ u_char tmp_buf[8]; ++ cfi_word datum; ++ ++ retry: ++ cfi_spin_lock(cfi->chips[chipnum].mutex); ++ ++ if (cfi->chips[chipnum].state != FL_READY) { ++#if 0 ++ printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state); ++#endif ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ add_wait_queue(&cfi->chips[chipnum].wq, &wait); ++ ++ cfi_spin_unlock(cfi->chips[chipnum].mutex); ++ ++ schedule(); ++ remove_wait_queue(&cfi->chips[chipnum].wq, &wait); ++#if 0 ++ if(signal_pending(current)) ++ return -EINTR; ++#endif ++ goto retry; ++ } ++ ++ map_copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH); + +- map->copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH); +- while (len && i < CFIDEV_BUSWIDTH) +- tmp_buf[i++] = buf[n++], len--; ++ cfi_spin_unlock(cfi->chips[chipnum].mutex); ++ ++ while (len && i < CFIDEV_BUSWIDTH) { ++ tmp_buf[i++] = buf[n++]; ++ len--; ++ } + ++ /* already know that buswidth > 1 */ + if (cfi_buswidth_is_2()) { + datum = *(__u16*)tmp_buf; + } else if (cfi_buswidth_is_4()) { + datum = *(__u32*)tmp_buf; ++#ifdef CFI_WORD_64 ++ } else if (cfi_buswidth_is_8()) { ++ datum = *(__u64*)tmp_buf; ++#endif + } else { +- return -EINVAL; /* should never happen, but be safe */ ++ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n", ++ __func__, CFIDEV_BUSWIDTH); ++ return -EINVAL; + } + + ret = do_write_oneword(map, &cfi->chips[chipnum], +@@ -628,7 +1083,7 @@ + + /* We are now aligned, write as much as possible */ + while(len >= CFIDEV_BUSWIDTH) { +- __u32 datum; ++ cfi_word datum; + + if (cfi_buswidth_is_1()) { + datum = *(__u8*)buf; +@@ -636,7 +1091,13 @@ + datum = *(__u16*)buf; + } else if (cfi_buswidth_is_4()) { + datum = *(__u32*)buf; ++#ifdef CFI_WORD_64 ++ } else if (cfi_buswidth_is_8()) { ++ datum = *(__u64*)buf; ++#endif + } else { ++ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n", ++ __func__, CFIDEV_BUSWIDTH); + return -EINVAL; + } + ret = do_write_oneword(map, &cfi->chips[chipnum], +@@ -685,10 +1146,34 @@ + /* Write the trailing bytes if any */ + if (len & (CFIDEV_BUSWIDTH-1)) { + int i = 0, n = 0; +- u_char tmp_buf[4]; +- __u32 datum; ++ u_char tmp_buf[8]; ++ cfi_word datum; ++ ++ retry1: ++ cfi_spin_lock(cfi->chips[chipnum].mutex); ++ ++ if (cfi->chips[chipnum].state != FL_READY) { ++#if 0 ++ printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state); ++#endif ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ add_wait_queue(&cfi->chips[chipnum].wq, &wait); ++ ++ cfi_spin_unlock(cfi->chips[chipnum].mutex); ++ ++ schedule(); ++ remove_wait_queue(&cfi->chips[chipnum].wq, &wait); ++#if 0 ++ if(signal_pending(current)) ++ return -EINTR; ++#endif ++ goto retry1; ++ } ++ ++ map_copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH); ++ ++ cfi_spin_unlock(cfi->chips[chipnum].mutex); + +- map->copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH); + while (len--) + tmp_buf[i++] = buf[n++]; + +@@ -696,8 +1181,14 @@ + datum = *(__u16*)tmp_buf; + } else if (cfi_buswidth_is_4()) { + datum = *(__u32*)tmp_buf; ++#ifdef CFI_WORD_64 ++ } else if (cfi_buswidth_is_8()) { ++ datum = *(__u64*)tmp_buf; ++#endif + } else { +- return -EINVAL; /* should never happen, but be safe */ ++ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n", ++ __func__, CFIDEV_BUSWIDTH); ++ return -EINVAL; + } + + ret = do_write_oneword(map, &cfi->chips[chipnum], +@@ -711,289 +1202,446 @@ + return 0; + } + +-static inline int do_erase_chip(struct map_info *map, struct flchip *chip) ++ ++/* ++ * FIXME: interleaved mode not tested, and probably not supported! ++ */ ++static inline int do_write_buffer(struct map_info *map, struct flchip *chip, ++ unsigned long adr, const u_char *buf, int len) + { +- unsigned int oldstatus, status; +- unsigned int dq6, dq5; +- unsigned long timeo = jiffies + HZ; +- unsigned int adr; + struct cfi_private *cfi = map->fldrv_priv; +- DECLARE_WAITQUEUE(wait, current); +- +- retry: +- cfi_spin_lock(chip->mutex); ++ unsigned long timeo = jiffies + HZ; ++ cfi_word oldstatus, status, prev_oldstatus, prev_status; ++ cfi_word dq6 = CMD(1<<6); ++ /* see comments in do_write_oneword() regarding uWriteTimeo. */ ++ static unsigned long uWriteTimeout = ( HZ / 1000 ) + 1; ++ int ret = -EIO; ++ int ta = 0; ++ unsigned long cmd_adr; ++ int z, bytes, words; ++ cfi_word datum; ++ DECLARE_RETRY_CMD_CNT(); + +- if (chip->state != FL_READY){ +- set_current_state(TASK_UNINTERRUPTIBLE); +- add_wait_queue(&chip->wq, &wait); ++ adr += chip->start; ++ cmd_adr = adr; + ++ cfi_spin_lock(chip->mutex); ++ ret = get_chip(map, chip, adr, FL_WRITING); ++ if (ret) { + cfi_spin_unlock(chip->mutex); ++ return ret; ++ } + +- schedule(); +- remove_wait_queue(&chip->wq, &wait); +-#if 0 +- if(signal_pending(current)) +- return -EINTR; ++ if (cfi_buswidth_is_1()) { ++ datum = *(__u8*)buf; ++ } else if (cfi_buswidth_is_2()) { ++ datum = *(__u16*)buf; ++ } else if (cfi_buswidth_is_4()) { ++ datum = *(__u32*)buf; ++#ifdef CFI_WORD_64 ++ } else if (cfi_buswidth_is_8()) { ++ datum = *(__u64*)buf; + #endif +- timeo = jiffies + HZ; +- +- goto retry; ++ } else { ++ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n", ++ __func__, CFIDEV_BUSWIDTH); ++ return -EINVAL; + } + +- chip->state = FL_ERASING; ++ RETRY_CMD_LABEL; ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8x)\n", ++ __func__, adr, datum ); + +- /* Handle devices with one erase region, that only implement +- * the chip erase command. +- */ + ENABLE_VPP(map); + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); +- cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); +- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); +- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); +- cfi_send_gen_cmd(0x10, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); +- timeo = jiffies + (HZ*20); +- adr = cfi->addr_unlock1; ++ //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); + +- /* Wait for the end of programing/erasure by using the toggle method. +- * As long as there is a programming procedure going on, bit 6 of the last +- * written byte is toggling it's state with each consectuve read. +- * The toggling stops as soon as the procedure is completed. +- * +- * If the process has gone on for too long on the chip bit 5 gets. +- * After bit5 is set you can kill the operation by sending a reset +- * command to the chip. +- */ +- dq6 = CMD(1<<6); +- dq5 = CMD(1<<5); ++ /* Write Buffer Load */ ++ cfi_write(map, CMD(0x25), cmd_adr); + +- oldstatus = cfi_read(map, adr); +- status = cfi_read(map, adr); +- while( ((status & dq6) != (oldstatus & dq6)) && +- ((status & dq5) != dq5) && +- !time_after(jiffies, timeo)) { +- int wait_reps; ++ chip->state = FL_WRITING_TO_BUFFER; ++ ++ /* Write length of data to come */ ++ bytes = len & (CFIDEV_BUSWIDTH-1); ++ words = len / CFIDEV_BUSWIDTH; ++ cfi_write(map, CMD(words - !bytes), cmd_adr ); ++ /* Write data */ ++ z = 0; ++ while(z < words * CFIDEV_BUSWIDTH) { ++ if (cfi_buswidth_is_1()) { ++ datum = *((__u8*)buf); ++ map_write8 (map, *((__u8*)buf)++, adr+z); ++ } else if (cfi_buswidth_is_2()) { ++ datum = *((__u16*)buf); ++ map_write16 (map, *((__u16*)buf)++, adr+z); ++ } else if (cfi_buswidth_is_4()) { ++ datum = *((__u32*)buf); ++ map_write32 (map, *((__u32*)buf)++, adr+z); ++#ifdef CFI_WORD_64 ++ } else if (cfi_buswidth_is_8()) { ++ datum = *((__u64*)buf); ++ map_write64 (map, *((__u64*)buf)++, adr+z); ++#endif ++ } else { ++ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n", ++ __func__, CFIDEV_BUSWIDTH); ++ ret = -EINVAL; ++ goto op_failed; ++ } ++ z += CFIDEV_BUSWIDTH; ++ } ++ if (bytes) { ++ int i = 0, n = 0; ++ u_char tmp_buf[8], *tmp_p = tmp_buf; ++ ++ while (bytes--) ++ tmp_buf[i++] = buf[n++]; ++ while (i < CFIDEV_BUSWIDTH) ++ tmp_buf[i++] = 0xff; ++ if (cfi_buswidth_is_2()) { ++ datum = *((__u16*)tmp_p); ++ map_write16 (map, *((__u16*)tmp_p)++, adr+z); ++ } else if (cfi_buswidth_is_4()) { ++ datum = *((__u32*)tmp_p); ++ map_write32 (map, *((__u32*)tmp_p)++, adr+z); ++#ifdef CFI_WORD_64 ++ } else if (cfi_buswidth_is_8()) { ++ datum = *((__u64*)tmp_p); ++ map_write64 (map, *((__u64*)tmp_p)++, adr+z); ++#endif ++ } else { ++ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n", ++ __func__, CFIDEV_BUSWIDTH); ++ ret = -EINVAL; ++ goto op_failed; ++ } ++ } else if (words > 0) { ++ z -= CFIDEV_BUSWIDTH; ++ } ++ ++ adr += z; ++ ++ /* Write Buffer Program Confirm: GO GO GO */ ++ cfi_write(map, CMD(0x29), cmd_adr); ++ chip->state = FL_WRITING; + +- /* an initial short sleep */ + cfi_spin_unlock(chip->mutex); +- schedule_timeout(HZ/100); ++ cfi_udelay(chip->buffer_write_time); + cfi_spin_lock(chip->mutex); + +- if (chip->state != FL_ERASING) { +- /* Someone's suspended the erase. Sleep */ ++ timeo = jiffies + uWriteTimeout; ++ ++ for (;;) { ++ if (chip->state != FL_WRITING) { ++ /* Someone's suspended the write. Sleep */ ++ DECLARE_WAITQUEUE(wait, current); ++ + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); +- + cfi_spin_unlock(chip->mutex); +- printk("erase suspended. Sleeping\n"); +- + schedule(); + remove_wait_queue(&chip->wq, &wait); +-#if 0 +- if (signal_pending(current)) +- return -EINTR; +-#endif +- timeo = jiffies + (HZ*2); /* FIXME */ ++ timeo = jiffies + (HZ / 2); /* FIXME */ + cfi_spin_lock(chip->mutex); + continue; + } + +- /* Busy wait for 1/10 of a milisecond */ +- for(wait_reps = 0; +- (wait_reps < 100) && +- ((status & dq6) != (oldstatus & dq6)) && +- ((status & dq5) != dq5); +- wait_reps++) { ++ oldstatus = cfi_read(map, adr); ++ status = cfi_read(map, adr); ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n", ++ __func__, oldstatus, status ); ++ ++ /* See comments in do_write_oneword() about checking status */ ++ if ( (((status ^ oldstatus) & dq6) == 0) ++ || ( ta = time_after(jiffies, timeo)) ) { ++ break; ++ } + + /* Latency issues. Drop the lock, wait a while and retry */ + cfi_spin_unlock(chip->mutex); +- + cfi_udelay(1); +- + cfi_spin_lock(chip->mutex); +- oldstatus = cfi_read(map, adr); +- status = cfi_read(map, adr); + } ++ ++ /* See comments in do_write_oneword() about "two more checks" */ ++ prev_oldstatus = oldstatus; ++ prev_status = status; + oldstatus = cfi_read(map, adr); + status = cfi_read(map, adr); ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n", ++ __func__, oldstatus, status ); ++ ++ if ( oldstatus == datum && status == datum ) { ++ /* success - do nothing */ ++ goto op_done; ++ } ++ ++ if ( ta ) { ++ /* Only check dq5 on the chips that are still toggling. */ ++ cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1; ++ if ( status & dq5mask ) { ++ /* dq5 asserted - decode interleave chips */ ++ printk( KERN_WARNING ++ "MTD %s(): FLASH internal timeout: 0x%.8x 0x%.8x 0x%8x\n", ++ __func__, ++ status & dq5mask, status, datum ); ++ } else { ++ printk( KERN_WARNING ++ "MTD %s(): Software timed out during write.\n", ++ __func__ ); + } +- if ((status & dq6) != (oldstatus & dq6)) { +- /* The erasing didn't stop?? */ +- if ((status & dq5) == dq5) { +- /* dq5 is active so we can do a reset and stop the erase */ +- cfi_write(map, CMD(0xF0), chip->start); ++ goto op_failed; + } ++ ++ HANDLE_WACKY_STATE(); ++ ++ op_failed: ++ /* reset on all failures. */ ++ cfi_write( map, CMD(0xF0), chip->start ); ++ /* FIXME - should have reset delay before continuing */ ++ CHECK_RETRIES(); ++ ret = -EIO; ++ ++ op_done: + chip->state = FL_READY; +- wake_up(&chip->wq); ++ put_chip(map, chip, adr); + cfi_spin_unlock(chip->mutex); +- printk("waiting for erase to complete timed out."); +- DISABLE_VPP(map); +- return -EIO; ++ ++ return ret; ++} ++ ++ ++static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf) ++{ ++ struct map_info *map = mtd->priv; ++ struct cfi_private *cfi = map->fldrv_priv; ++ int wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize; ++ int ret = 0; ++ int chipnum; ++ unsigned long ofs; ++ ++ *retlen = 0; ++ if (!len) ++ return 0; ++ ++ chipnum = to >> cfi->chipshift; ++ ofs = to - (chipnum << cfi->chipshift); ++ ++ /* If it's not bus-aligned, do the first word write */ ++ if (ofs & (CFIDEV_BUSWIDTH-1)) { ++ size_t local_len = (-ofs)&(CFIDEV_BUSWIDTH-1); ++ if (local_len > len) ++ local_len = len; ++ ret = cfi_amdstd_write_words(mtd, to, local_len, ++ retlen, buf); ++ if (ret) ++ return ret; ++ ofs += local_len; ++ buf += local_len; ++ len -= local_len; ++ ++ if (ofs >> cfi->chipshift) { ++ chipnum ++; ++ ofs = 0; ++ if (chipnum == cfi->numchips) ++ return 0; ++ } ++ } ++ ++ /* Write buffer is worth it only if more than one word to write... */ ++ while (len) { ++ /* We must not cross write block boundaries */ ++ int size = wbufsize - (ofs & (wbufsize-1)); ++ ++ if (size > len) ++ size = len; ++ ret = do_write_buffer(map, &cfi->chips[chipnum], ++ ofs, buf, size); ++ if (ret) ++ return ret; ++ ++ ofs += size; ++ buf += size; ++ (*retlen) += size; ++ len -= size; ++ ++ if (ofs >> cfi->chipshift) { ++ chipnum ++; ++ ofs = 0; ++ if (chipnum == cfi->numchips) ++ return 0; ++ } + } +- DISABLE_VPP(map); +- chip->state = FL_READY; +- wake_up(&chip->wq); +- cfi_spin_unlock(chip->mutex); + + return 0; + } + +-static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr) ++ ++/* ++ * Handle devices with one erase region, that only implement ++ * the chip erase command. ++ */ ++static inline int do_erase_chip(struct map_info *map, struct flchip *chip) + { +- unsigned int oldstatus, status; +- unsigned int dq6, dq5; +- unsigned long timeo = jiffies + HZ; + struct cfi_private *cfi = map->fldrv_priv; ++ cfi_word oldstatus, status, prev_oldstatus, prev_status; ++ cfi_word dq6 = CMD(1<<6); ++ unsigned long timeo = jiffies + HZ; ++ unsigned long int adr; + DECLARE_WAITQUEUE(wait, current); ++ int ret = 0; ++ int ta = 0; ++ cfi_word datum = 0; ++ DECLARE_RETRY_CMD_CNT(); + +- retry: +- cfi_spin_lock(chip->mutex); +- +- if (chip->state != FL_READY){ +- set_current_state(TASK_UNINTERRUPTIBLE); +- add_wait_queue(&chip->wq, &wait); ++ adr = cfi->addr_unlock1; + ++ cfi_spin_lock(chip->mutex); ++ ret = get_chip(map, chip, adr, FL_WRITING); ++ if (ret) { + cfi_spin_unlock(chip->mutex); +- +- schedule(); +- remove_wait_queue(&chip->wq, &wait); +-#if 0 +- if(signal_pending(current)) +- return -EINTR; +-#endif +- timeo = jiffies + HZ; +- +- goto retry; ++ return ret; + } + +- chip->state = FL_ERASING; ++ RETRY_CMD_LABEL; ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n", ++ __func__, chip->start ); + +- adr += chip->start; + ENABLE_VPP(map); + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); + cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); +- cfi_write(map, CMD(0x30), adr); +- +- timeo = jiffies + (HZ*20); +- +- /* Wait for the end of programing/erasure by using the toggle method. +- * As long as there is a programming procedure going on, bit 6 of the last +- * written byte is toggling it's state with each consectuve read. +- * The toggling stops as soon as the procedure is completed. +- * +- * If the process has gone on for too long on the chip bit 5 gets. +- * After bit5 is set you can kill the operation by sending a reset +- * command to the chip. +- */ +- dq6 = CMD(1<<6); +- dq5 = CMD(1<<5); ++ cfi_send_gen_cmd(0x10, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); + +- oldstatus = cfi_read(map, adr); +- status = cfi_read(map, adr); +- while( ((status & dq6) != (oldstatus & dq6)) && +- ((status & dq5) != dq5) && +- !time_after(jiffies, timeo)) { +- int wait_reps; ++ chip->state = FL_ERASING; ++ chip->erase_suspended = 0; ++ chip->in_progress_block_addr = adr; + +- /* an initial short sleep */ + cfi_spin_unlock(chip->mutex); +- schedule_timeout(HZ/100); ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ schedule_timeout((chip->erase_time*HZ)/(2*1000)); + cfi_spin_lock(chip->mutex); + ++ timeo = jiffies + (HZ*20); ++ ++ for (;;) { + if (chip->state != FL_ERASING) { + /* Someone's suspended the erase. Sleep */ + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); +- + cfi_spin_unlock(chip->mutex); +- printk(KERN_DEBUG "erase suspended. Sleeping\n"); +- + schedule(); + remove_wait_queue(&chip->wq, &wait); +-#if 0 +- if (signal_pending(current)) +- return -EINTR; +-#endif +- timeo = jiffies + (HZ*2); /* FIXME */ + cfi_spin_lock(chip->mutex); + continue; + } ++ if (chip->erase_suspended) { ++ /* This erase was suspended and resumed. ++ Adjust the timeout */ ++ timeo = jiffies + (HZ*20); /* FIXME */ ++ chip->erase_suspended = 0; ++ } + +- /* Busy wait for 1/10 of a milisecond */ +- for(wait_reps = 0; +- (wait_reps < 100) && +- ((status & dq6) != (oldstatus & dq6)) && +- ((status & dq5) != dq5); +- wait_reps++) { ++ oldstatus = cfi_read(map, adr); ++ status = cfi_read(map, adr); ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n", ++ __func__, oldstatus, status ); ++ if ( (((status ^ oldstatus) & dq6) == 0) ++ || ( ta = time_after(jiffies, timeo)) ) ++ break; + + /* Latency issues. Drop the lock, wait a while and retry */ + cfi_spin_unlock(chip->mutex); +- +- cfi_udelay(1); +- ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ schedule_timeout(1); + cfi_spin_lock(chip->mutex); +- oldstatus = cfi_read(map, adr); +- status = cfi_read(map, adr); + } ++ ++ prev_oldstatus = oldstatus; ++ prev_status = status; + oldstatus = cfi_read(map, adr); + status = cfi_read(map, adr); +- } +- if( (status & dq6) != (oldstatus & dq6) ) +- { +- /* The erasing didn't stop?? */ +- if( ( status & dq5 ) == dq5 ) +- { +- /* When DQ5 raises, we must check once again if DQ6 is toggling. +- If not, the erase has been completed OK. If not, reset chip. */ +- oldstatus = cfi_read( map, adr ); +- status = cfi_read( map, adr ); ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n", ++ __func__, oldstatus, status ); + +- if( ( oldstatus & 0x00FF ) == ( status & 0x00FF ) ) +- { +- printk( "Warning: DQ5 raised while erase operation was in progress, but erase completed OK\n" ); +- } +- else +- { +- /* DQ5 is active so we can do a reset and stop the erase */ +- cfi_write(map, CMD(0xF0), chip->start); +- printk( KERN_WARNING "Internal flash device timeout occured or write operation was performed while flash was erasing\n" ); ++ if ( cfi_buswidth_is_1() ) { ++ datum = (__u8)~0; ++ } else if ( cfi_buswidth_is_2() ) { ++ datum = (__u16)~0; ++ } else if ( cfi_buswidth_is_4() ) { ++ datum = (__u32)~0; ++#ifdef CFI_WORD_64 ++ } else if ( cfi_buswidth_is_8() ) { ++ datum = (__u64)~0; ++#endif ++ } else { ++ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n", ++ __func__, CFIDEV_BUSWIDTH); ++ goto op_failed; ++ } ++ ++ if ( oldstatus == datum && status == datum ) { ++ /* success - do nothing */ ++ goto op_done; ++ } ++ ++ if ( ta ) { ++ /* Only check dq5 on the chips that are still toggling. */ ++ cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1; ++ if ( status & dq5mask ) { ++ /* dq5 asserted - decode interleave chips */ ++ printk( KERN_WARNING ++ "MTD %s(): FLASH internal timeout: 0x%.8x\n", ++ __func__, ++ status & dq5mask ); ++ } else { ++ printk( KERN_WARNING ++ "MTD %s(): Software timed out during write.\n", ++ __func__ ); + } ++ goto op_failed; + } +- else +- { +- printk( "Waiting for erase to complete timed out in do_erase_oneblock."); + +- chip->state = FL_READY; +- wake_up(&chip->wq); +- cfi_spin_unlock(chip->mutex); +- DISABLE_VPP(map); +- return -EIO; +- } +- } ++ HANDLE_WACKY_STATE(); + +- DISABLE_VPP(map); ++ op_failed: ++ /* reset on all failures. */ ++ cfi_write( map, CMD(0xF0), chip->start ); ++ /* FIXME - should have reset delay before continuing */ ++ CHECK_RETRIES(); ++ ret = -EIO; ++ ++ op_done: + chip->state = FL_READY; +- wake_up(&chip->wq); ++ put_chip(map, chip, adr); + cfi_spin_unlock(chip->mutex); +- return 0; ++ ++ return ret; + } + +-static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) ++ ++typedef int (*frob_t)(struct map_info *map, struct flchip *chip, ++ unsigned long adr, void *thunk); ++ ++ ++static int cfi_amdstd_varsize_frob(struct mtd_info *mtd, frob_t frob, ++ loff_t ofs, size_t len, void *thunk) + { + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; +- unsigned long adr, len; ++ unsigned long adr; + int chipnum, ret = 0; + int i, first; + struct mtd_erase_region_info *regions = mtd->eraseregions; + +- if (instr->addr > mtd->size) ++ if (ofs > mtd->size) + return -EINVAL; + +- if ((instr->len + instr->addr) > mtd->size) ++ if ((len + ofs) > mtd->size) + return -EINVAL; + + /* Check that both start and end of the requested erase are +@@ -1008,7 +1656,7 @@ + start of the requested erase, and then go back one. + */ + +- while (i < mtd->numeraseregions && instr->addr >= regions[i].offset) ++ while (i < mtd->numeraseregions && ofs >= regions[i].offset) + i++; + i--; + +@@ -1018,7 +1666,7 @@ + effect here. + */ + +- if (instr->addr & (regions[i].erasesize-1)) ++ if (ofs & (regions[i].erasesize-1)) + return -EINVAL; + + /* Remember the erase region we start on */ +@@ -1028,7 +1676,7 @@ + * with the erase region at that address. + */ + +- while (inumeraseregions && (instr->addr + instr->len) >= regions[i].offset) ++ while (inumeraseregions && (ofs + len) >= regions[i].offset) + i++; + + /* As before, drop back one to point at the region in which +@@ -1036,17 +1684,16 @@ + */ + i--; + +- if ((instr->addr + instr->len) & (regions[i].erasesize-1)) ++ if ((ofs + len) & (regions[i].erasesize-1)) + return -EINVAL; + +- chipnum = instr->addr >> cfi->chipshift; +- adr = instr->addr - (chipnum << cfi->chipshift); +- len = instr->len; ++ chipnum = ofs >> cfi->chipshift; ++ adr = ofs - (chipnum << cfi->chipshift); + + i=first; + +- while(len) { +- ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); ++ while (len) { ++ ret = (*frob)(map, &cfi->chips[chipnum], adr, thunk); + + if (ret) + return ret; +@@ -1066,50 +1713,171 @@ + } + } + +- instr->state = MTD_ERASE_DONE; +- if (instr->callback) +- instr->callback(instr); +- + return 0; + } + +-static int cfi_amdstd_erase_onesize(struct mtd_info *mtd, struct erase_info *instr) ++ ++static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, void *thunk) + { +- struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; +- unsigned long adr, len; +- int chipnum, ret = 0; ++ cfi_word oldstatus, status, prev_oldstatus, prev_status; ++ cfi_word dq6 = CMD(1<<6); ++ unsigned long timeo = jiffies + HZ; ++ DECLARE_WAITQUEUE(wait, current); ++ int ret = 0; ++ int ta = 0; ++ cfi_word datum = 0; ++ DECLARE_RETRY_CMD_CNT(); + +- if (instr->addr & (mtd->erasesize - 1)) +- return -EINVAL; ++ adr += chip->start; + +- if (instr->len & (mtd->erasesize -1)) +- return -EINVAL; ++ cfi_spin_lock(chip->mutex); ++ ret = get_chip(map, chip, adr, FL_ERASING); ++ if (ret) { ++ cfi_spin_unlock(chip->mutex); ++ return ret; ++ } + +- if ((instr->len + instr->addr) > mtd->size) +- return -EINVAL; ++ RETRY_CMD_LABEL; ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n", ++ __func__, adr ); + +- chipnum = instr->addr >> cfi->chipshift; +- adr = instr->addr - (chipnum << cfi->chipshift); +- len = instr->len; ++ ENABLE_VPP(map); ++ cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); ++ cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); ++ cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); ++ cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); ++ cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL); ++ cfi_write(map, CMD(0x30), adr); + +- while(len) { +- ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); ++ chip->state = FL_ERASING; ++ chip->erase_suspended = 0; ++ chip->in_progress_block_addr = adr; + +- if (ret) +- return ret; ++ cfi_spin_unlock(chip->mutex); ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ schedule_timeout((chip->erase_time*HZ)/(2*1000)); ++ cfi_spin_lock(chip->mutex); + +- adr += mtd->erasesize; +- len -= mtd->erasesize; ++ timeo = jiffies + (HZ*20); + +- if (adr >> cfi->chipshift) { +- adr = 0; +- chipnum++; ++ /* Wait for the end of programing/erasure by using the toggle method. ++ * As long as there is a programming procedure going on, bit 6 is ++ * toggling its state with each consecutive read. The toggling stops ++ * as soon as the procedure is completed. ++ * ++ * If the process has gone on for too long on the chip, bit 5 gets ++ * set. After bit5 is set you can kill the operation by sending a ++ * reset command to the chip. ++ */ ++ /* See comments in do_write_oneword(). */ + +- if (chipnum >= cfi->numchips) ++ for (;;) { ++ if (chip->state != FL_ERASING) { ++ /* Someone's suspended the erase. Sleep */ ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ add_wait_queue(&chip->wq, &wait); ++ cfi_spin_unlock(chip->mutex); ++ schedule(); ++ remove_wait_queue(&chip->wq, &wait); ++ cfi_spin_lock(chip->mutex); ++ continue; ++ } ++ if (chip->erase_suspended) { ++ /* This erase was suspended and resumed. ++ Adjust the timeout */ ++ timeo = jiffies + (HZ*20); /* FIXME */ ++ chip->erase_suspended = 0; ++ } ++ ++ oldstatus = cfi_read(map, adr); ++ status = cfi_read(map, adr); ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n", ++ __func__, oldstatus, status ); ++ if ( (((status ^ oldstatus) & dq6) == 0) ++ || ( ta = time_after(jiffies, timeo)) ) + break; ++ ++ /* Latency issues. Drop the lock, wait a while and retry */ ++ cfi_spin_unlock(chip->mutex); ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ schedule_timeout(1); ++ cfi_spin_lock(chip->mutex); + } ++ ++ prev_oldstatus = oldstatus; ++ prev_status = status; ++ oldstatus = cfi_read(map, adr); ++ status = cfi_read(map, adr); ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n", ++ __func__, oldstatus, status ); ++ ++ if ( cfi_buswidth_is_1() ) { ++ datum = (__u8)~0; ++ } else if ( cfi_buswidth_is_2() ) { ++ datum = (__u16)~0; ++ } else if ( cfi_buswidth_is_4() ) { ++ datum = (__u32)~0; ++#ifdef CFI_WORD_64 ++ } else if ( cfi_buswidth_is_8() ) { ++ datum = (__u64)~0; ++#endif ++ } else { ++ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n", ++ __func__, CFIDEV_BUSWIDTH); ++ goto op_failed; ++ } ++ ++ if ( oldstatus == datum && status == datum ) { ++ /* success - do nothing */ ++ goto op_done; ++ } ++ ++ if ( ta ) { ++ /* Only check dq5 on the chips that are still toggling. */ ++ cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1; ++ if ( status & dq5mask ) { ++ /* dq5 asserted - decode interleave chips */ ++ printk( KERN_WARNING ++ "MTD %s(): FLASH internal timeout: 0x%.8x\n", ++ __func__, ++ status & dq5mask ); ++ } else { ++ printk( KERN_WARNING ++ "MTD %s(): Software timed out during write.\n", ++ __func__ ); + } ++ goto op_failed; ++ } ++ ++ HANDLE_WACKY_STATE(); ++ ++ op_failed: ++ /* reset on all failures. */ ++ cfi_write( map, CMD(0xF0), chip->start ); ++ /* FIXME - should have reset delay before continuing */ ++ CHECK_RETRIES(); ++ ret = -EIO; ++ ++ op_done: ++ chip->state = FL_READY; ++ put_chip(map, chip, adr); ++ cfi_spin_unlock(chip->mutex); ++ return ret; ++} ++ ++ ++int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr) ++{ ++ unsigned long ofs, len; ++ int ret; ++ ++ ofs = instr->addr; ++ len = instr->len; ++ ++ ret = cfi_amdstd_varsize_frob(mtd, do_erase_oneblock, ofs, len, 0); ++ if (ret) ++ return ret; + + instr->state = MTD_ERASE_DONE; + if (instr->callback) +@@ -1118,6 +1886,7 @@ + return 0; + } + ++ + static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr) + { + struct map_info *map = mtd->priv; +@@ -1141,6 +1910,7 @@ + return 0; + } + ++ + static void cfi_amdstd_sync (struct mtd_info *mtd) + { + struct map_info *map = mtd->priv; +@@ -1254,6 +2024,7 @@ + return ret; + } + ++ + static void cfi_amdstd_resume(struct mtd_info *mtd) + { + struct map_info *map = mtd->priv; +@@ -1279,6 +2050,137 @@ + } + } + ++ ++#ifdef DEBUG_LOCK_BITS ++ ++static int do_printlockstatus_oneblock(struct map_info *map, ++ struct flchip *chip, ++ unsigned long adr, ++ void *thunk) ++{ ++ struct cfi_private *cfi = map->fldrv_priv; ++ int ofs_factor = cfi->interleave * cfi->device_type; ++ ++ cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); ++ printk(KERN_DEBUG "block status register for 0x%08lx is %x\n", ++ adr, cfi_read_query(map, adr+(2*ofs_factor))); ++ cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); ++ ++ return 0; ++} ++ ++ ++#define debug_dump_locks(mtd, frob, ofs, len, thunk) \ ++ cfi_amdstd_varsize_frob((mtd), (frob), (ofs), (len), (thunk)) ++ ++#else ++ ++#define debug_dump_locks(...) ++ ++#endif /* DEBUG_LOCK_BITS */ ++ ++ ++struct xxlock_thunk { ++ cfi_word val; ++ flstate_t state; ++}; ++ ++ ++#define DO_XXLOCK_ONEBLOCK_LOCK ((struct xxlock_thunk){0x01, FL_LOCKING}) ++#define DO_XXLOCK_ONEBLOCK_UNLOCK ((struct xxlock_thunk){0x00, FL_UNLOCKING}) ++ ++ ++/* ++ * FIXME - this is *very* specific to a particular chip. It likely won't ++ * work for all chips that require unlock. It also hasn't been tested ++ * with interleaved chips. ++ */ ++static int do_xxlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, void *thunk) ++{ ++ struct cfi_private *cfi = map->fldrv_priv; ++ struct xxlock_thunk *xxlt = (struct xxlock_thunk *)thunk; ++ int ret; ++ ++ /* ++ * This is easy because these are writes to registers and not writes ++ * to flash memory - that means that we don't have to check status ++ * and timeout. ++ */ ++ ++ adr += chip->start; ++ /* ++ * lock block registers: ++ * - on 64k boundariesand ++ * - bit 1 set high ++ * - block lock registers are 4MiB lower - overflow subtract (danger) ++ */ ++ adr = ((adr & ~0xffff) | 0x2) + ~0x3fffff; ++ ++ cfi_spin_lock(chip->mutex); ++ ret = get_chip(map, chip, adr, FL_LOCKING); ++ if (ret) { ++ cfi_spin_unlock(chip->mutex); ++ return ret; ++ } ++ ++ chip->state = xxlt->state; ++ cfi_write(map, CMD(xxlt->val), adr); ++ ++ /* Done and happy. */ ++ chip->state = FL_READY; ++ put_chip(map, chip, adr); ++ cfi_spin_unlock(chip->mutex); ++ return 0; ++} ++ ++ ++static int cfi_amdstd_lock_varsize(struct mtd_info *mtd, ++ loff_t ofs, ++ size_t len) ++{ ++ int ret; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, ++ "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", ++ __func__, ofs, len); ++ debug_dump_locks(mtd, do_printlockstatus_oneblock, ofs, len, 0); ++ ++ ret = cfi_amdstd_varsize_frob(mtd, do_xxlock_oneblock, ofs, len, ++ (void *)&DO_XXLOCK_ONEBLOCK_LOCK); ++ ++ DEBUG(MTD_DEBUG_LEVEL3, ++ "%s: lock status after, ret=%d\n", ++ __func__, ret); ++ ++ debug_dump_locks(mtd, do_printlockstatus_oneblock, ofs, len, 0); ++ ++ return ret; ++} ++ ++ ++static int cfi_amdstd_unlock_varsize(struct mtd_info *mtd, ++ loff_t ofs, ++ size_t len) ++{ ++ int ret; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, ++ "%s: lock status before, ofs=0x%08llx, len=0x%08X\n", ++ __func__, ofs, len); ++ debug_dump_locks(mtd, do_printlockstatus_oneblock, ofs, len, 0); ++ ++ ret = cfi_amdstd_varsize_frob(mtd, do_xxlock_oneblock, ofs, len, ++ (void *)&DO_XXLOCK_ONEBLOCK_UNLOCK); ++ ++ DEBUG(MTD_DEBUG_LEVEL3, ++ "%s: lock status after, ret=%d\n", ++ __func__, ret); ++ debug_dump_locks(mtd, do_printlockstatus_oneblock, ofs, len, 0); ++ ++ return ret; ++} ++ ++ + static void cfi_amdstd_destroy(struct mtd_info *mtd) + { + struct map_info *map = mtd->priv; +@@ -1291,17 +2193,20 @@ + + static char im_name[]="cfi_cmdset_0002"; + ++ + int __init cfi_amdstd_init(void) + { + inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0002); + return 0; + } + ++ + static void __exit cfi_amdstd_exit(void) + { + inter_module_unregister(im_name); + } + ++ + module_init(cfi_amdstd_init); + module_exit(cfi_amdstd_exit); + +@@ -1309,3 +2214,7 @@ + MODULE_AUTHOR("Crossnet Co. et al."); + MODULE_DESCRIPTION("MTD chip driver for AMD/Fujitsu flash chips"); + ++#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY ++MODULE_PARM(retry_cmd_max, "i"); ++MODULE_PARM_DESC(retry_cmd_max, "Number of times to retry an erase or program command if it fails - should only be needed by buggy hardware: default 0"); ++#endif +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/cfi_cmdset_0020.c linux/drivers/mtd/chips/cfi_cmdset_0020.c +--- linux-mips-2.4.27/drivers/mtd/chips/cfi_cmdset_0020.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/chips/cfi_cmdset_0020.c 2004-11-19 10:25:11.747222896 +0100 +@@ -21,16 +21,19 @@ + #include + #include + #include ++#include + #include + #include + + #include ++#include + #include + #include + #include ++#include + #include + #include +-#include ++#include + + + static int cfi_staa_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); +@@ -51,10 +54,10 @@ + static struct mtd_info *cfi_staa_setup (struct map_info *); + + static struct mtd_chip_driver cfi_staa_chipdrv = { +- probe: NULL, /* Not usable directly */ +- destroy: cfi_staa_destroy, +- name: "cfi_cmdset_0020", +- module: THIS_MODULE ++ .probe = NULL, /* Not usable directly */ ++ .destroy = cfi_staa_destroy, ++ .name = "cfi_cmdset_0020", ++ .module = THIS_MODULE + }; + + /* #define DEBUG_LOCK_BITS */ +@@ -113,7 +116,6 @@ + { + struct cfi_private *cfi = map->fldrv_priv; + int i; +- __u32 base = cfi->chips[0].start; + + if (cfi->cfi_mode) { + /* +@@ -123,35 +125,10 @@ + */ + __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; + struct cfi_pri_intelext *extp; +- int ofs_factor = cfi->interleave * cfi->device_type; +- +- printk(" ST Microelectronics Extended Query Table at 0x%4.4X\n", adr); +- if (!adr) +- return NULL; +- +- /* Switch it into Query Mode */ +- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); +- +- extp = kmalloc(sizeof(*extp), GFP_KERNEL); +- if (!extp) { +- printk(KERN_ERR "Failed to allocate memory\n"); +- return NULL; +- } +- +- /* Read in the Extended Query Table */ +- for (i=0; iMajorVersion != '1' || +- (extp->MinorVersion < '0' || extp->MinorVersion > '2')) { +- printk(KERN_WARNING " Unknown staa Extended Query " +- "version %c.%c.\n", extp->MajorVersion, +- extp->MinorVersion); +- kfree(extp); ++ extp = (struct cfi_pri_intelext*)cfi_read_pri(map, adr, sizeof(*extp), "ST Microelectronics"); ++ if (!extp) + return NULL; +- } + + /* Do some byteswapping if necessary */ + extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); +@@ -172,11 +149,6 @@ + cfi->chips[i].erase_time = 1024; + } + +- map->fldrv = &cfi_staa_chipdrv; +- MOD_INC_USE_COUNT; +- +- /* Make sure it's in read mode */ +- cfi_send_gen_cmd(0xff, 0x55, base, map, cfi, cfi->device_type, NULL); + return cfi_staa_setup(map); + } + +@@ -208,6 +180,7 @@ + if (!mtd->eraseregions) { + printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); + kfree(cfi->cmdset_priv); ++ kfree(mtd); + return NULL; + } + +@@ -232,6 +205,7 @@ + printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize); + kfree(mtd->eraseregions); + kfree(cfi->cmdset_priv); ++ kfree(mtd); + return NULL; + } + +@@ -256,7 +230,7 @@ + mtd->flags |= MTD_ECC; /* FIXME: Not all STMicro flashes have this */ + mtd->eccsize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */ + map->fldrv = &cfi_staa_chipdrv; +- MOD_INC_USE_COUNT; ++ __module_get(THIS_MODULE); + mtd->name = map->name; + return mtd; + } +@@ -288,7 +262,7 @@ + */ + switch (chip->state) { + case FL_ERASING: +- if (!((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2) ++ if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) + goto sleep; /* We don't support erase suspend */ + + cfi_write (map, CMD(0xb0), cmd_addr); +@@ -374,7 +348,7 @@ + goto retry; + } + +- map->copy_from(map, buf, adr, len); ++ map_copy_from(map, buf, adr, len); + + if (suspended) { + chip->state = chip->oldstate; +@@ -540,11 +514,11 @@ + /* Write data */ + for (z = 0; z < len; z += CFIDEV_BUSWIDTH) { + if (cfi_buswidth_is_1()) { +- map->write8 (map, *((__u8*)buf)++, adr+z); ++ map_write8 (map, *((__u8*)buf)++, adr+z); + } else if (cfi_buswidth_is_2()) { +- map->write16 (map, *((__u16*)buf)++, adr+z); ++ map_write16 (map, *((__u16*)buf)++, adr+z); + } else if (cfi_buswidth_is_4()) { +- map->write32 (map, *((__u32*)buf)++, adr+z); ++ map_write32 (map, *((__u32*)buf)++, adr+z); + } else { + DISABLE_VPP(map); + return -EINVAL; +@@ -1436,13 +1410,13 @@ + + static char im_name[]="cfi_cmdset_0020"; + +-mod_init_t cfi_staa_init(void) ++int __init cfi_staa_init(void) + { + inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0020); + return 0; + } + +-mod_exit_t cfi_staa_exit(void) ++static void __exit cfi_staa_exit(void) + { + inter_module_unregister(im_name); + } +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/cfi_probe.c linux/drivers/mtd/chips/cfi_probe.c +--- linux-mips-2.4.27/drivers/mtd/chips/cfi_probe.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/chips/cfi_probe.c 2004-11-19 10:25:11.766220008 +0100 +@@ -1,13 +1,14 @@ + /* + Common Flash Interface probe code. + (C) 2000 Red Hat. GPL'd. +- $Id: cfi_probe.c,v 1.69 2002/05/11 22:13:03 dwmw2 Exp $ ++ $Id: cfi_probe.c,v 1.73 2003/11/08 00:51:21 dsaxena Exp $ + */ + + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -25,7 +26,7 @@ + #endif + + static int cfi_probe_chip(struct map_info *map, __u32 base, +- struct flchip *chips, struct cfi_private *cfi); ++ unsigned long *chip_map, struct cfi_private *cfi); + static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi); + + struct mtd_info *cfi_probe(struct map_info *map); +@@ -48,7 +49,7 @@ + } + + static int cfi_probe_chip(struct map_info *map, __u32 base, +- struct flchip *chips, struct cfi_private *cfi) ++ unsigned long *chip_map, struct cfi_private *cfi) + { + int i; + +@@ -77,18 +78,24 @@ + } + + /* Check each previous chip to see if it's an alias */ +- for (i=0; inumchips; i++) { ++ for (i=0; i < (base >> cfi->chipshift); i++) { ++ unsigned long start; ++ if(!test_bit(i, chip_map)) { ++ /* Skip location; no valid chip at this address */ ++ continue; ++ } ++ start = i << cfi->chipshift; + /* This chip should be in read mode if it's one + we've already touched. */ +- if (qry_present(map,chips[i].start,cfi)) { ++ if (qry_present(map, start, cfi)) { + /* Eep. This chip also had the QRY marker. + * Is it an alias for the new one? */ +- cfi_send_gen_cmd(0xF0, 0, chips[i].start, map, cfi, cfi->device_type, NULL); ++ cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL); + + /* If the QRY marker goes away, it's an alias */ +- if (!qry_present(map, chips[i].start, cfi)) { ++ if (!qry_present(map, start, cfi)) { + printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", +- map->name, base, chips[i].start); ++ map->name, base, start); + return 0; + } + /* Yes, it's actually got QRY for data. Most +@@ -99,7 +106,7 @@ + + if (qry_present(map, base, cfi)) { + printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", +- map->name, base, chips[i].start); ++ map->name, base, start); + return 0; + } + } +@@ -107,13 +114,7 @@ + + /* OK, if we got to here, then none of the previous chips appear to + be aliases for the current one. */ +- if (cfi->numchips == MAX_CFI_CHIPS) { +- printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS); +- /* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */ +- return -1; +- } +- chips[cfi->numchips].start = base; +- chips[cfi->numchips].state = FL_READY; ++ set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ + cfi->numchips++; + + /* Put it back into Read Mode */ +@@ -179,9 +180,28 @@ + (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1); + #endif + } ++ ++ /* Note we put the device back into Read Mode BEFORE going into Auto ++ * Select Mode, as some devices support nesting of modes, others ++ * don't. This way should always work. ++ * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and ++ * so should be treated as nops or illegal (and so put the device ++ * back into Read Mode, which is a nop in this case). ++ */ ++ cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL); ++ cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL); ++ cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL); ++ cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL); ++ cfi->mfr = cfi_read_query(map, base); ++ cfi->id = cfi_read_query(map, base + ofs_factor); ++ + /* Put it back into Read Mode */ + cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); + ++ printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\n", ++ map->name, cfi->interleave, cfi->device_type*8, base, ++ map->buswidth*8); ++ + return 1; + } + +@@ -240,11 +260,11 @@ + printk("No Alternate Algorithm Table\n"); + + +- printk("Vcc Minimum: %x.%x V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf); +- printk("Vcc Maximum: %x.%x V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf); ++ printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf); ++ printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf); + if (cfip->VppMin) { +- printk("Vpp Minimum: %x.%x V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf); +- printk("Vpp Maximum: %x.%x V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf); ++ printk("Vpp Minimum: %2d.%d V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf); ++ printk("Vpp Maximum: %2d.%d V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf); + } + else + printk("No Vpp line\n"); +@@ -303,8 +323,8 @@ + #endif /* DEBUG_CFI */ + + static struct chip_probe cfi_chip_probe = { +- name: "CFI", +- probe_chip: cfi_probe_chip ++ .name = "CFI", ++ .probe_chip = cfi_probe_chip + }; + + struct mtd_info *cfi_probe(struct map_info *map) +@@ -317,9 +337,9 @@ + } + + static struct mtd_chip_driver cfi_chipdrv = { +- probe: cfi_probe, +- name: "cfi_probe", +- module: THIS_MODULE ++ .probe = cfi_probe, ++ .name = "cfi_probe", ++ .module = THIS_MODULE + }; + + int __init cfi_probe_init(void) +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/cfi_util.c linux/drivers/mtd/chips/cfi_util.c +--- linux-mips-2.4.27/drivers/mtd/chips/cfi_util.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/chips/cfi_util.c 2004-11-19 10:25:11.767219856 +0100 +@@ -0,0 +1,91 @@ ++/* ++ * Common Flash Interface support: ++ * Generic utility functions not dependant on command set ++ * ++ * Copyright (C) 2002 Red Hat ++ * Copyright (C) 2003 STMicroelectronics Limited ++ * ++ * This code is covered by the GPL. ++ * ++ * $Id: cfi_util.c,v 1.3 2003/11/14 19:50:03 thayne Exp $ ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct cfi_extquery * ++cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name) ++{ ++ struct cfi_private *cfi = map->fldrv_priv; ++ __u32 base = 0; // cfi->chips[0].start; ++ int ofs_factor = cfi->interleave * cfi->device_type; ++ int i; ++ struct cfi_extquery *extp = NULL; ++ ++ printk(" %s Extended Query Table at 0x%4.4X\n", name, adr); ++ if (!adr) ++ goto out; ++ ++ /* Switch it into Query Mode */ ++ cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); ++ ++ extp = kmalloc(size, GFP_KERNEL); ++ if (!extp) { ++ printk(KERN_ERR "Failed to allocate memory\n"); ++ goto out; ++ } ++ ++ /* Read in the Extended Query Table */ ++ for (i=0; iMajorVersion != '1' || ++ (extp->MinorVersion < '0' || extp->MinorVersion > '3')) { ++ printk(KERN_WARNING " Unknown %s Extended Query " ++ "version %c.%c.\n", name, extp->MajorVersion, ++ extp->MinorVersion); ++ kfree(extp); ++ extp = NULL; ++ goto out; ++ } ++ ++out: ++ /* Make sure it's in read mode */ ++ cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL); ++ ++ return extp; ++} ++ ++EXPORT_SYMBOL(cfi_read_pri); ++ ++void cfi_fixup(struct map_info *map, struct cfi_fixup* fixups) ++{ ++ struct cfi_private *cfi = map->fldrv_priv; ++ struct cfi_fixup *f; ++ ++ for (f=fixups; f->fixup; f++) { ++ if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi->mfr)) && ++ ((f->id == CFI_ID_ANY) || (f->id == cfi->id))) { ++ f->fixup(map, f->param); ++ } ++ } ++} ++ ++EXPORT_SYMBOL(cfi_fixup); ++ ++MODULE_LICENSE("GPL"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/chipreg.c linux/drivers/mtd/chips/chipreg.c +--- linux-mips-2.4.27/drivers/mtd/chips/chipreg.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/chips/chipreg.c 2004-11-19 10:25:11.769219552 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: chipreg.c,v 1.13 2002/02/21 08:26:58 dwmw2 Exp $ ++ * $Id: chipreg.c,v 1.16 2003/05/29 09:36:15 dwmw2 Exp $ + * + * Registration for chip drivers + * +@@ -7,10 +7,13 @@ + + #include + #include ++#include + #include + #include +-#include ++#include + #include ++#include ++#include + + spinlock_t chip_drvs_lock = SPIN_LOCK_UNLOCKED; + static LIST_HEAD(chip_drvs_list); +@@ -44,10 +47,8 @@ + break; + } + } +- if (ret && !try_inc_mod_count(ret->module)) { +- /* Eep. Failed. */ ++ if (ret && !try_module_get(ret->module)) + ret = NULL; +- } + + spin_unlock(&chip_drvs_lock); + +@@ -64,32 +65,46 @@ + + drv = get_mtd_chip_driver(name); + +- if (!drv && !request_module(name)) ++ if (!drv && !request_module("%s", name)) + drv = get_mtd_chip_driver(name); + + if (!drv) + return NULL; + + ret = drv->probe(map); +-#ifdef CONFIG_MODULES ++ + /* We decrease the use count here. It may have been a + probe-only module, which is no longer required from this + point, having given us a handle on (and increased the use + count of) the actual driver code. + */ +- if(drv->module) +- __MOD_DEC_USE_COUNT(drv->module); +-#endif ++ module_put(drv->module); + + if (ret) + return ret; + + return NULL; + } ++/* ++ * Destroy an MTD device which was created for a map device. ++ * Make sure the MTD device is already unregistered before calling this ++ */ ++void map_destroy(struct mtd_info *mtd) ++{ ++ struct map_info *map = mtd->priv; ++ ++ if (map->fldrv->destroy) ++ map->fldrv->destroy(mtd); ++ ++ module_put(map->fldrv->module); ++ ++ kfree(mtd); ++} + + EXPORT_SYMBOL(register_mtd_chip_driver); + EXPORT_SYMBOL(unregister_mtd_chip_driver); + EXPORT_SYMBOL(do_map_probe); ++EXPORT_SYMBOL(map_destroy); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("David Woodhouse "); +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/gen_probe.c linux/drivers/mtd/chips/gen_probe.c +--- linux-mips-2.4.27/drivers/mtd/chips/gen_probe.c 2003-08-13 19:19:18.000000000 +0200 ++++ linux/drivers/mtd/chips/gen_probe.c 2004-11-19 10:25:11.770219400 +0100 +@@ -1,14 +1,17 @@ + /* + * Routines common to all CFI-type probes. +- * (C) 2001, 2001 Red Hat, Inc. ++ * (C) 2001-2003 Red Hat, Inc. + * GPL'd +- * $Id: gen_probe.c,v 1.9 2002/09/05 05:15:32 acurtis Exp $ ++ * $Id: gen_probe.c,v 1.14 2003/11/08 00:51:21 dsaxena Exp $ + */ + + #include ++#include ++#include + #include + #include + #include ++#include + #include + + static struct mtd_info *check_cmd_set(struct map_info *, int); +@@ -50,11 +53,11 @@ + + struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe *cp) + { +- unsigned long base=0; + struct cfi_private cfi; + struct cfi_private *retcfi; +- struct flchip chip[MAX_CFI_CHIPS]; +- int i; ++ unsigned long *chip_map; ++ int i, j; ++ int max_chips; + + memset(&cfi, 0, sizeof(cfi)); + +@@ -77,8 +80,6 @@ + return NULL; + } + #endif +- chip[0].start = 0; +- chip[0].state = FL_READY; + cfi.chipshift = cfi.cfiq->DevSize; + + switch(cfi.interleave) { +@@ -103,20 +104,28 @@ + cfi.numchips = 1; + + /* ++ * Allocate memory for bitmap of valid chips. ++ * Align bitmap storage size to full byte. ++ */ ++ max_chips = map->size >> cfi.chipshift; ++ chip_map = kmalloc((max_chips / 8) + ((max_chips % 8) ? 1 : 0), GFP_KERNEL); ++ if (!chip_map) { ++ printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name); ++ kfree(cfi.cfiq); ++ return NULL; ++ } ++ ++ set_bit(0, chip_map); /* Mark first chip valid */ ++ ++ /* + * Now probe for other chips, checking sensibly for aliases while + * we're at it. The new_chip probe above should have let the first + * chip in read mode. +- * +- * NOTE: Here, we're checking if there is room for another chip +- * the same size within the mapping. Therefore, +- * base + chipsize <= map->size is the correct thing to do, +- * because, base + chipsize would be the _first_ byte of the +- * next chip, not the one we're currently pondering. + */ + +- for (base = (1<size; +- base += (1<probe_chip(map, base, &chip[0], &cfi); ++ for (i = 1; i < max_chips; i++) { ++ cp->probe_chip(map, i << cfi.chipshift, chip_map, &cfi); ++ } + + /* + * Now allocate the space for the structures we need to return to +@@ -128,19 +137,26 @@ + if (!retcfi) { + printk(KERN_WARNING "%s: kmalloc failed for CFI private structure\n", map->name); + kfree(cfi.cfiq); ++ kfree(chip_map); + return NULL; + } + + memcpy(retcfi, &cfi, sizeof(cfi)); +- memcpy(&retcfi->chips[0], chip, sizeof(struct flchip) * cfi.numchips); ++ memset(&retcfi->chips[0], 0, sizeof(struct flchip) * cfi.numchips); + +- /* Fix up the stuff that breaks when you move it */ +- for (i=0; i< retcfi->numchips; i++) { +- init_waitqueue_head(&retcfi->chips[i].wq); +- spin_lock_init(&retcfi->chips[i]._spinlock); +- retcfi->chips[i].mutex = &retcfi->chips[i]._spinlock; ++ for (i = 0, j = 0; (j < cfi.numchips) && (i < max_chips); i++) { ++ if(test_bit(i, chip_map)) { ++ struct flchip *pchip = &retcfi->chips[j++]; ++ ++ pchip->start = (i << cfi.chipshift); ++ pchip->state = FL_READY; ++ init_waitqueue_head(&pchip->wq); ++ spin_lock_init(&pchip->_spinlock); ++ pchip->mutex = &pchip->_spinlock; ++ } + } + ++ kfree(chip_map); + return retcfi; + } + +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/jedec.c linux/drivers/mtd/chips/jedec.c +--- linux-mips-2.4.27/drivers/mtd/chips/jedec.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/chips/jedec.c 2004-11-19 10:25:11.772219096 +0100 +@@ -11,10 +11,16 @@ + * not going to guess how to send commands to them, plus I expect they will + * all speak CFI.. + * +- * $Id: jedec.c,v 1.14 2002/06/27 02:19:12 dwmw2 Exp $ ++ * $Id: jedec.c,v 1.19 2003/05/29 09:25:23 dwmw2 Exp $ + */ + ++#include ++#include ++#include + #include ++#include ++#include ++#include + + static struct mtd_info *jedec_probe(struct map_info *); + static int jedec_probe8(struct map_info *map,unsigned long base, +@@ -33,14 +39,51 @@ + + /* Listing of parts and sizes. We need this table to learn the sector + size of the chip and the total length */ +-static const struct JEDECTable JEDEC_table[] = +- {{0x013D,"AMD Am29F017D",2*1024*1024,64*1024,MTD_CAP_NORFLASH}, +- {0x01AD,"AMD Am29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH}, +- {0x01D5,"AMD Am29F080",1*1024*1024,64*1024,MTD_CAP_NORFLASH}, +- {0x01A4,"AMD Am29F040",512*1024,64*1024,MTD_CAP_NORFLASH}, +- {0x20E3,"AMD Am29W040B",512*1024,64*1024,MTD_CAP_NORFLASH}, +- {0xC2AD,"Macronix MX29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH}, +- {}}; ++static const struct JEDECTable JEDEC_table[] = { ++ { ++ .jedec = 0x013D, ++ .name = "AMD Am29F017D", ++ .size = 2*1024*1024, ++ .sectorsize = 64*1024, ++ .capabilities = MTD_CAP_NORFLASH ++ }, ++ { ++ .jedec = 0x01AD, ++ .name = "AMD Am29F016", ++ .size = 2*1024*1024, ++ .sectorsize = 64*1024, ++ .capabilities = MTD_CAP_NORFLASH ++ }, ++ { ++ .jedec = 0x01D5, ++ .name = "AMD Am29F080", ++ .size = 1*1024*1024, ++ .sectorsize = 64*1024, ++ .capabilities = MTD_CAP_NORFLASH ++ }, ++ { ++ .jedec = 0x01A4, ++ .name = "AMD Am29F040", ++ .size = 512*1024, ++ .sectorsize = 64*1024, ++ .capabilities = MTD_CAP_NORFLASH ++ }, ++ { ++ .jedec = 0x20E3, ++ .name = "AMD Am29W040B", ++ .size = 512*1024, ++ .sectorsize = 64*1024, ++ .capabilities = MTD_CAP_NORFLASH ++ }, ++ { ++ .jedec = 0xC2AD, ++ .name = "Macronix MX29F016", ++ .size = 2*1024*1024, ++ .sectorsize = 64*1024, ++ .capabilities = MTD_CAP_NORFLASH ++ }, ++ { .jedec = 0x0 } ++}; + + static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id); + static void jedec_sync(struct mtd_info *mtd) {}; +@@ -54,9 +97,9 @@ + + + static struct mtd_chip_driver jedec_chipdrv = { +- probe: jedec_probe, +- name: "jedec", +- module: THIS_MODULE ++ .probe = jedec_probe, ++ .name = "jedec", ++ .module = THIS_MODULE + }; + + /* Probe entry point */ +@@ -131,8 +174,7 @@ + /* Generate a part name that includes the number of different chips and + other configuration information */ + count = 1; +- strncpy(Part,map->name,sizeof(Part)-10); +- Part[sizeof(Part)-11] = 0; ++ strlcpy(Part,map->name,sizeof(Part)-10); + strcat(Part," "); + Uniq = 0; + for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) +@@ -209,8 +251,7 @@ + // printk("Part: '%s'\n",Part); + + memset(MTD,0,sizeof(*MTD)); +- // strncpy(MTD->name,Part,sizeof(MTD->name)); +- // MTD->name[sizeof(MTD->name)-1] = 0; ++ // strlcpy(MTD->name,Part,sizeof(MTD->name)); + MTD->name = map->name; + MTD->type = MTD_NORFLASH; + MTD->flags = MTD_CAP_NORFLASH; +@@ -229,7 +270,7 @@ + MTD->priv = map; + map->fldrv_priv = priv; + map->fldrv = &jedec_chipdrv; +- MOD_INC_USE_COUNT; ++ __module_get(THIS_MODULE); + return MTD; + } + +@@ -351,8 +392,8 @@ + static int jedec_probe8(struct map_info *map,unsigned long base, + struct jedec_private *priv) + { +- #define flread(x) map->read8(map,base+x) +- #define flwrite(v,x) map->write8(map,v,base+x) ++ #define flread(x) map_read8(map,base+x) ++ #define flwrite(v,x) map_write8(map,v,base+x) + + const unsigned long AutoSel1 = 0xAA; + const unsigned long AutoSel2 = 0x55; +@@ -411,8 +452,8 @@ + static int jedec_probe32(struct map_info *map,unsigned long base, + struct jedec_private *priv) + { +- #define flread(x) map->read32(map,base+((x)<<2)) +- #define flwrite(v,x) map->write32(map,v,base+((x)<<2)) ++ #define flread(x) map_read32(map,base+((x)<<2)) ++ #define flwrite(v,x) map_write32(map,v,base+((x)<<2)) + + const unsigned long AutoSel1 = 0xAAAAAAAA; + const unsigned long AutoSel2 = 0x55555555; +@@ -490,7 +531,7 @@ + { + struct map_info *map = (struct map_info *)mtd->priv; + +- map->copy_from(map, buf, from, len); ++ map_copy_from(map, buf, from, len); + *retlen = len; + return 0; + } +@@ -514,7 +555,7 @@ + get = priv->bank_fill[0] - offset; + + bank /= priv->bank_fill[0]; +- map->copy_from(map,buf + *retlen,bank*my_bank_size + offset,get); ++ map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get); + + len -= get; + *retlen += get; +@@ -545,8 +586,8 @@ + static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) + { + // Does IO to the currently selected chip +- #define flread(x) map->read8(map,chip->base+((x)<addrshift)) +- #define flwrite(v,x) map->write8(map,v,chip->base+((x)<addrshift)) ++ #define flread(x) map_read8(map,chip->base+((x)<addrshift)) ++ #define flwrite(v,x) map_write8(map,v,chip->base+((x)<addrshift)) + + unsigned long Time = 0; + unsigned long NoTime = 0; +@@ -608,7 +649,7 @@ + + /* Poll the flash for erasure completion, specs say this can take as long + as 480 seconds to do all the sectors (for a 2 meg flash). +- Erasure time is dependant on chip age, temp and wear.. */ ++ Erasure time is dependent on chip age, temp and wear.. */ + + /* This being a generic routine assumes a 32 bit bus. It does read32s + and bundles interleved chips into the same grouping. This will work +@@ -651,19 +692,19 @@ + or this is not really flash ;> */ + switch (map->buswidth) { + case 1: +- Last[0] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off); +- Last[1] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off); +- Last[2] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off); ++ Last[0] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off); ++ Last[1] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off); ++ Last[2] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off); + break; + case 2: +- Last[0] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off); +- Last[1] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off); +- Last[2] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off); ++ Last[0] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off); ++ Last[1] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off); ++ Last[2] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off); + break; + case 3: +- Last[0] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off); +- Last[1] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off); +- Last[2] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off); ++ Last[0] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off); ++ Last[1] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off); ++ Last[2] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off); + break; + } + Count = 3; +@@ -699,13 +740,13 @@ + + switch (map->buswidth) { + case 1: +- Last[Count % 4] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off); ++ Last[Count % 4] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off); + break; + case 2: +- Last[Count % 4] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off); ++ Last[Count % 4] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off); + break; + case 4: +- Last[Count % 4] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off); ++ Last[Count % 4] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off); + break; + } + Count++; +@@ -755,10 +796,10 @@ + size_t *retlen, const u_char *buf) + { + /* Does IO to the currently selected chip. It takes the bank addressing +- base (which is divisable by the chip size) adds the necesary lower bits +- of addrshift (interleve index) and then adds the control register index. */ +- #define flread(x) map->read8(map,base+(off&((1<addrshift)-1))+((x)<addrshift)) +- #define flwrite(v,x) map->write8(map,v,base+(off&((1<addrshift)-1))+((x)<addrshift)) ++ base (which is divisible by the chip size) adds the necessary lower bits ++ of addrshift (interleave index) and then adds the control register index. */ ++ #define flread(x) map_read8(map,base+(off&((1<addrshift)-1))+((x)<addrshift)) ++ #define flwrite(v,x) map_write8(map,v,base+(off&((1<addrshift)-1))+((x)<addrshift)) + + struct map_info *map = (struct map_info *)mtd->priv; + struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv; +@@ -794,7 +835,7 @@ + // Loop over this page + for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++) + { +- unsigned char oldbyte = map->read8(map,base+off); ++ unsigned char oldbyte = map_read8(map,base+off); + unsigned char Last[4]; + unsigned long Count = 0; + +@@ -809,10 +850,10 @@ + flwrite(0xAA,0x555); + flwrite(0x55,0x2AA); + flwrite(0xA0,0x555); +- map->write8(map,*buf,base + off); +- Last[0] = map->read8(map,base + off); +- Last[1] = map->read8(map,base + off); +- Last[2] = map->read8(map,base + off); ++ map_write8(map,*buf,base + off); ++ Last[0] = map_read8(map,base + off); ++ Last[1] = map_read8(map,base + off); ++ Last[2] = map_read8(map,base + off); + + /* Wait for the flash to finish the operation. We store the last 4 + status bytes that have been retrieved so we can determine why +@@ -820,7 +861,7 @@ + failure */ + for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && + Count < 10000; Count++) +- Last[Count % 4] = map->read8(map,base + off); ++ Last[Count % 4] = map_read8(map,base + off); + if (Last[(Count - 1) % 4] != *buf) + { + jedec_flash_failed(Last[(Count - 3) % 4]); +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/jedec_probe.c linux/drivers/mtd/chips/jedec_probe.c +--- linux-mips-2.4.27/drivers/mtd/chips/jedec_probe.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/chips/jedec_probe.c 2004-11-19 10:25:11.774218792 +0100 +@@ -1,9 +1,11 @@ + /* + Common Flash Interface probe code. + (C) 2000 Red Hat. GPL'd. +- $Id: jedec_probe.c,v 1.19 2002/11/12 13:12:10 dwmw2 Exp $ ++ $Id: jedec_probe.c,v 1.44 2003/11/17 15:57:35 thayne Exp $ + See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) + for the standard this probe goes back to. ++ ++ Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com + */ + + #include +@@ -15,7 +17,9 @@ + #include + #include + #include ++#include + ++#include + #include + #include + #include +@@ -26,20 +30,24 @@ + #define MANUFACTURER_FUJITSU 0x0004 + #define MANUFACTURER_INTEL 0x0089 + #define MANUFACTURER_MACRONIX 0x00C2 +-#define MANUFACTURER_ST 0x0020 ++#define MANUFACTURER_PMC 0x009D + #define MANUFACTURER_SST 0x00BF ++#define MANUFACTURER_ST 0x0020 + #define MANUFACTURER_TOSHIBA 0x0098 ++#define MANUFACTURER_WINBOND 0x00da + + + /* AMD */ + #define AM29F800BB 0x2258 + #define AM29F800BT 0x22D6 ++#define AM29LV400BB 0x22BA ++#define AM29LV400BT 0x22B9 + #define AM29LV800BB 0x225B + #define AM29LV800BT 0x22DA + #define AM29LV160DT 0x22C4 + #define AM29LV160DB 0x2249 + #define AM29F017D 0x003D +-#define AM29F016 0x00AD ++#define AM29F016D 0x00AD + #define AM29F080 0x00D5 + #define AM29F040 0x00A4 + #define AM29LV040B 0x004F +@@ -54,6 +62,7 @@ + #define AT49BV32XT 0x00C9 + + /* Fujitsu */ ++#define MBM29F040C 0x00A4 + #define MBM29LV650UE 0x22D7 + #define MBM29LV320TE 0x22F6 + #define MBM29LV320BE 0x22F9 +@@ -61,6 +70,9 @@ + #define MBM29LV160BE 0x2249 + #define MBM29LV800BA 0x225B + #define MBM29LV800TA 0x22DA ++#define MBM29LV400TC 0x22B9 ++#define MBM29LV400BC 0x22BA ++ + + /* Intel */ + #define I28F004B3T 0x00d4 +@@ -93,8 +105,14 @@ + #define MX29F004T 0x0045 + #define MX29F004B 0x0046 + ++/* PMC */ ++#define PM49FL002 0x006D ++#define PM49FL004 0x006E ++#define PM49FL008 0x006A ++ + /* ST - www.st.com */ +-#define M29W800T 0x00D7 ++#define M29W800DT 0x00D7 ++#define M29W800DB 0x005B + #define M29W160DT 0x22C4 + #define M29W160DB 0x2249 + #define M29W040B 0x00E3 +@@ -110,6 +128,7 @@ + #define SST39LF040 0x00D7 + #define SST39SF010A 0x00B5 + #define SST39SF020A 0x00B6 ++#define SST49LF004B 0x0060 + #define SST49LF030A 0x001C + #define SST49LF040A 0x0051 + #define SST49LF080A 0x005B +@@ -122,15 +141,87 @@ + #define TC58FVT641 0x0093 + #define TC58FVB641 0x0095 + ++/* Winbond */ ++#define W49V002A 0x00b0 ++ ++ ++/* ++ * Unlock address sets for AMD command sets. ++ * Intel command sets use the MTD_UADDR_UNNECESSARY. ++ * Each identifier, except MTD_UADDR_UNNECESSARY, and ++ * MTD_UADDR_NO_SUPPORT must be defined below in unlock_addrs[]. ++ * MTD_UADDR_NOT_SUPPORTED must be 0 so that structure ++ * initialization need not require initializing all of the ++ * unlock addresses for all bit widths. ++ */ ++enum uaddr { ++ MTD_UADDR_NOT_SUPPORTED = 0, /* data width not supported */ ++ MTD_UADDR_0x0555_0x02AA, ++ MTD_UADDR_0x0555_0x0AAA, ++ MTD_UADDR_0x5555_0x2AAA, ++ MTD_UADDR_0x0AAA_0x0555, ++ MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */ ++ MTD_UADDR_UNNECESSARY, /* Does not require any address */ ++}; ++ ++ ++struct unlock_addr { ++ int addr1; ++ int addr2; ++}; ++ ++ ++/* ++ * I don't like the fact that the first entry in unlock_addrs[] ++ * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore, ++ * should not be used. The problem is that structures with ++ * initializers have extra fields initialized to 0. It is _very_ ++ * desireable to have the unlock address entries for unsupported ++ * data widths automatically initialized - that means that ++ * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here ++ * must go unused. ++ */ ++static const struct unlock_addr unlock_addrs[] = { ++ [MTD_UADDR_NOT_SUPPORTED] = { ++ .addr1 = 0xffff, ++ .addr2 = 0xffff ++ }, ++ ++ [MTD_UADDR_0x0555_0x02AA] = { ++ .addr1 = 0x0555, ++ .addr2 = 0x02aa ++ }, ++ ++ [MTD_UADDR_0x0555_0x0AAA] = { ++ .addr1 = 0x0555, ++ .addr2 = 0x0aaa ++ }, ++ ++ [MTD_UADDR_0x5555_0x2AAA] = { ++ .addr1 = 0x5555, ++ .addr2 = 0x2aaa ++ }, ++ ++ [MTD_UADDR_0x0AAA_0x0555] = { ++ .addr1 = 0x0AAA, ++ .addr2 = 0x0555 ++ }, ++ ++ [MTD_UADDR_DONT_CARE] = { ++ .addr1 = 0x0000, /* Doesn't matter which address */ ++ .addr2 = 0x0000 /* is used - must be last entry */ ++ } ++}; ++ + + struct amd_flash_info { + const __u16 mfr_id; + const __u16 dev_id; + const char *name; + const int DevSize; +- const int InterfaceDesc; + const int NumEraseRegions; + const int CmdSet; ++ const __u8 uaddr[4]; /* unlock addrs for 8, 16, 32, 64 */ + const ulong regions[4]; + }; + +@@ -145,760 +236,1214 @@ + #define SIZE_4MiB 22 + #define SIZE_8MiB 23 + ++ ++/* ++ * Please keep this list ordered by manufacturer! ++ * Fortunately, the list isn't searched often and so a ++ * slow, linear search isn't so bad. ++ */ + static const struct amd_flash_info jedec_table[] = { + { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29F032B, +- name: "AMD AM29F032B", +- DevSize: SIZE_4MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,64) +- } +- }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29LV160DT, +- name: "AMD AM29LV160DT", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x10000,31), ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29F032B, ++ .name = "AMD AM29F032B", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ ++ }, ++ .DevSize = SIZE_4MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,64) ++ } ++ }, { ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29LV160DT, ++ .name = "AMD AM29LV160DT", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000,31), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29LV160DB, +- name: "AMD AM29LV160DB", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x04000,1), ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29LV160DB, ++ .name = "AMD AM29LV160DB", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,31) + } + }, { +- mfr_id: MANUFACTURER_TOSHIBA, +- dev_id: TC58FVT160, +- name: "Toshiba TC58FVT160", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x10000,31), ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29LV400BB, ++ .name = "AMD AM29LV400BB", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x04000,1), ++ ERASEINFO(0x02000,2), ++ ERASEINFO(0x08000,1), ++ ERASEINFO(0x10000,7) ++ } ++ }, { ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29LV400BT, ++ .name = "AMD AM29LV400BT", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000,7), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { +- mfr_id: MANUFACTURER_TOSHIBA, +- dev_id: TC58FVB160, +- name: "Toshiba TC58FVB160", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x04000,1), ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29LV800BB, ++ .name = "AMD AM29LV800BB", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), +- ERASEINFO(0x10000,31) ++ ERASEINFO(0x10000,15), + } + }, { +- mfr_id: MANUFACTURER_TOSHIBA, +- dev_id: TC58FVB321, +- name: "Toshiba TC58FVB321", +- DevSize: SIZE_4MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 2, +- regions: {ERASEINFO(0x02000,8), +- ERASEINFO(0x10000,63) ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29F800BB, ++ .name = "AMD AM29F800BB", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x04000,1), ++ ERASEINFO(0x02000,2), ++ ERASEINFO(0x08000,1), ++ ERASEINFO(0x10000,15), + } + }, { +- mfr_id: MANUFACTURER_TOSHIBA, +- dev_id: TC58FVT321, +- name: "Toshiba TC58FVT321", +- DevSize: SIZE_4MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 2, +- regions: {ERASEINFO(0x10000,63), +- ERASEINFO(0x02000,8) ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29LV800BT, ++ .name = "AMD AM29LV800BT", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000,15), ++ ERASEINFO(0x08000,1), ++ ERASEINFO(0x02000,2), ++ ERASEINFO(0x04000,1) + } + }, { +- mfr_id: MANUFACTURER_TOSHIBA, +- dev_id: TC58FVB641, +- name: "Toshiba TC58FVB641", +- DevSize: SIZE_8MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 2, +- regions: {ERASEINFO(0x02000,8), +- ERASEINFO(0x10000,127) ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29F800BT, ++ .name = "AMD AM29F800BT", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000,15), ++ ERASEINFO(0x08000,1), ++ ERASEINFO(0x02000,2), ++ ERASEINFO(0x04000,1) + } + }, { +- mfr_id: MANUFACTURER_TOSHIBA, +- dev_id: TC58FVT641, +- name: "Toshiba TC58FVT641", +- DevSize: SIZE_8MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 2, +- regions: {ERASEINFO(0x10000,127), +- ERASEINFO(0x02000,8) ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29F017D, ++ .name = "AMD AM29F017D", ++ .uaddr = { ++ [0] = MTD_UADDR_DONT_CARE /* x8 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,32), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29F016D, ++ .name = "AMD AM29F016D", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,32), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29F080, ++ .name = "AMD AM29F080", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,16), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29F040, ++ .name = "AMD AM29F040", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,8), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_AMD, ++ .dev_id = AM29LV040B, ++ .name = "AMD AM29LV040B", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,8), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_ATMEL, ++ .dev_id = AT49BV512, ++ .name = "Atmel AT49BV512", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_64KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,1) ++ } ++ }, { ++ .mfr_id = MANUFACTURER_ATMEL, ++ .dev_id = AT29LV512, ++ .name = "Atmel AT29LV512", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_64KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x80,256), ++ ERASEINFO(0x80,256) ++ } ++ }, { ++ .mfr_id = MANUFACTURER_ATMEL, ++ .dev_id = AT49BV16X, ++ .name = "Atmel AT49BV16X", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 2, ++ .regions = { ++ ERASEINFO(0x02000,8), ++ ERASEINFO(0x10000,31) + } + }, { +- mfr_id: MANUFACTURER_FUJITSU, +- dev_id: MBM29LV650UE, +- name: "Fujitsu MBM29LV650UE", +- DevSize: SIZE_8MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,128) +- } +- }, { +- mfr_id: MANUFACTURER_FUJITSU, +- dev_id: MBM29LV320TE, +- name: "Fujitsu MBM29LV320TE", +- DevSize: SIZE_4MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 2, +- regions: {ERASEINFO(0x10000,63), ++ .mfr_id = MANUFACTURER_ATMEL, ++ .dev_id = AT49BV16XT, ++ .name = "Atmel AT49BV16XT", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 2, ++ .regions = { ++ ERASEINFO(0x10000,31), + ERASEINFO(0x02000,8) + } + }, { +- mfr_id: MANUFACTURER_FUJITSU, +- dev_id: MBM29LV320BE, +- name: "Fujitsu MBM29LV320BE", +- DevSize: SIZE_4MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 2, +- regions: {ERASEINFO(0x02000,8), ++ .mfr_id = MANUFACTURER_ATMEL, ++ .dev_id = AT49BV32X, ++ .name = "Atmel AT49BV32X", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ ++ }, ++ .DevSize = SIZE_4MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 2, ++ .regions = { ++ ERASEINFO(0x02000,8), + ERASEINFO(0x10000,63) + } + }, { +- mfr_id: MANUFACTURER_FUJITSU, +- dev_id: MBM29LV160TE, +- name: "Fujitsu MBM29LV160TE", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x10000,31), +- ERASEINFO(0x08000,1), +- ERASEINFO(0x02000,2), +- ERASEINFO(0x04000,1) ++ .mfr_id = MANUFACTURER_ATMEL, ++ .dev_id = AT49BV32XT, ++ .name = "Atmel AT49BV32XT", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ ++ }, ++ .DevSize = SIZE_4MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 2, ++ .regions = { ++ ERASEINFO(0x10000,63), ++ ERASEINFO(0x02000,8) + } + }, { +- mfr_id: MANUFACTURER_FUJITSU, +- dev_id: MBM29LV160BE, +- name: "Fujitsu MBM29LV160BE", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x04000,1), +- ERASEINFO(0x02000,2), +- ERASEINFO(0x08000,1), +- ERASEINFO(0x10000,31) ++ .mfr_id = MANUFACTURER_FUJITSU, ++ .dev_id = MBM29F040C, ++ .name = "Fujitsu MBM29F040C", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,8) ++ } ++ }, { ++ .mfr_id = MANUFACTURER_FUJITSU, ++ .dev_id = MBM29LV650UE, ++ .name = "Fujitsu MBM29LV650UE", ++ .uaddr = { ++ [0] = MTD_UADDR_DONT_CARE /* x16 */ ++ }, ++ .DevSize = SIZE_8MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,128) ++ } ++ }, { ++ .mfr_id = MANUFACTURER_FUJITSU, ++ .dev_id = MBM29LV320TE, ++ .name = "Fujitsu MBM29LV320TE", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_4MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 2, ++ .regions = { ++ ERASEINFO(0x10000,63), ++ ERASEINFO(0x02000,8) + } + }, { +- mfr_id: MANUFACTURER_FUJITSU, +- dev_id: MBM29LV800BA, +- name: "Fujitsu MBM29LV800BA", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x04000,1), +- ERASEINFO(0x02000,2), +- ERASEINFO(0x08000,1), +- ERASEINFO(0x10000,15) ++ .mfr_id = MANUFACTURER_FUJITSU, ++ .dev_id = MBM29LV320BE, ++ .name = "Fujitsu MBM29LV320BE", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_4MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 2, ++ .regions = { ++ ERASEINFO(0x02000,8), ++ ERASEINFO(0x10000,63) + } + }, { +- mfr_id: MANUFACTURER_FUJITSU, +- dev_id: MBM29LV800TA, +- name: "Fujitsu MBM29LV800TA", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x10000,15), ++ .mfr_id = MANUFACTURER_FUJITSU, ++ .dev_id = MBM29LV160TE, ++ .name = "Fujitsu MBM29LV160TE", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000,31), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29LV800BB, +- name: "AMD AM29LV800BB", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x04000,1), ++ .mfr_id = MANUFACTURER_FUJITSU, ++ .dev_id = MBM29LV160BE, ++ .name = "Fujitsu MBM29LV160BE", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), +- ERASEINFO(0x10000,15), ++ ERASEINFO(0x10000,31) + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29F800BB, +- name: "AMD AM29F800BB", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x04000,1), ++ .mfr_id = MANUFACTURER_FUJITSU, ++ .dev_id = MBM29LV800BA, ++ .name = "Fujitsu MBM29LV800BA", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), +- ERASEINFO(0x10000,15), ++ ERASEINFO(0x10000,15) + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29LV800BT, +- name: "AMD AM29LV800BT", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x10000,15), ++ .mfr_id = MANUFACTURER_FUJITSU, ++ .dev_id = MBM29LV800TA, ++ .name = "Fujitsu MBM29LV800TA", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000,15), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29F800BT, +- name: "AMD AM29F800BT", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x10000,15), +- ERASEINFO(0x08000,1), ++ .mfr_id = MANUFACTURER_FUJITSU, ++ .dev_id = MBM29LV400BC, ++ .name = "Fujitsu MBM29LV400BC", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), +- ERASEINFO(0x04000,1) ++ ERASEINFO(0x08000,1), ++ ERASEINFO(0x10000,7) + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29LV800BB, +- name: "AMD AM29LV800BB", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x10000,15), ++ .mfr_id = MANUFACTURER_FUJITSU, ++ .dev_id = MBM29LV400TC, ++ .name = "Fujitsu MBM29LV400TC", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000,7), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F004B3B, +- name: "Intel 28F004B3B", +- DevSize: SIZE_512KiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F004B3B, ++ .name = "Intel 28F004B3B", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x02000, 8), + ERASEINFO(0x10000, 7), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F004B3T, +- name: "Intel 28F004B3T", +- DevSize: SIZE_512KiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F004B3T, ++ .name = "Intel 28F004B3T", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x10000, 7), + ERASEINFO(0x02000, 8), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F400B3B, +- name: "Intel 28F400B3B", +- DevSize: SIZE_512KiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F400B3B, ++ .name = "Intel 28F400B3B", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ [1] = MTD_UADDR_UNNECESSARY, /* x16 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x02000, 8), + ERASEINFO(0x10000, 7), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F400B3T, +- name: "Intel 28F400B3T", +- DevSize: SIZE_512KiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F400B3T, ++ .name = "Intel 28F400B3T", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ [1] = MTD_UADDR_UNNECESSARY, /* x16 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x10000, 7), + ERASEINFO(0x02000, 8), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F008B3B, +- name: "Intel 28F008B3B", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F008B3B, ++ .name = "Intel 28F008B3B", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x02000, 8), + ERASEINFO(0x10000, 15), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F008B3T, +- name: "Intel 28F008B3T", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F008B3T, ++ .name = "Intel 28F008B3T", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x10000, 15), + ERASEINFO(0x02000, 8), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F008S5, +- name: "Intel 28F008S5", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_INTEL_EXT, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,16), +- } +- }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F016S5, +- name: "Intel 28F016S5", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_INTEL_EXT, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,32), +- } +- }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F008SA, +- name: "Intel 28F008SA", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 1, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F008S5, ++ .name = "Intel 28F008S5", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_INTEL_EXT, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,16), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F016S5, ++ .name = "Intel 28F016S5", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_INTEL_EXT, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,32), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F008SA, ++ .name = "Intel 28F008SA", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 1, ++ .regions = { + ERASEINFO(0x10000, 16), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F800B3B, +- name: "Intel 28F800B3B", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F800B3B, ++ .name = "Intel 28F800B3B", ++ .uaddr = { ++ [1] = MTD_UADDR_UNNECESSARY, /* x16 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x02000, 8), + ERASEINFO(0x10000, 15), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F800B3T, +- name: "Intel 28F800B3T", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F800B3T, ++ .name = "Intel 28F800B3T", ++ .uaddr = { ++ [1] = MTD_UADDR_UNNECESSARY, /* x16 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x10000, 15), + ERASEINFO(0x02000, 8), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F016B3B, +- name: "Intel 28F016B3B", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F016B3B, ++ .name = "Intel 28F016B3B", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x02000, 8), + ERASEINFO(0x10000, 31), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F016S3, +- name: "Intel I28F016S3", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 1, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F016S3, ++ .name = "Intel I28F016S3", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 1, ++ .regions = { + ERASEINFO(0x10000, 32), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F016B3T, +- name: "Intel 28F016B3T", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F016B3T, ++ .name = "Intel 28F016B3T", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x10000, 31), + ERASEINFO(0x02000, 8), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F160B3B, +- name: "Intel 28F160B3B", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F160B3B, ++ .name = "Intel 28F160B3B", ++ .uaddr = { ++ [1] = MTD_UADDR_UNNECESSARY, /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x02000, 8), + ERASEINFO(0x10000, 31), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F160B3T, +- name: "Intel 28F160B3T", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F160B3T, ++ .name = "Intel 28F160B3T", ++ .uaddr = { ++ [1] = MTD_UADDR_UNNECESSARY, /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x10000, 31), + ERASEINFO(0x02000, 8), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F320B3B, +- name: "Intel 28F320B3B", +- DevSize: SIZE_4MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F320B3B, ++ .name = "Intel 28F320B3B", ++ .uaddr = { ++ [1] = MTD_UADDR_UNNECESSARY, /* x16 */ ++ }, ++ .DevSize = SIZE_4MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x02000, 8), + ERASEINFO(0x10000, 63), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F320B3T, +- name: "Intel 28F320B3T", +- DevSize: SIZE_4MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F320B3T, ++ .name = "Intel 28F320B3T", ++ .uaddr = { ++ [1] = MTD_UADDR_UNNECESSARY, /* x16 */ ++ }, ++ .DevSize = SIZE_4MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x10000, 63), + ERASEINFO(0x02000, 8), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F640B3B, +- name: "Intel 28F640B3B", +- DevSize: SIZE_8MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F640B3B, ++ .name = "Intel 28F640B3B", ++ .uaddr = { ++ [1] = MTD_UADDR_UNNECESSARY, /* x16 */ ++ }, ++ .DevSize = SIZE_8MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x02000, 8), + ERASEINFO(0x10000, 127), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I28F640B3T, +- name: "Intel 28F640B3T", +- DevSize: SIZE_8MiB, +- CmdSet: P_ID_INTEL_STD, +- NumEraseRegions: 2, +- regions: { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I28F640B3T, ++ .name = "Intel 28F640B3T", ++ .uaddr = { ++ [1] = MTD_UADDR_UNNECESSARY, /* x16 */ ++ }, ++ .DevSize = SIZE_8MiB, ++ .CmdSet = P_ID_INTEL_STD, ++ .NumEraseRegions= 2, ++ .regions = { + ERASEINFO(0x10000, 127), + ERASEINFO(0x02000, 8), + } + }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I82802AB, +- name: "Intel 82802AB", +- DevSize: SIZE_512KiB, +- CmdSet: P_ID_INTEL_EXT, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,8), +- } +- }, { +- mfr_id: MANUFACTURER_INTEL, +- dev_id: I82802AC, +- name: "Intel 82802AC", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_INTEL_EXT, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,16), +- } +- }, { +- mfr_id: MANUFACTURER_ST, +- dev_id: M29W800T, +- name: "ST M29W800T", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x10000,15), ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I82802AB, ++ .name = "Intel 82802AB", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_INTEL_EXT, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,8), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_INTEL, ++ .dev_id = I82802AC, ++ .name = "Intel 82802AC", ++ .uaddr = { ++ [0] = MTD_UADDR_UNNECESSARY, /* x8 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_INTEL_EXT, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,16), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_MACRONIX, ++ .dev_id = MX29LV160T, ++ .name = "MXIC MX29LV160T", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000,31), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { +- mfr_id: MANUFACTURER_ST, +- dev_id: M29W160DT, +- name: "ST M29W160DT", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x10000,31), +- ERASEINFO(0x08000,1), +- ERASEINFO(0x02000,2), +- ERASEINFO(0x04000,1) +- } +- }, { +- mfr_id: MANUFACTURER_ST, +- dev_id: M29W160DB, +- name: "ST M29W160DB", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x04000,1), ++ .mfr_id = MANUFACTURER_MACRONIX, ++ .dev_id = MX29LV160B, ++ .name = "MXIC MX29LV160B", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,31) + } + }, { +- mfr_id: MANUFACTURER_ATMEL, +- dev_id: AT49BV512, +- name: "Atmel AT49BV512", +- DevSize: SIZE_64KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,1) +- } +- }, { +- mfr_id: MANUFACTURER_ATMEL, +- dev_id: AT29LV512, +- name: "Atmel AT29LV512", +- DevSize: SIZE_64KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: { +- ERASEINFO(0x80,256), +- ERASEINFO(0x80,256) +- } +- }, { +- mfr_id: MANUFACTURER_ATMEL, +- dev_id: AT49BV16X, +- name: "Atmel AT49BV16X", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 2, +- regions: {ERASEINFO(0x02000,8), +- ERASEINFO(0x10000,31) ++ .mfr_id = MANUFACTURER_MACRONIX, ++ .dev_id = MX29F016, ++ .name = "Macronix MX29F016", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,32), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_MACRONIX, ++ .dev_id = MX29F004T, ++ .name = "Macronix MX29F004T", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000,7), ++ ERASEINFO(0x08000,1), ++ ERASEINFO(0x02000,2), ++ ERASEINFO(0x04000,1), + } + }, { +- mfr_id: MANUFACTURER_ATMEL, +- dev_id: AT49BV16XT, +- name: "Atmel AT49BV16XT", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 2, +- regions: {ERASEINFO(0x10000,31), +- ERASEINFO(0x02000,8) ++ .mfr_id = MANUFACTURER_MACRONIX, ++ .dev_id = MX29F004B, ++ .name = "Macronix MX29F004B", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x04000,1), ++ ERASEINFO(0x02000,2), ++ ERASEINFO(0x08000,1), ++ ERASEINFO(0x10000,7), + } + }, { +- mfr_id: MANUFACTURER_ATMEL, +- dev_id: AT49BV32X, +- name: "Atmel AT49BV32X", +- DevSize: SIZE_4MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 2, +- regions: {ERASEINFO(0x02000,8), +- ERASEINFO(0x10000,63) ++ .mfr_id = MANUFACTURER_PMC, ++ .dev_id = PM49FL002, ++ .name = "PMC Pm49FL002", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_256KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO( 0x01000, 64 ) ++ } ++ }, { ++ .mfr_id = MANUFACTURER_PMC, ++ .dev_id = PM49FL004, ++ .name = "PMC Pm49FL004", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO( 0x01000, 128 ) ++ } ++ }, { ++ .mfr_id = MANUFACTURER_PMC, ++ .dev_id = PM49FL008, ++ .name = "PMC Pm49FL008", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO( 0x01000, 256 ) ++ } ++ }, { ++ .mfr_id = MANUFACTURER_SST, ++ .dev_id = SST39LF512, ++ .name = "SST 39LF512", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_64KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x01000,16), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_SST, ++ .dev_id = SST39LF010, ++ .name = "SST 39LF010", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_128KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x01000,32), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_SST, ++ .dev_id = SST39LF020, ++ .name = "SST 39LF020", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_256KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x01000,64), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_SST, ++ .dev_id = SST39LF040, ++ .name = "SST 39LF040", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x01000,128), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_SST, ++ .dev_id = SST39SF010A, ++ .name = "SST 39SF010A", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_128KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x01000,32), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_SST, ++ .dev_id = SST39SF020A, ++ .name = "SST 39SF020A", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_256KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x01000,64), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_SST, ++ .dev_id = SST49LF004B, ++ .name = "SST 49LF004B", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x01000,128), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_SST, ++ .dev_id = SST49LF030A, ++ .name = "SST 49LF030A", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x01000,96), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_SST, ++ .dev_id = SST49LF040A, ++ .name = "SST 49LF040A", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x01000,128), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_SST, ++ .dev_id = SST49LF080A, ++ .name = "SST 49LF080A", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x01000,256), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ ++ .dev_id = M29W800DT, ++ .name = "ST M29W800DT", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */ ++ [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000,15), ++ ERASEINFO(0x08000,1), ++ ERASEINFO(0x02000,2), ++ ERASEINFO(0x04000,1) + } + }, { +- mfr_id: MANUFACTURER_ATMEL, +- dev_id: AT49BV32XT, +- name: "Atmel AT49BV32XT", +- DevSize: SIZE_4MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 2, +- regions: {ERASEINFO(0x10000,63), +- ERASEINFO(0x02000,8) ++ .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ ++ .dev_id = M29W800DB, ++ .name = "ST M29W800DB", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */ ++ [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */ ++ }, ++ .DevSize = SIZE_1MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x04000,1), ++ ERASEINFO(0x02000,2), ++ ERASEINFO(0x08000,1), ++ ERASEINFO(0x10000,15) + } + }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29F017D, +- name: "AMD AM29F017D", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,32), +- } +- }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29F016, +- name: "AMD AM29F016", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,32), +- } +- }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29F080, +- name: "AMD AM29F080", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,16), +- } +- }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29F040, +- name: "AMD AM29F040", +- DevSize: SIZE_512KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,8), +- } +- }, { +- mfr_id: MANUFACTURER_AMD, +- dev_id: AM29LV040B, +- name: "AMD AM29LV040B", +- DevSize: SIZE_512KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,8), +- } +- }, { +- mfr_id: MANUFACTURER_ST, +- dev_id: M29W040B, +- name: "ST M29W040B", +- DevSize: SIZE_512KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,8), +- } +- }, { +- mfr_id: MANUFACTURER_MACRONIX, +- dev_id: MX29LV160T, +- name: "MXIC MX29LV160T", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x10000,31), ++ .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ ++ .dev_id = M29W160DT, ++ .name = "ST M29W160DT", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000,31), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x04000,1) + } + }, { +- mfr_id: MANUFACTURER_MACRONIX, +- dev_id: MX29LV160B, +- name: "MXIC MX29LV160B", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x04000,1), ++ .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */ ++ .dev_id = M29W160DB, ++ .name = "ST M29W160DB", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), + ERASEINFO(0x10000,31) + } + }, { +- mfr_id: MANUFACTURER_MACRONIX, +- dev_id: MX29F016, +- name: "Macronix MX29F016", +- DevSize: SIZE_2MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x10000,32), +- } +- }, { +- mfr_id: MANUFACTURER_MACRONIX, +- dev_id: MX29F004T, +- name: "Macronix MX29F004T", +- DevSize: SIZE_512KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x10000,7), ++ .mfr_id = MANUFACTURER_ST, ++ .dev_id = M29W040B, ++ .name = "ST M29W040B", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ ++ }, ++ .DevSize = SIZE_512KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 1, ++ .regions = { ++ ERASEINFO(0x10000,8), ++ } ++ }, { ++ .mfr_id = MANUFACTURER_TOSHIBA, ++ .dev_id = TC58FVT160, ++ .name = "Toshiba TC58FVT160", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000,31), + ERASEINFO(0x08000,1), + ERASEINFO(0x02000,2), +- ERASEINFO(0x04000,1), ++ ERASEINFO(0x04000,1) + } + }, { +- mfr_id: MANUFACTURER_MACRONIX, +- dev_id: MX29F004B, +- name: "Macronix MX29F004B", +- DevSize: SIZE_512KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 4, +- regions: {ERASEINFO(0x04000,1), ++ .mfr_id = MANUFACTURER_TOSHIBA, ++ .dev_id = TC58FVB160, ++ .name = "Toshiba TC58FVB160", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ ++ }, ++ .DevSize = SIZE_2MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x04000,1), + ERASEINFO(0x02000,2), + ERASEINFO(0x08000,1), +- ERASEINFO(0x10000,7), ++ ERASEINFO(0x10000,31) ++ } ++ }, { ++ .mfr_id = MANUFACTURER_TOSHIBA, ++ .dev_id = TC58FVB321, ++ .name = "Toshiba TC58FVB321", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ ++ }, ++ .DevSize = SIZE_4MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 2, ++ .regions = { ++ ERASEINFO(0x02000,8), ++ ERASEINFO(0x10000,63) ++ } ++ }, { ++ .mfr_id = MANUFACTURER_TOSHIBA, ++ .dev_id = TC58FVT321, ++ .name = "Toshiba TC58FVT321", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ ++ }, ++ .DevSize = SIZE_4MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 2, ++ .regions = { ++ ERASEINFO(0x10000,63), ++ ERASEINFO(0x02000,8) ++ } ++ }, { ++ .mfr_id = MANUFACTURER_TOSHIBA, ++ .dev_id = TC58FVB641, ++ .name = "Toshiba TC58FVB641", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_8MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 2, ++ .regions = { ++ ERASEINFO(0x02000,8), ++ ERASEINFO(0x10000,127) ++ } ++ }, { ++ .mfr_id = MANUFACTURER_TOSHIBA, ++ .dev_id = TC58FVT641, ++ .name = "Toshiba TC58FVT641", ++ .uaddr = { ++ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ ++ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ ++ }, ++ .DevSize = SIZE_8MiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 2, ++ .regions = { ++ ERASEINFO(0x10000,127), ++ ERASEINFO(0x02000,8) + } + }, { +- mfr_id: MANUFACTURER_SST, +- dev_id: SST39LF512, +- name: "SST 39LF512", +- DevSize: SIZE_64KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x01000,16), +- } +- }, { +- mfr_id: MANUFACTURER_SST, +- dev_id: SST39LF010, +- name: "SST 39LF010", +- DevSize: SIZE_128KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x01000,32), +- } +- }, { +- mfr_id: MANUFACTURER_SST, +- dev_id: SST39LF020, +- name: "SST 39LF020", +- DevSize: SIZE_256KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x01000,64), +- } +- }, { +- mfr_id: MANUFACTURER_SST, +- dev_id: SST39LF040, +- name: "SST 39LF040", +- DevSize: SIZE_512KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x01000,128), +- } +- }, { +- mfr_id: MANUFACTURER_SST, +- dev_id: SST39SF010A, +- name: "SST 39SF010A", +- DevSize: SIZE_128KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x01000,32), +- } +- }, { +- mfr_id: MANUFACTURER_SST, +- dev_id: SST39SF020A, +- name: "SST 39SF020A", +- DevSize: SIZE_256KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x01000,64), +- } +- }, { +- mfr_id: MANUFACTURER_SST, +- dev_id: SST49LF030A, +- name: "SST 49LF030A", +- DevSize: SIZE_512KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x01000,96), +- } +- }, { +- mfr_id: MANUFACTURER_SST, +- dev_id: SST49LF040A, +- name: "SST 49LF040A", +- DevSize: SIZE_512KiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x01000,128), +- } +- }, { +- mfr_id: MANUFACTURER_SST, +- dev_id: SST49LF080A, +- name: "SST 49LF080A", +- DevSize: SIZE_1MiB, +- CmdSet: P_ID_AMD_STD, +- NumEraseRegions: 1, +- regions: {ERASEINFO(0x01000,256), ++ .mfr_id = MANUFACTURER_WINBOND, ++ .dev_id = W49V002A, ++ .name = "Winbond W49V002A", ++ .uaddr = { ++ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */ ++ }, ++ .DevSize = SIZE_256KiB, ++ .CmdSet = P_ID_AMD_STD, ++ .NumEraseRegions= 4, ++ .regions = { ++ ERASEINFO(0x10000, 3), ++ ERASEINFO(0x08000, 1), ++ ERASEINFO(0x02000, 2), ++ ERASEINFO(0x04000, 1), + } + } + }; +@@ -907,7 +1452,7 @@ + static int cfi_jedec_setup(struct cfi_private *p_cfi, int index); + + static int jedec_probe_chip(struct map_info *map, __u32 base, +- struct flchip *chips, struct cfi_private *cfi); ++ unsigned long *chip_map, struct cfi_private *cfi); + + struct mtd_info *jedec_probe(struct map_info *map); + +@@ -944,11 +1489,43 @@ + * this should be safe. + */ + cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); ++ /* FIXME - should have reset delay before continuing */ ++} + ++ ++static inline __u8 finfo_uaddr(const struct amd_flash_info *finfo, int device_type) ++{ ++ int uaddr_idx; ++ __u8 uaddr = MTD_UADDR_NOT_SUPPORTED; ++ ++ switch ( device_type ) { ++ case CFI_DEVICETYPE_X8: uaddr_idx = 0; break; ++ case CFI_DEVICETYPE_X16: uaddr_idx = 1; break; ++ case CFI_DEVICETYPE_X32: uaddr_idx = 2; break; ++ default: ++ printk(KERN_NOTICE "MTD: %s(): unknown device_type %d\n", ++ __func__, device_type); ++ goto uaddr_done; ++ } ++ ++ uaddr = finfo->uaddr[uaddr_idx]; ++ ++ if (uaddr != MTD_UADDR_NOT_SUPPORTED ) { ++ /* ASSERT("The unlock addresses for non-8-bit mode ++ are bollocks. We don't really need an array."); */ ++ uaddr = finfo->uaddr[0]; ++ } ++ ++ uaddr_done: ++ return uaddr; + } ++ ++ + static int cfi_jedec_setup(struct cfi_private *p_cfi, int index) + { + int i,num_erase_regions; ++ unsigned long mask; ++ __u8 uaddr; + + printk("Found: %s\n",jedec_table[index].name); + +@@ -971,41 +1548,170 @@ + p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i]; + } + p_cfi->cmdset_priv = 0; ++ ++ /* This may be redundant for some cases, but it doesn't hurt */ ++ p_cfi->mfr = jedec_table[index].mfr_id; ++ p_cfi->id = jedec_table[index].dev_id; ++ ++ uaddr = finfo_uaddr(&jedec_table[index], p_cfi->device_type); ++ if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) { ++ kfree( p_cfi->cfiq ); ++ return 0; ++ } ++ ++ /* Mask out address bits which are smaller than the device type */ ++ mask = ~(p_cfi->device_type-1); ++ p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1 & mask; ++ p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2 & mask; ++ + return 1; /* ok */ + } + +-static int jedec_probe_chip(struct map_info *map, __u32 base, +- struct flchip *chips, struct cfi_private *cfi) ++ ++/* ++ * There is a BIG problem properly ID'ing the JEDEC devic and guaranteeing ++ * the mapped address, unlock addresses, and proper chip ID. This function ++ * attempts to minimize errors. It is doubtfull that this probe will ever ++ * be perfect - consequently there should be some module parameters that ++ * could be manually specified to force the chip info. ++ */ ++static inline int jedec_match( __u32 base, ++ struct map_info *map, ++ struct cfi_private *cfi, ++ const struct amd_flash_info *finfo ) + { +- int i; +- int unlockpass = 0; ++ int rc = 0; /* failure until all tests pass */ ++ u32 mfr, id; ++ __u8 uaddr; ++ unsigned long mask; + +- if (!cfi->numchips) { ++ /* ++ * The IDs must match. For X16 and X32 devices operating in ++ * a lower width ( X8 or X16 ), the device ID's are usually just ++ * the lower byte(s) of the larger device ID for wider mode. If ++ * a part is found that doesn't fit this assumption (device id for ++ * smaller width mode is completely unrealated to full-width mode) ++ * then the jedec_table[] will have to be augmented with the IDs ++ * for different widths. ++ */ + switch (cfi->device_type) { + case CFI_DEVICETYPE_X8: +- cfi->addr_unlock1 = 0x555; +- cfi->addr_unlock2 = 0x2aa; ++ mfr = (__u8)finfo->mfr_id; ++ id = (__u8)finfo->dev_id; + break; + case CFI_DEVICETYPE_X16: +- cfi->addr_unlock1 = 0xaaa; +- if (map->buswidth == cfi->interleave) { +- /* X16 chip(s) in X8 mode */ +- cfi->addr_unlock2 = 0x555; +- } else { +- cfi->addr_unlock2 = 0x554; +- } ++ mfr = (__u16)finfo->mfr_id; ++ id = (__u16)finfo->dev_id; + break; + case CFI_DEVICETYPE_X32: +- cfi->addr_unlock1 = 0x1555; +- cfi->addr_unlock2 = 0xaaa; ++ mfr = (__u16)finfo->mfr_id; ++ id = (__u32)finfo->dev_id; + break; + default: +- printk(KERN_NOTICE "Eep. Unknown jedec_probe device type %d\n", cfi->device_type); +- return 0; ++ printk(KERN_WARNING ++ "MTD %s(): Unsupported device type %d\n", ++ __func__, cfi->device_type); ++ goto match_done; ++ } ++ if ( cfi->mfr != mfr || cfi->id != id ) { ++ goto match_done; ++ } ++ ++ /* the part size must fit in the memory window */ ++ DEBUG( MTD_DEBUG_LEVEL3, ++ "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n", ++ __func__, base, 1 << finfo->DevSize, base + (1 << finfo->DevSize) ); ++ if ( base + cfi->interleave * ( 1 << finfo->DevSize ) > map->size ) { ++ DEBUG( MTD_DEBUG_LEVEL3, ++ "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n", ++ __func__, finfo->mfr_id, finfo->dev_id, ++ 1 << finfo->DevSize ); ++ goto match_done; ++ } ++ ++ uaddr = finfo_uaddr(finfo, cfi->device_type); ++ if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) { ++ goto match_done; ++ } ++ ++ mask = ~(cfi->device_type-1); ++ ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n", ++ __func__, cfi->addr_unlock1, cfi->addr_unlock2 ); ++ if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr ++ && ( (unlock_addrs[uaddr].addr1 & mask) != cfi->addr_unlock1 || ++ (unlock_addrs[uaddr].addr2 & mask) != cfi->addr_unlock2 ) ) { ++ DEBUG( MTD_DEBUG_LEVEL3, ++ "MTD %s(): 0x%.4x 0x%.4x did not match\n", ++ __func__, ++ unlock_addrs[uaddr].addr1 & mask, ++ unlock_addrs[uaddr].addr2 & mask); ++ goto match_done; + } ++ ++ /* ++ * Make sure the ID's dissappear when the device is taken out of ++ * ID mode. The only time this should fail when it should succeed ++ * is when the ID's are written as data to the same ++ * addresses. For this rare and unfortunate case the chip ++ * cannot be probed correctly. ++ * FIXME - write a driver that takes all of the chip info as ++ * module parameters, doesn't probe but forces a load. ++ */ ++ DEBUG( MTD_DEBUG_LEVEL3, ++ "MTD %s(): check ID's disappear when not in ID mode\n", ++ __func__ ); ++ jedec_reset( base, map, cfi ); ++ mfr = jedec_read_mfr( map, base, cfi ); ++ id = jedec_read_id( map, base, cfi ); ++ if ( mfr == cfi->mfr && id == cfi->id ) { ++ DEBUG( MTD_DEBUG_LEVEL3, ++ "MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n" ++ "You might need to manually specify JEDEC parameters.\n", ++ __func__, cfi->mfr, cfi->id ); ++ goto match_done; ++ } ++ ++ /* all tests passed - mark as success */ ++ rc = 1; ++ ++ /* ++ * Put the device back in ID mode - only need to do this if we ++ * were truly frobbing a real device. ++ */ ++ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ ); ++ if(cfi->addr_unlock1) { ++ cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL); ++ cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL); + } ++ cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL); ++ /* FIXME - should have a delay before continuing */ ++ ++ match_done: ++ return rc; ++} ++ ++ ++static int jedec_probe_chip(struct map_info *map, __u32 base, ++ unsigned long *chip_map, struct cfi_private *cfi) ++{ ++ int i; ++ enum uaddr uaddr_idx = MTD_UADDR_NOT_SUPPORTED; + + retry: ++ if (!cfi->numchips) { ++ unsigned long mask = ~(cfi->device_type-1); ++ ++ uaddr_idx++; ++ ++ if (MTD_UADDR_UNNECESSARY == uaddr_idx) ++ return 0; ++ ++ /* Mask out address bits which are smaller than the device type */ ++ cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1 & mask; ++ cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2 & mask; ++ } ++ + /* Make certain we aren't probing past the end of map */ + if (base >= map->size) { + printk(KERN_NOTICE +@@ -1038,6 +1744,7 @@ + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL); + } + cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL); ++ /* FIXME - should have a delay before continuing */ + + if (!cfi->numchips) { + /* This is the first time we're called. Set up the CFI +@@ -1045,26 +1752,21 @@ + + cfi->mfr = jedec_read_mfr(map, base, cfi); + cfi->id = jedec_read_id(map, base, cfi); +- printk(KERN_INFO "Search for id:(%02x %02x) interleave(%d) type(%d)\n", ++ DEBUG(MTD_DEBUG_LEVEL3, ++ "Search for id:(%02x %02x) interleave(%d) type(%d)\n", + cfi->mfr, cfi->id, cfi->interleave, cfi->device_type); + for (i=0; imfr == jedec_table[i].mfr_id && +- cfi->id == jedec_table[i].dev_id) { ++ if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) { ++ DEBUG( MTD_DEBUG_LEVEL3, ++ "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n", ++ __func__, cfi->mfr, cfi->id, ++ cfi->addr_unlock1, cfi->addr_unlock2 ); + if (!cfi_jedec_setup(cfi, i)) + return 0; + goto ok_out; + } + } +- switch(unlockpass++) { +- case 0: +- cfi->addr_unlock1 |= cfi->addr_unlock1 << 4; +- cfi->addr_unlock2 |= cfi->addr_unlock2 << 4; +- goto retry; +- case 1: +- cfi->addr_unlock1 = cfi->addr_unlock2 = 0; + goto retry; +- } +- return 0; + } else { + __u16 mfr; + __u16 id; +@@ -1081,21 +1783,24 @@ + } + } + +- /* Check each previous chip to see if it's an alias */ +- for (i=0; inumchips; i++) { +- /* This chip should be in read mode if it's one +- we've already touched. */ +- if (jedec_read_mfr(map, chips[i].start, cfi) == cfi->mfr && +- jedec_read_id(map, chips[i].start, cfi) == cfi->id) { ++ /* Check each previous chip locations to see if it's an alias */ ++ for (i=0; i < (base >> cfi->chipshift); i++) { ++ unsigned long start; ++ if(!test_bit(i, chip_map)) { ++ continue; /* Skip location; no valid chip at this address */ ++ } ++ start = i << cfi->chipshift; ++ if (jedec_read_mfr(map, start, cfi) == cfi->mfr && ++ jedec_read_id(map, start, cfi) == cfi->id) { + /* Eep. This chip also looks like it's in autoselect mode. + Is it an alias for the new one? */ +- jedec_reset(chips[i].start, map, cfi); ++ jedec_reset(start, map, cfi); + + /* If the device IDs go away, it's an alias */ + if (jedec_read_mfr(map, base, cfi) != cfi->mfr || + jedec_read_id(map, base, cfi) != cfi->id) { + printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", +- map->name, base, chips[i].start); ++ map->name, base, start); + return 0; + } + +@@ -1107,7 +1812,7 @@ + if (jedec_read_mfr(map, base, cfi) == cfi->mfr && + jedec_read_id(map, base, cfi) == cfi->id) { + printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", +- map->name, base, chips[i].start); ++ map->name, base, start); + return 0; + } + } +@@ -1115,13 +1820,7 @@ + + /* OK, if we got to here, then none of the previous chips appear to + be aliases for the current one. */ +- if (cfi->numchips == MAX_CFI_CHIPS) { +- printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS); +- /* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */ +- return -1; +- } +- chips[cfi->numchips].start = base; +- chips[cfi->numchips].state = FL_READY; ++ set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ + cfi->numchips++; + + ok_out: +@@ -1136,8 +1835,8 @@ + } + + static struct chip_probe jedec_chip_probe = { +- name: "JEDEC", +- probe_chip: jedec_probe_chip ++ .name = "JEDEC", ++ .probe_chip = jedec_probe_chip + }; + + struct mtd_info *jedec_probe(struct map_info *map) +@@ -1150,9 +1849,9 @@ + } + + static struct mtd_chip_driver jedec_chipdrv = { +- probe: jedec_probe, +- name: "jedec_probe", +- module: THIS_MODULE ++ .probe = jedec_probe, ++ .name = "jedec_probe", ++ .module = THIS_MODULE + }; + + int __init jedec_probe_init(void) +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/map_absent.c linux/drivers/mtd/chips/map_absent.c +--- linux-mips-2.4.27/drivers/mtd/chips/map_absent.c 2001-11-05 21:15:51.000000000 +0100 ++++ linux/drivers/mtd/chips/map_absent.c 2004-11-19 10:25:11.776218488 +0100 +@@ -1,7 +1,7 @@ + /* + * Common code to handle absent "placeholder" devices + * Copyright 2001 Resilience Corporation +- * $Id: map_absent.c,v 1.2 2001/10/02 15:05:12 dwmw2 Exp $ ++ * $Id: map_absent.c,v 1.4 2003/05/28 12:51:49 dwmw2 Exp $ + * + * This map driver is used to allocate "placeholder" MTD + * devices on systems that have socketed/removable media. +@@ -23,9 +23,10 @@ + #include + #include + #include +- ++#include ++#include + #include +- ++#include + + static int map_absent_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); + static int map_absent_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); +@@ -36,10 +37,10 @@ + + + static struct mtd_chip_driver map_absent_chipdrv = { +- probe: map_absent_probe, +- destroy: map_absent_destroy, +- name: "map_absent", +- module: THIS_MODULE ++ .probe = map_absent_probe, ++ .destroy = map_absent_destroy, ++ .name = "map_absent", ++ .module = THIS_MODULE + }; + + static struct mtd_info *map_absent_probe(struct map_info *map) +@@ -65,7 +66,7 @@ + mtd->flags = 0; + mtd->erasesize = PAGE_SIZE; + +- MOD_INC_USE_COUNT; ++ __module_get(THIS_MODULE); + return mtd; + } + +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/map_ram.c linux/drivers/mtd/chips/map_ram.c +--- linux-mips-2.4.27/drivers/mtd/chips/map_ram.c 2001-11-05 21:15:51.000000000 +0100 ++++ linux/drivers/mtd/chips/map_ram.c 2004-11-19 10:25:11.777218336 +0100 +@@ -1,7 +1,7 @@ + /* + * Common code to handle map devices which are simple RAM + * (C) 2000 Red Hat. GPL'd. +- * $Id: map_ram.c,v 1.14 2001/10/02 15:05:12 dwmw2 Exp $ ++ * $Id: map_ram.c,v 1.17 2003/05/28 12:51:49 dwmw2 Exp $ + */ + + #include +@@ -11,8 +11,10 @@ + #include + #include + #include +- ++#include ++#include + #include ++#include + + + static int mapram_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); +@@ -23,9 +25,9 @@ + + + static struct mtd_chip_driver mapram_chipdrv = { +- probe: map_ram_probe, +- name: "map_ram", +- module: THIS_MODULE ++ .probe = map_ram_probe, ++ .name = "map_ram", ++ .module = THIS_MODULE + }; + + static struct mtd_info *map_ram_probe(struct map_info *map) +@@ -34,21 +36,21 @@ + + /* Check the first byte is RAM */ + #if 0 +- map->write8(map, 0x55, 0); +- if (map->read8(map, 0) != 0x55) ++ map_write8(map, 0x55, 0); ++ if (map_read8(map, 0) != 0x55) + return NULL; + +- map->write8(map, 0xAA, 0); +- if (map->read8(map, 0) != 0xAA) ++ map_write8(map, 0xAA, 0); ++ if (map_read8(map, 0) != 0xAA) + return NULL; + + /* Check the last byte is RAM */ +- map->write8(map, 0x55, map->size-1); +- if (map->read8(map, map->size-1) != 0x55) ++ map_write8(map, 0x55, map->size-1); ++ if (map_read8(map, map->size-1) != 0x55) + return NULL; + +- map->write8(map, 0xAA, map->size-1); +- if (map->read8(map, map->size-1) != 0xAA) ++ map_write8(map, 0xAA, map->size-1); ++ if (map_read8(map, map->size-1) != 0xAA) + return NULL; + #endif + /* OK. It seems to be RAM. */ +@@ -74,7 +76,7 @@ + while(mtd->size & (mtd->erasesize - 1)) + mtd->erasesize >>= 1; + +- MOD_INC_USE_COUNT; ++ __module_get(THIS_MODULE); + return mtd; + } + +@@ -83,7 +85,7 @@ + { + struct map_info *map = (struct map_info *)mtd->priv; + +- map->copy_from(map, buf, from, len); ++ map_copy_from(map, buf, from, len); + *retlen = len; + return 0; + } +@@ -92,7 +94,7 @@ + { + struct map_info *map = (struct map_info *)mtd->priv; + +- map->copy_to(map, to, buf, len); ++ map_copy_to(map, to, buf, len); + *retlen = len; + return 0; + } +@@ -105,7 +107,7 @@ + unsigned long i; + + for (i=0; ilen; i++) +- map->write8(map, 0xFF, instr->addr + i); ++ map_write8(map, 0xFF, instr->addr + i); + + if (instr->callback) + instr->callback(instr); +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/map_rom.c linux/drivers/mtd/chips/map_rom.c +--- linux-mips-2.4.27/drivers/mtd/chips/map_rom.c 2001-11-05 21:15:52.000000000 +0100 ++++ linux/drivers/mtd/chips/map_rom.c 2004-11-19 10:25:11.778218184 +0100 +@@ -1,7 +1,7 @@ + /* + * Common code to handle map devices which are simple ROM + * (C) 2000 Red Hat. GPL'd. +- * $Id: map_rom.c,v 1.17 2001/10/02 15:05:12 dwmw2 Exp $ ++ * $Id: map_rom.c,v 1.20 2003/05/28 12:51:49 dwmw2 Exp $ + */ + + #include +@@ -12,8 +12,10 @@ + #include + #include + #include +- ++#include ++#include + #include ++#include + + static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); + static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); +@@ -21,9 +23,9 @@ + struct mtd_info *map_rom_probe(struct map_info *map); + + static struct mtd_chip_driver maprom_chipdrv = { +- probe: map_rom_probe, +- name: "map_rom", +- module: THIS_MODULE ++ .probe = map_rom_probe, ++ .name = "map_rom", ++ .module = THIS_MODULE + }; + + struct mtd_info *map_rom_probe(struct map_info *map) +@@ -49,7 +51,7 @@ + while(mtd->size & (mtd->erasesize - 1)) + mtd->erasesize >>= 1; + +- MOD_INC_USE_COUNT; ++ __module_get(THIS_MODULE); + return mtd; + } + +@@ -58,7 +60,7 @@ + { + struct map_info *map = (struct map_info *)mtd->priv; + +- map->copy_from(map, buf, from, len); ++ map_copy_from(map, buf, from, len); + *retlen = len; + return 0; + } +diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/sharp.c linux/drivers/mtd/chips/sharp.c +--- linux-mips-2.4.27/drivers/mtd/chips/sharp.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/chips/sharp.c 2004-11-19 10:25:11.792216056 +0100 +@@ -4,7 +4,7 @@ + * Copyright 2000,2001 David A. Schleef + * 2000,2001 Lineo, Inc. + * +- * $Id: sharp.c,v 1.8 2002/05/17 08:59:19 dwmw2 Exp $ ++ * $Id: sharp.c,v 1.12 2003/05/28 15:39:52 dwmw2 Exp $ + * + * Devices supported: + * LH28F016SCT Symmetrical block flash memory, 2Mx8 +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -98,10 +99,10 @@ + static void sharp_destroy(struct mtd_info *mtd); + + static struct mtd_chip_driver sharp_chipdrv = { +- probe: sharp_probe, +- destroy: sharp_destroy, +- name: "sharp", +- module: THIS_MODULE ++ .probe = sharp_probe, ++ .destroy = sharp_destroy, ++ .name = "sharp", ++ .module = THIS_MODULE + }; + + +@@ -116,8 +117,10 @@ + return NULL; + + sharp = kmalloc(sizeof(*sharp), GFP_KERNEL); +- if(!sharp) ++ if(!sharp) { ++ kfree(mtd); + return NULL; ++ } + + memset(mtd, 0, sizeof(*mtd)); + +@@ -163,12 +166,12 @@ + u32 read0, read4; + int width = 4; + +- tmp = map->read32(map, base+0); ++ tmp = map_read32(map, base+0); + +- map->write32(map, CMD_READ_ID, base+0); ++ map_write32(map, CMD_READ_ID, base+0); + +- read0=map->read32(map, base+0); +- read4=map->read32(map, base+4); ++ read0=map_read32(map, base+0); ++ read4=map_read32(map, base+4); + if(read0 == 0x89898989){ + printk("Looks like sharp flash\n"); + switch(read4){ +@@ -196,10 +199,10 @@ + printk("Sort-of looks like sharp flash, 0x%08x 0x%08x\n", + read0,read4); + } +- }else if((map->read32(map, base+0) == CMD_READ_ID)){ ++ }else if((map_read32(map, base+0) == CMD_READ_ID)){ + /* RAM, probably */ + printk("Looks like RAM\n"); +- map->write32(map, tmp, base+0); ++ map_write32(map, tmp, base+0); + }else{ + printk("Doesn't look like sharp flash, 0x%08x 0x%08x\n", + read0,read4); +@@ -221,10 +224,10 @@ + + switch(chip->state){ + case FL_READY: +- map->write32(map,CMD_READ_STATUS,adr); ++ map_write32(map,CMD_READ_STATUS,adr); + chip->state = FL_STATUS; + case FL_STATUS: +- status = map->read32(map,adr); ++ status = map_read32(map,adr); + //printk("status=%08x\n",status); + + udelay(100); +@@ -252,7 +255,7 @@ + goto retry; + } + +- map->write32(map,CMD_RESET, adr); ++ map_write32(map,CMD_RESET, adr); + + chip->state = FL_READY; + +@@ -293,7 +296,7 @@ + if(ret<0) + break; + +- map->copy_from(map,buf,ofs,thislen); ++ map_copy_from(map,buf,ofs,thislen); + + sharp_release(&sharp->chips[chipnum]); + +@@ -354,17 +357,17 @@ + ret = sharp_wait(map,chip); + + for(try=0;try<10;try++){ +- map->write32(map,CMD_BYTE_WRITE,adr); ++ map_write32(map,CMD_BYTE_WRITE,adr); + /* cpu_to_le32 -> hack to fix the writel be->le conversion */ +- map->write32(map,cpu_to_le32(datum),adr); ++ map_write32(map,cpu_to_le32(datum),adr); + + chip->state = FL_WRITING; + + timeo = jiffies + (HZ/2); + +- map->write32(map,CMD_READ_STATUS,adr); ++ map_write32(map,CMD_READ_STATUS,adr); + for(i=0;i<100;i++){ +- status = map->read32(map,adr); ++ status = map_read32(map,adr); + if((status & SR_READY)==SR_READY) + break; + } +@@ -377,9 +380,9 @@ + + printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status); + +- map->write32(map,CMD_CLEAR_STATUS,adr); ++ map_write32(map,CMD_CLEAR_STATUS,adr); + } +- map->write32(map,CMD_RESET,adr); ++ map_write32(map,CMD_RESET,adr); + chip->state = FL_READY; + + wake_up(&chip->wq); +@@ -436,14 +439,14 @@ + int status; + DECLARE_WAITQUEUE(wait, current); + +- map->write32(map,CMD_READ_STATUS,adr); +- status = map->read32(map,adr); ++ map_write32(map,CMD_READ_STATUS,adr); ++ status = map_read32(map,adr); + + timeo = jiffies + HZ; + + while(time_before(jiffies, timeo)){ +- map->write32(map,CMD_READ_STATUS,adr); +- status = map->read32(map,adr); ++ map_write32(map,CMD_READ_STATUS,adr); ++ status = map_read32(map,adr); + if((status & SR_READY)==SR_READY){ + ret = 0; + goto out; +@@ -485,26 +488,26 @@ + sharp_unlock_oneblock(map,chip,adr); + #endif + +- map->write32(map,CMD_BLOCK_ERASE_1,adr); +- map->write32(map,CMD_BLOCK_ERASE_2,adr); ++ map_write32(map,CMD_BLOCK_ERASE_1,adr); ++ map_write32(map,CMD_BLOCK_ERASE_2,adr); + + chip->state = FL_ERASING; + + ret = sharp_do_wait_for_ready(map,chip,adr); + if(ret<0)return ret; + +- map->write32(map,CMD_READ_STATUS,adr); +- status = map->read32(map,adr); ++ map_write32(map,CMD_READ_STATUS,adr); ++ status = map_read32(map,adr); + + if(!(status&SR_ERRORS)){ +- map->write32(map,CMD_RESET,adr); ++ map_write32(map,CMD_RESET,adr); + chip->state = FL_READY; + //spin_unlock_bh(chip->mutex); + return 0; + } + + printk("sharp: error erasing block at addr=%08lx status=%08x\n",adr,status); +- map->write32(map,CMD_CLEAR_STATUS,adr); ++ map_write32(map,CMD_CLEAR_STATUS,adr); + + //spin_unlock_bh(chip->mutex); + +@@ -518,17 +521,17 @@ + int i; + int status; + +- map->write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr); +- map->write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr); ++ map_write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr); ++ map_write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr); + + udelay(100); + +- status = map->read32(map,adr); ++ status = map_read32(map,adr); + printk("status=%08x\n",status); + + for(i=0;i<1000;i++){ +- //map->write32(map,CMD_READ_STATUS,adr); +- status = map->read32(map,adr); ++ //map_write32(map,CMD_READ_STATUS,adr); ++ status = map_read32(map,adr); + if((status & SR_READY)==SR_READY) + break; + udelay(100); +@@ -538,13 +541,13 @@ + } + + if(!(status&SR_ERRORS)){ +- map->write32(map,CMD_RESET,adr); ++ map_write32(map,CMD_RESET,adr); + chip->state = FL_READY; + return; + } + + printk("sharp: error unlocking block at addr=%08lx status=%08x\n",adr,status); +- map->write32(map,CMD_CLEAR_STATUS,adr); ++ map_write32(map,CMD_CLEAR_STATUS,adr); + } + #endif + +diff -Nurb linux-mips-2.4.27/drivers/mtd/cmdlinepart.c linux/drivers/mtd/cmdlinepart.c +--- linux-mips-2.4.27/drivers/mtd/cmdlinepart.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/cmdlinepart.c 2004-11-19 10:25:11.628240984 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: cmdlinepart.c,v 1.6 2002/11/16 01:37:39 dneuer Exp $ ++ * $Id: cmdlinepart.c,v 1.11 2003/10/23 08:32:45 dwmw2 Exp $ + * + * Read flash partition table from command line + * +@@ -28,7 +28,7 @@ + + #include + #include +-#include ++#include + #include + + /* error message prefix */ +@@ -178,8 +178,7 @@ + parts[this_part].mask_flags = mask_flags; + if (name) + { +- strncpy(extra_mem, name, name_len); +- extra_mem[name_len] = 0; ++ strlcpy(extra_mem, name, name_len + 1); + } + else + { +@@ -258,8 +257,7 @@ + this_mtd->parts = parts; + this_mtd->num_parts = num_parts; + this_mtd->mtd_id = (char*)(this_mtd + 1); +- strncpy(this_mtd->mtd_id, mtd_id, mtd_id_len); +- this_mtd->mtd_id[mtd_id_len] = 0; ++ strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1); + + /* link into chain */ + this_mtd->next = partitions; +@@ -291,13 +289,14 @@ + * information. It returns partitions for the requested mtd device, or + * the first one in the chain if a NULL mtd_id is passed in. + */ +-int parse_cmdline_partitions(struct mtd_info *master, ++static int parse_cmdline_partitions(struct mtd_info *master, + struct mtd_partition **pparts, +- const char *mtd_id) ++ unsigned long origin) + { + unsigned long offset; + int i; + struct cmdline_mtd_partition *part; ++ char *mtd_id = master->name; + + if(!cmdline) + return -EINVAL; +@@ -349,7 +348,25 @@ + + __setup("mtdparts=", mtdpart_setup); + +-EXPORT_SYMBOL(parse_cmdline_partitions); ++static struct mtd_part_parser cmdline_parser = { ++ .owner = THIS_MODULE, ++ .parse_fn = parse_cmdline_partitions, ++ .name = "cmdlinepart", ++}; ++ ++static int __init cmdline_parser_init(void) ++{ ++ return register_mtd_parser(&cmdline_parser); ++} ++ ++static void __exit cmdline_parser_exit(void) ++{ ++ deregister_mtd_parser(&cmdline_parser); ++} ++ ++module_init(cmdline_parser_init); ++module_exit(cmdline_parser_exit); ++ + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Marius Groeger "); +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/Config.in linux/drivers/mtd/devices/Config.in +--- linux-mips-2.4.27/drivers/mtd/devices/Config.in 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/devices/Config.in 2004-11-19 10:25:11.811213168 +0100 +@@ -1,6 +1,6 @@ +-# drivers/mtd/maps/Config.in ++# drivers/mtd/devices/Config.in + +-# $Id: Config.in,v 1.8 2003/01/24 23:25:14 dwmw2 Exp $ ++# $Id: Config.in,v 1.11 2003/05/28 10:54:23 dwmw2 Exp $ + + mainmenu_option next_comment + +@@ -28,13 +28,13 @@ + dep_tristate ' MTD emulation using block device' CONFIG_MTD_BLKMTD $CONFIG_MTD + + comment 'Disk-On-Chip Device Drivers' +- dep_tristate ' M-Systems Disk-On-Chip 1000' CONFIG_MTD_DOC1000 $CONFIG_MTD + dep_tristate ' M-Systems Disk-On-Chip 2000 and Millennium' CONFIG_MTD_DOC2000 $CONFIG_MTD + dep_tristate ' M-Systems Disk-On-Chip Millennium-only alternative driver (see help)' CONFIG_MTD_DOC2001 $CONFIG_MTD +- if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then ++ dep_tristate ' M-Systems Disk-On-Chip Millennium Plus driver (see help)' CONFIG_MTD_DOC2001PLUS $CONFIG_MTD ++ if [ "$CONFIG_MTD_DOC2001PLUS" = "y" -o "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then + define_bool CONFIG_MTD_DOCPROBE y + else +- if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then ++ if [ "$CONFIG_MTD_DOC2001PLUS" = "m" -o "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then + define_bool CONFIG_MTD_DOCPROBE m + else + define_bool CONFIG_MTD_DOCPROBE n +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/Makefile linux/drivers/mtd/devices/Makefile +--- linux-mips-2.4.27/drivers/mtd/devices/Makefile 2002-03-30 09:15:50.000000000 +0100 ++++ linux/drivers/mtd/devices/Makefile 2004-11-19 10:25:11.813212864 +0100 +@@ -1,9 +1,12 @@ + # + # linux/drivers/devices/Makefile + # +-# $Id: Makefile,v 1.4 2001/06/26 21:10:05 spse Exp $ ++# $Id: Makefile.common,v 1.4 2003/08/21 17:52:29 joern Exp $ + ++ifeq ($(PATCHLEVEL),4) + O_TARGET := devlink.o ++export-objs := docecc.o ++endif + + # *** BIG UGLY NOTE *** + # +@@ -12,15 +15,16 @@ + # here where previously there was none. We now have to ensure that + # doc200[01].o are linked before docprobe.o + +-obj-$(CONFIG_MTD_DOC1000) += doc1000.o + obj-$(CONFIG_MTD_DOC2000) += doc2000.o + obj-$(CONFIG_MTD_DOC2001) += doc2001.o ++obj-$(CONFIG_MTD_DOC2001PLUS) += doc2001plus.o + obj-$(CONFIG_MTD_DOCPROBE) += docprobe.o docecc.o + obj-$(CONFIG_MTD_SLRAM) += slram.o ++obj-$(CONFIG_MTD_PHRAM) += phram.o + obj-$(CONFIG_MTD_PMC551) += pmc551.o + obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o + obj-$(CONFIG_MTD_MTDRAM) += mtdram.o + obj-$(CONFIG_MTD_LART) += lart.o + obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o + +-include $(TOPDIR)/Rules.make ++-include $(TOPDIR)/Rules.make +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/blkmtd-25.c linux/drivers/mtd/devices/blkmtd-25.c +--- linux-mips-2.4.27/drivers/mtd/devices/blkmtd-25.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/devices/blkmtd-25.c 2004-11-19 10:25:11.814212712 +0100 +@@ -0,0 +1,827 @@ ++/* ++ * $Id: blkmtd-25.c,v 1.5 2003/07/16 06:48:27 spse Exp $ ++ * ++ * blkmtd.c - use a block device as a fake MTD ++ * ++ * Author: Simon Evans ++ * ++ * Copyright (C) 2001,2002 Simon Evans ++ * ++ * Licence: GPL ++ * ++ * How it works: ++ * The driver uses raw/io to read/write the device and the page ++ * cache to cache access. Writes update the page cache with the ++ * new data and mark it dirty and add the page into a BIO which ++ * is then written out. ++ * ++ * It can be loaded Read-Only to prevent erases and writes to the ++ * medium. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg) ++#define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg) ++#define warn(format, arg...) printk(KERN_WARNING "blkmtd: " format "\n" , ## arg) ++#define crit(format, arg...) printk(KERN_CRIT "blkmtd: " format "\n" , ## arg) ++ ++ ++/* Default erase size in K, always make it a multiple of PAGE_SIZE */ ++#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */ ++#define VERSION "$Revision: 1.5 $" ++ ++/* Info for the block device */ ++struct blkmtd_dev { ++ struct list_head list; ++ struct block_device *blkdev; ++ struct mtd_info mtd_info; ++ struct semaphore wrbuf_mutex; ++}; ++ ++ ++/* Static info about the MTD, used in cleanup_module */ ++static LIST_HEAD(blkmtd_device_list); ++ ++ ++static void blkmtd_sync(struct mtd_info *mtd); ++ ++#define MAX_DEVICES 4 ++ ++/* Module parameters passed by insmod/modprobe */ ++char *device[MAX_DEVICES]; /* the block device to use */ ++int erasesz[MAX_DEVICES]; /* optional default erase size */ ++int ro[MAX_DEVICES]; /* optional read only flag */ ++int sync; ++ ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Simon Evans "); ++MODULE_DESCRIPTION("Emulate an MTD using a block device"); ++MODULE_PARM(device, "1-4s"); ++MODULE_PARM_DESC(device, "block device to use"); ++MODULE_PARM(erasesz, "1-4i"); ++MODULE_PARM_DESC(erasesz, "optional erase size to use in KiB. eg 4=4KiB."); ++MODULE_PARM(ro, "1-4i"); ++MODULE_PARM_DESC(ro, "1=Read only, writes and erases cause errors"); ++MODULE_PARM(sync, "i"); ++MODULE_PARM_DESC(sync, "1=Synchronous writes"); ++ ++ ++/* completion handler for BIO reads */ ++static int bi_read_complete(struct bio *bio, unsigned int bytes_done, int error) ++{ ++ if (bio->bi_size) ++ return 1; ++ ++ complete((struct completion*)bio->bi_private); ++ return 0; ++} ++ ++ ++/* completion handler for BIO writes */ ++static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error) ++{ ++ const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); ++ struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; ++ ++ if (bio->bi_size) ++ return 1; ++ ++ if(!uptodate) ++ err("bi_write_complete: not uptodate\n"); ++ ++ do { ++ struct page *page = bvec->bv_page; ++ DEBUG(3, "Cleaning up page %ld\n", page->index); ++ if (--bvec >= bio->bi_io_vec) ++ prefetchw(&bvec->bv_page->flags); ++ ++ if (uptodate) { ++ SetPageUptodate(page); ++ } else { ++ ClearPageUptodate(page); ++ SetPageError(page); ++ } ++ ClearPageDirty(page); ++ unlock_page(page); ++ page_cache_release(page); ++ } while (bvec >= bio->bi_io_vec); ++ ++ complete((struct completion*)bio->bi_private); ++ return 0; ++} ++ ++ ++/* read one page from the block device */ ++static int blkmtd_readpage(struct blkmtd_dev *dev, struct page *page) ++{ ++ struct bio *bio; ++ struct completion event; ++ int err = -ENOMEM; ++ ++ if(PageUptodate(page)) { ++ DEBUG(2, "blkmtd: readpage page %ld is already upto date\n", page->index); ++ unlock_page(page); ++ return 0; ++ } ++ ++ ClearPageUptodate(page); ++ ClearPageError(page); ++ ++ bio = bio_alloc(GFP_KERNEL, 1); ++ if(bio) { ++ init_completion(&event); ++ bio->bi_bdev = dev->blkdev; ++ bio->bi_sector = page->index << (PAGE_SHIFT-9); ++ bio->bi_private = &event; ++ bio->bi_end_io = bi_read_complete; ++ if(bio_add_page(bio, page, PAGE_SIZE, 0) == PAGE_SIZE) { ++ submit_bio(READ, bio); ++ blk_run_queues(); ++ wait_for_completion(&event); ++ err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO; ++ bio_put(bio); ++ } ++ } ++ ++ if(err) ++ SetPageError(page); ++ else ++ SetPageUptodate(page); ++ flush_dcache_page(page); ++ unlock_page(page); ++ return err; ++} ++ ++ ++/* write out the current BIO and wait for it to finish */ ++static int blkmtd_write_out(struct bio *bio) ++{ ++ struct completion event; ++ int err; ++ ++ if(!bio->bi_vcnt) { ++ bio_put(bio); ++ return 0; ++ } ++ ++ init_completion(&event); ++ bio->bi_private = &event; ++ bio->bi_end_io = bi_write_complete; ++ submit_bio(WRITE, bio); ++ blk_run_queues(); ++ wait_for_completion(&event); ++ DEBUG(3, "submit_bio completed, bi_vcnt = %d\n", bio->bi_vcnt); ++ err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO; ++ bio_put(bio); ++ return err; ++} ++ ++ ++/** ++ * blkmtd_add_page - add a page to the current BIO ++ * @bio: bio to add to (NULL to alloc initial bio) ++ * @blkdev: block device ++ * @page: page to add ++ * @pagecnt: pages left to add ++ * ++ * Adds a page to the current bio, allocating it if necessary. If it cannot be ++ * added, the current bio is written out and a new one is allocated. Returns ++ * the new bio to add or NULL on error ++ */ ++static struct bio *blkmtd_add_page(struct bio *bio, struct block_device *blkdev, ++ struct page *page, int pagecnt) ++{ ++ ++ retry: ++ if(!bio) { ++ bio = bio_alloc(GFP_KERNEL, pagecnt); ++ if(!bio) ++ return NULL; ++ bio->bi_sector = page->index << (PAGE_SHIFT-9); ++ bio->bi_bdev = blkdev; ++ } ++ ++ if(bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) { ++ blkmtd_write_out(bio); ++ bio = NULL; ++ goto retry; ++ } ++ return bio; ++} ++ ++ ++/** ++ * write_pages - write block of data to device via the page cache ++ * @dev: device to write to ++ * @buf: data source or NULL if erase (output is set to 0xff) ++ * @to: offset into output device ++ * @len: amount to data to write ++ * @retlen: amount of data written ++ * ++ * Grab pages from the page cache and fill them with the source data. ++ * Non page aligned start and end result in a readin of the page and ++ * part of the page being modified. Pages are added to the bio and then written ++ * out. ++ */ ++static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to, ++ size_t len, size_t *retlen) ++{ ++ int pagenr, offset; ++ size_t start_len = 0, end_len; ++ int pagecnt = 0; ++ int err = 0; ++ struct bio *bio = NULL; ++ size_t thislen = 0; ++ ++ pagenr = to >> PAGE_SHIFT; ++ offset = to & ~PAGE_MASK; ++ ++ DEBUG(2, "blkmtd: write_pages: buf = %p to = %ld len = %d pagenr = %d offset = %d\n", ++ buf, (long)to, len, pagenr, offset); ++ ++ /* see if we have to do a partial write at the start */ ++ if(offset) { ++ start_len = ((offset + len) > PAGE_SIZE) ? PAGE_SIZE - offset : len; ++ len -= start_len; ++ } ++ ++ /* calculate the length of the other two regions */ ++ end_len = len & ~PAGE_MASK; ++ len -= end_len; ++ ++ if(start_len) ++ pagecnt++; ++ ++ if(len) ++ pagecnt += len >> PAGE_SHIFT; ++ ++ if(end_len) ++ pagecnt++; ++ ++ down(&dev->wrbuf_mutex); ++ ++ DEBUG(3, "blkmtd: write: start_len = %d len = %d end_len = %d pagecnt = %d\n", ++ start_len, len, end_len, pagecnt); ++ ++ if(start_len) { ++ /* do partial start region */ ++ struct page *page; ++ ++ DEBUG(3, "blkmtd: write: doing partial start, page = %d len = %d offset = %d\n", ++ pagenr, start_len, offset); ++ ++ BUG_ON(!buf); ++ page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); ++ lock_page(page); ++ if(PageDirty(page)) { ++ err("to = %lld start_len = %d len = %d end_len = %d pagenr = %d\n", ++ to, start_len, len, end_len, pagenr); ++ BUG(); ++ } ++ memcpy(page_address(page)+offset, buf, start_len); ++ SetPageDirty(page); ++ SetPageUptodate(page); ++ buf += start_len; ++ thislen = start_len; ++ bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); ++ if(!bio) { ++ err = -ENOMEM; ++ err("bio_add_page failed\n"); ++ goto write_err; ++ } ++ pagecnt--; ++ pagenr++; ++ } ++ ++ /* Now do the main loop to a page aligned, n page sized output */ ++ if(len) { ++ int pagesc = len >> PAGE_SHIFT; ++ DEBUG(3, "blkmtd: write: whole pages start = %d, count = %d\n", ++ pagenr, pagesc); ++ while(pagesc) { ++ struct page *page; ++ ++ /* see if page is in the page cache */ ++ DEBUG(3, "blkmtd: write: grabbing page %d from page cache\n", pagenr); ++ page = grab_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr); ++ if(PageDirty(page)) { ++ BUG(); ++ } ++ if(!page) { ++ warn("write: cannot grab cache page %d", pagenr); ++ err = -ENOMEM; ++ goto write_err; ++ } ++ if(!buf) { ++ memset(page_address(page), 0xff, PAGE_SIZE); ++ } else { ++ memcpy(page_address(page), buf, PAGE_SIZE); ++ buf += PAGE_SIZE; ++ } ++ bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); ++ if(!bio) { ++ err = -ENOMEM; ++ err("bio_add_page failed\n"); ++ goto write_err; ++ } ++ pagenr++; ++ pagecnt--; ++ SetPageDirty(page); ++ SetPageUptodate(page); ++ pagesc--; ++ thislen += PAGE_SIZE; ++ } ++ } ++ ++ if(end_len) { ++ /* do the third region */ ++ struct page *page; ++ DEBUG(3, "blkmtd: write: doing partial end, page = %d len = %d\n", ++ pagenr, end_len); ++ BUG_ON(!buf); ++ page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); ++ lock_page(page); ++ if(PageDirty(page)) { ++ err("to = %lld start_len = %d len = %d end_len = %d pagenr = %d\n", ++ to, start_len, len, end_len, pagenr); ++ BUG(); ++ } ++ memcpy(page_address(page), buf, end_len); ++ SetPageDirty(page); ++ SetPageUptodate(page); ++ DEBUG(3, "blkmtd: write: writing out partial end\n"); ++ thislen += end_len; ++ bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt); ++ if(!bio) { ++ err = -ENOMEM; ++ err("bio_add_page failed\n"); ++ goto write_err; ++ } ++ pagenr++; ++ } ++ ++ DEBUG(3, "blkmtd: write: got %d vectors to write\n", bio->bi_vcnt); ++ write_err: ++ if(bio) ++ blkmtd_write_out(bio); ++ ++ DEBUG(2, "blkmtd: write: end, retlen = %d, err = %d\n", *retlen, err); ++ up(&dev->wrbuf_mutex); ++ ++ if(retlen) ++ *retlen = thislen; ++ return err; ++} ++ ++ ++/* erase a specified part of the device */ ++static int blkmtd_erase(struct mtd_info *mtd, struct erase_info *instr) ++{ ++ struct blkmtd_dev *dev = mtd->priv; ++ struct mtd_erase_region_info *einfo = mtd->eraseregions; ++ int numregions = mtd->numeraseregions; ++ size_t from; ++ u_long len; ++ int err = -EIO; ++ int retlen; ++ ++ instr->state = MTD_ERASING; ++ from = instr->addr; ++ len = instr->len; ++ ++ /* check erase region has valid start and length */ ++ DEBUG(2, "blkmtd: erase: dev = `%s' from = 0x%x len = 0x%lx\n", ++ mtd->name+9, from, len); ++ while(numregions) { ++ DEBUG(3, "blkmtd: checking erase region = 0x%08X size = 0x%X num = 0x%x\n", ++ einfo->offset, einfo->erasesize, einfo->numblocks); ++ if(from >= einfo->offset ++ && from < einfo->offset + (einfo->erasesize * einfo->numblocks)) { ++ if(len == einfo->erasesize ++ && ( (from - einfo->offset) % einfo->erasesize == 0)) ++ break; ++ } ++ numregions--; ++ einfo++; ++ } ++ ++ if(!numregions) { ++ /* Not a valid erase block */ ++ err("erase: invalid erase request 0x%lX @ 0x%08X", len, from); ++ instr->state = MTD_ERASE_FAILED; ++ err = -EIO; ++ } ++ ++ if(instr->state != MTD_ERASE_FAILED) { ++ /* do the erase */ ++ DEBUG(3, "Doing erase from = %d len = %ld\n", from, len); ++ err = write_pages(dev, NULL, from, len, &retlen); ++ if(err || retlen != len) { ++ err("erase failed err = %d", err); ++ instr->state = MTD_ERASE_FAILED; ++ } else { ++ instr->state = MTD_ERASE_DONE; ++ } ++ } ++ ++ DEBUG(3, "blkmtd: erase: checking callback\n"); ++ if (instr->callback) { ++ (*(instr->callback))(instr); ++ } ++ DEBUG(2, "blkmtd: erase: finished (err = %d)\n", err); ++ return err; ++} ++ ++ ++/* read a range of the data via the page cache */ ++static int blkmtd_read(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char *buf) ++{ ++ struct blkmtd_dev *dev = mtd->priv; ++ int err = 0; ++ int offset; ++ int pagenr, pages; ++ size_t thislen = 0; ++ ++ DEBUG(2, "blkmtd: read: dev = `%s' from = %ld len = %d buf = %p\n", ++ mtd->name+9, (long int)from, len, buf); ++ ++ if(from > mtd->size) ++ return -EINVAL; ++ if(from + len > mtd->size) ++ len = mtd->size - from; ++ ++ pagenr = from >> PAGE_SHIFT; ++ offset = from - (pagenr << PAGE_SHIFT); ++ ++ pages = (offset+len+PAGE_SIZE-1) >> PAGE_SHIFT; ++ DEBUG(3, "blkmtd: read: pagenr = %d offset = %d, pages = %d\n", ++ pagenr, offset, pages); ++ ++ while(pages) { ++ struct page *page; ++ int cpylen; ++ ++ DEBUG(3, "blkmtd: read: looking for page: %d\n", pagenr); ++ page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev); ++ if(IS_ERR(page)) { ++ err = -EIO; ++ goto readerr; ++ } ++ ++ cpylen = (PAGE_SIZE > len) ? len : PAGE_SIZE; ++ if(offset+cpylen > PAGE_SIZE) ++ cpylen = PAGE_SIZE-offset; ++ ++ memcpy(buf + thislen, page_address(page) + offset, cpylen); ++ offset = 0; ++ len -= cpylen; ++ thislen += cpylen; ++ pagenr++; ++ pages--; ++ if(!PageDirty(page)) ++ page_cache_release(page); ++ } ++ ++ readerr: ++ if(retlen) ++ *retlen = thislen; ++ DEBUG(2, "blkmtd: end read: retlen = %d, err = %d\n", thislen, err); ++ return err; ++} ++ ++ ++/* write data to the underlying device */ ++static int blkmtd_write(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf) ++{ ++ struct blkmtd_dev *dev = mtd->priv; ++ int err; ++ ++ if(!len) ++ return 0; ++ ++ DEBUG(2, "blkmtd: write: dev = `%s' to = %ld len = %d buf = %p\n", ++ mtd->name+9, (long int)to, len, buf); ++ ++ if(to >= mtd->size) { ++ return -ENOSPC; ++ } ++ ++ if(to + len > mtd->size) { ++ len = mtd->size - to; ++ } ++ ++ err = write_pages(dev, buf, to, len, retlen); ++ if(err > 0) ++ err = 0; ++ DEBUG(2, "blkmtd: write: end, err = %d\n", err); ++ return err; ++} ++ ++ ++/* sync the device - wait until the write queue is empty */ ++static void blkmtd_sync(struct mtd_info *mtd) ++{ ++ /* Currently all writes are synchronous */ ++} ++ ++ ++static void free_device(struct blkmtd_dev *dev) ++{ ++ DEBUG(2, "blkmtd: free_device() dev = %p\n", dev); ++ if(dev) { ++ if(dev->mtd_info.eraseregions) ++ kfree(dev->mtd_info.eraseregions); ++ if(dev->mtd_info.name) ++ kfree(dev->mtd_info.name); ++ ++ if(dev->blkdev) { ++ invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping); ++ close_bdev_excl(dev->blkdev, BDEV_RAW); ++ } ++ kfree(dev); ++ } ++} ++ ++ ++/* For a given size and initial erase size, calculate the number ++ * and size of each erase region. Goes round the loop twice, ++ * once to find out how many regions, then allocates space, ++ * then round the loop again to fill it in. ++ */ ++static struct mtd_erase_region_info *calc_erase_regions( ++ size_t erase_size, size_t total_size, int *regions) ++{ ++ struct mtd_erase_region_info *info = NULL; ++ ++ DEBUG(2, "calc_erase_regions, es = %d size = %d regions = %d\n", ++ erase_size, total_size, *regions); ++ /* Make any user specified erasesize be a power of 2 ++ and at least PAGE_SIZE */ ++ if(erase_size) { ++ int es = erase_size; ++ erase_size = 1; ++ while(es != 1) { ++ es >>= 1; ++ erase_size <<= 1; ++ } ++ if(erase_size < PAGE_SIZE) ++ erase_size = PAGE_SIZE; ++ } else { ++ erase_size = CONFIG_MTD_BLKDEV_ERASESIZE; ++ } ++ ++ *regions = 0; ++ ++ do { ++ int tot_size = total_size; ++ int er_size = erase_size; ++ int count = 0, offset = 0, regcnt = 0; ++ ++ while(tot_size) { ++ count = tot_size / er_size; ++ if(count) { ++ tot_size = tot_size % er_size; ++ if(info) { ++ DEBUG(2, "adding to erase info off=%d er=%d cnt=%d\n", ++ offset, er_size, count); ++ (info+regcnt)->offset = offset; ++ (info+regcnt)->erasesize = er_size; ++ (info+regcnt)->numblocks = count; ++ (*regions)++; ++ } ++ regcnt++; ++ offset += (count * er_size); ++ } ++ while(er_size > tot_size) ++ er_size >>= 1; ++ } ++ if(info == NULL) { ++ info = kmalloc(regcnt * sizeof(struct mtd_erase_region_info), GFP_KERNEL); ++ if(!info) ++ break; ++ } ++ } while(!(*regions)); ++ DEBUG(2, "calc_erase_regions done, es = %d size = %d regions = %d\n", ++ erase_size, total_size, *regions); ++ return info; ++} ++ ++ ++extern dev_t __init name_to_dev_t(const char *line); ++ ++static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size) ++{ ++ struct block_device *bdev; ++ int mode; ++ struct blkmtd_dev *dev; ++ ++ if(!devname) ++ return NULL; ++ ++ /* Get a handle on the device */ ++ ++ ++#ifdef MODULE ++ mode = (readonly) ? O_RDONLY : O_RDWR; ++ bdev = open_bdev_excl(devname, mode, BDEV_RAW, NULL); ++#else ++ mode = (readonly) ? FMODE_READ : FMODE_WRITE; ++ bdev = open_by_devnum(name_to_dev_t(devname), mode, BDEV_RAW); ++#endif ++ if(IS_ERR(bdev)) { ++ err("error: cannot open device %s", devname); ++ DEBUG(2, "blkmtd: opening bdev returned %ld\n", PTR_ERR(bdev)); ++ return NULL; ++ } ++ ++ DEBUG(1, "blkmtd: found a block device major = %d, minor = %d\n", ++ MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); ++ ++ if(MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { ++ err("attempting to use an MTD device as a block device"); ++ blkdev_put(bdev, BDEV_RAW); ++ return NULL; ++ } ++ ++ dev = kmalloc(sizeof(struct blkmtd_dev), GFP_KERNEL); ++ if(dev == NULL) { ++ blkdev_put(bdev, BDEV_RAW); ++ return NULL; ++ } ++ ++ memset(dev, 0, sizeof(struct blkmtd_dev)); ++ if(!readonly) { ++ init_MUTEX(&dev->wrbuf_mutex); ++ } ++ ++ dev->blkdev = bdev; ++ dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; ++ ++ /* Setup the MTD structure */ ++ /* make the name contain the block device in */ ++ dev->mtd_info.name = kmalloc(sizeof("blkmtd: ") + strlen(devname), GFP_KERNEL); ++ if(dev->mtd_info.name == NULL) ++ goto devinit_err; ++ ++ sprintf(dev->mtd_info.name, "blkmtd: %s", devname); ++ dev->mtd_info.eraseregions = calc_erase_regions(erase_size, dev->mtd_info.size, ++ &dev->mtd_info.numeraseregions); ++ if(dev->mtd_info.eraseregions == NULL) ++ goto devinit_err; ++ ++ dev->mtd_info.erasesize = dev->mtd_info.eraseregions->erasesize; ++ DEBUG(1, "blkmtd: init: found %d erase regions\n", ++ dev->mtd_info.numeraseregions); ++ ++ if(readonly) { ++ dev->mtd_info.type = MTD_ROM; ++ dev->mtd_info.flags = MTD_CAP_ROM; ++ } else { ++ dev->mtd_info.type = MTD_RAM; ++ dev->mtd_info.flags = MTD_CAP_RAM; ++ dev->mtd_info.erase = blkmtd_erase; ++ dev->mtd_info.write = blkmtd_write; ++ dev->mtd_info.writev = default_mtd_writev; ++ dev->mtd_info.sync = blkmtd_sync; ++ } ++ dev->mtd_info.read = blkmtd_read; ++ dev->mtd_info.readv = default_mtd_readv; ++ dev->mtd_info.priv = dev; ++ dev->mtd_info.owner = THIS_MODULE; ++ ++ list_add(&dev->list, &blkmtd_device_list); ++ if (add_mtd_device(&dev->mtd_info)) { ++ /* Device didnt get added, so free the entry */ ++ list_del(&dev->list); ++ goto devinit_err; ++ } else { ++ info("mtd%d: [%s] erase_size = %dKiB %s", ++ dev->mtd_info.index, dev->mtd_info.name + strlen("blkmtd: "), ++ dev->mtd_info.erasesize >> 10, ++ readonly ? "(read-only)" : ""); ++ } ++ ++ return dev; ++ ++ devinit_err: ++ free_device(dev); ++ return NULL; ++} ++ ++ ++/* Cleanup and exit - sync the device and kill of the kernel thread */ ++static void __devexit cleanup_blkmtd(void) ++{ ++ struct list_head *temp1, *temp2; ++ ++ /* Remove the MTD devices */ ++ list_for_each_safe(temp1, temp2, &blkmtd_device_list) { ++ struct blkmtd_dev *dev = list_entry(temp1, struct blkmtd_dev, ++ list); ++ blkmtd_sync(&dev->mtd_info); ++ del_mtd_device(&dev->mtd_info); ++ info("mtd%d: [%s] removed", dev->mtd_info.index, ++ dev->mtd_info.name + strlen("blkmtd: ")); ++ list_del(&dev->list); ++ free_device(dev); ++ } ++} ++ ++#ifndef MODULE ++ ++/* Handle kernel boot params */ ++ ++ ++static int __init param_blkmtd_device(char *str) ++{ ++ int i; ++ ++ for(i = 0; i < MAX_DEVICES; i++) { ++ device[i] = str; ++ DEBUG(2, "blkmtd: device setup: %d = %s\n", i, device[i]); ++ strsep(&str, ","); ++ } ++ return 1; ++} ++ ++ ++static int __init param_blkmtd_erasesz(char *str) ++{ ++ int i; ++ for(i = 0; i < MAX_DEVICES; i++) { ++ char *val = strsep(&str, ","); ++ if(val) ++ erasesz[i] = simple_strtoul(val, NULL, 0); ++ DEBUG(2, "blkmtd: erasesz setup: %d = %d\n", i, erasesz[i]); ++ } ++ ++ return 1; ++} ++ ++ ++static int __init param_blkmtd_ro(char *str) ++{ ++ int i; ++ for(i = 0; i < MAX_DEVICES; i++) { ++ char *val = strsep(&str, ","); ++ if(val) ++ ro[i] = simple_strtoul(val, NULL, 0); ++ DEBUG(2, "blkmtd: ro setup: %d = %d\n", i, ro[i]); ++ } ++ ++ return 1; ++} ++ ++ ++static int __init param_blkmtd_sync(char *str) ++{ ++ if(str[0] == '1') ++ sync = 1; ++ return 1; ++} ++ ++__setup("blkmtd_device=", param_blkmtd_device); ++__setup("blkmtd_erasesz=", param_blkmtd_erasesz); ++__setup("blkmtd_ro=", param_blkmtd_ro); ++__setup("blkmtd_sync=", param_blkmtd_sync); ++ ++#endif ++ ++ ++/* Startup */ ++static int __init init_blkmtd(void) ++{ ++ int i; ++ ++ info("version " VERSION); ++ /* Check args - device[0] is the bare minimum*/ ++ if(!device[0]) { ++ err("error: missing `device' name\n"); ++ return -EINVAL; ++ } ++ ++ for(i = 0; i < MAX_DEVICES; i++) ++ add_device(device[i], ro[i], erasesz[i] << 10); ++ ++ if(list_empty(&blkmtd_device_list)) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++module_init(init_blkmtd); ++module_exit(cleanup_blkmtd); +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/blkmtd.c linux/drivers/mtd/devices/blkmtd.c +--- linux-mips-2.4.27/drivers/mtd/devices/blkmtd.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/devices/blkmtd.c 2004-11-19 10:25:11.816212408 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: blkmtd.c,v 1.17 2003/01/24 13:00:24 dwmw2 Exp $ ++ * $Id: blkmtd.c,v 1.20 2003/06/27 15:10:35 dwmw2 Exp $ + * + * blkmtd.c - use a block device as a fake MTD + * +@@ -143,7 +143,7 @@ + for(cnt = 0; cnt < pages; cnt++) { + page = grab_cache_page(dev->binding->bd_inode->i_mapping, pagenrs[cnt]); + pagelst[cnt] = page; +- if(!PageUptodate(page)) { ++ if(!Page_Uptodate(page)) { + iobuf->blocks[iobuf->nr_pages] = pagenrs[cnt]; + iobuf->maplist[iobuf->nr_pages++] = page; + } +@@ -912,7 +912,7 @@ + dev->mtd_info.point = 0; + dev->mtd_info.unpoint = 0; + dev->mtd_info.priv = dev; +- dev->mtd_info.module = THIS_MODULE; ++ dev->mtd_info.owner = THIS_MODULE; + + list_add(&dev->list, &blkmtd_device_list); + if (add_mtd_device(&dev->mtd_info)) { +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/doc2000.c linux/drivers/mtd/devices/doc2000.c +--- linux-mips-2.4.27/drivers/mtd/devices/doc2000.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/devices/doc2000.c 2004-11-19 10:25:11.818212104 +0100 +@@ -4,7 +4,7 @@ + * (c) 1999 Machine Vision Holdings, Inc. + * (c) 1999, 2000 David Woodhouse + * +- * $Id: doc2000.c,v 1.50 2002/12/10 15:05:42 gleixner Exp $ ++ * $Id: doc2000.c,v 1.58 2003/11/05 16:42:25 dwmw2 Exp $ + */ + + #include +@@ -25,6 +25,7 @@ + #include + + #define DOC_SUPPORT_2000 ++#define DOC_SUPPORT_2000TSOP + #define DOC_SUPPORT_MILLENNIUM + + #ifdef DOC_SUPPORT_2000 +@@ -33,7 +34,7 @@ + #define DoC_is_2000(doc) (0) + #endif + +-#ifdef DOC_SUPPORT_MILLENNIUM ++#if defined(DOC_SUPPORT_2000TSOP) || defined(DOC_SUPPORT_MILLENNIUM) + #define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil) + #else + #define DoC_is_Millennium(doc) (0) +@@ -56,6 +57,9 @@ + size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel); + static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel); ++static int doc_writev_ecc(struct mtd_info *mtd, const struct iovec *vecs, ++ unsigned long count, loff_t to, size_t *retlen, ++ u_char *eccbuf, struct nand_oobinfo *oobsel); + static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, + size_t *retlen, u_char *buf); + static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, +@@ -92,6 +96,10 @@ + + /* Out-of-line routine to wait for chip response */ + while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) { ++ /* issue 2 read from NOP register after reading from CDSNControl register ++ see Software Requirement 11.4 item 2. */ ++ DoC_Delay(doc, 2); ++ + if (time_after(jiffies, timeo)) { + DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n"); + return -EIO; +@@ -145,6 +153,8 @@ + + /* Send the command */ + WriteDOC_(command, docptr, doc->ioreg); ++ if (DoC_is_Millennium(doc)) ++ WriteDOC(command, docptr, WritePipeTerm); + + /* Lower the CLE line */ + WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl); +@@ -206,6 +216,9 @@ + } + } + ++ if (DoC_is_Millennium(doc)) ++ WriteDOC(ofs & 0xff, docptr, WritePipeTerm); ++ + DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */ + + /* FIXME: The SlowIO's for millennium could be replaced by +@@ -344,15 +357,25 @@ + + /* Read the manufacturer and device id codes from the device */ + +- /* CDSN Slow IO register see Software Requirement 11.4 item 5. */ ++ if (DoC_is_Millennium(doc)) { ++ DoC_Delay(doc, 2); ++ dummy = ReadDOC(doc->virtadr, ReadPipeInit); ++ mfr = ReadDOC(doc->virtadr, LastDataRead); ++ ++ DoC_Delay(doc, 2); ++ dummy = ReadDOC(doc->virtadr, ReadPipeInit); ++ id = ReadDOC(doc->virtadr, LastDataRead); ++ } else { ++ /* CDSN Slow IO register see Software Req 11.4 item 5. */ + dummy = ReadDOC(doc->virtadr, CDSNSlowIO); + DoC_Delay(doc, 2); + mfr = ReadDOC_(doc->virtadr, doc->ioreg); + +- /* CDSN Slow IO register see Software Requirement 11.4 item 5. */ ++ /* CDSN Slow IO register see Software Req 11.4 item 5. */ + dummy = ReadDOC(doc->virtadr, CDSNSlowIO); + DoC_Delay(doc, 2); + id = ReadDOC_(doc->virtadr, doc->ioreg); ++ } + + /* No response - return failure */ + if (mfr == 0xff || mfr == 0) +@@ -410,20 +433,16 @@ + + /* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */ + +-static void DoC_ScanChips(struct DiskOnChip *this) ++static void DoC_ScanChips(struct DiskOnChip *this, int maxchips) + { + int floor, chip; + int numchips[MAX_FLOORS]; +- int maxchips = MAX_CHIPS; + int ret = 1; + + this->numchips = 0; + this->mfr = 0; + this->id = 0; + +- if (DoC_is_Millennium(this)) +- maxchips = MAX_CHIPS_MIL; +- + /* For each floor, find the number of valid chips it contains */ + for (floor = 0; floor < MAX_FLOORS; floor++) { + ret = 1; +@@ -515,6 +534,7 @@ + { + struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv; + struct DiskOnChip *old = NULL; ++ int maxchips; + + /* We must avoid being called twice for the same device. */ + +@@ -538,14 +558,28 @@ + + + switch (this->ChipID) { ++ case DOC_ChipID_Doc2kTSOP: ++ mtd->name = "DiskOnChip 2000 TSOP"; ++ this->ioreg = DoC_Mil_CDSN_IO; ++ /* Pretend it's a Millennium */ ++ this->ChipID = DOC_ChipID_DocMil; ++ maxchips = MAX_CHIPS; ++ break; + case DOC_ChipID_Doc2k: + mtd->name = "DiskOnChip 2000"; + this->ioreg = DoC_2k_CDSN_IO; ++ maxchips = MAX_CHIPS; + break; + case DOC_ChipID_DocMil: + mtd->name = "DiskOnChip Millennium"; + this->ioreg = DoC_Mil_CDSN_IO; ++ maxchips = MAX_CHIPS_MIL; + break; ++ default: ++ printk("Unknown ChipID 0x%02x\n", this->ChipID); ++ kfree(mtd); ++ iounmap((void *) this->virtadr); ++ return; + } + + printk(KERN_NOTICE "%s found at address 0x%lX\n", mtd->name, +@@ -553,11 +587,12 @@ + + mtd->type = MTD_NANDFLASH; + mtd->flags = MTD_CAP_NANDFLASH; ++ mtd->ecctype = MTD_ECC_RS_DiskOnChip; + mtd->size = 0; + mtd->erasesize = 0; + mtd->oobblock = 512; + mtd->oobsize = 16; +- mtd->module = THIS_MODULE; ++ mtd->owner = THIS_MODULE; + mtd->erase = doc_erase; + mtd->point = NULL; + mtd->unpoint = NULL; +@@ -565,6 +600,7 @@ + mtd->write = doc_write; + mtd->read_ecc = doc_read_ecc; + mtd->write_ecc = doc_write_ecc; ++ mtd->writev_ecc = doc_writev_ecc; + mtd->read_oob = doc_read_oob; + mtd->write_oob = doc_write_oob; + mtd->sync = NULL; +@@ -577,7 +613,7 @@ + init_MUTEX(&this->lock); + + /* Ident all the chips present. */ +- DoC_ScanChips(this); ++ DoC_ScanChips(this, maxchips); + + if (!this->totlen) { + kfree(mtd); +@@ -608,6 +644,7 @@ + unsigned char syndrome[6]; + volatile char dummy; + int i, len256 = 0, ret=0; ++ size_t left = len; + + docptr = this->virtadr; + +@@ -617,6 +654,10 @@ + + down(&this->lock); + ++ *retlen = 0; ++ while (left) { ++ len = left; ++ + /* Don't allow a single read to cross a 512-byte block boundary */ + if (from + len > ((from | 0x1ff) + 1)) + len = ((from | 0x1ff) + 1) - from; +@@ -673,7 +714,7 @@ + DoC_ReadBuf(this, &buf[len256], len - len256); + + /* Let the caller know we completed it */ +- *retlen = len; ++ *retlen += len; + + if (eccbuf) { + /* Read the ECC data through the DiskOnChip ECC logic */ +@@ -730,11 +771,16 @@ + + /* according to 11.4.1, we need to wait for the busy line + * drop if we read to the end of the page. */ +- if(0 == ((from + *retlen) & 0x1ff)) ++ if(0 == ((from + len) & 0x1ff)) + { + DoC_WaitReady(this); + } + ++ from += len; ++ left -= len; ++ buf += len; ++ } ++ + up(&this->lock); + + return ret; +@@ -757,6 +803,8 @@ + volatile char dummy; + int len256 = 0; + struct Nand *mychip; ++ size_t left = len; ++ int status; + + docptr = this->virtadr; + +@@ -766,15 +814,21 @@ + + down(&this->lock); + ++ *retlen = 0; ++ while (left) { ++ len = left; ++ + /* Don't allow a single write to cross a 512-byte block boundary */ + if (to + len > ((to | 0x1ff) + 1)) + len = ((to | 0x1ff) + 1) - to; + + /* The ECC will not be calculated correctly if less than 512 is written */ ++/* DBB- + if (len != 0x200 && eccbuf) + printk(KERN_WARNING + "ECC needs a full sector write (adr: %lx size %lx)\n", + (long) to, (long) len); ++ -DBB */ + + /* printk("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */ + +@@ -853,6 +907,9 @@ + WriteDOC_(0, docptr, this->ioreg); + } + ++ WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr, ++ CDSNControl); ++ + /* Read the ECC data through the DiskOnChip ECC logic */ + for (di = 0; di < 6; di++) { + eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di); +@@ -874,10 +931,16 @@ + DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP); + /* There's an implicit DoC_WaitReady() in DoC_Command */ + ++ if (DoC_is_Millennium(this)) { ++ ReadDOC(docptr, ReadPipeInit); ++ status = ReadDOC(docptr, LastDataRead); ++ } else { + dummy = ReadDOC(docptr, CDSNSlowIO); + DoC_Delay(this, 2); ++ status = ReadDOC_(docptr, this->ioreg); ++ } + +- if (ReadDOC_(docptr, this->ioreg) & 1) { ++ if (status & 1) { + printk(KERN_ERR "Error programming flash\n"); + /* Error in programming */ + *retlen = 0; +@@ -886,7 +949,7 @@ + } + + /* Let the caller know we completed it */ +- *retlen = len; ++ *retlen += len; + + if (eccbuf) { + unsigned char x[8]; +@@ -901,13 +964,81 @@ + x[7]=0x55; + + ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x); ++ if (ret) { + up(&this->lock); + return ret; + } ++ } ++ ++ to += len; ++ left -= len; ++ buf += len; ++ } ++ + up(&this->lock); + return 0; + } + ++static int doc_writev_ecc(struct mtd_info *mtd, const struct iovec *vecs, ++ unsigned long count, loff_t to, size_t *retlen, ++ u_char *eccbuf, struct nand_oobinfo *oobsel) ++{ ++ static char static_buf[512]; ++ static DECLARE_MUTEX(writev_buf_sem); ++ ++ size_t totretlen = 0; ++ size_t thisvecofs = 0; ++ int ret= 0; ++ ++ down(&writev_buf_sem); ++ ++ while(count) { ++ size_t thislen, thisretlen; ++ unsigned char *buf; ++ ++ buf = vecs->iov_base + thisvecofs; ++ thislen = vecs->iov_len - thisvecofs; ++ ++ ++ if (thislen >= 512) { ++ thislen = thislen & ~(512-1); ++ thisvecofs += thislen; ++ } else { ++ /* Not enough to fill a page. Copy into buf */ ++ memcpy(static_buf, buf, thislen); ++ buf = &static_buf[thislen]; ++ ++ while(count && thislen < 512) { ++ vecs++; ++ count--; ++ thisvecofs = min((512-thislen), vecs->iov_len); ++ memcpy(buf, vecs->iov_base, thisvecofs); ++ thislen += thisvecofs; ++ buf += thisvecofs; ++ } ++ buf = static_buf; ++ } ++ if (count && thisvecofs == vecs->iov_len) { ++ thisvecofs = 0; ++ vecs++; ++ count--; ++ } ++ ret = doc_write_ecc(mtd, to, thislen, &thisretlen, buf, eccbuf, oobsel); ++ ++ totretlen += thisretlen; ++ ++ if (ret || thisretlen != thislen) ++ break; ++ ++ to += thislen; ++ } ++ ++ up(&writev_buf_sem); ++ *retlen = totretlen; ++ return ret; ++} ++ ++ + static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, + size_t * retlen, u_char * buf) + { +@@ -977,6 +1108,7 @@ + unsigned long docptr = this->virtadr; + struct Nand *mychip = &this->chips[ofs >> this->chipshift]; + volatile int dummy; ++ int status; + + // printk("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",(long)ofs, len, + // buf[0], buf[1], buf[2], buf[3], buf[8], buf[9], buf[14],buf[15]); +@@ -1025,10 +1157,16 @@ + DoC_Command(this, NAND_CMD_STATUS, 0); + /* DoC_WaitReady() is implicit in DoC_Command */ + ++ if (DoC_is_Millennium(this)) { ++ ReadDOC(docptr, ReadPipeInit); ++ status = ReadDOC(docptr, LastDataRead); ++ } else { + dummy = ReadDOC(docptr, CDSNSlowIO); + DoC_Delay(this, 2); ++ status = ReadDOC_(docptr, this->ioreg); ++ } + +- if (ReadDOC_(docptr, this->ioreg) & 1) { ++ if (status & 1) { + printk(KERN_ERR "Error programming oob data\n"); + /* There was an error */ + *retlen = 0; +@@ -1044,10 +1182,16 @@ + DoC_Command(this, NAND_CMD_STATUS, 0); + /* DoC_WaitReady() is implicit in DoC_Command */ + ++ if (DoC_is_Millennium(this)) { ++ ReadDOC(docptr, ReadPipeInit); ++ status = ReadDOC(docptr, LastDataRead); ++ } else { + dummy = ReadDOC(docptr, CDSNSlowIO); + DoC_Delay(this, 2); ++ status = ReadDOC_(docptr, this->ioreg); ++ } + +- if (ReadDOC_(docptr, this->ioreg) & 1) { ++ if (status & 1) { + printk(KERN_ERR "Error programming oob data\n"); + /* There was an error */ + *retlen = 0; +@@ -1080,6 +1224,7 @@ + volatile int dummy; + unsigned long docptr; + struct Nand *mychip; ++ int status; + + down(&this->lock); + +@@ -1111,10 +1256,16 @@ + + DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP); + ++ if (DoC_is_Millennium(this)) { ++ ReadDOC(docptr, ReadPipeInit); ++ status = ReadDOC(docptr, LastDataRead); ++ } else { + dummy = ReadDOC(docptr, CDSNSlowIO); + DoC_Delay(this, 2); ++ status = ReadDOC_(docptr, this->ioreg); ++ } + +- if (ReadDOC_(docptr, this->ioreg) & 1) { ++ if (status & 1) { + printk(KERN_ERR "Error erasing at 0x%x\n", ofs); + /* There was an error */ + instr->state = MTD_ERASE_FAILED; +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/doc2001.c linux/drivers/mtd/devices/doc2001.c +--- linux-mips-2.4.27/drivers/mtd/devices/doc2001.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/devices/doc2001.c 2004-11-19 10:25:11.835209520 +0100 +@@ -4,7 +4,7 @@ + * (c) 1999 Machine Vision Holdings, Inc. + * (c) 1999, 2000 David Woodhouse + * +- * $Id: doc2001.c,v 1.38 2002/12/10 15:05:42 gleixner Exp $ ++ * $Id: doc2001.c,v 1.41 2003/06/11 09:45:19 dwmw2 Exp $ + */ + + #include +@@ -359,14 +359,15 @@ + + mtd->type = MTD_NANDFLASH; + mtd->flags = MTD_CAP_NANDFLASH; ++ mtd->ecctype = MTD_ECC_RS_DiskOnChip; + mtd->size = 0; + +- /* FIXME: erase size is not always 8kB */ ++ /* FIXME: erase size is not always 8KiB */ + mtd->erasesize = 0x2000; + + mtd->oobblock = 512; + mtd->oobsize = 16; +- mtd->module = THIS_MODULE; ++ mtd->owner = THIS_MODULE; + mtd->erase = doc_erase; + mtd->point = NULL; + mtd->unpoint = NULL; +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/doc2001plus.c linux/drivers/mtd/devices/doc2001plus.c +--- linux-mips-2.4.27/drivers/mtd/devices/doc2001plus.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/devices/doc2001plus.c 2004-11-19 10:25:11.837209216 +0100 +@@ -0,0 +1,1154 @@ ++/* ++ * Linux driver for Disk-On-Chip Millennium Plus ++ * ++ * (c) 2002-2003 Greg Ungerer ++ * (c) 2002-2003 SnapGear Inc ++ * (c) 1999 Machine Vision Holdings, Inc. ++ * (c) 1999, 2000 David Woodhouse ++ * ++ * $Id: doc2001plus.c,v 1.7 2003/07/11 07:36:22 dwmw2 Exp $ ++ * ++ * Released under GPL ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* #define ECC_DEBUG */ ++ ++/* I have no idea why some DoC chips can not use memcop_form|to_io(). ++ * This may be due to the different revisions of the ASIC controller built-in or ++ * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment ++ * this:*/ ++#undef USE_MEMCPY ++ ++static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char *buf); ++static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf); ++static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char *buf, u_char *eccbuf, ++ struct nand_oobinfo *oobsel); ++static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf, u_char *eccbuf, ++ struct nand_oobinfo *oobsel); ++static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ++ size_t *retlen, u_char *buf); ++static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ++ size_t *retlen, const u_char *buf); ++static int doc_erase (struct mtd_info *mtd, struct erase_info *instr); ++ ++static struct mtd_info *docmilpluslist = NULL; ++ ++ ++/* Perform the required delay cycles by writing to the NOP register */ ++static void DoC_Delay(unsigned long docptr, int cycles) ++{ ++ int i; ++ ++ for (i = 0; (i < cycles); i++) ++ WriteDOC(0, docptr, Mplus_NOP); ++} ++ ++#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1) ++ ++/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ ++static int _DoC_WaitReady(unsigned long docptr) ++{ ++ unsigned int c = 0xffff; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, ++ "_DoC_WaitReady called for out-of-line wait\n"); ++ ++ /* Out-of-line routine to wait for chip response */ ++ while (((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) && --c) ++ ; ++ ++ if (c == 0) ++ DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n"); ++ ++ return (c == 0); ++} ++ ++static inline int DoC_WaitReady(unsigned long docptr) ++{ ++ /* This is inline, to optimise the common case, where it's ready instantly */ ++ int ret = 0; ++ ++ /* read form NOP register should be issued prior to the read from CDSNControl ++ see Software Requirement 11.4 item 2. */ ++ DoC_Delay(docptr, 4); ++ ++ if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) ++ /* Call the out-of-line routine to wait */ ++ ret = _DoC_WaitReady(docptr); ++ ++ return ret; ++} ++ ++/* For some reason the Millennium Plus seems to occassionally put itself ++ * into reset mode. For me this happens randomly, with no pattern that I ++ * can detect. M-systems suggest always check this on any block level ++ * operation and setting to normal mode if in reset mode. ++ */ ++static inline void DoC_CheckASIC(unsigned long docptr) ++{ ++ /* Make sure the DoC is in normal mode */ ++ if ((ReadDOC(docptr, Mplus_DOCControl) & DOC_MODE_NORMAL) == 0) { ++ WriteDOC((DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_DOCControl); ++ WriteDOC(~(DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_CtrlConfirm); ++ } ++} ++ ++/* DoC_Command: Send a flash command to the flash chip through the Flash ++ * command register. Need 2 Write Pipeline Terminates to complete send. ++ */ ++static inline void DoC_Command(unsigned long docptr, unsigned char command, ++ unsigned char xtraflags) ++{ ++ WriteDOC(command, docptr, Mplus_FlashCmd); ++ WriteDOC(command, docptr, Mplus_WritePipeTerm); ++ WriteDOC(command, docptr, Mplus_WritePipeTerm); ++} ++ ++/* DoC_Address: Set the current address for the flash chip through the Flash ++ * Address register. Need 2 Write Pipeline Terminates to complete send. ++ */ ++static inline void DoC_Address(struct DiskOnChip *doc, int numbytes, ++ unsigned long ofs, unsigned char xtraflags1, ++ unsigned char xtraflags2) ++{ ++ unsigned long docptr = doc->virtadr; ++ ++ /* Allow for possible Mill Plus internal flash interleaving */ ++ ofs >>= doc->interleave; ++ ++ switch (numbytes) { ++ case 1: ++ /* Send single byte, bits 0-7. */ ++ WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress); ++ break; ++ case 2: ++ /* Send bits 9-16 followed by 17-23 */ ++ WriteDOC((ofs >> 9) & 0xff, docptr, Mplus_FlashAddress); ++ WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress); ++ break; ++ case 3: ++ /* Send 0-7, 9-16, then 17-23 */ ++ WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress); ++ WriteDOC((ofs >> 9) & 0xff, docptr, Mplus_FlashAddress); ++ WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress); ++ break; ++ default: ++ return; ++ } ++ ++ WriteDOC(0x00, docptr, Mplus_WritePipeTerm); ++ WriteDOC(0x00, docptr, Mplus_WritePipeTerm); ++} ++ ++/* DoC_SelectChip: Select a given flash chip within the current floor */ ++static int DoC_SelectChip(unsigned long docptr, int chip) ++{ ++ /* No choice for flash chip on Millennium Plus */ ++ return 0; ++} ++ ++/* DoC_SelectFloor: Select a given floor (bank of flash chips) */ ++static int DoC_SelectFloor(unsigned long docptr, int floor) ++{ ++ WriteDOC((floor & 0x3), docptr, Mplus_DeviceSelect); ++ return 0; ++} ++ ++/* ++ * Translate the given offset into the appropriate command and offset. ++ * This does the mapping using the 16bit interleave layout defined by ++ * M-Systems, and looks like this for a sector pair: ++ * +-----------+-------+-------+-------+--------------+---------+-----------+ ++ * | 0 --- 511 |512-517|518-519|520-521| 522 --- 1033 |1034-1039|1040 - 1055| ++ * +-----------+-------+-------+-------+--------------+---------+-----------+ ++ * | Data 0 | ECC 0 |Flags0 |Flags1 | Data 1 |ECC 1 | OOB 1 + 2 | ++ * +-----------+-------+-------+-------+--------------+---------+-----------+ ++ */ ++/* FIXME: This lives in INFTL not here. Other users of flash devices ++ may not want it */ ++static unsigned int DoC_GetDataOffset(struct mtd_info *mtd, loff_t *from) ++{ ++ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; ++ ++ if (this->interleave) { ++ unsigned int ofs = *from & 0x3ff; ++ unsigned int cmd; ++ ++ if (ofs < 512) { ++ cmd = NAND_CMD_READ0; ++ ofs &= 0x1ff; ++ } else if (ofs < 1014) { ++ cmd = NAND_CMD_READ1; ++ ofs = (ofs & 0x1ff) + 10; ++ } else { ++ cmd = NAND_CMD_READOOB; ++ ofs = ofs - 1014; ++ } ++ ++ *from = (*from & ~0x3ff) | ofs; ++ return cmd; ++ } else { ++ /* No interleave */ ++ if ((*from) & 0x100) ++ return NAND_CMD_READ1; ++ return NAND_CMD_READ0; ++ } ++} ++ ++static unsigned int DoC_GetECCOffset(struct mtd_info *mtd, loff_t *from) ++{ ++ unsigned int ofs, cmd; ++ ++ if (*from & 0x200) { ++ cmd = NAND_CMD_READOOB; ++ ofs = 10 + (*from & 0xf); ++ } else { ++ cmd = NAND_CMD_READ1; ++ ofs = (*from & 0xf); ++ } ++ ++ *from = (*from & ~0x3ff) | ofs; ++ return cmd; ++} ++ ++static unsigned int DoC_GetFlagsOffset(struct mtd_info *mtd, loff_t *from) ++{ ++ unsigned int ofs, cmd; ++ ++ cmd = NAND_CMD_READ1; ++ ofs = (*from & 0x200) ? 8 : 6; ++ *from = (*from & ~0x3ff) | ofs; ++ return cmd; ++} ++ ++static unsigned int DoC_GetHdrOffset(struct mtd_info *mtd, loff_t *from) ++{ ++ unsigned int ofs, cmd; ++ ++ cmd = NAND_CMD_READOOB; ++ ofs = (*from & 0x200) ? 24 : 16; ++ *from = (*from & ~0x3ff) | ofs; ++ return cmd; ++} ++ ++static inline void MemReadDOC(unsigned long docptr, unsigned char *buf, int len) ++{ ++#ifndef USE_MEMCPY ++ int i; ++ for (i = 0; i < len; i++) ++ buf[i] = ReadDOC(docptr, Mil_CDSN_IO + i); ++#else ++ memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len); ++#endif ++} ++ ++static inline void MemWriteDOC(unsigned long docptr, unsigned char *buf, int len) ++{ ++#ifndef USE_MEMCPY ++ int i; ++ for (i = 0; i < len; i++) ++ WriteDOC(buf[i], docptr, Mil_CDSN_IO + i); ++#else ++ memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len); ++#endif ++} ++ ++/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */ ++static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip) ++{ ++ int mfr, id, i, j; ++ volatile char dummy; ++ unsigned long docptr = doc->virtadr; ++ ++ /* Page in the required floor/chip */ ++ DoC_SelectFloor(docptr, floor); ++ DoC_SelectChip(docptr, chip); ++ ++ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ ++ WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect); ++ ++ /* Reset the chip, see Software Requirement 11.4 item 1. */ ++ DoC_Command(docptr, NAND_CMD_RESET, 0); ++ DoC_WaitReady(docptr); ++ ++ /* Read the NAND chip ID: 1. Send ReadID command */ ++ DoC_Command(docptr, NAND_CMD_READID, 0); ++ ++ /* Read the NAND chip ID: 2. Send address byte zero */ ++ DoC_Address(doc, 1, 0x00, 0, 0x00); ++ ++ WriteDOC(0, docptr, Mplus_FlashControl); ++ DoC_WaitReady(docptr); ++ ++ /* Read the manufacturer and device id codes of the flash device through ++ CDSN IO register see Software Requirement 11.4 item 5.*/ ++ dummy = ReadDOC(docptr, Mplus_ReadPipeInit); ++ dummy = ReadDOC(docptr, Mplus_ReadPipeInit); ++ ++ mfr = ReadDOC(docptr, Mil_CDSN_IO); ++ if (doc->interleave) ++ dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */ ++ ++ id = ReadDOC(docptr, Mil_CDSN_IO); ++ if (doc->interleave) ++ dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */ ++ ++ dummy = ReadDOC(docptr, Mplus_LastDataRead); ++ dummy = ReadDOC(docptr, Mplus_LastDataRead); ++ ++ /* Disable flash internally */ ++ WriteDOC(0, docptr, Mplus_FlashSelect); ++ ++ /* No response - return failure */ ++ if (mfr == 0xff || mfr == 0) ++ return 0; ++ ++ for (i = 0; nand_flash_ids[i].name != NULL; i++) { ++ if (id == nand_flash_ids[i].id) { ++ /* Try to identify manufacturer */ ++ for (j = 0; nand_manuf_ids[j].id != 0x0; j++) { ++ if (nand_manuf_ids[j].id == mfr) ++ break; ++ } ++ printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, " ++ "Chip ID: %2.2X (%s:%s)\n", mfr, id, ++ nand_manuf_ids[j].name, nand_flash_ids[i].name); ++ doc->mfr = mfr; ++ doc->id = id; ++ doc->chipshift = nand_flash_ids[i].chipshift; ++ doc->erasesize = nand_flash_ids[i].erasesize << doc->interleave; ++ break; ++ } ++ } ++ ++ if (nand_flash_ids[i].name == NULL) ++ return 0; ++ return 1; ++} ++ ++/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */ ++static void DoC_ScanChips(struct DiskOnChip *this) ++{ ++ int floor, chip; ++ int numchips[MAX_FLOORS_MPLUS]; ++ int ret; ++ ++ this->numchips = 0; ++ this->mfr = 0; ++ this->id = 0; ++ ++ /* Work out the intended interleave setting */ ++ this->interleave = 0; ++ if (this->ChipID == DOC_ChipID_DocMilPlus32) ++ this->interleave = 1; ++ ++ /* Check the ASIC agrees */ ++ if ( (this->interleave << 2) != ++ (ReadDOC(this->virtadr, Mplus_Configuration) & 4)) { ++ u_char conf = ReadDOC(this->virtadr, Mplus_Configuration); ++ printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n", ++ this->interleave?"on (16-bit)":"off (8-bit)"); ++ conf ^= 4; ++ WriteDOC(this->virtadr, conf, Mplus_Configuration); ++ } ++ ++ /* For each floor, find the number of valid chips it contains */ ++ for (floor = 0,ret = 1; floor < MAX_FLOORS_MPLUS; floor++) { ++ numchips[floor] = 0; ++ for (chip = 0; chip < MAX_CHIPS_MPLUS && ret != 0; chip++) { ++ ret = DoC_IdentChip(this, floor, chip); ++ if (ret) { ++ numchips[floor]++; ++ this->numchips++; ++ } ++ } ++ } ++ /* If there are none at all that we recognise, bail */ ++ if (!this->numchips) { ++ printk("No flash chips recognised.\n"); ++ return; ++ } ++ ++ /* Allocate an array to hold the information for each chip */ ++ this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL); ++ if (!this->chips){ ++ printk("MTD: No memory for allocating chip info structures\n"); ++ return; ++ } ++ ++ /* Fill out the chip array with {floor, chipno} for each ++ * detected chip in the device. */ ++ for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) { ++ for (chip = 0 ; chip < numchips[floor] ; chip++) { ++ this->chips[ret].floor = floor; ++ this->chips[ret].chip = chip; ++ this->chips[ret].curadr = 0; ++ this->chips[ret].curmode = 0x50; ++ ret++; ++ } ++ } ++ ++ /* Calculate and print the total size of the device */ ++ this->totlen = this->numchips * (1 << this->chipshift); ++ printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n", ++ this->numchips ,this->totlen >> 20); ++} ++ ++static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2) ++{ ++ int tmp1, tmp2, retval; ++ ++ if (doc1->physadr == doc2->physadr) ++ return 1; ++ ++ /* Use the alias resolution register which was set aside for this ++ * purpose. If it's value is the same on both chips, they might ++ * be the same chip, and we write to one and check for a change in ++ * the other. It's unclear if this register is usuable in the ++ * DoC 2000 (it's in the Millennium docs), but it seems to work. */ ++ tmp1 = ReadDOC(doc1->virtadr, Mplus_AliasResolution); ++ tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution); ++ if (tmp1 != tmp2) ++ return 0; ++ ++ WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution); ++ tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution); ++ if (tmp2 == (tmp1+1) % 0xff) ++ retval = 1; ++ else ++ retval = 0; ++ ++ /* Restore register contents. May not be necessary, but do it just to ++ * be safe. */ ++ WriteDOC(tmp1, doc1->virtadr, Mplus_AliasResolution); ++ ++ return retval; ++} ++ ++static const char im_name[] = "DoCMilPlus_init"; ++ ++/* This routine is made available to other mtd code via ++ * inter_module_register. It must only be accessed through ++ * inter_module_get which will bump the use count of this module. The ++ * addresses passed back in mtd are valid as long as the use count of ++ * this module is non-zero, i.e. between inter_module_get and ++ * inter_module_put. Keith Owens 29 Oct 2000. ++ */ ++static void DoCMilPlus_init(struct mtd_info *mtd) ++{ ++ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; ++ struct DiskOnChip *old = NULL; ++ ++ /* We must avoid being called twice for the same device. */ ++ if (docmilpluslist) ++ old = (struct DiskOnChip *)docmilpluslist->priv; ++ ++ while (old) { ++ if (DoCMilPlus_is_alias(this, old)) { ++ printk(KERN_NOTICE "Ignoring DiskOnChip Millennium " ++ "Plus at 0x%lX - already configured\n", ++ this->physadr); ++ iounmap((void *)this->virtadr); ++ kfree(mtd); ++ return; ++ } ++ if (old->nextdoc) ++ old = (struct DiskOnChip *)old->nextdoc->priv; ++ else ++ old = NULL; ++ } ++ ++ mtd->name = "DiskOnChip Millennium Plus"; ++ printk(KERN_NOTICE "DiskOnChip Millennium Plus found at " ++ "address 0x%lX\n", this->physadr); ++ ++ mtd->type = MTD_NANDFLASH; ++ mtd->flags = MTD_CAP_NANDFLASH; ++ mtd->ecctype = MTD_ECC_RS_DiskOnChip; ++ mtd->size = 0; ++ ++ mtd->erasesize = 0; ++ mtd->oobblock = 512; ++ mtd->oobsize = 16; ++ mtd->owner = THIS_MODULE; ++ mtd->erase = doc_erase; ++ mtd->point = NULL; ++ mtd->unpoint = NULL; ++ mtd->read = doc_read; ++ mtd->write = doc_write; ++ mtd->read_ecc = doc_read_ecc; ++ mtd->write_ecc = doc_write_ecc; ++ mtd->read_oob = doc_read_oob; ++ mtd->write_oob = doc_write_oob; ++ mtd->sync = NULL; ++ ++ this->totlen = 0; ++ this->numchips = 0; ++ this->curfloor = -1; ++ this->curchip = -1; ++ ++ /* Ident all the chips present. */ ++ DoC_ScanChips(this); ++ ++ if (!this->totlen) { ++ kfree(mtd); ++ iounmap((void *)this->virtadr); ++ } else { ++ this->nextdoc = docmilpluslist; ++ docmilpluslist = mtd; ++ mtd->size = this->totlen; ++ mtd->erasesize = this->erasesize; ++ add_mtd_device(mtd); ++ return; ++ } ++} ++ ++#if 0 ++static int doc_dumpblk(struct mtd_info *mtd, loff_t from) ++{ ++ int i; ++ loff_t fofs; ++ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; ++ unsigned long docptr = this->virtadr; ++ struct Nand *mychip = &this->chips[from >> (this->chipshift)]; ++ unsigned char *bp, buf[1056]; ++ char c[32]; ++ ++ from &= ~0x3ff; ++ ++ /* Don't allow read past end of device */ ++ if (from >= this->totlen) ++ return -EINVAL; ++ ++ DoC_CheckASIC(docptr); ++ ++ /* Find the chip which is to be used and select it */ ++ if (this->curfloor != mychip->floor) { ++ DoC_SelectFloor(docptr, mychip->floor); ++ DoC_SelectChip(docptr, mychip->chip); ++ } else if (this->curchip != mychip->chip) { ++ DoC_SelectChip(docptr, mychip->chip); ++ } ++ this->curfloor = mychip->floor; ++ this->curchip = mychip->chip; ++ ++ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ ++ WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect); ++ ++ /* Reset the chip, see Software Requirement 11.4 item 1. */ ++ DoC_Command(docptr, NAND_CMD_RESET, 0); ++ DoC_WaitReady(docptr); ++ ++ fofs = from; ++ DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0); ++ DoC_Address(this, 3, fofs, 0, 0x00); ++ WriteDOC(0, docptr, Mplus_FlashControl); ++ DoC_WaitReady(docptr); ++ ++ /* disable the ECC engine */ ++ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); ++ ++ ReadDOC(docptr, Mplus_ReadPipeInit); ++ ReadDOC(docptr, Mplus_ReadPipeInit); ++ ++ /* Read the data via the internal pipeline through CDSN IO ++ register, see Pipelined Read Operations 11.3 */ ++ MemReadDOC(docptr, buf, 1054); ++ buf[1054] = ReadDOC(docptr, Mplus_LastDataRead); ++ buf[1055] = ReadDOC(docptr, Mplus_LastDataRead); ++ ++ memset(&c[0], 0, sizeof(c)); ++ printk("DUMP OFFSET=%x:\n", (int)from); ++ ++ for (i = 0, bp = &buf[0]; (i < 1056); i++) { ++ if ((i % 16) == 0) ++ printk("%08x: ", i); ++ printk(" %02x", *bp); ++ c[(i & 0xf)] = ((*bp >= 0x20) && (*bp <= 0x7f)) ? *bp : '.'; ++ bp++; ++ if (((i + 1) % 16) == 0) ++ printk(" %s\n", c); ++ } ++ printk("\n"); ++ ++ /* Disable flash internally */ ++ WriteDOC(0, docptr, Mplus_FlashSelect); ++ ++ return 0; ++} ++#endif ++ ++static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char *buf) ++{ ++ /* Just a special case of doc_read_ecc */ ++ return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL); ++} ++ ++static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char *buf, u_char *eccbuf, ++ struct nand_oobinfo *oobsel) ++{ ++ int ret, i; ++ volatile char dummy; ++ loff_t fofs; ++ unsigned char syndrome[6]; ++ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; ++ unsigned long docptr = this->virtadr; ++ struct Nand *mychip = &this->chips[from >> (this->chipshift)]; ++ ++ /* Don't allow read past end of device */ ++ if (from >= this->totlen) ++ return -EINVAL; ++ ++ /* Don't allow a single read to cross a 512-byte block boundary */ ++ if (from + len > ((from | 0x1ff) + 1)) ++ len = ((from | 0x1ff) + 1) - from; ++ ++ DoC_CheckASIC(docptr); ++ ++ /* Find the chip which is to be used and select it */ ++ if (this->curfloor != mychip->floor) { ++ DoC_SelectFloor(docptr, mychip->floor); ++ DoC_SelectChip(docptr, mychip->chip); ++ } else if (this->curchip != mychip->chip) { ++ DoC_SelectChip(docptr, mychip->chip); ++ } ++ this->curfloor = mychip->floor; ++ this->curchip = mychip->chip; ++ ++ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ ++ WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect); ++ ++ /* Reset the chip, see Software Requirement 11.4 item 1. */ ++ DoC_Command(docptr, NAND_CMD_RESET, 0); ++ DoC_WaitReady(docptr); ++ ++ fofs = from; ++ DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0); ++ DoC_Address(this, 3, fofs, 0, 0x00); ++ WriteDOC(0, docptr, Mplus_FlashControl); ++ DoC_WaitReady(docptr); ++ ++ if (eccbuf) { ++ /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ ++ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); ++ WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf); ++ } else { ++ /* disable the ECC engine */ ++ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); ++ } ++ ++ /* Let the caller know we completed it */ ++ *retlen = len; ++ ret = 0; ++ ++ ReadDOC(docptr, Mplus_ReadPipeInit); ++ ReadDOC(docptr, Mplus_ReadPipeInit); ++ ++ if (eccbuf) { ++ /* Read the data via the internal pipeline through CDSN IO ++ register, see Pipelined Read Operations 11.3 */ ++ MemReadDOC(docptr, buf, len); ++ ++ /* Read the ECC data following raw data */ ++ MemReadDOC(docptr, eccbuf, 4); ++ eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead); ++ eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead); ++ ++ /* Flush the pipeline */ ++ dummy = ReadDOC(docptr, Mplus_ECCConf); ++ dummy = ReadDOC(docptr, Mplus_ECCConf); ++ ++ /* Check the ECC Status */ ++ if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) { ++ int nb_errors; ++ /* There was an ECC error */ ++#ifdef ECC_DEBUG ++ printk("DiskOnChip ECC Error: Read at %lx\n", (long)from); ++#endif ++ /* Read the ECC syndrom through the DiskOnChip ECC logic. ++ These syndrome will be all ZERO when there is no error */ ++ for (i = 0; i < 6; i++) ++ syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); ++ ++ nb_errors = doc_decode_ecc(buf, syndrome); ++#ifdef ECC_DEBUG ++ printk("ECC Errors corrected: %x\n", nb_errors); ++#endif ++ if (nb_errors < 0) { ++ /* We return error, but have actually done the read. Not that ++ this can be told to user-space, via sys_read(), but at least ++ MTD-aware stuff can know about it by checking *retlen */ ++#ifdef ECC_DEBUG ++ printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n", ++ __FILE__, __LINE__, (int)from); ++ printk(" syndrome= %02x:%02x:%02x:%02x:%02x:" ++ "%02x\n", ++ syndrome[0], syndrome[1], syndrome[2], ++ syndrome[3], syndrome[4], syndrome[5]); ++ printk(" eccbuf= %02x:%02x:%02x:%02x:%02x:" ++ "%02x\n", ++ eccbuf[0], eccbuf[1], eccbuf[2], ++ eccbuf[3], eccbuf[4], eccbuf[5]); ++#endif ++ ret = -EIO; ++ } ++ } ++ ++#ifdef PSYCHO_DEBUG ++ printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", ++ (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], ++ eccbuf[4], eccbuf[5]); ++#endif ++ ++ /* disable the ECC engine */ ++ WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf); ++ } else { ++ /* Read the data via the internal pipeline through CDSN IO ++ register, see Pipelined Read Operations 11.3 */ ++ MemReadDOC(docptr, buf, len-2); ++ buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead); ++ buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead); ++ } ++ ++ /* Disable flash internally */ ++ WriteDOC(0, docptr, Mplus_FlashSelect); ++ ++ return ret; ++} ++ ++static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf) ++{ ++ char eccbuf[6]; ++ return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL); ++} ++ ++static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf, u_char *eccbuf, ++ struct nand_oobinfo *oobsel) ++{ ++ int i, before, ret = 0; ++ loff_t fto; ++ volatile char dummy; ++ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; ++ unsigned long docptr = this->virtadr; ++ struct Nand *mychip = &this->chips[to >> (this->chipshift)]; ++ ++ /* Don't allow write past end of device */ ++ if (to >= this->totlen) ++ return -EINVAL; ++ ++ /* Don't allow writes which aren't exactly one block (512 bytes) */ ++ if ((to & 0x1ff) || (len != 0x200)) ++ return -EINVAL; ++ ++ /* Determine position of OOB flags, before or after data */ ++ before = (this->interleave && (to & 0x200)); ++ ++ DoC_CheckASIC(docptr); ++ ++ /* Find the chip which is to be used and select it */ ++ if (this->curfloor != mychip->floor) { ++ DoC_SelectFloor(docptr, mychip->floor); ++ DoC_SelectChip(docptr, mychip->chip); ++ } else if (this->curchip != mychip->chip) { ++ DoC_SelectChip(docptr, mychip->chip); ++ } ++ this->curfloor = mychip->floor; ++ this->curchip = mychip->chip; ++ ++ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ ++ WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect); ++ ++ /* Reset the chip, see Software Requirement 11.4 item 1. */ ++ DoC_Command(docptr, NAND_CMD_RESET, 0); ++ DoC_WaitReady(docptr); ++ ++ /* Set device to appropriate plane of flash */ ++ fto = to; ++ WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd); ++ ++ /* On interleaved devices the flags for 2nd half 512 are before data */ ++ if (eccbuf && before) ++ fto -= 2; ++ ++ /* issue the Serial Data In command to initial the Page Program process */ ++ DoC_Command(docptr, NAND_CMD_SEQIN, 0x00); ++ DoC_Address(this, 3, fto, 0x00, 0x00); ++ ++ /* Disable the ECC engine */ ++ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); ++ ++ if (eccbuf) { ++ if (before) { ++ /* Write the block status BLOCK_USED (0x5555) */ ++ WriteDOC(0x55, docptr, Mil_CDSN_IO); ++ WriteDOC(0x55, docptr, Mil_CDSN_IO); ++ } ++ ++ /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ ++ WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf); ++ } ++ ++ MemWriteDOC(docptr, (unsigned char *) buf, len); ++ ++ if (eccbuf) { ++ /* Write ECC data to flash, the ECC info is generated by ++ the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */ ++ DoC_Delay(docptr, 3); ++ ++ /* Read the ECC data through the DiskOnChip ECC logic */ ++ for (i = 0; i < 6; i++) ++ eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i); ++ ++ /* disable the ECC engine */ ++ WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); ++ ++ /* Write the ECC data to flash */ ++ MemWriteDOC(docptr, eccbuf, 6); ++ ++ if (!before) { ++ /* Write the block status BLOCK_USED (0x5555) */ ++ WriteDOC(0x55, docptr, Mil_CDSN_IO+6); ++ WriteDOC(0x55, docptr, Mil_CDSN_IO+7); ++ } ++ ++#ifdef PSYCHO_DEBUG ++ printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", ++ (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], ++ eccbuf[4], eccbuf[5]); ++#endif ++ } ++ ++ WriteDOC(0x00, docptr, Mplus_WritePipeTerm); ++ WriteDOC(0x00, docptr, Mplus_WritePipeTerm); ++ ++ /* Commit the Page Program command and wait for ready ++ see Software Requirement 11.4 item 1.*/ ++ DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00); ++ DoC_WaitReady(docptr); ++ ++ /* Read the status of the flash device through CDSN IO register ++ see Software Requirement 11.4 item 5.*/ ++ DoC_Command(docptr, NAND_CMD_STATUS, 0); ++ dummy = ReadDOC(docptr, Mplus_ReadPipeInit); ++ dummy = ReadDOC(docptr, Mplus_ReadPipeInit); ++ DoC_Delay(docptr, 2); ++ if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) { ++ printk("MTD: Error 0x%x programming at 0x%x\n", dummy, (int)to); ++ /* Error in programming ++ FIXME: implement Bad Block Replacement (in nftl.c ??) */ ++ *retlen = 0; ++ ret = -EIO; ++ } ++ dummy = ReadDOC(docptr, Mplus_LastDataRead); ++ ++ /* Disable flash internally */ ++ WriteDOC(0, docptr, Mplus_FlashSelect); ++ ++ /* Let the caller know we completed it */ ++ *retlen = len; ++ ++ return ret; ++} ++ ++static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ++ size_t *retlen, u_char *buf) ++{ ++ loff_t fofs, base; ++ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; ++ unsigned long docptr = this->virtadr; ++ struct Nand *mychip = &this->chips[ofs >> this->chipshift]; ++ size_t i, size, got, want; ++ ++ DoC_CheckASIC(docptr); ++ ++ /* Find the chip which is to be used and select it */ ++ if (this->curfloor != mychip->floor) { ++ DoC_SelectFloor(docptr, mychip->floor); ++ DoC_SelectChip(docptr, mychip->chip); ++ } else if (this->curchip != mychip->chip) { ++ DoC_SelectChip(docptr, mychip->chip); ++ } ++ this->curfloor = mychip->floor; ++ this->curchip = mychip->chip; ++ ++ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ ++ WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect); ++ ++ /* disable the ECC engine */ ++ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); ++ DoC_WaitReady(docptr); ++ ++ /* Maximum of 16 bytes in the OOB region, so limit read to that */ ++ if (len > 16) ++ len = 16; ++ got = 0; ++ want = len; ++ ++ for (i = 0; ((i < 3) && (want > 0)); i++) { ++ /* Figure out which region we are accessing... */ ++ fofs = ofs; ++ base = ofs & 0xf; ++ if (!this->interleave) { ++ DoC_Command(docptr, NAND_CMD_READOOB, 0); ++ size = 16 - base; ++ } else if (base < 6) { ++ DoC_Command(docptr, DoC_GetECCOffset(mtd, &fofs), 0); ++ size = 6 - base; ++ } else if (base < 8) { ++ DoC_Command(docptr, DoC_GetFlagsOffset(mtd, &fofs), 0); ++ size = 8 - base; ++ } else { ++ DoC_Command(docptr, DoC_GetHdrOffset(mtd, &fofs), 0); ++ size = 16 - base; ++ } ++ if (size > want) ++ size = want; ++ ++ /* Issue read command */ ++ DoC_Address(this, 3, fofs, 0, 0x00); ++ WriteDOC(0, docptr, Mplus_FlashControl); ++ DoC_WaitReady(docptr); ++ ++ ReadDOC(docptr, Mplus_ReadPipeInit); ++ ReadDOC(docptr, Mplus_ReadPipeInit); ++ MemReadDOC(docptr, &buf[got], size - 2); ++ buf[got + size - 2] = ReadDOC(docptr, Mplus_LastDataRead); ++ buf[got + size - 1] = ReadDOC(docptr, Mplus_LastDataRead); ++ ++ ofs += size; ++ got += size; ++ want -= size; ++ } ++ ++ /* Disable flash internally */ ++ WriteDOC(0, docptr, Mplus_FlashSelect); ++ ++ *retlen = len; ++ return 0; ++} ++ ++static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ++ size_t *retlen, const u_char *buf) ++{ ++ volatile char dummy; ++ loff_t fofs, base; ++ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; ++ unsigned long docptr = this->virtadr; ++ struct Nand *mychip = &this->chips[ofs >> this->chipshift]; ++ size_t i, size, got, want; ++ int ret = 0; ++ ++ DoC_CheckASIC(docptr); ++ ++ /* Find the chip which is to be used and select it */ ++ if (this->curfloor != mychip->floor) { ++ DoC_SelectFloor(docptr, mychip->floor); ++ DoC_SelectChip(docptr, mychip->chip); ++ } else if (this->curchip != mychip->chip) { ++ DoC_SelectChip(docptr, mychip->chip); ++ } ++ this->curfloor = mychip->floor; ++ this->curchip = mychip->chip; ++ ++ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ ++ WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect); ++ ++ ++ /* Maximum of 16 bytes in the OOB region, so limit write to that */ ++ if (len > 16) ++ len = 16; ++ got = 0; ++ want = len; ++ ++ for (i = 0; ((i < 3) && (want > 0)); i++) { ++ /* Reset the chip, see Software Requirement 11.4 item 1. */ ++ DoC_Command(docptr, NAND_CMD_RESET, 0); ++ DoC_WaitReady(docptr); ++ ++ /* Figure out which region we are accessing... */ ++ fofs = ofs; ++ base = ofs & 0x0f; ++ if (!this->interleave) { ++ WriteDOC(NAND_CMD_READOOB, docptr, Mplus_FlashCmd); ++ size = 16 - base; ++ } else if (base < 6) { ++ WriteDOC(DoC_GetECCOffset(mtd, &fofs), docptr, Mplus_FlashCmd); ++ size = 6 - base; ++ } else if (base < 8) { ++ WriteDOC(DoC_GetFlagsOffset(mtd, &fofs), docptr, Mplus_FlashCmd); ++ size = 8 - base; ++ } else { ++ WriteDOC(DoC_GetHdrOffset(mtd, &fofs), docptr, Mplus_FlashCmd); ++ size = 16 - base; ++ } ++ if (size > want) ++ size = want; ++ ++ /* Issue the Serial Data In command to initial the Page Program process */ ++ DoC_Command(docptr, NAND_CMD_SEQIN, 0x00); ++ DoC_Address(this, 3, fofs, 0, 0x00); ++ ++ /* Disable the ECC engine */ ++ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); ++ ++ /* Write the data via the internal pipeline through CDSN IO ++ register, see Pipelined Write Operations 11.2 */ ++ MemWriteDOC(docptr, (unsigned char *) &buf[got], size); ++ WriteDOC(0x00, docptr, Mplus_WritePipeTerm); ++ WriteDOC(0x00, docptr, Mplus_WritePipeTerm); ++ ++ /* Commit the Page Program command and wait for ready ++ see Software Requirement 11.4 item 1.*/ ++ DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00); ++ DoC_WaitReady(docptr); ++ ++ /* Read the status of the flash device through CDSN IO register ++ see Software Requirement 11.4 item 5.*/ ++ DoC_Command(docptr, NAND_CMD_STATUS, 0x00); ++ dummy = ReadDOC(docptr, Mplus_ReadPipeInit); ++ dummy = ReadDOC(docptr, Mplus_ReadPipeInit); ++ DoC_Delay(docptr, 2); ++ if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) { ++ printk("MTD: Error 0x%x programming oob at 0x%x\n", ++ dummy, (int)ofs); ++ /* FIXME: implement Bad Block Replacement */ ++ *retlen = 0; ++ ret = -EIO; ++ } ++ dummy = ReadDOC(docptr, Mplus_LastDataRead); ++ ++ ofs += size; ++ got += size; ++ want -= size; ++ } ++ ++ /* Disable flash internally */ ++ WriteDOC(0, docptr, Mplus_FlashSelect); ++ ++ *retlen = len; ++ return ret; ++} ++ ++int doc_erase(struct mtd_info *mtd, struct erase_info *instr) ++{ ++ volatile char dummy; ++ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; ++ __u32 ofs = instr->addr; ++ __u32 len = instr->len; ++ unsigned long docptr = this->virtadr; ++ struct Nand *mychip = &this->chips[ofs >> this->chipshift]; ++ ++ DoC_CheckASIC(docptr); ++ ++ if (len != mtd->erasesize) ++ printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n", ++ len, mtd->erasesize); ++ ++ /* Find the chip which is to be used and select it */ ++ if (this->curfloor != mychip->floor) { ++ DoC_SelectFloor(docptr, mychip->floor); ++ DoC_SelectChip(docptr, mychip->chip); ++ } else if (this->curchip != mychip->chip) { ++ DoC_SelectChip(docptr, mychip->chip); ++ } ++ this->curfloor = mychip->floor; ++ this->curchip = mychip->chip; ++ ++ instr->state = MTD_ERASE_PENDING; ++ ++ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */ ++ WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect); ++ ++ DoC_Command(docptr, NAND_CMD_RESET, 0x00); ++ DoC_WaitReady(docptr); ++ ++ DoC_Command(docptr, NAND_CMD_ERASE1, 0); ++ DoC_Address(this, 2, ofs, 0, 0x00); ++ DoC_Command(docptr, NAND_CMD_ERASE2, 0); ++ DoC_WaitReady(docptr); ++ instr->state = MTD_ERASING; ++ ++ /* Read the status of the flash device through CDSN IO register ++ see Software Requirement 11.4 item 5. */ ++ DoC_Command(docptr, NAND_CMD_STATUS, 0); ++ dummy = ReadDOC(docptr, Mplus_ReadPipeInit); ++ dummy = ReadDOC(docptr, Mplus_ReadPipeInit); ++ if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) { ++ printk("MTD: Error 0x%x erasing at 0x%x\n", dummy, ofs); ++ /* FIXME: implement Bad Block Replacement (in nftl.c ??) */ ++ instr->state = MTD_ERASE_FAILED; ++ } else { ++ instr->state = MTD_ERASE_DONE; ++ } ++ dummy = ReadDOC(docptr, Mplus_LastDataRead); ++ ++ /* Disable flash internally */ ++ WriteDOC(0, docptr, Mplus_FlashSelect); ++ ++ if (instr->callback) ++ instr->callback(instr); ++ ++ return 0; ++} ++ ++/**************************************************************************** ++ * ++ * Module stuff ++ * ++ ****************************************************************************/ ++ ++int __init init_doc2001plus(void) ++{ ++ inter_module_register(im_name, THIS_MODULE, &DoCMilPlus_init); ++ return 0; ++} ++ ++static void __exit cleanup_doc2001plus(void) ++{ ++ struct mtd_info *mtd; ++ struct DiskOnChip *this; ++ ++ while ((mtd=docmilpluslist)) { ++ this = (struct DiskOnChip *)mtd->priv; ++ docmilpluslist = this->nextdoc; ++ ++ del_mtd_device(mtd); ++ ++ iounmap((void *)this->virtadr); ++ kfree(this->chips); ++ kfree(mtd); ++ } ++ inter_module_unregister(im_name); ++} ++ ++module_exit(cleanup_doc2001plus); ++module_init(init_doc2001plus); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Greg Ungerer et al."); ++MODULE_DESCRIPTION("Driver for DiskOnChip Millennium Plus"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/docecc.c linux/drivers/mtd/devices/docecc.c +--- linux-mips-2.4.27/drivers/mtd/devices/docecc.c 2001-11-05 21:15:52.000000000 +0100 ++++ linux/drivers/mtd/devices/docecc.c 2004-11-19 10:25:11.851207088 +0100 +@@ -7,7 +7,7 @@ + * Author: Fabrice Bellard (fabrice.bellard@netgem.com) + * Copyright (C) 2000 Netgem S.A. + * +- * $Id: docecc.c,v 1.4 2001/10/02 15:05:13 dwmw2 Exp $ ++ * $Id: docecc.c,v 1.5 2003/05/21 15:15:06 dwmw2 Exp $ + * + * 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 +@@ -519,6 +519,8 @@ + return nb_errors; + } + ++EXPORT_SYMBOL_GPL(doc_decode_ecc); ++ + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Fabrice Bellard "); + MODULE_DESCRIPTION("ECC code for correcting errors detected by DiskOnChip 2000 and Millennium ECC hardware"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/docprobe.c linux/drivers/mtd/devices/docprobe.c +--- linux-mips-2.4.27/drivers/mtd/devices/docprobe.c 2003-06-16 01:42:21.000000000 +0200 ++++ linux/drivers/mtd/devices/docprobe.c 2004-11-19 10:25:11.853206784 +0100 +@@ -4,7 +4,7 @@ + /* (C) 1999 Machine Vision Holdings, Inc. */ + /* (C) 1999-2003 David Woodhouse */ + +-/* $Id: docprobe.c,v 1.33 2003/01/24 14:02:47 dwmw2 Exp $ */ ++/* $Id: docprobe.c,v 1.41 2003/12/03 10:19:57 dwmw2 Exp $ */ + + + +@@ -31,14 +31,12 @@ + /* DOC_SINGLE_DRIVER: + Millennium driver has been merged into DOC2000 driver. + +- The newly-merged driver doesn't appear to work for writing. It's the +- same with the DiskOnChip 2000 and the Millennium. If you have a +- Millennium and you want write support to work, remove the definition +- of DOC_SINGLE_DRIVER below to use the old doc2001-specific driver. +- +- Otherwise, it's left on in the hope that it'll annoy someone with +- a Millennium enough that they go through and work out what the +- difference is :) ++ The old Millennium-only driver has been retained just in case there ++ are problems with the new code. If the combined driver doesn't work ++ for you, you can try the old one by undefining DOC_SINGLE_DRIVER ++ below and also enabling it in your configuration. If this fixes the ++ problems, please send a report to the MTD mailing list at ++ . + */ + #define DOC_SINGLE_DRIVER + +@@ -47,18 +45,15 @@ + #include + #include + #include +-#include +-#include +-#include + #include + #include +-#include + #include + #include + + #include + #include + #include ++#include + + /* Where to look for the devices? */ + #ifndef CONFIG_MTD_DOCPROBE_ADDRESS +@@ -92,17 +87,17 @@ + 0xff000000, + #elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C) + 0xff000000, +-#else ++##else + #warning Unknown architecture for DiskOnChip. No default probe locations defined + #endif +- 0 }; ++ 0xffffffff }; + + /* doccheck: Probe a given memory window to see if there's a DiskOnChip present */ + + static inline int __init doccheck(unsigned long potential, unsigned long physadr) + { + unsigned long window=potential; +- unsigned char tmp, ChipID; ++ unsigned char tmp, tmpb, tmpc, ChipID; + #ifndef DOC_PASSIVE_PROBE + unsigned char tmp2; + #endif +@@ -140,26 +135,80 @@ + window, DOCControl); + #endif /* !DOC_PASSIVE_PROBE */ + ++ /* We need to read the ChipID register four times. For some ++ newer DiskOnChip 2000 units, the first three reads will ++ return the DiskOnChip Millennium ident. Don't ask. */ + ChipID = ReadDOC(window, ChipID); + + switch (ChipID) { + case DOC_ChipID_Doc2k: + /* Check the TOGGLE bit in the ECC register */ + tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT; +- if ((ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT) != tmp) ++ tmpb = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT; ++ tmpc = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT; ++ if (tmp != tmpb && tmp == tmpc) + return ChipID; + break; + + case DOC_ChipID_DocMil: ++ /* Check for the new 2000 with Millennium ASIC */ ++ ReadDOC(window, ChipID); ++ ReadDOC(window, ChipID); ++ if (ReadDOC(window, ChipID) != DOC_ChipID_DocMil) ++ ChipID = DOC_ChipID_Doc2kTSOP; ++ + /* Check the TOGGLE bit in the ECC register */ + tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT; +- if ((ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT) != tmp) ++ tmpb = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT; ++ tmpc = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT; ++ if (tmp != tmpb && tmp == tmpc) ++ return ChipID; ++ break; ++ ++ case DOC_ChipID_DocMilPlus16: ++ case DOC_ChipID_DocMilPlus32: ++ case 0: ++ /* Possible Millennium+, need to do more checks */ ++#ifndef DOC_PASSIVE_PROBE ++ /* Possibly release from power down mode */ ++ for (tmp = 0; (tmp < 4); tmp++) ++ ReadDOC(window, Mplus_Power); ++ ++ /* Reset the DiskOnChip ASIC */ ++ tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | ++ DOC_MODE_BDECT; ++ WriteDOC(tmp, window, Mplus_DOCControl); ++ WriteDOC(~tmp, window, Mplus_CtrlConfirm); ++ ++ mdelay(1); ++ /* Enable the DiskOnChip ASIC */ ++ tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | ++ DOC_MODE_BDECT; ++ WriteDOC(tmp, window, Mplus_DOCControl); ++ WriteDOC(~tmp, window, Mplus_CtrlConfirm); ++ mdelay(1); ++#endif /* !DOC_PASSIVE_PROBE */ ++ ++ ChipID = ReadDOC(window, ChipID); ++ ++ switch (ChipID) { ++ case DOC_ChipID_DocMilPlus16: ++ case DOC_ChipID_DocMilPlus32: ++ /* Check the TOGGLE bit in the toggle register */ ++ tmp = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT; ++ tmpb = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT; ++ tmpc = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT; ++ if (tmp != tmpb && tmp == tmpc) + return ChipID; ++ default: + break; ++ } ++ /* FALL TRHU */ + + default: +-#ifndef CONFIG_MTD_DOCPROBE_55AA +- printk(KERN_WARNING "Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n", ++ ++#ifdef CONFIG_MTD_DOCPROBE_55AA ++ printk(KERN_DEBUG "Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n", + ChipID, physadr); + #endif + #ifndef DOC_PASSIVE_PROBE +@@ -200,6 +249,12 @@ + return; + + if ((ChipID = doccheck(docptr, physadr))) { ++ if (ChipID == DOC_ChipID_Doc2kTSOP) { ++ /* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */ ++ printk(KERN_NOTICE "Refusing to drive DiskOnChip 2000 TSOP until Bad Block Table is correctly supported by INFTL\n"); ++ iounmap((void *)docptr); ++ return; ++ } + docfound = 1; + mtd = kmalloc(sizeof(struct DiskOnChip) + sizeof(struct mtd_info), GFP_KERNEL); + +@@ -221,6 +276,12 @@ + sprintf(namebuf, "with ChipID %2.2X", ChipID); + + switch(ChipID) { ++ case DOC_ChipID_Doc2kTSOP: ++ name="2000 TSOP"; ++ im_funcname = "DoC2k_init"; ++ im_modname = "doc2000"; ++ break; ++ + case DOC_ChipID_Doc2k: + name="2000"; + im_funcname = "DoC2k_init"; +@@ -237,6 +298,13 @@ + im_modname = "doc2001"; + #endif /* DOC_SINGLE_DRIVER */ + break; ++ ++ case DOC_ChipID_DocMilPlus16: ++ case DOC_ChipID_DocMilPlus32: ++ name="MillenniumPlus"; ++ im_funcname = "DoCMilPlus_init"; ++ im_modname = "doc2001plus"; ++ break; + } + + if (im_funcname) +@@ -248,6 +316,7 @@ + return; + } + printk(KERN_NOTICE "Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr); ++ kfree(mtd); + } + iounmap((void *)docptr); + } +@@ -267,7 +336,7 @@ + printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location); + DoC_Probe(doc_config_location); + } else { +- for (i=0; doc_locations[i]; i++) { ++ for (i=0; (doc_locations[i] != 0xffffffff); i++) { + DoC_Probe(doc_locations[i]); + } + } +@@ -275,11 +344,7 @@ + found, so the user knows we at least tried. */ + if (!docfound) + printk(KERN_INFO "No recognised DiskOnChip devices found\n"); +- /* So it looks like we've been used and we get unloaded */ +- MOD_INC_USE_COUNT; +- MOD_DEC_USE_COUNT; +- return 0; +- ++ return -EAGAIN; + } + + module_init(init_doc); +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/lart.c linux/drivers/mtd/devices/lart.c +--- linux-mips-2.4.27/drivers/mtd/devices/lart.c 2001-11-05 21:15:52.000000000 +0100 ++++ linux/drivers/mtd/devices/lart.c 2004-11-19 10:25:11.854206632 +0100 +@@ -2,7 +2,7 @@ + /* + * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART. + * +- * $Id: lart.c,v 1.2 2001/10/02 15:05:13 dwmw2 Exp $ ++ * $Id: lart.c,v 1.5 2003/05/20 21:03:07 dwmw2 Exp $ + * + * Author: Abraham vd Merwe + * +@@ -584,45 +584,40 @@ + + static struct mtd_info mtd; + +-static struct mtd_erase_region_info erase_regions[] = +-{ ++static struct mtd_erase_region_info erase_regions[] = { + /* parameter blocks */ + { +- offset: 0x00000000, +- erasesize: FLASH_BLOCKSIZE_PARAM, +- numblocks: FLASH_NUMBLOCKS_16m_PARAM ++ .offset = 0x00000000, ++ .erasesize = FLASH_BLOCKSIZE_PARAM, ++ .numblocks = FLASH_NUMBLOCKS_16m_PARAM, + }, + /* main blocks */ + { +- offset: FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM, +- erasesize: FLASH_BLOCKSIZE_MAIN, +- numblocks: FLASH_NUMBLOCKS_16m_MAIN ++ .offset = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM, ++ .erasesize = FLASH_BLOCKSIZE_MAIN, ++ .numblocks = FLASH_NUMBLOCKS_16m_MAIN, + } + }; + + #ifdef HAVE_PARTITIONS +-static struct mtd_partition lart_partitions[] = +-{ ++static struct mtd_partition lart_partitions[] = { + /* blob */ + { +- name: "blob", +- offset: BLOB_START, +- size: BLOB_LEN, +- mask_flags: 0 ++ .name = "blob", ++ .offset = BLOB_START, ++ .size = BLOB_LEN, + }, + /* kernel */ + { +- name: "kernel", +- offset: KERNEL_START, /* MTDPART_OFS_APPEND */ +- size: KERNEL_LEN, +- mask_flags: 0 ++ .name = "kernel", ++ .offset = KERNEL_START, /* MTDPART_OFS_APPEND */ ++ .size = KERNEL_LEN, + }, + /* initial ramdisk / file system */ + { +- name: "file system", +- offset: INITRD_START, /* MTDPART_OFS_APPEND */ +- size: INITRD_LEN, /* MTDPART_SIZ_FULL */ +- mask_flags: 0 ++ .name = "file system", ++ .offset = INITRD_START, /* MTDPART_OFS_APPEND */ ++ .size = INITRD_LEN, /* MTDPART_SIZ_FULL */ + } + }; + #endif +@@ -646,10 +641,10 @@ + mtd.erasesize = FLASH_BLOCKSIZE_MAIN; + mtd.numeraseregions = NB_OF (erase_regions); + mtd.eraseregions = erase_regions; +- mtd.module = THIS_MODULE; + mtd.erase = flash_erase; + mtd.read = flash_read; + mtd.write = flash_write; ++ mtd.owner = THIS_MODULE; + + #ifdef LART_DEBUG + printk (KERN_DEBUG +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/ms02-nv.c linux/drivers/mtd/devices/ms02-nv.c +--- linux-mips-2.4.27/drivers/mtd/devices/ms02-nv.c 2004-07-30 12:22:40.000000000 +0200 ++++ linux/drivers/mtd/devices/ms02-nv.c 2004-11-19 10:25:11.856206328 +0100 +@@ -6,7 +6,7 @@ + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * +- * $Id: ms02-nv.c,v 1.2 2003/01/24 14:05:17 dwmw2 Exp $ ++ * $Id: ms02-nv.c,v 1.6 2003/08/19 09:25:36 dwmw2 Exp $ + */ + + #include +@@ -31,7 +31,7 @@ + static char version[] __initdata = + "ms02-nv.c: v.1.0.0 13 Aug 2001 Maciej W. Rozycki.\n"; + +-MODULE_AUTHOR("Maciej W. Rozycki "); ++MODULE_AUTHOR("Maciej W. Rozycki "); + MODULE_DESCRIPTION("DEC MS02-NV NVRAM module driver"); + MODULE_LICENSE("GPL"); + +@@ -222,7 +222,7 @@ + mtd->flags = MTD_CAP_RAM | MTD_XIP; + mtd->size = fixsize; + mtd->name = (char *)ms02nv_name; +- mtd->module = THIS_MODULE; ++ mtd->owner = THIS_MODULE; + mtd->read = ms02nv_read; + mtd->write = ms02nv_write; + +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/mtdram.c linux/drivers/mtd/devices/mtdram.c +--- linux-mips-2.4.27/drivers/mtd/devices/mtdram.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/devices/mtdram.c 2004-11-19 10:25:11.859205872 +0100 +@@ -1,6 +1,6 @@ + /* + * mtdram - a test mtd device +- * $Id: mtdram.c,v 1.29 2002/10/21 13:40:06 jocke Exp $ ++ * $Id: mtdram.c,v 1.32 2003/05/21 15:15:07 dwmw2 Exp $ + * Author: Alexander Larsson + * + * Copyright (c) 1999 Alexander Larsson +@@ -13,6 +13,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + +@@ -136,7 +138,7 @@ + mtd->erasesize = MTDRAM_ERASE_SIZE; + mtd->priv = mapped_address; + +- mtd->module = THIS_MODULE; ++ mtd->owner = THIS_MODULE; + mtd->erase = ram_erase; + mtd->point = ram_point; + mtd->unpoint = ram_unpoint; +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/phram.c linux/drivers/mtd/devices/phram.c +--- linux-mips-2.4.27/drivers/mtd/devices/phram.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/devices/phram.c 2004-11-19 10:25:11.860205720 +0100 +@@ -0,0 +1,362 @@ ++/** ++ * ++ * $Id: phram.c,v 1.1 2003/08/21 17:52:30 joern Exp $ ++ * ++ * Copyright (c) Jochen Schaeuble ++ * 07/2003 rewritten by Joern Engel ++ * ++ * DISCLAIMER: This driver makes use of Rusty's excellent module code, ++ * so it will not work for 2.4 without changes and it wont work for 2.4 ++ * as a module without major changes. Oh well! ++ * ++ * Usage: ++ * ++ * one commend line parameter per device, each in the form: ++ * phram=,, ++ * may be up to 63 characters. ++ * and can be octal, decimal or hexadecimal. If followed ++ * by "k", "M" or "G", the numbers will be interpreted as kilo, mega or ++ * gigabytes. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define ERROR(fmt, args...) printk(KERN_ERR "phram: " fmt , ## args) ++ ++struct phram_mtd_list { ++ struct list_head list; ++ struct mtd_info *mtdinfo; ++}; ++ ++static LIST_HEAD(phram_list); ++ ++ ++ ++int phram_erase(struct mtd_info *mtd, struct erase_info *instr) ++{ ++ u_char *start = (u_char *)mtd->priv; ++ ++ if (instr->addr + instr->len > mtd->size) ++ return -EINVAL; ++ ++ memset(start + instr->addr, 0xff, instr->len); ++ ++ /* This'll catch a few races. Free the thing before returning :) ++ * I don't feel at all ashamed. This kind of thing is possible anyway ++ * with flash, but unlikely. ++ */ ++ ++ instr->state = MTD_ERASE_DONE; ++ ++ if (instr->callback) ++ (*(instr->callback))(instr); ++ else ++ kfree(instr); ++ ++ return 0; ++} ++ ++int phram_point(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char **mtdbuf) ++{ ++ u_char *start = (u_char *)mtd->priv; ++ ++ if (from + len > mtd->size) ++ return -EINVAL; ++ ++ *mtdbuf = start + from; ++ *retlen = len; ++ return 0; ++} ++ ++void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) ++{ ++} ++ ++int phram_read(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char *buf) ++{ ++ u_char *start = (u_char *)mtd->priv; ++ ++ if (from + len > mtd->size) ++ return -EINVAL; ++ ++ memcpy(buf, start + from, len); ++ ++ *retlen = len; ++ return 0; ++} ++ ++int phram_write(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf) ++{ ++ u_char *start = (u_char *)mtd->priv; ++ ++ if (to + len > mtd->size) ++ return -EINVAL; ++ ++ memcpy(start + to, buf, len); ++ ++ *retlen = len; ++ return 0; ++} ++ ++ ++ ++static void unregister_devices(void) ++{ ++ struct phram_mtd_list *this; ++ ++ list_for_each_entry(this, &phram_list, list) { ++ del_mtd_device(this->mtdinfo); ++ iounmap(this->mtdinfo->priv); ++ kfree(this->mtdinfo); ++ kfree(this); ++ } ++} ++ ++static int register_device(char *name, unsigned long start, unsigned long len) ++{ ++ struct phram_mtd_list *new; ++ int ret = -ENOMEM; ++ ++ new = kmalloc(sizeof(*new), GFP_KERNEL); ++ if (!new) ++ goto out0; ++ ++ new->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); ++ if (!new->mtdinfo) ++ goto out1; ++ ++ memset(new->mtdinfo, 0, sizeof(struct mtd_info)); ++ ++ ret = -EIO; ++ new->mtdinfo->priv = ioremap(start, len); ++ if (!new->mtdinfo->priv) { ++ ERROR("ioremap failed\n"); ++ goto out2; ++ } ++ ++ ++ new->mtdinfo->name = name; ++ new->mtdinfo->size = len; ++ new->mtdinfo->flags = MTD_CAP_RAM | MTD_ERASEABLE | MTD_VOLATILE; ++ new->mtdinfo->erase = phram_erase; ++ new->mtdinfo->point = phram_point; ++ new->mtdinfo->unpoint = phram_unpoint; ++ new->mtdinfo->read = phram_read; ++ new->mtdinfo->write = phram_write; ++ new->mtdinfo->owner = THIS_MODULE; ++ new->mtdinfo->type = MTD_RAM; ++ new->mtdinfo->erasesize = 0x0; ++ ++ ret = -EAGAIN; ++ if (add_mtd_device(new->mtdinfo)) { ++ ERROR("Failed to register new device\n"); ++ goto out3; ++ } ++ ++ list_add_tail(&new->list, &phram_list); ++ return 0; ++ ++out3: ++ iounmap(new->mtdinfo->priv); ++out2: ++ kfree(new->mtdinfo); ++out1: ++ kfree(new); ++out0: ++ return ret; ++} ++ ++static int ustrtoul(const char *cp, char **endp, unsigned int base) ++{ ++ unsigned long result = simple_strtoul(cp, endp, base); ++ ++ switch (**endp) { ++ case 'G': ++ result *= 1024; ++ case 'M': ++ result *= 1024; ++ case 'k': ++ result *= 1024; ++ endp++; ++ } ++ return result; ++} ++ ++static int parse_num32(uint32_t *num32, const char *token) ++{ ++ char *endp; ++ unsigned long n; ++ ++ n = ustrtoul(token, &endp, 0); ++ if (*endp) ++ return -EINVAL; ++ ++ *num32 = n; ++ return 0; ++} ++ ++static int parse_name(char **pname, const char *token) ++{ ++ size_t len; ++ char *name; ++ ++ len = strlen(token) + 1; ++ if (len > 64) ++ return -ENOSPC; ++ ++ name = kmalloc(len, GFP_KERNEL); ++ if (!name) ++ return -ENOMEM; ++ ++ strcpy(name, token); ++ ++ *pname = name; ++ return 0; ++} ++ ++#define parse_err(fmt, args...) do { \ ++ ERROR(fmt , ## args); \ ++ return 0; \ ++} while (0) ++ ++static int phram_setup(const char *val, struct kernel_param *kp) ++{ ++ char buf[64+12+12], *str = buf; ++ char *token[3]; ++ char *name; ++ uint32_t start; ++ uint32_t len; ++ int i, ret; ++ ++ if (strnlen(val, sizeof(str)) >= sizeof(str)) ++ parse_err("parameter too long\n"); ++ ++ strcpy(str, val); ++ ++ for (i=0; i<3; i++) ++ token[i] = strsep(&str, ","); ++ ++ if (str) ++ parse_err("too many arguments\n"); ++ ++ if (!token[2]) ++ parse_err("not enough arguments\n"); ++ ++ ret = parse_name(&name, token[0]); ++ if (ret == -ENOMEM) ++ parse_err("out of memory\n"); ++ if (ret == -ENOSPC) ++ parse_err("name too long\n"); ++ if (ret) ++ return 0; ++ ++ ret = parse_num32(&start, token[1]); ++ if (ret) ++ parse_err("illegal start address\n"); ++ ++ ret = parse_num32(&len, token[2]); ++ if (ret) ++ parse_err("illegal device length\n"); ++ ++ register_device(name, start, len); ++ ++ return 0; ++} ++ ++module_param_call(phram, phram_setup, NULL, NULL, 000); ++MODULE_PARM_DESC(phram, "Memory region to map. \"map=,\""); ++ ++/* ++ * Just for compatibility with slram, this is horrible and should go someday. ++ */ ++static int __init slram_setup(const char *val, struct kernel_param *kp) ++{ ++ char buf[256], *str = buf; ++ ++ if (!val || !val[0]) ++ parse_err("no arguments to \"slram=\"\n"); ++ ++ if (strnlen(val, sizeof(str)) >= sizeof(str)) ++ parse_err("parameter too long\n"); ++ ++ strcpy(str, val); ++ ++ while (str) { ++ char *token[3]; ++ char *name; ++ uint32_t start; ++ uint32_t len; ++ int i, ret; ++ ++ for (i=0; i<3; i++) { ++ token[i] = strsep(&str, ","); ++ if (token[i]) ++ continue; ++ parse_err("wrong number of arguments to \"slram=\"\n"); ++ } ++ ++ /* name */ ++ ret = parse_name(&name, token[0]); ++ if (ret == -ENOMEM) ++ parse_err("of memory\n"); ++ if (ret == -ENOSPC) ++ parse_err("too long\n"); ++ if (ret) ++ return 1; ++ ++ /* start */ ++ ret = parse_num32(&start, token[1]); ++ if (ret) ++ parse_err("illegal start address\n"); ++ ++ /* len */ ++ if (token[2][0] == '+') ++ ret = parse_num32(&len, token[2] + 1); ++ else ++ ret = parse_num32(&len, token[2]); ++ ++ if (ret) ++ parse_err("illegal device length\n"); ++ ++ if (token[2][0] != '+') { ++ if (len < start) ++ parse_err("end < start\n"); ++ len -= start; ++ } ++ ++ register_device(name, start, len); ++ } ++ return 1; ++} ++ ++module_param_call(slram, slram_setup, NULL, NULL, 000); ++MODULE_PARM_DESC(slram, "List of memory regions to map. \"map=,\""); ++ ++ ++int __init init_phram(void) ++{ ++ printk(KERN_ERR "phram loaded\n"); ++ return 0; ++} ++ ++static void __exit cleanup_phram(void) ++{ ++ unregister_devices(); ++} ++ ++module_init(init_phram); ++module_exit(cleanup_phram); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Jörn Engel "); ++MODULE_DESCRIPTION("MTD driver for physical RAM"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/pmc551.c linux/drivers/mtd/devices/pmc551.c +--- linux-mips-2.4.27/drivers/mtd/devices/pmc551.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/devices/pmc551.c 2004-11-19 10:25:11.862205416 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: pmc551.c,v 1.22 2003/01/24 13:34:30 dwmw2 Exp $ ++ * $Id: pmc551.c,v 1.25 2003/06/23 12:24:01 dwmw2 Exp $ + * + * PMC551 PCI Mezzanine Ram Device + * +@@ -681,11 +681,6 @@ + + printk(KERN_INFO PMC551_VERSION); + +- if(!pci_present()) { +- printk(KERN_NOTICE "pmc551: PCI not enabled.\n"); +- return -ENODEV; +- } +- + /* + * PCU-bus chipset probe. + */ +@@ -787,10 +782,10 @@ + mtd->write = pmc551_write; + mtd->point = pmc551_point; + mtd->unpoint = pmc551_unpoint; +- mtd->module = THIS_MODULE; + mtd->type = MTD_RAM; + mtd->name = "PMC551 RAM board"; + mtd->erasesize = 0x10000; ++ mtd->owner = THIS_MODULE; + + if (add_mtd_device(mtd)) { + printk(KERN_NOTICE "pmc551: Failed to register new device\n"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/slram.c linux/drivers/mtd/devices/slram.c +--- linux-mips-2.4.27/drivers/mtd/devices/slram.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/devices/slram.c 2004-11-19 10:25:11.863205264 +0100 +@@ -1,6 +1,6 @@ + /*====================================================================== + +- $Id: slram.c,v 1.28 2003/01/24 13:35:34 dwmw2 Exp $ ++ $Id: slram.c,v 1.30 2003/05/20 21:03:08 dwmw2 Exp $ + + This driver provides a method to access memory not used by the kernel + itself (i.e. if the kernel commandline mem=xxx is used). To actually +@@ -199,7 +199,7 @@ + (*curmtd)->mtdinfo->unpoint = slram_unpoint; + (*curmtd)->mtdinfo->read = slram_read; + (*curmtd)->mtdinfo->write = slram_write; +- (*curmtd)->mtdinfo->module = THIS_MODULE; ++ (*curmtd)->mtdinfo->owner = THIS_MODULE; + (*curmtd)->mtdinfo->type = MTD_RAM; + (*curmtd)->mtdinfo->erasesize = 0x0; + +diff -Nurb linux-mips-2.4.27/drivers/mtd/ftl.c linux/drivers/mtd/ftl.c +--- linux-mips-2.4.27/drivers/mtd/ftl.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/ftl.c 2004-11-19 10:25:11.630240680 +0100 +@@ -1,5 +1,5 @@ + /* This version ported to the Linux-MTD system by dwmw2@infradead.org +- * $Id: ftl.c,v 1.45 2003/01/24 23:31:27 dwmw2 Exp $ ++ * $Id: ftl.c,v 1.52 2003/08/11 09:00:44 dwmw2 Exp $ + * + * Fixes: Arnaldo Carvalho de Melo + * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups +@@ -55,8 +55,8 @@ + contact M-Systems (http://www.m-sys.com) directly. + + ======================================================================*/ ++#include + #include +-#include + #include + /*#define PSYCHO_DEBUG */ + +@@ -68,43 +68,13 @@ + #include + #include + #include +-#include ++#include + #include +- +-#if (LINUX_VERSION_CODE >= 0x20100) + #include +-#endif +-#if (LINUX_VERSION_CODE >= 0x20303) + #include +-#endif ++#include + + #include +-/*====================================================================*/ +-/* Stuff which really ought to be in compatmac.h */ +- +-#if (LINUX_VERSION_CODE < 0x20328) +-#define register_disk(dev, drive, minors, ops, size) \ +- do { (dev)->part[(drive)*(minors)].nr_sects = size; \ +- if (size == 0) (dev)->part[(drive)*(minors)].start_sect = -1; \ +- resetup_one_dev(dev, drive); } while (0) +-#endif +- +-#if (LINUX_VERSION_CODE < 0x20320) +-#define BLK_DEFAULT_QUEUE(n) blk_dev[n].request_fn +-#define blk_init_queue(q, req) q = (req) +-#define blk_cleanup_queue(q) q = NULL +-#define request_arg_t void +-#else +-#define request_arg_t request_queue_t *q +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14) +-#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT +-#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT +-#else +-#define BLK_INC_USE_COUNT do {} while(0) +-#define BLK_DEC_USE_COUNT do {} while(0) +-#endif + + /*====================================================================*/ + +@@ -119,19 +89,6 @@ + #define FTL_MAJOR 44 + #endif + +-/* Funky stuff for setting up a block device */ +-#define MAJOR_NR FTL_MAJOR +-#define DEVICE_NAME "ftl" +-#define DEVICE_REQUEST do_ftl_request +-#define DEVICE_ON(device) +-#define DEVICE_OFF(device) +- +-#define DEVICE_NR(minor) ((minor)>>5) +-#define REGION_NR(minor) (((minor)>>3)&3) +-#define PART_NR(minor) ((minor)&7) +-#define MINOR_NR(dev,reg,part) (((dev)<<5)+((reg)<<3)+(part)) +- +-#include + + /*====================================================================*/ + +@@ -142,8 +99,7 @@ + #define MAX_REGION 4 + + /* Maximum number of partitions in an FTL region */ +-#define PART_BITS 3 +-#define MAX_PART 8 ++#define PART_BITS 4 + + /* Maximum number of outstanding erase requests per socket */ + #define MAX_ERASE 8 +@@ -154,7 +110,7 @@ + + /* Each memory region corresponds to a minor device */ + typedef struct partition_t { +- struct mtd_info *mtd; ++ struct mtd_blktrans_dev mbd; + u_int32_t state; + u_int32_t *VirtualBlockMap; + u_int32_t *VirtualPageMap; +@@ -179,21 +135,10 @@ + region_info_t region; + memory_handle_t handle; + #endif +- atomic_t open; + } partition_t; + +-partition_t *myparts[MAX_MTD_DEVICES]; +- +-static void ftl_notify_add(struct mtd_info *mtd); +-static void ftl_notify_remove(struct mtd_info *mtd); +- + void ftl_freepart(partition_t *part); + +-static struct mtd_notifier ftl_notifier = { +- add: ftl_notify_add, +- remove: ftl_notify_remove, +-}; +- + /* Partition state flags */ + #define FTL_FORMATTED 0x01 + +@@ -204,51 +149,11 @@ + #define XFER_PREPARED 0x03 + #define XFER_FAILED 0x04 + +-static struct hd_struct ftl_hd[MINOR_NR(MAX_DEV, 0, 0)]; +-static int ftl_sizes[MINOR_NR(MAX_DEV, 0, 0)]; +-static int ftl_blocksizes[MINOR_NR(MAX_DEV, 0, 0)]; +- +-static struct gendisk ftl_gendisk = { +- major: FTL_MAJOR, +- major_name: "ftl", +- minor_shift: PART_BITS, +- max_p: MAX_PART, +-#if (LINUX_VERSION_CODE < 0x20328) +- max_nr: MAX_DEV*MAX_PART, +-#endif +- part: ftl_hd, +- sizes: ftl_sizes, +-}; +- + /*====================================================================*/ + +-static int ftl_ioctl(struct inode *inode, struct file *file, +- u_int cmd, u_long arg); +-static int ftl_open(struct inode *inode, struct file *file); +-static release_t ftl_close(struct inode *inode, struct file *file); +-static int ftl_reread_partitions(int minor); + + static void ftl_erase_callback(struct erase_info *done); + +-#if LINUX_VERSION_CODE < 0x20326 +-static struct file_operations ftl_blk_fops = { +- open: ftl_open, +- release: ftl_close, +- ioctl: ftl_ioctl, +- read: block_read, +- write: block_write, +- fsync: block_fsync +-}; +-#else +-static struct block_device_operations ftl_blk_fops = { +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14) +- owner: THIS_MODULE, +-#endif +- open: ftl_open, +- release: ftl_close, +- ioctl: ftl_ioctl, +-}; +-#endif + + /*====================================================================== + +@@ -264,13 +169,13 @@ + loff_t offset, max_offset; + int ret; + part->header.FormattedSize = 0; +- max_offset = (0x100000mtd->size)?0x100000:part->mtd->size; ++ max_offset = (0x100000mbd.mtd->size)?0x100000:part->mbd.mtd->size; + /* Search first megabyte for a valid FTL header */ + for (offset = 0; + (offset + sizeof(header)) < max_offset; +- offset += part->mtd->erasesize ? : 0x2000) { ++ offset += part->mbd.mtd->erasesize ? : 0x2000) { + +- ret = part->mtd->read(part->mtd, offset, sizeof(header), &ret, ++ ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret, + (unsigned char *)&header); + + if (ret) +@@ -283,15 +188,15 @@ + printk(KERN_NOTICE "ftl_cs: FTL header not found.\n"); + return -ENOENT; + } +- if ((le16_to_cpu(header.NumEraseUnits) > 65536) || header.BlockSize != 9 || ++ if (header.BlockSize != 9 || + (header.EraseUnitSize < 10) || (header.EraseUnitSize > 31) || + (header.NumTransferUnits >= le16_to_cpu(header.NumEraseUnits))) { + printk(KERN_NOTICE "ftl_cs: FTL header corrupt!\n"); + return -1; + } +- if ((1 << header.EraseUnitSize) != part->mtd->erasesize) { ++ if ((1 << header.EraseUnitSize) != part->mbd.mtd->erasesize) { + printk(KERN_NOTICE "ftl: FTL EraseUnitSize %x != MTD erasesize %x\n", +- 1 << header.EraseUnitSize,part->mtd->erasesize); ++ 1 << header.EraseUnitSize,part->mbd.mtd->erasesize); + return -1; + } + part->header = header; +@@ -326,7 +231,7 @@ + for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) { + offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN)) + << part->header.EraseUnitSize); +- ret = part->mtd->read(part->mtd, offset, sizeof(header), &retval, ++ ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval, + (unsigned char *)&header); + + if (ret) +@@ -391,7 +296,7 @@ + part->EUNInfo[i].Deleted = 0; + offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset); + +- ret = part->mtd->read(part->mtd, offset, ++ ret = part->mbd.mtd->read(part->mbd.mtd, offset, + part->BlocksPerUnit * sizeof(u_int32_t), &retval, + (unsigned char *)part->bam_cache); + +@@ -456,7 +361,7 @@ + erase->len = 1 << part->header.EraseUnitSize; + erase->priv = (u_long)part; + +- ret = part->mtd->erase(part->mtd, erase); ++ ret = part->mbd.mtd->erase(part->mbd.mtd, erase); + + if (!ret) + xfer->EraseCount++; +@@ -523,7 +428,7 @@ + header.LogicalEUN = cpu_to_le16(0xffff); + header.EraseCount = cpu_to_le32(xfer->EraseCount); + +- ret = part->mtd->write(part->mtd, xfer->Offset, sizeof(header), ++ ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset, sizeof(header), + &retlen, (u_char *)&header); + + if (ret) { +@@ -539,7 +444,7 @@ + + for (i = 0; i < nbam; i++, offset += sizeof(u_int32_t)) { + +- ret = part->mtd->write(part->mtd, offset, sizeof(u_int32_t), ++ ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t), + &retlen, (u_char *)&ctl); + + if (ret) +@@ -586,7 +491,7 @@ + + offset = eun->Offset + le32_to_cpu(part->header.BAMOffset); + +- ret = part->mtd->read(part->mtd, offset, ++ ret = part->mbd.mtd->read(part->mbd.mtd, offset, + part->BlocksPerUnit * sizeof(u_int32_t), + &retlen, (u_char *) (part->bam_cache)); + +@@ -604,7 +509,7 @@ + offset = xfer->Offset + 20; /* Bad! */ + unit = cpu_to_le16(0x7fff); + +- ret = part->mtd->write(part->mtd, offset, sizeof(u_int16_t), ++ ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t), + &retlen, (u_char *) &unit); + + if (ret) { +@@ -624,7 +529,7 @@ + break; + case BLOCK_DATA: + case BLOCK_REPLACEMENT: +- ret = part->mtd->read(part->mtd, src, SECTOR_SIZE, ++ ret = part->mbd.mtd->read(part->mbd.mtd, src, SECTOR_SIZE, + &retlen, (u_char *) buf); + if (ret) { + printk(KERN_WARNING "ftl: Error reading old xfer unit in copy_erase_unit\n"); +@@ -632,7 +537,7 @@ + } + + +- ret = part->mtd->write(part->mtd, dest, SECTOR_SIZE, ++ ret = part->mbd.mtd->write(part->mbd.mtd, dest, SECTOR_SIZE, + &retlen, (u_char *) buf); + if (ret) { + printk(KERN_WARNING "ftl: Error writing new xfer unit in copy_erase_unit\n"); +@@ -651,7 +556,7 @@ + } + + /* Write the BAM to the transfer unit */ +- ret = part->mtd->write(part->mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset), ++ ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset), + part->BlocksPerUnit * sizeof(int32_t), &retlen, + (u_char *)part->bam_cache); + if (ret) { +@@ -661,7 +566,7 @@ + + + /* All clear? Then update the LogicalEUN again */ +- ret = part->mtd->write(part->mtd, xfer->Offset + 20, sizeof(u_int16_t), ++ ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t), + &retlen, (u_char *)&srcunitswap); + + if (ret) { +@@ -749,8 +654,8 @@ + if (queued) { + DEBUG(1, "ftl_cs: waiting for transfer " + "unit to be prepared...\n"); +- if (part->mtd->sync) +- part->mtd->sync(part->mtd); ++ if (part->mbd.mtd->sync) ++ part->mbd.mtd->sync(part->mbd.mtd); + } else { + static int ne = 0; + if (++ne < 5) +@@ -848,7 +753,7 @@ + /* Invalidate cache */ + part->bam_index = 0xffff; + +- ret = part->mtd->read(part->mtd, ++ ret = part->mbd.mtd->read(part->mbd.mtd, + part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset), + part->BlocksPerUnit * sizeof(u_int32_t), + &retlen, (u_char *) (part->bam_cache)); +@@ -877,78 +782,6 @@ + + } /* find_free */ + +-/*====================================================================== +- +- This gets a memory handle for the region corresponding to the +- minor device number. +- +-======================================================================*/ +- +-static int ftl_open(struct inode *inode, struct file *file) +-{ +- int minor = MINOR(inode->i_rdev); +- partition_t *partition; +- +- if (minor>>4 >= MAX_MTD_DEVICES) +- return -ENODEV; +- +- partition = myparts[minor>>4]; +- +- if (!partition) +- return -ENODEV; +- +- if (partition->state != FTL_FORMATTED) +- return -ENXIO; +- +- if (ftl_gendisk.part[minor].nr_sects == 0) +- return -ENXIO; +- +- BLK_INC_USE_COUNT; +- +- if (!get_mtd_device(partition->mtd, -1)) { +- BLK_DEC_USE_COUNT; +- return -ENXIO; +- } +- +- if ((file->f_mode & 2) && !(partition->mtd->flags & MTD_CLEAR_BITS) ) { +- put_mtd_device(partition->mtd); +- BLK_DEC_USE_COUNT; +- return -EROFS; +- } +- +- DEBUG(0, "ftl_cs: ftl_open(%d)\n", minor); +- +- atomic_inc(&partition->open); +- +- return 0; +-} +- +-/*====================================================================*/ +- +-static release_t ftl_close(struct inode *inode, struct file *file) +-{ +- int minor = MINOR(inode->i_rdev); +- partition_t *part = myparts[minor >> 4]; +- int i; +- +- DEBUG(0, "ftl_cs: ftl_close(%d)\n", minor); +- +- /* Wait for any pending erase operations to complete */ +- if (part->mtd->sync) +- part->mtd->sync(part->mtd); +- +- for (i = 0; i < part->header.NumTransferUnits; i++) { +- if (part->XferInfo[i].state == XFER_ERASED) +- prepare_xfer(part, i); +- } +- +- atomic_dec(&part->open); +- +- put_mtd_device(part->mtd); +- BLK_DEC_USE_COUNT; +- release_return(0); +-} /* ftl_close */ +- + + /*====================================================================== + +@@ -983,7 +816,7 @@ + else { + offset = (part->EUNInfo[log_addr / bsize].Offset + + (log_addr % bsize)); +- ret = part->mtd->read(part->mtd, offset, SECTOR_SIZE, ++ ret = part->mbd.mtd->read(part->mbd.mtd, offset, SECTOR_SIZE, + &retlen, (u_char *) buffer); + + if (ret) { +@@ -1022,7 +855,7 @@ + le32_to_cpu(part->header.BAMOffset)); + + #ifdef PSYCHO_DEBUG +- ret = part->mtd->read(part->mtd, offset, sizeof(u_int32_t), ++ ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t), + &retlen, (u_char *)&old_addr); + if (ret) { + printk(KERN_WARNING"ftl: Error reading old_addr in set_bam_entry: %d\n",ret); +@@ -1059,7 +892,7 @@ + #endif + part->bam_cache[blk] = le_virt_addr; + } +- ret = part->mtd->write(part->mtd, offset, sizeof(u_int32_t), ++ ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t), + &retlen, (u_char *)&le_virt_addr); + + if (ret) { +@@ -1119,7 +952,7 @@ + part->EUNInfo[part->bam_index].Deleted++; + offset = (part->EUNInfo[part->bam_index].Offset + + blk * SECTOR_SIZE); +- ret = part->mtd->write(part->mtd, offset, SECTOR_SIZE, &retlen, ++ ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen, + buffer); + + if (ret) { +@@ -1151,164 +984,32 @@ + return 0; + } /* ftl_write */ + +-/*====================================================================== +- +- IOCTL calls for getting device parameters. +- +-======================================================================*/ +- +-static int ftl_ioctl(struct inode *inode, struct file *file, +- u_int cmd, u_long arg) ++static int ftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo) + { +- struct hd_geometry *geo = (struct hd_geometry *)arg; +- int ret = 0, minor = MINOR(inode->i_rdev); +- partition_t *part= myparts[minor >> 4]; ++ partition_t *part = (void *)dev; + u_long sect; + +- if (!part) +- return -ENODEV; /* How? */ +- +- switch (cmd) { +- case HDIO_GETGEO: +- ret = verify_area(VERIFY_WRITE, (long *)arg, sizeof(*geo)); +- if (ret) return ret; +- /* Sort of arbitrary: round size down to 4K boundary */ ++ /* Sort of arbitrary: round size down to 4KiB boundary */ + sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE; +- put_user(1, (char *)&geo->heads); +- put_user(8, (char *)&geo->sectors); +- put_user((sect>>3), (short *)&geo->cylinders); +- put_user(ftl_hd[minor].start_sect, (u_long *)&geo->start); +- break; +- case BLKGETSIZE: +- ret = put_user(ftl_hd[minor].nr_sects, (unsigned long *)arg); +- break; +-#ifdef BLKGETSIZE64 +- case BLKGETSIZE64: +- ret = put_user((u64)ftl_hd[minor].nr_sects << 9, (u64 *)arg); +- break; +-#endif +- case BLKRRPART: +- ret = ftl_reread_partitions(minor); +- break; +-#if (LINUX_VERSION_CODE < 0x20303) +- case BLKFLSBUF: +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) +- if (!capable(CAP_SYS_ADMIN)) return -EACCES; +-#endif +- fsync_dev(inode->i_rdev); +- invalidate_buffers(inode->i_rdev); +- break; +- RO_IOCTLS(inode->i_rdev, arg); +-#else +- case BLKROSET: +- case BLKROGET: +- case BLKFLSBUF: +- ret = blk_ioctl(inode->i_rdev, cmd, arg); +- break; +-#endif +- default: +- ret = -EINVAL; +- } +- +- return ret; +-} /* ftl_ioctl */ +- +-/*====================================================================== + +- Handler for block device requests ++ geo->heads = 1; ++ geo->sectors = 8; ++ geo->cylinders = sect >> 3; + +-======================================================================*/ +- +-static int ftl_reread_partitions(int minor) +-{ +- partition_t *part = myparts[minor >> 4]; +- int i, whole; +- +- DEBUG(0, "ftl_cs: ftl_reread_partition(%d)\n", minor); +- if ((atomic_read(&part->open) > 1)) { +- return -EBUSY; +- } +- whole = minor & ~(MAX_PART-1); +- +- i = MAX_PART - 1; +- while (i-- > 0) { +- if (ftl_hd[whole+i].nr_sects > 0) { +- kdev_t rdev = MKDEV(FTL_MAJOR, whole+i); +- +- invalidate_device(rdev, 1); +- } +- ftl_hd[whole+i].start_sect = 0; +- ftl_hd[whole+i].nr_sects = 0; +- } +- +- scan_header(part); +- +- register_disk(&ftl_gendisk, whole >> PART_BITS, MAX_PART, +- &ftl_blk_fops, le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE); +- +-#ifdef PCMCIA_DEBUG +- for (i = 0; i < MAX_PART; i++) { +- if (ftl_hd[whole+i].nr_sects > 0) +- printk(KERN_INFO " %d: start %ld size %ld\n", i, +- ftl_hd[whole+i].start_sect, +- ftl_hd[whole+i].nr_sects); +- } +-#endif + return 0; + } + +-/*====================================================================== +- +- Handler for block device requests +- +-======================================================================*/ +- +-static void do_ftl_request(request_arg_t) ++static int ftl_readsect(struct mtd_blktrans_dev *dev, ++ unsigned long block, char *buf) + { +- int ret, minor; +- partition_t *part; +- +- do { +- // sti(); +- INIT_REQUEST; +- +- minor = MINOR(CURRENT->rq_dev); +- +- part = myparts[minor >> 4]; +- if (part) { +- ret = 0; +- +- switch (CURRENT->cmd) { +- case READ: +- ret = ftl_read(part, CURRENT->buffer, +- CURRENT->sector+ftl_hd[minor].start_sect, +- CURRENT->current_nr_sectors); +- if (ret) printk("ftl_read returned %d\n", ret); +- break; +- +- case WRITE: +- ret = ftl_write(part, CURRENT->buffer, +- CURRENT->sector+ftl_hd[minor].start_sect, +- CURRENT->current_nr_sectors); +- if (ret) printk("ftl_write returned %d\n", ret); +- break; +- +- default: +- panic("ftl_cs: unknown block command!\n"); +- +- } +- } else { +- ret = 1; +- printk("NULL part in ftl_request\n"); +- } +- +- if (!ret) { +- CURRENT->sector += CURRENT->current_nr_sectors; +- } ++ return ftl_read((void *)dev, buf, block, 1); ++} + +- end_request((ret == 0) ? 1 : 0); +- } while (1); +-} /* do_ftl_request */ ++static int ftl_writesect(struct mtd_blktrans_dev *dev, ++ unsigned long block, char *buf) ++{ ++ return ftl_write((void *)dev, buf, block, 1); ++} + + /*====================================================================*/ + +@@ -1337,19 +1038,9 @@ + + } /* ftl_freepart */ + +-static void ftl_notify_add(struct mtd_info *mtd) ++static void ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) + { + partition_t *partition; +- int device; +- +- for (device=0; device < MAX_MTD_DEVICES && myparts[device]; device++) +- ; +- +- if (device == MAX_MTD_DEVICES) { +- printk(KERN_NOTICE "Maximum number of FTL partitions reached\n" +- "Not scanning <%s>\n", mtd->name); +- return; +- } + + partition = kmalloc(sizeof(partition_t), GFP_KERNEL); + +@@ -1361,92 +1052,55 @@ + + memset(partition, 0, sizeof(partition_t)); + +- partition->mtd = mtd; ++ partition->mbd.mtd = mtd; + + if ((scan_header(partition) == 0) && + (build_maps(partition) == 0)) { + + partition->state = FTL_FORMATTED; +- atomic_set(&partition->open, 0); +- myparts[device] = partition; +- ftl_reread_partitions(device << 4); + #ifdef PCMCIA_DEBUG +- printk(KERN_INFO "ftl_cs: opening %d kb FTL partition\n", ++ printk(KERN_INFO "ftl_cs: opening %d KiB FTL partition\n", + le32_to_cpu(partition->header.FormattedSize) >> 10); + #endif ++ partition->mbd.size = le32_to_cpu(partition->header.FormattedSize) >> 9; ++ partition->mbd.blksize = SECTOR_SIZE; ++ partition->mbd.tr = tr; ++ partition->mbd.devnum = -1; ++ if (add_mtd_blktrans_dev((void *)partition)) ++ kfree(partition); ++ + } else + kfree(partition); + } + +-static void ftl_notify_remove(struct mtd_info *mtd) ++static void ftl_remove_dev(struct mtd_blktrans_dev *dev) + { +- int i,j; +- +- /* Q: What happens if you try to remove a device which has +- * a currently-open FTL partition on it? +- * +- * A: You don't. The ftl_open routine is responsible for +- * increasing the use count of the driver module which +- * it uses. +- */ +- +- /* That's the theory, anyway :) */ +- +- for (i=0; i< MAX_MTD_DEVICES; i++) +- if (myparts[i] && myparts[i]->mtd == mtd) { +- +- if (myparts[i]->state == FTL_FORMATTED) +- ftl_freepart(myparts[i]); +- +- myparts[i]->state = 0; +- for (j=0; j<16; j++) { +- ftl_gendisk.part[j].nr_sects=0; +- ftl_gendisk.part[j].start_sect=0; +- } +- kfree(myparts[i]); +- myparts[i] = NULL; +- } ++ del_mtd_blktrans_dev(dev); ++ kfree(dev); + } + ++struct mtd_blktrans_ops ftl_tr = { ++ .name = "ftl", ++ .major = FTL_MAJOR, ++ .part_bits = PART_BITS, ++ .readsect = ftl_readsect, ++ .writesect = ftl_writesect, ++ .getgeo = ftl_getgeo, ++ .add_mtd = ftl_add_mtd, ++ .remove_dev = ftl_remove_dev, ++ .owner = THIS_MODULE, ++}; ++ + int init_ftl(void) + { +- int i; +- +- memset(myparts, 0, sizeof(myparts)); ++ DEBUG(0, "$Id: ftl.c,v 1.52 2003/08/11 09:00:44 dwmw2 Exp $\n"); + +- DEBUG(0, "$Id: ftl.c,v 1.45 2003/01/24 23:31:27 dwmw2 Exp $\n"); +- +- if (register_blkdev(FTL_MAJOR, "ftl", &ftl_blk_fops)) { +- printk(KERN_NOTICE "ftl_cs: unable to grab major " +- "device number!\n"); +- return -EAGAIN; +- } +- +- for (i = 0; i < MINOR_NR(MAX_DEV, 0, 0); i++) +- ftl_blocksizes[i] = 1024; +- for (i = 0; i < MAX_DEV*MAX_PART; i++) { +- ftl_hd[i].nr_sects = 0; +- ftl_hd[i].start_sect = 0; +- } +- blksize_size[FTL_MAJOR] = ftl_blocksizes; +- ftl_gendisk.major = FTL_MAJOR; +- blk_init_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR), &do_ftl_request); +- add_gendisk(&ftl_gendisk); +- +- register_mtd_user(&ftl_notifier); +- +- return 0; ++ return register_mtd_blktrans(&ftl_tr); + } + + static void __exit cleanup_ftl(void) + { +- unregister_mtd_user(&ftl_notifier); +- +- unregister_blkdev(FTL_MAJOR, "ftl"); +- blk_cleanup_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR)); +- blksize_size[FTL_MAJOR] = NULL; +- +- del_gendisk(&ftl_gendisk); ++ deregister_mtd_blktrans(&ftl_tr); + } + + module_init(init_ftl); +diff -Nurb linux-mips-2.4.27/drivers/mtd/inftlcore.c linux/drivers/mtd/inftlcore.c +--- linux-mips-2.4.27/drivers/mtd/inftlcore.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/inftlcore.c 2004-11-19 10:25:11.632240376 +0100 +@@ -0,0 +1,900 @@ ++/* ++ * inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL) ++ * ++ * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) ++ * ++ * Based heavily on the nftlcore.c code which is: ++ * (c) 1999 Machine Vision Holdings, Inc. ++ * Author: David Woodhouse ++ * ++ * $Id: inftlcore.c,v 1.14 2003/06/26 08:28:26 dwmw2 Exp $ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * Maximum number of loops while examining next block, to have a ++ * chance to detect consistency problems (they should never happen ++ * because of the checks done in the mounting. ++ */ ++#define MAX_LOOPS 10000 ++ ++extern void INFTL_dumptables(struct INFTLrecord *inftl); ++extern void INFTL_dumpVUchains(struct INFTLrecord *inftl); ++ ++static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) ++{ ++ struct INFTLrecord *inftl; ++ unsigned long temp; ++ ++ if (mtd->ecctype != MTD_ECC_RS_DiskOnChip) ++ return; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: add_mtd for %s\n", mtd->name); ++ ++ inftl = kmalloc(sizeof(*inftl), GFP_KERNEL); ++ ++ if (!inftl) { ++ printk(KERN_WARNING "INFTL: Out of memory for data structures\n"); ++ return; ++ } ++ memset(inftl, 0, sizeof(*inftl)); ++ ++ inftl->mbd.mtd = mtd; ++ inftl->mbd.devnum = -1; ++ inftl->mbd.blksize = 512; ++ inftl->mbd.tr = tr; ++ ++ if (INFTL_mount(inftl) < 0) { ++ printk(KERN_WARNING "INFTL: could not mount device\n"); ++ kfree(inftl); ++ return; ++ } ++ ++ /* OK, it's a new one. Set up all the data structures. */ ++ ++ /* Calculate geometry */ ++ inftl->cylinders = 1024; ++ inftl->heads = 16; ++ ++ temp = inftl->cylinders * inftl->heads; ++ inftl->sectors = inftl->mbd.size / temp; ++ if (inftl->mbd.size % temp) { ++ inftl->sectors++; ++ temp = inftl->cylinders * inftl->sectors; ++ inftl->heads = inftl->mbd.size / temp; ++ ++ if (inftl->mbd.size % temp) { ++ inftl->heads++; ++ temp = inftl->heads * inftl->sectors; ++ inftl->cylinders = inftl->mbd.size / temp; ++ } ++ } ++ ++ if (inftl->mbd.size != inftl->heads * inftl->cylinders * inftl->sectors) { ++ /* ++ Oh no we don't have ++ mbd.size == heads * cylinders * sectors ++ */ ++ printk(KERN_WARNING "INFTL: cannot calculate a geometry to " ++ "match size of 0x%lx.\n", inftl->mbd.size); ++ printk(KERN_WARNING "INFTL: using C:%d H:%d S:%d " ++ "(== 0x%lx sects)\n", ++ inftl->cylinders, inftl->heads , inftl->sectors, ++ (long)inftl->cylinders * (long)inftl->heads * ++ (long)inftl->sectors ); ++ } ++ ++ if (add_mtd_blktrans_dev(&inftl->mbd)) { ++ if (inftl->PUtable) ++ kfree(inftl->PUtable); ++ if (inftl->VUtable) ++ kfree(inftl->VUtable); ++ kfree(inftl); ++ return; ++ } ++#ifdef PSYCHO_DEBUG ++ printk(KERN_INFO "INFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a'); ++#endif ++ return; ++} ++ ++static void inftl_remove_dev(struct mtd_blktrans_dev *dev) ++{ ++ struct INFTLrecord *inftl = (void *)dev; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: remove_dev (i=%d)\n", dev->devnum); ++ ++ del_mtd_blktrans_dev(dev); ++ ++ if (inftl->PUtable) ++ kfree(inftl->PUtable); ++ if (inftl->VUtable) ++ kfree(inftl->VUtable); ++ kfree(inftl); ++} ++ ++/* ++ * Actual INFTL access routines. ++ */ ++ ++/* ++ * INFTL_findfreeblock: Find a free Erase Unit on the INFTL partition. ++ * This function is used when the give Virtual Unit Chain. ++ */ ++static u16 INFTL_findfreeblock(struct INFTLrecord *inftl, int desperate) ++{ ++ u16 pot = inftl->LastFreeEUN; ++ int silly = inftl->nb_blocks; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findfreeblock(inftl=0x%x," ++ "desperate=%d)\n", (int)inftl, desperate); ++ ++ /* ++ * Normally, we force a fold to happen before we run out of free ++ * blocks completely. ++ */ ++ if (!desperate && inftl->numfreeEUNs < 2) { ++ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: there are too few free " ++ "EUNs (%d)\n", inftl->numfreeEUNs); ++ return 0xffff; ++ } ++ ++ /* Scan for a free block */ ++ do { ++ if (inftl->PUtable[pot] == BLOCK_FREE) { ++ inftl->LastFreeEUN = pot; ++ return pot; ++ } ++ ++ if (++pot > inftl->lastEUN) ++ pot = 0; ++ ++ if (!silly--) { ++ printk(KERN_WARNING "INFTL: no free blocks found! " ++ "EUN range = %d - %d\n", 0, inftl->LastFreeEUN); ++ return BLOCK_NIL; ++ } ++ } while (pot != inftl->LastFreeEUN); ++ ++ return BLOCK_NIL; ++} ++ ++static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned pendingblock) ++{ ++ u16 BlockMap[MAX_SECTORS_PER_UNIT]; ++ unsigned char BlockDeleted[MAX_SECTORS_PER_UNIT]; ++ unsigned int thisEUN, prevEUN, status; ++ int block, silly; ++ unsigned int targetEUN; ++ struct inftl_oob oob; ++ size_t retlen; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_foldchain(inftl=0x%x,thisVUC=%d," ++ "pending=%d)\n", (int)inftl, thisVUC, pendingblock); ++ ++ memset(BlockMap, 0xff, sizeof(BlockMap)); ++ memset(BlockDeleted, 0, sizeof(BlockDeleted)); ++ ++ thisEUN = targetEUN = inftl->VUtable[thisVUC]; ++ ++ if (thisEUN == BLOCK_NIL) { ++ printk(KERN_WARNING "INFTL: trying to fold non-existent " ++ "Virtual Unit Chain %d!\n", thisVUC); ++ return BLOCK_NIL; ++ } ++ ++ /* ++ * Scan to find the Erase Unit which holds the actual data for each ++ * 512-byte block within the Chain. ++ */ ++ silly = MAX_LOOPS; ++ while (thisEUN < inftl->nb_blocks) { ++ for (block = 0; block < inftl->EraseSize/SECTORSIZE; block ++) { ++ if ((BlockMap[block] != 0xffff) || BlockDeleted[block]) ++ continue; ++ ++ if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) ++ + (block * SECTORSIZE), 16 , &retlen, ++ (char *)&oob) < 0) ++ status = SECTOR_IGNORE; ++ else ++ status = oob.b.Status | oob.b.Status1; ++ ++ switch(status) { ++ case SECTOR_FREE: ++ case SECTOR_IGNORE: ++ break; ++ case SECTOR_USED: ++ BlockMap[block] = thisEUN; ++ continue; ++ case SECTOR_DELETED: ++ BlockDeleted[block] = 1; ++ continue; ++ default: ++ printk(KERN_WARNING "INFTL: unknown status " ++ "for block %d in EUN %d: %x\n", ++ block, thisEUN, status); ++ break; ++ } ++ } ++ ++ if (!silly--) { ++ printk(KERN_WARNING "INFTL: infinite loop in Virtual " ++ "Unit Chain 0x%x\n", thisVUC); ++ return BLOCK_NIL; ++ } ++ ++ thisEUN = inftl->PUtable[thisEUN]; ++ } ++ ++ /* ++ * OK. We now know the location of every block in the Virtual Unit ++ * Chain, and the Erase Unit into which we are supposed to be copying. ++ * Go for it. ++ */ ++ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: folding chain %d into unit %d\n", ++ thisVUC, targetEUN); ++ ++ for (block = 0; block < inftl->EraseSize/SECTORSIZE ; block++) { ++ unsigned char movebuf[SECTORSIZE]; ++ int ret; ++ ++ /* ++ * If it's in the target EUN already, or if it's pending write, ++ * do nothing. ++ */ ++ if (BlockMap[block] == targetEUN || (pendingblock == ++ (thisVUC * (inftl->EraseSize / SECTORSIZE) + block))) { ++ continue; ++ } ++ ++ /* ++ * Copy only in non free block (free blocks can only ++ * happen in case of media errors or deleted blocks). ++ */ ++ if (BlockMap[block] == BLOCK_NIL) ++ continue; ++ ++ ret = MTD_READECC(inftl->mbd.mtd, (inftl->EraseSize * ++ BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE, ++ &retlen, movebuf, (char *)&oob, NULL); ++ if (ret < 0) { ++ ret = MTD_READECC(inftl->mbd.mtd, (inftl->EraseSize * ++ BlockMap[block]) + (block * SECTORSIZE), ++ SECTORSIZE, &retlen, movebuf, (char *)&oob, ++ NULL); ++ if (ret != -EIO) ++ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went " ++ "away on retry?\n"); ++ } ++ MTD_WRITEECC(inftl->mbd.mtd, (inftl->EraseSize * targetEUN) + ++ (block * SECTORSIZE), SECTORSIZE, &retlen, ++ movebuf, (char *)&oob, NULL); ++ } ++ ++ /* ++ * Newest unit in chain now contains data from _all_ older units. ++ * So go through and erase each unit in chain, oldest first. (This ++ * is important, by doing oldest first if we crash/reboot then it ++ * it is relatively simple to clean up the mess). ++ */ ++ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: want to erase virtual chain %d\n", ++ thisVUC); ++ ++ for (;;) { ++ /* Find oldest unit in chain. */ ++ thisEUN = inftl->VUtable[thisVUC]; ++ prevEUN = BLOCK_NIL; ++ while (inftl->PUtable[thisEUN] != BLOCK_NIL) { ++ prevEUN = thisEUN; ++ thisEUN = inftl->PUtable[thisEUN]; ++ } ++ ++ /* Check if we are all done */ ++ if (thisEUN == targetEUN) ++ break; ++ ++ if (INFTL_formatblock(inftl, thisEUN) < 0) { ++ /* ++ * Could not erase : mark block as reserved. ++ * FixMe: Update Bad Unit Table on disk. ++ */ ++ inftl->PUtable[thisEUN] = BLOCK_RESERVED; ++ } else { ++ /* Correctly erased : mark it as free */ ++ inftl->PUtable[thisEUN] = BLOCK_FREE; ++ inftl->PUtable[prevEUN] = BLOCK_NIL; ++ inftl->numfreeEUNs++; ++ } ++ } ++ ++ return targetEUN; ++} ++ ++u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock) ++{ ++ /* ++ * This is the part that needs some cleverness applied. ++ * For now, I'm doing the minimum applicable to actually ++ * get the thing to work. ++ * Wear-levelling and other clever stuff needs to be implemented ++ * and we also need to do some assessment of the results when ++ * the system loses power half-way through the routine. ++ */ ++ u16 LongestChain = 0; ++ u16 ChainLength = 0, thislen; ++ u16 chain, EUN; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_makefreeblock(inftl=0x%x," ++ "pending=%d)\n", (int)inftl, pendingblock); ++ ++ for (chain = 0; chain < inftl->nb_blocks; chain++) { ++ EUN = inftl->VUtable[chain]; ++ thislen = 0; ++ ++ while (EUN <= inftl->lastEUN) { ++ thislen++; ++ EUN = inftl->PUtable[EUN]; ++ if (thislen > 0xff00) { ++ printk(KERN_WARNING "INFTL: endless loop in " ++ "Virtual Chain %d: Unit %x\n", ++ chain, EUN); ++ /* ++ * Actually, don't return failure. ++ * Just ignore this chain and get on with it. ++ */ ++ thislen = 0; ++ break; ++ } ++ } ++ ++ if (thislen > ChainLength) { ++ ChainLength = thislen; ++ LongestChain = chain; ++ } ++ } ++ ++ if (ChainLength < 2) { ++ printk(KERN_WARNING "INFTL: no Virtual Unit Chains available " ++ "for folding. Failing request\n"); ++ return BLOCK_NIL; ++ } ++ ++ return INFTL_foldchain(inftl, LongestChain, pendingblock); ++} ++ ++static int nrbits(unsigned int val, int bitcount) ++{ ++ int i, total = 0; ++ ++ for (i = 0; (i < bitcount); i++) ++ total += (((0x1 << i) & val) ? 1 : 0); ++ return total; ++} ++ ++/* ++ * INFTL_findwriteunit: Return the unit number into which we can write ++ * for this block. Make it available if it isn't already. ++ */ ++static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block) ++{ ++ unsigned int thisVUC = block / (inftl->EraseSize / SECTORSIZE); ++ unsigned int thisEUN, writeEUN, prev_block, status; ++ unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize -1); ++ struct inftl_oob oob; ++ struct inftl_bci bci; ++ unsigned char anac, nacs, parity; ++ size_t retlen; ++ int silly, silly2 = 3; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findwriteunit(inftl=0x%x," ++ "block=%d)\n", (int)inftl, block); ++ ++ do { ++ /* ++ * Scan the media to find a unit in the VUC which has ++ * a free space for the block in question. ++ */ ++ writeEUN = BLOCK_NIL; ++ thisEUN = inftl->VUtable[thisVUC]; ++ silly = MAX_LOOPS; ++ ++ while (thisEUN <= inftl->lastEUN) { ++ MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) + ++ blockofs, 8, &retlen, (char *)&bci); ++ ++ status = bci.Status | bci.Status1; ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: status of block %d in " ++ "EUN %d is %x\n", block , writeEUN, status); ++ ++ switch(status) { ++ case SECTOR_FREE: ++ writeEUN = thisEUN; ++ break; ++ case SECTOR_DELETED: ++ case SECTOR_USED: ++ /* Can't go any further */ ++ goto hitused; ++ case SECTOR_IGNORE: ++ break; ++ default: ++ /* ++ * Invalid block. Don't use it any more. ++ * Must implement. ++ */ ++ break; ++ } ++ ++ if (!silly--) { ++ printk(KERN_WARNING "INFTL: infinite loop in " ++ "Virtual Unit Chain 0x%x\n", thisVUC); ++ return 0xffff; ++ } ++ ++ /* Skip to next block in chain */ ++ thisEUN = inftl->PUtable[thisEUN]; ++ } ++ ++hitused: ++ if (writeEUN != BLOCK_NIL) ++ return writeEUN; ++ ++ ++ /* ++ * OK. We didn't find one in the existing chain, or there ++ * is no existing chain. Allocate a new one. ++ */ ++ writeEUN = INFTL_findfreeblock(inftl, 0); ++ ++ if (writeEUN == BLOCK_NIL) { ++ /* ++ * That didn't work - there were no free blocks just ++ * waiting to be picked up. We're going to have to fold ++ * a chain to make room. ++ */ ++ thisEUN = INFTL_makefreeblock(inftl, 0xffff); ++ ++ /* ++ * Hopefully we free something, lets try again. ++ * This time we are desperate... ++ */ ++ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: using desperate==1 " ++ "to find free EUN to accommodate write to " ++ "VUC %d\n", thisVUC); ++ writeEUN = INFTL_findfreeblock(inftl, 1); ++ if (writeEUN == BLOCK_NIL) { ++ /* ++ * Ouch. This should never happen - we should ++ * always be able to make some room somehow. ++ * If we get here, we've allocated more storage ++ * space than actual media, or our makefreeblock ++ * routine is missing something. ++ */ ++ printk(KERN_WARNING "INFTL: cannot make free " ++ "space.\n"); ++#ifdef DEBUG ++ INFTL_dumptables(inftl); ++ INFTL_dumpVUchains(inftl); ++#endif ++ return BLOCK_NIL; ++ } ++ } ++ ++ /* ++ * Insert new block into virtual chain. Firstly update the ++ * block headers in flash... ++ */ ++ anac = 0; ++ nacs = 0; ++ thisEUN = inftl->VUtable[thisVUC]; ++ if (thisEUN != BLOCK_NIL) { ++ MTD_READOOB(inftl->mbd.mtd, thisEUN * inftl->EraseSize ++ + 8, 8, &retlen, (char *)&oob.u); ++ anac = oob.u.a.ANAC + 1; ++ nacs = oob.u.a.NACs + 1; ++ } ++ ++ prev_block = inftl->VUtable[thisVUC]; ++ if (prev_block < inftl->nb_blocks) ++ prev_block -= inftl->firstEUN; ++ ++ parity = (nrbits(thisVUC, 16) & 0x1) ? 0x1 : 0; ++ parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0; ++ parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0; ++ parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0; ++ ++ oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC); ++ oob.u.a.prevUnitNo = cpu_to_le16(prev_block); ++ oob.u.a.ANAC = anac; ++ oob.u.a.NACs = nacs; ++ oob.u.a.parityPerField = parity; ++ oob.u.a.discarded = 0xaa; ++ ++ MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize + 8, 8, ++ &retlen, (char *)&oob.u); ++ ++ /* Also back up header... */ ++ oob.u.b.virtualUnitNo = cpu_to_le16(thisVUC); ++ oob.u.b.prevUnitNo = cpu_to_le16(prev_block); ++ oob.u.b.ANAC = anac; ++ oob.u.b.NACs = nacs; ++ oob.u.b.parityPerField = parity; ++ oob.u.b.discarded = 0xaa; ++ ++ MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize + ++ SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u); ++ ++ inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC]; ++ inftl->VUtable[thisVUC] = writeEUN; ++ ++ inftl->numfreeEUNs--; ++ return writeEUN; ++ ++ } while (silly2--); ++ ++ printk(KERN_WARNING "INFTL: error folding to make room for Virtual " ++ "Unit Chain 0x%x\n", thisVUC); ++ return 0xffff; ++} ++ ++/* ++ * Given a Virtual Unit Chain, see if it can be deleted, and if so do it. ++ */ ++static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC) ++{ ++ unsigned char BlockUsed[MAX_SECTORS_PER_UNIT]; ++ unsigned char BlockDeleted[MAX_SECTORS_PER_UNIT]; ++ unsigned int thisEUN, status; ++ int block, silly; ++ struct inftl_bci bci; ++ size_t retlen; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_trydeletechain(inftl=0x%x," ++ "thisVUC=%d)\n", (int)inftl, thisVUC); ++ ++ memset(BlockUsed, 0, sizeof(BlockUsed)); ++ memset(BlockDeleted, 0, sizeof(BlockDeleted)); ++ ++ thisEUN = inftl->VUtable[thisVUC]; ++ if (thisEUN == BLOCK_NIL) { ++ printk(KERN_WARNING "INFTL: trying to delete non-existent " ++ "Virtual Unit Chain %d!\n", thisVUC); ++ return; ++ } ++ ++ /* ++ * Scan through the Erase Units to determine whether any data is in ++ * each of the 512-byte blocks within the Chain. ++ */ ++ silly = MAX_LOOPS; ++ while (thisEUN < inftl->nb_blocks) { ++ for (block = 0; block < inftl->EraseSize/SECTORSIZE; block++) { ++ if (BlockUsed[block] || BlockDeleted[block]) ++ continue; ++ ++ if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) ++ + (block * SECTORSIZE), 8 , &retlen, ++ (char *)&bci) < 0) ++ status = SECTOR_IGNORE; ++ else ++ status = bci.Status | bci.Status1; ++ ++ switch(status) { ++ case SECTOR_FREE: ++ case SECTOR_IGNORE: ++ break; ++ case SECTOR_USED: ++ BlockUsed[block] = 1; ++ continue; ++ case SECTOR_DELETED: ++ BlockDeleted[block] = 1; ++ continue; ++ default: ++ printk(KERN_WARNING "INFTL: unknown status " ++ "for block %d in EUN %d: 0x%x\n", ++ block, thisEUN, status); ++ } ++ } ++ ++ if (!silly--) { ++ printk(KERN_WARNING "INFTL: infinite loop in Virtual " ++ "Unit Chain 0x%x\n", thisVUC); ++ return; ++ } ++ ++ thisEUN = inftl->PUtable[thisEUN]; ++ } ++ ++ for (block = 0; block < inftl->EraseSize/SECTORSIZE; block++) ++ if (BlockUsed[block]) ++ return; ++ ++ /* ++ * For each block in the chain free it and make it available ++ * for future use. Erase from the oldest unit first. ++ */ ++ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: deleting empty VUC %d\n", thisVUC); ++ ++ for (;;) { ++ u16 *prevEUN = &inftl->VUtable[thisVUC]; ++ thisEUN = *prevEUN; ++ ++ /* If the chain is all gone already, we're done */ ++ if (thisEUN == BLOCK_NIL) { ++ DEBUG(MTD_DEBUG_LEVEL2, "INFTL: Empty VUC %d for deletion was already absent\n", thisEUN); ++ return; ++ } ++ ++ /* Find oldest unit in chain. */ ++ while (inftl->PUtable[thisEUN] != BLOCK_NIL) { ++ BUG_ON(thisEUN >= inftl->nb_blocks); ++ ++ prevEUN = &inftl->PUtable[thisEUN]; ++ thisEUN = *prevEUN; ++ } ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "Deleting EUN %d from VUC %d\n", ++ thisEUN, thisVUC); ++ ++ if (INFTL_formatblock(inftl, thisEUN) < 0) { ++ /* ++ * Could not erase : mark block as reserved. ++ * FixMe: Update Bad Unit Table on medium. ++ */ ++ inftl->PUtable[thisEUN] = BLOCK_RESERVED; ++ } else { ++ /* Correctly erased : mark it as free */ ++ inftl->PUtable[thisEUN] = BLOCK_FREE; ++ inftl->numfreeEUNs++; ++ } ++ ++ /* Now sort out whatever was pointing to it... */ ++ *prevEUN = BLOCK_NIL; ++ ++ /* Ideally we'd actually be responsive to new ++ requests while we're doing this -- if there's ++ free space why should others be made to wait? */ ++ cond_resched(); ++ } ++ ++ inftl->VUtable[thisVUC] = BLOCK_NIL; ++} ++ ++static int INFTL_deleteblock(struct INFTLrecord *inftl, unsigned block) ++{ ++ unsigned int thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)]; ++ unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1); ++ unsigned int status; ++ int silly = MAX_LOOPS; ++ size_t retlen; ++ struct inftl_bci bci; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_deleteblock(inftl=0x%x," ++ "block=%d)\n", (int)inftl, block); ++ ++ while (thisEUN < inftl->nb_blocks) { ++ if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) + ++ blockofs, 8, &retlen, (char *)&bci) < 0) ++ status = SECTOR_IGNORE; ++ else ++ status = bci.Status | bci.Status1; ++ ++ switch (status) { ++ case SECTOR_FREE: ++ case SECTOR_IGNORE: ++ break; ++ case SECTOR_DELETED: ++ thisEUN = BLOCK_NIL; ++ goto foundit; ++ case SECTOR_USED: ++ goto foundit; ++ default: ++ printk(KERN_WARNING "INFTL: unknown status for " ++ "block %d in EUN %d: 0x%x\n", ++ block, thisEUN, status); ++ break; ++ } ++ ++ if (!silly--) { ++ printk(KERN_WARNING "INFTL: infinite loop in Virtual " ++ "Unit Chain 0x%x\n", ++ block / (inftl->EraseSize / SECTORSIZE)); ++ return 1; ++ } ++ thisEUN = inftl->PUtable[thisEUN]; ++ } ++ ++foundit: ++ if (thisEUN != BLOCK_NIL) { ++ loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs; ++ ++ if (MTD_READOOB(inftl->mbd.mtd, ptr, 8, &retlen, (char *)&bci) < 0) ++ return -EIO; ++ bci.Status = bci.Status1 = SECTOR_DELETED; ++ if (MTD_WRITEOOB(inftl->mbd.mtd, ptr, 8, &retlen, (char *)&bci) < 0) ++ return -EIO; ++ INFTL_trydeletechain(inftl, block / (inftl->EraseSize / SECTORSIZE)); ++ } ++ return 0; ++} ++ ++static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block, ++ char *buffer) ++{ ++ struct INFTLrecord *inftl = (void *)mbd; ++ unsigned int writeEUN; ++ unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1); ++ size_t retlen; ++ u8 eccbuf[6]; ++ char *p, *pend; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_writeblock(inftl=0x%x,block=%d," ++ "buffer=0x%x)\n", (int)inftl, block, (int)buffer); ++ ++ /* Is block all zero? */ ++ pend = buffer + SECTORSIZE; ++ for (p = buffer; p < pend && !*p; p++) ++ ; ++ ++ if (p < pend) { ++ writeEUN = INFTL_findwriteunit(inftl, block); ++ ++ if (writeEUN == BLOCK_NIL) { ++ printk(KERN_WARNING "inftl_writeblock(): cannot find " ++ "block to write to\n"); ++ /* ++ * If we _still_ haven't got a block to use, ++ * we're screwed. ++ */ ++ return 1; ++ } ++ ++ MTD_WRITEECC(inftl->mbd.mtd, (writeEUN * inftl->EraseSize) + ++ blockofs, SECTORSIZE, &retlen, (char *)buffer, ++ (char *)eccbuf, NULL); ++ /* ++ * No need to write SECTOR_USED flags since they are written ++ * in mtd_writeecc ++ */ ++ } else { ++ INFTL_deleteblock(inftl, block); ++ } ++ ++ return 0; ++} ++ ++static int inftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block, ++ char *buffer) ++{ ++ struct INFTLrecord *inftl = (void *)mbd; ++ unsigned int thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)]; ++ unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1); ++ unsigned int status; ++ int silly = MAX_LOOPS; ++ struct inftl_bci bci; ++ size_t retlen; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_readblock(inftl=0x%x,block=%d," ++ "buffer=0x%x)\n", (int)inftl, block, (int)buffer); ++ ++ while (thisEUN < inftl->nb_blocks) { ++ if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) + ++ blockofs, 8, &retlen, (char *)&bci) < 0) ++ status = SECTOR_IGNORE; ++ else ++ status = bci.Status | bci.Status1; ++ ++ switch (status) { ++ case SECTOR_DELETED: ++ thisEUN = BLOCK_NIL; ++ goto foundit; ++ case SECTOR_USED: ++ goto foundit; ++ case SECTOR_FREE: ++ case SECTOR_IGNORE: ++ break; ++ default: ++ printk(KERN_WARNING "INFTL: unknown status for " ++ "block %ld in EUN %d: 0x%04x\n", ++ block, thisEUN, status); ++ break; ++ } ++ ++ if (!silly--) { ++ printk(KERN_WARNING "INFTL: infinite loop in " ++ "Virtual Unit Chain 0x%lx\n", ++ block / (inftl->EraseSize / SECTORSIZE)); ++ return 1; ++ } ++ ++ thisEUN = inftl->PUtable[thisEUN]; ++ } ++ ++foundit: ++ if (thisEUN == BLOCK_NIL) { ++ /* The requested block is not on the media, return all 0x00 */ ++ memset(buffer, 0, SECTORSIZE); ++ } else { ++ size_t retlen; ++ loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs; ++ u_char eccbuf[6]; ++ if (MTD_READECC(inftl->mbd.mtd, ptr, SECTORSIZE, &retlen, ++ buffer, eccbuf, NULL)) ++ return -EIO; ++ } ++ return 0; ++} ++ ++static int inftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo) ++{ ++ struct INFTLrecord *inftl = (void *)dev; ++ ++ geo->heads = inftl->heads; ++ geo->sectors = inftl->sectors; ++ geo->cylinders = inftl->cylinders; ++ ++ return 0; ++} ++ ++struct mtd_blktrans_ops inftl_tr = { ++ .name = "inftl", ++ .major = INFTL_MAJOR, ++ .part_bits = INFTL_PARTN_BITS, ++ .getgeo = inftl_getgeo, ++ .readsect = inftl_readblock, ++ .writesect = inftl_writeblock, ++ .add_mtd = inftl_add_mtd, ++ .remove_dev = inftl_remove_dev, ++ .owner = THIS_MODULE, ++}; ++ ++extern char inftlmountrev[]; ++ ++int __init init_inftl(void) ++{ ++ printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.14 $, " ++ "inftlmount.c %s\n", inftlmountrev); ++ ++ return register_mtd_blktrans(&inftl_tr); ++} ++ ++static void __exit cleanup_inftl(void) ++{ ++ deregister_mtd_blktrans(&inftl_tr); ++} ++ ++module_init(init_inftl); ++module_exit(cleanup_inftl); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Greg Ungerer , David Woodhouse , Fabrice Bellard et al."); ++MODULE_DESCRIPTION("Support code for Inverse Flash Translation Layer, used on M-Systems DiskOnChip 2000, Millennium and Millennium Plus"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/inftlmount.c linux/drivers/mtd/inftlmount.c +--- linux-mips-2.4.27/drivers/mtd/inftlmount.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/inftlmount.c 2004-11-19 10:25:11.633240224 +0100 +@@ -0,0 +1,817 @@ ++/* ++ * inftlmount.c -- INFTL mount code with extensive checks. ++ * ++ * Author: Greg Ungerer (gerg@snapgear.com) ++ * (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com) ++ * ++ * Based heavily on the nftlmount.c code which is: ++ * Author: Fabrice Bellard (fabrice.bellard@netgem.com) ++ * Copyright (C) 2000 Netgem S.A. ++ * ++ * $Id: inftlmount.c,v 1.12 2003/06/26 07:31:36 dwmw2 Exp $ ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++char inftlmountrev[]="$Revision: 1.12 $"; ++ ++/* ++ * find_boot_record: Find the INFTL Media Header and its Spare copy which ++ * contains the various device information of the INFTL partition and ++ * Bad Unit Table. Update the PUtable[] table according to the Bad ++ * Unit Table. PUtable[] is used for management of Erase Unit in ++ * other routines in inftlcore.c and inftlmount.c. ++ */ ++static int find_boot_record(struct INFTLrecord *inftl) ++{ ++ struct inftl_unittail h1; ++ //struct inftl_oob oob; ++ unsigned int i, block, boot_record_count = 0; ++ u8 buf[SECTORSIZE]; ++ struct INFTLMediaHeader *mh = &inftl->MediaHdr; ++ struct INFTLPartition *ip; ++ int retlen; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: find_boot_record(inftl=0x%x)\n", ++ (int)inftl); ++ ++ /* ++ * Assume logical EraseSize == physical erasesize for starting the ++ * scan. We'll sort it out later if we find a MediaHeader which says ++ * otherwise. ++ */ ++ inftl->EraseSize = inftl->mbd.mtd->erasesize; ++ inftl->nb_blocks = inftl->mbd.mtd->size / inftl->EraseSize; ++ ++ inftl->MediaUnit = BLOCK_NIL; ++ inftl->SpareMediaUnit = BLOCK_NIL; ++ ++ /* Search for a valid boot record */ ++ for (block = 0; block < inftl->nb_blocks; block++) { ++ int ret; ++ ++ /* ++ * Check for BNAND header first. Then whinge if it's found ++ * but later checks fail. ++ */ ++ if ((ret = MTD_READ(inftl->mbd.mtd, block * inftl->EraseSize, ++ SECTORSIZE, &retlen, buf))) { ++ static int warncount = 5; ++ ++ if (warncount) { ++ printk(KERN_WARNING "INFTL: block read at 0x%x " ++ "of mtd%d failed: %d\n", ++ block * inftl->EraseSize, ++ inftl->mbd.mtd->index, ret); ++ if (!--warncount) ++ printk(KERN_WARNING "INFTL: further " ++ "failures for this block will " ++ "not be printed\n"); ++ } ++ continue; ++ } ++ ++ if (retlen < 6 || memcmp(buf, "BNAND", 6)) { ++ /* BNAND\0 not found. Continue */ ++ continue; ++ } ++ ++ /* To be safer with BIOS, also use erase mark as discriminant */ ++ if ((ret = MTD_READOOB(inftl->mbd.mtd, block * inftl->EraseSize + ++ SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0)) { ++ printk(KERN_WARNING "INFTL: ANAND header found at " ++ "0x%x in mtd%d, but OOB data read failed " ++ "(err %d)\n", block * inftl->EraseSize, ++ inftl->mbd.mtd->index, ret); ++ continue; ++ } ++ ++ if (boot_record_count) { ++ /* ++ * We've already processed one. So we just check if ++ * this one is the same as the first one we found. ++ */ ++ if (memcmp(mh, buf, sizeof(struct INFTLMediaHeader))) { ++ printk(KERN_WARNING "INFTL: Media Headers at " ++ "0x%x and 0x%x disagree.\n", ++ inftl->MediaUnit * inftl->EraseSize, ++ block * inftl->EraseSize); ++ return -1; ++ } ++ if (boot_record_count == 1) ++ inftl->SpareMediaUnit = block; ++ ++ /* ++ * Mark this boot record (INFTL MediaHeader) block as ++ * reserved. ++ */ ++ inftl->PUtable[block] = BLOCK_RESERVED; ++ ++ boot_record_count++; ++ continue; ++ } ++ ++ /* ++ * This is the first we've seen. ++ * Copy the media header structure into place. ++ */ ++ memcpy(mh, buf, sizeof(struct INFTLMediaHeader)); ++ mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks); ++ mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions); ++ mh->NoOfBDTLPartitions = le32_to_cpu(mh->NoOfBDTLPartitions); ++ mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits); ++ mh->FormatFlags = le32_to_cpu(mh->FormatFlags); ++ mh->PercentUsed = le32_to_cpu(mh->PercentUsed); ++ ++#ifdef CONFIG_MTD_DEBUG_VERBOSE ++ if (CONFIG_MTD_DEBUG_VERBOSE >= 2) { ++ printk("INFTL: Media Header ->\n" ++ " bootRecordID = %s\n" ++ " NoOfBootImageBlocks = %d\n" ++ " NoOfBinaryPartitions = %d\n" ++ " NoOfBDTLPartitions = %d\n" ++ " BlockMultiplerBits = %d\n" ++ " FormatFlgs = %d\n" ++ " OsakVersion = 0x%x\n" ++ " PercentUsed = %d\n", ++ mh->bootRecordID, mh->NoOfBootImageBlocks, ++ mh->NoOfBinaryPartitions, ++ mh->NoOfBDTLPartitions, ++ mh->BlockMultiplierBits, mh->FormatFlags, ++ mh->OsakVersion, mh->PercentUsed); ++ } ++#endif ++ ++ if (mh->NoOfBDTLPartitions == 0) { ++ printk(KERN_WARNING "INFTL: Media Header sanity check " ++ "failed: NoOfBDTLPartitions (%d) == 0, " ++ "must be at least 1\n", mh->NoOfBDTLPartitions); ++ return -1; ++ } ++ ++ if ((mh->NoOfBDTLPartitions + mh->NoOfBinaryPartitions) > 4) { ++ printk(KERN_WARNING "INFTL: Media Header sanity check " ++ "failed: Total Partitions (%d) > 4, " ++ "BDTL=%d Binary=%d\n", mh->NoOfBDTLPartitions + ++ mh->NoOfBinaryPartitions, ++ mh->NoOfBDTLPartitions, ++ mh->NoOfBinaryPartitions); ++ return -1; ++ } ++ ++ if (mh->BlockMultiplierBits > 1) { ++ printk(KERN_WARNING "INFTL: sorry, we don't support " ++ "UnitSizeFactor 0x%02x\n", ++ mh->BlockMultiplierBits); ++ return -1; ++ } else if (mh->BlockMultiplierBits == 1) { ++ printk(KERN_WARNING "INFTL: support for INFTL with " ++ "UnitSizeFactor 0x%02x is experimental\n", ++ mh->BlockMultiplierBits); ++ inftl->EraseSize = inftl->mbd.mtd->erasesize << ++ (0xff - mh->BlockMultiplierBits); ++ inftl->nb_blocks = inftl->mbd.mtd->size / inftl->EraseSize; ++ } ++ ++ /* Scan the partitions */ ++ for (i = 0; (i < 4); i++) { ++ ip = &mh->Partitions[i]; ++ ip->virtualUnits = le32_to_cpu(ip->virtualUnits); ++ ip->firstUnit = le32_to_cpu(ip->firstUnit); ++ ip->lastUnit = le32_to_cpu(ip->lastUnit); ++ ip->flags = le32_to_cpu(ip->flags); ++ ip->spareUnits = le32_to_cpu(ip->spareUnits); ++ ip->Reserved0 = le32_to_cpu(ip->Reserved0); ++ ++#ifdef CONFIG_MTD_DEBUG_VERBOSE ++ if (CONFIG_MTD_DEBUG_VERBOSE >= 2) { ++ printk(" PARTITION[%d] ->\n" ++ " virtualUnits = %d\n" ++ " firstUnit = %d\n" ++ " lastUnit = %d\n" ++ " flags = 0x%x\n" ++ " spareUnits = %d\n", ++ i, ip->virtualUnits, ip->firstUnit, ++ ip->lastUnit, ip->flags, ++ ip->spareUnits); ++ } ++#endif ++ ++ if (ip->Reserved0 != ip->firstUnit) { ++ struct erase_info *instr = &inftl->instr; ++ ++ /* ++ * Most likely this is using the ++ * undocumented qiuck mount feature. ++ * We don't support that, we will need ++ * to erase the hidden block for full ++ * compatibility. ++ */ ++ instr->addr = ip->Reserved0 * inftl->EraseSize; ++ instr->len = inftl->EraseSize; ++ MTD_ERASE(inftl->mbd.mtd, instr); ++ } ++ if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) { ++ printk(KERN_WARNING "INFTL: Media Header " ++ "Partition %d sanity check failed\n" ++ " firstUnit %d : lastUnit %d > " ++ "virtualUnits %d\n", i, ip->lastUnit, ++ ip->firstUnit, ip->Reserved0); ++ return -1; ++ } ++ if (ip->Reserved1 != 0) { ++ printk(KERN_WARNING "INFTL: Media Header " ++ "Partition %d sanity check failed: " ++ "Reserved1 %d != 0\n", ++ i, ip->Reserved1); ++ return -1; ++ } ++ ++ if (ip->flags & INFTL_BDTL) ++ break; ++ } ++ ++ if (i >= 4) { ++ printk(KERN_WARNING "INFTL: Media Header Partition " ++ "sanity check failed:\n No partition " ++ "marked as Disk Partition\n"); ++ return -1; ++ } ++ ++ inftl->nb_boot_blocks = ip->firstUnit; ++ inftl->numvunits = ip->virtualUnits; ++ if (inftl->numvunits > (inftl->nb_blocks - ++ inftl->nb_boot_blocks - 2)) { ++ printk(KERN_WARNING "INFTL: Media Header sanity check " ++ "failed:\n numvunits (%d) > nb_blocks " ++ "(%d) - nb_boot_blocks(%d) - 2\n", ++ inftl->numvunits, inftl->nb_blocks, ++ inftl->nb_boot_blocks); ++ return -1; ++ } ++ ++ inftl->mbd.size = inftl->numvunits * ++ (inftl->EraseSize / SECTORSIZE); ++ ++ /* ++ * Block count is set to last used EUN (we won't need to keep ++ * any meta-data past that point). ++ */ ++ inftl->firstEUN = ip->firstUnit; ++ inftl->lastEUN = ip->lastUnit; ++ inftl->nb_blocks = ip->lastUnit + 1; ++ ++ /* Memory alloc */ ++ inftl->PUtable = kmalloc(inftl->nb_blocks * sizeof(u16), GFP_KERNEL); ++ if (!inftl->PUtable) { ++ printk(KERN_WARNING "INFTL: allocation of PUtable " ++ "failed (%d bytes)\n", ++ inftl->nb_blocks * sizeof(u16)); ++ return -ENOMEM; ++ } ++ ++ inftl->VUtable = kmalloc(inftl->nb_blocks * sizeof(u16), GFP_KERNEL); ++ if (!inftl->VUtable) { ++ kfree(inftl->PUtable); ++ printk(KERN_WARNING "INFTL: allocation of VUtable " ++ "failed (%d bytes)\n", ++ inftl->nb_blocks * sizeof(u16)); ++ return -ENOMEM; ++ } ++ ++ /* Mark the blocks before INFTL MediaHeader as reserved */ ++ for (i = 0; i < inftl->nb_boot_blocks; i++) ++ inftl->PUtable[i] = BLOCK_RESERVED; ++ /* Mark all remaining blocks as potentially containing data */ ++ for (; i < inftl->nb_blocks; i++) ++ inftl->PUtable[i] = BLOCK_NOTEXPLORED; ++ ++ /* Mark this boot record (NFTL MediaHeader) block as reserved */ ++ inftl->PUtable[block] = BLOCK_RESERVED; ++ ++#if 0 ++ /* Read Bad Erase Unit Table and modify PUtable[] accordingly */ ++ for (i = 0; i < inftl->nb_blocks; i++) { ++ if ((i & (SECTORSIZE - 1)) == 0) { ++ /* read one sector for every SECTORSIZE of blocks */ ++ if ((ret = MTD_READECC(inftl->mbd.mtd, ++ block * inftl->EraseSize + i + SECTORSIZE, ++ SECTORSIZE, &retlen, buf, ++ (char *)&oob, NULL)) < 0) { ++ printk(KERN_WARNING "INFTL: read of " ++ "bad sector table failed " ++ "(err %d)\n", ret); ++ kfree(inftl->VUtable); ++ kfree(inftl->PUtable); ++ return -1; ++ } ++ } ++ /* Mark the Bad Erase Unit as RESERVED in PUtable */ ++ if (buf[i & (SECTORSIZE - 1)] != 0xff) ++ inftl->PUtable[i] = BLOCK_RESERVED; ++ } ++#endif ++ ++ inftl->MediaUnit = block; ++ boot_record_count++; ++ } ++ ++ return boot_record_count ? 0 : -1; ++} ++ ++static int memcmpb(void *a, int c, int n) ++{ ++ int i; ++ for (i = 0; i < n; i++) { ++ if (c != ((unsigned char *)a)[i]) ++ return 1; ++ } ++ return 0; ++} ++ ++/* ++ * check_free_sector: check if a free sector is actually FREE, ++ * i.e. All 0xff in data and oob area. ++ */ ++static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address, ++ int len, int check_oob) ++{ ++ int i, retlen; ++ u8 buf[SECTORSIZE]; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: check_free_sectors(inftl=0x%x," ++ "address=0x%x,len=%d,check_oob=%d)\n", (int)inftl, ++ address, len, check_oob); ++ ++ for (i = 0; i < len; i += SECTORSIZE) { ++ /* ++ * We want to read the sector without ECC check here since a ++ * free sector does not have ECC syndrome on it yet. ++ */ ++ if (MTD_READ(inftl->mbd.mtd, address, SECTORSIZE, &retlen, buf) < 0) ++ return -1; ++ if (memcmpb(buf, 0xff, SECTORSIZE) != 0) ++ return -1; ++ ++ if (check_oob) { ++ if (MTD_READOOB(inftl->mbd.mtd, address, ++ inftl->mbd.mtd->oobsize, &retlen, buf) < 0) ++ return -1; ++ if (memcmpb(buf, 0xff, inftl->mbd.mtd->oobsize) != 0) ++ return -1; ++ } ++ address += SECTORSIZE; ++ } ++ ++ return 0; ++} ++ ++/* ++ * INFTL_format: format a Erase Unit by erasing ALL Erase Zones in the Erase ++ * Unit and Update INFTL metadata. Each erase operation is ++ * checked with check_free_sectors. ++ * ++ * Return: 0 when succeed, -1 on error. ++ * ++ * ToDo: 1. Is it neceressary to check_free_sector after erasing ?? ++ * 2. UnitSizeFactor != 0xFF ++ */ ++int INFTL_formatblock(struct INFTLrecord *inftl, int block) ++{ ++ int retlen; ++ struct inftl_unittail uci; ++ struct erase_info *instr = &inftl->instr; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=0x%x," ++ "block=%d)\n", (int)inftl, block); ++ ++ memset(instr, 0, sizeof(struct erase_info)); ++ ++ /* FIXME: Shouldn't we be setting the 'discarded' flag to zero ++ _first_? */ ++ ++ /* Use async erase interface, test return code */ ++ instr->addr = block * inftl->EraseSize; ++ instr->len = inftl->EraseSize; ++ MTD_ERASE(inftl->mbd.mtd, instr); ++ ++ if (instr->state == MTD_ERASE_FAILED) { ++ /* ++ * Could not format, FixMe: We should update the BadUnitTable ++ * both in memory and on disk. ++ */ ++ printk(KERN_WARNING "INFTL: error while formatting block %d\n", ++ block); ++ return -1; ++ } ++ ++ /* ++ * Check the "freeness" of Erase Unit before updating metadata. ++ * FixMe: is this check really necessary? Since we have check the ++ * return code after the erase operation. ++ */ ++ if (check_free_sectors(inftl, instr->addr, inftl->EraseSize, 1) != 0) ++ return -1; ++ ++ uci.EraseMark = cpu_to_le16(ERASE_MARK); ++ uci.EraseMark1 = cpu_to_le16(ERASE_MARK); ++ uci.Reserved[0] = 0; ++ uci.Reserved[1] = 0; ++ uci.Reserved[2] = 0; ++ uci.Reserved[3] = 0; ++ if (MTD_WRITEOOB(inftl->mbd.mtd, block * inftl->EraseSize + SECTORSIZE * 2 + ++ 8, 8, &retlen, (char *)&uci) < 0) ++ return -1; ++ return 0; ++} ++ ++/* ++ * format_chain: Format an invalid Virtual Unit chain. It frees all the Erase ++ * Units in a Virtual Unit Chain, i.e. all the units are disconnected. ++ * ++ * Since the chain is invalid then we will have to erase it from its ++ * head (normally for INFTL we go from the oldest). But if it has a ++ * loop then there is no oldest... ++ */ ++static void format_chain(struct INFTLrecord *inftl, unsigned int first_block) ++{ ++ unsigned int block = first_block, block1; ++ ++ printk(KERN_WARNING "INFTL: formatting chain at block %d\n", ++ first_block); ++ ++ for (;;) { ++ block1 = inftl->PUtable[block]; ++ ++ printk(KERN_WARNING "INFTL: formatting block %d\n", block); ++ if (INFTL_formatblock(inftl, block) < 0) { ++ /* ++ * Cannot format !!!! Mark it as Bad Unit, ++ * FixMe: update the BadUnitTable on disk. ++ */ ++ inftl->PUtable[block] = BLOCK_RESERVED; ++ } else { ++ inftl->PUtable[block] = BLOCK_FREE; ++ } ++ ++ /* Goto next block on the chain */ ++ block = block1; ++ ++ if (block == BLOCK_NIL || block >= inftl->lastEUN) ++ break; ++ } ++} ++ ++void INFTL_dumptables(struct INFTLrecord *s) ++{ ++ int i; ++ ++ printk("-------------------------------------------" ++ "----------------------------------\n"); ++ ++ printk("VUtable[%d] ->", s->nb_blocks); ++ for (i = 0; i < s->nb_blocks; i++) { ++ if ((i % 8) == 0) ++ printk("\n%04x: ", i); ++ printk("%04x ", s->VUtable[i]); ++ } ++ ++ printk("\n-------------------------------------------" ++ "----------------------------------\n"); ++ ++ printk("PUtable[%d-%d=%d] ->", s->firstEUN, s->lastEUN, s->nb_blocks); ++ for (i = 0; i <= s->lastEUN; i++) { ++ if ((i % 8) == 0) ++ printk("\n%04x: ", i); ++ printk("%04x ", s->PUtable[i]); ++ } ++ ++ printk("\n-------------------------------------------" ++ "----------------------------------\n"); ++ ++ printk("INFTL ->\n" ++ " EraseSize = %d\n" ++ " h/s/c = %d/%d/%d\n" ++ " numvunits = %d\n" ++ " firstEUN = %d\n" ++ " lastEUN = %d\n" ++ " numfreeEUNs = %d\n" ++ " LastFreeEUN = %d\n" ++ " nb_blocks = %d\n" ++ " nb_boot_blocks = %d", ++ s->EraseSize, s->heads, s->sectors, s->cylinders, ++ s->numvunits, s->firstEUN, s->lastEUN, s->numfreeEUNs, ++ s->LastFreeEUN, s->nb_blocks, s->nb_boot_blocks); ++ ++ printk("\n-------------------------------------------" ++ "----------------------------------\n"); ++} ++ ++void INFTL_dumpVUchains(struct INFTLrecord *s) ++{ ++ int logical, block, i; ++ ++ printk("-------------------------------------------" ++ "----------------------------------\n"); ++ ++ printk("INFTL Virtual Unit Chains:\n"); ++ for (logical = 0; logical < s->nb_blocks; logical++) { ++ block = s->VUtable[logical]; ++ if (block > s->nb_blocks) ++ continue; ++ printk(" LOGICAL %d --> %d ", logical, block); ++ for (i = 0; i < s->nb_blocks; i++) { ++ if (s->PUtable[block] == BLOCK_NIL) ++ break; ++ block = s->PUtable[block]; ++ printk("%d ", block); ++ } ++ printk("\n"); ++ } ++ ++ printk("-------------------------------------------" ++ "----------------------------------\n"); ++} ++ ++int INFTL_mount(struct INFTLrecord *s) ++{ ++ unsigned int block, first_block, prev_block, last_block; ++ unsigned int first_logical_block, logical_block, erase_mark; ++ int chain_length, do_format_chain; ++ struct inftl_unithead1 h0; ++ struct inftl_unittail h1; ++ int i, retlen; ++ u8 *ANACtable, ANAC; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_mount(inftl=0x%x)\n", (int)s); ++ ++ /* Search for INFTL MediaHeader and Spare INFTL Media Header */ ++ if (find_boot_record(s) < 0) { ++ printk(KERN_WARNING "INFTL: could not find valid boot record?\n"); ++ return -1; ++ } ++ ++ /* Init the logical to physical table */ ++ for (i = 0; i < s->nb_blocks; i++) ++ s->VUtable[i] = BLOCK_NIL; ++ ++ logical_block = block = BLOCK_NIL; ++ ++ /* Temporary buffer to store ANAC numbers. */ ++ ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL); ++ memset(ANACtable, 0, s->nb_blocks); ++ ++ /* ++ * First pass is to explore each physical unit, and construct the ++ * virtual chains that exist (newest physical unit goes into VUtable). ++ * Any block that is in any way invalid will be left in the ++ * NOTEXPLORED state. Then at the end we will try to format it and ++ * mark it as free. ++ */ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 1, explore each unit\n"); ++ for (first_block = s->firstEUN; first_block <= s->lastEUN; first_block++) { ++ if (s->PUtable[first_block] != BLOCK_NOTEXPLORED) ++ continue; ++ ++ do_format_chain = 0; ++ first_logical_block = BLOCK_NIL; ++ last_block = BLOCK_NIL; ++ block = first_block; ++ ++ for (chain_length = 0; ; chain_length++) { ++ ++ if ((chain_length == 0) && ++ (s->PUtable[block] != BLOCK_NOTEXPLORED)) { ++ /* Nothing to do here, onto next block */ ++ break; ++ } ++ ++ if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, ++ 8, &retlen, (char *)&h0) < 0 || ++ MTD_READOOB(s->mbd.mtd, block * s->EraseSize + ++ 2 * SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0) { ++ /* Should never happen? */ ++ do_format_chain++; ++ break; ++ } ++ ++ logical_block = le16_to_cpu(h0.virtualUnitNo); ++ prev_block = le16_to_cpu(h0.prevUnitNo); ++ erase_mark = le16_to_cpu((h1.EraseMark | h1.EraseMark1)); ++ ANACtable[block] = h0.ANAC; ++ ++ /* Previous block is relative to start of Partition */ ++ if (prev_block < s->nb_blocks) ++ prev_block += s->firstEUN; ++ ++ /* Already explored partial chain? */ ++ if (s->PUtable[block] != BLOCK_NOTEXPLORED) { ++ /* Check if chain for this logical */ ++ if (logical_block == first_logical_block) { ++ if (last_block != BLOCK_NIL) ++ s->PUtable[last_block] = block; ++ } ++ break; ++ } ++ ++ /* Check for invalid block */ ++ if (erase_mark != ERASE_MARK) { ++ printk(KERN_WARNING "INFTL: corrupt block %d " ++ "in chain %d, chain length %d, erase " ++ "mark 0x%x?\n", block, first_block, ++ chain_length, erase_mark); ++ /* ++ * Assume end of chain, probably incomplete ++ * fold/erase... ++ */ ++ if (chain_length == 0) ++ do_format_chain++; ++ break; ++ } ++ ++ /* Check for it being free already then... */ ++ if ((logical_block == BLOCK_FREE) || ++ (logical_block == BLOCK_NIL)) { ++ s->PUtable[block] = BLOCK_FREE; ++ break; ++ } ++ ++ /* Sanity checks on block numbers */ ++ if ((logical_block >= s->nb_blocks) || ++ ((prev_block >= s->nb_blocks) && ++ (prev_block != BLOCK_NIL))) { ++ if (chain_length > 0) { ++ printk(KERN_WARNING "INFTL: corrupt " ++ "block %d in chain %d?\n", ++ block, first_block); ++ do_format_chain++; ++ } ++ break; ++ } ++ ++ if (first_logical_block == BLOCK_NIL) { ++ first_logical_block = logical_block; ++ } else { ++ if (first_logical_block != logical_block) { ++ /* Normal for folded chain... */ ++ break; ++ } ++ } ++ ++ /* ++ * Current block is valid, so if we followed a virtual ++ * chain to get here then we can set the previous ++ * block pointer in our PUtable now. Then move onto ++ * the previous block in the chain. ++ */ ++ s->PUtable[block] = BLOCK_NIL; ++ if (last_block != BLOCK_NIL) ++ s->PUtable[last_block] = block; ++ last_block = block; ++ block = prev_block; ++ ++ /* Check for end of chain */ ++ if (block == BLOCK_NIL) ++ break; ++ ++ /* Validate next block before following it... */ ++ if (block > s->lastEUN) { ++ printk(KERN_WARNING "INFTL: invalid previous " ++ "block %d in chain %d?\n", block, ++ first_block); ++ do_format_chain++; ++ break; ++ } ++ } ++ ++ if (do_format_chain) { ++ format_chain(s, first_block); ++ continue; ++ } ++ ++ /* ++ * Looks like a valid chain then. It may not really be the ++ * newest block in the chain, but it is the newest we have ++ * found so far. We might update it in later iterations of ++ * this loop if we find something newer. ++ */ ++ s->VUtable[first_logical_block] = first_block; ++ logical_block = BLOCK_NIL; ++ } ++ ++#ifdef CONFIG_MTD_DEBUG_VERBOSE ++ if (CONFIG_MTD_DEBUG_VERBOSE >= 2) ++ INFTL_dumptables(s); ++#endif ++ ++ /* ++ * Second pass, check for infinite loops in chains. These are ++ * possible because we don't update the previous pointers when ++ * we fold chains. No big deal, just fix them up in PUtable. ++ */ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 2, validate virtual chains\n"); ++ for (logical_block = 0; logical_block < s->numvunits; logical_block++) { ++ block = s->VUtable[logical_block]; ++ last_block = BLOCK_NIL; ++ ++ /* Check for free/reserved/nil */ ++ if (block >= BLOCK_RESERVED) ++ continue; ++ ++ ANAC = ANACtable[block]; ++ for (i = 0; i < s->numvunits; i++) { ++ if (s->PUtable[block] == BLOCK_NIL) ++ break; ++ if (s->PUtable[block] > s->lastEUN) { ++ printk(KERN_WARNING "INFTL: invalid prev %d, " ++ "in virtual chain %d\n", ++ s->PUtable[block], logical_block); ++ s->PUtable[block] = BLOCK_NIL; ++ ++ } ++ if (ANACtable[block] != ANAC) { ++ /* ++ * Chain must point back to itself. This is ok, ++ * but we will need adjust the tables with this ++ * newest block and oldest block. ++ */ ++ s->VUtable[logical_block] = block; ++ s->PUtable[last_block] = BLOCK_NIL; ++ break; ++ } ++ ++ ANAC--; ++ last_block = block; ++ block = s->PUtable[block]; ++ } ++ ++ if (i >= s->nb_blocks) { ++ /* ++ * Uhoo, infinite chain with valid ANACS! ++ * Format whole chain... ++ */ ++ format_chain(s, first_block); ++ } ++ } ++ ++#ifdef CONFIG_MTD_DEBUG_VERBOSE ++ if (CONFIG_MTD_DEBUG_VERBOSE >= 2) ++ INFTL_dumptables(s); ++ if (CONFIG_MTD_DEBUG_VERBOSE >= 2) ++ INFTL_dumpVUchains(s); ++#endif ++ ++ /* ++ * Third pass, format unreferenced blocks and init free block count. ++ */ ++ s->numfreeEUNs = 0; ++ s->LastFreeEUN = BLOCK_NIL; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 3, format unused blocks\n"); ++ for (block = s->firstEUN; block <= s->lastEUN; block++) { ++ if (s->PUtable[block] == BLOCK_NOTEXPLORED) { ++ printk("INFTL: unreferenced block %d, formatting it\n", ++ block); ++ if (INFTL_formatblock(s, block) < 0) ++ s->PUtable[block] = BLOCK_RESERVED; ++ else ++ s->PUtable[block] = BLOCK_FREE; ++ } ++ if (s->PUtable[block] == BLOCK_FREE) { ++ s->numfreeEUNs++; ++ if (s->LastFreeEUN == BLOCK_NIL) ++ s->LastFreeEUN = block; ++ } ++ } ++ ++ kfree(ANACtable); ++ return 0; ++} +-include $(TOPDIR)/Rules.make ++-include $(TOPDIR)/Rules.make +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/amd76xrom.c linux/drivers/mtd/maps/amd76xrom.c +--- linux-mips-2.4.27/drivers/mtd/maps/amd76xrom.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/maps/amd76xrom.c 2004-11-19 10:25:11.891201008 +0100 +@@ -2,12 +2,13 @@ + * amd76xrom.c + * + * Normal mappings of chips in physical memory +- * $Id: amd76xrom.c,v 1.1 2002/10/18 22:45:48 eric Exp $ ++ * $Id: amd76xrom.c,v 1.9 2003/10/23 23:10:59 thayne Exp $ + */ + + #include + #include + #include ++#include + #include + #include + #include +@@ -16,77 +17,59 @@ + #include + + ++#define xstr(s) str(s) ++#define str(s) #s ++#define MOD_NAME xstr(KBUILD_BASENAME) ++ ++#define MTD_DEV_NAME_LENGTH 16 ++ + struct amd76xrom_map_info { + struct map_info map; + struct mtd_info *mtd; + unsigned long window_addr; + u32 window_start, window_size; + struct pci_dev *pdev; ++ struct resource window_rsrc; ++ struct resource rom_rsrc; ++ char mtd_name[MTD_DEV_NAME_LENGTH]; + }; + +-static __u8 amd76xrom_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-static __u16 amd76xrom_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} + +-static __u32 amd76xrom_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} ++static struct amd76xrom_map_info amd76xrom_map = { ++ .map = { ++ .name = MOD_NAME, ++ .size = 0, ++ .buswidth = 1, ++ } ++ /* remaining fields of structure are initialized to 0 */ ++}; + +-static void amd76xrom_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} + +-static void amd76xrom_write8(struct map_info *map, __u8 d, unsigned long adr) ++static void amd76xrom_cleanup(struct amd76xrom_map_info *info) + { +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} ++ u8 byte; + +-static void amd76xrom_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} ++ /* Disable writes through the rom window */ ++ pci_read_config_byte(info->pdev, 0x40, &byte); ++ pci_write_config_byte(info->pdev, 0x40, byte & ~1); + +-static void amd76xrom_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} ++ if (info->mtd) { ++ del_mtd_device(info->mtd); ++ map_destroy(info->mtd); ++ info->mtd = NULL; ++ info->map.virt = 0; ++ } ++ if (info->rom_rsrc.parent) ++ release_resource(&info->rom_rsrc); ++ if (info->window_rsrc.parent) ++ release_resource(&info->window_rsrc); + +-static void amd76xrom_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio(map->map_priv_1 + to, from, len); ++ if (info->window_addr) { ++ iounmap((void *)(info->window_addr)); ++ info->window_addr = 0; ++ } + } + +-static struct amd76xrom_map_info amd76xrom_map = { +- map: { +- name: "AMD76X rom", +- size: 0, +- buswidth: 1, +- read8: amd76xrom_read8, +- read16: amd76xrom_read16, +- read32: amd76xrom_read32, +- copy_from: amd76xrom_copy_from, +- write8: amd76xrom_write8, +- write16: amd76xrom_write16, +- write32: amd76xrom_write32, +- copy_to: amd76xrom_copy_to, +- /* The standard rom socket is for single power supply chips +- * that don't have an extra vpp. +- */ +- }, +- mtd: 0, +- window_addr: 0, +-}; + + static int __devinit amd76xrom_init_one (struct pci_dev *pdev, + const struct pci_device_id *ent) +@@ -97,6 +80,10 @@ + u8 segen_bits; + }; + static struct rom_window rom_window[] = { ++ /* ++ * Need the 5MiB window for chips that have block lock/unlock ++ * registers located below 4MiB window. ++ */ + { 0xffb00000, 5*1024*1024, (1<<7) | (1<<6), }, + { 0xffc00000, 4*1024*1024, (1<<7), }, + { 0xffff0000, 64*1024, 0 }, +@@ -112,19 +99,29 @@ + int i; + u32 rom_size; + ++ info->pdev = pdev; + window = &rom_window[0]; +-#if 0 +- while(window->size) { +- if (request_mem_region(window->start, window->size, "amd76xrom")) { +- break; +- } +- window++; +- } +- if (!window->size) { +- printk(KERN_ERR "amd76xrom: cannot reserve rom window\n"); +- goto err_out_none; ++ ++ while (window->size) { ++ /* ++ * Try to reserve the window mem region. If this fails then ++ * it is likely due to a fragment of the window being ++ * "reseved" by the BIOS. In the case that the ++ * request_mem_region() fails then once the rom size is ++ * discovered we will try to reserve the unreserved fragment. ++ */ ++ info->window_rsrc.name = MOD_NAME; ++ info->window_rsrc.start = window->start; ++ info->window_rsrc.end = window->start + window->size - 1; ++ info->window_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; ++ if (request_resource(&iomem_resource, &info->window_rsrc)) { ++ info->window_rsrc.parent = NULL; ++ printk(KERN_ERR MOD_NAME ++ " %s(): Unable to register resource" ++ " 0x%.08lx-0x%.08lx - kernel bug?\n", ++ __func__, ++ info->window_rsrc.start, info->window_rsrc.end); + } +-#endif + + /* Enable the selected rom window */ + pci_read_config_byte(pdev, 0x43, &byte); +@@ -136,49 +133,94 @@ + + /* FIXME handle registers 0x80 - 0x8C the bios region locks */ + +- printk(KERN_NOTICE "amd76xrom window : %x at %x\n", ++ printk(KERN_NOTICE MOD_NAME " window : %x at %x\n", + window->size, window->start); + /* For write accesses caches are useless */ +- info->window_addr = (unsigned long)ioremap_nocache(window->start, window->size); ++ info->window_addr = ++ (unsigned long)ioremap_nocache(window->start, ++ window->size); + + if (!info->window_addr) { + printk(KERN_ERR "Failed to ioremap\n"); +- goto err_out_free_mmio_region; ++ continue; + } +- info->mtd = 0; ++ ++ info->mtd = NULL; ++ + for(i = 0; (rom_size = rom_probe_sizes[i]); i++) { + char **chip_type; + if (rom_size > window->size) { + continue; + } +- info->map.map_priv_1 = ++ info->map.phys = window->start + window->size - rom_size; ++ info->map.virt = + info->window_addr + window->size - rom_size; + info->map.size = rom_size; ++ simple_map_init(&info->map); + chip_type = rom_probe_types; + for(; !info->mtd && *chip_type; chip_type++) { + info->mtd = do_map_probe(*chip_type, &amd76xrom_map.map); + } +- if (info->mtd) { +- break; +- } ++ if (info->mtd) goto found_mtd; + } +- if (!info->mtd) { +- goto err_out_iounmap; ++ iounmap((void *)(info->window_addr)); ++ info->window_addr = 0; ++ ++ /* Disable writes through the rom window */ ++ pci_read_config_byte(pdev, 0x40, &byte); ++ pci_write_config_byte(pdev, 0x40, byte & ~1); ++ ++ window++; + } +- printk(KERN_NOTICE "amd76xrom chip at offset: %x\n", ++ goto failed; ++ ++ found_mtd: ++ printk(KERN_NOTICE MOD_NAME " chip at offset: 0x%x\n", + window->size - rom_size); + +- info->mtd->module = THIS_MODULE; ++ info->mtd->owner = THIS_MODULE; ++ ++ if (!info->window_rsrc.parent) { ++ /* failed to reserve entire window - try fragments */ ++ info->window_rsrc.name = MOD_NAME; ++ info->window_rsrc.start = window->start; ++ info->window_rsrc.end = window->start + window->size - rom_size - 1; ++ info->window_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; ++ if (request_resource(&iomem_resource, &info->window_rsrc)) { ++ printk(KERN_ERR MOD_NAME ++ ": cannot reserve window resource fragment\n"); ++ goto failed; ++ } ++ } ++ + add_mtd_device(info->mtd); + info->window_start = window->start; + info->window_size = window->size; ++ ++ if (info->window_rsrc.parent) { ++ /* ++ * Registering the MTD device in iomem may not be possible ++ * if there is a BIOS "reserved" and BUSY range. If this ++ * fails then continue anyway. ++ */ ++ snprintf(info->mtd_name, MTD_DEV_NAME_LENGTH, ++ "mtd%d", info->mtd->index); ++ ++ info->rom_rsrc.name = info->mtd_name; ++ info->rom_rsrc.start = window->start + window->size - rom_size; ++ info->rom_rsrc.end = window->start + window->size - 1; ++ info->rom_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; ++ if (request_resource(&info->window_rsrc, &info->rom_rsrc)) { ++ printk(KERN_ERR MOD_NAME ++ ": cannot reserve MTD resource\n"); ++ info->rom_rsrc.parent = NULL; ++ } ++ } ++ + return 0; + +-err_out_iounmap: +- iounmap((void *)(info->window_addr)); +-err_out_free_mmio_region: +- release_mem_region(window->start, window->size); +-err_out_none: ++ failed: ++ amd76xrom_cleanup(info); + return -ENODEV; + } + +@@ -186,21 +228,8 @@ + static void __devexit amd76xrom_remove_one (struct pci_dev *pdev) + { + struct amd76xrom_map_info *info = &amd76xrom_map; +- u8 byte; +- +- del_mtd_device(info->mtd); +- map_destroy(info->mtd); +- info->mtd = 0; +- info->map.map_priv_1 = 0; +- +- iounmap((void *)(info->window_addr)); +- info->window_addr = 0; +- +- /* Disable writes through the rom window */ +- pci_read_config_byte(pdev, 0x40, &byte); +- pci_write_config_byte(pdev, 0x40, byte & ~1); + +- release_mem_region(info->window_start, info->window_size); ++ amd76xrom_cleanup(info); + } + + static struct pci_device_id amd76xrom_pci_tbl[] __devinitdata = { +@@ -208,6 +237,7 @@ + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440, + PCI_ANY_ID, PCI_ANY_ID, }, ++ { PCI_VENDOR_ID_AMD, 0x7468 }, /* amd8111 support */ + { 0, } + }; + +@@ -215,10 +245,10 @@ + + #if 0 + static struct pci_driver amd76xrom_driver = { +- name: "amd76xrom", +- id_table: amd76xrom_pci_tbl, +- probe: amd76xrom_init_one, +- remove: amd76xrom_remove_one, ++ .name = MOD_NAME, ++ .id_table = amd76xrom_pci_tbl, ++ .probe = amd76xrom_init_one, ++ .remove = amd76xrom_remove_one, + }; + #endif + +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/arctic-mtd.c linux/drivers/mtd/maps/arctic-mtd.c +--- linux-mips-2.4.27/drivers/mtd/maps/arctic-mtd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/maps/arctic-mtd.c 2004-11-19 10:25:11.893200704 +0100 +@@ -0,0 +1,135 @@ ++/* ++ * $Id: arctic-mtd.c,v 1.10 2003/06/02 16:37:59 trini Exp $ ++ * ++ * drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for ++ * IBM 405LP Arctic boards. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Copyright (C) 2002, International Business Machines Corporation ++ * All Rights Reserved. ++ * ++ * Bishop Brock ++ * IBM Research, Austin Center for Low-Power Computing ++ * bcbrock@us.ibm.com ++ * March 2002 ++ * ++ * modified for Arctic by, ++ * David Gibson ++ * IBM OzLabs, Canberra, Australia ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* ++ * 0 : 0xFE00 0000 - 0xFEFF FFFF : Filesystem 1 (16MiB) ++ * 1 : 0xFF00 0000 - 0xFF4F FFFF : kernel (5.12MiB) ++ * 2 : 0xFF50 0000 - 0xFFF5 FFFF : Filesystem 2 (10.624MiB) (if non-XIP) ++ * 3 : 0xFFF6 0000 - 0xFFFF FFFF : PIBS Firmware (640KiB) ++ */ ++ ++#define FFS1_SIZE 0x01000000 /* 16MiB */ ++#define KERNEL_SIZE 0x00500000 /* 5.12MiB */ ++#define FFS2_SIZE 0x00a60000 /* 10.624MiB */ ++#define FIRMWARE_SIZE 0x000a0000 /* 640KiB */ ++ ++ ++#define NAME "Arctic Linux Flash" ++#define PADDR SUBZERO_BOOTFLASH_PADDR ++#define BUSWIDTH 2 ++#define SIZE SUBZERO_BOOTFLASH_SIZE ++#define PARTITIONS 4 ++ ++/* Flash memories on these boards are memory resources, accessed big-endian. */ ++ ++{ ++ /* do nothing for now */ ++} ++ ++static struct map_info arctic_mtd_map = { ++ .name = NAME, ++ .size = SIZE, ++ .buswidth = BUSWIDTH, ++ .phys = PADDR, ++}; ++ ++static struct mtd_info *arctic_mtd; ++ ++static struct mtd_partition arctic_partitions[PARTITIONS] = { ++ { .name = "Filesystem", ++ .size = FFS1_SIZE, ++ .offset = 0,}, ++ { .name = "Kernel", ++ .size = KERNEL_SIZE, ++ .offset = FFS1_SIZE,}, ++ { .name = "Filesystem", ++ .size = FFS2_SIZE, ++ .offset = FFS1_SIZE + KERNEL_SIZE,}, ++ { .name = "Firmware", ++ .size = FIRMWARE_SIZE, ++ .offset = SUBZERO_BOOTFLASH_SIZE - FIRMWARE_SIZE,}, ++}; ++ ++static int __init ++init_arctic_mtd(void) ++{ ++ printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR); ++ ++ arctic_mtd_map.virt = (unsigned long) ioremap(PADDR, SIZE); ++ ++ if (!arctic_mtd_map.virt) { ++ printk("%s: failed to ioremap 0x%x\n", NAME, PADDR); ++ return -EIO; ++ } ++ simple_map_init(&arctic_mtd_map); ++ ++ printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8); ++ arctic_mtd = do_map_probe("cfi_probe", &arctic_mtd_map); ++ ++ if (!arctic_mtd) ++ return -ENXIO; ++ ++ arctic_mtd->owner = THIS_MODULE; ++ ++ return add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS); ++} ++ ++static void __exit ++cleanup_arctic_mtd(void) ++{ ++ if (arctic_mtd) { ++ del_mtd_partitions(arctic_mtd); ++ map_destroy(arctic_mtd); ++ iounmap((void *) arctic_mtd_map.virt); ++ } ++} ++ ++module_init(init_arctic_mtd); ++module_exit(cleanup_arctic_mtd); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("David Gibson "); ++MODULE_DESCRIPTION("MTD map and partitions for IBM 405LP Arctic boards"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/autcpu12-nvram.c linux/drivers/mtd/maps/autcpu12-nvram.c +--- linux-mips-2.4.27/drivers/mtd/maps/autcpu12-nvram.c 2002-06-27 00:35:50.000000000 +0200 ++++ linux/drivers/mtd/maps/autcpu12-nvram.c 2004-11-19 10:25:11.894200552 +0100 +@@ -2,7 +2,7 @@ + * NV-RAM memory access on autcpu12 + * (C) 2002 Thomas Gleixner (gleixner@autronix.de) + * +- * $Id: autcpu12-nvram.c,v 1.1 2002/02/22 09:30:24 gleixner Exp $ ++ * $Id: autcpu12-nvram.c,v 1.5 2003/05/21 12:45:18 dwmw2 Exp $ + * + * 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 +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -32,80 +33,27 @@ + #include + #include + +-__u8 autcpu12_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-__u16 autcpu12_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} +- +-__u32 autcpu12_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} +- +-void autcpu12_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void autcpu12_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void autcpu12_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void autcpu12_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-void autcpu12_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- while(len) { +- __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to); +- from++; +- to++; +- len--; +- } +-} + + static struct mtd_info *sram_mtd; + + struct map_info autcpu12_sram_map = { +- name: "SRAM", +- size: 32768, +- buswidth: 8, +- read8: autcpu12_read8, +- read16: autcpu12_read16, +- read32: autcpu12_read32, +- copy_from: autcpu12_copy_from, +- write8: autcpu12_write8, +- write16: autcpu12_write16, +- write32: autcpu12_write32, +- copy_to: autcpu12_copy_to ++ .name = "SRAM", ++ .size = 32768, ++ .buswidth = 4, ++ .phys = 0x12000000, + }; + + static int __init init_autcpu12_sram (void) + { + int err, save0, save1; + +- autcpu12_sram_map.map_priv_1 = (unsigned long)ioremap(0x12000000, SZ_128K); +- if (!autcpu12_sram_map.map_priv_1) { ++ autcpu12_sram_map.virt = (unsigned long)ioremap(0x12000000, SZ_128K); ++ if (!autcpu12_sram_map.virt) { + printk("Failed to ioremap autcpu12 NV-RAM space\n"); + err = -EIO; + goto out; + } ++ simple_map_init(&autcpu_sram_map); + + /* + * Check for 32K/128K +@@ -115,20 +63,20 @@ + * Read and check result on ofs 0x0 + * Restore contents + */ +- save0 = autcpu12_read32(&autcpu12_sram_map,0); +- save1 = autcpu12_read32(&autcpu12_sram_map,0x10000); +- autcpu12_write32(&autcpu12_sram_map,~save0,0x10000); ++ save0 = map_read32(&autcpu12_sram_map,0); ++ save1 = map_read32(&autcpu12_sram_map,0x10000); ++ map_write32(&autcpu12_sram_map,~save0,0x10000); + /* if we find this pattern on 0x0, we have 32K size + * restore contents and exit + */ +- if ( autcpu12_read32(&autcpu12_sram_map,0) != save0) { +- autcpu12_write32(&autcpu12_sram_map,save0,0x0); ++ if ( map_read32(&autcpu12_sram_map,0) != save0) { ++ map_write32(&autcpu12_sram_map,save0,0x0); + goto map; + } + /* We have a 128K found, restore 0x10000 and set size + * to 128K + */ +- autcpu12_write32(&autcpu12_sram_map,save1,0x10000); ++ ma[_write32(&autcpu12_sram_map,save1,0x10000); + autcpu12_sram_map.size = SZ_128K; + + map: +@@ -139,7 +87,7 @@ + goto out_ioremap; + } + +- sram_mtd->module = THIS_MODULE; ++ sram_mtd->owner = THIS_MODULE; + sram_mtd->erasesize = 16; + + if (add_mtd_device(sram_mtd)) { +@@ -148,7 +96,7 @@ + goto out_probe; + } + +- printk("NV-RAM device size %ldK registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K); ++ printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K); + + return 0; + +@@ -157,7 +105,7 @@ + sram_mtd = 0; + + out_ioremap: +- iounmap((void *)autcpu12_sram_map.map_priv_1); ++ iounmap((void *)autcpu12_sram_map.virt); + out: + return err; + } +@@ -167,7 +115,7 @@ + if (sram_mtd) { + del_mtd_device(sram_mtd); + map_destroy(sram_mtd); +- iounmap((void *)autcpu12_sram_map.map_priv_1); ++ iounmap((void *)autcpu12_sram_map.virt); + } + } + +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/beech-mtd.c linux/drivers/mtd/maps/beech-mtd.c +--- linux-mips-2.4.27/drivers/mtd/maps/beech-mtd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/maps/beech-mtd.c 2004-11-19 10:25:11.895200400 +0100 +@@ -0,0 +1,112 @@ ++/* ++ * $Id: beech-mtd.c,v 1.7 2003/05/21 12:45:18 dwmw2 Exp $ ++ * ++ * drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for ++ * IBM 405LP Beech boards. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Copyright (C) 2002, International Business Machines Corporation ++ * All Rights Reserved. ++ * ++ * Bishop Brock ++ * IBM Research, Austin Center for Low-Power Computing ++ * bcbrock@us.ibm.com ++ * March 2002 ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define NAME "Beech Linux Flash" ++#define PADDR BEECH_BIGFLASH_PADDR ++#define SIZE BEECH_BIGFLASH_SIZE ++#define BUSWIDTH 1 ++ ++/* Flash memories on these boards are memory resources, accessed big-endian. */ ++ ++ ++static struct map_info beech_mtd_map = { ++ .name = NAME, ++ .size = SIZE, ++ .buswidth = BUSWIDTH, ++ .phys = PADDR ++}; ++ ++static struct mtd_info *beech_mtd; ++ ++static struct mtd_partition beech_partitions[2] = { ++ { ++ .name = "Linux Kernel", ++ .size = BEECH_KERNEL_SIZE, ++ .offset = BEECH_KERNEL_OFFSET ++ }, { ++ .name = "Free Area", ++ .size = BEECH_FREE_AREA_SIZE, ++ .offset = BEECH_FREE_AREA_OFFSET ++ } ++}; ++ ++static int __init ++init_beech_mtd(void) ++{ ++ printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR); ++ ++ beech_mtd_map.virt = (unsigned long) ioremap(PADDR, SIZE); ++ ++ if (!beech_mtd_map.virt) { ++ printk("%s: failed to ioremap 0x%x\n", NAME, PADDR); ++ return -EIO; ++ } ++ ++ simple_map_init(&beech_mtd_map); ++ ++ printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8); ++ beech_mtd = do_map_probe("cfi_probe", &beech_mtd_map); ++ ++ if (!beech_mtd) ++ return -ENXIO; ++ ++ beech_mtd->owner = THIS_MODULE; ++ ++ return add_mtd_partitions(beech_mtd, beech_partitions, 2); ++} ++ ++static void __exit ++cleanup_beech_mtd(void) ++{ ++ if (beech_mtd) { ++ del_mtd_partitions(beech_mtd); ++ map_destroy(beech_mtd); ++ iounmap((void *) beech_mtd_map.virt); ++ } ++} ++ ++module_init(init_beech_mtd); ++module_exit(cleanup_beech_mtd); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Bishop Brock "); ++MODULE_DESCRIPTION("MTD map and partitions for IBM 405LP Beech boards"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/cdb89712.c linux/drivers/mtd/maps/cdb89712.c +--- linux-mips-2.4.27/drivers/mtd/maps/cdb89712.c 2001-11-05 21:15:52.000000000 +0100 ++++ linux/drivers/mtd/maps/cdb89712.c 2004-11-19 10:25:11.897200096 +0100 +@@ -1,13 +1,14 @@ + /* + * Flash on Cirrus CDB89712 + * +- * $Id: cdb89712.c,v 1.3 2001/10/02 15:14:43 rmk Exp $ ++ * $Id: cdb89712.c,v 1.7 2003/05/21 12:45:18 dwmw2 Exp $ + */ + + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -16,77 +17,21 @@ + + + +-__u8 cdb89712_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-__u16 cdb89712_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} +- +-__u32 cdb89712_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} +- +-void cdb89712_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void cdb89712_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void cdb89712_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void cdb89712_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- // printk ("cdb89712_copy_from: 0x%x@0x%x -> 0x%x\n", len, from, to); +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-void cdb89712_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- while(len) { +- __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to); +- from++; +- to++; +- len--; +- } +-} +- + + static struct mtd_info *flash_mtd; + + struct map_info cdb89712_flash_map = { +- name: "flash", +- size: FLASH_SIZE, +- buswidth: FLASH_WIDTH, +- read8: cdb89712_read8, +- read16: cdb89712_read16, +- read32: cdb89712_read32, +- copy_from: cdb89712_copy_from, +- write8: cdb89712_write8, +- write16: cdb89712_write16, +- write32: cdb89712_write32, +- copy_to: cdb89712_copy_to ++ .name = "flash", ++ .size = FLASH_SIZE, ++ .buswidth = FLASH_WIDTH, ++ .phys = FLASH_START, + }; + + struct resource cdb89712_flash_resource = { +- name: "Flash", +- start: FLASH_START, +- end: FLASH_START + FLASH_SIZE - 1, +- flags: IORESOURCE_IO | IORESOURCE_BUSY, ++ .name = "Flash", ++ .start = FLASH_START, ++ .end = FLASH_START + FLASH_SIZE - 1, ++ .flags = IORESOURCE_IO | IORESOURCE_BUSY, + }; + + static int __init init_cdb89712_flash (void) +@@ -99,13 +44,13 @@ + goto out; + } + +- cdb89712_flash_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE); +- if (!cdb89712_flash_map.map_priv_1) { ++ cdb89712_flash_map.virt = (unsigned long)ioremap(FLASH_START, FLASH_SIZE); ++ if (!cdb89712_flash_map.virt) { + printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n"); + err = -EIO; + goto out_resource; + } +- ++ simple_map_init(&cdb89712_flash_map); + flash_mtd = do_map_probe("cfi_probe", &cdb89712_flash_map); + if (!flash_mtd) { + flash_mtd = do_map_probe("map_rom", &cdb89712_flash_map); +@@ -118,7 +63,7 @@ + goto out_ioremap; + } + +- flash_mtd->module = THIS_MODULE; ++ flash_mtd->owner = THIS_MODULE; + + if (add_mtd_device(flash_mtd)) { + printk("FLASH device addition failed\n"); +@@ -132,7 +77,7 @@ + map_destroy(flash_mtd); + flash_mtd = 0; + out_ioremap: +- iounmap((void *)cdb89712_flash_map.map_priv_1); ++ iounmap((void *)cdb89712_flash_map.virt); + out_resource: + release_resource (&cdb89712_flash_resource); + out: +@@ -146,24 +91,17 @@ + static struct mtd_info *sram_mtd; + + struct map_info cdb89712_sram_map = { +- name: "SRAM", +- size: SRAM_SIZE, +- buswidth: SRAM_WIDTH, +- read8: cdb89712_read8, +- read16: cdb89712_read16, +- read32: cdb89712_read32, +- copy_from: cdb89712_copy_from, +- write8: cdb89712_write8, +- write16: cdb89712_write16, +- write32: cdb89712_write32, +- copy_to: cdb89712_copy_to ++ .name = "SRAM", ++ .size = SRAM_SIZE, ++ .buswidth = SRAM_WIDTH, ++ .phys = SRAM_START, + }; + + struct resource cdb89712_sram_resource = { +- name: "SRAM", +- start: SRAM_START, +- end: SRAM_START + SRAM_SIZE - 1, +- flags: IORESOURCE_IO | IORESOURCE_BUSY, ++ .name = "SRAM", ++ .start = SRAM_START, ++ .end = SRAM_START + SRAM_SIZE - 1, ++ .flags = IORESOURCE_IO | IORESOURCE_BUSY, + }; + + static int __init init_cdb89712_sram (void) +@@ -176,13 +114,13 @@ + goto out; + } + +- cdb89712_sram_map.map_priv_1 = (unsigned long)ioremap(SRAM_START, SRAM_SIZE); +- if (!cdb89712_sram_map.map_priv_1) { ++ cdb89712_sram_map.virt = (unsigned long)ioremap(SRAM_START, SRAM_SIZE); ++ if (!cdb89712_sram_map.virt) { + printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n"); + err = -EIO; + goto out_resource; + } +- ++ simple_map_init(&cdb89712_sram_map); + sram_mtd = do_map_probe("map_ram", &cdb89712_sram_map); + if (!sram_mtd) { + printk("SRAM probe failed\n"); +@@ -190,7 +128,7 @@ + goto out_ioremap; + } + +- sram_mtd->module = THIS_MODULE; ++ sram_mtd->owner = THIS_MODULE; + sram_mtd->erasesize = 16; + + if (add_mtd_device(sram_mtd)) { +@@ -205,7 +143,7 @@ + map_destroy(sram_mtd); + sram_mtd = 0; + out_ioremap: +- iounmap((void *)cdb89712_sram_map.map_priv_1); ++ iounmap((void *)cdb89712_sram_map.virt); + out_resource: + release_resource (&cdb89712_sram_resource); + out: +@@ -221,20 +159,17 @@ + static struct mtd_info *bootrom_mtd; + + struct map_info cdb89712_bootrom_map = { +- name: "BootROM", +- size: BOOTROM_SIZE, +- buswidth: BOOTROM_WIDTH, +- read8: cdb89712_read8, +- read16: cdb89712_read16, +- read32: cdb89712_read32, +- copy_from: cdb89712_copy_from, ++ .name = "BootROM", ++ .size = BOOTROM_SIZE, ++ .buswidth = BOOTROM_WIDTH, ++ .phys = BOOTROM_START, + }; + + struct resource cdb89712_bootrom_resource = { +- name: "BootROM", +- start: BOOTROM_START, +- end: BOOTROM_START + BOOTROM_SIZE - 1, +- flags: IORESOURCE_IO | IORESOURCE_BUSY, ++ .name = "BootROM", ++ .start = BOOTROM_START, ++ .end = BOOTROM_START + BOOTROM_SIZE - 1, ++ .flags = IORESOURCE_IO | IORESOURCE_BUSY, + }; + + static int __init init_cdb89712_bootrom (void) +@@ -247,13 +182,13 @@ + goto out; + } + +- cdb89712_bootrom_map.map_priv_1 = (unsigned long)ioremap(BOOTROM_START, BOOTROM_SIZE); +- if (!cdb89712_bootrom_map.map_priv_1) { ++ cdb89712_bootrom_map.virt = (unsigned long)ioremap(BOOTROM_START, BOOTROM_SIZE); ++ if (!cdb89712_bootrom_map.virt) { + printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n"); + err = -EIO; + goto out_resource; + } +- ++ simple_map_init(&cdb89712_bootrom_map); + bootrom_mtd = do_map_probe("map_rom", &cdb89712_bootrom_map); + if (!bootrom_mtd) { + printk("BootROM probe failed\n"); +@@ -261,7 +196,7 @@ + goto out_ioremap; + } + +- bootrom_mtd->module = THIS_MODULE; ++ bootrom_mtd->owner = THIS_MODULE; + bootrom_mtd->erasesize = 0x10000; + + if (add_mtd_device(bootrom_mtd)) { +@@ -276,7 +211,7 @@ + map_destroy(bootrom_mtd); + bootrom_mtd = 0; + out_ioremap: +- iounmap((void *)cdb89712_bootrom_map.map_priv_1); ++ iounmap((void *)cdb89712_bootrom_map.virt); + out_resource: + release_resource (&cdb89712_bootrom_resource); + out: +@@ -306,21 +241,21 @@ + if (sram_mtd) { + del_mtd_device(sram_mtd); + map_destroy(sram_mtd); +- iounmap((void *)cdb89712_sram_map.map_priv_1); ++ iounmap((void *)cdb89712_sram_map.virt); + release_resource (&cdb89712_sram_resource); + } + + if (flash_mtd) { + del_mtd_device(flash_mtd); + map_destroy(flash_mtd); +- iounmap((void *)cdb89712_flash_map.map_priv_1); ++ iounmap((void *)cdb89712_flash_map.virt); + release_resource (&cdb89712_flash_resource); + } + + if (bootrom_mtd) { + del_mtd_device(bootrom_mtd); + map_destroy(bootrom_mtd); +- iounmap((void *)cdb89712_bootrom_map.map_priv_1); ++ iounmap((void *)cdb89712_bootrom_map.virt); + release_resource (&cdb89712_bootrom_resource); + } + } +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/ceiva.c linux/drivers/mtd/maps/ceiva.c +--- linux-mips-2.4.27/drivers/mtd/maps/ceiva.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/maps/ceiva.c 2004-11-19 10:25:11.898199944 +0100 +@@ -11,7 +11,7 @@ + * + * (C) 2000 Nicolas Pitre + * +- * $Id: ceiva.c,v 1.2 2002/10/14 12:50:22 rmk Exp $ ++ * $Id: ceiva.c,v 1.8 2003/05/21 12:45:18 dwmw2 Exp $ + */ + + #include +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -31,62 +32,10 @@ + #include + + /* +- * This isnt complete yet, so... ++ * This isn't complete yet, so... + */ + #define CONFIG_MTD_CEIVA_STATICMAP + +-static __u8 clps_read8(struct map_info *map, unsigned long ofs) +-{ +- return readb(map->map_priv_1 + ofs); +-} +- +-static __u16 clps_read16(struct map_info *map, unsigned long ofs) +-{ +- return readw(map->map_priv_1 + ofs); +-} +- +-static __u32 clps_read32(struct map_info *map, unsigned long ofs) +-{ +- return readl(map->map_priv_1 + ofs); +-} +- +-static void clps_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy(to, (void *)(map->map_priv_1 + from), len); +-} +- +-static void clps_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- writeb(d, map->map_priv_1 + adr); +-} +- +-static void clps_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- writew(d, map->map_priv_1 + adr); +-} +- +-static void clps_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- writel(d, map->map_priv_1 + adr); +-} +- +-static void clps_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy((void *)(map->map_priv_1 + to), from, len); +-} +- +-static struct map_info clps_map __initdata = { +- name: "clps flash", +- read8: clps_read8, +- read16: clps_read16, +- read32: clps_read32, +- copy_from: clps_copy_from, +- write8: clps_write8, +- write16: clps_write16, +- write32: clps_write32, +- copy_to: clps_copy_to, +-}; +- + #ifdef CONFIG_MTD_CEIVA_STATICMAP + /* + * See include/linux/mtd/partitions.h for definition of the mtd_partition +@@ -176,7 +125,7 @@ + maps = kmalloc(sizeof(struct map_info) * nr, GFP_KERNEL); + if (!maps) + return -ENOMEM; +- ++ memset(maps, 0, sizeof(struct map_info) * nr); + /* + * Claim and then map the memory regions. + */ +@@ -191,7 +140,9 @@ + } + + clps[i].map = maps + i; +- memcpy(clps[i].map, &clps_map, sizeof(struct map_info)); ++ ++ clps[i].map->name = "clps flash"; ++ clps[i].map->phys = clps[i].base; + + clps[i].vbase = ioremap(clps[i].base, clps[i].size); + if (!clps[i].vbase) { +@@ -199,16 +150,18 @@ + break; + } + +- clps[i].map->map_priv_1 = (unsigned long)clps[i].vbase; ++ clps[i].map->virt = (unsigned long)clps[i].vbase; + clps[i].map->buswidth = clps[i].width; + clps[i].map->size = clps[i].size; + ++ simple_map_init(&clps[i].map); ++ + clps[i].mtd = do_map_probe("jedec_probe", clps[i].map); + if (clps[i].mtd == NULL) { + ret = -ENXIO; + break; + } +- clps[i].mtd->module = THIS_MODULE; ++ clps[i].mtd->owner = THIS_MODULE; + subdev[i] = clps[i].mtd; + + printk(KERN_INFO "clps flash: JEDEC device at 0x%08lx, %dMiB, " +@@ -318,10 +271,8 @@ + return nr; + } + +-extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); +-extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *); +- + static struct mtd_partition *parsed_parts; ++static const char *probes[] = { "cmdlinepart", "RedBoot", NULL }; + + static void __init clps_locate_partitions(struct mtd_info *mtd) + { +@@ -331,20 +282,11 @@ + /* + * Partition selection stuff. + */ +-#ifdef CONFIG_MTD_CMDLINE_PARTS +- nr_parts = parse_cmdline_partitions(mtd, &parsed_parts, "clps"); ++ nr_parts = parse_mtd_partitions(mtd, probes, &parsed_parts, 0); + if (nr_parts > 0) { + part_type = "command line"; + break; + } +-#endif +-#ifdef CONFIG_MTD_REDBOOT_PARTS +- nr_parts = parse_redboot_partitions(mtd, &parsed_parts); +- if (nr_parts > 0) { +- part_type = "RedBoot"; +- break; +- } +-#endif + #ifdef CONFIG_MTD_CEIVA_STATICMAP + nr_parts = clps_static_partitions(&parsed_parts); + if (nr_parts > 0) { +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/cfi_flagadm.c linux/drivers/mtd/maps/cfi_flagadm.c +--- linux-mips-2.4.27/drivers/mtd/maps/cfi_flagadm.c 2001-11-05 21:15:52.000000000 +0100 ++++ linux/drivers/mtd/maps/cfi_flagadm.c 2004-11-19 10:25:11.900199640 +0100 +@@ -1,7 +1,7 @@ + /* + * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson + * +- * $Id: cfi_flagadm.c,v 1.7 2001/10/02 15:05:13 dwmw2 Exp $ ++ * $Id: cfi_flagadm.c,v 1.11 2003/05/21 12:45:18 dwmw2 Exp $ + * + * 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 +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -55,83 +56,33 @@ + #define FLASH_PARTITION3_ADDR 0x00240000 + #define FLASH_PARTITION3_SIZE 0x001C0000 + +-__u8 flagadm_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-__u16 flagadm_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} +- +-__u32 flagadm_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} +- +-void flagadm_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-void flagadm_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void flagadm_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void flagadm_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void flagadm_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio(map->map_priv_1 + to, from, len); +-} + + struct map_info flagadm_map = { +- name: "FlagaDM flash device", +- size: FLASH_SIZE, +- buswidth: 2, +- read8: flagadm_read8, +- read16: flagadm_read16, +- read32: flagadm_read32, +- copy_from: flagadm_copy_from, +- write8: flagadm_write8, +- write16: flagadm_write16, +- write32: flagadm_write32, +- copy_to: flagadm_copy_to ++ .name = "FlagaDM flash device", ++ .size = FLASH_SIZE, ++ .buswidth = 2, + }; + + struct mtd_partition flagadm_parts[] = { + { +- name : "Bootloader", +- offset : FLASH_PARTITION0_ADDR, +- size : FLASH_PARTITION0_SIZE ++ .name = "Bootloader", ++ .offset = FLASH_PARTITION0_ADDR, ++ .size = FLASH_PARTITION0_SIZE + }, + { +- name : "Kernel image", +- offset : FLASH_PARTITION1_ADDR, +- size : FLASH_PARTITION1_SIZE ++ .name = "Kernel image", ++ .offset = FLASH_PARTITION1_ADDR, ++ .size = FLASH_PARTITION1_SIZE + }, + { +- name : "Initial ramdisk image", +- offset : FLASH_PARTITION2_ADDR, +- size : FLASH_PARTITION2_SIZE ++ .name = "Initial ramdisk image", ++ .offset = FLASH_PARTITION2_ADDR, ++ .size = FLASH_PARTITION2_SIZE + }, + { +- name : "Persistant storage", +- offset : FLASH_PARTITION3_ADDR, +- size : FLASH_PARTITION3_SIZE ++ .name = "Persistant storage", ++ .offset = FLASH_PARTITION3_ADDR, ++ .size = FLASH_PARTITION3_SIZE + } + }; + +@@ -144,22 +95,26 @@ + printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n", + FLASH_SIZE, FLASH_PHYS_ADDR); + +- flagadm_map.map_priv_1 = (unsigned long)ioremap(FLASH_PHYS_ADDR, ++ flagadm_map.phys = FLASH_PHYS_ADDR; ++ flagadm_map.virt = (unsigned long)ioremap(FLASH_PHYS_ADDR, + FLASH_SIZE); + +- if (!flagadm_map.map_priv_1) { ++ if (!flagadm_map.virt) { + printk("Failed to ioremap\n"); + return -EIO; + } ++ ++ simple_map_init(&flagadm_map); ++ + mymtd = do_map_probe("cfi_probe", &flagadm_map); + if (mymtd) { +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + add_mtd_partitions(mymtd, flagadm_parts, PARTITION_COUNT); + printk(KERN_NOTICE "FlagaDM flash device initialized\n"); + return 0; + } + +- iounmap((void *)flagadm_map.map_priv_1); ++ iounmap((void *)flagadm_map.virt); + return -ENXIO; + } + +@@ -169,9 +124,9 @@ + del_mtd_partitions(mymtd); + map_destroy(mymtd); + } +- if (flagadm_map.map_priv_1) { +- iounmap((void *)flagadm_map.map_priv_1); +- flagadm_map.map_priv_1 = 0; ++ if (flagadm_map.virt) { ++ iounmap((void *)flagadm_map.virt); ++ flagadm_map.virt = 0; + } + } + +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/cstm_mips_ixx.c linux/drivers/mtd/maps/cstm_mips_ixx.c +--- linux-mips-2.4.27/drivers/mtd/maps/cstm_mips_ixx.c 2001-11-05 21:15:52.000000000 +0100 ++++ linux/drivers/mtd/maps/cstm_mips_ixx.c 2004-11-19 10:25:11.901199488 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: cstm_mips_ixx.c,v 1.5 2001/10/02 15:05:14 dwmw2 Exp $ ++ * $Id: cstm_mips_ixx.c,v 1.9 2003/05/21 12:45:18 dwmw2 Exp $ + * + * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions. + * Config with both CFI and JEDEC device support. +@@ -33,55 +33,13 @@ + #include + #include + #include ++#include + #include + #include + #include + #include + #include +- +-#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) + #include +-#endif +- +-__u8 cstm_mips_ixx_read8(struct map_info *map, unsigned long ofs) +-{ +- return *(__u8 *)(map->map_priv_1 + ofs); +-} +- +-__u16 cstm_mips_ixx_read16(struct map_info *map, unsigned long ofs) +-{ +- return *(__u16 *)(map->map_priv_1 + ofs); +-} +- +-__u32 cstm_mips_ixx_read32(struct map_info *map, unsigned long ofs) +-{ +- return *(__u32 *)(map->map_priv_1 + ofs); +-} +- +-void cstm_mips_ixx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-void cstm_mips_ixx_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- *(__u8 *)(map->map_priv_1 + adr) = d; +-} +- +-void cstm_mips_ixx_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- *(__u16 *)(map->map_priv_1 + adr) = d; +-} +- +-void cstm_mips_ixx_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- *(__u32 *)(map->map_priv_1 + adr) = d; +-} +- +-void cstm_mips_ixx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio(map->map_priv_1 + to, from, len); +-} + + #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) + #define CC_GCR 0xB4013818 +@@ -97,10 +55,17 @@ + #define CC_GPAICR 0xB4013804 + #endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */ + ++#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) + void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp) + { ++ static spinlock_t vpp_lock = SPIN_LOCK_UNLOCKED; ++ static int vpp_count = 0; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&vpp_lock, flags); ++ + if (vpp) { +-#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) ++ if (!vpp_count++) { + __u16 data; + __u8 data1; + static u8 first = 1; +@@ -116,10 +81,9 @@ + enabling vpp after powerup */ + udelay(40); + } +-#endif /* CONFIG_MIPS_ITE8172 */ + } +- else { +-#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) ++ } else { ++ if (!--vpp_count) { + __u16 data; + + // Set GPIO port B pin3 to high +@@ -127,26 +91,11 @@ + data = (data & 0xff3f) | 0x0040; + *(__u16 *)CC_GPBCR = data; + *(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) & 0xf7; +-#endif /* CONFIG_MIPS_ITE8172 */ + } ++ } ++ spin_unlock_irqrestore(&vpp_lock, flags); + } +- +-const struct map_info basic_cstm_mips_ixx_map = { +- NULL, +- 0, +- 0, +- cstm_mips_ixx_read8, +- cstm_mips_ixx_read16, +- cstm_mips_ixx_read32, +- cstm_mips_ixx_copy_from, +- cstm_mips_ixx_write8, +- cstm_mips_ixx_write16, +- cstm_mips_ixx_write32, +- cstm_mips_ixx_copy_to, +- cstm_mips_ixx_set_vpp, +- 0, +- 0 +-}; ++#endif + + /* board and partition description */ + +@@ -175,9 +124,9 @@ + static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = { + { // 28F128J3A in 2x16 configuration + { +- name: "main partition ", +- size: 0x02000000, // 128 x 2 x 128k byte sectors +- offset: 0, ++ .name = "main partition ", ++ .size = 0x02000000, // 128 x 2 x 128k byte sectors ++ .offset = 0, + }, + }, + }; +@@ -197,9 +146,9 @@ + static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = { + { + { +- name: "main partition", +- size: CONFIG_MTD_CSTM_MIPS_IXX_LEN, +- offset: 0, ++ .name = "main partition", ++ .size = CONFIG_MTD_CSTM_MIPS_IXX_LEN, ++ .offset = 0, + }, + }, + }; +@@ -216,17 +165,24 @@ + + /* Initialize mapping */ + for (i=0;imodule = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + + cstm_mips_ixx_map[i].map_priv_2 = (unsigned long)mymtd; + add_mtd_partitions(mymtd, parts, cstm_mips_ixx_board_desc[i].num_partitions); +@@ -266,9 +222,9 @@ + del_mtd_partitions(mymtd); + map_destroy(mymtd); + } +- if (cstm_mips_ixx_map[i].map_priv_1) { +- iounmap((void *)cstm_mips_ixx_map[i].map_priv_1); +- cstm_mips_ixx_map[i].map_priv_1 = 0; ++ if (cstm_mips_ixx_map[i].virt) { ++ iounmap((void *)cstm_mips_ixx_map[i].virt); ++ cstm_mips_ixx_map[i].virt = 0; + } + } + } +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/db1x00-flash.c linux/drivers/mtd/maps/db1x00-flash.c +--- linux-mips-2.4.27/drivers/mtd/maps/db1x00-flash.c 2003-02-16 07:25:24.000000000 +0100 ++++ linux/drivers/mtd/maps/db1x00-flash.c 2004-11-19 10:25:11.903199184 +0100 +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -29,76 +30,6 @@ + static unsigned long flash_size; + + static BCSR * const bcsr = (BCSR *)0xAE000000; +- +-__u8 physmap_read8(struct map_info *map, unsigned long ofs) +-{ +- __u8 ret; +- ret = __raw_readb(map->map_priv_1 + ofs); +- DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); +- return ret; +-} +- +-__u16 physmap_read16(struct map_info *map, unsigned long ofs) +-{ +- __u16 ret; +- ret = __raw_readw(map->map_priv_1 + ofs); +- DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); +- return ret; +-} +- +-__u32 physmap_read32(struct map_info *map, unsigned long ofs) +-{ +- __u32 ret; +- ret = __raw_readl(map->map_priv_1 + ofs); +- DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); +- return ret; +-} +- +-void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to); +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-void physmap_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void physmap_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void physmap_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from); +- memcpy_toio(map->map_priv_1 + to, from, len); +-} +- +-static struct map_info db1x00_map = { +- name: "Db1x00 flash", +- read8: physmap_read8, +- read16: physmap_read16, +- read32: physmap_read32, +- copy_from: physmap_copy_from, +- write8: physmap_write8, +- write16: physmap_write16, +- write32: physmap_write32, +- copy_to: physmap_copy_to, +-}; +- + static unsigned char flash_buswidth = 4; + + /* +@@ -115,58 +46,62 @@ + */ + static struct mtd_partition db1x00_partitions[] = { + { +- name: "User FS", +- size: 0x1c00000, +- offset: 0x0000000 ++ .name = "User FS", ++ .size = 0x1c00000, ++ .offset = 0x0000000 + },{ +- name: "yamon", +- size: 0x0100000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE ++ .name = "yamon", ++ .size = 0x0100000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE + },{ +- name: "raw kernel", +- size: (0x300000-0x40000), /* last 256KB is yamon env */ +- offset: MTDPART_OFS_APPEND, ++ .name = "raw kernel", ++ .size = (0x300000-0x40000), /* last 256KB is env */ ++ .offset = MTDPART_OFS_APPEND, + } + }; + #elif defined(DB1X00_BOOT_ONLY) + static struct mtd_partition db1x00_partitions[] = { + { +- name: "User FS", +- size: 0x00c00000, +- offset: 0x0000000 ++ .name = "User FS", ++ .size = 0x00c00000, ++ .offset = 0x0000000 + },{ +- name: "yamon", +- size: 0x0100000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE ++ .name = "yamon", ++ .size = 0x0100000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE + },{ +- name: "raw kernel", +- size: (0x300000-0x40000), /* last 256KB is yamon env */ +- offset: MTDPART_OFS_APPEND, ++ .name = "raw kernel", ++ .size = (0x300000-0x40000), /* last 256KB is env */ ++ .offset = MTDPART_OFS_APPEND, + } + }; + #elif defined(DB1X00_USER_ONLY) + static struct mtd_partition db1x00_partitions[] = { + { +- name: "User FS", +- size: 0x0e00000, +- offset: 0x0000000 ++ .name = "User FS", ++ .size = 0x0e00000, ++ .offset = 0x0000000 + },{ +- name: "raw kernel", +- size: MTDPART_SIZ_FULL, +- offset: MTDPART_OFS_APPEND, ++ .name = "raw kernel", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND, + } + }; + #else + #error MTD_DB1X00 define combo error /* should never happen */ + #endif ++#define NB_OF(x) (sizeof(x)/sizeof(x[0])) + ++#define NAME "Db1x00 Linux Flash" + +-#define NB_OF(x) (sizeof(x)/sizeof(x[0])) ++static struct map_info db1xxx_mtd_map = { ++ .name = NAME, ++}; + + static struct mtd_partition *parsed_parts; +-static struct mtd_info *mymtd; ++static struct mtd_info *db1xxx_mtd; + + /* + * Probe the flash density and setup window address and size +@@ -174,7 +109,7 @@ + * want the MTD driver to be probing the boot or user flash, + * so having the option to enable only one bank is important. + */ +-int setup_flash_params() ++int setup_flash_params(void) + { + switch ((bcsr->status >> 14) & 0x3) { + case 0: /* 64Mbit devices */ +@@ -228,6 +163,10 @@ + default: + return 1; + } ++ db1xxx_mtd_map.size = window_size; ++ db1xxx_mtd_map.buswidth = flash_buswidth; ++ db1xxx_mtd_map.phys = window_addr; ++ db1xxx_mtd_map.buswidth = flash_buswidth; + return 0; + } + +@@ -235,10 +174,6 @@ + { + struct mtd_partition *parts; + int nb_parts = 0; +- char *part_type; +- +- /* Default flash buswidth */ +- db1x00_map.buswidth = flash_buswidth; + + if (setup_flash_params()) + return -ENXIO; +@@ -246,32 +181,29 @@ + /* + * Static partition definition selection + */ +- part_type = "static"; + parts = db1x00_partitions; + nb_parts = NB_OF(db1x00_partitions); +- db1x00_map.size = window_size; + + /* + * Now let's probe for the actual flash. Do it here since + * specific machine settings might have been set above. + */ + printk(KERN_NOTICE "Db1xxx flash: probing %d-bit flash bus\n", +- db1x00_map.buswidth*8); +- db1x00_map.map_priv_1 = +- (unsigned long)ioremap(window_addr, window_size); +- mymtd = do_map_probe("cfi_probe", &db1x00_map); +- if (!mymtd) return -ENXIO; +- mymtd->module = THIS_MODULE; ++ db1xxx_mtd_map.buswidth*8); ++ db1xxx_mtd_map.virt = (unsigned long)ioremap(window_addr, window_size); ++ db1xxx_mtd = do_map_probe("cfi_probe", &db1xxx_mtd_map); ++ if (!db1xxx_mtd) return -ENXIO; ++ db1xxx_mtd->owner = THIS_MODULE; + +- add_mtd_partitions(mymtd, parts, nb_parts); ++ add_mtd_partitions(db1xxx_mtd, parts, nb_parts); + return 0; + } + + static void __exit db1x00_mtd_cleanup(void) + { +- if (mymtd) { +- del_mtd_partitions(mymtd); +- map_destroy(mymtd); ++ if (db1xxx_mtd) { ++ del_mtd_partitions(db1xxx_mtd); ++ map_destroy(db1xxx_mtd); + if (parsed_parts) + kfree(parsed_parts); + } +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/dbox2-flash.c linux/drivers/mtd/maps/dbox2-flash.c +--- linux-mips-2.4.27/drivers/mtd/maps/dbox2-flash.c 2001-11-05 21:15:52.000000000 +0100 ++++ linux/drivers/mtd/maps/dbox2-flash.c 2004-11-19 10:25:11.904199032 +0100 +@@ -1,12 +1,13 @@ + /* +- * $Id: dbox2-flash.c,v 1.4 2001/10/02 15:05:14 dwmw2 Exp $ ++ * $Id: dbox2-flash.c,v 1.9 2003/05/21 12:45:18 dwmw2 Exp $ + * +- * Nokia / Sagem D-Box 2 flash driver ++ * D-Box 2 flash driver + */ + + #include + #include + #include ++#include + #include + #include + #include +@@ -16,22 +17,44 @@ + /* partition_info gives details on the logical partitions that the split the + * single flash device into. If the size if zero we use up to the end of the + * device. */ +-static struct mtd_partition partition_info[]= {{name: "BR bootloader", // raw +- size: 128 * 1024, +- offset: 0, +- mask_flags: MTD_WRITEABLE}, +- {name: "PPC bootloader", // flfs +- size: 128 * 1024, +- offset: MTDPART_OFS_APPEND, +- mask_flags: 0}, +- {name: "Kernel", // idxfs +- size: 768 * 1024, +- offset: MTDPART_OFS_APPEND, +- mask_flags: 0}, +- {name: "System", // jffs +- size: MTDPART_SIZ_FULL, +- offset: MTDPART_OFS_APPEND, +- mask_flags: 0}}; ++static struct mtd_partition partition_info[]= { ++ { ++ .name = "BR bootloader", ++ .size = 128 * 1024, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE ++ }, ++ { ++ .name = "flfs (ppcboot)", ++ .size = 128 * 1024, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = 0 ++ }, ++ { ++ .name = "root (cramfs)", ++ .size = 7040 * 1024, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = 0 ++ }, ++ { ++ .name = "var (jffs2)", ++ .size = 896 * 1024, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = 0 ++ }, ++ { ++ .name = "flash without bootloader", ++ .size = MTDPART_SIZ_FULL, ++ .offset = 128 * 1024, ++ .mask_flags = 0 ++ }, ++ { ++ .name = "complete flash", ++ .size = MTDPART_SIZ_FULL, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE ++ } ++}; + + #define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0])) + +@@ -40,72 +63,24 @@ + + static struct mtd_info *mymtd; + +-__u8 dbox2_flash_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-__u16 dbox2_flash_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} +- +-__u32 dbox2_flash_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} +- +-void dbox2_flash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-void dbox2_flash_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void dbox2_flash_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void dbox2_flash_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void dbox2_flash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio(map->map_priv_1 + to, from, len); +-} + + struct map_info dbox2_flash_map = { +- name: "D-Box 2 flash memory", +- size: WINDOW_SIZE, +- buswidth: 4, +- read8: dbox2_flash_read8, +- read16: dbox2_flash_read16, +- read32: dbox2_flash_read32, +- copy_from: dbox2_flash_copy_from, +- write8: dbox2_flash_write8, +- write16: dbox2_flash_write16, +- write32: dbox2_flash_write32, +- copy_to: dbox2_flash_copy_to ++ .name = "D-Box 2 flash memory", ++ .size = WINDOW_SIZE, ++ .buswidth = 4, ++ .phys = WINDOW_ADDR, + }; + + int __init init_dbox2_flash(void) + { + printk(KERN_NOTICE "D-Box 2 flash driver (size->0x%X mem->0x%X)\n", WINDOW_SIZE, WINDOW_ADDR); +- dbox2_flash_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); ++ dbox2_flash_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); + +- if (!dbox2_flash_map.map_priv_1) { ++ if (!dbox2_flash_map.virt) { + printk("Failed to ioremap\n"); + return -EIO; + } ++ simple_map_init(&dbox2_flash_map); + + // Probe for dual Intel 28F320 or dual AMD + mymtd = do_map_probe("cfi_probe", &dbox2_flash_map); +@@ -117,7 +92,7 @@ + } + + if (mymtd) { +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + + /* Create MTD devices for each partition. */ + add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS); +@@ -125,7 +100,7 @@ + return 0; + } + +- iounmap((void *)dbox2_flash_map.map_priv_1); ++ iounmap((void *)dbox2_flash_map.virt); + return -ENXIO; + } + +@@ -135,9 +110,9 @@ + del_mtd_partitions(mymtd); + map_destroy(mymtd); + } +- if (dbox2_flash_map.map_priv_1) { +- iounmap((void *)dbox2_flash_map.map_priv_1); +- dbox2_flash_map.map_priv_1 = 0; ++ if (dbox2_flash_map.virt) { ++ iounmap((void *)dbox2_flash_map.virt); ++ dbox2_flash_map.virt = 0; + } + } + +@@ -146,5 +121,5 @@ + + + MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Kári Davíðsson "); +-MODULE_DESCRIPTION("MTD map driver for Nokia/Sagem D-Box 2 board"); ++MODULE_AUTHOR("Kári Davíðsson , Bastian Blank , Alexander Wild "); ++MODULE_DESCRIPTION("MTD map driver for D-Box 2 board"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/dc21285.c linux/drivers/mtd/maps/dc21285.c +--- linux-mips-2.4.27/drivers/mtd/maps/dc21285.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/maps/dc21285.c 2004-11-19 10:25:11.906198728 +0100 +@@ -5,12 +5,13 @@ + * + * This code is GPL + * +- * $Id: dc21285.c,v 1.9 2002/10/14 12:22:10 rmk Exp $ ++ * $Id: dc21285.c,v 1.15 2003/05/21 12:45:18 dwmw2 Exp $ + */ + #include + #include + #include + #include ++#include + + #include + #include +@@ -92,26 +93,42 @@ + } + + struct map_info dc21285_map = { +- name: "DC21285 flash", +- size: 16*1024*1024, +- read8: dc21285_read8, +- read16: dc21285_read16, +- read32: dc21285_read32, +- copy_from: dc21285_copy_from, +- write8: dc21285_write8, +- write16: dc21285_write16, +- write32: dc21285_write32, +- copy_to: dc21285_copy_to ++ .name = "DC21285 flash", ++ .phys = NO_XIP, ++ .size = 16*1024*1024, ++ .read8 = dc21285_read8, ++ .read16 = dc21285_read16, ++ .read32 = dc21285_read32, ++ .copy_from = dc21285_copy_from, ++ .write8 = dc21285_write8, ++ .write16 = dc21285_write16, ++ .write32 = dc21285_write32, ++ .copy_to = dc21285_copy_to + }; + + + /* Partition stuff */ + static struct mtd_partition *dc21285_parts; +- +-extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **); ++#ifdef CONFIG_MTD_PARTITIONS ++static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; ++#endif + + int __init init_dc21285(void) + { ++ ++ /* ++ * Flash timing is determined with bits 19-16 of the ++ * CSR_SA110_CNTL. The value is the number of wait cycles, or ++ * 0 for 16 cycles (the default). Cycles are 20 ns. ++ * Here we use 7 for 140 ns flash chips. ++ */ ++ /* access time */ ++ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16)); ++ /* burst time */ ++ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20)); ++ /* tristate time */ ++ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24)); ++ + /* Determine buswidth */ + switch (*CSR_SA110_CNTL & (3<<14)) { + case SA110_CNTL_ROMWIDTH_8: +@@ -141,33 +158,18 @@ + if (mymtd) { + int nrparts = 0; + +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + + /* partition fixup */ + +-#ifdef CONFIG_MTD_REDBOOT_PARTS +- nrparts = parse_redboot_partitions(mymtd, &dc21285_parts); +-#endif ++#ifdef CONFIG_MTD_PARTITIONS ++ nrparts = parse_mtd_partitions(mymtd, probes, &dc21285_parts, (void *)0); + if (nrparts > 0) { + add_mtd_partitions(mymtd, dc21285_parts, nrparts); +- } else if (nrparts == 0) { +- printk(KERN_NOTICE "RedBoot partition table failed\n"); +- add_mtd_device(mymtd); ++ return 0; + } +- +- /* +- * Flash timing is determined with bits 19-16 of the +- * CSR_SA110_CNTL. The value is the number of wait cycles, or +- * 0 for 16 cycles (the default). Cycles are 20 ns. +- * Here we use 7 for 140 ns flash chips. +- */ +- /* access time */ +- *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16)); +- /* burst time */ +- *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20)); +- /* tristate time */ +- *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24)); +- ++#endif ++ add_mtd_device(mymtd); + return 0; + } + +@@ -177,17 +179,16 @@ + + static void __exit cleanup_dc21285(void) + { +- if (mymtd) { ++#ifdef CONFIG_MTD_PARTITIONS ++ if (dc21285_parts) { ++ del_mtd_partitions(mymtd); ++ kfree(dc21285_parts); ++ } else ++#endif + del_mtd_device(mymtd); ++ + map_destroy(mymtd); +- mymtd = NULL; +- } +- if (dc21285_map.map_priv_1) { + iounmap((void *)dc21285_map.map_priv_1); +- dc21285_map.map_priv_1 = 0; +- } +- if(dc21285_parts) +- kfree(dc21285_parts); + } + + module_init(init_dc21285); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/dilnetpc.c linux/drivers/mtd/maps/dilnetpc.c +--- linux-mips-2.4.27/drivers/mtd/maps/dilnetpc.c 2002-06-27 00:35:50.000000000 +0200 ++++ linux/drivers/mtd/maps/dilnetpc.c 2004-11-19 10:25:11.907198576 +0100 +@@ -14,7 +14,7 @@ + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * +- * $Id: dilnetpc.c,v 1.8 2002/03/12 13:07:26 rkaiser Exp $ ++ * $Id: dilnetpc.c,v 1.12 2003/05/21 12:45:18 dwmw2 Exp $ + * + * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems + * featuring the AMD Elan SC410 processor. There are two variants of this +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -36,7 +37,7 @@ + #include + + /* +-** The DIL/NetPC keeps it's BIOS in two distinct flash blocks. ++** The DIL/NetPC keeps its BIOS in two distinct flash blocks. + ** Destroying any of these blocks transforms the DNPC into + ** a paperweight (albeit not a very useful one, considering + ** it only weighs a few grams). +@@ -189,45 +190,6 @@ + } + + +-static __u8 dnpc_read8(struct map_info *map, unsigned long ofs) +-{ +- return readb(map->map_priv_1 + ofs); +-} +- +-static __u16 dnpc_read16(struct map_info *map, unsigned long ofs) +-{ +- return readw(map->map_priv_1 + ofs); +-} +- +-static __u32 dnpc_read32(struct map_info *map, unsigned long ofs) +-{ +- return readl(map->map_priv_1 + ofs); +-} +- +-static void dnpc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len); +-} +- +-static void dnpc_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- writeb(d, map->map_priv_1 + adr); +-} +- +-static void dnpc_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- writew(d, map->map_priv_1 + adr); +-} +- +-static void dnpc_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- writel(d, map->map_priv_1 + adr); +-} +- +-static void dnpc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio((void *)(map->map_priv_1 + to), from, len); +-} + + /* + ************************************************************ +@@ -288,19 +250,11 @@ + #define WINDOW_ADDR FLASH_BASE + + static struct map_info dnpc_map = { +- name: "ADNP Flash Bank", +- size: ADNP_WINDOW_SIZE, +- buswidth: 1, +- read8: dnpc_read8, +- read16: dnpc_read16, +- read32: dnpc_read32, +- copy_from: dnpc_copy_from, +- write8: dnpc_write8, +- write16: dnpc_write16, +- write32: dnpc_write32, +- copy_to: dnpc_copy_to, +- set_vpp: adnp_set_vpp, +- map_priv_2: WINDOW_ADDR ++ .name = "ADNP Flash Bank", ++ .size = ADNP_WINDOW_SIZE, ++ .buswidth = 1, ++ .set_vpp = adnp_set_vpp, ++ .phys = WINDOW_ADDR + }; + + /* +@@ -316,29 +270,29 @@ + static struct mtd_partition partition_info[]= + { + { +- name: "ADNP boot", +- offset: 0, +- size: 0xf0000, ++ .name = "ADNP boot", ++ .offset = 0, ++ .size = 0xf0000, + }, + { +- name: "ADNP system BIOS", +- offset: MTDPART_OFS_NXTBLK, +- size: 0x10000, ++ .name = "ADNP system BIOS", ++ .offset = MTDPART_OFS_NXTBLK, ++ .size = 0x10000, + #ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED +- mask_flags: MTD_WRITEABLE, ++ .mask_flags = MTD_WRITEABLE, + #endif + }, + { +- name: "ADNP file system", +- offset: MTDPART_OFS_NXTBLK, +- size: 0x2f0000, ++ .name = "ADNP file system", ++ .offset = MTDPART_OFS_NXTBLK, ++ .size = 0x2f0000, + }, + { +- name: "ADNP system BIOS entry", +- offset: MTDPART_OFS_NXTBLK, +- size: MTDPART_SIZ_FULL, ++ .name = "ADNP system BIOS entry", ++ .offset = MTDPART_OFS_NXTBLK, ++ .size = MTDPART_SIZ_FULL, + #ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED +- mask_flags: MTD_WRITEABLE, ++ .mask_flags = MTD_WRITEABLE, + #endif + }, + }; +@@ -369,21 +323,21 @@ + static struct mtd_partition higlvl_partition_info[]= + { + { +- name: "ADNP boot block", +- offset: 0, +- size: CONFIG_MTD_DILNETPC_BOOTSIZE, ++ .name = "ADNP boot block", ++ .offset = 0, ++ .size = CONFIG_MTD_DILNETPC_BOOTSIZE, + }, + { +- name: "ADNP file system space", +- offset: MTDPART_OFS_NXTBLK, +- size: ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000, ++ .name = "ADNP file system space", ++ .offset = MTDPART_OFS_NXTBLK, ++ .size = ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000, + }, + { +- name: "ADNP system BIOS + BIOS Entry", +- offset: MTDPART_OFS_NXTBLK, +- size: MTDPART_SIZ_FULL, ++ .name = "ADNP system BIOS + BIOS Entry", ++ .offset = MTDPART_OFS_NXTBLK, ++ .size = MTDPART_SIZ_FULL, + #ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED +- mask_flags: MTD_WRITEABLE, ++ .mask_flags = MTD_WRITEABLE, + #endif + }, + }; +@@ -447,18 +401,19 @@ + } + + printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n", +- is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.map_priv_2); ++ is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys); + +- dnpc_map.map_priv_1 = (unsigned long)ioremap_nocache(dnpc_map.map_priv_2, dnpc_map.size); ++ dnpc_map.virt = (unsigned long)ioremap_nocache(dnpc_map.phys, dnpc_map.size); + +- dnpc_map_flash(dnpc_map.map_priv_2, dnpc_map.size); ++ dnpc_map_flash(dnpc_map.phys, dnpc_map.size); + +- if (!dnpc_map.map_priv_1) { ++ if (!dnpc_map.virt) { + printk("Failed to ioremap_nocache\n"); + return -EIO; + } ++ simple_map_init(&dnpc_map); + +- printk("FLASH virtual address: 0x%lx\n", dnpc_map.map_priv_1); ++ printk("FLASH virtual address: 0x%lx\n", dnpc_map.virt); + + mymtd = do_map_probe("jedec_probe", &dnpc_map); + +@@ -475,11 +430,11 @@ + mymtd->erasesize = 0x10000; + + if (!mymtd) { +- iounmap((void *)dnpc_map.map_priv_1); ++ iounmap((void *)dnpc_map.virt); + return -ENXIO; + } + +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + + /* + ** Supply pointers to lowlvl_parts[] array to add_mtd_partitions() +@@ -525,10 +480,10 @@ + del_mtd_partitions(mymtd); + map_destroy(mymtd); + } +- if (dnpc_map.map_priv_1) { +- iounmap((void *)dnpc_map.map_priv_1); ++ if (dnpc_map.virt) { ++ iounmap((void *)dnpc_map.virt); + dnpc_unmap_flash(); +- dnpc_map.map_priv_1 = 0; ++ dnpc_map.virt = 0; + } + } + +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/ebony.c linux/drivers/mtd/maps/ebony.c +--- linux-mips-2.4.27/drivers/mtd/maps/ebony.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/maps/ebony.c 2004-11-19 10:25:11.909198272 +0100 +@@ -0,0 +1,164 @@ ++/* ++ * $Id: ebony.c,v 1.8 2003/06/23 11:48:18 dwmw2 Exp $ ++ * ++ * Mapping for Ebony user flash ++ * ++ * Matt Porter ++ * ++ * Copyright 2002 MontaVista Software Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static struct mtd_info *flash; ++ ++static struct map_info ebony_small_map = { ++ .name = "Ebony small flash", ++ .size = EBONY_SMALL_FLASH_SIZE, ++ .buswidth = 1, ++}; ++ ++static struct map_info ebony_large_map = { ++ .name = "Ebony large flash", ++ .size = EBONY_LARGE_FLASH_SIZE, ++ .buswidth = 1, ++}; ++ ++static struct mtd_partition ebony_small_partitions[] = { ++ { ++ .name = "OpenBIOS", ++ .offset = 0x0, ++ .size = 0x80000, ++ } ++}; ++ ++static struct mtd_partition ebony_large_partitions[] = { ++ { ++ .name = "fs", ++ .offset = 0, ++ .size = 0x380000, ++ }, ++ { ++ .name = "firmware", ++ .offset = 0x380000, ++ .size = 0x80000, ++ } ++}; ++ ++int __init init_ebony(void) ++{ ++ u8 fpga0_reg; ++ unsigned long fpga0_adr; ++ unsigned long long small_flash_base, large_flash_base; ++ ++ fpga0_adr = ioremap64(EBONY_FPGA_ADDR, 16); ++ if (!fpga0_adr) ++ return -ENOMEM; ++ ++ fpga0_reg = readb(fpga0_adr); ++ iounmap64(fpga0_adr); ++ ++ if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) && ++ !EBONY_FLASH_SEL(fpga0_reg)) ++ small_flash_base = EBONY_SMALL_FLASH_HIGH2; ++ else if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) && ++ EBONY_FLASH_SEL(fpga0_reg)) ++ small_flash_base = EBONY_SMALL_FLASH_HIGH1; ++ else if (!EBONY_BOOT_SMALL_FLASH(fpga0_reg) && ++ !EBONY_FLASH_SEL(fpga0_reg)) ++ small_flash_base = EBONY_SMALL_FLASH_LOW2; ++ else ++ small_flash_base = EBONY_SMALL_FLASH_LOW1; ++ ++ if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) && ++ !EBONY_ONBRD_FLASH_EN(fpga0_reg)) ++ large_flash_base = EBONY_LARGE_FLASH_LOW; ++ else ++ large_flash_base = EBONY_LARGE_FLASH_HIGH; ++ ++ ebony_small_map.phys = small_flash_base; ++ ebony_small_map.virt = ++ (unsigned long)ioremap64(small_flash_base, ++ ebony_small_map.size); ++ ++ if (!ebony_small_map.virt) { ++ printk("Failed to ioremap flash\n"); ++ return -EIO; ++ } ++ ++ simple_map_init(&ebony_small_map); ++ ++ flash = do_map_probe("map_rom", &ebony_small_map); ++ if (flash) { ++ flash->owner = THIS_MODULE; ++ add_mtd_partitions(flash, ebony_small_partitions, ++ ARRAY_SIZE(ebony_small_partitions)); ++ } else { ++ printk("map probe failed for flash\n"); ++ return -ENXIO; ++ } ++ ++ ebony_large_map.phys = large_flash_base; ++ ebony_large_map.virt = ++ (unsigned long)ioremap64(large_flash_base, ++ ebony_large_map.size); ++ ++ if (!ebony_large_map.virt) { ++ printk("Failed to ioremap flash\n"); ++ return -EIO; ++ } ++ ++ simple_map_init(&ebony_large_map); ++ ++ flash = do_map_probe("cfi_probe", &ebony_large_map); ++ if (flash) { ++ flash->owner = THIS_MODULE; ++ add_mtd_partitions(flash, ebony_large_partitions, ++ ARRAY_SIZE(ebony_large_partitions)); ++ } else { ++ printk("map probe failed for flash\n"); ++ return -ENXIO; ++ } ++ ++ return 0; ++} ++ ++static void __exit cleanup_ebony(void) ++{ ++ if (flash) { ++ del_mtd_partitions(flash); ++ map_destroy(flash); ++ } ++ ++ if (ebony_small_map.virt) { ++ iounmap((void *)ebony_small_map.virt); ++ ebony_small_map.virt = 0; ++ } ++ ++ if (ebony_large_map.virt) { ++ iounmap((void *)ebony_large_map.virt); ++ ebony_large_map.virt = 0; ++ } ++} ++ ++module_init(init_ebony); ++module_exit(cleanup_ebony); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Matt Porter "); ++MODULE_DESCRIPTION("MTD map and partitions for IBM 440GP Ebony boards"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/edb7312.c linux/drivers/mtd/maps/edb7312.c +--- linux-mips-2.4.27/drivers/mtd/maps/edb7312.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/maps/edb7312.c 2004-11-19 10:25:11.910198120 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: edb7312.c,v 1.2 2002/09/05 05:11:24 acurtis Exp $ ++ * $Id: edb7312.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $ + * + * Handle mapping of the NOR flash on Cogent EDB7312 boards + * +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -35,61 +36,11 @@ + + static struct mtd_info *mymtd; + +-__u8 edb7312nor_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-__u16 edb7312nor_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} +- +-__u32 edb7312nor_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} +- +-void edb7312nor_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-void edb7312nor_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void edb7312nor_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void edb7312nor_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void edb7312nor_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio(map->map_priv_1 + to, from, len); +-} +- + struct map_info edb7312nor_map = { +- name: "NOR flash on EDB7312", +- size: WINDOW_SIZE, +- buswidth: BUSWIDTH, +- read8: edb7312nor_read8, +- read16: edb7312nor_read16, +- read32: edb7312nor_read32, +- copy_from: edb7312nor_copy_from, +- write8: edb7312nor_write8, +- write16: edb7312nor_write16, +- write32: edb7312nor_write32, +- copy_to: edb7312nor_copy_to ++ .name = "NOR flash on EDB7312", ++ .size = WINDOW_SIZE, ++ .buswidth = BUSWIDTH, ++ .phys = WINDOW_ADDR, + }; + + #ifdef CONFIG_MTD_PARTITIONS +@@ -100,29 +51,23 @@ + static struct mtd_partition static_partitions[3] = + { + { +- name: "ARMboot", +- size: 0x40000, +- offset: 0 ++ .name = "ARMboot", ++ .size = 0x40000, ++ .offset = 0 + }, + { +- name: "Kernel", +- size: 0x200000, +- offset: 0x40000 ++ .name = "Kernel", ++ .size = 0x200000, ++ .offset = 0x40000 + }, + { +- name: "RootFS", +- size: 0xDC0000, +- offset: 0x240000 ++ .name = "RootFS", ++ .size = 0xDC0000, ++ .offset = 0x240000 + }, + }; + +-#define NB_OF(x) (sizeof (x) / sizeof (x[0])) +- +-#ifdef CONFIG_MTD_CMDLINE_PARTS +-int parse_cmdline_partitions(struct mtd_info *master, +- struct mtd_partition **pparts, +- const char *mtd_id); +-#endif ++static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; + + #endif + +@@ -137,32 +82,33 @@ + + printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n", + WINDOW_SIZE, WINDOW_ADDR); +- edb7312nor_map.map_priv_1 = (unsigned long) ++ edb7312nor_map.virt = (unsigned long) + ioremap(WINDOW_ADDR, WINDOW_SIZE); + +- if (!edb7312nor_map.map_priv_1) { ++ if (!edb7312nor_map.virt) { + printk(MSG_PREFIX "failed to ioremap\n"); + return -EIO; + } + ++ simple_map_init(&edb7312nor_map); ++ + mymtd = 0; + type = rom_probe_types; + for(; !mymtd && *type; type++) { + mymtd = do_map_probe(*type, &edb7312nor_map); + } + if (mymtd) { +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + + #ifdef CONFIG_MTD_PARTITIONS +-#ifdef CONFIG_MTD_CMDLINE_PARTS +- mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, MTDID); ++ mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID); + if (mtd_parts_nb > 0) +- part_type = "command line"; +-#endif ++ part_type = "detected"; ++ + if (mtd_parts_nb == 0) + { + mtd_parts = static_partitions; +- mtd_parts_nb = NB_OF(static_partitions); ++ mtd_parts_nb = ARRAY_SIZE(static_partitions); + part_type = "static"; + } + #endif +@@ -178,7 +124,7 @@ + return 0; + } + +- iounmap((void *)edb7312nor_map.map_priv_1); ++ iounmap((void *)edb7312nor_map.virt); + return -ENXIO; + } + +@@ -188,9 +134,9 @@ + del_mtd_device(mymtd); + map_destroy(mymtd); + } +- if (edb7312nor_map.map_priv_1) { +- iounmap((void *)edb7312nor_map.map_priv_1); +- edb7312nor_map.map_priv_1 = 0; ++ if (edb7312nor_map.virt) { ++ iounmap((void *)edb7312nor_map.virt); ++ edb7312nor_map.virt = 0; + } + } + +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/elan-104nc.c linux/drivers/mtd/maps/elan-104nc.c +--- linux-mips-2.4.27/drivers/mtd/maps/elan-104nc.c 2002-06-27 00:35:50.000000000 +0200 ++++ linux/drivers/mtd/maps/elan-104nc.c 2004-11-19 10:25:11.912197816 +0100 +@@ -16,7 +16,7 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +- $Id: elan-104nc.c,v 1.13 2002/02/13 15:30:20 dwmw2 Exp $ ++ $Id: elan-104nc.c,v 1.18 2003/06/23 07:37:02 dwmw2 Exp $ + + The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16 + mode. This drivers uses the CFI probe and Intel Extended Command Set drivers. +@@ -40,6 +40,7 @@ + #include + + #include ++#include + #include + + #define WINDOW_START 0xb0000 +@@ -59,14 +60,14 @@ + * single flash device into. If the size if zero we use up to the end of the + * device. */ + static struct mtd_partition partition_info[]={ +- { name: "ELAN-104NC flash boot partition", +- offset: 0, +- size: 640*1024 }, +- { name: "ELAN-104NC flash partition 1", +- offset: 640*1024, +- size: 896*1024 }, +- { name: "ELAN-104NC flash partition 2", +- offset: (640+896)*1024 } ++ { .name = "ELAN-104NC flash boot partition", ++ .offset = 0, ++ .size = 640*1024 }, ++ { .name = "ELAN-104NC flash partition 1", ++ .offset = 640*1024, ++ .size = 896*1024 }, ++ { .name = "ELAN-104NC flash partition 2", ++ .offset = (640+896)*1024 } + }; + #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) + +@@ -195,19 +196,20 @@ + } + + static struct map_info elan_104nc_map = { +- name: "ELAN-104NC flash", +- size: 8*1024*1024, /* this must be set to a maximum possible amount ++ .name = "ELAN-104NC flash", ++ .phys = NO_XIP, ++ .size = 8*1024*1024, /* this must be set to a maximum possible amount + of flash so the cfi probe routines find all + the chips */ +- buswidth: 2, +- read8: elan_104nc_read8, +- read16: elan_104nc_read16, +- read32: elan_104nc_read32, +- copy_from: elan_104nc_copy_from, +- write8: elan_104nc_write8, +- write16: elan_104nc_write16, +- write32: elan_104nc_write32, +- copy_to: elan_104nc_copy_to ++ .buswidth = 2, ++ .read8 = elan_104nc_read8, ++ .read16 = elan_104nc_read16, ++ .read32 = elan_104nc_read32, ++ .copy_from = elan_104nc_copy_from, ++ .write8 = elan_104nc_write8, ++ .write16 = elan_104nc_write16, ++ .write32 = elan_104nc_write32, ++ .copy_to = elan_104nc_copy_to + }; + + /* MTD device for all of the flash. */ +@@ -221,20 +223,13 @@ + } + + iounmap((void *)iomapadr); +- release_region(PAGE_IO,PAGE_IO_SIZE); + } + + int __init init_elan_104nc(void) + { +- /* Urg! We use I/O port 0x22 without request_region()ing it */ +- /* +- if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) { +- printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n", +- elan_104nc_map.name, +- PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 ); +- return -EAGAIN; +- } +- */ ++ /* Urg! We use I/O port 0x22 without request_region()ing it, ++ because it's already allocated to the PIC. */ ++ + iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH); + if (!iomapadr) { + printk( KERN_ERR"%s: failed to ioremap memory region\n", +@@ -242,10 +237,6 @@ + return -EIO; + } + +- /* +- request_region( PAGE_IO, PAGE_IO_SIZE, "ELAN-104NC flash" ); +- */ +- + printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n", + elan_104nc_map.name, + PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1, +@@ -260,7 +251,7 @@ + return -ENXIO; + } + +- all_mtd->module=THIS_MODULE; ++ all_mtd->owner = THIS_MODULE; + + /* Create MTD devices for each partition. */ + add_mtd_partitions( all_mtd, partition_info, NUM_PARTITIONS ); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/epxa10db-flash.c linux/drivers/mtd/maps/epxa10db-flash.c +--- linux-mips-2.4.27/drivers/mtd/maps/epxa10db-flash.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/maps/epxa10db-flash.c 2004-11-19 10:25:11.913197664 +0100 +@@ -5,7 +5,7 @@ + * Copyright (C) 2001 Altera Corporation + * Copyright (C) 2001 Red Hat, Inc. + * +- * $Id: epxa10db-flash.c,v 1.4 2002/08/22 10:46:19 cdavies Exp $ ++ * $Id: epxa10db-flash.c,v 1.10 2003/05/21 12:45:18 dwmw2 Exp $ + * + * 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 +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -43,87 +44,38 @@ + + static struct mtd_info *mymtd; + +-extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **); + static int epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts); + +-static __u8 epxa_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-static __u16 epxa_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} +- +-static __u32 epxa_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} +- +-static void epxa_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len); +-} +- +-static void epxa_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-static void epxa_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-static void epxa_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} +- +-static void epxa_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio((void *)(map->map_priv_1 + to), from, len); +-} +- +- + + static struct map_info epxa_map = { +- name: "EPXA flash", +- size: FLASH_SIZE, +- buswidth: 2, +- read8: epxa_read8, +- read16: epxa_read16, +- read32: epxa_read32, +- copy_from: epxa_copy_from, +- write8: epxa_write8, +- write16: epxa_write16, +- write32: epxa_write32, +- copy_to: epxa_copy_to ++ .name = "EPXA flash", ++ .size = FLASH_SIZE, ++ .buswidth = 2, ++ .phys = FLASH_START, + }; + ++static const char *probes[] = { "RedBoot", "afs", NULL }; + + static int __init epxa_mtd_init(void) + { + int i; + +- printk(KERN_NOTICE "%s flash device: %x at %x\n", BOARD_NAME, FLASH_SIZE, FLASH_START); +- epxa_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE); +- if (!epxa_map.map_priv_1) { ++ printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START); ++ ++ epxa_map.virt = (unsigned long)ioremap(FLASH_START, FLASH_SIZE); ++ if (!epxa_map.virt) { + printk("Failed to ioremap %s flash\n",BOARD_NAME); + return -EIO; + } ++ simple_map_init(&epxa_map); + + mymtd = do_map_probe("cfi_probe", &epxa_map); + if (!mymtd) { +- iounmap((void *)epxa_map.map_priv_1); ++ iounmap((void *)epxa_map.virt); + return -ENXIO; + } + +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + + /* Unlock the flash device. */ + if(mymtd->unlock){ +@@ -135,23 +87,14 @@ + } + } + +-#ifdef CONFIG_MTD_REDBOOT_PARTS +- nr_parts = parse_redboot_partitions(mymtd, &parts); +- +- if (nr_parts > 0) { +- add_mtd_partitions(mymtd, parts, nr_parts); +- return 0; +- } +-#endif +-#ifdef CONFIG_MTD_AFS_PARTS +- nr_parts = parse_afs_partitions(mymtd, &parts); ++#ifdef CONFIG_MTD_PARTITIONS ++ nr_parts = parse_mtd_partitions(mymtd, probes, &parts, 0); + + if (nr_parts > 0) { + add_mtd_partitions(mymtd, parts, nr_parts); + return 0; + } + #endif +- + /* No recognised partitioning schemes found - use defaults */ + nr_parts = epxa_default_partitions(mymtd, &parts); + if (nr_parts > 0) { +@@ -173,9 +116,9 @@ + del_mtd_device(mymtd); + map_destroy(mymtd); + } +- if (epxa_map.map_priv_1) { +- iounmap((void *)epxa_map.map_priv_1); +- epxa_map.map_priv_1 = 0; ++ if (epxa_map.virt) { ++ iounmap((void *)epxa_map.virt); ++ epxa_map.virt = 0; + } + } + +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/fortunet.c linux/drivers/mtd/maps/fortunet.c +--- linux-mips-2.4.27/drivers/mtd/maps/fortunet.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/maps/fortunet.c 2004-11-19 10:25:11.915197360 +0100 +@@ -1,11 +1,12 @@ + /* fortunet.c memory map + * +- * $Id: fortunet.c,v 1.2 2002/10/14 12:50:22 rmk Exp $ ++ * $Id: fortunet.c,v 1.6 2003/05/21 12:45:18 dwmw2 Exp $ + */ + + #include + #include + #include ++#include + #include + #include + #include +@@ -23,7 +24,7 @@ + + struct map_region + { +- int window_addr_phyical; ++ int window_addr_physical; + int altbuswidth; + struct map_info map_info; + struct mtd_info *mymtd; +@@ -37,57 +38,10 @@ + static int map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0}; + + +-__u8 fortunet_read8(struct map_info *map, unsigned long ofs) +-{ +- return *(__u8 *)(map->map_priv_1 + ofs); +-} +- +-__u16 fortunet_read16(struct map_info *map, unsigned long ofs) +-{ +- return *(__u16 *)(map->map_priv_1 + ofs); +-} +- +-__u32 fortunet_read32(struct map_info *map, unsigned long ofs) +-{ +- return *(__u32 *)(map->map_priv_1 + ofs); +-} +- +-void fortunet_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy(to, (void *)(map->map_priv_1 + from), len); +-} +- +-void fortunet_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- *(__u8 *)(map->map_priv_1 + adr) = d; +-} +- +-void fortunet_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- *(__u16 *)(map->map_priv_1 + adr) = d; +-} +- +-void fortunet_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- *(__u32 *)(map->map_priv_1 + adr) = d; +-} +- +-void fortunet_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy((void *)(map->map_priv_1 + to), from, len); +-} + + struct map_info default_map = { +- size: DEF_WINDOW_SIZE, +- buswidth: 4, +- read8: fortunet_read8, +- read16: fortunet_read16, +- read32: fortunet_read32, +- copy_from: fortunet_copy_from, +- write8: fortunet_write8, +- write16: fortunet_write16, +- write32: fortunet_write32, +- copy_to: fortunet_copy_to ++ .size = DEF_WINDOW_SIZE, ++ .buswidth = 4, + }; + + static char * __init get_string_option(char *dest,int dest_size,char *sor) +@@ -147,7 +101,7 @@ + get_options (get_string_option(string,sizeof(string),line),6,params); + if(params[0]<1) + { +- printk(MTD_FORTUNET_PK "Bad paramters for MTD Region " ++ printk(MTD_FORTUNET_PK "Bad parameters for MTD Region " + " name,region-number[,base,size,buswidth,altbuswidth]\n"); + return 1; + } +@@ -161,14 +115,14 @@ + memcpy(&map_regions[params[1]].map_info, + &default_map,sizeof(map_regions[params[1]].map_info)); + map_regions_set[params[1]] = 1; +- map_regions[params[1]].window_addr_phyical = DEF_WINDOW_ADDR_PHY; ++ map_regions[params[1]].window_addr_physical = DEF_WINDOW_ADDR_PHY; + map_regions[params[1]].altbuswidth = 2; + map_regions[params[1]].mymtd = NULL; + map_regions[params[1]].map_info.name = map_regions[params[1]].map_name; + strcpy(map_regions[params[1]].map_info.name,string); + if(params[0]>1) + { +- map_regions[params[1]].window_addr_phyical = params[2]; ++ map_regions[params[1]].window_addr_physical = params[2]; + } + if(params[0]>2) + { +@@ -185,14 +139,14 @@ + return 1; + } + +-static int __init MTD_New_Partion(char *line) ++static int __init MTD_New_Partition(char *line) + { + char string[MAX_NAME_SIZE]; + int params[4]; + get_options (get_string_option(string,sizeof(string),line),4,params); + if(params[0]<3) + { +- printk(MTD_FORTUNET_PK "Bad paramters for MTD Partion " ++ printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition " + " name,region-number,size,offset\n"); + return 1; + } +@@ -204,7 +158,7 @@ + } + if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS) + { +- printk(MTD_FORTUNET_PK "Out of space for partion in this region\n"); ++ printk(MTD_FORTUNET_PK "Out of space for partition in this region\n"); + return 1; + } + map_regions[params[1]].parts[map_regions_parts[params[1]]].name = +@@ -220,7 +174,10 @@ + } + + __setup("MTD_Region=", MTD_New_Region); +-__setup("MTD_Partion=", MTD_New_Partion); ++__setup("MTD_Partition=", MTD_New_Partition); ++ ++/* Backwards-spelling-compatibility */ ++__setup("MTD_Partion=", MTD_New_Partition); + + int __init init_fortunet(void) + { +@@ -229,13 +186,13 @@ + { + if(map_regions_parts[ix]&&(!map_regions_set[ix])) + { +- printk(MTD_FORTUNET_PK "Region %d is not setup (Seting to default)\n", ++ printk(MTD_FORTUNET_PK "Region %d is not setup (Setting to default)\n", + ix); + memset(&map_regions[ix],0,sizeof(map_regions[ix])); + memcpy(&map_regions[ix].map_info,&default_map, + sizeof(map_regions[ix].map_info)); + map_regions_set[ix] = 1; +- map_regions[ix].window_addr_phyical = DEF_WINDOW_ADDR_PHY; ++ map_regions[ix].window_addr_physical = DEF_WINDOW_ADDR_PHY; + map_regions[ix].altbuswidth = 2; + map_regions[ix].mymtd = NULL; + map_regions[ix].map_info.name = map_regions[ix].map_name; +@@ -244,30 +201,35 @@ + if(map_regions_set[ix]) + { + iy++; +- printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at phyicaly " ++ printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at physically " + " address %x size %x\n", + map_regions[ix].map_info.name, +- map_regions[ix].window_addr_phyical, ++ map_regions[ix].window_addr_physical, + map_regions[ix].map_info.size); +- map_regions[ix].map_info.map_priv_1 = ++ ++ map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical, ++ ++ map_regions[ix].map_info.virt = + (int)ioremap_nocache( +- map_regions[ix].window_addr_phyical, ++ map_regions[ix].window_addr_physical, + map_regions[ix].map_info.size); +- if(!map_regions[ix].map_info.map_priv_1) ++ if(!map_regions[ix].map_info.virt) + { + printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n", + map_regions[ix].map_info.name); + return -ENXIO; + } +- printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is veritualy at: %x\n", ++ simple_map_init(&map_regions[ix].map_info); ++ ++ printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is virtually at: %x\n", + map_regions[ix].map_info.name, +- map_regions[ix].map_info.map_priv_1); ++ map_regions[ix].map_info.virt); + map_regions[ix].mymtd = do_map_probe("cfi_probe", + &map_regions[ix].map_info); + if((!map_regions[ix].mymtd)&&( + map_regions[ix].altbuswidth!=map_regions[ix].map_info.buswidth)) + { +- printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternet buswidth " ++ printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternate buswidth " + "for %s flash.\n", + map_regions[ix].map_info.name); + map_regions[ix].map_info.buswidth = +@@ -275,7 +237,7 @@ + map_regions[ix].mymtd = do_map_probe("cfi_probe", + &map_regions[ix].map_info); + } +- map_regions[ix].mymtd->module = THIS_MODULE; ++ map_regions[ix].mymtd->owner = THIS_MODULE; + add_mtd_partitions(map_regions[ix].mymtd, + map_regions[ix].parts,map_regions_parts[ix]); + } +@@ -297,7 +259,7 @@ + del_mtd_partitions( map_regions[ix].mymtd ); + map_destroy( map_regions[ix].mymtd ); + } +- iounmap((void *)map_regions[ix].map_info.map_priv_1); ++ iounmap((void *)map_regions[ix].map_info.virt); + } + } + } +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/h720x-flash.c linux/drivers/mtd/maps/h720x-flash.c +--- linux-mips-2.4.27/drivers/mtd/maps/h720x-flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/maps/h720x-flash.c 2004-11-19 10:25:11.917197056 +0100 +@@ -0,0 +1,142 @@ ++/* ++ * Flash memory access on Hynix GMS30C7201/HMS30C7202 based ++ * evaluation boards ++ * ++ * (C) 2002 Jungjun Kim ++ * 2003 Thomas Gleixner ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static struct mtd_info *mymtd; ++ ++static struct map_info h720x_map = { ++ .name = "H720X", ++ .buswidth = 4, ++ .size = FLASH_SIZE, ++ .phys = FLASH_PHYS, ++}; ++ ++static struct mtd_partition h720x_partitions[] = { ++ { ++ .name = "ArMon", ++ .size = 0x00080000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE ++ },{ ++ .name = "Env", ++ .size = 0x00040000, ++ .offset = 0x00080000, ++ .mask_flags = MTD_WRITEABLE ++ },{ ++ .name = "Kernel", ++ .size = 0x00180000, ++ .offset = 0x000c0000, ++ .mask_flags = MTD_WRITEABLE ++ },{ ++ .name = "Ramdisk", ++ .size = 0x00400000, ++ .offset = 0x00240000, ++ .mask_flags = MTD_WRITEABLE ++ },{ ++ .name = "jffs2", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND ++ } ++}; ++ ++#define NUM_PARTITIONS (sizeof(h720x_partitions)/sizeof(h720x_partitions[0])) ++ ++static int nr_mtd_parts; ++static struct mtd_partition *mtd_parts; ++static const char *probes[] = { "cmdlinepart", NULL }; ++ ++/* ++ * Initialize FLASH support ++ */ ++int __init h720x_mtd_init(void) ++{ ++ ++ char *part_type = NULL; ++ ++ h720x_map.virt = (unsigned long)ioremap(FLASH_PHYS, FLASH_SIZE); ++ ++ if (!h720x_map.virt) { ++ printk(KERN_ERR "H720x-MTD: ioremap failed\n"); ++ return -EIO; ++ } ++ ++ simple_map_init(&h720x_map); ++ ++ // Probe for flash buswidth 4 ++ printk (KERN_INFO "H720x-MTD probing 32bit FLASH\n"); ++ mymtd = do_map_probe("cfi_probe", &h720x_map); ++ if (!mymtd) { ++ printk (KERN_INFO "H720x-MTD probing 16bit FLASH\n"); ++ // Probe for buswidth 2 ++ h720x_map.buswidth = 2; ++ mymtd = do_map_probe("cfi_probe", &h720x_map); ++ } ++ ++ if (mymtd) { ++ mymtd->owner = THIS_MODULE; ++ ++#ifdef CONFIG_MTD_PARTITIONS ++ nr_mtd_parts = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0); ++ if (nr_mtd_parts > 0) ++ part_type = "command line"; ++#endif ++ if (nr_mtd_parts <= 0) { ++ mtd_parts = h720x_partitions; ++ nr_mtd_parts = NUM_PARTITIONS; ++ part_type = "builtin"; ++ } ++ printk(KERN_INFO "Using %s partition table\n", part_type); ++ add_mtd_partitions(mymtd, mtd_parts, nr_mtd_parts); ++ return 0; ++ } ++ ++ iounmap((void *)h720x_map.virt); ++ return -ENXIO; ++} ++ ++/* ++ * Cleanup ++ */ ++static void __exit h720x_mtd_cleanup(void) ++{ ++ ++ if (mymtd) { ++ del_mtd_partitions(mymtd); ++ map_destroy(mymtd); ++ } ++ ++ /* Free partition info, if commandline partition was used */ ++ if (mtd_parts && (mtd_parts != h720x_partitions)) ++ kfree (mtd_parts); ++ ++ if (h720x_map.virt) { ++ iounmap((void *)h720x_map.virt); ++ h720x_map.virt = 0; ++ } ++} ++ ++ ++module_init(h720x_mtd_init); ++module_exit(h720x_mtd_cleanup); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Thomas Gleixner "); ++MODULE_DESCRIPTION("MTD map driver for Hynix evaluation boards"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/ichxrom.c linux/drivers/mtd/maps/ichxrom.c +--- linux-mips-2.4.27/drivers/mtd/maps/ichxrom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/maps/ichxrom.c 2004-11-19 10:25:11.918196904 +0100 +@@ -0,0 +1,380 @@ ++/* ++ * ichxrom.c ++ * ++ * Normal mappings of chips in physical memory ++ * $Id: ichxrom.c,v 1.1 2003/10/27 19:49:23 thayne Exp $ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define xstr(s) str(s) ++#define str(s) #s ++#define MOD_NAME xstr(KBUILD_BASENAME) ++ ++#define MTD_DEV_NAME_LENGTH 16 ++ ++#define RESERVE_MEM_REGION 0 ++ ++#define ICHX_FWH_REGION_START 0xFF000000UL ++#define ICHX_FWH_REGION_SIZE 0x01000000UL ++#define BIOS_CNTL 0x4e ++#define FWH_DEC_EN1 0xE3 ++#define FWH_DEC_EN2 0xF0 ++#define FWH_SEL1 0xE8 ++#define FWH_SEL2 0xEE ++ ++struct ichxrom_map_info { ++ struct map_info map; ++ struct mtd_info *mtd; ++ unsigned long window_addr; ++ struct pci_dev *pdev; ++ struct resource window_rsrc; ++ struct resource rom_rsrc; ++ char mtd_name[MTD_DEV_NAME_LENGTH]; ++}; ++ ++static inline unsigned long addr(struct map_info *map, unsigned long ofs) ++{ ++ unsigned long offset; ++ offset = ((8*1024*1024) - map->size) + ofs; ++ if (offset >= (4*1024*1024)) { ++ offset += 0x400000; ++ } ++ return map->map_priv_1 + 0x400000 + offset; ++} ++ ++static inline unsigned long dbg_addr(struct map_info *map, unsigned long addr) ++{ ++ return addr - map->map_priv_1 + ICHX_FWH_REGION_START; ++} ++ ++static __u8 ichxrom_read8(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readb(addr(map, ofs)); ++} ++ ++static __u16 ichxrom_read16(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readw(addr(map, ofs)); ++} ++ ++static __u32 ichxrom_read32(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readl(addr(map, ofs)); ++} ++ ++static void ichxrom_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++{ ++ memcpy_fromio(to, addr(map, from), len); ++} ++ ++static void ichxrom_write8(struct map_info *map, __u8 d, unsigned long ofs) ++{ ++ __raw_writeb(d, addr(map,ofs)); ++ mb(); ++} ++ ++static void ichxrom_write16(struct map_info *map, __u16 d, unsigned long ofs) ++{ ++ __raw_writew(d, addr(map, ofs)); ++ mb(); ++} ++ ++static void ichxrom_write32(struct map_info *map, __u32 d, unsigned long ofs) ++{ ++ __raw_writel(d, addr(map, ofs)); ++ mb(); ++} ++ ++static void ichxrom_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) ++{ ++ memcpy_toio(addr(map, to), from, len); ++} ++ ++static struct ichxrom_map_info ichxrom_map = { ++ .map = { ++ .name = MOD_NAME, ++ .phys = NO_XIP, ++ .size = 0, ++ .buswidth = 1, ++ .read8 = ichxrom_read8, ++ .read16 = ichxrom_read16, ++ .read32 = ichxrom_read32, ++ .copy_from = ichxrom_copy_from, ++ .write8 = ichxrom_write8, ++ .write16 = ichxrom_write16, ++ .write32 = ichxrom_write32, ++ .copy_to = ichxrom_copy_to, ++ /* Firmware hubs only use vpp when being programmed ++ * in a factory setting. So in-place programming ++ * needs to use a different method. ++ */ ++ }, ++ /* remaining fields of structure are initialized to 0 */ ++}; ++ ++enum fwh_lock_state { ++ FWH_DENY_WRITE = 1, ++ FWH_IMMUTABLE = 2, ++ FWH_DENY_READ = 4, ++}; ++ ++static void ichxrom_cleanup(struct ichxrom_map_info *info) ++{ ++ u16 word; ++ ++ /* Disable writes through the rom window */ ++ pci_read_config_word(info->pdev, BIOS_CNTL, &word); ++ pci_write_config_word(info->pdev, BIOS_CNTL, word & ~1); ++ ++ if (info->mtd) { ++ del_mtd_device(info->mtd); ++ map_destroy(info->mtd); ++ info->mtd = NULL; ++ info->map.virt = 0; ++ } ++ if (info->rom_rsrc.parent) ++ release_resource(&info->rom_rsrc); ++ if (info->window_rsrc.parent) ++ release_resource(&info->window_rsrc); ++ ++ if (info->window_addr) { ++ iounmap((void *)(info->window_addr)); ++ info->window_addr = 0; ++ } ++} ++ ++ ++static int ichxrom_set_lock_state(struct mtd_info *mtd, loff_t ofs, size_t len, ++ enum fwh_lock_state state) ++{ ++ struct map_info *map = mtd->priv; ++ unsigned long start = ofs; ++ unsigned long end = start + len -1; ++ ++ /* FIXME do I need to guard against concurrency here? */ ++ /* round down to 64K boundaries */ ++ start = start & ~0xFFFF; ++ end = end & ~0xFFFF; ++ while (start <= end) { ++ unsigned long ctrl_addr; ++ ctrl_addr = addr(map, start) - 0x400000 + 2; ++ writeb(state, ctrl_addr); ++ start = start + 0x10000; ++ } ++ return 0; ++} ++ ++static int ichxrom_lock(struct mtd_info *mtd, loff_t ofs, size_t len) ++{ ++ return ichxrom_set_lock_state(mtd, ofs, len, FWH_DENY_WRITE); ++} ++ ++static int ichxrom_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) ++{ ++ return ichxrom_set_lock_state(mtd, ofs, len, 0); ++} ++ ++static int __devinit ichxrom_init_one (struct pci_dev *pdev, ++ const struct pci_device_id *ent) ++{ ++ u16 word; ++ struct ichxrom_map_info *info = &ichxrom_map; ++ unsigned long map_size; ++ ++ /* For now I just handle the ichx and I assume there ++ * are not a lot of resources up at the top of the address ++ * space. It is possible to handle other devices in the ++ * top 16MB but it is very painful. Also since ++ * you can only really attach a FWH to an ICHX there ++ * a number of simplifications you can make. ++ * ++ * Also you can page firmware hubs if an 8MB window isn't enough ++ * but don't currently handle that case either. ++ */ ++ ++ info->pdev = pdev; ++ ++ /* ++ * Try to reserve the window mem region. If this fails then ++ * it is likely due to the window being "reseved" by the BIOS. ++ */ ++ info->window_rsrc.name = MOD_NAME; ++ info->window_rsrc.start = ICHX_FWH_REGION_START; ++ info->window_rsrc.end = ICHX_FWH_REGION_START + ICHX_FWH_REGION_SIZE - 1; ++ info->window_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; ++ if (request_resource(&iomem_resource, &info->window_rsrc)) { ++ info->window_rsrc.parent = NULL; ++ printk(KERN_ERR MOD_NAME ++ " %s(): Unable to register resource" ++ " 0x%.08lx-0x%.08lx - kernel bug?\n", ++ __func__, ++ info->window_rsrc.start, info->window_rsrc.end); ++ } ++ ++ /* Enable writes through the rom window */ ++ pci_read_config_word(pdev, BIOS_CNTL, &word); ++ if (!(word & 1) && (word & (1<<1))) { ++ /* The BIOS will generate an error if I enable ++ * this device, so don't even try. ++ */ ++ printk(KERN_ERR MOD_NAME ": firmware access control, I can't enable writes\n"); ++ goto failed; ++ } ++ pci_write_config_word(pdev, BIOS_CNTL, word | 1); ++ ++ ++ /* Map the firmware hub into my address space. */ ++ /* Does this use too much virtual address space? */ ++ info->window_addr = (unsigned long)ioremap( ++ ICHX_FWH_REGION_START, ICHX_FWH_REGION_SIZE); ++ if (!info->window_addr) { ++ printk(KERN_ERR "Failed to ioremap\n"); ++ goto failed; ++ } ++ ++ /* For now assume the firmware has setup all relevant firmware ++ * windows. We don't have enough information to handle this case ++ * intelligently. ++ */ ++ ++ /* FIXME select the firmware hub and enable a window to it. */ ++ ++ info->mtd = 0; ++ info->map.map_priv_1 = info->window_addr; ++ ++ map_size = ICHX_FWH_REGION_SIZE; ++ while(!info->mtd && (map_size > 0)) { ++ info->map.size = map_size; ++ info->mtd = do_map_probe("jedec_probe", &ichxrom_map.map); ++ map_size -= 512*1024; ++ } ++ if (!info->mtd) { ++ goto failed; ++ } ++ /* I know I can only be a firmware hub here so put ++ * in the special lock and unlock routines. ++ */ ++ info->mtd->lock = ichxrom_lock; ++ info->mtd->unlock = ichxrom_unlock; ++ ++ info->mtd->owner = THIS_MODULE; ++ add_mtd_device(info->mtd); ++ ++ if (info->window_rsrc.parent) { ++ /* ++ * Registering the MTD device in iomem may not be possible ++ * if there is a BIOS "reserved" and BUSY range. If this ++ * fails then continue anyway. ++ */ ++ snprintf(info->mtd_name, MTD_DEV_NAME_LENGTH, ++ "mtd%d", info->mtd->index); ++ ++ info->rom_rsrc.name = info->mtd_name; ++ info->rom_rsrc.start = ICHX_FWH_REGION_START ++ + ICHX_FWH_REGION_SIZE - map_size; ++ info->rom_rsrc.end = ICHX_FWH_REGION_START ++ + ICHX_FWH_REGION_SIZE; ++ info->rom_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; ++ if (request_resource(&info->window_rsrc, &info->rom_rsrc)) { ++ printk(KERN_ERR MOD_NAME ++ ": cannot reserve MTD resource\n"); ++ info->rom_rsrc.parent = NULL; ++ } ++ } ++ ++ return 0; ++ ++ failed: ++ ichxrom_cleanup(info); ++ return -ENODEV; ++} ++ ++ ++static void __devexit ichxrom_remove_one (struct pci_dev *pdev) ++{ ++ struct ichxrom_map_info *info = &ichxrom_map; ++ u16 word; ++ ++ del_mtd_device(info->mtd); ++ map_destroy(info->mtd); ++ info->mtd = 0; ++ info->map.map_priv_1 = 0; ++ ++ iounmap((void *)(info->window_addr)); ++ info->window_addr = 0; ++ ++ /* Disable writes through the rom window */ ++ pci_read_config_word(pdev, BIOS_CNTL, &word); ++ pci_write_config_word(pdev, BIOS_CNTL, word & ~1); ++ ++#if RESERVE_MEM_REGION ++ release_mem_region(ICHX_FWH_REGION_START, ICHX_FWH_REGION_SIZE); ++#endif ++} ++ ++static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = { ++ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, ++ PCI_ANY_ID, PCI_ANY_ID, }, ++ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, ++ PCI_ANY_ID, PCI_ANY_ID, }, ++ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, ++ PCI_ANY_ID, PCI_ANY_ID, }, ++ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, ++ PCI_ANY_ID, PCI_ANY_ID, }, ++ { 0, }, ++}; ++ ++MODULE_DEVICE_TABLE(pci, ichxrom_pci_tbl); ++ ++#if 0 ++static struct pci_driver ichxrom_driver = { ++ .name = MOD_NAME, ++ .id_table = ichxrom_pci_tbl, ++ .probe = ichxrom_init_one, ++ .remove = ichxrom_remove_one, ++}; ++#endif ++ ++static struct pci_dev *mydev; ++int __init init_ichxrom(void) ++{ ++ struct pci_dev *pdev; ++ struct pci_device_id *id; ++ pdev = 0; ++ for(id = ichxrom_pci_tbl; id->vendor; id++) { ++ pdev = pci_find_device(id->vendor, id->device, 0); ++ if (pdev) { ++ break; ++ } ++ } ++ if (pdev) { ++ mydev = pdev; ++ return ichxrom_init_one(pdev, &ichxrom_pci_tbl[0]); ++ } ++ return -ENXIO; ++#if 0 ++ return pci_module_init(&ichxrom_driver); ++#endif ++} ++ ++static void __exit cleanup_ichxrom(void) ++{ ++ ichxrom_remove_one(mydev); ++} ++ ++module_init(init_ichxrom); ++module_exit(cleanup_ichxrom); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Eric Biederman "); ++MODULE_DESCRIPTION("MTD map driver for BIOS chips on the ICHX southbridge"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/impa7.c linux/drivers/mtd/maps/impa7.c +--- linux-mips-2.4.27/drivers/mtd/maps/impa7.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/maps/impa7.c 2004-11-19 10:25:11.920196600 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: impa7.c,v 1.2 2002/09/05 05:11:24 acurtis Exp $ ++ * $Id: impa7.c,v 1.9 2003/06/23 11:47:43 dwmw2 Exp $ + * + * Handle mapping of the NOR flash on implementa A7 boards + * +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -37,75 +38,17 @@ + + static struct mtd_info *impa7_mtd[NUM_FLASHBANKS] = { 0 }; + +-__u8 impa7_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-__u16 impa7_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} +- +-__u32 impa7_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} +- +-void impa7_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-void impa7_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void impa7_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void impa7_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void impa7_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio(map->map_priv_1 + to, from, len); +-} + + static struct map_info impa7_map[NUM_FLASHBANKS] = { + { +- name: "impA7 NOR Flash Bank #0", +- size: WINDOW_SIZE0, +- buswidth: BUSWIDTH, +- read8: impa7_read8, +- read16: impa7_read16, +- read32: impa7_read32, +- copy_from: impa7_copy_from, +- write8: impa7_write8, +- write16: impa7_write16, +- write32: impa7_write32, +- copy_to: impa7_copy_to ++ .name = "impA7 NOR Flash Bank #0", ++ .size = WINDOW_SIZE0, ++ .buswidth = BUSWIDTH, + }, + { +- name: "impA7 NOR Flash Bank #1", +- size: WINDOW_SIZE1, +- buswidth: BUSWIDTH, +- read8: impa7_read8, +- read16: impa7_read16, +- read32: impa7_read32, +- copy_from: impa7_copy_from, +- write8: impa7_write8, +- write16: impa7_write16, +- write32: impa7_write32, +- copy_to: impa7_copy_to ++ .name = "impA7 NOR Flash Bank #1", ++ .size = WINDOW_SIZE1, ++ .buswidth = BUSWIDTH, + }, + }; + +@@ -117,24 +60,18 @@ + static struct mtd_partition static_partitions[] = + { + { +- name: "FileSystem", +- size: 0x800000, +- offset: 0x00000000 ++ .name = "FileSystem", ++ .size = 0x800000, ++ .offset = 0x00000000 + }, + }; + +-#define NB_OF(x) (sizeof (x) / sizeof (x[0])) ++static int mtd_parts_nb[NUM_FLASHBANKS]; ++static struct mtd_partition *mtd_parts[NUM_FLASHBANKS]; + +-#ifdef CONFIG_MTD_CMDLINE_PARTS +-int parse_cmdline_partitions(struct mtd_info *master, +- struct mtd_partition **pparts, +- const char *mtd_id); + #endif + +-#endif +- +-static int mtd_parts_nb = 0; +-static struct mtd_partition *mtd_parts = 0; ++static const char *probes[] = { "cmdlinepart", NULL }; + + int __init init_impa7(void) + { +@@ -146,20 +83,21 @@ + { WINDOW_ADDR0, WINDOW_SIZE0 }, + { WINDOW_ADDR1, WINDOW_SIZE1 }, + }; +- char mtdid[10]; + int devicesfound = 0; + + for(i=0; imodule = THIS_MODULE; +- add_mtd_device(impa7_mtd[i]); ++ if (impa7_mtd[i]) { ++ impa7_mtd[i]->owner = THIS_MODULE; + devicesfound++; + #ifdef CONFIG_MTD_PARTITIONS +-#ifdef CONFIG_MTD_CMDLINE_PARTS +- sprintf(mtdid, MTDID, i); +- mtd_parts_nb = parse_cmdline_partitions(impa7_mtd[i], +- &mtd_parts, +- mtdid); +- if (mtd_parts_nb > 0) ++ mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i], ++ probes, ++ &mtd_parts[i], ++ 0); ++ if (mtd_parts_nb[i] > 0) { + part_type = "command line"; +-#endif +- if (mtd_parts_nb <= 0) +- { +- mtd_parts = static_partitions; +- mtd_parts_nb = NB_OF(static_partitions); ++ } else { ++ mtd_parts[i] = static_partitions; ++ mtd_parts_nb[i] = ARRAY_SIZE(static_partitions); + part_type = "static"; + } +- if (mtd_parts_nb <= 0) +- { +- printk(KERN_NOTICE MSG_PREFIX +- "no partition info available\n"); +- } +- else +- { ++ + printk(KERN_NOTICE MSG_PREFIX + "using %s partition definition\n", + part_type); + add_mtd_partitions(impa7_mtd[i], +- mtd_parts, mtd_parts_nb); +- } ++ mtd_parts[i], mtd_parts_nb[i]); ++#else ++ add_mtd_device(impa7_mtd[i]); ++ + #endif + } + else +- iounmap((void *)impa7_map[i].map_priv_1); ++ iounmap((void *)impa7_map[i].virt); + } + return devicesfound == 0 ? -ENXIO : 0; + } +@@ -211,17 +140,16 @@ + static void __exit cleanup_impa7(void) + { + int i; +- for (i=0; i ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++// board specific stuff - sorry, it should be in arch/arm/mach-*. ++#ifdef CONFIG_ARCH_INTEGRATOR ++ ++#define FLASH_BASE INTEGRATOR_FLASH_BASE ++#define FLASH_SIZE INTEGRATOR_FLASH_SIZE ++ ++#define FLASH_PART_SIZE 0x400000 ++ ++#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET) ++#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET) ++#define EBI_CSR1 (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_CSR1_OFFSET) ++#define EBI_LOCK (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_LOCK_OFFSET) ++ ++/* ++ * Initialise the flash access systems: ++ * - Disable VPP ++ * - Assert WP ++ * - Set write enable bit in EBI reg ++ */ ++static void armflash_flash_init(void) ++{ ++ unsigned int tmp; ++ ++ __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); ++ ++ tmp = __raw_readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE; ++ __raw_writel(tmp, EBI_CSR1); ++ ++ if (!(__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) { ++ __raw_writel(0xa05f, EBI_LOCK); ++ __raw_writel(tmp, EBI_CSR1); ++ __raw_writel(0, EBI_LOCK); ++ } ++} ++ ++/* ++ * Shutdown the flash access systems: ++ * - Disable VPP ++ * - Assert WP ++ * - Clear write enable bit in EBI reg ++ */ ++static void armflash_flash_exit(void) ++{ ++ unsigned int tmp; ++ ++ __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); ++ ++ /* ++ * Clear the write enable bit in system controller EBI register. ++ */ ++ tmp = __raw_readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE; ++ __raw_writel(tmp, EBI_CSR1); ++ ++ if (__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) { ++ __raw_writel(0xa05f, EBI_LOCK); ++ __raw_writel(tmp, EBI_CSR1); ++ __raw_writel(0, EBI_LOCK); ++ } ++} ++ ++static void armflash_flash_wp(int on) ++{ ++ unsigned int reg; ++ ++ if (on) ++ reg = SC_CTRLC; ++ else ++ reg = SC_CTRLS; ++ ++ __raw_writel(INTEGRATOR_SC_CTRL_nFLWP, reg); ++} ++ ++static void armflash_set_vpp(struct map_info *map, int on) ++{ ++ unsigned int reg; ++ ++ if (on) ++ reg = SC_CTRLS; ++ else ++ reg = SC_CTRLC; ++ ++ __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg); ++} ++#endif ++ ++#ifdef CONFIG_ARCH_P720T ++ ++#define FLASH_BASE (0x04000000) ++#define FLASH_SIZE (64*1024*1024) ++ ++#define FLASH_PART_SIZE (4*1024*1024) ++#define FLASH_BLOCK_SIZE (128*1024) ++ ++static void armflash_flash_init(void) ++{ ++} ++ ++static void armflash_flash_exit(void) ++{ ++} ++ ++static void armflash_flash_wp(int on) ++{ ++} ++ ++static void armflash_set_vpp(struct map_info *map, int on) ++{ ++} ++#endif ++ ++ ++static struct map_info armflash_map = ++{ ++ .name = "AFS", ++ .set_vpp = armflash_set_vpp, ++ .phys = FLASH_BASE, ++}; ++ ++static struct mtd_info *mtd; ++static struct mtd_partition *parts; ++static const char *probes[] = { "RedBoot", "afs", NULL }; ++ ++static int __init armflash_cfi_init(void *base, u_int size) ++{ ++ int ret; ++ ++ armflash_flash_init(); ++ armflash_flash_wp(1); ++ ++ /* ++ * look for CFI based flash parts fitted to this board ++ */ ++ armflash_map.size = size; ++ armflash_map.buswidth = 4; ++ armflash_map.virt = (unsigned long) base; ++ ++ simple_map_init(&armflash_map); ++ ++ /* ++ * Also, the CFI layer automatically works out what size ++ * of chips we have, and does the necessary identification ++ * for us automatically. ++ */ ++ mtd = do_map_probe("cfi_probe", &armflash_map); ++ if (!mtd) ++ return -ENXIO; ++ ++ mtd->owner = THIS_MODULE; ++ ++ ret = parse_mtd_partitions(mtd, probes, &parts, (void *)0); ++ if (ret > 0) { ++ ret = add_mtd_partitions(mtd, parts, ret); ++ if (ret) ++ printk(KERN_ERR "mtd partition registration " ++ "failed: %d\n", ret); ++ } ++ ++ /* ++ * If we got an error, free all resources. ++ */ ++ if (ret < 0) { ++ del_mtd_partitions(mtd); ++ map_destroy(mtd); ++ } ++ ++ return ret; ++} ++ ++static void armflash_cfi_exit(void) ++{ ++ if (mtd) { ++ del_mtd_partitions(mtd); ++ map_destroy(mtd); ++ } ++ if (parts) ++ kfree(parts); ++} ++ ++static int __init armflash_init(void) ++{ ++ int err = -EBUSY; ++ void *base; ++ ++ if (request_mem_region(FLASH_BASE, FLASH_SIZE, "flash") == NULL) ++ goto out; ++ ++ base = ioremap(FLASH_BASE, FLASH_SIZE); ++ err = -ENOMEM; ++ if (base == NULL) ++ goto release; ++ ++ err = armflash_cfi_init(base, FLASH_SIZE); ++ if (err) { ++ iounmap(base); ++release: ++ release_mem_region(FLASH_BASE, FLASH_SIZE); ++ } ++out: ++ return err; ++} ++ ++static void __exit armflash_exit(void) ++{ ++ armflash_cfi_exit(); ++ iounmap((void *)armflash_map.virt); ++ release_mem_region(FLASH_BASE, FLASH_SIZE); ++ armflash_flash_exit(); ++} ++ ++module_init(armflash_init); ++module_exit(armflash_exit); ++ ++MODULE_AUTHOR("ARM Ltd"); ++MODULE_DESCRIPTION("ARM Integrator CFI map driver"); ++MODULE_LICENSE("GPL"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/integrator-flash.c linux/drivers/mtd/maps/integrator-flash.c +--- linux-mips-2.4.27/drivers/mtd/maps/integrator-flash.c 2002-06-27 00:35:50.000000000 +0200 ++++ linux/drivers/mtd/maps/integrator-flash.c 2004-11-19 10:25:11.923196144 +0100 +@@ -1,8 +1,9 @@ + /*====================================================================== + +- drivers/mtd/maps/armflash.c: ARM Flash Layout/Partitioning ++ drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver + + Copyright (C) 2000 ARM Limited ++ Copyright (C) 2003 Deep Blue Solutions Ltd. + + 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 +@@ -21,7 +22,7 @@ + This is access code for flashes using ARM's flash partitioning + standards. + +- $Id: integrator-flash.c,v 1.7 2001/11/01 20:55:47 rmk Exp $ ++ $Id: integrator-flash.c,v 1.14 2003/10/11 10:00:31 rmk Exp $ + + ======================================================================*/ + +@@ -31,268 +32,181 @@ + #include + #include + #include ++#include + #include + + #include + #include + #include + ++#include + #include + #include + #include + +-extern int parse_afs_partitions(struct mtd_info *, struct mtd_partition **); +- +-// board specific stuff - sorry, it should be in arch/arm/mach-*. +-#ifdef CONFIG_ARCH_INTEGRATOR +- +-#define FLASH_BASE INTEGRATOR_FLASH_BASE +-#define FLASH_SIZE INTEGRATOR_FLASH_SIZE +- +-#define FLASH_PART_SIZE 0x400000 +- +-#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET) +-#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET) +-#define EBI_CSR1 (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_CSR1_OFFSET) +-#define EBI_LOCK (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_LOCK_OFFSET) +- +-/* +- * Initialise the flash access systems: +- * - Disable VPP +- * - Assert WP +- * - Set write enable bit in EBI reg +- */ +-static void armflash_flash_init(void) +-{ +- unsigned int tmp; +- +- __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); +- +- tmp = __raw_readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE; +- __raw_writel(tmp, EBI_CSR1); +- +- if (!(__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) { +- __raw_writel(0xa05f, EBI_LOCK); +- __raw_writel(tmp, EBI_CSR1); +- __raw_writel(0, EBI_LOCK); +- } +-} +- +-/* +- * Shutdown the flash access systems: +- * - Disable VPP +- * - Assert WP +- * - Clear write enable bit in EBI reg +- */ +-static void armflash_flash_exit(void) +-{ +- unsigned int tmp; +- +- __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC); +- +- /* +- * Clear the write enable bit in system controller EBI register. +- */ +- tmp = __raw_readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE; +- __raw_writel(tmp, EBI_CSR1); +- +- if (__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) { +- __raw_writel(0xa05f, EBI_LOCK); +- __raw_writel(tmp, EBI_CSR1); +- __raw_writel(0, EBI_LOCK); +- } +-} +- +-static void armflash_flash_wp(int on) +-{ +- unsigned int reg; +- +- if (on) +- reg = SC_CTRLC; +- else +- reg = SC_CTRLS; +- +- __raw_writel(INTEGRATOR_SC_CTRL_nFLWP, reg); +-} +- +-static void armflash_set_vpp(struct map_info *map, int on) +-{ +- unsigned int reg; +- +- if (on) +- reg = SC_CTRLS; +- else +- reg = SC_CTRLC; +- +- __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg); +-} +-#endif +- + #ifdef CONFIG_ARCH_P720T +- + #define FLASH_BASE (0x04000000) + #define FLASH_SIZE (64*1024*1024) +- +-#define FLASH_PART_SIZE (4*1024*1024) +-#define FLASH_BLOCK_SIZE (128*1024) +- +-static void armflash_flash_init(void) +-{ +-} +- +-static void armflash_flash_exit(void) +-{ +-} +- +-static void armflash_flash_wp(int on) +-{ +-} +- +-static void armflash_set_vpp(struct map_info *map, int on) +-{ +-} + #endif + +-static __u8 armflash_read8(struct map_info *map, unsigned long ofs) +-{ +- return readb(ofs + map->map_priv_2); +-} +- +-static __u16 armflash_read16(struct map_info *map, unsigned long ofs) +-{ +- return readw(ofs + map->map_priv_2); +-} ++struct armflash_info { ++ struct flash_platform_data *plat; ++ struct resource *res; ++ struct mtd_partition *parts; ++ struct mtd_info *mtd; ++ struct map_info map; ++}; + +-static __u32 armflash_read32(struct map_info *map, unsigned long ofs) ++static void armflash_set_vpp(struct map_info *map, int on) + { +- return readl(ofs + map->map_priv_2); +-} ++ struct armflash_info *info = container_of(map, struct armflash_info, map); + +-static void armflash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy(to, (void *) (from + map->map_priv_2), len); ++ if (info->plat && info->plat->set_vpp) ++ info->plat->set_vpp(on); + } + +-static void armflash_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- writeb(d, adr + map->map_priv_2); +-} +- +-static void armflash_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- writew(d, adr + map->map_priv_2); +-} ++static const char *probes[] = { "RedBoot", "afs", NULL }; + +-static void armflash_write32(struct map_info *map, __u32 d, unsigned long adr) ++static int armflash_probe(struct device *_dev) + { +- writel(d, adr + map->map_priv_2); +-} ++ struct platform_device *dev = to_platform_device(_dev); ++ struct flash_platform_data *plat = dev->dev.platform_data; ++ struct resource *res = dev->resource; ++ unsigned int size = res->end - res->start + 1; ++ struct armflash_info *info; ++ int err; ++ void *base; + +-static void armflash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy((void *) (to + map->map_priv_2), from, len); +-} ++ info = kmalloc(sizeof(struct armflash_info), GFP_KERNEL); ++ if (!info) { ++ err = -ENOMEM; ++ goto out; ++ } + +-static struct map_info armflash_map = +-{ +- name: "AFS", +- read8: armflash_read8, +- read16: armflash_read16, +- read32: armflash_read32, +- copy_from: armflash_copy_from, +- write8: armflash_write8, +- write16: armflash_write16, +- write32: armflash_write32, +- copy_to: armflash_copy_to, +- set_vpp: armflash_set_vpp, +-}; ++ memset(info, 0, sizeof(struct armflash_info)); + +-static struct mtd_info *mtd; +-static struct mtd_partition *parts; ++ info->plat = plat; ++ if (plat && plat->init) { ++ err = plat->init(); ++ if (err) ++ goto no_resource; ++ } + +-static int __init armflash_cfi_init(void *base, u_int size) +-{ +- int ret; ++ info->res = request_mem_region(res->start, size, "armflash"); ++ if (!info->res) { ++ err = -EBUSY; ++ goto no_resource; ++ } + +- armflash_flash_init(); +- armflash_flash_wp(1); ++ base = ioremap(res->start, size); ++ if (!base) { ++ err = -ENOMEM; ++ goto no_mem; ++ } + + /* + * look for CFI based flash parts fitted to this board + */ +- armflash_map.size = size; +- armflash_map.buswidth = 4; +- armflash_map.map_priv_2 = (unsigned long) base; ++ info->map.size = size; ++ info->map.buswidth = plat->width; ++ info->map.phys = res->start; ++ info->map.virt = (unsigned long) base; ++ info->map.name = dev->dev.bus_id; ++ info->map.set_vpp = armflash_set_vpp; ++ ++ simple_map_init(&info->map); + + /* + * Also, the CFI layer automatically works out what size + * of chips we have, and does the necessary identification + * for us automatically. + */ +- mtd = do_map_probe("cfi_probe", &armflash_map); +- if (!mtd) +- return -ENXIO; +- +- mtd->module = THIS_MODULE; +- +- ret = parse_afs_partitions(mtd, &parts); +- if (ret > 0) { +- ret = add_mtd_partitions(mtd, parts, ret); +- if (ret) +- printk(KERN_ERR "mtd partition registration " +- "failed: %d\n", ret); ++ info->mtd = do_map_probe(plat->map_name, &info->map); ++ if (!info->mtd) { ++ err = -ENXIO; ++ goto no_device; + } + ++ info->mtd->owner = THIS_MODULE; ++ ++ err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0); ++ if (err > 0) { ++ err = add_mtd_partitions(info->mtd, info->parts, err); ++ if (err) ++ printk(KERN_ERR ++ "mtd partition registration failed: %d\n", err); ++ } ++ ++ if (err == 0) ++ dev_set_drvdata(&dev->dev, info); ++ + /* + * If we got an error, free all resources. + */ +- if (ret < 0) { +- del_mtd_partitions(mtd); +- map_destroy(mtd); ++ if (err < 0) { ++ if (info->mtd) { ++ del_mtd_partitions(info->mtd); ++ map_destroy(info->mtd); + } ++ if (info->parts) ++ kfree(info->parts); + +- return ret; +-} +- +-static void armflash_cfi_exit(void) +-{ +- if (mtd) { +- del_mtd_partitions(mtd); +- map_destroy(mtd); ++ no_device: ++ iounmap(base); ++ no_mem: ++ release_mem_region(res->start, size); ++ no_resource: ++ if (plat && plat->exit) ++ plat->exit(); ++ kfree(info); + } +- if (parts) +- kfree(parts); ++ out: ++ return err; + } + +-static int __init armflash_init(void) ++static int armflash_remove(struct device *_dev) + { +- int err = -EBUSY; +- void *base; ++ struct platform_device *dev = to_platform_device(_dev); ++ struct armflash_info *info = dev_get_drvdata(&dev->dev); + +- if (request_mem_region(FLASH_BASE, FLASH_SIZE, "flash") == NULL) +- goto out; ++ dev_set_drvdata(&dev->dev, NULL); + +- base = ioremap(FLASH_BASE, FLASH_SIZE); +- err = -ENOMEM; +- if (base == NULL) +- goto release; ++ if (info) { ++ if (info->mtd) { ++ del_mtd_partitions(info->mtd); ++ map_destroy(info->mtd); ++ } ++ if (info->parts) ++ kfree(info->parts); + +- err = armflash_cfi_init(base, FLASH_SIZE); +- if (err) { +- iounmap(base); +-release: +- release_mem_region(FLASH_BASE, FLASH_SIZE); ++ iounmap((void *)info->map.virt); ++ release_resource(info->res); ++ kfree(info->res); ++ ++ if (info->plat && info->plat->exit) ++ info->plat->exit(); ++ ++ kfree(info); + } +-out: +- return err; ++ ++ return 0; ++} ++ ++static struct device_driver armflash_driver = { ++ .name = "armflash", ++ .bus = &platform_bus_type, ++ .probe = armflash_probe, ++ .remove = armflash_remove, ++}; ++ ++static int __init armflash_init(void) ++{ ++ return driver_register(&armflash_driver); + } + + static void __exit armflash_exit(void) + { +- armflash_cfi_exit(); +- iounmap((void *)armflash_map.map_priv_2); +- release_mem_region(FLASH_BASE, FLASH_SIZE); +- armflash_flash_exit(); ++ driver_unregister(&armflash_driver); + } + + module_init(armflash_init); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/iq80310.c linux/drivers/mtd/maps/iq80310.c +--- linux-mips-2.4.27/drivers/mtd/maps/iq80310.c 2002-06-27 00:35:50.000000000 +0200 ++++ linux/drivers/mtd/maps/iq80310.c 2004-11-19 10:25:11.924195992 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: iq80310.c,v 1.9 2002/01/01 22:45:02 rmk Exp $ ++ * $Id: iq80310.c,v 1.17 2003/06/23 11:48:18 dwmw2 Exp $ + * + * Mapping for the Intel XScale IQ80310 evaluation board + * +@@ -14,6 +14,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -26,127 +28,72 @@ + + static struct mtd_info *mymtd; + +-static __u8 iq80310_read8(struct map_info *map, unsigned long ofs) +-{ +- return *(__u8 *)(map->map_priv_1 + ofs); +-} +- +-static __u16 iq80310_read16(struct map_info *map, unsigned long ofs) +-{ +- return *(__u16 *)(map->map_priv_1 + ofs); +-} +- +-static __u32 iq80310_read32(struct map_info *map, unsigned long ofs) +-{ +- return *(__u32 *)(map->map_priv_1 + ofs); +-} +- +-static void iq80310_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy(to, (void *)(map->map_priv_1 + from), len); +-} +- +-static void iq80310_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- *(__u8 *)(map->map_priv_1 + adr) = d; +-} +- +-static void iq80310_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- *(__u16 *)(map->map_priv_1 + adr) = d; +-} +- +-static void iq80310_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- *(__u32 *)(map->map_priv_1 + adr) = d; +-} +- +-static void iq80310_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy((void *)(map->map_priv_1 + to), from, len); +-} +- + static struct map_info iq80310_map = { +- name: "IQ80310 flash", +- size: WINDOW_SIZE, +- buswidth: BUSWIDTH, +- read8: iq80310_read8, +- read16: iq80310_read16, +- read32: iq80310_read32, +- copy_from: iq80310_copy_from, +- write8: iq80310_write8, +- write16: iq80310_write16, +- write32: iq80310_write32, +- copy_to: iq80310_copy_to ++ .name = "IQ80310 flash", ++ .size = WINDOW_SIZE, ++ .buswidth = BUSWIDTH, ++ .phys = WINDOW_ADDR + }; + + static struct mtd_partition iq80310_partitions[4] = { + { +- name: "Firmware", +- size: 0x00080000, +- offset: 0, +- mask_flags: MTD_WRITEABLE /* force read-only */ ++ .name = "Firmware", ++ .size = 0x00080000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE /* force read-only */ + },{ +- name: "Kernel", +- size: 0x000a0000, +- offset: 0x00080000, ++ .name = "Kernel", ++ .size = 0x000a0000, ++ .offset = 0x00080000, + },{ +- name: "Filesystem", +- size: 0x00600000, +- offset: 0x00120000 ++ .name = "Filesystem", ++ .size = 0x00600000, ++ .offset = 0x00120000 + },{ +- name: "RedBoot", +- size: 0x000e0000, +- offset: 0x00720000, +- mask_flags: MTD_WRITEABLE ++ .name = "RedBoot", ++ .size = 0x000e0000, ++ .offset = 0x00720000, ++ .mask_flags = MTD_WRITEABLE + } + }; + +-#define NB_OF(x) (sizeof(x)/sizeof(x[0])) +- + static struct mtd_info *mymtd; + static struct mtd_partition *parsed_parts; +- +-extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); ++static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; + + static int __init init_iq80310(void) + { + struct mtd_partition *parts; + int nb_parts = 0; + int parsed_nr_parts = 0; +- char *part_type = "static"; ++ int ret; + +- iq80310_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); +- if (!iq80310_map.map_priv_1) { ++ iq80310_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); ++ if (!iq80310_map.virt) { + printk("Failed to ioremap\n"); + return -EIO; + } ++ simple_map_init(&iq80310_map); ++ + mymtd = do_map_probe("cfi_probe", &iq80310_map); + if (!mymtd) { +- iounmap((void *)iq80310_map.map_priv_1); ++ iounmap((void *)iq80310_map.virt); + return -ENXIO; + } +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + +-#ifdef CONFIG_MTD_REDBOOT_PARTS +- if (parsed_nr_parts == 0) { +- int ret = parse_redboot_partitions(mymtd, &parsed_parts); ++ ret = parse_mtd_partitions(mymtd, probes, &parsed_parts, 0); + +- if (ret > 0) { +- part_type = "RedBoot"; ++ if (ret > 0) + parsed_nr_parts = ret; +- } +- } +-#endif + + if (parsed_nr_parts > 0) { + parts = parsed_parts; + nb_parts = parsed_nr_parts; + } else { + parts = iq80310_partitions; +- nb_parts = NB_OF(iq80310_partitions); ++ nb_parts = ARRAY_SIZE(iq80310_partitions); + } +- printk(KERN_NOTICE "Using %s partition definition\n", part_type); + add_mtd_partitions(mymtd, parts, nb_parts); + return 0; + } +@@ -159,8 +106,8 @@ + if (parsed_parts) + kfree(parsed_parts); + } +- if (iq80310_map.map_priv_1) +- iounmap((void *)iq80310_map.map_priv_1); ++ if (iq80310_map.virt) ++ iounmap((void *)iq80310_map.virt); + } + + module_init(init_iq80310); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/ixp425.c linux/drivers/mtd/maps/ixp425.c +--- linux-mips-2.4.27/drivers/mtd/maps/ixp425.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/maps/ixp425.c 2004-11-19 10:25:11.925195840 +0100 +@@ -0,0 +1,220 @@ ++/* ++ * $Id: ixp425.c,v 1.1 2003/11/26 21:26:09 dsaxena Exp $ ++ * ++ * drivers/mtd/maps/ixp425.c ++ * ++ * MTD Map file for IXP425 based systems. Please do not make per-board ++ * map driver as the code will be 90% identical. For now just add ++ * if(machine_is_XXX()) checks to the code. I'll clean this stuff to ++ * use platform_data in the the future so we can get rid of that too. ++ * ++ * Original Author: Intel Corporation ++ * Maintainer: Deepak Saxena ++ * ++ * Copyright (C) 2002 Intel Corporation ++ * Copyright (C) 2003 MontaVista Software, Inc. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define WINDOW_ADDR 0x50000000 ++#define BUSWIDTH 2 ++ ++#ifndef __ARMEB__ ++#define BYTE0(h) ((h) & 0xFF) ++#define BYTE1(h) (((h) >> 8) & 0xFF) ++#else ++#define BYTE0(h) (((h) >> 8) & 0xFF) ++#define BYTE1(h) ((h) & 0xFF) ++#endif ++ ++static __u16 ++ixp425_read16(struct map_info *map, unsigned long ofs) ++{ ++ return *(__u16 *) (map->map_priv_1 + ofs); ++} ++ ++/* ++ * The IXP425 expansion bus only allows 16-bit wide acceses ++ * when attached to a 16-bit wide device (such as the 28F128J3A), ++ * so we can't just memcpy_fromio(). ++ */ ++static void ++ixp425_copy_from(struct map_info *map, void *to, ++ unsigned long from, ssize_t len) ++{ ++ int i; ++ u8 *dest = (u8 *) to; ++ u16 *src = (u16 *) (map->map_priv_1 + from); ++ u16 data; ++ ++ for (i = 0; i < (len / 2); i++) { ++ data = src[i]; ++ dest[i * 2] = BYTE0(data); ++ dest[i * 2 + 1] = BYTE1(data); ++ } ++ ++ if (len & 1) ++ dest[len - 1] = BYTE0(src[i]); ++} ++ ++static void ++ixp425_write16(struct map_info *map, __u16 d, unsigned long adr) ++{ ++ *(__u16 *) (map->map_priv_1 + adr) = d; ++} ++ ++static struct map_info ixp425_map = { ++ .name = "IXP425 Flash", ++ .buswidth = BUSWIDTH, ++ .read16 = ixp425_read16, ++ .copy_from = ixp425_copy_from, ++ .write16 = ixp425_write16, ++}; ++ ++/* ++ * Put flash back in read mode so RedBoot can boot properly. ++ */ ++int ixp425_mtd_reboot(struct notifier_block *n, unsigned long code, void *p) ++{ ++ if (code != SYS_RESTART) ++ return NOTIFY_DONE; ++ ++ ixp425_write16(&ixp425_map, 0xff, 0x55 * 0x2); ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block ixp425_mtd_notifier = { ++ notifier_call:ixp425_mtd_reboot, ++ next:NULL, ++ priority:0 ++}; ++ ++static struct mtd_partition *parsed_parts; ++static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; ++ ++static struct mtd_partition ixp425_partitions[] = { ++ { ++ .name = "image", ++ .offset = 0x00040000, ++ .size = 0x00400000, ++ }, { ++ .name = "user", ++ .offset = 0x00440000, ++ .size = MTDPART_SIZ_FULL ++ } ++}; ++ ++#define NB_OF(x) (sizeof(x)/sizeof(x[0])) ++ ++static struct mtd_info *ixp425_mtd; ++static struct resource *mtd_resource; ++ ++static void ++ixp425_exit(void) ++{ ++ if (ixp425_mtd) { ++ del_mtd_partitions(ixp425_mtd); ++ map_destroy(ixp425_mtd); ++ } ++ if (ixp425_map.map_priv_1) ++ iounmap((void *) ixp425_map.map_priv_1); ++ if (mtd_resource) ++ release_mem_region(WINDOW_ADDR, ixp425_map.size); ++ ++ if (parsed_parts) ++ kfree(parsed_parts); ++ ++ unregister_reboot_notifier(&ixp425_mtd_notifier); ++ ++ /* Disable flash write */ ++ *IXP425_EXP_CS0 &= ~IXP425_FLASH_WRITABLE; ++ ++ if(machine_is_adi_coyote()) ++ *IXP425_EXP_CS1 &= ~IXP425_FLASH_WRITABLE; ++} ++ ++static int __init ++ixp425_init(void) ++{ ++ int res = -1, npart; ++ ++ /* Enable flash write */ ++ *IXP425_EXP_CS0 |= IXP425_FLASH_WRITABLE; ++ ++ /* ++ * Coyote requires CS1 write to be enabled and has 32MB flash. ++ * This will move to the platform init code in 2.6 ++ */ ++ if(machine_is_adi_coyote()) { ++ *IXP425_EXP_CS1 |= IXP425_FLASH_WRITABLE; ++ ixp425_map.size = 0x02000000; ++ } else ++ ixp425_map.size = 0x01000000; ++ ++ ixp425_map.map_priv_1 = 0; ++ mtd_resource = ++ request_mem_region(WINDOW_ADDR, ixp425_map.size, "IXP425 Flash"); ++ if (!mtd_resource) { ++ printk(KERN_ERR ++ "ixp425 flash: Could not request mem region.\n"); ++ res = -ENOMEM; ++ goto Error; ++ } ++ ++ ixp425_map.map_priv_1 = ++ (unsigned long) ioremap(WINDOW_ADDR, ixp425_map.size); ++ if (!ixp425_map.map_priv_1) { ++ printk("ixp425 Flash: Failed to map IO region. (ioremap)\n"); ++ res = -EIO; ++ goto Error; ++ } ++ ++ ixp425_mtd = do_map_probe("cfi_probe", &ixp425_map); ++ if (!ixp425_mtd) { ++ res = -ENXIO; ++ goto Error; ++ } ++ ixp425_mtd->owner = THIS_MODULE; ++ ++ /* Try to parse RedBoot partitions */ ++ npart = parse_mtd_partitions(ixp425_mtd, probes, &parsed_parts, 0); ++ if (npart > 0) ++ res = add_mtd_partitions(ixp425_mtd, parsed_parts, npart); ++ else { ++ printk("IXP425 Flash: Using static MTD partitions.\n"); ++ res = add_mtd_partitions(ixp425_mtd, ixp425_partitions, ++ NB_OF(ixp425_partitions)); ++ } ++ ++ if (res) ++ goto Error; ++ ++ register_reboot_notifier(&ixp425_mtd_notifier); ++ ++ return res; ++ ++Error: ++ ixp425_exit(); ++ return res; ++} ++ ++module_init(ixp425_init); ++module_exit(ixp425_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("MTD map driver for ixp425 evaluation board"); ++MODULE_AUTHOR("Deepak Saxena"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/l440gx.c linux/drivers/mtd/maps/l440gx.c +--- linux-mips-2.4.27/drivers/mtd/maps/l440gx.c 2002-06-27 00:35:50.000000000 +0200 ++++ linux/drivers/mtd/maps/l440gx.c 2004-11-19 10:25:11.927195536 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: l440gx.c,v 1.8 2002/01/10 20:27:40 eric Exp $ ++ * $Id: l440gx.c,v 1.12 2003/05/21 12:45:19 dwmw2 Exp $ + * + * BIOS Flash chip on Intel 440GX board. + * +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -27,48 +28,6 @@ + + static struct mtd_info *mymtd; + +-__u8 l440gx_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-__u16 l440gx_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} +- +-__u32 l440gx_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} +- +-void l440gx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-void l440gx_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void l440gx_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void l440gx_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void l440gx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio(map->map_priv_1 + to, from, len); +-} + + /* Is this really the vpp port? */ + void l440gx_set_vpp(struct map_info *map, int vpp) +@@ -85,22 +44,15 @@ + } + + struct map_info l440gx_map = { +- name: "L440GX BIOS", +- size: WINDOW_SIZE, +- buswidth: BUSWIDTH, +- read8: l440gx_read8, +- read16: l440gx_read16, +- read32: l440gx_read32, +- copy_from: l440gx_copy_from, +- write8: l440gx_write8, +- write16: l440gx_write16, +- write32: l440gx_write32, +- copy_to: l440gx_copy_to, ++ .name = "L440GX BIOS", ++ .size = WINDOW_SIZE, ++ .buswidth = BUSWIDTH, ++ .phys = WINDOW_ADDR, + #if 0 + /* FIXME verify that this is the + * appripriate code for vpp enable/disable + */ +- set_vpp: l440gx_set_vpp ++ .set_vpp = l440gx_set_vpp + #endif + }; + +@@ -113,7 +65,6 @@ + dev = pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB_0, NULL); + +- + pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB_3, NULL); + +@@ -122,15 +73,14 @@ + return -ENODEV; + } + ++ l440gx_map.virt = (unsigned long)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE); + +- l440gx_map.map_priv_1 = (unsigned long)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE); +- +- if (!l440gx_map.map_priv_1) { ++ if (!l440gx_map.virt) { + printk(KERN_WARNING "Failed to ioremap L440GX flash region\n"); + return -ENOMEM; + } +- +- printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.map_priv_1); ++ simple_map_init(&l440gx_map); ++ printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt); + + /* Setup the pm iobase resource + * This code should move into some kind of generic bridge +@@ -153,7 +103,7 @@ + /* Allocate the resource region */ + if (pci_assign_resource(pm_dev, PIIXE_IOBASE_RESOURCE) != 0) { + printk(KERN_WARNING "Could not allocate pm iobase resource\n"); +- iounmap((void *)l440gx_map.map_priv_1); ++ iounmap((void *)l440gx_map.virt); + return -ENXIO; + } + } +@@ -181,13 +131,13 @@ + mymtd = do_map_probe("map_rom", &l440gx_map); + } + if (mymtd) { +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + + add_mtd_device(mymtd); + return 0; + } + +- iounmap((void *)l440gx_map.map_priv_1); ++ iounmap((void *)l440gx_map.virt); + return -ENXIO; + } + +@@ -196,7 +146,7 @@ + del_mtd_device(mymtd); + map_destroy(mymtd); + +- iounmap((void *)l440gx_map.map_priv_1); ++ iounmap((void *)l440gx_map.virt); + } + + module_init(init_l440gx); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/lasat.c linux/drivers/mtd/maps/lasat.c +--- linux-mips-2.4.27/drivers/mtd/maps/lasat.c 2003-08-18 04:59:02.000000000 +0200 ++++ linux/drivers/mtd/maps/lasat.c 2004-11-19 10:25:11.928195384 +0100 +@@ -1,11 +1,20 @@ + /* +- * Flash device on lasat 100 and 200 boards ++ * Flash device on Lasat 100 and 200 boards ++ * ++ * (C) 2002 Brian Murphy ++ * ++ * 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. ++ * ++ * $Id: lasat.c,v 1.6 2003/09/02 16:36:40 brm Exp $ + * + */ + + #include + #include + #include ++#include + #include + #include + #include +@@ -13,123 +22,80 @@ + #include + #include + +-static struct mtd_info *mymtd; +- +-static __u8 sp_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-static __u16 sp_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} +- +-static __u32 sp_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} +- +-static void sp_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} ++static struct mtd_info *lasat_mtd; + +-static void sp_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-static void sp_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-static void sp_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} ++static struct mtd_partition partition_info[LASAT_MTD_LAST]; ++static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"}; + +-static void sp_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) ++static void lasat_set_vpp(struct map_info *map, int vpp) + { +- memcpy_toio(map->map_priv_1 + to, from, len); ++ if (vpp) ++ *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit; ++ else ++ *lasat_misc->flash_wp_reg &= ~(1 << lasat_misc->flash_wp_bit); + } + +-static struct map_info sp_map = { +- name: "SP flash", +- buswidth: 4, +- read8: sp_read8, +- read16: sp_read16, +- read32: sp_read32, +- copy_from: sp_copy_from, +- write8: sp_write8, +- write16: sp_write16, +- write32: sp_write32, +- copy_to: sp_copy_to ++static struct map_info lasat_map = { ++ .name = "LASAT flash", ++ .buswidth = 4, ++ .set_vpp = lasat_set_vpp + }; + +-static struct mtd_partition partition_info[LASAT_MTD_LAST]; +-static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Config", "Filesystem"}; +- +-static int __init init_sp(void) ++static int __init init_lasat(void) + { + int i; +- int nparts = 0; +- /* this does not play well with the old flash code which +- * protects and uprotects the flash when necessary */ ++ /* since we use AMD chips and set_vpp is not implimented ++ * for these (yet) we still have to permanently enable flash write */ + printk(KERN_NOTICE "Unprotecting flash\n"); +- *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit; ++ ENABLE_VPP((&lasat_map)); + +- sp_map.map_priv_1 = ioremap_nocache( +- lasat_flash_partition_start(LASAT_MTD_BOOTLOADER), +- lasat_board_info.li_flash_size); +- sp_map.size = lasat_board_info.li_flash_size; ++ lasat_map.phys = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER); ++ lasat_map.virt = (unsigned long)ioremap_nocache( ++ lasat_map.phys, lasat_board_info.li_flash_size); ++ lasat_map.size = lasat_board_info.li_flash_size; + +- printk(KERN_NOTICE "sp flash device: %lx at %lx\n", +- sp_map.size, sp_map.map_priv_1); ++ simple_map_init(&lasat_map); + + for (i=0; i < LASAT_MTD_LAST; i++) + partition_info[i].name = lasat_mtd_partnames[i]; + +- mymtd = do_map_probe("cfi_probe", &sp_map); +- if (mymtd) { ++ lasat_mtd = do_map_probe("cfi_probe", &lasat_map); ++ ++ if (!lasat_mtd) ++ lasat_mtd = do_map_probe("jedec_probe", &lasat_map); ++ ++ if (lasat_mtd) { + u32 size, offset = 0; + +- mymtd->module = THIS_MODULE; ++ lasat_mtd->owner = THIS_MODULE; + + for (i=0; i < LASAT_MTD_LAST; i++) { + size = lasat_flash_partition_size(i); +- if (size != 0) { +- nparts++; + partition_info[i].size = size; + partition_info[i].offset = offset; + offset += size; + } +- } + +- add_mtd_partitions( mymtd, partition_info, nparts ); ++ add_mtd_partitions( lasat_mtd, partition_info, LASAT_MTD_LAST ); + return 0; + } + + return -ENXIO; + } + +-static void __exit cleanup_sp(void) ++static void __exit cleanup_lasat(void) + { +- if (mymtd) { +- del_mtd_partitions(mymtd); +- map_destroy(mymtd); ++ if (lasat_mtd) { ++ del_mtd_partitions(lasat_mtd); ++ map_destroy(lasat_mtd); + } +- if (sp_map.map_priv_1) { +- sp_map.map_priv_1 = 0; ++ if (lasat_map.virt) { ++ lasat_map.virt = 0; + } + } + +-module_init(init_sp); +-module_exit(cleanup_sp); ++module_init(init_lasat); ++module_exit(cleanup_lasat); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Brian Murphy "); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/lubbock-flash.c linux/drivers/mtd/maps/lubbock-flash.c +--- linux-mips-2.4.27/drivers/mtd/maps/lubbock-flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/maps/lubbock-flash.c 2004-11-19 10:25:11.930195080 +0100 +@@ -0,0 +1,151 @@ ++/* ++ * $Id: lubbock-flash.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $ ++ * ++ * Map driver for the Lubbock developer platform. ++ * ++ * Author: Nicolas Pitre ++ * Copyright: (C) 2001 MontaVista Software Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define ROM_ADDR 0x00000000 ++#define FLASH_ADDR 0x04000000 ++ ++#define WINDOW_SIZE 64*1024*1024 ++ ++static struct map_info lubbock_maps[2] = { { ++ .size = WINDOW_SIZE, ++ .phys = 0x00000000, ++}, { ++ .size = WINDOW_SIZE, ++ .phys = 0x04000000, ++} }; ++ ++static struct mtd_partition lubbock_partitions[] = { ++ { ++ .name = "Bootloader", ++ .size = 0x00040000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE /* force read-only */ ++ },{ ++ .name = "Kernel", ++ .size = 0x00100000, ++ .offset = 0x00040000, ++ },{ ++ .name = "Filesystem", ++ .size = MTDPART_SIZ_FULL, ++ .offset = 0x00140000 ++ } ++}; ++ ++static struct mtd_info *mymtds[2]; ++static struct mtd_partition *parsed_parts[2]; ++static int nr_parsed_parts[2]; ++ ++static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; ++ ++static int __init init_lubbock(void) ++{ ++ int flashboot = (CONF_SWITCHES & 1); ++ int ret = 0, i; ++ ++ lubbock_maps[0].buswidth = lubbock_maps[1].buswidth = ++ (BOOT_DEF & 1) ? 2 : 4; ++ ++ /* Compensate for the nROMBT switch which swaps the flash banks */ ++ printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n", ++ flashboot?"Flash":"ROM", flashboot); ++ ++ lubbock_maps[flashboot^1].name = "Lubbock Application Flash"; ++ lubbock_maps[flashboot].name = "Lubbock Boot ROM"; ++ ++ for (i = 0; i < 2; i++) { ++ lubbock_maps[i].virt = (unsigned long)__ioremap(lubbock_maps[i].phys, WINDOW_SIZE, 0); ++ if (!lubbock_maps[i].virt) { ++ printk(KERN_WARNING "Failed to ioremap %s\n", lubbock_maps[i].name); ++ if (!ret) ++ ret = -ENOMEM; ++ continue; ++ } ++ simple_map_init(&lubbock_maps[i]); ++ ++ printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit buswidth)\n", ++ lubbock_maps[i].name, lubbock_maps[i].phys, ++ lubbock_maps[i].buswidth * 8); ++ ++ mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]); ++ ++ if (!mymtds[i]) { ++ iounmap((void *)lubbock_maps[i].virt); ++ if (!ret) ++ ret = -EIO; ++ continue; ++ } ++ mymtds[i]->owner = THIS_MODULE; ++ ++ int ret = parse_mtd_partitions(mymtds[i], probes, ++ &parsed_parts[i], 0); ++ ++ if (ret > 0) ++ nr_parsed_parts[i] = ret; ++ } ++ ++ if (!mymtds[0] && !mymtds[1]) ++ return ret; ++ ++ for (i = 0; i < 2; i++) { ++ if (!mymtds[i]) { ++ printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name); ++ } else if (nr_parsed_parts[i]) { ++ add_mtd_partitions(mymtds[i], parsed_parts[i], nr_parsed_parts[i]); ++ } else if (!i) { ++ printk("Using static partitions on %s\n", lubbock_maps[i].name); ++ add_mtd_partitions(mymtds[i], lubbock_partitions, ARRAY_SIZE(lubbock_partitions)); ++ } else { ++ printk("Registering %s as whole device\n", lubbock_maps[i].name); ++ add_mtd_device(mymtds[i]); ++ } ++ } ++ return 0; ++} ++ ++static void __exit cleanup_lubbock(void) ++{ ++ int i; ++ for (i = 0; i < 2; i++) { ++ if (!mymtds[i]) ++ continue; ++ ++ if (nr_parsed_parts[i] || !i) ++ del_mtd_partitions(mymtds[i]); ++ else ++ del_mtd_device(mymtds[i]); ++ ++ map_destroy(mymtds[i]); ++ iounmap((void *)lubbock_maps[i].virt); ++ ++ if (parsed_parts[i]) ++ kfree(parsed_parts[i]); ++ } ++} ++ ++module_init(init_lubbock); ++module_exit(cleanup_lubbock); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Nicolas Pitre "); ++MODULE_DESCRIPTION("MTD map driver for Intel Lubbock"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/map_funcs.c linux/drivers/mtd/maps/map_funcs.c +--- linux-mips-2.4.27/drivers/mtd/maps/map_funcs.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/maps/map_funcs.c 2004-11-19 10:25:11.931194928 +0100 +@@ -0,0 +1,96 @@ ++/* ++ * $Id: map_funcs.c,v 1.3 2003/11/14 19:50:04 thayne Exp $ ++ * ++ * Out-of-line map I/O functions for simple maps when CONFIG_COMPLEX_MAPPINGS ++ * is enabled. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++static u8 simple_map_read8(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readb(map->virt + ofs); ++} ++ ++static u16 simple_map_read16(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readw(map->virt + ofs); ++} ++ ++static u32 simple_map_read32(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readl(map->virt + ofs); ++} ++ ++static u64 simple_map_read64(struct map_info *map, unsigned long ofs) ++{ ++#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */ ++ BUG(); ++ return 0; ++#else ++ return __raw_readll(map->virt + ofs); ++#endif ++} ++ ++static void simple_map_write8(struct map_info *map, u8 datum, unsigned long ofs) ++{ ++ __raw_writeb(datum, map->virt + ofs); ++ mb(); ++} ++ ++static void simple_map_write16(struct map_info *map, u16 datum, unsigned long ofs) ++{ ++ __raw_writew(datum, map->virt + ofs); ++ mb(); ++} ++ ++static void simple_map_write32(struct map_info *map, u32 datum, unsigned long ofs) ++{ ++ __raw_writel(datum, map->virt + ofs); ++ mb(); ++} ++ ++static void simple_map_write64(struct map_info *map, u64 datum, unsigned long ofs) ++{ ++#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */ ++ BUG(); ++#else ++ __raw_writell(datum, map->virt + ofs); ++ mb(); ++#endif /* CFI_B8 */ ++} ++ ++static void simple_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++{ ++ memcpy_fromio(to, map->virt + from, len); ++} ++ ++static void simple_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) ++{ ++ memcpy_toio(map->virt + to, from, len); ++} ++ ++void simple_map_init(struct map_info *map) ++{ ++ map->read8 = simple_map_read8; ++ map->read16 = simple_map_read16; ++ map->read32 = simple_map_read32; ++ map->read64 = simple_map_read64; ++ map->write8 = simple_map_write8; ++ map->write16 = simple_map_write16; ++ map->write32 = simple_map_write32; ++ map->write64 = simple_map_write64; ++ map->copy_from = simple_map_copy_from; ++ map->copy_to = simple_map_copy_to; ++} ++ ++EXPORT_SYMBOL(simple_map_init); ++ ++MODULE_LICENSE("GPL"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/mbx860.c linux/drivers/mtd/maps/mbx860.c +--- linux-mips-2.4.27/drivers/mtd/maps/mbx860.c 2002-06-27 00:35:50.000000000 +0200 ++++ linux/drivers/mtd/maps/mbx860.c 2004-11-19 10:25:11.933194624 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: mbx860.c,v 1.1 2001/11/18 19:43:09 dwmw2 Exp $ ++ * $Id: mbx860.c,v 1.5 2003/05/21 12:45:19 dwmw2 Exp $ + * + * Handle mapping of the flash on MBX860 boards + * +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -36,91 +37,46 @@ + * single flash device into. If the size if zero we use up to the end of the + * device. */ + static struct mtd_partition partition_info[]={ +- { name: "MBX flash BOOT partition", +- offset: 0, +- size: BOOT_PARTITION_SIZE_KiB*1024 }, +- { name: "MBX flash DATA partition", +- offset: BOOT_PARTITION_SIZE_KiB*1024, +- size: (KERNEL_PARTITION_SIZE_KiB)*1024 }, +- { name: "MBX flash APPLICATION partition", +- offset: (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 } ++ { .name = "MBX flash BOOT partition", ++ .offset = 0, ++ .size = BOOT_PARTITION_SIZE_KiB*1024 }, ++ { .name = "MBX flash DATA partition", ++ .offset = BOOT_PARTITION_SIZE_KiB*1024, ++ .size = (KERNEL_PARTITION_SIZE_KiB)*1024 }, ++ { .name = "MBX flash APPLICATION partition", ++ .offset = (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 } + }; + + + static struct mtd_info *mymtd; + +-__u8 mbx_read8(struct map_info *map, unsigned long ofs) +-{ +- return readb(map->map_priv_1 + ofs); +-} +- +-__u16 mbx_read16(struct map_info *map, unsigned long ofs) +-{ +- return readw(map->map_priv_1 + ofs); +-} +- +-__u32 mbx_read32(struct map_info *map, unsigned long ofs) +-{ +- return readl(map->map_priv_1 + ofs); +-} +- +-void mbx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len); +-} +- +-void mbx_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- writeb(d, map->map_priv_1 + adr); +-} +- +-void mbx_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- writew(d, map->map_priv_1 + adr); +-} +- +-void mbx_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- writel(d, map->map_priv_1 + adr); +-} +- +-void mbx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio((void *)(map->map_priv_1 + to), from, len); +-} +- + struct map_info mbx_map = { +- name: "MBX flash", +- size: WINDOW_SIZE, +- buswidth: 4, +- read8: mbx_read8, +- read16: mbx_read16, +- read32: mbx_read32, +- copy_from: mbx_copy_from, +- write8: mbx_write8, +- write16: mbx_write16, +- write32: mbx_write32, +- copy_to: mbx_copy_to ++ .name = "MBX flash", ++ .size = WINDOW_SIZE, ++ .phys = WINDOW_ADDR, ++ .buswidth = 4, + }; + + int __init init_mbx(void) + { +- printk(KERN_NOTICE "Motorola MBX flash device: %x at %x\n", WINDOW_SIZE*4, WINDOW_ADDR); +- mbx_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4); ++ printk(KERN_NOTICE "Motorola MBX flash device: 0x%x at 0x%x\n", WINDOW_SIZE*4, WINDOW_ADDR); ++ mbx_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4); + +- if (!mbx_map.map_priv_1) { ++ if (!mbx_map.virt) { + printk("Failed to ioremap\n"); + return -EIO; + } ++ simple_map_init(&mbx_map); ++ + mymtd = do_map_probe("jedec_probe", &mbx_map); + if (mymtd) { +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + add_mtd_device(mymtd); + add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS); + return 0; + } + +- iounmap((void *)mbx_map.map_priv_1); ++ iounmap((void *)mbx_map.virt); + return -ENXIO; + } + +@@ -130,9 +86,9 @@ + del_mtd_device(mymtd); + map_destroy(mymtd); + } +- if (mbx_map.map_priv_1) { +- iounmap((void *)mbx_map.map_priv_1); +- mbx_map.map_priv_1 = 0; ++ if (mbx_map.virt) { ++ iounmap((void *)mbx_map.virt); ++ mbx_map.virt = 0; + } + } + +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/mpc1211.c linux/drivers/mtd/maps/mpc1211.c +--- linux-mips-2.4.27/drivers/mtd/maps/mpc1211.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/maps/mpc1211.c 2004-11-19 10:25:11.934194472 +0100 +@@ -0,0 +1,79 @@ ++/* ++ * Flash on MPC-1211 ++ * ++ * (C) 2002 Interface, Saito.K & Jeanne ++ * ++ * GPL'd ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static struct mtd_info *flash_mtd; ++static struct mtd_partition *parsed_parts; ++ ++struct map_info mpc1211_flash_map = { ++ .name = "MPC-1211 FLASH", ++ .size = 0x80000, ++ .buswidth = 1, ++}; ++ ++static struct mtd_partition mpc1211_partitions[] = { ++ { ++ .name = "IPL & ETH-BOOT", ++ .offset = 0x00000000, ++ .size = 0x10000, ++ }, ++ { ++ .name = "Flash FS", ++ .offset = 0x00010000, ++ .size = MTDPART_SIZ_FULL, ++ } ++}; ++ ++static int __init init_mpc1211_maps(void) ++{ ++ int nr_parts; ++ ++ mpc1211_flash_map.phys = 0; ++ mpc1211_flash_map.virt = P2SEGADDR(0); ++ ++ simple_map_init(&mpc1211_flash_map); ++ ++ printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n"); ++ flash_mtd = do_map_probe("jedec_probe", &mpc1211_flash_map); ++ if (!flash_mtd) { ++ printk(KERN_NOTICE "Flash chips not detected at either possible location.\n"); ++ return -ENXIO; ++ } ++ printk(KERN_NOTICE "MPC-1211: Flash at 0x%08lx\n", mpc1211_flash_map.virt & 0x1fffffff); ++ flash_mtd->module = THIS_MODULE; ++ ++ parsed_parts = mpc1211_partitions; ++ nr_parts = ARRAY_SIZE(mpc1211_partitions); ++ ++ add_mtd_partitions(flash_mtd, parsed_parts, nr_parts); ++ return 0; ++} ++ ++static void __exit cleanup_mpc1211_maps(void) ++{ ++ if (parsed_parts) ++ del_mtd_partitions(flash_mtd); ++ else ++ del_mtd_device(flash_mtd); ++ map_destroy(flash_mtd); ++} ++ ++module_init(init_mpc1211_maps); ++module_exit(cleanup_mpc1211_maps); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Saito.K & Jeanne "); ++MODULE_DESCRIPTION("MTD map driver for MPC-1211 boards. Interface"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/netsc520.c linux/drivers/mtd/maps/netsc520.c +--- linux-mips-2.4.27/drivers/mtd/maps/netsc520.c 2001-11-05 21:15:52.000000000 +0100 ++++ linux/drivers/mtd/maps/netsc520.c 2004-11-19 10:25:11.935194320 +0100 +@@ -3,7 +3,7 @@ + * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com) + * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH + * +- * $Id: netsc520.c,v 1.5 2001/10/02 15:05:14 dwmw2 Exp $ ++ * $Id: netsc520.c,v 1.9 2003/05/21 12:45:19 dwmw2 Exp $ + * + * 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 +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -50,95 +51,41 @@ + ** recoverable afterwards. + */ + +-static __u8 netsc520_read8(struct map_info *map, unsigned long ofs) +-{ +- return readb(map->map_priv_1 + ofs); +-} +- +-static __u16 netsc520_read16(struct map_info *map, unsigned long ofs) +-{ +- return readw(map->map_priv_1 + ofs); +-} +- +-static __u32 netsc520_read32(struct map_info *map, unsigned long ofs) +-{ +- return readl(map->map_priv_1 + ofs); +-} +- +-static void netsc520_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len); +-} +- +-static void netsc520_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- writeb(d, map->map_priv_1 + adr); +-} +- +-static void netsc520_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- writew(d, map->map_priv_1 + adr); +-} +- +-static void netsc520_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- writel(d, map->map_priv_1 + adr); +-} +- +-static void netsc520_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio((void *)(map->map_priv_1 + to), from, len); +-} +- + /* partition_info gives details on the logical partitions that the split the + * single flash device into. If the size if zero we use up to the end of the + * device. */ + static struct mtd_partition partition_info[]={ + { +- name: "NetSc520 boot kernel", +- offset: 0, +- size: 0xc0000 ++ .name = "NetSc520 boot kernel", ++ .offset = 0, ++ .size = 0xc0000 + }, + { +- name: "NetSc520 Low BIOS", +- offset: 0xc0000, +- size: 0x40000 ++ .name = "NetSc520 Low BIOS", ++ .offset = 0xc0000, ++ .size = 0x40000 + }, + { +- name: "NetSc520 file system", +- offset: 0x100000, +- size: 0xe80000 ++ .name = "NetSc520 file system", ++ .offset = 0x100000, ++ .size = 0xe80000 + }, + { +- name: "NetSc520 High BIOS", +- offset: 0xf80000, +- size: 0x80000 ++ .name = "NetSc520 High BIOS", ++ .offset = 0xf80000, ++ .size = 0x80000 + }, + }; + #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) + +-/* +- * If no idea what is going on here. This is taken from the FlashFX stuff. +- */ +-#define ROMCS 1 +- +- + #define WINDOW_SIZE 0x00100000 + #define WINDOW_ADDR 0x00200000 + + static struct map_info netsc520_map = { +- name: "netsc520 Flash Bank", +- size: WINDOW_SIZE, +- buswidth: 4, +- read8: netsc520_read8, +- read16: netsc520_read16, +- read32: netsc520_read32, +- copy_from: netsc520_copy_from, +- write8: netsc520_write8, +- write16: netsc520_write16, +- write32: netsc520_write32, +- copy_to: netsc520_copy_to, +- map_priv_2: WINDOW_ADDR ++ .name = "netsc520 Flash Bank", ++ .size = WINDOW_SIZE, ++ .buswidth = 4, ++ .phys = WINDOW_ADDR, + }; + + #define NUM_FLASH_BANKS (sizeof(netsc520_map)/sizeof(struct map_info)) +@@ -147,13 +94,16 @@ + + static int __init init_netsc520(void) + { +- printk(KERN_NOTICE "NetSc520 flash device: %lx at %lx\n", netsc520_map.size, netsc520_map.map_priv_2); +- netsc520_map.map_priv_1 = (unsigned long)ioremap_nocache(netsc520_map.map_priv_2, netsc520_map.size); ++ printk(KERN_NOTICE "NetSc520 flash device: 0x%lx at 0x%lx\n", netsc520_map.size, netsc520_map.phys); ++ netsc520_map.virt = (unsigned long)ioremap_nocache(netsc520_map.phys, netsc520_map.size); + +- if (!netsc520_map.map_priv_1) { ++ if (!netsc520_map.virt) { + printk("Failed to ioremap_nocache\n"); + return -EIO; + } ++ ++ simple_map_init(&netsc520_map); ++ + mymtd = do_map_probe("cfi_probe", &netsc520_map); + if(!mymtd) + mymtd = do_map_probe("map_ram", &netsc520_map); +@@ -161,11 +111,11 @@ + mymtd = do_map_probe("map_rom", &netsc520_map); + + if (!mymtd) { +- iounmap((void *)netsc520_map.map_priv_1); ++ iounmap((void *)netsc520_map.virt); + return -ENXIO; + } + +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS ); + return 0; + } +@@ -176,9 +126,9 @@ + del_mtd_partitions(mymtd); + map_destroy(mymtd); + } +- if (netsc520_map.map_priv_1) { +- iounmap((void *)netsc520_map.map_priv_1); +- netsc520_map.map_priv_1 = 0; ++ if (netsc520_map.virt) { ++ iounmap((void *)netsc520_map.virt); ++ netsc520_map.virt = 0; + } + } + +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/nettel.c linux/drivers/mtd/maps/nettel.c +--- linux-mips-2.4.27/drivers/mtd/maps/nettel.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/maps/nettel.c 2004-11-19 10:25:11.937194016 +0100 +@@ -6,7 +6,7 @@ + * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com) + * (C) Copyright 2001-2002, SnapGear (www.snapgear.com) + * +- * $Id: nettel.c,v 1.1 2002/08/08 06:30:13 gerg Exp $ ++ * $Id: nettel.c,v 1.4 2003/05/20 20:59:30 dwmw2 Exp $ + */ + + /****************************************************************************/ +@@ -59,128 +59,72 @@ + + /****************************************************************************/ + +-static __u8 nettel_read8(struct map_info *map, unsigned long ofs) +-{ +- return(readb(map->map_priv_1 + ofs)); +-} +- +-static __u16 nettel_read16(struct map_info *map, unsigned long ofs) +-{ +- return(readw(map->map_priv_1 + ofs)); +-} +- +-static __u32 nettel_read32(struct map_info *map, unsigned long ofs) +-{ +- return(readl(map->map_priv_1 + ofs)); +-} +- +-static void nettel_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-static void nettel_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- writeb(d, map->map_priv_1 + adr); +-} +- +-static void nettel_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- writew(d, map->map_priv_1 + adr); +-} +- +-static void nettel_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- writel(d, map->map_priv_1 + adr); +-} +- +-static void nettel_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio(map->map_priv_1 + to, from, len); +-} +- + /****************************************************************************/ + + #ifdef CONFIG_MTD_CFI_INTELEXT + static struct map_info nettel_intel_map = { +- name: "SnapGear Intel", +- size: 0, +- buswidth: INTEL_BUSWIDTH, +- read8: nettel_read8, +- read16: nettel_read16, +- read32: nettel_read32, +- copy_from: nettel_copy_from, +- write8: nettel_write8, +- write16: nettel_write16, +- write32: nettel_write32, +- copy_to: nettel_copy_to ++ .name = "SnapGear Intel", ++ .size = 0, ++ .buswidth = INTEL_BUSWIDTH, + }; + + static struct mtd_partition nettel_intel_partitions[] = { + { +- name: "SnapGear kernel", +- offset: 0, +- size: 0x000e0000 ++ .name = "SnapGear kernel", ++ .offset = 0, ++ .size = 0x000e0000 + }, + { +- name: "SnapGear filesystem", +- offset: 0x00100000, ++ .name = "SnapGear filesystem", ++ .offset = 0x00100000, + }, + { +- name: "SnapGear config", +- offset: 0x000e0000, +- size: 0x00020000 ++ .name = "SnapGear config", ++ .offset = 0x000e0000, ++ .size = 0x00020000 + }, + { +- name: "SnapGear Intel", +- offset: 0 ++ .name = "SnapGear Intel", ++ .offset = 0 + }, + { +- name: "SnapGear BIOS Config", +- offset: 0x007e0000, +- size: 0x00020000 ++ .name = "SnapGear BIOS Config", ++ .offset = 0x007e0000, ++ .size = 0x00020000 + }, + { +- name: "SnapGear BIOS", +- offset: 0x007e0000, +- size: 0x00020000 ++ .name = "SnapGear BIOS", ++ .offset = 0x007e0000, ++ .size = 0x00020000 + }, + }; + #endif + + static struct map_info nettel_amd_map = { +- name: "SnapGear AMD", +- size: AMD_WINDOW_MAXSIZE, +- buswidth: AMD_BUSWIDTH, +- read8: nettel_read8, +- read16: nettel_read16, +- read32: nettel_read32, +- copy_from: nettel_copy_from, +- write8: nettel_write8, +- write16: nettel_write16, +- write32: nettel_write32, +- copy_to: nettel_copy_to ++ .name = "SnapGear AMD", ++ .size = AMD_WINDOW_MAXSIZE, ++ .buswidth = AMD_BUSWIDTH, + }; + + static struct mtd_partition nettel_amd_partitions[] = { + { +- name: "SnapGear BIOS config", +- offset: 0x000e0000, +- size: 0x00010000 ++ .name = "SnapGear BIOS config", ++ .offset = 0x000e0000, ++ .size = 0x00010000 + }, + { +- name: "SnapGear BIOS", +- offset: 0x000f0000, +- size: 0x00010000 ++ .name = "SnapGear BIOS", ++ .offset = 0x000f0000, ++ .size = 0x00010000 + }, + { +- name: "SnapGear AMD", +- offset: 0 ++ .name = "SnapGear AMD", ++ .offset = 0 + }, + { +- name: "SnapGear high BIOS", +- offset: 0x001f0000, +- size: 0x00010000 ++ .name = "SnapGear high BIOS", ++ .offset = 0x001f0000, ++ .size = 0x00010000 + } + }; + +@@ -328,18 +272,20 @@ + *amdpar = SC520_PAR(SC520_PAR_BOOTCS, amdaddr, maxsize); + __asm__ ("wbinvd"); + +- nettel_amd_map.map_priv_1 = (unsigned long) ++ nettel_amd_map.phys = amdaddr; ++ nettel_amd_map.virt = (unsigned long) + ioremap_nocache(amdaddr, maxsize); +- if (!nettel_amd_map.map_priv_1) { ++ if (!nettel_amd_map.virt) { + printk("SNAPGEAR: failed to ioremap() BOOTCS\n"); + return(-EIO); + } ++ simple_map_init(&nettel_amd_map); + + if ((amd_mtd = do_map_probe("jedec_probe", &nettel_amd_map))) { + printk(KERN_NOTICE "SNAPGEAR: AMD flash device size = %dK\n", + amd_mtd->size>>10); + +- amd_mtd->module = THIS_MODULE; ++ amd_mtd->owner = THIS_MODULE; + + /* The high BIOS partition is only present for 2MB units */ + num_amd_partitions = NUM_AMD_PARTITIONS; +@@ -387,8 +333,8 @@ + + /* Destroy useless AMD MTD mapping */ + amd_mtd = NULL; +- iounmap((void *) nettel_amd_map.map_priv_1); +- nettel_amd_map.map_priv_1 = (unsigned long) NULL; ++ iounmap((void *) nettel_amd_map.virt); ++ nettel_amd_map.virt = (unsigned long) NULL; + #else + /* Only AMD flash supported */ + return(-ENXIO); +@@ -411,16 +357,18 @@ + + /* Probe for the the size of the first Intel flash */ + nettel_intel_map.size = maxsize; +- nettel_intel_map.map_priv_1 = (unsigned long) ++ nettel_intel_map.phys = intel0addr; ++ nettel_intel_map.virt = (unsigned long) + ioremap_nocache(intel0addr, maxsize); +- if (!nettel_intel_map.map_priv_1) { ++ if (!nettel_intel_map.virt) { + printk("SNAPGEAR: failed to ioremap() ROMCS1\n"); + return(-EIO); + } ++ simple_map_init(&nettel_intel_map); + + intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map); + if (! intel_mtd) { +- iounmap((void *) nettel_intel_map.map_priv_1); ++ iounmap((void *) nettel_intel_map.virt); + return(-ENXIO); + } + +@@ -441,19 +389,19 @@ + /* Delete the old map and probe again to do both chips */ + map_destroy(intel_mtd); + intel_mtd = NULL; +- iounmap((void *) nettel_intel_map.map_priv_1); ++ iounmap((void *) nettel_intel_map.virt); + + nettel_intel_map.size = maxsize; +- nettel_intel_map.map_priv_1 = (unsigned long) ++ nettel_intel_map.virt = (unsigned long) + ioremap_nocache(intel0addr, maxsize); +- if (!nettel_intel_map.map_priv_1) { ++ if (!nettel_intel_map.virt) { + printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n"); + return(-EIO); + } + + intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map); + if (! intel_mtd) { +- iounmap((void *) nettel_intel_map.map_priv_1); ++ iounmap((void *) nettel_intel_map.virt); + return(-ENXIO); + } + +@@ -468,7 +416,7 @@ + printk(KERN_NOTICE "SNAPGEAR: Intel flash device size = %dK\n", + (intel_mtd->size >> 10)); + +- intel_mtd->module = THIS_MODULE; ++ intel_mtd->owner = THIS_MODULE; + + #ifndef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 1); +@@ -523,18 +471,18 @@ + del_mtd_partitions(amd_mtd); + map_destroy(amd_mtd); + } +- if (nettel_amd_map.map_priv_1) { +- iounmap((void *)nettel_amd_map.map_priv_1); +- nettel_amd_map.map_priv_1 = 0; ++ if (nettel_amd_map.virt) { ++ iounmap((void *)nettel_amd_map.virt); ++ nettel_amd_map.virt = 0; + } + #ifdef CONFIG_MTD_CFI_INTELEXT + if (intel_mtd) { + del_mtd_partitions(intel_mtd); + map_destroy(intel_mtd); + } +- if (nettel_intel_map.map_priv_1) { +- iounmap((void *)nettel_intel_map.map_priv_1); +- nettel_intel_map.map_priv_1 = 0; ++ if (nettel_intel_map.virt) { ++ iounmap((void *)nettel_intel_map.virt); ++ nettel_intel_map.virt = 0; + } + #endif + } +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/ocelot.c linux/drivers/mtd/maps/ocelot.c +--- linux-mips-2.4.27/drivers/mtd/maps/ocelot.c 2001-11-05 21:15:52.000000000 +0100 ++++ linux/drivers/mtd/maps/ocelot.c 2004-11-19 10:25:11.938193864 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: ocelot.c,v 1.6 2001/10/02 15:05:14 dwmw2 Exp $ ++ * $Id: ocelot.c,v 1.12 2003/05/21 12:45:19 dwmw2 Exp $ + * + * Flash on Momenco Ocelot + */ +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -20,47 +21,23 @@ + #define NVRAM_WINDOW_SIZE 0x00007FF0 + #define NVRAM_BUSWIDTH 1 + +-extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); +- + static unsigned int cacheflush = 0; + + static struct mtd_info *flash_mtd; + static struct mtd_info *nvram_mtd; + +-__u8 ocelot_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-void ocelot_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- cacheflush = 1; +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void ocelot_copy_from_cache(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- if (cacheflush) { +- dma_cache_inv(map->map_priv_2, map->size); +- cacheflush = 0; +- } +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-void ocelot_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++static void ocelot_ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) + { +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} ++ struct map_info *map = (struct map_info *)mtd->priv; ++ size_t done = 0; + +-void ocelot_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ + /* If we use memcpy, it does word-wide writes. Even though we told the + GT64120A that it's an 8-bit wide region, word-wide writes don't work. + We end up just writing the first byte of the four to all four bytes. + So we have this loop instead */ ++ *retlen = len; + while(len) { +- __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to); ++ __raw_writeb(*(unsigned char *) from, map->virt + to); + from++; + to++; + len--; +@@ -70,24 +47,21 @@ + static struct mtd_partition *parsed_parts; + + struct map_info ocelot_flash_map = { +- name: "Ocelot boot flash", +- size: FLASH_WINDOW_SIZE, +- buswidth: FLASH_BUSWIDTH, +- read8: ocelot_read8, +- copy_from: ocelot_copy_from_cache, +- write8: ocelot_write8, ++ .name = "Ocelot boot flash", ++ .size = FLASH_WINDOW_SIZE, ++ .buswidth = FLASH_BUSWIDTH, ++ .phys = FLASH_WINDOW_ADDR, + }; + + struct map_info ocelot_nvram_map = { +- name: "Ocelot NVRAM", +- size: NVRAM_WINDOW_SIZE, +- buswidth: NVRAM_BUSWIDTH, +- read8: ocelot_read8, +- copy_from: ocelot_copy_from, +- write8: ocelot_write8, +- copy_to: ocelot_copy_to ++ .name = "Ocelot NVRAM", ++ .size = NVRAM_WINDOW_SIZE, ++ .buswidth = NVRAM_BUSWIDTH, ++ .phys = NVRAM_WINDOW_ADDR, + }; + ++static const char *probes[] = { "RedBoot", NULL }; ++ + static int __init init_ocelot_maps(void) + { + void *pld; +@@ -107,12 +81,13 @@ + iounmap(pld); + + /* Now ioremap the NVRAM space */ +- ocelot_nvram_map.map_priv_1 = (unsigned long)ioremap_nocache(NVRAM_WINDOW_ADDR, NVRAM_WINDOW_SIZE); +- if (!ocelot_nvram_map.map_priv_1) { ++ ocelot_nvram_map.virt = (unsigned long)ioremap_nocache(NVRAM_WINDOW_ADDR, NVRAM_WINDOW_SIZE); ++ if (!ocelot_nvram_map.virt) { + printk(KERN_NOTICE "Failed to ioremap Ocelot NVRAM space\n"); + return -EIO; + } +- // ocelot_nvram_map.map_priv_2 = ocelot_nvram_map.map_priv_1; ++ ++ simple_map_init(&ocelot_nvram_map); + + /* And do the RAM probe on it to get an MTD device */ + nvram_mtd = do_map_probe("map_ram", &ocelot_nvram_map); +@@ -120,22 +95,21 @@ + printk("NVRAM probe failed\n"); + goto fail_1; + } +- nvram_mtd->module = THIS_MODULE; ++ nvram_mtd->owner = THIS_MODULE; + nvram_mtd->erasesize = 16; ++ /* Override the write() method */ ++ nvram_mtd->write = ocelot_ram_write; + + /* Now map the flash space */ +- ocelot_flash_map.map_priv_1 = (unsigned long)ioremap_nocache(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE); +- if (!ocelot_flash_map.map_priv_1) { ++ ocelot_flash_map.virt = (unsigned long)ioremap_nocache(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE); ++ if (!ocelot_flash_map.virt) { + printk(KERN_NOTICE "Failed to ioremap Ocelot flash space\n"); + goto fail_2; + } + /* Now the cached version */ +- ocelot_flash_map.map_priv_2 = (unsigned long)__ioremap(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE, 0); ++ ocelot_flash_map.cached = (unsigned long)__ioremap(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE, 0); + +- if (!ocelot_flash_map.map_priv_2) { +- /* Doesn't matter if it failed. Just use the uncached version */ +- ocelot_flash_map.map_priv_2 = ocelot_flash_map.map_priv_1; +- } ++ simple_map_init(&ocelot_flash_map); + + /* Only probe for flash if the write jumper is present */ + if (brd_status & 0x40) { +@@ -155,10 +129,10 @@ + + add_mtd_device(nvram_mtd); + +- flash_mtd->module = THIS_MODULE; +- nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts); ++ flash_mtd->owner = THIS_MODULE; ++ nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0); + +- if (nr_parts) ++ if (nr_parts > 0) + add_mtd_partitions(flash_mtd, parsed_parts, nr_parts); + else + add_mtd_device(flash_mtd); +@@ -166,14 +140,13 @@ + return 0; + + fail3: +- iounmap((void *)ocelot_flash_map.map_priv_1); +- if (ocelot_flash_map.map_priv_2 && +- ocelot_flash_map.map_priv_2 != ocelot_flash_map.map_priv_1) +- iounmap((void *)ocelot_flash_map.map_priv_2); ++ iounmap((void *)ocelot_flash_map.virt); ++ if (ocelot_flash_map.cached) ++ iounmap((void *)ocelot_flash_map.cached); + fail_2: + map_destroy(nvram_mtd); + fail_1: +- iounmap((void *)ocelot_nvram_map.map_priv_1); ++ iounmap((void *)ocelot_nvram_map.virt); + + return -ENXIO; + } +@@ -182,16 +155,16 @@ + { + del_mtd_device(nvram_mtd); + map_destroy(nvram_mtd); +- iounmap((void *)ocelot_nvram_map.map_priv_1); ++ iounmap((void *)ocelot_nvram_map.virt); + + if (parsed_parts) + del_mtd_partitions(flash_mtd); + else + del_mtd_device(flash_mtd); + map_destroy(flash_mtd); +- iounmap((void *)ocelot_flash_map.map_priv_1); +- if (ocelot_flash_map.map_priv_2 != ocelot_flash_map.map_priv_1) +- iounmap((void *)ocelot_flash_map.map_priv_2); ++ iounmap((void *)ocelot_flash_map.virt); ++ if (ocelot_flash_map.cached) ++ iounmap((void *)ocelot_flash_map.cached); + } + + module_init(init_ocelot_maps); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/octagon-5066.c linux/drivers/mtd/maps/octagon-5066.c +--- linux-mips-2.4.27/drivers/mtd/maps/octagon-5066.c 2003-08-13 19:19:18.000000000 +0200 ++++ linux/drivers/mtd/maps/octagon-5066.c 2004-11-19 10:25:11.940193560 +0100 +@@ -1,4 +1,4 @@ +-// $Id: octagon-5066.c,v 1.20 2003/01/07 17:21:55 dwmw2 Exp $ ++// $Id: octagon-5066.c,v 1.24 2003/05/21 15:15:07 dwmw2 Exp $ + /* ###################################################################### + + Octagon 5066 MTD Driver. +@@ -31,6 +31,7 @@ + #include + + #include ++#include + + #define WINDOW_START 0xe8000 + #define WINDOW_LENGTH 0x8000 +@@ -151,32 +152,34 @@ + + static struct map_info oct5066_map[2] = { + { +- name: "Octagon 5066 Socket", +- size: 512 * 1024, +- buswidth: 1, +- read8: oct5066_read8, +- read16: oct5066_read16, +- read32: oct5066_read32, +- copy_from: oct5066_copy_from, +- write8: oct5066_write8, +- write16: oct5066_write16, +- write32: oct5066_write32, +- copy_to: oct5066_copy_to, +- map_priv_1: 1<<6 ++ .name = "Octagon 5066 Socket", ++ .phys = NO_XIP, ++ .size = 512 * 1024, ++ .buswidth = 1, ++ .read8 = oct5066_read8, ++ .read16 = oct5066_read16, ++ .read32 = oct5066_read32, ++ .copy_from = oct5066_copy_from, ++ .write8 = oct5066_write8, ++ .write16 = oct5066_write16, ++ .write32 = oct5066_write32, ++ .copy_to = oct5066_copy_to, ++ .map_priv_1 = 1<<6 + }, + { +- name: "Octagon 5066 Internal Flash", +- size: 2 * 1024 * 1024, +- buswidth: 1, +- read8: oct5066_read8, +- read16: oct5066_read16, +- read32: oct5066_read32, +- copy_from: oct5066_copy_from, +- write8: oct5066_write8, +- write16: oct5066_write16, +- write32: oct5066_write32, +- copy_to: oct5066_copy_to, +- map_priv_1: 2<<6 ++ .name = "Octagon 5066 Internal Flash", ++ .phys = NO_XIP, ++ .size = 2 * 1024 * 1024, ++ .buswidth = 1, ++ .read8 = oct5066_read8, ++ .read16 = oct5066_read16, ++ .read32 = oct5066_read32, ++ .copy_from = oct5066_copy_from, ++ .write8 = oct5066_write8, ++ .write16 = oct5066_write16, ++ .write32 = oct5066_write32, ++ .copy_to = oct5066_copy_to, ++ .map_priv_1 = 2<<6 + } + }; + +@@ -244,6 +247,7 @@ + } + if (OctProbe() != 0) { + printk(KERN_NOTICE "5066: Octagon Probe Failed, is this an Octagon 5066 SBC?\n"); ++ iounmap((void *)iomapadr); + ret = -EAGAIN; + goto out_unmap; + } +@@ -261,7 +265,7 @@ + if (!oct5066_mtd[i]) + oct5066_mtd[i] = do_map_probe("map_rom", &oct5066_map[i]); + if (oct5066_mtd[i]) { +- oct5066_mtd[i]->module = THIS_MODULE; ++ oct5066_mtd[i]->owner = THIS_MODULE; + add_mtd_device(oct5066_mtd[i]); + } + } +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/omap-toto-flash.c linux/drivers/mtd/maps/omap-toto-flash.c +--- linux-mips-2.4.27/drivers/mtd/maps/omap-toto-flash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/maps/omap-toto-flash.c 2004-11-19 10:25:11.941193408 +0100 +@@ -0,0 +1,137 @@ ++/* ++ * NOR Flash memory access on TI Toto board ++ * ++ * jzhang@ti.com (C) 2003 Texas Instruments. ++ * ++ * (C) 2002 MontVista Software, Inc. ++ * ++ * $Id: omap-toto-flash.c,v 1.1 2003/10/21 13:55:21 dwmw2 Exp $ ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++ ++#ifndef CONFIG_ARCH_OMAP ++#error This is for OMAP architecture only ++#endif ++ ++//these lines need be moved to a hardware header file ++#define OMAP_TOTO_FLASH_BASE 0xd8000000 ++#define OMAP_TOTO_FLASH_SIZE 0x80000 ++ ++static struct map_info omap_toto_map_flash = { ++ .name = "OMAP Toto flash", ++ .buswidth = 2, ++ .virt = OMAP_TOTO_FLASH_BASE, ++}; ++ ++ ++static struct mtd_partition toto_flash_partitions[] = { ++ { ++ .name = "BootLoader", ++ .size = 0x00040000, /* hopefully u-boot will stay 128k + 128*/ ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, { ++ .name = "ReservedSpace", ++ .size = 0x00030000, ++ .offset = MTDPART_OFS_APPEND, ++ //mask_flags: MTD_WRITEABLE, /* force read-only */ ++ }, { ++ .name = "EnvArea", /* bottom 64KiB for env vars */ ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND, ++ } ++}; ++ ++static struct mtd_partition *parsed_parts; ++ ++static struct mtd_info *flash_mtd; ++ ++static int __init init_flash (void) ++{ ++ ++ struct mtd_partition *parts; ++ int nb_parts = 0; ++ int parsed_nr_parts = 0; ++ const char *part_type; ++ ++ /* ++ * Static partition definition selection ++ */ ++ part_type = "static"; ++ ++ parts = toto_flash_partitions; ++ nb_parts = ARRAY_SIZE(toto_flash_partitions); ++ omap_toto_map_flash.size = OMAP_TOTO_FLASH_SIZE; ++ omap_toto_map_flash.phys = virt_to_phys(OMAP_TOTO_FLASH_BASE); ++ ++ simple_map_init(&omap_toto_map_flash); ++ /* ++ * Now let's probe for the actual flash. Do it here since ++ * specific machine settings might have been set above. ++ */ ++ printk(KERN_NOTICE "OMAP toto flash: probing %d-bit flash bus\n", ++ omap_toto_map_flash.buswidth*8); ++ flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash); ++ if (!flash_mtd) ++ return -ENXIO; ++ ++ if (parsed_nr_parts > 0) { ++ parts = parsed_parts; ++ nb_parts = parsed_nr_parts; ++ } ++ ++ if (nb_parts == 0) { ++ printk(KERN_NOTICE "OMAP toto flash: no partition info available," ++ "registering whole flash at once\n"); ++ if (add_mtd_device(flash_mtd)){ ++ return -ENXIO; ++ } ++ } else { ++ printk(KERN_NOTICE "Using %s partition definition\n", ++ part_type); ++ return add_mtd_partitions(flash_mtd, parts, nb_parts); ++ } ++ return 0; ++} ++ ++int __init omap_toto_mtd_init(void) ++{ ++ int status; ++ ++ if (status = init_flash()) { ++ printk(KERN_ERR "OMAP Toto Flash: unable to init map for toto flash\n"); ++ } ++ return status; ++} ++ ++static void __exit omap_toto_mtd_cleanup(void) ++{ ++ if (flash_mtd) { ++ del_mtd_partitions(flash_mtd); ++ map_destroy(flash_mtd); ++ if (parsed_parts) ++ kfree(parsed_parts); ++ } ++} ++ ++module_init(omap_toto_mtd_init); ++module_exit(omap_toto_mtd_cleanup); ++ ++MODULE_AUTHOR("Jian Zhang"); ++MODULE_DESCRIPTION("OMAP Toto board map driver"); ++MODULE_LICENSE("GPL"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/pb1xxx-flash.c linux/drivers/mtd/maps/pb1xxx-flash.c +--- linux-mips-2.4.27/drivers/mtd/maps/pb1xxx-flash.c 2003-05-19 08:27:22.000000000 +0200 ++++ linux/drivers/mtd/maps/pb1xxx-flash.c 2004-11-19 10:25:11.943193104 +0100 +@@ -3,12 +3,13 @@ + * + * (C) 2001 Pete Popov + * +- * $Id: pb1xxx-flash.c,v 1.4 2002/09/13 13:51:54 dwmw2 Exp $ ++ * $Id: pb1xxx-flash.c,v 1.10 2003/08/28 06:50:24 ppopov Exp $ + */ + + #include + #include + #include ++#include + #include + + #include +@@ -25,210 +26,110 @@ + #endif + + #ifdef CONFIG_MIPS_PB1000 ++ + #define WINDOW_ADDR 0x1F800000 + #define WINDOW_SIZE 0x800000 +-#endif +- +-__u8 physmap_read8(struct map_info *map, unsigned long ofs) +-{ +- __u8 ret; +- ret = __raw_readb(map->map_priv_1 + ofs); +- DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); +- return ret; +-} +- +-__u16 physmap_read16(struct map_info *map, unsigned long ofs) +-{ +- __u16 ret; +- ret = __raw_readw(map->map_priv_1 + ofs); +- DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); +- return ret; +-} +- +-__u32 physmap_read32(struct map_info *map, unsigned long ofs) +-{ +- __u32 ret; +- ret = __raw_readl(map->map_priv_1 + ofs); +- DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret); +- return ret; +-} +- +-void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to); +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-void physmap_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void physmap_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void physmap_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d); +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from); +- memcpy_toio(map->map_priv_1 + to, from, len); +-} +- +- +- +-static struct map_info pb1xxx_map = { +- name: "Pb1xxx flash", +- read8: physmap_read8, +- read16: physmap_read16, +- read32: physmap_read32, +- copy_from: physmap_copy_from, +- write8: physmap_write8, +- write16: physmap_write16, +- write32: physmap_write32, +- copy_to: physmap_copy_to, +-}; + +- +-#ifdef CONFIG_MIPS_PB1000 +- +-static unsigned long flash_size = 0x00800000; +-static unsigned char flash_buswidth = 4; + static struct mtd_partition pb1xxx_partitions[] = { + { +- name: "yamon env", +- size: 0x00020000, +- offset: 0, +- mask_flags: MTD_WRITEABLE +- },{ +- name: "User FS", +- size: 0x003e0000, +- offset: 0x20000, +- },{ +- name: "boot code", +- size: 0x100000, +- offset: 0x400000, +- mask_flags: MTD_WRITEABLE +- },{ +- name: "raw/kernel", +- size: 0x300000, +- offset: 0x500000 +- } ++ .name = "yamon env", ++ .size = 0x00020000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE}, ++ { ++ .name = "User FS", ++ .size = 0x003e0000, ++ .offset = 0x20000,}, ++ { ++ .name = "boot code", ++ .size = 0x100000, ++ .offset = 0x400000, ++ .mask_flags = MTD_WRITEABLE}, ++ { ++ .name = "raw/kernel", ++ .size = 0x300000, ++ .offset = 0x500000} + }; + + #elif defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100) + +-static unsigned char flash_buswidth = 4; + #if defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER) +-/* both 32MiB banks will be used. Combine the first 32MiB bank and the +- * first 28MiB of the second bank together into a single jffs/jffs2 ++/* both 32MB banks will be used. Combine the first 32MB bank and the ++ * first 28MB of the second bank together into a single jffs/jffs2 + * partition. + */ +-static unsigned long flash_size = 0x04000000; + #define WINDOW_ADDR 0x1C000000 + #define WINDOW_SIZE 0x4000000 + static struct mtd_partition pb1xxx_partitions[] = { + { +- name: "User FS", +- size: 0x3c00000, +- offset: 0x0000000 +- },{ +- name: "yamon", +- size: 0x0100000, +- offset: 0x3c00000, +- mask_flags: MTD_WRITEABLE +- },{ +- name: "raw kernel", +- size: 0x02c0000, +- offset: 0x3d00000 ++ .name = "User FS", ++ .size = 0x3c00000, ++ .offset = 0x0000000 ++ },{ ++ .name = "yamon", ++ .size = 0x0100000, ++ .offset = 0x3c00000, ++ .mask_flags = MTD_WRITEABLE ++ },{ ++ .name = "raw kernel", ++ .size = 0x02c0000, ++ .offset = 0x3d00000 + } + }; + #elif defined(CONFIG_MTD_PB1500_BOOT) && !defined(CONFIG_MTD_PB1500_USER) +-static unsigned long flash_size = 0x02000000; + #define WINDOW_ADDR 0x1E000000 + #define WINDOW_SIZE 0x2000000 + static struct mtd_partition pb1xxx_partitions[] = { + { +- name: "User FS", +- size: 0x1c00000, +- offset: 0x0000000 +- },{ +- name: "yamon", +- size: 0x0100000, +- offset: 0x1c00000, +- mask_flags: MTD_WRITEABLE +- },{ +- name: "raw kernel", +- size: 0x02c0000, +- offset: 0x1d00000 ++ .name = "User FS", ++ .size = 0x1c00000, ++ .offset = 0x0000000 ++ },{ ++ .name = "yamon", ++ .size = 0x0100000, ++ .offset = 0x1c00000, ++ .mask_flags = MTD_WRITEABLE ++ },{ ++ .name = "raw kernel", ++ .size = 0x02c0000, ++ .offset = 0x1d00000 + } + }; + #elif !defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER) +-static unsigned long flash_size = 0x02000000; + #define WINDOW_ADDR 0x1C000000 + #define WINDOW_SIZE 0x2000000 + static struct mtd_partition pb1xxx_partitions[] = { + { +- name: "User FS", +- size: 0x1e00000, +- offset: 0x0000000 +- },{ +- name: "raw kernel", +- size: 0x0200000, +- offset: 0x1e00000, ++ .name = "User FS", ++ .size = 0x1e00000, ++ .offset = 0x0000000 ++ },{ ++ .name = "raw kernel", ++ .size = 0x0200000, ++ .offset = 0x1e00000, + } + }; + #else + #error MTD_PB1500 define combo error /* should never happen */ + #endif +-#elif defined(CONFIG_MTD_BOSPORUS) +-static unsigned char flash_buswidth = 2; +-static unsigned long flash_size = 0x02000000; +-#define WINDOW_ADDR 0x1F000000 +-#define WINDOW_SIZE 0x2000000 +-static struct mtd_partition pb1xxx_partitions[] = { +- { +- name: "User FS", +- size: 0x00400000, +- offset: 0x00000000, +- },{ +- name: "Yamon-2", +- size: 0x00100000, +- offset: 0x00400000, +- },{ +- name: "Root FS", +- size: 0x00700000, +- offset: 0x00500000, +- },{ +- name: "Yamon-1", +- size: 0x00100000, +- offset: 0x00C00000, +- },{ +- name: "Kernel", +- size: 0x00300000, +- offset: 0x00D00000, +- } +-}; + #else + #error Unsupported board + #endif + ++#define NAME "Pb1x00 Linux Flash" ++#define PADDR WINDOW_ADDR ++#define BUSWIDTH 4 ++#define SIZE WINDOW_SIZE ++#define PARTITIONS 4 ++ ++static struct map_info pb1xxx_mtd_map = { ++ .name = NAME, ++ .size = SIZE, ++ .buswidth = BUSWIDTH, ++ .phys = PADDR, ++}; + +-#define NB_OF(x) (sizeof(x)/sizeof(x[0])) +- +-static struct mtd_partition *parsed_parts; +-static struct mtd_info *mymtd; ++static struct mtd_info *pb1xxx_mtd; + + int __init pb1xxx_mtd_init(void) + { +@@ -236,40 +137,37 @@ + int nb_parts = 0; + char *part_type; + +- /* Default flash buswidth */ +- pb1xxx_map.buswidth = flash_buswidth; +- + /* + * Static partition definition selection + */ + part_type = "static"; + parts = pb1xxx_partitions; +- nb_parts = NB_OF(pb1xxx_partitions); +- pb1xxx_map.size = flash_size; ++ nb_parts = ARRAY_SIZE(pb1xxx_partitions); + + /* + * Now let's probe for the actual flash. Do it here since + * specific machine settings might have been set above. + */ + printk(KERN_NOTICE "Pb1xxx flash: probing %d-bit flash bus\n", +- pb1xxx_map.buswidth*8); +- pb1xxx_map.map_priv_1 = +- (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); +- mymtd = do_map_probe("cfi_probe", &pb1xxx_map); +- if (!mymtd) return -ENXIO; +- mymtd->module = THIS_MODULE; ++ BUSWIDTH*8); ++ pb1xxx_mtd_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); ++ ++ simple_map_init(&pb1xxx_mtd_map); ++ ++ pb1xxx_mtd = do_map_probe("cfi_probe", &pb1xxx_mtd_map); ++ if (!pb1xxx_mtd) return -ENXIO; ++ pb1xxx_mtd->owner = THIS_MODULE; + +- add_mtd_partitions(mymtd, parts, nb_parts); ++ add_mtd_partitions(pb1xxx_mtd, parts, nb_parts); + return 0; + } + + static void __exit pb1xxx_mtd_cleanup(void) + { +- if (mymtd) { +- del_mtd_partitions(mymtd); +- map_destroy(mymtd); +- if (parsed_parts) +- kfree(parsed_parts); ++ if (pb1xxx_mtd) { ++ del_mtd_partitions(pb1xxx_mtd); ++ map_destroy(pb1xxx_mtd); ++ iounmap((void *) pb1xxx_mtd_map.virt); + } + } + +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/pci.c linux/drivers/mtd/maps/pci.c +--- linux-mips-2.4.27/drivers/mtd/maps/pci.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/maps/pci.c 2004-11-19 10:25:11.944192952 +0100 +@@ -7,7 +7,7 @@ + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * +- * $Id: pci.c,v 1.2 2003/01/24 13:11:43 dwmw2 Exp $ ++ * $Id: pci.c,v 1.5 2003/05/20 20:59:31 dwmw2 Exp $ + * + * Generic PCI memory map driver. We support the following boards: + * - Intel IQ80310 ATU. +@@ -98,10 +98,10 @@ + } + + static struct mtd_pci_info intel_iq80310_info = { +- init: intel_iq80310_init, +- exit: intel_iq80310_exit, +- translate: intel_iq80310_translate, +- map_name: "cfi_probe", ++ .init = intel_iq80310_init, ++ .exit = intel_iq80310_exit, ++ .translate = intel_iq80310_translate, ++ .map_name = "cfi_probe", + }; + + /* +@@ -181,10 +181,10 @@ + } + + static struct mtd_pci_info intel_dc21285_info = { +- init: intel_dc21285_init, +- exit: intel_dc21285_exit, +- translate: intel_dc21285_translate, +- map_name: "jedec_probe", ++ .init = intel_dc21285_init, ++ .exit = intel_dc21285_exit, ++ .translate = intel_dc21285_translate, ++ .map_name = "jedec_probe", + }; + + /* +@@ -193,22 +193,20 @@ + + static struct pci_device_id mtd_pci_ids[] __devinitdata = { + { +- vendor: PCI_VENDOR_ID_INTEL, +- device: 0x530d, +- subvendor: PCI_ANY_ID, +- subdevice: PCI_ANY_ID, +- class: PCI_CLASS_MEMORY_OTHER << 8, +- class_mask: 0xffff00, +- driver_data: (unsigned long)&intel_iq80310_info, ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = 0x530d, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .class = PCI_CLASS_MEMORY_OTHER << 8, ++ .class_mask = 0xffff00, ++ .driver_data = (unsigned long)&intel_iq80310_info, + }, + { +- vendor: PCI_VENDOR_ID_DEC, +- device: PCI_DEVICE_ID_DEC_21285, +- subvendor: 0, /* DC21285 defaults to 0 on reset */ +- subdevice: 0, /* DC21285 defaults to 0 on reset */ +- class: 0, +- class_mask: 0, +- driver_data: (unsigned long)&intel_dc21285_info, ++ .vendor = PCI_VENDOR_ID_DEC, ++ .device = PCI_DEVICE_ID_DEC_21285, ++ .subvendor = 0, /* DC21285 defaults to 0 on reset */ ++ .subdevice = 0, /* DC21285 defaults to 0 on reset */ ++ .driver_data = (unsigned long)&intel_dc21285_info, + }, + { 0, } + }; +@@ -275,14 +273,15 @@ + } + + static struct map_info mtd_pci_map = { +- read8: mtd_pci_read8, +- read16: mtd_pci_read16, +- read32: mtd_pci_read32, +- copy_from: mtd_pci_copyfrom, +- write8: mtd_pci_write8, +- write16: mtd_pci_write16, +- write32: mtd_pci_write32, +- copy_to: mtd_pci_copyto, ++ .phys = NO_XIP, ++ .read8 = mtd_pci_read8, ++ .read16 = mtd_pci_read16, ++ .read32 = mtd_pci_read32, ++ .copy_from = mtd_pci_copyfrom, ++ .write8 = mtd_pci_write8, ++ .write16 = mtd_pci_write16, ++ .write32 = mtd_pci_write32, ++ .copy_to = mtd_pci_copyto, + }; + + static int __devinit +@@ -322,7 +321,7 @@ + if (!mtd) + goto release; + +- mtd->module = THIS_MODULE; ++ mtd->owner = THIS_MODULE; + add_mtd_device(mtd); + + pci_set_drvdata(dev, mtd); +@@ -359,10 +358,10 @@ + } + + static struct pci_driver mtd_pci_driver = { +- name: "MTD PCI", +- probe: mtd_pci_probe, +- remove: __devexit_p(mtd_pci_remove), +- id_table: mtd_pci_ids, ++ .name = "MTD PCI", ++ .probe = mtd_pci_probe, ++ .remove = __devexit_p(mtd_pci_remove), ++ .id_table = mtd_pci_ids, + }; + + static int __init mtd_pci_maps_init(void) +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/pcmciamtd.c linux/drivers/mtd/maps/pcmciamtd.c +--- linux-mips-2.4.27/drivers/mtd/maps/pcmciamtd.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/maps/pcmciamtd.c 2004-11-19 10:25:11.946192648 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: pcmciamtd.c,v 1.39 2003/01/06 17:51:38 spse Exp $ ++ * $Id: pcmciamtd.c,v 1.48 2003/06/24 07:14:38 spse Exp $ + * + * pcmciamtd.c - MTD driver for PCMCIA flash memory cards + * +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -24,6 +25,7 @@ + #include + + #include ++#include + + #ifdef CONFIG_MTD_DEBUG + static int debug = CONFIG_MTD_DEBUG_VERBOSE; +@@ -47,7 +49,7 @@ + + + #define DRIVER_DESC "PCMCIA Flash memory card driver" +-#define DRIVER_VERSION "$Revision: 1.39 $" ++#define DRIVER_VERSION "$Revision: 1.48 $" + + /* Size of the PCMCIA address space: 26 bits = 64 MB */ + #define MAX_PCMCIA_ADDR 0x4000000 +@@ -96,7 +98,7 @@ + MODULE_PARM(mem_speed, "i"); + MODULE_PARM_DESC(mem_speed, "Set memory access speed in ns"); + MODULE_PARM(force_size, "i"); +-MODULE_PARM_DESC(force_size, "Force size of card in MB (1-64)"); ++MODULE_PARM_DESC(force_size, "Force size of card in MiB (1-64)"); + MODULE_PARM(setvpp, "i"); + MODULE_PARM_DESC(setvpp, "Set Vpp (0=Never, 1=On writes, 2=Always on, default=0)"); + MODULE_PARM(vpp, "i"); +@@ -106,11 +108,13 @@ + + + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69) + static inline void cs_error(client_handle_t handle, int func, int ret) + { + error_info_t err = { func, ret }; + CardServices(ReportError, handle, &err); + } ++#endif + + + /* read/write{8,16} copy_{from,to} routines with window remapping to access whole card */ +@@ -529,6 +533,7 @@ + + card_settings(dev, link, &new_name); + ++ dev->pcmcia_map.phys = NO_XIP; + dev->pcmcia_map.read8 = pcmcia_read8_remap; + dev->pcmcia_map.read16 = pcmcia_read16_remap; + dev->pcmcia_map.copy_from = pcmcia_copy_from_remap; +@@ -539,7 +544,7 @@ + dev->pcmcia_map.set_vpp = pcmciamtd_set_vpp; + + /* Request a memory window for PCMCIA. Some architeures can map windows upto the maximum +- that PCMCIA can support (64Mb) - this is ideal and we aim for a window the size of the ++ that PCMCIA can support (64MiB) - this is ideal and we aim for a window the size of the + whole card - otherwise we try smaller windows until we succeed */ + + req.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE; +@@ -552,7 +557,7 @@ + + do { + int ret; +- DEBUG(2, "requesting window with size = %dKB memspeed = %d", ++ DEBUG(2, "requesting window with size = %dKiB memspeed = %d", + req.Size >> 10, req.AccessSpeed); + link->win = (window_handle_t)link->handle; + ret = CardServices(RequestWindow, &link->win, &req); +@@ -560,7 +565,7 @@ + if(ret) { + req.Size >>= 1; + } else { +- DEBUG(2, "Got window of size %dKB", req.Size >> 10); ++ DEBUG(2, "Got window of size %dKiB", req.Size >> 10); + dev->win_size = req.Size; + break; + } +@@ -573,7 +578,7 @@ + pcmciamtd_release((u_long)link); + return; + } +- DEBUG(1, "Allocated a window of %dKB", dev->win_size >> 10); ++ DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); + + /* Get write protect status */ + CS_CHECK(GetStatus, link->handle, &status); +@@ -642,21 +647,21 @@ + } + + dev->mtd_info = mtd; +- mtd->module = THIS_MODULE; ++ mtd->owner = THIS_MODULE; + + if(new_name) { + int size = 0; + char unit = ' '; + /* Since we are using a default name, make it better by adding in the + size */ +- if(mtd->size < 1048576) { /* <1MB in size, show size in K */ ++ if(mtd->size < 1048576) { /* <1MiB in size, show size in KiB */ + size = mtd->size >> 10; + unit = 'K'; + } else { + size = mtd->size >> 20; + unit = 'M'; + } +- snprintf(dev->mtd_name, sizeof(dev->mtd_name), "%d%cB %s", size, unit, "PCMCIA Memory card"); ++ snprintf(dev->mtd_name, sizeof(dev->mtd_name), "%d%ciB %s", size, unit, "PCMCIA Memory card"); + } + + /* If the memory found is fits completely into the mapped PCMCIA window, +@@ -828,16 +833,20 @@ + } + + ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,68) ++static struct pcmcia_driver pcmciamtd_driver = { ++ .drv = { ++ .name = "pcmciamtd" ++ }, ++ .attach = pcmciamtd_attach, ++ .detach = pcmciamtd_detach, ++ .owner = THIS_MODULE ++}; ++#endif ++ ++ + static int __init init_pcmciamtd(void) + { +- servinfo_t serv; +- +- info(DRIVER_DESC " " DRIVER_VERSION); +- CardServices(GetCardServicesInfo, &serv); +- if (serv.Revision != CS_RELEASE_CODE) { +- err("Card Services release does not match!"); +- return -1; +- } + + if(buswidth && buswidth != 1 && buswidth != 2) { + info("bad buswidth (%d), using default", buswidth); +@@ -851,15 +860,24 @@ + info("bad mem_type (%d), using default", mem_type); + mem_type = 0; + } ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,68) ++ return pcmcia_register_driver(&pcmciamtd_driver); ++#else + register_pccard_driver(&dev_info, &pcmciamtd_attach, &pcmciamtd_detach); + return 0; ++#endif + } + + + static void __exit exit_pcmciamtd(void) + { + DEBUG(1, DRIVER_DESC " unloading"); ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,68) ++ pcmcia_unregister_driver(&pcmciamtd_driver); ++#else + unregister_pccard_driver(&dev_info); ++#endif + + while(dev_list) { + dev_link_t *link = dev_list; +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/physmap.c linux/drivers/mtd/maps/physmap.c +--- linux-mips-2.4.27/drivers/mtd/maps/physmap.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/maps/physmap.c 2004-11-19 10:25:11.947192496 +0100 +@@ -1,179 +1,114 @@ + /* +- * $Id: physmap.c,v 1.21 2002/09/05 05:12:54 acurtis Exp $ ++ * $Id: physmap.c,v 1.30 2003/11/11 19:05:18 jsun Exp $ + * + * Normal mappings of chips in physical memory ++ * ++ * Copyright (C) 2003 MontaVista Software Inc. ++ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net ++ * ++ * 031022 - [jsun] add run-time configure and partition setup + */ + + #include + #include + #include ++#include ++#include + #include + #include + #include + #include +- +-#ifdef CONFIG_MTD_PARTITIONS + #include +-#endif +- +-#define WINDOW_ADDR CONFIG_MTD_PHYSMAP_START +-#define WINDOW_SIZE CONFIG_MTD_PHYSMAP_LEN +-#define BUSWIDTH CONFIG_MTD_PHYSMAP_BUSWIDTH + + static struct mtd_info *mymtd; + +-__u8 physmap_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-__u16 physmap_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} +- +-__u32 physmap_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} +- +-void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} ++struct map_info physmap_map = {.name = "phys_mapped_flash"}; + +-void physmap_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} ++#ifdef CONFIG_MTD_PARTITIONS ++static struct mtd_partition *mtd_parts; ++static int mtd_parts_nb; + +-void physmap_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} ++static int num_physmap_partitions; ++static struct mtd_partition *physmap_partitions; + +-void physmap_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} ++char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL}; + +-void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) ++void physmap_set_partitions(struct mtd_partition *parts, int num_parts) + { +- memcpy_toio(map->map_priv_1 + to, from, len); ++ physmap_partitions=parts; ++ num_physmap_partitions=num_parts; + } +- +-struct map_info physmap_map = { +- name: "Physically mapped flash", +- size: WINDOW_SIZE, +- buswidth: BUSWIDTH, +- read8: physmap_read8, +- read16: physmap_read16, +- read32: physmap_read32, +- copy_from: physmap_copy_from, +- write8: physmap_write8, +- write16: physmap_write16, +- write32: physmap_write32, +- copy_to: physmap_copy_to +-}; +- +-#ifdef CONFIG_MTD_PARTITIONS +-#ifdef CONFIG_MTD_CMDLINE_PARTS +-static struct mtd_partition *mtd_parts = 0; +-static int mtd_parts_nb = 0; +-#else +-static struct mtd_partition physmap_partitions[] = { +-/* Put your own partition definitions here */ +-#if 0 +- { +- name: "bootROM", +- size: 0x80000, +- offset: 0, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "zImage", +- size: 0x100000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "ramdisk.gz", +- size: 0x300000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "User FS", +- size: MTDPART_SIZ_FULL, +- offset: MTDPART_OFS_APPEND, +- } +-#endif +-}; +- +-#define NUM_PARTITIONS (sizeof(physmap_partitions)/sizeof(struct mtd_partition)) +- +-#endif +-#endif ++#endif /* CONFIG_MTD_PARTITIONS */ + + int __init init_physmap(void) + { + static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", 0 }; + const char **type; + +- printk(KERN_NOTICE "physmap flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR); +- physmap_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); ++ printk(KERN_NOTICE "physmap flash device: %lx at %lx\n", physmap_map.size, physmap_map.phys); ++ physmap_map.virt = (unsigned long)ioremap(physmap_map.phys, physmap_map.size); + +- if (!physmap_map.map_priv_1) { ++ if (!physmap_map.virt) { + printk("Failed to ioremap\n"); + return -EIO; + } + ++ simple_map_init(&physmap_map); ++ + mymtd = 0; + type = rom_probe_types; + for(; !mymtd && *type; type++) { + mymtd = do_map_probe(*type, &physmap_map); + } + if (mymtd) { +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + +- add_mtd_device(mymtd); + #ifdef CONFIG_MTD_PARTITIONS +-#ifdef CONFIG_MTD_CMDLINE_PARTS +- mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, +- "phys"); ++ mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes, ++ &mtd_parts, 0); ++ + if (mtd_parts_nb > 0) + { +- printk(KERN_NOTICE +- "Using command line partition definition\n"); + add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb); ++ return 0; + } +-#else +- if (NUM_PARTITIONS != 0) ++ ++ if (num_physmap_partitions != 0) + { + printk(KERN_NOTICE + "Using physmap partition definition\n"); +- add_mtd_partitions (mymtd, physmap_partitions, NUM_PARTITIONS); ++ add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions); ++ return 0; + } + + #endif +-#endif ++ add_mtd_device(mymtd); ++ + return 0; + } + +- iounmap((void *)physmap_map.map_priv_1); ++ iounmap((void *)physmap_map.virt); + return -ENXIO; + } + + static void __exit cleanup_physmap(void) + { +- if (mymtd) { ++#ifdef CONFIG_MTD_PARTITIONS ++ if (mtd_parts_nb) { ++ del_mtd_partitions(mymtd); ++ kfree(mtd_parts); ++ } else if (num_physmap_partitions) { ++ del_mtd_partitions(mymtd); ++ } else { + del_mtd_device(mymtd); +- map_destroy(mymtd); +- } +- if (physmap_map.map_priv_1) { +- iounmap((void *)physmap_map.map_priv_1); +- physmap_map.map_priv_1 = 0; + } ++#else ++ del_mtd_device(mymtd); ++#endif ++ map_destroy(mymtd); ++ ++ iounmap((void *)physmap_map.virt); ++ physmap_map.virt = 0; + } + + module_init(init_physmap); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/pnc2000.c linux/drivers/mtd/maps/pnc2000.c +--- linux-mips-2.4.27/drivers/mtd/maps/pnc2000.c 2001-11-05 21:15:52.000000000 +0100 ++++ linux/drivers/mtd/maps/pnc2000.c 2004-11-19 10:25:11.949192192 +0100 +@@ -5,12 +5,13 @@ + * + * This code is GPL + * +- * $Id: pnc2000.c,v 1.10 2001/10/02 15:05:14 dwmw2 Exp $ ++ * $Id: pnc2000.c,v 1.14 2003/05/21 12:45:19 dwmw2 Exp $ + */ + + #include + #include + #include ++#include + + #include + #include +@@ -24,58 +25,13 @@ + * MAP DRIVER STUFF + */ + +-__u8 pnc_read8(struct map_info *map, unsigned long ofs) +-{ +- return *(__u8 *)(WINDOW_ADDR + ofs); +-} +- +-__u16 pnc_read16(struct map_info *map, unsigned long ofs) +-{ +- return *(__u16 *)(WINDOW_ADDR + ofs); +-} +- +-__u32 pnc_read32(struct map_info *map, unsigned long ofs) +-{ +- return *(volatile unsigned int *)(WINDOW_ADDR + ofs); +-} +- +-void pnc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy(to, (void *)(WINDOW_ADDR + from), len); +-} +- +-void pnc_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- *(__u8 *)(WINDOW_ADDR + adr) = d; +-} +- +-void pnc_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- *(__u16 *)(WINDOW_ADDR + adr) = d; +-} +- +-void pnc_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- *(__u32 *)(WINDOW_ADDR + adr) = d; +-} +- +-void pnc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy((void *)(WINDOW_ADDR + to), from, len); +-} + + struct map_info pnc_map = { +- name: "PNC-2000", +- size: WINDOW_SIZE, +- buswidth: 4, +- read8: pnc_read8, +- read16: pnc_read16, +- read32: pnc_read32, +- copy_from: pnc_copy_from, +- write8: pnc_write8, +- write16: pnc_write16, +- write32: pnc_write32, +- copy_to: pnc_copy_to ++ .name = "PNC-2000", ++ .size = WINDOW_SIZE, ++ .buswidth = 4, ++ .phys = 0xFFFFFFFF, ++ .virt = WINDOW_ADDR, + }; + + +@@ -84,19 +40,19 @@ + */ + static struct mtd_partition pnc_partitions[3] = { + { +- name: "PNC-2000 boot firmware", +- size: 0x20000, +- offset: 0 ++ .name = "PNC-2000 boot firmware", ++ .size = 0x20000, ++ .offset = 0 + }, + { +- name: "PNC-2000 kernel", +- size: 0x1a0000, +- offset: 0x20000 ++ .name = "PNC-2000 kernel", ++ .size = 0x1a0000, ++ .offset = 0x20000 + }, + { +- name: "PNC-2000 filesystem", +- size: 0x240000, +- offset: 0x1c0000 ++ .name = "PNC-2000 filesystem", ++ .size = 0x240000, ++ .offset = 0x1c0000 + } + }; + +@@ -110,9 +66,11 @@ + { + printk(KERN_NOTICE "Photron PNC-2000 flash mapping: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR); + ++ simple_map_init(&pnc_map); ++ + mymtd = do_map_probe("cfi_probe", &pnc_map); + if (mymtd) { +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + return add_mtd_partitions(mymtd, pnc_partitions, 3); + } + +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/redwood.c linux/drivers/mtd/maps/redwood.c +--- linux-mips-2.4.27/drivers/mtd/maps/redwood.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/maps/redwood.c 2004-11-19 10:25:11.962190216 +0100 +@@ -1,38 +1,23 @@ + /* +- * $Id: ++ * $Id: redwood.c,v 1.7 2003/11/21 23:09:52 trini Exp $ + * +- * redwood.c - mapper for IBM Redwood-4/5 board. ++ * drivers/mtd/maps/redwood.c + * +- * Copyright 2001 MontaVista Softare Inc. ++ * FLASH map for the IBM Redwood 4/5/6 boards. + * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- * +- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN +- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- * +- * You should have received a copy of the GNU General Public License along +- * with this program; if not, write to the Free Software Foundation, Inc., +- * 675 Mass Ave, Cambridge, MA 02139, USA. +- * +- * History: 12/17/2001 - Armin +- * migrated to use do_map_probe ++ * Author: MontaVista Software, Inc. + * ++ * 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under ++ * the terms of the GNU General Public License version 2. This program ++ * is licensed "as is" without any warranty of any kind, whether express ++ * or implied. + */ + ++#include + #include + #include + #include ++#include + + #include + #include +@@ -40,96 +25,102 @@ + + #include + ++#if !defined (CONFIG_REDWOOD_6) ++ + #define WINDOW_ADDR 0xffc00000 + #define WINDOW_SIZE 0x00400000 + +-__u8 redwood_flash_read8(struct map_info *map, unsigned long ofs) +-{ +- return *(__u8 *)(map->map_priv_1 + ofs); +-} +- +-__u16 redwood_flash_read16(struct map_info *map, unsigned long ofs) +-{ +- return *(__u16 *)(map->map_priv_1 + ofs); +-} +- +-__u32 redwood_flash_read32(struct map_info *map, unsigned long ofs) +-{ +- return *(volatile unsigned int *)(map->map_priv_1 + ofs); +-} +- +-void redwood_flash_copy_from(struct map_info *map, void *to, +- unsigned long from, ssize_t len) +-{ +- memcpy(to, (void *)(map->map_priv_1 + from), len); +-} +- +-void redwood_flash_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- *(__u8 *)(map->map_priv_1 + adr) = d; +-} +- +-void redwood_flash_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- *(__u16 *)(map->map_priv_1 + adr) = d; +-} +- +-void redwood_flash_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- *(__u32 *)(map->map_priv_1 + adr) = d; +-} +- +-void redwood_flash_copy_to(struct map_info *map, unsigned long to, +- const void *from, ssize_t len) +-{ +- memcpy((void *)(map->map_priv_1 + to), from, len); +-} ++#define RW_PART0_OF 0 ++#define RW_PART0_SZ 0x10000 ++#define RW_PART1_OF RW_PART0_SZ ++#define RW_PART1_SZ 0x200000 - 0x10000 ++#define RW_PART2_OF 0x200000 ++#define RW_PART2_SZ 0x10000 ++#define RW_PART3_OF 0x210000 ++#define RW_PART3_SZ 0x200000 - (0x10000 + 0x20000) ++#define RW_PART4_OF 0x3e0000 ++#define RW_PART4_SZ 0x20000 + +-struct map_info redwood_flash_map = { +- name: "IBM Redwood", +- size: WINDOW_SIZE, +- buswidth: 2, +- read8: redwood_flash_read8, +- read16: redwood_flash_read16, +- read32: redwood_flash_read32, +- copy_from: redwood_flash_copy_from, +- write8: redwood_flash_write8, +- write16: redwood_flash_write16, +- write32: redwood_flash_write32, +- copy_to: redwood_flash_copy_to ++static struct mtd_partition redwood_flash_partitions[] = { ++ { ++ .name = "Redwood OpenBIOS Vital Product Data", ++ .offset = RW_PART0_OF, ++ .size = RW_PART0_SZ, ++ .mask_flags = MTD_WRITEABLE /* force read-only */ ++ }, ++ { ++ .name = "Redwood kernel", ++ .offset = RW_PART1_OF, ++ .size = RW_PART1_SZ ++ }, ++ { ++ .name = "Redwood OpenBIOS non-volatile storage", ++ .offset = RW_PART2_OF, ++ .size = RW_PART2_SZ, ++ .mask_flags = MTD_WRITEABLE /* force read-only */ ++ }, ++ { ++ .name = "Redwood filesystem", ++ .offset = RW_PART3_OF, ++ .size = RW_PART3_SZ ++ }, ++ { ++ .name = "Redwood OpenBIOS", ++ .offset = RW_PART4_OF, ++ .size = RW_PART4_SZ, ++ .mask_flags = MTD_WRITEABLE /* force read-only */ ++ } + }; + ++#else /* CONFIG_REDWOOD_6 */ ++/* FIXME: the window is bigger - armin */ ++#define WINDOW_ADDR 0xff800000 ++#define WINDOW_SIZE 0x00800000 ++ ++#define RW_PART0_OF 0 ++#define RW_PART0_SZ 0x400000 /* 4 MiB data */ ++#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ ++#define RW_PART1_SZ 0x10000 /* 64K VPD */ ++#define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ ++#define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000) ++#define RW_PART3_OF RW_PART2_OF + RW_PART2_SZ ++#define RW_PART3_SZ 0x20000 + + static struct mtd_partition redwood_flash_partitions[] = { + { +- name: "Redwood OpenBIOS Vital Product Data", +- offset: 0, +- size: 0x10000, +- mask_flags: MTD_WRITEABLE /* force read-only */ ++ .name = "Redwood filesystem", ++ .offset = RW_PART0_OF, ++ .size = RW_PART0_SZ + }, + { +- name: "Redwood kernel", +- offset: 0x10000, +- size: 0x200000 - 0x10000 ++ .name = "Redwood OpenBIOS Vital Product Data", ++ .offset = RW_PART1_OF, ++ .size = RW_PART1_SZ, ++ .mask_flags = MTD_WRITEABLE /* force read-only */ + }, + { +- name: "Redwood OpenBIOS non-volatile storage", +- offset: 0x200000, +- size: 0x10000, +- mask_flags: MTD_WRITEABLE /* force read-only */ ++ .name = "Redwood kernel", ++ .offset = RW_PART2_OF, ++ .size = RW_PART2_SZ + }, + { +- name: "Redwood filesystem", +- offset: 0x210000, +- size: 0x200000 - (0x10000 + 0x20000) +- }, +- { +- name: "Redwood OpenBIOS", +- offset: 0x3e0000, +- size: 0x20000, +- mask_flags: MTD_WRITEABLE /* force read-only */ ++ .name = "Redwood OpenBIOS", ++ .offset = RW_PART3_OF, ++ .size = RW_PART3_SZ, ++ .mask_flags = MTD_WRITEABLE /* force read-only */ + } + }; ++ ++#endif /* CONFIG_REDWOOD_6 */ ++ ++struct map_info redwood_flash_map = { ++ .name = "IBM Redwood", ++ .size = WINDOW_SIZE, ++ .buswidth = 2, ++ .phys = WINDOW_ADDR, ++}; ++ ++ + #define NUM_REDWOOD_FLASH_PARTITIONS \ + (sizeof(redwood_flash_partitions)/sizeof(redwood_flash_partitions[0])) + +@@ -140,18 +131,19 @@ + printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n", + WINDOW_SIZE, WINDOW_ADDR); + +- redwood_flash_map.map_priv_1 = ++ redwood_flash_map.virt = + (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); + +- if (!redwood_flash_map.map_priv_1) { ++ if (!redwood_flash_map.virt) { + printk("init_redwood_flash: failed to ioremap\n"); + return -EIO; + } ++ simple_map_init(&redwood_flash_map); + + redwood_mtd = do_map_probe("cfi_probe",&redwood_flash_map); + + if (redwood_mtd) { +- redwood_mtd->module = THIS_MODULE; ++ redwood_mtd->owner = THIS_MODULE; + return add_mtd_partitions(redwood_mtd, + redwood_flash_partitions, + NUM_REDWOOD_FLASH_PARTITIONS); +@@ -164,10 +156,15 @@ + { + if (redwood_mtd) { + del_mtd_partitions(redwood_mtd); +- iounmap((void *)redwood_flash_map.map_priv_1); ++ /* moved iounmap after map_destroy - armin */ + map_destroy(redwood_mtd); ++ iounmap((void *)redwood_flash_map.virt); + } + } + + module_init(init_redwood_flash); + module_exit(cleanup_redwood_flash); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("MontaVista Software "); ++MODULE_DESCRIPTION("MTD map driver for the IBM Redwood reference boards"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/rpxlite.c linux/drivers/mtd/maps/rpxlite.c +--- linux-mips-2.4.27/drivers/mtd/maps/rpxlite.c 2001-11-05 21:15:52.000000000 +0100 ++++ linux/drivers/mtd/maps/rpxlite.c 2004-11-19 10:25:11.963190064 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp $ ++ * $Id: rpxlite.c,v 1.19 2003/05/21 12:45:19 dwmw2 Exp $ + * + * Handle mapping of the flash on the RPX Lite and CLLF boards + */ +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -17,80 +18,31 @@ + + static struct mtd_info *mymtd; + +-__u8 rpxlite_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-__u16 rpxlite_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} +- +-__u32 rpxlite_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} +- +-void rpxlite_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len); +-} +- +-void rpxlite_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void rpxlite_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void rpxlite_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void rpxlite_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio((void *)(map->map_priv_1 + to), from, len); +-} +- +-struct map_info rpxlite_map = { +- name: "RPX", +- size: WINDOW_SIZE, +- buswidth: 4, +- read8: rpxlite_read8, +- read16: rpxlite_read16, +- read32: rpxlite_read32, +- copy_from: rpxlite_copy_from, +- write8: rpxlite_write8, +- write16: rpxlite_write16, +- write32: rpxlite_write32, +- copy_to: rpxlite_copy_to ++static struct map_info rpxlite_map = { ++ .name = "RPX", ++ .size = WINDOW_SIZE, ++ .buswidth = 4, ++ .phys = WINDOW_ADDR, + }; + + int __init init_rpxlite(void) + { + printk(KERN_NOTICE "RPX Lite or CLLF flash device: %x at %x\n", WINDOW_SIZE*4, WINDOW_ADDR); +- rpxlite_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4); ++ rpxlite_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4); + +- if (!rpxlite_map.map_priv_1) { ++ if (!rpxlite_map.virt) { + printk("Failed to ioremap\n"); + return -EIO; + } ++ simple_map_init(&rpxlite_map); + mymtd = do_map_probe("cfi_probe", &rpxlite_map); + if (mymtd) { +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + add_mtd_device(mymtd); + return 0; + } + +- iounmap((void *)rpxlite_map.map_priv_1); ++ iounmap((void *)rpxlite_map.virt); + return -ENXIO; + } + +@@ -100,9 +52,9 @@ + del_mtd_device(mymtd); + map_destroy(mymtd); + } +- if (rpxlite_map.map_priv_1) { +- iounmap((void *)rpxlite_map.map_priv_1); +- rpxlite_map.map_priv_1 = 0; ++ if (rpxlite_map.virt) { ++ iounmap((void *)rpxlite_map.virt); ++ rpxlite_map.virt = 0; + } + } + +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/sa1100-flash.c linux/drivers/mtd/maps/sa1100-flash.c +--- linux-mips-2.4.27/drivers/mtd/maps/sa1100-flash.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/maps/sa1100-flash.c 2004-11-19 10:25:11.966189608 +0100 +@@ -3,7 +3,7 @@ + * + * (C) 2000 Nicolas Pitre + * +- * $Id: sa1100-flash.c,v 1.29 2002/09/06 14:36:19 abz Exp $ ++ * $Id: sa1100-flash.c,v 1.38 2004/01/22 19:11:08 rmk Exp $ + */ + + #include +@@ -11,278 +11,212 @@ + #include + #include + #include ++#include ++#include ++#include + + #include + #include + #include ++#include + + #include ++#include + #include ++#include + ++#include + + #ifndef CONFIG_ARCH_SA1100 + #error This is for SA1100 architecture only + #endif + ++/* ++ * This isnt complete yet, so... ++ */ ++#define CONFIG_MTD_SA1100_STATICMAP 1 + +-#define WINDOW_ADDR 0xe8000000 +- +-static __u8 sa1100_read8(struct map_info *map, unsigned long ofs) +-{ +- return readb(map->map_priv_1 + ofs); +-} +- +-static __u16 sa1100_read16(struct map_info *map, unsigned long ofs) +-{ +- return readw(map->map_priv_1 + ofs); +-} +- +-static __u32 sa1100_read32(struct map_info *map, unsigned long ofs) +-{ +- return readl(map->map_priv_1 + ofs); +-} +- +-static void sa1100_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy(to, (void *)(map->map_priv_1 + from), len); +-} +- +-static void sa1100_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- writeb(d, map->map_priv_1 + adr); +-} +- +-static void sa1100_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- writew(d, map->map_priv_1 + adr); +-} +- +-static void sa1100_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- writel(d, map->map_priv_1 + adr); +-} +- +-static void sa1100_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy((void *)(map->map_priv_1 + to), from, len); +-} +- +-static struct map_info sa1100_map = { +- name: "SA1100 flash", +- read8: sa1100_read8, +- read16: sa1100_read16, +- read32: sa1100_read32, +- copy_from: sa1100_copy_from, +- write8: sa1100_write8, +- write16: sa1100_write16, +- write32: sa1100_write32, +- copy_to: sa1100_copy_to, +- +- map_priv_1: WINDOW_ADDR, +- map_priv_2: -1, +-}; +- +- ++#ifdef CONFIG_MTD_SA1100_STATICMAP + /* + * Here are partition information for all known SA1100-based devices. + * See include/linux/mtd/partitions.h for definition of the mtd_partition + * structure. + * +- * The *_max_flash_size is the maximum possible mapped flash size which +- * is not necessarily the actual flash size. It must be no more than +- * the value specified in the "struct map_desc *_io_desc" mapping +- * definition for the corresponding machine. ++ * Please note: ++ * 1. We no longer support static flash mappings via the machine io_desc ++ * structure. ++ * 2. The flash size given should be the largest flash size that can ++ * be accommodated. ++ * ++ * The MTD layer will detect flash chip aliasing and reduce the size of ++ * the map accordingly. + * + * Please keep these in alphabetical order, and formatted as per existing + * entries. Thanks. + */ + + #ifdef CONFIG_SA1100_ADSBITSY +-#define ADSBITSY_FLASH_SIZE 0x02000000 + static struct mtd_partition adsbitsy_partitions[] = { + { +- name: "bootROM", +- size: 0x80000, +- offset: 0, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "zImage", +- size: 0x100000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "ramdisk.gz", +- size: 0x300000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "User FS", +- size: MTDPART_SIZ_FULL, +- offset: MTDPART_OFS_APPEND, ++ .name = "bootROM", ++ .size = 0x80000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, { ++ .name = "zImage", ++ .size = 0x100000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, { ++ .name = "ramdisk.gz", ++ .size = 0x300000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, { ++ .name = "User FS", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND, + } + }; + #endif + + #ifdef CONFIG_SA1100_ASSABET + /* Phase 4 Assabet has two 28F160B3 flash parts in bank 0: */ +-#define ASSABET4_FLASH_SIZE 0x00400000 + static struct mtd_partition assabet4_partitions[] = { + { +- name: "bootloader", +- size: 0x00020000, +- offset: 0, +- mask_flags: MTD_WRITEABLE, +- }, { +- name: "bootloader params", +- size: 0x00020000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, +- }, { +- name: "jffs", +- size: MTDPART_SIZ_FULL, +- offset: MTDPART_OFS_APPEND, ++ .name = "bootloader", ++ .size = 0x00020000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "bootloader params", ++ .size = 0x00020000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "jffs", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND, + } + }; + + /* Phase 5 Assabet has two 28F128J3A flash parts in bank 0: */ +-#define ASSABET5_FLASH_SIZE 0x02000000 + static struct mtd_partition assabet5_partitions[] = { + { +- name: "bootloader", +- size: 0x00040000, +- offset: 0, +- mask_flags: MTD_WRITEABLE, +- }, { +- name: "bootloader params", +- size: 0x00040000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, +- }, { +- name: "jffs", +- size: MTDPART_SIZ_FULL, +- offset: MTDPART_OFS_APPEND, ++ .name = "bootloader", ++ .size = 0x00040000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "bootloader params", ++ .size = 0x00040000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "jffs", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND, + } + }; + +-#define ASSABET_FLASH_SIZE ASSABET5_FLASH_SIZE + #define assabet_partitions assabet5_partitions + #endif + + #ifdef CONFIG_SA1100_BADGE4 +- + /* +- * 1 x Intel 28F320C3BA100 Advanced+ Boot Block Flash (32 Mi bit) ++ * 1 x Intel 28F320C3 Advanced+ Boot Block Flash (32 Mi bit) + * Eight 4 KiW Parameter Bottom Blocks (64 KiB) + * Sixty-three 32 KiW Main Blocks (4032 Ki b) ++ * ++ * ++ * ++ * 1 x Intel 28F640C3 Advanced+ Boot Block Flash (64 Mi bit) ++ * Eight 4 KiW Parameter Bottom Blocks (64 KiB) ++ * One-hundred-twenty-seven 32 KiW Main Blocks (8128 Ki b) + */ +-#define BADGE4_FLASH_SIZE 0x00400000 + static struct mtd_partition badge4_partitions[] = { + { +- name: "BLOB boot loader", +- offset: 0, +- size: 0x0000A000 +- }, { +- name: "params", +- offset: MTDPART_OFS_APPEND, +- size: 0x00006000 +- }, { +- name: "kernel", +- offset: MTDPART_OFS_APPEND, +- size: 0x00100000 +- }, { +- name: "root", +- offset: MTDPART_OFS_APPEND, +- size: MTDPART_SIZ_FULL ++ .name = "BLOB boot loader", ++ .offset = 0, ++ .size = 0x0000A000 ++ }, { ++ .name = "params", ++ .offset = MTDPART_OFS_APPEND, ++ .size = 0x00006000 ++ }, { ++ .name = "root", ++ .offset = MTDPART_OFS_APPEND, ++ .size = MTDPART_SIZ_FULL + } + }; +- + #endif + + + #ifdef CONFIG_SA1100_CERF + #ifdef CONFIG_SA1100_CERF_FLASH_32MB +-#define CERF_FLASH_SIZE 0x02000000 +-static struct mtd_partition cerf_partitions[] = { +- { +- name: "firmware", +- size: 0x00040000, +- offset: 0, +- }, { +- name: "params", +- size: 0x00040000, +- offset: 0x00040000, +- }, { +- name: "kernel", +- size: 0x00100000, +- offset: 0x00080000, +- }, { +- name: "rootdisk", +- size: 0x01E80000, +- offset: 0x00180000, +- } +-}; ++# define CERF_FLASH_SIZE 0x02000000 + #elif defined CONFIG_SA1100_CERF_FLASH_16MB +-#define CERF_FLASH_SIZE 0x01000000 ++# define CERF_FLASH_SIZE 0x01000000 ++#elif defined CONFIG_SA1100_CERF_FLASH_8MB ++# define CERF_FLASH_SIZE 0x00800000 ++#else ++# error "Undefined flash size for CERF in sa1100-flash.c" ++#endif ++ + static struct mtd_partition cerf_partitions[] = { + { +- name: "firmware", +- size: 0x00020000, +- offset: 0, +- }, { +- name: "params", +- size: 0x00020000, +- offset: 0x00020000, +- }, { +- name: "kernel", +- size: 0x00100000, +- offset: 0x00040000, +- }, { +- name: "rootdisk", +- size: 0x00EC0000, +- offset: 0x00140000, ++ .name = "Bootloader", ++ .size = 0x00020000, ++ .offset = 0x00000000, ++ }, { ++ .name = "Params", ++ .size = 0x00040000, ++ .offset = 0x00020000, ++ }, { ++ .name = "Kernel", ++ .size = 0x00100000, ++ .offset = 0x00060000, ++ }, { ++ .name = "Filesystem", ++ .size = CERF_FLASH_SIZE-0x00160000, ++ .offset = 0x00160000, + } + }; +-#elif defined CONFIG_SA1100_CERF_FLASH_8MB +-# error "Unwritten type definition" +-#else +-# error "Undefined memory orientation for CERF in sa1100-flash.c" +-#endif + #endif + + #ifdef CONFIG_SA1100_CONSUS +-#define CONSUS_FLASH_SIZE 0x02000000 + static struct mtd_partition consus_partitions[] = { + { +- name: "Consus boot firmware", +- offset: 0, +- size: 0x00040000, +- mask_flags: MTD_WRITABLE, /* force read-only */ +- }, { +- name: "Consus kernel", +- offset: 0x00040000, +- size: 0x00100000, +- mask_flags: 0, ++ .name = "Consus boot firmware", ++ .offset = 0, ++ .size = 0x00040000, ++ .mask_flags = MTD_WRITABLE, /* force read-only */ ++ }, { ++ .name = "Consus kernel", ++ .offset = 0x00040000, ++ .size = 0x00100000, ++ .mask_flags = 0, + }, { +- name: "Consus disk", +- offset: 0x00140000, ++ .name = "Consus disk", ++ .offset = 0x00140000, + /* The rest (up to 16M) for jffs. We could put 0 and + make it find the size automatically, but right now + i have 32 megs. jffs will use all 32 megs if given + the chance, and this leads to horrible problems + when you try to re-flash the image because blob + won't erase the whole partition. */ +- size: 0x01000000 - 0x00140000, +- mask_flags: 0, ++ .size = 0x01000000 - 0x00140000, ++ .mask_flags = 0, + }, { + /* this disk is a secondary disk, which can be used as + needed, for simplicity, make it the size of the other + consus partition, although realistically it could be + the remainder of the disk (depending on the file + system used) */ +- name: "Consus disk2", +- offset: 0x01000000, +- size: 0x01000000 - 0x00140000, +- mask_flags: 0, ++ .name = "Consus disk2", ++ .offset = 0x01000000, ++ .size = 0x01000000 - 0x00140000, ++ .mask_flags = 0, + } + }; + #endif +@@ -292,96 +226,95 @@ + #define FLEXANET_FLASH_SIZE 0x02000000 + static struct mtd_partition flexanet_partitions[] = { + { +- name: "bootloader", +- size: 0x00040000, +- offset: 0, +- mask_flags: MTD_WRITEABLE, +- }, { +- name: "bootloader params", +- size: 0x00040000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, +- }, { +- name: "kernel", +- size: 0x000C0000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, +- }, { +- name: "altkernel", +- size: 0x000C0000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, +- }, { +- name: "root", +- size: 0x00400000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, +- }, { +- name: "free1", +- size: 0x00300000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, +- }, { +- name: "free2", +- size: 0x00300000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, +- }, { +- name: "free3", +- size: MTDPART_SIZ_FULL, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, ++ .name = "bootloader", ++ .size = 0x00040000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "bootloader params", ++ .size = 0x00040000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "kernel", ++ .size = 0x000C0000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "altkernel", ++ .size = 0x000C0000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "root", ++ .size = 0x00400000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "free1", ++ .size = 0x00300000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "free2", ++ .size = 0x00300000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE, ++ }, { ++ .name = "free3", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE, + } + }; + #endif + + #ifdef CONFIG_SA1100_FREEBIRD +-#define FREEBIRD_FLASH_SIZE 0x02000000 + static struct mtd_partition freebird_partitions[] = { +-#if CONFIG_SA1100_FREEBIRD_NEW ++#ifdef CONFIG_SA1100_FREEBIRD_NEW + { +- name: "firmware", +- size: 0x00040000, +- offset: 0, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "kernel", +- size: 0x00080000, +- offset: 0x00040000, +- }, { +- name: "params", +- size: 0x00040000, +- offset: 0x000C0000, +- }, { +- name: "initrd", +- size: 0x00100000, +- offset: 0x00100000, +- }, { +- name: "root cramfs", +- size: 0x00300000, +- offset: 0x00200000, +- }, { +- name: "usr cramfs", +- size: 0x00C00000, +- offset: 0x00500000, +- }, { +- name: "local", +- size: MTDPART_SIZ_FULL, +- offset: 0x01100000, ++ .name = "firmware", ++ .size = 0x00040000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, { ++ .name = "kernel", ++ .size = 0x00080000, ++ .offset = 0x00040000, ++ }, { ++ .name = "params", ++ .size = 0x00040000, ++ .offset = 0x000C0000, ++ }, { ++ .name = "initrd", ++ .size = 0x00100000, ++ .offset = 0x00100000, ++ }, { ++ .name = "root cramfs", ++ .size = 0x00300000, ++ .offset = 0x00200000, ++ }, { ++ .name = "usr cramfs", ++ .size = 0x00C00000, ++ .offset = 0x00500000, ++ }, { ++ .name = "local", ++ .size = MTDPART_SIZ_FULL, ++ .offset = 0x01100000, + } + #else + { +- size: 0x00040000, +- offset: 0, ++ .size = 0x00040000, ++ .offset = 0, + }, { +- size: 0x000c0000, +- offset: MTDPART_OFS_APPEND, ++ .size = 0x000c0000, ++ .offset = MTDPART_OFS_APPEND, + }, { +- size: 0x00400000, +- offset: MTDPART_OFS_APPEND, ++ .size = 0x00400000, ++ .offset = MTDPART_OFS_APPEND, + }, { +- size: MTDPART_SIZ_FULL, +- offset: MTDPART_OFS_APPEND, ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND, + } + #endif + }; +@@ -389,178 +322,215 @@ + + #ifdef CONFIG_SA1100_FRODO + /* Frodo has 2 x 16M 28F128J3A flash chips in bank 0: */ +-#define FRODO_FLASH_SIZE 0x02000000 + static struct mtd_partition frodo_partitions[] = + { + { +- name: "Boot Loader", +- size: 0x00040000, +- offset: 0x00000000 +- }, { +- name: "Parameter Block", +- size: 0x00040000, +- offset: MTDPART_OFS_APPEND +- }, { +- name: "Linux Kernel", +- size: 0x00100000, +- offset: MTDPART_OFS_APPEND +- }, { +- name: "Ramdisk", +- size: 0x00680000, +- offset: MTDPART_OFS_APPEND +- }, { +- name: "Flash File System", +- size: MTDPART_SIZ_FULL, +- offset: MTDPART_OFS_APPEND ++ .name = "bootloader", ++ .size = 0x00040000, ++ .offset = 0x00000000, ++ .mask_flags = MTD_WRITEABLE ++ }, { ++ .name = "bootloader params", ++ .size = 0x00040000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE ++ }, { ++ .name = "kernel", ++ .size = 0x00100000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE ++ }, { ++ .name = "ramdisk", ++ .size = 0x00400000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE ++ }, { ++ .name = "file system", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND + } + }; + #endif + + #ifdef CONFIG_SA1100_GRAPHICSCLIENT +-#define GRAPHICSCLIENT_FLASH_SIZE 0x02000000 + static struct mtd_partition graphicsclient_partitions[] = { + { +- name: "zImage", +- size: 0x100000, +- offset: 0, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "ramdisk.gz", +- size: 0x300000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "User FS", +- size: MTDPART_SIZ_FULL, +- offset: MTDPART_OFS_APPEND, ++ .name = "zImage", ++ .size = 0x100000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, { ++ .name = "ramdisk.gz", ++ .size = 0x300000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, { ++ .name = "User FS", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND, + } + }; + #endif + + #ifdef CONFIG_SA1100_GRAPHICSMASTER +-#define GRAPHICSMASTER_FLASH_SIZE 0x01000000 + static struct mtd_partition graphicsmaster_partitions[] = { + { +- name: "zImage", +- size: 0x100000, +- offset: 0, +- mask_flags: MTD_WRITEABLE, /* force read-only */ ++ .name = "zImage", ++ .size = 0x100000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { +- name: "ramdisk.gz", +- size: 0x300000, +- offset: MTDPART_OFS_APPEND, +- mask_flags: MTD_WRITEABLE, /* force read-only */ ++ .name = "ramdisk.gz", ++ .size = 0x300000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { +- name: "User FS", +- size: MTDPART_SIZ_FULL, +- offset: MTDPART_OFS_APPEND, ++ .name = "User FS", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND, + } + }; + #endif + +-#ifdef CONFIG_SA1100_H3600 +-#define H3600_FLASH_SIZE 0x02000000 +-static struct mtd_partition h3600_partitions[] = { ++#ifdef CONFIG_SA1100_H3XXX ++static struct mtd_partition h3xxx_partitions[] = { + { +- name: "H3600 boot firmware", +- size: 0x00040000, +- offset: 0, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "H3600 kernel", +- size: 0x00080000, +- offset: 0x00040000, ++ .name = "H3XXX boot firmware", ++ .size = 0x00040000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { +- name: "H3600 params", +- size: 0x00040000, +- offset: 0x000C0000, ++#ifdef CONFIG_MTD_2PARTS_IPAQ ++ .name = "H3XXX root jffs2", ++ .size = MTDPART_SIZ_FULL, ++ .offset = 0x00040000, ++#else ++ .name = "H3XXX kernel", ++ .size = 0x00080000, ++ .offset = 0x00040000, ++ }, { ++ .name = "H3XXX params", ++ .size = 0x00040000, ++ .offset = 0x000C0000, + }, { + #ifdef CONFIG_JFFS2_FS +- name: "H3600 root jffs2", +- size: MTDPART_SIZ_FULL, +- offset: 0x00100000, ++ .name = "H3XXX root jffs2", ++ .size = MTDPART_SIZ_FULL, ++ .offset = 0x00100000, + #else +- name: "H3600 initrd", +- size: 0x00100000, +- offset: 0x00100000, ++ .name = "H3XXX initrd", ++ .size = 0x00100000, ++ .offset = 0x00100000, + }, { +- name: "H3600 root cramfs", +- size: 0x00300000, +- offset: 0x00200000, ++ .name = "H3XXX root cramfs", ++ .size = 0x00300000, ++ .offset = 0x00200000, + }, { +- name: "H3600 usr cramfs", +- size: 0x00800000, +- offset: 0x00500000, ++ .name = "H3XXX usr cramfs", ++ .size = 0x00800000, ++ .offset = 0x00500000, + }, { +- name: "H3600 usr local", +- size: MTDPART_SIZ_FULL, +- offset: 0x00d00000, ++ .name = "H3XXX usr local", ++ .size = MTDPART_SIZ_FULL, ++ .offset = 0x00d00000, ++#endif + #endif + } + }; + +-static void h3600_set_vpp(struct map_info *map, int vpp) ++static void h3xxx_set_vpp(struct map_info *map, int vpp) + { + assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, vpp); + } ++#else ++#define h3xxx_set_vpp NULL ++#endif ++ ++#ifdef CONFIG_SA1100_HACKKIT ++static struct mtd_partition hackkit_partitions[] = { ++ { ++ .name = "BLOB", ++ .size = 0x00040000, ++ .offset = 0x00000000, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, { ++ .name = "config", ++ .size = 0x00040000, ++ .offset = MTDPART_OFS_APPEND, ++ }, { ++ .name = "kernel", ++ .size = 0x00100000, ++ .offset = MTDPART_OFS_APPEND, ++ }, { ++ .name = "initrd", ++ .size = 0x00180000, ++ .offset = MTDPART_OFS_APPEND, ++ }, { ++ .name = "rootfs", ++ .size = 0x700000, ++ .offset = MTDPART_OFS_APPEND, ++ }, { ++ .name = "data", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND, ++ } ++}; + #endif + + #ifdef CONFIG_SA1100_HUW_WEBPANEL +-#define HUW_WEBPANEL_FLASH_SIZE 0x01000000 + static struct mtd_partition huw_webpanel_partitions[] = { + { +- name: "Loader", +- size: 0x00040000, +- offset: 0, +- }, { +- name: "Sector 1", +- size: 0x00040000, +- offset: MTDPART_OFS_APPEND, ++ .name = "Loader", ++ .size = 0x00040000, ++ .offset = 0, ++ }, { ++ .name = "Sector 1", ++ .size = 0x00040000, ++ .offset = MTDPART_OFS_APPEND, + }, { +- size: MTDPART_SIZ_FULL, +- offset: MTDPART_OFS_APPEND, ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND, + } + }; + #endif + + #ifdef CONFIG_SA1100_JORNADA720 +-#define JORNADA720_FLASH_SIZE 0x02000000 + static struct mtd_partition jornada720_partitions[] = { + { +- name: "JORNADA720 boot firmware", +- size: 0x00040000, +- offset: 0, +- mask_flags: MTD_WRITEABLE, /* force read-only */ ++ .name = "JORNADA720 boot firmware", ++ .size = 0x00040000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { +- name: "JORNADA720 kernel", +- size: 0x000c0000, +- offset: 0x00040000, ++ .name = "JORNADA720 kernel", ++ .size = 0x000c0000, ++ .offset = 0x00040000, + }, { +- name: "JORNADA720 params", +- size: 0x00040000, +- offset: 0x00100000, ++ .name = "JORNADA720 params", ++ .size = 0x00040000, ++ .offset = 0x00100000, + }, { +- name: "JORNADA720 initrd", +- size: 0x00100000, +- offset: 0x00140000, ++ .name = "JORNADA720 initrd", ++ .size = 0x00100000, ++ .offset = 0x00140000, + }, { +- name: "JORNADA720 root cramfs", +- size: 0x00300000, +- offset: 0x00240000, ++ .name = "JORNADA720 root cramfs", ++ .size = 0x00300000, ++ .offset = 0x00240000, + }, { +- name: "JORNADA720 usr cramfs", +- size: 0x00800000, +- offset: 0x00540000, ++ .name = "JORNADA720 usr cramfs", ++ .size = 0x00800000, ++ .offset = 0x00540000, + }, { +- name: "JORNADA720 usr local", +- size: 0 /* will expand to the end of the flash */ +- offset: 0x00d00000, ++ .name = "JORNADA720 usr local", ++ .size = 0, /* will expand to the end of the flash */ ++ .offset = 0x00d00000, + } + }; + +-static void jornada720_set_vpp(int vpp) ++static void jornada720_set_vpp(struct map_info *map, int vpp) + { + if (vpp) + PPSR |= 0x80; +@@ -568,454 +538,811 @@ + PPSR &= ~0x80; + PPDR |= 0x80; + } +- ++#else ++#define jornada720_set_vpp NULL + #endif + + #ifdef CONFIG_SA1100_PANGOLIN +-#define PANGOLIN_FLASH_SIZE 0x04000000 + static struct mtd_partition pangolin_partitions[] = { + { +- name: "boot firmware", +- size: 0x00080000, +- offset: 0x00000000, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "kernel", +- size: 0x00100000, +- offset: 0x00080000, +- }, { +- name: "initrd", +- size: 0x00280000, +- offset: 0x00180000, +- }, { +- name: "initrd-test", +- size: 0x03C00000, +- offset: 0x00400000, ++ .name = "boot firmware", ++ .size = 0x00080000, ++ .offset = 0x00000000, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, { ++ .name = "kernel", ++ .size = 0x00100000, ++ .offset = 0x00080000, ++ }, { ++ .name = "initrd", ++ .size = 0x00280000, ++ .offset = 0x00180000, ++ }, { ++ .name = "initrd-test", ++ .size = 0x03C00000, ++ .offset = 0x00400000, + } + }; + #endif + + #ifdef CONFIG_SA1100_PT_SYSTEM3 + /* erase size is 0x40000 == 256k partitions have to have this boundary */ +-#define SYSTEM3_FLASH_SIZE 0x01000000 + static struct mtd_partition system3_partitions[] = { + { +- name: "BLOB", +- size: 0x00040000, +- offset: 0x00000000, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "config", +- size: 0x00040000, +- offset: MTDPART_OFS_APPEND, +- }, { +- name: "kernel", +- size: 0x00100000, +- offset: MTDPART_OFS_APPEND, +- }, { +- name: "root", +- size: MTDPART_SIZ_FULL, +- offset: MTDPART_OFS_APPEND, ++ .name = "BLOB", ++ .size = 0x00040000, ++ .offset = 0x00000000, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, { ++ .name = "config", ++ .size = 0x00040000, ++ .offset = MTDPART_OFS_APPEND, ++ }, { ++ .name = "kernel", ++ .size = 0x00100000, ++ .offset = MTDPART_OFS_APPEND, ++ }, { ++ .name = "root", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND, + } + }; + #endif + + #ifdef CONFIG_SA1100_SHANNON +-#define SHANNON_FLASH_SIZE 0x00400000 + static struct mtd_partition shannon_partitions[] = { + { +- name: "BLOB boot loader", +- offset: 0, +- size: 0x20000 ++ .name = "BLOB boot loader", ++ .offset = 0, ++ .size = 0x20000 + }, + { +- name: "kernel", +- offset: MTDPART_OFS_APPEND, +- size: 0xe0000 ++ .name = "kernel", ++ .offset = MTDPART_OFS_APPEND, ++ .size = 0xe0000 + }, + { +- name: "initrd", +- offset: MTDPART_OFS_APPEND, +- size: MTDPART_SIZ_FULL ++ .name = "initrd", ++ .offset = MTDPART_OFS_APPEND, ++ .size = MTDPART_SIZ_FULL + } + }; + + #endif + + #ifdef CONFIG_SA1100_SHERMAN +-#define SHERMAN_FLASH_SIZE 0x02000000 + static struct mtd_partition sherman_partitions[] = { + { +- size: 0x50000, +- offset: 0, ++ .size = 0x50000, ++ .offset = 0, + }, { +- size: 0x70000, +- offset: MTDPART_OFS_APPEND, ++ .size = 0x70000, ++ .offset = MTDPART_OFS_APPEND, + }, { +- size: 0x600000, +- offset: MTDPART_OFS_APPEND, ++ .size = 0x600000, ++ .offset = MTDPART_OFS_APPEND, + }, { +- size: 0xA0000, +- offset: MTDPART_OFS_APPEND, ++ .size = 0xA0000, ++ .offset = MTDPART_OFS_APPEND, + } + }; + #endif + + #ifdef CONFIG_SA1100_SIMPAD +-#define SIMPAD_FLASH_SIZE 0x02000000 + static struct mtd_partition simpad_partitions[] = { + { +- name: "SIMpad boot firmware", +- size: 0x00080000, +- offset: 0, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "SIMpad kernel", +- size: 0x00100000, +- offset: 0x00080000, +- }, { +-#ifdef CONFIG_JFFS2_FS +- name: "SIMpad root jffs2", +- size: MTDPART_SIZ_FULL, +- offset: 0x00180000, ++ .name = "SIMpad boot firmware", ++ .size = 0x00080000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, { ++ .name = "SIMpad kernel", ++ .size = 0x00100000, ++ .offset = MTDPART_OFS_APPEND, ++ }, { ++#ifdef CONFIG_ROOT_CRAMFS ++ .name = "SIMpad root cramfs", ++ .size =0x00D80000, ++ .offset = MTDPART_OFS_APPEND ++ ++ }, { ++ .name = "SIMpad local jffs2", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND + #else +- name: "SIMpad initrd", +- size: 0x00300000, +- offset: 0x00180000, +- }, { +- name: "SIMpad root cramfs", +- size: 0x00300000, +- offset: 0x00480000, +- }, { +- name: "SIMpad usr cramfs", +- size: 0x005c0000, +- offset: 0x00780000, +- }, { +- name: "SIMpad usr local", +- size: MTDPART_SIZ_FULL, +- offset: 0x00d40000, ++ .name = "SIMpad root jffs2", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND + #endif + } + }; + #endif /* CONFIG_SA1100_SIMPAD */ + + #ifdef CONFIG_SA1100_STORK +-#define STORK_FLASH_SIZE 0x02000000 + static struct mtd_partition stork_partitions[] = { + { +- name: "STORK boot firmware", +- size: 0x00040000, +- offset: 0, +- mask_flags: MTD_WRITEABLE, /* force read-only */ +- }, { +- name: "STORK params", +- size: 0x00040000, +- offset: 0x00040000, +- }, { +- name: "STORK kernel", +- size: 0x00100000, +- offset: 0x00080000, ++ .name = "STORK boot firmware", ++ .size = 0x00040000, ++ .offset = 0, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, { ++ .name = "STORK params", ++ .size = 0x00040000, ++ .offset = 0x00040000, ++ }, { ++ .name = "STORK kernel", ++ .size = 0x00100000, ++ .offset = 0x00080000, + }, { + #ifdef CONFIG_JFFS2_FS +- name: "STORK root jffs2", +- offset: 0x00180000, +- size: MTDPART_SIZ_FULL, ++ .name = "STORK root jffs2", ++ .offset = 0x00180000, ++ .size = MTDPART_SIZ_FULL, + #else +- name: "STORK initrd", +- size: 0x00100000, +- offset: 0x00180000, +- }, { +- name: "STORK root cramfs", +- size: 0x00300000, +- offset: 0x00280000, +- }, { +- name: "STORK usr cramfs", +- size: 0x00800000, +- offset: 0x00580000, +- }, { +- name: "STORK usr local", +- offset: 0x00d80000, +- size: MTDPART_SIZ_FULL, ++ .name = "STORK initrd", ++ .size = 0x00100000, ++ .offset = 0x00180000, ++ }, { ++ .name = "STORK root cramfs", ++ .size = 0x00300000, ++ .offset = 0x00280000, ++ }, { ++ .name = "STORK usr cramfs", ++ .size = 0x00800000, ++ .offset = 0x00580000, ++ }, { ++ .name = "STORK usr local", ++ .offset = 0x00d80000, ++ .size = MTDPART_SIZ_FULL, ++#endif ++ } ++}; + #endif ++ ++#ifdef CONFIG_SA1100_TRIZEPS ++static struct mtd_partition trizeps_partitions[] = { ++ { ++ .name = "Bootloader", ++ .size = 0x00100000, ++ .offset = 0, ++ }, { ++ .name = "Kernel", ++ .size = 0x00100000, ++ .offset = MTDPART_OFS_APPEND, ++ }, { ++ .name = "root", ++ .size = MTDPART_SIZ_FULL, ++ .offset = MTDPART_OFS_APPEND, + } + }; + #endif + + #ifdef CONFIG_SA1100_YOPY +-#define YOPY_FLASH_SIZE 0x08000000 + static struct mtd_partition yopy_partitions[] = { + { +- name: "boot firmware", +- size: 0x00040000, +- offset: 0x00000000, +- mask_flags: MTD_WRITEABLE, /* force read-only */ ++ .name = "boot firmware", ++ .size = 0x00040000, ++ .offset = 0x00000000, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { +- name: "kernel", +- size: 0x00080000, +- offset: 0x00080000, ++ .name = "kernel", ++ .size = 0x00080000, ++ .offset = 0x00080000, + }, { +- name: "initrd", +- size: 0x00300000, +- offset: 0x00100000, ++ .name = "initrd", ++ .size = 0x00300000, ++ .offset = 0x00100000, + }, { +- name: "root", +- size: 0x01000000, +- offset: 0x00400000, ++ .name = "root", ++ .size = 0x01000000, ++ .offset = 0x00400000, + } + }; + #endif + +-extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); +-extern int parse_bootldr_partitions(struct mtd_info *master, struct mtd_partition **pparts); +- +-static struct mtd_partition *parsed_parts; +-static struct mtd_info *mymtd; +- +-int __init sa1100_mtd_init(void) ++static int __init sa1100_static_partitions(struct mtd_partition **parts) + { +- struct mtd_partition *parts; +- int nb_parts = 0, ret; +- int parsed_nr_parts = 0; +- const char *part_type; +- unsigned long base = -1UL; +- +- /* Default flash buswidth */ +- sa1100_map.buswidth = (MSC0 & MSC_RBW) ? 2 : 4; +- +- /* +- * Static partition definition selection +- */ +- part_type = "static"; ++ int nb_parts = 0; + + #ifdef CONFIG_SA1100_ADSBITSY + if (machine_is_adsbitsy()) { +- parts = adsbitsy_partitions; ++ *parts = adsbitsy_partitions; + nb_parts = ARRAY_SIZE(adsbitsy_partitions); +- sa1100_map.size = ADSBITSY_FLASH_SIZE; +- sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2 : 4; + } + #endif + #ifdef CONFIG_SA1100_ASSABET + if (machine_is_assabet()) { +- parts = assabet_partitions; ++ *parts = assabet_partitions; + nb_parts = ARRAY_SIZE(assabet_partitions); +- sa1100_map.size = ASSABET_FLASH_SIZE; + } + #endif + #ifdef CONFIG_SA1100_BADGE4 + if (machine_is_badge4()) { +- parts = badge4_partitions; ++ *parts = badge4_partitions; + nb_parts = ARRAY_SIZE(badge4_partitions); +- sa1100_map.size = BADGE4_FLASH_SIZE; + } + #endif + #ifdef CONFIG_SA1100_CERF + if (machine_is_cerf()) { +- parts = cerf_partitions; ++ *parts = cerf_partitions; + nb_parts = ARRAY_SIZE(cerf_partitions); +- sa1100_map.size = CERF_FLASH_SIZE; + } + #endif + #ifdef CONFIG_SA1100_CONSUS + if (machine_is_consus()) { +- parts = consus_partitions; ++ *parts = consus_partitions; + nb_parts = ARRAY_SIZE(consus_partitions); +- sa1100_map.size = CONSUS_FLASH_SIZE; + } + #endif + #ifdef CONFIG_SA1100_FLEXANET + if (machine_is_flexanet()) { +- parts = flexanet_partitions; ++ *parts = flexanet_partitions; + nb_parts = ARRAY_SIZE(flexanet_partitions); +- sa1100_map.size = FLEXANET_FLASH_SIZE; + } + #endif + #ifdef CONFIG_SA1100_FREEBIRD + if (machine_is_freebird()) { +- parts = freebird_partitions; ++ *parts = freebird_partitions; + nb_parts = ARRAY_SIZE(freebird_partitions); +- sa1100_map.size = FREEBIRD_FLASH_SIZE; + } + #endif + #ifdef CONFIG_SA1100_FRODO + if (machine_is_frodo()) { +- parts = frodo_partitions; ++ *parts = frodo_partitions; + nb_parts = ARRAY_SIZE(frodo_partitions); +- sa1100_map.size = FRODO_FLASH_SIZE; +- base = 0x00000000; + } + #endif + #ifdef CONFIG_SA1100_GRAPHICSCLIENT + if (machine_is_graphicsclient()) { +- parts = graphicsclient_partitions; ++ *parts = graphicsclient_partitions; + nb_parts = ARRAY_SIZE(graphicsclient_partitions); +- sa1100_map.size = GRAPHICSCLIENT_FLASH_SIZE; +- sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4; + } + #endif + #ifdef CONFIG_SA1100_GRAPHICSMASTER + if (machine_is_graphicsmaster()) { +- parts = graphicsmaster_partitions; ++ *parts = graphicsmaster_partitions; + nb_parts = ARRAY_SIZE(graphicsmaster_partitions); +- sa1100_map.size = GRAPHICSMASTER_FLASH_SIZE; +- sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4; + } + #endif +-#ifdef CONFIG_SA1100_H3600 +- if (machine_is_h3600()) { +- parts = h3600_partitions; +- nb_parts = ARRAY_SIZE(h3600_partitions); +- sa1100_map.size = H3600_FLASH_SIZE; +- sa1100_map.set_vpp = h3600_set_vpp; ++#ifdef CONFIG_SA1100_H3XXX ++ if (machine_is_h3xxx()) { ++ *parts = h3xxx_partitions; ++ nb_parts = ARRAY_SIZE(h3xxx_partitions); ++ } ++#endif ++#ifdef CONFIG_SA1100_HACKKIT ++ if (machine_is_hackkit()) { ++ *parts = hackkit_partitions; ++ nb_parts = ARRAY_SIZE(hackkit_partitions); + } + #endif + #ifdef CONFIG_SA1100_HUW_WEBPANEL + if (machine_is_huw_webpanel()) { +- parts = huw_webpanel_partitions; ++ *parts = huw_webpanel_partitions; + nb_parts = ARRAY_SIZE(huw_webpanel_partitions); +- sa1100_map.size = HUW_WEBPANEL_FLASH_SIZE; + } + #endif + #ifdef CONFIG_SA1100_JORNADA720 + if (machine_is_jornada720()) { +- parts = jornada720_partitions; ++ *parts = jornada720_partitions; + nb_parts = ARRAY_SIZE(jornada720_partitions); +- sa1100_map.size = JORNADA720_FLASH_SIZE; +- sa1100_map.set_vpp = jornada720_set_vpp; + } + #endif + #ifdef CONFIG_SA1100_PANGOLIN + if (machine_is_pangolin()) { +- parts = pangolin_partitions; ++ *parts = pangolin_partitions; + nb_parts = ARRAY_SIZE(pangolin_partitions); +- sa1100_map.size = PANGOLIN_FLASH_SIZE; + } + #endif + #ifdef CONFIG_SA1100_PT_SYSTEM3 + if (machine_is_pt_system3()) { +- parts = system3_partitions; ++ *parts = system3_partitions; + nb_parts = ARRAY_SIZE(system3_partitions); +- sa1100_map.size = SYSTEM3_FLASH_SIZE; + } + #endif + #ifdef CONFIG_SA1100_SHANNON + if (machine_is_shannon()) { +- parts = shannon_partitions; ++ *parts = shannon_partitions; + nb_parts = ARRAY_SIZE(shannon_partitions); +- sa1100_map.size = SHANNON_FLASH_SIZE; + } + #endif + #ifdef CONFIG_SA1100_SHERMAN + if (machine_is_sherman()) { +- parts = sherman_partitions; ++ *parts = sherman_partitions; + nb_parts = ARRAY_SIZE(sherman_partitions); +- sa1100_map.size = SHERMAN_FLASH_SIZE; + } + #endif + #ifdef CONFIG_SA1100_SIMPAD + if (machine_is_simpad()) { +- parts = simpad_partitions; ++ *parts = simpad_partitions; + nb_parts = ARRAY_SIZE(simpad_partitions); +- sa1100_map.size = SIMPAD_FLASH_SIZE; + } + #endif + #ifdef CONFIG_SA1100_STORK + if (machine_is_stork()) { +- parts = stork_partitions; ++ *parts = stork_partitions; + nb_parts = ARRAY_SIZE(stork_partitions); +- sa1100_map.size = STORK_FLASH_SIZE; ++ } ++#endif ++#ifdef CONFIG_SA1100_TRIZEPS ++ if (machine_is_trizeps()) { ++ *parts = trizeps_partitions; ++ nb_parts = ARRAY_SIZE(trizeps_partitions); + } + #endif + #ifdef CONFIG_SA1100_YOPY + if (machine_is_yopy()) { +- parts = yopy_partitions; ++ *parts = yopy_partitions; + nb_parts = ARRAY_SIZE(yopy_partitions); +- sa1100_map.size = YOPY_FLASH_SIZE; + } + #endif + ++ return nb_parts; ++} ++#endif ++ ++struct sa_info { ++ unsigned long base; ++ unsigned long size; ++ int width; ++ void *vbase; ++ void (*set_vpp)(struct map_info *, int); ++ struct map_info *map; ++ struct mtd_info *mtd; ++ struct resource *res; ++}; ++ ++#define NR_SUBMTD 4 ++ ++static struct sa_info info[NR_SUBMTD]; ++ ++static int __init sa1100_setup_mtd(struct sa_info *sa, int nr, struct mtd_info **rmtd) ++{ ++ struct mtd_info *subdev[nr]; ++ struct map_info *maps; ++ int i, found = 0, ret = 0; ++ + /* +- * For simple flash devices, use ioremap to map the flash. ++ * Allocate the map_info structs in one go. + */ +- if (base != (unsigned long)-1) { +- if (!request_mem_region(base, sa1100_map.size, "flash")) +- return -EBUSY; +- sa1100_map.map_priv_2 = base; +- sa1100_map.map_priv_1 = (unsigned long) +- ioremap(base, sa1100_map.size); ++ maps = kmalloc(sizeof(struct map_info) * nr, GFP_KERNEL); ++ if (!maps) ++ return -ENOMEM; ++ ++ memset(maps, 0, sizeof(struct map_info) * nr); ++ ++ /* ++ * Claim and then map the memory regions. ++ */ ++ for (i = 0; i < nr; i++) { ++ if (sa[i].base == (unsigned long)-1) ++ break; ++ ++ sa[i].res = request_mem_region(sa[i].base, sa[i].size, "sa1100 flash"); ++ if (!sa[i].res) { ++ ret = -EBUSY; ++ break; ++ } ++ ++ sa[i].map = maps + i; ++ ++ sa[i].vbase = ioremap(sa[i].base, sa[i].size); ++ if (!sa[i].vbase) { + ret = -ENOMEM; +- if (!sa1100_map.map_priv_1) +- goto out_err; ++ break; + } + ++ sa[i].map->virt = (unsigned long)sa[i].vbase; ++ sa[i].map->phys = sa[i].base; ++ sa[i].map->set_vpp = sa[i].set_vpp; ++ sa[i].map->buswidth = sa[i].width; ++ sa[i].map->size = sa[i].size; ++ ++ simple_map_init(sa[i].map); ++ + /* + * Now let's probe for the actual flash. Do it here since + * specific machine settings might have been set above. + */ +- printk(KERN_NOTICE "SA1100 flash: probing %d-bit flash bus\n", sa1100_map.buswidth*8); +- mymtd = do_map_probe("cfi_probe", &sa1100_map); ++ sa[i].mtd = do_map_probe("cfi_probe", sa[i].map); ++ if (sa[i].mtd == NULL) { + ret = -ENXIO; +- if (!mymtd) +- goto out_err; +- mymtd->module = THIS_MODULE; ++ break; ++ } ++ sa[i].mtd->owner = THIS_MODULE; ++ subdev[i] = sa[i].mtd; ++ ++ printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, " ++ "%d-bit\n", sa[i].base, sa[i].mtd->size >> 20, ++ sa[i].width * 8); ++ found += 1; ++ } + + /* +- * Dynamic partition selection stuff (might override the static ones) ++ * ENXIO is special. It means we didn't find a chip when ++ * we probed. We need to tear down the mapping, free the ++ * resource and mark it as such. + */ +-#ifdef CONFIG_MTD_REDBOOT_PARTS +- if (parsed_nr_parts == 0) { +- int ret = parse_redboot_partitions(mymtd, &parsed_parts); ++ if (ret == -ENXIO) { ++ iounmap(sa[i].vbase); ++ sa[i].vbase = NULL; ++ release_resource(sa[i].res); ++ sa[i].res = NULL; ++ } + +- if (ret > 0) { +- part_type = "RedBoot"; +- parsed_nr_parts = ret; ++ /* ++ * If we found one device, don't bother with concat support. ++ * If we found multiple devices, use concat if we have it ++ * available, otherwise fail. ++ */ ++ if (ret == 0 || ret == -ENXIO) { ++ if (found == 1) { ++ *rmtd = subdev[0]; ++ ret = 0; ++ } else if (found > 1) { ++ /* ++ * We detected multiple devices. Concatenate ++ * them together. ++ */ ++#ifdef CONFIG_MTD_CONCAT ++ *rmtd = mtd_concat_create(subdev, found, ++ "sa1100 flash"); ++ if (*rmtd == NULL) ++ ret = -ENXIO; ++#else ++ printk(KERN_ERR "SA1100 flash: multiple devices " ++ "found but MTD concat support disabled.\n"); ++ ret = -ENXIO; ++#endif + } + } ++ ++ /* ++ * If we failed, clean up. ++ */ ++ if (ret) { ++ do { ++ if (sa[i].mtd) ++ map_destroy(sa[i].mtd); ++ if (sa[i].vbase) ++ iounmap(sa[i].vbase); ++ if (sa[i].res) ++ release_resource(sa[i].res); ++ } while (i--); ++ ++ kfree(maps); ++ } ++ ++ return ret; ++} ++ ++static void __exit sa1100_destroy_mtd(struct sa_info *sa, struct mtd_info *mtd) ++{ ++ int i; ++ ++ del_mtd_partitions(mtd); ++ ++#ifdef CONFIG_MTD_CONCAT ++ if (mtd != sa[0].mtd) ++ mtd_concat_destroy(mtd); + #endif +-#ifdef CONFIG_MTD_CMDLINE_PARTS +- if (parsed_nr_parts == 0) { +- int ret = parse_cmdline_partitions(mymtd, &parsed_parts, "sa1100"); +- if (ret > 0) { +- part_type = "Command Line"; +- parsed_nr_parts = ret; ++ ++ for (i = NR_SUBMTD; i >= 0; i--) { ++ if (sa[i].mtd) ++ map_destroy(sa[i].mtd); ++ if (sa[i].vbase) ++ iounmap(sa[i].vbase); ++ if (sa[i].res) ++ release_resource(sa[i].res); + } ++ kfree(sa[0].map); ++} ++ ++/* ++ * A Thought: can we automatically detect the flash? ++ * - Check to see if the region is busy (yes -> failure) ++ * - Is the MSC setup for flash (no -> failure) ++ * - Probe for flash ++ */ ++ ++static struct map_info sa1100_probe_map __initdata = { ++ .name = "SA1100-flash", ++}; ++ ++static void __init sa1100_probe_one_cs(unsigned int msc, unsigned long phys) ++{ ++ struct mtd_info *mtd; ++ ++ printk(KERN_INFO "* Probing 0x%08lx: MSC = 0x%04x %d bit ", ++ phys, msc & 0xffff, msc & MSC_RBW ? 16 : 32); ++ ++ if (check_mem_region(phys, 0x08000000)) { ++ printk("busy\n"); ++ return; + } +-#endif + +- if (parsed_nr_parts > 0) { +- parts = parsed_parts; +- nb_parts = parsed_nr_parts; ++ if ((msc & 3) == 1) { ++ printk("wrong type\n"); ++ return; + } + +- if (nb_parts == 0) { +- printk(KERN_NOTICE "SA1100 flash: no partition info available, registering whole flash at once\n"); +- add_mtd_device(mymtd); +- } else { +- printk(KERN_NOTICE "Using %s partition definition\n", part_type); +- add_mtd_partitions(mymtd, parts, nb_parts); ++ sa1100_probe_map.buswidth = msc & MSC_RBW ? 2 : 4; ++ sa1100_probe_map.size = SZ_1M; ++ sa1100_probe_map.phys = phys; ++ sa1100_probe_map.virt = (unsigned long)ioremap(phys, SZ_1M); ++ if (sa1100_probe_map.virt == 0) ++ goto fail; ++ simple_map_init(&sa1100_probe_map); ++ ++ /* Shame cfi_probe blurts out kernel messages... */ ++ mtd = do_map_probe("cfi_probe", &sa1100_probe_map); ++ if (mtd) ++ map_destroy(mtd); ++ iounmap((void *)sa1100_probe_map.virt); ++ ++ if (!mtd) ++ goto fail; ++ ++ printk("pass\n"); ++ return; ++ ++ fail: ++ printk("failed\n"); ++} ++ ++static void __init sa1100_probe_flash(void) ++{ ++ printk(KERN_INFO "-- SA11xx Flash probe. Please report results.\n"); ++ sa1100_probe_one_cs(MSC0, SA1100_CS0_PHYS); ++ sa1100_probe_one_cs(MSC0 >> 16, SA1100_CS1_PHYS); ++ sa1100_probe_one_cs(MSC1, SA1100_CS2_PHYS); ++ sa1100_probe_one_cs(MSC1 >> 16, SA1100_CS3_PHYS); ++ sa1100_probe_one_cs(MSC2, SA1100_CS4_PHYS); ++ sa1100_probe_one_cs(MSC2 >> 16, SA1100_CS5_PHYS); ++ printk(KERN_INFO "-- SA11xx Flash probe complete.\n"); ++} ++ ++static int __init sa1100_locate_flash(void) ++{ ++ int i, nr = -ENODEV; ++ ++ sa1100_probe_flash(); ++ ++ if (machine_is_adsbitsy()) { ++ info[0].base = SA1100_CS1_PHYS; ++ info[0].size = SZ_32M; ++ nr = 1; ++ } ++ if (machine_is_assabet()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_32M; ++ info[1].base = SA1100_CS1_PHYS; /* neponset */ ++ info[1].size = SZ_32M; ++ nr = 2; ++ } ++ if (machine_is_badge4()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_64M; ++ nr = 1; ++ } ++ if (machine_is_cerf()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_32M; ++ nr = 1; ++ } ++ if (machine_is_consus()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_32M; ++ nr = 1; ++ } ++ if (machine_is_flexanet()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_32M; ++ nr = 1; ++ } ++ if (machine_is_freebird()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_32M; ++ nr = 1; ++ } ++ if (machine_is_frodo()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_32M; ++ nr = 1; ++ } ++ if (machine_is_graphicsclient()) { ++ info[0].base = SA1100_CS1_PHYS; ++ info[0].size = SZ_32M; ++ nr = 1; + } +- return 0; ++ if (machine_is_graphicsmaster()) { ++ info[0].base = SA1100_CS1_PHYS; ++ info[0].size = SZ_16M; ++ nr = 1; ++ } ++ if (machine_is_h3xxx()) { ++ info[0].set_vpp = h3xxx_set_vpp; ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_32M; ++ nr = 1; ++ } ++ if (machine_is_huw_webpanel()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_16M; ++ nr = 1; ++ } ++ if (machine_is_itsy()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_32M; ++ nr = 1; ++ } ++ if (machine_is_jornada720()) { ++ info[0].set_vpp = jornada720_set_vpp; ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_32M; ++ nr = 1; ++ } ++ if (machine_is_nanoengine()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[1].size = SZ_32M; ++ nr = 1; ++ } ++ if (machine_is_pangolin()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_64M; ++ nr = 1; ++ } ++ if (machine_is_pfs168()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_32M; ++ nr = 1; ++ } ++ if (machine_is_pleb()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_4M; ++ info[1].base = SA1100_CS1_PHYS; ++ info[1].size = SZ_4M; ++ nr = 2; ++ } ++ if (machine_is_pt_system3()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_16M; ++ nr = 1; ++ } ++ if (machine_is_shannon()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_4M; ++ nr = 1; ++ } ++ if (machine_is_sherman()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_32M; ++ nr = 1; ++ } ++ if (machine_is_simpad()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_16M; ++ info[1].base = SA1100_CS1_PHYS; ++ info[1].size = SZ_16M; ++ nr = 2; ++ } ++ if (machine_is_stork()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_32M; ++ nr = 1; ++ } ++ if (machine_is_trizeps()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_16M; ++ nr = 1; ++ } ++ if (machine_is_victor()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_2M; ++ nr = 1; ++ } ++ if (machine_is_yopy()) { ++ info[0].base = SA1100_CS0_PHYS; ++ info[0].size = SZ_64M; ++ info[1].base = SA1100_CS1_PHYS; ++ info[1].size = SZ_64M; ++ nr = 2; ++ } ++ ++ if (nr < 0) ++ return nr; + +- out_err: +- if (sa1100_map.map_priv_2 != -1) { +- iounmap((void *)sa1100_map.map_priv_1); +- release_mem_region(sa1100_map.map_priv_2, sa1100_map.size); ++ /* ++ * Retrieve the buswidth from the MSC registers. ++ * We currently only implement CS0 and CS1 here. ++ */ ++ for (i = 0; i < nr; i++) { ++ switch (info[i].base) { ++ default: ++ printk(KERN_WARNING "SA1100 flash: unknown base address " ++ "0x%08lx, assuming CS0\n", info[i].base); ++ case SA1100_CS0_PHYS: ++ info[i].width = (MSC0 & MSC_RBW) ? 2 : 4; ++ break; ++ ++ case SA1100_CS1_PHYS: ++ info[i].width = ((MSC0 >> 16) & MSC_RBW) ? 2 : 4; ++ break; + } +- return ret; ++ } ++ ++ return nr; + } + +-static void __exit sa1100_mtd_cleanup(void) ++static struct mtd_partition *parsed_parts; ++const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; ++ ++static void __init sa1100_locate_partitions(struct mtd_info *mtd) + { +- if (mymtd) { +- del_mtd_partitions(mymtd); +- map_destroy(mymtd); +- if (parsed_parts) +- kfree(parsed_parts); ++ const char *part_type = NULL; ++ int nr_parts = 0; ++ ++ do { ++ /* ++ * Partition selection stuff. ++ */ ++#ifdef CONFIG_MTD_PARTITIONS ++ nr_parts = parse_mtd_partitions(mtd, part_probes, &parsed_parts, 0); ++ if (nr_parts > 0) { ++ part_type = "dynamic"; ++ break; + } +- if (sa1100_map.map_priv_2 != -1) { +- iounmap((void *)sa1100_map.map_priv_1); +- release_mem_region(sa1100_map.map_priv_2, sa1100_map.size); ++#endif ++#ifdef CONFIG_MTD_SA1100_STATICMAP ++ nr_parts = sa1100_static_partitions(&parsed_parts); ++ if (nr_parts > 0) { ++ part_type = "static"; ++ break; + } ++#endif ++ } while (0); ++ ++ if (nr_parts == 0) { ++ printk(KERN_NOTICE "SA1100 flash: no partition info " ++ "available, registering whole flash\n"); ++ add_mtd_device(mtd); ++ } else { ++ printk(KERN_NOTICE "SA1100 flash: using %s partition " ++ "definition\n", part_type); ++ add_mtd_partitions(mtd, parsed_parts, nr_parts); ++ } ++ ++ /* Always succeeds. */ ++} ++ ++static void __exit sa1100_destroy_partitions(void) ++{ ++ if (parsed_parts) ++ kfree(parsed_parts); ++} ++ ++static struct mtd_info *mymtd; ++ ++static int __init sa1100_mtd_init(void) ++{ ++ int ret; ++ int nr; ++ ++ nr = sa1100_locate_flash(); ++ if (nr < 0) ++ return nr; ++ ++ ret = sa1100_setup_mtd(info, nr, &mymtd); ++ if (ret == 0) ++ sa1100_locate_partitions(mymtd); ++ ++ return ret; ++} ++ ++static void __exit sa1100_mtd_cleanup(void) ++{ ++ sa1100_destroy_mtd(info, mymtd); ++ sa1100_destroy_partitions(); + } + + module_init(sa1100_mtd_init); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/sbc8240.c linux/drivers/mtd/maps/sbc8240.c +--- linux-mips-2.4.27/drivers/mtd/maps/sbc8240.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/maps/sbc8240.c 2004-11-19 10:25:11.967189456 +0100 +@@ -0,0 +1,417 @@ ++/* ++ * Handle mapping of the flash memory access routines on the SBC8240 board. ++ * ++ * Carolyn Smith, Tektronix, Inc. ++ * ++ * This code is GPLed ++ * ++ * $Id: sbc8240.c,v 1.2 2003/09/30 19:37:00 thayne Exp $ ++ * ++ */ ++ ++/* ++ * The SBC8240 has 2 flash banks. ++ * Bank 0 is a 512 KiB AMD AM29F040B; 8 x 64 KiB sectors. ++ * It contains the U-Boot code (7 sectors) and the environment (1 sector). ++ * Bank 1 is 4 x 1 MiB AMD AM29LV800BT; 15 x 64 KiB sectors, 1 x 32 KiB sector, ++ * 2 x 8 KiB sectors, 1 x 16 KiB sectors. ++ * Both parts are JEDEC compatible. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#ifdef CONFIG_MTD_PARTITIONS ++#include ++#endif ++ ++#define DEBUG ++ ++#ifdef DEBUG ++# define debugk(fmt,args...) printk(fmt ,##args) ++#else ++# define debugk(fmt,args...) ++#endif ++ ++ ++#define WINDOW_ADDR0 0xFFF00000 /* 512 KiB */ ++#define WINDOW_SIZE0 0x00080000 ++#define BUSWIDTH0 1 ++ ++#define WINDOW_ADDR1 0xFF000000 /* 4 MiB */ ++#define WINDOW_SIZE1 0x00400000 ++#define BUSWIDTH1 8 ++ ++#define MSG_PREFIX "sbc8240:" /* prefix for our printk()'s */ ++#define MTDID "sbc8240-%d" /* for mtdparts= partitioning */ ++ ++ ++static __u8 sbc8240_read8 (struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readb(map->map_priv_1 + ofs); ++} ++ ++static __u16 sbc8240_read16 (struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readw(map->map_priv_1 + ofs); ++} ++ ++static __u32 sbc8240_read32 (struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readl(map->map_priv_1 + ofs); ++} ++ ++unsigned long long result64; ++ ++static __u64 sbc8240_read64 (struct map_info *map, unsigned long ofs) ++{ ++ unsigned long flags, msr, saved_msr; ++ volatile long saved_fr[2]; ++ volatile unsigned long long result; ++ volatile unsigned long *p; ++ ++ save_flags(flags); ++ cli(); ++ ++ /* turn off floating point unavailable exceptions */ ++ ++ __asm__ __volatile__ ( ++ "mfmsr %0" ++ : "=r" (msr) :); ++ ++ saved_msr = msr; ++ msr |= MSR_FP; ++ msr &= ~(MSR_FE0 | MSR_FE1); ++ ++ __asm__ __volatile__ ( ++ "mtmsr %0\n" ++ "isync\n" ++ : : "r" (msr)); ++ ++ /* read the data via a floating point register */ ++ ++ ofs = map->map_priv_1 + ofs; ++ p = (unsigned long *) &result64; ++ ++ __asm__ __volatile__ ( ++ "lfd 1,0(%1)\n" ++ "stfd 1,0(%0)\n" ++ : : "r" (p), "r" (ofs) ++ ); ++ ++ /* restore state */ ++ ++ __asm__ __volatile__ ( ++ "mtmsr %0\n" ++ "isync\n" ++ : : "r" (saved_msr)); ++ ++ restore_flags(flags); ++ ++ p = (unsigned long *) &result64; ++ debugk("sbc8240_read64 ofs 0x%x result 0x%08x%08x\n", ofs, *p, *(p+1)); ++ ++ return result64; ++} ++ ++static void sbc8240_copy_from (struct map_info *map, ++ void *to, unsigned long from, ssize_t len) ++{ ++ memcpy_fromio (to, (void *) (map->map_priv_1 + from), len); ++} ++ ++static void sbc8240_write8 (struct map_info *map, __u8 d, unsigned long adr) ++{ ++ __raw_writeb(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++static void sbc8240_write16 (struct map_info *map, __u16 d, ++ unsigned long adr) ++{ ++ __raw_writew(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++static void sbc8240_write32 (struct map_info *map, __u32 d, ++ unsigned long adr) ++{ ++ __raw_writel(d, map->map_priv_1 + adr); ++ mb(); ++} ++ ++static void sbc8240_write64 (struct map_info *map, __u64 data, ++ unsigned long adr) ++{ ++ unsigned long long tmp; ++ unsigned long flags, msr, saved_msr, *p; ++ volatile long saved_fr[2]; ++ ++ save_flags(flags); ++ cli(); ++ ++ /* turn off floating point unavailable exceptions */ ++ ++ __asm__ __volatile__ ( ++ "mfmsr %0" ++ : "=r" (msr) :); ++ ++ saved_msr = msr; ++ msr |= MSR_FP; ++ msr &= ~(MSR_FE0 | MSR_FE1); ++ ++ __asm__ __volatile__ ( ++ "mtmsr %0\n" ++ "isync\n" ++ : : "r" (msr)); ++ ++ ++ /* write the data via a floating point register */ ++ ++ tmp = data; ++ p = (unsigned long *) &tmp; ++ adr = map->map_priv_1 + adr; ++ debugk("sbc8240_write64 adr 0x%x data 0x%08x%08x\n", adr, *p, *(p+1)); ++ ++ __asm__ __volatile__ ( ++ "stfd 1,0(%2)\n" ++ "lfd 1,0(%0)\n" ++ "stfd 1,0(%1)\n" ++ "lfd 1,0(%2)\n" ++ : : "r" (p), "r" (adr), "b" (saved_fr) ++ ); ++ ++ /* restore state */ ++ ++ __asm__ __volatile__ ( ++ "mtmsr %0\n" ++ "isync\n" ++ : : "r" (saved_msr)); ++ ++ restore_flags(flags); ++} ++ ++static void sbc8240_copy_to (struct map_info *map, ++ unsigned long to, const void *from, ssize_t len) ++{ ++ memcpy_toio ((void *) (map->map_priv_1 + to), from, len); ++} ++ ++static struct map_info sbc8240_map[2] = { ++ { ++ .name = "sbc8240 Flash Bank #0", ++ .size = WINDOW_SIZE0, ++ .buswidth = BUSWIDTH0, ++ .read8 = sbc8240_read8, ++ .read16 = sbc8240_read16, ++ .read32 = sbc8240_read32, ++ .read64 = sbc8240_read64, ++ .copy_from = sbc8240_copy_from, ++ .write8 = sbc8240_write8, ++ .write16 = sbc8240_write16, ++ .write32 = sbc8240_write32, ++ .write64 = sbc8240_write64, ++ .copy_to = sbc8240_copy_to ++ }, ++ { ++ .name = "sbc8240 Flash Bank #1", ++ .size = WINDOW_SIZE1, ++ .buswidth = BUSWIDTH1, ++ .read8 = sbc8240_read8, ++ .read16 = sbc8240_read16, ++ .read32 = sbc8240_read32, ++ .read64 = sbc8240_read64, ++ .copy_from = sbc8240_copy_from, ++ .write8 = sbc8240_write8, ++ .write16 = sbc8240_write16, ++ .write32 = sbc8240_write32, ++ .write64 = sbc8240_write64, ++ .copy_to = sbc8240_copy_to ++ } ++}; ++ ++#define NUM_FLASH_BANKS (sizeof(sbc8240_map) / sizeof(struct map_info)) ++ ++/* ++ * The following defines the partition layout of SBC8240 boards. ++ * ++ * See include/linux/mtd/partitions.h for definition of the ++ * mtd_partition structure. ++ * ++ * The *_max_flash_size is the maximum possible mapped flash size ++ * which is not necessarily the actual flash size. It must correspond ++ * to the value specified in the mapping definition defined by the ++ * "struct map_desc *_io_desc" for the corresponding machine. ++ */ ++ ++#ifdef CONFIG_MTD_PARTITIONS ++ ++static struct mtd_partition sbc8240_uboot_partitions [] = { ++ /* Bank 0 */ ++ { ++ .name = "U-boot", /* U-Boot Firmware */ ++ .offset = 0, ++ .size = 0x00070000, /* 7 x 64 KiB sectors */ ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, ++ { ++ .name = "environment", /* U-Boot environment */ ++ .offset = 0x00070000, ++ .size = 0x00010000, /* 1 x 64 KiB sector */ ++ }, ++}; ++ ++static struct mtd_partition sbc8240_fs_partitions [] = { ++ { ++ .name = "jffs", /* JFFS filesystem */ ++ .offset = 0, ++ .size = 0x003C0000, /* 4 * 15 * 64KiB */ ++ }, ++ { ++ .name = "tmp32", ++ .offset = 0x003C0000, ++ .size = 0x00020000, /* 4 * 32KiB */ ++ }, ++ { ++ .name = "tmp8a", ++ .offset = 0x003E0000, ++ .size = 0x00008000, /* 4 * 8KiB */ ++ }, ++ { ++ .name = "tmp8b", ++ .offset = 0x003E8000, ++ .size = 0x00008000, /* 4 * 8KiB */ ++ }, ++ { ++ .name = "tmp16", ++ .offset = 0x003F0000, ++ .size = 0x00010000, /* 4 * 16KiB */ ++ } ++}; ++ ++#define NB_OF(x) (sizeof (x) / sizeof (x[0])) ++ ++/* trivial struct to describe partition information */ ++struct mtd_part_def ++{ ++ int nums; ++ unsigned char *type; ++ struct mtd_partition* mtd_part; ++}; ++ ++static struct mtd_info *sbc8240_mtd[NUM_FLASH_BANKS]; ++static struct mtd_part_def sbc8240_part_banks[NUM_FLASH_BANKS]; ++ ++ ++#endif /* CONFIG_MTD_PARTITIONS */ ++ ++ ++int __init init_sbc8240_mtd (void) ++{ ++ static struct _cjs { ++ u_long addr; ++ u_long size; ++ } pt[NUM_FLASH_BANKS] = { ++ { ++ .addr = WINDOW_ADDR0, ++ .size = WINDOW_SIZE0 ++ }, ++ { ++ .addr = WINDOW_ADDR1, ++ .size = WINDOW_SIZE1 ++ }, ++ }; ++ ++ int devicesfound = 0; ++ int i; ++ ++ for (i = 0; i < NUM_FLASH_BANKS; i++) { ++ printk (KERN_NOTICE MSG_PREFIX ++ "Probing 0x%08lx at 0x%08lx\n", pt[i].size, pt[i].addr); ++ ++ sbc8240_map[i].map_priv_1 = ++ (unsigned long) ioremap (pt[i].addr, pt[i].size); ++ if (!sbc8240_map[i].map_priv_1) { ++ printk (MSG_PREFIX "failed to ioremap\n"); ++ return -EIO; ++ } ++ ++ sbc8240_mtd[i] = do_map_probe("jedec_probe", &sbc8240_map[i]); ++ ++ if (sbc8240_mtd[i]) { ++ sbc8240_mtd[i]->module = THIS_MODULE; ++ devicesfound++; ++ } ++ } ++ ++ if (!devicesfound) { ++ printk(KERN_NOTICE MSG_PREFIX ++ "No suppported flash chips found!\n"); ++ return -ENXIO; ++ } ++ ++#ifdef CONFIG_MTD_PARTITIONS ++ sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions; ++ sbc8240_part_banks[0].type = "static image"; ++ sbc8240_part_banks[0].nums = NB_OF(sbc8240_uboot_partitions); ++ sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions; ++ sbc8240_part_banks[1].type = "static file system"; ++ sbc8240_part_banks[1].nums = NB_OF(sbc8240_fs_partitions); ++ ++ for (i = 0; i < NUM_FLASH_BANKS; i++) { ++ ++ if (!sbc8240_mtd[i]) continue; ++ if (sbc8240_part_banks[i].nums == 0) { ++ printk (KERN_NOTICE MSG_PREFIX ++ "No partition info available, registering whole device\n"); ++ add_mtd_device(sbc8240_mtd[i]); ++ } else { ++ printk (KERN_NOTICE MSG_PREFIX ++ "Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name); ++ add_mtd_partitions (sbc8240_mtd[i], ++ sbc8240_part_banks[i].mtd_part, ++ sbc8240_part_banks[i].nums); ++ } ++ } ++#else ++ printk(KERN_NOTICE MSG_PREFIX ++ "Registering %d flash banks at once\n", devicesfound); ++ ++ for (i = 0; i < devicesfound; i++) { ++ add_mtd_device(sbc8240_mtd[i]); ++ } ++#endif /* CONFIG_MTD_PARTITIONS */ ++ ++ return devicesfound == 0 ? -ENXIO : 0; ++} ++ ++static void __exit cleanup_sbc8240_mtd (void) ++{ ++ int i; ++ ++ for (i = 0; i < NUM_FLASH_BANKS; i++) { ++ if (sbc8240_mtd[i]) { ++ del_mtd_device (sbc8240_mtd[i]); ++ map_destroy (sbc8240_mtd[i]); ++ } ++ if (sbc8240_map[i].map_priv_1) { ++ iounmap ((void *) sbc8240_map[i].map_priv_1); ++ sbc8240_map[i].map_priv_1 = 0; ++ } ++ } ++} ++ ++module_init (init_sbc8240_mtd); ++module_exit (cleanup_sbc8240_mtd); ++ ++MODULE_LICENSE ("GPL"); ++MODULE_AUTHOR ("Carolyn Smith "); ++MODULE_DESCRIPTION ("MTD map driver for SBC8240 boards"); ++ +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/sbc_gxx.c linux/drivers/mtd/maps/sbc_gxx.c +--- linux-mips-2.4.27/drivers/mtd/maps/sbc_gxx.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/maps/sbc_gxx.c 2004-11-19 10:25:11.969189152 +0100 +@@ -17,7 +17,7 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +- $Id: sbc_gxx.c,v 1.21 2003/01/24 13:40:14 dwmw2 Exp $ ++ $Id: sbc_gxx.c,v 1.26 2003/05/26 08:50:36 dwmw2 Exp $ + + The SBC-MediaGX / SBC-GXx has up to 16 MiB of + Intel StrataFlash (28F320/28F640) in x8 mode. +@@ -91,14 +91,14 @@ + * single flash device into. If the size if zero we use up to the end of the + * device. */ + static struct mtd_partition partition_info[]={ +- { name: "SBC-GXx flash boot partition", +- offset: 0, +- size: BOOT_PARTITION_SIZE_KiB*1024 }, +- { name: "SBC-GXx flash data partition", +- offset: BOOT_PARTITION_SIZE_KiB*1024, +- size: (DATA_PARTITION_SIZE_KiB)*1024 }, +- { name: "SBC-GXx flash application partition", +- offset: (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 } ++ { .name = "SBC-GXx flash boot partition", ++ .offset = 0, ++ .size = BOOT_PARTITION_SIZE_KiB*1024 }, ++ { .name = "SBC-GXx flash data partition", ++ .offset = BOOT_PARTITION_SIZE_KiB*1024, ++ .size = (DATA_PARTITION_SIZE_KiB)*1024 }, ++ { .name = "SBC-GXx flash application partition", ++ .offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 } + }; + + #define NUM_PARTITIONS 3 +@@ -203,19 +203,20 @@ + } + + static struct map_info sbc_gxx_map = { +- name: "SBC-GXx flash", +- size: MAX_SIZE_KiB*1024, /* this must be set to a maximum possible amount ++ .name = "SBC-GXx flash", ++ .phys = NO_XIP, ++ .size = MAX_SIZE_KiB*1024, /* this must be set to a maximum possible amount + of flash so the cfi probe routines find all + the chips */ +- buswidth: 1, +- read8: sbc_gxx_read8, +- read16: sbc_gxx_read16, +- read32: sbc_gxx_read32, +- copy_from: sbc_gxx_copy_from, +- write8: sbc_gxx_write8, +- write16: sbc_gxx_write16, +- write32: sbc_gxx_write32, +- copy_to: sbc_gxx_copy_to ++ .buswidth = 1, ++ .read8 = sbc_gxx_read8, ++ .read16 = sbc_gxx_read16, ++ .read32 = sbc_gxx_read32, ++ .copy_from = sbc_gxx_copy_from, ++ .write8 = sbc_gxx_write8, ++ .write16 = sbc_gxx_write16, ++ .write32 = sbc_gxx_write32, ++ .copy_to = sbc_gxx_copy_to + }; + + /* MTD device for all of the flash. */ +@@ -234,12 +235,6 @@ + + int __init init_sbc_gxx(void) + { +- if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) { +- printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n", +- sbc_gxx_map.name, +- PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 ); +- return -EAGAIN; +- } + iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH); + if (!iomapadr) { + printk( KERN_ERR"%s: failed to ioremap memory region\n", +@@ -247,7 +242,14 @@ + return -EIO; + } + +- request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash" ); ++ if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) { ++ printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n", ++ sbc_gxx_map.name, ++ PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 ); ++ iounmap((void *)iomapadr); ++ return -EAGAIN; ++ } ++ + + printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n", + sbc_gxx_map.name, +@@ -261,7 +263,7 @@ + return -ENXIO; + } + +- all_mtd->module=THIS_MODULE; ++ all_mtd->owner = THIS_MODULE; + + /* Create MTD devices for each partition. */ + add_mtd_partitions(all_mtd, partition_info, NUM_PARTITIONS ); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/sc520cdp.c linux/drivers/mtd/maps/sc520cdp.c +--- linux-mips-2.4.27/drivers/mtd/maps/sc520cdp.c 2002-06-27 00:35:50.000000000 +0200 ++++ linux/drivers/mtd/maps/sc520cdp.c 2004-11-19 10:25:11.970189000 +0100 +@@ -16,7 +16,7 @@ + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * +- * $Id: sc520cdp.c,v 1.11 2002/03/08 16:34:35 rkaiser Exp $ ++ * $Id: sc520cdp.c,v 1.15 2003/05/21 12:45:20 dwmw2 Exp $ + * + * + * The SC520CDP is an evaluation board for the Elan SC520 processor available +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -84,88 +85,25 @@ + #define WINDOW_SIZE_1 0x00800000 + #define WINDOW_SIZE_2 0x00080000 + +-static __u8 sc520cdp_read8(struct map_info *map, unsigned long ofs) +-{ +- return readb(map->map_priv_1 + ofs); +-} +- +-static __u16 sc520cdp_read16(struct map_info *map, unsigned long ofs) +-{ +- return readw(map->map_priv_1 + ofs); +-} +- +-static __u32 sc520cdp_read32(struct map_info *map, unsigned long ofs) +-{ +- return readl(map->map_priv_1 + ofs); +-} +- +-static void sc520cdp_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len); +-} +- +-static void sc520cdp_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- writeb(d, map->map_priv_1 + adr); +-} +- +-static void sc520cdp_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- writew(d, map->map_priv_1 + adr); +-} +- +-static void sc520cdp_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- writel(d, map->map_priv_1 + adr); +-} +- +-static void sc520cdp_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio((void *)(map->map_priv_1 + to), from, len); +-} + + static struct map_info sc520cdp_map[] = { + { +- name: "SC520CDP Flash Bank #0", +- size: WINDOW_SIZE_0, +- buswidth: 4, +- read8: sc520cdp_read8, +- read16: sc520cdp_read16, +- read32: sc520cdp_read32, +- copy_from: sc520cdp_copy_from, +- write8: sc520cdp_write8, +- write16: sc520cdp_write16, +- write32: sc520cdp_write32, +- copy_to: sc520cdp_copy_to, +- map_priv_2: WINDOW_ADDR_0 ++ .name = "SC520CDP Flash Bank #0", ++ .size = WINDOW_SIZE_0, ++ .buswidth = 4, ++ .phys = WINDOW_ADDR_0 + }, + { +- name: "SC520CDP Flash Bank #1", +- size: WINDOW_SIZE_1, +- buswidth: 4, +- read8: sc520cdp_read8, +- read16: sc520cdp_read16, +- read32: sc520cdp_read32, +- copy_from: sc520cdp_copy_from, +- write8: sc520cdp_write8, +- write16: sc520cdp_write16, +- write32: sc520cdp_write32, +- copy_to: sc520cdp_copy_to, +- map_priv_2: WINDOW_ADDR_1 ++ .name = "SC520CDP Flash Bank #1", ++ .size = WINDOW_SIZE_1, ++ .buswidth = 4, ++ .phys = WINDOW_ADDR_1 + }, + { +- name: "SC520CDP DIL Flash", +- size: WINDOW_SIZE_2, +- buswidth: 1, +- read8: sc520cdp_read8, +- read16: sc520cdp_read16, +- read32: sc520cdp_read32, +- copy_from: sc520cdp_copy_from, +- write8: sc520cdp_write8, +- write16: sc520cdp_write16, +- write32: sc520cdp_write32, +- copy_to: sc520cdp_copy_to, +- map_priv_2: WINDOW_ADDR_2 ++ .name = "SC520CDP DIL Flash", ++ .size = WINDOW_SIZE_2, ++ .buswidth = 1, ++ .phys = WINDOW_ADDR_2 + }, + }; + +@@ -255,9 +193,9 @@ + /* map in SC520's MMCR area */ + mmcr = (unsigned long *)ioremap_nocache(SC520_MMCR_BASE, SC520_MMCR_EXTENT); + if(!mmcr) { /* ioremap_nocache failed: skip the PAR reprogramming */ +- /* force map_priv_2 fields to BIOS defaults: */ ++ /* force physical address fields to BIOS defaults: */ + for(i = 0; i < NUM_FLASH_BANKS; i++) +- sc520cdp_map[i].map_priv_2 = par_table[i].default_address; ++ sc520cdp_map[i].phys = par_table[i].default_address; + return; + } + +@@ -282,7 +220,7 @@ + sc520cdp_map[i].name); + printk(KERN_NOTICE "Trying default address 0x%lx\n", + par_table[i].default_address); +- sc520cdp_map[i].map_priv_2 = par_table[i].default_address; ++ sc520cdp_map[i].phys = par_table[i].default_address; + } + } + iounmap((void *)mmcr); +@@ -300,13 +238,18 @@ + #endif + + for (i = 0; i < NUM_FLASH_BANKS; i++) { +- printk(KERN_NOTICE "SC520 CDP flash device: %lx at %lx\n", sc520cdp_map[i].size, sc520cdp_map[i].map_priv_2); +- sc520cdp_map[i].map_priv_1 = (unsigned long)ioremap_nocache(sc520cdp_map[i].map_priv_2, sc520cdp_map[i].size); ++ printk(KERN_NOTICE "SC520 CDP flash device: 0x%lx at 0x%lx\n", ++ sc520cdp_map[i].size, sc520cdp_map[i].phys); + +- if (!sc520cdp_map[i].map_priv_1) { ++ sc520cdp_map[i].virt = (unsigned long)ioremap_nocache(sc520cdp_map[i].phys, sc520cdp_map[i].size); ++ ++ if (!sc520cdp_map[i].virt) { + printk("Failed to ioremap_nocache\n"); + return -EIO; + } ++ ++ simple_map_init(&sc520cdp_map[i]); ++ + mymtd[i] = do_map_probe("cfi_probe", &sc520cdp_map[i]); + if(!mymtd[i]) + mymtd[i] = do_map_probe("jedec_probe", &sc520cdp_map[i]); +@@ -314,11 +257,11 @@ + mymtd[i] = do_map_probe("map_rom", &sc520cdp_map[i]); + + if (mymtd[i]) { +- mymtd[i]->module = THIS_MODULE; ++ mymtd[i]->owner = THIS_MODULE; + ++devices_found; + } + else { +- iounmap((void *)sc520cdp_map[i].map_priv_1); ++ iounmap((void *)sc520cdp_map[i].virt); + } + } + if(devices_found >= 2) { +@@ -346,9 +289,9 @@ + for (i = 0; i < NUM_FLASH_BANKS; i++) { + if (mymtd[i]) + map_destroy(mymtd[i]); +- if (sc520cdp_map[i].map_priv_1) { +- iounmap((void *)sc520cdp_map[i].map_priv_1); +- sc520cdp_map[i].map_priv_1 = 0; ++ if (sc520cdp_map[i].virt) { ++ iounmap((void *)sc520cdp_map[i].virt); ++ sc520cdp_map[i].virt = 0; + } + } + } +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/scb2_flash.c linux/drivers/mtd/maps/scb2_flash.c +--- linux-mips-2.4.27/drivers/mtd/maps/scb2_flash.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/maps/scb2_flash.c 2004-11-19 10:25:11.972188696 +0100 +@@ -1,6 +1,6 @@ + /* + * MTD map driver for BIOS Flash on Intel SCB2 boards +- * $Id: scb2_flash.c,v 1.2 2003/01/24 13:09:56 dwmw2 Exp $ ++ * $Id: scb2_flash.c,v 1.6 2003/05/21 12:45:20 dwmw2 Exp $ + * Copyright (C) 2002 Sun Microsystems, Inc. + * Tim Hockin + * +@@ -14,7 +14,7 @@ + * try to request it here, but if it fails, we carry on anyway. + * + * This is how the chip is attached, so said the schematic: +- * * a 4 MiB (32 Mb) 16 bit chip ++ * * a 4 MiB (32 Mib) 16 bit chip + * * a 1 MiB memory region + * * A20 and A21 pulled up + * * D8-D15 ignored +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -60,65 +61,13 @@ + #define SCB2_ADDR 0xfff00000 + #define SCB2_WINDOW 0x00100000 + +-static __u8 scb2_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-static __u16 scb2_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} +- +-static __u32 scb2_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} +- +-static void scb2_copy_from(struct map_info *map, void *to, +- unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-static void scb2_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-static void scb2_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-static void scb2_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} +- +-static void scb2_copy_to(struct map_info *map, unsigned long to, +- const void *from, ssize_t len) +-{ +- memcpy_toio(map->map_priv_1 + to, from, len); +-} + + static void *scb2_ioaddr; + static struct mtd_info *scb2_mtd; + struct map_info scb2_map = { +- name: "SCB2 BIOS Flash", +- size: 0, +- buswidth: 1, +- read8: scb2_read8, +- read16: scb2_read16, +- read32: scb2_read32, +- copy_from: scb2_copy_from, +- write8: scb2_write8, +- write16: scb2_write16, +- write32: scb2_write32, +- copy_to: scb2_copy_to, ++ .name = "SCB2 BIOS Flash", ++ .size = 0, ++ .buswidth = 1, + }; + static int region_fail; + +@@ -137,6 +86,8 @@ + return -1; + } + ++ /* I wasn't here. I didn't see. dwmw2. */ ++ + /* the chip is sometimes bigger than the map - what a waste */ + mtd->size = map->size; + +@@ -211,9 +162,12 @@ + return -ENOMEM; + } + +- scb2_map.map_priv_1 = (unsigned long)scb2_ioaddr; ++ scb2_map.phys = SCB2_ADDR; ++ scb2_map.virt = (unsigned long)scb2_ioaddr; + scb2_map.size = SCB2_WINDOW; + ++ simple_map_init(&scb2_map); ++ + /* try to find a chip */ + scb2_mtd = do_map_probe("cfi_probe", &scb2_map); + +@@ -225,7 +179,7 @@ + return -ENODEV; + } + +- scb2_mtd->module = THIS_MODULE; ++ scb2_mtd->owner = THIS_MODULE; + if (scb2_fixup_mtd(scb2_mtd) < 0) { + del_mtd_device(scb2_mtd); + map_destroy(scb2_mtd); +@@ -235,7 +189,7 @@ + return -ENODEV; + } + +- printk(KERN_NOTICE MODNAME ": chip size %x at offset %x\n", ++ printk(KERN_NOTICE MODNAME ": chip size 0x%x at offset 0x%x\n", + scb2_mtd->size, SCB2_WINDOW - scb2_mtd->size); + + add_mtd_device(scb2_mtd); +@@ -266,19 +220,19 @@ + + static struct pci_device_id scb2_flash_pci_ids[] __devinitdata = { + { +- vendor: PCI_VENDOR_ID_SERVERWORKS, +- device: PCI_DEVICE_ID_SERVERWORKS_CSB5, +- subvendor: PCI_ANY_ID, +- subdevice: PCI_ANY_ID ++ .vendor = PCI_VENDOR_ID_SERVERWORKS, ++ .device = PCI_DEVICE_ID_SERVERWORKS_CSB5, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID + }, + { 0, } + }; + + static struct pci_driver scb2_flash_driver = { +- name: "Intel SCB2 BIOS Flash", +- id_table: scb2_flash_pci_ids, +- probe: scb2_flash_probe, +- remove: __devexit_p(scb2_flash_remove), ++ .name = "Intel SCB2 BIOS Flash", ++ .id_table = scb2_flash_pci_ids, ++ .probe = scb2_flash_probe, ++ .remove = __devexit_p(scb2_flash_remove), + }; + + static int __init +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/scx200_docflash.c linux/drivers/mtd/maps/scx200_docflash.c +--- linux-mips-2.4.27/drivers/mtd/maps/scx200_docflash.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/maps/scx200_docflash.c 2004-11-19 10:25:11.973188544 +0100 +@@ -2,7 +2,7 @@ + + Copyright (c) 2001,2002 Christer Weinigel + +- $Id: scx200_docflash.c,v 1.1 2003/01/24 13:20:40 dwmw2 Exp $ ++ $Id: scx200_docflash.c,v 1.5 2003/05/21 12:45:20 dwmw2 Exp $ + + National Semiconductor SCx200 flash mapped with DOCCS + */ +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -75,46 +76,9 @@ + #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) + #endif + +-static __u8 scx200_docflash_read8(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readb(map->map_priv_1 + ofs); +-} +- +-static __u16 scx200_docflash_read16(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readw(map->map_priv_1 + ofs); +-} +- +-static void scx200_docflash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-static void scx200_docflash_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +- mb(); +-} +- +-static void scx200_docflash_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +- mb(); +-} +- +-static void scx200_docflash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio(map->map_priv_1 + to, from, len); +-} + + static struct map_info scx200_docflash_map = { + .name = "NatSemi SCx200 DOCCS Flash", +- .read8 = scx200_docflash_read8, +- .read16 = scx200_docflash_read16, +- .copy_from = scx200_docflash_copy_from, +- .write8 = scx200_docflash_write8, +- .write16 = scx200_docflash_write16, +- .copy_to = scx200_docflash_copy_to + }; + + int __init init_scx200_docflash(void) +@@ -213,8 +177,11 @@ + else + scx200_docflash_map.buswidth = 2; + +- scx200_docflash_map.map_priv_1 = (unsigned long)ioremap(docmem.start, scx200_docflash_map.size); +- if (!scx200_docflash_map.map_priv_1) { ++ simple_map_init(&scx200_docflash_map); ++ ++ scx200_docflash_map.phys = docmem.start; ++ scx200_docflash_map.virt = (unsigned long)ioremap(docmem.start, scx200_docflash_map.size); ++ if (!scx200_docflash_map.virt) { + printk(KERN_ERR NAME ": failed to ioremap the flash\n"); + release_resource(&docmem); + return -EIO; +@@ -223,7 +190,7 @@ + mymtd = do_map_probe(flashtype, &scx200_docflash_map); + if (!mymtd) { + printk(KERN_ERR NAME ": unable to detect flash\n"); +- iounmap((void *)scx200_docflash_map.map_priv_1); ++ iounmap((void *)scx200_docflash_map.virt); + release_resource(&docmem); + return -ENXIO; + } +@@ -231,7 +198,7 @@ + if (size < mymtd->size) + printk(KERN_WARNING NAME ": warning, flash mapping is smaller than flash size\n"); + +- mymtd->module = THIS_MODULE; ++ mymtd->owner = THIS_MODULE; + + #if PARTITION + partition_info[3].offset = mymtd->size-partition_info[3].size; +@@ -253,8 +220,8 @@ + #endif + map_destroy(mymtd); + } +- if (scx200_docflash_map.map_priv_1) { +- iounmap((void *)scx200_docflash_map.map_priv_1); ++ if (scx200_docflash_map.virt) { ++ iounmap((void *)scx200_docflash_map.virt); + release_resource(&docmem); + } + } +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/solutionengine.c linux/drivers/mtd/maps/solutionengine.c +--- linux-mips-2.4.27/drivers/mtd/maps/solutionengine.c 2002-06-27 00:35:50.000000000 +0200 ++++ linux/drivers/mtd/maps/solutionengine.c 2004-11-19 10:25:11.975188240 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: solutionengine.c,v 1.4 2001/11/07 01:20:59 jsiegel Exp $ ++ * $Id: solutionengine.c,v 1.10 2003/05/21 12:45:20 dwmw2 Exp $ + * + * Flash and EPROM on Hitachi Solution Engine and similar boards. + * +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -18,60 +19,39 @@ + #include + + +-extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); +- +-__u32 soleng_read32(struct map_info *map, unsigned long ofs) +-{ +- return __raw_readl(map->map_priv_1 + ofs); +-} +- +-void soleng_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +- mb(); +-} +- +-void soleng_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +- + static struct mtd_info *flash_mtd; + static struct mtd_info *eprom_mtd; + + static struct mtd_partition *parsed_parts; + + struct map_info soleng_eprom_map = { +- name: "Solution Engine EPROM", +- size: 0x400000, +- buswidth: 4, +- copy_from: soleng_copy_from, ++ .name = "Solution Engine EPROM", ++ .size = 0x400000, ++ .buswidth = 4, + }; + + struct map_info soleng_flash_map = { +- name: "Solution Engine FLASH", +- size: 0x400000, +- buswidth: 4, +- read32: soleng_read32, +- copy_from: soleng_copy_from, +- write32: soleng_write32, ++ .name = "Solution Engine FLASH", ++ .size = 0x400000, ++ .buswidth = 4, + }; + ++static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; ++ + #ifdef CONFIG_MTD_SUPERH_RESERVE + static struct mtd_partition superh_se_partitions[] = { + /* Reserved for boot code, read-only */ + { +- name: "flash_boot", +- offset: 0x00000000, +- size: CONFIG_MTD_SUPERH_RESERVE, +- mask_flags: MTD_WRITEABLE, ++ .name = "flash_boot", ++ .offset = 0x00000000, ++ .size = CONFIG_MTD_SUPERH_RESERVE, ++ .mask_flags = MTD_WRITEABLE, + }, + /* All else is writable (e.g. JFFS) */ + { +- name: "Flash FS", +- offset: MTDPART_OFS_NXTBLK, +- size: MTDPART_SIZ_FULL, ++ .name = "Flash FS", ++ .offset = MTDPART_OFS_NXTBLK, ++ .size = MTDPART_SIZ_FULL, + } + }; + #endif /* CONFIG_MTD_SUPERH_RESERVE */ +@@ -81,16 +61,22 @@ + int nr_parts = 0; + + /* First probe at offset 0 */ +- soleng_flash_map.map_priv_1 = P2SEGADDR(0); +- soleng_eprom_map.map_priv_1 = P1SEGADDR(0x01000000); ++ soleng_flash_map.phys = 0; ++ soleng_flash_map.virt = P2SEGADDR(0); ++ soleng_eprom_map.phys = 0x01000000; ++ soleng_eprom_map.virt = P1SEGADDR(0x01000000); ++ simple_map_init(&soleng_eprom_map); ++ simple_map_init(&soleng_flash_map); + + printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n"); + flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map); + if (!flash_mtd) { + /* Not there. Try swapping */ + printk(KERN_NOTICE "Probing for flash chips at 0x01000000:\n"); +- soleng_flash_map.map_priv_1 = P2SEGADDR(0x01000000); +- soleng_eprom_map.map_priv_1 = P1SEGADDR(0); ++ soleng_flash_map.phys = 0x01000000; ++ soleng_flash_map.virt = P2SEGADDR(0x01000000); ++ soleng_eprom_map.phys = 0; ++ soleng_eprom_map.virt = P1SEGADDR(0); + flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map); + if (!flash_mtd) { + /* Eep. */ +@@ -99,25 +85,20 @@ + } + } + printk(KERN_NOTICE "Solution Engine: Flash at 0x%08lx, EPROM at 0x%08lx\n", +- soleng_flash_map.map_priv_1 & 0x1fffffff, +- soleng_eprom_map.map_priv_1 & 0x1fffffff); +- flash_mtd->module = THIS_MODULE; ++ soleng_flash_map.phys & 0x1fffffff, ++ soleng_eprom_map.phys & 0x1fffffff); ++ flash_mtd->owner = THIS_MODULE; + + eprom_mtd = do_map_probe("map_rom", &soleng_eprom_map); + if (eprom_mtd) { +- eprom_mtd->module = THIS_MODULE; ++ eprom_mtd->owner = THIS_MODULE; + add_mtd_device(eprom_mtd); + } + +-#ifdef CONFIG_MTD_REDBOOT_PARTS +- nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts); +- if (nr_parts > 0) +- printk(KERN_NOTICE "Found RedBoot partition table.\n"); +- else if (nr_parts < 0) +- printk(KERN_NOTICE "Error looking for RedBoot partitions.\n"); +-#endif /* CONFIG_MTD_REDBOOT_PARTS */ ++ nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0); ++ + #if CONFIG_MTD_SUPERH_RESERVE +- if (nr_parts == 0) { ++ if (nr_parts <= 0) { + printk(KERN_NOTICE "Using configured partition at 0x%08x.\n", + CONFIG_MTD_SUPERH_RESERVE); + parsed_parts = superh_se_partitions; +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/sun_uflash.c linux/drivers/mtd/maps/sun_uflash.c +--- linux-mips-2.4.27/drivers/mtd/maps/sun_uflash.c 2001-11-05 21:15:52.000000000 +0100 ++++ linux/drivers/mtd/maps/sun_uflash.c 2004-11-19 10:25:11.976188088 +0100 +@@ -1,4 +1,4 @@ +-/* $Id: sun_uflash.c,v 1.4 2001/10/02 15:05:14 dwmw2 Exp $ ++/* $Id: sun_uflash.c,v 1.7 2003/05/20 20:59:32 dwmw2 Exp $ + * + * sun_uflash - Driver implementation for user-programmable flash + * present on many Sun Microsystems SME boardsets. +@@ -48,60 +48,11 @@ + struct list_head list; + }; + +-__u8 uflash_read8(struct map_info *map, unsigned long ofs) +-{ +- return(__raw_readb(map->map_priv_1 + ofs)); +-} +- +-__u16 uflash_read16(struct map_info *map, unsigned long ofs) +-{ +- return(__raw_readw(map->map_priv_1 + ofs)); +-} +- +-__u32 uflash_read32(struct map_info *map, unsigned long ofs) +-{ +- return(__raw_readl(map->map_priv_1 + ofs)); +-} +- +-void uflash_copy_from(struct map_info *map, void *to, unsigned long from, +- ssize_t len) +-{ +- memcpy_fromio(to, map->map_priv_1 + from, len); +-} +- +-void uflash_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- __raw_writeb(d, map->map_priv_1 + adr); +-} +- +-void uflash_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- __raw_writew(d, map->map_priv_1 + adr); +-} +- +-void uflash_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- __raw_writel(d, map->map_priv_1 + adr); +-} +- +-void uflash_copy_to(struct map_info *map, unsigned long to, const void *from, +- ssize_t len) +-{ +- memcpy_toio(map->map_priv_1 + to, from, len); +-} + + struct map_info uflash_map_templ = { +- name: "SUNW,???-????", +- size: UFLASH_WINDOW_SIZE, +- buswidth: UFLASH_BUSWIDTH, +- read8: uflash_read8, +- read16: uflash_read16, +- read32: uflash_read32, +- copy_from: uflash_copy_from, +- write8: uflash_write8, +- write16: uflash_write16, +- write32: uflash_write32, +- copy_to: uflash_copy_to ++ .name = "SUNW,???-????", ++ .size = UFLASH_WINDOW_SIZE, ++ .buswidth = UFLASH_BUSWIDTH, + }; + + int uflash_devinit(struct linux_ebus_device* edev) +@@ -145,20 +96,22 @@ + if(0 != pdev->name && 0 < strlen(pdev->name)) { + pdev->map.name = pdev->name; + } +- +- pdev->map.map_priv_1 = ++ pdev->phys = edev->resource[0].start; ++ pdev->virt = + (unsigned long)ioremap_nocache(edev->resource[0].start, pdev->map.size); +- if(0 == pdev->map.map_priv_1) { ++ if(0 == pdev->map.virt) { + printk("%s: failed to map device\n", __FUNCTION__); + kfree(pdev->name); + kfree(pdev); + return(-1); + } + ++ simple_map_init(&pdev->map); ++ + /* MTD registration */ + pdev->mtd = do_map_probe("cfi_probe", &pdev->map); + if(0 == pdev->mtd) { +- iounmap((void *)pdev->map.map_priv_1); ++ iounmap((void *)pdev->map.virt); + kfree(pdev->name); + kfree(pdev); + return(-ENXIO); +@@ -166,7 +119,7 @@ + + list_add(&pdev->list, &device_list); + +- pdev->mtd->module = THIS_MODULE; ++ pdev->mtd->owner = THIS_MODULE; + + add_mtd_device(pdev->mtd); + return(0); +@@ -211,9 +164,9 @@ + del_mtd_device(udev->mtd); + map_destroy(udev->mtd); + } +- if(0 != udev->map.map_priv_1) { +- iounmap((void*)udev->map.map_priv_1); +- udev->map.map_priv_1 = 0; ++ if(0 != udev->map.virt) { ++ iounmap((void*)udev->map.virt); ++ udev->map.virt = 0; + } + if(0 != udev->name) { + kfree(udev->name); +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/tqm8xxl.c linux/drivers/mtd/maps/tqm8xxl.c +--- linux-mips-2.4.27/drivers/mtd/maps/tqm8xxl.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/maps/tqm8xxl.c 2004-11-19 10:25:11.978187784 +0100 +@@ -2,7 +2,7 @@ + * Handle mapping of the flash memory access routines + * on TQM8xxL based devices. + * +- * $Id: tqm8xxl.c,v 1.4 2002/06/20 13:41:20 mag Exp $ ++ * $Id: tqm8xxl.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $ + * + * based on rpxlite.c + * +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -51,46 +52,6 @@ + static unsigned long num_banks; + static unsigned long start_scan_addr; + +-__u8 tqm8xxl_read8(struct map_info *map, unsigned long ofs) +-{ +- return *((__u8 *)(map->map_priv_1 + ofs)); +-} +- +-__u16 tqm8xxl_read16(struct map_info *map, unsigned long ofs) +-{ +- return *((__u16 *)(map->map_priv_1 + ofs)); +-} +- +-__u32 tqm8xxl_read32(struct map_info *map, unsigned long ofs) +-{ +- return *((__u32 *)(map->map_priv_1 + ofs)); +-} +- +-void tqm8xxl_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len); +-} +- +-void tqm8xxl_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- *((__u8 *)(map->map_priv_1 + adr)) = d; +-} +- +-void tqm8xxl_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- *((__u16 *)( map->map_priv_1 + adr)) = d; +-} +- +-void tqm8xxl_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- *((__u32 *)(map->map_priv_1 + adr)) = d; +-} +- +-void tqm8xxl_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy_toio((void *)(map->map_priv_1 + to), from, len); +-} +- + /* + * Here are partition information for all known TQM8xxL series devices. + * See include/linux/mtd/partitions.h for definition of the mtd_partition +@@ -107,50 +68,48 @@ + static unsigned long tqm8xxl_max_flash_size = 0x00800000; + + /* partition definition for first flash bank +- * also ref. to "drivers\char\flash_config.c" ++ * (cf. "drivers/char/flash_config.c") + */ + static struct mtd_partition tqm8xxl_partitions[] = { + { +- name: "ppcboot", +- offset: 0x00000000, +- size: 0x00020000, /* 128KB */ +- mask_flags: MTD_WRITEABLE, /* force read-only */ ++ .name = "ppcboot", ++ .offset = 0x00000000, ++ .size = 0x00020000, /* 128KB */ ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { +- name: "kernel", /* default kernel image */ +- offset: 0x00020000, +- size: 0x000e0000, +- mask_flags: MTD_WRITEABLE, /* force read-only */ ++ .name = "kernel", /* default kernel image */ ++ .offset = 0x00020000, ++ .size = 0x000e0000, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { +- name: "user", +- offset: 0x00100000, +- size: 0x00100000, ++ .name = "user", ++ .offset = 0x00100000, ++ .size = 0x00100000, + }, + { +- name: "initrd", +- offset: 0x00200000, +- size: 0x00200000, ++ .name = "initrd", ++ .offset = 0x00200000, ++ .size = 0x00200000, + } + }; +-/* partition definition for second flahs bank */ ++/* partition definition for second flash bank */ + static struct mtd_partition tqm8xxl_fs_partitions[] = { + { +- name: "cramfs", +- offset: 0x00000000, +- size: 0x00200000, ++ .name = "cramfs", ++ .offset = 0x00000000, ++ .size = 0x00200000, + }, + { +- name: "jffs", +- offset: 0x00200000, +- size: 0x00200000, +- //size: MTDPART_SIZ_FULL, ++ .name = "jffs", ++ .offset = 0x00200000, ++ .size = 0x00200000, ++ .//size = MTDPART_SIZ_FULL, + } + }; + #endif + +-#define NB_OF(x) (sizeof(x)/sizeof(x[0])) +- + int __init init_tqm_mtd(void) + { + int idx = 0, ret = 0; +@@ -160,67 +119,73 @@ + + flash_addr = bd->bi_flashstart; + flash_size = bd->bi_flashsize; +- //request maximum flash size address spzce ++ ++ //request maximum flash size address space + start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size); + if (!start_scan_addr) { +- //printk("%s:Failed to ioremap address:0x%x\n", __FUNCTION__, FLASH_ADDR); +- printk("%s:Failed to ioremap address:0x%x\n", __FUNCTION__, flash_addr); ++ printk(KERN_WARNING "%s:Failed to ioremap address:0x%x\n", __FUNCTION__, flash_addr); + return -EIO; + } +- for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) +- { ++ ++ for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) { + if(mtd_size >= flash_size) + break; + +- printk("%s: chip probing count %d\n", __FUNCTION__, idx); ++ printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx); + + map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL); +- if(map_banks[idx] == NULL) +- { +- //return -ENOMEM; ++ if(map_banks[idx] == NULL) { + ret = -ENOMEM; ++ /* FIXME: What if some MTD devices were probed already? */ + goto error_mem; + } ++ + memset((void *)map_banks[idx], 0, sizeof(struct map_info)); + map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL); +- if(map_banks[idx]->name == NULL) +- { +- //return -ENOMEM; ++ ++ if (!map_banks[idx]->name) { + ret = -ENOMEM; ++ /* FIXME: What if some MTD devices were probed already? */ + goto error_mem; + } +- memset((void *)map_banks[idx]->name, 0, 16); +- + sprintf(map_banks[idx]->name, "TQM8xxL%d", idx); ++ + map_banks[idx]->size = flash_size; + map_banks[idx]->buswidth = 4; +- map_banks[idx]->read8 = tqm8xxl_read8; +- map_banks[idx]->read16 = tqm8xxl_read16; +- map_banks[idx]->read32 = tqm8xxl_read32; +- map_banks[idx]->copy_from = tqm8xxl_copy_from; +- map_banks[idx]->write8 = tqm8xxl_write8; +- map_banks[idx]->write16 = tqm8xxl_write16; +- map_banks[idx]->write32 = tqm8xxl_write32; +- map_banks[idx]->copy_to = tqm8xxl_copy_to; ++ ++ simple_map_init(map_banks[idx]); ++ ++ map_banks[idx]->virt = start_scan_addr; ++ map_banks[idx]->phys = flash_addr; ++ /* FIXME: This looks utterly bogus, but I'm trying to ++ preserve the behaviour of the original (shown here)... ++ + map_banks[idx]->map_priv_1 = + start_scan_addr + ((idx > 0) ? + (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0); ++ */ ++ ++ if (idx && mtd_banks[idx-1]) { ++ map_banks[idx]->virt += mtd_banks[idx-1]->size; ++ map_banks[idx]->phys += mtd_banks[idx-1]->size; ++ } ++ + //start to probe flash chips + mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]); +- if(mtd_banks[idx]) +- { +- mtd_banks[idx]->module = THIS_MODULE; ++ ++ if (mtd_banks[idx]) { ++ mtd_banks[idx]->owner = THIS_MODULE; + mtd_size += mtd_banks[idx]->size; + num_banks++; +- printk("%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks, ++ ++ printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks, + mtd_banks[idx]->name, mtd_banks[idx]->size); + } + } + + /* no supported flash chips found */ +- if(!num_banks) +- { +- printk("TQM8xxL: No support flash chips found!\n"); ++ if (!num_banks) { ++ printk(KERN_NOTICE "TQM8xxL: No support flash chips found!\n"); + ret = -ENXIO; + goto error_mem; + } +@@ -231,12 +196,13 @@ + */ + part_banks[0].mtd_part = tqm8xxl_partitions; + part_banks[0].type = "Static image"; +- part_banks[0].nums = NB_OF(tqm8xxl_partitions); ++ part_banks[0].nums = ARRAY_SIZE(tqm8xxl_partitions); ++ + part_banks[1].mtd_part = tqm8xxl_fs_partitions; + part_banks[1].type = "Static file system"; +- part_banks[1].nums = NB_OF(tqm8xxl_fs_partitions); +- for(idx = 0; idx < num_banks ; idx++) +- { ++ part_banks[1].nums = ARRAY_SIZE(tqm8xxl_fs_partitions); ++ ++ for(idx = 0; idx < num_banks ; idx++) { + if (part_banks[idx].nums == 0) { + printk(KERN_NOTICE "TQM flash%d: no partition info available, registering whole flash at once\n", idx); + add_mtd_device(mtd_banks[idx]); +@@ -254,12 +220,9 @@ + #endif + return 0; + error_mem: +- for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) +- { +- if(map_banks[idx] != NULL) +- { +- if(map_banks[idx]->name != NULL) +- { ++ for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) { ++ if(map_banks[idx] != NULL) { ++ if(map_banks[idx]->name != NULL) { + kfree(map_banks[idx]->name); + map_banks[idx]->name = NULL; + } +@@ -267,18 +230,15 @@ + map_banks[idx] = NULL; + } + } +- //return -ENOMEM; + error: + iounmap((void *)start_scan_addr); +- //return -ENXIO; + return ret; + } + + static void __exit cleanup_tqm_mtd(void) + { + unsigned int idx = 0; +- for(idx = 0 ; idx < num_banks ; idx++) +- { ++ for(idx = 0 ; idx < num_banks ; idx++) { + /* destroy mtd_info previously allocated */ + if (mtd_banks[idx]) { + del_mtd_partitions(mtd_banks[idx]); +@@ -288,6 +248,7 @@ + kfree(map_banks[idx]->name); + kfree(map_banks[idx]); + } ++ + if (start_scan_addr) { + iounmap((void *)start_scan_addr); + start_scan_addr = 0; +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/tsunami_flash.c linux/drivers/mtd/maps/tsunami_flash.c +--- linux-mips-2.4.27/drivers/mtd/maps/tsunami_flash.c 2002-06-27 00:35:50.000000000 +0200 ++++ linux/drivers/mtd/maps/tsunami_flash.c 2004-11-19 10:25:11.979187632 +0100 +@@ -2,11 +2,13 @@ + * tsunami_flash.c + * + * flash chip on alpha ds10... +- * $Id: tsunami_flash.c,v 1.1 2002/01/10 22:59:13 eric Exp $ ++ * $Id: tsunami_flash.c,v 1.6 2003/05/21 15:15:08 dwmw2 Exp $ + */ + #include + #include ++#include + #include ++#include + + #define FLASH_ENABLE_PORT 0x00C00001 + #define FLASH_ENABLE_BYTE 0x01 +@@ -58,18 +60,12 @@ + static struct map_info tsunami_flash_map = { + .name = "flash chip on the Tsunami TIG bus", + .size = MAX_TIG_FLASH_SIZE, ++ .phys = NO_XIP; + .buswidth = 1, + .read8 = tsunami_flash_read8, +- .read16 = 0, +- .read32 = 0, + .copy_from = tsunami_flash_copy_from, + .write8 = tsunami_flash_write8, +- .write16 = 0, +- .write32 = 0, + .copy_to = tsunami_flash_copy_to, +- .set_vpp = 0, +- .map_priv_1 = 0, +- + }; + + static struct mtd_info *tsunami_flash_mtd; +@@ -99,7 +95,7 @@ + tsunami_flash_mtd = do_map_probe(*type, &tsunami_flash_map); + } + if (tsunami_flash_mtd) { +- tsunami_flash_mtd->module = THIS_MODULE; ++ tsunami_flash_mtd->owner = THIS_MODULE; + add_mtd_device(tsunami_flash_mtd); + return 0; + } +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/uclinux.c linux/drivers/mtd/maps/uclinux.c +--- linux-mips-2.4.27/drivers/mtd/maps/uclinux.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/maps/uclinux.c 2004-11-19 10:25:11.980187480 +0100 +@@ -5,7 +5,7 @@ + * + * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) + * +- * $Id: uclinux.c,v 1.2 2002/08/07 00:43:45 gerg Exp $ ++ * $Id: uclinux.c,v 1.5 2003/05/20 20:59:32 dwmw2 Exp $ + */ + + /****************************************************************************/ +@@ -24,58 +24,11 @@ + + /****************************************************************************/ + +-__u8 uclinux_read8(struct map_info *map, unsigned long ofs) +-{ +- return(*((__u8 *) (map->map_priv_1 + ofs))); +-} +- +-__u16 uclinux_read16(struct map_info *map, unsigned long ofs) +-{ +- return(*((__u16 *) (map->map_priv_1 + ofs))); +-} +- +-__u32 uclinux_read32(struct map_info *map, unsigned long ofs) +-{ +- return(*((__u32 *) (map->map_priv_1 + ofs))); +-} +- +-void uclinux_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +-{ +- memcpy(to, (void *)(map->map_priv_1 + from), len); +-} +- +-void uclinux_write8(struct map_info *map, __u8 d, unsigned long adr) +-{ +- *((__u8 *) (map->map_priv_1 + adr)) = d; +-} +- +-void uclinux_write16(struct map_info *map, __u16 d, unsigned long adr) +-{ +- *((__u16 *) (map->map_priv_1 + adr)) = d; +-} +- +-void uclinux_write32(struct map_info *map, __u32 d, unsigned long adr) +-{ +- *((__u32 *) (map->map_priv_1 + adr)) = d; +-} +- +-void uclinux_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +-{ +- memcpy((void *) (map->map_priv_1 + to), from, len); +-} + + /****************************************************************************/ + + struct map_info uclinux_ram_map = { +- name: "RAM", +- read8: uclinux_read8, +- read16: uclinux_read16, +- read32: uclinux_read32, +- copy_from: uclinux_copy_from, +- write8: uclinux_write8, +- write16: uclinux_write16, +- write32: uclinux_write32, +- copy_to: uclinux_copy_to, ++ .name = "RAM", + }; + + struct mtd_info *uclinux_ram_mtdinfo; +@@ -83,7 +36,7 @@ + /****************************************************************************/ + + struct mtd_partition uclinux_romfs[] = { +- { name: "ROMfs", offset: 0 } ++ { .name = "ROMfs" } + }; + + #define NUM_PARTITIONS (sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0])) +@@ -94,7 +47,7 @@ + size_t *retlen, u_char **mtdbuf) + { + struct map_info *map = (struct map_info *) mtd->priv; +- *mtdbuf = (u_char *) (map->map_priv_1 + ((int) from)); ++ *mtdbuf = (u_char *) (map->virt + ((int) from)); + *retlen = len; + return(0); + } +@@ -108,29 +61,31 @@ + extern char _ebss; + + mapp = &uclinux_ram_map; +- mapp->map_priv_2 = (unsigned long) &_ebss; ++ mapp->phys = (unsigned long) &_ebss; + mapp->size = PAGE_ALIGN(*((unsigned long *)((&_ebss) + 8))); + mapp->buswidth = 4; + + printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n", + (int) mapp->map_priv_2, (int) mapp->size); + +- mapp->map_priv_1 = (unsigned long) +- ioremap_nocache(mapp->map_priv_2, mapp->size); ++ mapp->virt = (unsigned long) ++ ioremap_nocache(mapp->phys, mapp->size); + +- if (mapp->map_priv_1 == 0) { ++ if (mapp->virt == 0) { + printk("uclinux[mtd]: ioremap_nocache() failed\n"); + return(-EIO); + } + ++ simple_map_init(mapp); ++ + mtd = do_map_probe("map_ram", mapp); + if (!mtd) { + printk("uclinux[mtd]: failed to find a mapping?\n"); +- iounmap((void *) mapp->map_priv_1); ++ iounmap((void *) mapp->virt); + return(-ENXIO); + } + +- mtd->module = THIS_MODULE; ++ mtd->owner = THIS_MODULE; + mtd->point = uclinux_point; + mtd->priv = mapp; + +@@ -155,8 +110,8 @@ + uclinux_ram_mtdinfo = NULL; + } + if (uclinux_ram_map.map_priv_1) { +- iounmap((void *) uclinux_ram_map.map_priv_1); +- uclinux_ram_map.map_priv_1 = 0; ++ iounmap((void *) uclinux_ram_map.virt); ++ uclinux_ram_map.virt = 0; + } + } + +diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/vmax301.c linux/drivers/mtd/maps/vmax301.c +--- linux-mips-2.4.27/drivers/mtd/maps/vmax301.c 2001-11-05 21:15:52.000000000 +0100 ++++ linux/drivers/mtd/maps/vmax301.c 2004-11-19 10:25:11.982187176 +0100 +@@ -1,4 +1,4 @@ +-// $Id: vmax301.c,v 1.24 2001/10/02 15:05:14 dwmw2 Exp $ ++// $Id: vmax301.c,v 1.28 2003/05/21 15:15:08 dwmw2 Exp $ + /* ###################################################################### + + Tempustech VMAX SBC301 MTD Driver. +@@ -24,6 +24,7 @@ + #include + + #include ++#include + + + #define WINDOW_START 0xd8000 +@@ -142,34 +143,36 @@ + + static struct map_info vmax_map[2] = { + { +- name: "VMAX301 Internal Flash", +- size: 3*2*1024*1024, +- buswidth: 1, +- read8: vmax301_read8, +- read16: vmax301_read16, +- read32: vmax301_read32, +- copy_from: vmax301_copy_from, +- write8: vmax301_write8, +- write16: vmax301_write16, +- write32: vmax301_write32, +- copy_to: vmax301_copy_to, +- map_priv_1: WINDOW_START + WINDOW_LENGTH, +- map_priv_2: 0xFFFFFFFF ++ .name = "VMAX301 Internal Flash", ++ .phys = NO_XIP, ++ .size = 3*2*1024*1024, ++ .buswidth = 1, ++ .read8 = vmax301_read8, ++ .read16 = vmax301_read16, ++ .read32 = vmax301_read32, ++ .copy_from = vmax301_copy_from, ++ .write8 = vmax301_write8, ++ .write16 = vmax301_write16, ++ .write32 = vmax301_write32, ++ .copy_to = vmax301_copy_to, ++ .map_priv_1 = WINDOW_START + WINDOW_LENGTH, ++ .map_priv_2 = 0xFFFFFFFF + }, + { +- name: "VMAX301 Socket", +- size: 0, +- buswidth: 1, +- read8: vmax301_read8, +- read16: vmax301_read16, +- read32: vmax301_read32, +- copy_from: vmax301_copy_from, +- write8: vmax301_write8, +- write16: vmax301_write16, +- write32: vmax301_write32, +- copy_to: vmax301_copy_to, +- map_priv_1: WINDOW_START + (3*WINDOW_LENGTH), +- map_priv_2: 0xFFFFFFFF ++ .name = "VMAX301 Socket", ++ .phys = NO_XIP, ++ .size = 0, ++ .buswidth = 1, ++ .read8 = vmax301_read8, ++ .read16 = vmax301_read16, ++ .read32 = vmax301_read32, ++ .copy_from = vmax301_copy_from, ++ .write8 = vmax301_write8, ++ .write16 = vmax301_write16, ++ .write32 = vmax301_write32, ++ .copy_to = vmax301_copy_to, ++ .map_priv_1 = WINDOW_START + (3*WINDOW_LENGTH), ++ .map_priv_2 = 0xFFFFFFFF + } + }; + +@@ -206,8 +209,8 @@ + address of the first half, because it's used more + often. + */ +- vmax_map[0].map_priv_1 = iomapadr + WINDOW_START; +- vmax_map[1].map_priv_1 = iomapadr + (3*WINDOW_START); ++ vmax_map[0].map_priv_2 = iomapadr + WINDOW_START; ++ vmax_map[1].map_priv_2 = iomapadr + (3*WINDOW_START); + + for (i=0; i<2; i++) { + vmax_mtd[i] = do_map_probe("cfi_probe", &vmax_map[i]); +@@ -218,7 +221,7 @@ + if (!vmax_mtd[i]) + vmax_mtd[i] = do_map_probe("map_rom", &vmax_map[i]); + if (vmax_mtd[i]) { +- vmax_mtd[i]->module = THIS_MODULE; ++ vmax_mtd[i]->owner = THIS_MODULE; + add_mtd_device(vmax_mtd[i]); + } + } +diff -Nurb linux-mips-2.4.27/drivers/mtd/mtd_blkdevs-24.c linux/drivers/mtd/mtd_blkdevs-24.c +--- linux-mips-2.4.27/drivers/mtd/mtd_blkdevs-24.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/mtd_blkdevs-24.c 2004-11-19 10:25:11.640239160 +0100 +@@ -0,0 +1,699 @@ ++/* ++ * $Id: mtd_blkdevs-24.c,v 1.15 2003/10/10 08:55:03 dwmw2 Exp $ ++ * ++ * (C) 2003 David Woodhouse ++ * ++ * Interface to Linux 2.4 block layer for MTD 'translation layers'. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static LIST_HEAD(blktrans_majors); ++ ++extern struct semaphore mtd_table_mutex; ++extern struct mtd_info *mtd_table[]; ++ ++struct mtd_blkcore_priv { ++ devfs_handle_t devfs_dir_handle; ++ int blksizes[256]; ++ int sizes[256]; ++ struct hd_struct part_table[256]; ++ struct gendisk gd; ++ spinlock_t devs_lock; /* See comment in _request function */ ++ struct completion thread_dead; ++ int exiting; ++ wait_queue_head_t thread_wq; ++}; ++ ++static inline struct mtd_blktrans_dev *tr_get_dev(struct mtd_blktrans_ops *tr, ++ int devnum) ++{ ++ struct list_head *this; ++ struct mtd_blktrans_dev *d; ++ ++ list_for_each(this, &tr->devs) { ++ d = list_entry(this, struct mtd_blktrans_dev, list); ++ ++ if (d->devnum == devnum) ++ return d; ++ } ++ return NULL; ++} ++ ++static inline struct mtd_blktrans_ops *get_tr(int major) ++{ ++ struct list_head *this; ++ struct mtd_blktrans_ops *t; ++ ++ list_for_each(this, &blktrans_majors) { ++ t = list_entry(this, struct mtd_blktrans_ops, list); ++ ++ if (t->major == major) ++ return t; ++ } ++ return NULL; ++} ++ ++static int do_blktrans_request(struct mtd_blktrans_ops *tr, ++ struct mtd_blktrans_dev *dev, ++ struct request *req) ++{ ++ unsigned long block, nsect; ++ char *buf; ++ int minor; ++ ++ minor = MINOR(req->rq_dev); ++ block = req->sector; ++ nsect = req->current_nr_sectors; ++ buf = req->buffer; ++ ++ if (block + nsect > tr->blkcore_priv->part_table[minor].nr_sects) { ++ printk(KERN_WARNING "Access beyond end of device.\n"); ++ return 0; ++ } ++ block += tr->blkcore_priv->part_table[minor].start_sect; ++ ++ switch(req->cmd) { ++ case READ: ++ for (; nsect > 0; nsect--, block++, buf += 512) ++ if (tr->readsect(dev, block, buf)) ++ return 0; ++ return 1; ++ ++ case WRITE: ++ if (!tr->writesect) ++ return 0; ++ ++ for (; nsect > 0; nsect--, block++, buf += 512) ++ if (tr->writesect(dev, block, buf)) ++ return 0; ++ return 1; ++ ++ default: ++ printk(KERN_NOTICE "Unknown request cmd %d\n", req->cmd); ++ return 0; ++ } ++} ++ ++static int mtd_blktrans_thread(void *arg) ++{ ++ struct mtd_blktrans_ops *tr = arg; ++ struct request_queue *rq = BLK_DEFAULT_QUEUE(tr->major); ++ ++ /* we might get involved when memory gets low, so use PF_MEMALLOC */ ++ current->flags |= PF_MEMALLOC; ++ ++ snprintf(current->comm, sizeof(current->comm), "%sd", tr->name); ++ ++ /* daemonize() doesn't do this for us since some kernel threads ++ actually want to deal with signals. We can't just call ++ exit_sighand() since that'll cause an oops when we finally ++ do exit. */ ++ ++#ifndef __rh_config_h__ /* HAVE_NPTL */ ++ spin_lock_irq(¤t->sigmask_lock); ++ sigfillset(¤t->blocked); ++ recalc_sigpending(current); ++ spin_unlock_irq(¤t->sigmask_lock); ++#else ++ spin_lock_irq(¤t->sighand->siglock); ++ sigfillset(¤t->blocked); ++ recalc_sigpending(); ++ spin_unlock_irq(¤t->sighand->siglock); ++#endif ++ daemonize(); ++ ++ while (!tr->blkcore_priv->exiting) { ++ struct request *req; ++ struct mtd_blktrans_dev *dev; ++ int devnum; ++ int res = 0; ++ DECLARE_WAITQUEUE(wait, current); ++ ++ spin_lock_irq(&io_request_lock); ++ ++ if (list_empty(&rq->queue_head)) { ++ ++ add_wait_queue(&tr->blkcore_priv->thread_wq, &wait); ++ set_current_state(TASK_INTERRUPTIBLE); ++ ++ spin_unlock_irq(&io_request_lock); ++ ++ schedule(); ++ remove_wait_queue(&tr->blkcore_priv->thread_wq, &wait); ++ ++ continue; ++ } ++ ++ req = blkdev_entry_next_request(&rq->queue_head); ++ ++ devnum = MINOR(req->rq_dev) >> tr->part_bits; ++ ++ /* The ll_rw_blk code knows not to touch the request ++ at the head of the queue */ ++ spin_unlock_irq(&io_request_lock); ++ ++ /* FIXME: Where can we store the dev, on which ++ we already have a refcount anyway? We need to ++ lock against concurrent addition/removal of devices, ++ but if we use the mtd_table_mutex we deadlock when ++ grok_partitions is called from the registration ++ callbacks. */ ++ spin_lock(&tr->blkcore_priv->devs_lock); ++ dev = tr_get_dev(tr, devnum); ++ spin_unlock(&tr->blkcore_priv->devs_lock); ++ ++ BUG_ON(!dev); ++ ++ /* Ensure serialisation of requests */ ++ down(&dev->sem); ++ ++ res = do_blktrans_request(tr, dev, req); ++ up(&dev->sem); ++ ++ if (!end_that_request_first(req, res, tr->name)) { ++ spin_lock_irq(&io_request_lock); ++ blkdev_dequeue_request(req); ++ end_that_request_last(req); ++ spin_unlock_irq(&io_request_lock); ++ } ++ } ++ complete_and_exit(&tr->blkcore_priv->thread_dead, 0); ++} ++ ++static void mtd_blktrans_request(struct request_queue *rq) ++{ ++ struct mtd_blktrans_ops *tr = rq->queuedata; ++ wake_up(&tr->blkcore_priv->thread_wq); ++} ++ ++int blktrans_open(struct inode *i, struct file *f) ++{ ++ struct mtd_blktrans_ops *tr = NULL; ++ struct mtd_blktrans_dev *dev = NULL; ++ int major_nr = MAJOR(i->i_rdev); ++ int minor_nr = MINOR(i->i_rdev); ++ int devnum; ++ int ret = -ENODEV; ++ ++ if (is_read_only(i->i_rdev) && (f->f_mode & FMODE_WRITE)) ++ return -EROFS; ++ ++ down(&mtd_table_mutex); ++ ++ tr = get_tr(major_nr); ++ ++ if (!tr) ++ goto out; ++ ++ devnum = minor_nr >> tr->part_bits; ++ ++ dev = tr_get_dev(tr, devnum); ++ ++ if (!dev) ++ goto out; ++ ++ if (!tr->blkcore_priv->part_table[minor_nr].nr_sects) { ++ ret = -ENODEV; ++ goto out; ++ } ++ ++ if (!try_inc_mod_count(dev->mtd->owner)) ++ goto out; ++ ++ if (!try_inc_mod_count(tr->owner)) ++ goto out_tr; ++ ++ dev->mtd->usecount++; ++ ++ ret = 0; ++ if (tr->open && (ret = tr->open(dev))) { ++ dev->mtd->usecount--; ++ if (dev->mtd->owner) ++ __MOD_DEC_USE_COUNT(dev->mtd->owner); ++ out_tr: ++ if (tr->owner) ++ __MOD_DEC_USE_COUNT(tr->owner); ++ } ++ out: ++ up(&mtd_table_mutex); ++ ++ return ret; ++} ++ ++int blktrans_release(struct inode *i, struct file *f) ++{ ++ struct mtd_blktrans_dev *dev; ++ struct mtd_blktrans_ops *tr; ++ int ret = 0; ++ int devnum; ++ ++ down(&mtd_table_mutex); ++ ++ tr = get_tr(MAJOR(i->i_rdev)); ++ if (!tr) { ++ up(&mtd_table_mutex); ++ return -ENODEV; ++ } ++ ++ devnum = MINOR(i->i_rdev) >> tr->part_bits; ++ dev = tr_get_dev(tr, devnum); ++ ++ if (!dev) { ++ up(&mtd_table_mutex); ++ return -ENODEV; ++ } ++ ++ if (tr->release) ++ ret = tr->release(dev); ++ ++ if (!ret) { ++ dev->mtd->usecount--; ++ if (dev->mtd->owner) ++ __MOD_DEC_USE_COUNT(dev->mtd->owner); ++ if (tr->owner) ++ __MOD_DEC_USE_COUNT(tr->owner); ++ } ++ ++ up(&mtd_table_mutex); ++ ++ return ret; ++} ++ ++static int mtd_blktrans_rrpart(kdev_t rdev, struct mtd_blktrans_ops *tr, ++ struct mtd_blktrans_dev *dev) ++{ ++ struct gendisk *gd = &(tr->blkcore_priv->gd); ++ int i; ++ int minor = MINOR(rdev); ++ ++ if (minor & ((1<part_bits)-1) || !tr->part_bits) { ++ /* BLKRRPART on a partition. Go away. */ ++ return -ENOTTY; ++ } ++ ++ if (!capable(CAP_SYS_ADMIN)) ++ return -EACCES; ++ ++ /* We are required to prevent simultaneous open() ourselves. ++ The core doesn't do that for us. Did I ever mention how ++ much the Linux block layer sucks? Sledgehammer approach... */ ++ down(&mtd_table_mutex); ++ ++ for (i=0; i < (1<part_bits); i++) { ++ invalidate_device(MKDEV(tr->major, minor+i), 1); ++ gd->part[minor + i].start_sect = 0; ++ gd->part[minor + i].nr_sects = 0; ++ } ++ ++ grok_partitions(gd, minor, 1 << tr->part_bits, ++ tr->blkcore_priv->sizes[minor]); ++ up(&mtd_table_mutex); ++ ++ return 0; ++} ++ ++static int blktrans_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ struct mtd_blktrans_dev *dev; ++ struct mtd_blktrans_ops *tr; ++ int devnum; ++ ++ switch(cmd) { ++ case BLKGETSIZE: ++ case BLKGETSIZE64: ++ case BLKBSZSET: ++ case BLKBSZGET: ++ case BLKROSET: ++ case BLKROGET: ++ case BLKRASET: ++ case BLKRAGET: ++ case BLKPG: ++ case BLKELVGET: ++ case BLKELVSET: ++ return blk_ioctl(inode->i_rdev, cmd, arg); ++ } ++ ++ down(&mtd_table_mutex); ++ ++ tr = get_tr(MAJOR(inode->i_rdev)); ++ if (!tr) { ++ up(&mtd_table_mutex); ++ return -ENODEV; ++ } ++ ++ devnum = MINOR(inode->i_rdev) >> tr->part_bits; ++ dev = tr_get_dev(tr, devnum); ++ ++ up(&mtd_table_mutex); ++ ++ if (!dev) ++ return -ENODEV; ++ ++ switch(cmd) { ++ case BLKRRPART: ++ return mtd_blktrans_rrpart(inode->i_rdev, tr, dev); ++ ++ case BLKFLSBUF: ++ blk_ioctl(inode->i_rdev, cmd, arg); ++ if (tr->flush) ++ return tr->flush(dev); ++ /* The core code did the work, we had nothing to do. */ ++ return 0; ++ ++ case HDIO_GETGEO: ++ if (tr->getgeo) { ++ struct hd_geometry g; ++ struct gendisk *gd = &(tr->blkcore_priv->gd); ++ int ret; ++ ++ memset(&g, 0, sizeof(g)); ++ ret = tr->getgeo(dev, &g); ++ if (ret) ++ return ret; ++ ++ g.start = gd->part[MINOR(inode->i_rdev)].start_sect; ++ if (copy_to_user((void *)arg, &g, sizeof(g))) ++ return -EFAULT; ++ return 0; ++ } /* else */ ++ default: ++ return -ENOTTY; ++ } ++} ++ ++struct block_device_operations mtd_blktrans_ops = { ++ .owner = THIS_MODULE, ++ .open = blktrans_open, ++ .release = blktrans_release, ++ .ioctl = blktrans_ioctl, ++}; ++ ++int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) ++{ ++ struct mtd_blktrans_ops *tr = new->tr; ++ struct list_head *this; ++ int last_devnum = -1; ++ int i; ++ ++ if (!down_trylock(&mtd_table_mutex)) { ++ up(&mtd_table_mutex); ++ BUG(); ++ } ++ ++ spin_lock(&tr->blkcore_priv->devs_lock); ++ ++ list_for_each(this, &tr->devs) { ++ struct mtd_blktrans_dev *d = list_entry(this, struct mtd_blktrans_dev, list); ++ if (new->devnum == -1) { ++ /* Use first free number */ ++ if (d->devnum != last_devnum+1) { ++ /* Found a free devnum. Plug it in here */ ++ new->devnum = last_devnum+1; ++ list_add_tail(&new->list, &d->list); ++ goto added; ++ } ++ } else if (d->devnum == new->devnum) { ++ /* Required number taken */ ++ spin_unlock(&tr->blkcore_priv->devs_lock); ++ return -EBUSY; ++ } else if (d->devnum > new->devnum) { ++ /* Required number was free */ ++ list_add_tail(&new->list, &d->list); ++ goto added; ++ } ++ last_devnum = d->devnum; ++ } ++ if (new->devnum == -1) ++ new->devnum = last_devnum+1; ++ ++ if ((new->devnum << tr->part_bits) > 256) { ++ spin_unlock(&tr->blkcore_priv->devs_lock); ++ return -EBUSY; ++ } ++ ++ init_MUTEX(&new->sem); ++ list_add_tail(&new->list, &tr->devs); ++ added: ++ spin_unlock(&tr->blkcore_priv->devs_lock); ++ ++ if (!tr->writesect) ++ new->readonly = 1; ++ ++ for (i = new->devnum << tr->part_bits; ++ i < (new->devnum+1) << tr->part_bits; ++ i++) { ++ set_device_ro(MKDEV(tr->major, i), new->readonly); ++ tr->blkcore_priv->blksizes[i] = new->blksize; ++ tr->blkcore_priv->sizes[i] = 0; ++ tr->blkcore_priv->part_table[i].nr_sects = 0; ++ tr->blkcore_priv->part_table[i].start_sect = 0; ++ } ++ ++ /* ++ dwmw2: BLOCK_SIZE_BITS has nothing to do with block devices ++ dwmw2: any code which sets blk_size[][] should be ++ size >> 10 /+ 2.4 and its dumb units */ ++ ++ tr->blkcore_priv->sizes[new->devnum << tr->part_bits] = ++ (new->size * new->blksize) >> 10; /* 2.4 and its dumb units */ ++ ++ /* But this is still in device's sectors? $DEITY knows */ ++ tr->blkcore_priv->part_table[new->devnum << tr->part_bits].nr_sects = new->size; ++ ++ if (tr->part_bits) { ++ grok_partitions(&tr->blkcore_priv->gd, new->devnum, ++ 1 << tr->part_bits, new->size); ++ } ++#ifdef CONFIG_DEVFS_FS ++ if (!tr->part_bits) { ++ char name[2]; ++ ++ name[0] = '0' + new->devnum; ++ name[1] = 0; ++ ++ new->blkcore_priv = ++ devfs_register(tr->blkcore_priv->devfs_dir_handle, ++ name, DEVFS_FL_DEFAULT, tr->major, ++ new->devnum, S_IFBLK|S_IRUGO|S_IWUGO, ++ &mtd_blktrans_ops, NULL); ++ } ++#endif ++ return 0; ++} ++ ++int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) ++{ ++ struct mtd_blktrans_ops *tr = old->tr; ++ int i; ++ ++ if (!down_trylock(&mtd_table_mutex)) { ++ up(&mtd_table_mutex); ++ BUG(); ++ } ++ ++#ifdef CONFIG_DEVFS_FS ++ if (!tr->part_bits) { ++ devfs_unregister(old->blkcore_priv); ++ old->blkcore_priv = NULL; ++ } else { ++ devfs_register_partitions(&tr->blkcore_priv->gd, ++ old->devnum << tr->part_bits, 1); ++ } ++#endif ++ spin_lock(&tr->blkcore_priv->devs_lock); ++ list_del(&old->list); ++ spin_unlock(&tr->blkcore_priv->devs_lock); ++ ++ for (i = (old->devnum << tr->part_bits); ++ i < ((old->devnum+1) << tr->part_bits); i++) { ++ tr->blkcore_priv->sizes[i] = 0; ++ tr->blkcore_priv->part_table[i].nr_sects = 0; ++ tr->blkcore_priv->part_table[i].start_sect = 0; ++ } ++ ++ return 0; ++} ++ ++void blktrans_notify_remove(struct mtd_info *mtd) ++{ ++ struct list_head *this, *this2, *next; ++ ++ list_for_each(this, &blktrans_majors) { ++ struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list); ++ ++ list_for_each_safe(this2, next, &tr->devs) { ++ struct mtd_blktrans_dev *dev = list_entry(this2, struct mtd_blktrans_dev, list); ++ ++ if (dev->mtd == mtd) ++ tr->remove_dev(dev); ++ } ++ } ++} ++ ++void blktrans_notify_add(struct mtd_info *mtd) ++{ ++ struct list_head *this; ++ ++ if (mtd->type == MTD_ABSENT) ++ return; ++ ++ list_for_each(this, &blktrans_majors) { ++ struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list); ++ ++ tr->add_mtd(tr, mtd); ++ } ++ ++} ++ ++static struct mtd_notifier blktrans_notifier = { ++ .add = blktrans_notify_add, ++ .remove = blktrans_notify_remove, ++}; ++ ++int register_mtd_blktrans(struct mtd_blktrans_ops *tr) ++{ ++ int ret, i; ++ ++ /* Register the notifier if/when the first device type is ++ registered, to prevent the link/init ordering from fucking ++ us over. */ ++ if (!blktrans_notifier.list.next) ++ register_mtd_user(&blktrans_notifier); ++ ++ tr->blkcore_priv = kmalloc(sizeof(*tr->blkcore_priv), GFP_KERNEL); ++ if (!tr->blkcore_priv) ++ return -ENOMEM; ++ ++ memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv)); ++ ++ down(&mtd_table_mutex); ++ ++ ret = devfs_register_blkdev(tr->major, tr->name, &mtd_blktrans_ops); ++ if (ret) { ++ printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n", ++ tr->name, tr->major, ret); ++ kfree(tr->blkcore_priv); ++ up(&mtd_table_mutex); ++ return ret; ++ } ++ ++ blk_init_queue(BLK_DEFAULT_QUEUE(tr->major), &mtd_blktrans_request); ++ (BLK_DEFAULT_QUEUE(tr->major))->queuedata = tr; ++ ++ init_completion(&tr->blkcore_priv->thread_dead); ++ init_waitqueue_head(&tr->blkcore_priv->thread_wq); ++ ++ ret = kernel_thread(mtd_blktrans_thread, tr, ++ CLONE_FS|CLONE_FILES|CLONE_SIGHAND); ++ if (ret < 0) { ++ blk_cleanup_queue(BLK_DEFAULT_QUEUE(tr->major)); ++ devfs_unregister_blkdev(tr->major, tr->name); ++ kfree(tr->blkcore_priv); ++ up(&mtd_table_mutex); ++ return ret; ++ } ++ ++ tr->blkcore_priv->devfs_dir_handle = ++ devfs_mk_dir(NULL, tr->name, NULL); ++ ++ blksize_size[tr->major] = tr->blkcore_priv->blksizes; ++ blk_size[tr->major] = tr->blkcore_priv->sizes; ++ ++ tr->blkcore_priv->gd.major = tr->major; ++ tr->blkcore_priv->gd.major_name = tr->name; ++ tr->blkcore_priv->gd.minor_shift = tr->part_bits; ++ tr->blkcore_priv->gd.max_p = (1<part_bits) - 1; ++ tr->blkcore_priv->gd.part = tr->blkcore_priv->part_table; ++ tr->blkcore_priv->gd.sizes = tr->blkcore_priv->sizes; ++ tr->blkcore_priv->gd.nr_real = 256 >> tr->part_bits; ++ ++ spin_lock_init(&tr->blkcore_priv->devs_lock); ++ ++ add_gendisk(&tr->blkcore_priv->gd); ++ ++ INIT_LIST_HEAD(&tr->devs); ++ list_add(&tr->list, &blktrans_majors); ++ ++ for (i=0; itype != MTD_ABSENT) ++ tr->add_mtd(tr, mtd_table[i]); ++ } ++ up(&mtd_table_mutex); ++ ++ return 0; ++} ++ ++int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) ++{ ++ struct list_head *this, *next; ++ ++ down(&mtd_table_mutex); ++ ++ /* Clean up the kernel thread */ ++ tr->blkcore_priv->exiting = 1; ++ wake_up(&tr->blkcore_priv->thread_wq); ++ wait_for_completion(&tr->blkcore_priv->thread_dead); ++ ++ /* Remove it from the list of active majors */ ++ list_del(&tr->list); ++ ++ /* Remove each of its devices */ ++ list_for_each_safe(this, next, &tr->devs) { ++ struct mtd_blktrans_dev *dev = list_entry(this, struct mtd_blktrans_dev, list); ++ tr->remove_dev(dev); ++ } ++ ++ blksize_size[tr->major] = NULL; ++ blk_size[tr->major] = NULL; ++ ++ del_gendisk(&tr->blkcore_priv->gd); ++ ++ blk_cleanup_queue(BLK_DEFAULT_QUEUE(tr->major)); ++ devfs_unregister_blkdev(tr->major, tr->name); ++ ++ devfs_unregister(tr->blkcore_priv->devfs_dir_handle); ++ ++ up(&mtd_table_mutex); ++ ++ kfree(tr->blkcore_priv); ++ ++ if (!list_empty(&tr->devs)) ++ BUG(); ++ return 0; ++} ++ ++static void __exit mtd_blktrans_exit(void) ++{ ++ /* No race here -- if someone's currently in register_mtd_blktrans ++ we're screwed anyway. */ ++ if (blktrans_notifier.list.next) ++ unregister_mtd_user(&blktrans_notifier); ++} ++ ++module_exit(mtd_blktrans_exit); ++ ++EXPORT_SYMBOL_GPL(register_mtd_blktrans); ++EXPORT_SYMBOL_GPL(deregister_mtd_blktrans); ++EXPORT_SYMBOL_GPL(add_mtd_blktrans_dev); ++EXPORT_SYMBOL_GPL(del_mtd_blktrans_dev); ++ ++MODULE_AUTHOR("David Woodhouse "); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Common interface to block layer for MTD 'translation layers'"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/mtd_blkdevs.c linux/drivers/mtd/mtd_blkdevs.c +--- linux-mips-2.4.27/drivers/mtd/mtd_blkdevs.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/mtd_blkdevs.c 2004-11-19 10:25:11.642238856 +0100 +@@ -0,0 +1,479 @@ ++/* ++ * $Id: mtd_blkdevs.c,v 1.19 2003/11/07 09:52:46 dwmw2 Exp $ ++ * ++ * (C) 2003 David Woodhouse ++ * ++ * Interface to Linux 2.5 block layer for MTD 'translation layers'. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static LIST_HEAD(blktrans_majors); ++ ++extern struct semaphore mtd_table_mutex; ++extern struct mtd_info *mtd_table[]; ++ ++struct mtd_blkcore_priv { ++ struct completion thread_dead; ++ int exiting; ++ wait_queue_head_t thread_wq; ++ struct request_queue *rq; ++ spinlock_t queue_lock; ++}; ++ ++static int do_blktrans_request(struct mtd_blktrans_ops *tr, ++ struct mtd_blktrans_dev *dev, ++ struct request *req) ++{ ++ unsigned long block, nsect; ++ char *buf; ++ ++ block = req->sector; ++ nsect = req->current_nr_sectors; ++ buf = req->buffer; ++ ++ if (!(req->flags & REQ_CMD)) ++ return 0; ++ ++ if (block + nsect > get_capacity(req->rq_disk)) ++ return 0; ++ ++ switch(rq_data_dir(req)) { ++ case READ: ++ for (; nsect > 0; nsect--, block++, buf += 512) ++ if (tr->readsect(dev, block, buf)) ++ return 0; ++ return 1; ++ ++ case WRITE: ++ if (!tr->writesect) ++ return 0; ++ ++ for (; nsect > 0; nsect--, block++, buf += 512) ++ if (tr->writesect(dev, block, buf)) ++ return 0; ++ return 1; ++ ++ default: ++ printk(KERN_NOTICE "Unknown request %ld\n", rq_data_dir(req)); ++ return 0; ++ } ++} ++ ++static int mtd_blktrans_thread(void *arg) ++{ ++ struct mtd_blktrans_ops *tr = arg; ++ struct request_queue *rq = tr->blkcore_priv->rq; ++ ++ /* we might get involved when memory gets low, so use PF_MEMALLOC */ ++ current->flags |= PF_MEMALLOC; ++ ++ daemonize("%sd", tr->name); ++ ++ /* daemonize() doesn't do this for us since some kernel threads ++ actually want to deal with signals. We can't just call ++ exit_sighand() since that'll cause an oops when we finally ++ do exit. */ ++ spin_lock_irq(¤t->sighand->siglock); ++ sigfillset(¤t->blocked); ++ recalc_sigpending(); ++ spin_unlock_irq(¤t->sighand->siglock); ++ ++ spin_lock_irq(rq->queue_lock); ++ ++ while (!tr->blkcore_priv->exiting) { ++ struct request *req; ++ struct mtd_blktrans_dev *dev; ++ int res = 0; ++ DECLARE_WAITQUEUE(wait, current); ++ ++ req = elv_next_request(rq); ++ ++ if (!req) { ++ add_wait_queue(&tr->blkcore_priv->thread_wq, &wait); ++ set_current_state(TASK_INTERRUPTIBLE); ++ ++ spin_unlock_irq(rq->queue_lock); ++ ++ schedule(); ++ remove_wait_queue(&tr->blkcore_priv->thread_wq, &wait); ++ ++ spin_lock_irq(rq->queue_lock); ++ ++ continue; ++ } ++ ++ dev = req->rq_disk->private_data; ++ tr = dev->tr; ++ ++ spin_unlock_irq(rq->queue_lock); ++ ++ down(&dev->sem); ++ res = do_blktrans_request(tr, dev, req); ++ up(&dev->sem); ++ ++ spin_lock_irq(rq->queue_lock); ++ ++ end_request(req, res); ++ } ++ complete_and_exit(&tr->blkcore_priv->thread_dead, 0); ++} ++ ++static void mtd_blktrans_request(struct request_queue *rq) ++{ ++ struct mtd_blktrans_ops *tr = rq->queuedata; ++ wake_up(&tr->blkcore_priv->thread_wq); ++} ++ ++ ++int blktrans_open(struct inode *i, struct file *f) ++{ ++ struct mtd_blktrans_dev *dev; ++ struct mtd_blktrans_ops *tr; ++ int ret = -ENODEV; ++ ++ dev = i->i_bdev->bd_disk->private_data; ++ tr = dev->tr; ++ ++ if (!try_module_get(dev->mtd->owner)) ++ goto out; ++ ++ if (!try_module_get(tr->owner)) ++ goto out_tr; ++ ++ /* FIXME: Locking. A hot pluggable device can go away ++ (del_mtd_device can be called for it) without its module ++ being unloaded. */ ++ dev->mtd->usecount++; ++ ++ ret = 0; ++ if (tr->open && (ret = tr->open(dev))) { ++ dev->mtd->usecount--; ++ module_put(dev->mtd->owner); ++ out_tr: ++ module_put(tr->owner); ++ } ++ out: ++ return ret; ++} ++ ++int blktrans_release(struct inode *i, struct file *f) ++{ ++ struct mtd_blktrans_dev *dev; ++ struct mtd_blktrans_ops *tr; ++ int ret = 0; ++ ++ dev = i->i_bdev->bd_disk->private_data; ++ tr = dev->tr; ++ ++ if (tr->release) ++ ret = tr->release(dev); ++ ++ if (!ret) { ++ dev->mtd->usecount--; ++ module_put(dev->mtd->owner); ++ module_put(tr->owner); ++ } ++ ++ return ret; ++} ++ ++ ++static int blktrans_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data; ++ struct mtd_blktrans_ops *tr = dev->tr; ++ ++ switch (cmd) { ++ case BLKFLSBUF: ++ if (tr->flush) ++ return tr->flush(dev); ++ /* The core code did the work, we had nothing to do. */ ++ return 0; ++ ++ case HDIO_GETGEO: ++ if (tr->getgeo) { ++ struct hd_geometry g; ++ int ret; ++ ++ memset(&g, 0, sizeof(g)); ++ ret = tr->getgeo(dev, &g); ++ ++ if (ret) ++ return ret; ++ ++ g.start = get_start_sect(inode->i_bdev); ++ if (copy_to_user((void *)arg, &g, sizeof(g))) ++ return -EFAULT; ++ return 0; ++ } /* else */ ++ default: ++ return -ENOTTY; ++ } ++} ++ ++struct block_device_operations mtd_blktrans_ops = { ++ .owner = THIS_MODULE, ++ .open = blktrans_open, ++ .release = blktrans_release, ++ .ioctl = blktrans_ioctl, ++}; ++ ++int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) ++{ ++ struct mtd_blktrans_ops *tr = new->tr; ++ struct list_head *this; ++ int last_devnum = -1; ++ struct gendisk *gd; ++ ++ if (!down_trylock(&mtd_table_mutex)) { ++ up(&mtd_table_mutex); ++ BUG(); ++ } ++ ++ list_for_each(this, &tr->devs) { ++ struct mtd_blktrans_dev *d = list_entry(this, struct mtd_blktrans_dev, list); ++ if (new->devnum == -1) { ++ /* Use first free number */ ++ if (d->devnum != last_devnum+1) { ++ /* Found a free devnum. Plug it in here */ ++ new->devnum = last_devnum+1; ++ list_add_tail(&new->list, &d->list); ++ goto added; ++ } ++ } else if (d->devnum == new->devnum) { ++ /* Required number taken */ ++ return -EBUSY; ++ } else if (d->devnum > new->devnum) { ++ /* Required number was free */ ++ list_add_tail(&new->list, &d->list); ++ goto added; ++ } ++ last_devnum = d->devnum; ++ } ++ if (new->devnum == -1) ++ new->devnum = last_devnum+1; ++ ++ if ((new->devnum << tr->part_bits) > 256) { ++ return -EBUSY; ++ } ++ ++ init_MUTEX(&new->sem); ++ list_add_tail(&new->list, &tr->devs); ++ added: ++ if (!tr->writesect) ++ new->readonly = 1; ++ ++ gd = alloc_disk(1 << tr->part_bits); ++ if (!gd) { ++ list_del(&new->list); ++ return -ENOMEM; ++ } ++ gd->major = tr->major; ++ gd->first_minor = (new->devnum) << tr->part_bits; ++ gd->fops = &mtd_blktrans_ops; ++ ++ snprintf(gd->disk_name, sizeof(gd->disk_name), ++ "%s%c", tr->name, (tr->part_bits?'a':'0') + new->devnum); ++ snprintf(gd->devfs_name, sizeof(gd->devfs_name), ++ "%s/%c", tr->name, (tr->part_bits?'a':'0') + new->devnum); ++ ++ /* 2.5 has capacity in units of 512 bytes while still ++ having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */ ++ set_capacity(gd, (new->size * new->blksize) >> 9); ++ ++ gd->private_data = new; ++ new->blkcore_priv = gd; ++ gd->queue = tr->blkcore_priv->rq; ++ ++ if (new->readonly) ++ set_disk_ro(gd, 1); ++ ++ add_disk(gd); ++ ++ return 0; ++} ++ ++int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) ++{ ++ if (!down_trylock(&mtd_table_mutex)) { ++ up(&mtd_table_mutex); ++ BUG(); ++ } ++ ++ list_del(&old->list); ++ ++ del_gendisk(old->blkcore_priv); ++ put_disk(old->blkcore_priv); ++ ++ return 0; ++} ++ ++void blktrans_notify_remove(struct mtd_info *mtd) ++{ ++ struct list_head *this, *this2, *next; ++ ++ list_for_each(this, &blktrans_majors) { ++ struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list); ++ ++ list_for_each_safe(this2, next, &tr->devs) { ++ struct mtd_blktrans_dev *dev = list_entry(this2, struct mtd_blktrans_dev, list); ++ ++ if (dev->mtd == mtd) ++ tr->remove_dev(dev); ++ } ++ } ++} ++ ++void blktrans_notify_add(struct mtd_info *mtd) ++{ ++ struct list_head *this; ++ ++ if (mtd->type == MTD_ABSENT) ++ return; ++ ++ list_for_each(this, &blktrans_majors) { ++ struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list); ++ ++ tr->add_mtd(tr, mtd); ++ } ++ ++} ++ ++static struct mtd_notifier blktrans_notifier = { ++ .add = blktrans_notify_add, ++ .remove = blktrans_notify_remove, ++}; ++ ++int register_mtd_blktrans(struct mtd_blktrans_ops *tr) ++{ ++ int ret, i; ++ ++ /* Register the notifier if/when the first device type is ++ registered, to prevent the link/init ordering from fucking ++ us over. */ ++ if (!blktrans_notifier.list.next) ++ register_mtd_user(&blktrans_notifier); ++ ++ tr->blkcore_priv = kmalloc(sizeof(*tr->blkcore_priv), GFP_KERNEL); ++ if (!tr->blkcore_priv) ++ return -ENOMEM; ++ ++ memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv)); ++ ++ down(&mtd_table_mutex); ++ ++ ret = register_blkdev(tr->major, tr->name); ++ if (ret) { ++ printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n", ++ tr->name, tr->major, ret); ++ kfree(tr->blkcore_priv); ++ up(&mtd_table_mutex); ++ return ret; ++ } ++ spin_lock_init(&tr->blkcore_priv->queue_lock); ++ init_completion(&tr->blkcore_priv->thread_dead); ++ init_waitqueue_head(&tr->blkcore_priv->thread_wq); ++ ++ tr->blkcore_priv->rq = blk_init_queue(mtd_blktrans_request, &tr->blkcore_priv->queue_lock); ++ if (!tr->blkcore_priv->rq) { ++ unregister_blkdev(tr->major, tr->name); ++ kfree(tr->blkcore_priv); ++ up(&mtd_table_mutex); ++ return -ENOMEM; ++ } ++ ++ tr->blkcore_priv->rq->queuedata = tr; ++ ++ ret = kernel_thread(mtd_blktrans_thread, tr, ++ CLONE_FS|CLONE_FILES|CLONE_SIGHAND); ++ if (ret < 0) { ++ blk_cleanup_queue(tr->blkcore_priv->rq); ++ unregister_blkdev(tr->major, tr->name); ++ kfree(tr->blkcore_priv); ++ up(&mtd_table_mutex); ++ return ret; ++ } ++ ++ devfs_mk_dir(tr->name); ++ ++ INIT_LIST_HEAD(&tr->devs); ++ list_add(&tr->list, &blktrans_majors); ++ ++ for (i=0; itype != MTD_ABSENT) ++ tr->add_mtd(tr, mtd_table[i]); ++ } ++ ++ up(&mtd_table_mutex); ++ ++ return 0; ++} ++ ++int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) ++{ ++ struct list_head *this, *next; ++ ++ down(&mtd_table_mutex); ++ ++ /* Clean up the kernel thread */ ++ tr->blkcore_priv->exiting = 1; ++ wake_up(&tr->blkcore_priv->thread_wq); ++ wait_for_completion(&tr->blkcore_priv->thread_dead); ++ ++ /* Remove it from the list of active majors */ ++ list_del(&tr->list); ++ ++ list_for_each_safe(this, next, &tr->devs) { ++ struct mtd_blktrans_dev *dev = list_entry(this, struct mtd_blktrans_dev, list); ++ tr->remove_dev(dev); ++ } ++ ++ devfs_remove(tr->name); ++ blk_cleanup_queue(tr->blkcore_priv->rq); ++ unregister_blkdev(tr->major, tr->name); ++ ++ up(&mtd_table_mutex); ++ ++ kfree(tr->blkcore_priv); ++ ++ if (!list_empty(&tr->devs)) ++ BUG(); ++ return 0; ++} ++ ++static void __exit mtd_blktrans_exit(void) ++{ ++ /* No race here -- if someone's currently in register_mtd_blktrans ++ we're screwed anyway. */ ++ if (blktrans_notifier.list.next) ++ unregister_mtd_user(&blktrans_notifier); ++} ++ ++module_exit(mtd_blktrans_exit); ++ ++EXPORT_SYMBOL_GPL(register_mtd_blktrans); ++EXPORT_SYMBOL_GPL(deregister_mtd_blktrans); ++EXPORT_SYMBOL_GPL(add_mtd_blktrans_dev); ++EXPORT_SYMBOL_GPL(del_mtd_blktrans_dev); ++ ++MODULE_AUTHOR("David Woodhouse "); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Common interface to block layer for MTD 'translation layers'"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/mtdblock.c linux/drivers/mtd/mtdblock.c +--- linux-mips-2.4.27/drivers/mtd/mtdblock.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/mtdblock.c 2004-11-19 10:25:11.643238704 +0100 +@@ -1,52 +1,25 @@ + /* + * Direct MTD block device access + * +- * $Id: mtdblock.c,v 1.51 2001/11/20 11:42:33 dwmw2 Exp $ ++ * $Id: mtdblock.c,v 1.64 2003/10/04 17:14:14 dwmw2 Exp $ + * +- * 02-nov-2000 Nicolas Pitre Added read-modify-write with cache ++ * (C) 2000-2003 Nicolas Pitre ++ * (C) 1999-2003 David Woodhouse + */ + + #include + #include + #include + #include ++#include ++#include + #include ++#include + #include +-#include +- +-#define MAJOR_NR MTD_BLOCK_MAJOR +-#define DEVICE_NAME "mtdblock" +-#define DEVICE_REQUEST mtdblock_request +-#define DEVICE_NR(device) (device) +-#define DEVICE_ON(device) +-#define DEVICE_OFF(device) +-#define DEVICE_NO_RANDOM +-#include +-/* for old kernels... */ +-#ifndef QUEUE_EMPTY +-#define QUEUE_EMPTY (!CURRENT) +-#endif +-#if LINUX_VERSION_CODE < 0x20300 +-#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].plug_tq.sync) +-#else +-#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].request_queue.plugged) +-#endif +- +-#ifdef CONFIG_DEVFS_FS +-#include +-static void mtd_notify_add(struct mtd_info* mtd); +-static void mtd_notify_remove(struct mtd_info* mtd); +-static struct mtd_notifier notifier = { +- mtd_notify_add, +- mtd_notify_remove, +- NULL +-}; +-static devfs_handle_t devfs_dir_handle = NULL; +-static devfs_handle_t devfs_rw_handle[MAX_MTD_DEVICES]; +-#endif ++#include + + static struct mtdblk_dev { +- struct mtd_info *mtd; /* Locked */ ++ struct mtd_info *mtd; + int count; + struct semaphore cache_sem; + unsigned char *cache_data; +@@ -55,19 +28,6 @@ + enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state; + } *mtdblks[MAX_MTD_DEVICES]; + +-static spinlock_t mtdblks_lock; +- +-static int mtd_sizes[MAX_MTD_DEVICES]; +-static int mtd_blksizes[MAX_MTD_DEVICES]; +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14) +-#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT +-#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT +-#else +-#define BLK_INC_USE_COUNT do {} while(0) +-#define BLK_DEC_USE_COUNT do {} while(0) +-#endif +- + /* + * Cache stuff... + * +@@ -151,7 +111,7 @@ + return ret; + + /* +- * Here we could argably set the cache state to STATE_CLEAN. ++ * Here we could argubly set the cache state to STATE_CLEAN. + * However this could lead to inconsistency since we will not + * be notified if this content is altered on the flash by other + * means. Let's declare it empty and leave buffering tasks to +@@ -277,57 +237,47 @@ + return 0; + } + ++static int mtdblock_readsect(struct mtd_blktrans_dev *dev, ++ unsigned long block, char *buf) ++{ ++ struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; ++ return do_cached_read(mtdblk, block<<9, 512, buf); ++} + ++static int mtdblock_writesect(struct mtd_blktrans_dev *dev, ++ unsigned long block, char *buf) ++{ ++ struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; ++ if (unlikely(!mtdblk->cache_data)) { ++ mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize); ++ if (!mtdblk->cache_data) ++ return -EINTR; ++ /* -EINTR is not really correct, but it is the best match ++ * documented in man 2 write for all cases. We could also ++ * return -EAGAIN sometimes, but why bother? ++ */ ++ } ++ return do_cached_write(mtdblk, block<<9, 512, buf); ++} + +-static int mtdblock_open(struct inode *inode, struct file *file) ++static int mtdblock_open(struct mtd_blktrans_dev *mbd) + { + struct mtdblk_dev *mtdblk; +- struct mtd_info *mtd; +- int dev; ++ struct mtd_info *mtd = mbd->mtd; ++ int dev = mbd->devnum; + + DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n"); + +- if (!inode) +- return -EINVAL; +- +- dev = MINOR(inode->i_rdev); +- if (dev >= MAX_MTD_DEVICES) +- return -EINVAL; +- +- BLK_INC_USE_COUNT; +- +- mtd = get_mtd_device(NULL, dev); +- if (!mtd) +- return -ENODEV; +- if (MTD_ABSENT == mtd->type) { +- put_mtd_device(mtd); +- BLK_DEC_USE_COUNT; +- return -ENODEV; +- } +- +- spin_lock(&mtdblks_lock); +- +- /* If it's already open, no need to piss about. */ + if (mtdblks[dev]) { + mtdblks[dev]->count++; +- spin_unlock(&mtdblks_lock); +- put_mtd_device(mtd); + return 0; + } + +- /* OK, it's not open. Try to find it */ +- +- /* First we have to drop the lock, because we have to +- to things which might sleep. +- */ +- spin_unlock(&mtdblks_lock); +- ++ /* OK, it's not open. Create cache info for it */ + mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL); +- if (!mtdblk) { +- put_mtd_device(mtd); +- BLK_DEC_USE_COUNT; ++ if (!mtdblk) + return -ENOMEM; +- } ++ + memset(mtdblk, 0, sizeof(*mtdblk)); + mtdblk->count = 1; + mtdblk->mtd = mtd; +@@ -337,336 +287,102 @@ + if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM && + mtdblk->mtd->erasesize) { + mtdblk->cache_size = mtdblk->mtd->erasesize; +- mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize); +- if (!mtdblk->cache_data) { +- put_mtd_device(mtdblk->mtd); +- kfree(mtdblk); +- BLK_DEC_USE_COUNT; +- return -ENOMEM; +- } +- } +- +- /* OK, we've created a new one. Add it to the list. */ +- +- spin_lock(&mtdblks_lock); +- +- if (mtdblks[dev]) { +- /* Another CPU made one at the same time as us. */ +- mtdblks[dev]->count++; +- spin_unlock(&mtdblks_lock); +- put_mtd_device(mtdblk->mtd); +- vfree(mtdblk->cache_data); +- kfree(mtdblk); +- return 0; ++ mtdblk->cache_data = NULL; + } + + mtdblks[dev] = mtdblk; +- mtd_sizes[dev] = mtdblk->mtd->size/1024; +- if (mtdblk->mtd->erasesize) +- mtd_blksizes[dev] = mtdblk->mtd->erasesize; +- if (mtd_blksizes[dev] > PAGE_SIZE) +- mtd_blksizes[dev] = PAGE_SIZE; +- set_device_ro (inode->i_rdev, !(mtdblk->mtd->flags & MTD_WRITEABLE)); +- +- spin_unlock(&mtdblks_lock); + + DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); + + return 0; + } + +-static release_t mtdblock_release(struct inode *inode, struct file *file) ++static int mtdblock_release(struct mtd_blktrans_dev *mbd) + { +- int dev; +- struct mtdblk_dev *mtdblk; +- DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); ++ int dev = mbd->devnum; ++ struct mtdblk_dev *mtdblk = mtdblks[dev]; + +- if (inode == NULL) +- release_return(-ENODEV); +- +- dev = MINOR(inode->i_rdev); +- mtdblk = mtdblks[dev]; ++ DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); + + down(&mtdblk->cache_sem); + write_cached_data(mtdblk); + up(&mtdblk->cache_sem); + +- spin_lock(&mtdblks_lock); + if (!--mtdblk->count) { + /* It was the last usage. Free the device */ + mtdblks[dev] = NULL; +- spin_unlock(&mtdblks_lock); + if (mtdblk->mtd->sync) + mtdblk->mtd->sync(mtdblk->mtd); +- put_mtd_device(mtdblk->mtd); + vfree(mtdblk->cache_data); + kfree(mtdblk); +- } else { +- spin_unlock(&mtdblks_lock); + } +- + DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); + +- BLK_DEC_USE_COUNT; +- release_return(0); +-} +- +- +-/* +- * This is a special request_fn because it is executed in a process context +- * to be able to sleep independently of the caller. The io_request_lock +- * is held upon entry and exit. +- * The head of our request queue is considered active so there is no need +- * to dequeue requests before we are done. +- */ +-static void handle_mtdblock_request(void) +-{ +- struct request *req; +- struct mtdblk_dev *mtdblk; +- unsigned int res; +- +- for (;;) { +- INIT_REQUEST; +- req = CURRENT; +- spin_unlock_irq(&io_request_lock); +- mtdblk = mtdblks[MINOR(req->rq_dev)]; +- res = 0; +- +- if (MINOR(req->rq_dev) >= MAX_MTD_DEVICES) +- panic("%s: minor out of bounds", __FUNCTION__); +- +- if ((req->sector + req->current_nr_sectors) > (mtdblk->mtd->size >> 9)) +- goto end_req; +- +- // Handle the request +- switch (req->cmd) +- { +- int err; +- +- case READ: +- down(&mtdblk->cache_sem); +- err = do_cached_read (mtdblk, req->sector << 9, +- req->current_nr_sectors << 9, +- req->buffer); +- up(&mtdblk->cache_sem); +- if (!err) +- res = 1; +- break; +- +- case WRITE: +- // Read only device +- if ( !(mtdblk->mtd->flags & MTD_WRITEABLE) ) +- break; +- +- // Do the write +- down(&mtdblk->cache_sem); +- err = do_cached_write (mtdblk, req->sector << 9, +- req->current_nr_sectors << 9, +- req->buffer); +- up(&mtdblk->cache_sem); +- if (!err) +- res = 1; +- break; +- } +- +-end_req: +- spin_lock_irq(&io_request_lock); +- end_request(res); +- } +-} +- +-static volatile int leaving = 0; +-static DECLARE_MUTEX_LOCKED(thread_sem); +-static DECLARE_WAIT_QUEUE_HEAD(thr_wq); +- +-int mtdblock_thread(void *dummy) +-{ +- struct task_struct *tsk = current; +- DECLARE_WAITQUEUE(wait, tsk); +- +- /* we might get involved when memory gets low, so use PF_MEMALLOC */ +- tsk->flags |= PF_MEMALLOC; +- strcpy(tsk->comm, "mtdblockd"); +- spin_lock_irq(&tsk->sigmask_lock); +- sigfillset(&tsk->blocked); +- recalc_sigpending(tsk); +- spin_unlock_irq(&tsk->sigmask_lock); +- daemonize(); +- +- while (!leaving) { +- add_wait_queue(&thr_wq, &wait); +- set_current_state(TASK_INTERRUPTIBLE); +- spin_lock_irq(&io_request_lock); +- if (QUEUE_EMPTY || QUEUE_PLUGGED) { +- spin_unlock_irq(&io_request_lock); +- schedule(); +- remove_wait_queue(&thr_wq, &wait); +- } else { +- remove_wait_queue(&thr_wq, &wait); +- set_current_state(TASK_RUNNING); +- handle_mtdblock_request(); +- spin_unlock_irq(&io_request_lock); +- } +- } +- +- up(&thread_sem); + return 0; + } + +-#if LINUX_VERSION_CODE < 0x20300 +-#define RQFUNC_ARG void +-#else +-#define RQFUNC_ARG request_queue_t *q +-#endif +- +-static void mtdblock_request(RQFUNC_ARG) ++static int mtdblock_flush(struct mtd_blktrans_dev *dev) + { +- /* Don't do anything, except wake the thread if necessary */ +- wake_up(&thr_wq); +-} ++ struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; + +- +-static int mtdblock_ioctl(struct inode * inode, struct file * file, +- unsigned int cmd, unsigned long arg) +-{ +- struct mtdblk_dev *mtdblk; +- +- mtdblk = mtdblks[MINOR(inode->i_rdev)]; +- +-#ifdef PARANOIA +- if (!mtdblk) +- BUG(); +-#endif +- +- switch (cmd) { +- case BLKGETSIZE: /* Return device size */ +- return put_user((mtdblk->mtd->size >> 9), (unsigned long *) arg); +- +-#ifdef BLKGETSIZE64 +- case BLKGETSIZE64: +- return put_user((u64)mtdblk->mtd->size, (u64 *)arg); +-#endif +- +- case BLKFLSBUF: +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) +- if(!capable(CAP_SYS_ADMIN)) +- return -EACCES; +-#endif +- fsync_dev(inode->i_rdev); +- invalidate_buffers(inode->i_rdev); + down(&mtdblk->cache_sem); + write_cached_data(mtdblk); + up(&mtdblk->cache_sem); ++ + if (mtdblk->mtd->sync) + mtdblk->mtd->sync(mtdblk->mtd); + return 0; +- +- default: +- return -EINVAL; +- } + } + +-#if LINUX_VERSION_CODE < 0x20326 +-static struct file_operations mtd_fops = ++static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) + { +- open: mtdblock_open, +- ioctl: mtdblock_ioctl, +- release: mtdblock_release, +- read: block_read, +- write: block_write +-}; +-#else +-static struct block_device_operations mtd_fops = +-{ +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14) +- owner: THIS_MODULE, +-#endif +- open: mtdblock_open, +- release: mtdblock_release, +- ioctl: mtdblock_ioctl +-}; +-#endif ++ struct mtd_blktrans_dev *dev = kmalloc(sizeof(*dev), GFP_KERNEL); + +-#ifdef CONFIG_DEVFS_FS +-/* Notification that a new device has been added. Create the devfs entry for +- * it. */ +- +-static void mtd_notify_add(struct mtd_info* mtd) +-{ +- char name[8]; +- +- if (!mtd || mtd->type == MTD_ABSENT) ++ if (!dev) + return; + +- sprintf(name, "%d", mtd->index); +- devfs_rw_handle[mtd->index] = devfs_register(devfs_dir_handle, name, +- DEVFS_FL_DEFAULT, MTD_BLOCK_MAJOR, mtd->index, +- S_IFBLK | S_IRUGO | S_IWUGO, +- &mtd_fops, NULL); +-} +- +-static void mtd_notify_remove(struct mtd_info* mtd) +-{ +- if (!mtd || mtd->type == MTD_ABSENT) +- return; ++ memset(dev, 0, sizeof(*dev)); + +- devfs_unregister(devfs_rw_handle[mtd->index]); +-} +-#endif ++ dev->mtd = mtd; ++ dev->devnum = mtd->index; ++ dev->blksize = 512; ++ dev->size = mtd->size >> 9; ++ dev->tr = tr; ++ ++ if (!(mtd->flags & MTD_WRITEABLE)) ++ dev->readonly = 1; ++ ++ add_mtd_blktrans_dev(dev); ++} ++ ++static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev) ++{ ++ del_mtd_blktrans_dev(dev); ++ kfree(dev); ++} ++ ++struct mtd_blktrans_ops mtdblock_tr = { ++ .name = "mtdblock", ++ .major = 31, ++ .part_bits = 0, ++ .open = mtdblock_open, ++ .flush = mtdblock_flush, ++ .release = mtdblock_release, ++ .readsect = mtdblock_readsect, ++ .writesect = mtdblock_writesect, ++ .add_mtd = mtdblock_add_mtd, ++ .remove_dev = mtdblock_remove_dev, ++ .owner = THIS_MODULE, ++}; + + int __init init_mtdblock(void) + { +- int i; +- +- spin_lock_init(&mtdblks_lock); +-#ifdef CONFIG_DEVFS_FS +- if (devfs_register_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME, &mtd_fops)) +- { +- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", +- MTD_BLOCK_MAJOR); +- return -EAGAIN; +- } +- +- devfs_dir_handle = devfs_mk_dir(NULL, DEVICE_NAME, NULL); +- register_mtd_user(¬ifier); +-#else +- if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) { +- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", +- MTD_BLOCK_MAJOR); +- return -EAGAIN; +- } +-#endif +- +- /* We fill it in at open() time. */ +- for (i=0; i< MAX_MTD_DEVICES; i++) { +- mtd_sizes[i] = 0; +- mtd_blksizes[i] = BLOCK_SIZE; +- } +- init_waitqueue_head(&thr_wq); +- /* Allow the block size to default to BLOCK_SIZE. */ +- blksize_size[MAJOR_NR] = mtd_blksizes; +- blk_size[MAJOR_NR] = mtd_sizes; +- +- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request); +- kernel_thread (mtdblock_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND); +- return 0; ++ return register_mtd_blktrans(&mtdblock_tr); + } + + static void __exit cleanup_mtdblock(void) + { +- leaving = 1; +- wake_up(&thr_wq); +- down(&thread_sem); +-#ifdef CONFIG_DEVFS_FS +- unregister_mtd_user(¬ifier); +- devfs_unregister(devfs_dir_handle); +- devfs_unregister_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME); +-#else +- unregister_blkdev(MAJOR_NR,DEVICE_NAME); +-#endif +- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); +- blksize_size[MAJOR_NR] = NULL; +- blk_size[MAJOR_NR] = NULL; ++ deregister_mtd_blktrans(&mtdblock_tr); + } + + module_init(init_mtdblock); +diff -Nurb linux-mips-2.4.27/drivers/mtd/mtdblock_ro.c linux/drivers/mtd/mtdblock_ro.c +--- linux-mips-2.4.27/drivers/mtd/mtdblock_ro.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/mtdblock_ro.c 2004-11-19 10:25:11.645238400 +0100 +@@ -1,301 +1,87 @@ + /* +- * $Id: mtdblock_ro.c,v 1.12 2001/11/20 11:42:33 dwmw2 Exp $ ++ * $Id: mtdblock_ro.c,v 1.18 2003/06/23 12:00:08 dwmw2 Exp $ + * +- * Read-only version of the mtdblock device, without the +- * read/erase/modify/writeback stuff ++ * (C) 2003 David Woodhouse ++ * ++ * Simple read-only (writable only for RAM) mtdblock driver + */ + +-#ifdef MTDBLOCK_DEBUG +-#define DEBUGLVL debug +-#endif +- +- +-#include +-#include +- ++#include ++#include + #include +-#include +- +-#define MAJOR_NR MTD_BLOCK_MAJOR +-#define DEVICE_NAME "mtdblock" +-#define DEVICE_REQUEST mtdblock_request +-#define DEVICE_NR(device) (device) +-#define DEVICE_ON(device) +-#define DEVICE_OFF(device) +-#define DEVICE_NO_RANDOM +-#include +- +-#if LINUX_VERSION_CODE < 0x20300 +-#define RQFUNC_ARG void +-#define blkdev_dequeue_request(req) do {CURRENT = req->next;} while (0) +-#else +-#define RQFUNC_ARG request_queue_t *q +-#endif +- +-#ifdef MTDBLOCK_DEBUG +-static int debug = MTDBLOCK_DEBUG; +-MODULE_PARM(debug, "i"); +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14) +-#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT +-#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT +-#else +-#define BLK_INC_USE_COUNT do {} while(0) +-#define BLK_DEC_USE_COUNT do {} while(0) +-#endif +- +-static int mtd_sizes[MAX_MTD_DEVICES]; ++#include + +- +-static int mtdblock_open(struct inode *inode, struct file *file) ++static int mtdblock_readsect(struct mtd_blktrans_dev *dev, ++ unsigned long block, char *buf) + { +- struct mtd_info *mtd = NULL; +- +- int dev; +- +- DEBUG(1,"mtdblock_open\n"); +- +- if (inode == 0) +- return -EINVAL; +- +- dev = MINOR(inode->i_rdev); +- +- mtd = get_mtd_device(NULL, dev); +- if (!mtd) +- return -EINVAL; +- if (MTD_ABSENT == mtd->type) { +- put_mtd_device(mtd); +- return -EINVAL; +- } +- +- BLK_INC_USE_COUNT; +- +- mtd_sizes[dev] = mtd->size>>9; +- +- DEBUG(1, "ok\n"); ++ size_t retlen; + ++ if (dev->mtd->read(dev->mtd, (block * 512), 512, &retlen, buf)) ++ return 1; + return 0; + } + +-static release_t mtdblock_release(struct inode *inode, struct file *file) ++static int mtdblock_writesect(struct mtd_blktrans_dev *dev, ++ unsigned long block, char *buf) + { +- int dev; +- struct mtd_info *mtd; +- +- DEBUG(1, "mtdblock_release\n"); +- +- if (inode == NULL) +- release_return(-ENODEV); +- +- dev = MINOR(inode->i_rdev); +- mtd = __get_mtd_device(NULL, dev); +- +- if (!mtd) { +- printk(KERN_WARNING "MTD device is absent on mtd_release!\n"); +- BLK_DEC_USE_COUNT; +- release_return(-ENODEV); +- } +- +- if (mtd->sync) +- mtd->sync(mtd); +- +- put_mtd_device(mtd); +- +- DEBUG(1, "ok\n"); ++ size_t retlen; + +- BLK_DEC_USE_COUNT; +- release_return(0); ++ if (dev->mtd->write(dev->mtd, (block * 512), 512, &retlen, buf)) ++ return 1; ++ return 0; + } + +- +-static void mtdblock_request(RQFUNC_ARG) ++static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) + { +- struct request *current_request; +- unsigned int res = 0; +- struct mtd_info *mtd; +- +- while (1) +- { +- /* Grab the Request and unlink it from the request list, INIT_REQUEST +- will execute a return if we are done. */ +- INIT_REQUEST; +- current_request = CURRENT; +- +- if (MINOR(current_request->rq_dev) >= MAX_MTD_DEVICES) +- { +- printk("mtd: Unsupported device!\n"); +- end_request(0); +- continue; +- } +- +- // Grab our MTD structure +- +- mtd = __get_mtd_device(NULL, MINOR(current_request->rq_dev)); +- if (!mtd) { +- printk("MTD device %d doesn't appear to exist any more\n", CURRENT_DEV); +- end_request(0); +- } +- +- if (current_request->sector << 9 > mtd->size || +- (current_request->sector + current_request->current_nr_sectors) << 9 > mtd->size) +- { +- printk("mtd: Attempt to read past end of device!\n"); +- printk("size: %x, sector: %lx, nr_sectors %lx\n", mtd->size, +- current_request->sector, current_request->current_nr_sectors); +- end_request(0); +- continue; +- } +- +- /* Remove the request we are handling from the request list so nobody messes +- with it */ +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) +- /* Now drop the lock that the ll_rw_blk functions grabbed for us +- and process the request. This is necessary due to the extreme time +- we spend processing it. */ +- spin_unlock_irq(&io_request_lock); +-#endif +- +- // Handle the request +- switch (current_request->cmd) +- { +- size_t retlen; ++ struct mtd_blktrans_dev *dev = kmalloc(sizeof(*dev), GFP_KERNEL); + +- case READ: +- if (MTD_READ(mtd,current_request->sector<<9, +- current_request->current_nr_sectors << 9, +- &retlen, current_request->buffer) == 0) +- res = 1; +- else +- res = 0; +- break; ++ if (!dev) ++ return; + +- case WRITE: ++ memset(dev, 0, sizeof(*dev)); + +- /* printk("mtdblock_request WRITE sector=%d(%d)\n",current_request->sector, +- current_request->current_nr_sectors); +- */ ++ dev->mtd = mtd; ++ dev->devnum = mtd->index; ++ dev->blksize = 512; ++ dev->size = mtd->size >> 9; ++ dev->tr = tr; ++ if ((mtd->flags & (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEABLE)) != ++ (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEABLE)) ++ dev->readonly = 1; + +- // Read only device +- if ((mtd->flags & MTD_CAP_RAM) == 0) +- { +- res = 0; +- break; +- } +- +- // Do the write +- if (MTD_WRITE(mtd,current_request->sector<<9, +- current_request->current_nr_sectors << 9, +- &retlen, current_request->buffer) == 0) +- res = 1; +- else +- res = 0; +- break; +- +- // Shouldn't happen +- default: +- printk("mtd: unknown request\n"); +- break; +- } +- +- // Grab the lock and re-thread the item onto the linked list +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) +- spin_lock_irq(&io_request_lock); +-#endif +- end_request(res); +- } ++ add_mtd_blktrans_dev(dev); + } + +- +- +-static int mtdblock_ioctl(struct inode * inode, struct file * file, +- unsigned int cmd, unsigned long arg) ++static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev) + { +- struct mtd_info *mtd; +- +- mtd = __get_mtd_device(NULL, MINOR(inode->i_rdev)); +- +- if (!mtd) return -EINVAL; +- +- switch (cmd) { +- case BLKGETSIZE: /* Return device size */ +- return put_user((mtd->size >> 9), (unsigned long *) arg); +- +-#ifdef BLKGETSIZE64 +- case BLKGETSIZE64: +- return put_user((u64)mtd->size, (u64 *)arg); +-#endif +- +- case BLKFLSBUF: +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) +- if(!capable(CAP_SYS_ADMIN)) return -EACCES; +-#endif +- fsync_dev(inode->i_rdev); +- invalidate_buffers(inode->i_rdev); +- if (mtd->sync) +- mtd->sync(mtd); +- return 0; +- +- default: +- return -ENOTTY; +- } ++ del_mtd_blktrans_dev(dev); ++ kfree(dev); + } + +-#if LINUX_VERSION_CODE < 0x20326 +-static struct file_operations mtd_fops = +-{ +- open: mtdblock_open, +- ioctl: mtdblock_ioctl, +- release: mtdblock_release, +- read: block_read, +- write: block_write +-}; +-#else +-static struct block_device_operations mtd_fops = +-{ +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14) +- owner: THIS_MODULE, +-#endif +- open: mtdblock_open, +- release: mtdblock_release, +- ioctl: mtdblock_ioctl ++struct mtd_blktrans_ops mtdblock_tr = { ++ .name = "mtdblock", ++ .major = 31, ++ .part_bits = 0, ++ .readsect = mtdblock_readsect, ++ .writesect = mtdblock_writesect, ++ .add_mtd = mtdblock_add_mtd, ++ .remove_dev = mtdblock_remove_dev, ++ .owner = THIS_MODULE, + }; +-#endif + +-int __init init_mtdblock(void) ++static int __init mtdblock_init(void) + { +- int i; +- +- if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) { +- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", +- MTD_BLOCK_MAJOR); +- return -EAGAIN; +- } +- +- /* We fill it in at open() time. */ +- for (i=0; i< MAX_MTD_DEVICES; i++) { +- mtd_sizes[i] = 0; +- } +- +- /* Allow the block size to default to BLOCK_SIZE. */ +- blksize_size[MAJOR_NR] = NULL; +- blk_size[MAJOR_NR] = mtd_sizes; +- +- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request); +- return 0; ++ return register_mtd_blktrans(&mtdblock_tr); + } + +-static void __exit cleanup_mtdblock(void) ++static void __exit mtdblock_exit(void) + { +- unregister_blkdev(MAJOR_NR,DEVICE_NAME); +- blk_size[MAJOR_NR] = NULL; +- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); ++ deregister_mtd_blktrans(&mtdblock_tr); + } + +-module_init(init_mtdblock); +-module_exit(cleanup_mtdblock); +- ++module_init(mtdblock_init); ++module_exit(mtdblock_exit); + + MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Erwin Authried et al."); ++MODULE_AUTHOR("David Woodhouse "); + MODULE_DESCRIPTION("Simple read-only block device emulation access to MTD devices"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/mtdchar.c linux/drivers/mtd/mtdchar.c +--- linux-mips-2.4.27/drivers/mtd/mtdchar.c 2004-08-14 20:38:51.000000000 +0200 ++++ linux/drivers/mtd/mtdchar.c 2004-11-19 10:25:11.647238096 +0100 +@@ -1,8 +1,7 @@ + /* +- * $Id: mtdchar.c,v 1.49 2003/01/24 12:02:58 dwmw2 Exp $ ++ * $Id: mtdchar.c,v 1.56 2003/11/14 19:50:03 thayne Exp $ + * + * Character-device access to raw MTD devices. +- * Pure 2.4 version - compatibility cruft removed to mtdchar-compat.c + * + */ + +@@ -10,7 +9,11 @@ + #include + #include + #include ++#include + #include ++#include ++#include ++#include + + #ifdef CONFIG_DEVFS_FS + #include +@@ -18,8 +21,8 @@ + static void mtd_notify_remove(struct mtd_info* mtd); + + static struct mtd_notifier notifier = { +- add: mtd_notify_add, +- remove: mtd_notify_remove, ++ .add = mtd_notify_add, ++ .remove = mtd_notify_remove, + }; + + static devfs_handle_t devfs_dir_handle; +@@ -60,7 +63,7 @@ + + static int mtd_open(struct inode *inode, struct file *file) + { +- int minor = minor(inode->i_rdev); ++ int minor = iminor(inode); + int devnum = minor >> 1; + struct mtd_info *mtd; + +@@ -125,15 +128,11 @@ + int ret=0; + int len; + char *kbuf; +- loff_t pos = *ppos; + + DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n"); + +- if (pos < 0 || pos > mtd->size) +- return 0; +- +- if (count > mtd->size - pos) +- count = mtd->size - pos; ++ if (*ppos + count > mtd->size) ++ count = mtd->size - *ppos; + + if (!count) + return 0; +@@ -150,9 +149,9 @@ + if (!kbuf) + return -ENOMEM; + +- ret = MTD_READ(mtd, pos, len, &retlen, kbuf); ++ ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf); + if (!ret) { +- pos += retlen; ++ *ppos += retlen; + if (copy_to_user(buf, kbuf, retlen)) { + kfree(kbuf); + return -EFAULT; +@@ -171,8 +170,6 @@ + kfree(kbuf); + } + +- *ppos = pos; +- + return total_retlen; + } /* mtd_read */ + +@@ -182,17 +179,16 @@ + char *kbuf; + size_t retlen; + size_t total_retlen=0; +- loff_t pos = *ppos; + int ret=0; + int len; + + DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n"); + +- if (pos < 0 || pos >= mtd->size) ++ if (*ppos == mtd->size) + return -ENOSPC; + +- if (count > mtd->size - pos) +- count = mtd->size - pos; ++ if (*ppos + count > mtd->size) ++ count = mtd->size - *ppos; + + if (!count) + return 0; +@@ -214,9 +210,9 @@ + return -EFAULT; + } + +- ret = (*(mtd->write))(mtd, pos, len, &retlen, kbuf); ++ ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf); + if (!ret) { +- pos += retlen; ++ *ppos += retlen; + total_retlen += retlen; + count -= retlen; + buf += retlen; +@@ -228,7 +224,6 @@ + + kfree(kbuf); + } +- *ppos = pos; + + return total_retlen; + } /* mtd_write */ +@@ -450,81 +445,13 @@ + break; + } + +- case MEMWRITEDATA: +- { +- struct mtd_oob_buf buf; +- void *databuf; +- ssize_t retlen; +- +- if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf))) +- return -EFAULT; +- +- if (buf.length > 0x4096) +- return -EINVAL; +- +- if (!mtd->write_ecc) +- ret = -EOPNOTSUPP; +- else +- ret = verify_area(VERIFY_READ, (char *)buf.ptr, buf.length); +- +- if (ret) +- return ret; +- +- databuf = kmalloc(buf.length, GFP_KERNEL); +- if (!databuf) +- return -ENOMEM; +- +- if (copy_from_user(databuf, buf.ptr, buf.length)) { +- kfree(databuf); +- return -EFAULT; +- } +- +- ret = (mtd->write_ecc)(mtd, buf.start, buf.length, &retlen, databuf, NULL, 0); +- +- if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) +- ret = -EFAULT; +- +- kfree(databuf); +- break; +- +- } +- +- case MEMREADDATA: ++ case MEMSETOOBSEL: + { +- struct mtd_oob_buf buf; +- void *databuf; +- ssize_t retlen = 0; +- +- if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf))) ++ if (copy_from_user(&mtd->oobinfo ,(void *)arg, sizeof(struct nand_oobinfo))) + return -EFAULT; +- +- if (buf.length > 0x4096) +- return -EINVAL; +- +- if (!mtd->read_ecc) +- ret = -EOPNOTSUPP; +- else +- ret = verify_area(VERIFY_WRITE, (char *)buf.ptr, buf.length); +- +- if (ret) +- return ret; +- +- databuf = kmalloc(buf.length, GFP_KERNEL); +- if (!databuf) +- return -ENOMEM; +- +- ret = (mtd->read_ecc)(mtd, buf.start, buf.length, &retlen, databuf, NULL, 0); +- +- if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t))) +- ret = -EFAULT; +- else if (retlen && copy_to_user(buf.ptr, databuf, retlen)) +- ret = -EFAULT; +- +- kfree(databuf); + break; + } + +- + default: + DEBUG(MTD_DEBUG_LEVEL0, "Invalid ioctl %x (MEMGETINFO = %x)\n", cmd, MEMGETINFO); + ret = -ENOTTY; +@@ -534,13 +461,13 @@ + } /* memory_ioctl */ + + static struct file_operations mtd_fops = { +- owner: THIS_MODULE, +- llseek: mtd_lseek, /* lseek */ +- read: mtd_read, /* read */ +- write: mtd_write, /* write */ +- ioctl: mtd_ioctl, /* ioctl */ +- open: mtd_open, /* open */ +- release: mtd_close, /* release */ ++ .owner = THIS_MODULE, ++ .llseek = mtd_lseek, ++ .read = mtd_read, ++ .write = mtd_write, ++ .ioctl = mtd_ioctl, ++ .open = mtd_open, ++ .release = mtd_close, + }; + + +@@ -580,26 +507,18 @@ + + static int __init init_mtdchar(void) + { +-#ifdef CONFIG_DEVFS_FS +- if (devfs_register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) ++ if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) + { + printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", + MTD_CHAR_MAJOR); + return -EAGAIN; + } + ++#ifdef CONFIG_DEVFS_FS + devfs_dir_handle = devfs_mk_dir(NULL, "mtd", NULL); + + register_mtd_user(¬ifier); +-#else +- if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) +- { +- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n", +- MTD_CHAR_MAJOR); +- return -EAGAIN; +- } + #endif +- + return 0; + } + +@@ -608,10 +527,8 @@ + #ifdef CONFIG_DEVFS_FS + unregister_mtd_user(¬ifier); + devfs_unregister(devfs_dir_handle); +- devfs_unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); +-#else +- unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); + #endif ++ unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); + } + + module_init(init_mtdchar); +diff -Nurb linux-mips-2.4.27/drivers/mtd/mtdconcat.c linux/drivers/mtd/mtdconcat.c +--- linux-mips-2.4.27/drivers/mtd/mtdconcat.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/mtdconcat.c 2004-11-19 10:25:11.649237792 +0100 +@@ -3,9 +3,11 @@ + * + * (C) 2002 Robert Kaiser + * ++ * NAND support by Christian Gan ++ * + * This code is GPL + * +- * $Id: mtdconcat.c,v 1.3 2002/05/21 21:04:25 dwmw2 Exp $ ++ * $Id: mtdconcat.c,v 1.8 2003/06/30 11:01:26 dwmw2 Exp $ + */ + + #include +@@ -35,21 +37,20 @@ + #define SIZEOF_STRUCT_MTD_CONCAT(num_subdev) \ + ((sizeof(struct mtd_concat) + (num_subdev) * sizeof(struct mtd_info *))) + +- + /* + * Given a pointer to the MTD object in the mtd_concat structure, + * we can retrieve the pointer to that structure with this macro. + */ + #define CONCAT(x) ((struct mtd_concat *)(x)) + +- + /* + * MTD methods which look up the relevant subdevice, translate the + * effective address and pass through to the subdevice. + */ + +-static int concat_read (struct mtd_info *mtd, loff_t from, size_t len, +- size_t *retlen, u_char *buf) ++static int ++concat_read(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t * retlen, u_char * buf) + { + struct mtd_concat *concat = CONCAT(mtd); + int err = -EINVAL; +@@ -57,43 +58,43 @@ + + *retlen = 0; + +- for(i = 0; i < concat->num_subdev; i++) +- { ++ for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; + size_t size, retsize; + +- if (from >= subdev->size) +- { ++ if (from >= subdev->size) { ++ /* Not destined for this subdev */ + size = 0; + from -= subdev->size; ++ continue; + } +- else +- { + if (from + len > subdev->size) ++ /* First part goes into this subdev */ + size = subdev->size - from; + else ++ /* Entire transaction goes into this subdev */ + size = len; + + err = subdev->read(subdev, from, size, &retsize, buf); + +- if(err) ++ if (err) + break; + + *retlen += retsize; + len -= size; +- if(len == 0) ++ if (len == 0) + break; + + err = -EINVAL; + buf += size; + from = 0; + } +- } + return err; + } + +-static int concat_write (struct mtd_info *mtd, loff_t to, size_t len, +- size_t *retlen, const u_char *buf) ++static int ++concat_write(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t * retlen, const u_char * buf) + { + struct mtd_concat *concat = CONCAT(mtd); + int err = -EINVAL; +@@ -104,18 +105,15 @@ + + *retlen = 0; + +- for(i = 0; i < concat->num_subdev; i++) +- { ++ for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; + size_t size, retsize; + +- if (to >= subdev->size) +- { ++ if (to >= subdev->size) { + size = 0; + to -= subdev->size; ++ continue; + } +- else +- { + if (to + len > subdev->size) + size = subdev->size - to; + else +@@ -126,25 +124,232 @@ + else + err = subdev->write(subdev, to, size, &retsize, buf); + +- if(err) ++ if (err) + break; + + *retlen += retsize; + len -= size; +- if(len == 0) ++ if (len == 0) + break; + + err = -EINVAL; + buf += size; + to = 0; + } ++ return err; ++} ++ ++static int ++concat_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t * retlen, u_char * buf, u_char * eccbuf, ++ struct nand_oobinfo *oobsel) ++{ ++ struct mtd_concat *concat = CONCAT(mtd); ++ int err = -EINVAL; ++ int i; ++ ++ *retlen = 0; ++ ++ for (i = 0; i < concat->num_subdev; i++) { ++ struct mtd_info *subdev = concat->subdev[i]; ++ size_t size, retsize; ++ ++ if (from >= subdev->size) { ++ /* Not destined for this subdev */ ++ size = 0; ++ from -= subdev->size; ++ continue; ++ } ++ ++ if (from + len > subdev->size) ++ /* First part goes into this subdev */ ++ size = subdev->size - from; ++ else ++ /* Entire transaction goes into this subdev */ ++ size = len; ++ ++ if (subdev->read_ecc) ++ err = subdev->read_ecc(subdev, from, size, ++ &retsize, buf, eccbuf, oobsel); ++ else ++ err = -EINVAL; ++ ++ if (err) ++ break; ++ ++ *retlen += retsize; ++ len -= size; ++ if (len == 0) ++ break; ++ ++ err = -EINVAL; ++ buf += size; ++ if (eccbuf) { ++ eccbuf += subdev->oobsize; ++ /* in nand.c at least, eccbufs are ++ tagged with 2 (int)eccstatus'; we ++ must account for these */ ++ eccbuf += 2 * (sizeof (int)); ++ } ++ from = 0; + } + return err; + } + +-static void concat_erase_callback (struct erase_info *instr) ++static int ++concat_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t * retlen, const u_char * buf, u_char * eccbuf, ++ struct nand_oobinfo *oobsel) + { +- wake_up((wait_queue_head_t *)instr->priv); ++ struct mtd_concat *concat = CONCAT(mtd); ++ int err = -EINVAL; ++ int i; ++ ++ if (!(mtd->flags & MTD_WRITEABLE)) ++ return -EROFS; ++ ++ *retlen = 0; ++ ++ for (i = 0; i < concat->num_subdev; i++) { ++ struct mtd_info *subdev = concat->subdev[i]; ++ size_t size, retsize; ++ ++ if (to >= subdev->size) { ++ size = 0; ++ to -= subdev->size; ++ continue; ++ } ++ if (to + len > subdev->size) ++ size = subdev->size - to; ++ else ++ size = len; ++ ++ if (!(subdev->flags & MTD_WRITEABLE)) ++ err = -EROFS; ++ else if (subdev->write_ecc) ++ err = subdev->write_ecc(subdev, to, size, ++ &retsize, buf, eccbuf, oobsel); ++ else ++ err = -EINVAL; ++ ++ if (err) ++ break; ++ ++ *retlen += retsize; ++ len -= size; ++ if (len == 0) ++ break; ++ ++ err = -EINVAL; ++ buf += size; ++ if (eccbuf) ++ eccbuf += subdev->oobsize; ++ to = 0; ++ } ++ return err; ++} ++ ++static int ++concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t * retlen, u_char * buf) ++{ ++ struct mtd_concat *concat = CONCAT(mtd); ++ int err = -EINVAL; ++ int i; ++ ++ *retlen = 0; ++ ++ for (i = 0; i < concat->num_subdev; i++) { ++ struct mtd_info *subdev = concat->subdev[i]; ++ size_t size, retsize; ++ ++ if (from >= subdev->size) { ++ /* Not destined for this subdev */ ++ size = 0; ++ from -= subdev->size; ++ continue; ++ } ++ if (from + len > subdev->size) ++ /* First part goes into this subdev */ ++ size = subdev->size - from; ++ else ++ /* Entire transaction goes into this subdev */ ++ size = len; ++ ++ if (subdev->read_oob) ++ err = subdev->read_oob(subdev, from, size, ++ &retsize, buf); ++ else ++ err = -EINVAL; ++ ++ if (err) ++ break; ++ ++ *retlen += retsize; ++ len -= size; ++ if (len == 0) ++ break; ++ ++ err = -EINVAL; ++ buf += size; ++ from = 0; ++ } ++ return err; ++} ++ ++static int ++concat_write_oob(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t * retlen, const u_char * buf) ++{ ++ struct mtd_concat *concat = CONCAT(mtd); ++ int err = -EINVAL; ++ int i; ++ ++ if (!(mtd->flags & MTD_WRITEABLE)) ++ return -EROFS; ++ ++ *retlen = 0; ++ ++ for (i = 0; i < concat->num_subdev; i++) { ++ struct mtd_info *subdev = concat->subdev[i]; ++ size_t size, retsize; ++ ++ if (to >= subdev->size) { ++ size = 0; ++ to -= subdev->size; ++ continue; ++ } ++ if (to + len > subdev->size) ++ size = subdev->size - to; ++ else ++ size = len; ++ ++ if (!(subdev->flags & MTD_WRITEABLE)) ++ err = -EROFS; ++ else if (subdev->write_oob) ++ err = subdev->write_oob(subdev, to, size, &retsize, ++ buf); ++ else ++ err = -EINVAL; ++ ++ if (err) ++ break; ++ ++ *retlen += retsize; ++ len -= size; ++ if (len == 0) ++ break; ++ ++ err = -EINVAL; ++ buf += size; ++ to = 0; ++ } ++ return err; ++} ++ ++static void concat_erase_callback(struct erase_info *instr) ++{ ++ wake_up((wait_queue_head_t *) instr->priv); + } + + static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase) +@@ -160,18 +365,18 @@ + + erase->mtd = mtd; + erase->callback = concat_erase_callback; +- erase->priv = (unsigned long)&waitq; ++ erase->priv = (unsigned long) &waitq; + + /* + * FIXME: Allow INTERRUPTIBLE. Which means + * not having the wait_queue head on the stack. + */ + err = mtd->erase(mtd, erase); +- if (!err) +- { ++ if (!err) { + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&waitq, &wait); +- if (erase->state != MTD_ERASE_DONE && erase->state != MTD_ERASE_FAILED) ++ if (erase->state != MTD_ERASE_DONE ++ && erase->state != MTD_ERASE_FAILED) + schedule(); + remove_wait_queue(&waitq, &wait); + set_current_state(TASK_RUNNING); +@@ -181,7 +386,7 @@ + return err; + } + +-static int concat_erase (struct mtd_info *mtd, struct erase_info *instr) ++static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) + { + struct mtd_concat *concat = CONCAT(mtd); + struct mtd_info *subdev; +@@ -192,10 +397,10 @@ + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + +- if(instr->addr > concat->mtd.size) ++ if (instr->addr > concat->mtd.size) + return -EINVAL; + +- if(instr->len + instr->addr > concat->mtd.size) ++ if (instr->len + instr->addr > concat->mtd.size) + return -EINVAL; + + /* +@@ -204,23 +409,22 @@ + * region info rather than looking at each particular sub-device + * in turn. + */ +- if (!concat->mtd.numeraseregions) +- { /* the easy case: device has uniform erase block size */ +- if(instr->addr & (concat->mtd.erasesize - 1)) ++ if (!concat->mtd.numeraseregions) { ++ /* the easy case: device has uniform erase block size */ ++ if (instr->addr & (concat->mtd.erasesize - 1)) + return -EINVAL; +- if(instr->len & (concat->mtd.erasesize - 1)) ++ if (instr->len & (concat->mtd.erasesize - 1)) + return -EINVAL; +- } +- else +- { /* device has variable erase size */ +- struct mtd_erase_region_info *erase_regions = concat->mtd.eraseregions; ++ } else { ++ /* device has variable erase size */ ++ struct mtd_erase_region_info *erase_regions = ++ concat->mtd.eraseregions; + + /* + * Find the erase region where the to-be-erased area begins: + */ +- for(i = 0; i < concat->mtd.numeraseregions && +- instr->addr >= erase_regions[i].offset; i++) +- ; ++ for (i = 0; i < concat->mtd.numeraseregions && ++ instr->addr >= erase_regions[i].offset; i++) ; + --i; + + /* +@@ -228,25 +432,26 @@ + * to-be-erased area begins. Verify that the starting + * offset is aligned to this region's erase size: + */ +- if (instr->addr & (erase_regions[i].erasesize-1)) ++ if (instr->addr & (erase_regions[i].erasesize - 1)) + return -EINVAL; + + /* + * now find the erase region where the to-be-erased area ends: + */ +- for(; i < concat->mtd.numeraseregions && +- (instr->addr + instr->len) >= erase_regions[i].offset ; ++i) +- ; ++ for (; i < concat->mtd.numeraseregions && ++ (instr->addr + instr->len) >= erase_regions[i].offset; ++ ++i) ; + --i; + /* + * check if the ending offset is aligned to this region's erase size + */ +- if ((instr->addr + instr->len) & (erase_regions[i].erasesize-1)) ++ if ((instr->addr + instr->len) & (erase_regions[i].erasesize - ++ 1)) + return -EINVAL; + } + + /* make a local copy of instr to avoid modifying the caller's struct */ +- erase = kmalloc(sizeof(struct erase_info),GFP_KERNEL); ++ erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL); + + if (!erase) + return -ENOMEM; +@@ -258,39 +463,40 @@ + * find the subdevice where the to-be-erased area begins, adjust + * starting offset to be relative to the subdevice start + */ +- for(i = 0; i < concat->num_subdev; i++) +- { ++ for (i = 0; i < concat->num_subdev; i++) { + subdev = concat->subdev[i]; +- if(subdev->size <= erase->addr) ++ if (subdev->size <= erase->addr) + erase->addr -= subdev->size; + else + break; + } +- if(i >= concat->num_subdev) /* must never happen since size */ +- BUG(); /* limit has been verified above */ ++ ++ /* must never happen since size limit has been verified above */ ++ if (i >= concat->num_subdev) ++ BUG(); + + /* now do the erase: */ + err = 0; +- for(;length > 0; i++) /* loop for all subevices affected by this request */ +- { ++ for (; length > 0; i++) { ++ /* loop for all subdevices affected by this request */ + subdev = concat->subdev[i]; /* get current subdevice */ + + /* limit length to subdevice's size: */ +- if(erase->addr + length > subdev->size) ++ if (erase->addr + length > subdev->size) + erase->len = subdev->size - erase->addr; + else + erase->len = length; + +- if (!(subdev->flags & MTD_WRITEABLE)) +- { ++ if (!(subdev->flags & MTD_WRITEABLE)) { + err = -EROFS; + break; + } + length -= erase->len; +- if ((err = concat_dev_erase(subdev, erase))) +- { +- if(err == -EINVAL) /* sanity check: must never happen since */ +- BUG(); /* block alignment has been checked above */ ++ if ((err = concat_dev_erase(subdev, erase))) { ++ /* sanity check: should never happen since ++ * block alignment has been checked above */ ++ if (err == -EINVAL) ++ BUG(); + break; + } + /* +@@ -313,7 +519,7 @@ + return 0; + } + +-static int concat_lock (struct mtd_info *mtd, loff_t ofs, size_t len) ++static int concat_lock(struct mtd_info *mtd, loff_t ofs, size_t len) + { + struct mtd_concat *concat = CONCAT(mtd); + int i, err = -EINVAL; +@@ -321,18 +527,15 @@ + if ((len + ofs) > mtd->size) + return -EINVAL; + +- for(i = 0; i < concat->num_subdev; i++) +- { ++ for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; + size_t size; + +- if (ofs >= subdev->size) +- { ++ if (ofs >= subdev->size) { + size = 0; + ofs -= subdev->size; ++ continue; + } +- else +- { + if (ofs + len > subdev->size) + size = subdev->size - ofs; + else +@@ -340,21 +543,21 @@ + + err = subdev->lock(subdev, ofs, size); + +- if(err) ++ if (err) + break; + + len -= size; +- if(len == 0) ++ if (len == 0) + break; + + err = -EINVAL; + ofs = 0; + } +- } ++ + return err; + } + +-static int concat_unlock (struct mtd_info *mtd, loff_t ofs, size_t len) ++static int concat_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) + { + struct mtd_concat *concat = CONCAT(mtd); + int i, err = 0; +@@ -362,18 +565,15 @@ + if ((len + ofs) > mtd->size) + return -EINVAL; + +- for(i = 0; i < concat->num_subdev; i++) +- { ++ for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; + size_t size; + +- if (ofs >= subdev->size) +- { ++ if (ofs >= subdev->size) { + size = 0; + ofs -= subdev->size; ++ continue; + } +- else +- { + if (ofs + len > subdev->size) + size = subdev->size - ofs; + else +@@ -381,17 +581,17 @@ + + err = subdev->unlock(subdev, ofs, size); + +- if(err) ++ if (err) + break; + + len -= size; +- if(len == 0) ++ if (len == 0) + break; + + err = -EINVAL; + ofs = 0; + } +- } ++ + return err; + } + +@@ -400,8 +600,7 @@ + struct mtd_concat *concat = CONCAT(mtd); + int i; + +- for(i = 0; i < concat->num_subdev; i++) +- { ++ for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; + subdev->sync(subdev); + } +@@ -412,10 +611,9 @@ + struct mtd_concat *concat = CONCAT(mtd); + int i, rc = 0; + +- for(i = 0; i < concat->num_subdev; i++) +- { ++ for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; +- if((rc = subdev->suspend(subdev)) < 0) ++ if ((rc = subdev->suspend(subdev)) < 0) + return rc; + } + return rc; +@@ -426,8 +624,7 @@ + struct mtd_concat *concat = CONCAT(mtd); + int i; + +- for(i = 0; i < concat->num_subdev; i++) +- { ++ for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; + subdev->resume(subdev); + } +@@ -439,11 +636,10 @@ + * stored to *new_dev upon success. This function does _not_ + * register any devices: this is the caller's responsibility. + */ +-struct mtd_info *mtd_concat_create( +- struct mtd_info *subdev[], /* subdevices to concatenate */ ++struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to concatenate */ + int num_devs, /* number of subdevices */ +- char *name) /* name for the new device */ +-{ ++ char *name) ++{ /* name for the new device */ + int i; + size_t size; + struct mtd_concat *concat; +@@ -451,21 +647,21 @@ + int num_erase_region; + + printk(KERN_NOTICE "Concatenating MTD devices:\n"); +- for(i = 0; i < num_devs; i++) ++ for (i = 0; i < num_devs; i++) + printk(KERN_NOTICE "(%d): \"%s\"\n", i, subdev[i]->name); + printk(KERN_NOTICE "into device \"%s\"\n", name); + + /* allocate the device structure */ + size = SIZEOF_STRUCT_MTD_CONCAT(num_devs); +- concat = kmalloc (size, GFP_KERNEL); +- if(!concat) +- { +- printk ("memory allocation error while creating concatenated device \"%s\"\n", ++ concat = kmalloc(size, GFP_KERNEL); ++ if (!concat) { ++ printk ++ ("memory allocation error while creating concatenated device \"%s\"\n", + name); + return NULL; + } + memset(concat, 0, size); +- concat->subdev = (struct mtd_info **)(concat + 1); ++ concat->subdev = (struct mtd_info **) (concat + 1); + + /* + * Set up the new "super" device's MTD object structure, check for +@@ -479,39 +675,53 @@ + concat->mtd.oobsize = subdev[0]->oobsize; + concat->mtd.ecctype = subdev[0]->ecctype; + concat->mtd.eccsize = subdev[0]->eccsize; ++ if (subdev[0]->read_ecc) ++ concat->mtd.read_ecc = concat_read_ecc; ++ if (subdev[0]->write_ecc) ++ concat->mtd.write_ecc = concat_write_ecc; ++ if (subdev[0]->read_oob) ++ concat->mtd.read_oob = concat_read_oob; ++ if (subdev[0]->write_oob) ++ concat->mtd.write_oob = concat_write_oob; + + concat->subdev[0] = subdev[0]; + +- for(i = 1; i < num_devs; i++) +- { +- if(concat->mtd.type != subdev[i]->type) +- { ++ for (i = 1; i < num_devs; i++) { ++ if (concat->mtd.type != subdev[i]->type) { + kfree(concat); +- printk ("Incompatible device type on \"%s\"\n", subdev[i]->name); ++ printk("Incompatible device type on \"%s\"\n", ++ subdev[i]->name); + return NULL; + } +- if(concat->mtd.flags != subdev[i]->flags) +- { /* +- * Expect all flags except MTD_WRITEABLE to be equal on +- * all subdevices. ++ if (concat->mtd.flags != subdev[i]->flags) { ++ /* ++ * Expect all flags except MTD_WRITEABLE to be ++ * equal on all subdevices. + */ +- if((concat->mtd.flags ^ subdev[i]->flags) & ~MTD_WRITEABLE) +- { ++ if ((concat->mtd.flags ^ subdev[i]-> ++ flags) & ~MTD_WRITEABLE) { + kfree(concat); +- printk ("Incompatible device flags on \"%s\"\n", subdev[i]->name); ++ printk("Incompatible device flags on \"%s\"\n", ++ subdev[i]->name); + return NULL; +- } +- else /* if writeable attribute differs, make super device writeable */ +- concat->mtd.flags |= subdev[i]->flags & MTD_WRITEABLE; ++ } else ++ /* if writeable attribute differs, ++ make super device writeable */ ++ concat->mtd.flags |= ++ subdev[i]->flags & MTD_WRITEABLE; + } + concat->mtd.size += subdev[i]->size; +- if(concat->mtd.oobblock != subdev[i]->oobblock || ++ if (concat->mtd.oobblock != subdev[i]->oobblock || + concat->mtd.oobsize != subdev[i]->oobsize || + concat->mtd.ecctype != subdev[i]->ecctype || +- concat->mtd.eccsize != subdev[i]->eccsize) +- { ++ concat->mtd.eccsize != subdev[i]->eccsize || ++ !concat->mtd.read_ecc != !subdev[i]->read_ecc || ++ !concat->mtd.write_ecc != !subdev[i]->write_ecc || ++ !concat->mtd.read_oob != !subdev[i]->read_oob || ++ !concat->mtd.write_oob != !subdev[i]->write_oob) { + kfree(concat); +- printk ("Incompatible OOB or ECC data on \"%s\"\n", subdev[i]->name); ++ printk("Incompatible OOB or ECC data on \"%s\"\n", ++ subdev[i]->name); + return NULL; + } + concat->subdev[i] = subdev[i]; +@@ -535,7 +745,6 @@ + concat->mtd.suspend = concat_suspend; + concat->mtd.resume = concat_resume; + +- + /* + * Combine the erase block size info of the subdevices: + * +@@ -544,44 +753,44 @@ + */ + max_erasesize = curr_erasesize = subdev[0]->erasesize; + num_erase_region = 1; +- for(i = 0; i < num_devs; i++) +- { +- if(subdev[i]->numeraseregions == 0) +- { /* current subdevice has uniform erase size */ +- if(subdev[i]->erasesize != curr_erasesize) +- { /* if it differs from the last subdevice's erase size, count it */ ++ for (i = 0; i < num_devs; i++) { ++ if (subdev[i]->numeraseregions == 0) { ++ /* current subdevice has uniform erase size */ ++ if (subdev[i]->erasesize != curr_erasesize) { ++ /* if it differs from the last subdevice's erase size, count it */ + ++num_erase_region; + curr_erasesize = subdev[i]->erasesize; +- if(curr_erasesize > max_erasesize) ++ if (curr_erasesize > max_erasesize) + max_erasesize = curr_erasesize; + } +- } +- else +- { /* current subdevice has variable erase size */ ++ } else { ++ /* current subdevice has variable erase size */ + int j; +- for(j = 0; j < subdev[i]->numeraseregions; j++) +- { /* walk the list of erase regions, count any changes */ +- if(subdev[i]->eraseregions[j].erasesize != curr_erasesize) +- { ++ for (j = 0; j < subdev[i]->numeraseregions; j++) { ++ ++ /* walk the list of erase regions, count any changes */ ++ if (subdev[i]->eraseregions[j].erasesize != ++ curr_erasesize) { + ++num_erase_region; +- curr_erasesize = subdev[i]->eraseregions[j].erasesize; +- if(curr_erasesize > max_erasesize) ++ curr_erasesize = ++ subdev[i]->eraseregions[j]. ++ erasesize; ++ if (curr_erasesize > max_erasesize) + max_erasesize = curr_erasesize; + } + } + } + } + +- if(num_erase_region == 1) +- { /* ++ if (num_erase_region == 1) { ++ /* + * All subdevices have the same uniform erase size. + * This is easy: + */ + concat->mtd.erasesize = curr_erasesize; + concat->mtd.numeraseregions = 0; +- } +- else +- { /* ++ } else { ++ /* + * erase block size varies across the subdevices: allocate + * space to store the data describing the variable erase regions + */ +@@ -590,12 +799,13 @@ + + concat->mtd.erasesize = max_erasesize; + concat->mtd.numeraseregions = num_erase_region; +- concat->mtd.eraseregions = erase_region_p = kmalloc ( +- num_erase_region * sizeof(struct mtd_erase_region_info), GFP_KERNEL); +- if(!erase_region_p) +- { ++ concat->mtd.eraseregions = erase_region_p = ++ kmalloc(num_erase_region * ++ sizeof (struct mtd_erase_region_info), GFP_KERNEL); ++ if (!erase_region_p) { + kfree(concat); +- printk ("memory allocation error while creating erase region list" ++ printk ++ ("memory allocation error while creating erase region list" + " for device \"%s\"\n", name); + return NULL; + } +@@ -606,41 +816,48 @@ + */ + curr_erasesize = subdev[0]->erasesize; + begin = position = 0; +- for(i = 0; i < num_devs; i++) +- { +- if(subdev[i]->numeraseregions == 0) +- { /* current subdevice has uniform erase size */ +- if(subdev[i]->erasesize != curr_erasesize) +- { /* ++ for (i = 0; i < num_devs; i++) { ++ if (subdev[i]->numeraseregions == 0) { ++ /* current subdevice has uniform erase size */ ++ if (subdev[i]->erasesize != curr_erasesize) { ++ /* + * fill in an mtd_erase_region_info structure for the area + * we have walked so far: + */ + erase_region_p->offset = begin; +- erase_region_p->erasesize = curr_erasesize; +- erase_region_p->numblocks = (position - begin) / curr_erasesize; ++ erase_region_p->erasesize = ++ curr_erasesize; ++ erase_region_p->numblocks = ++ (position - begin) / curr_erasesize; + begin = position; + + curr_erasesize = subdev[i]->erasesize; + ++erase_region_p; + } + position += subdev[i]->size; +- } +- else +- { /* current subdevice has variable erase size */ ++ } else { ++ /* current subdevice has variable erase size */ + int j; +- for(j = 0; j < subdev[i]->numeraseregions; j++) +- { /* walk the list of erase regions, count any changes */ +- if(subdev[i]->eraseregions[j].erasesize != curr_erasesize) +- { ++ for (j = 0; j < subdev[i]->numeraseregions; j++) { ++ /* walk the list of erase regions, count any changes */ ++ if (subdev[i]->eraseregions[j]. ++ erasesize != curr_erasesize) { + erase_region_p->offset = begin; +- erase_region_p->erasesize = curr_erasesize; +- erase_region_p->numblocks = (position - begin) / curr_erasesize; ++ erase_region_p->erasesize = ++ curr_erasesize; ++ erase_region_p->numblocks = ++ (position - ++ begin) / curr_erasesize; + begin = position; + +- curr_erasesize = subdev[i]->eraseregions[j].erasesize; ++ curr_erasesize = ++ subdev[i]->eraseregions[j]. ++ erasesize; + ++erase_region_p; + } +- position += subdev[i]->eraseregions[j].numblocks * curr_erasesize; ++ position += ++ subdev[i]->eraseregions[j]. ++ numblocks * curr_erasesize; + } + } + } +@@ -660,16 +877,14 @@ + void mtd_concat_destroy(struct mtd_info *mtd) + { + struct mtd_concat *concat = CONCAT(mtd); +- if(concat->mtd.numeraseregions) ++ if (concat->mtd.numeraseregions) + kfree(concat->mtd.eraseregions); + kfree(concat); + } + +- + EXPORT_SYMBOL(mtd_concat_create); + EXPORT_SYMBOL(mtd_concat_destroy); + +- + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Robert Kaiser "); + MODULE_DESCRIPTION("Generic support for concatenating of MTD devices"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/mtdcore.c linux/drivers/mtd/mtdcore.c +--- linux-mips-2.4.27/drivers/mtd/mtdcore.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/mtdcore.c 2004-11-19 10:25:11.650237640 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: mtdcore.c,v 1.34 2003/01/24 23:32:25 dwmw2 Exp $ ++ * $Id: mtdcore.c,v 1.39 2003/05/21 15:15:03 dwmw2 Exp $ + * + * Core registration and callback routines for MTD + * drivers and users. +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + #ifdef CONFIG_PROC_FS + #include +@@ -24,9 +25,15 @@ + + #include + +-static DECLARE_MUTEX(mtd_table_mutex); +-static struct mtd_info *mtd_table[MAX_MTD_DEVICES]; +-static struct mtd_notifier *mtd_notifiers = NULL; ++/* These are exported solely for the purpose of mtd_blkdevs.c. You ++ should not use them for _anything_ else */ ++DECLARE_MUTEX(mtd_table_mutex); ++struct mtd_info *mtd_table[MAX_MTD_DEVICES]; ++ ++EXPORT_SYMBOL_GPL(mtd_table_mutex); ++EXPORT_SYMBOL_GPL(mtd_table); ++ ++static LIST_HEAD(mtd_notifiers); + + /** + * add_mtd_device - register an MTD device +@@ -44,21 +51,28 @@ + + down(&mtd_table_mutex); + +- for (i=0; i< MAX_MTD_DEVICES; i++) +- if (!mtd_table[i]) +- { +- struct mtd_notifier *not=mtd_notifiers; ++ for (i=0; i < MAX_MTD_DEVICES; i++) ++ if (!mtd_table[i]) { ++ struct list_head *this; + + mtd_table[i] = mtd; + mtd->index = i; ++ mtd->usecount = 0; ++ + DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name); +- while (not) +- { +- (*(not->add))(mtd); +- not = not->next; ++ /* No need to get a refcount on the module containing ++ the notifier, since we hold the mtd_table_mutex */ ++ list_for_each(this, &mtd_notifiers) { ++ struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list); ++ not->add(mtd); + } ++ + up(&mtd_table_mutex); +- MOD_INC_USE_COUNT; ++ /* We _know_ we aren't being removed, because ++ our caller is still holding us here. So none ++ of this try_ nonsense, and no bitching about it ++ either. :) */ ++ __module_get(THIS_MODULE); + return 0; + } + +@@ -78,29 +92,34 @@ + + int del_mtd_device (struct mtd_info *mtd) + { +- struct mtd_notifier *not=mtd_notifiers; +- int i; ++ int ret; + + down(&mtd_table_mutex); + +- for (i=0; i < MAX_MTD_DEVICES; i++) +- { +- if (mtd_table[i] == mtd) +- { +- while (not) +- { +- (*(not->remove))(mtd); +- not = not->next; +- } +- mtd_table[i] = NULL; +- up (&mtd_table_mutex); +- MOD_DEC_USE_COUNT; +- return 0; ++ if (mtd_table[mtd->index] != mtd) { ++ ret = -ENODEV; ++ } else if (mtd->usecount) { ++ printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n", ++ mtd->index, mtd->name, mtd->usecount); ++ ret = -EBUSY; ++ } else { ++ struct list_head *this; ++ ++ /* No need to get a refcount on the module containing ++ the notifier, since we hold the mtd_table_mutex */ ++ list_for_each(this, &mtd_notifiers) { ++ struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list); ++ not->remove(mtd); + } ++ ++ mtd_table[mtd->index] = NULL; ++ ++ module_put(THIS_MODULE); ++ ret = 0; + } + + up(&mtd_table_mutex); +- return 1; ++ return ret; + } + + /** +@@ -118,10 +137,9 @@ + + down(&mtd_table_mutex); + +- new->next = mtd_notifiers; +- mtd_notifiers = new; ++ list_add(&new->list, &mtd_notifiers); + +- MOD_INC_USE_COUNT; ++ __module_get(THIS_MODULE); + + for (i=0; i< MAX_MTD_DEVICES; i++) + if (mtd_table[i]) +@@ -142,34 +160,24 @@ + + int unregister_mtd_user (struct mtd_notifier *old) + { +- struct mtd_notifier **prev = &mtd_notifiers; +- struct mtd_notifier *cur; + int i; + + down(&mtd_table_mutex); + +- while ((cur = *prev)) { +- if (cur == old) { +- *prev = cur->next; +- +- MOD_DEC_USE_COUNT; ++ module_put(THIS_MODULE); + + for (i=0; i< MAX_MTD_DEVICES; i++) + if (mtd_table[i]) + old->remove(mtd_table[i]); + ++ list_del(&old->list); + up(&mtd_table_mutex); + return 0; +- } +- prev = &cur->next; +- } +- up(&mtd_table_mutex); +- return 1; + } + + + /** +- * __get_mtd_device - obtain a validated handle for an MTD device ++ * get_mtd_device - obtain a validated handle for an MTD device + * @mtd: last known address of the required MTD device + * @num: internal device number of the required MTD device + * +@@ -177,11 +185,10 @@ + * table, if any. Given an address and num == -1, search the device table + * for a device with that address and return if it's still present. Given + * both, return the num'th driver only if its address matches. Return NULL +- * if not. get_mtd_device() increases the use count, but +- * __get_mtd_device() doesn't - you should generally use get_mtd_device(). ++ * if not. + */ + +-struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num) ++struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) + { + struct mtd_info *ret = NULL; + int i; +@@ -198,10 +205,27 @@ + ret = NULL; + } + ++ if (ret && !try_module_get(ret->owner)) ++ ret = NULL; ++ ++ if (ret) ++ ret->usecount++; ++ + up(&mtd_table_mutex); + return ret; + } + ++void put_mtd_device(struct mtd_info *mtd) ++{ ++ int c; ++ ++ down(&mtd_table_mutex); ++ c = --mtd->usecount; ++ up(&mtd_table_mutex); ++ BUG_ON(c < 0); ++ ++ module_put(mtd->owner); ++} + + /* default_mtd_writev - default mtd writev method for MTD devices that + * dont implement their own +@@ -265,7 +289,8 @@ + + EXPORT_SYMBOL(add_mtd_device); + EXPORT_SYMBOL(del_mtd_device); +-EXPORT_SYMBOL(__get_mtd_device); ++EXPORT_SYMBOL(get_mtd_device); ++EXPORT_SYMBOL(put_mtd_device); + EXPORT_SYMBOL(register_mtd_user); + EXPORT_SYMBOL(unregister_mtd_user); + EXPORT_SYMBOL(default_mtd_writev); +diff -Nurb linux-mips-2.4.27/drivers/mtd/mtdpart.c linux/drivers/mtd/mtdpart.c +--- linux-mips-2.4.27/drivers/mtd/mtdpart.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/mtdpart.c 2004-11-19 10:25:11.652237336 +0100 +@@ -5,7 +5,7 @@ + * + * This code is GPL + * +- * $Id: mtdpart.c,v 1.32 2002/10/21 13:40:05 jocke Exp $ ++ * $Id: mtdpart.c,v 1.42 2003/07/09 11:19:01 dwmw2 Exp $ + * + * 02-21-2002 Thomas Gleixner + * added support for read_oob, write_oob +@@ -16,10 +16,11 @@ + #include + #include + #include +- ++#include ++#include + #include + #include +- ++#include + + /* Our partition linked list */ + static LIST_HEAD(mtd_partitions); +@@ -54,8 +55,12 @@ + len = 0; + else if (from + len > mtd->size) + len = mtd->size - from; ++ if (part->master->read_ecc == NULL) + return part->master->read (part->master, from + part->offset, + len, retlen, buf); ++ else ++ return part->master->read_ecc (part->master, from + part->offset, ++ len, retlen, buf, NULL, &mtd->oobinfo); + } + + static int part_point (struct mtd_info *mtd, loff_t from, size_t len, +@@ -78,9 +83,11 @@ + + + static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, +- size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel) ++ size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel) + { + struct mtd_part *part = PART(mtd); ++ if (oobsel == NULL) ++ oobsel = &mtd->oobinfo; + if (from >= mtd->size) + len = 0; + else if (from + len > mtd->size) +@@ -113,7 +120,7 @@ + size_t *retlen, u_char *buf) + { + struct mtd_part *part = PART(mtd); +- return part->master->read_user_prot_reg (part->master, from, ++ return part->master->read_fact_prot_reg (part->master, from, + len, retlen, buf); + } + +@@ -127,17 +134,24 @@ + len = 0; + else if (to + len > mtd->size) + len = mtd->size - to; ++ if (part->master->write_ecc == NULL) + return part->master->write (part->master, to + part->offset, + len, retlen, buf); ++ else ++ return part->master->write_ecc (part->master, to + part->offset, ++ len, retlen, buf, NULL, &mtd->oobinfo); ++ + } + + static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf, +- u_char *eccbuf, int oobsel) ++ u_char *eccbuf, struct nand_oobinfo *oobsel) + { + struct mtd_part *part = PART(mtd); + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; ++ if (oobsel == NULL) ++ oobsel = &mtd->oobinfo; + if (to >= mtd->size) + len = 0; + else if (to + len > mtd->size) +@@ -174,25 +188,37 @@ + struct mtd_part *part = PART(mtd); + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; ++ if (part->master->writev_ecc == NULL) + return part->master->writev (part->master, vecs, count, + to + part->offset, retlen); ++ else ++ return part->master->writev_ecc (part->master, vecs, count, ++ to + part->offset, retlen, ++ NULL, &mtd->oobinfo); + } + + static int part_readv (struct mtd_info *mtd, struct iovec *vecs, + unsigned long count, loff_t from, size_t *retlen) + { + struct mtd_part *part = PART(mtd); ++ if (part->master->readv_ecc == NULL) + return part->master->readv (part->master, vecs, count, + from + part->offset, retlen); ++ else ++ return part->master->readv_ecc (part->master, vecs, count, ++ from + part->offset, retlen, ++ NULL, &mtd->oobinfo); + } + + static int part_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs, + unsigned long count, loff_t to, size_t *retlen, +- u_char *eccbuf, int oobsel) ++ u_char *eccbuf, struct nand_oobinfo *oobsel) + { + struct mtd_part *part = PART(mtd); + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; ++ if (oobsel == NULL) ++ oobsel = &mtd->oobinfo; + return part->master->writev_ecc (part->master, vecs, count, + to + part->offset, retlen, + eccbuf, oobsel); +@@ -200,9 +226,11 @@ + + static int part_readv_ecc (struct mtd_info *mtd, struct iovec *vecs, + unsigned long count, loff_t from, size_t *retlen, +- u_char *eccbuf, int oobsel) ++ u_char *eccbuf, struct nand_oobinfo *oobsel) + { + struct mtd_part *part = PART(mtd); ++ if (oobsel == NULL) ++ oobsel = &mtd->oobinfo; + return part->master->readv_ecc (part->master, vecs, count, + from + part->offset, retlen, + eccbuf, oobsel); +@@ -288,7 +316,7 @@ + */ + + int add_mtd_partitions(struct mtd_info *master, +- struct mtd_partition *parts, ++ const struct mtd_partition *parts, + int nbparts) + { + struct mtd_part *slave; +@@ -321,7 +349,7 @@ + + slave->mtd.name = parts[i].name; + slave->mtd.bank_size = master->bank_size; +- slave->mtd.module = master->module; ++ slave->mtd.owner = master->owner; + + slave->mtd.read = part_read; + slave->mtd.write = part_write; +@@ -452,6 +480,75 @@ + EXPORT_SYMBOL(add_mtd_partitions); + EXPORT_SYMBOL(del_mtd_partitions); + ++static spinlock_t part_parser_lock = SPIN_LOCK_UNLOCKED; ++static LIST_HEAD(part_parsers); ++ ++struct mtd_part_parser *get_partition_parser(const char *name) ++{ ++ struct list_head *this; ++ void *ret = NULL; ++ spin_lock(&part_parser_lock); ++ ++ list_for_each(this, &part_parsers) { ++ struct mtd_part_parser *p = list_entry(this, struct mtd_part_parser, list); ++ ++ if (!strcmp(p->name, name) && try_module_get(p->owner)) { ++ ret = p; ++ break; ++ } ++ } ++ spin_unlock(&part_parser_lock); ++ ++ return ret; ++} ++ ++int register_mtd_parser(struct mtd_part_parser *p) ++{ ++ spin_lock(&part_parser_lock); ++ list_add(&p->list, &part_parsers); ++ spin_unlock(&part_parser_lock); ++ ++ return 0; ++} ++ ++int deregister_mtd_parser(struct mtd_part_parser *p) ++{ ++ spin_lock(&part_parser_lock); ++ list_del(&p->list); ++ spin_unlock(&part_parser_lock); ++ return 0; ++} ++ ++int parse_mtd_partitions(struct mtd_info *master, const char **types, ++ struct mtd_partition **pparts, unsigned long origin) ++{ ++ struct mtd_part_parser *parser; ++ int ret = 0; ++ ++ for ( ; ret <= 0 && *types; types++) { ++ parser = get_partition_parser(*types); ++#ifdef CONFIG_KMOD ++ if (!parser && !request_module("%s", *types)) ++ parser = get_partition_parser(*types); ++#endif ++ if (!parser) { ++ printk(KERN_NOTICE "%s partition parsing not available\n", ++ *types); ++ continue; ++ } ++ ret = (*parser->parse_fn)(master, pparts, origin); ++ if (ret > 0) { ++ printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", ++ ret, parser->name, master->name); ++ } ++ put_partition_parser(parser); ++ } ++ return ret; ++} ++ ++EXPORT_SYMBOL_GPL(parse_mtd_partitions); ++EXPORT_SYMBOL_GPL(register_mtd_parser); ++EXPORT_SYMBOL_GPL(deregister_mtd_parser); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Nicolas Pitre "); +diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/Config.in linux/drivers/mtd/nand/Config.in +--- linux-mips-2.4.27/drivers/mtd/nand/Config.in 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/nand/Config.in 2004-11-19 10:25:11.987186416 +0100 +@@ -1,6 +1,6 @@ + # drivers/mtd/nand/Config.in + +-# $Id: Config.in,v 1.11 2002/12/01 13:23:05 gleixner Exp $ ++# $Id: Config.in,v 1.14 2003/11/04 22:59:11 ahennessy Exp $ + + mainmenu_option next_comment + +@@ -11,26 +11,27 @@ + bool ' Verify NAND page writes' CONFIG_MTD_NAND_VERIFY_WRITE + fi + +-if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_P720T" = "y" ]; then +- dep_tristate ' NAND Flash device on SPIA board' CONFIG_MTD_NAND_SPIA $CONFIG_MTD_NAND ++if [ "$CONFIG_ARM" = "y" ]; then ++ dep_tristate ' NAND Flash device on SPIA board' CONFIG_MTD_NAND_SPIA $CONFIG_MTD_NAND $CONFIG_ARCH_P720T ++ dep_tristate ' NAND Flash device on TOTO board' CONFIG_MTD_NAND_TOTO $CONFIG_MTD_NAND $CONFIG_ARCH_OMAP ++ dep_tristate ' SmartMedia Card on AUTCPU12 board' CONFIG_MTD_NAND_AUTCPU12 $CONFIG_MTD_NAND $CONFIG_ARCH_AUTCPU12 ++ dep_tristate ' NAND Flash device on EDP7312 board' CONFIG_MTD_NAND_EDB7312 $CONFIG_MTD_NAND $CONFIG_ARCH_EDB7312 + fi + +-if [ "$CONFIG_ARCH_AUTCPU12" = "y" ]; then +- dep_tristate ' SmartMedia Card on AUTCPU12 board' CONFIG_MTD_NAND_AUTCPU12 $CONFIG_MTD_NAND +-fi +- +-if [ "$CONFIG_ARCH_EDB7312" = "y" ]; then +- dep_tristate ' NAND Flash device on EDP7312 board' CONFIG_MTD_NAND_EDB7312 $CONFIG_MTD_NAND +-fi +- +-if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" -o "$CONFIG_MTD_NAND" = "y" ]; then ++if [ "$CONFIG_MTD_DOC2001PLUS" = "y" -o "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" -o "$CONFIG_MTD_NAND" = "y" ]; then + define_bool CONFIG_MTD_NAND_IDS y ++else ++ if [ "$CONFIG_MTD_DOC2001PLUS" = "m" -o "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" -o "$CONFIG_MTD_NAND" = "m" ]; then ++ define_bool CONFIG_MTD_NAND_IDS m ++ fi + fi + +-if [ "$CONFIG_MTD_NAND_IDS" != "y" ]; then +-if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" -o "$CONFIG_MTD_NAND" = "m" ]; then +- define_bool CONFIG_MTD_NAND_IDS m ++if [ "$CONFIG_TOSHIBA_RBTX4925" = "y" ]; then ++ dep_tristate ' SmartMedia Card on Toshiba RBTX4925 reference board' CONFIG_MTD_NAND_TX4925NDFMC $CONFIG_MTD_NAND $CONFIG_TOSHIBA_RBTX4925_MPLEX_NAND + fi ++ ++if [ "$CONFIG_TOSHIBA_RBTX4938" = "y" ]; then ++ dep_tristate ' NAND Flash device on Toshiba RBTX4938 reference board' CONFIG_MTD_NAND_TX4938NDFMC $CONFIG_MTD_NAND $CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND + fi + + endmenu +diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/Makefile linux/drivers/mtd/nand/Makefile +--- linux-mips-2.4.27/drivers/mtd/nand/Makefile 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/nand/Makefile 2004-11-19 10:25:11.989186112 +0100 +@@ -1,16 +1,20 @@ + # + # linux/drivers/nand/Makefile + # +-# $Id: Makefile,v 1.10 2002/12/01 13:23:05 gleixner Exp $ ++# $Id: Makefile.common,v 1.4 2003/11/04 22:59:11 ahennessy Exp $ + ++ifeq ($(PATCHLEVEL),4) + O_TARGET := nandlink.o +- + export-objs := nand.o nand_ecc.o nand_ids.o ++endif + + obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o + obj-$(CONFIG_MTD_NAND_SPIA) += spia.o ++obj-$(CONFIG_MTD_NAND_TOTO) += toto.o + obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o + obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o ++obj-$(CONFIG_MTD_NAND_TX4925NDFMC) += tx4925ndfmc.o ++obj-$(CONFIG_MTD_NAND_TX4938NDFMC) += tx4938ndfmc.o + obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o + +-include $(TOPDIR)/Rules.make ++-include $(TOPDIR)/Rules.make +diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/autcpu12.c linux/drivers/mtd/nand/autcpu12.c +--- linux-mips-2.4.27/drivers/mtd/nand/autcpu12.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/nand/autcpu12.c 2004-11-19 10:25:11.990185960 +0100 +@@ -4,9 +4,9 @@ + * Copyright (c) 2002 Thomas Gleixner + * + * Derived from drivers/mtd/spia.c +- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) ++ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) + * +- * $Id: autcpu12.c,v 1.6 2002/11/11 15:47:56 gleixner Exp $ ++ * $Id: autcpu12.c,v 1.13 2003/07/11 15:12:29 dwmw2 Exp $ + * + * 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 +@@ -25,10 +25,10 @@ + * added page_cache + * + * 10-06-2002 TG 128K card support added +- * + */ + + #include ++#include + #include + #include + #include +@@ -70,6 +70,7 @@ + /* + * Define partitions for flash devices + */ ++extern struct nand_oobinfo jffs2_oobinfo; + + static struct mtd_partition partition_info16k[] = { + { name: "AUTCPU12 flash partition 1", +@@ -95,7 +96,7 @@ + size: 16 * SZ_1M }, + { name: "AUTCPU12 flash partition 2", + offset: 16 * SZ_1M, +- size: 48 * SZ_1M}, ++ size: 48 * SZ_1M }, + }; + + static struct mtd_partition partition_info128k[] = { +@@ -104,7 +105,7 @@ + size: 16 * SZ_1M }, + { name: "AUTCPU12 flash partition 2", + offset: 16 * SZ_1M, +- size: 112 * SZ_1M}, ++ size: 112 * SZ_1M }, + }; + + #define NUM_PARTITIONS16K 2 +@@ -114,7 +115,7 @@ + /* + * hardware specific access to control-lines + */ +-void autcpu12_hwcontrol(int cmd) ++static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd) + { + + switch(cmd){ +@@ -133,7 +134,7 @@ + /* + * read device ready pin + */ +-int autcpu12_device_ready(void) ++int autcpu12_device_ready(struct mtd_info *mtd) + { + + return ( (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) & AUTCPU12_SMC_RDY) ? 1 : 0; +@@ -184,7 +185,7 @@ + this->eccmode = NAND_ECC_SOFT; + + /* Scan to find existance of the device */ +- if (nand_scan (autcpu12_mtd)) { ++ if (nand_scan (autcpu12_mtd, 1)) { + err = -ENXIO; + goto out_ior; + } +@@ -197,15 +198,6 @@ + goto out_ior; + } + +- /* Allocate memory for internal data buffer */ +- this->data_cache = kmalloc (sizeof(u_char) * (autcpu12_mtd->oobblock + autcpu12_mtd->oobsize), GFP_KERNEL); +- if (!this->data_cache) { +- printk ("Unable to allocate NAND data cache for AUTCPU12.\n"); +- err = -ENOMEM; +- goto out_buf; +- } +- this->cache_page = -1; +- + /* Register the partitions */ + switch(autcpu12_mtd->size){ + case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break; +@@ -215,13 +207,11 @@ + default: { + printk ("Unsupported SmartMedia device\n"); + err = -ENXIO; +- goto out_cac; ++ goto out_buf; + } + } + goto out; + +-out_cac: +- kfree (this->data_cache); + out_buf: + kfree (this->data_buf); + out_ior: +@@ -250,7 +240,6 @@ + + /* Free internal data buffers */ + kfree (this->data_buf); +- kfree (this->data_cache); + + /* unmap physical adress */ + iounmap((void *)autcpu12_fio_base); +diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/diskonchip.c linux/drivers/mtd/nand/diskonchip.c +--- linux-mips-2.4.27/drivers/mtd/nand/diskonchip.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/nand/diskonchip.c 2004-11-19 10:25:11.992185656 +0100 +@@ -0,0 +1,534 @@ ++/* ++ * drivers/mtd/nand/diskonchip.c ++ * ++ * (C) 2003 Red Hat, Inc. ++ * ++ * Author: David Woodhouse ++ * ++ * Interface to generic NAND code for M-Systems DiskOnChip devices ++ * ++ * $Id: diskonchip.c,v 1.8 2003/11/05 16:52:34 dwmw2 Exp $ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++struct doc_priv { ++ unsigned long virtadr; ++ unsigned long physadr; ++ u_char ChipID; ++ u_char CDSNControl; ++ int chips_per_floor; /* The number of chips detected on each floor */ ++ int curfloor; ++ int curchip; ++}; ++ ++#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil) ++#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k) ++ ++static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd); ++static void doc200x_select_chip(struct mtd_info *mtd, int chip); ++ ++static int debug=0; ++MODULE_PARM(debug, "i"); ++ ++static int try_dword=1; ++MODULE_PARM(try_dword, "i"); ++ ++static void DoC_Delay(struct doc_priv *doc, unsigned short cycles) ++{ ++ volatile char dummy; ++ int i; ++ ++ for (i = 0; i < cycles; i++) { ++ if (DoC_is_Millennium(doc)) ++ dummy = ReadDOC(doc->virtadr, NOP); ++ else ++ dummy = ReadDOC(doc->virtadr, DOCStatus); ++ } ++ ++} ++/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ ++static int _DoC_WaitReady(struct doc_priv *doc) ++{ ++ unsigned long docptr = doc->virtadr; ++ unsigned long timeo = jiffies + (HZ * 10); ++ ++ if(debug) printk("_DoC_WaitReady...\n"); ++ /* Out-of-line routine to wait for chip response */ ++ while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) { ++ if (time_after(jiffies, timeo)) { ++ printk("_DoC_WaitReady timed out.\n"); ++ return -EIO; ++ } ++ udelay(1); ++ cond_resched(); ++ } ++ ++ return 0; ++} ++ ++static inline int DoC_WaitReady(struct doc_priv *doc) ++{ ++ unsigned long docptr = doc->virtadr; ++ int ret = 0; ++ ++ DoC_Delay(doc, 4); ++ ++ if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) ++ /* Call the out-of-line routine to wait */ ++ ret = _DoC_WaitReady(doc); ++ ++ DoC_Delay(doc, 2); ++ if(debug) printk("DoC_WaitReady OK\n"); ++ return ret; ++} ++ ++static void doc2000_write_byte(struct mtd_info *mtd, u_char datum) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ ++ if(debug)printk("write_byte %02x\n", datum); ++ WriteDOC(datum, docptr, CDSNSlowIO); ++ WriteDOC(datum, docptr, 2k_CDSN_IO); ++} ++ ++static u_char doc2000_read_byte(struct mtd_info *mtd) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ ++ ReadDOC(docptr, CDSNSlowIO); ++ u_char ret = ReadDOC(docptr, 2k_CDSN_IO); ++ if (debug) printk("read_byte returns %02x\n", ret); ++ return ret; ++} ++static void doc2000_writebuf(struct mtd_info *mtd, ++ const u_char *buf, int len) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ int i; ++ if (debug)printk("writebuf of %d bytes: ", len); ++ for (i=0; i < len; i++) { ++ WriteDOC_(buf[i], docptr, DoC_2k_CDSN_IO + i); ++ if (debug && i < 16) ++ printk("%02x ", buf[i]); ++ } ++ if (debug) printk("\n"); ++} ++ ++static void doc2000_readbuf(struct mtd_info *mtd, ++ u_char *buf, int len) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ int i; ++ ++ if (debug)printk("readbuf of %d bytes: ", len); ++ ++ for (i=0; i < len; i++) { ++ buf[i] = ReadDOC(docptr, 2k_CDSN_IO + i); ++ } ++} ++ ++static void doc2000_readbuf_dword(struct mtd_info *mtd, ++ u_char *buf, int len) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ int i; ++ ++ if (debug) printk("readbuf_dword of %d bytes: ", len); ++ ++ if (unlikely((((unsigned long)buf)|len) & 3)) { ++ for (i=0; i < len; i++) { ++ *(uint8_t *)(&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i); ++ } ++ } else { ++ for (i=0; i < len; i+=4) { ++ *(uint32_t*)(&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i); ++ } ++ } ++} ++ ++static int doc2000_verifybuf(struct mtd_info *mtd, ++ const u_char *buf, int len) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ int i; ++ ++ for (i=0; i < len; i++) ++ if (buf[i] != ReadDOC(docptr, 2k_CDSN_IO)) ++ return i; ++ return 0; ++} ++ ++static uint16_t doc200x_ident_chip(struct mtd_info *mtd, int nr) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ uint16_t ret; ++ ++ doc200x_select_chip(mtd, nr); ++ doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); ++ this->write_byte(mtd, NAND_CMD_READID); ++ doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); ++ doc200x_hwcontrol(mtd, NAND_CTL_SETALE); ++ this->write_byte(mtd, 0); ++ doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); ++ ++ ret = this->read_byte(mtd) << 8; ++ ret |= this->read_byte(mtd); ++ ++ if (doc->ChipID == DOC_ChipID_Doc2k && try_dword && !nr) { ++ /* First chip probe. See if we get same results by 32-bit access */ ++ union { ++ uint32_t dword; ++ uint8_t byte[4]; ++ } ident; ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ ++ doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); ++ doc2000_write_byte(mtd, NAND_CMD_READID); ++ doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); ++ doc200x_hwcontrol(mtd, NAND_CTL_SETALE); ++ doc2000_write_byte(mtd, 0); ++ doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); ++ ++ ident.dword = readl(docptr + DoC_2k_CDSN_IO); ++ if (((ident.byte[0] << 8) | ident.byte[1]) == ret) { ++ printk(KERN_INFO "DiskOnChip 2000 responds to DWORD access\n"); ++ this->read_buf = &doc2000_readbuf_dword; ++ } ++ } ++ ++ return ret; ++} ++ ++static void doc2000_count_chips(struct mtd_info *mtd) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ uint16_t mfrid; ++ int i; ++ ++ /* Max 4 chips per floor on DiskOnChip 2000 */ ++ doc->chips_per_floor = 4; ++ ++ /* Find out what the first chip is */ ++ mfrid = doc200x_ident_chip(mtd, 0); ++ ++ /* Find how many chips in each floor. */ ++ for (i = 1; i < 4; i++) { ++ if (doc200x_ident_chip(mtd, i) != mfrid) ++ break; ++ } ++ doc->chips_per_floor = i; ++} ++ ++static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state) ++{ ++ struct doc_priv *doc = (void *)this->priv; ++ ++ int status; ++ ++ DoC_WaitReady(doc); ++ this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); ++ DoC_WaitReady(doc); ++ status = (int)this->read_byte(mtd); ++ ++ return status; ++} ++ ++static void doc2001_write_byte(struct mtd_info *mtd, u_char datum) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ ++ WriteDOC(datum, docptr, CDSNSlowIO); ++ WriteDOC(datum, docptr, Mil_CDSN_IO); ++ WriteDOC(datum, docptr, WritePipeTerm); ++} ++ ++static u_char doc2001_read_byte(struct mtd_info *mtd) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ ++ ReadDOC(docptr, CDSNSlowIO); ++ /* 11.4.5 -- delay twice to allow extended length cycle */ ++ DoC_Delay(doc, 2); ++ ReadDOC(docptr, ReadPipeInit); ++ return ReadDOC(docptr, Mil_CDSN_IO); ++} ++ ++static void doc2001_writebuf(struct mtd_info *mtd, ++ const u_char *buf, int len) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ int i; ++ ++ for (i=0; i < len; i++) ++ WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i); ++ /* Terminate write pipeline */ ++ WriteDOC(0x00, docptr, WritePipeTerm); ++} ++ ++static void doc2001_readbuf(struct mtd_info *mtd, ++ u_char *buf, int len) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ int i; ++ ++ /* Start read pipeline */ ++ ReadDOC(docptr, ReadPipeInit); ++ ++ for (i=0; i < len-1; i++) ++ buf[i] = ReadDOC(docptr, Mil_CDSN_IO); ++ ++ /* Terminate read pipeline */ ++ buf[i] = ReadDOC(docptr, LastDataRead); ++} ++static int doc2001_verifybuf(struct mtd_info *mtd, ++ const u_char *buf, int len) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ int i; ++ ++ /* Start read pipeline */ ++ ReadDOC(docptr, ReadPipeInit); ++ ++ for (i=0; i < len-1; i++) ++ if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) { ++ ReadDOC(docptr, LastDataRead); ++ return i; ++ } ++ if (buf[i] != ReadDOC(docptr, LastDataRead)) ++ return i; ++ return 0; ++} ++ ++static void doc200x_select_chip(struct mtd_info *mtd, int chip) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ int floor = 0; ++ ++ /* 11.4.4 -- deassert CE before changing chip */ ++ doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE); ++ ++ if(debug)printk("select chip (%d)\n", chip); ++ ++ if (chip == -1) ++ return; ++ ++ floor = chip / doc->chips_per_floor; ++ chip -= (floor * doc->chips_per_floor); ++ ++ WriteDOC(floor, docptr, FloorSelect); ++ WriteDOC(chip, docptr, CDSNDeviceSelect); ++ ++ doc200x_hwcontrol(mtd, NAND_CTL_SETNCE); ++ ++ doc->curchip = chip; ++ doc->curfloor = floor; ++} ++ ++static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ ++ switch(cmd) { ++ case NAND_CTL_SETNCE: ++ doc->CDSNControl |= CDSN_CTRL_CE; ++ break; ++ case NAND_CTL_CLRNCE: ++ doc->CDSNControl &= ~CDSN_CTRL_CE; ++ break; ++ case NAND_CTL_SETCLE: ++ doc->CDSNControl |= CDSN_CTRL_CLE; ++ break; ++ case NAND_CTL_CLRCLE: ++ doc->CDSNControl &= ~CDSN_CTRL_CLE; ++ break; ++ case NAND_CTL_SETALE: ++ doc->CDSNControl |= CDSN_CTRL_ALE; ++ break; ++ case NAND_CTL_CLRALE: ++ doc->CDSNControl &= ~CDSN_CTRL_ALE; ++ break; ++ case NAND_CTL_SETWP: ++ doc->CDSNControl |= CDSN_CTRL_WP; ++ break; ++ case NAND_CTL_CLRWP: ++ doc->CDSNControl &= ~CDSN_CTRL_WP; ++ break; ++ } ++ if (debug)printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl); ++ WriteDOC(doc->CDSNControl, docptr, CDSNControl); ++ /* 11.4.3 -- 4 NOPs after CSDNControl write */ ++ DoC_Delay(doc, 4); ++} ++ ++static int doc200x_dev_ready(struct mtd_info *mtd) ++{ ++ struct nand_chip *this = mtd->priv; ++ struct doc_priv *doc = (void *)this->priv; ++ unsigned long docptr = doc->virtadr; ++ ++ /* 11.4.2 -- must NOP four times before checking FR/B# */ ++ DoC_Delay(doc, 4); ++ if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) { ++ if(debug) ++ printk("not ready\n"); ++ return 0; ++ } ++ /* 11.4.2 -- Must NOP twice if it's ready */ ++ DoC_Delay(doc, 2); ++ if (debug)printk("was ready\n"); ++ return 1; ++} ++ ++static int doc200x_block_bad(struct mtd_info *mtd, unsigned long block) ++{ ++ /* FIXME: Look it up in the BBT */ ++ return 0; ++} ++ ++struct doc_priv mydoc = { ++ .physadr = 0xd4000, ++ .curfloor = -1, ++ .curchip = -1, ++}; ++ ++u_char mydatabuf[528]; ++ ++struct nand_chip mynand = { ++ .priv = (void *)&mydoc, ++ .select_chip = doc200x_select_chip, ++ .hwcontrol = doc200x_hwcontrol, ++ .dev_ready = doc200x_dev_ready, ++ .waitfunc = doc200x_wait, ++ .block_bad = doc200x_block_bad, ++ .eccmode = NAND_ECC_SOFT, ++ .data_buf = mydatabuf, ++}; ++ ++struct mtd_info mymtd = { ++ .priv = (void *)&mynand, ++ .owner = THIS_MODULE, ++}; ++ ++int __init init_nanddoc(void) ++{ ++ mydoc.virtadr = (unsigned long)ioremap(mydoc.physadr, DOC_IOREMAP_LEN); ++ int nrchips = 1; ++ char *name; ++ ++ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, ++ mydoc.virtadr, DOCControl); ++ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, ++ mydoc.virtadr, DOCControl); ++ ++ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, ++ mydoc.virtadr, DOCControl); ++ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, ++ mydoc.virtadr, DOCControl); ++ ++ mydoc.ChipID = ReadDOC(mydoc.virtadr, ChipID); ++ ++ switch(mydoc.ChipID) { ++ case DOC_ChipID_DocMil: ++ mynand.write_byte = doc2001_write_byte; ++ mynand.read_byte = doc2001_read_byte; ++ mynand.write_buf = doc2001_writebuf; ++ mynand.read_buf = doc2001_readbuf; ++ mynand.verify_buf = doc2001_verifybuf; ++ ++ ReadDOC(mydoc.virtadr, ChipID); ++ ReadDOC(mydoc.virtadr, ChipID); ++ if (ReadDOC(mydoc.virtadr, ChipID) != DOC_ChipID_DocMil) { ++ /* It's not a Millennium; it's one of the newer ++ DiskOnChip 2000 units with a similar ASIC. ++ Treat it like a Millennium, except that it ++ can have multiple chips. */ ++ doc2000_count_chips(&mymtd); ++ nrchips = 4 * mydoc.chips_per_floor; ++ name = "DiskOnChip 2000 (INFTL Model)"; ++ } else { ++ /* Bog-standard Millennium */ ++ mydoc.chips_per_floor = 1; ++ nrchips = 1; ++ name = "DiskOnChip Millennium"; ++ } ++ break; ++ ++ case DOC_ChipID_Doc2k: ++ mynand.write_byte = doc2000_write_byte; ++ mynand.read_byte = doc2000_read_byte; ++ mynand.write_buf = doc2000_writebuf; ++ mynand.read_buf = doc2000_readbuf; ++ mynand.verify_buf = doc2000_verifybuf; ++ ++ doc2000_count_chips(&mymtd); ++ nrchips = 4 * mydoc.chips_per_floor; ++ name = "DiskOnChip 2000 (NFTL Model)"; ++ mydoc.CDSNControl |= CDSN_CTRL_FLASH_IO; ++ ++ break; ++ ++ default: ++ return -EIO; ++ } ++ if (nand_scan(&mymtd, nrchips)) { ++ iounmap((void *)mydoc.virtadr); ++ return -EIO; ++ } ++ mymtd.name = name; ++ add_mtd_device(&mymtd); ++ ++ return 0; ++} ++ ++void __exit cleanup_nanddoc(void) ++{ ++ del_mtd_device(&mymtd); ++ iounmap((void *)mydoc.virtadr); ++} ++ ++module_init(init_nanddoc); ++module_exit(cleanup_nanddoc); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("David Woodhouse "); ++MODULE_DESCRIPTION("M-Systems DiskOnChip 2000 and Millennium device driver\n"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/edb7312.c linux/drivers/mtd/nand/edb7312.c +--- linux-mips-2.4.27/drivers/mtd/nand/edb7312.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/nand/edb7312.c 2004-11-19 10:25:11.997184896 +0100 +@@ -6,7 +6,7 @@ + * Derived from drivers/mtd/nand/autcpu12.c + * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) + * +- * $Id: edb7312.c,v 1.3 2002/06/06 12:58:16 mag Exp $ ++ * $Id: edb7312.c,v 1.7 2003/07/11 15:12:29 dwmw2 Exp $ + * + * 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 +@@ -20,6 +20,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -77,16 +78,13 @@ + }; + #define NUM_PARTITIONS 1 + +-extern int parse_cmdline_partitions(struct mtd_info *master, +- struct mtd_partition **pparts, +- const char *mtd_id); + #endif + + + /* + * hardware specific access to control-lines + */ +-static void ep7312_hwcontrol(int cmd) ++static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd) + { + switch(cmd) { + +@@ -116,10 +114,13 @@ + /* + * read device ready pin + */ +-static int ep7312_device_ready(void) ++static int ep7312_device_ready(struct mtd_info *mtd) + { + return 1; + } ++#ifdef CONFIG_MTD_PARTITIONS ++const char *part_probes[] = { "cmdlinepart", NULL }; ++#endif + + /* + * Main initialization routine +@@ -174,7 +175,7 @@ + this->chip_delay = 15; + + /* Scan to find existence of the device */ +- if (nand_scan (ep7312_mtd)) { ++ if (nand_scan (ep7312_mtd, 1)) { + iounmap((void *)ep7312_fio_base); + kfree (ep7312_mtd); + return -ENXIO; +@@ -189,27 +190,16 @@ + return -ENOMEM; + } + +- /* Allocate memory for internal data buffer */ +- this->data_cache = kmalloc (sizeof(u_char) * (ep7312_mtd->oobblock + ep7312_mtd->oobsize), GFP_KERNEL); +- if (!this->data_cache) { +- printk("Unable to allocate NAND data cache for EDB7312.\n"); +- kfree (this->data_buf); +- iounmap((void *)ep7312_fio_base); +- kfree (ep7312_mtd); +- return -ENOMEM; +- } +- this->cache_page = -1; +- +-#ifdef CONFIG_MTD_CMDLINE_PARTS +- mtd_parts_nb = parse_cmdline_partitions(ep7312_mtd, &mtd_parts, +- "edb7312-nand"); ++#ifdef CONFIG_PARTITIONS ++ ep7312_mtd->name = "edb7312-nand"; ++ mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, ++ &mtd_parts, 0); + if (mtd_parts_nb > 0) + part_type = "command line"; + else + mtd_parts_nb = 0; + #endif +- if (mtd_parts_nb == 0) +- { ++ if (mtd_parts_nb == 0) { + mtd_parts = partition_info; + mtd_parts_nb = NUM_PARTITIONS; + part_type = "static"; +@@ -236,7 +226,6 @@ + + /* Free internal data buffer */ + kfree (this->data_buf); +- kfree (this->data_cache); + + /* Free the MTD device structure */ + kfree (ep7312_mtd); +diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/nand.c linux/drivers/mtd/nand/nand.c +--- linux-mips-2.4.27/drivers/mtd/nand/nand.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/nand/nand.c 2004-11-19 10:25:12.010182920 +0100 +@@ -8,7 +8,7 @@ + * Additional technical information is available on + * http://www.linux-mtd.infradead.org/tech/nand.html + * +- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) ++ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) + * 2002 Thomas Gleixner (tglx@linutronix.de) + * + * 10-29-2001 Thomas Gleixner (tglx@linutronix.de) +@@ -112,10 +112,27 @@ + * for mtd->read_ecc / mtd->write_ecc + * some minor cleanups + * +- * 12-05-2000 tglx: Dave Ellis (DGE@sixnetio) provided the fix for ++ * 12-05-2002 tglx: Dave Ellis (DGE@sixnetio) provided the fix for + * WRITE_VERIFY long time ago. Thanks for remembering me. + * +- * $Id: nand.c,v 1.36 2002/12/05 20:59:11 gleixner Exp $ ++ * 02-14-2003 tglx: Reject non page aligned writes ++ * Fixed ecc select in nand_write_page to match semantics. ++ * ++ * 02-18-2003 tglx: Changed oobsel to pointer. Added a default oob-selector ++ * ++ * 02-18-2003 tglx: Implemented oobsel again. Now it uses a pointer to ++ + a structure, which will be supplied by a filesystem driver ++ * If NULL is given, then the defaults (none or defaults ++ * supplied by ioctl (MEMSETOOBSEL) are used. ++ * For partitions the partition defaults are used (mtdpart.c) ++ * ++ * 06-04-2003 tglx: fix compile errors and fix write verify problem for ++ * some chips, which need either a delay between the readback ++ * and the next write command or have the CE removed. The ++ * CE disable/enable is much faster than a 20us delay and ++ * it should work on all available chips. ++ * ++ * $Id: nand.c,v 1.60 2003/10/23 08:28:43 dwmw2 Exp $ + * + * 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 +@@ -130,102 +147,151 @@ + #include + #include + #include ++#include + #include + #include + + /* +- * Macros for low-level register control +- */ +-#define nand_select() this->hwcontrol(NAND_CTL_SETNCE); +- +-#define nand_deselect() this->hwcontrol(NAND_CTL_CLRNCE); +- +-/* +- * out of band configuration for different filesystems +- */ +-static int oobconfigs[][6] = { +- { 0,0,0,0,0,0}, +- +- { NAND_JFFS2_OOB_ECCPOS0, NAND_JFFS2_OOB_ECCPOS1, NAND_JFFS2_OOB_ECCPOS2, +- NAND_JFFS2_OOB_ECCPOS3, NAND_JFFS2_OOB_ECCPOS4, NAND_JFFS2_OOB_ECCPOS5 }, +- +- { NAND_YAFFS_OOB_ECCPOS0, NAND_YAFFS_OOB_ECCPOS1, NAND_YAFFS_OOB_ECCPOS2, +- NAND_YAFFS_OOB_ECCPOS3, NAND_YAFFS_OOB_ECCPOS4, NAND_YAFFS_OOB_ECCPOS5 } +-}; +- +-/* + * NAND low-level MTD interface functions + */ ++static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len); ++static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len); ++static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len); ++ + static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf); + static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, +- size_t * retlen, u_char * buf, u_char * eccbuf, int oobsel); ++ size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel); + static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf); + static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf); + static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, +- size_t * retlen, const u_char * buf, u_char * eccbuf, int oobsel); ++ size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel); + static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf); + static int nand_writev (struct mtd_info *mtd, const struct iovec *vecs, + unsigned long count, loff_t to, size_t * retlen); + static int nand_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs, +- unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, int oobsel); ++ unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); + static int nand_erase (struct mtd_info *mtd, struct erase_info *instr); + static void nand_sync (struct mtd_info *mtd); +-static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, int col, +- int last, u_char *oob_buf, int oobsel); ++static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, struct nand_oobinfo *oobsel); ++ ++static u_char nand_read_byte(struct mtd_info *mtd) ++{ ++ struct nand_chip *this = mtd->priv; ++ return readb(this->IO_ADDR_R); ++} ++ ++static void nand_write_byte(struct mtd_info *mtd, u_char byte) ++{ ++ struct nand_chip *this = mtd->priv; ++ writeb(byte, this->IO_ADDR_W); ++} ++ ++static void nand_select_chip(struct mtd_info *mtd, int chip) ++{ ++ struct nand_chip *this = mtd->priv; ++ switch(chip) { ++ case -1: ++ this->hwcontrol(mtd, NAND_CTL_CLRNCE); ++ break; ++ case 0: ++ this->hwcontrol(mtd, NAND_CTL_SETNCE); ++ break; ++ ++ default: ++ BUG(); ++ } ++} ++ ++static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++ for (i=0; iIO_ADDR_W); ++} ++ ++static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++ for (i=0; iIO_ADDR_R); ++} ++ ++static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++ for (i=0; iIO_ADDR_R)) ++ return i; ++ ++ return 0; ++} ++ ++/* Appropriate chip should already be selected */ ++static int nand_block_bad(struct mtd_info *mtd, unsigned long page) ++{ ++ struct nand_chip *this = mtd->priv; ++ ++ this->cmdfunc (mtd, NAND_CMD_READOOB, NAND_BADBLOCK_POS, page); ++ if (this->read_byte(mtd) != 0xff) ++ return 1; ++ ++ return 0; ++} ++ + /* + * Send command to NAND device + */ + static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr) + { + register struct nand_chip *this = mtd->priv; +- register unsigned long NAND_IO_ADDR = this->IO_ADDR_W; + + /* Begin command latch cycle */ +- this->hwcontrol (NAND_CTL_SETCLE); ++ this->hwcontrol(mtd, NAND_CTL_SETCLE); + /* + * Write out the command to the device. + */ +- if (command != NAND_CMD_SEQIN) +- writeb (command, NAND_IO_ADDR); +- else { +- if (mtd->oobblock == 256 && column >= 256) { +- column -= 256; +- writeb (NAND_CMD_READOOB, NAND_IO_ADDR); +- writeb (NAND_CMD_SEQIN, NAND_IO_ADDR); +- } else if (mtd->oobblock == 512 && column >= 256) { +- if (column < 512) { +- column -= 256; +- writeb (NAND_CMD_READ1, NAND_IO_ADDR); +- writeb (NAND_CMD_SEQIN, NAND_IO_ADDR); +- } else { +- column -= 512; +- writeb (NAND_CMD_READOOB, NAND_IO_ADDR); +- writeb (NAND_CMD_SEQIN, NAND_IO_ADDR); +- } ++ if (command == NAND_CMD_SEQIN) { ++ int readcmd; ++ ++ if (column >= mtd->oobblock) { ++ /* OOB area */ ++ column -= mtd->oobblock; ++ readcmd = NAND_CMD_READOOB; ++ } else if (column < 256) { ++ /* First 256 bytes --> READ0 */ ++ readcmd = NAND_CMD_READ0; + } else { +- writeb (NAND_CMD_READ0, NAND_IO_ADDR); +- writeb (NAND_CMD_SEQIN, NAND_IO_ADDR); ++ column -= 256; ++ readcmd = NAND_CMD_READ1; + } ++ this->write_byte(mtd, readcmd); + } ++ this->write_byte(mtd, command); + + /* Set ALE and clear CLE to start address cycle */ +- this->hwcontrol (NAND_CTL_CLRCLE); ++ this->hwcontrol(mtd, NAND_CTL_CLRCLE); + + if (column != -1 || page_addr != -1) { +- this->hwcontrol (NAND_CTL_SETALE); ++ this->hwcontrol(mtd, NAND_CTL_SETALE); + + /* Serially input address */ + if (column != -1) +- writeb (column, NAND_IO_ADDR); ++ this->write_byte(mtd, column); + if (page_addr != -1) { +- writeb ((unsigned char) (page_addr & 0xff), NAND_IO_ADDR); +- writeb ((unsigned char) ((page_addr >> 8) & 0xff), NAND_IO_ADDR); ++ this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); ++ this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); + /* One more address cycle for higher density devices */ + if (mtd->size & 0x0c000000) +- writeb ((unsigned char) ((page_addr >> 16) & 0x0f), NAND_IO_ADDR); ++ this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f)); + } + /* Latch in address */ +- this->hwcontrol (NAND_CTL_CLRALE); ++ this->hwcontrol(mtd, NAND_CTL_CLRALE); + } + + /* +@@ -244,10 +310,11 @@ + case NAND_CMD_RESET: + if (this->dev_ready) + break; +- this->hwcontrol (NAND_CTL_SETCLE); +- writeb (NAND_CMD_STATUS, NAND_IO_ADDR); +- this->hwcontrol (NAND_CTL_CLRCLE); +- while ( !(readb (this->IO_ADDR_R) & 0x40)); ++ udelay(this->chip_delay); ++ this->hwcontrol(mtd, NAND_CTL_SETCLE); ++ this->write_byte(mtd, NAND_CMD_STATUS); ++ this->hwcontrol(mtd, NAND_CTL_CLRCLE); ++ while ( !(this->read_byte(mtd) & 0x40)); + return; + + /* This applies to read commands */ +@@ -263,7 +330,7 @@ + } + + /* wait until command is processed */ +- while (!this->dev_ready()); ++ while (!this->dev_ready(mtd)); + } + + /* +@@ -288,17 +355,17 @@ + spin_unlock_bh (&this->chip_lock); + return; + } +- ++#if 0 /* This was broken. And of dubious utility */ + if (this->state == FL_ERASING) { + if (new_state != FL_ERASING) { + this->state = new_state; + spin_unlock_bh (&this->chip_lock); +- nand_select (); /* select in any case */ ++ this->select_chip(mtd, 0); /* select in any case */ + this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + return; + } + } +- ++#endif + set_current_state (TASK_UNINTERRUPTIBLE); + add_wait_queue (&this->wq, &wait); + spin_unlock_bh (&this->chip_lock); +@@ -334,17 +401,17 @@ + return 0; + } + if (this->dev_ready) { +- if (this->dev_ready ()) ++ if (this->dev_ready(mtd)) + break; + } +- if (readb (this->IO_ADDR_R) & 0x40) ++ if (this->read_byte(mtd) & 0x40) + break; + + spin_unlock_bh (&this->chip_lock); + yield (); + spin_lock_bh (&this->chip_lock); + } +- status = (int) readb (this->IO_ADDR_R); ++ status = (int) this->read_byte(mtd); + spin_unlock_bh (&this->chip_lock); + + return status; +@@ -352,14 +419,15 @@ + + /* + * Nand_page_program function is used for write and writev ! ++ * This function will always program a full page of data ++ * If you call it with a non page aligned buffer, you're lost :) + */ +-static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, +- int page, int col, int last, u_char *oob_buf, int oobsel) ++static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, struct nand_oobinfo *oobsel) + { + int i, status; + u_char ecc_code[6], *oob_data; +- int eccmode = oobsel ? this->eccmode : NAND_ECC_NONE; +- int *oob_config = oobconfigs[oobsel]; ++ int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; ++ int *oob_config = oobsel->eccpos; + + /* pad oob area, if we have no oob buffer from fs-driver */ + if (!oob_buf) { +@@ -369,66 +437,42 @@ + } else + oob_data = oob_buf; + +- /* software ecc 3 Bytes ECC / 256 Byte Data ? */ +- if (eccmode == NAND_ECC_SOFT) { +- /* Read back previous written data, if col > 0 */ +- if (col) { +- this->cmdfunc (mtd, NAND_CMD_READ0, 0, page); +- for (i = 0; i < col; i++) +- this->data_poi[i] = readb (this->IO_ADDR_R); +- } +- if ((col < this->eccsize) && (last >= this->eccsize)) { +- this->calculate_ecc (&this->data_poi[0], &(ecc_code[0])); +- for (i = 0; i < 3; i++) +- oob_data[oob_config[i]] = ecc_code[i]; +- } +- /* Calculate and write the second ECC if we have enough data */ +- if ((mtd->oobblock == 512) && (last == 512)) { +- this->calculate_ecc (&this->data_poi[256], &(ecc_code[3])); +- for (i = 3; i < 6; i++) +- oob_data[oob_config[i]] = ecc_code[i]; +- } +- } else { +- /* For hardware ECC skip ECC, if we have no full page write */ +- if (eccmode != NAND_ECC_NONE && (col || last != mtd->oobblock)) +- eccmode = NAND_ECC_NONE; +- } +- +- /* Prepad for partial page programming !!! */ +- for (i = 0; i < col; i++) +- this->data_poi[i] = 0xff; +- +- /* Postpad for partial page programming !!! oob is already padded */ +- for (i = last; i < mtd->oobblock; i++) +- this->data_poi[i] = 0xff; +- + /* Send command to begin auto page programming */ + this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page); + + /* Write out complete page of data, take care of eccmode */ +- switch (this->eccmode) { ++ switch (eccmode) { + /* No ecc and software ecc 3/256, write all */ + case NAND_ECC_NONE: ++ printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n"); ++ this->write_buf(mtd, this->data_poi, mtd->oobblock); ++ break; + case NAND_ECC_SOFT: +- for (i = 0; i < mtd->oobblock; i++) +- writeb ( this->data_poi[i] , this->IO_ADDR_W); ++ this->calculate_ecc(mtd, &this->data_poi[0], &(ecc_code[0])); ++ for (i = 0; i < 3; i++) ++ oob_data[oob_config[i]] = ecc_code[i]; ++ /* Calculate and write the second ECC for 512 Byte page size */ ++ if (mtd->oobblock == 512) { ++ this->calculate_ecc(mtd, &this->data_poi[256], &(ecc_code[3])); ++ for (i = 3; i < 6; i++) ++ oob_data[oob_config[i]] = ecc_code[i]; ++ } ++ this->write_buf(mtd, this->data_poi, mtd->oobblock); + break; + + /* Hardware ecc 3 byte / 256 data, write first half, get ecc, then second, if 512 byte pagesize */ + case NAND_ECC_HW3_256: +- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic for write */ +- for (i = 0; i < mtd->eccsize; i++) +- writeb ( this->data_poi[i] , this->IO_ADDR_W); ++ this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic for write */ ++ this->write_buf(mtd, this->data_poi, mtd->eccsize); + +- this->calculate_ecc (NULL, &(ecc_code[0])); ++ this->calculate_ecc(mtd, NULL, &(ecc_code[0])); + for (i = 0; i < 3; i++) + oob_data[oob_config[i]] = ecc_code[i]; + + if (mtd->oobblock == 512) { +- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic for write*/ +- for (i = mtd->eccsize; i < mtd->oobblock; i++) +- writeb ( this->data_poi[i] , this->IO_ADDR_W); +- this->calculate_ecc (NULL, &(ecc_code[3])); ++ this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic for write*/ ++ this->write_buf(mtd, &this->data_poi[mtd->eccsize], mtd->oobblock - mtd->eccsize); ++ this->calculate_ecc(mtd, NULL, &(ecc_code[3])); + for (i = 3; i < 6; i++) + oob_data[oob_config[i]] = ecc_code[i]; + } +@@ -436,20 +480,18 @@ + + /* Hardware ecc 3 byte / 512 byte data, write full page */ + case NAND_ECC_HW3_512: +- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic */ +- for (i = 0; i < mtd->oobblock; i++) +- writeb ( this->data_poi[i] , this->IO_ADDR_W); +- this->calculate_ecc (NULL, &(ecc_code[0])); ++ this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic */ ++ this->write_buf(mtd, this->data_poi, mtd->oobblock); ++ this->calculate_ecc(mtd, NULL, &(ecc_code[0])); + for (i = 0; i < 3; i++) + oob_data[oob_config[i]] = ecc_code[i]; + break; + + /* Hardware ecc 6 byte / 512 byte data, write full page */ + case NAND_ECC_HW6_512: +- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic */ +- for (i = 0; i < mtd->oobblock; i++) +- writeb ( this->data_poi[i] , this->IO_ADDR_W); +- this->calculate_ecc (NULL, &(ecc_code[0])); ++ this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic */ ++ this->write_buf(mtd, this->data_poi, mtd->oobblock); ++ this->calculate_ecc(mtd, NULL, &(ecc_code[0])); + for (i = 0; i < 6; i++) + oob_data[oob_config[i]] = ecc_code[i]; + break; +@@ -460,8 +502,7 @@ + } + + /* Write out OOB data */ +- for (i = 0; i < mtd->oobsize; i++) +- writeb ( oob_data[i] , this->IO_ADDR_W); ++ this->write_buf(mtd, oob_data, mtd->oobsize); + + /* Send command to actually program the data */ + this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1); +@@ -490,25 +531,21 @@ + */ + + /* Send command to read back the page */ +- this->cmdfunc (mtd, NAND_CMD_READ0, col, page); ++ this->cmdfunc (mtd, NAND_CMD_READ0, 0, page); + /* Loop through and verify the data */ +- for (i = col; i < last; i++) { +- if (this->data_poi[i] != readb (this->IO_ADDR_R)) { ++ if (this->verify_buf(mtd, this->data_poi, mtd->oobblock)) { + DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page); + return -EIO; + } +- } + + /* check, if we have a fs-supplied oob-buffer */ + if (oob_buf) { +- for (i = 0; i < mtd->oobsize; i++) { +- if (oob_data[i] != readb (this->IO_ADDR_R)) { ++ if (this->verify_buf(mtd, oob_data, mtd->oobsize)) { + DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page); + return -EIO; + } +- } + } else { +- if (eccmode != NAND_ECC_NONE && !col && last == mtd->oobblock) { ++ if (eccmode != NAND_ECC_NONE) { + int ecc_bytes = 0; + + switch (this->eccmode) { +@@ -518,8 +555,7 @@ + case NAND_ECC_HW6_512: ecc_bytes = 6; break; + } + +- for (i = 0; i < mtd->oobsize; i++) +- oob_data[i] = readb (this->IO_ADDR_R); ++ this->read_buf(mtd, oob_data, mtd->oobsize); + + for (i = 0; i < ecc_bytes; i++) { + if (oob_data[oob_config[i]] != ecc_code[i]) { +@@ -531,6 +567,13 @@ + } + } + } ++ /* ++ * Terminate the read command. This is faster than sending a reset command or ++ * applying a 20us delay before issuing the next programm sequence. ++ * This is not a problem for all chips, but I have found a bunch of them. ++ */ ++ this->select_chip(mtd, -1); ++ this->select_chip(mtd, 0); + #endif + return 0; + } +@@ -540,7 +583,7 @@ + */ + static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf) + { +- return (nand_read_ecc (mtd, from, len, retlen, buf, NULL, 0)); ++ return nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL); + } + + +@@ -548,7 +591,7 @@ + * NAND read with ECC + */ + static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, +- size_t * retlen, u_char * buf, u_char * oob_buf, int oobsel) ++ size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel) + { + int j, col, page, end, ecc; + int erase_state = 0; +@@ -557,9 +600,15 @@ + u_char *data_poi, *oob_data = oob_buf; + u_char ecc_calc[6]; + u_char ecc_code[6]; +- int eccmode = oobsel ? this->eccmode : NAND_ECC_NONE; ++ int eccmode; ++ int *oob_config; ++ ++ // use chip default if zero ++ if (oobsel == NULL) ++ oobsel = &mtd->oobinfo; + +- int *oob_config = oobconfigs[oobsel]; ++ eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; ++ oob_config = oobsel->eccpos; + + DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len); + +@@ -574,7 +623,7 @@ + nand_get_chip (this, mtd ,FL_READING, &erase_state); + + /* Select the NAND device */ +- nand_select (); ++ this->select_chip(mtd, 0); + + /* First we calculate the starting page */ + page = from >> this->page_shift; +@@ -596,7 +645,7 @@ + if (!this->dev_ready) + udelay (this->chip_delay); + else +- while (!this->dev_ready()); ++ while (!this->dev_ready(mtd)); + } + + /* +@@ -616,39 +665,40 @@ + + j = 0; + switch (eccmode) { +- case NAND_ECC_NONE: /* No ECC, Read in a page */ +- while (j < end) +- data_poi[j++] = readb (this->IO_ADDR_R); ++ case NAND_ECC_NONE: { /* No ECC, Read in a page */ ++ static unsigned long lastwhinge = 0; ++ if ((lastwhinge / HZ) != (jiffies / HZ)) { ++ printk (KERN_WARNING "Reading data from NAND FLASH without ECC is not recommended\n"); ++ lastwhinge = jiffies; ++ } ++ this->read_buf(mtd, data_poi, end); + break; ++ } + + case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */ +- while (j < end) +- data_poi[j++] = readb (this->IO_ADDR_R); +- this->calculate_ecc (&data_poi[0], &ecc_calc[0]); ++ this->read_buf(mtd, data_poi, end); ++ this->calculate_ecc(mtd, &data_poi[0], &ecc_calc[0]); + if (mtd->oobblock == 512) +- this->calculate_ecc (&data_poi[256], &ecc_calc[3]); ++ this->calculate_ecc(mtd, &data_poi[256], &ecc_calc[3]); + break; + + case NAND_ECC_HW3_256: /* Hardware ECC 3 byte /256 byte data: Read in first 256 byte, get ecc, */ +- this->enable_hwecc (NAND_ECC_READ); +- while (j < ecc) +- data_poi[j++] = readb (this->IO_ADDR_R); +- this->calculate_ecc (&data_poi[0], &ecc_calc[0]); /* read from hardware */ ++ this->enable_hwecc(mtd, NAND_ECC_READ); ++ this->read_buf(mtd, data_poi, ecc); ++ this->calculate_ecc(mtd, &data_poi[0], &ecc_calc[0]); /* read from hardware */ + + if (mtd->oobblock == 512) { /* read second, if pagesize = 512 */ +- this->enable_hwecc (NAND_ECC_READ); +- while (j < end) +- data_poi[j++] = readb (this->IO_ADDR_R); +- this->calculate_ecc (&data_poi[256], &ecc_calc[3]); /* read from hardware */ ++ this->enable_hwecc(mtd, NAND_ECC_READ); ++ this->read_buf(mtd, &data_poi[ecc], end-ecc); ++ this->calculate_ecc(mtd, &data_poi[256], &ecc_calc[3]); /* read from hardware */ + } + break; + + case NAND_ECC_HW3_512: + case NAND_ECC_HW6_512: /* Hardware ECC 3/6 byte / 512 byte data : Read in a page */ +- this->enable_hwecc (NAND_ECC_READ); +- while (j < end) +- data_poi[j++] = readb (this->IO_ADDR_R); +- this->calculate_ecc (&data_poi[0], &ecc_calc[0]); /* read from hardware */ ++ this->enable_hwecc(mtd, NAND_ECC_READ); ++ this->read_buf(mtd, data_poi, end); ++ this->calculate_ecc(mtd, &data_poi[0], &ecc_calc[0]); /* read from hardware */ + break; + + default: +@@ -658,7 +708,7 @@ + + /* read oobdata */ + for (j = 0; j < mtd->oobsize; j++) +- oob_data[oob + j] = readb (this->IO_ADDR_R); ++ oob_data[oob + j] = this->read_byte(mtd); + + /* Skip ECC, if not active */ + if (eccmode == NAND_ECC_NONE) +@@ -669,7 +719,7 @@ + ecc_code[j] = oob_data[oob + oob_config[j]]; + + /* correct data, if neccecary */ +- ecc_status = this->correct_data (&data_poi[0], &ecc_code[0], &ecc_calc[0]); ++ ecc_status = this->correct_data(mtd, &data_poi[0], &ecc_code[0], &ecc_calc[0]); + /* check, if we have a fs supplied oob-buffer */ + if (oob_buf) { + oob += mtd->oobsize; +@@ -682,7 +732,7 @@ + } + + if (mtd->oobblock == 512 && eccmode != NAND_ECC_HW3_512) { +- ecc_status = this->correct_data (&data_poi[256], &ecc_code[3], &ecc_calc[3]); ++ ecc_status = this->correct_data(mtd, &data_poi[256], &ecc_code[3], &ecc_calc[3]); + if (oob_buf) { + *((int *)&oob_data[oob]) = ecc_status; + oob += sizeof(int); +@@ -705,7 +755,7 @@ + } + + /* De-select the NAND device */ +- nand_deselect (); ++ this->select_chip(mtd, -1); + + /* Wake up anyone waiting on the device */ + spin_lock_bh (&this->chip_lock); +@@ -753,7 +803,7 @@ + nand_get_chip (this, mtd , FL_READING, &erase_state); + + /* Select the NAND device */ +- nand_select (); ++ this->select_chip(mtd, 0); + + /* Send the read command */ + this->cmdfunc (mtd, NAND_CMD_READOOB, col, page); +@@ -761,13 +811,20 @@ + * Read the data, if we read more than one page + * oob data, let the device transfer the data ! + */ +- for (i = 0; i < len; i++) { +- buf[i] = readb (this->IO_ADDR_R); +- if ((col++ & (mtd->oobsize - 1)) == (mtd->oobsize - 1)) ++ i = 0; ++ while (i < len) { ++ int thislen = (mtd->oobsize - col) & (mtd->oobsize - 1); ++ if (!thislen) ++ thislen = mtd->oobsize; ++ thislen = min_t(int, thislen, len); ++ this->read_buf(mtd, &buf[i], thislen); ++ i += thislen; ++ col += thislen; ++ /* Delay between pages */ + udelay (this->chip_delay); + } + /* De-select the NAND device */ +- nand_deselect (); ++ this->select_chip(mtd, -1); + + /* Wake up anyone waiting on the device */ + spin_lock_bh (&this->chip_lock); +@@ -780,45 +837,54 @@ + return 0; + } + ++#define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0 ++ + /* + * Use NAND write ECC + */ + static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf) + { +- return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, 0)); ++ return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL)); + } + /* + * NAND write with ECC + */ + static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, +- size_t * retlen, const u_char * buf, u_char * eccbuf, int oobsel) ++ size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel) + { +- int i, page, col, cnt, ret = 0, oob = 0, written = 0; ++ int page, ret = 0, oob = 0, written = 0; + struct nand_chip *this = mtd->priv; + + DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); + + /* Do not allow write past end of device */ + if ((to + len) > mtd->size) { +- DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n"); ++ DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n"); ++ return -EINVAL; ++ } ++ ++ /* reject writes, which are not page aligned */ ++ if (NOTALIGNED (to) || NOTALIGNED(len)) { ++ printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); + return -EINVAL; + } + ++ // if oobsel is NULL, use chip defaults ++ if (oobsel == NULL) ++ oobsel = &mtd->oobinfo; ++ + /* Shift to get page */ + page = ((int) to) >> this->page_shift; + +- /* Get the starting column */ +- col = to & (mtd->oobblock - 1); +- + /* Grab the lock and see if the device is available */ + nand_get_chip (this, mtd, FL_WRITING, NULL); + + /* Select the NAND device */ +- nand_select (); ++ this->select_chip(mtd, 0); + + /* Check the WP bit */ + this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); +- if (!(readb (this->IO_ADDR_R) & 0x80)) { ++ if (!(this->read_byte(mtd) & 0x80)) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Device is write protected!!!\n"); + ret = -EIO; + goto out; +@@ -826,42 +892,27 @@ + + /* Loop until all data is written */ + while (written < len) { +- /* +- * Check, if we have a full page write, then we can +- * use the given buffer, else we have to copy +- */ +- if (!col && (len - written) >= mtd->oobblock) { ++ int cnt = mtd->oobblock; + this->data_poi = (u_char*) &buf[written]; +- cnt = mtd->oobblock; +- } else { +- cnt = 0; +- for (i = col; i < len && i < mtd->oobblock; i++) { +- this->data_buf[i] = buf[written + i]; +- cnt++; +- } +- this->data_poi = this->data_buf; +- } +- /* We use the same function for write and writev !) */ ++ /* We use the same function for write and writev */ + if (eccbuf) { +- ret = nand_write_page (mtd, this, page, col, cnt ,&eccbuf[oob], oobsel); ++ ret = nand_write_page (mtd, this, page, &eccbuf[oob], oobsel); + oob += mtd->oobsize; + } else +- ret = nand_write_page (mtd, this, page, col, cnt, NULL, oobsel); ++ ret = nand_write_page (mtd, this, page, NULL, oobsel); + + if (ret) + goto out; + + /* Update written bytes count */ + written += cnt; +- /* Next write is aligned */ +- col = 0; + /* Increment page address */ + page++; + } + + out: + /* De-select the NAND device */ +- nand_deselect (); ++ this->select_chip(mtd, -1); + + /* Wake up anyone waiting on the device */ + spin_lock_bh (&this->chip_lock); +@@ -873,13 +924,21 @@ + return ret; + } + ++static u_char ffchars[] = { ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ++}; ++ + /* + * NAND write out-of-band + */ + static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf) + { +- int i, column, page, status, ret = 0; ++ int column, page, status, ret = 0; + struct nand_chip *this = mtd->priv; ++#ifdef CONFIG_MTD_NAND_VERIFY_WRITE ++ int i; ++#endif + + DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len); + +@@ -902,27 +961,31 @@ + nand_get_chip (this, mtd, FL_WRITING, NULL); + + /* Select the NAND device */ +- nand_select (); ++ this->select_chip(mtd, 0); ++ ++ /* Reset the chip. Some chips (like the Toshiba TC5832DC found ++ in one of my DiskOnChip 2000 test units) will clear the whole ++ data page too if we don't do this. I have no clue why, but ++ I seem to have 'fixed' it in the doc2000 driver in ++ August 1999. dwmw2. */ ++ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + + /* Check the WP bit */ + this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); +- if (!(readb (this->IO_ADDR_R) & 0x80)) { ++ if (!(this->read_byte(mtd) & 0x80)) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Device is write protected!!!\n"); + ret = -EIO; + goto out; + } +- + /* Write out desired data */ + this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page); ++ + /* prepad 0xff for partial programming */ +- for (i = 0; i < column; i++) +- writeb (0xff, this->IO_ADDR_W); ++ this->write_buf(mtd, ffchars, column); + /* write data */ +- for (i = 0; i < len; i++) +- writeb (buf[i], this->IO_ADDR_W); ++ this->write_buf(mtd, buf, len); + /* postpad 0xff for partial programming */ +- for (i = len + column; i < mtd->oobsize; i++) +- writeb (0xff, this->IO_ADDR_W); ++ this->write_buf(mtd, ffchars, mtd->oobsize - (len+column)); + + /* Send command to program the OOB data */ + this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1); +@@ -944,7 +1007,7 @@ + + /* Loop through and verify the data */ + for (i = 0; i < len; i++) { +- if (buf[i] != readb (this->IO_ADDR_R)) { ++ if (buf[i] != this->read_byte(mtd)) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page); + ret = -EIO; + goto out; +@@ -954,7 +1017,7 @@ + + out: + /* De-select the NAND device */ +- nand_deselect (); ++ this->select_chip(mtd, -1); + + /* Wake up anyone waiting on the device */ + spin_lock_bh (&this->chip_lock); +@@ -976,9 +1039,9 @@ + } + + static int nand_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, +- loff_t to, size_t * retlen, u_char *eccbuf, int oobsel) ++ loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) + { +- int i, page, col, cnt, len, total_len, ret = 0, written = 0; ++ int i, page, len, total_len, ret = 0, written = 0; + struct nand_chip *this = mtd->priv; + + /* Calculate total length of data */ +@@ -995,39 +1058,42 @@ + return -EINVAL; + } + ++ /* reject writes, which are not page aligned */ ++ if (NOTALIGNED (to) || NOTALIGNED(total_len)) { ++ printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); ++ return -EINVAL; ++ } ++ ++ // if oobsel is NULL, use chip defaults ++ if (oobsel == NULL) ++ oobsel = &mtd->oobinfo; ++ + /* Shift to get page */ + page = ((int) to) >> this->page_shift; + +- /* Get the starting column */ +- col = to & (mtd->oobblock - 1); +- + /* Grab the lock and see if the device is available */ + nand_get_chip (this, mtd, FL_WRITING, NULL); + + /* Select the NAND device */ +- nand_select (); ++ this->select_chip(mtd, 0); + + /* Check the WP bit */ + this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); +- if (!(readb (this->IO_ADDR_R) & 0x80)) { ++ if (!(this->read_byte(mtd) & 0x80)) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Device is write protected!!!\n"); + ret = -EIO; + goto out; + } + + /* Loop until all iovecs' data has been written */ +- cnt = col; + len = 0; +- + while (count) { + /* +- * Check, if we write from offset 0 and if the tuple +- * gives us not enough data for a full page write. Then we +- * can use the iov direct, else we have to copy into +- * data_buf. ++ * Check, if the tuple gives us not enough data for a ++ * full page write. Then we can use the iov direct, ++ * else we have to copy into data_buf. + */ +- if (!cnt && (vecs->iov_len - len) >= mtd->oobblock) { +- cnt = mtd->oobblock; ++ if ((vecs->iov_len - len) >= mtd->oobblock) { + this->data_poi = (u_char *) vecs->iov_base; + this->data_poi += len; + len += mtd->oobblock; +@@ -1042,6 +1108,7 @@ + * Read data out of each tuple until we have a full page + * to write or we've read all the tuples. + */ ++ int cnt = 0; + while ((cnt < mtd->oobblock) && count) { + if (vecs->iov_base != NULL && vecs->iov_len) { + this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++]; +@@ -1057,15 +1124,12 @@ + } + + /* We use the same function for write and writev !) */ +- ret = nand_write_page (mtd, this, page, col, cnt, NULL, oobsel); ++ ret = nand_write_page (mtd, this, page, NULL, oobsel); + if (ret) + goto out; + + /* Update written bytes count */ +- written += (cnt - col); +- +- /* Reset written byte counter and column */ +- col = cnt = 0; ++ written += mtd->oobblock;; + + /* Increment page address */ + page++; +@@ -1073,7 +1137,7 @@ + + out: + /* De-select the NAND device */ +- nand_deselect (); ++ this->select_chip(mtd, -1); + + /* Wake up anyone waiting on the device */ + spin_lock_bh (&this->chip_lock); +@@ -1125,11 +1189,11 @@ + pages_per_block = mtd->erasesize / mtd->oobblock; + + /* Select the NAND device */ +- nand_select (); ++ this->select_chip(mtd, 0); + + /* Check the WP bit */ + this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); +- if (!(readb (this->IO_ADDR_R) & 0x80)) { ++ if (!(this->read_byte(mtd) & 0x80)) { + DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n"); + instr->state = MTD_ERASE_FAILED; + goto erase_exit; +@@ -1142,8 +1206,7 @@ + + while (len) { + /* Check if we have a bad block, we do not erase bad blocks ! */ +- this->cmdfunc (mtd, NAND_CMD_READOOB, NAND_BADBLOCK_POS, page); +- if (readb (this->IO_ADDR_R) != 0xff) { ++ if (this->block_bad(mtd, page)) { + printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page); + instr->state = MTD_ERASE_FAILED; + goto erase_exit; +@@ -1179,7 +1242,7 @@ + if (this->state == FL_ERASING || this->state == FL_READY) { + /* Select the NAND device again, if we were interrupted */ + this->state = FL_ERASING; +- nand_select (); ++ this->select_chip(mtd, 0); + continue; + } else { + set_current_state (TASK_UNINTERRUPTIBLE); +@@ -1194,7 +1257,7 @@ + + erase_exit: + /* De-select the NAND device */ +- nand_deselect (); ++ this->select_chip(mtd, -1); + spin_unlock_bh (&this->chip_lock); + + ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;; +@@ -1205,6 +1268,7 @@ + /* The device is ready */ + spin_lock_bh (&this->chip_lock); + this->state = FL_READY; ++ wake_up (&this->wq); + spin_unlock_bh (&this->chip_lock); + + /* Return more or less happy */ +@@ -1259,7 +1323,7 @@ + /* + * Scan for the NAND device + */ +-int nand_scan (struct mtd_info *mtd) ++int nand_scan (struct mtd_info *mtd, int maxchips) + { + int i, nand_maf_id, nand_dev_id; + struct nand_chip *this = mtd->priv; +@@ -1276,23 +1340,38 @@ + if (this->waitfunc == NULL) + this->waitfunc = nand_wait; + ++ if (!this->block_bad) ++ this->block_bad = nand_block_bad; ++ if (!this->select_chip) ++ this->select_chip = nand_select_chip; ++ if (!this->write_byte) ++ this->write_byte = nand_write_byte; ++ if (!this->read_byte) ++ this->read_byte = nand_read_byte; ++ if (!this->write_buf) ++ this->write_buf = nand_write_buf; ++ if (!this->read_buf) ++ this->read_buf = nand_read_buf; ++ if (!this->verify_buf) ++ this->verify_buf = nand_verify_buf; ++ + /* Select the device */ +- nand_select (); ++ this->select_chip(mtd, 0); + + /* Send the command for reading device ID */ + this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1); + + /* Read manufacturer and device IDs */ +- nand_maf_id = readb (this->IO_ADDR_R); +- nand_dev_id = readb (this->IO_ADDR_R); ++ nand_maf_id = this->read_byte(mtd); ++ nand_dev_id = this->read_byte(mtd); + + /* Print and store flash device information */ + for (i = 0; nand_flash_ids[i].name != NULL; i++) { + if (nand_dev_id == nand_flash_ids[i].id && !mtd->size) { + mtd->name = nand_flash_ids[i].name; + mtd->erasesize = nand_flash_ids[i].erasesize; +- mtd->size = (1 << nand_flash_ids[i].chipshift); + mtd->eccsize = 256; ++ this->chipshift = nand_flash_ids[i].chipshift; + if (nand_flash_ids[i].page256) { + mtd->oobblock = 256; + mtd->oobsize = 8; +@@ -1307,13 +1386,34 @@ + if (nand_manuf_ids[i].id == nand_maf_id) + break; + } +- printk (KERN_INFO "NAND device: Manufacture ID:" ++ printk (KERN_INFO "NAND device: Manufacturer ID:" + " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, + nand_manuf_ids[i].name , mtd->name); + break; + } + } + ++ if (!mtd->name) { ++ printk (KERN_WARNING "No NAND device found!!!\n"); ++ return 1; ++ } ++ ++ for (i=1; i < maxchips; i++) { ++ this->select_chip(mtd, i); ++ ++ /* Send the command for reading device ID */ ++ this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1); ++ ++ /* Read manufacturer and device IDs */ ++ if (nand_maf_id != this->read_byte(mtd) || ++ nand_dev_id != this->read_byte(mtd)) ++ break; ++ } ++ if (i > 1) ++ printk(KERN_INFO "%d NAND chips detected\n", i); ++ ++ mtd->size = (1 << this->chipshift) /* * i when we fix the rest of the code */; ++ + /* + * check ECC mode, default to software + * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize +@@ -1324,6 +1424,7 @@ + switch (this->eccmode) { + + case NAND_ECC_HW3_512: ++ case NAND_ECC_HW6_512: + if (mtd->oobblock == 256) { + printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n"); + this->eccmode = NAND_ECC_SOFT; +@@ -1340,6 +1441,7 @@ + BUG(); + + case NAND_ECC_NONE: ++ printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n"); + this->eccmode = NAND_ECC_NONE; + break; + +@@ -1359,18 +1461,11 @@ + spin_lock_init (&this->chip_lock); + + /* De-select the device */ +- nand_deselect (); +- +- /* Print warning message for no device */ +- if (!mtd->size) { +- printk (KERN_WARNING "No NAND device found!!!\n"); +- return 1; +- } ++ this->select_chip(mtd, -1); + + /* Fill in remaining MTD driver data */ + mtd->type = MTD_NANDFLASH; + mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC; +- mtd->module = THIS_MODULE; + mtd->ecctype = MTD_ECC_SW; + mtd->erase = nand_erase; + mtd->point = NULL; +@@ -1389,6 +1484,7 @@ + mtd->unlock = NULL; + mtd->suspend = NULL; + mtd->resume = NULL; ++ mtd->owner = THIS_MODULE; + + /* Return happy */ + return 0; +@@ -1397,5 +1493,5 @@ + EXPORT_SYMBOL (nand_scan); + + MODULE_LICENSE ("GPL"); +-MODULE_AUTHOR ("Steven J. Hill , Thomas Gleixner "); ++MODULE_AUTHOR ("Steven J. Hill , Thomas Gleixner "); + MODULE_DESCRIPTION ("Generic NAND flash driver code"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/nand_ecc.c linux/drivers/mtd/nand/nand_ecc.c +--- linux-mips-2.4.27/drivers/mtd/nand/nand_ecc.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/nand/nand_ecc.c 2004-11-19 10:25:12.011182768 +0100 +@@ -1,10 +1,10 @@ + /* + * drivers/mtd/nand_ecc.c + * +- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) ++ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) + * Toshiba America Electronics Components, Inc. + * +- * $Id: nand_ecc.c,v 1.8 2002/09/16 09:19:53 dwmw2 Exp $ ++ * $Id: nand_ecc.c,v 1.10 2003/07/01 23:31:15 dwmw2 Exp $ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + + /* + * Pre-calculated 256-way 1 byte column parity +@@ -84,7 +85,7 @@ + /* + * Calculate 3 byte ECC code for 256 byte block + */ +-void nand_calculate_ecc (const u_char *dat, u_char *ecc_code) ++void nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) + { + u_char idx, reg1, reg2, reg3; + int j; +@@ -119,7 +120,7 @@ + /* + * Detect and correct a 1 bit error for 256 byte block + */ +-int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc) ++int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) + { + u_char a, b, c, d1, d2, d3, add, bit, i; + +@@ -209,5 +210,5 @@ + EXPORT_SYMBOL(nand_correct_data); + + MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Steven J. Hill "); ++MODULE_AUTHOR("Steven J. Hill "); + MODULE_DESCRIPTION("Generic NAND ECC support"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/nand_ids.c linux/drivers/mtd/nand/nand_ids.c +--- linux-mips-2.4.27/drivers/mtd/nand/nand_ids.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/nand/nand_ids.c 2004-11-19 10:25:12.013182464 +0100 +@@ -4,7 +4,7 @@ + * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) + * + * +- * $Id: nand_ids.c,v 1.1 2002/12/02 22:06:04 gleixner Exp $ ++ * $Id: nand_ids.c,v 1.4 2003/05/21 15:15:08 dwmw2 Exp $ + * + * 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 +@@ -18,21 +18,21 @@ + * Chip ID list + */ + struct nand_flash_dev nand_flash_ids[] = { +- {"NAND 1MB 5V", 0x6e, 20, 0x1000, 1}, // 1Mb 5V +- {"NAND 2MB 5V", 0x64, 21, 0x1000, 1}, // 2Mb 5V +- {"NAND 4MB 5V", 0x6b, 22, 0x2000, 0}, // 4Mb 5V +- {"NAND 1MB 3,3V", 0xe8, 20, 0x1000, 1}, // 1Mb 3.3V +- {"NAND 1MB 3,3V", 0xec, 20, 0x1000, 1}, // 1Mb 3.3V +- {"NAND 2MB 3,3V", 0xea, 21, 0x1000, 1}, // 2Mb 3.3V +- {"NAND 4MB 3,3V", 0xd5, 22, 0x2000, 0}, // 4Mb 3.3V +- {"NAND 4MB 3,3V", 0xe3, 22, 0x2000, 0}, // 4Mb 3.3V +- {"NAND 4MB 3,3V", 0xe5, 22, 0x2000, 0}, // 4Mb 3.3V +- {"NAND 8MB 3,3V", 0xd6, 23, 0x2000, 0}, // 8Mb 3.3V +- {"NAND 8MB 3,3V", 0xe6, 23, 0x2000, 0}, // 8Mb 3.3V +- {"NAND 16MB 3,3V", 0x73, 24, 0x4000, 0},// 16Mb 3,3V +- {"NAND 32MB 3,3V", 0x75, 25, 0x4000, 0}, // 32Mb 3,3V +- {"NAND 64MB 3,3V", 0x76, 26, 0x4000, 0}, // 64Mb 3,3V +- {"NAND 128MB 3,3V", 0x79, 27, 0x4000, 0}, // 128Mb 3,3V ++ {"NAND 1MiB 5V", 0x6e, 20, 0x1000, 1}, ++ {"NAND 2MiB 5V", 0x64, 21, 0x1000, 1}, ++ {"NAND 4MiB 5V", 0x6b, 22, 0x2000, 0}, ++ {"NAND 1MiB 3,3V", 0xe8, 20, 0x1000, 1}, ++ {"NAND 1MiB 3,3V", 0xec, 20, 0x1000, 1}, ++ {"NAND 2MiB 3,3V", 0xea, 21, 0x1000, 1}, ++ {"NAND 4MiB 3,3V", 0xd5, 22, 0x2000, 0}, ++ {"NAND 4MiB 3,3V", 0xe3, 22, 0x2000, 0}, ++ {"NAND 4MiB 3,3V", 0xe5, 22, 0x2000, 0}, ++ {"NAND 8MiB 3,3V", 0xd6, 23, 0x2000, 0}, ++ {"NAND 8MiB 3,3V", 0xe6, 23, 0x2000, 0}, ++ {"NAND 16MiB 3,3V", 0x73, 24, 0x4000, 0}, ++ {"NAND 32MiB 3,3V", 0x75, 25, 0x4000, 0}, ++ {"NAND 64MiB 3,3V", 0x76, 26, 0x4000, 0}, ++ {"NAND 128MiB 3,3V", 0x79, 27, 0x4000, 0}, + {NULL,} + }; + +diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/spia.c linux/drivers/mtd/nand/spia.c +--- linux-mips-2.4.27/drivers/mtd/nand/spia.c 2003-02-26 01:53:50.000000000 +0100 ++++ linux/drivers/mtd/nand/spia.c 2004-11-19 10:25:12.014182312 +0100 +@@ -1,14 +1,14 @@ + /* + * drivers/mtd/nand/spia.c + * +- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) ++ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) + * + * + * 10-29-2001 TG change to support hardwarespecific access + * to controllines (due to change in nand.c) + * page_cache added + * +- * $Id: spia.c,v 1.16 2002/03/05 13:50:47 dwmw2 Exp $ ++ * $Id: spia.c,v 1.21 2003/07/11 15:12:29 dwmw2 Exp $ + * + * 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 +@@ -20,6 +20,8 @@ + * a 64Mibit (8MiB x 8 bits) NAND flash device. + */ + ++#include ++#include + #include + #include + #include +@@ -35,14 +37,14 @@ + /* + * Values specific to the SPIA board (used with EP7212 processor) + */ +-#define SPIA_IO_ADDR = 0xd0000000 /* Start of EP7212 IO address space */ +-#define SPIA_FIO_ADDR = 0xf0000000 /* Address where flash is mapped */ +-#define SPIA_PEDR = 0x0080 /* ++#define SPIA_IO_BASE 0xd0000000 /* Start of EP7212 IO address space */ ++#define SPIA_FIO_BASE 0xf0000000 /* Address where flash is mapped */ ++#define SPIA_PEDR 0x0080 /* + * IO offset to Port E data register + * where the CLE, ALE and NCE pins + * are wired to. + */ +-#define SPIA_PEDDR = 0x00c0 /* ++#define SPIA_PEDDR 0x00c0 /* + * IO offset to Port E data direction + * register so we can control the IO + * lines. +@@ -62,21 +64,20 @@ + MODULE_PARM(spia_pedr, "i"); + MODULE_PARM(spia_peddr, "i"); + +-__setup("spia_io_base=",spia_io_base); +-__setup("spia_fio_base=",spia_fio_base); +-__setup("spia_pedr=",spia_pedr); +-__setup("spia_peddr=",spia_peddr); +- + /* + * Define partitions for flash device + */ + const static struct mtd_partition partition_info[] = { +- { name: "SPIA flash partition 1", +- offset: 0, +- size: 2*1024*1024 }, +- { name: "SPIA flash partition 2", +- offset: 2*1024*1024, +- size: 6*1024*1024 } ++ { ++ .name = "SPIA flash partition 1", ++ .offset = 0, ++ .size = 2*1024*1024 ++ }, ++ { ++ .name = "SPIA flash partition 2", ++ .offset = 2*1024*1024, ++ .size = 6*1024*1024 ++ } + }; + #define NUM_PARTITIONS 2 + +@@ -84,7 +85,7 @@ + /* + * hardware specific access to control-lines + */ +-void spia_hwcontrol(int cmd){ ++static void spia_hwcontrol(struct mtd_info *mtd, int cmd){ + + switch(cmd){ + +@@ -139,7 +140,7 @@ + this->chip_delay = 15; + + /* Scan to find existence of the device */ +- if (nand_scan (spia_mtd)) { ++ if (nand_scan (spia_mtd, 1)) { + kfree (spia_mtd); + return -ENXIO; + } +@@ -152,16 +153,6 @@ + return -ENOMEM; + } + +- /* Allocate memory for internal data buffer */ +- this->data_cache = kmalloc (sizeof(u_char) * (spia_mtd->oobblock + spia_mtd->oobsize), GFP_KERNEL); +- if (!this->data_cache) { +- printk ("Unable to allocate NAND data cache for SPIA.\n"); +- kfree (this->data_buf); +- kfree (spia_mtd); +- return = -ENOMEM; +- } +- this->cache_page = -1; +- + /* Register the partitions */ + add_mtd_partitions(spia_mtd, partition_info, NUM_PARTITIONS); + +@@ -183,7 +174,6 @@ + + /* Free internal data buffer */ + kfree (this->data_buf); +- kfree (this->page_cache); + + /* Free the MTD device structure */ + kfree (spia_mtd); +@@ -192,5 +182,5 @@ + #endif + + MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Steven J. Hill ++ * ++ * 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. ++ * ++ * Overview: ++ * This is a device driver for the NAND flash device found on the ++ * TI fido board. It supports 32MiB and 64MiB cards ++ * ++ * $Id: toto.c,v 1.2 2003/10/21 10:04:58 dwmw2 Exp $ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * MTD structure for TOTO board ++ */ ++static struct mtd_info *toto_mtd = NULL; ++ ++static int toto_io_base = OMAP_FLASH_1_BASE; ++ ++#define CONFIG_NAND_WORKAROUND 1 ++ ++#define NAND_NCE 0x4000 ++#define NAND_CLE 0x1000 ++#define NAND_ALE 0x0002 ++#define NAND_MASK (NAND_CLE | NAND_ALE | NAND_NCE) ++ ++#define T_NAND_CTL_CLRALE(iob) gpiosetout(NAND_ALE, 0) ++#define T_NAND_CTL_SETALE(iob) gpiosetout(NAND_ALE, NAND_ALE) ++#ifdef CONFIG_NAND_WORKAROUND /* "some" dev boards busted, blue wired to rts2 :( */ ++#define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0); rts2setout(2, 2) ++#define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE); rts2setout(2, 0) ++#else ++#define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0) ++#define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE) ++#endif ++#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0) ++#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE) ++ ++/* ++ * Define partitions for flash devices ++ */ ++ ++static struct mtd_partition partition_info64M[] = { ++ { .name = "toto kernel partition 1", ++ .offset = 0, ++ .size = 2 * SZ_1M }, ++ { .name = "toto file sys partition 2", ++ .offset = 2 * SZ_1M, ++ .size = 14 * SZ_1M }, ++ { .name = "toto user partition 3", ++ .offset = 16 * SZ_1M, ++ .size = 16 * SZ_1M }, ++ { .name = "toto devboard extra partition 4", ++ .offset = 32 * SZ_1M, ++ .size = 32 * SZ_1M }, ++}; ++ ++static struct mtd_partition partition_info32M[] = { ++ { .name = "toto kernel partition 1", ++ .offset = 0, ++ .size = 2 * SZ_1M }, ++ { .name = "toto file sys partition 2", ++ .offset = 2 * SZ_1M, ++ .size = 14 * SZ_1M }, ++ { .name = "toto user partition 3", ++ .offset = 16 * SZ_1M, ++ .size = 16 * SZ_1M }, ++}; ++ ++#define NUM_PARTITIONS32M 3 ++#define NUM_PARTITIONS64M 4 ++/* ++ * hardware specific access to control-lines ++*/ ++ ++static void toto_hwcontrol(struct mtd_info *mtd, int cmd) ++{ ++ ++ udelay(1); /* hopefully enough time for tc make proceding write to clear */ ++ switch(cmd){ ++ ++ case NAND_CTL_SETCLE: T_NAND_CTL_SETCLE(cmd); break; ++ case NAND_CTL_CLRCLE: T_NAND_CTL_CLRCLE(cmd); break; ++ ++ case NAND_CTL_SETALE: T_NAND_CTL_SETALE(cmd); break; ++ case NAND_CTL_CLRALE: T_NAND_CTL_CLRALE(cmd); break; ++ ++ case NAND_CTL_SETNCE: T_NAND_CTL_SETNCE(cmd); break; ++ case NAND_CTL_CLRNCE: T_NAND_CTL_CLRNCE(cmd); break; ++ } ++ udelay(1); /* allow time to ensure gpio state to over take memory write */ ++} ++ ++/* ++ * Main initialization routine ++ */ ++int __init toto_init (void) ++{ ++ struct nand_chip *this; ++ int err = 0; ++ ++ /* Allocate memory for MTD device structure and private data */ ++ toto_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), ++ GFP_KERNEL); ++ if (!toto_mtd) { ++ printk (KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n"); ++ err = -ENOMEM; ++ goto out; ++ } ++ ++ /* Get pointer to private data */ ++ this = (struct nand_chip *) (&toto_mtd[1]); ++ ++ /* Initialize structures */ ++ memset((char *) toto_mtd, 0, sizeof(struct mtd_info)); ++ memset((char *) this, 0, sizeof(struct nand_chip)); ++ ++ /* Link the private data with the MTD structure */ ++ toto_mtd->priv = this; ++ ++ /* Set address of NAND IO lines */ ++ this->IO_ADDR_R = toto_io_base; ++ this->IO_ADDR_W = toto_io_base; ++ this->hwcontrol = toto_hwcontrol; ++ this->dev_ready = NULL; ++ /* 25 us command delay time */ ++ this->chip_delay = 30; ++ this->eccmode = NAND_ECC_SOFT; ++ ++ /* Scan to find existance of the device */ ++ if (nand_scan (toto_mtd, 1)) { ++ err = -ENXIO; ++ goto out_mtd; ++ } ++ ++ /* Allocate memory for internal data buffer */ ++ this->data_buf = kmalloc (sizeof(u_char) * (toto_mtd->oobblock + toto_mtd->oobsize), GFP_KERNEL); ++ if (!this->data_buf) { ++ printk (KERN_WARNING "Unable to allocate NAND data buffer for toto.\n"); ++ err = -ENOMEM; ++ goto out_mtd; ++ } ++ ++ /* Register the partitions */ ++ switch(toto_mtd->size){ ++ case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break; ++ case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break; ++ default: { ++ printk (KERN_WARNING "Unsupported Nand device\n"); ++ err = -ENXIO; ++ goto out_buf; ++ } ++ } ++ ++ gpioreserve(NAND_MASK); /* claim our gpios */ ++ archflashwp(0,0); /* open up flash for writing */ ++ ++ goto out; ++ ++out_buf: ++ kfree (this->data_buf); ++out_mtd: ++ kfree (toto_mtd); ++out: ++ return err; ++} ++ ++module_init(toto_init); ++ ++/* ++ * Clean up routine ++ */ ++static void __exit toto_cleanup (void) ++{ ++ struct nand_chip *this = (struct nand_chip *) &toto_mtd[1]; ++ ++ /* Unregister partitions */ ++ del_mtd_partitions(toto_mtd); ++ ++ /* Unregister the device */ ++ del_mtd_device (toto_mtd); ++ ++ /* Free internal data buffers */ ++ kfree (this->data_buf); ++ ++ /* Free the MTD device structure */ ++ kfree (toto_mtd); ++ ++ /* stop flash writes */ ++ archflashwp(0,1); ++ ++ /* release gpios to system */ ++ gpiorelease(NAND_MASK); ++} ++module_exit(toto_cleanup); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Richard Woodruff "); ++MODULE_DESCRIPTION("Glue layer for NAND flash on toto board"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/tx4925ndfmc.c linux/drivers/mtd/nand/tx4925ndfmc.c +--- linux-mips-2.4.27/drivers/mtd/nand/tx4925ndfmc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/nand/tx4925ndfmc.c 2004-11-19 10:25:12.017181856 +0100 +@@ -0,0 +1,442 @@ ++/* ++ * drivers/mtd/tx4925ndfmc.c ++ * ++ * Overview: ++ * This is a device driver for the NAND flash device found on the ++ * Toshiba RBTX4925 reference board, which is a SmartMediaCard. It supports ++ * 16MiB, 32MiB and 64MiB cards. ++ * ++ * Author: MontaVista Software, Inc. source@mvista.com ++ * ++ * Derived from drivers/mtd/autcpu12.c ++ * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) ++ * ++ * $Id: tx4925ndfmc.c,v 1.1 2003/11/04 22:59:11 ahennessy Exp $ ++ * ++ * Copyright (C) 2001 Toshiba Corporation ++ * ++ * 2003 (c) MontaVista Software, Inc. This file is licensed under ++ * the terms of the GNU General Public License version 2. This program ++ * is licensed "as is" without any warranty of any kind, whether express ++ * or implied. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern struct nand_oobinfo jffs2_oobinfo; ++ ++/* ++ * MTD structure for RBTX4925 board ++ */ ++static struct mtd_info *tx4925ndfmc_mtd = NULL; ++ ++/* ++ * Module stuff ++ */ ++#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE) ++#define tx4925ndfmc_init init_module ++#define tx4925ndfmc_cleanup cleanup_module ++#endif ++ ++/* ++ * Define partitions for flash devices ++ */ ++ ++static struct mtd_partition partition_info16k[] = { ++ { .name = "RBTX4925 flash partition 1", ++ .offset = 0, ++ .size = 8 * 0x00100000 }, ++ { .name = "RBTX4925 flash partition 2", ++ .offset = 8 * 0x00100000, ++ .size = 8 * 0x00100000 }, ++}; ++ ++static struct mtd_partition partition_info32k[] = { ++ { .name = "RBTX4925 flash partition 1", ++ .offset = 0, ++ .size = 8 * 0x00100000 }, ++ { .name = "RBTX4925 flash partition 2", ++ .offset = 8 * 0x00100000, ++ .size = 24 * 0x00100000 }, ++}; ++ ++static struct mtd_partition partition_info64k[] = { ++ { .name = "User FS", ++ .offset = 0, ++ .size = 16 * 0x00100000 }, ++ { .name = "RBTX4925 flash partition 2", ++ .offset = 16 * 0x00100000, ++ .size = 48 * 0x00100000}, ++}; ++ ++static struct mtd_partition partition_info128k[] = { ++ { .name = "Skip bad section", ++ .offset = 0, ++ .size = 16 * 0x00100000 }, ++ { .name = "User FS", ++ .offset = 16 * 0x00100000, ++ .size = 112 * 0x00100000 }, ++}; ++#define NUM_PARTITIONS16K 2 ++#define NUM_PARTITIONS32K 2 ++#define NUM_PARTITIONS64K 2 ++#define NUM_PARTITIONS128K 2 ++ ++/* ++ * hardware specific access to control-lines ++*/ ++static void tx4925ndfmc_hwcontrol(struct mtd_info *mtd, int cmd) ++{ ++ ++ switch(cmd){ ++ ++ case NAND_CTL_SETCLE: ++ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CLE; ++ break; ++ case NAND_CTL_CLRCLE: ++ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CLE; ++ break; ++ case NAND_CTL_SETALE: ++ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ALE; ++ break; ++ case NAND_CTL_CLRALE: ++ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ALE; ++ break; ++ case NAND_CTL_SETNCE: ++ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CE; ++ break; ++ case NAND_CTL_CLRNCE: ++ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CE; ++ break; ++ case NAND_CTL_SETWP: ++ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_WE; ++ break; ++ case NAND_CTL_CLRWP: ++ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_WE; ++ break; ++ } ++} ++ ++/* ++* read device ready pin ++*/ ++static int tx4925ndfmc_device_ready(struct mtd_info *mtd) ++{ ++ int ready; ++ ready = (tx4925_ndfmcptr->sr & TX4925_NDSFR_BUSY) ? 0 : 1; ++ return ready; ++} ++void tx4925ndfmc_enable_hwecc(struct mtd_info *mtd, int mode) ++{ ++ /* reset first */ ++ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_MASK; ++ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK; ++ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_ENAB; ++} ++static void tx4925ndfmc_disable_ecc(void) ++{ ++ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK; ++} ++static void tx4925ndfmc_enable_read_ecc(void) ++{ ++ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK; ++ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_READ; ++} ++void tx4925ndfmc_readecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code){ ++ int i; ++ u_char *ecc = ecc_code; ++ tx4925ndfmc_enable_read_ecc(); ++ for (i = 0;i < 6;i++,ecc++) ++ *ecc = tx4925_read_nfmc(&(tx4925_ndfmcptr->dtr)); ++ tx4925ndfmc_disable_ecc(); ++} ++void tx4925ndfmc_device_setup(void) ++{ ++ ++ *(unsigned char *)0xbb005000 &= ~0x08; ++ ++ /* reset NDFMC */ ++ tx4925_ndfmcptr->rstr |= TX4925_NDFRSTR_RST; ++ while (tx4925_ndfmcptr->rstr & TX4925_NDFRSTR_RST); ++ ++ /* setup BusSeparete, Hold Time, Strobe Pulse Width */ ++ tx4925_ndfmcptr->mcr = TX4925_BSPRT ? TX4925_NDFMCR_BSPRT : 0; ++ tx4925_ndfmcptr->spr = TX4925_HOLD << 4 | TX4925_SPW; ++} ++static u_char tx4925ndfmc_nand_read_byte(struct mtd_info *mtd) ++{ ++ struct nand_chip *this = mtd->priv; ++ return tx4925_read_nfmc(this->IO_ADDR_R); ++} ++ ++static void tx4925ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte) ++{ ++ struct nand_chip *this = mtd->priv; ++ tx4925_write_nfmc(byte, this->IO_ADDR_W); ++} ++ ++static void tx4925ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++ for (i=0; iIO_ADDR_W); ++} ++ ++static void tx4925ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++ for (i=0; iIO_ADDR_R); ++} ++ ++static int tx4925ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++ for (i=0; iIO_ADDR_R)) ++ return i; ++ ++ return 0; ++} ++ ++/* ++ * Send command to NAND device ++ */ ++static void tx4925ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr) ++{ ++ register struct nand_chip *this = mtd->priv; ++ ++ /* Begin command latch cycle */ ++ this->hwcontrol(mtd, NAND_CTL_SETCLE); ++ /* ++ * Write out the command to the device. ++ */ ++ if (command == NAND_CMD_SEQIN) { ++ int readcmd; ++ ++ if (column >= mtd->oobblock) { ++ /* OOB area */ ++ column -= mtd->oobblock; ++ readcmd = NAND_CMD_READOOB; ++ } else if (column < 256) { ++ /* First 256 bytes --> READ0 */ ++ readcmd = NAND_CMD_READ0; ++ } else { ++ column -= 256; ++ readcmd = NAND_CMD_READ1; ++ } ++ this->write_byte(mtd, readcmd); ++ } ++ this->write_byte(mtd, command); ++ ++ /* Set ALE and clear CLE to start address cycle */ ++ this->hwcontrol(mtd, NAND_CTL_CLRCLE); ++ ++ if (column != -1 || page_addr != -1) { ++ this->hwcontrol(mtd, NAND_CTL_SETALE); ++ ++ /* Serially input address */ ++ if (column != -1) ++ this->write_byte(mtd, column); ++ if (page_addr != -1) { ++ this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); ++ this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); ++ /* One more address cycle for higher density devices */ ++ if (mtd->size & 0x0c000000) ++ this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f)); ++ } ++ /* Latch in address */ ++ this->hwcontrol(mtd, NAND_CTL_CLRALE); ++ } ++ ++ /* ++ * program and erase have their own busy handlers ++ * status and sequential in needs no delay ++ */ ++ switch (command) { ++ ++ case NAND_CMD_PAGEPROG: ++ /* Turn off WE */ ++ this->hwcontrol (mtd, NAND_CTL_CLRWP); ++ return; ++ ++ case NAND_CMD_SEQIN: ++ /* Turn on WE */ ++ this->hwcontrol (mtd, NAND_CTL_SETWP); ++ return; ++ ++ case NAND_CMD_ERASE1: ++ case NAND_CMD_ERASE2: ++ case NAND_CMD_STATUS: ++ return; ++ ++ case NAND_CMD_RESET: ++ if (this->dev_ready) ++ break; ++ this->hwcontrol(mtd, NAND_CTL_SETCLE); ++ this->write_byte(mtd, NAND_CMD_STATUS); ++ this->hwcontrol(mtd, NAND_CTL_CLRCLE); ++ while ( !(this->read_byte(mtd) & 0x40)); ++ return; ++ ++ /* This applies to read commands */ ++ default: ++ /* ++ * If we don't have access to the busy pin, we apply the given ++ * command delay ++ */ ++ if (!this->dev_ready) { ++ udelay (this->chip_delay); ++ return; ++ } ++ } ++ ++ /* wait until command is processed */ ++ while (!this->dev_ready(mtd)); ++} ++ ++#ifdef CONFIG_MTD_CMDLINE_PARTS ++extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partitio ++n **pparts, char *); ++#endif ++ ++/* ++ * Main initialization routine ++ */ ++extern int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); ++int __init tx4925ndfmc_init (void) ++{ ++ struct nand_chip *this; ++ int err = 0; ++ ++ /* Allocate memory for MTD device structure and private data */ ++ tx4925ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), ++ GFP_KERNEL); ++ if (!tx4925ndfmc_mtd) { ++ printk ("Unable to allocate RBTX4925 NAND MTD device structure.\n"); ++ err = -ENOMEM; ++ goto out; ++ } ++ ++ tx4925ndfmc_device_setup(); ++ ++ /* io is indirect via a register so don't need to ioremap address */ ++ ++ /* Get pointer to private data */ ++ this = (struct nand_chip *) (&tx4925ndfmc_mtd[1]); ++ ++ /* Initialize structures */ ++ memset((char *) tx4925ndfmc_mtd, 0, sizeof(struct mtd_info)); ++ memset((char *) this, 0, sizeof(struct nand_chip)); ++ ++ /* Link the private data with the MTD structure */ ++ tx4925ndfmc_mtd->priv = this; ++ ++ /* Set address of NAND IO lines */ ++ this->IO_ADDR_R = (unsigned long)&(tx4925_ndfmcptr->dtr); ++ this->IO_ADDR_W = (unsigned long)&(tx4925_ndfmcptr->dtr); ++ this->hwcontrol = tx4925ndfmc_hwcontrol; ++ this->enable_hwecc = tx4925ndfmc_enable_hwecc; ++ this->calculate_ecc = tx4925ndfmc_readecc; ++ this->correct_data = nand_correct_data; ++ this->eccmode = NAND_ECC_HW6_512; ++ this->dev_ready = tx4925ndfmc_device_ready; ++ /* 20 us command delay time */ ++ this->chip_delay = 20; ++ this->read_byte = tx4925ndfmc_nand_read_byte; ++ this->write_byte = tx4925ndfmc_nand_write_byte; ++ this->cmdfunc = tx4925ndfmc_nand_command; ++ this->write_buf = tx4925ndfmc_nand_write_buf; ++ this->read_buf = tx4925ndfmc_nand_read_buf; ++ this->verify_buf = tx4925ndfmc_nand_verify_buf; ++ ++ /* Scan to find existance of the device */ ++ if (nand_scan (tx4925ndfmc_mtd, 1)) { ++ err = -ENXIO; ++ goto out_ior; ++ } ++ ++ /* Allocate memory for internal data buffer */ ++ this->data_buf = kmalloc (sizeof(u_char) * (tx4925ndfmc_mtd->oobblock + tx4925ndfmc_mtd->oobsize), GFP_KERNEL); ++ if (!this->data_buf) { ++ printk ("Unable to allocate NAND data buffer for RBTX4925.\n"); ++ err = -ENOMEM; ++ goto out_ior; ++ } ++ ++ /* Register the partitions */ ++#ifdef CONFIG_MTD_CMDLINE_PARTS ++ { ++ int mtd_parts_nb = 0; ++ struct mtd_partition *mtd_parts = 0; ++ mtd_parts_nb = parse_cmdline_partitions(tx4925ndfmc_mtd, &mtd_parts, "tx4925ndfmc"); ++ if (mtd_parts_nb > 0) ++ add_mtd_partitions(tx4925ndfmc_mtd, mtd_parts, mtd_parts_nb); ++ else ++ add_mtd_device(tx4925ndfmc_mtd); ++ } ++#else /* ifdef CONFIG_MTD_CMDLINE_PARTS */ ++ switch(tx4925ndfmc_mtd->size){ ++ case 0x01000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info16k, NUM_PARTITIONS16K); break; ++ case 0x02000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info32k, NUM_PARTITIONS32K); break; ++ case 0x04000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info64k, NUM_PARTITIONS64K); break; ++ case 0x08000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info128k, NUM_PARTITIONS128K); break; ++ default: { ++ printk ("Unsupported SmartMedia device\n"); ++ err = -ENXIO; ++ goto out_buf; ++ } ++ } ++#endif /* ifdef CONFIG_MTD_CMDLINE_PARTS */ ++ goto out; ++ ++out_buf: ++ kfree (this->data_buf); ++out_ior: ++out: ++ return err; ++} ++ ++module_init(tx4925ndfmc_init); ++ ++/* ++ * Clean up routine ++ */ ++#ifdef MODULE ++static void __exit tx4925ndfmc_cleanup (void) ++{ ++ struct nand_chip *this = (struct nand_chip *) &tx4925ndfmc_mtd[1]; ++ ++ /* Unregister partitions */ ++ del_mtd_partitions(tx4925ndfmc_mtd); ++ ++ /* Unregister the device */ ++ del_mtd_device (tx4925ndfmc_mtd); ++ ++ /* Free internal data buffers */ ++ kfree (this->data_buf); ++ ++ /* Free the MTD device structure */ ++ kfree (tx4925ndfmc_mtd); ++} ++module_exit(tx4925ndfmc_cleanup); ++#endif ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Alice Hennessy "); ++MODULE_DESCRIPTION("Glue layer for SmartMediaCard on Toshiba RBTX4925"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/tx4938ndfmc.c linux/drivers/mtd/nand/tx4938ndfmc.c +--- linux-mips-2.4.27/drivers/mtd/nand/tx4938ndfmc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/mtd/nand/tx4938ndfmc.c 2004-11-19 10:25:12.019181552 +0100 +@@ -0,0 +1,422 @@ ++/* ++ * drivers/mtd/nand/tx4938ndfmc.c ++ * ++ * Overview: ++ * This is a device driver for the NAND flash device connected to ++ * TX4938 internal NAND Memory Controller. ++ * TX4938 NDFMC is almost same as TX4925 NDFMC, but register size are 64 bit. ++ * ++ * Author: source@mvista.com ++ * ++ * Based on spia.c by Steven J. Hill ++ * ++ * $Id: tx4938ndfmc.c,v 1.1 2003/11/04 22:59:11 ahennessy Exp $ ++ * ++ * Copyright (C) 2000-2001 Toshiba Corporation ++ * ++ * 2003 (c) MontaVista Software, Inc. This file is licensed under the ++ * terms of the GNU General Public License version 2. This program is ++ * licensed "as is" without any warranty of any kind, whether express ++ * or implied. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern struct nand_oobinfo jffs2_oobinfo; ++ ++/* ++ * MTD structure for TX4938 NDFMC ++ */ ++static struct mtd_info *tx4938ndfmc_mtd; ++ ++/* ++ * Define partitions for flash device ++ */ ++#define flush_wb() (void)tx4938_ndfmcptr->mcr; ++ ++#define NUM_PARTITIONS 3 ++#define NUMBER_OF_CIS_BLOCKS 24 ++#define SIZE_OF_BLOCK 0x00004000 ++#define NUMBER_OF_BLOCK_PER_ZONE 1024 ++#define SIZE_OF_ZONE (NUMBER_OF_BLOCK_PER_ZONE * SIZE_OF_BLOCK) ++#ifndef CONFIG_MTD_CMDLINE_PARTS ++/* ++ * You can use the following sample of MTD partitions ++ * on the NAND Flash Memory 32MB or more. ++ * ++ * The following figure shows the image of the sample partition on ++ * the 32MB NAND Flash Memory. ++ * ++ * Block No. ++ * 0 +-----------------------------+ ------ ++ * | CIS | ^ ++ * 24 +-----------------------------+ | ++ * | kernel image | | Zone 0 ++ * | | | ++ * +-----------------------------+ | ++ * 1023 | unused area | v ++ * +-----------------------------+ ------ ++ * 1024 | JFFS2 | ^ ++ * | | | ++ * | | | Zone 1 ++ * | | | ++ * | | | ++ * | | v ++ * 2047 +-----------------------------+ ------ ++ * ++ */ ++static struct mtd_partition partition_info[NUM_PARTITIONS] = { ++ { ++ .name = "RBTX4938 CIS Area", ++ .offset = 0, ++ .size = (NUMBER_OF_CIS_BLOCKS * SIZE_OF_BLOCK), ++ .mask_flags = MTD_WRITEABLE /* This partition is NOT writable */ ++ }, ++ { ++ .name = "RBTX4938 kernel image", ++ .offset = MTDPART_OFS_APPEND, ++ .size = 8 * 0x00100000, /* 8MB (Depends on size of kernel image) */ ++ .mask_flags = MTD_WRITEABLE /* This partition is NOT writable */ ++ }, ++ { ++ .name = "Root FS (JFFS2)", ++ .offset = (0 + SIZE_OF_ZONE), /* start address of next zone */ ++ .size = MTDPART_SIZ_FULL ++ }, ++}; ++#endif ++ ++static void tx4938ndfmc_hwcontrol(struct mtd_info *mtd, int cmd) ++{ ++ switch (cmd) { ++ case NAND_CTL_SETCLE: ++ tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CLE; ++ break; ++ case NAND_CTL_CLRCLE: ++ tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CLE; ++ break; ++ case NAND_CTL_SETALE: ++ tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_ALE; ++ break; ++ case NAND_CTL_CLRALE: ++ tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_ALE; ++ break; ++ /* TX4938_NDFMCR_CE bit is 0:high 1:low */ ++ case NAND_CTL_SETNCE: ++ tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CE; ++ break; ++ case NAND_CTL_CLRNCE: ++ tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CE; ++ break; ++ case NAND_CTL_SETWP: ++ tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_WE; ++ break; ++ case NAND_CTL_CLRWP: ++ tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_WE; ++ break; ++ } ++} ++static int tx4938ndfmc_dev_ready(struct mtd_info *mtd) ++{ ++ flush_wb(); ++ return !(tx4938_ndfmcptr->sr & TX4938_NDFSR_BUSY); ++} ++static void tx4938ndfmc_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) ++{ ++ u32 mcr = tx4938_ndfmcptr->mcr; ++ mcr &= ~TX4938_NDFMCR_ECC_ALL; ++ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF; ++ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_READ; ++ ecc_code[1] = tx4938_ndfmcptr->dtr; ++ ecc_code[0] = tx4938_ndfmcptr->dtr; ++ ecc_code[2] = tx4938_ndfmcptr->dtr; ++ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF; ++} ++static void tx4938ndfmc_enable_hwecc(struct mtd_info *mtd, int mode) ++{ ++ u32 mcr = tx4938_ndfmcptr->mcr; ++ mcr &= ~TX4938_NDFMCR_ECC_ALL; ++ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_RESET; ++ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF; ++ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_ON; ++} ++ ++static u_char tx4938ndfmc_nand_read_byte(struct mtd_info *mtd) ++{ ++ struct nand_chip *this = mtd->priv; ++ return tx4938_read_nfmc(this->IO_ADDR_R); ++} ++ ++static void tx4938ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte) ++{ ++ struct nand_chip *this = mtd->priv; ++ tx4938_write_nfmc(byte, this->IO_ADDR_W); ++} ++ ++static void tx4938ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++ for (i=0; iIO_ADDR_W); ++} ++ ++static void tx4938ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++ for (i=0; iIO_ADDR_R); ++} ++ ++static int tx4938ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) ++{ ++ int i; ++ struct nand_chip *this = mtd->priv; ++ ++ for (i=0; iIO_ADDR_R)) ++ return i; ++ ++ return 0; ++} ++ ++/* ++ * Send command to NAND device ++ */ ++static void tx4938ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr) ++{ ++ register struct nand_chip *this = mtd->priv; ++ ++ /* Begin command latch cycle */ ++ this->hwcontrol(mtd, NAND_CTL_SETCLE); ++ /* ++ * Write out the command to the device. ++ */ ++ if (command == NAND_CMD_SEQIN) { ++ int readcmd; ++ ++ if (column >= mtd->oobblock) { ++ /* OOB area */ ++ column -= mtd->oobblock; ++ readcmd = NAND_CMD_READOOB; ++ } else if (column < 256) { ++ /* First 256 bytes --> READ0 */ ++ readcmd = NAND_CMD_READ0; ++ } else { ++ column -= 256; ++ readcmd = NAND_CMD_READ1; ++ } ++ this->write_byte(mtd, readcmd); ++ } ++ this->write_byte(mtd, command); ++ ++ /* Set ALE and clear CLE to start address cycle */ ++ this->hwcontrol(mtd, NAND_CTL_CLRCLE); ++ ++ if (column != -1 || page_addr != -1) { ++ this->hwcontrol(mtd, NAND_CTL_SETALE); ++ ++ /* Serially input address */ ++ if (column != -1) ++ this->write_byte(mtd, column); ++ if (page_addr != -1) { ++ this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); ++ this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); ++ /* One more address cycle for higher density devices */ ++ if (mtd->size & 0x0c000000) ++ this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f)); ++ } ++ /* Latch in address */ ++ this->hwcontrol(mtd, NAND_CTL_CLRALE); ++ } ++ ++ /* ++ * program and erase have their own busy handlers ++ * status and sequential in needs no delay ++ */ ++ switch (command) { ++ ++ case NAND_CMD_PAGEPROG: ++ /* Turn off WE */ ++ this->hwcontrol (mtd, NAND_CTL_CLRWP); ++ return; ++ ++ case NAND_CMD_SEQIN: ++ /* Turn on WE */ ++ this->hwcontrol (mtd, NAND_CTL_SETWP); ++ return; ++ ++ case NAND_CMD_ERASE1: ++ case NAND_CMD_ERASE2: ++ case NAND_CMD_STATUS: ++ return; ++ ++ case NAND_CMD_RESET: ++ if (this->dev_ready) ++ break; ++ this->hwcontrol(mtd, NAND_CTL_SETCLE); ++ this->write_byte(mtd, NAND_CMD_STATUS); ++ this->hwcontrol(mtd, NAND_CTL_CLRCLE); ++ while ( !(this->read_byte(mtd) & 0x40)); ++ return; ++ ++ /* This applies to read commands */ ++ default: ++ /* ++ * If we don't have access to the busy pin, we apply the given ++ * command delay ++ */ ++ if (!this->dev_ready) { ++ udelay (this->chip_delay); ++ return; ++ } ++ } ++ ++ /* wait until command is processed */ ++ while (!this->dev_ready(mtd)); ++} ++ ++#ifdef CONFIG_MTD_CMDLINE_PARTS ++extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *); ++#endif ++/* ++ * Main initialization routine ++ */ ++int __init tx4938ndfmc_init (void) ++{ ++ struct nand_chip *this; ++ int bsprt = 0, hold = 0xf, spw = 0xf; ++ int protected = 0; ++ ++ if ((*rbtx4938_piosel_ptr & 0x0c) != 0x08) { ++ printk("TX4938 NDFMC: disabled by IOC PIOSEL\n"); ++ return -ENODEV; ++ } ++ bsprt = 1; ++ hold = 2; ++ spw = 9 - 1; /* 8 GBUSCLK = 80ns (@ GBUSCLK 100MHz) */ ++ ++ if ((tx4938_ccfgptr->pcfg & ++ (TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL)) ++ != TX4938_PCFG_NDF_SEL) { ++ printk("TX4938 NDFMC: disabled by PCFG.\n"); ++ return -ENODEV; ++ } ++ ++ /* reset NDFMC */ ++ tx4938_ndfmcptr->rstr |= TX4938_NDFRSTR_RST; ++ while (tx4938_ndfmcptr->rstr & TX4938_NDFRSTR_RST) ++ ; ++ /* setup BusSeparete, Hold Time, Strobe Pulse Width */ ++ tx4938_ndfmcptr->mcr = bsprt ? TX4938_NDFMCR_BSPRT : 0; ++ tx4938_ndfmcptr->spr = hold << 4 | spw; ++ ++ /* Allocate memory for MTD device structure and private data */ ++ tx4938ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), ++ GFP_KERNEL); ++ if (!tx4938ndfmc_mtd) { ++ printk ("Unable to allocate TX4938 NDFMC MTD device structure.\n"); ++ return -ENOMEM; ++ } ++ ++ /* Get pointer to private data */ ++ this = (struct nand_chip *) (&tx4938ndfmc_mtd[1]); ++ ++ /* Initialize structures */ ++ memset((char *) tx4938ndfmc_mtd, 0, sizeof(struct mtd_info)); ++ memset((char *) this, 0, sizeof(struct nand_chip)); ++ ++ /* Link the private data with the MTD structure */ ++ tx4938ndfmc_mtd->priv = this; ++ ++ /* Set address of NAND IO lines */ ++ this->IO_ADDR_R = (unsigned long)&tx4938_ndfmcptr->dtr; ++ this->IO_ADDR_W = (unsigned long)&tx4938_ndfmcptr->dtr; ++ this->hwcontrol = tx4938ndfmc_hwcontrol; ++ this->dev_ready = tx4938ndfmc_dev_ready; ++ this->calculate_ecc = tx4938ndfmc_calculate_ecc; ++ this->correct_data = nand_correct_data; ++ this->enable_hwecc = tx4938ndfmc_enable_hwecc; ++ this->eccmode = NAND_ECC_HW3_256; ++ this->chip_delay = 100; ++ this->read_byte = tx4938ndfmc_nand_read_byte; ++ this->write_byte = tx4938ndfmc_nand_write_byte; ++ this->cmdfunc = tx4938ndfmc_nand_command; ++ this->write_buf = tx4938ndfmc_nand_write_buf; ++ this->read_buf = tx4938ndfmc_nand_read_buf; ++ this->verify_buf = tx4938ndfmc_nand_verify_buf; ++ ++ /* Scan to find existance of the device */ ++ if (nand_scan (tx4938ndfmc_mtd, 1)) { ++ kfree (tx4938ndfmc_mtd); ++ return -ENXIO; ++ } ++ ++ /* Allocate memory for internal data buffer */ ++ this->data_buf = kmalloc (sizeof(u_char) * (tx4938ndfmc_mtd->oobblock + tx4938ndfmc_mtd->oobsize), GFP_KERNEL); ++ if (!this->data_buf) { ++ printk ("Unable to allocate NAND data buffer for TX4938.\n"); ++ kfree (tx4938ndfmc_mtd); ++ return -ENOMEM; ++ } ++ ++ if (protected) { ++ printk(KERN_INFO "TX4938 NDFMC: write protected.\n"); ++ tx4938ndfmc_mtd->flags &= ~(MTD_WRITEABLE | MTD_ERASEABLE); ++ } ++ ++#ifdef CONFIG_MTD_CMDLINE_PARTS ++ { ++ int mtd_parts_nb = 0; ++ struct mtd_partition *mtd_parts = 0; ++ mtd_parts_nb = parse_cmdline_partitions(tx4938ndfmc_mtd, &mtd_parts, "tx4938ndfmc"); ++ if (mtd_parts_nb > 0) ++ add_mtd_partitions(tx4938ndfmc_mtd, mtd_parts, mtd_parts_nb); ++ else ++ add_mtd_device(tx4938ndfmc_mtd); ++ } ++#else ++ add_mtd_partitions(tx4938ndfmc_mtd, partition_info, NUM_PARTITIONS ); ++#endif ++ ++ return 0; ++} ++module_init(tx4938ndfmc_init); ++ ++/* ++ * Clean up routine ++ */ ++static void __exit tx4938ndfmc_cleanup (void) ++{ ++ struct nand_chip *this = (struct nand_chip *) tx4938ndfmc_mtd->priv; ++ ++ /* Unregister the device */ ++#ifdef CONFIG_MTD_CMDLINE_PARTS ++ del_mtd_partitions(tx4938ndfmc_mtd); ++#endif ++ del_mtd_device (tx4938ndfmc_mtd); ++ ++ /* Free the MTD device structure */ ++ kfree (tx4938ndfmc_mtd); ++ ++ /* Free internal data buffer */ ++ kfree (this->data_buf); ++} ++module_exit(tx4938ndfmc_cleanup); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Alice Hennessy "); ++MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on TX4938 NDFMC"); +diff -Nurb linux-mips-2.4.27/drivers/mtd/nftlcore.c linux/drivers/mtd/nftlcore.c +--- linux-mips-2.4.27/drivers/mtd/nftlcore.c 2003-02-26 01:53:49.000000000 +0100 ++++ linux/drivers/mtd/nftlcore.c 2004-11-19 10:25:11.653237184 +0100 +@@ -1,7 +1,7 @@ + /* Linux driver for NAND Flash Translation Layer */ + /* (c) 1999 Machine Vision Holdings, Inc. */ + /* Author: David Woodhouse */ +-/* $Id: nftlcore.c,v 1.87 2002/09/13 14:35:33 dwmw2 Exp $ */ ++/* $Id: nftlcore.c,v 1.94 2003/06/23 12:00:08 dwmw2 Exp $ */ + + /* + The contents of this file are distributed under the GNU General +@@ -23,15 +23,13 @@ + #include + #include + #include +-#include ++#include + +-#ifdef CONFIG_KMOD + #include +-#endif + #include + #include + #include +-#include ++#include + + /* maximum number of loops while examining next block, to have a + chance to detect consistency problems (they should never happen +@@ -39,187 +37,95 @@ + + #define MAX_LOOPS 10000 + +-/* NFTL block device stuff */ +-#define MAJOR_NR NFTL_MAJOR +-#define DEVICE_REQUEST nftl_request +-#define DEVICE_OFF(device) +- +- +-#include +-#include +- +-/* Linux-specific block device functions */ +- +-/* I _HATE_ the Linux block device setup more than anything else I've ever +- * encountered, except ... +- */ +- +-static int nftl_sizes[256]; +-static int nftl_blocksizes[256]; +- +-/* .. for the Linux partition table handling. */ +-struct hd_struct part_table[256]; +- +-#if LINUX_VERSION_CODE < 0x20328 +-static void dummy_init (struct gendisk *crap) +-{} +-#endif +- +-static struct gendisk nftl_gendisk = { +- major: MAJOR_NR, +- major_name: "nftl", +- minor_shift: NFTL_PARTN_BITS, /* Bits to shift to get real from partition */ +- max_p: (1<mtd == mtd) { +- /* This is a Spare Media Header for an NFTL we've already found */ +- DEBUG(MTD_DEBUG_LEVEL1, "MTD already mounted as NFTL\n"); ++ if (mtd->ecctype != MTD_ECC_RS_DiskOnChip) + return; +- } +- } +- if (firstfree == -1) { +- printk(KERN_WARNING "No more NFTL slot available\n"); +- return; +- } ++ ++ DEBUG(MTD_DEBUG_LEVEL1, "NFTL: add_mtd for %s\n", mtd->name); + + nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL); ++ + if (!nftl) { +- printk(KERN_WARNING "Out of memory for NFTL data structures\n"); ++ printk(KERN_WARNING "NFTL: out of memory for data structures\n"); + return; + } ++ memset(nftl, 0, sizeof(*nftl)); + +- init_MUTEX(&nftl->mutex); +- +- nftl->mtd = mtd; ++ nftl->mbd.mtd = mtd; ++ nftl->mbd.devnum = -1; ++ nftl->mbd.blksize = 512; ++ nftl->mbd.tr = tr; + + if (NFTL_mount(nftl) < 0) { +- printk(KERN_WARNING "Could not mount NFTL device\n"); ++ printk(KERN_WARNING "NFTL: could not mount device\n"); + kfree(nftl); + return; + } + + /* OK, it's a new one. Set up all the data structures. */ +-#ifdef PSYCHO_DEBUG +- printk("Found new NFTL nftl%c\n", firstfree + 'a'); +-#endif + +- /* linux stuff */ +- nftl->usecount = 0; ++ /* Calculate geometry */ + nftl->cylinders = 1024; + nftl->heads = 16; + + temp = nftl->cylinders * nftl->heads; +- nftl->sectors = nftl->nr_sects / temp; +- if (nftl->nr_sects % temp) { ++ nftl->sectors = nftl->mbd.size / temp; ++ if (nftl->mbd.size % temp) { + nftl->sectors++; + temp = nftl->cylinders * nftl->sectors; +- nftl->heads = nftl->nr_sects / temp; ++ nftl->heads = nftl->mbd.size / temp; + +- if (nftl->nr_sects % temp) { ++ if (nftl->mbd.size % temp) { + nftl->heads++; + temp = nftl->heads * nftl->sectors; +- nftl->cylinders = nftl->nr_sects / temp; ++ nftl->cylinders = nftl->mbd.size / temp; + } + } + +- if (nftl->nr_sects != nftl->heads * nftl->cylinders * nftl->sectors) { +- printk(KERN_WARNING "Cannot calculate an NFTL geometry to " +- "match size of 0x%x.\n", nftl->nr_sects); +- printk(KERN_WARNING "Using C:%d H:%d S:%d (== 0x%lx sects)\n", ++ if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) { ++ /* ++ Oh no we don't have ++ mbd.size == heads * cylinders * sectors ++ */ ++ printk(KERN_WARNING "NFTL: cannot calculate a geometry to " ++ "match size of 0x%lx.\n", nftl->mbd.size); ++ printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d " ++ "(== 0x%lx sects)\n", + nftl->cylinders, nftl->heads , nftl->sectors, +- (long)nftl->cylinders * (long)nftl->heads * (long)nftl->sectors ); +- +- /* Oh no we don't have nftl->nr_sects = nftl->heads * nftl->cylinders * nftl->sectors; */ ++ (long)nftl->cylinders * (long)nftl->heads * ++ (long)nftl->sectors ); + } +- NFTLs[firstfree] = nftl; +- /* Finally, set up the block device sizes */ +- nftl_sizes[firstfree * 16] = nftl->nr_sects; +- //nftl_blocksizes[firstfree*16] = 512; +- part_table[firstfree * 16].nr_sects = nftl->nr_sects; +- +- nftl_gendisk.nr_real++; +- +- /* partition check ... */ +-#if LINUX_VERSION_CODE < 0x20328 +- resetup_one_dev(&nftl_gendisk, firstfree); +-#else +- grok_partitions(&nftl_gendisk, firstfree, 1<nr_sects); +-#endif +-} +- +-static void NFTL_unsetup(int i) +-{ +- struct NFTLrecord *nftl = NFTLs[i]; +- +- DEBUG(MTD_DEBUG_LEVEL1, "NFTL_unsetup %d\n", i); +- +- NFTLs[i] = NULL; + ++ if (add_mtd_blktrans_dev(&nftl->mbd)) { + if (nftl->ReplUnitTable) + kfree(nftl->ReplUnitTable); + if (nftl->EUNtable) + kfree(nftl->EUNtable); +- +- nftl_gendisk.nr_real--; + kfree(nftl); +-} +- +-/* Search the MTD device for NFTL partitions */ +-static void NFTL_notify_add(struct mtd_info *mtd) +-{ +- DEBUG(MTD_DEBUG_LEVEL1, "NFTL_notify_add for %s\n", mtd->name); +- +- if (mtd) { +- if (!mtd->read_oob) { +- /* If this MTD doesn't have out-of-band data, +- then there's no point continuing */ +- DEBUG(MTD_DEBUG_LEVEL1, "No OOB data, quitting\n"); + return; + } +- DEBUG(MTD_DEBUG_LEVEL3, "mtd->read = %p, size = %d, erasesize = %d\n", +- mtd->read, mtd->size, mtd->erasesize); +- +- NFTL_setup(mtd); +- } ++#ifdef PSYCHO_DEBUG ++ printk(KERN_INFO "NFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a'); ++#endif + } + +-static void NFTL_notify_remove(struct mtd_info *mtd) ++static void nftl_remove_dev(struct mtd_blktrans_dev *dev) + { +- int i; ++ struct NFTLrecord *nftl = (void *)dev; + +- for (i = 0; i < MAX_NFTLS; i++) { +- if (NFTLs[i] && NFTLs[i]->mtd == mtd) +- NFTL_unsetup(i); +- } ++ DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum); ++ ++ del_mtd_blktrans_dev(dev); ++ if (nftl->ReplUnitTable) ++ kfree(nftl->ReplUnitTable); ++ if (nftl->EUNtable) ++ kfree(nftl->EUNtable); ++ kfree(nftl); + } + + #ifdef CONFIG_NFTL_RW +@@ -303,7 +209,7 @@ + + targetEUN = thisEUN; + for (block = 0; block < nftl->EraseSize / 512; block ++) { +- MTD_READOOB(nftl->mtd, ++ MTD_READOOB(nftl->mbd.mtd, + (thisEUN * nftl->EraseSize) + (block * 512), + 16 , &retlen, (char *)&oob); + if (block == 2) { +@@ -420,7 +326,7 @@ + chain by selecting the longer one */ + oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS); + oob.u.c.unused = 0xffffffff; +- MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, ++ MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, + 8, &retlen, (char *)&oob.u); + } + +@@ -444,16 +350,16 @@ + if (BlockMap[block] == BLOCK_NIL) + continue; + +- ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512), ++ ret = MTD_READECC(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512), + 512, &retlen, movebuf, (char *)&oob, NAND_ECC_DISKONCHIP); + if (ret < 0) { +- ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block]) ++ ret = MTD_READECC(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + + (block * 512), 512, &retlen, + movebuf, (char *)&oob, NAND_ECC_DISKONCHIP); + if (ret != -EIO) + printk("Error went away on retry.\n"); + } +- MTD_WRITEECC(nftl->mtd, (nftl->EraseSize * targetEUN) + (block * 512), ++ MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512), + 512, &retlen, movebuf, (char *)&oob, NAND_ECC_DISKONCHIP); + } + +@@ -462,7 +368,7 @@ + = cpu_to_le16(thisVUC); + oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff; + +- MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 8, ++ MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8, + 8, &retlen, (char *)&oob.u); + + /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */ +@@ -582,7 +488,7 @@ + + lastEUN = writeEUN; + +- MTD_READOOB(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs, ++ MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs, + 8, &retlen, (char *)&bci); + + DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n", +@@ -670,12 +576,12 @@ + nftl->ReplUnitTable[writeEUN] = BLOCK_NIL; + + /* ... and on the flash itself */ +- MTD_READOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8, ++ MTD_READOOB(nftl->mbd.mtd, writeEUN * nftl->EraseSize + 8, 8, + &retlen, (char *)&oob.u); + + oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC); + +- MTD_WRITEOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8, ++ MTD_WRITEOOB(nftl->mbd.mtd, writeEUN * nftl->EraseSize + 8, 8, + &retlen, (char *)&oob.u); + + /* we link the new block to the chain only after the +@@ -685,13 +591,13 @@ + /* Both in our cache... */ + nftl->ReplUnitTable[lastEUN] = writeEUN; + /* ... and on the flash itself */ +- MTD_READOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8, ++ MTD_READOOB(nftl->mbd.mtd, (lastEUN * nftl->EraseSize) + 8, + 8, &retlen, (char *)&oob.u); + + oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum + = cpu_to_le16(writeEUN); + +- MTD_WRITEOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8, ++ MTD_WRITEOOB(nftl->mbd.mtd, (lastEUN * nftl->EraseSize) + 8, + 8, &retlen, (char *)&oob.u); + } + +@@ -704,8 +610,10 @@ + return 0xffff; + } + +-static int NFTL_writeblock(struct NFTLrecord *nftl, unsigned block, char *buffer) ++static int nftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block, ++ char *buffer) + { ++ struct NFTLrecord *nftl = (void *)mbd; + u16 writeEUN; + unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1); + size_t retlen; +@@ -720,7 +628,7 @@ + return 1; + } + +- MTD_WRITEECC(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs, ++ MTD_WRITEECC(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs, + 512, &retlen, (char *)buffer, (char *)eccbuf, NAND_ECC_DISKONCHIP); + /* no need to write SECTOR_USED flags since they are written in mtd_writeecc */ + +@@ -728,8 +636,10 @@ + } + #endif /* CONFIG_NFTL_RW */ + +-static int NFTL_readblock(struct NFTLrecord *nftl, unsigned block, char *buffer) ++static int nftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block, ++ char *buffer) + { ++ struct NFTLrecord *nftl = (void *)mbd; + u16 lastgoodEUN; + u16 thisEUN = nftl->EUNtable[block / (nftl->EraseSize / 512)]; + unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1); +@@ -742,7 +652,7 @@ + + if (thisEUN != BLOCK_NIL) { + while (thisEUN < nftl->nb_blocks) { +- if (MTD_READOOB(nftl->mtd, (thisEUN * nftl->EraseSize) + blockofs, ++ if (MTD_READOOB(nftl->mbd.mtd, (thisEUN * nftl->EraseSize) + blockofs, + 8, &retlen, (char *)&bci) < 0) + status = SECTOR_IGNORE; + else +@@ -761,13 +671,13 @@ + case SECTOR_IGNORE: + break; + default: +- printk("Unknown status for block %d in EUN %d: %x\n", ++ printk("Unknown status for block %ld in EUN %d: %x\n", + block, thisEUN, status); + break; + } + + if (!silly--) { +- printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n", ++ printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%lx\n", + block / (nftl->EraseSize / 512)); + return 1; + } +@@ -783,264 +693,22 @@ + loff_t ptr = (lastgoodEUN * nftl->EraseSize) + blockofs; + size_t retlen; + u_char eccbuf[6]; +- if (MTD_READECC(nftl->mtd, ptr, 512, &retlen, buffer, eccbuf, NAND_ECC_DISKONCHIP)) ++ if (MTD_READECC(nftl->mbd.mtd, ptr, 512, &retlen, buffer, eccbuf, NAND_ECC_DISKONCHIP)) + return -EIO; + } + return 0; + } + +-static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) +-{ +- struct NFTLrecord *nftl; +- int p; +- +- nftl = NFTLs[MINOR(inode->i_rdev) >> NFTL_PARTN_BITS]; +- +- if (!nftl) return -EINVAL; +- +- switch (cmd) { +- case HDIO_GETGEO: { +- struct hd_geometry g; +- +- g.heads = nftl->heads; +- g.sectors = nftl->sectors; +- g.cylinders = nftl->cylinders; +- g.start = part_table[MINOR(inode->i_rdev)].start_sect; +- return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0; +- } +- case BLKGETSIZE: /* Return device size */ +- return put_user(part_table[MINOR(inode->i_rdev)].nr_sects, +- (unsigned long *) arg); +- +-#ifdef BLKGETSIZE64 +- case BLKGETSIZE64: +- return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9, +- (u64 *)arg); +-#endif +- +- case BLKFLSBUF: +- if (!capable(CAP_SYS_ADMIN)) return -EACCES; +- fsync_dev(inode->i_rdev); +- invalidate_buffers(inode->i_rdev); +- if (nftl->mtd->sync) +- nftl->mtd->sync(nftl->mtd); +- return 0; +- +- case BLKRRPART: +- if (!capable(CAP_SYS_ADMIN)) return -EACCES; +- if (nftl->usecount > 1) return -EBUSY; +- /* +- * We have to flush all buffers and invalidate caches, +- * or we won't be able to re-use the partitions, +- * if there was a change and we don't want to reboot +- */ +- p = (1< 0) { +- kdev_t devp = MKDEV(MAJOR(inode->i_dev), MINOR(inode->i_dev)+p); +- if (part_table[p].nr_sects > 0) +- invalidate_device (devp, 1); +- +- part_table[MINOR(inode->i_dev)+p].start_sect = 0; +- part_table[MINOR(inode->i_dev)+p].nr_sects = 0; +- } +- +-#if LINUX_VERSION_CODE < 0x20328 +- resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS); +-#else +- grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS, +- 1<nr_sects); +-#endif +- return 0; +- +-#if (LINUX_VERSION_CODE < 0x20303) +- RO_IOCTLS(inode->i_rdev, arg); /* ref. linux/blk.h */ +-#else +- case BLKROSET: +- case BLKROGET: +- case BLKSSZGET: +- return blk_ioctl(inode->i_rdev, cmd, arg); +-#endif +- +- default: +- return -EINVAL; +- } +-} +- +-void nftl_request(RQFUNC_ARG) +-{ +- unsigned int dev, block, nsect; +- struct NFTLrecord *nftl; +- char *buffer; +- struct request *req; +- int res; +- +- while (1) { +- INIT_REQUEST; /* blk.h */ +- req = CURRENT; +- +- /* We can do this because the generic code knows not to +- touch the request at the head of the queue */ +- spin_unlock_irq(&io_request_lock); +- +- DEBUG(MTD_DEBUG_LEVEL2, "NFTL_request\n"); +- DEBUG(MTD_DEBUG_LEVEL3, "NFTL %s request, from sector 0x%04lx for 0x%04lx sectors\n", +- (req->cmd == READ) ? "Read " : "Write", +- req->sector, req->current_nr_sectors); +- +- dev = MINOR(req->rq_dev); +- block = req->sector; +- nsect = req->current_nr_sectors; +- buffer = req->buffer; +- res = 1; /* succeed */ +- +- if (dev >= MAX_NFTLS * (1<rq_dev)); +- res = 0; /* fail */ +- goto repeat; +- } +- +- nftl = NFTLs[dev / (1<mutex); +- DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n"); +- +- if (block + nsect > part_table[dev].nr_sects) { +- /* access past the end of device */ +- printk("nftl%c%d: bad access: block = %d, count = %d\n", +- (MINOR(req->rq_dev)>>6)+'a', dev & 0xf, block, nsect); +- up(&nftl->mutex); +- res = 0; /* fail */ +- goto repeat; +- } +- +- block += part_table[dev].start_sect; +- +- if (req->cmd == READ) { +- DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request of 0x%x sectors @ %x " +- "(req->nr_sectors == %lx)\n", nsect, block, req->nr_sectors); +- +- for ( ; nsect > 0; nsect-- , block++, buffer += 512) { +- /* Read a single sector to req->buffer + (512 * i) */ +- if (NFTL_readblock(nftl, block, buffer)) { +- DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request failed\n"); +- up(&nftl->mutex); +- res = 0; +- goto repeat; +- } +- } +- +- DEBUG(MTD_DEBUG_LEVEL2,"NFTL read request completed OK\n"); +- up(&nftl->mutex); +- goto repeat; +- } else if (req->cmd == WRITE) { +- DEBUG(MTD_DEBUG_LEVEL2, "NFTL write request of 0x%x sectors @ %x " +- "(req->nr_sectors == %lx)\n", nsect, block, +- req->nr_sectors); +-#ifdef CONFIG_NFTL_RW +- for ( ; nsect > 0; nsect-- , block++, buffer += 512) { +- /* Read a single sector to req->buffer + (512 * i) */ +- if (NFTL_writeblock(nftl, block, buffer)) { +- DEBUG(MTD_DEBUG_LEVEL1,"NFTL write request failed\n"); +- up(&nftl->mutex); +- res = 0; +- goto repeat; +- } +- } +- DEBUG(MTD_DEBUG_LEVEL2,"NFTL write request completed OK\n"); +-#else +- res = 0; /* Writes always fail */ +-#endif /* CONFIG_NFTL_RW */ +- up(&nftl->mutex); +- goto repeat; +- } else { +- DEBUG(MTD_DEBUG_LEVEL0, "NFTL unknown request\n"); +- up(&nftl->mutex); +- res = 0; +- goto repeat; +- } +- repeat: +- DEBUG(MTD_DEBUG_LEVEL3, "end_request(%d)\n", res); +- spin_lock_irq(&io_request_lock); +- end_request(res); +- } +-} +- +-static int nftl_open(struct inode *ip, struct file *fp) +-{ +- int nftlnum = MINOR(ip->i_rdev) >> NFTL_PARTN_BITS; +- struct NFTLrecord *thisNFTL; +- thisNFTL = NFTLs[nftlnum]; +- +- DEBUG(MTD_DEBUG_LEVEL2,"NFTL_open\n"); +- +-#ifdef CONFIG_KMOD +- if (!thisNFTL && nftlnum == 0) { +- request_module("docprobe"); +- thisNFTL = NFTLs[nftlnum]; +- } +-#endif +- if (!thisNFTL) { +- DEBUG(MTD_DEBUG_LEVEL2,"ENODEV: thisNFTL = %d, minor = %d, ip = %p, fp = %p\n", +- nftlnum, ip->i_rdev, ip, fp); +- return -ENODEV; +- } +- +-#ifndef CONFIG_NFTL_RW +- if (fp->f_mode & FMODE_WRITE) +- return -EROFS; +-#endif /* !CONFIG_NFTL_RW */ +- +- thisNFTL->usecount++; +- BLK_INC_USE_COUNT; +- if (!get_mtd_device(thisNFTL->mtd, -1)) { +- BLK_DEC_USE_COUNT; +- return -ENXIO; +- } +- +- return 0; +-} +- +-static int nftl_release(struct inode *inode, struct file *fp) ++static int nftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo) + { +- struct NFTLrecord *thisNFTL; +- +- thisNFTL = NFTLs[MINOR(inode->i_rdev) / 16]; +- +- DEBUG(MTD_DEBUG_LEVEL2, "NFTL_release\n"); +- +- if (thisNFTL->mtd->sync) +- thisNFTL->mtd->sync(thisNFTL->mtd); +- thisNFTL->usecount--; +- BLK_DEC_USE_COUNT; ++ struct NFTLrecord *nftl = (void *)dev; + +- put_mtd_device(thisNFTL->mtd); ++ geo->heads = nftl->heads; ++ geo->sectors = nftl->sectors; ++ geo->cylinders = nftl->cylinders; + + return 0; + } +-#if LINUX_VERSION_CODE < 0x20326 +-static struct file_operations nftl_fops = { +- read: block_read, +- write: block_write, +- ioctl: nftl_ioctl, +- open: nftl_open, +- release: nftl_release, +- fsync: block_fsync, +-}; +-#else +-static struct block_device_operations nftl_fops = +-{ +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14) +- owner: THIS_MODULE, +-#endif +- open: nftl_open, +- release: nftl_release, +- ioctl: nftl_ioctl +-}; +-#endif +- +- + + /**************************************************************************** + * +@@ -1048,49 +716,33 @@ + * + ****************************************************************************/ + +-static struct mtd_notifier nftl_notifier = { +- add: NFTL_notify_add, +- remove: NFTL_notify_remove ++ ++struct mtd_blktrans_ops nftl_tr = { ++ .name = "nftl", ++ .major = NFTL_MAJOR, ++ .part_bits = NFTL_PARTN_BITS, ++ .getgeo = nftl_getgeo, ++ .readsect = nftl_readblock, ++#ifdef CONFIG_NFTL_RW ++ .writesect = nftl_writeblock, ++#endif ++ .add_mtd = nftl_add_mtd, ++ .remove_dev = nftl_remove_dev, ++ .owner = THIS_MODULE, + }; + + extern char nftlmountrev[]; + + int __init init_nftl(void) + { +- int i; +- +-#ifdef PRERELEASE +- printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.87 $, nftlmount.c %s\n", nftlmountrev); +-#endif +- +- if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)){ +- printk("unable to register NFTL block device on major %d\n", MAJOR_NR); +- return -EBUSY; +- } else { +- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &nftl_request); ++ printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.94 $, nftlmount.c %s\n", nftlmountrev); + +- /* set block size to 1kB each */ +- for (i = 0; i < 256; i++) { +- nftl_blocksizes[i] = 1024; +- } +- blksize_size[MAJOR_NR] = nftl_blocksizes; +- +- add_gendisk(&nftl_gendisk); +- } +- +- register_mtd_user(&nftl_notifier); +- +- return 0; ++ return register_mtd_blktrans(&nftl_tr); + } + + static void __exit cleanup_nftl(void) + { +- unregister_mtd_user(&nftl_notifier); +- unregister_blkdev(MAJOR_NR, "nftl"); +- +- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); +- +- del_gendisk(&nftl_gendisk); ++ deregister_mtd_blktrans(&nftl_tr); + } + + module_init(init_nftl); +diff -Nurb linux-mips-2.4.27/drivers/mtd/nftlmount.c linux/drivers/mtd/nftlmount.c +--- linux-mips-2.4.27/drivers/mtd/nftlmount.c 2003-07-05 05:23:38.000000000 +0200 ++++ linux/drivers/mtd/nftlmount.c 2004-11-19 10:25:11.655236880 +0100 +@@ -4,7 +4,7 @@ + * Author: Fabrice Bellard (fabrice.bellard@netgem.com) + * Copyright (C) 2000 Netgem S.A. + * +- * $Id: nftlmount.c,v 1.31 2002/11/15 16:34:43 dwmw2 Exp $ ++ * $Id: nftlmount.c,v 1.34 2003/05/21 10:54:10 dwmw2 Exp $ + * + * 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 +@@ -21,26 +21,17 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +-#define __NO_VERSION__ + #include +-#include + #include +-#include +-#include +-#include +-#include + #include + #include +-#include +-#include + #include + #include + #include +-#include + + #define SECTORSIZE 512 + +-char nftlmountrev[]="$Revision: 1.31 $"; ++char nftlmountrev[]="$Revision: 1.34 $"; + + /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the + * various device information of the NFTL partition and Bad Unit Table. Update +@@ -59,8 +50,8 @@ + + /* Assume logical EraseSize == physical erasesize for starting the scan. + We'll sort it out later if we find a MediaHeader which says otherwise */ +- nftl->EraseSize = nftl->mtd->erasesize; +- nftl->nb_blocks = nftl->mtd->size / nftl->EraseSize; ++ nftl->EraseSize = nftl->mbd.mtd->erasesize; ++ nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize; + + nftl->MediaUnit = BLOCK_NIL; + nftl->SpareMediaUnit = BLOCK_NIL; +@@ -71,12 +62,12 @@ + + /* Check for ANAND header first. Then can whinge if it's found but later + checks fail */ +- if ((ret = MTD_READ(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf))) { ++ if ((ret = MTD_READ(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf))) { + static int warncount = 5; + + if (warncount) { + printk(KERN_WARNING "Block read at 0x%x of mtd%d failed: %d\n", +- block * nftl->EraseSize, nftl->mtd->index, ret); ++ block * nftl->EraseSize, nftl->mbd.mtd->index, ret); + if (!--warncount) + printk(KERN_WARNING "Further failures for this block will not be printed\n"); + } +@@ -87,16 +78,16 @@ + /* ANAND\0 not found. Continue */ + #if 0 + printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n", +- block * nftl->EraseSize, nftl->mtd->index); ++ block * nftl->EraseSize, nftl->mbd.mtd->index); + #endif + continue; + } + + /* To be safer with BIOS, also use erase mark as discriminant */ +- if ((ret = MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, +- 8, &retlen, (char *)&h1)) < 0) { ++ if ((ret = MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, ++ 8, &retlen, (char *)&h1) < 0)) { + printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n", +- block * nftl->EraseSize, nftl->mtd->index, ret); ++ block * nftl->EraseSize, nftl->mbd.mtd->index, ret); + continue; + } + +@@ -106,23 +97,23 @@ + */ + if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) { + printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n", +- block * nftl->EraseSize, nftl->mtd->index, ++ block * nftl->EraseSize, nftl->mbd.mtd->index, + le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1)); + continue; + } + + /* Finally reread to check ECC */ +- if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, +- &retlen, buf, (char *)&oob, NAND_ECC_DISKONCHIP)) < 0) { ++ if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, ++ &retlen, buf, (char *)&oob, NAND_ECC_DISKONCHIP) < 0)) { + printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n", +- block * nftl->EraseSize, nftl->mtd->index, ret); ++ block * nftl->EraseSize, nftl->mbd.mtd->index, ret); + continue; + } + + /* Paranoia. Check the ANAND header is still there after the ECC read */ + if (memcmp(buf, "ANAND", 6)) { + printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but went away on reread!\n", +- block * nftl->EraseSize, nftl->mtd->index); ++ block * nftl->EraseSize, nftl->mbd.mtd->index); + printk(KERN_NOTICE "New data are: %02x %02x %02x %02x %02x %02x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + continue; +@@ -137,8 +128,12 @@ + printk(KERN_NOTICE "NFTL Media Headers at 0x%x and 0x%x disagree.\n", + nftl->MediaUnit * nftl->EraseSize, block * nftl->EraseSize); + /* if (debug) Print both side by side */ ++ if (boot_record_count < 2) { ++ /* We haven't yet seen two real ones */ + return -1; + } ++ continue; ++ } + if (boot_record_count == 1) + nftl->SpareMediaUnit = block; + +@@ -163,8 +158,8 @@ + } else if (mh->UnitSizeFactor != 0xff) { + printk(KERN_NOTICE "WARNING: Support for NFTL with UnitSizeFactor 0x%02x is experimental\n", + mh->UnitSizeFactor); +- nftl->EraseSize = nftl->mtd->erasesize << (0xff - mh->UnitSizeFactor); +- nftl->nb_blocks = nftl->mtd->size / nftl->EraseSize; ++ nftl->EraseSize = nftl->mbd.mtd->erasesize << (0xff - mh->UnitSizeFactor); ++ nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize; + } + nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN); + if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) { +@@ -182,7 +177,7 @@ + return -1; + } + +- nftl->nr_sects = nftl->numvunits * (nftl->EraseSize / SECTORSIZE); ++ nftl->mbd.size = nftl->numvunits * (nftl->EraseSize / SECTORSIZE); + + /* If we're not using the last sectors in the device for some reason, + reduce nb_blocks accordingly so we forget they're there */ +@@ -220,7 +215,7 @@ + for (i = 0; i < nftl->nb_blocks; i++) { + if ((i & (SECTORSIZE - 1)) == 0) { + /* read one sector for every SECTORSIZE of blocks */ +- if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize + ++ if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize + + i + SECTORSIZE, SECTORSIZE, &retlen, buf, + (char *)&oob, NAND_ECC_DISKONCHIP)) < 0) { + printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n", +@@ -263,16 +258,16 @@ + for (i = 0; i < len; i += SECTORSIZE) { + /* we want to read the sector without ECC check here since a free + sector does not have ECC syndrome on it yet */ +- if (MTD_READ(nftl->mtd, address, SECTORSIZE, &retlen, buf) < 0) ++ if (MTD_READ(nftl->mbd.mtd, address, SECTORSIZE, &retlen, buf) < 0) + return -1; + if (memcmpb(buf, 0xff, SECTORSIZE) != 0) + return -1; + + if (check_oob) { +- if (MTD_READOOB(nftl->mtd, address, nftl->mtd->oobsize, ++ if (MTD_READOOB(nftl->mbd.mtd, address, nftl->mbd.mtd->oobsize, + &retlen, buf) < 0) + return -1; +- if (memcmpb(buf, 0xff, nftl->mtd->oobsize) != 0) ++ if (memcmpb(buf, 0xff, nftl->mbd.mtd->oobsize) != 0) + return -1; + } + address += SECTORSIZE; +@@ -297,7 +292,7 @@ + struct erase_info *instr = &nftl->instr; + + /* Read the Unit Control Information #1 for Wear-Leveling */ +- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, ++ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, + 8, &retlen, (char *)&uci) < 0) + goto default_uci1; + +@@ -314,7 +309,7 @@ + /* XXX: use async erase interface, XXX: test return code */ + instr->addr = block * nftl->EraseSize; + instr->len = nftl->EraseSize; +- MTD_ERASE(nftl->mtd, instr); ++ MTD_ERASE(nftl->mbd.mtd, instr); + + if (instr->state == MTD_ERASE_FAILED) { + /* could not format, FixMe: We should update the BadUnitTable +@@ -337,7 +332,7 @@ + return -1; + + uci.WearInfo = le32_to_cpu(nb_erases); +- if (MTD_WRITEOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, ++ if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, + &retlen, (char *)&uci) < 0) + return -1; + return 0; +@@ -363,7 +358,7 @@ + block = first_block; + for (;;) { + for (i = 0; i < sectors_per_block; i++) { +- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + i * SECTORSIZE, ++ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i * SECTORSIZE, + 8, &retlen, (char *)&bci) < 0) + status = SECTOR_IGNORE; + else +@@ -383,7 +378,7 @@ + /* sector not free actually : mark it as SECTOR_IGNORE */ + bci.Status = SECTOR_IGNORE; + bci.Status1 = SECTOR_IGNORE; +- MTD_WRITEOOB(nftl->mtd, ++ MTD_WRITEOOB(nftl->mbd.mtd, + block * nftl->EraseSize + i * SECTORSIZE, + 8, &retlen, (char *)&bci); + } +@@ -476,7 +471,7 @@ + size_t retlen; + + /* check erase mark. */ +- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, ++ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, + &retlen, (char *)&h1) < 0) + return -1; + +@@ -491,7 +486,7 @@ + h1.EraseMark = cpu_to_le16(ERASE_MARK); + h1.EraseMark1 = cpu_to_le16(ERASE_MARK); + h1.WearInfo = cpu_to_le32(0); +- if (MTD_WRITEOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, ++ if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, + &retlen, (char *)&h1) < 0) + return -1; + } else { +@@ -503,7 +498,7 @@ + SECTORSIZE, 0) != 0) + return -1; + +- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + i, ++ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i, + 16, &retlen, buf) < 0) + return -1; + if (i == SECTORSIZE) { +@@ -533,7 +528,7 @@ + struct nftl_uci2 uci; + size_t retlen; + +- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8, ++ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8, + 8, &retlen, (char *)&uci) < 0) + return 0; + +@@ -572,9 +567,9 @@ + + for (;;) { + /* read the block header. If error, we format the chain */ +- if (MTD_READOOB(s->mtd, block * s->EraseSize + 8, 8, ++ if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8, + &retlen, (char *)&h0) < 0 || +- MTD_READOOB(s->mtd, block * s->EraseSize + SECTORSIZE + 8, 8, ++ MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8, + &retlen, (char *)&h1) < 0) { + s->ReplUnitTable[block] = BLOCK_NIL; + do_format_chain = 1; +diff -Nurb linux-mips-2.4.27/drivers/mtd/redboot.c linux/drivers/mtd/redboot.c +--- linux-mips-2.4.27/drivers/mtd/redboot.c 2001-12-02 12:34:42.000000000 +0100 ++++ linux/drivers/mtd/redboot.c 2004-11-19 10:25:11.656236728 +0100 +@@ -1,5 +1,5 @@ + /* +- * $Id: redboot.c,v 1.6 2001/10/25 09:16:06 dwmw2 Exp $ ++ * $Id: redboot.c,v 1.12 2003/06/25 16:08:10 dwmw2 Exp $ + * + * Parse RedBoot-style Flash Image System (FIS) tables and + * produce a Linux partition array to match. +@@ -7,6 +7,7 @@ + + #include + #include ++#include + + #include + #include +@@ -34,7 +35,9 @@ + return 1; + } + +-int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts) ++static int parse_redboot_partitions(struct mtd_info *master, ++ struct mtd_partition **pparts, ++ unsigned long fis_origin) + { + int nrparts = 0; + struct fis_image_desc *buf; +@@ -43,7 +46,9 @@ + int ret, i; + size_t retlen; + char *names; ++ char *nullname; + int namelen = 0; ++ static char nullstring[] = "unallocated"; + + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + +@@ -90,7 +95,11 @@ + goto out; + } + new_fl->img = &buf[i]; ++ if (fis_origin) { ++ buf[i].flash_base -= fis_origin; ++ } else { + buf[i].flash_base &= master->size-1; ++ } + + /* I'm sure the JFFS2 code has done me permanent damage. + * I now think the following is _normal_ +@@ -110,18 +119,24 @@ + if (tmp_fl->img->flash_base + tmp_fl->img->size + master->erasesize < tmp_fl->next->img->flash_base) + nrparts++; + } +- parts = kmalloc(sizeof(*parts)*nrparts + namelen, GFP_KERNEL); ++ parts = kmalloc(sizeof(*parts)*nrparts + sizeof(nullstring) + namelen, GFP_KERNEL); + + if (!parts) { + ret = -ENOMEM; + goto out; + } +- names = (char *)&parts[nrparts]; ++ + memset(parts, 0, sizeof(*parts)*nrparts + namelen); ++ ++ /* FIXME: Include nullname only if it's used */ ++ nullname = (char *)&parts[nrparts]; ++ sprintf(nullname, nullstring); ++ names = nullname + sizeof(nullstring); ++ + i=0; + + if (fl->img->flash_base) { +- parts[0].name = "unallocated space"; ++ parts[0].name = nullname; + parts[0].size = fl->img->flash_base; + parts[0].offset = 0; + } +@@ -133,11 +148,11 @@ + strcpy(names, fl->img->name); + names += strlen(names)+1; + +- if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize < fl->next->img->flash_base) { ++ if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) { + i++; + parts[i].offset = parts[i-1].size + parts[i-1].offset; + parts[i].size = fl->next->img->flash_base - parts[i].offset; +- parts[i].name = "unallocated space"; ++ parts[i].name = nullname; + } + tmp_fl = fl; + fl = fl->next; +@@ -155,7 +170,24 @@ + return ret; + } + +-EXPORT_SYMBOL(parse_redboot_partitions); ++static struct mtd_part_parser redboot_parser = { ++ .owner = THIS_MODULE, ++ .parse_fn = parse_redboot_partitions, ++ .name = "RedBoot", ++}; ++ ++static int __init redboot_parser_init(void) ++{ ++ return register_mtd_parser(&redboot_parser); ++} ++ ++static void __exit redboot_parser_exit(void) ++{ ++ deregister_mtd_parser(&redboot_parser); ++} ++ ++module_init(redboot_parser_init); ++module_exit(redboot_parser_exit); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Red Hat, Inc. - David Woodhouse "); +diff -Nurb linux-mips-2.4.27/fs/Config.in linux/fs/Config.in +--- linux-mips-2.4.27/fs/Config.in 2004-02-20 02:22:19.000000000 +0100 ++++ linux/fs/Config.in 2004-11-19 10:25:12.229149632 +0100 +@@ -49,6 +49,7 @@ + dep_tristate 'Journalling Flash File System v2 (JFFS2) support' CONFIG_JFFS2_FS $CONFIG_MTD + if [ "$CONFIG_JFFS2_FS" = "y" -o "$CONFIG_JFFS2_FS" = "m" ] ; then + int 'JFFS2 debugging verbosity (0 = quiet, 2 = noisy)' CONFIG_JFFS2_FS_DEBUG 0 ++ bool 'JFFS2 support for NAND chips' CONFIG_JFFS2_FS_NAND + fi + tristate 'Compressed ROM file system support' CONFIG_CRAMFS + bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS +diff -Nurb linux-mips-2.4.27/fs/jffs2/Makefile linux/fs/jffs2/Makefile +--- linux-mips-2.4.27/fs/jffs2/Makefile 2003-08-13 19:19:25.000000000 +0200 ++++ linux/fs/jffs2/Makefile 2004-11-19 10:25:12.071173648 +0100 +@@ -1,7 +1,7 @@ + # + # Makefile for the linux Journalling Flash FileSystem (JFFS) routines. + # +-# $Id: Makefile,v 1.25.2.1 2002/10/11 09:04:44 dwmw2 Exp $ ++# $Id: Makefile.common,v 1.1 2003/05/27 09:34:41 dwmw2 Exp $ + # + # Note! Dependencies are done automagically by 'make dep', which also + # removes any old dependencies. DON'T put your own dependencies here +@@ -10,16 +10,31 @@ + # Note 2! The CFLAGS definitions are now in the main makefile... + + +-COMPR_OBJS := compr.o compr_rubin.o compr_rtime.o pushpull.o \ +- compr_zlib.o ++obj-$(CONFIG_JFFS2_FS) := jffs2.o ++ ++COMPR_OBJS := compr.o compr_rubin.o compr_rtime.o compr_zlib.o + JFFS2_OBJS := dir.o file.o ioctl.o nodelist.o malloc.o \ +- read.o nodemgmt.o readinode.o super.o write.o scan.o gc.o \ +- symlink.o build.o erase.o background.o ++ read.o nodemgmt.o readinode.o write.o scan.o gc.o \ ++ symlink.o build.o erase.o background.o fs.o writev.o + +-O_TARGET := jffs2.o ++BELOW25 := $(shell echo $(PATCHLEVEL) | sed s/[1234]/y/) ++ ++ifeq ($(BELOW25),y) ++LINUX_OBJS := super-v24.o crc32.o rbtree.o ++else ++LINUX_OBJS := super.o ++endif + +-obj-y := $(COMPR_OBJS) $(JFFS2_OBJS) +-obj-m := $(O_TARGET) ++NAND_OBJS-$(CONFIG_JFFS2_FS_NAND) := wbuf.o + ++jffs2-objs := $(COMPR_OBJS) $(JFFS2_OBJS) $(VERS_OBJS) $(NAND_OBJS-y) \ ++ $(LINUX_OBJS) ++ ++ ++# 2.4 build compatibility ++ifeq ($(BELOW25),y) ++obj-y := $(jffs2-objs) ++O_TARGET := jffs2.o + include $(TOPDIR)/Rules.make ++endif + +diff -Nurb linux-mips-2.4.27/fs/jffs2/background.c linux/fs/jffs2/background.c +--- linux-mips-2.4.27/fs/jffs2/background.c 2001-11-06 08:56:10.000000000 +0100 ++++ linux/fs/jffs2/background.c 2004-11-19 10:25:12.072173496 +0100 +@@ -1,61 +1,36 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: background.c,v 1.16 2001/10/08 09:22:38 dwmw2 Exp $ ++ * $Id: background.c,v 1.47 2003/11/26 15:30:58 dwmw2 Exp $ + * + */ + + #define __KERNEL_SYSCALLS__ + + #include +-#include +-#include + #include + #include +-#include + #include ++#include ++#include ++#include + #include "nodelist.h" + + + static int jffs2_garbage_collect_thread(void *); +-static int thread_should_wake(struct jffs2_sb_info *c); + + void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c) + { +- spin_lock_bh(&c->erase_completion_lock); +- if (c->gc_task && thread_should_wake(c)) ++ spin_lock(&c->erase_completion_lock); ++ if (c->gc_task && jffs2_thread_should_wake(c)) + send_sig(SIGHUP, c->gc_task, 1); +- spin_unlock_bh(&c->erase_completion_lock); ++ spin_unlock(&c->erase_completion_lock); + } + + /* This must only ever be called when no GC thread is currently running */ +@@ -86,12 +61,12 @@ + + void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c) + { +- spin_lock_bh(&c->erase_completion_lock); ++ spin_lock(&c->erase_completion_lock); + if (c->gc_task) { + D1(printk(KERN_DEBUG "jffs2: Killing GC task %d\n", c->gc_task->pid)); + send_sig(SIGKILL, c->gc_task, 1); + } +- spin_unlock_bh(&c->erase_completion_lock); ++ spin_unlock(&c->erase_completion_lock); + wait_for_completion(&c->gc_thread_exit); + } + +@@ -99,34 +74,37 @@ + { + struct jffs2_sb_info *c = _c; + +- daemonize(); +- current->tty = NULL; ++ daemonize("jffs2_gcd_mtd%d", c->mtd->index); ++ allow_signal(SIGKILL); ++ allow_signal(SIGSTOP); ++ allow_signal(SIGCONT); ++ + c->gc_task = current; + up(&c->gc_thread_start); + +- sprintf(current->comm, "jffs2_gcd_mtd%d", c->mtd->index); +- +- /* FIXME in the 2.2 backport */ +- current->nice = 10; ++ set_user_nice(current, 10); + + for (;;) { +- spin_lock_irq(¤t->sigmask_lock); +- siginitsetinv (¤t->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT)); +- recalc_sigpending(current); +- spin_unlock_irq(¤t->sigmask_lock); ++ allow_signal(SIGHUP); + +- if (!thread_should_wake(c)) { ++ if (!jffs2_thread_should_wake(c)) { + set_current_state (TASK_INTERRUPTIBLE); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n")); +- /* Yes, there's a race here; we checked thread_should_wake() before +- setting current->state to TASK_INTERRUPTIBLE. But it doesn't ++ /* Yes, there's a race here; we checked jffs2_thread_should_wake() ++ before setting current->state to TASK_INTERRUPTIBLE. But it doesn't + matter - We don't care if we miss a wakeup, because the GC thread + is only an optimisation anyway. */ + schedule(); + } + +- if (current->need_resched) +- schedule(); ++ if (current->flags & PF_FREEZE) { ++ refrigerator(0); ++ /* refrigerator() should recalc sigpending for us ++ but doesn't. No matter - allow_signal() will. */ ++ continue; ++ } ++ ++ cond_resched(); + + /* Put_super will send a SIGKILL and then wait on the sem. + */ +@@ -134,9 +112,7 @@ + siginfo_t info; + unsigned long signr; + +- spin_lock_irq(¤t->sigmask_lock); +- signr = dequeue_signal(¤t->blocked, &info); +- spin_unlock_irq(¤t->sigmask_lock); ++ signr = dequeue_signal_lock(current, ¤t->blocked, &info); + + switch(signr) { + case SIGSTOP: +@@ -147,9 +123,10 @@ + + case SIGKILL: + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): SIGKILL received.\n")); +- spin_lock_bh(&c->erase_completion_lock); ++ die: ++ spin_lock(&c->erase_completion_lock); + c->gc_task = NULL; +- spin_unlock_bh(&c->erase_completion_lock); ++ spin_unlock(&c->erase_completion_lock); + complete_and_exit(&c->gc_thread_exit, 0); + + case SIGHUP: +@@ -157,27 +134,15 @@ + break; + default: + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): signal %ld received\n", signr)); +- + } + } + /* We don't want SIGHUP to interrupt us. STOP and KILL are OK though. */ +- spin_lock_irq(¤t->sigmask_lock); +- siginitsetinv (¤t->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT)); +- recalc_sigpending(current); +- spin_unlock_irq(¤t->sigmask_lock); ++ disallow_signal(SIGHUP); + + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): pass\n")); +- jffs2_garbage_collect_pass(c); ++ if (jffs2_garbage_collect_pass(c) == -ENOSPC) { ++ printk(KERN_NOTICE "No space for garbage collection. Aborting GC thread\n"); ++ goto die; ++ } + } +-} +- +-static int thread_should_wake(struct jffs2_sb_info *c) +-{ +- D1(printk(KERN_DEBUG "thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x\n", +- c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size)); +- if (c->nr_free_blocks + c->nr_erasing_blocks < JFFS2_RESERVED_BLOCKS_GCTRIGGER && +- c->dirty_size > c->sector_size) +- return 1; +- else +- return 0; + } +diff -Nurb linux-mips-2.4.27/fs/jffs2/build.c linux/fs/jffs2/build.c +--- linux-mips-2.4.27/fs/jffs2/build.c 2003-07-05 05:23:44.000000000 +0200 ++++ linux/fs/jffs2/build.c 2004-11-19 10:25:12.073173344 +0100 +@@ -1,47 +1,22 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: build.c,v 1.16.2.3 2003/04/30 09:43:32 dwmw2 Exp $ ++ * $Id: build.c,v 1.55 2003/10/28 17:02:44 dwmw2 Exp $ + * + */ + + #include +-#include ++#include + #include + #include "nodelist.h" + +-int jffs2_build_inode_pass1(struct jffs2_sb_info *, struct jffs2_inode_cache *); +-int jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, struct jffs2_inode_cache *); ++static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, struct jffs2_inode_cache *, struct jffs2_full_dirent **); + + static inline struct jffs2_inode_cache * + first_inode_chain(int *i, struct jffs2_sb_info *c) +@@ -68,16 +43,52 @@ + ic; \ + ic = next_inode(&i, ic, (c))) + ++ ++static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) ++{ ++ struct jffs2_full_dirent *fd; ++ ++ D1(printk(KERN_DEBUG "jffs2_build_inode building directory inode #%u\n", ic->ino)); ++ ++ /* For each child, increase nlink */ ++ for(fd = ic->scan_dents; fd; fd = fd->next) { ++ struct jffs2_inode_cache *child_ic; ++ if (!fd->ino) ++ continue; ++ ++ /* XXX: Can get high latency here with huge directories */ ++ ++ child_ic = jffs2_get_ino_cache(c, fd->ino); ++ if (!child_ic) { ++ printk(KERN_NOTICE "Eep. Child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n", ++ fd->name, fd->ino, ic->ino); ++ continue; ++ } ++ ++ if (child_ic->nlink++ && fd->type == DT_DIR) { ++ printk(KERN_NOTICE "Child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", fd->name, fd->ino, ic->ino); ++ if (fd->ino == 1 && ic->ino == 1) { ++ printk(KERN_NOTICE "This is mostly harmless, and probably caused by creating a JFFS2 image\n"); ++ printk(KERN_NOTICE "using a buggy version of mkfs.jffs2. Use at least v1.17.\n"); ++ } ++ /* What do we do about it? */ ++ } ++ D1(printk(KERN_DEBUG "Increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino)); ++ /* Can't free them. We might need them in pass 2 */ ++ } ++} ++ + /* Scan plan: + - Scan physical nodes. Build map of inodes/dirents. Allocate inocaches as we go + - Scan directory tree from top down, setting nlink in inocaches + - Scan inocaches for inodes with nlink==0 + */ +-int jffs2_build_filesystem(struct jffs2_sb_info *c) ++static int jffs2_build_filesystem(struct jffs2_sb_info *c) + { + int ret; + int i; + struct jffs2_inode_cache *ic; ++ struct jffs2_full_dirent *dead_fds = NULL; + + /* First, scan the medium and build all the inode caches with + lists of physical nodes */ +@@ -90,14 +101,17 @@ + return ret; + + D1(printk(KERN_DEBUG "Scanned flash completely\n")); +- /* Now build the data map for each inode, marking obsoleted nodes +- as such, and also increase nlink of any children. */ ++ D1(jffs2_dump_block_lists(c)); ++ ++ /* Now scan the directory tree, increasing nlink according to every dirent found. */ + for_each_inode(i, c, ic) { + D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino)); +- ret = jffs2_build_inode_pass1(c, ic); +- if (ret) { +- D1(printk(KERN_WARNING "Eep. jffs2_build_inode_pass1 for ino %d returned %d\n", ic->ino, ret)); +- return ret; ++ ++ D1(BUG_ON(ic->ino > c->highest_ino)); ++ ++ if (ic->scan_dents) { ++ jffs2_build_inode_pass1(c, ic); ++ cond_resched(); + } + } + D1(printk(KERN_DEBUG "Pass 1 complete\n")); +@@ -107,181 +121,226 @@ + children too, and repeat the scan. As that's going to be + a fairly uncommon occurrence, it's not so evil to do it this + way. Recursion bad. */ +- do { +- D1(printk(KERN_DEBUG "Pass 2 (re)starting\n")); +- ret = 0; ++ D1(printk(KERN_DEBUG "Pass 2 starting\n")); ++ + for_each_inode(i, c, ic) { + D1(printk(KERN_DEBUG "Pass 2: ino #%u, nlink %d, ic %p, nodes %p\n", ic->ino, ic->nlink, ic, ic->nodes)); + if (ic->nlink) + continue; + +- ret = jffs2_build_remove_unlinked_inode(c, ic); +- if (ret) +- break; +- /* -EAGAIN means the inode's nlink was zero, so we deleted it, +- and furthermore that it had children and their nlink has now +- gone to zero too. So we have to restart the scan. */ ++ jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); ++ cond_resched(); ++ } ++ ++ D1(printk(KERN_DEBUG "Pass 2a starting\n")); ++ ++ while (dead_fds) { ++ struct jffs2_inode_cache *ic; ++ struct jffs2_full_dirent *fd = dead_fds; ++ ++ dead_fds = fd->next; ++ ++ ic = jffs2_get_ino_cache(c, fd->ino); ++ D1(printk(KERN_DEBUG "Removing dead_fd ino #%u (\"%s\"), ic at %p\n", fd->ino, fd->name, ic)); ++ ++ if (ic) ++ jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); ++ jffs2_free_full_dirent(fd); + } +- } while(ret == -EAGAIN); + + D1(printk(KERN_DEBUG "Pass 2 complete\n")); + +- /* Finally, we can scan again and free the dirent nodes and scan_info structs */ ++ /* Finally, we can scan again and free the dirent structs */ + for_each_inode(i, c, ic) { +- struct jffs2_scan_info *scan = ic->scan; + struct jffs2_full_dirent *fd; + D1(printk(KERN_DEBUG "Pass 3: ino #%u, ic %p, nodes %p\n", ic->ino, ic, ic->nodes)); +- if (!scan) { +- if (ic->nlink) { +- D1(printk(KERN_WARNING "Why no scan struct for ino #%u which has nlink %d?\n", ic->ino, ic->nlink)); +- } +- continue; +- } +- ic->scan = NULL; +- while(scan->dents) { +- fd = scan->dents; +- scan->dents = fd->next; ++ ++ while(ic->scan_dents) { ++ fd = ic->scan_dents; ++ ic->scan_dents = fd->next; + jffs2_free_full_dirent(fd); + } +- kfree(scan); ++ ic->scan_dents = NULL; ++ cond_resched(); + } + D1(printk(KERN_DEBUG "Pass 3 complete\n")); ++ D1(jffs2_dump_block_lists(c)); ++ ++ /* Rotate the lists by some number to ensure wear levelling */ ++ jffs2_rotate_lists(c); + + return ret; + } + +-int jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) ++static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, struct jffs2_full_dirent **dead_fds) + { +- struct jffs2_tmp_dnode_info *tn; ++ struct jffs2_raw_node_ref *raw; + struct jffs2_full_dirent *fd; +- struct jffs2_node_frag *fraglist = NULL; +- struct jffs2_tmp_dnode_info *metadata = NULL; +- +- D1(printk(KERN_DEBUG "jffs2_build_inode building inode #%u\n", ic->ino)); +- if (ic->ino > c->highest_ino) +- c->highest_ino = ic->ino; + +- if (!ic->scan->tmpnodes && ic->ino != 1) { +- D1(printk(KERN_DEBUG "jffs2_build_inode: ino #%u has no data nodes!\n", ic->ino)); +- } +- /* Build the list to make sure any obsolete nodes are marked as such */ +- while(ic->scan->tmpnodes) { +- tn = ic->scan->tmpnodes; +- ic->scan->tmpnodes = tn->next; +- +- if (metadata && tn->version > metadata->version) { +- D1(printk(KERN_DEBUG "jffs2_build_inode_pass1 ignoring old metadata at 0x%08x\n", +- metadata->fn->raw->flash_offset &~3)); ++ D1(printk(KERN_DEBUG "JFFS2: Removing ino #%u with nlink == zero.\n", ic->ino)); + +- jffs2_free_full_dnode(metadata->fn); +- jffs2_free_tmp_dnode_info(metadata); +- metadata = NULL; ++ for (raw = ic->nodes; raw != (void *)ic; raw = raw->next_in_ino) { ++ D1(printk(KERN_DEBUG "obsoleting node at 0x%08x\n", ref_offset(raw))); ++ jffs2_mark_node_obsolete(c, raw); + } + +- if (tn->fn->size) { +- jffs2_add_full_dnode_to_fraglist (c, &fraglist, tn->fn); +- jffs2_free_tmp_dnode_info(tn); +- } else { +- if (!metadata) { +- metadata = tn; +- } else { +- D1(printk(KERN_DEBUG "jffs2_build_inode_pass1 ignoring new metadata at 0x%08x\n", +- tn->fn->raw->flash_offset &~3)); +- +- jffs2_free_full_dnode(tn->fn); +- jffs2_free_tmp_dnode_info(tn); +- } +- } +- } ++ if (ic->scan_dents) { ++ int whinged = 0; ++ D1(printk(KERN_DEBUG "Inode #%u was a directory which may have children...\n", ic->ino)); + +- /* OK. Now clear up */ +- if (metadata) { +- jffs2_free_full_dnode(metadata->fn); +- jffs2_free_tmp_dnode_info(metadata); +- } +- metadata = NULL; ++ while(ic->scan_dents) { ++ struct jffs2_inode_cache *child_ic; + +- while (fraglist) { +- struct jffs2_node_frag *frag; +- frag = fraglist; +- fraglist = fraglist->next; ++ fd = ic->scan_dents; ++ ic->scan_dents = fd->next; + +- if (frag->node && !(--frag->node->frags)) { +- jffs2_free_full_dnode(frag->node); ++ if (!fd->ino) { ++ /* It's a deletion dirent. Ignore it */ ++ D1(printk(KERN_DEBUG "Child \"%s\" is a deletion dirent, skipping...\n", fd->name)); ++ jffs2_free_full_dirent(fd); ++ continue; + } +- jffs2_free_node_frag(frag); ++ if (!whinged) { ++ whinged = 1; ++ printk(KERN_NOTICE "Inode #%u was a directory with children - removing those too...\n", ic->ino); + } + +- /* Now for each child, increase nlink */ +- for(fd=ic->scan->dents; fd; fd = fd->next) { +- struct jffs2_inode_cache *child_ic; +- if (!fd->ino) +- continue; ++ D1(printk(KERN_DEBUG "Removing child \"%s\", ino #%u\n", ++ fd->name, fd->ino)); + + child_ic = jffs2_get_ino_cache(c, fd->ino); + if (!child_ic) { +- printk(KERN_NOTICE "Eep. Child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n", +- fd->name, fd->ino, ic->ino); ++ printk(KERN_NOTICE "Cannot remove child \"%s\", ino #%u, because it doesn't exist\n", fd->name, fd->ino); ++ jffs2_free_full_dirent(fd); + continue; + } + +- if (child_ic->nlink++ && fd->type == DT_DIR) { +- printk(KERN_NOTICE "Child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", fd->name, fd->ino, ic->ino); +- if (fd->ino == 1 && ic->ino == 1) { +- printk(KERN_NOTICE "This is mostly harmless, and probably caused by creating a JFFS2 image\n"); +- printk(KERN_NOTICE "using a buggy version of mkfs.jffs2. Use at least v1.17.\n"); ++ /* Reduce nlink of the child. If it's now zero, stick it on the ++ dead_fds list to be cleaned up later. Else just free the fd */ ++ ++ child_ic->nlink--; ++ ++ if (!child_ic->nlink) { ++ D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got zero nlink. Adding to dead_fds list.\n", ++ fd->ino, fd->name)); ++ fd->next = *dead_fds; ++ *dead_fds = fd; ++ } else { ++ D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got nlink %d. Ignoring.\n", ++ fd->ino, fd->name, child_ic->nlink)); ++ jffs2_free_full_dirent(fd); + } +- /* What do we do about it? */ + } +- D1(printk(KERN_DEBUG "Increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino)); +- /* Can't free them. We might need them in pass 2 */ + } +- return 0; ++ ++ /* ++ We don't delete the inocache from the hash list and free it yet. ++ The erase code will do that, when all the nodes are completely gone. ++ */ + } + +-int jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) ++static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c) + { +- struct jffs2_raw_node_ref *raw; +- struct jffs2_full_dirent *fd; +- int ret = 0; ++ uint32_t size; + +- if(!ic->scan) { +- D1(printk(KERN_DEBUG "ino #%u was already removed\n", ic->ino)); +- return 0; +- } ++ /* Deletion should almost _always_ be allowed. We're fairly ++ buggered once we stop allowing people to delete stuff ++ because there's not enough free space... */ ++ c->resv_blocks_deletion = 2; ++ ++ /* Be conservative about how much space we need before we allow writes. ++ On top of that which is required for deletia, require an extra 2% ++ of the medium to be available, for overhead caused by nodes being ++ split across blocks, etc. */ ++ ++ size = c->flash_size / 50; /* 2% of flash size */ ++ size += c->nr_blocks * 100; /* And 100 bytes per eraseblock */ ++ size += c->sector_size - 1; /* ... and round up */ ++ ++ c->resv_blocks_write = c->resv_blocks_deletion + (size / c->sector_size); ++ ++ /* When do we let the GC thread run in the background */ ++ ++ c->resv_blocks_gctrigger = c->resv_blocks_write + 1; ++ ++ /* When do we allow garbage collection to merge nodes to make ++ long-term progress at the expense of short-term space exhaustion? */ ++ c->resv_blocks_gcmerge = c->resv_blocks_deletion + 1; ++ ++ /* When do we allow garbage collection to eat from bad blocks rather ++ than actually making progress? */ ++ c->resv_blocks_gcbad = 0;//c->resv_blocks_deletion + 2; ++ ++ /* If there's less than this amount of dirty space, don't bother ++ trying to GC to make more space. It'll be a fruitless task */ ++ c->nospc_dirty_size = c->sector_size + (c->flash_size / 100); ++ ++ D1(printk(KERN_DEBUG "JFFS2 trigger levels (size %d KiB, block size %d KiB, %d blocks)\n", ++ c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks)); ++ D1(printk(KERN_DEBUG "Blocks required to allow deletion: %d (%d KiB)\n", ++ c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024)); ++ D1(printk(KERN_DEBUG "Blocks required to allow writes: %d (%d KiB)\n", ++ c->resv_blocks_write, c->resv_blocks_write*c->sector_size/1024)); ++ D1(printk(KERN_DEBUG "Blocks required to quiesce GC thread: %d (%d KiB)\n", ++ c->resv_blocks_gctrigger, c->resv_blocks_gctrigger*c->sector_size/1024)); ++ D1(printk(KERN_DEBUG "Blocks required to allow GC merges: %d (%d KiB)\n", ++ c->resv_blocks_gcmerge, c->resv_blocks_gcmerge*c->sector_size/1024)); ++ D1(printk(KERN_DEBUG "Blocks required to GC bad blocks: %d (%d KiB)\n", ++ c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024)); ++ D1(printk(KERN_DEBUG "Amount of dirty space required to GC: %d bytes\n", ++ c->nospc_dirty_size)); ++} + +- D1(printk(KERN_DEBUG "JFFS2: Removing ino #%u with nlink == zero.\n", ic->ino)); ++int jffs2_do_mount_fs(struct jffs2_sb_info *c) ++{ ++ int i; + +- for (raw = ic->nodes; raw != (void *)ic; raw = raw->next_in_ino) { +- D1(printk(KERN_DEBUG "obsoleting node at 0x%08x\n", raw->flash_offset&~3)); +- jffs2_mark_node_obsolete(c, raw); ++ c->free_size = c->flash_size; ++ c->nr_blocks = c->flash_size / c->sector_size; ++ c->blocks = kmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks, GFP_KERNEL); ++ if (!c->blocks) ++ return -ENOMEM; ++ for (i=0; inr_blocks; i++) { ++ INIT_LIST_HEAD(&c->blocks[i].list); ++ c->blocks[i].offset = i * c->sector_size; ++ c->blocks[i].free_size = c->sector_size; ++ c->blocks[i].dirty_size = 0; ++ c->blocks[i].wasted_size = 0; ++ c->blocks[i].unchecked_size = 0; ++ c->blocks[i].used_size = 0; ++ c->blocks[i].first_node = NULL; ++ c->blocks[i].last_node = NULL; ++ } ++ ++ init_MUTEX(&c->alloc_sem); ++ init_MUTEX(&c->erase_free_sem); ++ init_waitqueue_head(&c->erase_wait); ++ init_waitqueue_head(&c->inocache_wq); ++ spin_lock_init(&c->erase_completion_lock); ++ spin_lock_init(&c->inocache_lock); ++ ++ INIT_LIST_HEAD(&c->clean_list); ++ INIT_LIST_HEAD(&c->very_dirty_list); ++ INIT_LIST_HEAD(&c->dirty_list); ++ INIT_LIST_HEAD(&c->erasable_list); ++ INIT_LIST_HEAD(&c->erasing_list); ++ INIT_LIST_HEAD(&c->erase_pending_list); ++ INIT_LIST_HEAD(&c->erasable_pending_wbuf_list); ++ INIT_LIST_HEAD(&c->erase_complete_list); ++ INIT_LIST_HEAD(&c->free_list); ++ INIT_LIST_HEAD(&c->bad_list); ++ INIT_LIST_HEAD(&c->bad_used_list); ++ c->highest_ino = 1; ++ ++ if (jffs2_build_filesystem(c)) { ++ D1(printk(KERN_DEBUG "build_fs failed\n")); ++ jffs2_free_ino_caches(c); ++ jffs2_free_raw_node_refs(c); ++ kfree(c->blocks); ++ return -EIO; + } + +- if (ic->scan->dents) { +- printk(KERN_NOTICE "Inode #%u was a directory with children - removing those too...\n", ic->ino); +- +- while(ic->scan->dents) { +- struct jffs2_inode_cache *child_ic; ++ jffs2_calc_trigger_levels(c); + +- fd = ic->scan->dents; +- ic->scan->dents = fd->next; +- +- D1(printk(KERN_DEBUG "Removing child \"%s\", ino #%u\n", +- fd->name, fd->ino)); +- +- child_ic = jffs2_get_ino_cache(c, fd->ino); +- if (!child_ic) { +- printk(KERN_NOTICE "Cannot remove child \"%s\", ino #%u, because it doesn't exist\n", fd->name, fd->ino); +- continue; +- } +- jffs2_free_full_dirent(fd); +- child_ic->nlink--; +- } +- ret = -EAGAIN; +- } +- kfree(ic->scan); +- ic->scan = NULL; +- // jffs2_del_ino_cache(c, ic); +- // jffs2_free_inode_cache(ic); +- return ret; ++ return 0; + } +diff -Nurb linux-mips-2.4.27/fs/jffs2/compr.c linux/fs/jffs2/compr.c +--- linux-mips-2.4.27/fs/jffs2/compr.c 2001-11-05 21:16:18.000000000 +0100 ++++ linux/fs/jffs2/compr.c 2004-11-19 10:25:12.085171520 +0100 +@@ -1,59 +1,37 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * + * Created by Arjan van de Ven + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: compr.c,v 1.17 2001/09/23 09:56:46 dwmw2 Exp $ ++ * $Id: compr.c,v 1.33 2003/11/28 17:22:54 dwmw2 Exp $ + * + */ + + #include + #include +-#include + #include ++#include ++#include + #include ++#include "nodelist.h" + +-int zlib_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen); +-void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen); +-int rtime_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen); +-void rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen); +-int rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen); +-void rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen); +-int dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen); +-void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen); ++int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen); ++void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen); ++int jffs2_rtime_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen); ++void jffs2_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen); ++int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen); ++void jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen); ++int jffs2_dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen); ++void jffs2_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen); + + + /* jffs2_compress: + * @data: Pointer to uncompressed data +- * @cdata: Pointer to buffer for compressed data ++ * @cdata: Pointer to returned pointer to buffer for compressed data + * @datalen: On entry, holds the amount of data available for compression. + * On exit, expected to hold the amount of data actually compressed. + * @cdatalen: On entry, holds the amount of space available for compressed +@@ -68,47 +46,59 @@ + * jffs2_compress should compress as much as will fit, and should set + * *datalen accordingly to show the amount of data which were compressed. + */ +-unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out, +- __u32 *datalen, __u32 *cdatalen) ++unsigned char jffs2_compress(unsigned char *data_in, unsigned char **cpage_out, ++ uint32_t *datalen, uint32_t *cdatalen) + { ++#ifdef JFFS2_COMPRESSION + int ret; + +- ret = zlib_compress(data_in, cpage_out, datalen, cdatalen); ++ *cpage_out = kmalloc(*cdatalen, GFP_KERNEL); ++ if (!*cpage_out) { ++ printk(KERN_WARNING "No memory for compressor allocation. Compression failed\n"); ++ goto out; ++ } ++ ++#ifdef JFFS2_USE_ZLIB ++ ret = jffs2_zlib_compress(data_in, *cpage_out, datalen, cdatalen); + if (!ret) { + return JFFS2_COMPR_ZLIB; + } +-#if 0 /* Disabled 23/9/1. With zlib it hardly ever gets a look in */ +- ret = dynrubin_compress(data_in, cpage_out, datalen, cdatalen); ++#endif ++#ifdef JFFS2_USE_DYNRUBIN ++ ret = jffs2_dynrubin_compress(data_in, *cpage_out, datalen, cdatalen); + if (!ret) { + return JFFS2_COMPR_DYNRUBIN; + } + #endif +-#if 0 /* Disabled 26/2/1. Obsoleted by dynrubin */ +- ret = rubinmips_compress(data_in, cpage_out, datalen, cdatalen); ++#ifdef JFFS2_USE_RUBINMIPS ++ ret = jffs2_rubinmips_compress(data_in, *cpage_out, datalen, cdatalen); + if (!ret) { + return JFFS2_COMPR_RUBINMIPS; + } + #endif ++#ifdef JFFS2_USE_RTIME + /* rtime does manage to recompress already-compressed data */ +- ret = rtime_compress(data_in, cpage_out, datalen, cdatalen); ++ ret = jffs2_rtime_compress(data_in, *cpage_out, datalen, cdatalen); + if (!ret) { + return JFFS2_COMPR_RTIME; + } +-#if 0 +- /* We don't need to copy. Let the caller special-case the COMPR_NONE case. */ +- /* If we get here, no compression is going to work */ +- /* But we might want to use the fragmentation part -- Arjan */ +- memcpy(cpage_out,data_in,min(*datalen,*cdatalen)); +- if (*datalen > *cdatalen) +- *datalen = *cdatalen; + #endif ++ kfree(*cpage_out); ++#endif /* Compression */ ++ out: ++ *cpage_out = data_in; ++ *datalen = *cdatalen; + return JFFS2_COMPR_NONE; /* We failed to compress */ +- + } + ++void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig) ++{ ++ if (orig != comprbuf) ++ kfree(comprbuf); ++} + + int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in, +- unsigned char *data_out, __u32 cdatalen, __u32 datalen) ++ unsigned char *data_out, uint32_t cdatalen, uint32_t datalen) + { + switch (comprtype) { + case JFFS2_COMPR_NONE: +@@ -119,30 +109,27 @@ + case JFFS2_COMPR_ZERO: + memset(data_out, 0, datalen); + break; +- ++#ifdef JFFS2_USE_ZLIB + case JFFS2_COMPR_ZLIB: +- zlib_decompress(cdata_in, data_out, cdatalen, datalen); ++ jffs2_zlib_decompress(cdata_in, data_out, cdatalen, datalen); + break; +- ++#endif ++#ifdef JFFS2_USE_RTIME + case JFFS2_COMPR_RTIME: +- rtime_decompress(cdata_in, data_out, cdatalen, datalen); ++ jffs2_rtime_decompress(cdata_in, data_out, cdatalen, datalen); + break; +- +- case JFFS2_COMPR_RUBINMIPS: +-#if 0 /* Disabled 23/9/1 */ +- rubinmips_decompress(cdata_in, data_out, cdatalen, datalen); +-#else +- printk(KERN_WARNING "JFFS2: Rubinmips compression encountered but support not compiled in!\n"); + #endif ++#ifdef JFFS2_USE_RUBINMIPS ++ case JFFS2_COMPR_RUBINMIPS: ++ jffs2_rubinmips_decompress(cdata_in, data_out, cdatalen, datalen); + break; +- case JFFS2_COMPR_DYNRUBIN: +-#if 1 /* Phase this one out */ +- dynrubin_decompress(cdata_in, data_out, cdatalen, datalen); +-#else +- printk(KERN_WARNING "JFFS2: Dynrubin compression encountered but support not compiled in!\n"); + #endif +- break; ++#ifdef JFFS2_USE_DYNRUBIN ++ case JFFS2_COMPR_DYNRUBIN: + ++ jffs2_dynrubin_decompress(cdata_in, data_out, cdatalen, datalen); ++ break; ++#endif + default: + printk(KERN_NOTICE "Unknown JFFS2 compression type 0x%02x\n", comprtype); + return -EIO; +diff -Nurb linux-mips-2.4.27/fs/jffs2/compr_rtime.c linux/fs/jffs2/compr_rtime.c +--- linux-mips-2.4.27/fs/jffs2/compr_rtime.c 2001-10-19 03:24:56.000000000 +0200 ++++ linux/fs/jffs2/compr_rtime.c 2004-11-19 10:25:12.087171216 +0100 +@@ -1,43 +1,19 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * + * Created by Arjan van de Ven + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: compr_rtime.c,v 1.5 2001/03/15 15:38:23 dwmw2 Exp $ ++ * $Id: compr_rtime.c,v 1.11 2003/10/04 08:33:06 dwmw2 Exp $ + * + * + * Very simple lz77-ish encoder. + * + * Theory of operation: Both encoder and decoder have a list of "last +- * occurances" for every possible source-value; after sending the ++ * occurrences" for every possible source-value; after sending the + * first source-byte, the second byte indicated the "run" length of + * matches + * +@@ -51,10 +27,10 @@ + #include + + /* _compress returns the compressed size, -1 if bigger */ +-int rtime_compress(unsigned char *data_in, unsigned char *cpage_out, +- __u32 *sourcelen, __u32 *dstlen) ++int jffs2_rtime_compress(unsigned char *data_in, unsigned char *cpage_out, ++ uint32_t *sourcelen, uint32_t *dstlen) + { +- int positions[256]; ++ short positions[256]; + int outpos = 0; + int pos=0; + +@@ -91,10 +67,10 @@ + } + + +-void rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, +- __u32 srclen, __u32 destlen) ++void jffs2_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, ++ uint32_t srclen, uint32_t destlen) + { +- int positions[256]; ++ short positions[256]; + int outpos = 0; + int pos=0; + +diff -Nurb linux-mips-2.4.27/fs/jffs2/compr_rubin.c linux/fs/jffs2/compr_rubin.c +--- linux-mips-2.4.27/fs/jffs2/compr_rubin.c 2001-11-05 21:16:18.000000000 +0100 ++++ linux/fs/jffs2/compr_rubin.c 2004-11-19 10:25:12.088171064 +0100 +@@ -1,37 +1,13 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001, 2002 Red Hat, Inc. + * + * Created by Arjan van de Ven + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: compr_rubin.c,v 1.13 2001/09/23 10:06:05 rmk Exp $ ++ * $Id: compr_rubin.c,v 1.17 2002/05/20 14:56:37 dwmw2 Exp $ + * + */ + +@@ -43,7 +19,7 @@ + + + +-void init_rubin(struct rubin_state *rs, int div, int *bits) ++static void init_rubin(struct rubin_state *rs, int div, int *bits) + { + int c; + +@@ -56,7 +32,7 @@ + } + + +-int encode(struct rubin_state *rs, long A, long B, int symbol) ++static int encode(struct rubin_state *rs, long A, long B, int symbol) + { + + long i0, i1; +@@ -91,7 +67,7 @@ + } + + +-void end_rubin(struct rubin_state *rs) ++static void end_rubin(struct rubin_state *rs) + { + + int i; +@@ -104,7 +80,7 @@ + } + + +-void init_decode(struct rubin_state *rs, int div, int *bits) ++static void init_decode(struct rubin_state *rs, int div, int *bits) + { + init_rubin(rs, div, bits); + +@@ -151,7 +127,7 @@ + rs->rec_q = rec_q; + } + +-int decode(struct rubin_state *rs, long A, long B) ++static int decode(struct rubin_state *rs, long A, long B) + { + unsigned long p = rs->p, q = rs->q; + long i0, threshold; +@@ -212,8 +188,8 @@ + + + +-int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in, +- unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen) ++static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in, ++ unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen) + { + int outpos = 0; + int pos=0; +@@ -246,20 +222,20 @@ + } + #if 0 + /* _compress returns the compressed size, -1 if bigger */ +-int rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, +- __u32 *sourcelen, __u32 *dstlen) ++int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, ++ uint32_t *sourcelen, uint32_t *dstlen) + { + return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); + } + #endif +-int dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, +- __u32 *sourcelen, __u32 *dstlen) ++int jffs2_dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, ++ uint32_t *sourcelen, uint32_t *dstlen) + { + int bits[8]; + unsigned char histo[256]; + int i; + int ret; +- __u32 mysrclen, mydstlen; ++ uint32_t mysrclen, mydstlen; + + mysrclen = *sourcelen; + mydstlen = *dstlen - 8; +@@ -315,8 +291,8 @@ + return 0; + } + +-void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in, +- unsigned char *page_out, __u32 srclen, __u32 destlen) ++static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in, ++ unsigned char *page_out, uint32_t srclen, uint32_t destlen) + { + int outpos = 0; + struct rubin_state rs; +@@ -330,14 +306,14 @@ + } + + +-void rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, +- __u32 sourcelen, __u32 dstlen) ++void jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, ++ uint32_t sourcelen, uint32_t dstlen) + { + rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); + } + +-void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, +- __u32 sourcelen, __u32 dstlen) ++void jffs2_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, ++ uint32_t sourcelen, uint32_t dstlen) + { + int bits[8]; + int c; +diff -Nurb linux-mips-2.4.27/fs/jffs2/compr_rubin.h linux/fs/jffs2/compr_rubin.h +--- linux-mips-2.4.27/fs/jffs2/compr_rubin.h 2001-10-19 03:24:56.000000000 +0200 ++++ linux/fs/jffs2/compr_rubin.h 2004-11-19 10:25:12.090170760 +0100 +@@ -1,7 +1,7 @@ + /* Rubin encoder/decoder header */ + /* work started at : aug 3, 1994 */ + /* last modification : aug 15, 1994 */ +-/* $Id: compr_rubin.h,v 1.5 2001/02/26 13:50:01 dwmw2 Exp $ */ ++/* $Id: compr_rubin.h,v 1.6 2002/01/25 01:49:26 dwmw2 Exp $ */ + + #include "pushpull.h" + +@@ -19,10 +19,3 @@ + int bit_divider; + int bits[8]; + }; +- +- +-void init_rubin (struct rubin_state *rs, int div, int *bits); +-int encode (struct rubin_state *, long, long, int); +-void end_rubin (struct rubin_state *); +-void init_decode (struct rubin_state *, int div, int *bits); +-int decode (struct rubin_state *, long, long); +diff -Nurb linux-mips-2.4.27/fs/jffs2/compr_zlib.c linux/fs/jffs2/compr_zlib.c +--- linux-mips-2.4.27/fs/jffs2/compr_zlib.c 2003-01-11 18:53:17.000000000 +0100 ++++ linux/fs/jffs2/compr_zlib.c 2004-11-19 10:25:12.091170608 +0100 +@@ -1,50 +1,26 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001, 2002 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: compr_zlib.c,v 1.8.2.1 2002/10/11 09:04:44 dwmw2 Exp $ ++ * $Id: compr_zlib.c,v 1.25 2003/12/03 09:25:43 dwmw2 Exp $ + * + */ + +-#ifndef __KERNEL__ ++#if !defined(__KERNEL__) && !defined(__ECOS) + #error "The userspace support got too messy and was removed. Update your mkfs.jffs2" + #endif + + #include + #include +-#include /* for min() */ + #include +-#include + #include ++#include ++#include + #include "nodelist.h" + + /* Plan: call deflate() with avail_in == *sourcelen, +@@ -58,21 +34,24 @@ + + static DECLARE_MUTEX(deflate_sem); + static DECLARE_MUTEX(inflate_sem); +-static void *deflate_workspace; +-static void *inflate_workspace; ++static z_stream inf_strm, def_strm; ++ ++#ifdef __KERNEL__ /* Linux-only */ ++#include ++#include + + int __init jffs2_zlib_init(void) + { +- deflate_workspace = vmalloc(zlib_deflate_workspacesize()); +- if (!deflate_workspace) { ++ def_strm.workspace = vmalloc(zlib_deflate_workspacesize()); ++ if (!def_strm.workspace) { + printk(KERN_WARNING "Failed to allocate %d bytes for deflate workspace\n", zlib_deflate_workspacesize()); + return -ENOMEM; + } + D1(printk(KERN_DEBUG "Allocated %d bytes for deflate workspace\n", zlib_deflate_workspacesize())); +- inflate_workspace = vmalloc(zlib_inflate_workspacesize()); +- if (!inflate_workspace) { ++ inf_strm.workspace = vmalloc(zlib_inflate_workspacesize()); ++ if (!inf_strm.workspace) { + printk(KERN_WARNING "Failed to allocate %d bytes for inflate workspace\n", zlib_inflate_workspacesize()); +- vfree(deflate_workspace); ++ vfree(def_strm.workspace); + return -ENOMEM; + } + D1(printk(KERN_DEBUG "Allocated %d bytes for inflate workspace\n", zlib_inflate_workspacesize())); +@@ -81,97 +60,120 @@ + + void jffs2_zlib_exit(void) + { +- vfree(deflate_workspace); +- vfree(inflate_workspace); ++ vfree(def_strm.workspace); ++ vfree(inf_strm.workspace); + } ++#endif /* __KERNEL__ */ + +-int zlib_compress(unsigned char *data_in, unsigned char *cpage_out, +- __u32 *sourcelen, __u32 *dstlen) ++int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, ++ uint32_t *sourcelen, uint32_t *dstlen) + { +- z_stream strm; + int ret; + + if (*dstlen <= STREAM_END_SPACE) + return -1; + + down(&deflate_sem); +- strm.workspace = deflate_workspace; + +- if (Z_OK != zlib_deflateInit(&strm, 3)) { ++ if (Z_OK != zlib_deflateInit(&def_strm, 3)) { + printk(KERN_WARNING "deflateInit failed\n"); + up(&deflate_sem); + return -1; + } + +- strm.next_in = data_in; +- strm.total_in = 0; ++ def_strm.next_in = data_in; ++ def_strm.total_in = 0; + +- strm.next_out = cpage_out; +- strm.total_out = 0; ++ def_strm.next_out = cpage_out; ++ def_strm.total_out = 0; + +- while (strm.total_out < *dstlen - STREAM_END_SPACE && strm.total_in < *sourcelen) { +- strm.avail_out = *dstlen - (strm.total_out + STREAM_END_SPACE); +- strm.avail_in = min((unsigned)(*sourcelen-strm.total_in), strm.avail_out); ++ while (def_strm.total_out < *dstlen - STREAM_END_SPACE && def_strm.total_in < *sourcelen) { ++ def_strm.avail_out = *dstlen - (def_strm.total_out + STREAM_END_SPACE); ++ def_strm.avail_in = min((unsigned)(*sourcelen-def_strm.total_in), def_strm.avail_out); + D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n", +- strm.avail_in, strm.avail_out)); +- ret = zlib_deflate(&strm, Z_PARTIAL_FLUSH); ++ def_strm.avail_in, def_strm.avail_out)); ++ ret = zlib_deflate(&def_strm, Z_PARTIAL_FLUSH); + D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n", +- strm.avail_in, strm.avail_out, strm.total_in, strm.total_out)); ++ def_strm.avail_in, def_strm.avail_out, def_strm.total_in, def_strm.total_out)); + if (ret != Z_OK) { + D1(printk(KERN_DEBUG "deflate in loop returned %d\n", ret)); +- zlib_deflateEnd(&strm); ++ zlib_deflateEnd(&def_strm); + up(&deflate_sem); + return -1; + } + } +- strm.avail_out += STREAM_END_SPACE; +- strm.avail_in = 0; +- ret = zlib_deflate(&strm, Z_FINISH); +- zlib_deflateEnd(&strm); +- up(&deflate_sem); ++ def_strm.avail_out += STREAM_END_SPACE; ++ def_strm.avail_in = 0; ++ ret = zlib_deflate(&def_strm, Z_FINISH); ++ zlib_deflateEnd(&def_strm); ++ + if (ret != Z_STREAM_END) { + D1(printk(KERN_DEBUG "final deflate returned %d\n", ret)); +- return -1; ++ ret = -1; ++ goto out; + } + +- D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n", +- strm.total_in, strm.total_out)); ++ if (def_strm.total_out >= def_strm.total_in) { ++ D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld; failing\n", ++ def_strm.total_in, def_strm.total_out)); ++ ret = -1; ++ goto out; ++ } + +- if (strm.total_out >= strm.total_in) +- return -1; ++ D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n", ++ def_strm.total_in, def_strm.total_out)); + +- *dstlen = strm.total_out; +- *sourcelen = strm.total_in; +- return 0; ++ *dstlen = def_strm.total_out; ++ *sourcelen = def_strm.total_in; ++ ret = 0; ++ out: ++ up(&deflate_sem); ++ return ret; + } + +-void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, +- __u32 srclen, __u32 destlen) ++void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, ++ uint32_t srclen, uint32_t destlen) + { +- z_stream strm; + int ret; ++ int wbits = MAX_WBITS; + + down(&inflate_sem); +- strm.workspace = inflate_workspace; + +- if (Z_OK != zlib_inflateInit(&strm)) { ++ inf_strm.next_in = data_in; ++ inf_strm.avail_in = srclen; ++ inf_strm.total_in = 0; ++ ++ inf_strm.next_out = cpage_out; ++ inf_strm.avail_out = destlen; ++ inf_strm.total_out = 0; ++ ++ /* If it's deflate, and it's got no preset dictionary, then ++ we can tell zlib to skip the adler32 check. */ ++ if (srclen > 2 && !(data_in[1] & PRESET_DICT) && ++ ((data_in[0] & 0x0f) == Z_DEFLATED) && ++ !(((data_in[0]<<8) + data_in[1]) % 31)) { ++ ++ D2(printk(KERN_DEBUG "inflate skipping adler32\n")); ++ wbits = -((data_in[0] >> 4) + 8); ++ inf_strm.next_in += 2; ++ inf_strm.avail_in -= 2; ++ } else { ++ /* Let this remain D1 for now -- it should never happen */ ++ D1(printk(KERN_DEBUG "inflate not skipping adler32\n")); ++ } ++ ++ ++ if (Z_OK != zlib_inflateInit2(&inf_strm, wbits)) { + printk(KERN_WARNING "inflateInit failed\n"); + up(&inflate_sem); + return; + } +- strm.next_in = data_in; +- strm.avail_in = srclen; +- strm.total_in = 0; +- +- strm.next_out = cpage_out; +- strm.avail_out = destlen; +- strm.total_out = 0; + +- while((ret = zlib_inflate(&strm, Z_FINISH)) == Z_OK) ++ while((ret = zlib_inflate(&inf_strm, Z_FINISH)) == Z_OK) + ; + if (ret != Z_STREAM_END) { + printk(KERN_NOTICE "inflate returned %d\n", ret); + } +- zlib_inflateEnd(&strm); ++ zlib_inflateEnd(&inf_strm); + up(&inflate_sem); + } +diff -Nurb linux-mips-2.4.27/fs/jffs2/comprtest.c linux/fs/jffs2/comprtest.c +--- linux-mips-2.4.27/fs/jffs2/comprtest.c 2001-10-19 03:24:56.000000000 +0200 ++++ linux/fs/jffs2/comprtest.c 2004-11-19 10:25:12.093170304 +0100 +@@ -1,4 +1,4 @@ +-/* $Id: comprtest.c,v 1.4 2001/02/21 14:03:20 dwmw2 Exp $ */ ++/* $Id: comprtest.c,v 1.5 2002/01/03 15:20:44 dwmw2 Exp $ */ + + #include + #include +@@ -266,13 +266,13 @@ + static unsigned char decomprbuf[TESTDATA_LEN]; + + int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in, +- unsigned char *data_out, __u32 cdatalen, __u32 datalen); ++ unsigned char *data_out, uint32_t cdatalen, uint32_t datalen); + unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out, +- __u32 *datalen, __u32 *cdatalen); ++ uint32_t *datalen, uint32_t *cdatalen); + + int init_module(void ) { + unsigned char comprtype; +- __u32 c, d; ++ uint32_t c, d; + int ret; + + printk("Original data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", +diff -Nurb linux-mips-2.4.27/fs/jffs2/crc32.c linux/fs/jffs2/crc32.c +--- linux-mips-2.4.27/fs/jffs2/crc32.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/fs/jffs2/crc32.c 2004-11-19 10:25:12.095170000 +0100 +@@ -0,0 +1,97 @@ ++/* ++ * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or ++ * code or tables extracted from it, as desired without restriction. ++ * ++ * First, the polynomial itself and its table of feedback terms. The ++ * polynomial is ++ * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 ++ * ++ * Note that we take it "backwards" and put the highest-order term in ++ * the lowest-order bit. The X^32 term is "implied"; the LSB is the ++ * X^31 term, etc. The X^0 term (usually shown as "+1") results in ++ * the MSB being 1 ++ * ++ * Note that the usual hardware shift register implementation, which ++ * is what we're using (we're merely optimizing it by doing eight-bit ++ * chunks at a time) shifts bits into the lowest-order term. In our ++ * implementation, that means shifting towards the right. Why do we ++ * do it this way? Because the calculated CRC must be transmitted in ++ * order from highest-order term to lowest-order term. UARTs transmit ++ * characters in order from LSB to MSB. By storing the CRC this way ++ * we hand it to the UART in the order low-byte to high-byte; the UART ++ * sends each low-bit to hight-bit; and the result is transmission bit ++ * by bit from highest- to lowest-order term without requiring any bit ++ * shuffling on our part. Reception works similarly ++ * ++ * The feedback terms table consists of 256, 32-bit entries. Notes ++ * ++ * The table can be generated at runtime if desired; code to do so ++ * is shown later. It might not be obvious, but the feedback ++ * terms simply represent the results of eight shift/xor opera ++ * tions for all combinations of data and CRC register values ++ * ++ * The values must be right-shifted by eight bits by the "updcrc ++ * logic; the shift must be unsigned (bring in zeroes). On some ++ * hardware you could probably optimize the shift in assembler by ++ * using byte-swap instructions ++ * polynomial $edb88320 ++ */ ++ ++/* $Id: crc32.c,v 1.4 2002/01/03 15:20:44 dwmw2 Exp $ */ ++ ++#include "crc32.h" ++ ++const uint32_t crc32_table[256] = { ++ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, ++ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, ++ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, ++ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, ++ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, ++ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, ++ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, ++ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, ++ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, ++ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, ++ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, ++ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, ++ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, ++ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, ++ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, ++ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, ++ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, ++ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, ++ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, ++ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, ++ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, ++ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, ++ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, ++ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, ++ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, ++ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, ++ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, ++ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, ++ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, ++ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, ++ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, ++ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, ++ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, ++ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, ++ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, ++ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, ++ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, ++ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, ++ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, ++ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, ++ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, ++ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, ++ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, ++ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, ++ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, ++ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, ++ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, ++ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, ++ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, ++ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, ++ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, ++ 0x2d02ef8dL ++}; +diff -Nurb linux-mips-2.4.27/fs/jffs2/crc32.h linux/fs/jffs2/crc32.h +--- linux-mips-2.4.27/fs/jffs2/crc32.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux/fs/jffs2/crc32.h 2004-11-19 10:25:12.096169848 +0100 +@@ -0,0 +1,21 @@ ++#ifndef CRC32_H ++#define CRC32_H ++ ++/* $Id: crc32.h,v 1.4 2002/01/03 15:20:44 dwmw2 Exp $ */ ++ ++#include ++ ++extern const uint32_t crc32_table[256]; ++ ++/* Return a 32-bit CRC of the contents of the buffer. */ ++ ++static inline uint32_t ++crc32(uint32_t val, const void *ss, int len) ++{ ++ const unsigned char *s = ss; ++ while (--len >= 0) ++ val = crc32_table[(val ^ *s++) & 0xff] ^ (val >> 8); ++ return val; ++} ++ ++#endif +diff -Nurb linux-mips-2.4.27/fs/jffs2/dir.c linux/fs/jffs2/dir.c +--- linux-mips-2.4.27/fs/jffs2/dir.c 2003-11-17 02:07:44.000000000 +0100 ++++ linux/fs/jffs2/dir.c 2004-11-19 10:25:12.097169696 +0100 +@@ -1,84 +1,73 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: dir.c,v 1.45.2.8 2003/11/02 13:51:17 dwmw2 Exp $ ++ * $Id: dir.c,v 1.82 2003/10/11 11:47:23 dwmw2 Exp $ + * + */ + + #include + #include ++#include + #include +-#include /* For completion */ ++#include + #include + #include + #include ++#include + #include "nodelist.h" +-#include ++ ++/* Urgh. Please tell me there's a nicer way of doing these. */ ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,48) ++typedef int mknod_arg_t; ++#define NAMEI_COMPAT(x) ((void *)x) ++#else ++typedef dev_t mknod_arg_t; ++#define NAMEI_COMPAT(x) (x) ++#endif + + static int jffs2_readdir (struct file *, void *, filldir_t); + +-static int jffs2_create (struct inode *,struct dentry *,int); +-static struct dentry *jffs2_lookup (struct inode *,struct dentry *); ++static int jffs2_create (struct inode *,struct dentry *,int, ++ struct nameidata *); ++static struct dentry *jffs2_lookup (struct inode *,struct dentry *, ++ struct nameidata *); + static int jffs2_link (struct dentry *,struct inode *,struct dentry *); + static int jffs2_unlink (struct inode *,struct dentry *); + static int jffs2_symlink (struct inode *,struct dentry *,const char *); + static int jffs2_mkdir (struct inode *,struct dentry *,int); + static int jffs2_rmdir (struct inode *,struct dentry *); +-static int jffs2_mknod (struct inode *,struct dentry *,int,int); ++static int jffs2_mknod (struct inode *,struct dentry *,int,mknod_arg_t); + static int jffs2_rename (struct inode *, struct dentry *, + struct inode *, struct dentry *); + + struct file_operations jffs2_dir_operations = + { +- read: generic_read_dir, +- readdir: jffs2_readdir, +- ioctl: jffs2_ioctl, +- fsync: jffs2_null_fsync ++ .read = generic_read_dir, ++ .readdir = jffs2_readdir, ++ .ioctl = jffs2_ioctl, ++ .fsync = jffs2_fsync + }; + + + struct inode_operations jffs2_dir_inode_operations = + { +- create: jffs2_create, +- lookup: jffs2_lookup, +- link: jffs2_link, +- unlink: jffs2_unlink, +- symlink: jffs2_symlink, +- mkdir: jffs2_mkdir, +- rmdir: jffs2_rmdir, +- mknod: jffs2_mknod, +- rename: jffs2_rename, +- setattr: jffs2_setattr, ++ .create = NAMEI_COMPAT(jffs2_create), ++ .lookup = NAMEI_COMPAT(jffs2_lookup), ++ .link = jffs2_link, ++ .unlink = jffs2_unlink, ++ .symlink = jffs2_symlink, ++ .mkdir = jffs2_mkdir, ++ .rmdir = jffs2_rmdir, ++ .mknod = jffs2_mknod, ++ .rename = jffs2_rename, ++ .setattr = jffs2_setattr, + }; + + /***********************************************************************/ +@@ -88,12 +77,13 @@ + and we use the same hash function as the dentries. Makes this + nice and simple + */ +-static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target) ++static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, ++ struct nameidata *nd) + { + struct jffs2_inode_info *dir_f; + struct jffs2_sb_info *c; + struct jffs2_full_dirent *fd = NULL, *fd_list; +- __u32 ino = 0; ++ uint32_t ino = 0; + struct inode *inode = NULL; + + D1(printk(KERN_DEBUG "jffs2_lookup()\n")); +@@ -153,8 +143,9 @@ + offset++; + } + if (offset == 1) { +- D1(printk(KERN_DEBUG "Dirent 1: \"..\", ino #%lu\n", filp->f_dentry->d_parent->d_inode->i_ino)); +- if (filldir(dirent, "..", 2, 1, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) ++ unsigned long pino = parent_ino(filp->f_dentry); ++ D1(printk(KERN_DEBUG "Dirent 1: \"..\", ino #%lu\n", pino)); ++ if (filldir(dirent, "..", 2, 1, pino, DT_DIR) < 0) + goto out; + offset++; + } +@@ -188,18 +179,14 @@ + + /***********************************************************************/ + +-static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode) ++ ++static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, ++ struct nameidata *nd) + { ++ struct jffs2_raw_inode *ri; + struct jffs2_inode_info *f, *dir_f; + struct jffs2_sb_info *c; + struct inode *inode; +- struct jffs2_raw_inode *ri; +- struct jffs2_raw_dirent *rd; +- struct jffs2_full_dnode *fn; +- struct jffs2_full_dirent *fd; +- int namelen; +- __u32 alloclen, phys_ofs; +- __u32 writtenlen; + int ret; + + ri = jffs2_alloc_raw_inode(); +@@ -210,23 +197,11 @@ + + D1(printk(KERN_DEBUG "jffs2_create()\n")); + +- /* Try to reserve enough space for both node and dirent. +- * Just the node will do for now, though +- */ +- namelen = dentry->d_name.len; +- ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL); +- D1(printk(KERN_DEBUG "jffs2_create(): reserved 0x%x bytes\n", alloclen)); +- if (ret) { +- jffs2_free_raw_inode(ri); +- return ret; +- } +- + inode = jffs2_new_inode(dir_i, mode, ri); + + if (IS_ERR(inode)) { + D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n")); + jffs2_free_raw_inode(ri); +- jffs2_complete_reservation(c); + return PTR_ERR(inode); + } + +@@ -236,93 +211,22 @@ + inode->i_mapping->nrpages = 0; + + f = JFFS2_INODE_INFO(inode); ++ dir_f = JFFS2_INODE_INFO(dir_i); + +- ri->data_crc = 0; +- ri->node_crc = crc32(0, ri, sizeof(*ri)-8); +- +- fn = jffs2_write_dnode(inode, ri, NULL, 0, phys_ofs, &writtenlen); +- D1(printk(KERN_DEBUG "jffs2_create created file with mode 0x%x\n", ri->mode)); +- jffs2_free_raw_inode(ri); +- +- if (IS_ERR(fn)) { +- D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n")); +- /* Eeek. Wave bye bye */ +- up(&f->sem); +- jffs2_complete_reservation(c); +- jffs2_clear_inode(inode); +- return PTR_ERR(fn); +- } +- /* No data here. Only a metadata node, which will be +- obsoleted by the first data write +- */ +- f->metadata = fn; +- +- /* Work out where to put the dirent node now. */ +- writtenlen = PAD(writtenlen); +- phys_ofs += writtenlen; +- alloclen -= writtenlen; +- up(&f->sem); +- +- if (alloclen < sizeof(*rd)+namelen) { +- /* Not enough space left in this chunk. Get some more */ +- jffs2_complete_reservation(c); +- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); ++ ret = jffs2_do_create(c, dir_f, f, ri, ++ dentry->d_name.name, dentry->d_name.len); + + if (ret) { +- /* Eep. */ +- D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n")); + jffs2_clear_inode(inode); ++ make_bad_inode(inode); ++ iput(inode); ++ jffs2_free_raw_inode(ri); + return ret; + } +- } + +- rd = jffs2_alloc_raw_dirent(); +- if (!rd) { +- /* Argh. Now we treat it like a normal delete */ +- jffs2_complete_reservation(c); +- jffs2_clear_inode(inode); +- return -ENOMEM; +- } +- +- dir_f = JFFS2_INODE_INFO(dir_i); +- down(&dir_f->sem); +- +- rd->magic = JFFS2_MAGIC_BITMASK; +- rd->nodetype = JFFS2_NODETYPE_DIRENT; +- rd->totlen = sizeof(*rd) + namelen; +- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4); +- +- rd->pino = dir_i->i_ino; +- rd->version = ++dir_f->highest_version; +- rd->ino = inode->i_ino; +- rd->mctime = CURRENT_TIME; +- rd->nsize = namelen; +- rd->type = DT_REG; +- rd->node_crc = crc32(0, rd, sizeof(*rd)-8); +- rd->name_crc = crc32(0, dentry->d_name.name, namelen); +- +- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen); +- +- jffs2_complete_reservation(c); +- +- if (IS_ERR(fd)) { +- /* dirent failed to write. Delete the inode normally +- as if it were the final unlink() */ +- jffs2_free_raw_dirent(rd); +- up(&dir_f->sem); +- jffs2_clear_inode(inode); +- return PTR_ERR(fd); +- } +- +- dir_i->i_mtime = dir_i->i_ctime = rd->mctime; +- +- jffs2_free_raw_dirent(rd); +- +- /* Link the fd into the inode's list, obsoleting an old +- one if necessary. */ +- jffs2_add_fd_to_list(c, fd, &dir_f->dents); +- up(&dir_f->sem); ++ dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime)); + ++ jffs2_free_raw_inode(ri); + d_instantiate(dentry, inode); + + D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", +@@ -332,173 +236,48 @@ + + /***********************************************************************/ + +-static int jffs2_do_unlink(struct inode *dir_i, struct dentry *dentry, int rename) +-{ +- struct jffs2_inode_info *dir_f, *f; +- struct jffs2_sb_info *c; +- struct jffs2_raw_dirent *rd; +- struct jffs2_full_dirent *fd; +- __u32 alloclen, phys_ofs; +- int ret; +- +- c = JFFS2_SB_INFO(dir_i->i_sb); +- +- rd = jffs2_alloc_raw_dirent(); +- if (!rd) +- return -ENOMEM; +- +- ret = jffs2_reserve_space(c, sizeof(*rd)+dentry->d_name.len, &phys_ofs, &alloclen, ALLOC_DELETION); +- if (ret) { +- jffs2_free_raw_dirent(rd); +- return ret; +- } +- +- dir_f = JFFS2_INODE_INFO(dir_i); +- down(&dir_f->sem); +- +- /* Build a deletion node */ +- rd->magic = JFFS2_MAGIC_BITMASK; +- rd->nodetype = JFFS2_NODETYPE_DIRENT; +- rd->totlen = sizeof(*rd) + dentry->d_name.len; +- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4); +- +- rd->pino = dir_i->i_ino; +- rd->version = ++dir_f->highest_version; +- rd->ino = 0; +- rd->mctime = CURRENT_TIME; +- rd->nsize = dentry->d_name.len; +- rd->type = DT_UNKNOWN; +- rd->node_crc = crc32(0, rd, sizeof(*rd)-8); +- rd->name_crc = crc32(0, dentry->d_name.name, dentry->d_name.len); +- +- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, dentry->d_name.len, phys_ofs, NULL); +- +- jffs2_complete_reservation(c); +- jffs2_free_raw_dirent(rd); +- +- if (IS_ERR(fd)) { +- up(&dir_f->sem); +- return PTR_ERR(fd); +- } +- +- /* File it. This will mark the old one obsolete. */ +- jffs2_add_fd_to_list(c, fd, &dir_f->dents); +- up(&dir_f->sem); +- +- if (!rename) { +- f = JFFS2_INODE_INFO(dentry->d_inode); +- down(&f->sem); +- +- while (f->dents) { +- /* There can be only deleted ones */ +- fd = f->dents; +- +- f->dents = fd->next; +- +- if (fd->ino) { +- printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n", +- f->inocache->ino, fd->name, fd->ino); +- } else { +- D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", fd->name, f->inocache->ino)); +- } +- jffs2_mark_node_obsolete(c, fd->raw); +- jffs2_free_full_dirent(fd); +- } +- /* Don't oops on unlinking a bad inode */ +- if (f->inocache) +- f->inocache->nlink--; +- dentry->d_inode->i_nlink--; +- up(&f->sem); +- } +- +- return 0; +-} + + static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry) + { +- return jffs2_do_unlink(dir_i, dentry, 0); +-} +-/***********************************************************************/ +- +-static int jffs2_do_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry, int rename) +-{ +- struct jffs2_inode_info *dir_f, *f; +- struct jffs2_sb_info *c; +- struct jffs2_raw_dirent *rd; +- struct jffs2_full_dirent *fd; +- __u32 alloclen, phys_ofs; ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb); ++ struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); ++ struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(dentry->d_inode); + int ret; + +- c = JFFS2_SB_INFO(dir_i->i_sb); +- +- rd = jffs2_alloc_raw_dirent(); +- if (!rd) +- return -ENOMEM; +- +- ret = jffs2_reserve_space(c, sizeof(*rd)+dentry->d_name.len, &phys_ofs, &alloclen, ALLOC_NORMAL); +- if (ret) { +- jffs2_free_raw_dirent(rd); ++ ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, ++ dentry->d_name.len, dead_f); ++ if (dead_f->inocache) ++ dentry->d_inode->i_nlink = dead_f->inocache->nlink; + return ret; +- } +- +- dir_f = JFFS2_INODE_INFO(dir_i); +- down(&dir_f->sem); +- +- /* Build a deletion node */ +- rd->magic = JFFS2_MAGIC_BITMASK; +- rd->nodetype = JFFS2_NODETYPE_DIRENT; +- rd->totlen = sizeof(*rd) + dentry->d_name.len; +- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4); +- +- rd->pino = dir_i->i_ino; +- rd->version = ++dir_f->highest_version; +- rd->ino = old_dentry->d_inode->i_ino; +- rd->mctime = CURRENT_TIME; +- rd->nsize = dentry->d_name.len; +- +- /* XXX: This is ugly. */ +- rd->type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12; +- if (!rd->type) rd->type = DT_REG; +- +- rd->node_crc = crc32(0, rd, sizeof(*rd)-8); +- rd->name_crc = crc32(0, dentry->d_name.name, dentry->d_name.len); +- +- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, dentry->d_name.len, phys_ofs, NULL); +- +- jffs2_complete_reservation(c); +- jffs2_free_raw_dirent(rd); +- +- if (IS_ERR(fd)) { +- up(&dir_f->sem); +- return PTR_ERR(fd); +- } +- +- /* File it. This will mark the old one obsolete. */ +- jffs2_add_fd_to_list(c, fd, &dir_f->dents); +- up(&dir_f->sem); +- +- if (!rename) { +- f = JFFS2_INODE_INFO(old_dentry->d_inode); +- down(&f->sem); +- old_dentry->d_inode->i_nlink = ++f->inocache->nlink; +- up(&f->sem); +- } +- return 0; + } ++/***********************************************************************/ ++ + + static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry) + { ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dentry->d_inode->i_sb); ++ struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode); ++ struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); + int ret; ++ uint8_t type; + +- /* Can't link a bad inode. */ +- if (!JFFS2_INODE_INFO(old_dentry->d_inode)->inocache) ++ /* Don't let people make hard links to bad inodes. */ ++ if (!f->inocache) + return -EIO; + + if (S_ISDIR(old_dentry->d_inode->i_mode)) + return -EPERM; + +- ret = jffs2_do_link(old_dentry, dir_i, dentry, 0); ++ /* XXX: This is ugly */ ++ type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12; ++ if (!type) type = DT_REG; ++ ++ ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len); ++ + if (!ret) { ++ down(&f->sem); ++ old_dentry->d_inode->i_nlink = ++f->inocache->nlink; ++ up(&f->sem); + d_instantiate(dentry, old_dentry->d_inode); + atomic_inc(&old_dentry->d_inode->i_count); + } +@@ -517,8 +296,7 @@ + struct jffs2_full_dnode *fn; + struct jffs2_full_dirent *fd; + int namelen; +- __u32 alloclen, phys_ofs; +- __u32 writtenlen; ++ uint32_t alloclen, phys_ofs; + int ret; + + /* FIXME: If you care. We'd need to use frags for the target +@@ -556,15 +334,16 @@ + + f = JFFS2_INODE_INFO(inode); + +- inode->i_size = ri->isize = ri->dsize = ri->csize = strlen(target); +- ri->totlen = sizeof(*ri) + ri->dsize; +- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4); ++ inode->i_size = strlen(target); ++ ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size); ++ ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size); ++ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); + + ri->compr = JFFS2_COMPR_NONE; +- ri->data_crc = crc32(0, target, strlen(target)); +- ri->node_crc = crc32(0, ri, sizeof(*ri)-8); ++ ri->data_crc = cpu_to_je32(crc32(0, target, strlen(target))); ++ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); + +- fn = jffs2_write_dnode(inode, ri, target, strlen(target), phys_ofs, &writtenlen); ++ fn = jffs2_write_dnode(c, f, ri, target, strlen(target), phys_ofs, ALLOC_NORMAL); + + jffs2_free_raw_inode(ri); + +@@ -581,13 +360,6 @@ + f->metadata = fn; + up(&f->sem); + +- /* Work out where to put the dirent node now. */ +- writtenlen = (writtenlen+3)&~3; +- phys_ofs += writtenlen; +- alloclen -= writtenlen; +- +- if (alloclen < sizeof(*rd)+namelen) { +- /* Not enough space left in this chunk. Get some more */ + jffs2_complete_reservation(c); + ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); + if (ret) { +@@ -595,7 +367,6 @@ + jffs2_clear_inode(inode); + return ret; + } +- } + + rd = jffs2_alloc_raw_dirent(); + if (!rd) { +@@ -608,41 +379,42 @@ + dir_f = JFFS2_INODE_INFO(dir_i); + down(&dir_f->sem); + +- rd->magic = JFFS2_MAGIC_BITMASK; +- rd->nodetype = JFFS2_NODETYPE_DIRENT; +- rd->totlen = sizeof(*rd) + namelen; +- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4); +- +- rd->pino = dir_i->i_ino; +- rd->version = ++dir_f->highest_version; +- rd->ino = inode->i_ino; +- rd->mctime = CURRENT_TIME; ++ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); ++ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); ++ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); ++ ++ rd->pino = cpu_to_je32(dir_i->i_ino); ++ rd->version = cpu_to_je32(++dir_f->highest_version); ++ rd->ino = cpu_to_je32(inode->i_ino); ++ rd->mctime = cpu_to_je32(get_seconds()); + rd->nsize = namelen; + rd->type = DT_LNK; +- rd->node_crc = crc32(0, rd, sizeof(*rd)-8); +- rd->name_crc = crc32(0, dentry->d_name.name, namelen); ++ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); ++ rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); + +- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen); +- +- jffs2_complete_reservation(c); ++ fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); + + if (IS_ERR(fd)) { + /* dirent failed to write. Delete the inode normally + as if it were the final unlink() */ ++ jffs2_complete_reservation(c); + jffs2_free_raw_dirent(rd); + up(&dir_f->sem); + jffs2_clear_inode(inode); + return PTR_ERR(fd); + } + +- dir_i->i_mtime = dir_i->i_ctime = rd->mctime; ++ dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); + + jffs2_free_raw_dirent(rd); + + /* Link the fd into the inode's list, obsoleting an old + one if necessary. */ + jffs2_add_fd_to_list(c, fd, &dir_f->dents); ++ + up(&dir_f->sem); ++ jffs2_complete_reservation(c); + + d_instantiate(dentry, inode); + return 0; +@@ -659,8 +431,7 @@ + struct jffs2_full_dnode *fn; + struct jffs2_full_dirent *fd; + int namelen; +- __u32 alloclen, phys_ofs; +- __u32 writtenlen; ++ uint32_t alloclen, phys_ofs; + int ret; + + mode |= S_IFDIR; +@@ -692,13 +463,15 @@ + + inode->i_op = &jffs2_dir_inode_operations; + inode->i_fop = &jffs2_dir_operations; ++ /* Directories get nlink 2 at start */ ++ inode->i_nlink = 2; + + f = JFFS2_INODE_INFO(inode); + +- ri->data_crc = 0; +- ri->node_crc = crc32(0, ri, sizeof(*ri)-8); ++ ri->data_crc = cpu_to_je32(0); ++ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); + +- fn = jffs2_write_dnode(inode, ri, NULL, 0, phys_ofs, &writtenlen); ++ fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); + + jffs2_free_raw_inode(ri); + +@@ -715,13 +488,6 @@ + f->metadata = fn; + up(&f->sem); + +- /* Work out where to put the dirent node now. */ +- writtenlen = PAD(writtenlen); +- phys_ofs += writtenlen; +- alloclen -= writtenlen; +- +- if (alloclen < sizeof(*rd)+namelen) { +- /* Not enough space left in this chunk. Get some more */ + jffs2_complete_reservation(c); + ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); + if (ret) { +@@ -729,7 +495,6 @@ + jffs2_clear_inode(inode); + return ret; + } +- } + + rd = jffs2_alloc_raw_dirent(); + if (!rd) { +@@ -742,41 +507,43 @@ + dir_f = JFFS2_INODE_INFO(dir_i); + down(&dir_f->sem); + +- rd->magic = JFFS2_MAGIC_BITMASK; +- rd->nodetype = JFFS2_NODETYPE_DIRENT; +- rd->totlen = sizeof(*rd) + namelen; +- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4); +- +- rd->pino = dir_i->i_ino; +- rd->version = ++dir_f->highest_version; +- rd->ino = inode->i_ino; +- rd->mctime = CURRENT_TIME; ++ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); ++ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); ++ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); ++ ++ rd->pino = cpu_to_je32(dir_i->i_ino); ++ rd->version = cpu_to_je32(++dir_f->highest_version); ++ rd->ino = cpu_to_je32(inode->i_ino); ++ rd->mctime = cpu_to_je32(get_seconds()); + rd->nsize = namelen; + rd->type = DT_DIR; +- rd->node_crc = crc32(0, rd, sizeof(*rd)-8); +- rd->name_crc = crc32(0, dentry->d_name.name, namelen); ++ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); ++ rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); + +- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen); +- +- jffs2_complete_reservation(c); ++ fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); + + if (IS_ERR(fd)) { + /* dirent failed to write. Delete the inode normally + as if it were the final unlink() */ ++ jffs2_complete_reservation(c); + jffs2_free_raw_dirent(rd); + up(&dir_f->sem); + jffs2_clear_inode(inode); + return PTR_ERR(fd); + } + +- dir_i->i_mtime = dir_i->i_ctime = rd->mctime; ++ dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); ++ dir_i->i_nlink++; + + jffs2_free_raw_dirent(rd); + + /* Link the fd into the inode's list, obsoleting an old + one if necessary. */ + jffs2_add_fd_to_list(c, fd, &dir_f->dents); ++ + up(&dir_f->sem); ++ jffs2_complete_reservation(c); + + d_instantiate(dentry, inode); + return 0; +@@ -786,15 +553,19 @@ + { + struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); + struct jffs2_full_dirent *fd; ++ int ret; + + for (fd = f->dents ; fd; fd = fd->next) { + if (fd->ino) + return -ENOTEMPTY; + } +- return jffs2_unlink(dir_i, dentry); ++ ret = jffs2_unlink(dir_i, dentry); ++ if (!ret) ++ dir_i->i_nlink--; ++ return ret; + } + +-static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, int rdev) ++static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mknod_arg_t rdev) + { + struct jffs2_inode_info *f, *dir_f; + struct jffs2_sb_info *c; +@@ -804,12 +575,14 @@ + struct jffs2_full_dnode *fn; + struct jffs2_full_dirent *fd; + int namelen; +- unsigned short dev; ++ jint16_t dev; + int devlen = 0; +- __u32 alloclen, phys_ofs; +- __u32 writtenlen; ++ uint32_t alloclen, phys_ofs; + int ret; + ++ if (!old_valid_dev(rdev)) ++ return -EINVAL; ++ + ri = jffs2_alloc_raw_inode(); + if (!ri) + return -ENOMEM; +@@ -817,7 +590,7 @@ + c = JFFS2_SB_INFO(dir_i->i_sb); + + if (S_ISBLK(mode) || S_ISCHR(mode)) { +- dev = (MAJOR(to_kdev_t(rdev)) << 8) | MINOR(to_kdev_t(rdev)); ++ dev = cpu_to_je16(old_encode_dev(rdev)); + devlen = sizeof(dev); + } + +@@ -844,15 +617,15 @@ + + f = JFFS2_INODE_INFO(inode); + +- ri->dsize = ri->csize = devlen; +- ri->totlen = sizeof(*ri) + ri->csize; +- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4); ++ ri->dsize = ri->csize = cpu_to_je32(devlen); ++ ri->totlen = cpu_to_je32(sizeof(*ri) + devlen); ++ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); + + ri->compr = JFFS2_COMPR_NONE; +- ri->data_crc = crc32(0, &dev, devlen); +- ri->node_crc = crc32(0, ri, sizeof(*ri)-8); ++ ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen)); ++ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); + +- fn = jffs2_write_dnode(inode, ri, (char *)&dev, devlen, phys_ofs, &writtenlen); ++ fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, phys_ofs, ALLOC_NORMAL); + + jffs2_free_raw_inode(ri); + +@@ -869,13 +642,6 @@ + f->metadata = fn; + up(&f->sem); + +- /* Work out where to put the dirent node now. */ +- writtenlen = (writtenlen+3)&~3; +- phys_ofs += writtenlen; +- alloclen -= writtenlen; +- +- if (alloclen < sizeof(*rd)+namelen) { +- /* Not enough space left in this chunk. Get some more */ + jffs2_complete_reservation(c); + ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); + if (ret) { +@@ -883,7 +649,6 @@ + jffs2_clear_inode(inode); + return ret; + } +- } + + rd = jffs2_alloc_raw_dirent(); + if (!rd) { +@@ -896,44 +661,45 @@ + dir_f = JFFS2_INODE_INFO(dir_i); + down(&dir_f->sem); + +- rd->magic = JFFS2_MAGIC_BITMASK; +- rd->nodetype = JFFS2_NODETYPE_DIRENT; +- rd->totlen = sizeof(*rd) + namelen; +- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4); +- +- rd->pino = dir_i->i_ino; +- rd->version = ++dir_f->highest_version; +- rd->ino = inode->i_ino; +- rd->mctime = CURRENT_TIME; ++ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); ++ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); ++ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); ++ ++ rd->pino = cpu_to_je32(dir_i->i_ino); ++ rd->version = cpu_to_je32(++dir_f->highest_version); ++ rd->ino = cpu_to_je32(inode->i_ino); ++ rd->mctime = cpu_to_je32(get_seconds()); + rd->nsize = namelen; + + /* XXX: This is ugly. */ + rd->type = (mode & S_IFMT) >> 12; + +- rd->node_crc = crc32(0, rd, sizeof(*rd)-8); +- rd->name_crc = crc32(0, dentry->d_name.name, namelen); +- +- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen); ++ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); ++ rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen)); + +- jffs2_complete_reservation(c); ++ fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL); + + if (IS_ERR(fd)) { + /* dirent failed to write. Delete the inode normally + as if it were the final unlink() */ ++ jffs2_complete_reservation(c); + jffs2_free_raw_dirent(rd); + up(&dir_f->sem); + jffs2_clear_inode(inode); + return PTR_ERR(fd); + } + +- dir_i->i_mtime = dir_i->i_ctime = rd->mctime; ++ dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); + + jffs2_free_raw_dirent(rd); + + /* Link the fd into the inode's list, obsoleting an old + one if necessary. */ + jffs2_add_fd_to_list(c, fd, &dir_f->dents); ++ + up(&dir_f->sem); ++ jffs2_complete_reservation(c); + + d_instantiate(dentry, inode); + +@@ -944,7 +710,9 @@ + struct inode *new_dir_i, struct dentry *new_dentry) + { + int ret; ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); + struct jffs2_inode_info *victim_f = NULL; ++ uint8_t type; + + /* The VFS will check for us and prevent trying to rename a + * file over a directory and vice versa, but if it's a directory, +@@ -973,7 +741,15 @@ + */ + + /* Make a hard link */ +- ret = jffs2_do_link(old_dentry, new_dir_i, new_dentry, 1); ++ ++ /* XXX: This is ugly */ ++ type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12; ++ if (!type) type = DT_REG; ++ ++ ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i), ++ old_dentry->d_inode->i_ino, type, ++ new_dentry->d_name.name, new_dentry->d_name.len); ++ + if (ret) + return ret; + +@@ -989,22 +765,36 @@ + } + } + ++ /* If it was a directory we moved, and there was no victim, ++ increase i_nlink on its new parent */ ++ if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f) ++ new_dir_i->i_nlink++; ++ + /* Unlink the original */ +- ret = jffs2_do_unlink(old_dir_i, old_dentry, 1); ++ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), ++ old_dentry->d_name.name, old_dentry->d_name.len, NULL); ++ ++ /* We don't touch inode->i_nlink */ + + if (ret) { + /* Oh shit. We really ought to make a single node which can do both atomically */ + struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode); + down(&f->sem); ++ old_dentry->d_inode->i_nlink++; + if (f->inocache) +- old_dentry->d_inode->i_nlink = f->inocache->nlink++; ++ f->inocache->nlink++; + up(&f->sem); + + printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret); + /* Might as well let the VFS know */ + d_instantiate(new_dentry, old_dentry->d_inode); + atomic_inc(&old_dentry->d_inode->i_count); +- } + return ret; ++ } ++ ++ if (S_ISDIR(old_dentry->d_inode->i_mode)) ++ old_dir_i->i_nlink--; ++ ++ return 0; + } + +diff -Nurb linux-mips-2.4.27/fs/jffs2/erase.c linux/fs/jffs2/erase.c +--- linux-mips-2.4.27/fs/jffs2/erase.c 2003-11-17 02:07:44.000000000 +0100 ++++ linux/fs/jffs2/erase.c 2004-11-19 10:25:12.099169392 +0100 +@@ -1,68 +1,60 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: erase.c,v 1.24.2.1 2003/11/02 13:51:17 dwmw2 Exp $ ++ * $Id: erase.c,v 1.58 2003/11/26 13:02:46 dwmw2 Exp $ + * + */ ++ + #include + #include + #include +-#include +-#include +-#include "nodelist.h" ++#include + #include ++#include ++#include ++#include "nodelist.h" + + struct erase_priv_struct { + struct jffs2_eraseblock *jeb; + struct jffs2_sb_info *c; + }; + ++#ifndef __ECOS + static void jffs2_erase_callback(struct erase_info *); ++#endif ++static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); ++static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); + static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); ++static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); + + void jffs2_erase_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) + { +- struct erase_info *instr; + int ret; ++#ifdef __ECOS ++ ret = jffs2_flash_erase(c, jeb); ++ if (!ret) { ++ jffs2_erase_succeeded(c, jeb); ++ return; ++ } ++#else /* Linux */ ++ struct erase_info *instr; + + instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL); + if (!instr) { + printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n"); +- spin_lock_bh(&c->erase_completion_lock); ++ spin_lock(&c->erase_completion_lock); + list_del(&jeb->list); + list_add(&jeb->list, &c->erase_pending_list); + c->erasing_size -= c->sector_size; +- spin_unlock_bh(&c->erase_completion_lock); ++ c->dirty_size += c->sector_size; ++ jeb->dirty_size = c->sector_size; ++ spin_unlock(&c->erase_completion_lock); + return; + } + +@@ -77,19 +69,27 @@ + ((struct erase_priv_struct *)instr->priv)->jeb = jeb; + ((struct erase_priv_struct *)instr->priv)->c = c; + ++ /* NAND , read out the fail counter, if possible */ ++ if (!jffs2_can_mark_obsolete(c)) ++ jffs2_nand_read_failcnt(c,jeb); ++ + ret = c->mtd->erase(c->mtd, instr); +- if (!ret) { ++ if (!ret) + return; +- } ++ ++ kfree(instr); ++#endif /* __ECOS */ ++ + if (ret == -ENOMEM || ret == -EAGAIN) { + /* Erase failed immediately. Refile it on the list */ + D1(printk(KERN_DEBUG "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", jeb->offset, ret)); +- spin_lock_bh(&c->erase_completion_lock); ++ spin_lock(&c->erase_completion_lock); + list_del(&jeb->list); + list_add(&jeb->list, &c->erase_pending_list); + c->erasing_size -= c->sector_size; +- spin_unlock_bh(&c->erase_completion_lock); +- kfree(instr); ++ c->dirty_size += c->sector_size; ++ jeb->dirty_size = c->sector_size; ++ spin_unlock(&c->erase_completion_lock); + return; + } + +@@ -97,74 +97,101 @@ + printk(KERN_WARNING "Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n", jeb->offset); + else + printk(KERN_WARNING "Erase at 0x%08x failed immediately: errno %d\n", jeb->offset, ret); +- spin_lock_bh(&c->erase_completion_lock); +- list_del(&jeb->list); +- list_add(&jeb->list, &c->bad_list); +- c->nr_erasing_blocks--; +- c->bad_size += c->sector_size; +- c->erasing_size -= c->sector_size; +- spin_unlock_bh(&c->erase_completion_lock); +- wake_up(&c->erase_wait); +- kfree(instr); ++ ++ jffs2_erase_failed(c, jeb); + } + +-void jffs2_erase_pending_blocks(struct jffs2_sb_info *c) ++void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count) + { + struct jffs2_eraseblock *jeb; + +- spin_lock_bh(&c->erase_completion_lock); +- while (!list_empty(&c->erase_pending_list)) { ++ down(&c->erase_free_sem); + +- jeb = list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list); ++ spin_lock(&c->erase_completion_lock); + +- D1(printk(KERN_DEBUG "Starting erase of pending block 0x%08x\n", jeb->offset)); ++ while (!list_empty(&c->erase_complete_list) || ++ !list_empty(&c->erase_pending_list)) { + ++ if (!list_empty(&c->erase_complete_list)) { ++ jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list); ++ list_del(&jeb->list); ++ spin_unlock(&c->erase_completion_lock); ++ jffs2_mark_erased_block(c, jeb); ++ ++ if (!--count) { ++ D1(printk(KERN_DEBUG "Count reached. jffs2_erase_pending_blocks leaving\n")); ++ goto done; ++ } ++ ++ } else if (!list_empty(&c->erase_pending_list)) { ++ jeb = list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list); ++ D1(printk(KERN_DEBUG "Starting erase of pending block 0x%08x\n", jeb->offset)); + list_del(&jeb->list); + c->erasing_size += c->sector_size; ++ c->wasted_size -= jeb->wasted_size; + c->free_size -= jeb->free_size; + c->used_size -= jeb->used_size; + c->dirty_size -= jeb->dirty_size; +- jeb->used_size = jeb->dirty_size = jeb->free_size = 0; ++ jeb->wasted_size = jeb->used_size = jeb->dirty_size = jeb->free_size = 0; + jffs2_free_all_node_refs(c, jeb); + list_add(&jeb->list, &c->erasing_list); +- spin_unlock_bh(&c->erase_completion_lock); ++ spin_unlock(&c->erase_completion_lock); + + jffs2_erase_block(c, jeb); ++ ++ } else { ++ BUG(); ++ } ++ + /* Be nice */ +- if (current->need_resched) +- schedule(); +- spin_lock_bh(&c->erase_completion_lock); ++ cond_resched(); ++ spin_lock(&c->erase_completion_lock); + } +- spin_unlock_bh(&c->erase_completion_lock); ++ ++ spin_unlock(&c->erase_completion_lock); ++ done: + D1(printk(KERN_DEBUG "jffs2_erase_pending_blocks completed\n")); ++ ++ up(&c->erase_free_sem); ++} ++ ++static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) ++{ ++ D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", jeb->offset)); ++ spin_lock(&c->erase_completion_lock); ++ list_del(&jeb->list); ++ list_add_tail(&jeb->list, &c->erase_complete_list); ++ spin_unlock(&c->erase_completion_lock); ++ /* Ensure that kupdated calls us again to mark them clean */ ++ jffs2_erase_pending_trigger(c); + } + ++static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) ++{ ++ spin_lock(&c->erase_completion_lock); ++ c->erasing_size -= c->sector_size; ++ c->bad_size += c->sector_size; ++ list_del(&jeb->list); ++ list_add(&jeb->list, &c->bad_list); ++ c->nr_erasing_blocks--; ++ spin_unlock(&c->erase_completion_lock); ++ wake_up(&c->erase_wait); ++} + ++#ifndef __ECOS + static void jffs2_erase_callback(struct erase_info *instr) + { + struct erase_priv_struct *priv = (void *)instr->priv; + + if(instr->state != MTD_ERASE_DONE) { + printk(KERN_WARNING "Erase at 0x%08x finished, but state != MTD_ERASE_DONE. State is 0x%x instead.\n", instr->addr, instr->state); +- spin_lock(&priv->c->erase_completion_lock); +- priv->c->erasing_size -= priv->c->sector_size; +- priv->c->bad_size += priv->c->sector_size; +- list_del(&priv->jeb->list); +- list_add(&priv->jeb->list, &priv->c->bad_list); +- priv->c->nr_erasing_blocks--; +- spin_unlock(&priv->c->erase_completion_lock); +- wake_up(&priv->c->erase_wait); ++ jffs2_erase_failed(priv->c, priv->jeb); + } else { +- D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", instr->addr)); +- spin_lock(&priv->c->erase_completion_lock); +- list_del(&priv->jeb->list); +- list_add_tail(&priv->jeb->list, &priv->c->erase_complete_list); +- spin_unlock(&priv->c->erase_completion_lock); ++ jffs2_erase_succeeded(priv->c, priv->jeb); + } +- /* Make sure someone picks up the block off the erase_complete list */ +- OFNI_BS_2SFFJ(priv->c)->s_dirt = 1; + kfree(instr); + } ++#endif /* !__ECOS */ + + /* Hmmm. Maybe we should accept the extra space it takes and make + this a standard doubly-linked list? */ +@@ -221,7 +248,7 @@ + this = ic->nodes; + + while(this) { +- printk( "0x%08x(%d)->", this->flash_offset & ~3, this->flash_offset &3); ++ printk( "0x%08x(%d)->", ref_offset(this), ref_flags(this)); + if (++i == 5) { + printk("\n" KERN_DEBUG); + i=0; +@@ -256,54 +283,43 @@ + jeb->last_node = NULL; + } + +-void jffs2_erase_pending_trigger(struct jffs2_sb_info *c) ++static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) + { +- OFNI_BS_2SFFJ(c)->s_dirt = 1; +-} +- +-void jffs2_mark_erased_blocks(struct jffs2_sb_info *c) +-{ +- static struct jffs2_unknown_node marker = {JFFS2_MAGIC_BITMASK, JFFS2_NODETYPE_CLEANMARKER, sizeof(struct jffs2_unknown_node)}; +- struct jffs2_eraseblock *jeb; +- struct jffs2_raw_node_ref *marker_ref; ++ struct jffs2_raw_node_ref *marker_ref = NULL; + unsigned char *ebuf; +- ssize_t retlen; ++ size_t retlen; + int ret; + +- marker.hdr_crc = crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4); +- +- spin_lock_bh(&c->erase_completion_lock); +- while (!list_empty(&c->erase_complete_list)) { +- jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list); +- list_del(&jeb->list); +- spin_unlock_bh(&c->erase_completion_lock); +- ++ if (!jffs2_cleanmarker_oob(c)) { + marker_ref = jffs2_alloc_raw_node_ref(); + if (!marker_ref) { + printk(KERN_WARNING "Failed to allocate raw node ref for clean marker\n"); +- /* Come back later */ ++ /* Stick it back on the list from whence it came and come back later */ + jffs2_erase_pending_trigger(c); ++ spin_lock(&c->erase_completion_lock); ++ list_add(&jeb->list, &c->erase_complete_list); ++ spin_unlock(&c->erase_completion_lock); + return; + } +- ++ } + ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!ebuf) { + printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Assuming it worked\n", jeb->offset); + } else { +- __u32 ofs = jeb->offset; ++ uint32_t ofs = jeb->offset; + + D1(printk(KERN_DEBUG "Verifying erase at 0x%08x\n", jeb->offset)); + while(ofs < jeb->offset + c->sector_size) { +- __u32 readlen = min((__u32)PAGE_SIZE, jeb->offset + c->sector_size - ofs); ++ uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs); + int i; + +- ret = c->mtd->read(c->mtd, ofs, readlen, &retlen, ebuf); +- if (ret < 0) { ++ ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf); ++ if (ret) { + printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret); + goto bad; + } + if (retlen != readlen) { +- printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %d\n", ofs, readlen, retlen); ++ printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n", ofs, readlen, retlen); + goto bad; + } + for (i=0; ierase_completion_lock); ++ spin_lock(&c->erase_completion_lock); + c->erasing_size -= c->sector_size; + c->bad_size += c->sector_size; + + list_add_tail(&jeb->list, &c->bad_list); + c->nr_erasing_blocks--; +- spin_unlock_bh(&c->erase_completion_lock); ++ spin_unlock(&c->erase_completion_lock); + wake_up(&c->erase_wait); + return; + } + } + ofs += readlen; ++ cond_resched(); + } + kfree(ebuf); + } + + /* Write the erase complete marker */ + D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset)); +- ret = c->mtd->write(c->mtd, jeb->offset, sizeof(marker), &retlen, (char *)&marker); ++ if (jffs2_cleanmarker_oob(c)) { ++ ++ if (jffs2_write_nand_cleanmarker(c, jeb)) ++ goto bad2; ++ ++ jeb->first_node = jeb->last_node = NULL; ++ ++ jeb->free_size = c->sector_size; ++ jeb->used_size = 0; ++ jeb->dirty_size = 0; ++ jeb->wasted_size = 0; ++ } else { ++ struct jffs2_unknown_node marker = { ++ .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK), ++ .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), ++ .totlen = cpu_to_je32(c->cleanmarker_size) ++ }; ++ ++ marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4)); ++ ++ /* We only write the header; the rest was noise or padding anyway */ ++ ret = jffs2_flash_write(c, jeb->offset, sizeof(marker), &retlen, (char *)&marker); + if (ret) { + printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n", + jeb->offset, ret); + goto bad2; + } + if (retlen != sizeof(marker)) { +- printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %d, got %d\n", ++ printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %d, got %zd\n", + jeb->offset, sizeof(marker), retlen); + goto bad2; + } + + marker_ref->next_in_ino = NULL; + marker_ref->next_phys = NULL; +- marker_ref->flash_offset = jeb->offset; +- marker_ref->totlen = PAD(sizeof(marker)); ++ marker_ref->flash_offset = jeb->offset | REF_NORMAL; ++ marker_ref->__totlen = c->cleanmarker_size; + + jeb->first_node = jeb->last_node = marker_ref; + +- jeb->free_size = c->sector_size - marker_ref->totlen; +- jeb->used_size = marker_ref->totlen; ++ jeb->free_size = c->sector_size - c->cleanmarker_size; ++ jeb->used_size = c->cleanmarker_size; + jeb->dirty_size = 0; ++ jeb->wasted_size = 0; ++ } + +- spin_lock_bh(&c->erase_completion_lock); ++ spin_lock(&c->erase_completion_lock); + c->erasing_size -= c->sector_size; + c->free_size += jeb->free_size; + c->used_size += jeb->used_size; + + ACCT_SANITY_CHECK(c,jeb); +- ACCT_PARANOIA_CHECK(jeb); ++ D1(ACCT_PARANOIA_CHECK(jeb)); + + list_add_tail(&jeb->list, &c->free_list); + c->nr_erasing_blocks--; + c->nr_free_blocks++; ++ spin_unlock(&c->erase_completion_lock); + wake_up(&c->erase_wait); +- } +- spin_unlock_bh(&c->erase_completion_lock); + } ++ +diff -Nurb linux-mips-2.4.27/fs/jffs2/file.c linux/fs/jffs2/file.c +--- linux-mips-2.4.27/fs/jffs2/file.c 2003-11-17 02:07:44.000000000 +0100 ++++ linux/fs/jffs2/file.c 2004-11-19 10:25:12.101169088 +0100 +@@ -1,319 +1,106 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: file.c,v 1.58.2.7 2003/11/02 13:51:17 dwmw2 Exp $ ++ * $Id: file.c,v 1.97 2003/11/02 08:52:35 dwmw2 Exp $ + * + */ + ++#include + #include +-#include /* for min() */ + #include + #include ++#include + #include ++#include ++#include + #include + #include "nodelist.h" +-#include + + extern int generic_file_open(struct inode *, struct file *) __attribute__((weak)); + extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) __attribute__((weak)); + + +-int jffs2_null_fsync(struct file *filp, struct dentry *dentry, int datasync) ++int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync) + { +- /* Move along. Nothing to see here */ ++ struct inode *inode = dentry->d_inode; ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); ++ ++ /* Trigger GC to flush any pending writes for this inode */ ++ jffs2_flush_wbuf_gc(c, inode->i_ino); ++ + return 0; + } + + struct file_operations jffs2_file_operations = + { +- llseek: generic_file_llseek, +- open: generic_file_open, +- read: generic_file_read, +- write: generic_file_write, +- ioctl: jffs2_ioctl, +- mmap: generic_file_mmap, +- fsync: jffs2_null_fsync ++ .llseek = generic_file_llseek, ++ .open = generic_file_open, ++ .read = generic_file_read, ++ .write = generic_file_write, ++ .ioctl = jffs2_ioctl, ++ .mmap = generic_file_readonly_mmap, ++ .fsync = jffs2_fsync, ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,29) ++ .sendfile = generic_file_sendfile ++#endif + }; + + /* jffs2_file_inode_operations */ + + struct inode_operations jffs2_file_inode_operations = + { +- setattr: jffs2_setattr ++ .setattr = jffs2_setattr + }; + + struct address_space_operations jffs2_file_address_operations = + { +- readpage: jffs2_readpage, +- prepare_write: jffs2_prepare_write, +- commit_write: jffs2_commit_write ++ .readpage = jffs2_readpage, ++ .prepare_write =jffs2_prepare_write, ++ .commit_write = jffs2_commit_write + }; + +-int jffs2_setattr (struct dentry *dentry, struct iattr *iattr) +-{ +- struct jffs2_full_dnode *old_metadata, *new_metadata; +- struct inode *inode = dentry->d_inode; +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); +- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +- struct jffs2_raw_inode *ri; +- unsigned short dev; +- unsigned char *mdata = NULL; +- int mdatalen = 0; +- unsigned int ivalid; +- __u32 phys_ofs, alloclen; +- int ret; +- D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino)); +- ret = inode_change_ok(inode, iattr); +- if (ret) +- return ret; +- +- /* Special cases - we don't want more than one data node +- for these types on the medium at any time. So setattr +- must read the original data associated with the node +- (i.e. the device numbers or the target name) and write +- it out again with the appropriate data attached */ +- if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { +- /* For these, we don't actually need to read the old node */ +- dev = (MAJOR(to_kdev_t(dentry->d_inode->i_rdev)) << 8) | +- MINOR(to_kdev_t(dentry->d_inode->i_rdev)); +- mdata = (char *)&dev; +- mdatalen = sizeof(dev); +- D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen)); +- } else if (S_ISLNK(inode->i_mode)) { +- mdatalen = f->metadata->size; +- mdata = kmalloc(f->metadata->size, GFP_USER); +- if (!mdata) +- return -ENOMEM; +- ret = jffs2_read_dnode(c, f->metadata, mdata, 0, mdatalen); +- if (ret) { +- kfree(mdata); +- return ret; +- } +- D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen)); +- } +- +- ri = jffs2_alloc_raw_inode(); +- if (!ri) { +- if (S_ISLNK(inode->i_mode)) +- kfree(mdata); +- return -ENOMEM; +- } +- +- ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL); +- if (ret) { +- jffs2_free_raw_inode(ri); +- if (S_ISLNK(inode->i_mode)) +- kfree(mdata); +- return ret; +- } +- down(&f->sem); +- ivalid = iattr->ia_valid; +- +- ri->magic = JFFS2_MAGIC_BITMASK; +- ri->nodetype = JFFS2_NODETYPE_INODE; +- ri->totlen = sizeof(*ri) + mdatalen; +- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4); +- +- ri->ino = inode->i_ino; +- ri->version = ++f->highest_version; +- +- ri->mode = (ivalid & ATTR_MODE)?iattr->ia_mode:inode->i_mode; +- ri->uid = (ivalid & ATTR_UID)?iattr->ia_uid:inode->i_uid; +- ri->gid = (ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid; +- +- if (ivalid & ATTR_MODE && ri->mode & S_ISGID && +- !in_group_p(ri->gid) && !capable(CAP_FSETID)) +- ri->mode &= ~S_ISGID; +- +- ri->isize = (ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size; +- ri->atime = (ivalid & ATTR_ATIME)?iattr->ia_atime:inode->i_atime; +- ri->mtime = (ivalid & ATTR_MTIME)?iattr->ia_mtime:inode->i_mtime; +- ri->ctime = (ivalid & ATTR_CTIME)?iattr->ia_ctime:inode->i_ctime; +- +- ri->offset = 0; +- ri->csize = ri->dsize = mdatalen; +- ri->compr = JFFS2_COMPR_NONE; +- if (inode->i_size < ri->isize) { +- /* It's an extension. Make it a hole node */ +- ri->compr = JFFS2_COMPR_ZERO; +- ri->dsize = ri->isize - inode->i_size; +- ri->offset = inode->i_size; +- } +- ri->node_crc = crc32(0, ri, sizeof(*ri)-8); +- if (mdatalen) +- ri->data_crc = crc32(0, mdata, mdatalen); +- else +- ri->data_crc = 0; +- +- new_metadata = jffs2_write_dnode(inode, ri, mdata, mdatalen, phys_ofs, NULL); +- if (S_ISLNK(inode->i_mode)) +- kfree(mdata); +- +- jffs2_complete_reservation(c); +- +- if (IS_ERR(new_metadata)) { +- jffs2_free_raw_inode(ri); +- up(&f->sem); +- return PTR_ERR(new_metadata); +- } +- /* It worked. Update the inode */ +- inode->i_atime = ri->atime; +- inode->i_ctime = ri->ctime; +- inode->i_mtime = ri->mtime; +- inode->i_mode = ri->mode; +- inode->i_uid = ri->uid; +- inode->i_gid = ri->gid; +- +- +- old_metadata = f->metadata; +- +- if (inode->i_size > ri->isize) { +- vmtruncate(inode, ri->isize); +- jffs2_truncate_fraglist (c, &f->fraglist, ri->isize); +- } +- +- if (inode->i_size < ri->isize) { +- jffs2_add_full_dnode_to_inode(c, f, new_metadata); +- inode->i_size = ri->isize; +- f->metadata = NULL; +- } else { +- f->metadata = new_metadata; +- } +- if (old_metadata) { +- jffs2_mark_node_obsolete(c, old_metadata->raw); +- jffs2_free_full_dnode(old_metadata); +- } +- jffs2_free_raw_inode(ri); +- up(&f->sem); +- return 0; +-} +- + int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg) + { + struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +- struct jffs2_node_frag *frag = f->fraglist; +- __u32 offset = pg->index << PAGE_CACHE_SHIFT; +- __u32 end = offset + PAGE_CACHE_SIZE; + unsigned char *pg_buf; + int ret; + +- D1(printk(KERN_DEBUG "jffs2_do_readpage_nolock(): ino #%lu, page at offset 0x%x\n", inode->i_ino, offset)); ++ D2(printk(KERN_DEBUG "jffs2_do_readpage_nolock(): ino #%lu, page at offset 0x%lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT)); + + if (!PageLocked(pg)) + PAGE_BUG(pg); + +- while(frag && frag->ofs + frag->size <= offset) { +- // D1(printk(KERN_DEBUG "skipping frag %d-%d; before the region we care about\n", frag->ofs, frag->ofs + frag->size)); +- frag = frag->next; +- } +- + pg_buf = kmap(pg); ++ /* FIXME: Can kmap fail? */ + +- /* XXX FIXME: Where a single physical node actually shows up in two +- frags, we read it twice. Don't do that. */ +- /* Now we're pointing at the first frag which overlaps our page */ +- while(offset < end) { +- D2(printk(KERN_DEBUG "jffs2_readpage: offset %d, end %d\n", offset, end)); +- if (!frag || frag->ofs > offset) { +- __u32 holesize = end - offset; +- if (frag) { +- D1(printk(KERN_NOTICE "Eep. Hole in ino %ld fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", inode->i_ino, frag->ofs, offset)); +- holesize = min(holesize, frag->ofs - offset); +- D1(jffs2_print_frag_list(f)); +- } +- D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize)); +- memset(pg_buf, 0, holesize); +- pg_buf += holesize; +- offset += holesize; +- continue; +- } else if (frag->ofs < offset && (offset & (PAGE_CACHE_SIZE-1)) != 0) { +- D1(printk(KERN_NOTICE "Eep. Overlap in ino #%ld fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", +- inode->i_ino, frag->ofs, offset)); +- D1(jffs2_print_frag_list(f)); +- memset(pg_buf, 0, end - offset); +- ClearPageUptodate(pg); +- SetPageError(pg); +- kunmap(pg); +- return -EIO; +- } else if (!frag->node) { +- __u32 holeend = min(end, frag->ofs + frag->size); +- D1(printk(KERN_DEBUG "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset, holeend, frag->ofs, frag->ofs + frag->size)); +- memset(pg_buf, 0, holeend - offset); +- pg_buf += holeend - offset; +- offset = holeend; +- frag = frag->next; +- continue; +- } else { +- __u32 readlen; +- __u32 fragofs; /* offset within the frag to start reading */ ++ ret = jffs2_read_inode_range(c, f, pg_buf, pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE); + +- fragofs = offset - frag->ofs; +- readlen = min(frag->size - fragofs, end - offset); +- D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%x\n", frag->ofs+fragofs, +- fragofs+frag->ofs+readlen, frag->node->raw->flash_offset & ~3)); +- ret = jffs2_read_dnode(c, frag->node, pg_buf, fragofs + frag->ofs - frag->node->ofs, readlen); +- D2(printk(KERN_DEBUG "node read done\n")); + if (ret) { +- D1(printk(KERN_DEBUG"jffs2_readpage error %d\n",ret)); +- memset(pg_buf, 0, readlen); + ClearPageUptodate(pg); + SetPageError(pg); +- kunmap(pg); +- return ret; +- } +- +- pg_buf += readlen; +- offset += readlen; +- frag = frag->next; +- D2(printk(KERN_DEBUG "node read was OK. Looping\n")); +- } +- } +- D2(printk(KERN_DEBUG "readpage finishing\n")); ++ } else { + SetPageUptodate(pg); + ClearPageError(pg); ++ } + + flush_dcache_page(pg); +- + kunmap(pg); +- D1(printk(KERN_DEBUG "readpage finished\n")); ++ ++ D2(printk(KERN_DEBUG "readpage finished\n")); + return 0; + } + + int jffs2_do_readpage_unlock(struct inode *inode, struct page *pg) + { + int ret = jffs2_do_readpage_nolock(inode, pg); +- UnlockPage(pg); ++ unlock_page(pg); + return ret; + } + +@@ -333,17 +120,17 @@ + { + struct inode *inode = pg->mapping->host; + struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); +- __u32 pageofs = pg->index << PAGE_CACHE_SHIFT; ++ uint32_t pageofs = pg->index << PAGE_CACHE_SHIFT; + int ret = 0; + +- D1(printk(KERN_DEBUG "jffs2_prepare_write() nrpages %ld\n", inode->i_mapping->nrpages)); ++ D1(printk(KERN_DEBUG "jffs2_prepare_write()\n")); + + if (pageofs > inode->i_size) { + /* Make new hole frag from old EOF to new page */ + struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); + struct jffs2_raw_inode ri; + struct jffs2_full_dnode *fn; +- __u32 phys_ofs, alloc_len; ++ uint32_t phys_ofs, alloc_len; + + D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", + (unsigned int)inode->i_size, pageofs)); +@@ -355,29 +142,30 @@ + down(&f->sem); + memset(&ri, 0, sizeof(ri)); + +- ri.magic = JFFS2_MAGIC_BITMASK; +- ri.nodetype = JFFS2_NODETYPE_INODE; +- ri.totlen = sizeof(ri); +- ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4); +- +- ri.ino = f->inocache->ino; +- ri.version = ++f->highest_version; +- ri.mode = inode->i_mode; +- ri.uid = inode->i_uid; +- ri.gid = inode->i_gid; +- ri.isize = max((__u32)inode->i_size, pageofs); +- ri.atime = ri.ctime = ri.mtime = CURRENT_TIME; +- ri.offset = inode->i_size; +- ri.dsize = pageofs - inode->i_size; +- ri.csize = 0; ++ ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); ++ ri.totlen = cpu_to_je32(sizeof(ri)); ++ ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4)); ++ ++ ri.ino = cpu_to_je32(f->inocache->ino); ++ ri.version = cpu_to_je32(++f->highest_version); ++ ri.mode = cpu_to_jemode(inode->i_mode); ++ ri.uid = cpu_to_je16(inode->i_uid); ++ ri.gid = cpu_to_je16(inode->i_gid); ++ ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs)); ++ ri.atime = ri.ctime = ri.mtime = cpu_to_je32(get_seconds()); ++ ri.offset = cpu_to_je32(inode->i_size); ++ ri.dsize = cpu_to_je32(pageofs - inode->i_size); ++ ri.csize = cpu_to_je32(0); + ri.compr = JFFS2_COMPR_ZERO; +- ri.node_crc = crc32(0, &ri, sizeof(ri)-8); +- ri.data_crc = 0; ++ ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); ++ ri.data_crc = cpu_to_je32(0); ++ ++ fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_NORMAL); + +- fn = jffs2_write_dnode(inode, &ri, NULL, 0, phys_ofs, NULL); +- jffs2_complete_reservation(c); + if (IS_ERR(fn)) { + ret = PTR_ERR(fn); ++ jffs2_complete_reservation(c); + up(&f->sem); + return ret; + } +@@ -391,16 +179,17 @@ + D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret)); + jffs2_mark_node_obsolete(c, fn->raw); + jffs2_free_full_dnode(fn); ++ jffs2_complete_reservation(c); + up(&f->sem); + return ret; + } ++ jffs2_complete_reservation(c); + inode->i_size = pageofs; + up(&f->sem); + } + +- + /* Read in the page if it wasn't already present, unless it's a whole page */ +- if (!Page_Uptodate(pg) && (start || end < PAGE_CACHE_SIZE)) { ++ if (!PageUptodate(pg) && (start || end < PAGE_CACHE_SIZE)) { + down(&f->sem); + ret = jffs2_do_readpage_nolock(inode, pg); + up(&f->sem); +@@ -417,14 +206,12 @@ + struct inode *inode = pg->mapping->host; + struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +- __u32 newsize = max_t(__u32, filp->f_dentry->d_inode->i_size, (pg->index << PAGE_CACHE_SHIFT) + end); +- __u32 file_ofs = (pg->index << PAGE_CACHE_SHIFT); +- __u32 writelen = min((__u32)PAGE_CACHE_SIZE, newsize - file_ofs); + struct jffs2_raw_inode *ri; + int ret = 0; +- ssize_t writtenlen = 0; ++ uint32_t writtenlen = 0; + +- D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags)); ++ D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", ++ inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags)); + + if (!start && end == PAGE_CACHE_SIZE) { + /* We need to avoid deadlock with page_cache_read() in +@@ -435,109 +222,47 @@ + } + + ri = jffs2_alloc_raw_inode(); +- if (!ri) +- return -ENOMEM; +- +- while(writelen) { +- struct jffs2_full_dnode *fn; +- unsigned char *comprbuf = NULL; +- unsigned char comprtype = JFFS2_COMPR_NONE; +- __u32 phys_ofs, alloclen; +- __u32 datalen, cdatalen; + +- D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, file_ofs)); +- +- ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL); +- if (ret) { +- SetPageError(pg); +- D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret)); +- break; ++ if (!ri) { ++ D1(printk(KERN_DEBUG "jffs2_commit_write(): Allocation of raw inode failed\n")); ++ return -ENOMEM; + } +- down(&f->sem); +- datalen = writelen; +- cdatalen = min(alloclen - sizeof(*ri), writelen); +- +- comprbuf = kmalloc(cdatalen, GFP_KERNEL); +- if (comprbuf) { +- comprtype = jffs2_compress(page_address(pg)+ (file_ofs & (PAGE_CACHE_SIZE-1)), comprbuf, &datalen, &cdatalen); +- } +- if (comprtype == JFFS2_COMPR_NONE) { +- /* Either compression failed, or the allocation of comprbuf failed */ +- if (comprbuf) +- kfree(comprbuf); +- comprbuf = page_address(pg) + (file_ofs & (PAGE_CACHE_SIZE -1)); +- datalen = cdatalen; +- } +- /* Now comprbuf points to the data to be written, be it compressed or not. +- comprtype holds the compression type, and comprtype == JFFS2_COMPR_NONE means +- that the comprbuf doesn't need to be kfree()d. +- */ +- +- ri->magic = JFFS2_MAGIC_BITMASK; +- ri->nodetype = JFFS2_NODETYPE_INODE; +- ri->totlen = sizeof(*ri) + cdatalen; +- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4); +- +- ri->ino = inode->i_ino; +- ri->version = ++f->highest_version; +- ri->mode = inode->i_mode; +- ri->uid = inode->i_uid; +- ri->gid = inode->i_gid; +- ri->isize = max((__u32)inode->i_size, file_ofs + datalen); +- ri->atime = ri->ctime = ri->mtime = CURRENT_TIME; +- ri->offset = file_ofs; +- ri->csize = cdatalen; +- ri->dsize = datalen; +- ri->compr = comprtype; +- ri->node_crc = crc32(0, ri, sizeof(*ri)-8); +- ri->data_crc = crc32(0, comprbuf, cdatalen); +- +- fn = jffs2_write_dnode(inode, ri, comprbuf, cdatalen, phys_ofs, NULL); + +- jffs2_complete_reservation(c); ++ /* Set the fields that the generic jffs2_write_inode_range() code can't find */ ++ ri->ino = cpu_to_je32(inode->i_ino); ++ ri->mode = cpu_to_jemode(inode->i_mode); ++ ri->uid = cpu_to_je16(inode->i_uid); ++ ri->gid = cpu_to_je16(inode->i_gid); ++ ri->isize = cpu_to_je32((uint32_t)inode->i_size); ++ ri->atime = ri->ctime = ri->mtime = cpu_to_je32(get_seconds()); ++ ++ /* In 2.4, it was already kmapped by generic_file_write(). Doesn't ++ hurt to do it again. The alternative is ifdefs, which are ugly. */ ++ kmap(pg); ++ ++ ret = jffs2_write_inode_range(c, f, ri, page_address(pg) + start, ++ (pg->index << PAGE_CACHE_SHIFT) + start, ++ end - start, &writtenlen); + +- if (comprtype != JFFS2_COMPR_NONE) +- kfree(comprbuf); ++ kunmap(pg); + +- if (IS_ERR(fn)) { +- ret = PTR_ERR(fn); +- up(&f->sem); +- SetPageError(pg); +- break; +- } +- ret = jffs2_add_full_dnode_to_inode(c, f, fn); +- if (f->metadata) { +- jffs2_mark_node_obsolete(c, f->metadata->raw); +- jffs2_free_full_dnode(f->metadata); +- f->metadata = NULL; +- } +- up(&f->sem); + if (ret) { +- /* Eep */ +- D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret)); +- jffs2_mark_node_obsolete(c, fn->raw); +- jffs2_free_full_dnode(fn); ++ /* There was an error writing. */ + SetPageError(pg); +- break; + } +- inode->i_size = ri->isize; ++ ++ if (writtenlen) { ++ if (inode->i_size < (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen) { ++ inode->i_size = (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen; + inode->i_blocks = (inode->i_size + 511) >> 9; +- inode->i_ctime = inode->i_mtime = ri->ctime; +- if (!datalen) { +- printk(KERN_WARNING "Eep. We didn't actually write any bloody data\n"); +- ret = -EIO; +- SetPageError(pg); +- break; ++ ++ inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime)); + } +- D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen)); +- writtenlen += datalen; +- file_ofs += datalen; +- writelen -= datalen; + } + + jffs2_free_raw_inode(ri); + +- if (writtenlen < end) { ++ if (start+writtenlen < end) { + /* generic_file_write has written more to the page cache than we've + actually written to the medium. Mark the page !Uptodate so that + it gets reread */ +@@ -545,13 +270,7 @@ + SetPageError(pg); + ClearPageUptodate(pg); + } +- if (writtenlen <= start) { +- /* We didn't even get to the start of the affected part */ +- ret = ret?ret:-ENOSPC; +- D1(printk(KERN_DEBUG "jffs2_commit_write(): Only %x bytes written to page. start (%x) not reached, returning %d\n", writtenlen, start, ret)); +- } +- writtenlen = min(end-start, writtenlen-start); + +- D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d. nrpages is %ld\n",writtenlen?writtenlen:ret, inode->i_mapping->nrpages)); ++ D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d\n",writtenlen?writtenlen:ret)); + return writtenlen?writtenlen:ret; + } +diff -Nurb linux-mips-2.4.27/fs/jffs2/fs.c linux/fs/jffs2/fs.c +--- linux-mips-2.4.27/fs/jffs2/fs.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/fs/jffs2/fs.c 2004-11-19 10:25:12.102168936 +0100 +@@ -0,0 +1,618 @@ ++/* ++ * JFFS2 -- Journalling Flash File System, Version 2. ++ * ++ * Copyright (C) 2001-2003 Red Hat, Inc. ++ * ++ * Created by David Woodhouse ++ * ++ * For licensing information, see the file 'LICENCE' in this directory. ++ * ++ * $Id: fs.c,v 1.37 2004/01/26 12:34:21 dwmw2 Exp $ ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "nodelist.h" ++ ++ ++static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) ++{ ++ struct jffs2_full_dnode *old_metadata, *new_metadata; ++ struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); ++ struct jffs2_raw_inode *ri; ++ unsigned short dev; ++ unsigned char *mdata = NULL; ++ int mdatalen = 0; ++ unsigned int ivalid; ++ uint32_t phys_ofs, alloclen; ++ int ret; ++ D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino)); ++ ret = inode_change_ok(inode, iattr); ++ if (ret) ++ return ret; ++ ++ /* Special cases - we don't want more than one data node ++ for these types on the medium at any time. So setattr ++ must read the original data associated with the node ++ (i.e. the device numbers or the target name) and write ++ it out again with the appropriate data attached */ ++ if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { ++ /* For these, we don't actually need to read the old node */ ++ dev = old_encode_dev(inode->i_rdev); ++ mdata = (char *)&dev; ++ mdatalen = sizeof(dev); ++ D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen)); ++ } else if (S_ISLNK(inode->i_mode)) { ++ mdatalen = f->metadata->size; ++ mdata = kmalloc(f->metadata->size, GFP_USER); ++ if (!mdata) ++ return -ENOMEM; ++ ret = jffs2_read_dnode(c, f->metadata, mdata, 0, mdatalen); ++ if (ret) { ++ kfree(mdata); ++ return ret; ++ } ++ D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen)); ++ } ++ ++ ri = jffs2_alloc_raw_inode(); ++ if (!ri) { ++ if (S_ISLNK(inode->i_mode)) ++ kfree(mdata); ++ return -ENOMEM; ++ } ++ ++ ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL); ++ if (ret) { ++ jffs2_free_raw_inode(ri); ++ if (S_ISLNK(inode->i_mode & S_IFMT)) ++ kfree(mdata); ++ return ret; ++ } ++ down(&f->sem); ++ ivalid = iattr->ia_valid; ++ ++ ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); ++ ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen); ++ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); ++ ++ ri->ino = cpu_to_je32(inode->i_ino); ++ ri->version = cpu_to_je32(++f->highest_version); ++ ++ ri->uid = cpu_to_je16((ivalid & ATTR_UID)?iattr->ia_uid:inode->i_uid); ++ ri->gid = cpu_to_je16((ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid); ++ ++ if (ivalid & ATTR_MODE) ++ if (iattr->ia_mode & S_ISGID && ++ !in_group_p(je16_to_cpu(ri->gid)) && !capable(CAP_FSETID)) ++ ri->mode = cpu_to_jemode(iattr->ia_mode & ~S_ISGID); ++ else ++ ri->mode = cpu_to_jemode(iattr->ia_mode); ++ else ++ ri->mode = cpu_to_jemode(inode->i_mode); ++ ++ ++ ri->isize = cpu_to_je32((ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size); ++ ri->atime = cpu_to_je32(I_SEC((ivalid & ATTR_ATIME)?iattr->ia_atime:inode->i_atime)); ++ ri->mtime = cpu_to_je32(I_SEC((ivalid & ATTR_MTIME)?iattr->ia_mtime:inode->i_mtime)); ++ ri->ctime = cpu_to_je32(I_SEC((ivalid & ATTR_CTIME)?iattr->ia_ctime:inode->i_ctime)); ++ ++ ri->offset = cpu_to_je32(0); ++ ri->csize = ri->dsize = cpu_to_je32(mdatalen); ++ ri->compr = JFFS2_COMPR_NONE; ++ if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) { ++ /* It's an extension. Make it a hole node */ ++ ri->compr = JFFS2_COMPR_ZERO; ++ ri->dsize = cpu_to_je32(iattr->ia_size - inode->i_size); ++ ri->offset = cpu_to_je32(inode->i_size); ++ } ++ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); ++ if (mdatalen) ++ ri->data_crc = cpu_to_je32(crc32(0, mdata, mdatalen)); ++ else ++ ri->data_crc = cpu_to_je32(0); ++ ++ new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, phys_ofs, ALLOC_NORMAL); ++ if (S_ISLNK(inode->i_mode)) ++ kfree(mdata); ++ ++ if (IS_ERR(new_metadata)) { ++ jffs2_complete_reservation(c); ++ jffs2_free_raw_inode(ri); ++ up(&f->sem); ++ return PTR_ERR(new_metadata); ++ } ++ /* It worked. Update the inode */ ++ inode->i_atime = ITIME(je32_to_cpu(ri->atime)); ++ inode->i_ctime = ITIME(je32_to_cpu(ri->ctime)); ++ inode->i_mtime = ITIME(je32_to_cpu(ri->mtime)); ++ inode->i_mode = jemode_to_cpu(ri->mode); ++ inode->i_uid = je16_to_cpu(ri->uid); ++ inode->i_gid = je16_to_cpu(ri->gid); ++ ++ ++ old_metadata = f->metadata; ++ ++ if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) ++ jffs2_truncate_fraglist (c, &f->fragtree, iattr->ia_size); ++ ++ if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) { ++ jffs2_add_full_dnode_to_inode(c, f, new_metadata); ++ inode->i_size = iattr->ia_size; ++ f->metadata = NULL; ++ } else { ++ f->metadata = new_metadata; ++ } ++ if (old_metadata) { ++ jffs2_mark_node_obsolete(c, old_metadata->raw); ++ jffs2_free_full_dnode(old_metadata); ++ } ++ jffs2_free_raw_inode(ri); ++ ++ up(&f->sem); ++ jffs2_complete_reservation(c); ++ ++ /* We have to do the vmtruncate() without f->sem held, since ++ some pages may be locked and waiting for it in readpage(). ++ We are protected from a simultaneous write() extending i_size ++ back past iattr->ia_size, because do_truncate() holds the ++ generic inode semaphore. */ ++ if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) ++ vmtruncate(inode, iattr->ia_size); ++ ++ return 0; ++} ++ ++int jffs2_setattr(struct dentry *dentry, struct iattr *iattr) ++{ ++ return jffs2_do_setattr(dentry->d_inode, iattr); ++} ++ ++int jffs2_statfs(struct super_block *sb, struct kstatfs *buf) ++{ ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); ++ unsigned long avail; ++ ++ buf->f_type = JFFS2_SUPER_MAGIC; ++ buf->f_bsize = 1 << PAGE_SHIFT; ++ buf->f_blocks = c->flash_size >> PAGE_SHIFT; ++ buf->f_files = 0; ++ buf->f_ffree = 0; ++ buf->f_namelen = JFFS2_MAX_NAME_LEN; ++ ++ spin_lock(&c->erase_completion_lock); ++ ++ avail = c->dirty_size + c->free_size; ++ if (avail > c->sector_size * c->resv_blocks_write) ++ avail -= c->sector_size * c->resv_blocks_write; ++ else ++ avail = 0; ++ ++ buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT; ++ ++ D1(jffs2_dump_block_lists(c)); ++ ++ spin_unlock(&c->erase_completion_lock); ++ ++ return 0; ++} ++ ++ ++void jffs2_clear_inode (struct inode *inode) ++{ ++ /* We can forget about this inode for now - drop all ++ * the nodelists associated with it, etc. ++ */ ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); ++ struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); ++ ++ D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode)); ++ ++ jffs2_do_clear_inode(c, f); ++} ++ ++void jffs2_read_inode (struct inode *inode) ++{ ++ struct jffs2_inode_info *f; ++ struct jffs2_sb_info *c; ++ struct jffs2_raw_inode latest_node; ++ int ret; ++ ++ D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino)); ++ ++ f = JFFS2_INODE_INFO(inode); ++ c = JFFS2_SB_INFO(inode->i_sb); ++ ++ jffs2_init_inode_info(f); ++ ++ ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node); ++ ++ if (ret) { ++ make_bad_inode(inode); ++ up(&f->sem); ++ return; ++ } ++ inode->i_mode = jemode_to_cpu(latest_node.mode); ++ inode->i_uid = je16_to_cpu(latest_node.uid); ++ inode->i_gid = je16_to_cpu(latest_node.gid); ++ inode->i_size = je32_to_cpu(latest_node.isize); ++ inode->i_atime = ITIME(je32_to_cpu(latest_node.atime)); ++ inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime)); ++ inode->i_ctime = ITIME(je32_to_cpu(latest_node.ctime)); ++ ++ inode->i_nlink = f->inocache->nlink; ++ ++ inode->i_blksize = PAGE_SIZE; ++ inode->i_blocks = (inode->i_size + 511) >> 9; ++ ++ switch (inode->i_mode & S_IFMT) { ++ jint16_t rdev; ++ ++ case S_IFLNK: ++ inode->i_op = &jffs2_symlink_inode_operations; ++ break; ++ ++ case S_IFDIR: ++ { ++ struct jffs2_full_dirent *fd; ++ ++ for (fd=f->dents; fd; fd = fd->next) { ++ if (fd->type == DT_DIR && fd->ino) ++ inode->i_nlink++; ++ } ++ /* and '..' */ ++ inode->i_nlink++; ++ /* Root dir gets i_nlink 3 for some reason */ ++ if (inode->i_ino == 1) ++ inode->i_nlink++; ++ ++ inode->i_op = &jffs2_dir_inode_operations; ++ inode->i_fop = &jffs2_dir_operations; ++ break; ++ } ++ case S_IFREG: ++ inode->i_op = &jffs2_file_inode_operations; ++ inode->i_fop = &jffs2_file_operations; ++ inode->i_mapping->a_ops = &jffs2_file_address_operations; ++ inode->i_mapping->nrpages = 0; ++ break; ++ ++ case S_IFBLK: ++ case S_IFCHR: ++ /* Read the device numbers from the media */ ++ D1(printk(KERN_DEBUG "Reading device numbers from flash\n")); ++ if (jffs2_read_dnode(c, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) { ++ /* Eep */ ++ printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino); ++ up(&f->sem); ++ jffs2_do_clear_inode(c, f); ++ make_bad_inode(inode); ++ return; ++ } ++ ++ case S_IFSOCK: ++ case S_IFIFO: ++ inode->i_op = &jffs2_file_inode_operations; ++ init_special_inode(inode, inode->i_mode, ++ old_decode_dev((je16_to_cpu(rdev)))); ++ break; ++ ++ default: ++ printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino); ++ } ++ ++ up(&f->sem); ++ ++ D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n")); ++} ++ ++void jffs2_dirty_inode(struct inode *inode) ++{ ++ struct iattr iattr; ++ ++ if (!(inode->i_state & I_DIRTY_DATASYNC)) { ++ D2(printk(KERN_DEBUG "jffs2_dirty_inode() not calling setattr() for ino #%lu\n", inode->i_ino)); ++ return; ++ } ++ ++ D1(printk(KERN_DEBUG "jffs2_dirty_inode() calling setattr() for ino #%lu\n", inode->i_ino)); ++ ++ iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME; ++ iattr.ia_mode = inode->i_mode; ++ iattr.ia_uid = inode->i_uid; ++ iattr.ia_gid = inode->i_gid; ++ iattr.ia_atime = inode->i_atime; ++ iattr.ia_mtime = inode->i_mtime; ++ iattr.ia_ctime = inode->i_ctime; ++ ++ jffs2_do_setattr(inode, &iattr); ++} ++ ++int jffs2_remount_fs (struct super_block *sb, int *flags, char *data) ++{ ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); ++ ++ if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY)) ++ return -EROFS; ++ ++ /* We stop if it was running, then restart if it needs to. ++ This also catches the case where it was stopped and this ++ is just a remount to restart it */ ++ if (!(sb->s_flags & MS_RDONLY)) ++ jffs2_stop_garbage_collect_thread(c); ++ ++ if (!(*flags & MS_RDONLY)) ++ jffs2_start_garbage_collect_thread(c); ++ ++ sb->s_flags = (sb->s_flags & ~MS_RDONLY)|(*flags & MS_RDONLY); ++ ++ return 0; ++} ++ ++void jffs2_write_super (struct super_block *sb) ++{ ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); ++ sb->s_dirt = 0; ++ ++ if (sb->s_flags & MS_RDONLY) ++ return; ++ ++ D1(printk(KERN_DEBUG "jffs2_write_super()\n")); ++ jffs2_garbage_collect_trigger(c); ++ jffs2_erase_pending_blocks(c, 0); ++ jffs2_flush_wbuf_gc(c, 0); ++} ++ ++ ++/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash, ++ fill in the raw_inode while you're at it. */ ++struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri) ++{ ++ struct inode *inode; ++ struct super_block *sb = dir_i->i_sb; ++ struct jffs2_sb_info *c; ++ struct jffs2_inode_info *f; ++ int ret; ++ ++ D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode)); ++ ++ c = JFFS2_SB_INFO(sb); ++ ++ inode = new_inode(sb); ++ ++ if (!inode) ++ return ERR_PTR(-ENOMEM); ++ ++ f = JFFS2_INODE_INFO(inode); ++ jffs2_init_inode_info(f); ++ ++ memset(ri, 0, sizeof(*ri)); ++ /* Set OS-specific defaults for new inodes */ ++ ri->uid = cpu_to_je16(current->fsuid); ++ ++ if (dir_i->i_mode & S_ISGID) { ++ ri->gid = cpu_to_je16(dir_i->i_gid); ++ if (S_ISDIR(mode)) ++ mode |= S_ISGID; ++ } else { ++ ri->gid = cpu_to_je16(current->fsgid); ++ } ++ ri->mode = cpu_to_jemode(mode); ++ ret = jffs2_do_new_inode (c, f, mode, ri); ++ if (ret) { ++ make_bad_inode(inode); ++ iput(inode); ++ return ERR_PTR(ret); ++ } ++ inode->i_nlink = 1; ++ inode->i_ino = je32_to_cpu(ri->ino); ++ inode->i_mode = jemode_to_cpu(ri->mode); ++ inode->i_gid = je16_to_cpu(ri->gid); ++ inode->i_uid = je16_to_cpu(ri->uid); ++ inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME; ++ ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime)); ++ ++ inode->i_blksize = PAGE_SIZE; ++ inode->i_blocks = 0; ++ inode->i_size = 0; ++ ++ insert_inode_hash(inode); ++ ++ return inode; ++} ++ ++ ++int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) ++{ ++ struct jffs2_sb_info *c; ++ struct inode *root_i; ++ int ret; ++ size_t blocks; ++ ++ c = JFFS2_SB_INFO(sb); ++ ++ c->flash_size = c->mtd->size; ++ ++ /* ++ * Check, if we have to concatenate physical blocks to larger virtual blocks ++ * to reduce the memorysize for c->blocks. (kmalloc allows max. 128K allocation) ++ */ ++ blocks = c->flash_size / c->mtd->erasesize; ++ while ((blocks * sizeof (struct jffs2_eraseblock)) > (128 * 1024)) ++ blocks >>= 1; ++ ++ c->sector_size = c->flash_size / blocks; ++ if (c->sector_size != c->mtd->erasesize) ++ printk(KERN_INFO "jffs2: Erase block size too small (%dKiB). Using virtual blocks size (%dKiB) instead\n", ++ c->mtd->erasesize / 1024, c->sector_size / 1024); ++ ++ if (c->flash_size < 5*c->sector_size) { ++ printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n", c->flash_size / c->sector_size); ++ return -EINVAL; ++ } ++ ++ c->cleanmarker_size = sizeof(struct jffs2_unknown_node); ++ /* Joern -- stick alignment for weird 8-byte-page flash here */ ++ ++ if (jffs2_cleanmarker_oob(c)) { ++ /* NAND (or other bizarre) flash... do setup accordingly */ ++ ret = jffs2_nand_flash_setup(c); ++ if (ret) ++ return ret; ++ } ++ ++ c->inocache_list = kmalloc(INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *), GFP_KERNEL); ++ if (!c->inocache_list) { ++ ret = -ENOMEM; ++ goto out_wbuf; ++ } ++ memset(c->inocache_list, 0, INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *)); ++ ++ if ((ret = jffs2_do_mount_fs(c))) ++ goto out_inohash; ++ ++ ret = -EINVAL; ++ ++ D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n")); ++ root_i = iget(sb, 1); ++ if (is_bad_inode(root_i)) { ++ D1(printk(KERN_WARNING "get root inode failed\n")); ++ goto out_nodes; ++ } ++ ++ D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n")); ++ sb->s_root = d_alloc_root(root_i); ++ if (!sb->s_root) ++ goto out_root_i; ++ ++#if LINUX_VERSION_CODE >= 0x20403 ++ sb->s_maxbytes = 0xFFFFFFFF; ++#endif ++ sb->s_blocksize = PAGE_CACHE_SIZE; ++ sb->s_blocksize_bits = PAGE_CACHE_SHIFT; ++ sb->s_magic = JFFS2_SUPER_MAGIC; ++ if (!(sb->s_flags & MS_RDONLY)) ++ jffs2_start_garbage_collect_thread(c); ++ return 0; ++ ++ out_root_i: ++ iput(root_i); ++ out_nodes: ++ jffs2_free_ino_caches(c); ++ jffs2_free_raw_node_refs(c); ++ kfree(c->blocks); ++ out_inohash: ++ kfree(c->inocache_list); ++ out_wbuf: ++ jffs2_nand_flash_cleanup(c); ++ ++ return ret; ++} ++ ++void jffs2_gc_release_inode(struct jffs2_sb_info *c, ++ struct jffs2_inode_info *f) ++{ ++ iput(OFNI_EDONI_2SFFJ(f)); ++} ++ ++struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, ++ int inum, int nlink) ++{ ++ struct inode *inode; ++ struct jffs2_inode_cache *ic; ++ if (!nlink) { ++ /* The inode has zero nlink but its nodes weren't yet marked ++ obsolete. This has to be because we're still waiting for ++ the final (close() and) iput() to happen. ++ ++ There's a possibility that the final iput() could have ++ happened while we were contemplating. In order to ensure ++ that we don't cause a new read_inode() (which would fail) ++ for the inode in question, we use ilookup() in this case ++ instead of iget(). ++ ++ The nlink can't _become_ zero at this point because we're ++ holding the alloc_sem, and jffs2_do_unlink() would also ++ need that while decrementing nlink on any inode. ++ */ ++ inode = ilookup(OFNI_BS_2SFFJ(c), inum); ++ if (!inode) { ++ D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n", ++ inum)); ++ ++ spin_lock(&c->inocache_lock); ++ ic = jffs2_get_ino_cache(c, inum); ++ if (!ic) { ++ D1(printk(KERN_DEBUG "Inode cache for ino #%u is gone.\n", inum)); ++ spin_unlock(&c->inocache_lock); ++ return NULL; ++ } ++ if (ic->state != INO_STATE_CHECKEDABSENT) { ++ /* Wait for progress. Don't just loop */ ++ D1(printk(KERN_DEBUG "Waiting for ino #%u in state %d\n", ++ ic->ino, ic->state)); ++ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); ++ } else { ++ spin_unlock(&c->inocache_lock); ++ } ++ ++ return NULL; ++ } ++ } else { ++ /* Inode has links to it still; they're not going away because ++ jffs2_do_unlink() would need the alloc_sem and we have it. ++ Just iget() it, and if read_inode() is necessary that's OK. ++ */ ++ inode = iget(OFNI_BS_2SFFJ(c), inum); ++ if (!inode) ++ return ERR_PTR(-ENOMEM); ++ } ++ if (is_bad_inode(inode)) { ++ printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n", ++ inum, nlink); ++ /* NB. This will happen again. We need to do something appropriate here. */ ++ iput(inode); ++ return ERR_PTR(-EIO); ++ } ++ ++ return JFFS2_INODE_INFO(inode); ++} ++ ++unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, ++ struct jffs2_inode_info *f, ++ unsigned long offset, ++ unsigned long *priv) ++{ ++ struct inode *inode = OFNI_EDONI_2SFFJ(f); ++ struct page *pg; ++ ++ pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT, ++ (void *)jffs2_do_readpage_unlock, inode); ++ if (IS_ERR(pg)) ++ return (void *)pg; ++ ++ *priv = (unsigned long)pg; ++ return kmap(pg); ++} ++ ++void jffs2_gc_release_page(struct jffs2_sb_info *c, ++ unsigned char *ptr, ++ unsigned long *priv) ++{ ++ struct page *pg = (void *)*priv; ++ ++ kunmap(pg); ++ page_cache_release(pg); ++} +diff -Nurb linux-mips-2.4.27/fs/jffs2/gc.c linux/fs/jffs2/gc.c +--- linux-mips-2.4.27/fs/jffs2/gc.c 2003-11-17 02:07:44.000000000 +0100 ++++ linux/fs/jffs2/gc.c 2004-11-19 10:25:12.104168632 +0100 +@@ -1,76 +1,67 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: gc.c,v 1.52.2.7 2003/11/02 13:54:20 dwmw2 Exp $ ++ * $Id: gc.c,v 1.132 2003/12/01 11:32:11 dwmw2 Exp $ + * + */ + + #include + #include + #include +-#include +-#include +-#include + #include +-#include "nodelist.h" + #include ++#include ++#include ++#include "nodelist.h" + ++static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, ++ struct jffs2_inode_cache *ic, ++ struct jffs2_raw_node_ref *raw); + static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, +- struct inode *inode, struct jffs2_full_dnode *fd); ++ struct jffs2_inode_info *f, struct jffs2_full_dnode *fd); + static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, +- struct inode *inode, struct jffs2_full_dirent *fd); ++ struct jffs2_inode_info *f, struct jffs2_full_dirent *fd); + static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, +- struct inode *inode, struct jffs2_full_dirent *fd); ++ struct jffs2_inode_info *f, struct jffs2_full_dirent *fd); + static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, +- struct inode *indeo, struct jffs2_full_dnode *fn, +- __u32 start, __u32 end); ++ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, ++ uint32_t start, uint32_t end); + static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, +- struct inode *inode, struct jffs2_full_dnode *fn, +- __u32 start, __u32 end); ++ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, ++ uint32_t start, uint32_t end); ++static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, ++ struct jffs2_raw_node_ref *raw, struct jffs2_inode_info *f); + + /* Called with erase_completion_lock held */ + static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c) + { + struct jffs2_eraseblock *ret; + struct list_head *nextlist = NULL; ++ int n = jiffies % 128; + + /* Pick an eraseblock to garbage collect next. This is where we'll + put the clever wear-levelling algorithms. Eventually. */ +- if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > JFFS2_RESERVED_BLOCKS_GCBAD) { ++ /* We possibly want to favour the dirtier blocks more when the ++ number of free blocks is low. */ ++ if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > c->resv_blocks_gcbad) { + D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n")); + nextlist = &c->bad_used_list; +- } else if (jiffies % 100 && !list_empty(&c->dirty_list)) { +- /* Most of the time, pick one off the dirty list */ ++ } else if (n < 50 && !list_empty(&c->erasable_list)) { ++ /* Note that most of them will have gone directly to be erased. ++ So don't favour the erasable_list _too_ much. */ ++ D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next\n")); ++ nextlist = &c->erasable_list; ++ } else if (n < 110 && !list_empty(&c->very_dirty_list)) { ++ /* Most of the time, pick one off the very_dirty list */ ++ D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next\n")); ++ nextlist = &c->very_dirty_list; ++ } else if (n < 126 && !list_empty(&c->dirty_list)) { + D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next\n")); + nextlist = &c->dirty_list; + } else if (!list_empty(&c->clean_list)) { +@@ -80,9 +71,16 @@ + D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next (clean_list was empty)\n")); + + nextlist = &c->dirty_list; ++ } else if (!list_empty(&c->very_dirty_list)) { ++ D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next (clean_list and dirty_list were empty)\n")); ++ nextlist = &c->very_dirty_list; ++ } else if (!list_empty(&c->erasable_list)) { ++ D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)\n")); ++ ++ nextlist = &c->erasable_list; + } else { +- /* Eep. Both were empty */ +- printk(KERN_NOTICE "jffs2: No clean _or_ dirty blocks to GC from! Where are they all?\n"); ++ /* Eep. All were empty */ ++ printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n"); + return NULL; + } + +@@ -94,6 +92,17 @@ + printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL\n", ret->offset); + BUG(); + } ++ ++ /* Have we accidentally picked a clean block with wasted space ? */ ++ if (ret->wasted_size) { ++ D1(printk(KERN_DEBUG "Converting wasted_size %08x to dirty_size\n", ret->wasted_size)); ++ ret->dirty_size += ret->wasted_size; ++ c->wasted_size -= ret->wasted_size; ++ c->dirty_size += ret->wasted_size; ++ ret->wasted_size = 0; ++ } ++ ++ D1(jffs2_dump_block_lists(c)); + return ret; + } + +@@ -103,21 +112,90 @@ + */ + int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) + { +- struct jffs2_eraseblock *jeb; + struct jffs2_inode_info *f; +- struct jffs2_raw_node_ref *raw; +- struct jffs2_node_frag *frag; +- struct jffs2_full_dnode *fn = NULL; +- struct jffs2_full_dirent *fd; + struct jffs2_inode_cache *ic; +- __u32 start = 0, end = 0, nrfrags = 0; +- struct inode *inode; +- int ret = 0; ++ struct jffs2_eraseblock *jeb; ++ struct jffs2_raw_node_ref *raw; ++ int ret = 0, inum, nlink; + + if (down_interruptible(&c->alloc_sem)) + return -EINTR; + +- spin_lock_bh(&c->erase_completion_lock); ++ for (;;) { ++ spin_lock(&c->erase_completion_lock); ++ if (!c->unchecked_size) ++ break; ++ ++ /* We can't start doing GC yet. We haven't finished checking ++ the node CRCs etc. Do it now. */ ++ ++ /* checked_ino is protected by the alloc_sem */ ++ if (c->checked_ino > c->highest_ino) { ++ printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n", ++ c->unchecked_size); ++ D1(jffs2_dump_block_lists(c)); ++ spin_unlock(&c->erase_completion_lock); ++ BUG(); ++ } ++ ++ spin_unlock(&c->erase_completion_lock); ++ ++ spin_lock(&c->inocache_lock); ++ ++ ic = jffs2_get_ino_cache(c, c->checked_ino++); ++ ++ if (!ic) { ++ spin_unlock(&c->inocache_lock); ++ continue; ++ } ++ ++ if (!ic->nlink) { ++ D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink zero\n", ++ ic->ino)); ++ spin_unlock(&c->inocache_lock); ++ continue; ++ } ++ switch(ic->state) { ++ case INO_STATE_CHECKEDABSENT: ++ case INO_STATE_PRESENT: ++ D1(printk(KERN_DEBUG "Skipping ino #%u already checked\n", ic->ino)); ++ spin_unlock(&c->inocache_lock); ++ continue; ++ ++ case INO_STATE_GC: ++ case INO_STATE_CHECKING: ++ printk(KERN_WARNING "Inode #%u is in state %d during CRC check phase!\n", ic->ino, ic->state); ++ spin_unlock(&c->inocache_lock); ++ BUG(); ++ ++ case INO_STATE_READING: ++ /* We need to wait for it to finish, lest we move on ++ and trigger the BUG() above while we haven't yet ++ finished checking all its nodes */ ++ D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino)); ++ up(&c->alloc_sem); ++ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); ++ return 0; ++ ++ default: ++ BUG(); ++ ++ case INO_STATE_UNCHECKED: ++ ; ++ } ++ ic->state = INO_STATE_CHECKING; ++ spin_unlock(&c->inocache_lock); ++ ++ D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() triggering inode scan of ino#%u\n", ic->ino)); ++ ++ ret = jffs2_do_crccheck_inode(c, ic); ++ if (ret) ++ printk(KERN_WARNING "Returned error for crccheck of ino #%u. Expect badness...\n", ic->ino); ++ ++ jffs2_set_inocache_state(c, ic, INO_STATE_CHECKEDABSENT); ++ up(&c->alloc_sem); ++ return ret; ++ } + + /* First, work out which block we're garbage-collecting */ + jeb = c->gcblock; +@@ -127,12 +205,14 @@ + + if (!jeb) { + printk(KERN_NOTICE "jffs2: Couldn't find erase block to garbage collect!\n"); +- spin_unlock_bh(&c->erase_completion_lock); ++ spin_unlock(&c->erase_completion_lock); + up(&c->alloc_sem); + return -EIO; + } + +- D1(printk(KERN_DEBUG "garbage collect from block at phys 0x%08x\n", jeb->offset)); ++ D1(printk(KERN_DEBUG "GC from block %08x, used_size %08x, dirty_size %08x, free_size %08x\n", jeb->offset, jeb->used_size, jeb->dirty_size, jeb->free_size)); ++ D1(if (c->nextblock) ++ printk(KERN_DEBUG "Nextblock at %08x, used_size %08x, dirty_size %08x, wasted_size %08x, free_size %08x\n", c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->free_size)); + + if (!jeb->used_size) { + up(&c->alloc_sem); +@@ -141,92 +221,211 @@ + + raw = jeb->gc_node; + +- while(raw->flash_offset & 1) { +- D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", raw->flash_offset &~3)); +- jeb->gc_node = raw = raw->next_phys; +- if (!raw) { ++ while(ref_obsolete(raw)) { ++ D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw))); ++ raw = raw->next_phys; ++ if (unlikely(!raw)) { + printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n"); + printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n", + jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size); +- spin_unlock_bh(&c->erase_completion_lock); ++ jeb->gc_node = raw; ++ spin_unlock(&c->erase_completion_lock); + up(&c->alloc_sem); + BUG(); + } + } +- D1(printk(KERN_DEBUG "Going to garbage collect node at 0x%08x\n", raw->flash_offset &~3)); ++ jeb->gc_node = raw; ++ ++ D1(printk(KERN_DEBUG "Going to garbage collect node at 0x%08x\n", ref_offset(raw))); ++ + if (!raw->next_in_ino) { + /* Inode-less node. Clean marker, snapshot or something like that */ +- spin_unlock_bh(&c->erase_completion_lock); ++ /* FIXME: If it's something that needs to be copied, including something ++ we don't grok that has JFFS2_NODETYPE_RWCOMPAT_COPY, we should do so */ ++ spin_unlock(&c->erase_completion_lock); + jffs2_mark_node_obsolete(c, raw); + up(&c->alloc_sem); + goto eraseit_lock; + } + + ic = jffs2_raw_ref_to_ic(raw); +- D1(printk(KERN_DEBUG "Inode number is #%u\n", ic->ino)); +- +- spin_unlock_bh(&c->erase_completion_lock); + +- D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass collecting from block @0x%08x. Node @0x%08x, ino #%u\n", jeb->offset, raw->flash_offset&~3, ic->ino)); +- if (!ic->nlink) { +- /* The inode has zero nlink but its nodes weren't yet marked +- obsolete. This has to be because we're still waiting for +- the final (close() and) iput() to happen. +- +- There's a possibility that the final iput() could have +- happened while we were contemplating. In order to ensure +- that we don't cause a new read_inode() (which would fail) +- for the inode in question, we use ilookup() in this case +- instead of iget(). +- +- The nlink can't _become_ zero at this point because we're +- holding the alloc_sem, and jffs2_do_unlink() would also +- need that while decrementing nlink on any inode. ++ /* We need to hold the inocache. Either the erase_completion_lock or ++ the inocache_lock are sufficient; we trade down since the inocache_lock ++ causes less contention. */ ++ spin_lock(&c->inocache_lock); ++ ++ spin_unlock(&c->erase_completion_lock); ++ ++ D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass collecting from block @0x%08x. Node @0x%08x(%d), ino #%u\n", jeb->offset, ref_offset(raw), ref_flags(raw), ic->ino)); ++ ++ /* Three possibilities: ++ 1. Inode is already in-core. We must iget it and do proper ++ updating to its fragtree, etc. ++ 2. Inode is not in-core, node is REF_PRISTINE. We lock the ++ inocache to prevent a read_inode(), copy the node intact. ++ 3. Inode is not in-core, node is not pristine. We must iget() ++ and take the slow path. + */ +- inode = ilookup(OFNI_BS_2SFFJ(c), ic->ino); +- if (!inode) { +- D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n", ++ ++ switch(ic->state) { ++ case INO_STATE_CHECKEDABSENT: ++ /* It's been checked, but it's not currently in-core. ++ We can just copy any pristine nodes, but have ++ to prevent anyone else from doing read_inode() while ++ we're at it, so we set the state accordingly */ ++ if (ref_flags(raw) == REF_PRISTINE) ++ ic->state = INO_STATE_GC; ++ else { ++ D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n", + ic->ino)); +- up(&c->alloc_sem); +- return 0; + } +- } else { +- /* Inode has links to it still; they're not going away because +- jffs2_do_unlink() would need the alloc_sem and we have it. +- Just iget() it, and if read_inode() is necessary that's OK. ++ break; ++ ++ case INO_STATE_PRESENT: ++ /* It's in-core. GC must iget() it. */ ++ break; ++ ++ case INO_STATE_UNCHECKED: ++ case INO_STATE_CHECKING: ++ case INO_STATE_GC: ++ /* Should never happen. We should have finished checking ++ by the time we actually start doing any GC, and since ++ we're holding the alloc_sem, no other garbage collection ++ can happen. + */ +- inode = iget(OFNI_BS_2SFFJ(c), ic->ino); +- if (!inode) { ++ printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n", ++ ic->ino, ic->state); + up(&c->alloc_sem); +- return -ENOMEM; ++ spin_unlock(&c->inocache_lock); ++ BUG(); ++ ++ case INO_STATE_READING: ++ /* Someone's currently trying to read it. We must wait for ++ them to finish and then go through the full iget() route ++ to do the GC. However, sometimes read_inode() needs to get ++ the alloc_sem() (for marking nodes invalid) so we must ++ drop the alloc_sem before sleeping. */ ++ ++ up(&c->alloc_sem); ++ D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n", ++ ic->ino, ic->state)); ++ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); ++ /* And because we dropped the alloc_sem we must start again from the ++ beginning. Ponder chance of livelock here -- we're returning success ++ without actually making any progress. ++ ++ Q: What are the chances that the inode is back in INO_STATE_READING ++ again by the time we next enter this function? And that this happens ++ enough times to cause a real delay? ++ ++ A: Small enough that I don't care :) ++ */ ++ return 0; + } ++ ++ /* OK. Now if the inode is in state INO_STATE_GC, we are going to copy the ++ node intact, and we don't have to muck about with the fragtree etc. ++ because we know it's not in-core. If it _was_ in-core, we go through ++ all the iget() crap anyway */ ++ ++ if (ic->state == INO_STATE_GC) { ++ spin_unlock(&c->inocache_lock); ++ ++ ret = jffs2_garbage_collect_pristine(c, ic, raw); ++ ++ spin_lock(&c->inocache_lock); ++ ic->state = INO_STATE_CHECKEDABSENT; ++ wake_up(&c->inocache_wq); ++ ++ if (ret != -EBADFD) { ++ spin_unlock(&c->inocache_lock); ++ goto release_sem; + } +- if (is_bad_inode(inode)) { +- printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u\n", ic->ino); +- /* NB. This will happen again. We need to do something appropriate here. */ ++ ++ /* Fall through if it wanted us to, with inocache_lock held */ ++ } ++ ++ /* Prevent the fairly unlikely race where the gcblock is ++ entirely obsoleted by the final close of a file which had ++ the only valid nodes in the block, followed by erasure, ++ followed by freeing of the ic because the erased block(s) ++ held _all_ the nodes of that inode.... never been seen but ++ it's vaguely possible. */ ++ ++ inum = ic->ino; ++ nlink = ic->nlink; ++ spin_unlock(&c->inocache_lock); ++ ++ f = jffs2_gc_fetch_inode(c, inum, nlink); ++ if (IS_ERR(f)) ++ return PTR_ERR(f); ++ if (!f) ++ return 0; ++ ++ ret = jffs2_garbage_collect_live(c, jeb, raw, f); ++ ++ jffs2_gc_release_inode(c, f); ++ ++ release_sem: + up(&c->alloc_sem); +- iput(inode); +- return -EIO; ++ ++ eraseit_lock: ++ /* If we've finished this block, start it erasing */ ++ spin_lock(&c->erase_completion_lock); ++ ++ eraseit: ++ if (c->gcblock && !c->gcblock->used_size) { ++ D1(printk(KERN_DEBUG "Block at 0x%08x completely obsoleted by GC. Moving to erase_pending_list\n", c->gcblock->offset)); ++ /* We're GC'ing an empty block? */ ++ list_add_tail(&c->gcblock->list, &c->erase_pending_list); ++ c->gcblock = NULL; ++ c->nr_erasing_blocks++; ++ jffs2_erase_pending_trigger(c); + } ++ spin_unlock(&c->erase_completion_lock); ++ ++ return ret; ++} ++ ++static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, ++ struct jffs2_raw_node_ref *raw, struct jffs2_inode_info *f) ++{ ++ struct jffs2_node_frag *frag; ++ struct jffs2_full_dnode *fn = NULL; ++ struct jffs2_full_dirent *fd; ++ uint32_t start = 0, end = 0, nrfrags = 0; ++ int ret = 0; + +- f = JFFS2_INODE_INFO(inode); + down(&f->sem); ++ + /* Now we have the lock for this inode. Check that it's still the one at the head + of the list. */ + +- if (raw->flash_offset & 1) { ++ spin_lock(&c->erase_completion_lock); ++ ++ if (c->gcblock != jeb) { ++ spin_unlock(&c->erase_completion_lock); ++ D1(printk(KERN_DEBUG "GC block is no longer gcblock. Restart\n")); ++ goto upnout; ++ } ++ if (ref_obsolete(raw)) { ++ spin_unlock(&c->erase_completion_lock); + D1(printk(KERN_DEBUG "node to be GC'd was obsoleted in the meantime.\n")); + /* They'll call again */ + goto upnout; + } ++ spin_unlock(&c->erase_completion_lock); ++ + /* OK. Looks safe. And nobody can get us now because we have the semaphore. Move the block */ + if (f->metadata && f->metadata->raw == raw) { + fn = f->metadata; +- ret = jffs2_garbage_collect_metadata(c, jeb, inode, fn); ++ ret = jffs2_garbage_collect_metadata(c, jeb, f, fn); + goto upnout; + } + +- for (frag = f->fraglist; frag; frag = frag->next) { ++ /* FIXME. Read node and do lookup? */ ++ for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) { + if (frag->node && frag->node->raw == raw) { + fn = frag->node; + end = frag->ofs + frag->size; +@@ -237,13 +436,22 @@ + } + } + if (fn) { ++ if (ref_flags(raw) == REF_PRISTINE) { ++ ret = jffs2_garbage_collect_pristine(c, f->inocache, raw); ++ if (!ret) { ++ /* Urgh. Return it sensibly. */ ++ frag->node->raw = f->inocache->nodes; ++ } ++ if (ret != -EBADFD) ++ goto upnout; ++ } + /* We found a datanode. Do the GC */ + if((start >> PAGE_CACHE_SHIFT) < ((end-1) >> PAGE_CACHE_SHIFT)) { + /* It crosses a page boundary. Therefore, it must be a hole. */ +- ret = jffs2_garbage_collect_hole(c, jeb, inode, fn, start, end); ++ ret = jffs2_garbage_collect_hole(c, jeb, f, fn, start, end); + } else { + /* It could still be a hole. But we GC the page this way anyway */ +- ret = jffs2_garbage_collect_dnode(c, jeb, inode, fn, start, end); ++ ret = jffs2_garbage_collect_dnode(c, jeb, f, fn, start, end); + } + goto upnout; + } +@@ -255,12 +463,13 @@ + } + + if (fd && fd->ino) { +- ret = jffs2_garbage_collect_dirent(c, jeb, inode, fd); ++ ret = jffs2_garbage_collect_dirent(c, jeb, f, fd); + } else if (fd) { +- ret = jffs2_garbage_collect_deletion_dirent(c, jeb, inode, fd); ++ ret = jffs2_garbage_collect_deletion_dirent(c, jeb, f, fd); + } else { +- printk(KERN_WARNING "Raw node at 0x%08x wasn't in node lists for ino #%lu\n", raw->flash_offset&~3, inode->i_ino); +- if (raw->flash_offset & 1) { ++ printk(KERN_WARNING "Raw node at 0x%08x wasn't in node lists for ino #%u\n", ++ ref_offset(raw), f->inocache->ino); ++ if (ref_obsolete(raw)) { + printk(KERN_WARNING "But it's obsolete so we don't mind too much\n"); + } else { + ret = -EIO; +@@ -268,46 +477,197 @@ + } + upnout: + up(&f->sem); +- up(&c->alloc_sem); +- iput(inode); + +- eraseit_lock: +- /* If we've finished this block, start it erasing */ +- spin_lock_bh(&c->erase_completion_lock); ++ return ret; ++} + +- eraseit: +- if (c->gcblock && !c->gcblock->used_size) { +- D1(printk(KERN_DEBUG "Block at 0x%08x completely obsoleted by GC. Moving to erase_pending_list\n", c->gcblock->offset)); +- /* We're GC'ing an empty block? */ +- list_add_tail(&c->gcblock->list, &c->erase_pending_list); +- c->gcblock = NULL; +- c->nr_erasing_blocks++; +- jffs2_erase_pending_trigger(c); ++static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, ++ struct jffs2_inode_cache *ic, ++ struct jffs2_raw_node_ref *raw) ++{ ++ union jffs2_node_union *node; ++ struct jffs2_raw_node_ref *nraw; ++ size_t retlen; ++ int ret; ++ uint32_t phys_ofs, alloclen; ++ uint32_t crc, rawlen; ++ int retried = 0; ++ ++ D1(printk(KERN_DEBUG "Going to GC REF_PRISTINE node at 0x%08x\n", ref_offset(raw))); ++ ++ rawlen = ref_totlen(c, c->gcblock, raw); ++ ++ /* Ask for a small amount of space (or the totlen if smaller) because we ++ don't want to force wastage of the end of a block if splitting would ++ work. */ ++ ret = jffs2_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN, ++ rawlen), &phys_ofs, &alloclen); ++ if (ret) ++ return ret; ++ ++ if (alloclen < rawlen) { ++ /* Doesn't fit untouched. We'll go the old route and split it */ ++ return -EBADFD; ++ } ++ ++ node = kmalloc(rawlen, GFP_KERNEL); ++ if (!node) ++ return -ENOMEM; ++ ++ ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)node); ++ if (!ret && retlen != rawlen) ++ ret = -EIO; ++ if (ret) ++ goto out_node; ++ ++ crc = crc32(0, node, sizeof(struct jffs2_unknown_node)-4); ++ if (je32_to_cpu(node->u.hdr_crc) != crc) { ++ printk(KERN_WARNING "Header CRC failed on REF_PRISTINE node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", ++ ref_offset(raw), je32_to_cpu(node->u.hdr_crc), crc); ++ goto bail; ++ } ++ ++ switch(je16_to_cpu(node->u.nodetype)) { ++ case JFFS2_NODETYPE_INODE: ++ crc = crc32(0, node, sizeof(node->i)-8); ++ if (je32_to_cpu(node->i.node_crc) != crc) { ++ printk(KERN_WARNING "Node CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", ++ ref_offset(raw), je32_to_cpu(node->i.node_crc), crc); ++ goto bail; ++ } ++ ++ if (je32_to_cpu(node->i.dsize)) { ++ crc = crc32(0, node->i.data, je32_to_cpu(node->i.csize)); ++ if (je32_to_cpu(node->i.data_crc) != crc) { ++ printk(KERN_WARNING "Data CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", ++ ref_offset(raw), je32_to_cpu(node->i.data_crc), crc); ++ goto bail; + } +- spin_unlock_bh(&c->erase_completion_lock); ++ } ++ break; ++ ++ case JFFS2_NODETYPE_DIRENT: ++ crc = crc32(0, node, sizeof(node->d)-8); ++ if (je32_to_cpu(node->d.node_crc) != crc) { ++ printk(KERN_WARNING "Node CRC failed on REF_PRISTINE dirent node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", ++ ref_offset(raw), je32_to_cpu(node->d.node_crc), crc); ++ goto bail; ++ } ++ ++ if (node->d.nsize) { ++ crc = crc32(0, node->d.name, node->d.nsize); ++ if (je32_to_cpu(node->d.name_crc) != crc) { ++ printk(KERN_WARNING "Name CRC failed on REF_PRISTINE dirent ode at 0x%08x: Read 0x%08x, calculated 0x%08x\n", ++ ref_offset(raw), je32_to_cpu(node->d.name_crc), crc); ++ goto bail; ++ } ++ } ++ break; ++ default: ++ printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n", ++ ref_offset(raw), je16_to_cpu(node->u.nodetype)); ++ goto bail; ++ } ++ ++ nraw = jffs2_alloc_raw_node_ref(); ++ if (!nraw) { ++ ret = -ENOMEM; ++ goto out_node; ++ } ++ ++ /* OK, all the CRCs are good; this node can just be copied as-is. */ ++ retry: ++ nraw->flash_offset = phys_ofs; ++ nraw->__totlen = rawlen; ++ nraw->next_phys = NULL; ++ ++ ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (char *)node); ++ ++ if (ret || (retlen != rawlen)) { ++ printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n", ++ rawlen, phys_ofs, ret, retlen); ++ if (retlen) { ++ /* Doesn't belong to any inode */ ++ nraw->next_in_ino = NULL; ++ ++ nraw->flash_offset |= REF_OBSOLETE; ++ jffs2_add_physical_node_ref(c, nraw); ++ jffs2_mark_node_obsolete(c, nraw); ++ } else { ++ printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", nraw->flash_offset); ++ jffs2_free_raw_node_ref(nraw); ++ } ++ if (!retried && (nraw == jffs2_alloc_raw_node_ref())) { ++ /* Try to reallocate space and retry */ ++ uint32_t dummy; ++ struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size]; ++ ++ retried = 1; ++ ++ D1(printk(KERN_DEBUG "Retrying failed write of REF_PRISTINE node.\n")); ++ ++ ACCT_SANITY_CHECK(c,jeb); ++ D1(ACCT_PARANOIA_CHECK(jeb)); ++ ++ ret = jffs2_reserve_space_gc(c, rawlen, &phys_ofs, &dummy); ++ ++ if (!ret) { ++ D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", phys_ofs)); + ++ ACCT_SANITY_CHECK(c,jeb); ++ D1(ACCT_PARANOIA_CHECK(jeb)); ++ ++ goto retry; ++ } ++ D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); ++ jffs2_free_raw_node_ref(nraw); ++ } ++ ++ if (!ret) ++ ret = -EIO; ++ goto out_node; ++ } ++ nraw->flash_offset |= REF_PRISTINE; ++ jffs2_add_physical_node_ref(c, nraw); ++ ++ /* Link into per-inode list. This is safe because of the ic ++ state being INO_STATE_GC. Note that if we're doing this ++ for an inode which is in-code, the 'nraw' pointer is then ++ going to be fetched from ic->nodes by our caller. */ ++ nraw->next_in_ino = ic->nodes; ++ ic->nodes = nraw; ++ ++ jffs2_mark_node_obsolete(c, raw); ++ D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", ref_offset(raw))); ++ ++ out_node: ++ kfree(node); + return ret; ++ bail: ++ ret = -EBADFD; ++ goto out_node; + } + + static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, +- struct inode *inode, struct jffs2_full_dnode *fn) ++ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn) + { +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_full_dnode *new_fn; + struct jffs2_raw_inode ri; +- unsigned short dev; ++ jint16_t dev; + char *mdata = NULL, mdatalen = 0; +- __u32 alloclen, phys_ofs; ++ uint32_t alloclen, phys_ofs; + int ret; + +- if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { ++ if (S_ISBLK(JFFS2_F_I_MODE(f)) || ++ S_ISCHR(JFFS2_F_I_MODE(f)) ) { + /* For these, we don't actually need to read the old node */ +- dev = (MAJOR(to_kdev_t(inode->i_rdev)) << 8) | +- MINOR(to_kdev_t(inode->i_rdev)); ++ /* FIXME: for minor or major > 255. */ ++ dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) | ++ JFFS2_F_I_RDEV_MIN(f))); + mdata = (char *)&dev; + mdatalen = sizeof(dev); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bytes of kdev_t\n", mdatalen)); +- } else if (S_ISLNK(inode->i_mode)) { ++ } else if (S_ISLNK(JFFS2_F_I_MODE(f))) { + mdatalen = fn->size; + mdata = kmalloc(fn->size, GFP_KERNEL); + if (!mdata) { +@@ -326,34 +686,34 @@ + + ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen); + if (ret) { +- printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_metadata failed: %d\n", ++ printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_metadata failed: %d\n", + sizeof(ri)+ mdatalen, ret); + goto out; + } + + memset(&ri, 0, sizeof(ri)); +- ri.magic = JFFS2_MAGIC_BITMASK; +- ri.nodetype = JFFS2_NODETYPE_INODE; +- ri.totlen = sizeof(ri) + mdatalen; +- ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4); +- +- ri.ino = inode->i_ino; +- ri.version = ++f->highest_version; +- ri.mode = inode->i_mode; +- ri.uid = inode->i_uid; +- ri.gid = inode->i_gid; +- ri.isize = inode->i_size; +- ri.atime = inode->i_atime; +- ri.ctime = inode->i_ctime; +- ri.mtime = inode->i_mtime; +- ri.offset = 0; +- ri.csize = mdatalen; +- ri.dsize = mdatalen; ++ ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); ++ ri.totlen = cpu_to_je32(sizeof(ri) + mdatalen); ++ ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4)); ++ ++ ri.ino = cpu_to_je32(f->inocache->ino); ++ ri.version = cpu_to_je32(++f->highest_version); ++ ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); ++ ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); ++ ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); ++ ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f)); ++ ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); ++ ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); ++ ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); ++ ri.offset = cpu_to_je32(0); ++ ri.csize = cpu_to_je32(mdatalen); ++ ri.dsize = cpu_to_je32(mdatalen); + ri.compr = JFFS2_COMPR_NONE; +- ri.node_crc = crc32(0, &ri, sizeof(ri)-8); +- ri.data_crc = crc32(0, mdata, mdatalen); ++ ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); ++ ri.data_crc = cpu_to_je32(crc32(0, mdata, mdatalen)); + +- new_fn = jffs2_write_dnode(inode, &ri, mdata, mdatalen, phys_ofs, NULL); ++ new_fn = jffs2_write_dnode(c, f, &ri, mdata, mdatalen, phys_ofs, ALLOC_GC); + + if (IS_ERR(new_fn)) { + printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn)); +@@ -364,41 +724,40 @@ + jffs2_free_full_dnode(fn); + f->metadata = new_fn; + out: +- if (S_ISLNK(inode->i_mode)) ++ if (S_ISLNK(JFFS2_F_I_MODE(f))) + kfree(mdata); + return ret; + } + + static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, +- struct inode *inode, struct jffs2_full_dirent *fd) ++ struct jffs2_inode_info *f, struct jffs2_full_dirent *fd) + { +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_full_dirent *new_fd; + struct jffs2_raw_dirent rd; +- __u32 alloclen, phys_ofs; ++ uint32_t alloclen, phys_ofs; + int ret; + +- rd.magic = JFFS2_MAGIC_BITMASK; +- rd.nodetype = JFFS2_NODETYPE_DIRENT; ++ rd.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ rd.nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); + rd.nsize = strlen(fd->name); +- rd.totlen = sizeof(rd) + rd.nsize; +- rd.hdr_crc = crc32(0, &rd, sizeof(struct jffs2_unknown_node)-4); ++ rd.totlen = cpu_to_je32(sizeof(rd) + rd.nsize); ++ rd.hdr_crc = cpu_to_je32(crc32(0, &rd, sizeof(struct jffs2_unknown_node)-4)); + +- rd.pino = inode->i_ino; +- rd.version = ++f->highest_version; +- rd.ino = fd->ino; +- rd.mctime = max(inode->i_mtime, inode->i_ctime); ++ rd.pino = cpu_to_je32(f->inocache->ino); ++ rd.version = cpu_to_je32(++f->highest_version); ++ rd.ino = cpu_to_je32(fd->ino); ++ rd.mctime = cpu_to_je32(max(JFFS2_F_I_MTIME(f), JFFS2_F_I_CTIME(f))); + rd.type = fd->type; +- rd.node_crc = crc32(0, &rd, sizeof(rd)-8); +- rd.name_crc = crc32(0, fd->name, rd.nsize); ++ rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8)); ++ rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize)); + + ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen); + if (ret) { +- printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_dirent failed: %d\n", ++ printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dirent failed: %d\n", + sizeof(rd)+rd.nsize, ret); + return ret; + } +- new_fd = jffs2_write_dirent(inode, &rd, fd->name, rd.nsize, phys_ofs, NULL); ++ new_fd = jffs2_write_dirent(c, f, &rd, fd->name, rd.nsize, phys_ofs, ALLOC_GC); + + if (IS_ERR(new_fd)) { + printk(KERN_WARNING "jffs2_write_dirent in garbage_collect_dirent failed: %ld\n", PTR_ERR(new_fd)); +@@ -409,19 +768,98 @@ + } + + static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, +- struct inode *inode, struct jffs2_full_dirent *fd) ++ struct jffs2_inode_info *f, struct jffs2_full_dirent *fd) + { +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_full_dirent **fdp = &f->dents; + int found = 0; + +- /* FIXME: When we run on NAND flash, we need to work out whether +- this deletion dirent is still needed to actively delete a +- 'real' dirent with the same name that's still somewhere else +- on the flash. For now, we know that we've actually obliterated +- all the older dirents when they became obsolete, so we didn't +- really need to write the deletion to flash in the first place. +- */ ++ /* On a medium where we can't actually mark nodes obsolete ++ pernamently, such as NAND flash, we need to work out ++ whether this deletion dirent is still needed to actively ++ delete a 'real' dirent with the same name that's still ++ somewhere else on the flash. */ ++ if (!jffs2_can_mark_obsolete(c)) { ++ struct jffs2_raw_dirent *rd; ++ struct jffs2_raw_node_ref *raw; ++ int ret; ++ size_t retlen; ++ int name_len = strlen(fd->name); ++ uint32_t name_crc = crc32(0, fd->name, name_len); ++ uint32_t rawlen = ref_totlen(c, jeb, fd->raw); ++ ++ rd = kmalloc(rawlen, GFP_KERNEL); ++ if (!rd) ++ return -ENOMEM; ++ ++ /* Prevent the erase code from nicking the obsolete node refs while ++ we're looking at them. I really don't like this extra lock but ++ can't see any alternative. Suggestions on a postcard to... */ ++ down(&c->erase_free_sem); ++ ++ for (raw = f->inocache->nodes; raw != (void *)f->inocache; raw = raw->next_in_ino) { ++ ++ /* We only care about obsolete ones */ ++ if (!(ref_obsolete(raw))) ++ continue; ++ ++ /* Any dirent with the same name is going to have the same length... */ ++ if (ref_totlen(c, NULL, raw) != rawlen) ++ continue; ++ ++ /* Doesn't matter if there's one in the same erase block. We're going to ++ delete it too at the same time. */ ++ if ((raw->flash_offset & ~(c->sector_size-1)) == ++ (fd->raw->flash_offset & ~(c->sector_size-1))) ++ continue; ++ ++ D1(printk(KERN_DEBUG "Check potential deletion dirent at %08x\n", ref_offset(raw))); ++ ++ /* This is an obsolete node belonging to the same directory, and it's of the right ++ length. We need to take a closer look...*/ ++ ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)rd); ++ if (ret) { ++ printk(KERN_WARNING "jffs2_g_c_deletion_dirent(): Read error (%d) reading obsolete node at %08x\n", ret, ref_offset(raw)); ++ /* If we can't read it, we don't need to continue to obsolete it. Continue */ ++ continue; ++ } ++ if (retlen != rawlen) { ++ printk(KERN_WARNING "jffs2_g_c_deletion_dirent(): Short read (%zd not %zd) reading header from obsolete node at %08x\n", ++ retlen, rawlen, ref_offset(raw)); ++ continue; ++ } ++ ++ if (je16_to_cpu(rd->nodetype) != JFFS2_NODETYPE_DIRENT) ++ continue; ++ ++ /* If the name CRC doesn't match, skip */ ++ if (je32_to_cpu(rd->name_crc) != name_crc) ++ continue; ++ ++ /* If the name length doesn't match, or it's another deletion dirent, skip */ ++ if (rd->nsize != name_len || !je32_to_cpu(rd->ino)) ++ continue; ++ ++ /* OK, check the actual name now */ ++ if (memcmp(rd->name, fd->name, name_len)) ++ continue; ++ ++ /* OK. The name really does match. There really is still an older node on ++ the flash which our deletion dirent obsoletes. So we have to write out ++ a new deletion dirent to replace it */ ++ up(&c->erase_free_sem); ++ ++ D1(printk(KERN_DEBUG "Deletion dirent at %08x still obsoletes real dirent \"%s\" at %08x for ino #%u\n", ++ ref_offset(fd->raw), fd->name, ref_offset(raw), je32_to_cpu(rd->ino))); ++ kfree(rd); ++ ++ return jffs2_garbage_collect_dirent(c, jeb, f, fd); ++ } ++ ++ up(&c->erase_free_sem); ++ kfree(rd); ++ } ++ ++ /* No need for it any more. Just mark it obsolete and remove it from the list */ + while (*fdp) { + if ((*fdp) == fd) { + found = 1; +@@ -431,7 +869,7 @@ + fdp = &(*fdp)->next; + } + if (!found) { +- printk(KERN_WARNING "Deletion dirent \"%s\" not found in list for ino #%lu\n", fd->name, inode->i_ino); ++ printk(KERN_WARNING "Deletion dirent \"%s\" not found in list for ino #%u\n", fd->name, f->inocache->ino); + } + jffs2_mark_node_obsolete(c, fd->raw); + jffs2_free_full_dirent(fd); +@@ -439,93 +877,95 @@ + } + + static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, +- struct inode *inode, struct jffs2_full_dnode *fn, +- __u32 start, __u32 end) ++ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, ++ uint32_t start, uint32_t end) + { +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_raw_inode ri; + struct jffs2_node_frag *frag; + struct jffs2_full_dnode *new_fn; +- __u32 alloclen, phys_ofs; ++ uint32_t alloclen, phys_ofs; + int ret; + +- D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%lu from offset 0x%x to 0x%x\n", +- inode->i_ino, start, end)); ++ D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n", ++ f->inocache->ino, start, end)); + + memset(&ri, 0, sizeof(ri)); + + if(fn->frags > 1) { + size_t readlen; +- __u32 crc; ++ uint32_t crc; + /* It's partially obsoleted by a later write. So we have to + write it out again with the _same_ version as before */ +- ret = c->mtd->read(c->mtd, fn->raw->flash_offset & ~3, sizeof(ri), &readlen, (char *)&ri); ++ ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (char *)&ri); + if (readlen != sizeof(ri) || ret) { +- printk(KERN_WARNING "Node read failed in jffs2_garbage_collect_hole. Ret %d, retlen %d. Data will be lost by writing new hold node\n", ret, readlen); ++ printk(KERN_WARNING "Node read failed in jffs2_garbage_collect_hole. Ret %d, retlen %zd. Data will be lost by writing new hole node\n", ret, readlen); + goto fill; + } +- if (ri.nodetype != JFFS2_NODETYPE_INODE) { ++ if (je16_to_cpu(ri.nodetype) != JFFS2_NODETYPE_INODE) { + printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had node type 0x%04x instead of JFFS2_NODETYPE_INODE(0x%04x)\n", +- fn->raw->flash_offset & ~3, ri.nodetype, JFFS2_NODETYPE_INODE); ++ ref_offset(fn->raw), ++ je16_to_cpu(ri.nodetype), JFFS2_NODETYPE_INODE); + return -EIO; + } +- if (ri.totlen != sizeof(ri)) { +- printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had totlen 0x%x instead of expected 0x%x\n", +- fn->raw->flash_offset & ~3, ri.totlen, sizeof(ri)); ++ if (je32_to_cpu(ri.totlen) != sizeof(ri)) { ++ printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had totlen 0x%x instead of expected 0x%zx\n", ++ ref_offset(fn->raw), ++ je32_to_cpu(ri.totlen), sizeof(ri)); + return -EIO; + } + crc = crc32(0, &ri, sizeof(ri)-8); +- if (crc != ri.node_crc) { ++ if (crc != je32_to_cpu(ri.node_crc)) { + printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n", +- fn->raw->flash_offset & ~3, ri.node_crc, crc); ++ ref_offset(fn->raw), ++ je32_to_cpu(ri.node_crc), crc); + /* FIXME: We could possibly deal with this by writing new holes for each frag */ +- printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%lu will be lost\n", +- start, end, inode->i_ino); ++ printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", ++ start, end, f->inocache->ino); + goto fill; + } + if (ri.compr != JFFS2_COMPR_ZERO) { +- printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", fn->raw->flash_offset & ~3); +- printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%lu will be lost\n", +- start, end, inode->i_ino); ++ printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", ref_offset(fn->raw)); ++ printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", ++ start, end, f->inocache->ino); + goto fill; + } + } else { + fill: +- ri.magic = JFFS2_MAGIC_BITMASK; +- ri.nodetype = JFFS2_NODETYPE_INODE; +- ri.totlen = sizeof(ri); +- ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4); +- +- ri.ino = inode->i_ino; +- ri.version = ++f->highest_version; +- ri.offset = start; +- ri.dsize = end - start; +- ri.csize = 0; ++ ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); ++ ri.totlen = cpu_to_je32(sizeof(ri)); ++ ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4)); ++ ++ ri.ino = cpu_to_je32(f->inocache->ino); ++ ri.version = cpu_to_je32(++f->highest_version); ++ ri.offset = cpu_to_je32(start); ++ ri.dsize = cpu_to_je32(end - start); ++ ri.csize = cpu_to_je32(0); + ri.compr = JFFS2_COMPR_ZERO; + } +- ri.mode = inode->i_mode; +- ri.uid = inode->i_uid; +- ri.gid = inode->i_gid; +- ri.isize = inode->i_size; +- ri.atime = inode->i_atime; +- ri.ctime = inode->i_ctime; +- ri.mtime = inode->i_mtime; +- ri.data_crc = 0; +- ri.node_crc = crc32(0, &ri, sizeof(ri)-8); ++ ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); ++ ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); ++ ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); ++ ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f)); ++ ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); ++ ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); ++ ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); ++ ri.data_crc = cpu_to_je32(0); ++ ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); + + ret = jffs2_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen); + if (ret) { +- printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_hole failed: %d\n", ++ printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n", + sizeof(ri), ret); + return ret; + } +- new_fn = jffs2_write_dnode(inode, &ri, NULL, 0, phys_ofs, NULL); ++ new_fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_GC); + + if (IS_ERR(new_fn)) { + printk(KERN_WARNING "Error writing new hole node: %ld\n", PTR_ERR(new_fn)); + return PTR_ERR(new_fn); + } +- if (ri.version == f->highest_version) { ++ if (je32_to_cpu(ri.version) == f->highest_version) { + jffs2_add_full_dnode_to_inode(c, f, new_fn); + if (f->metadata) { + jffs2_mark_node_obsolete(c, f->metadata->raw); +@@ -541,12 +981,17 @@ + * number as before. (Except in case of error -- see 'goto fill;' + * above.) + */ +- D1(if(fn->frags <= 1) { ++ D1(if(unlikely(fn->frags <= 1)) { + printk(KERN_WARNING "jffs2_garbage_collect_hole: Replacing fn with %d frag(s) but new ver %d != highest_version %d of ino #%d\n", +- fn->frags, ri.version, f->highest_version, ri.ino); ++ fn->frags, je32_to_cpu(ri.version), f->highest_version, ++ je32_to_cpu(ri.ino)); + }); + +- for (frag = f->fraglist; frag; frag = frag->next) { ++ /* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */ ++ mark_ref_normal(new_fn->raw); ++ ++ for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs); ++ frag; frag = frag_next(frag)) { + if (frag->ofs > fn->size + fn->ofs) + break; + if (frag->node == fn) { +@@ -571,49 +1016,146 @@ + } + + static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, +- struct inode *inode, struct jffs2_full_dnode *fn, +- __u32 start, __u32 end) ++ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, ++ uint32_t start, uint32_t end) + { +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_full_dnode *new_fn; + struct jffs2_raw_inode ri; +- __u32 alloclen, phys_ofs, offset, orig_end; ++ uint32_t alloclen, phys_ofs, offset, orig_end, orig_start; + int ret = 0; + unsigned char *comprbuf = NULL, *writebuf; +- struct page *pg; ++ unsigned long pg; + unsigned char *pg_ptr; + +- + memset(&ri, 0, sizeof(ri)); + +- D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%lu from offset 0x%x to 0x%x\n", +- inode->i_ino, start, end)); ++ D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n", ++ f->inocache->ino, start, end)); + + orig_end = end; ++ orig_start = start; + ++ if (c->nr_free_blocks + c->nr_erasing_blocks > c->resv_blocks_gcmerge) { ++ /* Attempt to do some merging. But only expand to cover logically ++ adjacent frags if the block containing them is already considered ++ to be dirty. Otherwise we end up with GC just going round in ++ circles dirtying the nodes it already wrote out, especially ++ on NAND where we have small eraseblocks and hence a much higher ++ chance of nodes having to be split to cross boundaries. */ + +- /* If we're looking at the last node in the block we're +- garbage-collecting, we allow ourselves to merge as if the +- block was already erasing. We're likely to be GC'ing a +- partial page, and the next block we GC is likely to have +- the other half of this page right at the beginning, which +- means we'd expand it _then_, as nr_erasing_blocks would have +- increased since we checked, and in doing so would obsolete +- the partial node which we'd have written here. Meaning that +- the GC would churn and churn, and just leave dirty blocks in +- it's wake. +- */ +- if(c->nr_free_blocks + c->nr_erasing_blocks > JFFS2_RESERVED_BLOCKS_GCMERGE - (fn->raw->next_phys?0:1)) { +- /* Shitloads of space */ +- /* FIXME: Integrate this properly with GC calculations */ +- start &= ~(PAGE_CACHE_SIZE-1); +- end = min_t(__u32, start + PAGE_CACHE_SIZE, inode->i_size); +- D1(printk(KERN_DEBUG "Plenty of free space, so expanding to write from offset 0x%x to 0x%x\n", +- start, end)); +- if (end < orig_end) { +- printk(KERN_WARNING "Eep. jffs2_garbage_collect_dnode extended node to write, but it got smaller: start 0x%x, orig_end 0x%x, end 0x%x\n", start, orig_end, end); +- end = orig_end; ++ struct jffs2_node_frag *frag; ++ uint32_t min, max; ++ ++ min = start & ~(PAGE_CACHE_SIZE-1); ++ max = min + PAGE_CACHE_SIZE; ++ ++ frag = jffs2_lookup_node_frag(&f->fragtree, start); ++ ++ /* BUG_ON(!frag) but that'll happen anyway... */ ++ ++ BUG_ON(frag->ofs != start); ++ ++ /* First grow down... */ ++ while((frag = frag_prev(frag)) && frag->ofs >= min) { ++ ++ /* If the previous frag doesn't even reach the beginning, there's ++ excessive fragmentation. Just merge. */ ++ if (frag->ofs > min) { ++ D1(printk(KERN_DEBUG "Expanding down to cover partial frag (0x%x-0x%x)\n", ++ frag->ofs, frag->ofs+frag->size)); ++ start = frag->ofs; ++ continue; ++ } ++ /* OK. This frag holds the first byte of the page. */ ++ if (!frag->node || !frag->node->raw) { ++ D1(printk(KERN_DEBUG "First frag in page is hole (0x%x-0x%x). Not expanding down.\n", ++ frag->ofs, frag->ofs+frag->size)); ++ break; ++ } else { ++ ++ /* OK, it's a frag which extends to the beginning of the page. Does it live ++ in a block which is still considered clean? If so, don't obsolete it. ++ If not, cover it anyway. */ ++ ++ struct jffs2_raw_node_ref *raw = frag->node->raw; ++ struct jffs2_eraseblock *jeb; ++ ++ jeb = &c->blocks[raw->flash_offset / c->sector_size]; ++ ++ if (jeb == c->gcblock) { ++ D1(printk(KERN_DEBUG "Expanding down to cover frag (0x%x-0x%x) in gcblock at %08x\n", ++ frag->ofs, frag->ofs+frag->size, ref_offset(raw))); ++ start = frag->ofs; ++ break; + } ++ if (!ISDIRTY(jeb->dirty_size + jeb->wasted_size)) { ++ D1(printk(KERN_DEBUG "Not expanding down to cover frag (0x%x-0x%x) in clean block %08x\n", ++ frag->ofs, frag->ofs+frag->size, jeb->offset)); ++ break; ++ } ++ ++ D1(printk(KERN_DEBUG "Expanding down to cover frag (0x%x-0x%x) in dirty block %08x\n", ++ frag->ofs, frag->ofs+frag->size, jeb->offset)); ++ start = frag->ofs; ++ break; ++ } ++ } ++ ++ /* ... then up */ ++ ++ /* Find last frag which is actually part of the node we're to GC. */ ++ frag = jffs2_lookup_node_frag(&f->fragtree, end-1); ++ ++ while((frag = frag_next(frag)) && frag->ofs+frag->size <= max) { ++ ++ /* If the previous frag doesn't even reach the beginning, there's lots ++ of fragmentation. Just merge. */ ++ if (frag->ofs+frag->size < max) { ++ D1(printk(KERN_DEBUG "Expanding up to cover partial frag (0x%x-0x%x)\n", ++ frag->ofs, frag->ofs+frag->size)); ++ end = frag->ofs + frag->size; ++ continue; ++ } ++ ++ if (!frag->node || !frag->node->raw) { ++ D1(printk(KERN_DEBUG "Last frag in page is hole (0x%x-0x%x). Not expanding up.\n", ++ frag->ofs, frag->ofs+frag->size)); ++ break; ++ } else { ++ ++ /* OK, it's a frag which extends to the beginning of the page. Does it live ++ in a block which is still considered clean? If so, don't obsolete it. ++ If not, cover it anyway. */ ++ ++ struct jffs2_raw_node_ref *raw = frag->node->raw; ++ struct jffs2_eraseblock *jeb; ++ ++ jeb = &c->blocks[raw->flash_offset / c->sector_size]; ++ ++ if (jeb == c->gcblock) { ++ D1(printk(KERN_DEBUG "Expanding up to cover frag (0x%x-0x%x) in gcblock at %08x\n", ++ frag->ofs, frag->ofs+frag->size, ref_offset(raw))); ++ end = frag->ofs + frag->size; ++ break; ++ } ++ if (!ISDIRTY(jeb->dirty_size + jeb->wasted_size)) { ++ D1(printk(KERN_DEBUG "Not expanding up to cover frag (0x%x-0x%x) in clean block %08x\n", ++ frag->ofs, frag->ofs+frag->size, jeb->offset)); ++ break; ++ } ++ ++ D1(printk(KERN_DEBUG "Expanding up to cover frag (0x%x-0x%x) in dirty block %08x\n", ++ frag->ofs, frag->ofs+frag->size, jeb->offset)); ++ end = frag->ofs + frag->size; ++ break; ++ } ++ } ++ D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n", ++ orig_start, orig_end, start, end)); ++ ++ BUG_ON(end > JFFS2_F_I_SIZE(f)); ++ BUG_ON(end < orig_end); ++ BUG_ON(start > orig_start); + } + + /* First, use readpage() to read the appropriate page into the page cache */ +@@ -623,63 +1165,57 @@ + * page OK. We'll actually write it out again in commit_write, which is a little + * suboptimal, but at least we're correct. + */ +- pg = read_cache_page(inode->i_mapping, start >> PAGE_CACHE_SHIFT, (void *)jffs2_do_readpage_unlock, inode); ++ pg_ptr = jffs2_gc_fetch_page(c, f, start, &pg); + +- if (IS_ERR(pg)) { +- printk(KERN_WARNING "read_cache_page() returned error: %ld\n", PTR_ERR(pg)); +- return PTR_ERR(pg); ++ if (IS_ERR(pg_ptr)) { ++ printk(KERN_WARNING "read_cache_page() returned error: %ld\n", PTR_ERR(pg_ptr)); ++ return PTR_ERR(pg_ptr); + } +- pg_ptr = (char *)kmap(pg); +- comprbuf = kmalloc(end - start, GFP_KERNEL); + + offset = start; + while(offset < orig_end) { +- __u32 datalen; +- __u32 cdatalen; ++ uint32_t datalen; ++ uint32_t cdatalen; + char comprtype = JFFS2_COMPR_NONE; + + ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen); + + if (ret) { +- printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_dnode failed: %d\n", ++ printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dnode failed: %d\n", + sizeof(ri)+ JFFS2_MIN_DATA_LEN, ret); + break; + } +- cdatalen = min(alloclen - sizeof(ri), end - offset); ++ cdatalen = min_t(uint32_t, alloclen - sizeof(ri), end - offset); + datalen = end - offset; + + writebuf = pg_ptr + (offset & (PAGE_CACHE_SIZE -1)); + +- if (comprbuf) { +- comprtype = jffs2_compress(writebuf, comprbuf, &datalen, &cdatalen); +- } +- if (comprtype) { +- writebuf = comprbuf; +- } else { +- datalen = cdatalen; +- } +- ri.magic = JFFS2_MAGIC_BITMASK; +- ri.nodetype = JFFS2_NODETYPE_INODE; +- ri.totlen = sizeof(ri) + cdatalen; +- ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4); +- +- ri.ino = inode->i_ino; +- ri.version = ++f->highest_version; +- ri.mode = inode->i_mode; +- ri.uid = inode->i_uid; +- ri.gid = inode->i_gid; +- ri.isize = inode->i_size; +- ri.atime = inode->i_atime; +- ri.ctime = inode->i_ctime; +- ri.mtime = inode->i_mtime; +- ri.offset = offset; +- ri.csize = cdatalen; +- ri.dsize = datalen; ++ comprtype = jffs2_compress(writebuf, &comprbuf, &datalen, &cdatalen); ++ ++ ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); ++ ri.totlen = cpu_to_je32(sizeof(ri) + cdatalen); ++ ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4)); ++ ++ ri.ino = cpu_to_je32(f->inocache->ino); ++ ri.version = cpu_to_je32(++f->highest_version); ++ ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); ++ ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); ++ ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); ++ ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f)); ++ ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); ++ ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); ++ ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); ++ ri.offset = cpu_to_je32(offset); ++ ri.csize = cpu_to_je32(cdatalen); ++ ri.dsize = cpu_to_je32(datalen); + ri.compr = comprtype; +- ri.node_crc = crc32(0, &ri, sizeof(ri)-8); +- ri.data_crc = crc32(0, writebuf, cdatalen); ++ ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); ++ ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen)); ++ ++ new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, phys_ofs, ALLOC_GC); + +- new_fn = jffs2_write_dnode(inode, &ri, writebuf, cdatalen, phys_ofs, NULL); ++ jffs2_free_comprbuf(comprbuf, writebuf); + + if (IS_ERR(new_fn)) { + printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn)); +@@ -694,12 +1230,8 @@ + f->metadata = NULL; + } + } +- if (comprbuf) kfree(comprbuf); + +- kunmap(pg); +- /* XXX: Does the page get freed automatically? */ +- /* AAA: Judging by the unmount getting stuck in __wait_on_page, nope. */ +- page_cache_release(pg); ++ jffs2_gc_release_page(c, pg_ptr, &pg); + return ret; + } + +diff -Nurb linux-mips-2.4.27/fs/jffs2/ioctl.c linux/fs/jffs2/ioctl.c +--- linux-mips-2.4.27/fs/jffs2/ioctl.c 2001-10-19 03:24:56.000000000 +0200 ++++ linux/fs/jffs2/ioctl.c 2004-11-19 10:25:12.108168024 +0100 +@@ -1,37 +1,13 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: ioctl.c,v 1.5 2001/03/15 15:38:24 dwmw2 Exp $ ++ * $Id: ioctl.c,v 1.8 2003/10/28 16:16:28 dwmw2 Exp $ + * + */ + +@@ -42,6 +18,6 @@ + { + /* Later, this will provide for lsattr.jffs2 and chattr.jffs2, which + will include compression support etc. */ +- return -EINVAL; ++ return -ENOTTY; + } + +diff -Nurb linux-mips-2.4.27/fs/jffs2/malloc.c linux/fs/jffs2/malloc.c +--- linux-mips-2.4.27/fs/jffs2/malloc.c 2001-10-19 03:24:56.000000000 +0200 ++++ linux/fs/jffs2/malloc.c 2004-11-19 10:25:12.110167720 +0100 +@@ -1,37 +1,13 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: malloc.c,v 1.16 2001/03/15 15:38:24 dwmw2 Exp $ ++ * $Id: malloc.c,v 1.27 2003/10/28 17:14:58 dwmw2 Exp $ + * + */ + +@@ -47,6 +23,9 @@ + #define JFFS2_SLAB_POISON 0 + #endif + ++// replace this by #define D3 (x) x for cache debugging ++#define D3(x) ++ + /* These are initialised to NULL in the kernel startup code. + If you're porting to other operating systems, beware */ + static kmem_cache_t *full_dnode_slab; +@@ -57,57 +36,47 @@ + static kmem_cache_t *node_frag_slab; + static kmem_cache_t *inode_cache_slab; + +-void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn) +-{ +- struct jffs2_tmp_dnode_info *next; +- +- while (tn) { +- next = tn; +- tn = tn->next; +- jffs2_free_full_dnode(next->fn); +- jffs2_free_tmp_dnode_info(next); +- } +-} +- +-void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd) +-{ +- struct jffs2_full_dirent *next; +- +- while (fd) { +- next = fd->next; +- jffs2_free_full_dirent(fd); +- fd = next; +- } +-} +- + int __init jffs2_create_slab_caches(void) + { +- full_dnode_slab = kmem_cache_create("jffs2_full_dnode", sizeof(struct jffs2_full_dnode), 0, JFFS2_SLAB_POISON, NULL, NULL); ++ full_dnode_slab = kmem_cache_create("jffs2_full_dnode", ++ sizeof(struct jffs2_full_dnode), ++ 0, JFFS2_SLAB_POISON, NULL, NULL); + if (!full_dnode_slab) + goto err; + +- raw_dirent_slab = kmem_cache_create("jffs2_raw_dirent", sizeof(struct jffs2_raw_dirent), 0, JFFS2_SLAB_POISON, NULL, NULL); ++ raw_dirent_slab = kmem_cache_create("jffs2_raw_dirent", ++ sizeof(struct jffs2_raw_dirent), ++ 0, JFFS2_SLAB_POISON, NULL, NULL); + if (!raw_dirent_slab) + goto err; + +- raw_inode_slab = kmem_cache_create("jffs2_raw_inode", sizeof(struct jffs2_raw_inode), 0, JFFS2_SLAB_POISON, NULL, NULL); ++ raw_inode_slab = kmem_cache_create("jffs2_raw_inode", ++ sizeof(struct jffs2_raw_inode), ++ 0, JFFS2_SLAB_POISON, NULL, NULL); + if (!raw_inode_slab) + goto err; + +- tmp_dnode_info_slab = kmem_cache_create("jffs2_tmp_dnode", sizeof(struct jffs2_tmp_dnode_info), 0, JFFS2_SLAB_POISON, NULL, NULL); ++ tmp_dnode_info_slab = kmem_cache_create("jffs2_tmp_dnode", ++ sizeof(struct jffs2_tmp_dnode_info), ++ 0, JFFS2_SLAB_POISON, NULL, NULL); + if (!tmp_dnode_info_slab) + goto err; + +- raw_node_ref_slab = kmem_cache_create("jffs2_raw_node_ref", sizeof(struct jffs2_raw_node_ref), 0, JFFS2_SLAB_POISON, NULL, NULL); ++ raw_node_ref_slab = kmem_cache_create("jffs2_raw_node_ref", ++ sizeof(struct jffs2_raw_node_ref), ++ 0, JFFS2_SLAB_POISON, NULL, NULL); + if (!raw_node_ref_slab) + goto err; + +- node_frag_slab = kmem_cache_create("jffs2_node_frag", sizeof(struct jffs2_node_frag), 0, JFFS2_SLAB_POISON, NULL, NULL); ++ node_frag_slab = kmem_cache_create("jffs2_node_frag", ++ sizeof(struct jffs2_node_frag), ++ 0, JFFS2_SLAB_POISON, NULL, NULL); + if (!node_frag_slab) + goto err; + +- inode_cache_slab = kmem_cache_create("jffs2_inode_cache", sizeof(struct jffs2_inode_cache), 0, JFFS2_SLAB_POISON, NULL, NULL); +- ++ inode_cache_slab = kmem_cache_create("jffs2_inode_cache", ++ sizeof(struct jffs2_inode_cache), ++ 0, JFFS2_SLAB_POISON, NULL, NULL); + if (inode_cache_slab) + return 0; + err: +@@ -131,7 +100,6 @@ + kmem_cache_destroy(node_frag_slab); + if(inode_cache_slab) + kmem_cache_destroy(inode_cache_slab); +- + } + + struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize) +@@ -146,75 +114,92 @@ + + struct jffs2_full_dnode *jffs2_alloc_full_dnode(void) + { +- void *ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL); ++ struct jffs2_full_dnode *ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL); ++ D3 (printk (KERN_DEBUG "alloc_full_dnode at %p\n", ret)); + return ret; + } + + void jffs2_free_full_dnode(struct jffs2_full_dnode *x) + { ++ D3 (printk (KERN_DEBUG "free full_dnode at %p\n", x)); + kmem_cache_free(full_dnode_slab, x); + } + + struct jffs2_raw_dirent *jffs2_alloc_raw_dirent(void) + { +- return kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL); ++ struct jffs2_raw_dirent *ret = kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL); ++ D3 (printk (KERN_DEBUG "alloc_raw_dirent\n", ret)); ++ return ret; + } + + void jffs2_free_raw_dirent(struct jffs2_raw_dirent *x) + { ++ D3 (printk (KERN_DEBUG "free_raw_dirent at %p\n", x)); + kmem_cache_free(raw_dirent_slab, x); + } + + struct jffs2_raw_inode *jffs2_alloc_raw_inode(void) + { +- return kmem_cache_alloc(raw_inode_slab, GFP_KERNEL); ++ struct jffs2_raw_inode *ret = kmem_cache_alloc(raw_inode_slab, GFP_KERNEL); ++ D3 (printk (KERN_DEBUG "alloc_raw_inode at %p\n", ret)); ++ return ret; + } + + void jffs2_free_raw_inode(struct jffs2_raw_inode *x) + { ++ D3 (printk (KERN_DEBUG "free_raw_inode at %p\n", x)); + kmem_cache_free(raw_inode_slab, x); + } + + struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void) + { +- return kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL); ++ struct jffs2_tmp_dnode_info *ret = kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL); ++ D3 (printk (KERN_DEBUG "alloc_tmp_dnode_info at %p\n", ret)); ++ return ret; + } + + void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x) + { ++ D3 (printk (KERN_DEBUG "free_tmp_dnode_info at %p\n", x)); + kmem_cache_free(tmp_dnode_info_slab, x); + } + + struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void) + { +- return kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL); ++ struct jffs2_raw_node_ref *ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL); ++ D3 (printk (KERN_DEBUG "alloc_raw_node_ref at %p\n", ret)); ++ return ret; + } + + void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x) + { ++ D3 (printk (KERN_DEBUG "free_raw_node_ref at %p\n", x)); + kmem_cache_free(raw_node_ref_slab, x); + } + + struct jffs2_node_frag *jffs2_alloc_node_frag(void) + { +- return kmem_cache_alloc(node_frag_slab, GFP_KERNEL); ++ struct jffs2_node_frag *ret = kmem_cache_alloc(node_frag_slab, GFP_KERNEL); ++ D3 (printk (KERN_DEBUG "alloc_node_frag at %p\n", ret)); ++ return ret; + } + + void jffs2_free_node_frag(struct jffs2_node_frag *x) + { ++ D3 (printk (KERN_DEBUG "free_node_frag at %p\n", x)); + kmem_cache_free(node_frag_slab, x); + } + + struct jffs2_inode_cache *jffs2_alloc_inode_cache(void) + { + struct jffs2_inode_cache *ret = kmem_cache_alloc(inode_cache_slab, GFP_KERNEL); +- D1(printk(KERN_DEBUG "Allocated inocache at %p\n", ret)); ++ D3 (printk(KERN_DEBUG "Allocated inocache at %p\n", ret)); + return ret; + } + + void jffs2_free_inode_cache(struct jffs2_inode_cache *x) + { +- D1(printk(KERN_DEBUG "Freeing inocache at %p\n", x)); ++ D3 (printk(KERN_DEBUG "Freeing inocache at %p\n", x)); + kmem_cache_free(inode_cache_slab, x); + } + +diff -Nurb linux-mips-2.4.27/fs/jffs2/nodelist.c linux/fs/jffs2/nodelist.c +--- linux-mips-2.4.27/fs/jffs2/nodelist.c 2003-07-05 05:23:44.000000000 +0200 ++++ linux/fs/jffs2/nodelist.c 2004-11-19 10:25:12.112167416 +0100 +@@ -1,44 +1,24 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001, 2002 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: nodelist.c,v 1.30.2.6 2003/02/24 21:49:33 dwmw2 Exp $ ++ * $Id: nodelist.c,v 1.86 2003/10/31 15:37:51 dwmw2 Exp $ + * + */ + + #include +-#include ++#include + #include + #include ++#include ++#include ++#include ++#include + #include "nodelist.h" + + void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list) +@@ -78,7 +58,7 @@ + /* Put a new tmp_dnode_info into the list, keeping the list in + order of increasing version + */ +-void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list) ++static void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list) + { + struct jffs2_tmp_dnode_info **prev = list; + +@@ -89,13 +69,37 @@ + *prev = tn; + } + ++static void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn) ++{ ++ struct jffs2_tmp_dnode_info *next; ++ ++ while (tn) { ++ next = tn; ++ tn = tn->next; ++ jffs2_free_full_dnode(next->fn); ++ jffs2_free_tmp_dnode_info(next); ++ } ++} ++ ++static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd) ++{ ++ struct jffs2_full_dirent *next; ++ ++ while (fd) { ++ next = fd->next; ++ jffs2_free_full_dirent(fd); ++ fd = next; ++ } ++} ++ ++ + /* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated + with this ino, returning the former in order of version */ + + int jffs2_get_inode_nodes(struct jffs2_sb_info *c, ino_t ino, struct jffs2_inode_info *f, + struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp, +- __u32 *highest_version, __u32 *latest_mctime, +- __u32 *mctime_ver) ++ uint32_t *highest_version, uint32_t *latest_mctime, ++ uint32_t *mctime_ver) + { + struct jffs2_raw_node_ref *ref = f->inocache->nodes; + struct jffs2_tmp_dnode_info *tn, *ret_tn = NULL; +@@ -109,43 +113,71 @@ + + D1(printk(KERN_DEBUG "jffs2_get_inode_nodes(): ino #%lu\n", ino)); + if (!f->inocache->nodes) { +- printk(KERN_WARNING "Eep. no nodes for ino #%lu\n", ino); ++ printk(KERN_WARNING "Eep. no nodes for ino #%lu\n", (unsigned long)ino); + } ++ ++ spin_lock(&c->erase_completion_lock); ++ + for (ref = f->inocache->nodes; ref && ref->next_in_ino; ref = ref->next_in_ino) { + /* Work out whether it's a data node or a dirent node */ +- if (ref->flash_offset & 1) { ++ if (ref_obsolete(ref)) { + /* FIXME: On NAND flash we may need to read these */ +- D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref->flash_offset &~3)); ++ D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref))); + continue; + } +- err = c->mtd->read(c->mtd, (ref->flash_offset & ~3), min(ref->totlen, sizeof(node)), &retlen, (void *)&node); ++ /* We can hold a pointer to a non-obsolete node without the spinlock, ++ but _obsolete_ nodes may disappear at any time, if the block ++ they're in gets erased */ ++ spin_unlock(&c->erase_completion_lock); ++ ++ cond_resched(); ++ ++ /* FIXME: point() */ ++ err = jffs2_flash_read(c, (ref_offset(ref)), ++ min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node)), ++ &retlen, (void *)&node); + if (err) { +- printk(KERN_WARNING "error %d reading node at 0x%08x in get_inode_nodes()\n", err, (ref->flash_offset) & ~3); ++ printk(KERN_WARNING "error %d reading node at 0x%08x in get_inode_nodes()\n", err, ref_offset(ref)); + goto free_out; + } + + + /* Check we've managed to read at least the common node header */ +- if (retlen < min(ref->totlen, sizeof(node.u))) { ++ if (retlen < min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node.u))) { + printk(KERN_WARNING "short read in get_inode_nodes()\n"); + err = -EIO; + goto free_out; + } + +- switch (node.u.nodetype) { ++ switch (je16_to_cpu(node.u.nodetype)) { + case JFFS2_NODETYPE_DIRENT: +- D1(printk(KERN_DEBUG "Node at %08x is a dirent node\n", ref->flash_offset &~3)); ++ D1(printk(KERN_DEBUG "Node at %08x (%d) is a dirent node\n", ref_offset(ref), ref_flags(ref))); ++ if (ref_flags(ref) == REF_UNCHECKED) { ++ printk(KERN_WARNING "BUG: Dirent node at 0x%08x never got checked? How?\n", ref_offset(ref)); ++ BUG(); ++ } + if (retlen < sizeof(node.d)) { + printk(KERN_WARNING "short read in get_inode_nodes()\n"); + err = -EIO; + goto free_out; + } +- if (node.d.version > *highest_version) +- *highest_version = node.d.version; +- if (ref->flash_offset & 1) { +- /* Obsoleted */ ++ /* sanity check */ ++ if (PAD((node.d.nsize + sizeof (node.d))) != PAD(je32_to_cpu (node.d.totlen))) { ++ printk(KERN_NOTICE "jffs2_get_inode_nodes(): Illegal nsize in node at 0x%08x: nsize 0x%02x, totlen %04x\n", ++ ref_offset(ref), node.d.nsize, je32_to_cpu(node.d.totlen)); ++ jffs2_mark_node_obsolete(c, ref); ++ spin_lock(&c->erase_completion_lock); + continue; + } ++ if (je32_to_cpu(node.d.version) > *highest_version) ++ *highest_version = je32_to_cpu(node.d.version); ++ if (ref_obsolete(ref)) { ++ /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ ++ printk(KERN_ERR "Dirent node at 0x%08x became obsolete while we weren't looking\n", ++ ref_offset(ref)); ++ BUG(); ++ } ++ + fd = jffs2_alloc_full_dirent(node.d.nsize+1); + if (!fd) { + err = -ENOMEM; +@@ -153,29 +185,30 @@ + } + memset(fd,0,sizeof(struct jffs2_full_dirent) + node.d.nsize+1); + fd->raw = ref; +- fd->version = node.d.version; +- fd->ino = node.d.ino; ++ fd->version = je32_to_cpu(node.d.version); ++ fd->ino = je32_to_cpu(node.d.ino); + fd->type = node.d.type; + + /* Pick out the mctime of the latest dirent */ + if(fd->version > *mctime_ver) { + *mctime_ver = fd->version; +- *latest_mctime = node.d.mctime; ++ *latest_mctime = je32_to_cpu(node.d.mctime); + } + + /* memcpy as much of the name as possible from the raw + dirent we've already read from the flash + */ + if (retlen > sizeof(struct jffs2_raw_dirent)) +- memcpy(&fd->name[0], &node.d.name[0], min((__u32)node.d.nsize, (retlen-sizeof(struct jffs2_raw_dirent)))); ++ memcpy(&fd->name[0], &node.d.name[0], min_t(uint32_t, node.d.nsize, (retlen-sizeof(struct jffs2_raw_dirent)))); + + /* Do we need to copy any more of the name directly + from the flash? + */ + if (node.d.nsize + sizeof(struct jffs2_raw_dirent) > retlen) { ++ /* FIXME: point() */ + int already = retlen - sizeof(struct jffs2_raw_dirent); + +- err = c->mtd->read(c->mtd, (ref->flash_offset & ~3) + retlen, ++ err = jffs2_flash_read(c, (ref_offset(ref)) + retlen, + node.d.nsize - already, &retlen, &fd->name[already]); + if (!err && retlen != node.d.nsize - already) + err = -EIO; +@@ -196,21 +229,126 @@ + break; + + case JFFS2_NODETYPE_INODE: +- D1(printk(KERN_DEBUG "Node at %08x is a data node\n", ref->flash_offset &~3)); ++ D1(printk(KERN_DEBUG "Node at %08x (%d) is a data node\n", ref_offset(ref), ref_flags(ref))); + if (retlen < sizeof(node.i)) { + printk(KERN_WARNING "read too short for dnode\n"); + err = -EIO; + goto free_out; + } +- if (node.i.version > *highest_version) +- *highest_version = node.i.version; +- D1(printk(KERN_DEBUG "version %d, highest_version now %d\n", node.i.version, *highest_version)); +- +- if (ref->flash_offset & 1) { +- D1(printk(KERN_DEBUG "obsoleted\n")); +- /* Obsoleted */ ++ if (je32_to_cpu(node.i.version) > *highest_version) ++ *highest_version = je32_to_cpu(node.i.version); ++ D1(printk(KERN_DEBUG "version %d, highest_version now %d\n", je32_to_cpu(node.i.version), *highest_version)); ++ ++ if (ref_obsolete(ref)) { ++ /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ ++ printk(KERN_ERR "Inode node at 0x%08x became obsolete while we weren't looking\n", ++ ref_offset(ref)); ++ BUG(); ++ } ++ ++ /* If we've never checked the CRCs on this node, check them now. */ ++ if (ref_flags(ref) == REF_UNCHECKED) { ++ uint32_t crc, len; ++ struct jffs2_eraseblock *jeb; ++ ++ crc = crc32(0, &node, sizeof(node.i)-8); ++ if (crc != je32_to_cpu(node.i.node_crc)) { ++ printk(KERN_NOTICE "jffs2_get_inode_nodes(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", ++ ref_offset(ref), je32_to_cpu(node.i.node_crc), crc); ++ jffs2_mark_node_obsolete(c, ref); ++ spin_lock(&c->erase_completion_lock); + continue; + } ++ ++ /* sanity checks */ ++ if ( je32_to_cpu(node.i.offset) > je32_to_cpu(node.i.isize) || ++ PAD(je32_to_cpu(node.i.csize) + sizeof (node.i)) != PAD(je32_to_cpu(node.i.totlen))) { ++ printk(KERN_NOTICE "jffs2_get_inode_nodes(): Inode corrupted at 0x%08x, totlen %d, #ino %d, version %d, isize %d, csize %d, dsize %d \n", ++ ref_offset(ref), je32_to_cpu(node.i.totlen), je32_to_cpu(node.i.ino), ++ je32_to_cpu(node.i.version), je32_to_cpu(node.i.isize), ++ je32_to_cpu(node.i.csize), je32_to_cpu(node.i.dsize)); ++ jffs2_mark_node_obsolete(c, ref); ++ spin_lock(&c->erase_completion_lock); ++ continue; ++ } ++ ++ if (node.i.compr != JFFS2_COMPR_ZERO && je32_to_cpu(node.i.csize)) { ++ unsigned char *buf=NULL; ++ uint32_t pointed = 0; ++#ifndef __ECOS ++ if (c->mtd->point) { ++ err = c->mtd->point (c->mtd, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize), ++ &retlen, &buf); ++ if (!err && retlen < je32_to_cpu(node.i.csize)) { ++ D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen)); ++ c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize)); ++ } else if (err){ ++ D1(printk(KERN_DEBUG "MTD point failed %d\n", err)); ++ } else ++ pointed = 1; /* succefully pointed to device */ ++ } ++#endif ++ if(!pointed){ ++ buf = kmalloc(je32_to_cpu(node.i.csize), GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ err = jffs2_flash_read(c, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize), ++ &retlen, buf); ++ if (!err && retlen != je32_to_cpu(node.i.csize)) ++ err = -EIO; ++ if (err) { ++ kfree(buf); ++ return err; ++ } ++ } ++ crc = crc32(0, buf, je32_to_cpu(node.i.csize)); ++ if(!pointed) ++ kfree(buf); ++#ifndef __ECOS ++ else ++ c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize)); ++#endif ++ ++ if (crc != je32_to_cpu(node.i.data_crc)) { ++ printk(KERN_NOTICE "jffs2_get_inode_nodes(): Data CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", ++ ref_offset(ref), je32_to_cpu(node.i.data_crc), crc); ++ jffs2_mark_node_obsolete(c, ref); ++ spin_lock(&c->erase_completion_lock); ++ continue; ++ } ++ ++ } ++ ++ /* Mark the node as having been checked and fix the accounting accordingly */ ++ spin_lock(&c->erase_completion_lock); ++ jeb = &c->blocks[ref->flash_offset / c->sector_size]; ++ len = ref_totlen(c, jeb, ref); ++ ++ jeb->used_size += len; ++ jeb->unchecked_size -= len; ++ c->used_size += len; ++ c->unchecked_size -= len; ++ ++ /* If node covers at least a whole page, or if it starts at the ++ beginning of a page and runs to the end of the file, or if ++ it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. ++ ++ If it's actually overlapped, it'll get made NORMAL (or OBSOLETE) ++ when the overlapping node(s) get added to the tree anyway. ++ */ ++ if ((je32_to_cpu(node.i.dsize) >= PAGE_CACHE_SIZE) || ++ ( ((je32_to_cpu(node.i.offset)&(PAGE_CACHE_SIZE-1))==0) && ++ (je32_to_cpu(node.i.dsize)+je32_to_cpu(node.i.offset) == je32_to_cpu(node.i.isize)))) { ++ D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_PRISTINE\n", ref_offset(ref))); ++ ref->flash_offset = ref_offset(ref) | REF_PRISTINE; ++ } else { ++ D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_NORMAL\n", ref_offset(ref))); ++ ref->flash_offset = ref_offset(ref) | REF_NORMAL; ++ } ++ spin_unlock(&c->erase_completion_lock); ++ } ++ + tn = jffs2_alloc_tmp_dnode_info(); + if (!tn) { + D1(printk(KERN_DEBUG "alloc tn failed\n")); +@@ -225,36 +363,76 @@ + jffs2_free_tmp_dnode_info(tn); + goto free_out; + } +- tn->version = node.i.version; +- tn->fn->ofs = node.i.offset; ++ tn->version = je32_to_cpu(node.i.version); ++ tn->fn->ofs = je32_to_cpu(node.i.offset); + /* There was a bug where we wrote hole nodes out with + csize/dsize swapped. Deal with it */ +- if (node.i.compr == JFFS2_COMPR_ZERO && !node.i.dsize && node.i.csize) +- tn->fn->size = node.i.csize; ++ if (node.i.compr == JFFS2_COMPR_ZERO && !je32_to_cpu(node.i.dsize) && je32_to_cpu(node.i.csize)) ++ tn->fn->size = je32_to_cpu(node.i.csize); + else // normal case... +- tn->fn->size = node.i.dsize; ++ tn->fn->size = je32_to_cpu(node.i.dsize); + tn->fn->raw = ref; +- D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n", ref->flash_offset &~3, node.i.version, node.i.offset, node.i.dsize)); ++ D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n", ++ ref_offset(ref), je32_to_cpu(node.i.version), ++ je32_to_cpu(node.i.offset), je32_to_cpu(node.i.dsize))); + jffs2_add_tn_to_list(tn, &ret_tn); + break; + + default: +- switch(node.u.nodetype & JFFS2_COMPAT_MASK) { ++ if (ref_flags(ref) == REF_UNCHECKED) { ++ struct jffs2_eraseblock *jeb; ++ uint32_t len; ++ ++ printk(KERN_ERR "Eep. Unknown node type %04x at %08x was marked REF_UNCHECKED\n", ++ je16_to_cpu(node.u.nodetype), ref_offset(ref)); ++ ++ /* Mark the node as having been checked and fix the accounting accordingly */ ++ spin_lock(&c->erase_completion_lock); ++ jeb = &c->blocks[ref->flash_offset / c->sector_size]; ++ len = ref_totlen(c, jeb, ref); ++ ++ jeb->used_size += len; ++ jeb->unchecked_size -= len; ++ c->used_size += len; ++ c->unchecked_size -= len; ++ ++ mark_ref_normal(ref); ++ spin_unlock(&c->erase_completion_lock); ++ } ++ node.u.nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(node.u.nodetype)); ++ if (crc32(0, &node, sizeof(struct jffs2_unknown_node)-4) != je32_to_cpu(node.u.hdr_crc)) { ++ /* Hmmm. This should have been caught at scan time. */ ++ printk(KERN_ERR "Node header CRC failed at %08x. But it must have been OK earlier.\n", ++ ref_offset(ref)); ++ printk(KERN_ERR "Node was: { %04x, %04x, %08x, %08x }\n", ++ je16_to_cpu(node.u.magic), je16_to_cpu(node.u.nodetype), je32_to_cpu(node.u.totlen), ++ je32_to_cpu(node.u.hdr_crc)); ++ jffs2_mark_node_obsolete(c, ref); ++ } else switch(je16_to_cpu(node.u.nodetype) & JFFS2_COMPAT_MASK) { + case JFFS2_FEATURE_INCOMPAT: +- printk(KERN_NOTICE "Unknown INCOMPAT nodetype %04X at %08X\n", node.u.nodetype, ref->flash_offset & ~3); ++ printk(KERN_NOTICE "Unknown INCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref)); ++ /* EEP */ ++ BUG(); + break; + case JFFS2_FEATURE_ROCOMPAT: +- printk(KERN_NOTICE "Unknown ROCOMPAT nodetype %04X at %08X\n", node.u.nodetype, ref->flash_offset & ~3); ++ printk(KERN_NOTICE "Unknown ROCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref)); ++ if (!(c->flags & JFFS2_SB_FLAG_RO)) ++ BUG(); + break; + case JFFS2_FEATURE_RWCOMPAT_COPY: +- printk(KERN_NOTICE "Unknown RWCOMPAT_COPY nodetype %04X at %08X\n", node.u.nodetype, ref->flash_offset & ~3); ++ printk(KERN_NOTICE "Unknown RWCOMPAT_COPY nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref)); + break; + case JFFS2_FEATURE_RWCOMPAT_DELETE: +- printk(KERN_NOTICE "Unknown RWCOMPAT_DELETE nodetype %04X at %08X\n", node.u.nodetype, ref->flash_offset & ~3); ++ printk(KERN_NOTICE "Unknown RWCOMPAT_DELETE nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref)); ++ jffs2_mark_node_obsolete(c, ref); + break; + } ++ + } ++ spin_lock(&c->erase_completion_lock); ++ + } ++ spin_unlock(&c->erase_completion_lock); + *tnp = ret_tn; + *fdp = ret_fd; + +@@ -266,19 +444,30 @@ + return err; + } + ++void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state) ++{ ++ spin_lock(&c->inocache_lock); ++ ic->state = state; ++ wake_up(&c->inocache_wq); ++ spin_unlock(&c->inocache_lock); ++} ++ ++/* During mount, this needs no locking. During normal operation, its ++ callers want to do other stuff while still holding the inocache_lock. ++ Rather than introducing special case get_ino_cache functions or ++ callbacks, we just let the caller do the locking itself. */ ++ + struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino) + { + struct jffs2_inode_cache *ret; + + D2(printk(KERN_DEBUG "jffs2_get_ino_cache(): ino %u\n", ino)); +- spin_lock (&c->inocache_lock); ++ + ret = c->inocache_list[ino % INOCACHE_HASHSIZE]; + while (ret && ret->ino < ino) { + ret = ret->next; + } + +- spin_unlock(&c->inocache_lock); +- + if (ret && ret->ino != ino) + ret = NULL; + +@@ -299,6 +488,7 @@ + } + new->next = *prev; + *prev = new; ++ + spin_unlock(&c->inocache_lock); + } + +@@ -316,6 +506,7 @@ + if ((*prev) == old) { + *prev = old->next; + } ++ + spin_unlock(&c->inocache_lock); + } + +@@ -352,3 +543,128 @@ + } + } + ++struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset) ++{ ++ /* The common case in lookup is that there will be a node ++ which precisely matches. So we go looking for that first */ ++ struct rb_node *next; ++ struct jffs2_node_frag *prev = NULL; ++ struct jffs2_node_frag *frag = NULL; ++ ++ D2(printk(KERN_DEBUG "jffs2_lookup_node_frag(%p, %d)\n", fragtree, offset)); ++ ++ next = fragtree->rb_node; ++ ++ while(next) { ++ frag = rb_entry(next, struct jffs2_node_frag, rb); ++ ++ D2(printk(KERN_DEBUG "Considering frag %d-%d (%p). left %p, right %p\n", ++ frag->ofs, frag->ofs+frag->size, frag, frag->rb.rb_left, frag->rb.rb_right)); ++ if (frag->ofs + frag->size <= offset) { ++ D2(printk(KERN_DEBUG "Going right from frag %d-%d, before the region we care about\n", ++ frag->ofs, frag->ofs+frag->size)); ++ /* Remember the closest smaller match on the way down */ ++ if (!prev || frag->ofs > prev->ofs) ++ prev = frag; ++ next = frag->rb.rb_right; ++ } else if (frag->ofs > offset) { ++ D2(printk(KERN_DEBUG "Going left from frag %d-%d, after the region we care about\n", ++ frag->ofs, frag->ofs+frag->size)); ++ next = frag->rb.rb_left; ++ } else { ++ D2(printk(KERN_DEBUG "Returning frag %d,%d, matched\n", ++ frag->ofs, frag->ofs+frag->size)); ++ return frag; ++ } ++ } ++ ++ /* Exact match not found. Go back up looking at each parent, ++ and return the closest smaller one */ ++ ++ if (prev) ++ D2(printk(KERN_DEBUG "No match. Returning frag %d,%d, closest previous\n", ++ prev->ofs, prev->ofs+prev->size)); ++ else ++ D2(printk(KERN_DEBUG "Returning NULL, empty fragtree\n")); ++ ++ return prev; ++} ++ ++/* Pass 'c' argument to indicate that nodes should be marked obsolete as ++ they're killed. */ ++void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c) ++{ ++ struct jffs2_node_frag *frag; ++ struct jffs2_node_frag *parent; ++ ++ if (!root->rb_node) ++ return; ++ ++ frag = (rb_entry(root->rb_node, struct jffs2_node_frag, rb)); ++ ++ while(frag) { ++ if (frag->rb.rb_left) { ++ D2(printk(KERN_DEBUG "Going left from frag (%p) %d-%d\n", ++ frag, frag->ofs, frag->ofs+frag->size)); ++ frag = frag_left(frag); ++ continue; ++ } ++ if (frag->rb.rb_right) { ++ D2(printk(KERN_DEBUG "Going right from frag (%p) %d-%d\n", ++ frag, frag->ofs, frag->ofs+frag->size)); ++ frag = frag_right(frag); ++ continue; ++ } ++ ++ D2(printk(KERN_DEBUG "jffs2_kill_fragtree: frag at 0x%x-0x%x: node %p, frags %d--\n", ++ frag->ofs, frag->ofs+frag->size, frag->node, ++ frag->node?frag->node->frags:0)); ++ ++ if (frag->node && !(--frag->node->frags)) { ++ /* Not a hole, and it's the final remaining frag ++ of this node. Free the node */ ++ if (c) ++ jffs2_mark_node_obsolete(c, frag->node->raw); ++ ++ jffs2_free_full_dnode(frag->node); ++ } ++ parent = frag_parent(frag); ++ if (parent) { ++ if (frag_left(parent) == frag) ++ parent->rb.rb_left = NULL; ++ else ++ parent->rb.rb_right = NULL; ++ } ++ ++ jffs2_free_node_frag(frag); ++ frag = parent; ++ ++ cond_resched(); ++ } ++} ++ ++void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base) ++{ ++ struct rb_node *parent = &base->rb; ++ struct rb_node **link = &parent; ++ ++ D2(printk(KERN_DEBUG "jffs2_fragtree_insert(%p; %d-%d, %p)\n", newfrag, ++ newfrag->ofs, newfrag->ofs+newfrag->size, base)); ++ ++ while (*link) { ++ parent = *link; ++ base = rb_entry(parent, struct jffs2_node_frag, rb); ++ ++ D2(printk(KERN_DEBUG "fragtree_insert considering frag at 0x%x\n", base->ofs)); ++ if (newfrag->ofs > base->ofs) ++ link = &base->rb.rb_right; ++ else if (newfrag->ofs < base->ofs) ++ link = &base->rb.rb_left; ++ else { ++ printk(KERN_CRIT "Duplicate frag at %08x (%p,%p)\n", newfrag->ofs, newfrag, base); ++ BUG(); ++ } ++ } ++ ++ rb_link_node(&newfrag->rb, &base->rb, link); ++} +diff -Nurb linux-mips-2.4.27/fs/jffs2/nodelist.h linux/fs/jffs2/nodelist.h +--- linux-mips-2.4.27/fs/jffs2/nodelist.h 2003-11-17 02:07:44.000000000 +0100 ++++ linux/fs/jffs2/nodelist.h 2004-11-19 10:25:12.113167264 +0100 +@@ -1,48 +1,35 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: nodelist.h,v 1.46.2.5 2003/11/02 13:54:20 dwmw2 Exp $ ++ * $Id: nodelist.h,v 1.115 2003/11/26 15:30:58 dwmw2 Exp $ + * + */ + ++#ifndef __JFFS2_NODELIST_H__ ++#define __JFFS2_NODELIST_H__ ++ + #include + #include +- ++#include ++#include + #include + #include + ++#ifdef __ECOS ++#include "os-ecos.h" ++#else ++#include /* For min/max in older kernels */ ++#include "os-linux.h" ++#endif ++ + #ifndef CONFIG_JFFS2_FS_DEBUG +-#define CONFIG_JFFS2_FS_DEBUG 2 ++#define CONFIG_JFFS2_FS_DEBUG 1 + #endif + + #if CONFIG_JFFS2_FS_DEBUG > 0 +@@ -71,17 +58,21 @@ + for this inode instead. The inode_cache will have NULL in the first + word so you know when you've got there :) */ + struct jffs2_raw_node_ref *next_phys; +- // __u32 ino; +- __u32 flash_offset; +- __u32 totlen; +-// __u16 nodetype; ++ uint32_t flash_offset; ++ uint32_t __totlen; /* This may die; use ref_totlen(c, jeb, ) below */ ++}; + + /* flash_offset & 3 always has to be zero, because nodes are + always aligned at 4 bytes. So we have a couple of extra bits +- to play with. So we set the least significant bit to 1 to +- signify that the node is obsoleted by later nodes. +- */ +-}; ++ to play with, which indicate the node's status; see below: */ ++#define REF_UNCHECKED 0 /* We haven't yet checked the CRC or built its inode */ ++#define REF_OBSOLETE 1 /* Obsolete, can be completely ignored */ ++#define REF_PRISTINE 2 /* Completely clean. GC without looking */ ++#define REF_NORMAL 3 /* Possibly overlapped. Read the page and write again on GC */ ++#define ref_flags(ref) ((ref)->flash_offset & 3) ++#define ref_offset(ref) ((ref)->flash_offset & ~3) ++#define ref_obsolete(ref) (((ref)->flash_offset & 3) == REF_OBSOLETE) ++#define mark_ref_normal(ref) do { (ref)->flash_offset = ref_offset(ref) | REF_NORMAL; } while(0) + + /* + Used for keeping track of deletion nodes &c, which can only be marked +@@ -101,19 +92,35 @@ + a pointer to the first physical node which is part of this inode, too. + */ + struct jffs2_inode_cache { +- struct jffs2_scan_info *scan; /* Used during scan to hold +- temporary lists of nodes, and later must be set to ++ struct jffs2_full_dirent *scan_dents; /* Used during scan to hold ++ temporary lists of dirents, and later must be set to + NULL to mark the end of the raw_node_ref->next_in_ino + chain. */ + struct jffs2_inode_cache *next; + struct jffs2_raw_node_ref *nodes; +- __u32 ino; ++ uint32_t ino; + int nlink; ++ int state; + }; + ++/* Inode states for 'state' above. We need the 'GC' state to prevent ++ someone from doing a read_inode() while we're moving a 'REF_PRISTINE' ++ node without going through all the iget() nonsense */ ++#define INO_STATE_UNCHECKED 0 /* CRC checks not yet done */ ++#define INO_STATE_CHECKING 1 /* CRC checks in progress */ ++#define INO_STATE_PRESENT 2 /* In core */ ++#define INO_STATE_CHECKEDABSENT 3 /* Checked, cleared again */ ++#define INO_STATE_GC 4 /* GCing a 'pristine' node */ ++#define INO_STATE_READING 5 /* In read_inode() */ ++ ++#define INOCACHE_HASHSIZE 128 ++ + struct jffs2_scan_info { + struct jffs2_full_dirent *dents; + struct jffs2_tmp_dnode_info *tmpnodes; ++ /* Latest i_size info */ ++ uint32_t version; ++ uint32_t isize; + }; + /* + Larger representation of a raw node, kept in-core only when the +@@ -123,9 +130,9 @@ + struct jffs2_full_dnode + { + struct jffs2_raw_node_ref *raw; +- __u32 ofs; /* Don't really need this, but optimisation */ +- __u32 size; +- __u32 frags; /* Number of fragments which currently refer ++ uint32_t ofs; /* Don't really need this, but optimisation */ ++ uint32_t size; ++ uint32_t frags; /* Number of fragments which currently refer + to this node. When this reaches zero, + the node is obsolete. + */ +@@ -140,15 +147,15 @@ + { + struct jffs2_tmp_dnode_info *next; + struct jffs2_full_dnode *fn; +- __u32 version; ++ uint32_t version; + }; + + struct jffs2_full_dirent + { + struct jffs2_raw_node_ref *raw; + struct jffs2_full_dirent *next; +- __u32 version; +- __u32 ino; /* == zero for unlink */ ++ uint32_t version; ++ uint32_t ino; /* == zero for unlink */ + unsigned int nhash; + unsigned char type; + unsigned char name[0]; +@@ -159,21 +166,23 @@ + */ + struct jffs2_node_frag + { +- struct jffs2_node_frag *next; ++ struct rb_node rb; + struct jffs2_full_dnode *node; /* NULL for holes */ +- __u32 size; +- __u32 ofs; /* Don't really need this, but optimisation */ ++ uint32_t size; ++ uint32_t ofs; /* Don't really need this, but optimisation */ + }; + + struct jffs2_eraseblock + { + struct list_head list; + int bad_count; +- __u32 offset; /* of this block in the MTD */ ++ uint32_t offset; /* of this block in the MTD */ + +- __u32 used_size; +- __u32 dirty_size; +- __u32 free_size; /* Note that sector_size - free_size ++ uint32_t unchecked_size; ++ uint32_t used_size; ++ uint32_t dirty_size; ++ uint32_t wasted_size; ++ uint32_t free_size; /* Note that sector_size - free_size + is the address of the first free space */ + struct jffs2_raw_node_ref *first_node; + struct jffs2_raw_node_ref *last_node; +@@ -190,45 +199,134 @@ + }; + + #define ACCT_SANITY_CHECK(c, jeb) do { \ +- if (jeb->used_size + jeb->dirty_size + jeb->free_size != c->sector_size) { \ +- printk(KERN_NOTICE "Eeep. Space accounting for block at 0x%08x is screwed\n", jeb->offset); \ +- printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x != total %08x\n", \ +- jeb->free_size, jeb->dirty_size, jeb->used_size, c->sector_size); \ ++ struct jffs2_eraseblock *___j = jeb; \ ++ if ((___j) && ___j->used_size + ___j->dirty_size + ___j->free_size + ___j->wasted_size + ___j->unchecked_size != c->sector_size) { \ ++ printk(KERN_NOTICE "Eeep. Space accounting for block at 0x%08x is screwed\n", ___j->offset); \ ++ printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + wasted %08x + unchecked %08x != total %08x\n", \ ++ ___j->free_size, ___j->dirty_size, ___j->used_size, ___j->wasted_size, ___j->unchecked_size, c->sector_size); \ + BUG(); \ + } \ +- if (c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size != c->flash_size) { \ ++ if (c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size + c->wasted_size + c->unchecked_size != c->flash_size) { \ + printk(KERN_NOTICE "Eeep. Space accounting superblock info is screwed\n"); \ +- printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + erasing %08x + bad %08x != total %08x\n", \ +- c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size, c->flash_size); \ ++ printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + erasing %08x + bad %08x + wasted %08x + unchecked %08x != total %08x\n", \ ++ c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size, c->wasted_size, c->unchecked_size, c->flash_size); \ + BUG(); \ + } \ + } while(0) + ++static inline void paranoia_failed_dump(struct jffs2_eraseblock *jeb) ++{ ++ struct jffs2_raw_node_ref *ref; ++ int i=0; ++ ++ printk(KERN_NOTICE); ++ for (ref = jeb->first_node; ref; ref = ref->next_phys) { ++ printk("%08x->", ref_offset(ref)); ++ if (++i == 8) { ++ i = 0; ++ printk("\n" KERN_NOTICE); ++ } ++ } ++ printk("\n"); ++} ++ ++ + #define ACCT_PARANOIA_CHECK(jeb) do { \ +- __u32 my_used_size = 0; \ ++ uint32_t my_used_size = 0; \ ++ uint32_t my_unchecked_size = 0; \ + struct jffs2_raw_node_ref *ref2 = jeb->first_node; \ + while (ref2) { \ +- if (!(ref2->flash_offset & 1)) \ +- my_used_size += ref2->totlen; \ ++ if (unlikely(ref2->flash_offset < jeb->offset || \ ++ ref2->flash_offset > jeb->offset + c->sector_size)) { \ ++ printk(KERN_NOTICE "Node %08x shouldn't be in block at %08x!\n", \ ++ ref_offset(ref2), jeb->offset); \ ++ paranoia_failed_dump(jeb); \ ++ BUG(); \ ++ } \ ++ if (ref_flags(ref2) == REF_UNCHECKED) \ ++ my_unchecked_size += ref_totlen(c, jeb, ref2); \ ++ else if (!ref_obsolete(ref2)) \ ++ my_used_size += ref_totlen(c, jeb, ref2); \ ++ if (unlikely((!ref2->next_phys) != (ref2 == jeb->last_node))) { \ ++ printk("ref for node at %p (phys %08x) has next_phys->%p (%08x), last_node->%p (phys %08x)\n", \ ++ ref2, ref_offset(ref2), ref2->next_phys, ref_offset(ref2->next_phys), \ ++ jeb->last_node, ref_offset(jeb->last_node)); \ ++ paranoia_failed_dump(jeb); \ ++ BUG(); \ ++ } \ + ref2 = ref2->next_phys; \ + } \ + if (my_used_size != jeb->used_size) { \ + printk(KERN_NOTICE "Calculated used size %08x != stored used size %08x\n", my_used_size, jeb->used_size); \ + BUG(); \ + } \ ++ if (my_unchecked_size != jeb->unchecked_size) { \ ++ printk(KERN_NOTICE "Calculated unchecked size %08x != stored unchecked size %08x\n", my_unchecked_size, jeb->unchecked_size); \ ++ BUG(); \ ++ } \ + } while(0) + ++/* Calculate totlen from surrounding nodes or eraseblock */ ++static inline uint32_t __ref_totlen(struct jffs2_sb_info *c, ++ struct jffs2_eraseblock *jeb, ++ struct jffs2_raw_node_ref *ref) ++{ ++ uint32_t ref_end; ++ ++ if (ref->next_phys) ++ ref_end = ref_offset(ref->next_phys); ++ else { ++ if (!jeb) ++ jeb = &c->blocks[ref->flash_offset / c->sector_size]; ++ ++ /* Last node in block. Use free_space */ ++ BUG_ON(ref != jeb->last_node); ++ ref_end = jeb->offset + c->sector_size - jeb->free_size; ++ } ++ return ref_end - ref_offset(ref); ++} ++ ++static inline uint32_t ref_totlen(struct jffs2_sb_info *c, ++ struct jffs2_eraseblock *jeb, ++ struct jffs2_raw_node_ref *ref) ++{ ++ uint32_t ret; ++ ++ D1(if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) { ++ printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n", ++ jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref)); ++ BUG(); ++ }) ++ ++#if 1 ++ ret = ref->__totlen; ++#else ++ /* This doesn't actually work yet */ ++ ret = __ref_totlen(c, jeb, ref); ++ if (ret != ref->__totlen) { ++ printk(KERN_CRIT "Totlen for ref at %p (0x%08x-0x%08x) miscalculated as 0x%x instead of %x\n", ++ ref, ref_offset(ref), ref_offset(ref)+ref->__totlen, ++ ret, ref->__totlen); ++ if (!jeb) ++ jeb = &c->blocks[ref->flash_offset / c->sector_size]; ++ paranoia_failed_dump(jeb); ++ BUG(); ++ } ++#endif ++ return ret; ++} ++ ++ + #define ALLOC_NORMAL 0 /* Normal allocation */ + #define ALLOC_DELETION 1 /* Deletion node. Best to allow it */ + #define ALLOC_GC 2 /* Space requested for GC. Give it or die */ ++#define ALLOC_NORETRY 3 /* For jffs2_write_dnode: On failure, return -EAGAIN instead of retrying */ + +-#define JFFS2_RESERVED_BLOCKS_BASE 3 /* Number of free blocks there must be before we... */ +-#define JFFS2_RESERVED_BLOCKS_WRITE (JFFS2_RESERVED_BLOCKS_BASE + 2) /* ... allow a normal filesystem write */ +-#define JFFS2_RESERVED_BLOCKS_DELETION (JFFS2_RESERVED_BLOCKS_BASE + 1) /* ... allow a normal filesystem deletion */ +-#define JFFS2_RESERVED_BLOCKS_GCTRIGGER (JFFS2_RESERVED_BLOCKS_BASE + 3) /* ... wake up the GC thread */ +-#define JFFS2_RESERVED_BLOCKS_GCBAD (JFFS2_RESERVED_BLOCKS_BASE + 1) /* ... pick a block from the bad_list to GC */ +-#define JFFS2_RESERVED_BLOCKS_GCMERGE (JFFS2_RESERVED_BLOCKS_BASE) /* ... merge pages when garbage collecting */ ++/* How much dirty space before it goes on the very_dirty_list */ ++#define VERYDIRTY(c, size) ((size) >= ((c)->sector_size / 2)) + ++/* check if dirty space is more than 255 Byte */ ++#define ISDIRTY(size) ((size) > sizeof (struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN) + + #define PAD(x) (((x)+3)&~3) + +@@ -241,43 +339,75 @@ + return ((struct jffs2_inode_cache *)raw); + } + ++static inline struct jffs2_node_frag *frag_first(struct rb_root *root) ++{ ++ struct rb_node *node = root->rb_node; ++ ++ if (!node) ++ return NULL; ++ while(node->rb_left) ++ node = node->rb_left; ++ return rb_entry(node, struct jffs2_node_frag, rb); ++} ++#define rb_parent(rb) ((rb)->rb_parent) ++#define frag_next(frag) rb_entry(rb_next(&(frag)->rb), struct jffs2_node_frag, rb) ++#define frag_prev(frag) rb_entry(rb_prev(&(frag)->rb), struct jffs2_node_frag, rb) ++#define frag_parent(frag) rb_entry(rb_parent(&(frag)->rb), struct jffs2_node_frag, rb) ++#define frag_left(frag) rb_entry((frag)->rb.rb_left, struct jffs2_node_frag, rb) ++#define frag_right(frag) rb_entry((frag)->rb.rb_right, struct jffs2_node_frag, rb) ++#define frag_erase(frag, list) rb_erase(&frag->rb, list); ++ + /* nodelist.c */ + D1(void jffs2_print_frag_list(struct jffs2_inode_info *f)); + void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list); +-void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list); + int jffs2_get_inode_nodes(struct jffs2_sb_info *c, ino_t ino, struct jffs2_inode_info *f, + struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp, +- __u32 *highest_version, __u32 *latest_mctime, +- __u32 *mctime_ver); ++ uint32_t *highest_version, uint32_t *latest_mctime, ++ uint32_t *mctime_ver); ++void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state); + struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino); + void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new); + void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old); + void jffs2_free_ino_caches(struct jffs2_sb_info *c); + void jffs2_free_raw_node_refs(struct jffs2_sb_info *c); ++struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset); ++void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c_delete); ++void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base); ++struct rb_node *rb_next(struct rb_node *); ++struct rb_node *rb_prev(struct rb_node *); ++void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root); + + /* nodemgmt.c */ +-int jffs2_reserve_space(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len, int prio); +-int jffs2_reserve_space_gc(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len); +-int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new, __u32 len, int dirty); ++int jffs2_thread_should_wake(struct jffs2_sb_info *c); ++int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio); ++int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len); ++int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new); + void jffs2_complete_reservation(struct jffs2_sb_info *c); + void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw); ++void jffs2_dump_block_lists(struct jffs2_sb_info *c); + + /* write.c */ +-struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri); +-struct jffs2_full_dnode *jffs2_write_dnode(struct inode *inode, struct jffs2_raw_inode *ri, const unsigned char *data, __u32 datalen, __u32 flash_ofs, __u32 *writelen); +-struct jffs2_full_dirent *jffs2_write_dirent(struct inode *inode, struct jffs2_raw_dirent *rd, const unsigned char *name, __u32 namelen, __u32 flash_ofs, __u32 *writelen); ++int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri); ++ ++struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode); ++struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode); ++int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, ++ struct jffs2_raw_inode *ri, unsigned char *buf, ++ uint32_t offset, uint32_t writelen, uint32_t *retlen); ++int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen); ++int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, int namelen, struct jffs2_inode_info *dead_f); ++int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen); ++ + + /* readinode.c */ +-void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct jffs2_node_frag **list, __u32 size); +-int jffs2_add_full_dnode_to_fraglist(struct jffs2_sb_info *c, struct jffs2_node_frag **list, struct jffs2_full_dnode *fn); ++void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); + int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn); +-void jffs2_read_inode (struct inode *); +-void jffs2_clear_inode (struct inode *); ++int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, ++ uint32_t ino, struct jffs2_raw_inode *latest_node); ++int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); ++void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f); + + /* malloc.c */ +-void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn); +-void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd); +- + int jffs2_create_slab_caches(void); + void jffs2_destroy_slab_caches(void); + +@@ -301,54 +431,41 @@ + /* gc.c */ + int jffs2_garbage_collect_pass(struct jffs2_sb_info *c); + +-/* background.c */ +-int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c); +-void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c); +-void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c); +- +-/* dir.c */ +-extern struct file_operations jffs2_dir_operations; +-extern struct inode_operations jffs2_dir_inode_operations; +- +-/* file.c */ +-extern struct file_operations jffs2_file_operations; +-extern struct inode_operations jffs2_file_inode_operations; +-extern struct address_space_operations jffs2_file_address_operations; +-int jffs2_null_fsync(struct file *, struct dentry *, int); +-int jffs2_setattr (struct dentry *dentry, struct iattr *iattr); +-int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg); +-int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg); +-int jffs2_readpage (struct file *, struct page *); +-int jffs2_prepare_write (struct file *, struct page *, unsigned, unsigned); +-int jffs2_commit_write (struct file *, struct page *, unsigned, unsigned); +- +-/* ioctl.c */ +-int jffs2_ioctl(struct inode *, struct file *, unsigned int, unsigned long); +- + /* read.c */ + int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_full_dnode *fd, unsigned char *buf, int ofs, int len); ++int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, ++ unsigned char *buf, uint32_t offset, uint32_t len); ++char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f); + + /* compr.c */ +-unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out, +- __u32 *datalen, __u32 *cdatalen); ++unsigned char jffs2_compress(unsigned char *data_in, unsigned char **cpage_out, ++ uint32_t *datalen, uint32_t *cdatalen); ++void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig); + int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in, +- unsigned char *data_out, __u32 cdatalen, __u32 datalen); ++ unsigned char *data_out, uint32_t cdatalen, uint32_t datalen); + + /* scan.c */ + int jffs2_scan_medium(struct jffs2_sb_info *c); ++void jffs2_rotate_lists(struct jffs2_sb_info *c); + + /* build.c */ +-int jffs2_build_filesystem(struct jffs2_sb_info *c); +- +-/* symlink.c */ +-extern struct inode_operations jffs2_symlink_inode_operations; ++int jffs2_do_mount_fs(struct jffs2_sb_info *c); + + /* erase.c */ + void jffs2_erase_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); +-void jffs2_erase_pending_blocks(struct jffs2_sb_info *c); +-void jffs2_mark_erased_blocks(struct jffs2_sb_info *c); +-void jffs2_erase_pending_trigger(struct jffs2_sb_info *c); ++void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count); ++ ++#ifdef CONFIG_JFFS2_FS_NAND ++/* wbuf.c */ ++int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino); ++int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c); ++int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); ++int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); ++int jffs2_nand_read_failcnt(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); ++#endif + + /* compr_zlib.c */ + int jffs2_zlib_init(void); + void jffs2_zlib_exit(void); ++ ++#endif /* __JFFS2_NODELIST_H__ */ +diff -Nurb linux-mips-2.4.27/fs/jffs2/nodemgmt.c linux/fs/jffs2/nodemgmt.c +--- linux-mips-2.4.27/fs/jffs2/nodemgmt.c 2002-06-27 00:36:20.000000000 +0200 ++++ linux/fs/jffs2/nodemgmt.c 2004-11-19 10:25:12.115166960 +0100 +@@ -1,45 +1,21 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: nodemgmt.c,v 1.45.2.1 2002/02/23 14:13:34 dwmw2 Exp $ ++ * $Id: nodemgmt.c,v 1.107 2003/11/26 15:30:58 dwmw2 Exp $ + * + */ + + #include + #include +-#include + #include +-#include ++#include ++#include /* For cond_resched() */ + #include "nodelist.h" + + /** +@@ -62,53 +38,95 @@ + * for the requested allocation. + */ + +-static int jffs2_do_reserve_space(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len); ++static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len); + +-int jffs2_reserve_space(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len, int prio) ++int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio) + { + int ret = -EAGAIN; +- int blocksneeded = JFFS2_RESERVED_BLOCKS_WRITE; ++ int blocksneeded = c->resv_blocks_write; + /* align it */ + minsize = PAD(minsize); + +- if (prio == ALLOC_DELETION) +- blocksneeded = JFFS2_RESERVED_BLOCKS_DELETION; +- + D1(printk(KERN_DEBUG "jffs2_reserve_space(): Requested 0x%x bytes\n", minsize)); + down(&c->alloc_sem); + + D1(printk(KERN_DEBUG "jffs2_reserve_space(): alloc sem got\n")); + +- spin_lock_bh(&c->erase_completion_lock); ++ spin_lock(&c->erase_completion_lock); + +- /* this needs a little more thought */ ++ /* this needs a little more thought (true :)) */ + while(ret == -EAGAIN) { + while(c->nr_free_blocks + c->nr_erasing_blocks < blocksneeded) { + int ret; ++ uint32_t dirty, avail; ++ ++ /* calculate real dirty size ++ * dirty_size contains blocks on erase_pending_list ++ * those blocks are counted in c->nr_erasing_blocks. ++ * If one block is actually erased, it is not longer counted as dirty_space ++ * but it is counted in c->nr_erasing_blocks, so we add it and subtract it ++ * with c->nr_erasing_blocks * c->sector_size again. ++ * Blocks on erasable_list are counted as dirty_size, but not in c->nr_erasing_blocks ++ * This helps us to force gc and pick eventually a clean block to spread the load. ++ * We add unchecked_size here, as we hopefully will find some space to use. ++ * This will affect the sum only once, as gc first finishes checking ++ * of nodes. ++ */ ++ dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size; ++ if (dirty < c->nospc_dirty_size) { ++ if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { ++ printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n"); ++ break; ++ } ++ D1(printk(KERN_DEBUG "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n", ++ dirty, c->unchecked_size, c->sector_size)); ++ ++ spin_unlock(&c->erase_completion_lock); ++ up(&c->alloc_sem); ++ return -ENOSPC; ++ } + ++ /* Calc possibly available space. Possibly available means that we ++ * don't know, if unchecked size contains obsoleted nodes, which could give us some ++ * more usable space. This will affect the sum only once, as gc first finishes checking ++ * of nodes. ++ + Return -ENOSPC, if the maximum possibly available space is less or equal than ++ * blocksneeded * sector_size. ++ * This blocks endless gc looping on a filesystem, which is nearly full, even if ++ * the check above passes. ++ */ ++ avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size; ++ if ( (avail / c->sector_size) <= blocksneeded) { ++ if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { ++ printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n"); ++ break; ++ } ++ ++ D1(printk(KERN_DEBUG "max. available size 0x%08x < blocksneeded * sector_size 0x%08x, returning -ENOSPC\n", ++ avail, blocksneeded * c->sector_size)); ++ spin_unlock(&c->erase_completion_lock); + up(&c->alloc_sem); +- if (c->dirty_size < c->sector_size) { +- D1(printk(KERN_DEBUG "Short on space, but total dirty size 0x%08x < sector size 0x%08x, so -ENOSPC\n", c->dirty_size, c->sector_size)); +- spin_unlock_bh(&c->erase_completion_lock); + return -ENOSPC; + } +- D1(printk(KERN_DEBUG "Triggering GC pass. nr_free_blocks %d, nr_erasing_blocks %d, free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x, erasing_size 0x%08x, bad_size 0x%08x (total 0x%08x of 0x%08x)\n", +- c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size, +- c->free_size + c->dirty_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size)); +- spin_unlock_bh(&c->erase_completion_lock); ++ ++ up(&c->alloc_sem); ++ ++ D1(printk(KERN_DEBUG "Triggering GC pass. nr_free_blocks %d, nr_erasing_blocks %d, free_size 0x%08x, dirty_size 0x%08x, wasted_size 0x%08x, used_size 0x%08x, erasing_size 0x%08x, bad_size 0x%08x (total 0x%08x of 0x%08x)\n", ++ c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->wasted_size, c->used_size, c->erasing_size, c->bad_size, ++ c->free_size + c->dirty_size + c->wasted_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size)); ++ spin_unlock(&c->erase_completion_lock); + + ret = jffs2_garbage_collect_pass(c); + if (ret) + return ret; + +- if (current->need_resched) +- schedule(); ++ cond_resched(); + + if (signal_pending(current)) + return -EINTR; + + down(&c->alloc_sem); +- spin_lock_bh(&c->erase_completion_lock); ++ spin_lock(&c->erase_completion_lock); + } + + ret = jffs2_do_reserve_space(c, minsize, ofs, len); +@@ -116,45 +134,72 @@ + D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret)); + } + } +- spin_unlock_bh(&c->erase_completion_lock); ++ spin_unlock(&c->erase_completion_lock); + if (ret) + up(&c->alloc_sem); + return ret; + } + +-int jffs2_reserve_space_gc(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len) ++int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len) + { + int ret = -EAGAIN; + minsize = PAD(minsize); + + D1(printk(KERN_DEBUG "jffs2_reserve_space_gc(): Requested 0x%x bytes\n", minsize)); + +- spin_lock_bh(&c->erase_completion_lock); ++ spin_lock(&c->erase_completion_lock); + while(ret == -EAGAIN) { + ret = jffs2_do_reserve_space(c, minsize, ofs, len); + if (ret) { + D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret)); + } + } +- spin_unlock_bh(&c->erase_completion_lock); ++ spin_unlock(&c->erase_completion_lock); + return ret; + } + + /* Called with alloc sem _and_ erase_completion_lock */ +-static int jffs2_do_reserve_space(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len) ++static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len) + { + struct jffs2_eraseblock *jeb = c->nextblock; + + restart: + if (jeb && minsize > jeb->free_size) { + /* Skip the end of this block and file it as having some dirty space */ +- c->dirty_size += jeb->free_size; ++ /* If there's a pending write to it, flush now */ ++ if (jffs2_wbuf_dirty(c)) { ++ spin_unlock(&c->erase_completion_lock); ++ D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n")); ++ jffs2_flush_wbuf_pad(c); ++ spin_lock(&c->erase_completion_lock); ++ jeb = c->nextblock; ++ goto restart; ++ } ++ c->wasted_size += jeb->free_size; + c->free_size -= jeb->free_size; +- jeb->dirty_size += jeb->free_size; ++ jeb->wasted_size += jeb->free_size; + jeb->free_size = 0; ++ ++ /* Check, if we have a dirty block now, or if it was dirty already */ ++ if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) { ++ c->dirty_size += jeb->wasted_size; ++ c->wasted_size -= jeb->wasted_size; ++ jeb->dirty_size += jeb->wasted_size; ++ jeb->wasted_size = 0; ++ if (VERYDIRTY(c, jeb->dirty_size)) { ++ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", ++ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); ++ list_add_tail(&jeb->list, &c->very_dirty_list); ++ } else { + D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", + jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); + list_add_tail(&jeb->list, &c->dirty_list); ++ } ++ } else { ++ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", ++ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); ++ list_add_tail(&jeb->list, &c->clean_list); ++ } + c->nextblock = jeb = NULL; + } + +@@ -164,33 +209,44 @@ + + if (list_empty(&c->free_list)) { + +- DECLARE_WAITQUEUE(wait, current); ++ if (!c->nr_erasing_blocks && ++ !list_empty(&c->erasable_list)) { ++ struct jffs2_eraseblock *ejeb; ++ ++ ejeb = list_entry(c->erasable_list.next, struct jffs2_eraseblock, list); ++ list_del(&ejeb->list); ++ list_add_tail(&ejeb->list, &c->erase_pending_list); ++ c->nr_erasing_blocks++; ++ jffs2_erase_pending_trigger(c); ++ D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Triggering erase of erasable block at 0x%08x\n", ++ ejeb->offset)); ++ } ++ ++ if (!c->nr_erasing_blocks && ++ !list_empty(&c->erasable_pending_wbuf_list)) { ++ D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n")); ++ /* c->nextblock is NULL, no update to c->nextblock allowed */ ++ spin_unlock(&c->erase_completion_lock); ++ jffs2_flush_wbuf_pad(c); ++ spin_lock(&c->erase_completion_lock); ++ /* Have another go. It'll be on the erasable_list now */ ++ return -EAGAIN; ++ } + + if (!c->nr_erasing_blocks) { +-// if (list_empty(&c->erasing_list) && list_empty(&c->erase_pending_list) && list_empty(c->erase_complete_list)) { + /* Ouch. We're in GC, or we wouldn't have got here. + And there's no space left. At all. */ +- printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasingempty: %s, erasependingempty: %s)\n", +- c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no"); ++ printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n", ++ c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasable_list)?"yes":"no", ++ list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no"); + return -ENOSPC; + } +- /* Make sure this can't deadlock. Someone has to start the erases +- of erase_pending blocks */ +- set_current_state(TASK_INTERRUPTIBLE); +- add_wait_queue(&c->erase_wait, &wait); +- D1(printk(KERN_DEBUG "Waiting for erases to complete. erasing_blocks is %d. (erasingempty: %s, erasependingempty: %s)\n", +- c->nr_erasing_blocks, list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no")); +- if (!list_empty(&c->erase_pending_list)) { +- D1(printk(KERN_DEBUG "Triggering pending erases\n")); +- jffs2_erase_pending_trigger(c); +- } +- spin_unlock_bh(&c->erase_completion_lock); +- schedule(); +- remove_wait_queue(&c->erase_wait, &wait); +- spin_lock_bh(&c->erase_completion_lock); +- if (signal_pending(current)) { +- return -EINTR; +- } ++ ++ spin_unlock(&c->erase_completion_lock); ++ /* Don't wait for it; just erase one right now */ ++ jffs2_erase_pending_blocks(c, 1); ++ spin_lock(&c->erase_completion_lock); ++ + /* An erase may have failed, decreasing the + amount of free space available. So we must + restart from the beginning */ +@@ -201,7 +257,8 @@ + list_del(next); + c->nextblock = jeb = list_entry(next, struct jffs2_eraseblock, list); + c->nr_free_blocks--; +- if (jeb->free_size != c->sector_size - sizeof(struct jffs2_unknown_node)) { ++ ++ if (jeb->free_size != c->sector_size - c->cleanmarker_size) { + printk(KERN_WARNING "Eep. Block 0x%08x taken from free_list had free_size of 0x%08x!!\n", jeb->offset, jeb->free_size); + goto restart; + } +@@ -210,6 +267,20 @@ + enough space */ + *ofs = jeb->offset + (c->sector_size - jeb->free_size); + *len = jeb->free_size; ++ ++ if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size && ++ !jeb->first_node->next_in_ino) { ++ /* Only node in it beforehand was a CLEANMARKER node (we think). ++ So mark it obsolete now that there's going to be another node ++ in the block. This will reduce used_size to zero but We've ++ already set c->nextblock so that jffs2_mark_node_obsolete() ++ won't try to refile it to the dirty_list. ++ */ ++ spin_unlock(&c->erase_completion_lock); ++ jffs2_mark_node_obsolete(c, jeb->first_node); ++ spin_lock(&c->erase_completion_lock); ++ } ++ + D1(printk(KERN_DEBUG "jffs2_do_reserve_space(): Giving 0x%x bytes at 0x%x\n", *len, *ofs)); + return 0; + } +@@ -217,9 +288,9 @@ + /** + * jffs2_add_physical_node_ref - add a physical node reference to the list + * @c: superblock info +- * @ofs: physical location of this physical node ++ * @new: new node reference to add + * @len: length of this physical node +- * @ino: inode number with which this physical node is associated ++ * @dirty: dirty flag for new node + * + * Should only be used to report nodes for which space has been allocated + * by jffs2_reserve_space. +@@ -227,47 +298,58 @@ + * Must be called with the alloc_sem held. + */ + +-int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new, __u32 len, int dirty) ++int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new) + { + struct jffs2_eraseblock *jeb; ++ uint32_t len; ++ ++ jeb = &c->blocks[new->flash_offset / c->sector_size]; ++ len = ref_totlen(c, jeb, new); + +- len = PAD(len); +- jeb = &c->blocks[(new->flash_offset & ~3) / c->sector_size]; +- D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x, size 0x%x\n", new->flash_offset & ~3, len)); ++ D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len)); + #if 1 +- if (jeb != c->nextblock || (new->flash_offset & ~3) != jeb->offset + (c->sector_size - jeb->free_size)) { ++ if (jeb != c->nextblock || (ref_offset(new)) != jeb->offset + (c->sector_size - jeb->free_size)) { + printk(KERN_WARNING "argh. node added in wrong place\n"); + jffs2_free_raw_node_ref(new); + return -EINVAL; + } + #endif ++ spin_lock(&c->erase_completion_lock); ++ + if (!jeb->first_node) + jeb->first_node = new; + if (jeb->last_node) + jeb->last_node->next_phys = new; + jeb->last_node = new; + +- spin_lock_bh(&c->erase_completion_lock); + jeb->free_size -= len; + c->free_size -= len; +- if (dirty) { +- new->flash_offset |= 1; ++ if (ref_obsolete(new)) { + jeb->dirty_size += len; + c->dirty_size += len; + } else { + jeb->used_size += len; + c->used_size += len; + } +- spin_unlock_bh(&c->erase_completion_lock); ++ + if (!jeb->free_size && !jeb->dirty_size) { + /* If it lives on the dirty_list, jffs2_reserve_space will put it there */ + D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", + jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); ++ if (jffs2_wbuf_dirty(c)) { ++ /* Flush the last write in the block if it's outstanding */ ++ spin_unlock(&c->erase_completion_lock); ++ jffs2_flush_wbuf_pad(c); ++ spin_lock(&c->erase_completion_lock); ++ } ++ + list_add_tail(&jeb->list, &c->clean_list); + c->nextblock = NULL; + } + ACCT_SANITY_CHECK(c,jeb); +- ACCT_PARANOIA_CHECK(jeb); ++ D1(ACCT_PARANOIA_CHECK(jeb)); ++ ++ spin_unlock(&c->erase_completion_lock); + + return 0; + } +@@ -280,20 +362,34 @@ + up(&c->alloc_sem); + } + ++static inline int on_list(struct list_head *obj, struct list_head *head) ++{ ++ struct list_head *this; ++ ++ list_for_each(this, head) { ++ if (this == obj) { ++ D1(printk("%p is on list at %p\n", obj, head)); ++ return 1; ++ ++ } ++ } ++ return 0; ++} ++ + void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref) + { + struct jffs2_eraseblock *jeb; + int blocknr; + struct jffs2_unknown_node n; +- int ret; +- ssize_t retlen; ++ int ret, addedsize; ++ size_t retlen; + + if(!ref) { + printk(KERN_NOTICE "EEEEEK. jffs2_mark_node_obsolete called with NULL node\n"); + return; + } +- if (ref->flash_offset & 1) { +- D1(printk(KERN_DEBUG "jffs2_mark_node_obsolete called with already obsolete node at 0x%08x\n", ref->flash_offset &~3)); ++ if (ref_obsolete(ref)) { ++ D1(printk(KERN_DEBUG "jffs2_mark_node_obsolete called with already obsolete node at 0x%08x\n", ref_offset(ref))); + return; + } + blocknr = ref->flash_offset / c->sector_size; +@@ -302,22 +398,63 @@ + BUG(); + } + jeb = &c->blocks[blocknr]; +- if (jeb->used_size < ref->totlen) { ++ ++ spin_lock(&c->erase_completion_lock); ++ ++ if (ref_flags(ref) == REF_UNCHECKED) { ++ D1(if (unlikely(jeb->unchecked_size < ref_totlen(c, jeb, ref))) { ++ printk(KERN_NOTICE "raw unchecked node of size 0x%08x freed from erase block %d at 0x%08x, but unchecked_size was already 0x%08x\n", ++ ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size); ++ BUG(); ++ }) ++ D1(printk(KERN_DEBUG "Obsoleting previously unchecked node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref))); ++ jeb->unchecked_size -= ref_totlen(c, jeb, ref); ++ c->unchecked_size -= ref_totlen(c, jeb, ref); ++ } else { ++ D1(if (unlikely(jeb->used_size < ref_totlen(c, jeb, ref))) { + printk(KERN_NOTICE "raw node of size 0x%08x freed from erase block %d at 0x%08x, but used_size was already 0x%08x\n", +- ref->totlen, blocknr, ref->flash_offset, jeb->used_size); ++ ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size); + BUG(); ++ }) ++ D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref))); ++ jeb->used_size -= ref_totlen(c, jeb, ref); ++ c->used_size -= ref_totlen(c, jeb, ref); ++ } ++ ++ // Take care, that wasted size is taken into concern ++ if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) { ++ D1(printk("Dirtying\n")); ++ addedsize = ref_totlen(c, jeb, ref); ++ jeb->dirty_size += ref_totlen(c, jeb, ref); ++ c->dirty_size += ref_totlen(c, jeb, ref); ++ ++ /* Convert wasted space to dirty, if not a bad block */ ++ if (jeb->wasted_size) { ++ if (on_list(&jeb->list, &c->bad_used_list)) { ++ D1(printk(KERN_DEBUG "Leaving block at %08x on the bad_used_list\n", ++ jeb->offset)); ++ addedsize = 0; /* To fool the refiling code later */ ++ } else { ++ D1(printk(KERN_DEBUG "Converting %d bytes of wasted space to dirty in block at %08x\n", ++ jeb->wasted_size, jeb->offset)); ++ addedsize += jeb->wasted_size; ++ jeb->dirty_size += jeb->wasted_size; ++ c->dirty_size += jeb->wasted_size; ++ c->wasted_size -= jeb->wasted_size; ++ jeb->wasted_size = 0; + } +- +- spin_lock_bh(&c->erase_completion_lock); +- jeb->used_size -= ref->totlen; +- jeb->dirty_size += ref->totlen; +- c->used_size -= ref->totlen; +- c->dirty_size += ref->totlen; +- ref->flash_offset |= 1; ++ } ++ } else { ++ D1(printk("Wasting\n")); ++ addedsize = 0; ++ jeb->wasted_size += ref_totlen(c, jeb, ref); ++ c->wasted_size += ref_totlen(c, jeb, ref); ++ } ++ ref->flash_offset = ref_offset(ref) | REF_OBSOLETE; + + ACCT_SANITY_CHECK(c, jeb); + +- ACCT_PARANOIA_CHECK(jeb); ++ D1(ACCT_PARANOIA_CHECK(jeb)); + + if (c->flags & JFFS2_SB_FLAG_MOUNTING) { + /* Mount in progress. Don't muck about with the block +@@ -325,68 +462,280 @@ + obliterate nodes that look obsolete. If they weren't + marked obsolete on the flash at the time they _became_ + obsolete, there was probably a reason for that. */ +- spin_unlock_bh(&c->erase_completion_lock); ++ spin_unlock(&c->erase_completion_lock); + return; + } ++ + if (jeb == c->nextblock) { + D2(printk(KERN_DEBUG "Not moving nextblock 0x%08x to dirty/erase_pending list\n", jeb->offset)); +- } else if (jeb == c->gcblock) { +- D2(printk(KERN_DEBUG "Not moving gcblock 0x%08x to dirty/erase_pending list\n", jeb->offset)); +-#if 0 /* We no longer do this here. It can screw the wear levelling. If you have a lot of static +- data and a few blocks free, and you just create new files and keep deleting/overwriting +- them, then you'd keep erasing and reusing those blocks without ever moving stuff around. +- So we leave completely obsoleted blocks on the dirty_list and let the GC delete them +- when it finds them there. That way, we still get the 'once in a while, take a clean block' +- to spread out the flash usage */ +- } else if (!jeb->used_size) { ++ } else if (!jeb->used_size && !jeb->unchecked_size) { ++ if (jeb == c->gcblock) { ++ D1(printk(KERN_DEBUG "gcblock at 0x%08x completely dirtied. Clearing gcblock...\n", jeb->offset)); ++ c->gcblock = NULL; ++ } else { + D1(printk(KERN_DEBUG "Eraseblock at 0x%08x completely dirtied. Removing from (dirty?) list...\n", jeb->offset)); + list_del(&jeb->list); ++ } ++ if (jffs2_wbuf_dirty(c)) { ++ D1(printk(KERN_DEBUG "...and adding to erasable_pending_wbuf_list\n")); ++ list_add_tail(&jeb->list, &c->erasable_pending_wbuf_list); ++ } else { ++ if (jiffies & 127) { ++ /* Most of the time, we just erase it immediately. Otherwise we ++ spend ages scanning it on mount, etc. */ + D1(printk(KERN_DEBUG "...and adding to erase_pending_list\n")); + list_add_tail(&jeb->list, &c->erase_pending_list); + c->nr_erasing_blocks++; + jffs2_erase_pending_trigger(c); +- // OFNI_BS_2SFFJ(c)->s_dirt = 1; ++ } else { ++ /* Sometimes, however, we leave it elsewhere so it doesn't get ++ immediately reused, and we spread the load a bit. */ ++ D1(printk(KERN_DEBUG "...and adding to erasable_list\n")); ++ list_add_tail(&jeb->list, &c->erasable_list); ++ } ++ } + D1(printk(KERN_DEBUG "Done OK\n")); +-#endif +- } else if (jeb->dirty_size == ref->totlen) { ++ } else if (jeb == c->gcblock) { ++ D2(printk(KERN_DEBUG "Not moving gcblock 0x%08x to dirty_list\n", jeb->offset)); ++ } else if (ISDIRTY(jeb->dirty_size) && !ISDIRTY(jeb->dirty_size - addedsize)) { + D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is freshly dirtied. Removing from clean list...\n", jeb->offset)); + list_del(&jeb->list); + D1(printk(KERN_DEBUG "...and adding to dirty_list\n")); + list_add_tail(&jeb->list, &c->dirty_list); ++ } else if (VERYDIRTY(c, jeb->dirty_size) && ++ !VERYDIRTY(c, jeb->dirty_size - addedsize)) { ++ D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is now very dirty. Removing from dirty list...\n", jeb->offset)); ++ list_del(&jeb->list); ++ D1(printk(KERN_DEBUG "...and adding to very_dirty_list\n")); ++ list_add_tail(&jeb->list, &c->very_dirty_list); ++ } else { ++ D1(printk(KERN_DEBUG "Eraseblock at 0x%08x not moved anywhere. (free 0x%08x, dirty 0x%08x, used 0x%08x)\n", ++ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); + } +- spin_unlock_bh(&c->erase_completion_lock); + +- if (c->mtd->type != MTD_NORFLASH && c->mtd->type != MTD_RAM) ++ spin_unlock(&c->erase_completion_lock); ++ ++ if (!jffs2_can_mark_obsolete(c)) + return; +- if (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY) ++ if (jffs2_is_readonly(c)) + return; + +- D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref->flash_offset &~3)); +- ret = c->mtd->read(c->mtd, ref->flash_offset &~3, sizeof(n), &retlen, (char *)&n); ++ D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref_offset(ref))); ++ ret = jffs2_flash_read(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n); + if (ret) { +- printk(KERN_WARNING "Read error reading from obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, ret); ++ printk(KERN_WARNING "Read error reading from obsoleted node at 0x%08x: %d\n", ref_offset(ref), ret); + return; + } + if (retlen != sizeof(n)) { +- printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, retlen); ++ printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen); + return; + } +- if (PAD(n.totlen) != PAD(ref->totlen)) { +- printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen in node ref (0x%08x)\n", n.totlen, ref->totlen); ++ if (PAD(je32_to_cpu(n.totlen)) != PAD(ref_totlen(c, jeb, ref))) { ++ printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen from node ref (0x%08x)\n", je32_to_cpu(n.totlen), ref_totlen(c, jeb, ref)); + return; + } +- if (!(n.nodetype & JFFS2_NODE_ACCURATE)) { +- D1(printk(KERN_DEBUG "Node at 0x%08x was already marked obsolete (nodetype 0x%04x\n", ref->flash_offset &~3, n.nodetype)); ++ if (!(je16_to_cpu(n.nodetype) & JFFS2_NODE_ACCURATE)) { ++ D1(printk(KERN_DEBUG "Node at 0x%08x was already marked obsolete (nodetype 0x%04x)\n", ref_offset(ref), je16_to_cpu(n.nodetype))); + return; + } +- n.nodetype &= ~JFFS2_NODE_ACCURATE; +- ret = c->mtd->write(c->mtd, ref->flash_offset&~3, sizeof(n), &retlen, (char *)&n); ++ /* XXX FIXME: This is ugly now */ ++ n.nodetype = cpu_to_je16(je16_to_cpu(n.nodetype) & ~JFFS2_NODE_ACCURATE); ++ ret = jffs2_flash_write(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n); + if (ret) { +- printk(KERN_WARNING "Write error in obliterating obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, ret); ++ printk(KERN_WARNING "Write error in obliterating obsoleted node at 0x%08x: %d\n", ref_offset(ref), ret); + return; + } + if (retlen != sizeof(n)) { +- printk(KERN_WARNING "Short write in obliterating obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, retlen); ++ printk(KERN_WARNING "Short write in obliterating obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen); + return; + } + } ++ ++#if CONFIG_JFFS2_FS_DEBUG > 0 ++void jffs2_dump_block_lists(struct jffs2_sb_info *c) ++{ ++ ++ ++ printk(KERN_DEBUG "jffs2_dump_block_lists:\n"); ++ printk(KERN_DEBUG "flash_size: %08x\n", c->flash_size); ++ printk(KERN_DEBUG "used_size: %08x\n", c->used_size); ++ printk(KERN_DEBUG "dirty_size: %08x\n", c->dirty_size); ++ printk(KERN_DEBUG "wasted_size: %08x\n", c->wasted_size); ++ printk(KERN_DEBUG "unchecked_size: %08x\n", c->unchecked_size); ++ printk(KERN_DEBUG "free_size: %08x\n", c->free_size); ++ printk(KERN_DEBUG "erasing_size: %08x\n", c->erasing_size); ++ printk(KERN_DEBUG "bad_size: %08x\n", c->bad_size); ++ printk(KERN_DEBUG "sector_size: %08x\n", c->sector_size); ++ printk(KERN_DEBUG "jffs2_reserved_blocks size: %08x\n",c->sector_size * c->resv_blocks_write); ++ ++ if (c->nextblock) { ++ printk(KERN_DEBUG "nextblock: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", ++ c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->unchecked_size, c->nextblock->free_size); ++ } else { ++ printk(KERN_DEBUG "nextblock: NULL\n"); ++ } ++ if (c->gcblock) { ++ printk(KERN_DEBUG "gcblock: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", ++ c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size, c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size); ++ } else { ++ printk(KERN_DEBUG "gcblock: NULL\n"); ++ } ++ if (list_empty(&c->clean_list)) { ++ printk(KERN_DEBUG "clean_list: empty\n"); ++ } else { ++ struct list_head *this; ++ int numblocks = 0; ++ uint32_t dirty = 0; ++ ++ list_for_each(this, &c->clean_list) { ++ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); ++ numblocks ++; ++ dirty += jeb->wasted_size; ++ printk(KERN_DEBUG "clean_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size); ++ } ++ printk (KERN_DEBUG "Contains %d blocks with total wasted size %u, average wasted size: %u\n", numblocks, dirty, dirty / numblocks); ++ } ++ if (list_empty(&c->very_dirty_list)) { ++ printk(KERN_DEBUG "very_dirty_list: empty\n"); ++ } else { ++ struct list_head *this; ++ int numblocks = 0; ++ uint32_t dirty = 0; ++ ++ list_for_each(this, &c->very_dirty_list) { ++ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); ++ numblocks ++; ++ dirty += jeb->dirty_size; ++ printk(KERN_DEBUG "very_dirty_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", ++ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size); ++ } ++ printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n", ++ numblocks, dirty, dirty / numblocks); ++ } ++ if (list_empty(&c->dirty_list)) { ++ printk(KERN_DEBUG "dirty_list: empty\n"); ++ } else { ++ struct list_head *this; ++ int numblocks = 0; ++ uint32_t dirty = 0; ++ ++ list_for_each(this, &c->dirty_list) { ++ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); ++ numblocks ++; ++ dirty += jeb->dirty_size; ++ printk(KERN_DEBUG "dirty_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", ++ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size); ++ } ++ printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n", ++ numblocks, dirty, dirty / numblocks); ++ } ++ if (list_empty(&c->erasable_list)) { ++ printk(KERN_DEBUG "erasable_list: empty\n"); ++ } else { ++ struct list_head *this; ++ ++ list_for_each(this, &c->erasable_list) { ++ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); ++ printk(KERN_DEBUG "erasable_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", ++ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size); ++ } ++ } ++ if (list_empty(&c->erasing_list)) { ++ printk(KERN_DEBUG "erasing_list: empty\n"); ++ } else { ++ struct list_head *this; ++ ++ list_for_each(this, &c->erasing_list) { ++ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); ++ printk(KERN_DEBUG "erasing_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", ++ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size); ++ } ++ } ++ if (list_empty(&c->erase_pending_list)) { ++ printk(KERN_DEBUG "erase_pending_list: empty\n"); ++ } else { ++ struct list_head *this; ++ ++ list_for_each(this, &c->erase_pending_list) { ++ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); ++ printk(KERN_DEBUG "erase_pending_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", ++ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size); ++ } ++ } ++ if (list_empty(&c->erasable_pending_wbuf_list)) { ++ printk(KERN_DEBUG "erasable_pending_wbuf_list: empty\n"); ++ } else { ++ struct list_head *this; ++ ++ list_for_each(this, &c->erasable_pending_wbuf_list) { ++ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); ++ printk(KERN_DEBUG "erasable_pending_wbuf_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", ++ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size); ++ } ++ } ++ if (list_empty(&c->free_list)) { ++ printk(KERN_DEBUG "free_list: empty\n"); ++ } else { ++ struct list_head *this; ++ ++ list_for_each(this, &c->free_list) { ++ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); ++ printk(KERN_DEBUG "free_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", ++ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size); ++ } ++ } ++ if (list_empty(&c->bad_list)) { ++ printk(KERN_DEBUG "bad_list: empty\n"); ++ } else { ++ struct list_head *this; ++ ++ list_for_each(this, &c->bad_list) { ++ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); ++ printk(KERN_DEBUG "bad_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", ++ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size); ++ } ++ } ++ if (list_empty(&c->bad_used_list)) { ++ printk(KERN_DEBUG "bad_used_list: empty\n"); ++ } else { ++ struct list_head *this; ++ ++ list_for_each(this, &c->bad_used_list) { ++ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); ++ printk(KERN_DEBUG "bad_used_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", ++ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size); ++ } ++ } ++} ++#endif /* CONFIG_JFFS2_FS_DEBUG */ ++ ++int jffs2_thread_should_wake(struct jffs2_sb_info *c) ++{ ++ int ret = 0; ++ uint32_t dirty; ++ ++ if (c->unchecked_size) { ++ D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): unchecked_size %d, checked_ino #%d\n", ++ c->unchecked_size, c->checked_ino)); ++ return 1; ++ } ++ ++ /* dirty_size contains blocks on erase_pending_list ++ * those blocks are counted in c->nr_erasing_blocks. ++ * If one block is actually erased, it is not longer counted as dirty_space ++ * but it is counted in c->nr_erasing_blocks, so we add it and subtract it ++ * with c->nr_erasing_blocks * c->sector_size again. ++ * Blocks on erasable_list are counted as dirty_size, but not in c->nr_erasing_blocks ++ * This helps us to force gc and pick eventually a clean block to spread the load. ++ */ ++ dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size; ++ ++ if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger && ++ (dirty > c->nospc_dirty_size)) ++ ret = 1; ++ ++ D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x: %s\n", ++ c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size, ret?"yes":"no")); ++ ++ return ret; ++} +diff -Nurb linux-mips-2.4.27/fs/jffs2/os-linux.h linux/fs/jffs2/os-linux.h +--- linux-mips-2.4.27/fs/jffs2/os-linux.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux/fs/jffs2/os-linux.h 2004-11-19 10:25:12.116166808 +0100 +@@ -0,0 +1,212 @@ ++/* ++ * JFFS2 -- Journalling Flash File System, Version 2. ++ * ++ * Copyright (C) 2002-2003 Red Hat, Inc. ++ * ++ * Created by David Woodhouse ++ * ++ * For licensing information, see the file 'LICENCE' in this directory. ++ * ++ * $Id: os-linux.h,v 1.41 2003/11/26 13:02:46 dwmw2 Exp $ ++ * ++ */ ++ ++#ifndef __JFFS2_OS_LINUX_H__ ++#define __JFFS2_OS_LINUX_H__ ++#include ++ ++/* JFFS2 uses Linux mode bits natively -- no need for conversion */ ++#define os_to_jffs2_mode(x) (x) ++#define jffs2_to_os_mode(x) (x) ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,73) ++#define kstatfs statfs ++#endif ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2) ++#define JFFS2_INODE_INFO(i) (list_entry(i, struct jffs2_inode_info, vfs_inode)) ++#define OFNI_EDONI_2SFFJ(f) (&(f)->vfs_inode) ++#define JFFS2_SB_INFO(sb) (sb->s_fs_info) ++#define OFNI_BS_2SFFJ(c) ((struct super_block *)c->os_priv) ++#elif defined(JFFS2_OUT_OF_KERNEL) ++#define JFFS2_INODE_INFO(i) ((struct jffs2_inode_info *) &(i)->u) ++#define OFNI_EDONI_2SFFJ(f) ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) ) ++#define JFFS2_SB_INFO(sb) ((struct jffs2_sb_info *) &(sb)->u) ++#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) ) ++#else ++#define JFFS2_INODE_INFO(i) (&i->u.jffs2_i) ++#define OFNI_EDONI_2SFFJ(f) ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) ) ++#define JFFS2_SB_INFO(sb) (&sb->u.jffs2_sb) ++#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) ) ++#endif ++ ++ ++#define JFFS2_F_I_SIZE(f) (OFNI_EDONI_2SFFJ(f)->i_size) ++#define JFFS2_F_I_MODE(f) (OFNI_EDONI_2SFFJ(f)->i_mode) ++#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid) ++#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid) ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,1) ++#define JFFS2_F_I_RDEV_MIN(f) (iminor(OFNI_EDONI_2SFFJ(f))) ++#define JFFS2_F_I_RDEV_MAJ(f) (imajor(OFNI_EDONI_2SFFJ(f))) ++#else ++#define JFFS2_F_I_RDEV_MIN(f) (MINOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev))) ++#define JFFS2_F_I_RDEV_MAJ(f) (MAJOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev))) ++#endif ++ ++/* Urgh. The things we do to keep the 2.4 build working */ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,47) ++#define ITIME(sec) ((struct timespec){sec, 0}) ++#define I_SEC(tv) ((tv).tv_sec) ++#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime.tv_sec) ++#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime.tv_sec) ++#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime.tv_sec) ++#else ++#define ITIME(x) (x) ++#define I_SEC(x) (x) ++#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime) ++#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime) ++#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime) ++#endif ++ ++#define sleep_on_spinunlock(wq, s) \ ++ do { \ ++ DECLARE_WAITQUEUE(__wait, current); \ ++ add_wait_queue((wq), &__wait); \ ++ set_current_state(TASK_UNINTERRUPTIBLE); \ ++ spin_unlock(s); \ ++ schedule(); \ ++ remove_wait_queue((wq), &__wait); \ ++ } while(0) ++ ++static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) ++{ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2) ++ f->highest_version = 0; ++ f->fragtree = RB_ROOT; ++ f->metadata = NULL; ++ f->dents = NULL; ++ f->flags = 0; ++ f->usercompr = 0; ++#else ++ memset(f, 0, sizeof(*f)); ++ init_MUTEX_LOCKED(&f->sem); ++#endif ++} ++ ++#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY) ++ ++#ifndef CONFIG_JFFS2_FS_NAND ++#define jffs2_can_mark_obsolete(c) (1) ++#define jffs2_cleanmarker_oob(c) (0) ++#define jffs2_write_nand_cleanmarker(c,jeb) (-EIO) ++ ++#define jffs2_flash_write(c, ofs, len, retlen, buf) ((c)->mtd->write((c)->mtd, ofs, len, retlen, buf)) ++#define jffs2_flash_read(c, ofs, len, retlen, buf) ((c)->mtd->read((c)->mtd, ofs, len, retlen, buf)) ++#define jffs2_flush_wbuf_pad(c) ({ (void)(c), 0; }) ++#define jffs2_flush_wbuf_gc(c, i) ({ (void)(c), (void) i, 0; }) ++#define jffs2_nand_read_failcnt(c,jeb) do { ; } while(0) ++#define jffs2_write_nand_badblock(c,jeb) do { ; } while(0) ++#define jffs2_nand_flash_setup(c) (0) ++#define jffs2_nand_flash_cleanup(c) do {} while(0) ++#define jffs2_wbuf_dirty(c) (0) ++#define jffs2_flash_writev(a,b,c,d,e,f) jffs2_flash_direct_writev(a,b,c,d,e) ++#define jffs2_wbuf_timeout NULL ++#define jffs2_wbuf_process NULL ++ ++#else /* NAND support present */ ++ ++#define jffs2_can_mark_obsolete(c) (c->mtd->type == MTD_NORFLASH || c->mtd->type == MTD_RAM) ++#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH) ++ ++#define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf)) ++#define jffs2_flash_read_oob(c, ofs, len, retlen, buf) ((c)->mtd->read_oob((c)->mtd, ofs, len, retlen, buf)) ++#define jffs2_wbuf_dirty(c) (!!(c)->wbuf_len) ++struct kstatfs; ++ ++/* wbuf.c */ ++int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino); ++int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, const u_char *buf); ++int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, u_char *buf); ++int jffs2_check_oob_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,int mode); ++int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); ++int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); ++int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); ++void jffs2_wbuf_timeout(unsigned long data); ++void jffs2_wbuf_process(void *data); ++int jffs2_nand_flash_setup(struct jffs2_sb_info *c); ++void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c); ++#endif /* NAND */ ++ ++/* erase.c */ ++static inline void jffs2_erase_pending_trigger(struct jffs2_sb_info *c) ++{ ++ OFNI_BS_2SFFJ(c)->s_dirt = 1; ++} ++ ++/* background.c */ ++int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c); ++void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c); ++void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c); ++ ++/* dir.c */ ++extern struct file_operations jffs2_dir_operations; ++extern struct inode_operations jffs2_dir_inode_operations; ++ ++/* file.c */ ++extern struct file_operations jffs2_file_operations; ++extern struct inode_operations jffs2_file_inode_operations; ++extern struct address_space_operations jffs2_file_address_operations; ++int jffs2_fsync(struct file *, struct dentry *, int); ++int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg); ++int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg); ++int jffs2_readpage (struct file *, struct page *); ++int jffs2_prepare_write (struct file *, struct page *, unsigned, unsigned); ++int jffs2_commit_write (struct file *, struct page *, unsigned, unsigned); ++ ++/* ioctl.c */ ++int jffs2_ioctl(struct inode *, struct file *, unsigned int, unsigned long); ++ ++/* symlink.c */ ++extern struct inode_operations jffs2_symlink_inode_operations; ++ ++/* fs.c */ ++int jffs2_setattr (struct dentry *, struct iattr *); ++void jffs2_read_inode (struct inode *); ++void jffs2_clear_inode (struct inode *); ++void jffs2_dirty_inode(struct inode *inode); ++struct inode *jffs2_new_inode (struct inode *dir_i, int mode, ++ struct jffs2_raw_inode *ri); ++int jffs2_statfs (struct super_block *, struct kstatfs *); ++void jffs2_write_super (struct super_block *); ++int jffs2_remount_fs (struct super_block *, int *, char *); ++int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); ++void jffs2_gc_release_inode(struct jffs2_sb_info *c, ++ struct jffs2_inode_info *f); ++struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, ++ int inum, int nlink); ++ ++unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, ++ struct jffs2_inode_info *f, ++ unsigned long offset, ++ unsigned long *priv); ++void jffs2_gc_release_page(struct jffs2_sb_info *c, ++ unsigned char *pg, ++ unsigned long *priv); ++ ++ ++/* writev.c */ ++int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs, ++ unsigned long count, loff_t to, size_t *retlen); ++ ++/* Compression config */ ++#define JFFS2_COMPRESSION ++#undef JFFS2_USE_DYNRUBIN /* Disabled 23/9/1. With zlib it hardly ever gets a look in */ ++#undef JFFS2_USE_RUBINMIPS /* Disabled 26/2/1. Obsoleted by dynrubin */ ++#define JFFS2_USE_ZLIB ++#define JFFS2_USE_RTIME /* rtime does manage to recompress already-compressed data */ ++ ++ ++#endif /* __JFFS2_OS_LINUX_H__ */ ++ ++ +diff -Nurb linux-mips-2.4.27/fs/jffs2/pushpull.h linux/fs/jffs2/pushpull.h +--- linux-mips-2.4.27/fs/jffs2/pushpull.h 2001-11-05 21:16:19.000000000 +0100 ++++ linux/fs/jffs2/pushpull.h 2004-11-19 10:25:12.118166504 +0100 +@@ -1,42 +1,21 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001, 2002 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: pushpull.h,v 1.5 2001/09/23 10:04:15 rmk Exp $ ++ * $Id: pushpull.h,v 1.9 2003/10/04 08:33:06 dwmw2 Exp $ + * + */ + + #ifndef __PUSHPULL_H__ + #define __PUSHPULL_H__ ++ ++#include ++ + struct pushpull { + unsigned char *buf; + unsigned int buflen; +@@ -44,9 +23,36 @@ + unsigned int reserve; + }; + +-void init_pushpull(struct pushpull *, char *, unsigned, unsigned, unsigned); +-int pushbit(struct pushpull *pp, int bit, int use_reserved); +-int pushedbits(struct pushpull *pp); ++ ++static inline void init_pushpull(struct pushpull *pp, char *buf, unsigned buflen, unsigned ofs, unsigned reserve) ++{ ++ pp->buf = buf; ++ pp->buflen = buflen; ++ pp->ofs = ofs; ++ pp->reserve = reserve; ++} ++ ++static inline int pushbit(struct pushpull *pp, int bit, int use_reserved) ++{ ++ if (pp->ofs >= pp->buflen - (use_reserved?0:pp->reserve)) { ++ return -ENOSPC; ++ } ++ ++ if (bit) { ++ pp->buf[pp->ofs >> 3] |= (1<<(7-(pp->ofs &7))); ++ } ++ else { ++ pp->buf[pp->ofs >> 3] &= ~(1<<(7-(pp->ofs &7))); ++ } ++ pp->ofs++; ++ ++ return 0; ++} ++ ++static inline int pushedbits(struct pushpull *pp) ++{ ++ return pp->ofs; ++} + + static inline int pullbit(struct pushpull *pp) + { +diff -Nurb linux-mips-2.4.27/fs/jffs2/rbtree.c linux/fs/jffs2/rbtree.c +--- linux-mips-2.4.27/fs/jffs2/rbtree.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/fs/jffs2/rbtree.c 2004-11-19 10:25:12.120166200 +0100 +@@ -0,0 +1,363 @@ ++/* ++ Red Black Trees ++ (C) 1999 Andrea Arcangeli ++ (C) 2002 David Woodhouse ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ $Id: rbtree.c,v 1.3 2003/10/16 08:02:19 dwmw2 Exp $ ++*/ ++ ++#ifdef __ECOS /* This file is _not_ under the eCos licence; it is pure GPL. */ ++#error "Licence problem. eCos has its own rbtree code." ++#endif ++ ++#include ++#include ++ ++/* This wasn't present till 2.4.11, wasn't exported till 2.4.19 */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,11) || \ ++ (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) && defined(MODULE)) ++static void __rb_rotate_left(struct rb_node * node, struct rb_root * root) ++{ ++ struct rb_node * right = node->rb_right; ++ ++ if ((node->rb_right = right->rb_left)) ++ right->rb_left->rb_parent = node; ++ right->rb_left = node; ++ ++ if ((right->rb_parent = node->rb_parent)) ++ { ++ if (node == node->rb_parent->rb_left) ++ node->rb_parent->rb_left = right; ++ else ++ node->rb_parent->rb_right = right; ++ } ++ else ++ root->rb_node = right; ++ node->rb_parent = right; ++} ++ ++static void __rb_rotate_right(struct rb_node * node, struct rb_root * root) ++{ ++ struct rb_node * left = node->rb_left; ++ ++ if ((node->rb_left = left->rb_right)) ++ left->rb_right->rb_parent = node; ++ left->rb_right = node; ++ ++ if ((left->rb_parent = node->rb_parent)) ++ { ++ if (node == node->rb_parent->rb_right) ++ node->rb_parent->rb_right = left; ++ else ++ node->rb_parent->rb_left = left; ++ } ++ else ++ root->rb_node = left; ++ node->rb_parent = left; ++} ++ ++void rb_insert_color(struct rb_node * node, struct rb_root * root) ++{ ++ struct rb_node * parent, * gparent; ++ ++ while ((parent = node->rb_parent) && parent->rb_color == RB_RED) ++ { ++ gparent = parent->rb_parent; ++ ++ if (parent == gparent->rb_left) ++ { ++ { ++ register struct rb_node * uncle = gparent->rb_right; ++ if (uncle && uncle->rb_color == RB_RED) ++ { ++ uncle->rb_color = RB_BLACK; ++ parent->rb_color = RB_BLACK; ++ gparent->rb_color = RB_RED; ++ node = gparent; ++ continue; ++ } ++ } ++ ++ if (parent->rb_right == node) ++ { ++ register struct rb_node * tmp; ++ __rb_rotate_left(parent, root); ++ tmp = parent; ++ parent = node; ++ node = tmp; ++ } ++ ++ parent->rb_color = RB_BLACK; ++ gparent->rb_color = RB_RED; ++ __rb_rotate_right(gparent, root); ++ } else { ++ { ++ register struct rb_node * uncle = gparent->rb_left; ++ if (uncle && uncle->rb_color == RB_RED) ++ { ++ uncle->rb_color = RB_BLACK; ++ parent->rb_color = RB_BLACK; ++ gparent->rb_color = RB_RED; ++ node = gparent; ++ continue; ++ } ++ } ++ ++ if (parent->rb_left == node) ++ { ++ register struct rb_node * tmp; ++ __rb_rotate_right(parent, root); ++ tmp = parent; ++ parent = node; ++ node = tmp; ++ } ++ ++ parent->rb_color = RB_BLACK; ++ gparent->rb_color = RB_RED; ++ __rb_rotate_left(gparent, root); ++ } ++ } ++ ++ root->rb_node->rb_color = RB_BLACK; ++} ++ ++static void __rb_erase_color(struct rb_node * node, struct rb_node * parent, ++ struct rb_root * root) ++{ ++ struct rb_node * other; ++ ++ while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node) ++ { ++ if (parent->rb_left == node) ++ { ++ other = parent->rb_right; ++ if (other->rb_color == RB_RED) ++ { ++ other->rb_color = RB_BLACK; ++ parent->rb_color = RB_RED; ++ __rb_rotate_left(parent, root); ++ other = parent->rb_right; ++ } ++ if ((!other->rb_left || ++ other->rb_left->rb_color == RB_BLACK) ++ && (!other->rb_right || ++ other->rb_right->rb_color == RB_BLACK)) ++ { ++ other->rb_color = RB_RED; ++ node = parent; ++ parent = node->rb_parent; ++ } ++ else ++ { ++ if (!other->rb_right || ++ other->rb_right->rb_color == RB_BLACK) ++ { ++ register struct rb_node * o_left; ++ if ((o_left = other->rb_left)) ++ o_left->rb_color = RB_BLACK; ++ other->rb_color = RB_RED; ++ __rb_rotate_right(other, root); ++ other = parent->rb_right; ++ } ++ other->rb_color = parent->rb_color; ++ parent->rb_color = RB_BLACK; ++ if (other->rb_right) ++ other->rb_right->rb_color = RB_BLACK; ++ __rb_rotate_left(parent, root); ++ node = root->rb_node; ++ break; ++ } ++ } ++ else ++ { ++ other = parent->rb_left; ++ if (other->rb_color == RB_RED) ++ { ++ other->rb_color = RB_BLACK; ++ parent->rb_color = RB_RED; ++ __rb_rotate_right(parent, root); ++ other = parent->rb_left; ++ } ++ if ((!other->rb_left || ++ other->rb_left->rb_color == RB_BLACK) ++ && (!other->rb_right || ++ other->rb_right->rb_color == RB_BLACK)) ++ { ++ other->rb_color = RB_RED; ++ node = parent; ++ parent = node->rb_parent; ++ } ++ else ++ { ++ if (!other->rb_left || ++ other->rb_left->rb_color == RB_BLACK) ++ { ++ register struct rb_node * o_right; ++ if ((o_right = other->rb_right)) ++ o_right->rb_color = RB_BLACK; ++ other->rb_color = RB_RED; ++ __rb_rotate_left(other, root); ++ other = parent->rb_left; ++ } ++ other->rb_color = parent->rb_color; ++ parent->rb_color = RB_BLACK; ++ if (other->rb_left) ++ other->rb_left->rb_color = RB_BLACK; ++ __rb_rotate_right(parent, root); ++ node = root->rb_node; ++ break; ++ } ++ } ++ } ++ if (node) ++ node->rb_color = RB_BLACK; ++} ++ ++void rb_erase(struct rb_node * node, struct rb_root * root) ++{ ++ struct rb_node * child, * parent; ++ int color; ++ ++ if (!node->rb_left) ++ child = node->rb_right; ++ else if (!node->rb_right) ++ child = node->rb_left; ++ else ++ { ++ struct rb_node * old = node, * left; ++ ++ node = node->rb_right; ++ while ((left = node->rb_left)) ++ node = left; ++ child = node->rb_right; ++ parent = node->rb_parent; ++ color = node->rb_color; ++ ++ if (child) ++ child->rb_parent = parent; ++ if (parent) ++ { ++ if (parent->rb_left == node) ++ parent->rb_left = child; ++ else ++ parent->rb_right = child; ++ } ++ else ++ root->rb_node = child; ++ ++ if (node->rb_parent == old) ++ parent = node; ++ node->rb_parent = old->rb_parent; ++ node->rb_color = old->rb_color; ++ node->rb_right = old->rb_right; ++ node->rb_left = old->rb_left; ++ ++ if (old->rb_parent) ++ { ++ if (old->rb_parent->rb_left == old) ++ old->rb_parent->rb_left = node; ++ else ++ old->rb_parent->rb_right = node; ++ } else ++ root->rb_node = node; ++ ++ old->rb_left->rb_parent = node; ++ if (old->rb_right) ++ old->rb_right->rb_parent = node; ++ goto color; ++ } ++ ++ parent = node->rb_parent; ++ color = node->rb_color; ++ ++ if (child) ++ child->rb_parent = parent; ++ if (parent) ++ { ++ if (parent->rb_left == node) ++ parent->rb_left = child; ++ else ++ parent->rb_right = child; ++ } ++ else ++ root->rb_node = child; ++ ++ color: ++ if (color == RB_BLACK) ++ __rb_erase_color(child, parent, root); ++} ++#endif /* Before 2.4.11 */ ++ ++ /* These routines haven't made it into 2.4 (yet) */ ++struct rb_node *rb_next(struct rb_node *node) ++{ ++ /* If we have a right-hand child, go down and then left as far ++ as we can. */ ++ if (node->rb_right) { ++ node = node->rb_right; ++ while (node->rb_left) ++ node=node->rb_left; ++ return node; ++ } ++ ++ /* No right-hand children. Everything down and left is ++ smaller than us, so any 'next' node must be in the general ++ direction of our parent. Go up the tree; any time the ++ ancestor is a right-hand child of its parent, keep going ++ up. First time it's a left-hand child of its parent, said ++ parent is our 'next' node. */ ++ while (node->rb_parent && node == node->rb_parent->rb_right) ++ node = node->rb_parent; ++ ++ return node->rb_parent; ++} ++ ++struct rb_node *rb_prev(struct rb_node *node) ++{ ++ if (node->rb_left) { ++ node = node->rb_left; ++ while (node->rb_right) ++ node=node->rb_right; ++ return node; ++ } ++ while (node->rb_parent && node == node->rb_parent->rb_left) ++ node = node->rb_parent; ++ ++ return node->rb_parent; ++} ++ ++void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root) ++{ ++ struct rb_node *parent = victim->rb_parent; ++ ++ /* Set the surrounding nodes to point to the replacement */ ++ if (parent) { ++ if (victim == parent->rb_left) ++ parent->rb_left = new; ++ else ++ parent->rb_right = new; ++ } else { ++ root->rb_node = new; ++ } ++ if (victim->rb_left) ++ victim->rb_left->rb_parent = new; ++ if (victim->rb_right) ++ victim->rb_right->rb_parent = new; ++ ++ /* Copy the pointers/colour from the victim to the replacement */ ++ *new = *victim; ++} +diff -Nurb linux-mips-2.4.27/fs/jffs2/read.c linux/fs/jffs2/read.c +--- linux-mips-2.4.27/fs/jffs2/read.c 2003-11-17 02:07:44.000000000 +0100 ++++ linux/fs/jffs2/read.c 2004-11-19 10:25:12.121166048 +0100 +@@ -1,52 +1,29 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: read.c,v 1.13.2.2 2003/11/02 13:51:18 dwmw2 Exp $ ++ * $Id: read.c,v 1.34 2003/10/04 08:33:06 dwmw2 Exp $ + * + */ + + #include + #include +-#include ++#include ++#include + #include ++#include + #include "nodelist.h" +-#include + + int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_full_dnode *fd, unsigned char *buf, int ofs, int len) + { + struct jffs2_raw_inode *ri; + size_t readlen; +- __u32 crc; ++ uint32_t crc; + unsigned char *decomprbuf = NULL; + unsigned char *readbuf = NULL; + int ret = 0; +@@ -55,35 +32,41 @@ + if (!ri) + return -ENOMEM; + +- ret = c->mtd->read(c->mtd, fd->raw->flash_offset & ~3, sizeof(*ri), &readlen, (char *)ri); ++ ret = jffs2_flash_read(c, ref_offset(fd->raw), sizeof(*ri), &readlen, (char *)ri); + if (ret) { + jffs2_free_raw_inode(ri); +- printk(KERN_WARNING "Error reading node from 0x%08x: %d\n", fd->raw->flash_offset & ~3, ret); ++ printk(KERN_WARNING "Error reading node from 0x%08x: %d\n", ref_offset(fd->raw), ret); + return ret; + } + if (readlen != sizeof(*ri)) { + jffs2_free_raw_inode(ri); +- printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%x bytes, got 0x%x\n", +- fd->raw->flash_offset & ~3, sizeof(*ri), readlen); ++ printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n", ++ ref_offset(fd->raw), sizeof(*ri), readlen); + return -EIO; + } + crc = crc32(0, ri, sizeof(*ri)-8); + +- D1(printk(KERN_DEBUG "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %p\n", fd->raw->flash_offset & ~3, ri->node_crc, crc, ri->dsize, ri->csize, ri->offset, buf)); +- if (crc != ri->node_crc) { +- printk(KERN_WARNING "Node CRC %08x != calculated CRC %08x for node at %08x\n", ri->node_crc, crc, fd->raw->flash_offset & ~3); ++ D1(printk(KERN_DEBUG "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %p\n", ++ ref_offset(fd->raw), je32_to_cpu(ri->node_crc), ++ crc, je32_to_cpu(ri->dsize), je32_to_cpu(ri->csize), ++ je32_to_cpu(ri->offset), buf)); ++ if (crc != je32_to_cpu(ri->node_crc)) { ++ printk(KERN_WARNING "Node CRC %08x != calculated CRC %08x for node at %08x\n", ++ je32_to_cpu(ri->node_crc), crc, ref_offset(fd->raw)); + ret = -EIO; + goto out_ri; + } + /* There was a bug where we wrote hole nodes out with csize/dsize + swapped. Deal with it */ +- if (ri->compr == JFFS2_COMPR_ZERO && !ri->dsize && ri->csize) { ++ if (ri->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(ri->dsize) && ++ je32_to_cpu(ri->csize)) { + ri->dsize = ri->csize; +- ri->csize = 0; ++ ri->csize = cpu_to_je32(0); + } + +- D1(if(ofs + len > ri->dsize) { +- printk(KERN_WARNING "jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n", len, ofs, ri->dsize); ++ D1(if(ofs + len > je32_to_cpu(ri->dsize)) { ++ printk(KERN_WARNING "jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n", ++ len, ofs, je32_to_cpu(ri->dsize)); + ret = -EINVAL; + goto out_ri; + }); +@@ -100,18 +83,18 @@ + Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy + Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy + */ +- if (ri->compr == JFFS2_COMPR_NONE && len == ri->dsize) { ++ if (ri->compr == JFFS2_COMPR_NONE && len == je32_to_cpu(ri->dsize)) { + readbuf = buf; + } else { +- readbuf = kmalloc(ri->csize, GFP_KERNEL); ++ readbuf = kmalloc(je32_to_cpu(ri->csize), GFP_KERNEL); + if (!readbuf) { + ret = -ENOMEM; + goto out_ri; + } + } + if (ri->compr != JFFS2_COMPR_NONE) { +- if (len < ri->dsize) { +- decomprbuf = kmalloc(ri->dsize, GFP_KERNEL); ++ if (len < je32_to_cpu(ri->dsize)) { ++ decomprbuf = kmalloc(je32_to_cpu(ri->dsize), GFP_KERNEL); + if (!decomprbuf) { + ret = -ENOMEM; + goto out_readbuf; +@@ -123,31 +106,35 @@ + decomprbuf = readbuf; + } + +- D2(printk(KERN_DEBUG "Read %d bytes to %p\n", ri->csize, readbuf)); +- ret = c->mtd->read(c->mtd, (fd->raw->flash_offset &~3) + sizeof(*ri), ri->csize, &readlen, readbuf); ++ D2(printk(KERN_DEBUG "Read %d bytes to %p\n", je32_to_cpu(ri->csize), ++ readbuf)); ++ ret = jffs2_flash_read(c, (ref_offset(fd->raw)) + sizeof(*ri), ++ je32_to_cpu(ri->csize), &readlen, readbuf); + +- if (!ret && readlen != ri->csize) ++ if (!ret && readlen != je32_to_cpu(ri->csize)) + ret = -EIO; + if (ret) + goto out_decomprbuf; + +- crc = crc32(0, readbuf, ri->csize); +- if (crc != ri->data_crc) { +- printk(KERN_WARNING "Data CRC %08x != calculated CRC %08x for node at %08x\n", ri->data_crc, crc, fd->raw->flash_offset & ~3); ++ crc = crc32(0, readbuf, je32_to_cpu(ri->csize)); ++ if (crc != je32_to_cpu(ri->data_crc)) { ++ printk(KERN_WARNING "Data CRC %08x != calculated CRC %08x for node at %08x\n", ++ je32_to_cpu(ri->data_crc), crc, ref_offset(fd->raw)); + ret = -EIO; + goto out_decomprbuf; + } + D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08x\n", crc)); + if (ri->compr != JFFS2_COMPR_NONE) { +- D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n", ri->csize, readbuf, ri->dsize, decomprbuf)); +- ret = jffs2_decompress(ri->compr, readbuf, decomprbuf, ri->csize, ri->dsize); ++ D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n", ++ je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf)); ++ ret = jffs2_decompress(ri->compr, readbuf, decomprbuf, je32_to_cpu(ri->csize), je32_to_cpu(ri->dsize)); + if (ret) { + printk(KERN_WARNING "Error: jffs2_decompress returned %d\n", ret); + goto out_decomprbuf; + } + } + +- if (len < ri->dsize) { ++ if (len < je32_to_cpu(ri->dsize)) { + memcpy(buf, decomprbuf+ofs, len); + } + out_decomprbuf: +@@ -161,3 +148,96 @@ + + return ret; + } ++ ++int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, ++ unsigned char *buf, uint32_t offset, uint32_t len) ++{ ++ uint32_t end = offset + len; ++ struct jffs2_node_frag *frag; ++ int ret; ++ ++ D1(printk(KERN_DEBUG "jffs2_read_inode_range: ino #%u, range 0x%08x-0x%08x\n", ++ f->inocache->ino, offset, offset+len)); ++ ++ frag = jffs2_lookup_node_frag(&f->fragtree, offset); ++ ++ /* XXX FIXME: Where a single physical node actually shows up in two ++ frags, we read it twice. Don't do that. */ ++ /* Now we're pointing at the first frag which overlaps our page */ ++ while(offset < end) { ++ D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end)); ++ if (unlikely(!frag || frag->ofs > offset)) { ++ uint32_t holesize = end - offset; ++ if (frag) { ++ D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset)); ++ holesize = min(holesize, frag->ofs - offset); ++ D1(jffs2_print_frag_list(f)); ++ } ++ D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize)); ++ memset(buf, 0, holesize); ++ buf += holesize; ++ offset += holesize; ++ continue; ++ } else if (unlikely(!frag->node)) { ++ uint32_t holeend = min(end, frag->ofs + frag->size); ++ D1(printk(KERN_DEBUG "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset, holeend, frag->ofs, frag->ofs + frag->size)); ++ memset(buf, 0, holeend - offset); ++ buf += holeend - offset; ++ offset = holeend; ++ frag = frag_next(frag); ++ continue; ++ } else { ++ uint32_t readlen; ++ uint32_t fragofs; /* offset within the frag to start reading */ ++ ++ fragofs = offset - frag->ofs; ++ readlen = min(frag->size - fragofs, end - offset); ++ D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%08x (%d)\n", ++ frag->ofs+fragofs, frag->ofs+fragofs+readlen, ++ ref_offset(frag->node->raw), ref_flags(frag->node->raw))); ++ ret = jffs2_read_dnode(c, frag->node, buf, fragofs + frag->ofs - frag->node->ofs, readlen); ++ D2(printk(KERN_DEBUG "node read done\n")); ++ if (ret) { ++ D1(printk(KERN_DEBUG"jffs2_read_inode_range error %d\n",ret)); ++ memset(buf, 0, readlen); ++ return ret; ++ } ++ buf += readlen; ++ offset += readlen; ++ frag = frag_next(frag); ++ D2(printk(KERN_DEBUG "node read was OK. Looping\n")); ++ } ++ } ++ return 0; ++} ++ ++/* Core function to read symlink target. */ ++char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f) ++{ ++ char *buf; ++ int ret; ++ ++ down(&f->sem); ++ ++ if (!f->metadata) { ++ printk(KERN_NOTICE "No metadata for symlink inode #%u\n", f->inocache->ino); ++ up(&f->sem); ++ return ERR_PTR(-EINVAL); ++ } ++ buf = kmalloc(f->metadata->size+1, GFP_USER); ++ if (!buf) { ++ up(&f->sem); ++ return ERR_PTR(-ENOMEM); ++ } ++ buf[f->metadata->size]=0; ++ ++ ret = jffs2_read_dnode(c, f->metadata, buf, 0, f->metadata->size); ++ ++ up(&f->sem); ++ ++ if (ret) { ++ kfree(buf); ++ return ERR_PTR(ret); ++ } ++ return buf; ++} +diff -Nurb linux-mips-2.4.27/fs/jffs2/readinode.c linux/fs/jffs2/readinode.c +--- linux-mips-2.4.27/fs/jffs2/readinode.c 2003-11-17 02:07:44.000000000 +0100 ++++ linux/fs/jffs2/readinode.c 2004-11-19 10:25:12.123165744 +0100 +@@ -1,79 +1,122 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: readinode.c,v 1.58.2.8 2003/11/02 13:54:20 dwmw2 Exp $ ++ * $Id: readinode.c,v 1.113 2003/11/03 13:20:33 dwmw2 Exp $ + * + */ + +-/* Given an inode, probably with existing list of fragments, add the new node +- * to the fragment list. +- */ + #include + #include + #include ++#include ++#include + #include +-#include ++#include + #include "nodelist.h" +-#include + ++static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag); + +-D1(void jffs2_print_frag_list(struct jffs2_inode_info *f) ++#if CONFIG_JFFS2_FS_DEBUG >= 1 ++static void jffs2_print_fragtree(struct rb_root *list, int permitbug) + { +- struct jffs2_node_frag *this = f->fraglist; ++ struct jffs2_node_frag *this = frag_first(list); ++ uint32_t lastofs = 0; ++ int buggy = 0; + + while(this) { + if (this->node) +- printk(KERN_DEBUG "frag %04x-%04x: 0x%08x on flash (*%p->%p)\n", this->ofs, this->ofs+this->size, this->node->raw->flash_offset &~3, this, this->next); ++ printk(KERN_DEBUG "frag %04x-%04x: 0x%08x(%d) on flash (*%p). left (%p), right (%p), parent (%p)\n", ++ this->ofs, this->ofs+this->size, ref_offset(this->node->raw), ref_flags(this->node->raw), ++ this, frag_left(this), frag_right(this), frag_parent(this)); + else +- printk(KERN_DEBUG "frag %04x-%04x: hole (*%p->%p)\n", this->ofs, this->ofs+this->size, this, this->next); +- this = this->next; ++ printk(KERN_DEBUG "frag %04x-%04x: hole (*%p). left (%p} right (%p), parent (%p)\n", this->ofs, ++ this->ofs+this->size, this, frag_left(this), frag_right(this), frag_parent(this)); ++ if (this->ofs != lastofs) ++ buggy = 1; ++ lastofs = this->ofs+this->size; ++ this = frag_next(this); ++ } ++ if (buggy && !permitbug) { ++ printk(KERN_CRIT "Frag tree got a hole in it\n"); ++ BUG(); + } ++} ++ ++void jffs2_print_frag_list(struct jffs2_inode_info *f) ++{ ++ jffs2_print_fragtree(&f->fragtree, 0); ++ + if (f->metadata) { +- printk(KERN_DEBUG "metadata at 0x%08x\n", f->metadata->raw->flash_offset &~3); ++ printk(KERN_DEBUG "metadata at 0x%08x\n", ref_offset(f->metadata->raw)); + } +-}) +- ++} + +-int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn) ++static int jffs2_sanitycheck_fragtree(struct jffs2_inode_info *f) + { +- int ret; +- D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn)); ++ struct jffs2_node_frag *frag; ++ int bitched = 0; + +- ret = jffs2_add_full_dnode_to_fraglist(c, &f->fraglist, fn); ++ for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) { + +- D2(jffs2_print_frag_list(f)); +- return ret; ++ struct jffs2_full_dnode *fn = frag->node; ++ if (!fn || !fn->raw) ++ continue; ++ ++ if (ref_flags(fn->raw) == REF_PRISTINE) { ++ ++ if (fn->frags > 1) { ++ printk(KERN_WARNING "REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2\n", ref_offset(fn->raw), fn->frags); ++ bitched = 1; ++ } ++ /* A hole node which isn't multi-page should be garbage-collected ++ and merged anyway, so we just check for the frag size here, ++ rather than mucking around with actually reading the node ++ and checking the compression type, which is the real way ++ to tell a hole node. */ ++ if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag) && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) { ++ printk(KERN_WARNING "REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2\n", ++ ref_offset(fn->raw)); ++ bitched = 1; ++ } ++ ++ if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag) && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) { ++ printk(KERN_WARNING "REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2\n", ++ ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size); ++ bitched = 1; ++ } ++ } ++ } ++ ++ if (bitched) { ++ struct jffs2_node_frag *thisfrag; ++ ++ printk(KERN_WARNING "Inode is #%u\n", f->inocache->ino); ++ thisfrag = frag_first(&f->fragtree); ++ while (thisfrag) { ++ if (!thisfrag->node) { ++ printk("Frag @0x%x-0x%x; node-less hole\n", ++ thisfrag->ofs, thisfrag->size + thisfrag->ofs); ++ } else if (!thisfrag->node->raw) { ++ printk("Frag @0x%x-0x%x; raw-less hole\n", ++ thisfrag->ofs, thisfrag->size + thisfrag->ofs); ++ } else { ++ printk("Frag @0x%x-0x%x; raw at 0x%08x(%d) (0x%x-0x%x)\n", ++ thisfrag->ofs, thisfrag->size + thisfrag->ofs, ++ ref_offset(thisfrag->node->raw), ref_flags(thisfrag->node->raw), ++ thisfrag->node->ofs, thisfrag->node->ofs+thisfrag->node->size); ++ } ++ thisfrag = frag_next(thisfrag); ++ } ++ } ++ return bitched; + } ++#endif /* D1 */ + + static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this) + { +@@ -82,42 +125,38 @@ + if (!this->node->frags) { + /* The node has no valid frags left. It's totally obsoleted */ + D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) obsolete\n", +- this->node->raw->flash_offset &~3, this->node->ofs, this->node->ofs+this->node->size)); ++ ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size)); + jffs2_mark_node_obsolete(c, this->node->raw); + jffs2_free_full_dnode(this->node); + } else { +- D2(printk(KERN_DEBUG "Not marking old node @0x%08x (0x%04x-0x%04x) obsolete. frags is %d\n", +- this->node->raw->flash_offset &~3, this->node->ofs, this->node->ofs+this->node->size, ++ D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n", ++ ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size, + this->node->frags)); ++ mark_ref_normal(this->node->raw); + } + + } + jffs2_free_node_frag(this); + } + +-/* Doesn't set inode->i_size */ +-int jffs2_add_full_dnode_to_fraglist(struct jffs2_sb_info *c, struct jffs2_node_frag **list, struct jffs2_full_dnode *fn) ++/* Given an inode, probably with existing list of fragments, add the new node ++ * to the fragment list. ++ */ ++int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn) + { ++ int ret; ++ struct jffs2_node_frag *newfrag; + +- struct jffs2_node_frag *this, **prev, *old; +- struct jffs2_node_frag *newfrag, *newfrag2; +- __u32 lastend = 0; +- ++ D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn)); + + newfrag = jffs2_alloc_node_frag(); +- if (!newfrag) { ++ if (unlikely(!newfrag)) + return -ENOMEM; +- } +- +- D2(if (fn->raw) +- printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n", fn->ofs, fn->ofs+fn->size, fn->raw->flash_offset &~3, newfrag); +- else +- printk(KERN_DEBUG "adding hole node %04x-%04x on flash, newfrag *%p\n", fn->ofs, fn->ofs+fn->size, newfrag)); + +- prev = list; +- this = *list; ++ D2(printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n", ++ fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag)); + +- if (!fn->size) { ++ if (unlikely(!fn->size)) { + jffs2_free_node_frag(newfrag); + return 0; + } +@@ -126,176 +165,358 @@ + newfrag->size = fn->size; + newfrag->node = fn; + newfrag->node->frags = 1; +- newfrag->next = (void *)0xdeadbeef; ++ ++ ret = jffs2_add_frag_to_fragtree(c, &f->fragtree, newfrag); ++ if (ret) ++ return ret; ++ ++ /* If we now share a page with other nodes, mark either previous ++ or next node REF_NORMAL, as appropriate. */ ++ if (newfrag->ofs & (PAGE_CACHE_SIZE-1)) { ++ struct jffs2_node_frag *prev = frag_prev(newfrag); ++ ++ mark_ref_normal(fn->raw); ++ /* If we don't start at zero there's _always_ a previous */ ++ if (prev->node) ++ mark_ref_normal(prev->node->raw); ++ } ++ ++ if ((newfrag->ofs+newfrag->size) & (PAGE_CACHE_SIZE-1)) { ++ struct jffs2_node_frag *next = frag_next(newfrag); ++ ++ if (next) { ++ mark_ref_normal(fn->raw); ++ if (next->node) ++ mark_ref_normal(next->node->raw); ++ } ++ } ++ D2(if (jffs2_sanitycheck_fragtree(f)) { ++ printk(KERN_WARNING "Just added node %04x-%04x @0x%08x on flash, newfrag *%p\n", ++ fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag); ++ return 0; ++ }) ++ D2(jffs2_print_frag_list(f)); ++ return 0; ++} ++ ++/* Doesn't set inode->i_size */ ++static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag) ++{ ++ struct jffs2_node_frag *this; ++ uint32_t lastend; + + /* Skip all the nodes which are completed before this one starts */ +- while(this && fn->ofs >= this->ofs+this->size) { +- lastend = this->ofs + this->size; ++ this = jffs2_lookup_node_frag(list, newfrag->node->ofs); + +- D2(printk(KERN_DEBUG "j_a_f_d_t_f: skipping frag 0x%04x-0x%04x; phys 0x%08x (*%p->%p)\n", +- this->ofs, this->ofs+this->size, this->node?(this->node->raw->flash_offset &~3):0xffffffff, this, this->next)); +- prev = &this->next; +- this = this->next; ++ if (this) { ++ D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n", ++ this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this)); ++ lastend = this->ofs + this->size; ++ } else { ++ D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave no frag\n")); ++ lastend = 0; + } + + /* See if we ran off the end of the list */ +- if (!this) { ++ if (lastend <= newfrag->ofs) { + /* We did */ +- if (lastend < fn->ofs) { ++ ++ /* Check if 'this' node was on the same page as the new node. ++ If so, both 'this' and the new node get marked REF_NORMAL so ++ the GC can take a look. ++ */ ++ if ((lastend-1) >> PAGE_CACHE_SHIFT == newfrag->ofs >> PAGE_CACHE_SHIFT) { ++ if (this->node) ++ mark_ref_normal(this->node->raw); ++ mark_ref_normal(newfrag->node->raw); ++ } ++ ++ if (lastend < newfrag->node->ofs) { + /* ... and we need to put a hole in before the new node */ + struct jffs2_node_frag *holefrag = jffs2_alloc_node_frag(); +- if (!holefrag) ++ if (!holefrag) { ++ jffs2_free_node_frag(newfrag); + return -ENOMEM; ++ } + holefrag->ofs = lastend; +- holefrag->size = fn->ofs - lastend; +- holefrag->next = NULL; ++ holefrag->size = newfrag->node->ofs - lastend; + holefrag->node = NULL; +- *prev = holefrag; +- prev = &holefrag->next; ++ if (this) { ++ /* By definition, the 'this' node has no right-hand child, ++ because there are no frags with offset greater than it. ++ So that's where we want to put the hole */ ++ D2(printk(KERN_DEBUG "Adding hole frag (%p) on right of node at (%p)\n", holefrag, this)); ++ rb_link_node(&holefrag->rb, &this->rb, &this->rb.rb_right); ++ } else { ++ D2(printk(KERN_DEBUG "Adding hole frag (%p) at root of tree\n", holefrag)); ++ rb_link_node(&holefrag->rb, NULL, &list->rb_node); ++ } ++ rb_insert_color(&holefrag->rb, list); ++ this = holefrag; + } +- newfrag->next = NULL; +- *prev = newfrag; ++ if (this) { ++ /* By definition, the 'this' node has no right-hand child, ++ because there are no frags with offset greater than it. ++ So that's where we want to put the hole */ ++ D2(printk(KERN_DEBUG "Adding new frag (%p) on right of node at (%p)\n", newfrag, this)); ++ rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right); ++ } else { ++ D2(printk(KERN_DEBUG "Adding new frag (%p) at root of tree\n", newfrag)); ++ rb_link_node(&newfrag->rb, NULL, &list->rb_node); ++ } ++ rb_insert_color(&newfrag->rb, list); + return 0; + } + +- D2(printk(KERN_DEBUG "j_a_f_d_t_f: dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p->%p)\n", +- this->ofs, this->ofs+this->size, this->node?(this->node->raw->flash_offset &~3):0xffffffff, this, this->next)); ++ D2(printk(KERN_DEBUG "j_a_f_d_t_f: dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n", ++ this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this)); + +- /* OK. 'this' is pointing at the first frag that fn->ofs at least partially obsoletes, +- * - i.e. fn->ofs < this->ofs+this->size && fn->ofs >= this->ofs ++ /* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes, ++ * - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs + */ +- if (fn->ofs > this->ofs) { ++ if (newfrag->ofs > this->ofs) { + /* This node isn't completely obsoleted. The start of it remains valid */ +- if (this->ofs + this->size > fn->ofs + fn->size) { ++ ++ /* Mark the new node and the partially covered node REF_NORMAL -- let ++ the GC take a look at them */ ++ mark_ref_normal(newfrag->node->raw); ++ if (this->node) ++ mark_ref_normal(this->node->raw); ++ ++ if (this->ofs + this->size > newfrag->ofs + newfrag->size) { + /* The new node splits 'this' frag into two */ +- newfrag2 = jffs2_alloc_node_frag(); ++ struct jffs2_node_frag *newfrag2 = jffs2_alloc_node_frag(); + if (!newfrag2) { + jffs2_free_node_frag(newfrag); + return -ENOMEM; + } +- D1(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size); ++ D2(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size); + if (this->node) +- printk("phys 0x%08x\n", this->node->raw->flash_offset &~3); ++ printk("phys 0x%08x\n", ref_offset(this->node->raw)); + else + printk("hole\n"); + ) +- newfrag2->ofs = fn->ofs + fn->size; ++ ++ /* New second frag pointing to this's node */ ++ newfrag2->ofs = newfrag->ofs + newfrag->size; + newfrag2->size = (this->ofs+this->size) - newfrag2->ofs; +- newfrag2->next = this->next; + newfrag2->node = this->node; + if (this->node) + this->node->frags++; +- newfrag->next = newfrag2; +- this->next = newfrag; ++ ++ /* Adjust size of original 'this' */ + this->size = newfrag->ofs - this->ofs; ++ ++ /* Now, we know there's no node with offset ++ greater than this->ofs but smaller than ++ newfrag2->ofs or newfrag->ofs, for obvious ++ reasons. So we can do a tree insert from ++ 'this' to insert newfrag, and a tree insert ++ from newfrag to insert newfrag2. */ ++ jffs2_fragtree_insert(newfrag, this); ++ rb_insert_color(&newfrag->rb, list); ++ ++ jffs2_fragtree_insert(newfrag2, newfrag); ++ rb_insert_color(&newfrag2->rb, list); ++ + return 0; + } + /* New node just reduces 'this' frag in size, doesn't split it */ +- this->size = fn->ofs - this->ofs; +- newfrag->next = this->next; +- this->next = newfrag; +- this = newfrag->next; ++ this->size = newfrag->ofs - this->ofs; ++ ++ /* Again, we know it lives down here in the tree */ ++ jffs2_fragtree_insert(newfrag, this); ++ rb_insert_color(&newfrag->rb, list); + } else { +- D2(printk(KERN_DEBUG "Inserting newfrag (*%p) in before 'this' (*%p)\n", newfrag, this)); +- *prev = newfrag; +- newfrag->next = this; ++ /* New frag starts at the same point as 'this' used to. Replace ++ it in the tree without doing a delete and insertion */ ++ D2(printk(KERN_DEBUG "Inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n", ++ newfrag, newfrag->ofs, newfrag->ofs+newfrag->size, ++ this, this->ofs, this->ofs+this->size)); ++ ++ rb_replace_node(&this->rb, &newfrag->rb, list); ++ ++ if (newfrag->ofs + newfrag->size >= this->ofs+this->size) { ++ D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size)); ++ jffs2_obsolete_node_frag(c, this); ++ } else { ++ this->ofs += newfrag->size; ++ this->size -= newfrag->size; ++ ++ jffs2_fragtree_insert(this, newfrag); ++ rb_insert_color(&this->rb, list); ++ return 0; + } +- /* OK, now we have newfrag added in the correct place in the list, but +- newfrag->next points to a fragment which may be overlapping it ++ } ++ /* OK, now we have newfrag added in the correct place in the tree, but ++ frag_next(newfrag) may be a fragment which is overlapped by it + */ +- while (this && newfrag->ofs + newfrag->size >= this->ofs + this->size) { +- /* 'this' frag is obsoleted. */ +- old = this; +- this = old->next; +- jffs2_obsolete_node_frag(c, old); ++ while ((this = frag_next(newfrag)) && newfrag->ofs + newfrag->size >= this->ofs + this->size) { ++ /* 'this' frag is obsoleted completely. */ ++ D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x) and removing from tree\n", this, this->ofs, this->ofs+this->size)); ++ rb_erase(&this->rb, list); ++ jffs2_obsolete_node_frag(c, this); + } + /* Now we're pointing at the first frag which isn't totally obsoleted by + the new frag */ +- newfrag->next = this; + + if (!this || newfrag->ofs + newfrag->size == this->ofs) { + return 0; + } +- /* Still some overlap */ ++ /* Still some overlap but we don't need to move it in the tree */ + this->size = (this->ofs + this->size) - (newfrag->ofs + newfrag->size); + this->ofs = newfrag->ofs + newfrag->size; ++ ++ /* And mark them REF_NORMAL so the GC takes a look at them */ ++ if (this->node) ++ mark_ref_normal(this->node->raw); ++ mark_ref_normal(newfrag->node->raw); ++ + return 0; + } + +-void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct jffs2_node_frag **list, __u32 size) ++void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size) + { ++ struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size); ++ + D1(printk(KERN_DEBUG "Truncating fraglist to 0x%08x bytes\n", size)); + +- while (*list) { +- if ((*list)->ofs >= size) { +- struct jffs2_node_frag *this = *list; +- *list = this->next; +- D1(printk(KERN_DEBUG "Removing frag 0x%08x-0x%08x\n", this->ofs, this->ofs+this->size)); +- jffs2_obsolete_node_frag(c, this); +- continue; +- } else if ((*list)->ofs + (*list)->size > size) { +- D1(printk(KERN_DEBUG "Truncating frag 0x%08x-0x%08x\n", (*list)->ofs, (*list)->ofs + (*list)->size)); +- (*list)->size = size - (*list)->ofs; +- } +- list = &(*list)->next; ++ /* We know frag->ofs <= size. That's what lookup does for us */ ++ if (frag && frag->ofs != size) { ++ if (frag->ofs+frag->size >= size) { ++ D1(printk(KERN_DEBUG "Truncating frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size)); ++ frag->size = size - frag->ofs; ++ } ++ frag = frag_next(frag); ++ } ++ while (frag && frag->ofs >= size) { ++ struct jffs2_node_frag *next = frag_next(frag); ++ ++ D1(printk(KERN_DEBUG "Removing frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size)); ++ frag_erase(frag, list); ++ jffs2_obsolete_node_frag(c, frag); ++ frag = next; + } + } + + /* Scan the list of all nodes present for this ino, build map of versions, etc. */ + +-void jffs2_read_inode (struct inode *inode) ++static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, ++ struct jffs2_inode_info *f, ++ struct jffs2_raw_inode *latest_node); ++ ++int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, ++ uint32_t ino, struct jffs2_raw_inode *latest_node) + { +- struct jffs2_tmp_dnode_info *tn_list, *tn; +- struct jffs2_full_dirent *fd_list; +- struct jffs2_inode_info *f; +- struct jffs2_full_dnode *fn = NULL; +- struct jffs2_sb_info *c; +- struct jffs2_raw_inode latest_node; +- __u32 latest_mctime, mctime_ver; +- __u32 mdata_ver = 0; +- int ret; +- ssize_t retlen; ++ D2(printk(KERN_DEBUG "jffs2_do_read_inode(): getting inocache\n")); + +- D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino)); ++ retry_inocache: ++ spin_lock(&c->inocache_lock); ++ f->inocache = jffs2_get_ino_cache(c, ino); ++ ++ D2(printk(KERN_DEBUG "jffs2_do_read_inode(): Got inocache at %p\n", f->inocache)); ++ ++ if (f->inocache) { ++ /* Check its state. We may need to wait before we can use it */ ++ switch(f->inocache->state) { ++ case INO_STATE_UNCHECKED: ++ case INO_STATE_CHECKEDABSENT: ++ f->inocache->state = INO_STATE_READING; ++ break; + +- f = JFFS2_INODE_INFO(inode); +- c = JFFS2_SB_INFO(inode->i_sb); ++ case INO_STATE_CHECKING: ++ case INO_STATE_GC: ++ /* If it's in either of these states, we need ++ to wait for whoever's got it to finish and ++ put it back. */ ++ D1(printk(KERN_DEBUG "jffs2_get_ino_cache_read waiting for ino #%u in state %d\n", ++ ino, f->inocache->state)); ++ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); ++ goto retry_inocache; ++ ++ case INO_STATE_READING: ++ case INO_STATE_PRESENT: ++ /* Eep. This should never happen. It can ++ happen if Linux calls read_inode() again ++ before clear_inode() has finished though. */ ++ printk(KERN_WARNING "Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state); ++ /* Fail. That's probably better than allowing it to succeed */ ++ f->inocache = NULL; ++ break; + +- memset(f, 0, sizeof(*f)); +- D2(printk(KERN_DEBUG "getting inocache\n")); +- init_MUTEX(&f->sem); +- f->inocache = jffs2_get_ino_cache(c, inode->i_ino); +- D2(printk(KERN_DEBUG "jffs2_read_inode(): Got inocache at %p\n", f->inocache)); ++ default: ++ BUG(); ++ } ++ } ++ spin_unlock(&c->inocache_lock); + +- if (!f->inocache && inode->i_ino == 1) { ++ if (!f->inocache && ino == 1) { + /* Special case - no root inode on medium */ + f->inocache = jffs2_alloc_inode_cache(); + if (!f->inocache) { +- printk(KERN_CRIT "jffs2_read_inode(): Cannot allocate inocache for root inode\n"); +- make_bad_inode(inode); +- return; ++ printk(KERN_CRIT "jffs2_do_read_inode(): Cannot allocate inocache for root inode\n"); ++ return -ENOMEM; + } +- D1(printk(KERN_DEBUG "jffs2_read_inode(): Creating inocache for root inode\n")); ++ D1(printk(KERN_DEBUG "jffs2_do_read_inode(): Creating inocache for root inode\n")); + memset(f->inocache, 0, sizeof(struct jffs2_inode_cache)); + f->inocache->ino = f->inocache->nlink = 1; + f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; ++ f->inocache->state = INO_STATE_READING; + jffs2_add_ino_cache(c, f->inocache); + } + if (!f->inocache) { +- printk(KERN_WARNING "jffs2_read_inode() on nonexistent ino %lu\n", (unsigned long)inode->i_ino); +- make_bad_inode(inode); +- return; ++ printk(KERN_WARNING "jffs2_do_read_inode() on nonexistent ino %u\n", ino); ++ return -ENOENT; + } +- D1(printk(KERN_DEBUG "jffs2_read_inode(): ino #%lu nlink is %d\n", (unsigned long)inode->i_ino, f->inocache->nlink)); +- inode->i_nlink = f->inocache->nlink; ++ ++ return jffs2_do_read_inode_internal(c, f, latest_node); ++} ++ ++int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) ++{ ++ struct jffs2_raw_inode n; ++ struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL); ++ int ret; ++ ++ if (!f) ++ return -ENOMEM; ++ ++ memset(f, 0, sizeof(*f)); ++ init_MUTEX_LOCKED(&f->sem); ++ f->inocache = ic; ++ ++ ret = jffs2_do_read_inode_internal(c, f, &n); ++ if (!ret) { ++ up(&f->sem); ++ jffs2_do_clear_inode(c, f); ++ } ++ kfree (f); ++ return ret; ++} ++ ++static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, ++ struct jffs2_inode_info *f, ++ struct jffs2_raw_inode *latest_node) ++{ ++ struct jffs2_tmp_dnode_info *tn_list, *tn; ++ struct jffs2_full_dirent *fd_list; ++ struct jffs2_full_dnode *fn = NULL; ++ uint32_t crc; ++ uint32_t latest_mctime, mctime_ver; ++ uint32_t mdata_ver = 0; ++ size_t retlen; ++ int ret; ++ ++ D1(printk(KERN_DEBUG "jffs2_do_read_inode_internal(): ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink)); + + /* Grab all nodes relevant to this ino */ +- ret = jffs2_get_inode_nodes(c, inode->i_ino, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver); ++ ret = jffs2_get_inode_nodes(c, f->inocache->ino, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver); + + if (ret) { +- printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %lu returned %d\n", inode->i_ino, ret); +- make_bad_inode(inode); +- return; ++ printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %u returned %d\n", f->inocache->ino, ret); ++ if (f->inocache->state == INO_STATE_READING) ++ jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); ++ return ret; + } + f->dents = fd_list; + +@@ -304,205 +525,169 @@ + + fn = tn->fn; + +- if (f->metadata && tn->version > mdata_ver) { +- D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", f->metadata->raw->flash_offset &~3)); ++ if (f->metadata) { ++ if (likely(tn->version >= mdata_ver)) { ++ D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", ref_offset(f->metadata->raw))); + jffs2_mark_node_obsolete(c, f->metadata->raw); + jffs2_free_full_dnode(f->metadata); + f->metadata = NULL; + + mdata_ver = 0; ++ } else { ++ /* This should never happen. */ ++ printk(KERN_WARNING "Er. New metadata at 0x%08x with ver %d is actually older than previous ver %d at 0x%08x\n", ++ ref_offset(fn->raw), tn->version, mdata_ver, ref_offset(f->metadata->raw)); ++ jffs2_mark_node_obsolete(c, fn->raw); ++ jffs2_free_full_dnode(fn); ++ /* Fill in latest_node from the metadata, not this one we're about to free... */ ++ fn = f->metadata; ++ goto next_tn; ++ } + } + + if (fn->size) { + jffs2_add_full_dnode_to_inode(c, f, fn); + } else { + /* Zero-sized node at end of version list. Just a metadata update */ +- D1(printk(KERN_DEBUG "metadata @%08x: ver %d\n", fn->raw->flash_offset &~3, tn->version)); ++ D1(printk(KERN_DEBUG "metadata @%08x: ver %d\n", ref_offset(fn->raw), tn->version)); + f->metadata = fn; + mdata_ver = tn->version; + } ++ next_tn: + tn_list = tn->next; + jffs2_free_tmp_dnode_info(tn); + } ++ D1(jffs2_sanitycheck_fragtree(f)); ++ + if (!fn) { + /* No data nodes for this inode. */ +- if (inode->i_ino != 1) { +- printk(KERN_WARNING "jffs2_read_inode(): No data nodes found for ino #%lu\n", inode->i_ino); ++ if (f->inocache->ino != 1) { ++ printk(KERN_WARNING "jffs2_do_read_inode(): No data nodes found for ino #%u\n", f->inocache->ino); + if (!fd_list) { +- make_bad_inode(inode); +- return; +- } +- printk(KERN_WARNING "jffs2_read_inode(): But it has children so we fake some modes for it\n"); ++ if (f->inocache->state == INO_STATE_READING) ++ jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); ++ return -EIO; ++ } ++ printk(KERN_WARNING "jffs2_do_read_inode(): But it has children so we fake some modes for it\n"); ++ } ++ latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO); ++ latest_node->version = cpu_to_je32(0); ++ latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0); ++ latest_node->isize = cpu_to_je32(0); ++ latest_node->gid = cpu_to_je16(0); ++ latest_node->uid = cpu_to_je16(0); ++ if (f->inocache->state == INO_STATE_READING) ++ jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT); ++ return 0; + } +- inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO; +- latest_node.version = 0; +- inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME; +- inode->i_nlink = f->inocache->nlink; +- inode->i_size = 0; +- } else { +- __u32 crc; + +- ret = c->mtd->read(c->mtd, fn->raw->flash_offset & ~3, sizeof(latest_node), &retlen, (void *)&latest_node); +- if (ret || retlen != sizeof(latest_node)) { +- printk(KERN_NOTICE "MTD read in jffs2_read_inode() failed: Returned %d, %ld of %d bytes read\n", +- ret, (long)retlen, sizeof(latest_node)); +- jffs2_clear_inode(inode); +- make_bad_inode(inode); +- return; +- } +- +- crc = crc32(0, &latest_node, sizeof(latest_node)-8); +- if (crc != latest_node.node_crc) { +- printk(KERN_NOTICE "CRC failed for read_inode of inode %ld at physical location 0x%x\n", inode->i_ino, fn->raw->flash_offset & ~3); +- jffs2_clear_inode(inode); +- make_bad_inode(inode); +- return; +- } +- +- inode->i_mode = latest_node.mode; +- inode->i_uid = latest_node.uid; +- inode->i_gid = latest_node.gid; +- inode->i_size = latest_node.isize; +- if (S_ISREG(inode->i_mode)) +- jffs2_truncate_fraglist(c, &f->fraglist, latest_node.isize); +- inode->i_atime = latest_node.atime; +- inode->i_mtime = latest_node.mtime; +- inode->i_ctime = latest_node.ctime; +- } +- +- /* OK, now the special cases. Certain inode types should +- have only one data node, and it's kept as the metadata +- node */ +- if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode) || +- S_ISLNK(inode->i_mode)) { +- if (f->metadata) { +- printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had metadata node\n", inode->i_ino, inode->i_mode); +- jffs2_clear_inode(inode); +- make_bad_inode(inode); +- return; +- } +- if (!f->fraglist) { +- printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o has no fragments\n", inode->i_ino, inode->i_mode); +- jffs2_clear_inode(inode); +- make_bad_inode(inode); +- return; +- } +- /* ASSERT: f->fraglist != NULL */ +- if (f->fraglist->next) { +- printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had more than one node\n", inode->i_ino, inode->i_mode); +- /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */ +- jffs2_clear_inode(inode); +- make_bad_inode(inode); +- return; +- } +- /* OK. We're happy */ +- f->metadata = f->fraglist->node; +- jffs2_free_node_frag(f->fraglist); +- f->fraglist = NULL; ++ ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node); ++ if (ret || retlen != sizeof(*latest_node)) { ++ printk(KERN_NOTICE "MTD read in jffs2_do_read_inode() failed: Returned %d, %zd of %zd bytes read\n", ++ ret, retlen, sizeof(*latest_node)); ++ /* FIXME: If this fails, there seems to be a memory leak. Find it. */ ++ up(&f->sem); ++ jffs2_do_clear_inode(c, f); ++ return ret?ret:-EIO; + } + +- inode->i_blksize = PAGE_SIZE; +- inode->i_blocks = (inode->i_size + 511) >> 9; +- +- switch (inode->i_mode & S_IFMT) { +- unsigned short rdev; +- +- case S_IFLNK: +- inode->i_op = &jffs2_symlink_inode_operations; +- /* Hack to work around broken isize in old symlink code. +- Remove this when dwmw2 comes to his senses and stops +- symlinks from being an entirely gratuitous special +- case. */ +- if (!inode->i_size) +- inode->i_size = latest_node.dsize; +- break; ++ crc = crc32(0, latest_node, sizeof(*latest_node)-8); ++ if (crc != je32_to_cpu(latest_node->node_crc)) { ++ printk(KERN_NOTICE "CRC failed for read_inode of inode %u at physical location 0x%x\n", f->inocache->ino, ref_offset(fn->raw)); ++ up(&f->sem); ++ jffs2_do_clear_inode(c, f); ++ return -EIO; ++ } + ++ switch(jemode_to_cpu(latest_node->mode) & S_IFMT) { + case S_IFDIR: +- if (mctime_ver > latest_node.version) { ++ if (mctime_ver > je32_to_cpu(latest_node->version)) { + /* The times in the latest_node are actually older than + mctime in the latest dirent. Cheat. */ +- inode->i_mtime = inode->i_ctime = inode->i_atime = +- latest_mctime; ++ latest_node->ctime = latest_node->mtime = cpu_to_je32(latest_mctime); + } +- inode->i_op = &jffs2_dir_inode_operations; +- inode->i_fop = &jffs2_dir_operations; + break; + ++ + case S_IFREG: +- inode->i_op = &jffs2_file_inode_operations; +- inode->i_fop = &jffs2_file_operations; +- inode->i_mapping->a_ops = &jffs2_file_address_operations; +- inode->i_mapping->nrpages = 0; ++ /* If it was a regular file, truncate it to the latest node's isize */ ++ jffs2_truncate_fraglist(c, &f->fragtree, je32_to_cpu(latest_node->isize)); + break; + ++ case S_IFLNK: ++ /* Hack to work around broken isize in old symlink code. ++ Remove this when dwmw2 comes to his senses and stops ++ symlinks from being an entirely gratuitous special ++ case. */ ++ if (!je32_to_cpu(latest_node->isize)) ++ latest_node->isize = latest_node->dsize; ++ /* fall through... */ ++ + case S_IFBLK: + case S_IFCHR: +- /* Read the device numbers from the media */ +- D1(printk(KERN_DEBUG "Reading device numbers from flash\n")); +- if (jffs2_read_dnode(c, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) { +- /* Eep */ +- printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino); +- jffs2_clear_inode(inode); +- make_bad_inode(inode); +- return; ++ /* Certain inode types should have only one data node, and it's ++ kept as the metadata node */ ++ if (f->metadata) { ++ printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o had metadata node\n", ++ f->inocache->ino, jemode_to_cpu(latest_node->mode)); ++ up(&f->sem); ++ jffs2_do_clear_inode(c, f); ++ return -EIO; + } +- +- case S_IFSOCK: +- case S_IFIFO: +- inode->i_op = &jffs2_file_inode_operations; +- init_special_inode(inode, inode->i_mode, kdev_t_to_nr(MKDEV(rdev>>8, rdev&0xff))); ++ if (!frag_first(&f->fragtree)) { ++ printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o has no fragments\n", ++ f->inocache->ino, jemode_to_cpu(latest_node->mode)); ++ up(&f->sem); ++ jffs2_do_clear_inode(c, f); ++ return -EIO; ++ } ++ /* ASSERT: f->fraglist != NULL */ ++ if (frag_next(frag_first(&f->fragtree))) { ++ printk(KERN_WARNING "Argh. Special inode #%u with mode 0x%x had more than one node\n", ++ f->inocache->ino, jemode_to_cpu(latest_node->mode)); ++ /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */ ++ up(&f->sem); ++ jffs2_do_clear_inode(c, f); ++ return -EIO; ++ } ++ /* OK. We're happy */ ++ f->metadata = frag_first(&f->fragtree)->node; ++ jffs2_free_node_frag(frag_first(&f->fragtree)); ++ f->fragtree = RB_ROOT; + break; +- +- default: +- printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu", inode->i_mode, (unsigned long)inode->i_ino); + } +- D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n")); ++ if (f->inocache->state == INO_STATE_READING) ++ jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT); ++ ++ return 0; + } + +-void jffs2_clear_inode (struct inode *inode) ++void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f) + { +- /* We can forget about this inode for now - drop all +- * the nodelists associated with it, etc. +- */ +- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +- struct jffs2_node_frag *frag, *frags; + struct jffs2_full_dirent *fd, *fds; +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + int deleted; + +- D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode)); +- + down(&f->sem); + deleted = f->inocache && !f->inocache->nlink; + +- frags = f->fraglist; +- fds = f->dents; + if (f->metadata) { + if (deleted) + jffs2_mark_node_obsolete(c, f->metadata->raw); + jffs2_free_full_dnode(f->metadata); + } + +- while (frags) { +- frag = frags; +- frags = frag->next; +- D2(printk(KERN_DEBUG "jffs2_clear_inode: frag at 0x%x-0x%x: node %p, frags %d--\n", frag->ofs, frag->ofs+frag->size, frag->node, frag->node?frag->node->frags:0)); ++ jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); + +- if (frag->node && !(--frag->node->frags)) { +- /* Not a hole, and it's the final remaining frag of this node. Free the node */ +- if (deleted) +- jffs2_mark_node_obsolete(c, frag->node->raw); ++ fds = f->dents; + +- jffs2_free_full_dnode(frag->node); +- } +- jffs2_free_node_frag(frag); +- } + while(fds) { + fd = fds; + fds = fd->next; + jffs2_free_full_dirent(fd); + } + +- up(&f->sem); +-}; ++ if (f->inocache && f->inocache->state != INO_STATE_CHECKING) ++ jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); + ++ up(&f->sem); ++} +diff -Nurb linux-mips-2.4.27/fs/jffs2/scan.c linux/fs/jffs2/scan.c +--- linux-mips-2.4.27/fs/jffs2/scan.c 2003-11-17 02:07:44.000000000 +0100 ++++ linux/fs/jffs2/scan.c 2004-11-19 10:25:12.124165592 +0100 +@@ -1,47 +1,25 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: scan.c,v 1.51.2.4 2003/11/02 13:51:18 dwmw2 Exp $ ++ * $Id: scan.c,v 1.106 2003/10/28 17:01:13 dwmw2 Exp $ + * + */ + #include ++#include + #include +-#include + #include + #include +-#include "nodelist.h" + #include ++#include ++#include "nodelist.h" + ++#define EMPTY_SCAN_SIZE 1024 + + #define DIRTY_SPACE(x) do { typeof(x) _x = (x); \ + c->free_size -= _x; c->dirty_size += _x; \ +@@ -51,6 +29,10 @@ + c->free_size -= _x; c->used_size += _x; \ + jeb->free_size -= _x ; jeb->used_size += _x; \ + }while(0) ++#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \ ++ c->free_size -= _x; c->unchecked_size += _x; \ ++ jeb->free_size -= _x ; jeb->unchecked_size += _x; \ ++ }while(0) + + #define noisy_printk(noise, args...) do { \ + if (*(noise)) { \ +@@ -63,39 +45,84 @@ + } while(0) + + static uint32_t pseudo_random; +-static void jffs2_rotate_lists(struct jffs2_sb_info *c); + +-static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); ++static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, ++ unsigned char *buf, uint32_t buf_size); + + /* These helper functions _must_ increase ofs and also do the dirty/used space accounting. + * Returning an error will abort the mount - bad checksums etc. should just mark the space + * as dirty. + */ +-static int jffs2_scan_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs, int *noise); +-static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs); +-static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs); ++static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, ++ struct jffs2_raw_inode *ri, uint32_t ofs); ++static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, ++ struct jffs2_raw_dirent *rd, uint32_t ofs); ++ ++#define BLK_STATE_ALLFF 0 ++#define BLK_STATE_CLEAN 1 ++#define BLK_STATE_PARTDIRTY 2 ++#define BLK_STATE_CLEANMARKER 3 ++#define BLK_STATE_ALLDIRTY 4 ++#define BLK_STATE_BADBLOCK 5 + ++static inline int min_free(struct jffs2_sb_info *c) ++{ ++ uint32_t min = 2 * sizeof(struct jffs2_raw_inode); ++#ifdef CONFIG_JFFS2_FS_NAND ++ if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize) ++ return c->wbuf_pagesize; ++#endif ++ return min; + ++} + int jffs2_scan_medium(struct jffs2_sb_info *c) + { + int i, ret; +- __u32 empty_blocks = 0; +- +- if (!c->blocks) { +- printk(KERN_WARNING "EEEK! c->blocks is NULL!\n"); +- return -EINVAL; ++ uint32_t empty_blocks = 0, bad_blocks = 0; ++ unsigned char *flashbuf = NULL; ++ uint32_t buf_size = 0; ++#ifndef __ECOS ++ size_t pointlen; ++ ++ if (c->mtd->point) { ++ ret = c->mtd->point (c->mtd, 0, c->mtd->size, &pointlen, &flashbuf); ++ if (!ret && pointlen < c->mtd->size) { ++ /* Don't muck about if it won't let us point to the whole flash */ ++ D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen)); ++ c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size); ++ flashbuf = NULL; ++ } ++ if (ret) ++ D1(printk(KERN_DEBUG "MTD point failed %d\n", ret)); ++ } ++#endif ++ if (!flashbuf) { ++ /* For NAND it's quicker to read a whole eraseblock at a time, ++ apparently */ ++ if (jffs2_cleanmarker_oob(c)) ++ buf_size = c->sector_size; ++ else ++ buf_size = PAGE_SIZE; ++ ++ D1(printk(KERN_DEBUG "Allocating readbuf of %d bytes\n", buf_size)); ++ flashbuf = kmalloc(buf_size, GFP_KERNEL); ++ if (!flashbuf) ++ return -ENOMEM; + } ++ + for (i=0; inr_blocks; i++) { + struct jffs2_eraseblock *jeb = &c->blocks[i]; + +- ret = jffs2_scan_eraseblock(c, jeb); ++ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), buf_size); ++ + if (ret < 0) +- return ret; ++ goto out; + + ACCT_PARANOIA_CHECK(jeb); + + /* Now decide which list to put it on */ +- if (ret == 1) { ++ switch(ret) { ++ case BLK_STATE_ALLFF: + /* + * Empty block. Since we can't be sure it + * was entirely erased, we just queue it for erase +@@ -103,10 +130,12 @@ + * is complete. Meanwhile we still count it as empty + * for later checks. + */ +- list_add(&jeb->list, &c->erase_pending_list); + empty_blocks++; ++ list_add(&jeb->list, &c->erase_pending_list); + c->nr_erasing_blocks++; +- } else if (jeb->used_size == PAD(sizeof(struct jffs2_unknown_node)) && !jeb->first_node->next_in_ino) { ++ break; ++ ++ case BLK_STATE_CLEANMARKER: + /* Only a CLEANMARKER node is valid */ + if (!jeb->dirty_size) { + /* It's actually free */ +@@ -118,74 +147,227 @@ + list_add(&jeb->list, &c->erase_pending_list); + c->nr_erasing_blocks++; + } +- } else if (jeb->used_size > c->sector_size - (2*sizeof(struct jffs2_raw_inode))) { ++ break; ++ ++ case BLK_STATE_CLEAN: + /* Full (or almost full) of clean data. Clean list */ + list_add(&jeb->list, &c->clean_list); +- } else if (jeb->used_size) { ++ break; ++ ++ case BLK_STATE_PARTDIRTY: + /* Some data, but not full. Dirty list. */ + /* Except that we want to remember the block with most free space, + and stick it in the 'nextblock' position to start writing to it. + Later when we do snapshots, this must be the most recent block, + not the one with most free space. + */ +- if (jeb->free_size > 2*sizeof(struct jffs2_raw_inode) && ++ if (jeb->free_size > min_free(c) && + (!c->nextblock || c->nextblock->free_size < jeb->free_size)) { + /* Better candidate for the next writes to go to */ +- if (c->nextblock) ++ if (c->nextblock) { ++ c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size; ++ c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size; ++ c->free_size -= c->nextblock->free_size; ++ c->wasted_size -= c->nextblock->wasted_size; ++ c->nextblock->free_size = c->nextblock->wasted_size = 0; ++ if (VERYDIRTY(c, c->nextblock->dirty_size)) { ++ list_add(&c->nextblock->list, &c->very_dirty_list); ++ } else { + list_add(&c->nextblock->list, &c->dirty_list); ++ } ++ } + c->nextblock = jeb; + } else { ++ jeb->dirty_size += jeb->free_size + jeb->wasted_size; ++ c->dirty_size += jeb->free_size + jeb->wasted_size; ++ c->free_size -= jeb->free_size; ++ c->wasted_size -= jeb->wasted_size; ++ jeb->free_size = jeb->wasted_size = 0; ++ if (VERYDIRTY(c, jeb->dirty_size)) { ++ list_add(&jeb->list, &c->very_dirty_list); ++ } else { + list_add(&jeb->list, &c->dirty_list); + } +- } else { ++ } ++ break; ++ ++ case BLK_STATE_ALLDIRTY: + /* Nothing valid - not even a clean marker. Needs erasing. */ + /* For now we just put it on the erasing list. We'll start the erases later */ +- printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset); ++ D1(printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset)); + list_add(&jeb->list, &c->erase_pending_list); + c->nr_erasing_blocks++; ++ break; ++ ++ case BLK_STATE_BADBLOCK: ++ D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset)); ++ list_add(&jeb->list, &c->bad_list); ++ c->bad_size += c->sector_size; ++ c->free_size -= c->sector_size; ++ bad_blocks++; ++ break; ++ default: ++ printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n"); ++ BUG(); + } + } +- /* Rotate the lists by some number to ensure wear levelling */ +- jffs2_rotate_lists(c); + ++ /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */ ++ if (c->nextblock && (c->nextblock->dirty_size)) { ++ c->nextblock->wasted_size += c->nextblock->dirty_size; ++ c->wasted_size += c->nextblock->dirty_size; ++ c->dirty_size -= c->nextblock->dirty_size; ++ c->nextblock->dirty_size = 0; ++ } ++#ifdef CONFIG_JFFS2_FS_NAND ++ if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) { ++ /* If we're going to start writing into a block which already ++ contains data, and the end of the data isn't page-aligned, ++ skip a little and align it. */ ++ ++ uint32_t skip = c->nextblock->free_size & (c->wbuf_pagesize-1); ++ ++ D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n", ++ skip)); ++ c->nextblock->wasted_size += skip; ++ c->wasted_size += skip; ++ ++ c->nextblock->free_size -= skip; ++ c->free_size -= skip; ++ } ++#endif + if (c->nr_erasing_blocks) { +- if (!c->used_size && empty_blocks != c->nr_blocks) { ++ if ( !c->used_size && ((empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) { + printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n"); +- return -EIO; ++ printk(KERN_NOTICE "empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",empty_blocks,bad_blocks,c->nr_blocks); ++ ret = -EIO; ++ goto out; + } + jffs2_erase_pending_trigger(c); + } ++ ret = 0; ++ out: ++ if (buf_size) ++ kfree(flashbuf); ++#ifndef __ECOS ++ else ++ c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size); ++#endif ++ return ret; ++} ++ ++static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf, ++ uint32_t ofs, uint32_t len) ++{ ++ int ret; ++ size_t retlen; ++ ++ ret = jffs2_flash_read(c, ofs, len, &retlen, buf); ++ if (ret) { ++ D1(printk(KERN_WARNING "mtd->read(0x%x bytes from 0x%x) returned %d\n", len, ofs, ret)); ++ return ret; ++ } ++ if (retlen < len) { ++ D1(printk(KERN_WARNING "Read at 0x%x gave only 0x%zx bytes\n", ofs, retlen)); ++ return -EIO; ++ } ++ D2(printk(KERN_DEBUG "Read 0x%x bytes from 0x%08x into buf\n", len, ofs)); ++ D2(printk(KERN_DEBUG "000: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", ++ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15])); + return 0; + } + +-static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) { +- struct jffs2_unknown_node node; +- __u32 ofs, prevofs; +- __u32 hdr_crc, nodetype; ++static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, ++ unsigned char *buf, uint32_t buf_size) { ++ struct jffs2_unknown_node *node; ++ struct jffs2_unknown_node crcnode; ++ uint32_t ofs, prevofs; ++ uint32_t hdr_crc, buf_ofs, buf_len; + int err; + int noise = 0; ++ int wasempty = 0; ++ uint32_t empty_start = 0; ++#ifdef CONFIG_JFFS2_FS_NAND ++ int cleanmarkerfound = 0; ++#endif + + ofs = jeb->offset; + prevofs = jeb->offset - 1; + + D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs)); + +- err = jffs2_scan_empty(c, jeb, &ofs, &noise); +- if (err) return err; +- if (ofs == jeb->offset + c->sector_size) { ++#ifdef CONFIG_JFFS2_FS_NAND ++ if (jffs2_cleanmarker_oob(c)) { ++ int ret = jffs2_check_nand_cleanmarker(c, jeb); ++ D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret)); ++ /* Even if it's not found, we still scan to see ++ if the block is empty. We use this information ++ to decide whether to erase it or not. */ ++ switch (ret) { ++ case 0: cleanmarkerfound = 1; break; ++ case 1: break; ++ case 2: return BLK_STATE_BADBLOCK; ++ case 3: return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */ ++ default: return ret; ++ } ++ } ++#endif ++ buf_ofs = jeb->offset; ++ ++ if (!buf_size) { ++ buf_len = c->sector_size; ++ } else { ++ buf_len = EMPTY_SCAN_SIZE; ++ err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len); ++ if (err) ++ return err; ++ } ++ ++ /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ ++ ofs = 0; ++ ++ /* Scan only 4KiB of 0xFF before declaring it's empty */ ++ while(ofs < EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) ++ ofs += 4; ++ ++ if (ofs == EMPTY_SCAN_SIZE) { ++#ifdef CONFIG_JFFS2_FS_NAND ++ if (jffs2_cleanmarker_oob(c)) { ++ /* scan oob, take care of cleanmarker */ ++ int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound); ++ D2(printk(KERN_NOTICE "jffs2_check_oob_empty returned %d\n",ret)); ++ switch (ret) { ++ case 0: return cleanmarkerfound ? BLK_STATE_CLEANMARKER : BLK_STATE_ALLFF; ++ case 1: return BLK_STATE_ALLDIRTY; ++ case 2: return BLK_STATE_BADBLOCK; /* case 2/3 are paranoia checks */ ++ case 3: return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */ ++ default: return ret; ++ } ++ } ++#endif + D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset)); +- return 1; /* special return code */ ++ return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */ ++ } ++ if (ofs) { ++ D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset, ++ jeb->offset + ofs)); ++ DIRTY_SPACE(ofs); + } + ++ /* Now ofs is a complete physical flash offset as it always was... */ ++ ofs += jeb->offset; ++ + noise = 10; + + while(ofs < jeb->offset + c->sector_size) { +- ssize_t retlen; +- ACCT_PARANOIA_CHECK(jeb); ++ ++ D1(ACCT_PARANOIA_CHECK(jeb)); ++ ++ cond_resched(); + + if (ofs & 3) { + printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs); +- ofs = (ofs+3)&~3; ++ ofs = PAD(ofs); + continue; + } + if (ofs == prevofs) { +@@ -196,102 +378,173 @@ + } + prevofs = ofs; + +- if (jeb->offset + c->sector_size < ofs + sizeof(node)) { +- D1(printk(KERN_DEBUG "Fewer than %d bytes left to end of block. Not reading\n", sizeof(struct jffs2_unknown_node))); ++ if (jeb->offset + c->sector_size < ofs + sizeof(*node)) { ++ D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node), ++ jeb->offset, c->sector_size, ofs, sizeof(*node))); + DIRTY_SPACE((jeb->offset + c->sector_size)-ofs); + break; + } + +- err = c->mtd->read(c->mtd, ofs, sizeof(node), &retlen, (char *)&node); +- +- if (err) { +- D1(printk(KERN_WARNING "mtd->read(0x%x bytes from 0x%x) returned %d\n", sizeof(node), ofs, err)); ++ if (buf_ofs + buf_len < ofs + sizeof(*node)) { ++ buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); ++ D1(printk(KERN_DEBUG "Fewer than %zd bytes (node header) left to end of buf. Reading 0x%x at 0x%08x\n", ++ sizeof(struct jffs2_unknown_node), buf_len, ofs)); ++ err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); ++ if (err) + return err; ++ buf_ofs = ofs; + } +- if (retlen < sizeof(node)) { +- D1(printk(KERN_WARNING "Read at 0x%x gave only 0x%x bytes\n", ofs, retlen)); +- DIRTY_SPACE(retlen); +- ofs += retlen; +- continue; ++ ++ node = (struct jffs2_unknown_node *)&buf[ofs-buf_ofs]; ++ ++ if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) { ++ uint32_t inbuf_ofs = ofs - buf_ofs + 4; ++ uint32_t scanend; ++ ++ empty_start = ofs; ++ ofs += 4; ++ ++ /* If scanning empty space after only a cleanmarker, don't ++ bother scanning the whole block */ ++ if (unlikely(empty_start == jeb->offset + c->cleanmarker_size && ++ jeb->offset + EMPTY_SCAN_SIZE < buf_ofs + buf_len)) ++ scanend = jeb->offset + EMPTY_SCAN_SIZE - buf_ofs; ++ else ++ scanend = buf_len; ++ ++ D1(printk(KERN_DEBUG "Found empty flash at 0x%08x\n", ofs)); ++ while (inbuf_ofs < scanend) { ++ if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) ++ goto emptyends; ++ ++ inbuf_ofs+=4; ++ ofs += 4; + } ++ /* Ran off end. */ ++ D1(printk(KERN_DEBUG "Empty flash ends normally at 0x%08x\n", ofs)); + +- if (node.magic == JFFS2_EMPTY_BITMASK && node.nodetype == JFFS2_EMPTY_BITMASK) { +- D1(printk(KERN_DEBUG "Found empty flash at 0x%x\n", ofs)); +- err = jffs2_scan_empty(c, jeb, &ofs, &noise); +- if (err) return err; ++ if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && ++ c->cleanmarker_size && !jeb->first_node->next_in_ino && !jeb->dirty_size) ++ return BLK_STATE_CLEANMARKER; ++ wasempty = 1; ++ continue; ++ } else if (wasempty) { ++ emptyends: ++ printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n", empty_start, ofs); ++ DIRTY_SPACE(ofs-empty_start); ++ wasempty = 0; + continue; + } + +- if (ofs == jeb->offset && node.magic == KSAMTIB_CIGAM_2SFFJ) { ++ if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) { + printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs); + DIRTY_SPACE(4); + ofs += 4; + continue; + } +- if (node.magic == JFFS2_DIRTY_BITMASK) { +- D1(printk(KERN_DEBUG "Empty bitmask at 0x%08x\n", ofs)); ++ if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) { ++ D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs)); + DIRTY_SPACE(4); + ofs += 4; + continue; + } +- if (node.magic == JFFS2_OLD_MAGIC_BITMASK) { ++ if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) { + printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs); + printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n"); + DIRTY_SPACE(4); + ofs += 4; + continue; + } +- if (node.magic != JFFS2_MAGIC_BITMASK) { ++ if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) { + /* OK. We're out of possibilities. Whinge and move on */ +- noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", JFFS2_MAGIC_BITMASK, ofs, node.magic); ++ noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", ++ JFFS2_MAGIC_BITMASK, ofs, ++ je16_to_cpu(node->magic)); + DIRTY_SPACE(4); + ofs += 4; + continue; + } + /* We seem to have a node of sorts. Check the CRC */ +- nodetype = node.nodetype; +- node.nodetype |= JFFS2_NODE_ACCURATE; +- hdr_crc = crc32(0, &node, sizeof(node)-4); +- node.nodetype = nodetype; +- if (hdr_crc != node.hdr_crc) { ++ crcnode.magic = node->magic; ++ crcnode.nodetype = cpu_to_je16( je16_to_cpu(node->nodetype) | JFFS2_NODE_ACCURATE); ++ crcnode.totlen = node->totlen; ++ hdr_crc = crc32(0, &crcnode, sizeof(crcnode)-4); ++ ++ if (hdr_crc != je32_to_cpu(node->hdr_crc)) { + noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n", +- ofs, node.magic, node.nodetype, node.totlen, node.hdr_crc, hdr_crc); ++ ofs, je16_to_cpu(node->magic), ++ je16_to_cpu(node->nodetype), ++ je32_to_cpu(node->totlen), ++ je32_to_cpu(node->hdr_crc), ++ hdr_crc); + DIRTY_SPACE(4); + ofs += 4; + continue; + } + +- if (ofs + node.totlen > jeb->offset + c->sector_size) { ++ if (ofs + je32_to_cpu(node->totlen) > ++ jeb->offset + c->sector_size) { + /* Eep. Node goes over the end of the erase block. */ + printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n", +- ofs, node.totlen); ++ ofs, je32_to_cpu(node->totlen)); + printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n"); + DIRTY_SPACE(4); + ofs += 4; + continue; + } + +- switch(node.nodetype | JFFS2_NODE_ACCURATE) { ++ if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) { ++ /* Wheee. This is an obsoleted node */ ++ D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs)); ++ DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); ++ ofs += PAD(je32_to_cpu(node->totlen)); ++ continue; ++ } ++ ++ switch(je16_to_cpu(node->nodetype)) { + case JFFS2_NODETYPE_INODE: +- err = jffs2_scan_inode_node(c, jeb, &ofs); ++ if (buf_ofs + buf_len < ofs + sizeof(struct jffs2_raw_inode)) { ++ buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); ++ D1(printk(KERN_DEBUG "Fewer than %zd bytes (inode node) left to end of buf. Reading 0x%x at 0x%08x\n", ++ sizeof(struct jffs2_raw_inode), buf_len, ofs)); ++ err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); ++ if (err) ++ return err; ++ buf_ofs = ofs; ++ node = (void *)buf; ++ } ++ err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs); + if (err) return err; ++ ofs += PAD(je32_to_cpu(node->totlen)); + break; + + case JFFS2_NODETYPE_DIRENT: +- err = jffs2_scan_dirent_node(c, jeb, &ofs); ++ if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) { ++ buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); ++ D1(printk(KERN_DEBUG "Fewer than %d bytes (dirent node) left to end of buf. Reading 0x%x at 0x%08x\n", ++ je32_to_cpu(node->totlen), buf_len, ofs)); ++ err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); ++ if (err) ++ return err; ++ buf_ofs = ofs; ++ node = (void *)buf; ++ } ++ err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs); + if (err) return err; ++ ofs += PAD(je32_to_cpu(node->totlen)); + break; + + case JFFS2_NODETYPE_CLEANMARKER: +- if (node.totlen != sizeof(struct jffs2_unknown_node)) { ++ D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs)); ++ if (je32_to_cpu(node->totlen) != c->cleanmarker_size) { + printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n", +- ofs, node.totlen, sizeof(struct jffs2_unknown_node)); ++ ofs, je32_to_cpu(node->totlen), c->cleanmarker_size); + DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node))); ++ ofs += PAD(sizeof(struct jffs2_unknown_node)); + } else if (jeb->first_node) { + printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset); + DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node))); + ofs += PAD(sizeof(struct jffs2_unknown_node)); +- continue; + } else { + struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref(); + if (!marker_ref) { +@@ -300,98 +553,80 @@ + } + marker_ref->next_in_ino = NULL; + marker_ref->next_phys = NULL; +- marker_ref->flash_offset = ofs; +- marker_ref->totlen = sizeof(struct jffs2_unknown_node); ++ marker_ref->flash_offset = ofs | REF_NORMAL; ++ marker_ref->__totlen = c->cleanmarker_size; + jeb->first_node = jeb->last_node = marker_ref; + +- USED_SPACE(PAD(sizeof(struct jffs2_unknown_node))); ++ USED_SPACE(PAD(c->cleanmarker_size)); ++ ofs += PAD(c->cleanmarker_size); + } +- ofs += PAD(sizeof(struct jffs2_unknown_node)); ++ break; ++ ++ case JFFS2_NODETYPE_PADDING: ++ DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); ++ ofs += PAD(je32_to_cpu(node->totlen)); + break; + + default: +- switch (node.nodetype & JFFS2_COMPAT_MASK) { ++ switch (je16_to_cpu(node->nodetype) & JFFS2_COMPAT_MASK) { + case JFFS2_FEATURE_ROCOMPAT: +- printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs); ++ printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs); + c->flags |= JFFS2_SB_FLAG_RO; +- if (!(OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)) ++ if (!(jffs2_is_readonly(c))) + return -EROFS; +- DIRTY_SPACE(PAD(node.totlen)); +- ofs += PAD(node.totlen); +- continue; ++ DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); ++ ofs += PAD(je32_to_cpu(node->totlen)); ++ break; + + case JFFS2_FEATURE_INCOMPAT: +- printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs); ++ printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs); + return -EINVAL; + + case JFFS2_FEATURE_RWCOMPAT_DELETE: +- printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs); +- DIRTY_SPACE(PAD(node.totlen)); +- ofs += PAD(node.totlen); ++ D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); ++ DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); ++ ofs += PAD(je32_to_cpu(node->totlen)); + break; + + case JFFS2_FEATURE_RWCOMPAT_COPY: +- printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs); +- USED_SPACE(PAD(node.totlen)); +- ofs += PAD(node.totlen); ++ D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); ++ USED_SPACE(PAD(je32_to_cpu(node->totlen))); ++ ofs += PAD(je32_to_cpu(node->totlen)); + break; + } + } + } +- D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, used 0x%08x\n", jeb->offset, +- jeb->free_size, jeb->dirty_size, jeb->used_size)); +- return 0; +-} + +-/* We're pointing at the first empty word on the flash. Scan and account for the whole dirty region */ +-static int jffs2_scan_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *startofs, int *noise) +-{ +- __u32 *buf; +- __u32 scanlen = (jeb->offset + c->sector_size) - *startofs; +- __u32 curofs = *startofs; +- +- buf = kmalloc(min((__u32)PAGE_SIZE, scanlen), GFP_KERNEL); +- if (!buf) { +- printk(KERN_WARNING "Scan buffer allocation failed\n"); +- return -ENOMEM; +- } +- while(scanlen) { +- ssize_t retlen; +- int ret, i; +- +- ret = c->mtd->read(c->mtd, curofs, min((__u32)PAGE_SIZE, scanlen), &retlen, (char *)buf); +- if(ret) { +- D1(printk(KERN_WARNING "jffs2_scan_empty(): Read 0x%x bytes at 0x%08x returned %d\n", min((__u32)PAGE_SIZE, scanlen), curofs, ret)); +- kfree(buf); +- return ret; +- } +- if (retlen < 4) { +- D1(printk(KERN_WARNING "Eep. too few bytes read in scan_empty()\n")); +- kfree(buf); +- return -EIO; +- } +- for (i=0; i<(retlen / 4); i++) { +- if (buf[i] != 0xffffffff) { +- curofs += i*4; +- +- noisy_printk(noise, "jffs2_scan_empty(): Empty block at 0x%08x ends at 0x%08x (with 0x%08x)! Marking dirty\n", *startofs, curofs, buf[i]); +- DIRTY_SPACE(curofs - (*startofs)); +- *startofs = curofs; +- kfree(buf); +- return 0; +- } +- } +- scanlen -= retlen&~3; +- curofs += retlen&~3; +- } + +- D1(printk(KERN_DEBUG "Empty flash detected from 0x%08x to 0x%08x\n", *startofs, curofs)); +- kfree(buf); +- *startofs = curofs; +- return 0; ++ D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset, ++ jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size)); ++ ++ /* mark_node_obsolete can add to wasted !! */ ++ if (jeb->wasted_size) { ++ jeb->dirty_size += jeb->wasted_size; ++ c->dirty_size += jeb->wasted_size; ++ c->wasted_size -= jeb->wasted_size; ++ jeb->wasted_size = 0; ++ } ++ ++ if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size ++ && (!jeb->first_node || jeb->first_node->next_in_ino) ) ++ return BLK_STATE_CLEANMARKER; ++ ++ /* move blocks with max 4 byte dirty space to cleanlist */ ++ else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) { ++ c->dirty_size -= jeb->dirty_size; ++ c->wasted_size += jeb->dirty_size; ++ jeb->wasted_size += jeb->dirty_size; ++ jeb->dirty_size = 0; ++ return BLK_STATE_CLEAN; ++ } else if (jeb->used_size || jeb->unchecked_size) ++ return BLK_STATE_PARTDIRTY; ++ else ++ return BLK_STATE_ALLDIRTY; + } + +-static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, __u32 ino) ++static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino) + { + struct jffs2_inode_cache *ic; + +@@ -399,137 +634,77 @@ + if (ic) + return ic; + ++ if (ino > c->highest_ino) ++ c->highest_ino = ino; ++ + ic = jffs2_alloc_inode_cache(); + if (!ic) { + printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of inode cache failed\n"); + return NULL; + } + memset(ic, 0, sizeof(*ic)); +- ic->scan = kmalloc(sizeof(struct jffs2_scan_info), GFP_KERNEL); +- if (!ic->scan) { +- printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of scan info for inode cache failed\n"); +- jffs2_free_inode_cache(ic); +- return NULL; +- } +- memset(ic->scan, 0, sizeof(*ic->scan)); ++ + ic->ino = ino; + ic->nodes = (void *)ic; + jffs2_add_ino_cache(c, ic); + if (ino == 1) +- ic->nlink=1; ++ ic->nlink = 1; + return ic; + } + +-static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs) ++static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, ++ struct jffs2_raw_inode *ri, uint32_t ofs) + { + struct jffs2_raw_node_ref *raw; +- struct jffs2_full_dnode *fn; +- struct jffs2_tmp_dnode_info *tn, **tn_list; + struct jffs2_inode_cache *ic; +- struct jffs2_raw_inode ri; +- __u32 crc; +- __u16 oldnodetype; +- int ret; +- ssize_t retlen; +- +- D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", *ofs)); +- +- ret = c->mtd->read(c->mtd, *ofs, sizeof(ri), &retlen, (char *)&ri); +- if (ret) { +- printk(KERN_NOTICE "jffs2_scan_inode_node(): Read error at 0x%08x: %d\n", *ofs, ret); +- return ret; +- } +- if (retlen != sizeof(ri)) { +- printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n", +- retlen, *ofs, sizeof(ri)); +- return -EIO; +- } ++ uint32_t ino = je32_to_cpu(ri->ino); + +- /* We sort of assume that the node was accurate when it was +- first written to the medium :) */ +- oldnodetype = ri.nodetype; +- ri.nodetype |= JFFS2_NODE_ACCURATE; +- crc = crc32(0, &ri, sizeof(ri)-8); +- ri.nodetype = oldnodetype; ++ D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs)); + +- if(crc != ri.node_crc) { +- printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", +- *ofs, ri.node_crc, crc); +- /* FIXME: Why do we believe totlen? */ +- DIRTY_SPACE(4); +- *ofs += 4; +- return 0; +- } +- /* There was a bug where we wrote hole nodes out with csize/dsize +- swapped. Deal with it */ +- if (ri.compr == JFFS2_COMPR_ZERO && !ri.dsize && ri.csize) { +- ri.dsize = ri.csize; +- ri.csize = 0; +- } ++ /* We do very little here now. Just check the ino# to which we should attribute ++ this node; we can do all the CRC checking etc. later. There's a tradeoff here -- ++ we used to scan the flash once only, reading everything we want from it into ++ memory, then building all our in-core data structures and freeing the extra ++ information. Now we allow the first part of the mount to complete a lot quicker, ++ but we have to go _back_ to the flash in order to finish the CRC checking, etc. ++ Which means that the _full_ amount of time to get to proper write mode with GC ++ operational may actually be _longer_ than before. Sucks to be me. */ + +- if (ri.csize) { +- /* Check data CRC too */ +- unsigned char *dbuf; +- __u32 crc; +- +- dbuf = kmalloc(PAGE_CACHE_SIZE, GFP_KERNEL); +- if (!dbuf) { +- printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of temporary data buffer for CRC check failed\n"); +- return -ENOMEM; +- } +- ret = c->mtd->read(c->mtd, *ofs+sizeof(ri), ri.csize, &retlen, dbuf); +- if (ret) { +- printk(KERN_NOTICE "jffs2_scan_inode_node(): Read error at 0x%08x: %d\n", *ofs+sizeof(ri), ret); +- kfree(dbuf); +- return ret; +- } +- if (retlen != ri.csize) { +- printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n", +- retlen, *ofs+ sizeof(ri), ri.csize); +- kfree(dbuf); +- return -EIO; +- } +- crc = crc32(0, dbuf, ri.csize); +- kfree(dbuf); +- if (crc != ri.data_crc) { +- printk(KERN_NOTICE "jffs2_scan_inode_node(): Data CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", +- *ofs, ri.data_crc, crc); +- DIRTY_SPACE(PAD(ri.totlen)); +- *ofs += PAD(ri.totlen); +- return 0; +- } +- } +- +- /* Wheee. It worked */ + raw = jffs2_alloc_raw_node_ref(); + if (!raw) { + printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of node reference failed\n"); + return -ENOMEM; + } +- tn = jffs2_alloc_tmp_dnode_info(); +- if (!tn) { +- jffs2_free_raw_node_ref(raw); +- return -ENOMEM; +- } +- fn = jffs2_alloc_full_dnode(); +- if (!fn) { +- jffs2_free_tmp_dnode_info(tn); ++ ++ ic = jffs2_get_ino_cache(c, ino); ++ if (!ic) { ++ /* Inocache get failed. Either we read a bogus ino# or it's just genuinely the ++ first node we found for this inode. Do a CRC check to protect against the former ++ case */ ++ uint32_t crc = crc32(0, ri, sizeof(*ri)-8); ++ ++ if (crc != je32_to_cpu(ri->node_crc)) { ++ printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", ++ ofs, je32_to_cpu(ri->node_crc), crc); ++ /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ ++ DIRTY_SPACE(PAD(je32_to_cpu(ri->totlen))); + jffs2_free_raw_node_ref(raw); +- return -ENOMEM; ++ return 0; + } +- ic = jffs2_scan_make_ino_cache(c, ri.ino); ++ ic = jffs2_scan_make_ino_cache(c, ino); + if (!ic) { +- jffs2_free_full_dnode(fn); +- jffs2_free_tmp_dnode_info(tn); + jffs2_free_raw_node_ref(raw); + return -ENOMEM; + } ++ } + +- /* Build the data structures and file them for later */ +- raw->flash_offset = *ofs; +- raw->totlen = PAD(ri.totlen); ++ /* Wheee. It worked */ ++ ++ raw->flash_offset = ofs | REF_UNCHECKED; ++ raw->__totlen = PAD(je32_to_cpu(ri->totlen)); + raw->next_phys = NULL; + raw->next_in_ino = ic->nodes; ++ + ic->nodes = raw; + if (!jeb->first_node) + jeb->first_node = raw; +@@ -538,134 +713,56 @@ + jeb->last_node = raw; + + D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n", +- ri.ino, ri.version, ri.offset, ri.offset+ri.dsize)); +- +- pseudo_random += ri.version; +- +- for (tn_list = &ic->scan->tmpnodes; *tn_list; tn_list = &((*tn_list)->next)) { +- if ((*tn_list)->version < ri.version) +- continue; +- if ((*tn_list)->version > ri.version) +- break; +- /* Wheee. We've found another instance of the same version number. +- We should obsolete one of them. +- */ +- D1(printk(KERN_DEBUG "Duplicate version %d found in ino #%u. Previous one is at 0x%08x\n", ri.version, ic->ino, (*tn_list)->fn->raw->flash_offset &~3)); +- if (!jeb->used_size) { +- D1(printk(KERN_DEBUG "No valid nodes yet found in this eraseblock 0x%08x, so obsoleting the new instance at 0x%08x\n", +- jeb->offset, raw->flash_offset & ~3)); +- ri.nodetype &= ~JFFS2_NODE_ACCURATE; +- /* Perhaps we could also mark it as such on the medium. Maybe later */ +- } +- break; +- } +- +- if (ri.nodetype & JFFS2_NODE_ACCURATE) { +- memset(fn,0,sizeof(*fn)); +- +- fn->ofs = ri.offset; +- fn->size = ri.dsize; +- fn->frags = 0; +- fn->raw = raw; +- +- tn->next = NULL; +- tn->fn = fn; +- tn->version = ri.version; ++ je32_to_cpu(ri->ino), je32_to_cpu(ri->version), ++ je32_to_cpu(ri->offset), ++ je32_to_cpu(ri->offset)+je32_to_cpu(ri->dsize))); + +- USED_SPACE(PAD(ri.totlen)); +- jffs2_add_tn_to_list(tn, &ic->scan->tmpnodes); +- /* Make sure the one we just added is the _last_ in the list +- with this version number, so the older ones get obsoleted */ +- while (tn->next && tn->next->version == tn->version) { ++ pseudo_random += je32_to_cpu(ri->version); + +- D1(printk(KERN_DEBUG "Shifting new node at 0x%08x after other node at 0x%08x for version %d in list\n", +- fn->raw->flash_offset&~3, tn->next->fn->raw->flash_offset &~3, ri.version)); +- +- if(tn->fn != fn) +- BUG(); +- tn->fn = tn->next->fn; +- tn->next->fn = fn; +- tn = tn->next; +- } +- } else { +- jffs2_free_full_dnode(fn); +- jffs2_free_tmp_dnode_info(tn); +- raw->flash_offset |= 1; +- DIRTY_SPACE(PAD(ri.totlen)); +- } +- *ofs += PAD(ri.totlen); ++ UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen))); + return 0; + } + +-static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs) ++static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, ++ struct jffs2_raw_dirent *rd, uint32_t ofs) + { + struct jffs2_raw_node_ref *raw; + struct jffs2_full_dirent *fd; + struct jffs2_inode_cache *ic; +- struct jffs2_raw_dirent rd; +- __u16 oldnodetype; +- int ret; +- __u32 crc; +- ssize_t retlen; +- +- D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", *ofs)); ++ uint32_t crc; + +- ret = c->mtd->read(c->mtd, *ofs, sizeof(rd), &retlen, (char *)&rd); +- if (ret) { +- printk(KERN_NOTICE "jffs2_scan_dirent_node(): Read error at 0x%08x: %d\n", *ofs, ret); +- return ret; +- } +- if (retlen != sizeof(rd)) { +- printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n", +- retlen, *ofs, sizeof(rd)); +- return -EIO; +- } ++ D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", ofs)); + +- /* We sort of assume that the node was accurate when it was +- first written to the medium :) */ +- oldnodetype = rd.nodetype; +- rd.nodetype |= JFFS2_NODE_ACCURATE; +- crc = crc32(0, &rd, sizeof(rd)-8); +- rd.nodetype = oldnodetype; ++ /* We don't get here unless the node is still valid, so we don't have to ++ mask in the ACCURATE bit any more. */ ++ crc = crc32(0, rd, sizeof(*rd)-8); + +- if (crc != rd.node_crc) { ++ if (crc != je32_to_cpu(rd->node_crc)) { + printk(KERN_NOTICE "jffs2_scan_dirent_node(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", +- *ofs, rd.node_crc, crc); +- /* FIXME: Why do we believe totlen? */ +- DIRTY_SPACE(4); +- *ofs += 4; ++ ofs, je32_to_cpu(rd->node_crc), crc); ++ /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ ++ DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen))); + return 0; + } + +- pseudo_random += rd.version; ++ pseudo_random += je32_to_cpu(rd->version); + +- fd = jffs2_alloc_full_dirent(rd.nsize+1); ++ fd = jffs2_alloc_full_dirent(rd->nsize+1); + if (!fd) { + return -ENOMEM; +-} +- ret = c->mtd->read(c->mtd, *ofs + sizeof(rd), rd.nsize, &retlen, &fd->name[0]); +- if (ret) { +- jffs2_free_full_dirent(fd); +- printk(KERN_NOTICE "jffs2_scan_dirent_node(): Read error at 0x%08x: %d\n", +- *ofs + sizeof(rd), ret); +- return ret; +- } +- if (retlen != rd.nsize) { +- jffs2_free_full_dirent(fd); +- printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n", +- retlen, *ofs + sizeof(rd), rd.nsize); +- return -EIO; + } +- crc = crc32(0, fd->name, rd.nsize); +- if (crc != rd.name_crc) { ++ memcpy(&fd->name, rd->name, rd->nsize); ++ fd->name[rd->nsize] = 0; ++ ++ crc = crc32(0, fd->name, rd->nsize); ++ if (crc != je32_to_cpu(rd->name_crc)) { + printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", +- *ofs, rd.name_crc, crc); +- fd->name[rd.nsize]=0; +- D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, rd.ino)); ++ ofs, je32_to_cpu(rd->name_crc), crc); ++ D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, je32_to_cpu(rd->ino))); + jffs2_free_full_dirent(fd); + /* FIXME: Why do we believe totlen? */ +- DIRTY_SPACE(PAD(rd.totlen)); +- *ofs += PAD(rd.totlen); ++ /* We believe totlen because the CRC on the node _header_ was OK, just the name failed. */ ++ DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen))); + return 0; + } + raw = jffs2_alloc_raw_node_ref(); +@@ -674,15 +771,15 @@ + printk(KERN_NOTICE "jffs2_scan_dirent_node(): allocation of node reference failed\n"); + return -ENOMEM; + } +- ic = jffs2_scan_make_ino_cache(c, rd.pino); ++ ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(rd->pino)); + if (!ic) { + jffs2_free_full_dirent(fd); + jffs2_free_raw_node_ref(raw); + return -ENOMEM; + } + +- raw->totlen = PAD(rd.totlen); +- raw->flash_offset = *ofs; ++ raw->__totlen = PAD(je32_to_cpu(rd->totlen)); ++ raw->flash_offset = ofs | REF_PRISTINE; + raw->next_phys = NULL; + raw->next_in_ino = ic->nodes; + ic->nodes = raw; +@@ -692,24 +789,15 @@ + jeb->last_node->next_phys = raw; + jeb->last_node = raw; + +- if (rd.nodetype & JFFS2_NODE_ACCURATE) { + fd->raw = raw; + fd->next = NULL; +- fd->version = rd.version; +- fd->ino = rd.ino; +- fd->name[rd.nsize]=0; +- fd->nhash = full_name_hash(fd->name, rd.nsize); +- fd->type = rd.type; +- +- USED_SPACE(PAD(rd.totlen)); +- jffs2_add_fd_to_list(c, fd, &ic->scan->dents); +- } else { +- raw->flash_offset |= 1; +- jffs2_free_full_dirent(fd); ++ fd->version = je32_to_cpu(rd->version); ++ fd->ino = je32_to_cpu(rd->ino); ++ fd->nhash = full_name_hash(fd->name, rd->nsize); ++ fd->type = rd->type; ++ USED_SPACE(PAD(je32_to_cpu(rd->totlen))); ++ jffs2_add_fd_to_list(c, fd, &ic->scan_dents); + +- DIRTY_SPACE(PAD(rd.totlen)); +- } +- *ofs += PAD(rd.totlen); + return 0; + } + +@@ -731,26 +819,90 @@ + struct list_head *n = head->next; + + list_del(head); +- while(count--) ++ while(count--) { + n = n->next; ++ } + list_add(head, n); + } + +-static void jffs2_rotate_lists(struct jffs2_sb_info *c) ++void jffs2_rotate_lists(struct jffs2_sb_info *c) + { + uint32_t x; ++ uint32_t rotateby; + + x = count_list(&c->clean_list); +- if (x) +- rotate_list((&c->clean_list), pseudo_random % x); ++ if (x) { ++ rotateby = pseudo_random % x; ++ D1(printk(KERN_DEBUG "Rotating clean_list by %d\n", rotateby)); ++ ++ rotate_list((&c->clean_list), rotateby); ++ ++ D1(printk(KERN_DEBUG "Erase block at front of clean_list is at %08x\n", ++ list_entry(c->clean_list.next, struct jffs2_eraseblock, list)->offset)); ++ } else { ++ D1(printk(KERN_DEBUG "Not rotating empty clean_list\n")); ++ } ++ ++ x = count_list(&c->very_dirty_list); ++ if (x) { ++ rotateby = pseudo_random % x; ++ D1(printk(KERN_DEBUG "Rotating very_dirty_list by %d\n", rotateby)); ++ ++ rotate_list((&c->very_dirty_list), rotateby); ++ ++ D1(printk(KERN_DEBUG "Erase block at front of very_dirty_list is at %08x\n", ++ list_entry(c->very_dirty_list.next, struct jffs2_eraseblock, list)->offset)); ++ } else { ++ D1(printk(KERN_DEBUG "Not rotating empty very_dirty_list\n")); ++ } + + x = count_list(&c->dirty_list); +- if (x) +- rotate_list((&c->dirty_list), pseudo_random % x); ++ if (x) { ++ rotateby = pseudo_random % x; ++ D1(printk(KERN_DEBUG "Rotating dirty_list by %d\n", rotateby)); ++ ++ rotate_list((&c->dirty_list), rotateby); ++ ++ D1(printk(KERN_DEBUG "Erase block at front of dirty_list is at %08x\n", ++ list_entry(c->dirty_list.next, struct jffs2_eraseblock, list)->offset)); ++ } else { ++ D1(printk(KERN_DEBUG "Not rotating empty dirty_list\n")); ++ } ++ ++ x = count_list(&c->erasable_list); ++ if (x) { ++ rotateby = pseudo_random % x; ++ D1(printk(KERN_DEBUG "Rotating erasable_list by %d\n", rotateby)); + +- if (c->nr_erasing_blocks) +- rotate_list((&c->erase_pending_list), pseudo_random % c->nr_erasing_blocks); ++ rotate_list((&c->erasable_list), rotateby); + +- if (c->nr_free_blocks) /* Not that it should ever be zero */ +- rotate_list((&c->free_list), pseudo_random % c->nr_free_blocks); ++ D1(printk(KERN_DEBUG "Erase block at front of erasable_list is at %08x\n", ++ list_entry(c->erasable_list.next, struct jffs2_eraseblock, list)->offset)); ++ } else { ++ D1(printk(KERN_DEBUG "Not rotating empty erasable_list\n")); ++ } ++ ++ if (c->nr_erasing_blocks) { ++ rotateby = pseudo_random % c->nr_erasing_blocks; ++ D1(printk(KERN_DEBUG "Rotating erase_pending_list by %d\n", rotateby)); ++ ++ rotate_list((&c->erase_pending_list), rotateby); ++ ++ D1(printk(KERN_DEBUG "Erase block at front of erase_pending_list is at %08x\n", ++ list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list)->offset)); ++ } else { ++ D1(printk(KERN_DEBUG "Not rotating empty erase_pending_list\n")); ++ } ++ ++ if (c->nr_free_blocks) { ++ rotateby = pseudo_random % c->nr_free_blocks; ++ D1(printk(KERN_DEBUG "Rotating free_list by %d\n", rotateby)); ++ ++ rotate_list((&c->free_list), rotateby); ++ ++ D1(printk(KERN_DEBUG "Erase block at front of free_list is at %08x\n", ++ list_entry(c->free_list.next, struct jffs2_eraseblock, list)->offset)); ++ } else { ++ D1(printk(KERN_DEBUG "Not rotating empty free_list\n")); ++ } + } +diff -Nurb linux-mips-2.4.27/fs/jffs2/super-v24.c linux/fs/jffs2/super-v24.c +--- linux-mips-2.4.27/fs/jffs2/super-v24.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/fs/jffs2/super-v24.c 2004-11-19 10:25:12.126165288 +0100 +@@ -0,0 +1,167 @@ ++/* ++ * JFFS2 -- Journalling Flash File System, Version 2. ++ * ++ * Copyright (C) 2001-2003 Red Hat, Inc. ++ * ++ * Created by David Woodhouse ++ * ++ * For licensing information, see the file 'LICENCE' in this directory. ++ * ++ * $Id: super-v24.c,v 1.75 2003/10/06 12:52:29 dwmw2 Exp $ ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "nodelist.h" ++ ++#ifndef MTD_BLOCK_MAJOR ++#define MTD_BLOCK_MAJOR 31 ++#endif ++ ++static void jffs2_put_super (struct super_block *); ++ ++static struct super_operations jffs2_super_operations = ++{ ++ .read_inode = jffs2_read_inode, ++ .put_super = jffs2_put_super, ++ .write_super = jffs2_write_super, ++ .statfs = jffs2_statfs, ++ .remount_fs = jffs2_remount_fs, ++ .clear_inode = jffs2_clear_inode, ++ .dirty_inode = jffs2_dirty_inode, ++}; ++ ++ ++static struct super_block *jffs2_read_super(struct super_block *sb, void *data, int silent) ++{ ++ struct jffs2_sb_info *c; ++ int ret; ++ ++ D1(printk(KERN_DEBUG "jffs2: read_super for device %s\n", kdevname(sb->s_dev))); ++ ++ if (major(sb->s_dev) != MTD_BLOCK_MAJOR) { ++ if (!silent) ++ printk(KERN_DEBUG "jffs2: attempt to mount non-MTD device %s\n", kdevname(sb->s_dev)); ++ return NULL; ++ } ++ ++ c = JFFS2_SB_INFO(sb); ++ memset(c, 0, sizeof(*c)); ++ ++ sb->s_op = &jffs2_super_operations; ++ ++ c->mtd = get_mtd_device(NULL, minor(sb->s_dev)); ++ if (!c->mtd) { ++ D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", minor(sb->s_dev))); ++ return NULL; ++ } ++ ++ ret = jffs2_do_fill_super(sb, data, silent); ++ if (ret) { ++ put_mtd_device(c->mtd); ++ return NULL; ++ } ++ ++ return sb; ++} ++ ++static void jffs2_put_super (struct super_block *sb) ++{ ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); ++ ++ D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n")); ++ ++ ++ if (!(sb->s_flags & MS_RDONLY)) ++ jffs2_stop_garbage_collect_thread(c); ++ down(&c->alloc_sem); ++ jffs2_flush_wbuf_pad(c); ++ up(&c->alloc_sem); ++ jffs2_free_ino_caches(c); ++ jffs2_free_raw_node_refs(c); ++ kfree(c->blocks); ++ jffs2_nand_flash_cleanup(c); ++ kfree(c->inocache_list); ++ if (c->mtd->sync) ++ c->mtd->sync(c->mtd); ++ put_mtd_device(c->mtd); ++ ++ D1(printk(KERN_DEBUG "jffs2_put_super returning\n")); ++} ++ ++static DECLARE_FSTYPE_DEV(jffs2_fs_type, "jffs2", jffs2_read_super); ++ ++static int __init init_jffs2_fs(void) ++{ ++ int ret; ++ ++ printk(KERN_INFO "JFFS2 version 2.2." ++#ifdef CONFIG_FS_JFFS2_NAND ++ " (NAND)" ++#endif ++ " (C) 2001-2003 Red Hat, Inc.\n"); ++ ++#ifdef JFFS2_OUT_OF_KERNEL ++ /* sanity checks. Could we do these at compile time? */ ++ if (sizeof(struct jffs2_sb_info) > sizeof (((struct super_block *)NULL)->u)) { ++ printk(KERN_ERR "JFFS2 error: struct jffs2_sb_info (%d bytes) doesn't fit in the super_block union (%d bytes)\n", ++ sizeof(struct jffs2_sb_info), sizeof (((struct super_block *)NULL)->u)); ++ return -EIO; ++ } ++ ++ if (sizeof(struct jffs2_inode_info) > sizeof (((struct inode *)NULL)->u)) { ++ printk(KERN_ERR "JFFS2 error: struct jffs2_inode_info (%d bytes) doesn't fit in the inode union (%d bytes)\n", ++ sizeof(struct jffs2_inode_info), sizeof (((struct inode *)NULL)->u)); ++ return -EIO; ++ } ++#endif ++ ret = jffs2_zlib_init(); ++ if (ret) { ++ printk(KERN_ERR "JFFS2 error: Failed to initialise zlib workspaces\n"); ++ goto out; ++ } ++ ret = jffs2_create_slab_caches(); ++ if (ret) { ++ printk(KERN_ERR "JFFS2 error: Failed to initialise slab caches\n"); ++ goto out_zlib; ++ } ++ ret = register_filesystem(&jffs2_fs_type); ++ if (ret) { ++ printk(KERN_ERR "JFFS2 error: Failed to register filesystem\n"); ++ goto out_slab; ++ } ++ return 0; ++ ++ out_slab: ++ jffs2_destroy_slab_caches(); ++ out_zlib: ++ jffs2_zlib_exit(); ++ out: ++ ++ return ret; ++} ++ ++static void __exit exit_jffs2_fs(void) ++{ ++ jffs2_destroy_slab_caches(); ++ jffs2_zlib_exit(); ++ unregister_filesystem(&jffs2_fs_type); ++} ++ ++module_init(init_jffs2_fs); ++module_exit(exit_jffs2_fs); ++ ++MODULE_DESCRIPTION("The Journalling Flash File System, v2"); ++MODULE_AUTHOR("Red Hat, Inc."); ++MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for ++ // the sake of this tag. It's Free Software. +diff -Nurb linux-mips-2.4.27/fs/jffs2/super.c linux/fs/jffs2/super.c +--- linux-mips-2.4.27/fs/jffs2/super.c 2003-01-11 18:53:17.000000000 +0100 ++++ linux/fs/jffs2/super.c 2004-11-19 10:25:12.127165136 +0100 +@@ -1,291 +1,257 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: super.c,v 1.48.2.3 2002/10/11 09:04:44 dwmw2 Exp $ ++ * $Id: super.c,v 1.90 2003/10/11 11:47:23 dwmw2 Exp $ + * + */ + + #include + #include + #include +-#include + #include + #include + #include + #include ++#include + #include + #include + #include +-#include ++#include ++#include + #include "nodelist.h" + +-#ifndef MTD_BLOCK_MAJOR +-#define MTD_BLOCK_MAJOR 31 +-#endif ++static void jffs2_put_super(struct super_block *); ++ ++static kmem_cache_t *jffs2_inode_cachep; ++ ++static struct inode *jffs2_alloc_inode(struct super_block *sb) ++{ ++ struct jffs2_inode_info *ei; ++ ei = (struct jffs2_inode_info *)kmem_cache_alloc(jffs2_inode_cachep, SLAB_KERNEL); ++ if (!ei) ++ return NULL; ++ return &ei->vfs_inode; ++} ++ ++static void jffs2_destroy_inode(struct inode *inode) ++{ ++ kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode)); ++} ++ ++static void jffs2_i_init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) ++{ ++ struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; + +-extern void jffs2_read_inode (struct inode *); +-void jffs2_put_super (struct super_block *); +-void jffs2_write_super (struct super_block *); +-static int jffs2_statfs (struct super_block *, struct statfs *); +-int jffs2_remount_fs (struct super_block *, int *, char *); +-extern void jffs2_clear_inode (struct inode *); ++ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == ++ SLAB_CTOR_CONSTRUCTOR) { ++ init_MUTEX_LOCKED(&ei->sem); ++ inode_init_once(&ei->vfs_inode); ++ } ++} + + static struct super_operations jffs2_super_operations = + { +- read_inode: jffs2_read_inode, +-// delete_inode: jffs2_delete_inode, +- put_super: jffs2_put_super, +- write_super: jffs2_write_super, +- statfs: jffs2_statfs, +- remount_fs: jffs2_remount_fs, +- clear_inode: jffs2_clear_inode ++ .alloc_inode = jffs2_alloc_inode, ++ .destroy_inode =jffs2_destroy_inode, ++ .read_inode = jffs2_read_inode, ++ .put_super = jffs2_put_super, ++ .write_super = jffs2_write_super, ++ .statfs = jffs2_statfs, ++ .remount_fs = jffs2_remount_fs, ++ .clear_inode = jffs2_clear_inode, ++ .dirty_inode = jffs2_dirty_inode, + }; + +-static int jffs2_statfs(struct super_block *sb, struct statfs *buf) ++static int jffs2_sb_compare(struct super_block *sb, void *data) + { ++ struct jffs2_sb_info *p = data; + struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); +- unsigned long avail; + +- buf->f_type = JFFS2_SUPER_MAGIC; +- buf->f_bsize = 1 << PAGE_SHIFT; +- buf->f_blocks = c->flash_size >> PAGE_SHIFT; +- buf->f_files = 0; +- buf->f_ffree = 0; +- buf->f_namelen = JFFS2_MAX_NAME_LEN; +- +- spin_lock_bh(&c->erase_completion_lock); +- +- avail = c->dirty_size + c->free_size; +- if (avail > c->sector_size * JFFS2_RESERVED_BLOCKS_WRITE) +- avail -= c->sector_size * JFFS2_RESERVED_BLOCKS_WRITE; +- else +- avail = 0; +- +- buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT; +- +-#if CONFIG_JFFS2_FS_DEBUG > 0 +- printk(KERN_DEBUG "STATFS:\n"); +- printk(KERN_DEBUG "flash_size: %08x\n", c->flash_size); +- printk(KERN_DEBUG "used_size: %08x\n", c->used_size); +- printk(KERN_DEBUG "dirty_size: %08x\n", c->dirty_size); +- printk(KERN_DEBUG "free_size: %08x\n", c->free_size); +- printk(KERN_DEBUG "erasing_size: %08x\n", c->erasing_size); +- printk(KERN_DEBUG "bad_size: %08x\n", c->bad_size); +- printk(KERN_DEBUG "sector_size: %08x\n", c->sector_size); +- +- if (c->nextblock) { +- printk(KERN_DEBUG "nextblock: 0x%08x\n", c->nextblock->offset); +- } else { +- printk(KERN_DEBUG "nextblock: NULL\n"); +- } +- if (c->gcblock) { +- printk(KERN_DEBUG "gcblock: 0x%08x\n", c->gcblock->offset); ++ /* The superblocks are considered to be equivalent if the underlying MTD ++ device is the same one */ ++ if (c->mtd == p->mtd) { ++ D1(printk(KERN_DEBUG "jffs2_sb_compare: match on device %d (\"%s\")\n", p->mtd->index, p->mtd->name)); ++ return 1; + } else { +- printk(KERN_DEBUG "gcblock: NULL\n"); ++ D1(printk(KERN_DEBUG "jffs2_sb_compare: No match, device %d (\"%s\"), device %d (\"%s\")\n", ++ c->mtd->index, c->mtd->name, p->mtd->index, p->mtd->name)); ++ return 0; + } +- if (list_empty(&c->clean_list)) { +- printk(KERN_DEBUG "clean_list: empty\n"); +- } else { +- struct list_head *this; ++} + +- list_for_each(this, &c->clean_list) { +- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); +- printk(KERN_DEBUG "clean_list: %08x\n", jeb->offset); +- } +- } +- if (list_empty(&c->dirty_list)) { +- printk(KERN_DEBUG "dirty_list: empty\n"); +- } else { +- struct list_head *this; ++static int jffs2_sb_set(struct super_block *sb, void *data) ++{ ++ struct jffs2_sb_info *p = data; + +- list_for_each(this, &c->dirty_list) { +- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); +- printk(KERN_DEBUG "dirty_list: %08x\n", jeb->offset); +- } +- } +- if (list_empty(&c->erasing_list)) { +- printk(KERN_DEBUG "erasing_list: empty\n"); +- } else { +- struct list_head *this; ++ /* For persistence of NFS exports etc. we use the same s_dev ++ each time we mount the device, don't just use an anonymous ++ device */ ++ sb->s_fs_info = p; ++ p->os_priv = sb; ++ sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, p->mtd->index); + +- list_for_each(this, &c->erasing_list) { +- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); +- printk(KERN_DEBUG "erasing_list: %08x\n", jeb->offset); +- } +- } +- if (list_empty(&c->erase_pending_list)) { +- printk(KERN_DEBUG "erase_pending_list: empty\n"); +- } else { +- struct list_head *this; ++ return 0; ++} + +- list_for_each(this, &c->erase_pending_list) { +- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); +- printk(KERN_DEBUG "erase_pending_list: %08x\n", jeb->offset); +- } +- } +- if (list_empty(&c->free_list)) { +- printk(KERN_DEBUG "free_list: empty\n"); +- } else { +- struct list_head *this; ++static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type, ++ int flags, const char *dev_name, ++ void *data, struct mtd_info *mtd) ++{ ++ struct super_block *sb; ++ struct jffs2_sb_info *c; ++ int ret; + +- list_for_each(this, &c->free_list) { +- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); +- printk(KERN_DEBUG "free_list: %08x\n", jeb->offset); +- } +- } +- if (list_empty(&c->bad_list)) { +- printk(KERN_DEBUG "bad_list: empty\n"); +- } else { +- struct list_head *this; ++ c = kmalloc(sizeof(*c), GFP_KERNEL); ++ if (!c) ++ return ERR_PTR(-ENOMEM); ++ memset(c, 0, sizeof(*c)); ++ c->mtd = mtd; + +- list_for_each(this, &c->bad_list) { +- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); +- printk(KERN_DEBUG "bad_list: %08x\n", jeb->offset); +- } +- } +- if (list_empty(&c->bad_used_list)) { +- printk(KERN_DEBUG "bad_used_list: empty\n"); +- } else { +- struct list_head *this; ++ sb = sget(fs_type, jffs2_sb_compare, jffs2_sb_set, c); ++ ++ if (IS_ERR(sb)) ++ goto out_put; + +- list_for_each(this, &c->bad_used_list) { +- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); +- printk(KERN_DEBUG "bad_used_list: %08x\n", jeb->offset); ++ if (sb->s_root) { ++ /* New mountpoint for JFFS2 which is already mounted */ ++ D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): Device %d (\"%s\") is already mounted\n", ++ mtd->index, mtd->name)); ++ goto out_put; + } ++ ++ D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): New superblock for device %d (\"%s\")\n", ++ mtd->index, mtd->name)); ++ ++ sb->s_op = &jffs2_super_operations; ++ ++ ret = jffs2_do_fill_super(sb, data, (flags&MS_VERBOSE)?1:0); ++ ++ if (ret) { ++ /* Failure case... */ ++ up_write(&sb->s_umount); ++ deactivate_super(sb); ++ return ERR_PTR(ret); + } +-#endif /* CONFIG_JFFS2_FS_DEBUG */ + +- spin_unlock_bh(&c->erase_completion_lock); ++ sb->s_flags |= MS_ACTIVE; ++ return sb; + ++ out_put: ++ kfree(c); ++ put_mtd_device(mtd); + +- return 0; ++ return sb; + } + +-static struct super_block *jffs2_read_super(struct super_block *sb, void *data, int silent) ++static struct super_block *jffs2_get_sb_mtdnr(struct file_system_type *fs_type, ++ int flags, const char *dev_name, ++ void *data, int mtdnr) + { +- struct jffs2_sb_info *c; +- struct inode *root_i; +- int i; +- +- D1(printk(KERN_DEBUG "jffs2: read_super for device %s\n", kdevname(sb->s_dev))); ++ struct mtd_info *mtd; + +- if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR) { +- if (!silent) +- printk(KERN_DEBUG "jffs2: attempt to mount non-MTD device %s\n", kdevname(sb->s_dev)); +- return NULL; ++ mtd = get_mtd_device(NULL, mtdnr); ++ if (!mtd) { ++ D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr)); ++ return ERR_PTR(-EINVAL); + } + +- c = JFFS2_SB_INFO(sb); +- memset(c, 0, sizeof(*c)); ++ return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd); ++} + +- c->mtd = get_mtd_device(NULL, MINOR(sb->s_dev)); +- if (!c->mtd) { +- D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", MINOR(sb->s_dev))); +- return NULL; ++static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, ++ int flags, const char *dev_name, ++ void *data) ++{ ++ int err; ++ struct nameidata nd; ++ int mtdnr; ++ ++ if (!dev_name) ++ return ERR_PTR(-EINVAL); ++ ++ D1(printk(KERN_DEBUG "jffs2_get_sb(): dev_name \"%s\"\n", dev_name)); ++ ++ /* The preferred way of mounting in future; especially when ++ CONFIG_BLK_DEV is implemented - we specify the underlying ++ MTD device by number or by name, so that we don't require ++ block device support to be present in the kernel. */ ++ ++ /* FIXME: How to do the root fs this way? */ ++ ++ if (dev_name[0] == 'm' && dev_name[1] == 't' && dev_name[2] == 'd') { ++ /* Probably mounting without the blkdev crap */ ++ if (dev_name[3] == ':') { ++ struct mtd_info *mtd; ++ ++ /* Mount by MTD device name */ ++ D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd:%%s, name \"%s\"\n", dev_name+4)); ++ for (mtdnr = 0; mtdnr < MAX_MTD_DEVICES; mtdnr++) { ++ mtd = get_mtd_device(NULL, mtdnr); ++ if (mtd) { ++ if (!strcmp(mtd->name, dev_name+4)) ++ return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd); ++ put_mtd_device(mtd); + } +- c->sector_size = c->mtd->erasesize; +- c->free_size = c->flash_size = c->mtd->size; +- c->nr_blocks = c->mtd->size / c->mtd->erasesize; +- c->blocks = kmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks, GFP_KERNEL); +- if (!c->blocks) +- goto out_mtd; +- for (i=0; inr_blocks; i++) { +- INIT_LIST_HEAD(&c->blocks[i].list); +- c->blocks[i].offset = i * c->sector_size; +- c->blocks[i].free_size = c->sector_size; +- c->blocks[i].dirty_size = 0; +- c->blocks[i].used_size = 0; +- c->blocks[i].first_node = NULL; +- c->blocks[i].last_node = NULL; +- } +- +- spin_lock_init(&c->nodelist_lock); +- init_MUTEX(&c->alloc_sem); +- init_waitqueue_head(&c->erase_wait); +- spin_lock_init(&c->erase_completion_lock); +- spin_lock_init(&c->inocache_lock); +- +- INIT_LIST_HEAD(&c->clean_list); +- INIT_LIST_HEAD(&c->dirty_list); +- INIT_LIST_HEAD(&c->erasing_list); +- INIT_LIST_HEAD(&c->erase_pending_list); +- INIT_LIST_HEAD(&c->erase_complete_list); +- INIT_LIST_HEAD(&c->free_list); +- INIT_LIST_HEAD(&c->bad_list); +- INIT_LIST_HEAD(&c->bad_used_list); +- c->highest_ino = 1; +- +- if (jffs2_build_filesystem(c)) { +- D1(printk(KERN_DEBUG "build_fs failed\n")); +- goto out_nodes; + } ++ printk(KERN_NOTICE "jffs2_get_sb(): MTD device with name \"%s\" not found.\n", dev_name+4); ++ } else if (isdigit(dev_name[3])) { ++ /* Mount by MTD device number name */ ++ char *endptr; + +- sb->s_op = &jffs2_super_operations; ++ mtdnr = simple_strtoul(dev_name+3, &endptr, 0); ++ if (!*endptr) { ++ /* It was a valid number */ ++ D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd%%d, mtdnr %d\n", mtdnr)); ++ return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr); ++ } ++ } ++ } + +- D1(printk(KERN_DEBUG "jffs2_read_super(): Getting root inode\n")); +- root_i = iget(sb, 1); +- if (is_bad_inode(root_i)) { +- D1(printk(KERN_WARNING "get root inode failed\n")); +- goto out_nodes; ++ /* Try the old way - the hack where we allowed users to mount ++ /dev/mtdblock$(n) but didn't actually _use_ the blkdev */ ++ ++ err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd); ++ ++ D1(printk(KERN_DEBUG "jffs2_get_sb(): path_lookup() returned %d, inode %p\n", ++ err, nd.dentry->d_inode)); ++ ++ if (err) ++ return ERR_PTR(err); ++ ++ err = -EINVAL; ++ ++ if (!S_ISBLK(nd.dentry->d_inode->i_mode)) ++ goto out; ++ ++ if (nd.mnt->mnt_flags & MNT_NODEV) { ++ err = -EACCES; ++ goto out; + } + +- D1(printk(KERN_DEBUG "jffs2_read_super(): d_alloc_root()\n")); +- sb->s_root = d_alloc_root(root_i); +- if (!sb->s_root) +- goto out_root_i; ++ if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR) { ++ if (!(flags & MS_VERBOSE)) /* Yes I mean this. Strangely */ ++ printk(KERN_NOTICE "Attempt to mount non-MTD device \"%s\" as JFFS2\n", ++ dev_name); ++ goto out; ++ } + +-#if LINUX_VERSION_CODE >= 0x20403 +- sb->s_maxbytes = 0xFFFFFFFF; +-#endif +- sb->s_blocksize = PAGE_CACHE_SIZE; +- sb->s_blocksize_bits = PAGE_CACHE_SHIFT; +- sb->s_magic = JFFS2_SUPER_MAGIC; +- if (!(sb->s_flags & MS_RDONLY)) +- jffs2_start_garbage_collect_thread(c); +- return sb; ++ mtdnr = iminor(nd.dentry->d_inode); ++ path_release(&nd); + +- out_root_i: +- iput(root_i); +- out_nodes: +- jffs2_free_ino_caches(c); +- jffs2_free_raw_node_refs(c); +- kfree(c->blocks); +- out_mtd: +- put_mtd_device(c->mtd); +- return NULL; ++ return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr); ++ ++out: ++ path_release(&nd); ++ return ERR_PTR(err); + } + +-void jffs2_put_super (struct super_block *sb) ++static void jffs2_put_super (struct super_block *sb) + { + struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); + +@@ -293,74 +259,53 @@ + + if (!(sb->s_flags & MS_RDONLY)) + jffs2_stop_garbage_collect_thread(c); ++ down(&c->alloc_sem); ++ jffs2_flush_wbuf_pad(c); ++ up(&c->alloc_sem); + jffs2_free_ino_caches(c); + jffs2_free_raw_node_refs(c); + kfree(c->blocks); ++ jffs2_nand_flash_cleanup(c); ++ kfree(c->inocache_list); + if (c->mtd->sync) + c->mtd->sync(c->mtd); +- put_mtd_device(c->mtd); + + D1(printk(KERN_DEBUG "jffs2_put_super returning\n")); + } + +-int jffs2_remount_fs (struct super_block *sb, int *flags, char *data) ++static void jffs2_kill_sb(struct super_block *sb) + { + struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); +- +- if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY)) +- return -EROFS; +- +- /* We stop if it was running, then restart if it needs to. +- This also catches the case where it was stopped and this +- is just a remount to restart it */ +- if (!(sb->s_flags & MS_RDONLY)) +- jffs2_stop_garbage_collect_thread(c); +- +- if (!(*flags & MS_RDONLY)) +- jffs2_start_garbage_collect_thread(c); +- +- sb->s_flags = (sb->s_flags & ~MS_RDONLY)|(*flags & MS_RDONLY); +- +- return 0; +-} +- +-void jffs2_write_super (struct super_block *sb) +-{ +- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); +- sb->s_dirt = 0; +- +- if (sb->s_flags & MS_RDONLY) +- return; +- +- jffs2_garbage_collect_trigger(c); +- jffs2_erase_pending_blocks(c); +- jffs2_mark_erased_blocks(c); ++ generic_shutdown_super(sb); ++ put_mtd_device(c->mtd); ++ kfree(c); + } + +- +-static DECLARE_FSTYPE_DEV(jffs2_fs_type, "jffs2", jffs2_read_super); ++static struct file_system_type jffs2_fs_type = { ++ .owner = THIS_MODULE, ++ .name = "jffs2", ++ .get_sb = jffs2_get_sb, ++ .kill_sb = jffs2_kill_sb, ++}; + + static int __init init_jffs2_fs(void) + { + int ret; + +- printk(KERN_NOTICE "JFFS2 version 2.1. (C) 2001 Red Hat, Inc., designed by Axis Communications AB.\n"); +- +-#ifdef JFFS2_OUT_OF_KERNEL +- /* sanity checks. Could we do these at compile time? */ +- if (sizeof(struct jffs2_sb_info) > sizeof (((struct super_block *)NULL)->u)) { +- printk(KERN_ERR "JFFS2 error: struct jffs2_sb_info (%d bytes) doesn't fit in the super_block union (%d bytes)\n", +- sizeof(struct jffs2_sb_info), sizeof (((struct super_block *)NULL)->u)); +- return -EIO; +- } +- +- if (sizeof(struct jffs2_inode_info) > sizeof (((struct inode *)NULL)->u)) { +- printk(KERN_ERR "JFFS2 error: struct jffs2_inode_info (%d bytes) doesn't fit in the inode union (%d bytes)\n", +- sizeof(struct jffs2_inode_info), sizeof (((struct inode *)NULL)->u)); +- return -EIO; +- } ++ printk(KERN_INFO "JFFS2 version 2.2." ++#ifdef CONFIG_FS_JFFS2_NAND ++ " (NAND)" + #endif ++ " (C) 2001-2003 Red Hat, Inc.\n"); + ++ jffs2_inode_cachep = kmem_cache_create("jffs2_i", ++ sizeof(struct jffs2_inode_info), ++ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, ++ jffs2_i_init_once, NULL); ++ if (!jffs2_inode_cachep) { ++ printk(KERN_ERR "JFFS2 error: Failed to initialise inode cache\n"); ++ return -ENOMEM; ++ } + ret = jffs2_zlib_init(); + if (ret) { + printk(KERN_ERR "JFFS2 error: Failed to initialise zlib workspaces\n"); +@@ -388,9 +333,10 @@ + + static void __exit exit_jffs2_fs(void) + { ++ unregister_filesystem(&jffs2_fs_type); + jffs2_destroy_slab_caches(); + jffs2_zlib_exit(); +- unregister_filesystem(&jffs2_fs_type); ++ kmem_cache_destroy(jffs2_inode_cachep); + } + + module_init(init_jffs2_fs); +diff -Nurb linux-mips-2.4.27/fs/jffs2/symlink.c linux/fs/jffs2/symlink.c +--- linux-mips-2.4.27/fs/jffs2/symlink.c 2002-06-27 00:36:20.000000000 +0200 ++++ linux/fs/jffs2/symlink.c 2004-11-19 10:25:12.129164832 +0100 +@@ -3,35 +3,11 @@ + * + * Copyright (C) 2001, 2002 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: symlink.c,v 1.5.2.1 2002/01/15 10:39:06 dwmw2 Exp $ ++ * $Id: symlink.c,v 1.12 2003/10/04 08:33:07 dwmw2 Exp $ + * + */ + +@@ -39,7 +15,6 @@ + #include + #include + #include +-#include + #include "nodelist.h" + + int jffs2_readlink(struct dentry *dentry, char *buffer, int buflen); +@@ -47,45 +22,17 @@ + + struct inode_operations jffs2_symlink_inode_operations = + { +- readlink: jffs2_readlink, +- follow_link: jffs2_follow_link, +- setattr: jffs2_setattr ++ .readlink = jffs2_readlink, ++ .follow_link = jffs2_follow_link, ++ .setattr = jffs2_setattr + }; + +-static char *jffs2_getlink(struct dentry *dentry) +-{ +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); +- char *buf; +- int ret; +- +- down(&f->sem); +- if (!f->metadata) { +- up(&f->sem); +- printk(KERN_NOTICE "No metadata for symlink inode #%lu\n", dentry->d_inode->i_ino); +- return ERR_PTR(-EINVAL); +- } +- buf = kmalloc(f->metadata->size+1, GFP_USER); +- if (!buf) { +- up(&f->sem); +- return ERR_PTR(-ENOMEM); +- } +- buf[f->metadata->size]=0; +- +- ret = jffs2_read_dnode(JFFS2_SB_INFO(dentry->d_inode->i_sb), f->metadata, buf, 0, f->metadata->size); +- up(&f->sem); +- if (ret) { +- kfree(buf); +- return ERR_PTR(ret); +- } +- return buf; +- +-} + int jffs2_readlink(struct dentry *dentry, char *buffer, int buflen) + { + unsigned char *kbuf; + int ret; + +- kbuf = jffs2_getlink(dentry); ++ kbuf = jffs2_getlink(JFFS2_SB_INFO(dentry->d_inode->i_sb), JFFS2_INODE_INFO(dentry->d_inode)); + if (IS_ERR(kbuf)) + return PTR_ERR(kbuf); + +@@ -99,7 +46,7 @@ + unsigned char *buf; + int ret; + +- buf = jffs2_getlink(dentry); ++ buf = jffs2_getlink(JFFS2_SB_INFO(dentry->d_inode->i_sb), JFFS2_INODE_INFO(dentry->d_inode)); + + if (IS_ERR(buf)) + return PTR_ERR(buf); +diff -Nurb linux-mips-2.4.27/fs/jffs2/wbuf.c linux/fs/jffs2/wbuf.c +--- linux-mips-2.4.27/fs/jffs2/wbuf.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/fs/jffs2/wbuf.c 2004-11-19 10:25:12.131164528 +0100 +@@ -0,0 +1,1156 @@ ++/* ++ * JFFS2 -- Journalling Flash File System, Version 2. ++ * ++ * Copyright (C) 2001-2003 Red Hat, Inc. ++ * ++ * Created by David Woodhouse ++ * ++ * For licensing information, see the file 'LICENCE' in this directory. ++ * ++ * $Id: wbuf.c,v 1.58 2003/11/02 09:51:10 dwmw2 Exp $ ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "nodelist.h" ++ ++/* For testing write failures */ ++#undef BREAKME ++#undef BREAKMEHEADER ++ ++#ifdef BREAKME ++static unsigned char *brokenbuf; ++#endif ++ ++/* max. erase failures before we mark a block bad */ ++#define MAX_ERASE_FAILURES 5 ++ ++/* two seconds timeout for timed wbuf-flushing */ ++#define WBUF_FLUSH_TIMEOUT 2 * HZ ++ ++struct jffs2_inodirty { ++ uint32_t ino; ++ struct jffs2_inodirty *next; ++}; ++ ++static struct jffs2_inodirty inodirty_nomem; ++ ++static int jffs2_wbuf_pending_for_ino(struct jffs2_sb_info *c, uint32_t ino) ++{ ++ struct jffs2_inodirty *this = c->wbuf_inodes; ++ ++ /* If a malloc failed, consider _everything_ dirty */ ++ if (this == &inodirty_nomem) ++ return 1; ++ ++ /* If ino == 0, _any_ non-GC writes mean 'yes' */ ++ if (this && !ino) ++ return 1; ++ ++ /* Look to see if the inode in question is pending in the wbuf */ ++ while (this) { ++ if (this->ino == ino) ++ return 1; ++ this = this->next; ++ } ++ return 0; ++} ++ ++static void jffs2_clear_wbuf_ino_list(struct jffs2_sb_info *c) ++{ ++ struct jffs2_inodirty *this; ++ ++ this = c->wbuf_inodes; ++ ++ if (this != &inodirty_nomem) { ++ while (this) { ++ struct jffs2_inodirty *next = this->next; ++ kfree(this); ++ this = next; ++ } ++ } ++ c->wbuf_inodes = NULL; ++} ++ ++static void jffs2_wbuf_dirties_inode(struct jffs2_sb_info *c, uint32_t ino) ++{ ++ struct jffs2_inodirty *new; ++ ++ /* Mark the superblock dirty so that kupdated will flush... */ ++ OFNI_BS_2SFFJ(c)->s_dirt = 1; ++ ++ if (jffs2_wbuf_pending_for_ino(c, ino)) ++ return; ++ ++ new = kmalloc(sizeof(*new), GFP_KERNEL); ++ if (!new) { ++ D1(printk(KERN_DEBUG "No memory to allocate inodirty. Fallback to all considered dirty\n")); ++ jffs2_clear_wbuf_ino_list(c); ++ c->wbuf_inodes = &inodirty_nomem; ++ return; ++ } ++ new->ino = ino; ++ new->next = c->wbuf_inodes; ++ c->wbuf_inodes = new; ++ return; ++} ++ ++static inline void jffs2_refile_wbuf_blocks(struct jffs2_sb_info *c) ++{ ++ struct list_head *this, *next; ++ static int n; ++ ++ if (list_empty(&c->erasable_pending_wbuf_list)) ++ return; ++ ++ list_for_each_safe(this, next, &c->erasable_pending_wbuf_list) { ++ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); ++ ++ D1(printk(KERN_DEBUG "Removing eraseblock at 0x%08x from erasable_pending_wbuf_list...\n", jeb->offset)); ++ list_del(this); ++ if ((jiffies + (n++)) & 127) { ++ /* Most of the time, we just erase it immediately. Otherwise we ++ spend ages scanning it on mount, etc. */ ++ D1(printk(KERN_DEBUG "...and adding to erase_pending_list\n")); ++ list_add_tail(&jeb->list, &c->erase_pending_list); ++ c->nr_erasing_blocks++; ++ jffs2_erase_pending_trigger(c); ++ } else { ++ /* Sometimes, however, we leave it elsewhere so it doesn't get ++ immediately reused, and we spread the load a bit. */ ++ D1(printk(KERN_DEBUG "...and adding to erasable_list\n")); ++ list_add_tail(&jeb->list, &c->erasable_list); ++ } ++ } ++} ++ ++/* Recover from failure to write wbuf. Recover the nodes up to the ++ * wbuf, not the one which we were starting to try to write. */ ++ ++static void jffs2_wbuf_recover(struct jffs2_sb_info *c) ++{ ++ struct jffs2_eraseblock *jeb, *new_jeb; ++ struct jffs2_raw_node_ref **first_raw, **raw; ++ size_t retlen; ++ int ret; ++ unsigned char *buf; ++ uint32_t start, end, ofs, len; ++ ++ spin_lock(&c->erase_completion_lock); ++ ++ jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; ++ ++ D1(printk("About to refile bad block at %08x\n", jeb->offset)); ++ ++ D2(jffs2_dump_block_lists(c)); ++ /* File the existing block on the bad_used_list.... */ ++ if (c->nextblock == jeb) ++ c->nextblock = NULL; ++ else /* Not sure this should ever happen... need more coffee */ ++ list_del(&jeb->list); ++ if (jeb->first_node) { ++ D1(printk("Refiling block at %08x to bad_used_list\n", jeb->offset)); ++ list_add(&jeb->list, &c->bad_used_list); ++ } else { ++ BUG(); ++ /* It has to have had some nodes or we couldn't be here */ ++ D1(printk("Refiling block at %08x to erase_pending_list\n", jeb->offset)); ++ list_add(&jeb->list, &c->erase_pending_list); ++ c->nr_erasing_blocks++; ++ jffs2_erase_pending_trigger(c); ++ } ++ D2(jffs2_dump_block_lists(c)); ++ ++ /* Adjust its size counts accordingly */ ++ c->wasted_size += jeb->free_size; ++ c->free_size -= jeb->free_size; ++ jeb->wasted_size += jeb->free_size; ++ jeb->free_size = 0; ++ ++ ACCT_SANITY_CHECK(c,jeb); ++ D1(ACCT_PARANOIA_CHECK(jeb)); ++ ++ /* Find the first node to be recovered, by skipping over every ++ node which ends before the wbuf starts, or which is obsolete. */ ++ first_raw = &jeb->first_node; ++ while (*first_raw && ++ (ref_obsolete(*first_raw) || ++ (ref_offset(*first_raw)+ref_totlen(c, jeb, *first_raw)) < c->wbuf_ofs)) { ++ D1(printk(KERN_DEBUG "Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n", ++ ref_offset(*first_raw), ref_flags(*first_raw), ++ (ref_offset(*first_raw) + ref_totlen(c, jeb, *first_raw)), ++ c->wbuf_ofs)); ++ first_raw = &(*first_raw)->next_phys; ++ } ++ ++ if (!*first_raw) { ++ /* All nodes were obsolete. Nothing to recover. */ ++ D1(printk(KERN_DEBUG "No non-obsolete nodes to be recovered. Just filing block bad\n")); ++ spin_unlock(&c->erase_completion_lock); ++ return; ++ } ++ ++ start = ref_offset(*first_raw); ++ end = ref_offset(*first_raw) + ref_totlen(c, jeb, *first_raw); ++ ++ /* Find the last node to be recovered */ ++ raw = first_raw; ++ while ((*raw)) { ++ if (!ref_obsolete(*raw)) ++ end = ref_offset(*raw) + ref_totlen(c, jeb, *raw); ++ ++ raw = &(*raw)->next_phys; ++ } ++ spin_unlock(&c->erase_completion_lock); ++ ++ D1(printk(KERN_DEBUG "wbuf recover %08x-%08x\n", start, end)); ++ ++ buf = NULL; ++ if (start < c->wbuf_ofs) { ++ /* First affected node was already partially written. ++ * Attempt to reread the old data into our buffer. */ ++ ++ buf = kmalloc(end - start, GFP_KERNEL); ++ if (!buf) { ++ printk(KERN_CRIT "Malloc failure in wbuf recovery. Data loss ensues.\n"); ++ ++ goto read_failed; ++ } ++ ++ /* Do the read... */ ++ ret = c->mtd->read_ecc(c->mtd, start, c->wbuf_ofs - start, &retlen, buf, NULL, c->oobinfo); ++ if (ret == -EIO && retlen == c->wbuf_ofs - start) { ++ /* ECC recovered */ ++ ret = 0; ++ } ++ if (ret || retlen != c->wbuf_ofs - start) { ++ printk(KERN_CRIT "Old data are already lost in wbuf recovery. Data loss ensues.\n"); ++ ++ kfree(buf); ++ buf = NULL; ++ read_failed: ++ first_raw = &(*first_raw)->next_phys; ++ /* If this was the only node to be recovered, give up */ ++ if (!(*first_raw)) ++ return; ++ ++ /* It wasn't. Go on and try to recover nodes complete in the wbuf */ ++ start = ref_offset(*first_raw); ++ } else { ++ /* Read succeeded. Copy the remaining data from the wbuf */ ++ memcpy(buf + (c->wbuf_ofs - start), c->wbuf, end - c->wbuf_ofs); ++ } ++ } ++ /* OK... we're to rewrite (end-start) bytes of data from first_raw onwards. ++ Either 'buf' contains the data, or we find it in the wbuf */ ++ ++ ++ /* ... and get an allocation of space from a shiny new block instead */ ++ ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len); ++ if (ret) { ++ printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n"); ++ if (buf) ++ kfree(buf); ++ return; ++ } ++ if (end-start >= c->wbuf_pagesize) { ++ /* Need to do another write immediately. This, btw, ++ means that we'll be writing from 'buf' and not from ++ the wbuf. Since if we're writing from the wbuf there ++ won't be more than a wbuf full of data, now will ++ there? :) */ ++ ++ uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize); ++ ++ D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n", ++ towrite, ofs)); ++ ++#ifdef BREAKMEHEADER ++ static int breakme; ++ if (breakme++ == 20) { ++ printk(KERN_NOTICE "Faking write error at 0x%08x\n", ofs); ++ breakme = 0; ++ c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen, ++ brokenbuf, NULL, c->oobinfo); ++ ret = -EIO; ++ } else ++#endif ++ ret = c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen, ++ buf, NULL, c->oobinfo); ++ ++ if (ret || retlen != towrite) { ++ /* Argh. We tried. Really we did. */ ++ printk(KERN_CRIT "Recovery of wbuf failed due to a second write error\n"); ++ kfree(buf); ++ ++ if (retlen) { ++ struct jffs2_raw_node_ref *raw2; ++ ++ raw2 = jffs2_alloc_raw_node_ref(); ++ if (!raw2) ++ return; ++ ++ raw2->flash_offset = ofs | REF_OBSOLETE; ++ raw2->__totlen = ref_totlen(c, jeb, *first_raw); ++ raw2->next_phys = NULL; ++ raw2->next_in_ino = NULL; ++ ++ jffs2_add_physical_node_ref(c, raw2); ++ } ++ return; ++ } ++ printk(KERN_NOTICE "Recovery of wbuf succeeded to %08x\n", ofs); ++ ++ c->wbuf_len = (end - start) - towrite; ++ c->wbuf_ofs = ofs + towrite; ++ memcpy(c->wbuf, buf + towrite, c->wbuf_len); ++ /* Don't muck about with c->wbuf_inodes. False positives are harmless. */ ++ ++ kfree(buf); ++ } else { ++ /* OK, now we're left with the dregs in whichever buffer we're using */ ++ if (buf) { ++ memcpy(c->wbuf, buf, end-start); ++ kfree(buf); ++ } else { ++ memmove(c->wbuf, c->wbuf + (start - c->wbuf_ofs), end - start); ++ } ++ c->wbuf_ofs = ofs; ++ c->wbuf_len = end - start; ++ } ++ ++ /* Now sort out the jffs2_raw_node_refs, moving them from the old to the next block */ ++ new_jeb = &c->blocks[ofs / c->sector_size]; ++ ++ spin_lock(&c->erase_completion_lock); ++ if (new_jeb->first_node) { ++ /* Odd, but possible with ST flash later maybe */ ++ new_jeb->last_node->next_phys = *first_raw; ++ } else { ++ new_jeb->first_node = *first_raw; ++ } ++ ++ raw = first_raw; ++ while (*raw) { ++ uint32_t rawlen = ref_totlen(c, jeb, *raw); ++ ++ D1(printk(KERN_DEBUG "Refiling block of %08x at %08x(%d) to %08x\n", ++ rawlen, ref_offset(*raw), ref_flags(*raw), ofs)); ++ ++ if (ref_obsolete(*raw)) { ++ /* Shouldn't really happen much */ ++ new_jeb->dirty_size += rawlen; ++ new_jeb->free_size -= rawlen; ++ c->dirty_size += rawlen; ++ } else { ++ new_jeb->used_size += rawlen; ++ new_jeb->free_size -= rawlen; ++ jeb->dirty_size += rawlen; ++ jeb->used_size -= rawlen; ++ c->dirty_size += rawlen; ++ } ++ c->free_size -= rawlen; ++ (*raw)->flash_offset = ofs | ref_flags(*raw); ++ ofs += rawlen; ++ new_jeb->last_node = *raw; ++ ++ raw = &(*raw)->next_phys; ++ } ++ ++ /* Fix up the original jeb now it's on the bad_list */ ++ *first_raw = NULL; ++ if (first_raw == &jeb->first_node) { ++ jeb->last_node = NULL; ++ D1(printk(KERN_DEBUG "Failing block at %08x is now empty. Moving to erase_pending_list\n", jeb->offset)); ++ list_del(&jeb->list); ++ list_add(&jeb->list, &c->erase_pending_list); ++ c->nr_erasing_blocks++; ++ jffs2_erase_pending_trigger(c); ++ } ++ else ++ jeb->last_node = container_of(first_raw, struct jffs2_raw_node_ref, next_phys); ++ ++ ACCT_SANITY_CHECK(c,jeb); ++ D1(ACCT_PARANOIA_CHECK(jeb)); ++ ++ ACCT_SANITY_CHECK(c,new_jeb); ++ D1(ACCT_PARANOIA_CHECK(new_jeb)); ++ ++ spin_unlock(&c->erase_completion_lock); ++ ++ D1(printk(KERN_DEBUG "wbuf recovery completed OK\n")); ++} ++ ++/* Meaning of pad argument: ++ 0: Do not pad. Probably pointless - we only ever use this when we can't pad anyway. ++ 1: Pad, do not adjust nextblock free_size ++ 2: Pad, adjust nextblock free_size ++*/ ++static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) ++{ ++ int ret; ++ size_t retlen; ++ ++ /* Nothing to do if not NAND flash. In particular, we shouldn't ++ del_timer() the timer we never initialised. */ ++ if (jffs2_can_mark_obsolete(c)) ++ return 0; ++ ++ if (!down_trylock(&c->alloc_sem)) { ++ up(&c->alloc_sem); ++ printk(KERN_CRIT "jffs2_flush_wbuf() called with alloc_sem not locked!\n"); ++ BUG(); ++ } ++ ++ if(!c->wbuf || !c->wbuf_len) ++ return 0; ++ ++ /* claim remaining space on the page ++ this happens, if we have a change to a new block, ++ or if fsync forces us to flush the writebuffer. ++ if we have a switch to next page, we will not have ++ enough remaining space for this. ++ */ ++ if (pad) { ++ c->wbuf_len = PAD(c->wbuf_len); ++ ++ if ( c->wbuf_len + sizeof(struct jffs2_unknown_node) < c->wbuf_pagesize) { ++ struct jffs2_unknown_node *padnode = (void *)(c->wbuf + c->wbuf_len); ++ padnode->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ padnode->nodetype = cpu_to_je16(JFFS2_NODETYPE_PADDING); ++ padnode->totlen = cpu_to_je32(c->wbuf_pagesize - c->wbuf_len); ++ padnode->hdr_crc = cpu_to_je32(crc32(0, padnode, sizeof(*padnode)-4)); ++ } ++ } ++ /* else jffs2_flash_writev has actually filled in the rest of the ++ buffer for us, and will deal with the node refs etc. later. */ ++ ++#ifdef BREAKME ++ static int breakme; ++ if (breakme++ == 20) { ++ printk(KERN_NOTICE "Faking write error at 0x%08x\n", c->wbuf_ofs); ++ breakme = 0; ++ c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, ++ &retlen, brokenbuf, NULL, c->oobinfo); ++ ret = -EIO; ++ } else ++#endif ++ ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, c->oobinfo); ++ ++ ++ if (ret || retlen != c->wbuf_pagesize) { ++ if (ret) ++ printk(KERN_WARNING "jffs2_flush_wbuf(): Write failed with %d\n",ret); ++ else { ++ printk(KERN_WARNING "jffs2_flush_wbuf(): Write was short: %zd instead of %d\n", ++ retlen, c->wbuf_pagesize); ++ ret = -EIO; ++ } ++ ++ jffs2_wbuf_recover(c); ++ ++ return ret; ++ } ++ ++ /* Adjusting free size of next block only, if it's called from fsync ! */ ++ if (pad == 2) { ++ D1(printk(KERN_DEBUG "jffs2_flush_wbuf() adjusting free_size of c->nextblock\n")); ++ spin_lock(&c->erase_completion_lock); ++ if (!c->nextblock) ++ BUG(); ++ /* wbuf_pagesize - wbuf_len is the amount of space that's to be ++ padded. If there is less free space in the block than that, ++ something screwed up */ ++ if (c->nextblock->free_size < (c->wbuf_pagesize - c->wbuf_len)) { ++ printk(KERN_CRIT "jffs2_flush_wbuf(): Accounting error. wbuf at 0x%08x has 0x%03x bytes, 0x%03x left.\n", ++ c->wbuf_ofs, c->wbuf_len, c->wbuf_pagesize-c->wbuf_len); ++ printk(KERN_CRIT "jffs2_flush_wbuf(): But free_size for block at 0x%08x is only 0x%08x\n", ++ c->nextblock->offset, c->nextblock->free_size); ++ BUG(); ++ } ++ c->nextblock->free_size -= (c->wbuf_pagesize - c->wbuf_len); ++ c->free_size -= (c->wbuf_pagesize - c->wbuf_len); ++ c->nextblock->wasted_size += (c->wbuf_pagesize - c->wbuf_len); ++ c->wasted_size += (c->wbuf_pagesize - c->wbuf_len); ++ spin_unlock(&c->erase_completion_lock); ++ } ++ ++ /* Stick any now-obsoleted blocks on the erase_pending_list */ ++ spin_lock(&c->erase_completion_lock); ++ jffs2_refile_wbuf_blocks(c); ++ jffs2_clear_wbuf_ino_list(c); ++ spin_unlock(&c->erase_completion_lock); ++ ++ memset(c->wbuf,0xff,c->wbuf_pagesize); ++ /* adjust write buffer offset, else we get a non contiguous write bug */ ++ c->wbuf_ofs += c->wbuf_pagesize; ++ c->wbuf_len = 0; ++ return 0; ++} ++ ++/* Trigger garbage collection to flush the write-buffer. ++ If ino arg is zero, do it if _any_ real (i.e. not GC) writes are ++ outstanding. If ino arg non-zero, do it only if a write for the ++ given inode is outstanding. */ ++int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino) ++{ ++ uint32_t old_wbuf_ofs; ++ uint32_t old_wbuf_len; ++ int ret = 0; ++ ++ D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() called for ino #%u...\n", ino)); ++ ++ down(&c->alloc_sem); ++ if (!jffs2_wbuf_pending_for_ino(c, ino)) { ++ D1(printk(KERN_DEBUG "Ino #%d not pending in wbuf. Returning\n", ino)); ++ up(&c->alloc_sem); ++ return 0; ++ } ++ ++ old_wbuf_ofs = c->wbuf_ofs; ++ old_wbuf_len = c->wbuf_len; ++ ++ if (c->unchecked_size) { ++ /* GC won't make any progress for a while */ ++ D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() padding. Not finished checking\n")); ++ ret = __jffs2_flush_wbuf(c, 2); ++ } else while (old_wbuf_len && ++ old_wbuf_ofs == c->wbuf_ofs) { ++ ++ up(&c->alloc_sem); ++ ++ D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() calls gc pass\n")); ++ ++ ret = jffs2_garbage_collect_pass(c); ++ if (ret) { ++ /* GC failed. Flush it with padding instead */ ++ down(&c->alloc_sem); ++ ret = __jffs2_flush_wbuf(c, 2); ++ break; ++ } ++ down(&c->alloc_sem); ++ } ++ ++ D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() ends...\n")); ++ ++ up(&c->alloc_sem); ++ return ret; ++} ++ ++/* Pad write-buffer to end and write it, wasting space. */ ++int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c) ++{ ++ return __jffs2_flush_wbuf(c, 1); ++} ++ ++ ++#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) ) ++#define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) ) ++int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino) ++{ ++ struct iovec outvecs[3]; ++ uint32_t totlen = 0; ++ uint32_t split_ofs = 0; ++ uint32_t old_totlen; ++ int ret, splitvec = -1; ++ int invec, outvec; ++ size_t wbuf_retlen; ++ unsigned char *wbuf_ptr; ++ size_t donelen = 0; ++ uint32_t outvec_to = to; ++ ++ /* If not NAND flash, don't bother */ ++ if (!c->wbuf) ++ return jffs2_flash_direct_writev(c, invecs, count, to, retlen); ++ ++ /* If wbuf_ofs is not initialized, set it to target address */ ++ if (c->wbuf_ofs == 0xFFFFFFFF) { ++ c->wbuf_ofs = PAGE_DIV(to); ++ c->wbuf_len = PAGE_MOD(to); ++ memset(c->wbuf,0xff,c->wbuf_pagesize); ++ } ++ ++ /* Sanity checks on target address. ++ It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs), ++ and it's permitted to write at the beginning of a new ++ erase block. Anything else, and you die. ++ New block starts at xxx000c (0-b = block header) ++ */ ++ if ( (to & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) { ++ /* It's a write to a new block */ ++ if (c->wbuf_len) { ++ D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs)); ++ ret = jffs2_flush_wbuf_pad(c); ++ if (ret) { ++ /* the underlying layer has to check wbuf_len to do the cleanup */ ++ D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret)); ++ *retlen = 0; ++ return ret; ++ } ++ } ++ /* set pointer to new block */ ++ c->wbuf_ofs = PAGE_DIV(to); ++ c->wbuf_len = PAGE_MOD(to); ++ } ++ ++ if (to != PAD(c->wbuf_ofs + c->wbuf_len)) { ++ /* We're not writing immediately after the writebuffer. Bad. */ ++ printk(KERN_CRIT "jffs2_flash_writev(): Non-contiguous write to %08lx\n", (unsigned long)to); ++ if (c->wbuf_len) ++ printk(KERN_CRIT "wbuf was previously %08x-%08x\n", ++ c->wbuf_ofs, c->wbuf_ofs+c->wbuf_len); ++ BUG(); ++ } ++ ++ /* Note outvecs[3] above. We know count is never greater than 2 */ ++ if (count > 2) { ++ printk(KERN_CRIT "jffs2_flash_writev(): count is %ld\n", count); ++ BUG(); ++ } ++ ++ invec = 0; ++ outvec = 0; ++ ++ ++ /* Fill writebuffer first, if already in use */ ++ if (c->wbuf_len) { ++ uint32_t invec_ofs = 0; ++ ++ /* adjust alignment offset */ ++ if (c->wbuf_len != PAGE_MOD(to)) { ++ c->wbuf_len = PAGE_MOD(to); ++ /* take care of alignment to next page */ ++ if (!c->wbuf_len) ++ c->wbuf_len = c->wbuf_pagesize; ++ } ++ ++ while(c->wbuf_len < c->wbuf_pagesize) { ++ uint32_t thislen; ++ ++ if (invec == count) ++ goto alldone; ++ ++ thislen = c->wbuf_pagesize - c->wbuf_len; ++ ++ if (thislen >= invecs[invec].iov_len) ++ thislen = invecs[invec].iov_len; ++ ++ invec_ofs = thislen; ++ ++ memcpy(c->wbuf + c->wbuf_len, invecs[invec].iov_base, thislen); ++ c->wbuf_len += thislen; ++ donelen += thislen; ++ /* Get next invec, if actual did not fill the buffer */ ++ if (c->wbuf_len < c->wbuf_pagesize) ++ invec++; ++ } ++ ++ /* write buffer is full, flush buffer */ ++ ret = __jffs2_flush_wbuf(c, 0); ++ if (ret) { ++ /* the underlying layer has to check wbuf_len to do the cleanup */ ++ D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret)); ++ /* Retlen zero to make sure our caller doesn't mark the space dirty. ++ We've already done everything that's necessary */ ++ *retlen = 0; ++ return ret; ++ } ++ outvec_to += donelen; ++ c->wbuf_ofs = outvec_to; ++ ++ /* All invecs done ? */ ++ if (invec == count) ++ goto alldone; ++ ++ /* Set up the first outvec, containing the remainder of the ++ invec we partially used */ ++ if (invecs[invec].iov_len > invec_ofs) { ++ outvecs[0].iov_base = invecs[invec].iov_base+invec_ofs; ++ totlen = outvecs[0].iov_len = invecs[invec].iov_len-invec_ofs; ++ if (totlen > c->wbuf_pagesize) { ++ splitvec = outvec; ++ split_ofs = outvecs[0].iov_len - PAGE_MOD(totlen); ++ } ++ outvec++; ++ } ++ invec++; ++ } ++ ++ /* OK, now we've flushed the wbuf and the start of the bits ++ we have been asked to write, now to write the rest.... */ ++ ++ /* totlen holds the amount of data still to be written */ ++ old_totlen = totlen; ++ for ( ; invec < count; invec++,outvec++ ) { ++ outvecs[outvec].iov_base = invecs[invec].iov_base; ++ totlen += outvecs[outvec].iov_len = invecs[invec].iov_len; ++ if (PAGE_DIV(totlen) != PAGE_DIV(old_totlen)) { ++ splitvec = outvec; ++ split_ofs = outvecs[outvec].iov_len - PAGE_MOD(totlen); ++ old_totlen = totlen; ++ } ++ } ++ ++ /* Now the outvecs array holds all the remaining data to write */ ++ /* Up to splitvec,split_ofs is to be written immediately. The rest ++ goes into the (now-empty) wbuf */ ++ ++ if (splitvec != -1) { ++ uint32_t remainder; ++ int ret; ++ ++ remainder = outvecs[splitvec].iov_len - split_ofs; ++ outvecs[splitvec].iov_len = split_ofs; ++ ++ /* We did cross a page boundary, so we write some now */ ++ ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo); ++ if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) { ++ /* At this point we have no problem, ++ c->wbuf is empty. ++ */ ++ *retlen = donelen; ++ return ret; ++ } ++ ++ donelen += wbuf_retlen; ++ c->wbuf_ofs = PAGE_DIV(outvec_to) + PAGE_DIV(totlen); ++ ++ if (remainder) { ++ outvecs[splitvec].iov_base += split_ofs; ++ outvecs[splitvec].iov_len = remainder; ++ } else { ++ splitvec++; ++ } ++ ++ } else { ++ splitvec = 0; ++ } ++ ++ /* Now splitvec points to the start of the bits we have to copy ++ into the wbuf */ ++ wbuf_ptr = c->wbuf; ++ ++ for ( ; splitvec < outvec; splitvec++) { ++ /* Don't copy the wbuf into itself */ ++ if (outvecs[splitvec].iov_base == c->wbuf) ++ continue; ++ memcpy(wbuf_ptr, outvecs[splitvec].iov_base, outvecs[splitvec].iov_len); ++ wbuf_ptr += outvecs[splitvec].iov_len; ++ donelen += outvecs[splitvec].iov_len; ++ } ++ c->wbuf_len = wbuf_ptr - c->wbuf; ++ ++ /* If there's a remainder in the wbuf and it's a non-GC write, ++ remember that the wbuf affects this ino */ ++alldone: ++ *retlen = donelen; ++ ++ if (c->wbuf_len && ino) ++ jffs2_wbuf_dirties_inode(c, ino); ++ ++ return 0; ++} ++ ++/* ++ * This is the entry for flash write. ++ * Check, if we work on NAND FLASH, if so build an iovec and write it via vritev ++*/ ++int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, const u_char *buf) ++{ ++ struct iovec vecs[1]; ++ ++ if (jffs2_can_mark_obsolete(c)) ++ return c->mtd->write(c->mtd, ofs, len, retlen, buf); ++ ++ vecs[0].iov_base = (unsigned char *) buf; ++ vecs[0].iov_len = len; ++ return jffs2_flash_writev(c, vecs, 1, ofs, retlen, 0); ++} ++ ++/* ++ Handle readback from writebuffer and ECC failure return ++*/ ++int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, u_char *buf) ++{ ++ loff_t orbf = 0, owbf = 0, lwbf = 0; ++ int ret; ++ ++ /* Read flash */ ++ if (!jffs2_can_mark_obsolete(c)) { ++ ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo); ++ ++ if ( (ret == -EIO) && (*retlen == len) ) { ++ printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n", ++ len, ofs); ++ /* ++ * We have the raw data without ECC correction in the buffer, maybe ++ * we are lucky and all data or parts are correct. We check the node. ++ * If data are corrupted node check will sort it out. ++ * We keep this block, it will fail on write or erase and the we ++ * mark it bad. Or should we do that now? But we should give him a chance. ++ * Maybe we had a system crash or power loss before the ecc write or ++ * a erase was completed. ++ * So we return success. :) ++ */ ++ ret = 0; ++ } ++ } else ++ return c->mtd->read(c->mtd, ofs, len, retlen, buf); ++ ++ /* if no writebuffer available or write buffer empty, return */ ++ if (!c->wbuf_pagesize || !c->wbuf_len) ++ return ret; ++ ++ /* if we read in a different block, return */ ++ if ( (ofs & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) ++ return ret; ++ ++ if (ofs >= c->wbuf_ofs) { ++ owbf = (ofs - c->wbuf_ofs); /* offset in write buffer */ ++ if (owbf > c->wbuf_len) /* is read beyond write buffer ? */ ++ return ret; ++ lwbf = c->wbuf_len - owbf; /* number of bytes to copy */ ++ if (lwbf > len) ++ lwbf = len; ++ } else { ++ orbf = (c->wbuf_ofs - ofs); /* offset in read buffer */ ++ if (orbf > len) /* is write beyond write buffer ? */ ++ return ret; ++ lwbf = len - orbf; /* number of bytes to copy */ ++ if (lwbf > c->wbuf_len) ++ lwbf = c->wbuf_len; ++ } ++ if (lwbf > 0) ++ memcpy(buf+orbf,c->wbuf+owbf,lwbf); ++ ++ return ret; ++} ++ ++/* ++ * Check, if the out of band area is empty ++ */ ++int jffs2_check_oob_empty( struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, int mode) ++{ ++ unsigned char *buf; ++ int ret = 0; ++ int i,len,page; ++ size_t retlen; ++ int oob_size; ++ ++ oob_size = c->mtd->oobsize; ++ ++ /* allocate a buffer for all oob data in this sector */ ++ len = 4 * oob_size; ++ buf = kmalloc(len, GFP_KERNEL); ++ if (!buf) { ++ printk(KERN_NOTICE "jffs2_check_oob_empty(): allocation of temporary data buffer for oob check failed\n"); ++ return -ENOMEM; ++ } ++ /* ++ * if mode = 0, we scan for a total empty oob area, else we have ++ * to take care of the cleanmarker in the first page of the block ++ */ ++ ret = jffs2_flash_read_oob(c, jeb->offset, len , &retlen, buf); ++ if (ret) { ++ D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB failed %d for block at %08x\n", ret, jeb->offset)); ++ goto out; ++ } ++ ++ if (retlen < len) { ++ D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB return short read " ++ "(%zd bytes not %d) for block at %08x\n", retlen, len, jeb->offset)); ++ ret = -EIO; ++ goto out; ++ } ++ ++ /* Special check for first two pages */ ++ for (page = 0; page < 2 * oob_size; page += oob_size) { ++ /* Check for bad block marker */ ++ if (buf[page+c->badblock_pos] != 0xff) { ++ D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Bad or failed block at %08x\n",jeb->offset)); ++ /* Return 2 for bad and 3 for failed block ++ bad goes to list_bad and failed to list_erase */ ++ ret = (!page) ? 2 : 3; ++ goto out; ++ } ++ for(i = 0; i < oob_size ; i++) { ++ /* Yeah, we know about the cleanmarker. */ ++ if (mode && i >= c->fsdata_pos && ++ i < c->fsdata_pos+c->fsdata_len) ++ continue; ++ ++ if (buf[page+i] != 0xFF) { ++ D2(printk(KERN_DEBUG "Found %02x at %x in OOB for %08x\n", ++ buf[page+i], page+i, jeb->offset)); ++ ret = 1; ++ goto out; ++ } ++ } ++ /* only the first page can contain a cleanmarker !*/ ++ mode = 0; ++ } ++ ++ /* we know, we are aligned :) */ ++ for (; page < len; page += sizeof(long)) { ++ unsigned long dat = *(unsigned long *)(&buf[page]); ++ if(dat != -1) { ++ ret = 1; ++ goto out; ++ } ++ } ++ ++out: ++ kfree(buf); ++ ++ return ret; ++} ++ ++/* ++* Scan for a valid cleanmarker and for bad blocks ++* For virtual blocks (concatenated physical blocks) check the cleanmarker ++* only in the first page of the first physical block, but scan for bad blocks in all ++* physical blocks ++*/ ++int jffs2_check_nand_cleanmarker (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) ++{ ++ struct jffs2_unknown_node n; ++ unsigned char buf[32]; ++ unsigned char *p; ++ int ret, i, cnt, retval = 0; ++ size_t retlen, offset; ++ int oob_size; ++ ++ offset = jeb->offset; ++ oob_size = c->mtd->oobsize; ++ ++ /* Loop through the physical blocks */ ++ for (cnt = 0; cnt < (c->sector_size / c->mtd->erasesize); cnt++) { ++ /* ++ * We read oob data from page 0 and 1 of the block. ++ * page 0 contains cleanmarker and badblock info ++ * page 1 contains failure count of this block ++ */ ++ ret = c->mtd->read_oob (c->mtd, offset, oob_size << 1, &retlen, buf); ++ ++ if (ret) { ++ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB failed %d for block at %08x\n", ret, jeb->offset)); ++ return ret; ++ } ++ if (retlen < (oob_size << 1)) { ++ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB return short read (%zd bytes not %d) for block at %08x\n", retlen, oob_size << 1, jeb->offset)); ++ return -EIO; ++ } ++ ++ /* Check for bad block marker */ ++ if (buf[c->badblock_pos] != 0xff) { ++ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Bad block at %08x (has %02x %02x in badblock_pos %d\n", ++ jeb->offset, buf[c->badblock_pos], buf[c->badblock_pos + oob_size], c->badblock_pos)); ++ return 2; ++ } ++ ++ /* Check for failure counter in the second page */ ++ if (buf[c->badblock_pos + oob_size] != 0xff) { ++ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Block marked as failed at %08x, fail count:%d\n", jeb->offset, buf[c->badblock_pos + oob_size])); ++ return 3; ++ } ++ ++ /* Check cleanmarker only on the first physical block */ ++ if (!cnt) { ++ n.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK); ++ n.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER); ++ n.totlen = cpu_to_je32 (8); ++ p = (unsigned char *) &n; ++ ++ for (i = 0; i < c->fsdata_len; i++) { ++ if (buf[c->fsdata_pos + i] != p[i]) { ++ retval = 1; ++ } ++ } ++ D1(if (retval == 1) { ++ printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Cleanmarker node not detected in block at %08x\n", jeb->offset); ++ printk(KERN_WARNING "OOB at %08x was ", offset); ++ for (i=0; i < oob_size; i++) { ++ printk("%02x ", buf[i]); ++ } ++ printk("\n"); ++ }) ++ } ++ offset += c->mtd->erasesize; ++ } ++ return retval; ++} ++ ++int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) ++{ ++ struct jffs2_unknown_node n; ++ int ret; ++ size_t retlen; ++ ++ n.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER); ++ n.totlen = cpu_to_je32(8); ++ ++ ret = jffs2_flash_write_oob(c, jeb->offset + c->fsdata_pos, c->fsdata_len, &retlen, (unsigned char *)&n); ++ ++ if (ret) { ++ D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Write failed for block at %08x: error %d\n", jeb->offset, ret)); ++ return ret; ++ } ++ if (retlen != c->fsdata_len) { ++ D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Short write for block at %08x: %zd not %d\n", jeb->offset, retlen, c->fsdata_len)); ++ return ret; ++ } ++ return 0; ++} ++ ++/* ++ * We try to get the failure count of this block. ++ */ ++int jffs2_nand_read_failcnt(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) { ++ ++ unsigned char buf[16]; ++ int ret; ++ size_t retlen; ++ int oob_size; ++ ++ oob_size = c->mtd->oobsize; ++ ++ ret = c->mtd->read_oob(c->mtd, jeb->offset + c->mtd->oobblock, oob_size , &retlen, buf); ++ ++ if (ret) { ++ D1(printk(KERN_WARNING "jffs2_nand_read_failcnt(): Read OOB failed %d for block at %08x\n", ret, jeb->offset)); ++ return ret; ++ } ++ ++ if (retlen < oob_size) { ++ D1(printk(KERN_WARNING "jffs2_nand_read_failcnt(): Read OOB return short read (%zd bytes not %d) for block at %08x\n", retlen, oob_size, jeb->offset)); ++ return -EIO; ++ } ++ ++ jeb->bad_count = buf[c->badblock_pos]; ++ return 0; ++} ++ ++/* ++ * On NAND we try to mark this block bad. We try to write how often ++ * the block was erased and mark it finaly bad, if the count ++ * is > MAX_ERASE_FAILURES. We read this information on mount ! ++ * jeb->bad_count contains the count before this erase. ++ * Don't care about failures. This block remains on the erase-pending ++ * or badblock list as long as nobody manipulates the flash with ++ * a bootloader or something like that. ++ */ ++ ++int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) ++{ ++ unsigned char buf = 0x0; ++ int ret; ++ size_t retlen; ++ ++ /* if the count is < max, we try to write the counter to the 2nd page oob area */ ++ if( ++jeb->bad_count < MAX_ERASE_FAILURES) { ++ buf = (unsigned char)jeb->bad_count; ++ c->badblock_pos += c->mtd->oobblock; ++ } ++ ++ ret = jffs2_flash_write_oob(c, jeb->offset + c->badblock_pos, 1, &retlen, &buf); ++ ++ if (ret) { ++ D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Write failed for block at %08x: error %d\n", jeb->offset, ret)); ++ return ret; ++ } ++ if (retlen != 1) { ++ D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Short write for block at %08x: %zd not 1\n", jeb->offset, retlen)); ++ return ret; ++ } ++ return 0; ++} ++ ++#define JFFS2_OOB_ECCPOS0 0 ++#define JFFS2_OOB_ECCPOS1 1 ++#define JFFS2_OOB_ECCPOS2 2 ++#define JFFS2_OOB_ECCPOS3 3 ++#define JFFS2_OOB_ECCPOS4 6 ++#define JFFS2_OOB_ECCPOS5 7 ++ ++#define NAND_JFFS2_OOB8_FSDAPOS 6 ++#define NAND_JFFS2_OOB16_FSDAPOS 8 ++#define NAND_JFFS2_OOB8_FSDALEN 2 ++#define NAND_JFFS2_OOB16_FSDALEN 8 ++ ++static struct nand_oobinfo jffs2_oobinfo_swecc = { ++ .useecc = 1, ++ .eccpos = {JFFS2_OOB_ECCPOS0, JFFS2_OOB_ECCPOS1, JFFS2_OOB_ECCPOS2, ++ JFFS2_OOB_ECCPOS3, JFFS2_OOB_ECCPOS4, JFFS2_OOB_ECCPOS5} ++}; ++ ++static struct nand_oobinfo jffs2_oobinfo_docecc = { ++ .useecc = 1, ++ .eccpos = {0,1,2,3,4,5} ++}; ++ ++ ++ ++int jffs2_nand_flash_setup(struct jffs2_sb_info *c) ++{ ++ /* Cleanmarker is out-of-band, so inline size zero */ ++ c->cleanmarker_size = 0; ++ ++ /* Initialise write buffer */ ++ c->wbuf_pagesize = c->mtd->oobblock; ++ c->wbuf_ofs = 0xFFFFFFFF; ++ ++ /* FIXME: If we had a generic way of describing the hardware's ++ use of OOB area, we could perhaps make this generic too. */ ++ switch(c->mtd->ecctype) { ++ case MTD_ECC_SW: ++ D1(printk(KERN_DEBUG "JFFS2 using software ECC\n")); ++ c->oobinfo = &jffs2_oobinfo_swecc; ++ if (c->mtd->oobsize == 8) { ++ c->fsdata_pos = NAND_JFFS2_OOB8_FSDAPOS; ++ c->fsdata_len = NAND_JFFS2_OOB8_FSDALEN; ++ } else { ++ c->fsdata_pos = NAND_JFFS2_OOB16_FSDAPOS; ++ c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN; ++ } ++ c->badblock_pos = NAND_BADBLOCK_POS; ++ break; ++ ++ case MTD_ECC_RS_DiskOnChip: ++ D1(printk(KERN_DEBUG "JFFS2 using DiskOnChip hardware ECC\n")); ++ c->oobinfo = &jffs2_oobinfo_docecc; ++ c->fsdata_pos = 6; ++ c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN; ++ c->badblock_pos = 15; ++ break; ++ ++ default: ++ printk("JFFS2 doesn't yet know how to handle ECC type %d\n", ++ c->mtd->ecctype); ++ return -EINVAL; ++ } ++ ++ c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); ++ if (!c->wbuf) ++ return -ENOMEM; ++ ++#ifdef BREAKME ++ if (!brokenbuf) ++ brokenbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); ++ if (!brokenbuf) { ++ kfree(c->wbuf); ++ return -ENOMEM; ++ } ++ memset(brokenbuf, 0xdb, c->wbuf_pagesize); ++#endif ++ return 0; ++} ++ ++void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c) ++{ ++ kfree(c->wbuf); ++} +diff -Nurb linux-mips-2.4.27/fs/jffs2/write.c linux/fs/jffs2/write.c +--- linux-mips-2.4.27/fs/jffs2/write.c 2003-11-17 02:07:44.000000000 +0100 ++++ linux/fs/jffs2/write.c 2004-11-19 10:25:12.132164376 +0100 +@@ -1,154 +1,70 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in this directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: write.c,v 1.30.2.2 2003/11/02 13:51:18 dwmw2 Exp $ ++ * $Id: write.c,v 1.80 2004/01/27 13:21:50 dwmw2 Exp $ + * + */ + + #include + #include +-#include ++#include ++#include ++#include + #include + #include "nodelist.h" +-#include + +-/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash, +- fill in the raw_inode while you're at it. */ +-struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri) ++ ++int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri) + { +- struct inode *inode; +- struct super_block *sb = dir_i->i_sb; + struct jffs2_inode_cache *ic; +- struct jffs2_sb_info *c; +- struct jffs2_inode_info *f; +- +- D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode)); +- +- c = JFFS2_SB_INFO(sb); +- memset(ri, 0, sizeof(*ri)); + + ic = jffs2_alloc_inode_cache(); + if (!ic) { +- return ERR_PTR(-ENOMEM); ++ return -ENOMEM; + } +- memset(ic, 0, sizeof(*ic)); +- +- inode = new_inode(sb); + +- if (!inode) { +- jffs2_free_inode_cache(ic); +- return ERR_PTR(-ENOMEM); +- } +- +- /* Alloc jffs2_inode_info when that's split in 2.5 */ ++ memset(ic, 0, sizeof(*ic)); + +- f = JFFS2_INODE_INFO(inode); +- memset(f, 0, sizeof(*f)); + init_MUTEX_LOCKED(&f->sem); + f->inocache = ic; +- inode->i_nlink = f->inocache->nlink = 1; ++ f->inocache->nlink = 1; + f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; +- f->inocache->ino = ri->ino = inode->i_ino = ++c->highest_ino; +- D1(printk(KERN_DEBUG "jffs2_new_inode(): Assigned ino# %d\n", ri->ino)); +- jffs2_add_ino_cache(c, f->inocache); ++ f->inocache->ino = ++c->highest_ino; ++ f->inocache->state = INO_STATE_PRESENT; + +- ri->magic = JFFS2_MAGIC_BITMASK; +- ri->nodetype = JFFS2_NODETYPE_INODE; +- ri->totlen = PAD(sizeof(*ri)); +- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4); +- ri->mode = mode; +- f->highest_version = ri->version = 1; +- ri->uid = current->fsuid; +- if (dir_i->i_mode & S_ISGID) { +- ri->gid = dir_i->i_gid; +- if (S_ISDIR(mode)) +- ri->mode |= S_ISGID; +- } else { +- ri->gid = current->fsgid; +- } +- inode->i_mode = ri->mode; +- inode->i_gid = ri->gid; +- inode->i_uid = ri->uid; +- inode->i_atime = inode->i_ctime = inode->i_mtime = +- ri->atime = ri->mtime = ri->ctime = CURRENT_TIME; +- inode->i_blksize = PAGE_SIZE; +- inode->i_blocks = 0; +- inode->i_size = 0; ++ ri->ino = cpu_to_je32(f->inocache->ino); + +- insert_inode_hash(inode); ++ D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino)); ++ jffs2_add_ino_cache(c, f->inocache); + +- return inode; +-} ++ ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); ++ ri->totlen = cpu_to_je32(PAD(sizeof(*ri))); ++ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); ++ ri->mode = cpu_to_jemode(mode); + +-/* This ought to be in core MTD code. All registered MTD devices +- without writev should have this put in place. Bug the MTD +- maintainer */ +-static int mtd_fake_writev(struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen) +-{ +- unsigned long i; +- size_t totlen = 0, thislen; +- int ret = 0; ++ f->highest_version = 1; ++ ri->version = cpu_to_je32(f->highest_version); + +- for (i=0; iwrite(mtd, to, vecs[i].iov_len, &thislen, vecs[i].iov_base); +- totlen += thislen; +- if (ret || thislen != vecs[i].iov_len) +- break; +- to += vecs[i].iov_len; +- } +- if (retlen) +- *retlen = totlen; +- return ret; +-} +- +- +-static inline int mtd_writev(struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen) +-{ +- if (mtd->writev) +- return mtd->writev(mtd,vecs,count,to,retlen); +- else +- return mtd_fake_writev(mtd, vecs, count, to, retlen); ++ return 0; + } + +-static void writecheck(struct mtd_info *mtd, __u32 ofs) ++#if CONFIG_JFFS2_FS_DEBUG > 0 ++static void writecheck(struct jffs2_sb_info *c, uint32_t ofs) + { + unsigned char buf[16]; +- ssize_t retlen; ++ size_t retlen; + int ret, i; + +- ret = mtd->read(mtd, ofs, 16, &retlen, buf); +- if (ret && retlen != 16) { +- D1(printk(KERN_DEBUG "read failed or short in writecheck(). ret %d, retlen %d\n", ret, retlen)); ++ ret = jffs2_flash_read(c, ofs, 16, &retlen, buf); ++ if (ret || (retlen != 16)) { ++ D1(printk(KERN_DEBUG "read failed or short in writecheck(). ret %d, retlen %zd\n", ret, retlen)); + return; + } + ret = 0; +@@ -157,32 +73,31 @@ + ret = 1; + } + if (ret) { +- printk(KERN_WARNING "ARGH. About to write node to 0x%08x on flash, but there's data already there:\n", ofs); ++ printk(KERN_WARNING "ARGH. About to write node to 0x%08x on flash, but there are data already there:\n", ofs); + printk(KERN_WARNING "0x%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + ofs, + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], + buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]); + } + } +- +- ++#endif + + + /* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it, + write it to the flash, link it into the existing inode/fragment list */ + +-struct jffs2_full_dnode *jffs2_write_dnode(struct inode *inode, struct jffs2_raw_inode *ri, const unsigned char *data, __u32 datalen, __u32 flash_ofs, __u32 *writelen) ++struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode) + + { +- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_raw_node_ref *raw; + struct jffs2_full_dnode *fn; +- ssize_t retlen; ++ size_t retlen; + struct iovec vecs[2]; + int ret; ++ int retried = 0; ++ unsigned long cnt = 2; + +- D1(if(ri->hdr_crc != crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)) { ++ D1(if(je32_to_cpu(ri->hdr_crc) != crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)) { + printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dnode()\n"); + BUG(); + } +@@ -192,10 +107,10 @@ + vecs[1].iov_base = (unsigned char *)data; + vecs[1].iov_len = datalen; + +- writecheck(c->mtd, flash_ofs); ++ D1(writecheck(c, flash_ofs)); + +- if (ri->totlen != sizeof(*ri) + datalen) { +- printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08x) + datalen (0x%08x)\n", ri->totlen, sizeof(*ri), datalen); ++ if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { ++ printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen); + } + raw = jffs2_alloc_raw_node_ref(); + if (!raw) +@@ -206,19 +121,28 @@ + jffs2_free_raw_node_ref(raw); + return ERR_PTR(-ENOMEM); + } +- raw->flash_offset = flash_ofs; +- raw->totlen = PAD(ri->totlen); +- raw->next_phys = NULL; + +- fn->ofs = ri->offset; +- fn->size = ri->dsize; ++ fn->ofs = je32_to_cpu(ri->offset); ++ fn->size = je32_to_cpu(ri->dsize); + fn->frags = 0; ++ ++ /* check number of valid vecs */ ++ if (!datalen || !data) ++ cnt = 1; ++ retry: + fn->raw = raw; + +- ret = mtd_writev(c->mtd, vecs, 2, flash_ofs, &retlen); ++ raw->flash_offset = flash_ofs; ++ raw->__totlen = PAD(sizeof(*ri)+datalen); ++ raw->next_phys = NULL; ++ ++ ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen, ++ (alloc_mode==ALLOC_GC)?0:f->inocache->ino); ++ + if (ret || (retlen != sizeof(*ri) + datalen)) { +- printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %d\n", ++ printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", + sizeof(*ri)+datalen, flash_ofs, ret, retlen); ++ + /* Mark the space as dirtied */ + if (retlen) { + /* Doesn't belong to any inode */ +@@ -229,48 +153,96 @@ + seem corrupted, in which case the scan would skip over + any node we write before the original intended end of + this node */ +- jffs2_add_physical_node_ref(c, raw, sizeof(*ri)+datalen, 1); ++ raw->flash_offset |= REF_OBSOLETE; ++ jffs2_add_physical_node_ref(c, raw); + jffs2_mark_node_obsolete(c, raw); + } else { + printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); + jffs2_free_raw_node_ref(raw); + } ++ if (!retried && alloc_mode != ALLOC_NORETRY && (raw = jffs2_alloc_raw_node_ref())) { ++ /* Try to reallocate space and retry */ ++ uint32_t dummy; ++ struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size]; ++ ++ retried = 1; ++ ++ D1(printk(KERN_DEBUG "Retrying failed write.\n")); ++ ++ ACCT_SANITY_CHECK(c,jeb); ++ D1(ACCT_PARANOIA_CHECK(jeb)); ++ ++ if (alloc_mode == ALLOC_GC) { ++ ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, &dummy); ++ } else { ++ /* Locking pain */ ++ up(&f->sem); ++ jffs2_complete_reservation(c); ++ ++ ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, &dummy, alloc_mode); ++ down(&f->sem); ++ } ++ ++ if (!ret) { ++ D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); ++ ++ ACCT_SANITY_CHECK(c,jeb); ++ D1(ACCT_PARANOIA_CHECK(jeb)); + ++ goto retry; ++ } ++ D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); ++ jffs2_free_raw_node_ref(raw); ++ } + /* Release the full_dnode which is now useless, and return */ + jffs2_free_full_dnode(fn); +- if (writelen) +- *writelen = retlen; + return ERR_PTR(ret?ret:-EIO); + } + /* Mark the space used */ +- jffs2_add_physical_node_ref(c, raw, retlen, 0); ++ /* If node covers at least a whole page, or if it starts at the ++ beginning of a page and runs to the end of the file, or if ++ it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. ++ */ ++ if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) || ++ ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) && ++ (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) { ++ raw->flash_offset |= REF_PRISTINE; ++ } else { ++ raw->flash_offset |= REF_NORMAL; ++ } ++ jffs2_add_physical_node_ref(c, raw); + + /* Link into per-inode list */ + raw->next_in_ino = f->inocache->nodes; + f->inocache->nodes = raw; + +- D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n", flash_ofs, ri->dsize, ri->csize, ri->node_crc, ri->data_crc, ri->totlen)); +- if (writelen) +- *writelen = retlen; ++ D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n", ++ flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize), ++ je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc), ++ je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen))); ++ ++ if (retried) { ++ ACCT_SANITY_CHECK(c,NULL); ++ } + +- f->inocache->nodes = raw; + return fn; + } + +-struct jffs2_full_dirent *jffs2_write_dirent(struct inode *inode, struct jffs2_raw_dirent *rd, const unsigned char *name, __u32 namelen, __u32 flash_ofs, __u32 *writelen) ++struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode) + { +- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_raw_node_ref *raw; + struct jffs2_full_dirent *fd; +- ssize_t retlen; ++ size_t retlen; + struct iovec vecs[2]; ++ int retried = 0; + int ret; + +- D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", rd->pino, name, name, rd->ino, rd->name_crc)); +- writecheck(c->mtd, flash_ofs); ++ D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", ++ je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino), ++ je32_to_cpu(rd->name_crc))); ++ D1(writecheck(c, flash_ofs)); + +- D1(if(rd->hdr_crc != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { ++ D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { + printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n"); + BUG(); + } +@@ -291,44 +263,414 @@ + jffs2_free_raw_node_ref(raw); + return ERR_PTR(-ENOMEM); + } +- raw->flash_offset = flash_ofs; +- raw->totlen = PAD(rd->totlen); +- raw->next_in_ino = f->inocache->nodes; +- f->inocache->nodes = raw; +- raw->next_phys = NULL; + +- fd->version = rd->version; +- fd->ino = rd->ino; ++ fd->version = je32_to_cpu(rd->version); ++ fd->ino = je32_to_cpu(rd->ino); + fd->nhash = full_name_hash(name, strlen(name)); + fd->type = rd->type; + memcpy(fd->name, name, namelen); + fd->name[namelen]=0; ++ ++ retry: + fd->raw = raw; + +- ret = mtd_writev(c->mtd, vecs, 2, flash_ofs, &retlen); ++ raw->flash_offset = flash_ofs; ++ raw->__totlen = PAD(sizeof(*rd)+namelen); ++ raw->next_phys = NULL; ++ ++ ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen, ++ (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino)); + if (ret || (retlen != sizeof(*rd) + namelen)) { +- printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %d\n", ++ printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", + sizeof(*rd)+namelen, flash_ofs, ret, retlen); + /* Mark the space as dirtied */ + if (retlen) { +- jffs2_add_physical_node_ref(c, raw, sizeof(*rd)+namelen, 1); ++ raw->next_in_ino = NULL; ++ raw->flash_offset |= REF_OBSOLETE; ++ jffs2_add_physical_node_ref(c, raw); + jffs2_mark_node_obsolete(c, raw); + } else { + printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); + jffs2_free_raw_node_ref(raw); + } ++ if (!retried && (raw = jffs2_alloc_raw_node_ref())) { ++ /* Try to reallocate space and retry */ ++ uint32_t dummy; ++ struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size]; ++ ++ retried = 1; ++ ++ D1(printk(KERN_DEBUG "Retrying failed write.\n")); ++ ++ ACCT_SANITY_CHECK(c,jeb); ++ D1(ACCT_PARANOIA_CHECK(jeb)); ++ ++ if (alloc_mode == ALLOC_GC) { ++ ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, &dummy); ++ } else { ++ /* Locking pain */ ++ up(&f->sem); ++ jffs2_complete_reservation(c); ++ ++ ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, &dummy, alloc_mode); ++ down(&f->sem); ++ } + ++ if (!ret) { ++ D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); ++ ACCT_SANITY_CHECK(c,jeb); ++ D1(ACCT_PARANOIA_CHECK(jeb)); ++ goto retry; ++ } ++ D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); ++ jffs2_free_raw_node_ref(raw); ++ } + /* Release the full_dnode which is now useless, and return */ + jffs2_free_full_dirent(fd); +- if (writelen) +- *writelen = retlen; + return ERR_PTR(ret?ret:-EIO); + } + /* Mark the space used */ +- jffs2_add_physical_node_ref(c, raw, retlen, 0); +- if (writelen) +- *writelen = retlen; ++ raw->flash_offset |= REF_PRISTINE; ++ jffs2_add_physical_node_ref(c, raw); + ++ raw->next_in_ino = f->inocache->nodes; + f->inocache->nodes = raw; ++ ++ if (retried) { ++ ACCT_SANITY_CHECK(c,NULL); ++ } ++ + return fd; + } ++ ++/* The OS-specific code fills in the metadata in the jffs2_raw_inode for us, so that ++ we don't have to go digging in struct inode or its equivalent. It should set: ++ mode, uid, gid, (starting)isize, atime, ctime, mtime */ ++int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, ++ struct jffs2_raw_inode *ri, unsigned char *buf, ++ uint32_t offset, uint32_t writelen, uint32_t *retlen) ++{ ++ int ret = 0; ++ uint32_t writtenlen = 0; ++ ++ D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n", ++ f->inocache->ino, offset, writelen)); ++ ++ while(writelen) { ++ struct jffs2_full_dnode *fn; ++ unsigned char *comprbuf = NULL; ++ unsigned char comprtype = JFFS2_COMPR_NONE; ++ uint32_t phys_ofs, alloclen; ++ uint32_t datalen, cdatalen; ++ int retried = 0; ++ ++ retry: ++ D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset)); ++ ++ ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL); ++ if (ret) { ++ D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret)); ++ break; ++ } ++ down(&f->sem); ++ datalen = min_t(uint32_t, writelen, PAGE_CACHE_SIZE - (offset & (PAGE_CACHE_SIZE-1))); ++ cdatalen = min_t(uint32_t, alloclen - sizeof(*ri), datalen); ++ ++ comprtype = jffs2_compress(buf, &comprbuf, &datalen, &cdatalen); ++ ++ ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); ++ ri->totlen = cpu_to_je32(sizeof(*ri) + cdatalen); ++ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); ++ ++ ri->ino = cpu_to_je32(f->inocache->ino); ++ ri->version = cpu_to_je32(++f->highest_version); ++ ri->isize = cpu_to_je32(max(je32_to_cpu(ri->isize), offset + datalen)); ++ ri->offset = cpu_to_je32(offset); ++ ri->csize = cpu_to_je32(cdatalen); ++ ri->dsize = cpu_to_je32(datalen); ++ ri->compr = comprtype; ++ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); ++ ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen)); ++ ++ fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, phys_ofs, ALLOC_NORETRY); ++ ++ jffs2_free_comprbuf(comprbuf, buf); ++ ++ if (IS_ERR(fn)) { ++ ret = PTR_ERR(fn); ++ up(&f->sem); ++ jffs2_complete_reservation(c); ++ if (!retried) { ++ /* Write error to be retried */ ++ retried = 1; ++ D1(printk(KERN_DEBUG "Retrying node write in jffs2_write_inode_range()\n")); ++ goto retry; ++ } ++ break; ++ } ++ ret = jffs2_add_full_dnode_to_inode(c, f, fn); ++ if (f->metadata) { ++ jffs2_mark_node_obsolete(c, f->metadata->raw); ++ jffs2_free_full_dnode(f->metadata); ++ f->metadata = NULL; ++ } ++ if (ret) { ++ /* Eep */ ++ D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret)); ++ jffs2_mark_node_obsolete(c, fn->raw); ++ jffs2_free_full_dnode(fn); ++ ++ up(&f->sem); ++ jffs2_complete_reservation(c); ++ break; ++ } ++ up(&f->sem); ++ jffs2_complete_reservation(c); ++ if (!datalen) { ++ printk(KERN_WARNING "Eep. We didn't actually write any data in jffs2_write_inode_range()\n"); ++ ret = -EIO; ++ break; ++ } ++ D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen)); ++ writtenlen += datalen; ++ offset += datalen; ++ writelen -= datalen; ++ buf += datalen; ++ } ++ *retlen = writtenlen; ++ return ret; ++} ++ ++int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen) ++{ ++ struct jffs2_raw_dirent *rd; ++ struct jffs2_full_dnode *fn; ++ struct jffs2_full_dirent *fd; ++ uint32_t alloclen, phys_ofs; ++ int ret; ++ ++ /* Try to reserve enough space for both node and dirent. ++ * Just the node will do for now, though ++ */ ++ ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL); ++ D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); ++ if (ret) { ++ up(&f->sem); ++ return ret; ++ } ++ ++ ri->data_crc = cpu_to_je32(0); ++ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); ++ ++ fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); ++ ++ D1(printk(KERN_DEBUG "jffs2_do_create created file with mode 0x%x\n", ++ jemode_to_cpu(ri->mode))); ++ ++ if (IS_ERR(fn)) { ++ D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n")); ++ /* Eeek. Wave bye bye */ ++ up(&f->sem); ++ jffs2_complete_reservation(c); ++ return PTR_ERR(fn); ++ } ++ /* No data here. Only a metadata node, which will be ++ obsoleted by the first data write ++ */ ++ f->metadata = fn; ++ ++ up(&f->sem); ++ jffs2_complete_reservation(c); ++ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); ++ ++ if (ret) { ++ /* Eep. */ ++ D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n")); ++ return ret; ++ } ++ ++ rd = jffs2_alloc_raw_dirent(); ++ if (!rd) { ++ /* Argh. Now we treat it like a normal delete */ ++ jffs2_complete_reservation(c); ++ return -ENOMEM; ++ } ++ ++ down(&dir_f->sem); ++ ++ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); ++ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); ++ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); ++ ++ rd->pino = cpu_to_je32(dir_f->inocache->ino); ++ rd->version = cpu_to_je32(++dir_f->highest_version); ++ rd->ino = ri->ino; ++ rd->mctime = ri->ctime; ++ rd->nsize = namelen; ++ rd->type = DT_REG; ++ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); ++ rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); ++ ++ fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); ++ ++ jffs2_free_raw_dirent(rd); ++ ++ if (IS_ERR(fd)) { ++ /* dirent failed to write. Delete the inode normally ++ as if it were the final unlink() */ ++ jffs2_complete_reservation(c); ++ up(&dir_f->sem); ++ return PTR_ERR(fd); ++ } ++ ++ /* Link the fd into the inode's list, obsoleting an old ++ one if necessary. */ ++ jffs2_add_fd_to_list(c, fd, &dir_f->dents); ++ ++ jffs2_complete_reservation(c); ++ up(&dir_f->sem); ++ ++ return 0; ++} ++ ++ ++int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, ++ const char *name, int namelen, struct jffs2_inode_info *dead_f) ++{ ++ struct jffs2_raw_dirent *rd; ++ struct jffs2_full_dirent *fd; ++ uint32_t alloclen, phys_ofs; ++ int ret; ++ ++ rd = jffs2_alloc_raw_dirent(); ++ if (!rd) ++ return -ENOMEM; ++ ++ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_DELETION); ++ if (ret) { ++ jffs2_free_raw_dirent(rd); ++ return ret; ++ } ++ ++ down(&dir_f->sem); ++ ++ /* Build a deletion node */ ++ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); ++ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); ++ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); ++ ++ rd->pino = cpu_to_je32(dir_f->inocache->ino); ++ rd->version = cpu_to_je32(++dir_f->highest_version); ++ rd->ino = cpu_to_je32(0); ++ rd->mctime = cpu_to_je32(get_seconds()); ++ rd->nsize = namelen; ++ rd->type = DT_UNKNOWN; ++ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); ++ rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); ++ ++ fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION); ++ ++ jffs2_free_raw_dirent(rd); ++ ++ if (IS_ERR(fd)) { ++ jffs2_complete_reservation(c); ++ up(&dir_f->sem); ++ return PTR_ERR(fd); ++ } ++ ++ /* File it. This will mark the old one obsolete. */ ++ jffs2_add_fd_to_list(c, fd, &dir_f->dents); ++ ++ up(&dir_f->sem); ++ ++ /* dead_f is NULL if this was a rename not a real unlink */ ++ /* Also catch the !f->inocache case, where there was a dirent ++ pointing to an inode which didn't exist. */ ++ if (dead_f && dead_f->inocache) { ++ ++ down(&dead_f->sem); ++ ++ while (dead_f->dents) { ++ /* There can be only deleted ones */ ++ fd = dead_f->dents; ++ ++ dead_f->dents = fd->next; ++ ++ if (fd->ino) { ++ printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n", ++ dead_f->inocache->ino, fd->name, fd->ino); ++ } else { ++ D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", fd->name, dead_f->inocache->ino)); ++ } ++ jffs2_mark_node_obsolete(c, fd->raw); ++ jffs2_free_full_dirent(fd); ++ } ++ ++ dead_f->inocache->nlink--; ++ /* NB: Caller must set inode nlink if appropriate */ ++ up(&dead_f->sem); ++ } ++ ++ jffs2_complete_reservation(c); ++ ++ return 0; ++} ++ ++ ++int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen) ++{ ++ struct jffs2_raw_dirent *rd; ++ struct jffs2_full_dirent *fd; ++ uint32_t alloclen, phys_ofs; ++ int ret; ++ ++ rd = jffs2_alloc_raw_dirent(); ++ if (!rd) ++ return -ENOMEM; ++ ++ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); ++ if (ret) { ++ jffs2_free_raw_dirent(rd); ++ return ret; ++ } ++ ++ down(&dir_f->sem); ++ ++ /* Build a deletion node */ ++ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); ++ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); ++ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); ++ ++ rd->pino = cpu_to_je32(dir_f->inocache->ino); ++ rd->version = cpu_to_je32(++dir_f->highest_version); ++ rd->ino = cpu_to_je32(ino); ++ rd->mctime = cpu_to_je32(get_seconds()); ++ rd->nsize = namelen; ++ ++ rd->type = type; ++ ++ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); ++ rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); ++ ++ fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL); ++ ++ jffs2_free_raw_dirent(rd); ++ ++ if (IS_ERR(fd)) { ++ jffs2_complete_reservation(c); ++ up(&dir_f->sem); ++ return PTR_ERR(fd); ++ } ++ ++ /* File it. This will mark the old one obsolete. */ ++ jffs2_add_fd_to_list(c, fd, &dir_f->dents); ++ ++ jffs2_complete_reservation(c); ++ up(&dir_f->sem); ++ ++ return 0; ++} +diff -Nurb linux-mips-2.4.27/fs/jffs2/writev.c linux/fs/jffs2/writev.c +--- linux-mips-2.4.27/fs/jffs2/writev.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/fs/jffs2/writev.c 2004-11-19 10:25:12.134164072 +0100 +@@ -0,0 +1,50 @@ ++/* ++ * JFFS2 -- Journalling Flash File System, Version 2. ++ * ++ * Copyright (C) 2001, 2002 Red Hat, Inc. ++ * ++ * Created by David Woodhouse ++ * ++ * For licensing information, see the file 'LICENCE' in this directory. ++ * ++ * $Id: writev.c,v 1.4 2003/10/04 08:33:07 dwmw2 Exp $ ++ * ++ */ ++ ++#include ++#include ++#include "nodelist.h" ++ ++/* This ought to be in core MTD code. All registered MTD devices ++ without writev should have this put in place. Bug the MTD ++ maintainer */ ++static inline int mtd_fake_writev(struct mtd_info *mtd, const struct iovec *vecs, ++ unsigned long count, loff_t to, size_t *retlen) ++{ ++ unsigned long i; ++ size_t totlen = 0, thislen; ++ int ret = 0; ++ ++ for (i=0; iwrite(mtd, to, vecs[i].iov_len, &thislen, vecs[i].iov_base); ++ totlen += thislen; ++ if (ret || thislen != vecs[i].iov_len) ++ break; ++ to += vecs[i].iov_len; ++ } ++ if (retlen) ++ *retlen = totlen; ++ return ret; ++} ++ ++int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs, ++ unsigned long count, loff_t to, size_t *retlen) ++{ ++ if (c->mtd->writev) ++ return c->mtd->writev(c->mtd, vecs, count, to, retlen); ++ else ++ return mtd_fake_writev(c->mtd, vecs, count, to, retlen); ++} ++ +diff -Nurb linux-mips-2.4.27/include/linux/jffs2.h linux/include/linux/jffs2.h +--- linux-mips-2.4.27/include/linux/jffs2.h 2002-06-27 00:36:46.000000000 +0200 ++++ linux/include/linux/jffs2.h 2004-11-19 10:25:12.139163312 +0100 +@@ -1,50 +1,30 @@ + /* + * JFFS2 -- Journalling Flash File System, Version 2. + * +- * Copyright (C) 2001 Red Hat, Inc. ++ * Copyright (C) 2001-2003 Red Hat, Inc. + * +- * Created by David Woodhouse ++ * Created by David Woodhouse + * +- * The original JFFS, from which the design for JFFS2 was derived, +- * was designed and implemented by Axis Communications AB. ++ * For licensing information, see the file 'LICENCE' in the ++ * jffs2 directory. + * +- * The contents of this file are subject to the Red Hat eCos Public +- * License Version 1.1 (the "Licence"); you may not use this file +- * except in compliance with the Licence. You may obtain a copy of +- * the Licence at http://www.redhat.com/ +- * +- * Software distributed under the Licence is distributed on an "AS IS" +- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. +- * See the Licence for the specific language governing rights and +- * limitations under the Licence. +- * +- * The Original Code is JFFS2 - Journalling Flash File System, version 2 +- * +- * Alternatively, the contents of this file may be used under the +- * terms of the GNU General Public License version 2 (the "GPL"), in +- * which case the provisions of the GPL are applicable instead of the +- * above. If you wish to allow the use of your version of this file +- * only under the terms of the GPL and not to allow others to use your +- * version of this file under the RHEPL, indicate your decision by +- * deleting the provisions above and replace them with the notice and +- * other provisions required by the GPL. If you do not delete the +- * provisions above, a recipient may use your version of this file +- * under either the RHEPL or the GPL. +- * +- * $Id: jffs2.h,v 1.19 2001/10/09 13:20:23 dwmw2 Exp $ ++ * $Id: jffs2.h,v 1.31 2003/10/04 08:33:05 dwmw2 Exp $ + * + */ + + #ifndef __LINUX_JFFS2_H__ + #define __LINUX_JFFS2_H__ + +-#include ++/* You must include something which defines the C99 uintXX_t types. ++ We don't do it from here because this file is used in too many ++ different environments. */ ++ + #define JFFS2_SUPER_MAGIC 0x72b6 + + /* Values we may expect to find in the 'magic' field */ + #define JFFS2_OLD_MAGIC_BITMASK 0x1984 + #define JFFS2_MAGIC_BITMASK 0x1985 +-#define KSAMTIB_CIGAM_2SFFJ 0x5981 /* For detecting wrong-endian fs */ ++#define KSAMTIB_CIGAM_2SFFJ 0x8519 /* For detecting wrong-endian fs */ + #define JFFS2_EMPTY_BITMASK 0xffff + #define JFFS2_DIRTY_BITMASK 0x0000 + +@@ -78,16 +58,12 @@ + #define JFFS2_NODETYPE_DIRENT (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 1) + #define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2) + #define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) ++#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4) + + // Maybe later... + //#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) + //#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4) + +-/* Same as the non_ECC versions, but with extra space for real +- * ECC instead of just the checksum. For use on NAND flash +- */ +-//#define JFFS2_NODETYPE_DIRENT_ECC (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 5) +-//#define JFFS2_NODETYPE_INODE_ECC (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 6) + + #define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at + mount time, don't wait for it to +@@ -96,31 +72,79 @@ + compression type */ + + ++/* These can go once we've made sure we've caught all uses without ++ byteswapping */ ++ ++typedef struct { ++ uint32_t v32; ++} __attribute__((packed)) jint32_t; ++ ++typedef struct { ++ uint32_t m; ++} __attribute__((packed)) jmode_t; ++ ++typedef struct { ++ uint16_t v16; ++} __attribute__((packed)) jint16_t; ++ ++#define JFFS2_NATIVE_ENDIAN ++ ++/* Note we handle mode bits conversion from JFFS2 (i.e. Linux) to/from ++ whatever OS we're actually running on here too. */ ++ ++#if defined(JFFS2_NATIVE_ENDIAN) ++#define cpu_to_je16(x) ((jint16_t){x}) ++#define cpu_to_je32(x) ((jint32_t){x}) ++#define cpu_to_jemode(x) ((jmode_t){os_to_jffs2_mode(x)}) ++ ++#define je16_to_cpu(x) ((x).v16) ++#define je32_to_cpu(x) ((x).v32) ++#define jemode_to_cpu(x) (jffs2_to_os_mode((x).m)) ++#elif defined(JFFS2_BIG_ENDIAN) ++#define cpu_to_je16(x) ((jint16_t){cpu_to_be16(x)}) ++#define cpu_to_je32(x) ((jint32_t){cpu_to_be32(x)}) ++#define cpu_to_jemode(x) ((jmode_t){cpu_to_be32(os_to_jffs2_mode(x))}) ++ ++#define je16_to_cpu(x) (be16_to_cpu(x.v16)) ++#define je32_to_cpu(x) (be32_to_cpu(x.v32)) ++#define jemode_to_cpu(x) (be32_to_cpu(jffs2_to_os_mode((x).m))) ++#elif defined(JFFS2_LITTLE_ENDIAN) ++#define cpu_to_je16(x) ((jint16_t){cpu_to_le16(x)}) ++#define cpu_to_je32(x) ((jint32_t){cpu_to_le32(x)}) ++#define cpu_to_jemode(x) ((jmode_t){cpu_to_le32(os_to_jffs2_mode(x))}) ++ ++#define je16_to_cpu(x) (le16_to_cpu(x.v16)) ++#define je32_to_cpu(x) (le32_to_cpu(x.v32)) ++#define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m))) ++#else ++#error wibble ++#endif ++ + struct jffs2_unknown_node + { + /* All start like this */ +- __u16 magic; +- __u16 nodetype; +- __u32 totlen; /* So we can skip over nodes we don't grok */ +- __u32 hdr_crc; ++ jint16_t magic; ++ jint16_t nodetype; ++ jint32_t totlen; /* So we can skip over nodes we don't grok */ ++ jint32_t hdr_crc; + } __attribute__((packed)); + + struct jffs2_raw_dirent + { +- __u16 magic; +- __u16 nodetype; /* == JFFS_NODETYPE_DIRENT */ +- __u32 totlen; +- __u32 hdr_crc; +- __u32 pino; +- __u32 version; +- __u32 ino; /* == zero for unlink */ +- __u32 mctime; +- __u8 nsize; +- __u8 type; +- __u8 unused[2]; +- __u32 node_crc; +- __u32 name_crc; +- __u8 name[0]; ++ jint16_t magic; ++ jint16_t nodetype; /* == JFFS_NODETYPE_DIRENT */ ++ jint32_t totlen; ++ jint32_t hdr_crc; ++ jint32_t pino; ++ jint32_t version; ++ jint32_t ino; /* == zero for unlink */ ++ jint32_t mctime; ++ uint8_t nsize; ++ uint8_t type; ++ uint8_t unused[2]; ++ jint32_t node_crc; ++ jint32_t name_crc; ++ uint8_t name[0]; + } __attribute__((packed)); + + /* The JFFS2 raw inode structure: Used for storage on physical media. */ +@@ -131,28 +155,28 @@ + */ + struct jffs2_raw_inode + { +- __u16 magic; /* A constant magic number. */ +- __u16 nodetype; /* == JFFS_NODETYPE_INODE */ +- __u32 totlen; /* Total length of this node (inc data, etc.) */ +- __u32 hdr_crc; +- __u32 ino; /* Inode number. */ +- __u32 version; /* Version number. */ +- __u32 mode; /* The file's type or mode. */ +- __u16 uid; /* The file's owner. */ +- __u16 gid; /* The file's group. */ +- __u32 isize; /* Total resultant size of this inode (used for truncations) */ +- __u32 atime; /* Last access time. */ +- __u32 mtime; /* Last modification time. */ +- __u32 ctime; /* Change time. */ +- __u32 offset; /* Where to begin to write. */ +- __u32 csize; /* (Compressed) data size */ +- __u32 dsize; /* Size of the node's data. (after decompression) */ +- __u8 compr; /* Compression algorithm used */ +- __u8 usercompr; /* Compression algorithm requested by the user */ +- __u16 flags; /* See JFFS2_INO_FLAG_* */ +- __u32 data_crc; /* CRC for the (compressed) data. */ +- __u32 node_crc; /* CRC for the raw inode (excluding data) */ +-// __u8 data[dsize]; ++ jint16_t magic; /* A constant magic number. */ ++ jint16_t nodetype; /* == JFFS_NODETYPE_INODE */ ++ jint32_t totlen; /* Total length of this node (inc data, etc.) */ ++ jint32_t hdr_crc; ++ jint32_t ino; /* Inode number. */ ++ jint32_t version; /* Version number. */ ++ jmode_t mode; /* The file's type or mode. */ ++ jint16_t uid; /* The file's owner. */ ++ jint16_t gid; /* The file's group. */ ++ jint32_t isize; /* Total resultant size of this inode (used for truncations) */ ++ jint32_t atime; /* Last access time. */ ++ jint32_t mtime; /* Last modification time. */ ++ jint32_t ctime; /* Change time. */ ++ jint32_t offset; /* Where to begin to write. */ ++ jint32_t csize; /* (Compressed) data size */ ++ jint32_t dsize; /* Size of the node's data. (after decompression) */ ++ uint8_t compr; /* Compression algorithm used */ ++ uint8_t usercompr; /* Compression algorithm requested by the user */ ++ jint16_t flags; /* See JFFS2_INO_FLAG_* */ ++ jint32_t data_crc; /* CRC for the (compressed) data. */ ++ jint32_t node_crc; /* CRC for the raw inode (excluding data) */ ++ uint8_t data[0]; + } __attribute__((packed)); + + union jffs2_node_union { +diff -Nurb linux-mips-2.4.27/include/linux/jffs2_fs_i.h linux/include/linux/jffs2_fs_i.h +--- linux-mips-2.4.27/include/linux/jffs2_fs_i.h 2001-10-19 03:25:03.000000000 +0200 ++++ linux/include/linux/jffs2_fs_i.h 2004-11-19 10:25:12.141163008 +0100 +@@ -1,22 +1,12 @@ +-/* $Id: jffs2_fs_i.h,v 1.8 2001/04/18 13:05:28 dwmw2 Exp $ */ ++/* $Id: jffs2_fs_i.h,v 1.16 2003/01/09 14:03:21 dwmw2 Exp $ */ + + #ifndef _JFFS2_FS_I + #define _JFFS2_FS_I + +-/* Include the pipe_inode_info at the beginning so that we can still +- use the storage space in the inode when we have a pipe inode. +- This sucks. +-*/ +- +-#undef THISSUCKS /* Only for 2.2 */ +-#ifdef THISSUCKS +-#include +-#endif ++#include ++#include + + struct jffs2_inode_info { +-#ifdef THISSUCKS +- struct pipe_inode_info pipecrap; +-#endif + /* We need an internal semaphore similar to inode->i_sem. + Unfortunately, we can't used the existing one, because + either the GC would deadlock, or we'd have to release it +@@ -26,10 +16,10 @@ + struct semaphore sem; + + /* The highest (datanode) version number used for this ino */ +- __u32 highest_version; ++ uint32_t highest_version; + + /* List of data fragments which make up the file */ +- struct jffs2_node_frag *fraglist; ++ struct rb_root fragtree; + + /* There may be one datanode which isn't referenced by any of the + above fragments, if it contains a metadata update but no actual +@@ -44,19 +34,13 @@ + /* Some stuff we just have to keep in-core at all times, for each inode. */ + struct jffs2_inode_cache *inocache; + +- /* Keep a pointer to the last physical node in the list. We don't +- use the doubly-linked lists because we don't want to increase +- the memory usage that much. This is simpler */ +- // struct jffs2_raw_node_ref *lastnode; +- __u16 flags; +- __u8 usercompr; +-}; +- +-#ifdef JFFS2_OUT_OF_KERNEL +-#define JFFS2_INODE_INFO(i) ((struct jffs2_inode_info *) &(i)->u) +-#else +-#define JFFS2_INODE_INFO(i) (&i->u.jffs2_i) ++ uint16_t flags; ++ uint8_t usercompr; ++#if !defined (__ECOS) ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2) ++ struct inode vfs_inode; + #endif ++#endif ++}; + + #endif /* _JFFS2_FS_I */ +- +diff -Nurb linux-mips-2.4.27/include/linux/jffs2_fs_sb.h linux/include/linux/jffs2_fs_sb.h +--- linux-mips-2.4.27/include/linux/jffs2_fs_sb.h 2002-06-27 00:36:46.000000000 +0200 ++++ linux/include/linux/jffs2_fs_sb.h 2004-11-19 10:25:12.142162856 +0100 +@@ -1,19 +1,22 @@ +-/* $Id: jffs2_fs_sb.h,v 1.16.2.1 2002/02/23 14:13:34 dwmw2 Exp $ */ ++/* $Id: jffs2_fs_sb.h,v 1.45 2003/10/08 11:46:27 dwmw2 Exp $ */ + + #ifndef _JFFS2_FS_SB + #define _JFFS2_FS_SB + + #include + #include ++#include + #include + #include ++#include ++#include + #include + +-#define INOCACHE_HASHSIZE 1 +- + #define JFFS2_SB_FLAG_RO 1 + #define JFFS2_SB_FLAG_MOUNTING 2 + ++struct jffs2_inodirty; ++ + /* A struct for the overall file system control. Pointers to + jffs2_sb_info structs are named `c' in the source code. + Nee jffs_control +@@ -21,36 +24,46 @@ + struct jffs2_sb_info { + struct mtd_info *mtd; + +- __u32 highest_ino; ++ uint32_t highest_ino; ++ uint32_t checked_ino; ++ + unsigned int flags; +- spinlock_t nodelist_lock; + +- // pid_t thread_pid; /* GC thread's PID */ + struct task_struct *gc_task; /* GC task struct */ + struct semaphore gc_thread_start; /* GC thread start mutex */ + struct completion gc_thread_exit; /* GC thread exit completion port */ +- // __u32 gc_minfree_threshold; /* GC trigger thresholds */ +- // __u32 gc_maxdirty_threshold; + + struct semaphore alloc_sem; /* Used to protect all the following + fields, and also to protect against + out-of-order writing of nodes. + And GC. + */ +- __u32 flash_size; +- __u32 used_size; +- __u32 dirty_size; +- __u32 free_size; +- __u32 erasing_size; +- __u32 bad_size; +- __u32 sector_size; +- // __u32 min_free_size; +- // __u32 max_chunk_size; ++ uint32_t cleanmarker_size; /* Size of an _inline_ CLEANMARKER ++ (i.e. zero for OOB CLEANMARKER */ ++ ++ uint32_t flash_size; ++ uint32_t used_size; ++ uint32_t dirty_size; ++ uint32_t wasted_size; ++ uint32_t free_size; ++ uint32_t erasing_size; ++ uint32_t bad_size; ++ uint32_t sector_size; ++ uint32_t unchecked_size; ++ ++ uint32_t nr_free_blocks; ++ uint32_t nr_erasing_blocks; ++ ++ /* Number of free blocks there must be before we... */ ++ uint8_t resv_blocks_write; /* ... allow a normal filesystem write */ ++ uint8_t resv_blocks_deletion; /* ... allow a normal filesystem deletion */ ++ uint8_t resv_blocks_gctrigger; /* ... wake up the GC thread */ ++ uint8_t resv_blocks_gcbad; /* ... pick a block from the bad_list to GC */ ++ uint8_t resv_blocks_gcmerge; /* ... merge pages when garbage collecting */ + +- __u32 nr_free_blocks; +- __u32 nr_erasing_blocks; ++ uint32_t nospc_dirty_size; + +- __u32 nr_blocks; ++ uint32_t nr_blocks; + struct jffs2_eraseblock *blocks; /* The whole array of blocks. Used for getting blocks + * from the offset (blocks[ofs / sector_size]) */ + struct jffs2_eraseblock *nextblock; /* The block we're currently filling */ +@@ -58,9 +71,12 @@ + struct jffs2_eraseblock *gcblock; /* The block we're currently garbage-collecting */ + + struct list_head clean_list; /* Blocks 100% full of clean data */ ++ struct list_head very_dirty_list; /* Blocks with lots of dirty space */ + struct list_head dirty_list; /* Blocks with some dirty space */ ++ struct list_head erasable_list; /* Blocks which are completely dirty, and need erasing */ ++ struct list_head erasable_pending_wbuf_list; /* Blocks which need erasing but only after the current wbuf is flushed */ + struct list_head erasing_list; /* Blocks which are currently erasing */ +- struct list_head erase_pending_list; /* Blocks which need erasing */ ++ struct list_head erase_pending_list; /* Blocks which need erasing now */ + struct list_head erase_complete_list; /* Blocks which are erased and need the clean marker written to them */ + struct list_head free_list; /* Blocks which are free and ready to be used */ + struct list_head bad_list; /* Bad blocks. */ +@@ -69,16 +85,33 @@ + spinlock_t erase_completion_lock; /* Protect free_list and erasing_list + against erase completion handler */ + wait_queue_head_t erase_wait; /* For waiting for erases to complete */ +- struct jffs2_inode_cache *inocache_list[INOCACHE_HASHSIZE]; ++ ++ wait_queue_head_t inocache_wq; ++ struct jffs2_inode_cache **inocache_list; + spinlock_t inocache_lock; +-}; + +-#ifdef JFFS2_OUT_OF_KERNEL +-#define JFFS2_SB_INFO(sb) ((struct jffs2_sb_info *) &(sb)->u) +-#else +-#define JFFS2_SB_INFO(sb) (&sb->u.jffs2_sb) ++ /* Sem to allow jffs2_garbage_collect_deletion_dirent to ++ drop the erase_completion_lock while it's holding a pointer ++ to an obsoleted node. I don't like this. Alternatives welcomed. */ ++ struct semaphore erase_free_sem; ++ ++#ifdef CONFIG_JFFS2_FS_NAND ++ /* Write-behind buffer for NAND flash */ ++ unsigned char *wbuf; ++ uint32_t wbuf_ofs; ++ uint32_t wbuf_len; ++ uint32_t wbuf_pagesize; ++ struct jffs2_inodirty *wbuf_inodes; ++ ++ /* Information about out-of-band area usage... */ ++ struct nand_oobinfo *oobinfo; ++ uint32_t badblock_pos; ++ uint32_t fsdata_pos; ++ uint32_t fsdata_len; + #endif + +-#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) ) ++ /* OS-private pointer for getting back to master superblock info */ ++ void *os_priv; ++}; + + #endif /* _JFFS2_FB_SB */ +diff -Nurb linux-mips-2.4.27/include/linux/mtd/blktrans.h linux/include/linux/mtd/blktrans.h +--- linux-mips-2.4.27/include/linux/mtd/blktrans.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux/include/linux/mtd/blktrans.h 2004-11-19 10:25:12.037178816 +0100 +@@ -0,0 +1,72 @@ ++/* ++ * $Id: blktrans.h,v 1.5 2003/06/23 12:00:08 dwmw2 Exp $ ++ * ++ * (C) 2003 David Woodhouse ++ * ++ * Interface to Linux block layer for MTD 'translation layers'. ++ * ++ */ ++ ++#ifndef __MTD_TRANS_H__ ++#define __MTD_TRANS_H__ ++ ++#include ++ ++struct hd_geometry; ++struct mtd_info; ++struct mtd_blktrans_ops; ++struct file; ++struct inode; ++ ++struct mtd_blktrans_dev { ++ struct mtd_blktrans_ops *tr; ++ struct list_head list; ++ struct mtd_info *mtd; ++ struct semaphore sem; ++ int devnum; ++ int blksize; ++ unsigned long size; ++ int readonly; ++ void *blkcore_priv; /* gendisk in 2.5, devfs_handle in 2.4 */ ++}; ++ ++struct blkcore_priv; /* Differs for 2.4 and 2.5 kernels; private */ ++ ++struct mtd_blktrans_ops { ++ char *name; ++ int major; ++ int part_bits; ++ ++ /* Access functions */ ++ int (*readsect)(struct mtd_blktrans_dev *dev, ++ unsigned long block, char *buffer); ++ int (*writesect)(struct mtd_blktrans_dev *dev, ++ unsigned long block, char *buffer); ++ ++ /* Block layer ioctls */ ++ int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo); ++ int (*flush)(struct mtd_blktrans_dev *dev); ++ ++ /* Called with mtd_table_mutex held; no race with add/remove */ ++ int (*open)(struct mtd_blktrans_dev *dev); ++ int (*release)(struct mtd_blktrans_dev *dev); ++ ++ /* Called on {de,}registration and on subsequent addition/removal ++ of devices, with mtd_table_mutex held. */ ++ void (*add_mtd)(struct mtd_blktrans_ops *tr, struct mtd_info *mtd); ++ void (*remove_dev)(struct mtd_blktrans_dev *dev); ++ ++ struct list_head devs; ++ struct list_head list; ++ struct module *owner; ++ ++ struct mtd_blkcore_priv *blkcore_priv; ++}; ++ ++extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr); ++extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr); ++extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); ++extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); ++ ++ ++#endif /* __MTD_TRANS_H__ */ +diff -Nurb linux-mips-2.4.27/include/linux/mtd/cfi.h linux/include/linux/mtd/cfi.h +--- linux-mips-2.4.27/include/linux/mtd/cfi.h 2003-02-26 01:53:51.000000000 +0100 ++++ linux/include/linux/mtd/cfi.h 2004-11-19 10:25:12.038178664 +0100 +@@ -1,13 +1,14 @@ + + /* Common Flash Interface structures + * See http://support.intel.com/design/flash/technote/index.htm +- * $Id: cfi.h,v 1.32 2002/09/05 05:15:32 acurtis Exp $ ++ * $Id: cfi.h,v 1.38 2003/11/08 00:51:21 dsaxena Exp $ + */ + + #ifndef __MTD_CFI_H__ + #define __MTD_CFI_H__ + + #include ++#include + #include + #include + #include +@@ -260,7 +261,8 @@ + __u8 pri[3]; + __u8 MajorVersion; + __u8 MinorVersion; +- __u32 FeatureSupport; ++ __u32 FeatureSupport; /* if bit 31 is set then an additional __u32 feature ++ block follows - FIXME - not currently supported */ + __u8 SuspendCmdSupport; + __u16 BlkStatusRegMask; + __u8 VccOptimal; +@@ -271,6 +273,25 @@ + __u8 UserProtRegSize; + } __attribute__((packed)); + ++/* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */ ++ ++struct cfi_pri_amdstd { ++ __u8 pri[3]; ++ __u8 MajorVersion; ++ __u8 MinorVersion; ++ __u8 SiliconRevision; /* bits 1-0: Address Sensitive Unlock */ ++ __u8 EraseSuspend; ++ __u8 BlkProt; ++ __u8 TmpBlkUnprotect; ++ __u8 BlkProtUnprot; ++ __u8 SimultaneousOps; ++ __u8 BurstMode; ++ __u8 PageMode; ++ __u8 VppMin; ++ __u8 VppMax; ++ __u8 TopBottom; ++} __attribute__((packed)); ++ + struct cfi_pri_query { + __u8 NumFields; + __u32 ProtField[1]; /* Not host ordered */ +@@ -314,8 +335,6 @@ + struct flchip chips[0]; /* per-chip data structure for each chip */ + }; + +-#define MAX_CFI_CHIPS 8 /* Entirely arbitrary to avoid realloc() */ +- + /* + * Returns the command address according to the given geometry. + */ +@@ -387,13 +406,13 @@ + static inline cfi_word cfi_read(struct map_info *map, __u32 addr) + { + if (cfi_buswidth_is_1()) { +- return map->read8(map, addr); ++ return map_read8(map, addr); + } else if (cfi_buswidth_is_2()) { +- return map->read16(map, addr); ++ return map_read16(map, addr); + } else if (cfi_buswidth_is_4()) { +- return map->read32(map, addr); ++ return map_read32(map, addr); + } else if (cfi_buswidth_is_8()) { +- return map->read64(map, addr); ++ return map_read64(map, addr); + } else { + return 0; + } +@@ -406,13 +425,13 @@ + static inline void cfi_write(struct map_info *map, cfi_word val, __u32 addr) + { + if (cfi_buswidth_is_1()) { +- map->write8(map, val, addr); ++ map_write8(map, val, addr); + } else if (cfi_buswidth_is_2()) { +- map->write16(map, val, addr); ++ map_write16(map, val, addr); + } else if (cfi_buswidth_is_4()) { +- map->write32(map, val, addr); ++ map_write32(map, val, addr); + } else if (cfi_buswidth_is_8()) { +- map->write64(map, val, addr); ++ map_write64(map, val, addr); + } + } + +@@ -443,13 +462,13 @@ + static inline __u8 cfi_read_query(struct map_info *map, __u32 addr) + { + if (cfi_buswidth_is_1()) { +- return map->read8(map, addr); ++ return map_read8(map, addr); + } else if (cfi_buswidth_is_2()) { +- return cfi16_to_cpu(map->read16(map, addr)); ++ return cfi16_to_cpu(map_read16(map, addr)); + } else if (cfi_buswidth_is_4()) { +- return cfi32_to_cpu(map->read32(map, addr)); ++ return cfi32_to_cpu(map_read32(map, addr)); + } else if (cfi_buswidth_is_8()) { +- return cfi64_to_cpu(map->read64(map, addr)); ++ return cfi64_to_cpu(map_read64(map, addr)); + } else { + return 0; + } +@@ -479,5 +498,19 @@ + spin_unlock_bh(mutex); + } + ++struct cfi_extquery *cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, ++ const char* name); ++ ++struct cfi_fixup { ++ __u16 mfr; ++ __u16 id; ++ void (*fixup)(struct map_info *map, void* param); ++ void* param; ++}; ++ ++#define CFI_MFR_ANY 0xffff ++#define CFI_ID_ANY 0xffff ++ ++void cfi_fixup(struct map_info *map, struct cfi_fixup* fixups); + + #endif /* __MTD_CFI_H__ */ +diff -Nurb linux-mips-2.4.27/include/linux/mtd/compatmac.h linux/include/linux/mtd/compatmac.h +--- linux-mips-2.4.27/include/linux/mtd/compatmac.h 2003-02-26 01:53:51.000000000 +0100 ++++ linux/include/linux/mtd/compatmac.h 2004-11-19 10:25:12.041178208 +0100 +@@ -1,573 +1,152 @@ +- + /* +- * mtd/include/compatmac.h +- * +- * $Id: compatmac.h,v 1.45 2003/01/24 15:50:57 dwmw2 Exp $ ++ * $Id: compatmac.h,v 1.63 2003/11/14 19:50:04 thayne Exp $ + * + * Extensions and omissions from the normal 'linux/compatmac.h' + * files. hopefully this will end up empty as the 'real' one + * becomes fully-featured. + */ + +- +-/* First, include the parts which the kernel is good enough to provide +- * to us +- */ +- + #ifndef __LINUX_MTD_COMPATMAC_H__ + #define __LINUX_MTD_COMPATMAC_H__ + +-#include +-#include +-#ifndef LINUX_VERSION_CODE + #include +-#endif +- +-#ifndef VERSION_CODE +-# define VERSION_CODE(vers,rel,seq) ( ((vers)<<16) | ((rel)<<8) | (seq) ) +-#endif +-#ifndef KERNEL_VERSION +-# define KERNEL_VERSION(a,b,c) VERSION_CODE(a,b,c) +-#endif + +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,0,0) +-# error "This kernel is too old: not supported by this file" +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) +-#include /* used later in this header */ +- +-#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) +-#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) +- +-typedef struct wait_queue * wait_queue_head_t; +- +-#define DECLARE_WAITQUEUE(x,y) struct wait_queue x = {y,NULL} +-#define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue *x = NULL +-#define init_waitqueue_head init_waitqueue +-#define DECLARE_MUTEX(x) struct semaphore x = MUTEX +-#define DECLARE_MUTEX_LOCKED(x) struct semaphore x = MUTEX_LOCKED +- +-/* from sysdep-2.1.h */ +-# include +-# define access_ok(t,a,sz) (verify_area((t),(a),(sz)) ? 0 : 1) +-# define verify_area_20 verify_area +-# define copy_to_user(t,f,n) (memcpy_tofs(t,f,n), 0) +-# define __copy_to_user(t,f,n) copy_to_user((t),(f),(n)) +-# define copy_to_user_ret(t,f,n,r) copy_to_user((t),(f),(n)) +-# define copy_from_user(t,f,n) (memcpy_fromfs((t),(f),(n)), 0) +-# define __copy_from_user(t,f,n) copy_from_user((t),(f),(n)) +-# define copy_from_user_ret(t,f,n,r) copy_from_user((t),(f),(n)) +-//xxx # define PUT_USER(val,add) (put_user((val),(add)), 0) +-# define Put_user(val,add) (put_user((val),(add)), 0) +-# define __PUT_USER(val,add) PUT_USER((val),(add)) +-# define PUT_USER_RET(val,add,ret) PUT_USER((val),(add)) +-# define GET_USER(dest,add) ((dest)=get_user((add)), 0) +-# define __GET_USER(dest,add) GET_USER((dest),(add)) +-# define GET_USER_RET(dest,add,ret) GET_USER((dest),(add)) +- +-#define ioremap(offset,size) vremap(offset,size) +-#define iounmap(adr) /* */ +- +-#define EXPORT_SYMBOL(s) /* */ +-#define EXPORT_SYMBOL_NOVERS(s) /* */ +- +-/* 2.1.10 and 2.1.43 introduced new functions. They are worth using */ +- +-#if LINUX_VERSION_CODE < VERSION_CODE(2,1,10) +- +-# include +-# ifdef __LITTLE_ENDIAN +-# define cpu_to_le16(x) (x) +-# define cpu_to_le32(x) (x) +-# define cpu_to_be16(x) htons((x)) +-# define cpu_to_be32(x) htonl((x)) +-# else +-# define cpu_to_be16(x) (x) +-# define cpu_to_be32(x) (x) +- extern inline __u16 cpu_to_le16(__u16 x) { return (x<<8) | (x>>8);} +- extern inline __u32 cpu_to_le32(__u32 x) { return((x>>24) | +- ((x>>8)&0xff00) | ((x<<8)&0xff0000) | (x<<24));} +-# endif +- +-# define le16_to_cpu(x) cpu_to_le16(x) +-# define le32_to_cpu(x) cpu_to_le32(x) +-# define be16_to_cpu(x) cpu_to_be16(x) +-# define be32_to_cpu(x) cpu_to_be32(x) +- +-#endif +- +-#if LINUX_VERSION_CODE < VERSION_CODE(2,1,43) +-# define cpu_to_le16p(addr) (cpu_to_le16(*(addr))) +-# define cpu_to_le32p(addr) (cpu_to_le32(*(addr))) +-# define cpu_to_be16p(addr) (cpu_to_be16(*(addr))) +-# define cpu_to_be32p(addr) (cpu_to_be32(*(addr))) +- +- extern inline void cpu_to_le16s(__u16 *a) {*a = cpu_to_le16(*a);} +- extern inline void cpu_to_le32s(__u16 *a) {*a = cpu_to_le32(*a);} +- extern inline void cpu_to_be16s(__u16 *a) {*a = cpu_to_be16(*a);} +- extern inline void cpu_to_be32s(__u16 *a) {*a = cpu_to_be32(*a);} +- +-# define le16_to_cpup(x) cpu_to_le16p(x) +-# define le32_to_cpup(x) cpu_to_le32p(x) +-# define be16_to_cpup(x) cpu_to_be16p(x) +-# define be32_to_cpup(x) cpu_to_be32p(x) +- +-# define le16_to_cpus(x) cpu_to_le16s(x) +-# define le32_to_cpus(x) cpu_to_le32s(x) +-# define be16_to_cpus(x) cpu_to_be16s(x) +-# define be32_to_cpus(x) cpu_to_be32s(x) +-#endif +- +-// from 2.2, linux/types.h +-#ifndef __BIT_TYPES_DEFINED__ +-#define __BIT_TYPES_DEFINED__ +- +-typedef __u8 u_int8_t; +-typedef __s8 int8_t; +-typedef __u16 u_int16_t; +-typedef __s16 int16_t; +-typedef __u32 u_int32_t; +-typedef __s32 int32_t; +- +-#endif /* !(__BIT_TYPES_DEFINED__) */ +- +-#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) +- typedef struct { } spinlock_t; +- #define SPIN_LOCK_UNLOCKED (spinlock_t) { } +-#else +- typedef struct { int gcc_is_buggy; } spinlock_t; +- #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } +-#endif +- +-#define spin_lock_init(lock) do { } while(0) +-#define spin_lock(lock) (void)(lock) /* Not "unused variable". */ +-#define spin_trylock(lock) (1) +-#define spin_unlock_wait(lock) do { } while(0) +-#define spin_unlock(lock) do { } while(0) +-#define spin_lock_irq(lock) cli() +-#define spin_unlock_irq(lock) sti() +- +-#define spin_lock_irqsave(lock, flags) \ +- do { save_flags(flags); cli(); } while (0) +-#define spin_unlock_irqrestore(lock, flags) \ +- restore_flags(flags) +- +-// Doesn't work when tqueue.h is included. +-// #define queue_task queue_task_irq_off +-#define tty_flip_buffer_push(tty) queue_task_irq_off(&tty->flip.tqueue, &tq_timer) +-#define signal_pending(current) (current->signal & ~current->blocked) +-#define schedule_timeout(to) do {current->timeout = jiffies + (to);schedule ();} while (0) +-#define time_after(t1,t2) (((long)t1-t2) > 0) +- +-#else +- #include +-#endif // LINUX_VERSION_CODE < 0x020100 +- +- +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) +-#include +-#endif +- +-/* Modularization issues */ +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,18) +-# define __USE_OLD_SYMTAB__ +-# define EXPORT_NO_SYMBOLS register_symtab(NULL); +-# define REGISTER_SYMTAB(tab) register_symtab(tab) +-#else +-# define REGISTER_SYMTAB(tab) /* nothing */ +-#endif +- +-#ifdef __USE_OLD_SYMTAB__ +-# define __MODULE_STRING(s) /* nothing */ +-# define MODULE_PARM(v,t) /* nothing */ +-# define MODULE_PARM_DESC(v,t) /* nothing */ +-# define MODULE_AUTHOR(n) /* nothing */ +-# define MODULE_DESCRIPTION(d) /* nothing */ +-# define MODULE_SUPPORTED_DEVICE(n) /* nothing */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) ++#error "This kernel is too old: not supported by this file" + #endif + +-/* +- * "select" changed in 2.1.23. The implementation is twin, but this +- * header is new +- */ +-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,22) +-# include +-#else +-# define __USE_OLD_SELECT__ +-#endif ++ /* O(1) scheduler stuff. */ + +-/* Other change in the fops are solved using pseudo-types */ +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) +-# define lseek_t long long +-# define lseek_off_t long long +-#else +-# define lseek_t int +-# define lseek_off_t off_t +-#endif ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,5) && !defined(__rh_config_h__) ++#include ++static inline void __recalc_sigpending(void) ++{ ++ recalc_sigpending(current); ++} ++#undef recalc_sigpending ++#define recalc_sigpending() __recalc_sigpending () + +-/* changed the prototype of read/write */ ++#define set_user_nice(tsk, n) do { (tsk)->nice = n; } while(0) + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) || defined(__alpha__) +-# define count_t unsigned long +-# define read_write_t long +-#else +-# define count_t int +-# define read_write_t int + #endif + + +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,31) +-# define release_t void +-# define release_return(x) return +-#else +-# define release_t int +-# define release_return(x) return (x) +-#endif +- +-#if LINUX_VERSION_CODE < 0x20300 +-#define __exit +-#endif +-#if LINUX_VERSION_CODE < 0x20200 +-#define __init +-#else +-#include +-#endif + +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) +-#define init_MUTEX(x) do {*(x) = MUTEX;} while (0) +-#define init_MUTEX_LOCKED(x) do {*(x) = MUTEX_LOCKED;} while (0) +-#endif ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20) + +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) +-#define RQFUNC_ARG void +-#define blkdev_dequeue_request(req) do {CURRENT = req->next;} while (0) +-#else +-#define RQFUNC_ARG request_queue_t *q ++#ifndef yield ++#define yield() do { set_current_state(TASK_RUNNING); schedule(); } while(0) + #endif + +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,32) +-#define blk_cleanup_queue(nr) do {blk_dev[nr].request_fn = 0;} while(0) +-#define BLK_DEFAULT_QUEUE(nr) (blk_dev[nr].request_fn) +-#define blk_init_queue(q, rq) do {q = rq;} while(0) ++#ifndef minor ++#define major(d) (MAJOR(to_kdev_t(d))) ++#define minor(d) (MINOR(to_kdev_t(d))) + #endif + +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0) +-#ifdef CONFIG_MODULES +-#define __MOD_INC_USE_COUNT(mod) \ +- (atomic_inc(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED|MOD_USED_ONCE) +-#define __MOD_DEC_USE_COUNT(mod) \ +- (atomic_dec(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED) +-#else +-#define __MOD_INC_USE_COUNT(mod) +-#define __MOD_DEC_USE_COUNT(mod) +-#endif ++#ifndef mk_kdev ++#define mk_kdev(ma,mi) MKDEV(ma,mi) ++#define kdev_t_to_nr(x) (x) + #endif + ++#define need_resched() (current->need_resched) ++#define cond_resched() do { if need_resched() { yield(); } } while(0) + +-#ifndef HAVE_INTER_MODULE +-static inline void *inter_module_get(char *x) {return NULL;} +-static inline void *inter_module_get_request(char *x, char *y) {return NULL;} +-static inline void inter_module_put(const char *x) {} +-static inline void inter_module_register(const char *x, struct module *y, const void *z) {} +-static inline void inter_module_unregister(const char *x) {} ++#endif /* < 2.4.20 */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,73) ++#define iminor(i) minor((i)->i_rdev) ++#define imajor(i) major((i)->i_rdev) ++#define old_encode_dev(d) ( (major(d)<<8) | minor(d) ) ++#define old_decode_dev(rdev) (kdev_t_to_nr(mk_kdev((rdev)>>8, (rdev)&0xff))) ++#define old_valid_dev(d) (1) + #endif + +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,61) + +-#define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue *x = NULL +-#define init_waitqueue_head init_waitqueue ++#include + ++#ifdef __rh_config_h__ ++#define sigmask_lock sighand->siglock ++#define sig sighand + #endif + +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) +- +-static inline int try_inc_mod_count(struct module *mod) ++static inline void __daemonize_modvers(void) + { +-#ifdef CONFIG_MODULES +- if (mod) +- __MOD_INC_USE_COUNT(mod); +-#endif +- return 1; +-} +-#endif ++ daemonize(); + ++ spin_lock_irq(¤t->sigmask_lock); ++ sigfillset(¤t->blocked); ++ recalc_sigpending(); ++ spin_unlock_irq(¤t->sigmask_lock); ++} ++#undef daemonize ++#define daemonize(fmt, ...) do { \ ++ snprintf(current->comm, sizeof(current->comm), fmt ,##__VA_ARGS__); \ ++ __daemonize_modvers(); \ ++ } while(0) + +-/* Yes, I'm aware that it's a fairly ugly hack. +- Until the __constant_* macros appear in Linus' own kernels, this is +- the way it has to be done. +- DW 19/1/00 +- */ +- +-#include +- +-#ifndef __constant_cpu_to_le16 +- +-#ifdef __BIG_ENDIAN +-#define __constant_cpu_to_le64(x) ___swab64((x)) +-#define __constant_le64_to_cpu(x) ___swab64((x)) +-#define __constant_cpu_to_le32(x) ___swab32((x)) +-#define __constant_le32_to_cpu(x) ___swab32((x)) +-#define __constant_cpu_to_le16(x) ___swab16((x)) +-#define __constant_le16_to_cpu(x) ___swab16((x)) +-#define __constant_cpu_to_be64(x) ((__u64)(x)) +-#define __constant_be64_to_cpu(x) ((__u64)(x)) +-#define __constant_cpu_to_be32(x) ((__u32)(x)) +-#define __constant_be32_to_cpu(x) ((__u32)(x)) +-#define __constant_cpu_to_be16(x) ((__u16)(x)) +-#define __constant_be16_to_cpu(x) ((__u16)(x)) +-#else +-#ifdef __LITTLE_ENDIAN +-#define __constant_cpu_to_le64(x) ((__u64)(x)) +-#define __constant_le64_to_cpu(x) ((__u64)(x)) +-#define __constant_cpu_to_le32(x) ((__u32)(x)) +-#define __constant_le32_to_cpu(x) ((__u32)(x)) +-#define __constant_cpu_to_le16(x) ((__u16)(x)) +-#define __constant_le16_to_cpu(x) ((__u16)(x)) +-#define __constant_cpu_to_be64(x) ___swab64((x)) +-#define __constant_be64_to_cpu(x) ___swab64((x)) +-#define __constant_cpu_to_be32(x) ___swab32((x)) +-#define __constant_be32_to_cpu(x) ___swab32((x)) +-#define __constant_cpu_to_be16(x) ___swab16((x)) +-#define __constant_be16_to_cpu(x) ___swab16((x)) +-#else +-#error No (recognised) endianness defined (unless it,s PDP) +-#endif /* __LITTLE_ENDIAN */ +-#endif /* __BIG_ENDIAN */ +- +-#endif /* ifndef __constant_cpu_to_le16 */ +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) +- #define mod_init_t int __init +- #define mod_exit_t void +-#else +- #define mod_init_t static int __init +- #define mod_exit_t static void __exit +-#endif +- +-#ifndef THIS_MODULE +-#ifdef MODULE +-#define THIS_MODULE (&__this_module) +-#else +-#define THIS_MODULE (NULL) +-#endif +-#endif +- +-#if LINUX_VERSION_CODE < 0x20300 +-#include +-#define spin_lock_bh(lock) do {start_bh_atomic();spin_lock(lock);}while(0) +-#define spin_unlock_bh(lock) do {spin_unlock(lock);end_bh_atomic();}while(0) +-#else +-#include +-#include +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) +-#define set_current_state(state_value) \ +- do { current->state = (state_value); } while (0) +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0) +-static inline int invalidate_device(kdev_t dev, int do_sync) { ++static inline int dequeue_signal_lock(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) ++{ ++ unsigned long flags; ++ unsigned long ret; + +- if (do_sync) +- fsync_dev(dev); ++ spin_lock_irqsave(¤t->sigmask_lock, flags); ++ ret = dequeue_signal(mask, info); ++ spin_unlock_irqrestore(¤t->sigmask_lock, flags); + +- invalidate_buffers(dev); +- return 0; ++ return ret; + } +-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5) +-static inline int invalidate_device(kdev_t dev, int do_sync) { +- struct super_block *sb = get_super(dev); +- int res = 0; + +- if (do_sync) +- fsync_dev(dev); +- +- if (sb) +- res = invalidate_inodes(sb); ++static inline int allow_signal(int sig) ++{ ++ if (sig < 1 || sig > _NSIG) ++ return -EINVAL; + +- invalidate_buffers(dev); +- return res; ++ spin_lock_irq(¤t->sigmask_lock); ++ sigdelset(¤t->blocked, sig); ++ recalc_sigpending(); ++ /* Make sure the kernel neither eats it now converts to SIGKILL */ ++ current->sig->action[sig-1].sa.sa_handler = (void *)2; ++ spin_unlock_irq(¤t->sigmask_lock); ++ return 0; + } +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) +-#undef min +-#undef max +-#undef min_t +-#undef max_t +-/* +- * min()/max() macros that also do +- * strict type-checking.. See the +- * "unnecessary" pointer comparison. +- */ +-#define min(x,y) ({ \ +- const typeof(x) _x = (x); \ +- const typeof(y) _y = (y); \ +- (void) (&_x == &_y); \ +- _x < _y ? _x : _y; }) +- +-#define max(x,y) ({ \ +- const typeof(x) _x = (x); \ +- const typeof(y) _y = (y); \ +- (void) (&_x == &_y); \ +- _x > _y ? _x : _y; }) +- +-/* +- * ..and if you can't take the strict +- * types, you can specify one yourself. +- * +- * Or not use min/max at all, of course. +- */ +-#define min_t(type,x,y) \ +- ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) +-#define max_t(type,x,y) \ +- ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,7) +-struct completion { +- struct semaphore s; +-}; +- +-#define complete(c) up(&(c)->s) +-#define wait_for_completion(c) down(&(c)->s) +-#define init_completion(c) init_MUTEX_LOCKED(&(c)->s); +- +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9) +-/* This came later */ +-#define complete_and_exit(c, r) do { complete(c); do_exit(r); } while(0) +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9) || \ +- (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) && !defined(__rh_config_h__)) ++static inline int disallow_signal(int sig) ++{ ++ if (sig < 1 || sig > _NSIG) ++ return -EINVAL; + +-#include ++ spin_lock_irq(¤t->sigmask_lock); ++ sigaddset(¤t->blocked, sig); ++ recalc_sigpending(); + +-static inline void add_gendisk(struct gendisk *gp) +-{ +- gp->next = gendisk_head; +- gendisk_head = gp; ++ current->sig->action[sig-1].sa.sa_handler = SIG_DFL; ++ spin_unlock_irq(¤t->sigmask_lock); ++ return 0; + } + +-static inline void del_gendisk(struct gendisk *gp) +-{ +- struct gendisk *gd, **gdp; ++#undef sighand ++#undef sigmask_lock + +- for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next)) +- if (*gdp == gp) { +- gd = *gdp; *gdp = gd->next; +- break; +- } +-} ++#define PF_FREEZE 0 ++#define refrigerator(x) do { ; } while(0) + #endif + +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) && defined(MODULE) ++ /* Module bits */ + +-#define module_init(func) \ +-mod_init_t init_module(void) { \ +- return func(); \ +-} + +-#define module_exit(func) \ +-mod_exit_t cleanup_module(void) { \ +- return func(); \ +-} ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60) ++#define try_module_get(m) try_inc_mod_count(m) ++#define __module_get(m) do { if (!try_inc_mod_count(m)) BUG(); } while(0) ++#define module_put(m) do { if (m) __MOD_DEC_USE_COUNT((struct module *)(m)); } while(0) ++#define set_module_owner(x) do { x->owner = THIS_MODULE; } while(0) + #endif + +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9) || \ +- (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) && !defined(__rh_config_h__)) +-#define MODULE_LICENSE(x) /* */ +-#endif + +-/* Removed for 2.4.21 kernel. This really should have been renamed +- when it was changed -- this is a PITA */ +-#if 0 && LINUX_VERSION_CODE < KERNEL_VERSION(2,5,5) +-#include +-static inline void __recalc_sigpending(void) +-{ +- recalc_sigpending(current); +-} +-#undef recalc_sigpending +-#define recalc_sigpending() __recalc_sigpending () +-#endif ++ /* Random filesystem stuff, only for JFFS2 really */ + + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,5) + #define parent_ino(d) ((d)->d_parent->d_inode->i_ino) + #endif + +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,3) +-#define need_resched() (current->need_resched) +-#define cond_resched() do { if need_resched() schedule(); } while(0) +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) +-#ifndef yield +-#define yield() do { set_current_state(TASK_RUNNING); schedule(); } while(0) +-#endif +-#ifndef minor +-#define major(d) (MAJOR(to_kdev_t(d))) +-#define minor(d) (MINOR(to_kdev_t(d))) +-#endif +-#ifndef mk_kdev +-#define mk_kdev(ma,mi) MKDEV(ma,mi) +-#define kdev_t_to_nr(x) (x) +-#endif +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) +- /* Is this right? */ +-#define set_user_nice(tsk, n) do { (tsk)->priority = 20-(n); } while(0) +-#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,4,21) && !defined(RED_HAT_LINUX_KERNEL) +-#define set_user_nice(tsk, n) do { (tsk)->nice = n; } while(0) +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,21) +-#define rq_data_dir(x) ((x)->cmd) +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +- +-#define IS_REQ_CMD(req) (1) +- +-#define QUEUE_LOCK(q) (&io_request_lock) +- +-#define BLK_INIT_QUEUE(q, req, lock) blk_init_queue((q), (req)) +- +-#else /* > 2.5.0 */ +- +-#define IS_REQ_CMD(req) ((req)->flags & REQ_CMD) +- +-#define QUEUE_LOCK(q) ((q)->queue_lock) +- +-#define BLK_INIT_QUEUE(q, req, lock) blk_init_queue((q), (req), (lock)) +- +-#endif +- +-/* Removed cos it broke stuff. Where is this required anyway? +- * #ifndef QUEUE_EMPTY +- * #define QUEUE_EMPTY (!CURRENT) +- * #endif +- */ +-#if LINUX_VERSION_CODE < 0x20300 +-#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].plug_tq.sync) +-#elif LINUX_VERSION_CODE < 0x20500 //FIXME (Si) +-#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].request_queue.plugged) +-#else +-#define QUEUE_PLUGGED (blk_queue_plugged(QUEUE)) +-#endif +- +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14) +-#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT +-#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT +-#else +-#define BLK_INC_USE_COUNT do {} while(0) +-#define BLK_DEC_USE_COUNT do {} while(0) +-#endif +- + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,12) + #define PageUptodate(x) Page_Uptodate(x) + #endif +@@ -580,4 +159,31 @@ + #define generic_file_readonly_mmap generic_file_mmap + #endif + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,70) ++ ++#include ++#include ++ ++static inline char *strlcpy(char *dest, const char *src, int len) ++{ ++ dest[len-1] = 0; ++ return strncpy(dest, src, len-1); ++} ++ ++static inline int do_old_request_module(const char *mod) ++{ ++ return request_module(mod); ++} ++#undef request_module ++#define request_module(fmt, ...) \ ++ ({ char modname[32]; snprintf(modname, 31, fmt ,##__VA_ARGS__); do_old_request_module(modname); }) ++ ++#endif /* 2.5.70 */ ++ ++#ifndef container_of ++#define container_of(ptr, type, member) ({ \ ++ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ ++ (type *)( (char *)__mptr - offsetof(type,member) );}) ++#endif ++ + #endif /* __LINUX_MTD_COMPATMAC_H__ */ +diff -Nurb linux-mips-2.4.27/include/linux/mtd/doc2000.h linux/include/linux/mtd/doc2000.h +--- linux-mips-2.4.27/include/linux/mtd/doc2000.h 2001-11-05 21:16:30.000000000 +0100 ++++ linux/include/linux/mtd/doc2000.h 2004-11-19 10:25:12.044177752 +0100 +@@ -1,13 +1,21 @@ +- +-/* Linux driver for Disk-On-Chip 2000 */ +-/* (c) 1999 Machine Vision Holdings, Inc. */ +-/* Author: David Woodhouse */ +-/* $Id: doc2000.h,v 1.15 2001/09/19 00:22:15 dwmw2 Exp $ */ ++/* ++ * Linux driver for Disk-On-Chip devices ++ * ++ * Copyright (C) 1999 Machine Vision Holdings, Inc. ++ * Copyright (C) 2001-2003 David Woodhouse ++ * Copyright (C) 2002-2003 Greg Ungerer ++ * Copyright (C) 2002-2003 SnapGear Inc ++ * ++ * $Id: doc2000.h,v 1.22 2003/11/05 10:51:36 dwmw2 Exp $ ++ * ++ * Released under GPL ++ */ + + #ifndef __MTD_DOC2000_H__ + #define __MTD_DOC2000_H__ + + #include ++#include + + #define DoC_Sig1 0 + #define DoC_Sig2 1 +@@ -38,18 +46,47 @@ + #define DoC_Mil_CDSN_IO 0x0800 + #define DoC_2k_CDSN_IO 0x1800 + ++#define DoC_Mplus_NOP 0x1002 ++#define DoC_Mplus_AliasResolution 0x1004 ++#define DoC_Mplus_DOCControl 0x1006 ++#define DoC_Mplus_AccessStatus 0x1008 ++#define DoC_Mplus_DeviceSelect 0x1008 ++#define DoC_Mplus_Configuration 0x100a ++#define DoC_Mplus_OutputControl 0x100c ++#define DoC_Mplus_FlashControl 0x1020 ++#define DoC_Mplus_FlashSelect 0x1022 ++#define DoC_Mplus_FlashCmd 0x1024 ++#define DoC_Mplus_FlashAddress 0x1026 ++#define DoC_Mplus_FlashData0 0x1028 ++#define DoC_Mplus_FlashData1 0x1029 ++#define DoC_Mplus_ReadPipeInit 0x102a ++#define DoC_Mplus_LastDataRead 0x102c ++#define DoC_Mplus_LastDataRead1 0x102d ++#define DoC_Mplus_WritePipeTerm 0x102e ++#define DoC_Mplus_ECCSyndrome0 0x1040 ++#define DoC_Mplus_ECCSyndrome1 0x1041 ++#define DoC_Mplus_ECCSyndrome2 0x1042 ++#define DoC_Mplus_ECCSyndrome3 0x1043 ++#define DoC_Mplus_ECCSyndrome4 0x1044 ++#define DoC_Mplus_ECCSyndrome5 0x1045 ++#define DoC_Mplus_ECCConf 0x1046 ++#define DoC_Mplus_Toggle 0x1046 ++#define DoC_Mplus_DownloadStatus 0x1074 ++#define DoC_Mplus_CtrlConfirm 0x1076 ++#define DoC_Mplus_Power 0x1fff ++ + /* How to access the device? + * On ARM, it'll be mmap'd directly with 32-bit wide accesses. + * On PPC, it's mmap'd and 16-bit wide. + * Others use readb/writeb + */ + #if defined(__arm__) +-#define ReadDOC_(adr, reg) ((unsigned char)(*(__u32 *)(((unsigned long)adr)+((reg)<<2)))) +-#define WriteDOC_(d, adr, reg) do{ *(__u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0) ++#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)))) ++#define WriteDOC_(d, adr, reg) do{ *(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0) + #define DOC_IOREMAP_LEN 0x8000 + #elif defined(__ppc__) +-#define ReadDOC_(adr, reg) ((unsigned char)(*(__u16 *)(((unsigned long)adr)+((reg)<<1)))) +-#define WriteDOC_(d, adr, reg) do{ *(__u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0) ++#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)))) ++#define WriteDOC_(d, adr, reg) do{ *(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0) + #define DOC_IOREMAP_LEN 0x4000 + #else + #define ReadDOC_(adr, reg) readb(((unsigned long)adr) + (reg)) +@@ -71,13 +108,21 @@ + #define DOC_MODE_RESERVED1 2 + #define DOC_MODE_RESERVED2 3 + +-#define DOC_MODE_MDWREN 4 + #define DOC_MODE_CLR_ERR 0x80 ++#define DOC_MODE_RST_LAT 0x10 ++#define DOC_MODE_BDECT 0x08 ++#define DOC_MODE_MDWREN 0x04 + + #define DOC_ChipID_Doc2k 0x20 ++#define DOC_ChipID_Doc2kTSOP 0x21 /* internal number for MTD */ + #define DOC_ChipID_DocMil 0x30 ++#define DOC_ChipID_DocMilPlus32 0x40 ++#define DOC_ChipID_DocMilPlus16 0x41 + + #define CDSN_CTRL_FR_B 0x80 ++#define CDSN_CTRL_FR_B0 0x40 ++#define CDSN_CTRL_FR_B1 0x80 ++ + #define CDSN_CTRL_ECC_IO 0x20 + #define CDSN_CTRL_FLASH_IO 0x10 + #define CDSN_CTRL_WP 0x08 +@@ -93,6 +138,10 @@ + #define DOC_ECC_RESV 0x02 + #define DOC_ECC_IGNORE 0x01 + ++#define DOC_FLASH_CE 0x80 ++#define DOC_FLASH_WP 0x40 ++#define DOC_FLASH_BANK 0x02 ++ + /* We have to also set the reserved bit 1 for enable */ + #define DOC_ECC_EN (DOC_ECC__EN | DOC_ECC_RESV) + #define DOC_ECC_DIS (DOC_ECC_RESV) +@@ -107,9 +156,12 @@ + #define MAX_FLOORS 4 + #define MAX_CHIPS 4 + +-#define MAX_FLOORS_MIL 4 ++#define MAX_FLOORS_MIL 1 + #define MAX_CHIPS_MIL 1 + ++#define MAX_FLOORS_MPLUS 2 ++#define MAX_CHIPS_MPLUS 1 ++ + #define ADDR_COLUMN 1 + #define ADDR_PAGE 2 + #define ADDR_COLUMN_PAGE 3 +@@ -118,7 +170,7 @@ + unsigned long physadr; + unsigned long virtadr; + unsigned long totlen; +- char ChipID; /* Type of DiskOnChip */ ++ unsigned char ChipID; /* Type of DiskOnChip */ + int ioreg; + + unsigned long mfr; /* Flash IDs - only one type of flash per device */ +@@ -126,6 +178,7 @@ + int chipshift; + char page256; + char pageadrlen; ++ char interleave; /* Internal interleaving - Millennium Plus style */ + unsigned long erasesize; + + int curfloor; +diff -Nurb linux-mips-2.4.27/include/linux/mtd/flashchip.h linux/include/linux/mtd/flashchip.h +--- linux-mips-2.4.27/include/linux/mtd/flashchip.h 2003-02-26 01:53:51.000000000 +0100 ++++ linux/include/linux/mtd/flashchip.h 2004-11-19 10:25:12.045177600 +0100 +@@ -6,7 +6,7 @@ + * + * (C) 2000 Red Hat. GPLd. + * +- * $Id: flashchip.h,v 1.8 2002/10/21 13:20:52 jocke Exp $ ++ * $Id: flashchip.h,v 1.10 2004/01/27 10:16:20 dvrabel Exp $ + * + */ + +@@ -58,6 +58,11 @@ + int ref_point_counter; + flstate_t state; + flstate_t oldstate; ++ ++ int write_suspended:1; ++ int erase_suspended:1; ++ unsigned long in_progress_block_addr; ++ + spinlock_t *mutex; + spinlock_t _spinlock; /* We do it like this because sometimes they'll be shared. */ + wait_queue_head_t wq; /* Wait on here when we're waiting for the chip +diff -Nurb linux-mips-2.4.27/include/linux/mtd/gen_probe.h linux/include/linux/mtd/gen_probe.h +--- linux-mips-2.4.27/include/linux/mtd/gen_probe.h 2001-11-05 21:16:30.000000000 +0100 ++++ linux/include/linux/mtd/gen_probe.h 2004-11-19 10:25:12.048177144 +0100 +@@ -1,7 +1,7 @@ + /* + * (C) 2001, 2001 Red Hat, Inc. + * GPL'd +- * $Id: gen_probe.h,v 1.1 2001/09/02 18:50:13 dwmw2 Exp $ ++ * $Id: gen_probe.h,v 1.2 2003/11/08 00:51:21 dsaxena Exp $ + */ + + #ifndef __LINUX_MTD_GEN_PROBE_H__ +@@ -10,12 +10,12 @@ + #include + #include + #include ++#include + + struct chip_probe { + char *name; + int (*probe_chip)(struct map_info *map, __u32 base, +- struct flchip *chips, struct cfi_private *cfi); +- ++ unsigned long *chip_map, struct cfi_private *cfi); + }; + + struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp); +diff -Nurb linux-mips-2.4.27/include/linux/mtd/inftl.h linux/include/linux/mtd/inftl.h +--- linux-mips-2.4.27/include/linux/mtd/inftl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux/include/linux/mtd/inftl.h 2004-11-19 10:25:12.051176688 +0100 +@@ -0,0 +1,129 @@ ++/* ++ * inftl.h -- defines to support the Inverse NAND Flash Translation Layer ++ * ++ * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) ++ * ++ * $Id: inftl.h,v 1.4 2003/06/29 16:15:46 dwmw2 Exp $ ++ */ ++ ++#ifndef __MTD_INFTL_H__ ++#define __MTD_INFTL_H__ ++ ++#include ++#include ++#include ++ ++#define OSAK_VERSION 0x5120 ++#define PERCENTUSED 98 ++ ++#define SECTORSIZE 512 ++ ++#ifndef INFTL_MAJOR ++#define INFTL_MAJOR 94 ++#endif ++#define INFTL_PARTN_BITS 4 ++ ++/* Block Control Information */ ++ ++struct inftl_bci { ++ __u8 ECCsig[6]; ++ __u8 Status; ++ __u8 Status1; ++} __attribute__((packed)); ++ ++struct inftl_unithead1 { ++ __u16 virtualUnitNo; ++ __u16 prevUnitNo; ++ __u8 ANAC; ++ __u8 NACs; ++ __u8 parityPerField; ++ __u8 discarded; ++} __attribute__((packed)); ++ ++struct inftl_unithead2 { ++ __u8 parityPerField; ++ __u8 ANAC; ++ __u16 prevUnitNo; ++ __u16 virtualUnitNo; ++ __u8 NACs; ++ __u8 discarded; ++} __attribute__((packed)); ++ ++struct inftl_unittail { ++ __u8 Reserved[4]; ++ __u16 EraseMark; ++ __u16 EraseMark1; ++} __attribute__((packed)); ++ ++union inftl_uci { ++ struct inftl_unithead1 a; ++ struct inftl_unithead2 b; ++ struct inftl_unittail c; ++}; ++ ++struct inftl_oob { ++ struct inftl_bci b; ++ union inftl_uci u; ++}; ++ ++ ++/* INFTL Media Header */ ++ ++struct INFTLPartition { ++ __u32 virtualUnits; ++ __u32 firstUnit; ++ __u32 lastUnit; ++ __u32 flags; ++ __u32 spareUnits; ++ __u32 Reserved0; ++ __u32 Reserved1; ++} __attribute__((packed)); ++ ++struct INFTLMediaHeader { ++ char bootRecordID[8]; ++ __u32 NoOfBootImageBlocks; ++ __u32 NoOfBinaryPartitions; ++ __u32 NoOfBDTLPartitions; ++ __u32 BlockMultiplierBits; ++ __u32 FormatFlags; ++ __u32 OsakVersion; ++ __u32 PercentUsed; ++ struct INFTLPartition Partitions[4]; ++} __attribute__((packed)); ++ ++/* Partition flag types */ ++#define INFTL_BINARY 0x20000000 ++#define INFTL_BDTL 0x40000000 ++#define INFTL_LAST 0x80000000 ++ ++ ++#ifdef __KERNEL__ ++ ++struct INFTLrecord { ++ struct mtd_blktrans_dev mbd; ++ __u16 MediaUnit, SpareMediaUnit; ++ __u32 EraseSize; ++ struct INFTLMediaHeader MediaHdr; ++ int usecount; ++ unsigned char heads; ++ unsigned char sectors; ++ unsigned short cylinders; ++ __u16 numvunits; ++ __u16 firstEUN; ++ __u16 lastEUN; ++ __u16 numfreeEUNs; ++ __u16 LastFreeEUN; /* To speed up finding a free EUN */ ++ int head,sect,cyl; ++ __u16 *PUtable; /* Physical Unit Table */ ++ __u16 *VUtable; /* Virtual Unit Table */ ++ unsigned int nb_blocks; /* number of physical blocks */ ++ unsigned int nb_boot_blocks; /* number of blocks used by the bios */ ++ struct erase_info instr; ++}; ++ ++int INFTL_mount(struct INFTLrecord *s); ++int INFTL_formatblock(struct INFTLrecord *s, int block); ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* __MTD_INFTL_H__ */ +diff -Nurb linux-mips-2.4.27/include/linux/mtd/jedec.h linux/include/linux/mtd/jedec.h +--- linux-mips-2.4.27/include/linux/mtd/jedec.h 2001-12-02 12:35:00.000000000 +0100 ++++ linux/include/linux/mtd/jedec.h 2004-11-19 10:25:12.052176536 +0100 +@@ -7,14 +7,13 @@ + * + * See the AMD flash databook for information on how to operate the interface. + * +- * $Id: jedec.h,v 1.2 2001/11/06 14:37:36 dwmw2 Exp $ ++ * $Id: jedec.h,v 1.3 2003/05/21 11:51:01 dwmw2 Exp $ + */ + + #ifndef __LINUX_MTD_JEDEC_H__ + #define __LINUX_MTD_JEDEC_H__ + + #include +-#include + + #define MAX_JEDEC_CHIPS 16 + +diff -Nurb linux-mips-2.4.27/include/linux/mtd/map.h linux/include/linux/mtd/map.h +--- linux-mips-2.4.27/include/linux/mtd/map.h 2003-02-26 01:53:51.000000000 +0100 ++++ linux/include/linux/mtd/map.h 2004-11-19 10:25:12.054176232 +0100 +@@ -1,14 +1,15 @@ + + /* Overhauled routines for dealing with different mmap regions of flash */ +-/* $Id: map.h,v 1.29 2002/10/21 13:20:52 jocke Exp $ */ ++/* $Id: map.h,v 1.34 2003/05/28 12:42:22 dwmw2 Exp $ */ + + #ifndef __LINUX_MTD_MAP_H__ + #define __LINUX_MTD_MAP_H__ + + #include + #include +-#include +-#include ++#include ++#include ++#include + + /* The map stuff is very simple. You fill in your struct map_info with + a handful of routines for accessing the device, making sure they handle +@@ -29,39 +30,44 @@ + struct map_info { + char *name; + unsigned long size; ++ unsigned long phys; ++#define NO_XIP (-1UL) ++ ++ unsigned long virt; ++ void *cached; ++ + int buswidth; /* in octets */ +- __u8 (*read8)(struct map_info *, unsigned long); +- __u16 (*read16)(struct map_info *, unsigned long); +- __u32 (*read32)(struct map_info *, unsigned long); +- __u64 (*read64)(struct map_info *, unsigned long); ++ ++#ifdef CONFIG_MTD_COMPLEX_MAPPINGS ++ u8 (*read8)(struct map_info *, unsigned long); ++ u16 (*read16)(struct map_info *, unsigned long); ++ u32 (*read32)(struct map_info *, unsigned long); ++ u64 (*read64)(struct map_info *, unsigned long); + /* If it returned a 'long' I'd call it readl. + * It doesn't. + * I won't. + * dwmw2 */ + + void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t); +- void (*write8)(struct map_info *, __u8, unsigned long); +- void (*write16)(struct map_info *, __u16, unsigned long); +- void (*write32)(struct map_info *, __u32, unsigned long); +- void (*write64)(struct map_info *, __u64, unsigned long); ++ void (*write8)(struct map_info *, u8, unsigned long); ++ void (*write16)(struct map_info *, u16, unsigned long); ++ void (*write32)(struct map_info *, u32, unsigned long); ++ void (*write64)(struct map_info *, u64, unsigned long); + void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t); + +- u_char * (*point) (struct map_info *, loff_t, size_t); +- void (*unpoint) (struct map_info *, u_char *, loff_t, size_t); +- ++ /* We can perhaps put in 'point' and 'unpoint' methods, if we really ++ want to enable XIP for non-linear mappings. Not yet though. */ ++#endif ++ /* set_vpp() must handle being reentered -- enable, enable, disable ++ must leave it enabled. */ + void (*set_vpp)(struct map_info *, int); +- /* We put these two here rather than a single void *map_priv, +- because we want mappers to be able to have quickly-accessible +- cache for the 'currently-mapped page' without the _extra_ +- redirection that would be necessary. If you need more than +- two longs, turn the second into a pointer. dwmw2 */ ++ + unsigned long map_priv_1; + unsigned long map_priv_2; + void *fldrv_priv; + struct mtd_chip_driver *fldrv; + }; + +- + struct mtd_chip_driver { + struct mtd_info *(*probe)(struct map_info *map); + void (*destroy)(struct mtd_info *); +@@ -74,26 +80,93 @@ + void unregister_mtd_chip_driver(struct mtd_chip_driver *); + + struct mtd_info *do_map_probe(const char *name, struct map_info *map); ++void map_destroy(struct mtd_info *mtd); ++ ++#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0) ++#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0) ++ ++#ifdef CONFIG_MTD_COMPLEX_MAPPINGS ++#define map_read8(map, ofs) (map)->read8(map, ofs) ++#define map_read16(map, ofs) (map)->read16(map, ofs) ++#define map_read32(map, ofs) (map)->read32(map, ofs) ++#define map_read64(map, ofs) (map)->read64(map, ofs) ++#define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len) ++#define map_write8(map, datum, ofs) (map)->write8(map, datum, ofs) ++#define map_write16(map, datum, ofs) (map)->write16(map, datum, ofs) ++#define map_write32(map, datum, ofs) (map)->write32(map, datum, ofs) ++#define map_write64(map, datum, ofs) (map)->write64(map, datum, ofs) ++#define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len) + ++extern void simple_map_init(struct map_info *); ++#define map_is_linear(map) (map->phys != NO_XIP) + +-/* +- * Destroy an MTD device which was created for a map device. +- * Make sure the MTD device is already unregistered before calling this +- */ +-static inline void map_destroy(struct mtd_info *mtd) +-{ +- struct map_info *map = mtd->priv; +- +- if (map->fldrv->destroy) +- map->fldrv->destroy(mtd); +-#ifdef CONFIG_MODULES +- if (map->fldrv->module) +- __MOD_DEC_USE_COUNT(map->fldrv->module); ++#else ++static inline u8 map_read8(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readb(map->virt + ofs); ++} ++ ++static inline u16 map_read16(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readw(map->virt + ofs); ++} ++ ++static inline u32 map_read32(struct map_info *map, unsigned long ofs) ++{ ++ return __raw_readl(map->virt + ofs); ++} ++ ++static inline u64 map_read64(struct map_info *map, unsigned long ofs) ++{ ++#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */ ++ BUG(); ++ return 0; ++#else ++ return __raw_readll(map->virt + ofs); + #endif +- kfree(mtd); + } + +-#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0) +-#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0) ++static inline void map_write8(struct map_info *map, u8 datum, unsigned long ofs) ++{ ++ __raw_writeb(datum, map->virt + ofs); ++ mb(); ++} ++ ++static inline void map_write16(struct map_info *map, u16 datum, unsigned long ofs) ++{ ++ __raw_writew(datum, map->virt + ofs); ++ mb(); ++} ++ ++static inline void map_write32(struct map_info *map, u32 datum, unsigned long ofs) ++{ ++ __raw_writel(datum, map->virt + ofs); ++ mb(); ++} ++ ++static inline void map_write64(struct map_info *map, u64 datum, unsigned long ofs) ++{ ++#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */ ++ BUG(); ++#else ++ __raw_writell(datum, map->virt + ofs); ++ mb(); ++#endif /* CFI_B8 */ ++} ++ ++static inline void map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) ++{ ++ memcpy_fromio(to, map->virt + from, len); ++} ++ ++static inline void map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) ++{ ++ memcpy_toio(map->virt + to, from, len); ++} ++ ++#define simple_map_init(map) do { } while (0) ++#define map_is_linear(map) (1) ++ ++#endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */ + + #endif /* __LINUX_MTD_MAP_H__ */ +diff -Nurb linux-mips-2.4.27/include/linux/mtd/mtd.h linux/include/linux/mtd/mtd.h +--- linux-mips-2.4.27/include/linux/mtd/mtd.h 2003-08-13 19:19:29.000000000 +0200 ++++ linux/include/linux/mtd/mtd.h 2004-11-19 10:25:12.055176080 +0100 +@@ -1,5 +1,10 @@ +- +-/* $Id: mtd.h,v 1.38 2003/01/12 16:30:19 spse Exp $ */ ++/* ++ * $Id: mtd.h,v 1.46 2003/07/11 07:36:21 dwmw2 Exp $ ++ * ++ * Copyright (C) 1999-2003 David Woodhouse et al. ++ * ++ * Released under GPL ++ */ + + #ifndef __MTD_MTD_H__ + #define __MTD_MTD_H__ +@@ -9,7 +14,6 @@ + #include + #include + #include +-#include + #include + #include + +@@ -26,7 +30,6 @@ + unsigned char *ptr; + }; + +- + #define MTD_CHAR_MAJOR 90 + #define MTD_BLOCK_MAJOR 31 + #define MAX_MTD_DEVICES 16 +@@ -93,18 +96,23 @@ + #define MEMUNLOCK _IOW('M', 6, struct erase_info_user) + #define MEMGETREGIONCOUNT _IOR('M', 7, int) + #define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) +-#define MEMREADDATA _IOWR('M', 9, struct mtd_oob_buf) +-#define MEMWRITEDATA _IOWR('M', 10, struct mtd_oob_buf) ++#define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) ++ ++struct nand_oobinfo { ++ int useecc; ++ int eccpos[6]; ++}; ++ + + #ifndef __KERNEL__ + + typedef struct mtd_info_user mtd_info_t; + typedef struct erase_info_user erase_info_t; + typedef struct region_info_user region_info_t; ++typedef struct nand_oobinfo nand_oobinfo_t; + + /* User-space ioctl definitions */ + +- + #else /* __KERNEL__ */ + + +@@ -150,10 +158,14 @@ + u_int32_t ecctype; + u_int32_t eccsize; + ++ + // Kernel-only stuff starts here. + char *name; + int index; + ++ // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) ++ struct nand_oobinfo oobinfo; ++ + /* Data for variable erase regions. If numeraseregions is zero, + * it means that the whole device has erasesize as given above. + */ +@@ -163,7 +175,6 @@ + /* This really shouldn't be here. It can go away in 2.5 */ + u_int32_t bank_size; + +- struct module *module; + int (*erase) (struct mtd_info *mtd, struct erase_info *instr); + + /* This stuff for eXecute-In-Place */ +@@ -176,8 +187,8 @@ + int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); + +- int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel); +- int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel); ++ int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); ++ int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); + + int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); +@@ -201,10 +212,10 @@ + */ + int (*readv) (struct mtd_info *mtd, struct iovec *vecs, unsigned long count, loff_t from, size_t *retlen); + int (*readv_ecc) (struct mtd_info *mtd, struct iovec *vecs, unsigned long count, loff_t from, +- size_t *retlen, u_char *eccbuf, int oobsel); ++ size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); + int (*writev) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen); + int (*writev_ecc) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, +- size_t *retlen, u_char *eccbuf, int oobsel); ++ size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); + + /* Sync */ + void (*sync) (struct mtd_info *mtd); +@@ -218,6 +229,9 @@ + void (*resume) (struct mtd_info *mtd); + + void *priv; ++ ++ struct module *owner; ++ int usecount; + }; + + +@@ -226,31 +240,15 @@ + extern int add_mtd_device(struct mtd_info *mtd); + extern int del_mtd_device (struct mtd_info *mtd); + +-extern struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num); +- +-static inline struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) +-{ +- struct mtd_info *ret; ++extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); + +- ret = __get_mtd_device(mtd, num); +- +- if (ret && ret->module && !try_inc_mod_count(ret->module)) +- return NULL; +- +- return ret; +-} +- +-static inline void put_mtd_device(struct mtd_info *mtd) +-{ +- if (mtd->module) +- __MOD_DEC_USE_COUNT(mtd->module); +-} ++extern void put_mtd_device(struct mtd_info *mtd); + + + struct mtd_notifier { + void (*add)(struct mtd_info *mtd); + void (*remove)(struct mtd_info *mtd); +- struct mtd_notifier *next; ++ struct list_head list; + }; + + +@@ -263,7 +261,6 @@ + int default_mtd_readv(struct mtd_info *mtd, struct iovec *vecs, + unsigned long count, loff_t from, size_t *retlen); + +-#ifndef MTDC + #define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args) + #define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d)) + #define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg) +@@ -276,7 +273,6 @@ + #define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args) + #define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args) + #define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0) +-#endif /* MTDC */ + + /* + * Debugging macro and defines +@@ -293,7 +289,8 @@ + printk(KERN_INFO args); \ + } while(0) + #else /* CONFIG_MTD_DEBUG */ +-#define DEBUG(n, args...) ++#define DEBUG(n, args...) do { } while(0) ++ + #endif /* CONFIG_MTD_DEBUG */ + + #endif /* __KERNEL__ */ +diff -Nurb linux-mips-2.4.27/include/linux/mtd/nand.h linux/include/linux/mtd/nand.h +--- linux-mips-2.4.27/include/linux/mtd/nand.h 2003-02-26 01:53:51.000000000 +0100 ++++ linux/include/linux/mtd/nand.h 2004-11-19 10:25:12.057175776 +0100 +@@ -2,10 +2,10 @@ + * linux/include/linux/mtd/nand.h + * + * Copyright (c) 2000 David Woodhouse +- * Steven J. Hill ++ * Steven J. Hill + * Thomas Gleixner + * +- * $Id: nand.h,v 1.19 2002/12/02 21:48:17 gleixner Exp $ ++ * $Id: nand.h,v 1.31 2003/07/11 15:07:02 dwmw2 Exp $ + * + * 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 +@@ -49,12 +49,14 @@ + #define __LINUX_MTD_NAND_H + + #include +-#include ++#include ++#include + ++struct mtd_info; + /* + * Searches for a NAND device + */ +-extern int nand_scan (struct mtd_info *mtd); ++extern int nand_scan (struct mtd_info *mtd, int max_chips); + + /* + * Constants for hardware specific CLE/ALE/NCE function +@@ -65,6 +67,8 @@ + #define NAND_CTL_CLRCLE 4 + #define NAND_CTL_SETALE 5 + #define NAND_CTL_CLRALE 6 ++#define NAND_CTL_SETWP 7 ++#define NAND_CTL_CLRWP 8 + + /* + * Standard NAND flash commands +@@ -160,24 +164,33 @@ + struct nand_chip { + unsigned long IO_ADDR_R; + unsigned long IO_ADDR_W; +- void (*hwcontrol)(int cmd); +- int (*dev_ready)(void); ++ ++ u_char (*read_byte)(struct mtd_info *mtd); ++ void (*write_byte)(struct mtd_info *mtd, u_char byte); ++ ++ void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len); ++ void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len); ++ int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len); ++ void (*select_chip)(struct mtd_info *mtd, int chip); ++ int (*block_bad)(struct mtd_info *mtd, unsigned long pos); ++ void (*hwcontrol)(struct mtd_info *mtd, int cmd); ++ int (*dev_ready)(struct mtd_info *mtd); + void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); + int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); +- void (*calculate_ecc)(const u_char *dat, u_char *ecc_code); +- int (*correct_data)(u_char *dat, u_char *read_ecc, u_char *calc_ecc); +- void (*enable_hwecc)(int mode); ++ void (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); ++ int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); ++ void (*enable_hwecc)(struct mtd_info *mtd, int mode); + int eccmode; + int eccsize; + int chip_delay; ++ int chipshift; + spinlock_t chip_lock; + wait_queue_head_t wq; + nand_state_t state; + int page_shift; + u_char *data_buf; + u_char *data_poi; +- u_char *data_cache; +- int cache_page; ++ void *priv; + }; + + /* +@@ -241,34 +254,4 @@ + */ + #define NAND_BADBLOCK_POS 5 + +-#define NAND_NONE_OOB 0 +-#define NAND_JFFS2_OOB 1 +-#define NAND_YAFFS_OOB 2 +- +-#define NAND_NOOB_ECCPOS0 0 +-#define NAND_NOOB_ECCPOS1 1 +-#define NAND_NOOB_ECCPOS2 2 +-#define NAND_NOOB_ECCPOS3 3 +-#define NAND_NOOB_ECCPOS4 6 +-#define NAND_NOOB_ECCPOS5 7 +- +-#define NAND_JFFS2_OOB_ECCPOS0 0 +-#define NAND_JFFS2_OOB_ECCPOS1 1 +-#define NAND_JFFS2_OOB_ECCPOS2 2 +-#define NAND_JFFS2_OOB_ECCPOS3 3 +-#define NAND_JFFS2_OOB_ECCPOS4 6 +-#define NAND_JFFS2_OOB_ECCPOS5 7 +- +-#define NAND_YAFFS_OOB_ECCPOS0 8 +-#define NAND_YAFFS_OOB_ECCPOS1 9 +-#define NAND_YAFFS_OOB_ECCPOS2 10 +-#define NAND_YAFFS_OOB_ECCPOS3 13 +-#define NAND_YAFFS_OOB_ECCPOS4 14 +-#define NAND_YAFFS_OOB_ECCPOS5 15 +- +-#define NAND_JFFS2_OOB8_FSDAPOS 6 +-#define NAND_JFFS2_OOB16_FSDAPOS 8 +-#define NAND_JFFS2_OOB8_FSDALEN 2 +-#define NAND_JFFS2_OOB16_FSDALEN 8 +- + #endif /* __LINUX_MTD_NAND_H */ +diff -Nurb linux-mips-2.4.27/include/linux/mtd/nand_ecc.h linux/include/linux/mtd/nand_ecc.h +--- linux-mips-2.4.27/include/linux/mtd/nand_ecc.h 2001-08-22 05:25:12.000000000 +0200 ++++ linux/include/linux/mtd/nand_ecc.h 2004-11-19 10:25:12.058175624 +0100 +@@ -1,9 +1,9 @@ + /* + * drivers/mtd/nand_ecc.h + * +- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) ++ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) + * +- * $Id: nand_ecc.h,v 1.1 2000/10/12 00:57:15 sjhill Exp $ ++ * $Id: nand_ecc.h,v 1.3 2003/07/01 23:31:15 dwmw2 Exp $ + * + * 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 +@@ -12,17 +12,19 @@ + * This file is the header for the ECC algorithm. + */ + +-/* +- * Creates non-inverted ECC code from line parity +- */ +-void nand_trans_result(u_char reg2, u_char reg3, u_char *ecc_code); ++#ifndef __MTD_NAND_ECC_H__ ++#define __MTD_NAND_ECC_H__ ++ ++struct mtd_info; + + /* + * Calculate 3 byte ECC code for 256 byte block + */ +-void nand_calculate_ecc (const u_char *dat, u_char *ecc_code); ++void nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); + + /* + * Detect and correct a 1 bit error for 256 byte block + */ +-int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc); ++int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); ++ ++#endif /* __MTD_NAND_ECC_H__ */ +diff -Nurb linux-mips-2.4.27/include/linux/mtd/nftl.h linux/include/linux/mtd/nftl.h +--- linux-mips-2.4.27/include/linux/mtd/nftl.h 2003-02-26 01:53:51.000000000 +0100 ++++ linux/include/linux/mtd/nftl.h 2004-11-19 10:25:12.060175320 +0100 +@@ -1,15 +1,14 @@ +- +-/* Defines for NAND Flash Translation Layer */ +-/* (c) 1999 Machine Vision Holdings, Inc. */ +-/* Author: David Woodhouse */ +-/* $Id: nftl.h,v 1.11 2002/06/18 13:54:24 dwmw2 Exp $ */ ++/* ++ * $Id: nftl.h,v 1.13 2003/05/23 11:25:02 dwmw2 Exp $ ++ * ++ * (C) 1999-2003 David Woodhouse ++ */ + + #ifndef __MTD_NFTL_H__ + #define __MTD_NFTL_H__ + +-#ifndef __BOOT__ + #include +-#endif ++#include + + /* Block Control Information */ + +@@ -84,8 +83,7 @@ + #define BLOCK_RESERVED 0xfffc /* bios block or bad block */ + + struct NFTLrecord { +- struct mtd_info *mtd; +- struct semaphore mutex; ++ struct mtd_blktrans_dev mbd; + __u16 MediaUnit, SpareMediaUnit; + __u32 EraseSize; + struct NFTLMediaHeader MediaHdr; +@@ -97,7 +95,6 @@ + __u16 lastEUN; /* should be suppressed */ + __u16 numfreeEUNs; + __u16 LastFreeEUN; /* To speed up finding a free EUN */ +- __u32 nr_sects; + int head,sect,cyl; + __u16 *EUNtable; /* [numvunits]: First EUN for each virtual unit */ + __u16 *ReplUnitTable; /* [numEUNs]: ReplUnitNumber for each */ +@@ -114,7 +111,7 @@ + #endif + + #define MAX_NFTLS 16 +-#define MAX_SECTORS_PER_UNIT 32 ++#define MAX_SECTORS_PER_UNIT 64 + #define NFTL_PARTN_BITS 4 + + #endif /* __KERNEL__ */ +diff -Nurb linux-mips-2.4.27/include/linux/mtd/partitions.h linux/include/linux/mtd/partitions.h +--- linux-mips-2.4.27/include/linux/mtd/partitions.h 2002-06-27 00:36:47.000000000 +0200 ++++ linux/include/linux/mtd/partitions.h 2004-11-19 10:25:12.061175168 +0100 +@@ -5,7 +5,7 @@ + * + * This code is GPL + * +- * $Id: partitions.h,v 1.8 2002/03/08 16:34:36 rkaiser Exp $ ++ * $Id: partitions.h,v 1.15 2003/07/09 11:15:43 dwmw2 Exp $ + */ + + #ifndef MTD_PARTITIONS_H +@@ -41,6 +41,7 @@ + u_int32_t size; /* partition size */ + u_int32_t offset; /* offset within the master MTD space */ + u_int32_t mask_flags; /* master MTD flags to mask out for this partition */ ++ struct nand_oobinfo *oobsel; /* out of band layout for this partition (NAND only)*/ + struct mtd_info **mtdp; /* pointer to store the MTD object */ + }; + +@@ -49,8 +50,27 @@ + #define MTDPART_SIZ_FULL (0) + + +-int add_mtd_partitions(struct mtd_info *, struct mtd_partition *, int); ++int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); + int del_mtd_partitions(struct mtd_info *); + ++/* ++ * Functions dealing with the various ways of partitioning the space ++ */ ++ ++struct mtd_part_parser { ++ struct list_head list; ++ struct module *owner; ++ const char *name; ++ int (*parse_fn)(struct mtd_info *, struct mtd_partition **, unsigned long); ++}; ++ ++extern struct mtd_part_parser *get_partition_parser(const char *name); ++extern int register_mtd_parser(struct mtd_part_parser *parser); ++extern int deregister_mtd_parser(struct mtd_part_parser *parser); ++extern int parse_mtd_partitions(struct mtd_info *master, const char **types, ++ struct mtd_partition **pparts, unsigned long origin); ++ ++#define put_partition_parser(p) do { module_put((p)->owner); } while(0) ++ + #endif + +diff -Nurb linux-mips-2.4.27/include/linux/mtd/physmap.h linux/include/linux/mtd/physmap.h +--- linux-mips-2.4.27/include/linux/mtd/physmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux/include/linux/mtd/physmap.h 2004-11-19 10:25:12.062175016 +0100 +@@ -0,0 +1,59 @@ ++/* ++ * For boards with physically mapped flash and using ++ * drivers/mtd/maps/physmap.c mapping driver. ++ * ++ * Copyright (C) 2003 MontaVista Software Inc. ++ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ */ ++ ++#ifndef __LINUX_MTD_PHYSMAP__ ++ ++#include ++ ++#if defined(CONFIG_MTD_PHYSMAP) ++ ++#include ++#include ++#include ++ ++/* ++ * The map_info for physmap. Board can override size, buswidth, phys, ++ * (*set_vpp)(), etc in their initial setup routine. ++ */ ++extern struct map_info physmap_map; ++ ++/* ++ * Board needs to specify the exact mapping during their setup time. ++ */ ++static inline void physmap_configure(unsigned long addr, unsigned long size, int buswidth, void (*set_vpp)(struct map_info *, int) ) ++{ ++ physmap_map.phys = addr; ++ physmap_map.size = size; ++ physmap_map.buswidth = buswidth; ++ physmap_map.set_vpp = set_vpp; ++} ++ ++#if defined(CONFIG_MTD_PARTITIONS) ++ ++/* ++ * Machines that wish to do flash partition may want to call this function in ++ * their setup routine. ++ * ++ * physmap_set_partitions(mypartitions, num_parts); ++ * ++ * Note that one can always override this hard-coded partition with ++ * command line partition (you need to enable CONFIG_MTD_CMDLINE_PARTS). ++ */ ++void physmap_set_partitions(struct mtd_partition *parts, int num_parts); ++ ++#endif /* defined(CONFIG_MTD_PARTITIONS) */ ++#endif /* defined(CONFIG_MTD) */ ++ ++#endif /* __LINUX_MTD_PHYSMAP__ */ ++ +diff -Nurb linux-mips-2.4.27/include/linux/rbtree-24.h linux/include/linux/rbtree-24.h +--- linux-mips-2.4.27/include/linux/rbtree-24.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux/include/linux/rbtree-24.h 2004-11-19 10:25:12.143162704 +0100 +@@ -0,0 +1,133 @@ ++/* ++ Red Black Trees ++ (C) 1999 Andrea Arcangeli ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ linux/include/linux/rbtree.h ++ ++ To use rbtrees you'll have to implement your own insert and search cores. ++ This will avoid us to use callbacks and to drop drammatically performances. ++ I know it's not the cleaner way, but in C (not in C++) to get ++ performances and genericity... ++ ++ Some example of insert and search follows here. The search is a plain ++ normal search over an ordered tree. The insert instead must be implemented ++ int two steps: as first thing the code must insert the element in ++ order as a red leaf in the tree, then the support library function ++ rb_insert_color() must be called. Such function will do the ++ not trivial work to rebalance the rbtree if necessary. ++ ++----------------------------------------------------------------------- ++static inline struct page * rb_search_page_cache(struct inode * inode, ++ unsigned long offset) ++{ ++ rb_node_t * n = inode->i_rb_page_cache.rb_node; ++ struct page * page; ++ ++ while (n) ++ { ++ page = rb_entry(n, struct page, rb_page_cache); ++ ++ if (offset < page->offset) ++ n = n->rb_left; ++ else if (offset > page->offset) ++ n = n->rb_right; ++ else ++ return page; ++ } ++ return NULL; ++} ++ ++static inline struct page * __rb_insert_page_cache(struct inode * inode, ++ unsigned long offset, ++ rb_node_t * node) ++{ ++ rb_node_t ** p = &inode->i_rb_page_cache.rb_node; ++ rb_node_t * parent = NULL; ++ struct page * page; ++ ++ while (*p) ++ { ++ parent = *p; ++ page = rb_entry(parent, struct page, rb_page_cache); ++ ++ if (offset < page->offset) ++ p = &(*p)->rb_left; ++ else if (offset > page->offset) ++ p = &(*p)->rb_right; ++ else ++ return page; ++ } ++ ++ rb_link_node(node, parent, p); ++ ++ return NULL; ++} ++ ++static inline struct page * rb_insert_page_cache(struct inode * inode, ++ unsigned long offset, ++ rb_node_t * node) ++{ ++ struct page * ret; ++ if ((ret = __rb_insert_page_cache(inode, offset, node))) ++ goto out; ++ rb_insert_color(node, &inode->i_rb_page_cache); ++ out: ++ return ret; ++} ++----------------------------------------------------------------------- ++*/ ++ ++#ifndef _LINUX_RBTREE_H ++#define _LINUX_RBTREE_H ++ ++#include ++#include ++ ++typedef struct rb_node_s ++{ ++ struct rb_node_s * rb_parent; ++ int rb_color; ++#define RB_RED 0 ++#define RB_BLACK 1 ++ struct rb_node_s * rb_right; ++ struct rb_node_s * rb_left; ++} ++rb_node_t; ++ ++typedef struct rb_root_s ++{ ++ struct rb_node_s * rb_node; ++} ++rb_root_t; ++ ++#define RB_ROOT (rb_root_t) { NULL, } ++#define rb_entry(ptr, type, member) \ ++ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) ++ ++extern void rb_insert_color(rb_node_t *, rb_root_t *); ++extern void rb_erase(rb_node_t *, rb_root_t *); ++ ++static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link) ++{ ++ node->rb_parent = parent; ++ node->rb_color = RB_RED; ++ node->rb_left = node->rb_right = NULL; ++ ++ *rb_link = node; ++} ++ ++#endif /* _LINUX_RBTREE_H */ +diff -Nurb linux-mips-2.4.27/include/linux/rbtree.h linux/include/linux/rbtree.h +--- linux-mips-2.4.27/include/linux/rbtree.h 2001-10-19 03:25:03.000000000 +0200 ++++ linux/include/linux/rbtree.h 2004-11-19 10:25:12.148161944 +0100 +@@ -1,133 +1,25 @@ + /* +- Red Black Trees +- (C) 1999 Andrea Arcangeli ++ * 2.5 compatibility ++ * $Id: rbtree.h,v 1.3 2003/01/14 13:56:05 dwmw2 Exp $ ++ */ ++ ++#ifndef __MTD_COMPAT_RBTREE_H__ ++#define __MTD_COMPAT_RBTREE_H__ ++ ++#include ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,40) ++#include_next ++#else ++#define rb_node_s rb_node ++#define rb_root_s rb_root ++ ++#include ++ ++/* Find logical next and previous nodes in a tree */ ++extern struct rb_node *rb_next(struct rb_node *); ++extern struct rb_node *rb_prev(struct rb_node *); ++extern struct rb_node *rb_first(struct rb_root *); ++#endif + +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 2 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; if not, write to the Free Software +- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +- +- linux/include/linux/rbtree.h +- +- To use rbtrees you'll have to implement your own insert and search cores. +- This will avoid us to use callbacks and to drop drammatically performances. +- I know it's not the cleaner way, but in C (not in C++) to get +- performances and genericity... +- +- Some example of insert and search follows here. The search is a plain +- normal search over an ordered tree. The insert instead must be implemented +- int two steps: as first thing the code must insert the element in +- order as a red leaf in the tree, then the support library function +- rb_insert_color() must be called. Such function will do the +- not trivial work to rebalance the rbtree if necessary. +- +------------------------------------------------------------------------ +-static inline struct page * rb_search_page_cache(struct inode * inode, +- unsigned long offset) +-{ +- rb_node_t * n = inode->i_rb_page_cache.rb_node; +- struct page * page; +- +- while (n) +- { +- page = rb_entry(n, struct page, rb_page_cache); +- +- if (offset < page->offset) +- n = n->rb_left; +- else if (offset > page->offset) +- n = n->rb_right; +- else +- return page; +- } +- return NULL; +-} +- +-static inline struct page * __rb_insert_page_cache(struct inode * inode, +- unsigned long offset, +- rb_node_t * node) +-{ +- rb_node_t ** p = &inode->i_rb_page_cache.rb_node; +- rb_node_t * parent = NULL; +- struct page * page; +- +- while (*p) +- { +- parent = *p; +- page = rb_entry(parent, struct page, rb_page_cache); +- +- if (offset < page->offset) +- p = &(*p)->rb_left; +- else if (offset > page->offset) +- p = &(*p)->rb_right; +- else +- return page; +- } +- +- rb_link_node(node, parent, p); +- +- return NULL; +-} +- +-static inline struct page * rb_insert_page_cache(struct inode * inode, +- unsigned long offset, +- rb_node_t * node) +-{ +- struct page * ret; +- if ((ret = __rb_insert_page_cache(inode, offset, node))) +- goto out; +- rb_insert_color(node, &inode->i_rb_page_cache); +- out: +- return ret; +-} +------------------------------------------------------------------------ +-*/ +- +-#ifndef _LINUX_RBTREE_H +-#define _LINUX_RBTREE_H +- +-#include +-#include +- +-typedef struct rb_node_s +-{ +- struct rb_node_s * rb_parent; +- int rb_color; +-#define RB_RED 0 +-#define RB_BLACK 1 +- struct rb_node_s * rb_right; +- struct rb_node_s * rb_left; +-} +-rb_node_t; +- +-typedef struct rb_root_s +-{ +- struct rb_node_s * rb_node; +-} +-rb_root_t; +- +-#define RB_ROOT (rb_root_t) { NULL, } +-#define rb_entry(ptr, type, member) \ +- ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) +- +-extern void rb_insert_color(rb_node_t *, rb_root_t *); +-extern void rb_erase(rb_node_t *, rb_root_t *); +- +-static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link) +-{ +- node->rb_parent = parent; +- node->rb_color = RB_RED; +- node->rb_left = node->rb_right = NULL; +- +- *rb_link = node; +-} +- +-#endif /* _LINUX_RBTREE_H */ ++#endif /* __MTD_COMPAT_RBTREE_H__ */ +diff -Nurb linux-mips-2.4.27/include/linux/suspend.h linux/include/linux/suspend.h +--- linux-mips-2.4.27/include/linux/suspend.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux/include/linux/suspend.h 2004-11-19 10:25:12.150161640 +0100 +@@ -0,0 +1,10 @@ ++/* $Id: suspend.h,v 1.1 2003/10/13 20:56:47 dwmw2 Exp $ */ ++ ++#ifndef __MTD_COMPAT_VERSION_H__ ++#include ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++#include_next ++#endif ++ ++#endif /* __MTD_COMPAT_VERSION_H__ */ +diff -Nurb linux-mips-2.4.27/include/linux/workqueue.h linux/include/linux/workqueue.h +--- linux-mips-2.4.27/include/linux/workqueue.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux/include/linux/workqueue.h 2004-11-19 10:25:12.152161336 +0100 +@@ -0,0 +1,21 @@ ++/* ++ * 2.5 compatibility ++ * $Id: workqueue.h,v 1.1 2002/11/11 16:39:10 dwmw2 Exp $ ++ */ ++ ++#ifndef __MTD_COMPAT_WORKQUEUE_H__ ++#define __MTD_COMPAT_WORKQUEUE_H__ ++ ++#include ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,40) ++#include_next ++#else ++#include ++#define work_struct tq_struct ++#define schedule_work(x) schedule_task(x) ++#define flush_scheduled_work flush_scheduled_tasks ++#define INIT_WORK(x,y,z) INIT_TQUEUE(x,y,z) ++#endif ++ ++#endif /* __MTD_COMPAT_WORKQUEUE_H__ */ +--- linux-old/drivers/mtd/maps/Config.in 2006-05-01 12:48:20.432213500 +0200 ++++ linux/drivers/mtd/maps/Config.in 2006-04-30 20:35:58.000000000 +0200 +@@ -1,17 +1,14 @@ + # drivers/mtd/maps/Config.in + +-# $Id: Config.in,v 1.43 2003/01/24 14:26:38 dwmw2 Exp $ ++# $Id: Config.in,v 1.63 2003/11/26 21:26:09 dsaxena Exp $ + + mainmenu_option next_comment + + comment 'Mapping drivers for chip access' + +-dep_tristate ' CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_GEN_PROBE +-if [ "$CONFIG_MTD_PHYSMAP" = "y" -o "$CONFIG_MTD_PHYSMAP" = "m" ]; then +- hex ' Physical start address of flash mapping' CONFIG_MTD_PHYSMAP_START 0x8000000 +- hex ' Physical length of flash mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000 +- int ' Bus width in octets' CONFIG_MTD_PHYSMAP_BUSWIDTH 2 +-fi ++bool ' Support for non-linear mappings of flash chips' CONFIG_MTD_COMPLEX_MAPPINGS ++ ++bool ' CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_GEN_PROBE + + if [ "$CONFIG_SPARC" = "y" -o "$CONFIG_SPARC64" = "y" ]; then + dep_tristate ' Sun Microsystems userflash support' CONFIG_MTD_SUN_UFLASH $CONFIG_MTD_CFI +@@ -21,57 +18,70 @@ + dep_tristate ' CFI Flash device mapped on Photron PNC-2000' CONFIG_MTD_PNC2000 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS + dep_tristate ' CFI Flash device mapped on AMD SC520 CDP' CONFIG_MTD_SC520CDP $CONFIG_MTD_CFI + dep_tristate ' CFI Flash device mapped on AMD NetSc520' CONFIG_MTD_NETSC520 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS +- dep_tristate ' CFI Flash device mapped on Arcom SBC-GXx boards' CONFIG_MTD_SBC_GXX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS +- dep_tristate ' CFI Flash device mapped on Arcom ELAN-104NC' CONFIG_MTD_ELAN_104NC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS ++ dep_tristate ' CFI Flash device mapped on Arcom SBC-GXx boards' CONFIG_MTD_SBC_GXX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS $CONFIG_MTD_COMPLEX_MAPPINGS ++ dep_tristate ' CFI Flash device mapped on Arcom ELAN-104NC' CONFIG_MTD_ELAN_104NC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS $CONFIG_MTD_COMPLEX_MAPPINGS + dep_tristate ' CFI Flash device mapped on DIL/Net PC' CONFIG_MTD_DILNETPC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS $CONFIG_MTD_CONCAT + if [ "$CONFIG_MTD_DILNETPC" = "y" -o "$CONFIG_MTD_DILNETPC" = "m" ]; then + hex ' Size of boot partition' CONFIG_MTD_DILNETPC_BOOTSIZE 0x80000 + fi +- dep_tristate ' JEDEC Flash device mapped on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC +- dep_tristate ' JEDEC Flash device mapped on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC +- dep_tristate ' JEDEC Flash device mapped on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC ++ dep_tristate ' JEDEC Flash device mapped on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC $CONFIG_MTD_COMPLEX_MAPPINGS ++ dep_tristate ' JEDEC Flash device mapped on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC $CONFIG_MTD_COMPLEX_MAPPINGS + dep_tristate ' Flash device mapped with DOCCS on NatSemi SCx200' CONFIG_MTD_SCx200_DOCFLASH $CONFIG_MTD_CFI + dep_tristate ' BIOS flash chip on Intel L440GX boards' CONFIG_MTD_L440GX $CONFIG_MTD_JEDECPROBE + dep_tristate ' ROM connected to AMD76X southbridge' CONFIG_MTD_AMD76XROM $CONFIG_MTD_GEN_PROBE +- dep_tristate ' ROM connected to Intel Hub Controller 2' CONFIG_MTD_ICH2ROM $CONFIG_MTD_JEDECPROBE ++ dep_tristate ' ROM connected to Intel Hub Controller 2/3/4/5' CONFIG_MTD_ICHXROM $CONFIG_MTD_JEDECPROBE $CONFIG_MTD_COMPLEX_MAPPINGS + dep_tristate ' CFI Flash device mapped on SnapGear/SecureEdge' CONFIG_MTD_NETtel $CONFIG_MTD_PARTITIONS + dep_tristate ' BIOS flash chip on Intel SCB2 boards' CONFIG_MTD_SCB2_FLASH $CONFIG_MTD_GEN_PROBE + fi + +-if [ "$CONFIG_PPC" = "y" ]; then +- dep_tristate ' CFI Flash device mapped on TQM8XXL' CONFIG_MTD_TQM8XXL $CONFIG_MTD_CFI $CONFIG_TQM8xxL ++if [ "$CONFIG_PPC32" = "y" ]; then ++ if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "y" ]; then ++ dep_tristate ' Flash device on SBC8240' CONFIG_MTD_SBC8240 $CONFIG_MTD_JEDECPROBE ++ fi ++ if [ "$CONFIG_8xx" = "y" ]; then ++ if [ "$CONFIG_TQM8xxL" = "y" ]; then ++ dep_tristate ' CFI Flash device mapped on TQM8XXL' CONFIG_MTD_TQM8XXL $CONFIG_MTD_CFI ++ fi ++ if [ "$CONFIG_RPXLITE" = "y" -o "$CONFIG_RPXCLASSIC" = "y" ]; then + dep_tristate ' CFI Flash device mapped on RPX Lite or CLLF' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI ++ fi ++ if [ "$CONFIG_MBX" = "y" ]; then + dep_tristate ' System flash on MBX860 board' CONFIG_MTD_MBX860 $CONFIG_MTD_CFI ++ fi ++ if [ "$CONFIG_DBOX2" = "y" ]; then + dep_tristate ' CFI Flash device mapped on D-Box2' CONFIG_MTD_DBOX2 $CONFIG_MTD_CFI ++ fi + dep_tristate ' CFI Flash device mapping on FlagaDM' CONFIG_MTD_CFI_FLAGADM $CONFIG_MTD_CFI +- dep_tristate ' CFI Flash device mapped on IBM Redwood-4/5' CONFIG_MTD_REDWOOD $CONFIG_MTD_CFI +-fi +- +-if [ "$CONFIG_MIPS" = "y" ]; then +- dep_tristate ' Pb1000 MTD support' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000 +- dep_tristate ' Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500 +- dep_tristate ' Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100 +- dep_tristate ' Bosporus MTD support' CONFIG_MTD_BOSPORUS $CONFIG_MIPS_BOSPORUS +- dep_tristate ' XXS1500 boot flash device' CONFIG_MTD_XXS1500 $CONFIG_MIPS_XXS1500 +- dep_tristate ' MTX-1 flash device' CONFIG_MTD_MTX1 $CONFIG_MIPS_MTX1 +- dep_tristate ' MTX-2 flash device' CONFIG_MTD_MTX2 $CONFIG_MIPS_MTX2 +- if [ "$CONFIG_MTD_PB1500" = "y" -o "$CONFIG_MTD_PB1500" = "m" \ +- -o "$CONFIG_MTD_PB1100" = "y" -o "$CONFIG_MTD_PB1100" = "m" ]; then +- bool ' Pb[15]00 boot flash device' CONFIG_MTD_PB1500_BOOT +- bool ' Pb[15]00 user flash device (2nd 32MiB bank)' CONFIG_MTD_PB1500_USER ++ fi ++ if [ "$CONFIG_4xx" = "y" ]; then ++ if [ "$CONFIG_40x" = "y" ]; then ++ if [ "$CONFIG_REDWOOD_4" = "y" -o "$CONFIG_REDWOOD_5" = "y" -o "$CONFIG_REDWOOD_6" = "y" ]; then ++ dep_tristate ' CFI Flash device mapped on IBM Redwood' CONFIG_MTD_REDWOOD $CONFIG_MTD_CFI ++ fi ++ dep_tristate ' CFI Flash device mapped on IBM Beech' CONFIG_MTD_BEECH $CONFIG_MTD_CFI $CONFIG_BEECH ++ dep_tristate ' CFI Flash device mapped on IBM Arctic' CONFIG_MTD_ARCTIC $CONFIG_MTD_CFI $CONFIG_ARCTIC2 ++ fi ++ if [ "$CONFIG_440" = "y" ]; then ++ dep_tristate ' Flash devices mapped on IBM Ebony' CONFIG_MTD_EBONY $CONFIG_MTD_CFI $CONFIG_EBONY ++ fi ++ fi ++fi ++ ++if [ "$CONFIG_MIPS" = "y" -o "$CONFIG_MIPS64" = "y" ]; then ++ if [ "$CONFIG_MIPS_PB1000" = "y" -o "$CONFIG_MIPS_PB1100" = "y" -o "$CONFIG_MIPS_PB1500" = "y" ]; then ++ tristate ' Pb1x00 MTD support' CONFIG_MTD_PB1XXX ++ if [ "$CONFIG_MIPS_PB1500" = "y" -o "$CONFIG_MIPS_PB1100" = "m" ]; then ++ bool ' Pb1x00 boot flash device' CONFIG_MTD_PB1500_BOOT ++ bool ' Pb1x00 user flash device (2nd 32MiB bank)' CONFIG_MTD_PB1500_USER ++ fi + fi + tristate ' Db1x00 MTD support' CONFIG_MTD_DB1X00 + if [ "$CONFIG_MTD_DB1X00" = "y" -o "$CONFIG_MTD_DB1X00" = "m" ]; then + bool ' Db1x00 boot flash device' CONFIG_MTD_DB1X00_BOOT + bool ' Db1x00 user flash device (2nd bank)' CONFIG_MTD_DB1X00_USER + fi +- tristate ' Pb1550 MTD support' CONFIG_MTD_PB1550 +- if [ "$CONFIG_MTD_PB1550" = "y" -o "$CONFIG_MTD_PB1550" = "m" ]; then +- bool ' Pb1550 Boot Flash' CONFIG_MTD_PB1550_BOOT +- bool ' Pb1550 User Parameter Flash' CONFIG_MTD_PB1550_USER +- fi +- dep_tristate ' Hydrogen 3 MTD support' CONFIG_MTD_HYDROGEN3 $CONFIG_MIPS_HYDROGEN3 +- dep_tristate ' Mirage MTD support' CONFIG_MTD_MIRAGE $CONFIG_MIPS_MIRAGE ++ dep_tristate ' MTX-1 flash device' CONFIG_MTD_MTX1 $CONFIG_MIPS_MTX1 ++ dep_tristate ' MTX-2 flash device' CONFIG_MTD_MTX2 $CONFIG_MIPS_MTX2 + dep_tristate ' Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board' CONFIG_MTD_CSTM_MIPS_IXX $CONFIG_MTD_CFI $CONFIG_MTD_JEDEC $CONFIG_MTD_PARTITIONS + if [ "$CONFIG_MTD_CSTM_MIPS_IXX" = "y" -o "$CONFIG_MTD_CSTM_MIPS_IXX" = "m" ]; then + hex ' Physical start address of flash mapping' CONFIG_MTD_CSTM_MIPS_IXX_START 0x8000000 +@@ -79,7 +89,7 @@ + int ' Bus width in octets' CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH 2 + fi + dep_tristate ' Momenco Ocelot boot flash device' CONFIG_MTD_OCELOT $CONFIG_MOMENCO_OCELOT +- dep_tristate ' LASAT flash device' CONFIG_MTD_LASAT $CONFIG_MTD_CFI $CONFIG_LASAT ++ dep_tristate ' LASAT flash device' CONFIG_MTD_LASAT $CONFIG_LASAT + fi + + if [ "$CONFIG_SUPERH" = "y" ]; then +@@ -91,21 +101,24 @@ + fi + + if [ "$CONFIG_ARM" = "y" ]; then +- dep_tristate ' CFI Flash device mapped on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI + dep_tristate ' CFI Flash device mapped on ARM Integrator/P720T' CONFIG_MTD_ARM_INTEGRATOR $CONFIG_MTD_CFI + dep_tristate ' Cirrus CDB89712 evaluation board mappings' CONFIG_MTD_CDB89712 $CONFIG_MTD_CFI $CONFIG_ARCH_CDB89712 + dep_tristate ' CFI Flash device mapped on StrongARM SA11x0' CONFIG_MTD_SA1100 $CONFIG_MTD_CFI $CONFIG_ARCH_SA1100 $CONFIG_MTD_PARTITIONS +- dep_tristate ' CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_CFI $CONFIG_ARCH_FOOTBRIDGE ++ dep_tristate ' CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_CFI $CONFIG_ARCH_FOOTBRIDGE $CONFIG_MTD_COMPLEX_MAPPINGS + dep_tristate ' CFI Flash device mapped on the XScale IQ80310 board' CONFIG_MTD_IQ80310 $CONFIG_MTD_CFI $CONFIG_ARCH_IQ80310 ++ dep_tristate ' CFI Flash device mapped on the XScale Lubbock board' CONFIG_MTD_LUBBOCK $CONFIG_MTD_CFI $CONFIG_ARCH_LUBBOCK ++ dep_tristate ' CFI Flash device mapped on XScale IXP425 systems' CONFIG_MTD_IXP425 $CONFIG_MTD_CFI $CONFIG_MTD_COMPLEX_MAPPINGS + dep_tristate ' CFI Flash device mapped on Epxa10db' CONFIG_MTD_EPXA10DB $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_ARCH_CAMELOT + dep_tristate ' CFI Flash device mapped on the FortuNet board' CONFIG_MTD_FORTUNET $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_SA1100_FORTUNET + dep_tristate ' NV-RAM mapping AUTCPU12 board' CONFIG_MTD_AUTCPU12 $CONFIG_ARCH_AUTCPU12 + dep_tristate ' CFI Flash device mapped on EDB7312' CONFIG_MTD_EDB7312 $CONFIG_MTD_CFI ++ dep_tristate ' CFI Flash device mapped on Hynix evaluation boards' CONFIG_MTD_H720X $CONFIG_MTD_CFI + dep_tristate ' JEDEC Flash device mapped on impA7' CONFIG_MTD_IMPA7 $CONFIG_MTD_JEDECPROBE + dep_tristate ' JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame' CONFIG_MTD_CEIVA $CONFIG_MTD_JEDECPROBE $CONFIG_ARCH_CEIVA ++ dep_tristate ' NOR Flash device on TOTO board' CONFIG_MTD_NOR_TOTO $CONFIG_MTD $CONFIG_OMAP_TOTO + fi + if [ "$CONFIG_ALPHA" = "y" ]; then +- dep_tristate ' Flash chip mapping on TSUNAMI' CONFIG_MTD_TSUNAMI $CONFIG_MTD_GENPROBE ++ dep_tristate ' Flash chip mapping on TSUNAMI' CONFIG_MTD_TSUNAMI $CONFIG_MTD_GENPROBE $CONFIG_MTD_COMPLEX_MAPPINGS + fi + + if [ "$CONFIG_UCLINUX" = "y" ]; then +@@ -113,7 +126,7 @@ + fi + + # This needs CFI or JEDEC, depending on the cards found. +-dep_tristate ' PCI MTD driver' CONFIG_MTD_PCI $CONFIG_MTD $CONFIG_PCI +-dep_tristate ' PCMCIA MTD driver' CONFIG_MTD_PCMCIA $CONFIG_MTD $CONFIG_PCMCIA ++dep_tristate ' PCI MTD driver' CONFIG_MTD_PCI $CONFIG_MTD $CONFIG_PCI $CONFIG_MTD_COMPLEX_MAPPINGS ++dep_tristate ' PCMCIA MTD driver' CONFIG_MTD_PCMCIA $CONFIG_MTD $CONFIG_PCMCIA $CONFIG_MTD_COMPLEX_MAPPINGS + + endmenu +--- linux-ld/drivers/mtd/maps/Makefile 2006-05-01 12:48:20.644226750 +0200 ++++ linux/drivers/mtd/maps/Makefile 2006-04-30 20:35:58.000000000 +0200 +@@ -1,12 +1,16 @@ + # + # linux/drivers/maps/Makefile + # +-# $Id: Makefile,v 1.37 2003/01/24 14:26:38 dwmw2 Exp $ ++# $Id: Makefile.common,v 1.8 2003/11/26 21:26:09 dsaxena Exp $ + +-BELOW25 := $(shell echo $(PATCHLEVEL) | sed s/[1234]/y/) +- +-ifeq ($(BELOW25),y) ++ifeq ($(PATCHLEVEL),4) + O_TARGET := mapslink.o ++export-objs := map_funcs.o ++endif ++ ++ ++ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y) ++obj-$(CONFIG_MTD) += map_funcs.o + endif + + # Chip mappings +@@ -21,19 +25,13 @@ + obj-$(CONFIG_MTD_IQ80310) += iq80310.o + obj-$(CONFIG_MTD_L440GX) += l440gx.o + obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o +-obj-$(CONFIG_MTD_ICH2ROM) += ich2rom.o ++obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o + obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o ++obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o + obj-$(CONFIG_MTD_MBX860) += mbx860.o +-obj-$(CONFIG_MTD_NORA) += nora.o + obj-$(CONFIG_MTD_CEIVA) += ceiva.o + obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o +-ifneq ($(CONFIG_MTD_PHYSMAP),n) +- ifeq ($(CONFIG_MTD_PHYSMAP_BUSWIDTH),8) +- obj-$(CONFIG_MTD_PHYSMAP) += physmap64.o +- else +- obj-$(CONFIG_MTD_PHYSMAP) += physmap.o +- endif +-endif ++obj-$(CONFIG_MTD_PHYSMAP) += physmap.o + obj-$(CONFIG_MTD_PNC2000) += pnc2000.o + obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o + obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o +@@ -49,17 +47,11 @@ + obj-$(CONFIG_MTD_OCELOT) += ocelot.o + obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o + obj-$(CONFIG_MTD_PCI) += pci.o +-obj-$(CONFIG_MTD_PB1000) += pb1xxx-flash.o +-obj-$(CONFIG_MTD_PB1100) += pb1xxx-flash.o +-obj-$(CONFIG_MTD_PB1500) += pb1xxx-flash.o +-obj-$(CONFIG_MTD_XXS1500) += xxs1500.o +-obj-$(CONFIG_MTD_MTX1) += mtx-1.o +-obj-$(CONFIG_MTD_MTX2) += mtx-2.o +-obj-$(CONFIG_MTD_LASAT) += lasat.o ++obj-$(CONFIG_MTD_PB1XXX) += pb1xxx-flash.o + obj-$(CONFIG_MTD_DB1X00) += db1x00-flash.o +-obj-$(CONFIG_MTD_PB1550) += pb1550-flash.o +-obj-$(CONFIG_MTD_HYDROGEN3) += hydrogen3-flash.o +-obj-$(CONFIG_MTD_BOSPORUS) += pb1xxx-flash.o ++obj-$(CONFIG_MTD_MTX1) += mtx-1.o ++obj-$(CONFIG_MTD_MTX2) += mtx-2.o ++obj-$(CONFIG_MTD_LASAT) += lasat.o + obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o + obj-$(CONFIG_MTD_EDB7312) += edb7312.o + obj-$(CONFIG_MTD_IMPA7) += impa7.o +@@ -68,6 +60,13 @@ + obj-$(CONFIG_MTD_UCLINUX) += uclinux.o + obj-$(CONFIG_MTD_NETtel) += nettel.o + obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o +-obj-$(CONFIG_MTD_MIRAGE) += mirage-flash.o ++obj-$(CONFIG_MTD_EBONY) += ebony.o ++obj-$(CONFIG_MTD_BEECH) += beech-mtd.o ++obj-$(CONFIG_MTD_ARCTIC) += arctic-mtd.o ++obj-$(CONFIG_MTD_H720X) += h720x-flash.o ++obj-$(CONFIG_MTD_SBC8240) += sbc8240.o ++obj-$(CONFIG_MTD_NOR_TOTO) += omap-toto-flash.o ++obj-$(CONFIG_MTD_MPC1211) += mpc1211.o ++obj-$(CONFIG_MTD_IXP425) += ixp425.o + +-include $(TOPDIR)/Rules.make ++-include $(TOPDIR)/Rules.make +--- linux-old/drivers/mtd/maps/mtx-2.c 2006-04-24 09:48:30.056554500 +0200 ++++ linux/drivers/mtd/maps/mtx-2.c 2006-05-01 22:36:17.636901000 +0200 +@@ -0,0 +1,270 @@ ++/* ++ * Flash memory access on 4G Systems MTX-2 board ++ * ++ * (C) Bruno Randolf (4G Systeme GmbH) ++ * (C) Michael Stickel (4G Systems GmbH) ++ * ++ * Nachtversion ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define WINDOW_ADDR 0x1F000000 ++#define WINDOW_SIZE 0x1000000 ++#define BUSWIDTH 2 ++ ++ ++ ++/* ++ * Au1x Ethernet found 1 ethernet devices ++ * MTX-2 flash: probing 16-bit flash bus at 1f000000 ++ * MTX-2 flash: Found 1 x16 devices at 0x0 in 16-bit mode ++ * Amd/Fujitsu Extended Query Table at 0x0040 ++ * MTX-2 flash: CFI does not contain boot bank location. Assuming top. ++ * number of CFI chips: 1 ++ * cfi_cmdset_0002: Disabling fast programming due to code brokenness. ++ * cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness. ++ * Creating 6 MTD partitions on "MTX-2 flash": ++ * 0x00000000-0x00c00000 : "user fs/0" ++ * 0x00c00000-0x00c60000 : "yamon" ++ * 0x00c60000-0x00d00000 : "user fs/1" ++ * 0x00d00000-0x00e40000 : "raw kernel" ++ * 0x00e40000-0x00fc0000 : "user fs/2" ++ * 0x00fc0000-0x01000000 : "yamon environment" ++ * Concatenating MTD devices: ++ * (0): "user fs/0" ++ * (1): "raw kernel" ++ * (2): "yamon" ++ * (3): "user fs/2" ++ * (4): "user fs/1" ++ * (5): "yamon environment" ++ * into device "MTX2 concatenated" ++ * Creating 4 MTD partitions on "MTX2 concatenated": ++ * 0x00000000-0x00e20000 : "user fs" ++ * 0x00e20000-0x00e80000 : "yamon" ++ * 0x00e80000-0x00fc0000 : "raw kernel" ++ * 0x00fc0000-0x01000000 : "yamon environment" ++ * usb.c: registered new driver usbdevfs ++ * usb.c: registered new driver hub ++ * Initializing Cryptographic API ++ * NET4: Linux TCP/IP 1.0 for NET4.0 ++ * IP Protocols: ICMP, UDP, TCP, IGMP ++ * IP: routing cache hash table of 512 buckets, 4Kbytes ++ * TCP: Hash tables configured (established 4096 bind 8192) ++ * Linux IP multicast router 0.06 plus PIM-SM ++ * eth0: open: dev=80399c00 ++ * ++ * */ ++ ++/* ++ * Physical Yamon Mapping: ++ * ======================= ++ * base size ++ * System 0x1f000000 0x00c00000 12MB ++ * Monitor 0x1fc00000 0x003c0000 3.75MB (3840KB) ++ * Env. 0x1ffc0000 0x00040000 0.25MB (256KB) ++ * ++ */ ++ ++ ++static struct map_info mtx2_map = { ++ .name = "MTX-2 flash", ++ .size = WINDOW_SIZE, ++ .buswidth = BUSWIDTH, ++ .phys = WINDOW_ADDR, ++}; ++ ++ ++/* ++ * Physical Linux Mapping: ++ * ======================= ++ * base size ++ * System 0x00000000 0x00c00000 12MB ++ * ++ * Monitor 0x00c00000 0x00060000 ++ * System1 0x00c60000 0x000A0000 0.625MB (640KB) ++ * Kernel 0x00d00000 0x00140000 --MB (--KB) ++ * System2 0x00E40000 0x00180000 --MB (--KB) ++ * ++ * Env. 0x00fc0000 0x00040000 0.25MB (256KB) ++ */ ++ ++static struct mtd_partition mtx2_phys_partitions[] = { ++ { ++ // * System 0x00000000 0x00c00000 ++ .name = "user fs/0", ++ .size = 0x00c00000, ++ .offset = 0x00000000, ++ },{ ++ // * Monitor 0x00c00000 0x00060000 ++ .name = "yamon", ++ .size = 0x00060000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE /* force read-only */ ++ },{ ++ // * System1 0x00c60000 0x000A0000 ++ .name = "user fs/1", ++ .size = 0x000A0000, ++ .offset = MTDPART_OFS_APPEND, ++ },{ ++ // * Kernel 0x00d00000 0x00140000 ++ .name = "raw kernel", ++ .size = 0x00140000, ++ .offset = MTDPART_OFS_APPEND, ++ },{ ++ // * System2 0x00E40000 0x00180000 ++ .name = "user fs/2", ++ .size = 0x00180000, ++ .offset = MTDPART_OFS_APPEND, ++ },{ ++ // * Env. 0x00fc0000 0x00040000 0.25MB (256KB) ++ .name = "yamon environment", ++ .size = 0x00040000, ++ .offset = MTDPART_OFS_APPEND, ++ .mask_flags = MTD_WRITEABLE /* force read-only */ ++ } ++}; ++ ++#define MTX2_NUM_PARTITIONS (sizeof(mtx2_phys_partitions)/sizeof(mtx2_phys_partitions[0])) ++ ++/* ++ * Virtual Linux Mapping: ++ * ====================== ++ * "user-fs" base = 0x00000000 size = 0x00E20000 ++ * - [0] System 0x1f000000 0x00c00000 12MB ++ * - [2] System1 0x1fc60000 0x000A0000 0.625MB (640KB) ++ * - [4] System2 0x1FE40000 0x00180000 --MB (--KB) ++ * => size = 0x00E20000 ++ * ++ * "yamon" base = 0x00E20000 size = 0x00060000 ++ * - [1] Monitor 0x1fc00000 0x00060000 3.75MB (3840KB) ++ * => size = 0x00060000 ++ * ++ * "raw kernel" base = 0x00E80000 size = 0x00140000 ++ * - [3] Kernel 0x1fd00000 0x00140000 --MB (--KB) ++ * => size = 0x00140000 ++ * ++ * "yamon environment" base = 0x00FC0000 size = 0x00040000 ++ * - [5] Env. 0x1ffc0000 0x00040000 0.25MB (256KB) ++ * => size = 0x00040000 ++ */ ++ ++// 0x00f20000-0x00fb0000 = Kernel ++ ++static struct mtd_partition mtx2_partitions[] = { ++ { ++ .name = "user fs", ++ .size = 0x00E20000, ++ .offset = 0x00000000, ++ },{ ++ .name = "yamon", ++ .size = 0x00060000, ++ .offset = MTDPART_OFS_NXTBLK, ++ .mask_flags = MTD_WRITEABLE /* force read-only */ ++ },{ ++ .name = "raw kernel", ++ .size = 0x00140000, ++ .offset = MTDPART_OFS_NXTBLK, ++ },{ ++ .name = "yamon environment", ++ .size = 0x00040000, ++ .offset = MTDPART_OFS_NXTBLK, ++ .mask_flags = MTD_WRITEABLE /* force read-only */ ++ } ++}; ++ ++ ++#define MTX2_NUM_HIGHLVL_PARTITIONS (sizeof(mtx2_partitions)/sizeof(mtx2_partitions[0])) ++ ++ ++static struct mtd_info *mymtd; ++static struct mtd_info *lowlevel_parts[MTX2_NUM_PARTITIONS]; ++static struct mtd_info *virtual_mtd; ++ ++int __init mtx2_mtd_init(void) ++{ ++ printk(KERN_NOTICE "MTX-2 flash: probing %d-bit flash bus at %x\n", ++ mtx2_map.buswidth*8, WINDOW_ADDR); ++ ++ mtx2_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE); ++ if (!mtx2_map.virt) { ++ printk("mtx_mtd_init: failed to ioremap\n"); ++ return -EIO; ++ } ++ ++ simple_map_init(&mtx2_map); ++ ++ mymtd = do_map_probe("cfi_probe", &mtx2_map); ++ if (!mymtd) { ++ iounmap(mtx2_map.virt); ++ return -ENXIO; ++ } ++ ++ mymtd->owner = THIS_MODULE; ++ ++ /* ++ ** Supply pointers to lowlvl_parts[] array to add_mtd_partitions() ++ ** -> add_mtd_partitions() will _not_ register MTD devices for ++ ** the partitions, but will instead store pointers to the MTD ++ ** objects it creates into our lowlvl_parts[] array. ++ ** NOTE: we arrange the pointers such that the sequence of the ++ ** partitions gets re-arranged: partition #2 follows ++ ** partition #0. ++ */ ++ ++ mtx2_phys_partitions[0].mtdp = &lowlevel_parts[0]; // user fs/0 ++ mtx2_phys_partitions[1].mtdp = &lowlevel_parts[3]; // yamon ++ mtx2_phys_partitions[2].mtdp = &lowlevel_parts[1]; // user fs/1 ++ mtx2_phys_partitions[3].mtdp = &lowlevel_parts[4]; // raw kernel ++ mtx2_phys_partitions[4].mtdp = &lowlevel_parts[2]; // user fs/2 ++ mtx2_phys_partitions[5].mtdp = &lowlevel_parts[5]; // yamon environment ++ ++ add_mtd_partitions(mymtd, mtx2_phys_partitions, MTX2_NUM_PARTITIONS); ++ ++ virtual_mtd = mtd_concat_create(lowlevel_parts, MTX2_NUM_PARTITIONS, "MTX2 concatenated"); ++ if(virtual_mtd) ++ { /* ++ ** now partition the new device the way we want it. This time, ++ ** we do not supply mtd pointers in higlvl_partition_info, so ++ ** add_mtd_partitions() will register the devices. ++ */ ++ return add_mtd_partitions(virtual_mtd, mtx2_partitions, MTX2_NUM_HIGHLVL_PARTITIONS); ++ } ++ ++ return 0; ++ // return add_mtd_partitions(mymtd, mtx2_partitions, ARRAY_SIZE(mtx2_partitions)); ++} ++ ++static void __exit mtx2_mtd_cleanup(void) ++{ ++ if(virtual_mtd) { ++ del_mtd_partitions(virtual_mtd); ++ mtd_concat_destroy(virtual_mtd); ++ } ++ ++ if (mymtd) { ++ del_mtd_partitions(mymtd); ++ map_destroy(mymtd); ++ } ++ ++ if (mtx2_map.virt) ++ iounmap(mtx2_map.virt); ++} ++ ++module_init(mtx2_mtd_init); ++module_exit(mtx2_mtd_cleanup); ++ ++MODULE_AUTHOR("Michael Stickel "); ++MODULE_DESCRIPTION("MTX-2 CFI map driver"); ++MODULE_LICENSE("GPL"); diff --git a/packages/linux/linux-mtx-2-2.4.27/03-mtd-erase-compiler-bug.diff b/packages/linux/linux-mtx-2-2.4.27/03-mtd-erase-compiler-bug.diff new file mode 100644 index 0000000000..9e310bf327 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/03-mtd-erase-compiler-bug.diff @@ -0,0 +1,21 @@ +--- linux-mips-2.4.24-pre2+mtd-2004-01-27/fs/jffs2/erase.c 2004-11-17 18:17:59.000000000 +0100 ++++ linux/fs/jffs2/erase.c 2004-11-17 18:44:52.260067088 +0100 +@@ -365,11 +365,13 @@ + jeb->dirty_size = 0; + jeb->wasted_size = 0; + } else { +- struct jffs2_unknown_node marker = { +- .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK), +- .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), +- .totlen = cpu_to_je32(c->cleanmarker_size) +- }; ++ /* compiler workaround, structure was not initialized before ++ on mipsel cross compilers ++ fix by Eugene.Wisor@flukenetworks.com */ ++ struct jffs2_unknown_node marker; ++ marker.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ++ marker.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER); ++ marker.totlen = cpu_to_je32(c->cleanmarker_size); + + marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4)); + diff --git a/packages/linux/linux-mtx-2-2.4.27/04-mtd-yamonenv-readwrite.diff b/packages/linux/linux-mtx-2-2.4.27/04-mtd-yamonenv-readwrite.diff new file mode 100644 index 0000000000..2595fcf124 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/04-mtd-yamonenv-readwrite.diff @@ -0,0 +1,20 @@ +--- linux/drivers/mtd/maps/mtx-2.c~ 2006-06-27 13:19:32.476822000 +0200 ++++ linux/drivers/mtd/maps/mtx-2.c 2006-07-03 12:40:28.940335250 +0200 +@@ -111,7 +111,7 @@ + .name = "yamon", + .size = 0x00060000, + .offset = MTDPART_OFS_APPEND, +- .mask_flags = MTD_WRITEABLE /* force read-only */ ++ /*.mask_flags = MTD_WRITEABLE */ /* force read-only */ + },{ + // * System1 0x00c60000 0x000A0000 + .name = "user fs/1", +@@ -132,7 +132,7 @@ + .name = "yamon environment", + .size = 0x00040000, + .offset = MTDPART_OFS_APPEND, +- .mask_flags = MTD_WRITEABLE /* force read-only */ ++ /*.mask_flags = MTD_WRITEABLE */ /* force read-only */ + } + }; + diff --git a/packages/linux/linux-mtx-2-2.4.27/05-mtx-2-pci-irq.diff b/packages/linux/linux-mtx-2-2.4.27/05-mtx-2-pci-irq.diff new file mode 100644 index 0000000000..63d51b06de --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/05-mtx-2-pci-irq.diff @@ -0,0 +1,18 @@ +diff -Nurb linux-mips-2.4.27/arch/mips/au1000/mtx-2/irqmap.c linux/arch/mips/au1000/mtx-2/irqmap.c +--- linux-mips-2.4.27/arch/mips/au1000/mtx-2/irqmap.c 2004-04-02 11:04:00.000000000 +0200 ++++ linux/arch/mips/au1000/mtx-2/irqmap.c 2004-11-22 14:15:56.000000000 +0100 +@@ -72,10 +72,10 @@ + * A B C D + */ + { +- {INTA, INTB, INTC, INTD}, /* IDSEL 0 */ +- {INTA, INTB, INTC, INTD}, /* IDSEL 1 */ +- {INTA, INTB, INTC, INTD}, /* IDSEL 2 */ +- {INTA, INTB, INTC, INTD}, /* IDSEL 3 */ ++ {INTA, INTB, INTX, INTX}, /* IDSEL 0 */ ++ {INTB, INTA, INTX, INTX}, /* IDSEL 1 */ ++ {INTC, INTD, INTX, INTX}, /* IDSEL 2 */ ++ {INTD, INTC, INTX, INTX}, /* IDSEL 3 */ + }; + const long min_idsel = 0, max_idsel = 3, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; diff --git a/packages/linux/linux-mtx-2-2.4.27/06-zboot-2.4.26.patch b/packages/linux/linux-mtx-2-2.4.27/06-zboot-2.4.26.patch new file mode 100644 index 0000000000..48495b5e5f --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/06-zboot-2.4.26.patch @@ -0,0 +1,5308 @@ +diff -Naru linux/arch/mips/Makefile linux.spi/arch/mips/Makefile +--- linux/arch/mips/Makefile 2004-05-06 15:23:41.000000000 -0400 ++++ linux.spi/arch/mips/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -29,6 +29,8 @@ + endif + + MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot ++MAKEZBOOT = $(MAKE) -C arch/$(ARCH)/zboot ++BOOT_TARGETS = zImage zImage.initrd zImage.flash + + check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) + +@@ -757,12 +749,16 @@ + + vmlinux.ecoff: vmlinux + @$(MAKEBOOT) $@ ++ ++$(BOOT_TARGETS): vmlinux ++ @$(MAKEZBOOT) $@ + + vmlinux.srec: vmlinux + @$(MAKEBOOT) $@ + + archclean: + @$(MAKEBOOT) clean ++ @$(MAKEZBOOT) clean + rm -f arch/$(ARCH)/ld.script + $(MAKE) -C arch/$(ARCH)/tools clean + $(MAKE) -C arch/mips/baget clean +diff -Naru linux/arch/mips/zboot/common/au1k_uart.c linux.spi/arch/mips/zboot/common/au1k_uart.c +--- linux/arch/mips/zboot/common/au1k_uart.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/au1k_uart.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,103 @@ ++/* ++ * BRIEF MODULE DESCRIPTION ++ * Simple Au1000 uart routines. ++ * ++ * Copyright 2001 MontaVista Software Inc. ++ * Author: MontaVista Software, Inc. ++ * ppopov@mvista.com or source@mvista.com ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++#include ++#include ++#include ++#include "ns16550.h" ++ ++typedef unsigned char uint8; ++typedef unsigned int uint32; ++ ++#define UART16550_BAUD_2400 2400 ++#define UART16550_BAUD_4800 4800 ++#define UART16550_BAUD_9600 9600 ++#define UART16550_BAUD_19200 19200 ++#define UART16550_BAUD_38400 38400 ++#define UART16550_BAUD_57600 57600 ++#define UART16550_BAUD_115200 115200 ++ ++#define UART16550_PARITY_NONE 0 ++#define UART16550_PARITY_ODD 0x08 ++#define UART16550_PARITY_EVEN 0x18 ++#define UART16550_PARITY_MARK 0x28 ++#define UART16550_PARITY_SPACE 0x38 ++ ++#define UART16550_DATA_5BIT 0x0 ++#define UART16550_DATA_6BIT 0x1 ++#define UART16550_DATA_7BIT 0x2 ++#define UART16550_DATA_8BIT 0x3 ++ ++#define UART16550_STOP_1BIT 0x0 ++#define UART16550_STOP_2BIT 0x4 ++ ++/* It would be nice if we had a better way to do this. ++ * It could be a variable defined in one of the board specific files. ++ */ ++#undef UART_BASE ++#ifdef CONFIG_COGENT_CSB250 ++#define UART_BASE UART3_ADDR ++#else ++#define UART_BASE UART0_ADDR ++#endif ++ ++/* memory-mapped read/write of the port */ ++#define UART16550_READ(y) (readl(UART_BASE + y) & 0xff) ++#define UART16550_WRITE(y,z) (writel(z&0xff, UART_BASE + y)) ++ ++/* ++ * We use uart 0, which is already initialized by ++ * yamon. ++ */ ++volatile struct NS16550 * ++serial_init(int chan) ++{ ++ volatile struct NS16550 *com_port; ++ com_port = (struct NS16550 *) UART_BASE; ++ return (com_port); ++} ++ ++void ++serial_putc(volatile struct NS16550 *com_port, unsigned char c) ++{ ++ while ((UART16550_READ(UART_LSR)&0x40) == 0); ++ UART16550_WRITE(UART_TX, c); ++} ++ ++unsigned char ++serial_getc(volatile struct NS16550 *com_port) ++{ ++ while((UART16550_READ(UART_LSR) & 0x1) == 0); ++ return UART16550_READ(UART_RX); ++} ++ ++int ++serial_tstc(volatile struct NS16550 *com_port) ++{ ++ return((UART16550_READ(UART_LSR) & LSR_DR) != 0); ++} +diff -Naru linux/arch/mips/zboot/common/ctype.c linux.spi/arch/mips/zboot/common/ctype.c +--- linux/arch/mips/zboot/common/ctype.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/ctype.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,35 @@ ++/* ++ * linux/lib/ctype.c ++ * ++ * Copyright (C) 1991, 1992 Linus Torvalds ++ */ ++ ++#include ++ ++unsigned char _ctype[] = { ++_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ ++_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ ++_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ ++_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ ++_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ ++_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ ++_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ ++_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ ++_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ ++_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ ++_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ ++_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ ++_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ ++_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ ++_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ ++_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ ++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ ++0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ ++_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ ++_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ ++_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ ++_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ ++_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ ++_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ ++ ++ +diff -Naru linux/arch/mips/zboot/common/dummy.c linux.spi/arch/mips/zboot/common/dummy.c +--- linux/arch/mips/zboot/common/dummy.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/dummy.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,4 @@ ++int main(void) ++{ ++ return 0; ++} +diff -Naru linux/arch/mips/zboot/common/Makefile linux.spi/arch/mips/zboot/common/Makefile +--- linux/arch/mips/zboot/common/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,27 @@ ++# ++# arch/mips/zboot/common/Makefile ++# ++# This file is subject to the terms and conditions of the GNU General Public ++# License. See the file "COPYING" in the main directory of this archive ++# for more details. ++# ++# Tom Rini January 2001 ++# ++ ++.c.s: ++ $(CC) $(CFLAGS) -S -o $*.s $< ++.s.o: ++ $(AS) -o $*.o $< ++.c.o: ++ $(CC) $(CFLAGS) -c -o $*.o $< ++.S.s: ++ $(CPP) $(AFLAGS) -o $*.o $< ++.S.o: ++ $(CC) $(AFLAGS) -c -o $*.o $< ++ ++clean: ++ rm -rf *.o ++ ++OBJCOPY_ARGS = -O elf32-tradlittlemips ++ ++include $(TOPDIR)/Rules.make +diff -Naru linux/arch/mips/zboot/common/misc-common.c linux.spi/arch/mips/zboot/common/misc-common.c +--- linux/arch/mips/zboot/common/misc-common.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/misc-common.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,437 @@ ++/* ++ * arch/mips/zboot/common/misc-common.c ++ * ++ * Misc. bootloader code (almost) all platforms can use ++ * ++ * Author: Johnnie Peters ++ * Editor: Tom Rini ++ * ++ * Derived from arch/ppc/boot/prep/misc.c ++ * ++ * Ported by Pete Popov to ++ * support mips board(s). I also got rid of the vga console ++ * code. ++ * ++ * Copyright 2000-2001 MontaVista Software Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include "zlib.h" ++#include ++ ++extern char *avail_ram; ++extern char *end_avail; ++extern char _end[]; ++ ++void puts(const char *); ++void putc(const char c); ++void puthex(unsigned long val); ++void _bcopy(char *src, char *dst, int len); ++void gunzip(void *, int, unsigned char *, int *); ++static int _cvt(unsigned long val, char *buf, long radix, char *digits); ++ ++void _vprintk(void(*)(const char), const char *, va_list ap); ++ ++struct NS16550 *com_port; ++ ++int serial_tstc(volatile struct NS16550 *); ++unsigned char serial_getc(volatile struct NS16550 *); ++void serial_putc(volatile struct NS16550 *, unsigned char); ++ ++void pause(void) ++{ ++ puts("pause\n"); ++} ++ ++void exit(void) ++{ ++ puts("exit\n"); ++ while(1); ++} ++ ++int tstc(void) ++{ ++ return (serial_tstc(com_port)); ++} ++ ++int getc(void) ++{ ++ while (1) { ++ if (serial_tstc(com_port)) ++ return (serial_getc(com_port)); ++ } ++} ++ ++void ++putc(const char c) ++{ ++ int x,y; ++ ++ serial_putc(com_port, c); ++ if ( c == '\n' ) ++ serial_putc(com_port, '\r'); ++} ++ ++void puts(const char *s) ++{ ++ char c; ++ while ( ( c = *s++ ) != '\0' ) { ++ serial_putc(com_port, c); ++ if ( c == '\n' ) serial_putc(com_port, '\r'); ++ } ++} ++ ++void error(char *x) ++{ ++ puts("\n\n"); ++ puts(x); ++ puts("\n\n -- System halted"); ++ ++ while(1); /* Halt */ ++} ++ ++void *zalloc(void *x, unsigned items, unsigned size) ++{ ++ void *p = avail_ram; ++ ++ size *= items; ++ size = (size + 7) & -8; ++ avail_ram += size; ++ if (avail_ram > end_avail) { ++ puts("oops... out of memory\n"); ++ pause(); ++ } ++ return p; ++} ++ ++void zfree(void *x, void *addr, unsigned nb) ++{ ++} ++ ++#define HEAD_CRC 2 ++#define EXTRA_FIELD 4 ++#define ORIG_NAME 8 ++#define COMMENT 0x10 ++#define RESERVED 0xe0 ++ ++#define DEFLATED 8 ++ ++void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) ++{ ++ z_stream s; ++ int r, i, flags; ++ ++ /* skip header */ ++ i = 10; ++ flags = src[3]; ++ if (src[2] != DEFLATED || (flags & RESERVED) != 0) { ++ puts("bad gzipped data\n"); ++ exit(); ++ } ++ if ((flags & EXTRA_FIELD) != 0) ++ i = 12 + src[10] + (src[11] << 8); ++ if ((flags & ORIG_NAME) != 0) ++ while (src[i++] != 0) ++ ; ++ if ((flags & COMMENT) != 0) ++ while (src[i++] != 0) ++ ; ++ if ((flags & HEAD_CRC) != 0) ++ i += 2; ++ if (i >= *lenp) { ++ puts("gunzip: ran out of data in header\n"); ++ exit(); ++ } ++ ++ s.zalloc = zalloc; ++ s.zfree = zfree; ++ r = inflateInit2(&s, -MAX_WBITS); ++ if (r != Z_OK) { ++ puts("inflateInit2 returned %d\n"); ++ exit(); ++ } ++ s.next_in = src + i; ++ s.avail_in = *lenp - i; ++ s.next_out = dst; ++ s.avail_out = dstlen; ++ r = inflate(&s, Z_FINISH); ++ if (r != Z_OK && r != Z_STREAM_END) { ++ puts("inflate returned %d\n"); ++ exit(); ++ } ++ *lenp = s.next_out - (unsigned char *) dst; ++ inflateEnd(&s); ++} ++ ++void ++puthex(unsigned long val) ++{ ++ ++ unsigned char buf[10]; ++ int i; ++ for (i = 7; i >= 0; i--) ++ { ++ buf[i] = "0123456789ABCDEF"[val & 0x0F]; ++ val >>= 4; ++ } ++ buf[8] = '\0'; ++ puts(buf); ++} ++ ++#define FALSE 0 ++#define TRUE 1 ++ ++void ++_printk(char const *fmt, ...) ++{ ++ va_list ap; ++ ++ va_start(ap, fmt); ++ _vprintk(putc, fmt, ap); ++ va_end(ap); ++ return; ++} ++ ++#define is_digit(c) ((c >= '0') && (c <= '9')) ++ ++void ++_vprintk(void(*putc)(const char), const char *fmt0, va_list ap) ++{ ++ char c, sign, *cp = 0; ++ int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right; ++ char buf[32]; ++ long val; ++ while ((c = *fmt0++)) ++ { ++ if (c == '%') ++ { ++ c = *fmt0++; ++ left_prec = right_prec = pad_on_right = 0; ++ if (c == '-') ++ { ++ c = *fmt0++; ++ pad_on_right++; ++ } ++ if (c == '0') ++ { ++ zero_fill = TRUE; ++ c = *fmt0++; ++ } else ++ { ++ zero_fill = FALSE; ++ } ++ while (is_digit(c)) ++ { ++ left_prec = (left_prec * 10) + (c - '0'); ++ c = *fmt0++; ++ } ++ if (c == '.') ++ { ++ c = *fmt0++; ++ zero_fill++; ++ while (is_digit(c)) ++ { ++ right_prec = (right_prec * 10) + (c - '0'); ++ c = *fmt0++; ++ } ++ } else ++ { ++ right_prec = left_prec; ++ } ++ sign = '\0'; ++ switch (c) ++ { ++ case 'd': ++ case 'x': ++ case 'X': ++ val = va_arg(ap, long); ++ switch (c) ++ { ++ case 'd': ++ if (val < 0) ++ { ++ sign = '-'; ++ val = -val; ++ } ++ length = _cvt(val, buf, 10, "0123456789"); ++ break; ++ case 'x': ++ length = _cvt(val, buf, 16, "0123456789abcdef"); ++ break; ++ case 'X': ++ length = _cvt(val, buf, 16, "0123456789ABCDEF"); ++ break; ++ } ++ cp = buf; ++ break; ++ case 's': ++ cp = va_arg(ap, char *); ++ length = strlen(cp); ++ break; ++ case 'c': ++ c = va_arg(ap, long /*char*/); ++ (*putc)(c); ++ continue; ++ default: ++ (*putc)('?'); ++ } ++ pad = left_prec - length; ++ if (sign != '\0') ++ { ++ pad--; ++ } ++ if (zero_fill) ++ { ++ c = '0'; ++ if (sign != '\0') ++ { ++ (*putc)(sign); ++ sign = '\0'; ++ } ++ } else ++ { ++ c = ' '; ++ } ++ if (!pad_on_right) ++ { ++ while (pad-- > 0) ++ { ++ (*putc)(c); ++ } ++ } ++ if (sign != '\0') ++ { ++ (*putc)(sign); ++ } ++ while (length-- > 0) ++ { ++ (*putc)(c = *cp++); ++ if (c == '\n') ++ { ++ (*putc)('\r'); ++ } ++ } ++ if (pad_on_right) ++ { ++ while (pad-- > 0) ++ { ++ (*putc)(c); ++ } ++ } ++ } else ++ { ++ (*putc)(c); ++ if (c == '\n') ++ { ++ (*putc)('\r'); ++ } ++ } ++ } ++} ++ ++int ++_cvt(unsigned long val, char *buf, long radix, char *digits) ++{ ++ char temp[80]; ++ char *cp = temp; ++ int length = 0; ++ if (val == 0) ++ { /* Special case */ ++ *cp++ = '0'; ++ } else ++ while (val) ++ { ++ *cp++ = digits[val % radix]; ++ val /= radix; ++ } ++ while (cp != temp) ++ { ++ *buf++ = *--cp; ++ length++; ++ } ++ *buf = '\0'; ++ return (length); ++} ++ ++void ++_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base) ++{ ++ int i, c; ++ if ((unsigned int)s > (unsigned int)p) ++ { ++ s = (unsigned int)s - (unsigned int)p; ++ } ++ while (s > 0) ++ { ++ if (base) ++ { ++ _printk("%06X: ", (int)p - (int)base); ++ } else ++ { ++ _printk("%06X: ", p); ++ } ++ for (i = 0; i < 16; i++) ++ { ++ if (i < s) ++ { ++ _printk("%02X", p[i] & 0xFF); ++ } else ++ { ++ _printk(" "); ++ } ++ if ((i % 2) == 1) _printk(" "); ++ if ((i % 8) == 7) _printk(" "); ++ } ++ _printk(" |"); ++ for (i = 0; i < 16; i++) ++ { ++ if (i < s) ++ { ++ c = p[i] & 0xFF; ++ if ((c < 0x20) || (c >= 0x7F)) c = '.'; ++ } else ++ { ++ c = ' '; ++ } ++ _printk("%c", c); ++ } ++ _printk("|\n"); ++ s -= 16; ++ p += 16; ++ } ++} ++ ++void ++_dump_buf(unsigned char *p, int s) ++{ ++ _printk("\n"); ++ _dump_buf_with_offset(p, s, 0); ++} ++ ++/* ++ * Local variables: ++ * c-indent-level: 8 ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * End: ++ */ +diff -Naru linux/arch/mips/zboot/common/misc-simple.c linux.spi/arch/mips/zboot/common/misc-simple.c +--- linux/arch/mips/zboot/common/misc-simple.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/misc-simple.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,127 @@ ++/* ++ * arch/mips/zboot/common/misc-simple.c ++ * ++ * Misc. bootloader code for many machines. This assumes you have are using ++ * a 6xx/7xx/74xx CPU in your machine. This assumes the chunk of memory ++ * below 8MB is free. Finally, it assumes you have a NS16550-style uart for ++ * your serial console. If a machine meets these requirements, it can quite ++ * likely use this code during boot. ++ * ++ * Author: Matt Porter ++ * Derived from arch/ppc/boot/prep/misc.c ++ * ++ * Copyright 2001 MontaVista Software Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "zlib.h" ++ ++extern struct NS16550 *com_port; ++ ++char *avail_ram; ++char *end_avail; ++extern char _end[]; ++char *zimage_start; ++ ++#ifdef CONFIG_CMDLINE ++#define CMDLINE CONFIG_CMDLINE ++#else ++#define CMDLINE "" ++#endif ++char cmd_preset[] = CMDLINE; ++char cmd_buf[256]; ++char *cmd_line = cmd_buf; ++ ++/* The linker tells us where the image is. ++*/ ++extern unsigned char __image_begin, __image_end; ++extern unsigned char __ramdisk_begin, __ramdisk_end; ++unsigned long initrd_size; ++ ++extern void puts(const char *); ++extern void putc(const char c); ++extern void puthex(unsigned long val); ++extern void *memcpy(void * __dest, __const void * __src, ++ __kernel_size_t __n); ++extern void gunzip(void *, int, unsigned char *, int *); ++extern void udelay(long delay); ++extern int tstc(void); ++extern int getc(void); ++extern volatile struct NS16550 *serial_init(int chan); ++ ++void ++decompress_kernel(unsigned long load_addr, int num_words, ++ unsigned long cksum, unsigned long *sp) ++{ ++ int timer = 0; ++ extern unsigned long start; ++ char *cp, ch; ++ int i; ++ int zimage_size; ++ ++ com_port = (struct NS16550 *)serial_init(0); ++ ++ initrd_size = (unsigned long)(&__ramdisk_end) - ++ (unsigned long)(&__ramdisk_begin); ++ ++ /* ++ * Reveal where we were loaded at and where we ++ * were relocated to. ++ */ ++ puts("loaded at: "); puthex(load_addr); ++ puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); ++ if ( (unsigned long)load_addr != (unsigned long)&start ) ++ { ++ puts("relocated to: "); puthex((unsigned long)&start); ++ puts(" "); ++ puthex((unsigned long)((unsigned long)&start + (4*num_words))); ++ puts("\n"); ++ } ++ ++ /* ++ * We link ourself to an arbitrary low address. When we run, we ++ * relocate outself to that address. __image_being points to ++ * the part of the image where the zImage is. -- Tom ++ */ ++ zimage_start = (char *)(unsigned long)(&__image_begin); ++ zimage_size = (unsigned long)(&__image_end) - ++ (unsigned long)(&__image_begin); ++ ++ /* ++ * The zImage and initrd will be between start and _end, so they've ++ * already been moved once. We're good to go now. -- Tom ++ */ ++ puts("zimage at: "); puthex((unsigned long)zimage_start); ++ puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); ++ puts("\n"); ++ ++ if ( initrd_size ) { ++ puts("initrd at: "); ++ puthex((unsigned long)(&__ramdisk_begin)); ++ puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n"); ++ } ++ ++ /* assume the chunk below 8M is free */ ++ avail_ram = (char *)AVAIL_RAM_START; ++ end_avail = (char *)AVAIL_RAM_END; ++ ++ /* Display standard Linux/MIPS boot prompt for kernel args */ ++ puts("Uncompressing Linux at load address "); ++ puthex(LOADADDR); ++ puts("\n"); ++ /* I don't like this hard coded gunzip size (fixme) */ ++ gunzip((void *)LOADADDR, 0x400000, zimage_start, &zimage_size); ++ puts("Now booting the kernel\n"); ++} +diff -Naru linux/arch/mips/zboot/common/no_initrd.c linux.spi/arch/mips/zboot/common/no_initrd.c +--- linux/arch/mips/zboot/common/no_initrd.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/no_initrd.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,2 @@ ++char initrd_data[1]; ++int initrd_len = 0; +diff -Naru linux/arch/mips/zboot/common/ns16550.c linux.spi/arch/mips/zboot/common/ns16550.c +--- linux/arch/mips/zboot/common/ns16550.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/ns16550.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,57 @@ ++/* ++ * NS16550 support ++ */ ++ ++#include ++#include ++#include "ns16550.h" ++ ++typedef struct NS16550 *NS16550_t; ++ ++const NS16550_t COM_PORTS[] = { (NS16550_t) COM1, ++ (NS16550_t) COM2, ++ (NS16550_t) COM3, ++ (NS16550_t) COM4 }; ++ ++volatile struct NS16550 * ++serial_init(int chan) ++{ ++ volatile struct NS16550 *com_port; ++ com_port = (struct NS16550 *) COM_PORTS[chan]; ++ /* See if port is present */ ++ com_port->lcr = 0x00; ++ com_port->ier = 0xFF; ++#if 0 ++ if (com_port->ier != 0x0F) return ((struct NS16550 *)0); ++#endif ++ com_port->ier = 0x00; ++ com_port->lcr = 0x80; /* Access baud rate */ ++#ifdef CONFIG_SERIAL_CONSOLE_NONSTD ++ com_port->dll = (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD); ++ com_port->dlm = (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD) >> 8; ++#endif ++ com_port->lcr = 0x03; /* 8 data, 1 stop, no parity */ ++ com_port->mcr = 0x03; /* RTS/DTR */ ++ com_port->fcr = 0x07; /* Clear & enable FIFOs */ ++ return (com_port); ++} ++ ++void ++serial_putc(volatile struct NS16550 *com_port, unsigned char c) ++{ ++ while ((com_port->lsr & LSR_THRE) == 0) ; ++ com_port->thr = c; ++} ++ ++unsigned char ++serial_getc(volatile struct NS16550 *com_port) ++{ ++ while ((com_port->lsr & LSR_DR) == 0) ; ++ return (com_port->rbr); ++} ++ ++int ++serial_tstc(volatile struct NS16550 *com_port) ++{ ++ return ((com_port->lsr & LSR_DR) != 0); ++} +diff -Naru linux/arch/mips/zboot/common/string.c linux.spi/arch/mips/zboot/common/string.c +--- linux/arch/mips/zboot/common/string.c 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/common/string.c 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,497 @@ ++/* ++ * linux/lib/string.c ++ * ++ * Copyright (C) 1991, 1992 Linus Torvalds ++ */ ++ ++/* ++ * stupid library routines.. The optimized versions should generally be found ++ * as inline code in ++ * ++ * These are buggy as well.. ++ * ++ * * Fri Jun 25 1999, Ingo Oeser ++ * - Added strsep() which will replace strtok() soon (because strsep() is ++ * reentrant and should be faster). Use only strsep() in new code, please. ++ */ ++ ++#include ++#include ++#include ++ ++/** ++ * strnicmp - Case insensitive, length-limited string comparison ++ * @s1: One string ++ * @s2: The other string ++ * @len: the maximum number of characters to compare ++ */ ++int strnicmp(const char *s1, const char *s2, size_t len) ++{ ++ /* Yes, Virginia, it had better be unsigned */ ++ unsigned char c1, c2; ++ ++ c1 = 0; c2 = 0; ++ if (len) { ++ do { ++ c1 = *s1; c2 = *s2; ++ s1++; s2++; ++ if (!c1) ++ break; ++ if (!c2) ++ break; ++ if (c1 == c2) ++ continue; ++ c1 = tolower(c1); ++ c2 = tolower(c2); ++ if (c1 != c2) ++ break; ++ } while (--len); ++ } ++ return (int)c1 - (int)c2; ++} ++ ++char * ___strtok; ++ ++#ifndef __HAVE_ARCH_STRCPY ++/** ++ * strcpy - Copy a %NUL terminated string ++ * @dest: Where to copy the string to ++ * @src: Where to copy the string from ++ */ ++char * strcpy(char * dest,const char *src) ++{ ++ char *tmp = dest; ++ ++ while ((*dest++ = *src++) != '\0') ++ /* nothing */; ++ return tmp; ++} ++#endif ++ ++#ifndef __HAVE_ARCH_STRNCPY ++/** ++ * strncpy - Copy a length-limited, %NUL-terminated string ++ * @dest: Where to copy the string to ++ * @src: Where to copy the string from ++ * @count: The maximum number of bytes to copy ++ * ++ * Note that unlike userspace strncpy, this does not %NUL-pad the buffer. ++ * However, the result is not %NUL-terminated if the source exceeds ++ * @count bytes. ++ */ ++char * strncpy(char * dest,const char *src,size_t count) ++{ ++ char *tmp = dest; ++ ++ while (count-- && (*dest++ = *src++) != '\0') ++ /* nothing */; ++ ++ return tmp; ++} ++#endif ++ ++/** ++ * strcat - Append one %NUL-terminated string to another ++ * @dest: The string to be appended to ++ * @src: The string to append to it ++ */ ++char * strcat(char * dest, const char * src) ++{ ++ char *tmp = dest; ++ ++ while (*dest) ++ dest++; ++ while ((*dest++ = *src++) != '\0') ++ ; ++ ++ return tmp; ++} ++ ++/** ++ * strncat - Append a length-limited, %NUL-terminated string to another ++ * @dest: The string to be appended to ++ * @src: The string to append to it ++ * @count: The maximum numbers of bytes to copy ++ * ++ * Note that in contrast to strncpy, strncat ensures the result is ++ * terminated. ++ */ ++char * strncat(char *dest, const char *src, size_t count) ++{ ++ char *tmp = dest; ++ ++ if (count) { ++ while (*dest) ++ dest++; ++ while ((*dest++ = *src++)) { ++ if (--count == 0) { ++ *dest = '\0'; ++ break; ++ } ++ } ++ } ++ ++ return tmp; ++} ++ ++#ifndef __HAVE_ARCH_STRCMP ++/** ++ * strcmp - Compare two strings ++ * @cs: One string ++ * @ct: Another string ++ */ ++int strcmp(const char * cs,const char * ct) ++{ ++ register signed char __res; ++ ++ while (1) { ++ if ((__res = *cs - *ct++) != 0 || !*cs++) ++ break; ++ } ++ ++ return __res; ++} ++#endif ++ ++#ifndef __HAVE_ARCH_STRNCMP ++/** ++ * strncmp - Compare two length-limited strings ++ * @cs: One string ++ * @ct: Another string ++ * @count: The maximum number of bytes to compare ++ */ ++int strncmp(const char * cs,const char * ct,size_t count) ++{ ++ register signed char __res = 0; ++ ++ while (count) { ++ if ((__res = *cs - *ct++) != 0 || !*cs++) ++ break; ++ count--; ++ } ++ ++ return __res; ++} ++#endif ++ ++/** ++ * strchr - Find the first occurrence of a character in a string ++ * @s: The string to be searched ++ * @c: The character to search for ++ */ ++char * strchr(const char * s, int c) ++{ ++ for(; *s != (char) c; ++s) ++ if (*s == '\0') ++ return NULL; ++ return (char *) s; ++} ++ ++/** ++ * strrchr - Find the last occurrence of a character in a string ++ * @s: The string to be searched ++ * @c: The character to search for ++ */ ++char * strrchr(const char * s, int c) ++{ ++ const char *p = s + strlen(s); ++ do { ++ if (*p == (char)c) ++ return (char *)p; ++ } while (--p >= s); ++ return NULL; ++} ++ ++/** ++ * strlen - Find the length of a string ++ * @s: The string to be sized ++ */ ++size_t strlen(const char * s) ++{ ++ const char *sc; ++ ++ for (sc = s; *sc != '\0'; ++sc) ++ /* nothing */; ++ return sc - s; ++} ++ ++/** ++ * strnlen - Find the length of a length-limited string ++ * @s: The string to be sized ++ * @count: The maximum number of bytes to search ++ */ ++size_t strnlen(const char * s, size_t count) ++{ ++ const char *sc; ++ ++ for (sc = s; count-- && *sc != '\0'; ++sc) ++ /* nothing */; ++ return sc - s; ++} ++ ++/** ++ * strspn - Calculate the length of the initial substring of @s which only ++ * contain letters in @accept ++ * @s: The string to be searched ++ * @accept: The string to search for ++ */ ++size_t strspn(const char *s, const char *accept) ++{ ++ const char *p; ++ const char *a; ++ size_t count = 0; ++ ++ for (p = s; *p != '\0'; ++p) { ++ for (a = accept; *a != '\0'; ++a) { ++ if (*p == *a) ++ break; ++ } ++ if (*a == '\0') ++ return count; ++ ++count; ++ } ++ ++ return count; ++} ++ ++/** ++ * strpbrk - Find the first occurrence of a set of characters ++ * @cs: The string to be searched ++ * @ct: The characters to search for ++ */ ++char * strpbrk(const char * cs,const char * ct) ++{ ++ const char *sc1,*sc2; ++ ++ for( sc1 = cs; *sc1 != '\0'; ++sc1) { ++ for( sc2 = ct; *sc2 != '\0'; ++sc2) { ++ if (*sc1 == *sc2) ++ return (char *) sc1; ++ } ++ } ++ return NULL; ++} ++ ++/** ++ * strtok - Split a string into tokens ++ * @s: The string to be searched ++ * @ct: The characters to search for ++ * ++ * WARNING: strtok is deprecated, use strsep instead. ++ */ ++char * strtok(char * s,const char * ct) ++{ ++ char *sbegin, *send; ++ ++ sbegin = s ? s : ___strtok; ++ if (!sbegin) { ++ return NULL; ++ } ++ sbegin += strspn(sbegin,ct); ++ if (*sbegin == '\0') { ++ ___strtok = NULL; ++ return( NULL ); ++ } ++ send = strpbrk( sbegin, ct); ++ if (send && *send != '\0') ++ *send++ = '\0'; ++ ___strtok = send; ++ return (sbegin); ++} ++ ++/** ++ * strsep - Split a string into tokens ++ * @s: The string to be searched ++ * @ct: The characters to search for ++ * ++ * strsep() updates @s to point after the token, ready for the next call. ++ * ++ * It returns empty tokens, too, behaving exactly like the libc function ++ * of that name. In fact, it was stolen from glibc2 and de-fancy-fied. ++ * Same semantics, slimmer shape. ;) ++ */ ++char * strsep(char **s, const char *ct) ++{ ++ char *sbegin = *s, *end; ++ ++ if (sbegin == NULL) ++ return NULL; ++ ++ end = strpbrk(sbegin, ct); ++ if (end) ++ *end++ = '\0'; ++ *s = end; ++ ++ return sbegin; ++} ++ ++/** ++ * memset - Fill a region of memory with the given value ++ * @s: Pointer to the start of the area. ++ * @c: The byte to fill the area with ++ * @count: The size of the area. ++ * ++ * Do not use memset() to access IO space, use memset_io() instead. ++ */ ++void * memset(void * s,int c, size_t count) ++{ ++ char *xs = (char *) s; ++ ++ while (count--) ++ *xs++ = c; ++ ++ return s; ++} ++ ++/** ++ * bcopy - Copy one area of memory to another ++ * @src: Where to copy from ++ * @dest: Where to copy to ++ * @count: The size of the area. ++ * ++ * Note that this is the same as memcpy(), with the arguments reversed. ++ * memcpy() is the standard, bcopy() is a legacy BSD function. ++ * ++ * You should not use this function to access IO space, use memcpy_toio() ++ * or memcpy_fromio() instead. ++ */ ++char * bcopy(const char * src, char * dest, int count) ++{ ++ char *tmp = dest; ++ ++ while (count--) ++ *tmp++ = *src++; ++ ++ return dest; ++} ++ ++/** ++ * memcpy - Copy one area of memory to another ++ * @dest: Where to copy to ++ * @src: Where to copy from ++ * @count: The size of the area. ++ * ++ * You should not use this function to access IO space, use memcpy_toio() ++ * or memcpy_fromio() instead. ++ */ ++void * memcpy(void * dest,const void *src,size_t count) ++{ ++ char *tmp = (char *) dest, *s = (char *) src; ++ ++ while (count--) ++ *tmp++ = *s++; ++ ++ return dest; ++} ++ ++/** ++ * memmove - Copy one area of memory to another ++ * @dest: Where to copy to ++ * @src: Where to copy from ++ * @count: The size of the area. ++ * ++ * Unlike memcpy(), memmove() copes with overlapping areas. ++ */ ++void * memmove(void * dest,const void *src,size_t count) ++{ ++ char *tmp, *s; ++ ++ if (dest <= src) { ++ tmp = (char *) dest; ++ s = (char *) src; ++ while (count--) ++ *tmp++ = *s++; ++ } ++ else { ++ tmp = (char *) dest + count; ++ s = (char *) src + count; ++ while (count--) ++ *--tmp = *--s; ++ } ++ ++ return dest; ++} ++ ++/** ++ * memcmp - Compare two areas of memory ++ * @cs: One area of memory ++ * @ct: Another area of memory ++ * @count: The size of the area. ++ */ ++int memcmp(const void * cs,const void * ct,size_t count) ++{ ++ const unsigned char *su1, *su2; ++ signed char res = 0; ++ ++ for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) ++ if ((res = *su1 - *su2) != 0) ++ break; ++ return res; ++} ++ ++#ifndef __HAVE_ARCH_MEMSCAN ++/** ++ * memscan - Find a character in an area of memory. ++ * @addr: The memory area ++ * @c: The byte to search for ++ * @size: The size of the area. ++ * ++ * returns the address of the first occurrence of @c, or 1 byte past ++ * the area if @c is not found ++ */ ++void * memscan(void * addr, int c, size_t size) ++{ ++ unsigned char * p = (unsigned char *) addr; ++ unsigned char * e = p + size; ++ ++ while (p != e) { ++ if (*p == c) ++ return (void *) p; ++ p++; ++ } ++ ++ return (void *) p; ++} ++#endif ++ ++/** ++ * strstr - Find the first substring in a %NUL terminated string ++ * @s1: The string to be searched ++ * @s2: The string to search for ++ */ ++char * strstr(const char * s1,const char * s2) ++{ ++ int l1, l2; ++ ++ l2 = strlen(s2); ++ if (!l2) ++ return (char *) s1; ++ l1 = strlen(s1); ++ while (l1 >= l2) { ++ l1--; ++ if (!memcmp(s1,s2,l2)) ++ return (char *) s1; ++ s1++; ++ } ++ return NULL; ++} ++ ++/** ++ * memchr - Find a character in an area of memory. ++ * @s: The memory area ++ * @c: The byte to search for ++ * @n: The size of the area. ++ * ++ * returns the address of the first occurrence of @c, or %NULL ++ * if @c is not found ++ */ ++void *memchr(const void *s, int c, size_t n) ++{ ++ const unsigned char *p = s; ++ while (n-- != 0) { ++ if ((unsigned char)c == *p++) { ++ return (void *)(p-1); ++ } ++ } ++ return NULL; ++} +diff -Naru linux/arch/mips/zboot/csb250/head.S linux.spi/arch/mips/zboot/csb250/head.S +--- linux/arch/mips/zboot/csb250/head.S 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/csb250/head.S 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,157 @@ ++/* ++ * arch/mips/kernel/head.S ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 1994, 1995 Waldorf Electronics ++ * Written by Ralf Baechle and Andreas Busse ++ * Copyright (C) 1995 - 1999 Ralf Baechle ++ * Copyright (C) 1996 Paul M. Antoine ++ * Modified for DECStation and hence R3000 support by Paul M. Antoine ++ * Further modifications by David S. Miller and Harald Koerfgen ++ * Copyright (C) 1999 Silicon Graphics, Inc. ++ * ++ * Head.S contains the MIPS exception handler and startup code. ++ * ++ ************************************************************************** ++ * 9 Nov, 2000. ++ * Added Cache Error exception handler and SBDDP EJTAG debug exception. ++ * ++ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. ++ ************************************************************************** ++ */ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define IndexInvalidate_I 0x00 ++#define IndexWriteBack_D 0x01 ++ ++ .set noreorder ++ .cprestore ++ LEAF(start) ++start: ++ bal locate ++ nop ++ ++ .globl asize /* Someday we'll put the initrd info here. */ ++asize: .word 0 ++ .word 0 ++ .word 0 ++ .word 0 ++ ++locate: ++ subu s8, ra, 8 /* Where we were loaded */ ++ la sp, (.stack + 8192) ++ ++ move s0, a0 /* Save boot rom start args */ ++ move s1, a1 ++ move s2, a2 ++ move s3, a3 ++ ++ la a0, start /* Where we were linked to run */ ++ ++ move a1, s8 ++ la a2, _edata ++ subu t1, a2, a0 ++ srl t1, t1, 2 ++ ++ /* copy text section */ ++ li t0, 0 ++1: lw v0, 0(a1) ++ nop ++ sw v0, 0(a0) ++ xor t0, t0, v0 ++ addu a0, 4 ++ bne a2, a0, 1b ++ addu a1, 4 ++ ++ /* Clear BSS */ ++ la a0, _edata ++ la a2, _end ++2: sw zero, 0(a0) ++ bne a2, a0, 2b ++ addu a0, 4 ++ ++ /* push the D-Cache and invalidate I-Cache */ ++ li k0, 0x80000000 # start address ++ li k1, 0x80004000 # end address (16KB I-Cache) ++ subu k1, 128 ++ ++1: ++ .set mips3 ++ cache IndexWriteBack_D, 0(k0) ++ cache IndexWriteBack_D, 32(k0) ++ cache IndexWriteBack_D, 64(k0) ++ cache IndexWriteBack_D, 96(k0) ++ cache IndexInvalidate_I, 0(k0) ++ cache IndexInvalidate_I, 32(k0) ++ cache IndexInvalidate_I, 64(k0) ++ cache IndexInvalidate_I, 96(k0) ++ .set mips0 ++ ++ bne k0, k1, 1b ++ addu k0, k0, 128 ++ /* done */ ++ ++/* move a0, s8 /* load address */ ++ subu a0, s8, 0x1000 /* load address */ ++ move a1, t1 /* length in words */ ++ move a2, t0 /* checksum */ ++ move a3, sp ++ ++ la ra, 1f ++ la k0, decompress_kernel ++ jr k0 ++ nop ++1: ++ ++ la a2, __ramdisk_begin ++ la a3, initrd_size ++ lw a0, 0(a2) ++ lw a1, 0(a3) ++ li k0, KERNEL_ENTRY ++ jr k0 ++ nop ++3: ++ b 3b ++ END(start) ++ ++ LEAF(udelay) ++udelay: ++ END(udelay) ++ ++ ++ LEAF(FlushCache) ++ li k0, 0x80000000 # start address ++ li k1, 0x80004000 # end address (16KB I-Cache) ++ subu k1, 128 ++ ++1: ++ .set mips3 ++ cache IndexWriteBack_D, 0(k0) ++ cache IndexWriteBack_D, 32(k0) ++ cache IndexWriteBack_D, 64(k0) ++ cache IndexWriteBack_D, 96(k0) ++ cache IndexInvalidate_I, 0(k0) ++ cache IndexInvalidate_I, 32(k0) ++ cache IndexInvalidate_I, 64(k0) ++ cache IndexInvalidate_I, 96(k0) ++ .set mips0 ++ ++ bne k0, k1, 1b ++ addu k0, k0, 128 ++ jr ra ++ nop ++ END(FlushCache) ++ ++ .comm .stack,4096*2,4 +diff -Naru linux/arch/mips/zboot/csb250/Makefile linux.spi/arch/mips/zboot/csb250/Makefile +--- linux/arch/mips/zboot/csb250/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/csb250/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,90 @@ ++# arch/mips/zboot/pb1xxx/Makefile ++# ++# Makefile for Cogent CSB250 Au1500 board. ++# All of the boot loader code was derived from the ppc ++# boot code. ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation; either version 2 of the License, or (at your ++# option) any later version. ++ ++.c.s: ++ $(CC) $(CFLAGS) -S -o $*.s $< ++.s.o: ++ $(AS) -o $*.o $< ++.c.o: ++ $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $< ++.S.s: ++ $(CPP) $(AFLAGS) -o $*.o $< ++.S.o: ++ $(CC) $(AFLAGS) -c -o $*.o $< ++ ++######################################################################### ++# START BOARD SPECIFIC VARIABLES ++BNAME=csb250 ++ ++# These two variables control where the zImage is stored ++# in flash and loaded in memory. It only controls how the srec ++# file is generated, the code is the same. ++RAM_RUN_ADDR = 0x80a00000 ++FLASH_LOAD_ADDR = 0xBFD00000 ++ ++# These two variables specify the free ram region ++# that can be used for temporary malloc area ++AVAIL_RAM_START=0x80400000 ++AVAIL_RAM_END=0x80800000 ++ ++# This one must match the LOADADDR in arch/mips/Makefile! ++LOADADDR=0x80100000 ++# END BOARD SPECIFIC VARIABLES ++######################################################################### ++ ++OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \ ++ ../common/au1k_uart.o ../common/string.o ../common/ctype.o ++LIBS := ../lib/zlib.a ++ ++ENTRY := ../utils/entry ++OFFSET := ../utils/offset ++SIZE := ../utils/size ++ ++LD_ARGS := -T ../ld.script -Ttext $(RAM_RUN_ADDR) -Bstatic ++OBJCOPY_ARGS = -O elf32-tradbigmips ++ ++all: zImage ++ ++clean: ++ rm -rf *.o vmlinux* zvmlinux.* ../images/*.srec ++ ++head.o: head.S $(TOPDIR)/vmlinux ++ $(CC) $(AFLAGS) \ ++ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) \ ++ -c -o $*.o $< ++ ++../common/misc-simple.o: ++ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ ++ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \ ++ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \ ++ -DLOADADDR=$(LOADADDR) \ ++ -DZIMAGE_SIZE=0 -c -o $@ $*.c ++ ++zvmlinux: $(OBJECTS) $(LIBS) ../ld.script ../images/vmlinux.gz ../common/dummy.o ++ $(OBJCOPY) \ ++ --add-section=.image=../images/vmlinux.gz \ ++ --set-section-flags=.image=contents,alloc,load,readonly,data \ ++ ../common/dummy.o image.o ++ $(LD) $(LD_ARGS) -o $@ $(OBJECTS) image.o $(LIBS) ++ $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr \ ++ -R .initrd -R .sysmap ++ ++# Here we manipulate the image in order to get it the necessary ++# srecord file we need. ++zImage: zvmlinux ++ mv zvmlinux ../images/zImage.$(BNAME) ++ $(OBJCOPY) -O binary ../images/zImage.$(BNAME) ../images/$(BNAME).bin ++ ++zImage.flash: zImage ++ $(OBJCOPY) -O srec --adjust-vma 0x3ed00000 \ ++ ../images/zImage.$(BNAME) ../images/$(BNAME).flash.srec ++ ++include $(TOPDIR)/Rules.make +diff -Naru linux/arch/mips/zboot/images/Makefile linux.spi/arch/mips/zboot/images/Makefile +--- linux/arch/mips/zboot/images/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/images/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,10 @@ ++ ++include $(TOPDIR)/Rules.make ++ ++vmlinux.gz: $(TOPDIR)/vmlinux ++ $(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux ++ gzip -vf vmlinux ++ ++clean: ++ rm -f vmlinux.* zImage.* ++ +diff -Naru linux/arch/mips/zboot/include/nonstdio.h linux.spi/arch/mips/zboot/include/nonstdio.h +--- linux/arch/mips/zboot/include/nonstdio.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/include/nonstdio.h 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,18 @@ ++/* ++ * Copyright (C) Paul Mackerras 1997. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++typedef int FILE; ++extern FILE *stdin, *stdout; ++#define NULL ((void *)0) ++#define EOF (-1) ++#define fopen(n, m) NULL ++#define fflush(f) 0 ++#define fclose(f) 0 ++extern char *fgets(); ++ ++#define perror(s) printf("%s: no files!\n", (s)) +diff -Naru linux/arch/mips/zboot/include/ns16550.h linux.spi/arch/mips/zboot/include/ns16550.h +--- linux/arch/mips/zboot/include/ns16550.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/include/ns16550.h 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,49 @@ ++/* ++ * NS16550 Serial Port ++ */ ++ ++/* ++ * Figure out which file will have the definitons of COMx ++ */ ++#if !defined(CONFIG_AU1X00_UART) ++#error no serial.h ++#endif ++ ++/* Some machines have their uart registers 16 bytes apart. Most don't. ++ * TODO: Make this work like drivers/char/serial does - Tom */ ++#if !defined(UART_REG_PAD) ++#define UART_REG_PAD(x) ++#endif ++ ++struct NS16550 ++ { ++ unsigned char rbr; /* 0 */ ++ UART_REG_PAD(rbr) ++ unsigned char ier; /* 1 */ ++ UART_REG_PAD(ier) ++ unsigned char fcr; /* 2 */ ++ UART_REG_PAD(fcr) ++ unsigned char lcr; /* 3 */ ++ UART_REG_PAD(lcr) ++ unsigned char mcr; /* 4 */ ++ UART_REG_PAD(mcr) ++ unsigned char lsr; /* 5 */ ++ UART_REG_PAD(lsr) ++ unsigned char msr; /* 6 */ ++ UART_REG_PAD(msr) ++ unsigned char scr; /* 7 */ ++ }; ++ ++#define thr rbr ++#define iir fcr ++#define dll rbr ++#define dlm ier ++ ++#define LSR_DR 0x01 /* Data ready */ ++#define LSR_OE 0x02 /* Overrun */ ++#define LSR_PE 0x04 /* Parity error */ ++#define LSR_FE 0x08 /* Framing error */ ++#define LSR_BI 0x10 /* Break */ ++#define LSR_THRE 0x20 /* Xmit holding register empty */ ++#define LSR_TEMT 0x40 /* Xmitter empty */ ++#define LSR_ERR 0x80 /* Error */ +diff -Naru linux/arch/mips/zboot/include/pb1000_serial.h linux.spi/arch/mips/zboot/include/pb1000_serial.h +--- linux/arch/mips/zboot/include/pb1000_serial.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/include/pb1000_serial.h 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,20 @@ ++/* ++ * arch/ppc/boot/include/sandpoint_serial.h ++ * ++ * Location of the COM ports on Motorola SPS Sandpoint machines ++ * ++ * Author: Mark A. Greer ++ * mgreer@mvista.com ++ * ++ * Copyright 2001 MontaVista Software Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#define COM1 0xfe0003f8 ++#define COM2 0xfe0002f8 ++#define COM3 0x00000000 /* No COM3 */ ++#define COM4 0x00000000 /* No COM4 */ +diff -Naru linux/arch/mips/zboot/include/zlib.h linux.spi/arch/mips/zboot/include/zlib.h +--- linux/arch/mips/zboot/include/zlib.h 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/include/zlib.h 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,432 @@ ++/* $Id: zlib.h,v 1.2 2002/02/16 16:55:45 ppopov Exp $ */ ++ ++/* ++ * This file is derived from zlib.h and zconf.h from the zlib-0.95 ++ * distribution by Jean-loup Gailly and Mark Adler, with some additions ++ * by Paul Mackerras to aid in implementing Deflate compression and ++ * decompression for PPP packets. ++ */ ++ ++/* ++ * ==FILEVERSION 960122== ++ * ++ * This marker is used by the Linux installation script to determine ++ * whether an up-to-date version of this file is already installed. ++ */ ++ ++/* zlib.h -- interface of the 'zlib' general purpose compression library ++ version 0.95, Aug 16th, 1995. ++ ++ Copyright (C) 1995 Jean-loup Gailly and Mark Adler ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++ ++ Jean-loup Gailly Mark Adler ++ gzip@prep.ai.mit.edu madler@alumni.caltech.edu ++ */ ++ ++#ifndef _ZLIB_H ++#define _ZLIB_H ++ ++/* #include "zconf.h" */ /* included directly here */ ++ ++/* zconf.h -- configuration of the zlib compression library ++ * Copyright (C) 1995 Jean-loup Gailly. ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ ++ ++/* ++ The library does not install any signal handler. It is recommended to ++ add at least a handler for SIGSEGV when decompressing; the library checks ++ the consistency of the input data whenever possible but may go nuts ++ for some forms of corrupted input. ++ */ ++ ++/* ++ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more ++ * than 64k bytes at a time (needed on systems with 16-bit int). ++ * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints ++ * at addresses which are not a multiple of their size. ++ * Under DOS, -DFAR=far or -DFAR=__far may be needed. ++ */ ++ ++#ifndef STDC ++# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) ++# define STDC ++# endif ++#endif ++ ++#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ ++# include ++#endif ++ ++/* Maximum value for memLevel in deflateInit2 */ ++#ifndef MAX_MEM_LEVEL ++# ifdef MAXSEG_64K ++# define MAX_MEM_LEVEL 8 ++# else ++# define MAX_MEM_LEVEL 9 ++# endif ++#endif ++ ++#ifndef FAR ++# define FAR ++#endif ++ ++/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ ++#ifndef MAX_WBITS ++# define MAX_WBITS 15 /* 32K LZ77 window */ ++#endif ++ ++/* The memory requirements for deflate are (in bytes): ++ 1 << (windowBits+2) + 1 << (memLevel+9) ++ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) ++ plus a few kilobytes for small objects. For example, if you want to reduce ++ the default memory requirements from 256K to 128K, compile with ++ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" ++ Of course this will generally degrade compression (there's no free lunch). ++ ++ The memory requirements for inflate are (in bytes) 1 << windowBits ++ that is, 32K for windowBits=15 (default value) plus a few kilobytes ++ for small objects. ++*/ ++ ++ /* Type declarations */ ++ ++#ifndef OF /* function prototypes */ ++# ifdef STDC ++# define OF(args) args ++# else ++# define OF(args) () ++# endif ++#endif ++ ++typedef unsigned char Byte; /* 8 bits */ ++typedef unsigned int uInt; /* 16 bits or more */ ++typedef unsigned long uLong; /* 32 bits or more */ ++ ++typedef Byte FAR Bytef; ++typedef char FAR charf; ++typedef int FAR intf; ++typedef uInt FAR uIntf; ++typedef uLong FAR uLongf; ++ ++#ifdef STDC ++ typedef void FAR *voidpf; ++ typedef void *voidp; ++#else ++ typedef Byte FAR *voidpf; ++ typedef Byte *voidp; ++#endif ++ ++/* end of original zconf.h */ ++ ++#define ZLIB_VERSION "0.95P" ++ ++/* ++ The 'zlib' compression library provides in-memory compression and ++ decompression functions, including integrity checks of the uncompressed ++ data. This version of the library supports only one compression method ++ (deflation) but other algorithms may be added later and will have the same ++ stream interface. ++ ++ For compression the application must provide the output buffer and ++ may optionally provide the input buffer for optimization. For decompression, ++ the application must provide the input buffer and may optionally provide ++ the output buffer for optimization. ++ ++ Compression can be done in a single step if the buffers are large ++ enough (for example if an input file is mmap'ed), or can be done by ++ repeated calls of the compression function. In the latter case, the ++ application must provide more input and/or consume the output ++ (providing more output space) before each call. ++*/ ++ ++typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); ++typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes)); ++ ++struct internal_state; ++ ++typedef struct z_stream_s { ++ Bytef *next_in; /* next input byte */ ++ uInt avail_in; /* number of bytes available at next_in */ ++ uLong total_in; /* total nb of input bytes read so far */ ++ ++ Bytef *next_out; /* next output byte should be put there */ ++ uInt avail_out; /* remaining free space at next_out */ ++ uLong total_out; /* total nb of bytes output so far */ ++ ++ char *msg; /* last error message, NULL if no error */ ++ struct internal_state FAR *state; /* not visible by applications */ ++ ++ alloc_func zalloc; /* used to allocate the internal state */ ++ free_func zfree; /* used to free the internal state */ ++ voidp opaque; /* private data object passed to zalloc and zfree */ ++ ++ Byte data_type; /* best guess about the data type: ascii or binary */ ++ ++} z_stream; ++ ++/* ++ The application must update next_in and avail_in when avail_in has ++ dropped to zero. It must update next_out and avail_out when avail_out ++ has dropped to zero. The application must initialize zalloc, zfree and ++ opaque before calling the init function. All other fields are set by the ++ compression library and must not be updated by the application. ++ ++ The opaque value provided by the application will be passed as the first ++ parameter for calls of zalloc and zfree. This can be useful for custom ++ memory management. The compression library attaches no meaning to the ++ opaque value. ++ ++ zalloc must return Z_NULL if there is not enough memory for the object. ++ On 16-bit systems, the functions zalloc and zfree must be able to allocate ++ exactly 65536 bytes, but will not be required to allocate more than this ++ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, ++ pointers returned by zalloc for objects of exactly 65536 bytes *must* ++ have their offset normalized to zero. The default allocation function ++ provided by this library ensures this (see zutil.c). To reduce memory ++ requirements and avoid any allocation of 64K objects, at the expense of ++ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). ++ ++ The fields total_in and total_out can be used for statistics or ++ progress reports. After compression, total_in holds the total size of ++ the uncompressed data and may be saved for use in the decompressor ++ (particularly if the decompressor wants to decompress everything in ++ a single step). ++*/ ++ ++ /* constants */ ++ ++#define Z_NO_FLUSH 0 ++#define Z_PARTIAL_FLUSH 1 ++#define Z_FULL_FLUSH 2 ++#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ ++#define Z_FINISH 4 ++#define Z_PACKET_FLUSH 5 ++/* See deflate() below for the usage of these constants */ ++ ++#define Z_OK 0 ++#define Z_STREAM_END 1 ++#define Z_ERRNO (-1) ++#define Z_STREAM_ERROR (-2) ++#define Z_DATA_ERROR (-3) ++#define Z_MEM_ERROR (-4) ++#define Z_BUF_ERROR (-5) ++/* error codes for the compression/decompression functions */ ++ ++#define Z_BEST_SPEED 1 ++#define Z_BEST_COMPRESSION 9 ++#define Z_DEFAULT_COMPRESSION (-1) ++/* compression levels */ ++ ++#define Z_FILTERED 1 ++#define Z_HUFFMAN_ONLY 2 ++#define Z_DEFAULT_STRATEGY 0 ++ ++#define Z_BINARY 0 ++#define Z_ASCII 1 ++#define Z_UNKNOWN 2 ++/* Used to set the data_type field */ ++ ++#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ ++ ++extern char *zlib_version; ++/* The application can compare zlib_version and ZLIB_VERSION for consistency. ++ If the first character differs, the library code actually used is ++ not compatible with the zlib.h header file used by the application. ++ */ ++ ++ /* basic functions */ ++ ++extern int inflateInit OF((z_stream *strm)); ++/* ++ Initializes the internal stream state for decompression. The fields ++ zalloc and zfree must be initialized before by the caller. If zalloc and ++ zfree are set to Z_NULL, inflateInit updates them to use default allocation ++ functions. ++ ++ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not ++ enough memory. msg is set to null if there is no error message. ++ inflateInit does not perform any decompression: this will be done by ++ inflate(). ++*/ ++ ++ ++extern int inflate OF((z_stream *strm, int flush)); ++/* ++ Performs one or both of the following actions: ++ ++ - Decompress more input starting at next_in and update next_in and avail_in ++ accordingly. If not all input can be processed (because there is not ++ enough room in the output buffer), next_in is updated and processing ++ will resume at this point for the next call of inflate(). ++ ++ - Provide more output starting at next_out and update next_out and avail_out ++ accordingly. inflate() always provides as much output as possible ++ (until there is no more input data or no more space in the output buffer). ++ ++ Before the call of inflate(), the application should ensure that at least ++ one of the actions is possible, by providing more input and/or consuming ++ more output, and updating the next_* and avail_* values accordingly. ++ The application can consume the uncompressed output when it wants, for ++ example when the output buffer is full (avail_out == 0), or after each ++ call of inflate(). ++ ++ If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, ++ inflate flushes as much output as possible to the output buffer. The ++ flushing behavior of inflate is not specified for values of the flush ++ parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the ++ current implementation actually flushes as much output as possible ++ anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data ++ has been consumed, it is expecting to see the length field of a stored ++ block; if not, it returns Z_DATA_ERROR. ++ ++ inflate() should normally be called until it returns Z_STREAM_END or an ++ error. However if all decompression is to be performed in a single step ++ (a single call of inflate), the parameter flush should be set to ++ Z_FINISH. In this case all pending input is processed and all pending ++ output is flushed; avail_out must be large enough to hold all the ++ uncompressed data. (The size of the uncompressed data may have been saved ++ by the compressor for this purpose.) The next operation on this stream must ++ be inflateEnd to deallocate the decompression state. The use of Z_FINISH ++ is never required, but can be used to inform inflate that a faster routine ++ may be used for the single inflate() call. ++ ++ inflate() returns Z_OK if some progress has been made (more input ++ processed or more output produced), Z_STREAM_END if the end of the ++ compressed data has been reached and all uncompressed output has been ++ produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if ++ the stream structure was inconsistent (for example if next_in or next_out ++ was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no ++ progress is possible or if there was not enough room in the output buffer ++ when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then ++ call inflateSync to look for a good compression block. */ ++ ++ ++extern int inflateEnd OF((z_stream *strm)); ++/* ++ All dynamically allocated data structures for this stream are freed. ++ This function discards any unprocessed input and does not flush any ++ pending output. ++ ++ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state ++ was inconsistent. In the error case, msg may be set but then points to a ++ static string (which must not be deallocated). ++*/ ++ ++ /* advanced functions */ ++ ++extern int inflateInit2 OF((z_stream *strm, ++ int windowBits)); ++/* ++ This is another version of inflateInit with more compression options. The ++ fields next_out, zalloc and zfree must be initialized before by the caller. ++ ++ The windowBits parameter is the base two logarithm of the maximum window ++ size (the size of the history buffer). It should be in the range 8..15 for ++ this version of the library (the value 16 will be allowed soon). The ++ default value is 15 if inflateInit is used instead. If a compressed stream ++ with a larger window size is given as input, inflate() will return with ++ the error code Z_DATA_ERROR instead of trying to allocate a larger window. ++ ++ If next_out is not null, the library will use this buffer for the history ++ buffer; the buffer must either be large enough to hold the entire output ++ data, or have at least 1<msg=z_errmsg[1-err], err) ++/* To be used only when the state is known to be valid */ ++ ++#ifndef NULL ++#define NULL ((void *) 0) ++#endif ++ ++ /* common constants */ ++ ++#define DEFLATED 8 ++ ++#ifndef DEF_WBITS ++# define DEF_WBITS MAX_WBITS ++#endif ++/* default windowBits for decompression. MAX_WBITS is for compression only */ ++ ++#if MAX_MEM_LEVEL >= 8 ++# define DEF_MEM_LEVEL 8 ++#else ++# define DEF_MEM_LEVEL MAX_MEM_LEVEL ++#endif ++/* default memLevel */ ++ ++#define STORED_BLOCK 0 ++#define STATIC_TREES 1 ++#define DYN_TREES 2 ++/* The three kinds of block type */ ++ ++#define MIN_MATCH 3 ++#define MAX_MATCH 258 ++/* The minimum and maximum match lengths */ ++ ++ /* functions */ ++ ++#include ++#define zmemcpy memcpy ++#define zmemzero(dest, len) memset(dest, 0, len) ++ ++/* Diagnostic functions */ ++#ifdef DEBUG_ZLIB ++# include ++# ifndef verbose ++# define verbose 0 ++# endif ++# define Assert(cond,msg) {if(!(cond)) z_error(msg);} ++# define Trace(x) fprintf x ++# define Tracev(x) {if (verbose) fprintf x ;} ++# define Tracevv(x) {if (verbose>1) fprintf x ;} ++# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} ++# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} ++#else ++# define Assert(cond,msg) ++# define Trace(x) ++# define Tracev(x) ++# define Tracevv(x) ++# define Tracec(c,x) ++# define Tracecv(c,x) ++#endif ++ ++ ++typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); ++ ++/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */ ++/* void zcfree OF((voidpf opaque, voidpf ptr)); */ ++ ++#define ZALLOC(strm, items, size) \ ++ (*((strm)->zalloc))((strm)->opaque, (items), (size)) ++#define ZFREE(strm, addr, size) \ ++ (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size)) ++#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);} ++ ++/* deflate.h -- internal compression state ++ * Copyright (C) 1995 Jean-loup Gailly ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++/*+++++*/ ++/* infblock.h -- header to use infblock.c ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++struct inflate_blocks_state; ++typedef struct inflate_blocks_state FAR inflate_blocks_statef; ++ ++local inflate_blocks_statef * inflate_blocks_new OF(( ++ z_stream *z, ++ check_func c, /* check function */ ++ uInt w)); /* window size */ ++ ++local int inflate_blocks OF(( ++ inflate_blocks_statef *, ++ z_stream *, ++ int)); /* initial return code */ ++ ++local void inflate_blocks_reset OF(( ++ inflate_blocks_statef *, ++ z_stream *, ++ uLongf *)); /* check value on output */ ++ ++local int inflate_blocks_free OF(( ++ inflate_blocks_statef *, ++ z_stream *, ++ uLongf *)); /* check value on output */ ++ ++local int inflate_addhistory OF(( ++ inflate_blocks_statef *, ++ z_stream *)); ++ ++local int inflate_packet_flush OF(( ++ inflate_blocks_statef *)); ++ ++/*+++++*/ ++/* inftrees.h -- header to use inftrees.c ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++/* Huffman code lookup table entry--this entry is four bytes for machines ++ that have 16-bit pointers (e.g. PC's in the small or medium model). */ ++ ++typedef struct inflate_huft_s FAR inflate_huft; ++ ++struct inflate_huft_s { ++ union { ++ struct { ++ Byte Exop; /* number of extra bits or operation */ ++ Byte Bits; /* number of bits in this code or subcode */ ++ } what; ++ uInt Nalloc; /* number of these allocated here */ ++ Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ ++ } word; /* 16-bit, 8 bytes for 32-bit machines) */ ++ union { ++ uInt Base; /* literal, length base, or distance base */ ++ inflate_huft *Next; /* pointer to next level of table */ ++ } more; ++}; ++ ++#ifdef DEBUG_ZLIB ++ local uInt inflate_hufts; ++#endif ++ ++local int inflate_trees_bits OF(( ++ uIntf *, /* 19 code lengths */ ++ uIntf *, /* bits tree desired/actual depth */ ++ inflate_huft * FAR *, /* bits tree result */ ++ z_stream *)); /* for zalloc, zfree functions */ ++ ++local int inflate_trees_dynamic OF(( ++ uInt, /* number of literal/length codes */ ++ uInt, /* number of distance codes */ ++ uIntf *, /* that many (total) code lengths */ ++ uIntf *, /* literal desired/actual bit depth */ ++ uIntf *, /* distance desired/actual bit depth */ ++ inflate_huft * FAR *, /* literal/length tree result */ ++ inflate_huft * FAR *, /* distance tree result */ ++ z_stream *)); /* for zalloc, zfree functions */ ++ ++local int inflate_trees_fixed OF(( ++ uIntf *, /* literal desired/actual bit depth */ ++ uIntf *, /* distance desired/actual bit depth */ ++ inflate_huft * FAR *, /* literal/length tree result */ ++ inflate_huft * FAR *)); /* distance tree result */ ++ ++local int inflate_trees_free OF(( ++ inflate_huft *, /* tables to free */ ++ z_stream *)); /* for zfree function */ ++ ++ ++/*+++++*/ ++/* infcodes.h -- header to use infcodes.c ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++struct inflate_codes_state; ++typedef struct inflate_codes_state FAR inflate_codes_statef; ++ ++local inflate_codes_statef *inflate_codes_new OF(( ++ uInt, uInt, ++ inflate_huft *, inflate_huft *, ++ z_stream *)); ++ ++local int inflate_codes OF(( ++ inflate_blocks_statef *, ++ z_stream *, ++ int)); ++ ++local void inflate_codes_free OF(( ++ inflate_codes_statef *, ++ z_stream *)); ++ ++ ++/*+++++*/ ++/* inflate.c -- zlib interface to inflate modules ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* inflate private state */ ++struct internal_state { ++ ++ /* mode */ ++ enum { ++ METHOD, /* waiting for method byte */ ++ FLAG, /* waiting for flag byte */ ++ BLOCKS, /* decompressing blocks */ ++ CHECK4, /* four check bytes to go */ ++ CHECK3, /* three check bytes to go */ ++ CHECK2, /* two check bytes to go */ ++ CHECK1, /* one check byte to go */ ++ DONE, /* finished check, done */ ++ BAD} /* got an error--stay here */ ++ mode; /* current inflate mode */ ++ ++ /* mode dependent information */ ++ union { ++ uInt method; /* if FLAGS, method byte */ ++ struct { ++ uLong was; /* computed check value */ ++ uLong need; /* stream check value */ ++ } check; /* if CHECK, check values to compare */ ++ uInt marker; /* if BAD, inflateSync's marker bytes count */ ++ } sub; /* submode */ ++ ++ /* mode independent information */ ++ int nowrap; /* flag for no wrapper */ ++ uInt wbits; /* log2(window size) (8..15, defaults to 15) */ ++ inflate_blocks_statef ++ *blocks; /* current inflate_blocks state */ ++ ++}; ++ ++ ++int inflateReset(z) ++z_stream *z; ++{ ++ uLong c; ++ ++ if (z == Z_NULL || z->state == Z_NULL) ++ return Z_STREAM_ERROR; ++ z->total_in = z->total_out = 0; ++ z->msg = Z_NULL; ++ z->state->mode = z->state->nowrap ? BLOCKS : METHOD; ++ inflate_blocks_reset(z->state->blocks, z, &c); ++ Trace((stderr, "inflate: reset\n")); ++ return Z_OK; ++} ++ ++ ++int inflateEnd(z) ++z_stream *z; ++{ ++ uLong c; ++ ++ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) ++ return Z_STREAM_ERROR; ++ if (z->state->blocks != Z_NULL) ++ inflate_blocks_free(z->state->blocks, z, &c); ++ ZFREE(z, z->state, sizeof(struct internal_state)); ++ z->state = Z_NULL; ++ Trace((stderr, "inflate: end\n")); ++ return Z_OK; ++} ++ ++ ++int inflateInit2(z, w) ++z_stream *z; ++int w; ++{ ++ /* initialize state */ ++ if (z == Z_NULL) ++ return Z_STREAM_ERROR; ++/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */ ++/* if (z->zfree == Z_NULL) z->zfree = zcfree; */ ++ if ((z->state = (struct internal_state FAR *) ++ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) ++ return Z_MEM_ERROR; ++ z->state->blocks = Z_NULL; ++ ++ /* handle undocumented nowrap option (no zlib header or check) */ ++ z->state->nowrap = 0; ++ if (w < 0) ++ { ++ w = - w; ++ z->state->nowrap = 1; ++ } ++ ++ /* set window size */ ++ if (w < 8 || w > 15) ++ { ++ inflateEnd(z); ++ return Z_STREAM_ERROR; ++ } ++ z->state->wbits = (uInt)w; ++ ++ /* create inflate_blocks state */ ++ if ((z->state->blocks = ++ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) ++ == Z_NULL) ++ { ++ inflateEnd(z); ++ return Z_MEM_ERROR; ++ } ++ Trace((stderr, "inflate: allocated\n")); ++ ++ /* reset state */ ++ inflateReset(z); ++ return Z_OK; ++} ++ ++ ++int inflateInit(z) ++z_stream *z; ++{ ++ return inflateInit2(z, DEF_WBITS); ++} ++ ++ ++#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} ++#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) ++ ++int inflate(z, f) ++z_stream *z; ++int f; ++{ ++ int r; ++ uInt b; ++ ++ if (z == Z_NULL || z->next_in == Z_NULL) ++ return Z_STREAM_ERROR; ++ r = Z_BUF_ERROR; ++ while (1) switch (z->state->mode) ++ { ++ case METHOD: ++ NEEDBYTE ++ if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) ++ { ++ z->state->mode = BAD; ++ z->msg = "unknown compression method"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ if ((z->state->sub.method >> 4) + 8 > z->state->wbits) ++ { ++ z->state->mode = BAD; ++ z->msg = "invalid window size"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ z->state->mode = FLAG; ++ case FLAG: ++ NEEDBYTE ++ if ((b = NEXTBYTE) & 0x20) ++ { ++ z->state->mode = BAD; ++ z->msg = "invalid reserved bit"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ if (((z->state->sub.method << 8) + b) % 31) ++ { ++ z->state->mode = BAD; ++ z->msg = "incorrect header check"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ Trace((stderr, "inflate: zlib header ok\n")); ++ z->state->mode = BLOCKS; ++ case BLOCKS: ++ r = inflate_blocks(z->state->blocks, z, r); ++ if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) ++ r = inflate_packet_flush(z->state->blocks); ++ if (r == Z_DATA_ERROR) ++ { ++ z->state->mode = BAD; ++ z->state->sub.marker = 0; /* can try inflateSync */ ++ break; ++ } ++ if (r != Z_STREAM_END) ++ return r; ++ r = Z_OK; ++ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); ++ if (z->state->nowrap) ++ { ++ z->state->mode = DONE; ++ break; ++ } ++ z->state->mode = CHECK4; ++ case CHECK4: ++ NEEDBYTE ++ z->state->sub.check.need = (uLong)NEXTBYTE << 24; ++ z->state->mode = CHECK3; ++ case CHECK3: ++ NEEDBYTE ++ z->state->sub.check.need += (uLong)NEXTBYTE << 16; ++ z->state->mode = CHECK2; ++ case CHECK2: ++ NEEDBYTE ++ z->state->sub.check.need += (uLong)NEXTBYTE << 8; ++ z->state->mode = CHECK1; ++ case CHECK1: ++ NEEDBYTE ++ z->state->sub.check.need += (uLong)NEXTBYTE; ++ ++ if (z->state->sub.check.was != z->state->sub.check.need) ++ { ++ z->state->mode = BAD; ++ z->msg = "incorrect data check"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ Trace((stderr, "inflate: zlib check ok\n")); ++ z->state->mode = DONE; ++ case DONE: ++ return Z_STREAM_END; ++ case BAD: ++ return Z_DATA_ERROR; ++ default: ++ return Z_STREAM_ERROR; ++ } ++ ++ empty: ++ if (f != Z_PACKET_FLUSH) ++ return r; ++ z->state->mode = BAD; ++ z->state->sub.marker = 0; /* can try inflateSync */ ++ return Z_DATA_ERROR; ++} ++ ++/* ++ * This subroutine adds the data at next_in/avail_in to the output history ++ * without performing any output. The output buffer must be "caught up"; ++ * i.e. no pending output (hence s->read equals s->write), and the state must ++ * be BLOCKS (i.e. we should be willing to see the start of a series of ++ * BLOCKS). On exit, the output will also be caught up, and the checksum ++ * will have been updated if need be. ++ */ ++ ++int inflateIncomp(z) ++z_stream *z; ++{ ++ if (z->state->mode != BLOCKS) ++ return Z_DATA_ERROR; ++ return inflate_addhistory(z->state->blocks, z); ++} ++ ++ ++int inflateSync(z) ++z_stream *z; ++{ ++ uInt n; /* number of bytes to look at */ ++ Bytef *p; /* pointer to bytes */ ++ uInt m; /* number of marker bytes found in a row */ ++ uLong r, w; /* temporaries to save total_in and total_out */ ++ ++ /* set up */ ++ if (z == Z_NULL || z->state == Z_NULL) ++ return Z_STREAM_ERROR; ++ if (z->state->mode != BAD) ++ { ++ z->state->mode = BAD; ++ z->state->sub.marker = 0; ++ } ++ if ((n = z->avail_in) == 0) ++ return Z_BUF_ERROR; ++ p = z->next_in; ++ m = z->state->sub.marker; ++ ++ /* search */ ++ while (n && m < 4) ++ { ++ if (*p == (Byte)(m < 2 ? 0 : 0xff)) ++ m++; ++ else if (*p) ++ m = 0; ++ else ++ m = 4 - m; ++ p++, n--; ++ } ++ ++ /* restore */ ++ z->total_in += p - z->next_in; ++ z->next_in = p; ++ z->avail_in = n; ++ z->state->sub.marker = m; ++ ++ /* return no joy or set up to restart on a new block */ ++ if (m != 4) ++ return Z_DATA_ERROR; ++ r = z->total_in; w = z->total_out; ++ inflateReset(z); ++ z->total_in = r; z->total_out = w; ++ z->state->mode = BLOCKS; ++ return Z_OK; ++} ++ ++#undef NEEDBYTE ++#undef NEXTBYTE ++ ++/*+++++*/ ++/* infutil.h -- types and macros common to blocks and codes ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++/* inflate blocks semi-private state */ ++struct inflate_blocks_state { ++ ++ /* mode */ ++ enum { ++ TYPE, /* get type bits (3, including end bit) */ ++ LENS, /* get lengths for stored */ ++ STORED, /* processing stored block */ ++ TABLE, /* get table lengths */ ++ BTREE, /* get bit lengths tree for a dynamic block */ ++ DTREE, /* get length, distance trees for a dynamic block */ ++ CODES, /* processing fixed or dynamic block */ ++ DRY, /* output remaining window bytes */ ++ DONEB, /* finished last block, done */ ++ BADB} /* got a data error--stuck here */ ++ mode; /* current inflate_block mode */ ++ ++ /* mode dependent information */ ++ union { ++ uInt left; /* if STORED, bytes left to copy */ ++ struct { ++ uInt table; /* table lengths (14 bits) */ ++ uInt index; /* index into blens (or border) */ ++ uIntf *blens; /* bit lengths of codes */ ++ uInt bb; /* bit length tree depth */ ++ inflate_huft *tb; /* bit length decoding tree */ ++ int nblens; /* # elements allocated at blens */ ++ } trees; /* if DTREE, decoding info for trees */ ++ struct { ++ inflate_huft *tl, *td; /* trees to free */ ++ inflate_codes_statef ++ *codes; ++ } decode; /* if CODES, current state */ ++ } sub; /* submode */ ++ uInt last; /* true if this block is the last block */ ++ ++ /* mode independent information */ ++ uInt bitk; /* bits in bit buffer */ ++ uLong bitb; /* bit buffer */ ++ Bytef *window; /* sliding window */ ++ Bytef *end; /* one byte after sliding window */ ++ Bytef *read; /* window read pointer */ ++ Bytef *write; /* window write pointer */ ++ check_func checkfn; /* check function */ ++ uLong check; /* check on output */ ++ ++}; ++ ++ ++/* defines for inflate input/output */ ++/* update pointers and return */ ++#define UPDBITS {s->bitb=b;s->bitk=k;} ++#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} ++#define UPDOUT {s->write=q;} ++#define UPDATE {UPDBITS UPDIN UPDOUT} ++#define LEAVE {UPDATE return inflate_flush(s,z,r);} ++/* get bytes and bits */ ++#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} ++#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} ++#define NEXTBYTE (n--,*p++) ++#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} ++/* output bytes */ ++#define WAVAIL (qread?s->read-q-1:s->end-q) ++#define LOADOUT {q=s->write;m=WAVAIL;} ++#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} ++#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} ++#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} ++#define OUTBYTE(a) {*q++=(Byte)(a);m--;} ++/* load local pointers */ ++#define LOAD {LOADIN LOADOUT} ++ ++/* ++ * The IBM 150 firmware munges the data right after _etext[]. This ++ * protects it. -- Cort ++ */ ++local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0}; ++/* And'ing with mask[n] masks the lower n bits */ ++local uInt inflate_mask[] = { ++ 0x0000, ++ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, ++ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff ++}; ++ ++/* copy as much as possible from the sliding window to the output area */ ++local int inflate_flush OF(( ++ inflate_blocks_statef *, ++ z_stream *, ++ int)); ++ ++/*+++++*/ ++/* inffast.h -- header to use inffast.c ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++local int inflate_fast OF(( ++ uInt, ++ uInt, ++ inflate_huft *, ++ inflate_huft *, ++ inflate_blocks_statef *, ++ z_stream *)); ++ ++ ++/*+++++*/ ++/* infblock.c -- interpret and process block types to last block ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* Table for deflate from PKZIP's appnote.txt. */ ++local uInt border[] = { /* Order of the bit length code lengths */ ++ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; ++ ++/* ++ Notes beyond the 1.93a appnote.txt: ++ ++ 1. Distance pointers never point before the beginning of the output ++ stream. ++ 2. Distance pointers can point back across blocks, up to 32k away. ++ 3. There is an implied maximum of 7 bits for the bit length table and ++ 15 bits for the actual data. ++ 4. If only one code exists, then it is encoded using one bit. (Zero ++ would be more efficient, but perhaps a little confusing.) If two ++ codes exist, they are coded using one bit each (0 and 1). ++ 5. There is no way of sending zero distance codes--a dummy must be ++ sent if there are none. (History: a pre 2.0 version of PKZIP would ++ store blocks with no distance codes, but this was discovered to be ++ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow ++ zero distance codes, which is sent as one code of zero bits in ++ length. ++ 6. There are up to 286 literal/length codes. Code 256 represents the ++ end-of-block. Note however that the static length tree defines ++ 288 codes just to fill out the Huffman codes. Codes 286 and 287 ++ cannot be used though, since there is no length base or extra bits ++ defined for them. Similarily, there are up to 30 distance codes. ++ However, static trees define 32 codes (all 5 bits) to fill out the ++ Huffman codes, but the last two had better not show up in the data. ++ 7. Unzip can check dynamic Huffman blocks for complete code sets. ++ The exception is that a single code would not be complete (see #4). ++ 8. The five bits following the block type is really the number of ++ literal codes sent minus 257. ++ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits ++ (1+6+6). Therefore, to output three times the length, you output ++ three codes (1+1+1), whereas to output four times the same length, ++ you only need two codes (1+3). Hmm. ++ 10. In the tree reconstruction algorithm, Code = Code + Increment ++ only if BitLength(i) is not zero. (Pretty obvious.) ++ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) ++ 12. Note: length code 284 can represent 227-258, but length code 285 ++ really is 258. The last length deserves its own, short code ++ since it gets used a lot in very redundant files. The length ++ 258 is special since 258 - 3 (the min match length) is 255. ++ 13. The literal/length and distance code bit lengths are read as a ++ single stream of lengths. It is possible (and advantageous) for ++ a repeat code (16, 17, or 18) to go across the boundary between ++ the two sets of lengths. ++ */ ++ ++ ++local void inflate_blocks_reset(s, z, c) ++inflate_blocks_statef *s; ++z_stream *z; ++uLongf *c; ++{ ++ if (s->checkfn != Z_NULL) ++ *c = s->check; ++ if (s->mode == BTREE || s->mode == DTREE) ++ ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); ++ if (s->mode == CODES) ++ { ++ inflate_codes_free(s->sub.decode.codes, z); ++ inflate_trees_free(s->sub.decode.td, z); ++ inflate_trees_free(s->sub.decode.tl, z); ++ } ++ s->mode = TYPE; ++ s->bitk = 0; ++ s->bitb = 0; ++ s->read = s->write = s->window; ++ if (s->checkfn != Z_NULL) ++ s->check = (*s->checkfn)(0L, Z_NULL, 0); ++ Trace((stderr, "inflate: blocks reset\n")); ++} ++ ++ ++local inflate_blocks_statef *inflate_blocks_new(z, c, w) ++z_stream *z; ++check_func c; ++uInt w; ++{ ++ inflate_blocks_statef *s; ++ ++ if ((s = (inflate_blocks_statef *)ZALLOC ++ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) ++ return s; ++ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) ++ { ++ ZFREE(z, s, sizeof(struct inflate_blocks_state)); ++ return Z_NULL; ++ } ++ s->end = s->window + w; ++ s->checkfn = c; ++ s->mode = TYPE; ++ Trace((stderr, "inflate: blocks allocated\n")); ++ inflate_blocks_reset(s, z, &s->check); ++ return s; ++} ++ ++ ++local int inflate_blocks(s, z, r) ++inflate_blocks_statef *s; ++z_stream *z; ++int r; ++{ ++ uInt t; /* temporary storage */ ++ uLong b; /* bit buffer */ ++ uInt k; /* bits in bit buffer */ ++ Bytef *p; /* input data pointer */ ++ uInt n; /* bytes available there */ ++ Bytef *q; /* output window write pointer */ ++ uInt m; /* bytes to end of window or read pointer */ ++ ++ /* copy input/output information to locals (UPDATE macro restores) */ ++ LOAD ++ ++ /* process input based on current state */ ++ while (1) switch (s->mode) ++ { ++ case TYPE: ++ NEEDBITS(3) ++ t = (uInt)b & 7; ++ s->last = t & 1; ++ switch (t >> 1) ++ { ++ case 0: /* stored */ ++ Trace((stderr, "inflate: stored block%s\n", ++ s->last ? " (last)" : "")); ++ DUMPBITS(3) ++ t = k & 7; /* go to byte boundary */ ++ DUMPBITS(t) ++ s->mode = LENS; /* get length of stored block */ ++ break; ++ case 1: /* fixed */ ++ Trace((stderr, "inflate: fixed codes block%s\n", ++ s->last ? " (last)" : "")); ++ { ++ uInt bl, bd; ++ inflate_huft *tl, *td; ++ ++ inflate_trees_fixed(&bl, &bd, &tl, &td); ++ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); ++ if (s->sub.decode.codes == Z_NULL) ++ { ++ r = Z_MEM_ERROR; ++ LEAVE ++ } ++ s->sub.decode.tl = Z_NULL; /* don't try to free these */ ++ s->sub.decode.td = Z_NULL; ++ } ++ DUMPBITS(3) ++ s->mode = CODES; ++ break; ++ case 2: /* dynamic */ ++ Trace((stderr, "inflate: dynamic codes block%s\n", ++ s->last ? " (last)" : "")); ++ DUMPBITS(3) ++ s->mode = TABLE; ++ break; ++ case 3: /* illegal */ ++ DUMPBITS(3) ++ s->mode = BADB; ++ z->msg = "invalid block type"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ } ++ break; ++ case LENS: ++ NEEDBITS(32) ++ if (((~b) >> 16) != (b & 0xffff)) ++ { ++ s->mode = BADB; ++ z->msg = "invalid stored block lengths"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ } ++ s->sub.left = (uInt)b & 0xffff; ++ b = k = 0; /* dump bits */ ++ Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); ++ s->mode = s->sub.left ? STORED : TYPE; ++ break; ++ case STORED: ++ if (n == 0) ++ LEAVE ++ NEEDOUT ++ t = s->sub.left; ++ if (t > n) t = n; ++ if (t > m) t = m; ++ zmemcpy(q, p, t); ++ p += t; n -= t; ++ q += t; m -= t; ++ if ((s->sub.left -= t) != 0) ++ break; ++ Tracev((stderr, "inflate: stored end, %lu total out\n", ++ z->total_out + (q >= s->read ? q - s->read : ++ (s->end - s->read) + (q - s->window)))); ++ s->mode = s->last ? DRY : TYPE; ++ break; ++ case TABLE: ++ NEEDBITS(14) ++ s->sub.trees.table = t = (uInt)b & 0x3fff; ++#ifndef PKZIP_BUG_WORKAROUND ++ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) ++ { ++ s->mode = BADB; ++ z->msg = "too many length or distance symbols"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ } ++#endif ++ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); ++ if (t < 19) ++ t = 19; ++ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) ++ { ++ r = Z_MEM_ERROR; ++ LEAVE ++ } ++ s->sub.trees.nblens = t; ++ DUMPBITS(14) ++ s->sub.trees.index = 0; ++ Tracev((stderr, "inflate: table sizes ok\n")); ++ s->mode = BTREE; ++ case BTREE: ++ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) ++ { ++ NEEDBITS(3) ++ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; ++ DUMPBITS(3) ++ } ++ while (s->sub.trees.index < 19) ++ s->sub.trees.blens[border[s->sub.trees.index++]] = 0; ++ s->sub.trees.bb = 7; ++ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, ++ &s->sub.trees.tb, z); ++ if (t != Z_OK) ++ { ++ r = t; ++ if (r == Z_DATA_ERROR) ++ s->mode = BADB; ++ LEAVE ++ } ++ s->sub.trees.index = 0; ++ Tracev((stderr, "inflate: bits tree ok\n")); ++ s->mode = DTREE; ++ case DTREE: ++ while (t = s->sub.trees.table, ++ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) ++ { ++ inflate_huft *h; ++ uInt i, j, c; ++ ++ t = s->sub.trees.bb; ++ NEEDBITS(t) ++ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); ++ t = h->word.what.Bits; ++ c = h->more.Base; ++ if (c < 16) ++ { ++ DUMPBITS(t) ++ s->sub.trees.blens[s->sub.trees.index++] = c; ++ } ++ else /* c == 16..18 */ ++ { ++ i = c == 18 ? 7 : c - 14; ++ j = c == 18 ? 11 : 3; ++ NEEDBITS(t + i) ++ DUMPBITS(t) ++ j += (uInt)b & inflate_mask[i]; ++ DUMPBITS(i) ++ i = s->sub.trees.index; ++ t = s->sub.trees.table; ++ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || ++ (c == 16 && i < 1)) ++ { ++ s->mode = BADB; ++ z->msg = "invalid bit length repeat"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ } ++ c = c == 16 ? s->sub.trees.blens[i - 1] : 0; ++ do { ++ s->sub.trees.blens[i++] = c; ++ } while (--j); ++ s->sub.trees.index = i; ++ } ++ } ++ inflate_trees_free(s->sub.trees.tb, z); ++ s->sub.trees.tb = Z_NULL; ++ { ++ uInt bl, bd; ++ inflate_huft *tl, *td; ++ inflate_codes_statef *c; ++ ++ bl = 9; /* must be <= 9 for lookahead assumptions */ ++ bd = 6; /* must be <= 9 for lookahead assumptions */ ++ t = s->sub.trees.table; ++ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), ++ s->sub.trees.blens, &bl, &bd, &tl, &td, z); ++ if (t != Z_OK) ++ { ++ if (t == (uInt)Z_DATA_ERROR) ++ s->mode = BADB; ++ r = t; ++ LEAVE ++ } ++ Tracev((stderr, "inflate: trees ok\n")); ++ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) ++ { ++ inflate_trees_free(td, z); ++ inflate_trees_free(tl, z); ++ r = Z_MEM_ERROR; ++ LEAVE ++ } ++ ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); ++ s->sub.decode.codes = c; ++ s->sub.decode.tl = tl; ++ s->sub.decode.td = td; ++ } ++ s->mode = CODES; ++ case CODES: ++ UPDATE ++ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) ++ return inflate_flush(s, z, r); ++ r = Z_OK; ++ inflate_codes_free(s->sub.decode.codes, z); ++ inflate_trees_free(s->sub.decode.td, z); ++ inflate_trees_free(s->sub.decode.tl, z); ++ LOAD ++ Tracev((stderr, "inflate: codes end, %lu total out\n", ++ z->total_out + (q >= s->read ? q - s->read : ++ (s->end - s->read) + (q - s->window)))); ++ if (!s->last) ++ { ++ s->mode = TYPE; ++ break; ++ } ++ if (k > 7) /* return unused byte, if any */ ++ { ++ Assert(k < 16, "inflate_codes grabbed too many bytes") ++ k -= 8; ++ n++; ++ p--; /* can always return one */ ++ } ++ s->mode = DRY; ++ case DRY: ++ FLUSH ++ if (s->read != s->write) ++ LEAVE ++ s->mode = DONEB; ++ case DONEB: ++ r = Z_STREAM_END; ++ LEAVE ++ case BADB: ++ r = Z_DATA_ERROR; ++ LEAVE ++ default: ++ r = Z_STREAM_ERROR; ++ LEAVE ++ } ++} ++ ++ ++local int inflate_blocks_free(s, z, c) ++inflate_blocks_statef *s; ++z_stream *z; ++uLongf *c; ++{ ++ inflate_blocks_reset(s, z, c); ++ ZFREE(z, s->window, s->end - s->window); ++ ZFREE(z, s, sizeof(struct inflate_blocks_state)); ++ Trace((stderr, "inflate: blocks freed\n")); ++ return Z_OK; ++} ++ ++/* ++ * This subroutine adds the data at next_in/avail_in to the output history ++ * without performing any output. The output buffer must be "caught up"; ++ * i.e. no pending output (hence s->read equals s->write), and the state must ++ * be BLOCKS (i.e. we should be willing to see the start of a series of ++ * BLOCKS). On exit, the output will also be caught up, and the checksum ++ * will have been updated if need be. ++ */ ++local int inflate_addhistory(s, z) ++inflate_blocks_statef *s; ++z_stream *z; ++{ ++ uLong b; /* bit buffer */ /* NOT USED HERE */ ++ uInt k; /* bits in bit buffer */ /* NOT USED HERE */ ++ uInt t; /* temporary storage */ ++ Bytef *p; /* input data pointer */ ++ uInt n; /* bytes available there */ ++ Bytef *q; /* output window write pointer */ ++ uInt m; /* bytes to end of window or read pointer */ ++ ++ if (s->read != s->write) ++ return Z_STREAM_ERROR; ++ if (s->mode != TYPE) ++ return Z_DATA_ERROR; ++ ++ /* we're ready to rock */ ++ LOAD ++ /* while there is input ready, copy to output buffer, moving ++ * pointers as needed. ++ */ ++ while (n) { ++ t = n; /* how many to do */ ++ /* is there room until end of buffer? */ ++ if (t > m) t = m; ++ /* update check information */ ++ if (s->checkfn != Z_NULL) ++ s->check = (*s->checkfn)(s->check, q, t); ++ zmemcpy(q, p, t); ++ q += t; ++ p += t; ++ n -= t; ++ z->total_out += t; ++ s->read = q; /* drag read pointer forward */ ++/* WRAP */ /* expand WRAP macro by hand to handle s->read */ ++ if (q == s->end) { ++ s->read = q = s->window; ++ m = WAVAIL; ++ } ++ } ++ UPDATE ++ return Z_OK; ++} ++ ++ ++/* ++ * At the end of a Deflate-compressed PPP packet, we expect to have seen ++ * a `stored' block type value but not the (zero) length bytes. ++ */ ++local int inflate_packet_flush(s) ++ inflate_blocks_statef *s; ++{ ++ if (s->mode != LENS) ++ return Z_DATA_ERROR; ++ s->mode = TYPE; ++ return Z_OK; ++} ++ ++ ++/*+++++*/ ++/* inftrees.c -- generate Huffman trees for efficient decoding ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* simplify the use of the inflate_huft type with some defines */ ++#define base more.Base ++#define next more.Next ++#define exop word.what.Exop ++#define bits word.what.Bits ++ ++ ++local int huft_build OF(( ++ uIntf *, /* code lengths in bits */ ++ uInt, /* number of codes */ ++ uInt, /* number of "simple" codes */ ++ uIntf *, /* list of base values for non-simple codes */ ++ uIntf *, /* list of extra bits for non-simple codes */ ++ inflate_huft * FAR*,/* result: starting table */ ++ uIntf *, /* maximum lookup bits (returns actual) */ ++ z_stream *)); /* for zalloc function */ ++ ++local voidpf falloc OF(( ++ voidpf, /* opaque pointer (not used) */ ++ uInt, /* number of items */ ++ uInt)); /* size of item */ ++ ++local void ffree OF(( ++ voidpf q, /* opaque pointer (not used) */ ++ voidpf p, /* what to free (not used) */ ++ uInt n)); /* number of bytes (not used) */ ++ ++/* Tables for deflate from PKZIP's appnote.txt. */ ++local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ ++ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, ++ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; ++ /* actually lengths - 2; also see note #13 above about 258 */ ++local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, ++ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ ++local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ ++ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, ++ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, ++ 8193, 12289, 16385, 24577}; ++local uInt cpdext[] = { /* Extra bits for distance codes */ ++ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, ++ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, ++ 12, 12, 13, 13}; ++ ++/* ++ Huffman code decoding is performed using a multi-level table lookup. ++ The fastest way to decode is to simply build a lookup table whose ++ size is determined by the longest code. However, the time it takes ++ to build this table can also be a factor if the data being decoded ++ is not very long. The most common codes are necessarily the ++ shortest codes, so those codes dominate the decoding time, and hence ++ the speed. The idea is you can have a shorter table that decodes the ++ shorter, more probable codes, and then point to subsidiary tables for ++ the longer codes. The time it costs to decode the longer codes is ++ then traded against the time it takes to make longer tables. ++ ++ This results of this trade are in the variables lbits and dbits ++ below. lbits is the number of bits the first level table for literal/ ++ length codes can decode in one step, and dbits is the same thing for ++ the distance codes. Subsequent tables are also less than or equal to ++ those sizes. These values may be adjusted either when all of the ++ codes are shorter than that, in which case the longest code length in ++ bits is used, or when the shortest code is *longer* than the requested ++ table size, in which case the length of the shortest code in bits is ++ used. ++ ++ There are two different values for the two tables, since they code a ++ different number of possibilities each. The literal/length table ++ codes 286 possible values, or in a flat code, a little over eight ++ bits. The distance table codes 30 possible values, or a little less ++ than five bits, flat. The optimum values for speed end up being ++ about one bit more than those, so lbits is 8+1 and dbits is 5+1. ++ The optimum values may differ though from machine to machine, and ++ possibly even between compilers. Your mileage may vary. ++ */ ++ ++ ++/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ ++#define BMAX 15 /* maximum bit length of any code */ ++#define N_MAX 288 /* maximum number of codes in any set */ ++ ++#ifdef DEBUG_ZLIB ++ uInt inflate_hufts; ++#endif ++ ++local int huft_build(b, n, s, d, e, t, m, zs) ++uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ ++uInt n; /* number of codes (assumed <= N_MAX) */ ++uInt s; /* number of simple-valued codes (0..s-1) */ ++uIntf *d; /* list of base values for non-simple codes */ ++uIntf *e; /* list of extra bits for non-simple codes */ ++inflate_huft * FAR *t; /* result: starting table */ ++uIntf *m; /* maximum lookup bits, returns actual */ ++z_stream *zs; /* for zalloc function */ ++/* Given a list of code lengths and a maximum table size, make a set of ++ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR ++ if the given code set is incomplete (the tables are still built in this ++ case), Z_DATA_ERROR if the input is invalid (all zero length codes or an ++ over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ ++{ ++ ++ uInt a; /* counter for codes of length k */ ++ uInt c[BMAX+1]; /* bit length count table */ ++ uInt f; /* i repeats in table every f entries */ ++ int g; /* maximum code length */ ++ int h; /* table level */ ++ register uInt i; /* counter, current code */ ++ register uInt j; /* counter */ ++ register int k; /* number of bits in current code */ ++ int l; /* bits per table (returned in m) */ ++ register uIntf *p; /* pointer into c[], b[], or v[] */ ++ inflate_huft *q; /* points to current table */ ++ struct inflate_huft_s r; /* table entry for structure assignment */ ++ inflate_huft *u[BMAX]; /* table stack */ ++ uInt v[N_MAX]; /* values in order of bit length */ ++ register int w; /* bits before this table == (l * h) */ ++ uInt x[BMAX+1]; /* bit offsets, then code stack */ ++ uIntf *xp; /* pointer into x */ ++ int y; /* number of dummy codes added */ ++ uInt z; /* number of entries in current table */ ++ ++ ++ /* Generate counts for each bit length */ ++ p = c; ++#define C0 *p++ = 0; ++#define C2 C0 C0 C0 C0 ++#define C4 C2 C2 C2 C2 ++ C4 /* clear c[]--assume BMAX+1 is 16 */ ++ p = b; i = n; ++ do { ++ c[*p++]++; /* assume all entries <= BMAX */ ++ } while (--i); ++ if (c[0] == n) /* null input--all zero length codes */ ++ { ++ *t = (inflate_huft *)Z_NULL; ++ *m = 0; ++ return Z_OK; ++ } ++ ++ ++ /* Find minimum and maximum length, bound *m by those */ ++ l = *m; ++ for (j = 1; j <= BMAX; j++) ++ if (c[j]) ++ break; ++ k = j; /* minimum code length */ ++ if ((uInt)l < j) ++ l = j; ++ for (i = BMAX; i; i--) ++ if (c[i]) ++ break; ++ g = i; /* maximum code length */ ++ if ((uInt)l > i) ++ l = i; ++ *m = l; ++ ++ ++ /* Adjust last length count to fill out codes, if needed */ ++ for (y = 1 << j; j < i; j++, y <<= 1) ++ if ((y -= c[j]) < 0) ++ return Z_DATA_ERROR; ++ if ((y -= c[i]) < 0) ++ return Z_DATA_ERROR; ++ c[i] += y; ++ ++ ++ /* Generate starting offsets into the value table for each length */ ++ x[1] = j = 0; ++ p = c + 1; xp = x + 2; ++ while (--i) { /* note that i == g from above */ ++ *xp++ = (j += *p++); ++ } ++ ++ ++ /* Make a table of values in order of bit lengths */ ++ p = b; i = 0; ++ do { ++ if ((j = *p++) != 0) ++ v[x[j]++] = i; ++ } while (++i < n); ++ ++ ++ /* Generate the Huffman codes and for each, make the table entries */ ++ x[0] = i = 0; /* first Huffman code is zero */ ++ p = v; /* grab values in bit order */ ++ h = -1; /* no tables yet--level -1 */ ++ w = -l; /* bits decoded == (l * h) */ ++ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ ++ q = (inflate_huft *)Z_NULL; /* ditto */ ++ z = 0; /* ditto */ ++ ++ /* go through the bit lengths (k already is bits in shortest code) */ ++ for (; k <= g; k++) ++ { ++ a = c[k]; ++ while (a--) ++ { ++ /* here i is the Huffman code of length k bits for value *p */ ++ /* make tables up to required level */ ++ while (k > w + l) ++ { ++ h++; ++ w += l; /* previous table always l bits */ ++ ++ /* compute minimum size table less than or equal to l bits */ ++ z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ ++ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ ++ { /* too few codes for k-w bit table */ ++ f -= a + 1; /* deduct codes from patterns left */ ++ xp = c + k; ++ if (j < z) ++ while (++j < z) /* try smaller tables up to z bits */ ++ { ++ if ((f <<= 1) <= *++xp) ++ break; /* enough codes to use up j bits */ ++ f -= *xp; /* else deduct codes from patterns */ ++ } ++ } ++ z = 1 << j; /* table entries for j-bit table */ ++ ++ /* allocate and link in new table */ ++ if ((q = (inflate_huft *)ZALLOC ++ (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) ++ { ++ if (h) ++ inflate_trees_free(u[0], zs); ++ return Z_MEM_ERROR; /* not enough memory */ ++ } ++ q->word.Nalloc = z + 1; ++#ifdef DEBUG_ZLIB ++ inflate_hufts += z + 1; ++#endif ++ *t = q + 1; /* link to list for huft_free() */ ++ *(t = &(q->next)) = Z_NULL; ++ u[h] = ++q; /* table starts after link */ ++ ++ /* connect to last table, if there is one */ ++ if (h) ++ { ++ x[h] = i; /* save pattern for backing up */ ++ r.bits = (Byte)l; /* bits to dump before this table */ ++ r.exop = (Byte)j; /* bits in this table */ ++ r.next = q; /* pointer to this table */ ++ j = i >> (w - l); /* (get around Turbo C bug) */ ++ u[h-1][j] = r; /* connect to last table */ ++ } ++ } ++ ++ /* set up table entry in r */ ++ r.bits = (Byte)(k - w); ++ if (p >= v + n) ++ r.exop = 128 + 64; /* out of values--invalid code */ ++ else if (*p < s) ++ { ++ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ ++ r.base = *p++; /* simple code is just the value */ ++ } ++ else ++ { ++ r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ ++ r.base = d[*p++ - s]; ++ } ++ ++ /* fill code-like entries with r */ ++ f = 1 << (k - w); ++ for (j = i >> w; j < z; j += f) ++ q[j] = r; ++ ++ /* backwards increment the k-bit code i */ ++ for (j = 1 << (k - 1); i & j; j >>= 1) ++ i ^= j; ++ i ^= j; ++ ++ /* backup over finished tables */ ++ while ((i & ((1 << w) - 1)) != x[h]) ++ { ++ h--; /* don't need to update q */ ++ w -= l; ++ } ++ } ++ } ++ ++ ++ /* Return Z_BUF_ERROR if we were given an incomplete table */ ++ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; ++} ++ ++ ++local int inflate_trees_bits(c, bb, tb, z) ++uIntf *c; /* 19 code lengths */ ++uIntf *bb; /* bits tree desired/actual depth */ ++inflate_huft * FAR *tb; /* bits tree result */ ++z_stream *z; /* for zfree function */ ++{ ++ int r; ++ ++ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); ++ if (r == Z_DATA_ERROR) ++ z->msg = "oversubscribed dynamic bit lengths tree"; ++ else if (r == Z_BUF_ERROR) ++ { ++ inflate_trees_free(*tb, z); ++ z->msg = "incomplete dynamic bit lengths tree"; ++ r = Z_DATA_ERROR; ++ } ++ return r; ++} ++ ++ ++local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) ++uInt nl; /* number of literal/length codes */ ++uInt nd; /* number of distance codes */ ++uIntf *c; /* that many (total) code lengths */ ++uIntf *bl; /* literal desired/actual bit depth */ ++uIntf *bd; /* distance desired/actual bit depth */ ++inflate_huft * FAR *tl; /* literal/length tree result */ ++inflate_huft * FAR *td; /* distance tree result */ ++z_stream *z; /* for zfree function */ ++{ ++ int r; ++ ++ /* build literal/length tree */ ++ if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) ++ { ++ if (r == Z_DATA_ERROR) ++ z->msg = "oversubscribed literal/length tree"; ++ else if (r == Z_BUF_ERROR) ++ { ++ inflate_trees_free(*tl, z); ++ z->msg = "incomplete literal/length tree"; ++ r = Z_DATA_ERROR; ++ } ++ return r; ++ } ++ ++ /* build distance tree */ ++ if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) ++ { ++ if (r == Z_DATA_ERROR) ++ z->msg = "oversubscribed literal/length tree"; ++ else if (r == Z_BUF_ERROR) { ++#ifdef PKZIP_BUG_WORKAROUND ++ r = Z_OK; ++ } ++#else ++ inflate_trees_free(*td, z); ++ z->msg = "incomplete literal/length tree"; ++ r = Z_DATA_ERROR; ++ } ++ inflate_trees_free(*tl, z); ++ return r; ++#endif ++ } ++ ++ /* done */ ++ return Z_OK; ++} ++ ++ ++/* build fixed tables only once--keep them here */ ++local int fixed_lock = 0; ++local int fixed_built = 0; ++#define FIXEDH 530 /* number of hufts used by fixed tables */ ++local uInt fixed_left = FIXEDH; ++local inflate_huft fixed_mem[FIXEDH]; ++local uInt fixed_bl; ++local uInt fixed_bd; ++local inflate_huft *fixed_tl; ++local inflate_huft *fixed_td; ++ ++ ++local voidpf falloc(q, n, s) ++voidpf q; /* opaque pointer (not used) */ ++uInt n; /* number of items */ ++uInt s; /* size of item */ ++{ ++ Assert(s == sizeof(inflate_huft) && n <= fixed_left, ++ "inflate_trees falloc overflow"); ++ if (q) s++; /* to make some compilers happy */ ++ fixed_left -= n; ++ return (voidpf)(fixed_mem + fixed_left); ++} ++ ++ ++local void ffree(q, p, n) ++voidpf q; ++voidpf p; ++uInt n; ++{ ++ Assert(0, "inflate_trees ffree called!"); ++ if (q) q = p; /* to make some compilers happy */ ++} ++ ++ ++local int inflate_trees_fixed(bl, bd, tl, td) ++uIntf *bl; /* literal desired/actual bit depth */ ++uIntf *bd; /* distance desired/actual bit depth */ ++inflate_huft * FAR *tl; /* literal/length tree result */ ++inflate_huft * FAR *td; /* distance tree result */ ++{ ++ /* build fixed tables if not built already--lock out other instances */ ++ while (++fixed_lock > 1) ++ fixed_lock--; ++ if (!fixed_built) ++ { ++ int k; /* temporary variable */ ++ unsigned c[288]; /* length list for huft_build */ ++ z_stream z; /* for falloc function */ ++ ++ /* set up fake z_stream for memory routines */ ++ z.zalloc = falloc; ++ z.zfree = ffree; ++ z.opaque = Z_NULL; ++ ++ /* literal table */ ++ for (k = 0; k < 144; k++) ++ c[k] = 8; ++ for (; k < 256; k++) ++ c[k] = 9; ++ for (; k < 280; k++) ++ c[k] = 7; ++ for (; k < 288; k++) ++ c[k] = 8; ++ fixed_bl = 7; ++ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); ++ ++ /* distance table */ ++ for (k = 0; k < 30; k++) ++ c[k] = 5; ++ fixed_bd = 5; ++ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); ++ ++ /* done */ ++ fixed_built = 1; ++ } ++ fixed_lock--; ++ *bl = fixed_bl; ++ *bd = fixed_bd; ++ *tl = fixed_tl; ++ *td = fixed_td; ++ return Z_OK; ++} ++ ++ ++local int inflate_trees_free(t, z) ++inflate_huft *t; /* table to free */ ++z_stream *z; /* for zfree function */ ++/* Free the malloc'ed tables built by huft_build(), which makes a linked ++ list of the tables it made, with the links in a dummy first entry of ++ each table. */ ++{ ++ register inflate_huft *p, *q; ++ ++ /* Go through linked list, freeing from the malloced (t[-1]) address. */ ++ p = t; ++ while (p != Z_NULL) ++ { ++ q = (--p)->next; ++ ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); ++ p = q; ++ } ++ return Z_OK; ++} ++ ++/*+++++*/ ++/* infcodes.c -- process literals and length/distance pairs ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* simplify the use of the inflate_huft type with some defines */ ++#define base more.Base ++#define next more.Next ++#define exop word.what.Exop ++#define bits word.what.Bits ++ ++/* inflate codes private state */ ++struct inflate_codes_state { ++ ++ /* mode */ ++ enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ ++ START, /* x: set up for LEN */ ++ LEN, /* i: get length/literal/eob next */ ++ LENEXT, /* i: getting length extra (have base) */ ++ DIST, /* i: get distance next */ ++ DISTEXT, /* i: getting distance extra */ ++ COPY, /* o: copying bytes in window, waiting for space */ ++ LIT, /* o: got literal, waiting for output space */ ++ WASH, /* o: got eob, possibly still output waiting */ ++ END, /* x: got eob and all data flushed */ ++ BADCODE} /* x: got error */ ++ mode; /* current inflate_codes mode */ ++ ++ /* mode dependent information */ ++ uInt len; ++ union { ++ struct { ++ inflate_huft *tree; /* pointer into tree */ ++ uInt need; /* bits needed */ ++ } code; /* if LEN or DIST, where in tree */ ++ uInt lit; /* if LIT, literal */ ++ struct { ++ uInt get; /* bits to get for extra */ ++ uInt dist; /* distance back to copy from */ ++ } copy; /* if EXT or COPY, where and how much */ ++ } sub; /* submode */ ++ ++ /* mode independent information */ ++ Byte lbits; /* ltree bits decoded per branch */ ++ Byte dbits; /* dtree bits decoder per branch */ ++ inflate_huft *ltree; /* literal/length/eob tree */ ++ inflate_huft *dtree; /* distance tree */ ++ ++}; ++ ++ ++local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) ++uInt bl, bd; ++inflate_huft *tl, *td; ++z_stream *z; ++{ ++ inflate_codes_statef *c; ++ ++ if ((c = (inflate_codes_statef *) ++ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) ++ { ++ c->mode = START; ++ c->lbits = (Byte)bl; ++ c->dbits = (Byte)bd; ++ c->ltree = tl; ++ c->dtree = td; ++ Tracev((stderr, "inflate: codes new\n")); ++ } ++ return c; ++} ++ ++ ++local int inflate_codes(s, z, r) ++inflate_blocks_statef *s; ++z_stream *z; ++int r; ++{ ++ uInt j; /* temporary storage */ ++ inflate_huft *t; /* temporary pointer */ ++ uInt e; /* extra bits or operation */ ++ uLong b; /* bit buffer */ ++ uInt k; /* bits in bit buffer */ ++ Bytef *p; /* input data pointer */ ++ uInt n; /* bytes available there */ ++ Bytef *q; /* output window write pointer */ ++ uInt m; /* bytes to end of window or read pointer */ ++ Bytef *f; /* pointer to copy strings from */ ++ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ ++ ++ /* copy input/output information to locals (UPDATE macro restores) */ ++ LOAD ++ ++ /* process input and output based on current state */ ++ while (1) switch (c->mode) ++ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ ++ case START: /* x: set up for LEN */ ++#ifndef SLOW ++ if (m >= 258 && n >= 10) ++ { ++ UPDATE ++ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); ++ LOAD ++ if (r != Z_OK) ++ { ++ c->mode = r == Z_STREAM_END ? WASH : BADCODE; ++ break; ++ } ++ } ++#endif /* !SLOW */ ++ c->sub.code.need = c->lbits; ++ c->sub.code.tree = c->ltree; ++ c->mode = LEN; ++ case LEN: /* i: get length/literal/eob next */ ++ j = c->sub.code.need; ++ NEEDBITS(j) ++ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); ++ DUMPBITS(t->bits) ++ e = (uInt)(t->exop); ++ if (e == 0) /* literal */ ++ { ++ c->sub.lit = t->base; ++ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? ++ "inflate: literal '%c'\n" : ++ "inflate: literal 0x%02x\n", t->base)); ++ c->mode = LIT; ++ break; ++ } ++ if (e & 16) /* length */ ++ { ++ c->sub.copy.get = e & 15; ++ c->len = t->base; ++ c->mode = LENEXT; ++ break; ++ } ++ if ((e & 64) == 0) /* next table */ ++ { ++ c->sub.code.need = e; ++ c->sub.code.tree = t->next; ++ break; ++ } ++ if (e & 32) /* end of block */ ++ { ++ Tracevv((stderr, "inflate: end of block\n")); ++ c->mode = WASH; ++ break; ++ } ++ c->mode = BADCODE; /* invalid code */ ++ z->msg = "invalid literal/length code"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ case LENEXT: /* i: getting length extra (have base) */ ++ j = c->sub.copy.get; ++ NEEDBITS(j) ++ c->len += (uInt)b & inflate_mask[j]; ++ DUMPBITS(j) ++ c->sub.code.need = c->dbits; ++ c->sub.code.tree = c->dtree; ++ Tracevv((stderr, "inflate: length %u\n", c->len)); ++ c->mode = DIST; ++ case DIST: /* i: get distance next */ ++ j = c->sub.code.need; ++ NEEDBITS(j) ++ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); ++ DUMPBITS(t->bits) ++ e = (uInt)(t->exop); ++ if (e & 16) /* distance */ ++ { ++ c->sub.copy.get = e & 15; ++ c->sub.copy.dist = t->base; ++ c->mode = DISTEXT; ++ break; ++ } ++ if ((e & 64) == 0) /* next table */ ++ { ++ c->sub.code.need = e; ++ c->sub.code.tree = t->next; ++ break; ++ } ++ c->mode = BADCODE; /* invalid code */ ++ z->msg = "invalid distance code"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ case DISTEXT: /* i: getting distance extra */ ++ j = c->sub.copy.get; ++ NEEDBITS(j) ++ c->sub.copy.dist += (uInt)b & inflate_mask[j]; ++ DUMPBITS(j) ++ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); ++ c->mode = COPY; ++ case COPY: /* o: copying bytes in window, waiting for space */ ++#ifndef __TURBOC__ /* Turbo C bug for following expression */ ++ f = (uInt)(q - s->window) < c->sub.copy.dist ? ++ s->end - (c->sub.copy.dist - (q - s->window)) : ++ q - c->sub.copy.dist; ++#else ++ f = q - c->sub.copy.dist; ++ if ((uInt)(q - s->window) < c->sub.copy.dist) ++ f = s->end - (c->sub.copy.dist - (q - s->window)); ++#endif ++ while (c->len) ++ { ++ NEEDOUT ++ OUTBYTE(*f++) ++ if (f == s->end) ++ f = s->window; ++ c->len--; ++ } ++ c->mode = START; ++ break; ++ case LIT: /* o: got literal, waiting for output space */ ++ NEEDOUT ++ OUTBYTE(c->sub.lit) ++ c->mode = START; ++ break; ++ case WASH: /* o: got eob, possibly more output */ ++ FLUSH ++ if (s->read != s->write) ++ LEAVE ++ c->mode = END; ++ case END: ++ r = Z_STREAM_END; ++ LEAVE ++ case BADCODE: /* x: got error */ ++ r = Z_DATA_ERROR; ++ LEAVE ++ default: ++ r = Z_STREAM_ERROR; ++ LEAVE ++ } ++} ++ ++ ++local void inflate_codes_free(c, z) ++inflate_codes_statef *c; ++z_stream *z; ++{ ++ ZFREE(z, c, sizeof(struct inflate_codes_state)); ++ Tracev((stderr, "inflate: codes free\n")); ++} ++ ++/*+++++*/ ++/* inflate_util.c -- data and routines common to blocks and codes ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* copy as much as possible from the sliding window to the output area */ ++local int inflate_flush(s, z, r) ++inflate_blocks_statef *s; ++z_stream *z; ++int r; ++{ ++ uInt n; ++ Bytef *p, *q; ++ ++ /* local copies of source and destination pointers */ ++ p = z->next_out; ++ q = s->read; ++ ++ /* compute number of bytes to copy as far as end of window */ ++ n = (uInt)((q <= s->write ? s->write : s->end) - q); ++ if (n > z->avail_out) n = z->avail_out; ++ if (n && r == Z_BUF_ERROR) r = Z_OK; ++ ++ /* update counters */ ++ z->avail_out -= n; ++ z->total_out += n; ++ ++ /* update check information */ ++ if (s->checkfn != Z_NULL) ++ s->check = (*s->checkfn)(s->check, q, n); ++ ++ /* copy as far as end of window */ ++ zmemcpy(p, q, n); ++ p += n; ++ q += n; ++ ++ /* see if more to copy at beginning of window */ ++ if (q == s->end) ++ { ++ /* wrap pointers */ ++ q = s->window; ++ if (s->write == s->end) ++ s->write = s->window; ++ ++ /* compute bytes to copy */ ++ n = (uInt)(s->write - q); ++ if (n > z->avail_out) n = z->avail_out; ++ if (n && r == Z_BUF_ERROR) r = Z_OK; ++ ++ /* update counters */ ++ z->avail_out -= n; ++ z->total_out += n; ++ ++ /* update check information */ ++ if (s->checkfn != Z_NULL) ++ s->check = (*s->checkfn)(s->check, q, n); ++ ++ /* copy */ ++ zmemcpy(p, q, n); ++ p += n; ++ q += n; ++ } ++ ++ /* update pointers */ ++ z->next_out = p; ++ s->read = q; ++ ++ /* done */ ++ return r; ++} ++ ++ ++/*+++++*/ ++/* inffast.c -- process literals and length/distance pairs fast ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* simplify the use of the inflate_huft type with some defines */ ++#define base more.Base ++#define next more.Next ++#define exop word.what.Exop ++#define bits word.what.Bits ++ ++/* macros for bit input with no checking and for returning unused bytes */ ++#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;} ++ ++/* Called with number of bytes left to write in window at least 258 ++ (the maximum string length) and number of input bytes available ++ at least ten. The ten bytes are six bytes for the longest length/ ++ distance pair plus four bytes for overloading the bit buffer. */ ++ ++local int inflate_fast(bl, bd, tl, td, s, z) ++uInt bl, bd; ++inflate_huft *tl, *td; ++inflate_blocks_statef *s; ++z_stream *z; ++{ ++ inflate_huft *t; /* temporary pointer */ ++ uInt e; /* extra bits or operation */ ++ uLong b; /* bit buffer */ ++ uInt k; /* bits in bit buffer */ ++ Bytef *p; /* input data pointer */ ++ uInt n; /* bytes available there */ ++ Bytef *q; /* output window write pointer */ ++ uInt m; /* bytes to end of window or read pointer */ ++ uInt ml; /* mask for literal/length tree */ ++ uInt md; /* mask for distance tree */ ++ uInt c; /* bytes to copy */ ++ uInt d; /* distance back to copy from */ ++ Bytef *r; /* copy source pointer */ ++ ++ /* load input, output, bit values */ ++ LOAD ++ ++ /* initialize masks */ ++ ml = inflate_mask[bl]; ++ md = inflate_mask[bd]; ++ ++ /* do until not enough input or output space for fast loop */ ++ do { /* assume called with m >= 258 && n >= 10 */ ++ /* get literal/length code */ ++ GRABBITS(20) /* max bits for literal/length code */ ++ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) ++ { ++ DUMPBITS(t->bits) ++ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? ++ "inflate: * literal '%c'\n" : ++ "inflate: * literal 0x%02x\n", t->base)); ++ *q++ = (Byte)t->base; ++ m--; ++ continue; ++ } ++ do { ++ DUMPBITS(t->bits) ++ if (e & 16) ++ { ++ /* get extra bits for length */ ++ e &= 15; ++ c = t->base + ((uInt)b & inflate_mask[e]); ++ DUMPBITS(e) ++ Tracevv((stderr, "inflate: * length %u\n", c)); ++ ++ /* decode distance base of block to copy */ ++ GRABBITS(15); /* max bits for distance code */ ++ e = (t = td + ((uInt)b & md))->exop; ++ do { ++ DUMPBITS(t->bits) ++ if (e & 16) ++ { ++ /* get extra bits to add to distance base */ ++ e &= 15; ++ GRABBITS(e) /* get extra bits (up to 13) */ ++ d = t->base + ((uInt)b & inflate_mask[e]); ++ DUMPBITS(e) ++ Tracevv((stderr, "inflate: * distance %u\n", d)); ++ ++ /* do the copy */ ++ m -= c; ++ if ((uInt)(q - s->window) >= d) /* offset before dest */ ++ { /* just copy */ ++ r = q - d; ++ *q++ = *r++; c--; /* minimum count is three, */ ++ *q++ = *r++; c--; /* so unroll loop a little */ ++ } ++ else /* else offset after destination */ ++ { ++ e = d - (q - s->window); /* bytes from offset to end */ ++ r = s->end - e; /* pointer to offset */ ++ if (c > e) /* if source crosses, */ ++ { ++ c -= e; /* copy to end of window */ ++ do { ++ *q++ = *r++; ++ } while (--e); ++ r = s->window; /* copy rest from start of window */ ++ } ++ } ++ do { /* copy all or what's left */ ++ *q++ = *r++; ++ } while (--c); ++ break; ++ } ++ else if ((e & 64) == 0) ++ e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; ++ else ++ { ++ z->msg = "invalid distance code"; ++ UNGRAB ++ UPDATE ++ return Z_DATA_ERROR; ++ } ++ } while (1); ++ break; ++ } ++ if ((e & 64) == 0) ++ { ++ if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) ++ { ++ DUMPBITS(t->bits) ++ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? ++ "inflate: * literal '%c'\n" : ++ "inflate: * literal 0x%02x\n", t->base)); ++ *q++ = (Byte)t->base; ++ m--; ++ break; ++ } ++ } ++ else if (e & 32) ++ { ++ Tracevv((stderr, "inflate: * end of block\n")); ++ UNGRAB ++ UPDATE ++ return Z_STREAM_END; ++ } ++ else ++ { ++ z->msg = "invalid literal/length code"; ++ UNGRAB ++ UPDATE ++ return Z_DATA_ERROR; ++ } ++ } while (1); ++ } while (m >= 258 && n >= 10); ++ ++ /* not enough input or output--restore pointers and return */ ++ UNGRAB ++ UPDATE ++ return Z_OK; ++} ++ ++ ++/*+++++*/ ++/* zutil.c -- target dependent utility functions for the compression library ++ * Copyright (C) 1995 Jean-loup Gailly. ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ ++ ++char *zlib_version = ZLIB_VERSION; ++ ++char *z_errmsg[] = { ++"stream end", /* Z_STREAM_END 1 */ ++"", /* Z_OK 0 */ ++"file error", /* Z_ERRNO (-1) */ ++"stream error", /* Z_STREAM_ERROR (-2) */ ++"data error", /* Z_DATA_ERROR (-3) */ ++"insufficient memory", /* Z_MEM_ERROR (-4) */ ++"buffer error", /* Z_BUF_ERROR (-5) */ ++""}; ++ ++ ++/*+++++*/ ++/* adler32.c -- compute the Adler-32 checksum of a data stream ++ * Copyright (C) 1995 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ ++ ++#define BASE 65521L /* largest prime smaller than 65536 */ ++#define NMAX 5552 ++/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ ++ ++#define DO1(buf) {s1 += *buf++; s2 += s1;} ++#define DO2(buf) DO1(buf); DO1(buf); ++#define DO4(buf) DO2(buf); DO2(buf); ++#define DO8(buf) DO4(buf); DO4(buf); ++#define DO16(buf) DO8(buf); DO8(buf); ++ ++/* ========================================================================= */ ++uLong adler32(adler, buf, len) ++ uLong adler; ++ Bytef *buf; ++ uInt len; ++{ ++ unsigned long s1 = adler & 0xffff; ++ unsigned long s2 = (adler >> 16) & 0xffff; ++ int k; ++ ++ if (buf == Z_NULL) return 1L; ++ ++ while (len > 0) { ++ k = len < NMAX ? len : NMAX; ++ len -= k; ++ while (k >= 16) { ++ DO16(buf); ++ k -= 16; ++ } ++ if (k != 0) do { ++ DO1(buf); ++ } while (--k); ++ s1 %= BASE; ++ s2 %= BASE; ++ } ++ return (s2 << 16) | s1; ++} +diff -Naru linux/arch/mips/zboot/Makefile linux.spi/arch/mips/zboot/Makefile +--- linux/arch/mips/zboot/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,84 @@ ++# ++# arch/mips/zboot/Makefile ++# ++# This file is subject to the terms and conditions of the GNU General Public ++# License. See the file "COPYING" in the main directory of this archive ++# for more details. ++ ++# Adapted for MIPS Pete Popov, Dan Malek ++# ++# Copyright (C) 1994 by Linus Torvalds ++# Adapted for PowerPC by Gary Thomas ++# modified by Cort (cort@cs.nmt.edu) ++# ++ ++.c.s: ++ $(CC) $(CFLAGS) -S -o $*.s $< ++.s.o: ++ $(AS) -o $*.o $< ++.c.o: ++ $(CC) $(CFLAGS) -c -o $*.o $< ++.S.s: ++ $(CPP) $(AFLAGS) -o $*.o $< ++.S.o: ++ $(CC) $(AFLAGS) -c -o $*.o $< ++ ++GZIP_FLAGS = -v9f ++ ++CFLAGS += -D__BOOTER__ -I$(TOPDIR)/arch/$(ARCH)/zboot/include ++AFLAGS += -D__BOOTER__ ++ ++BOOT_TARGETS = zImage zImage.initrd zImage.flash zImage.initrd.flash ++ ++lib/zlib.a: ++ $(MAKE) -C lib ++ ++images/vmlinux.gz: $(TOPDIR)/vmlinux ++ $(MAKE) -C images vmlinux.gz ++ ++$(BOOT_TARGETS): lib/zlib.a images/vmlinux.gz ++ifdef CONFIG_MIPS_PB1000 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_PB1500 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_PB1100 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_PB1550 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_DB1000 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_DB1100 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_DB1500 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_BOSPORUS ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_MIRAGE ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_MIPS_MTX2 ++ $(MAKE) -C pb1xxx $@ ++endif ++ifdef CONFIG_COGENT_CSB250 ++ $(MAKE) -C csb250 $@ ++endif ++ifdef CONFIG_MIPS_XXS1500 ++BOOT_DIR = xxs1500 ++endif ++ ++# Do the dirs ++clean: ++ $(MAKE) -C common clean ++ $(MAKE) -C images clean ++ $(MAKE) -C pb1xxx clean ++ $(MAKE) -C xxs1500 clean ++ ++include $(TOPDIR)/Rules.make +diff -Naru linux/arch/mips/zboot/pb1xxx/head.S linux.spi/arch/mips/zboot/pb1xxx/head.S +--- linux/arch/mips/zboot/pb1xxx/head.S 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/pb1xxx/head.S 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,149 @@ ++/* ++ * arch/mips/kernel/head.S ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 1994, 1995 Waldorf Electronics ++ * Written by Ralf Baechle and Andreas Busse ++ * Copyright (C) 1995 - 1999 Ralf Baechle ++ * Copyright (C) 1996 Paul M. Antoine ++ * Modified for DECStation and hence R3000 support by Paul M. Antoine ++ * Further modifications by David S. Miller and Harald Koerfgen ++ * Copyright (C) 1999 Silicon Graphics, Inc. ++ * ++ * Head.S contains the MIPS exception handler and startup code. ++ * ++ ************************************************************************** ++ * 9 Nov, 2000. ++ * Added Cache Error exception handler and SBDDP EJTAG debug exception. ++ * ++ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. ++ ************************************************************************** ++ */ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define IndexInvalidate_I 0x00 ++#define IndexWriteBack_D 0x01 ++ ++ .set noreorder ++ .cprestore ++ LEAF(start) ++start: ++ bal locate ++ nop ++locate: ++ subu s8, ra, 8 /* Where we were loaded */ ++ la sp, (.stack + 8192) ++ ++ move s0, a0 /* Save boot rom start args */ ++ move s1, a1 ++ move s2, a2 ++ move s3, a3 ++ ++ la a0, start /* Where we were linked to run */ ++ ++ move a1, s8 ++ la a2, _edata ++ subu t1, a2, a0 ++ srl t1, t1, 2 ++ ++ /* copy text section */ ++ li t0, 0 ++1: lw v0, 0(a1) ++ nop ++ sw v0, 0(a0) ++ xor t0, t0, v0 ++ addu a0, 4 ++ bne a2, a0, 1b ++ addu a1, 4 ++ ++ /* Clear BSS */ ++ la a0, _edata ++ la a2, _end ++2: sw zero, 0(a0) ++ bne a2, a0, 2b ++ addu a0, 4 ++ ++ /* push the D-Cache and invalidate I-Cache */ ++ li k0, 0x80000000 # start address ++ li k1, 0x80004000 # end address (16KB I-Cache) ++ subu k1, 128 ++ ++1: ++ .set mips3 ++ cache IndexWriteBack_D, 0(k0) ++ cache IndexWriteBack_D, 32(k0) ++ cache IndexWriteBack_D, 64(k0) ++ cache IndexWriteBack_D, 96(k0) ++ cache IndexInvalidate_I, 0(k0) ++ cache IndexInvalidate_I, 32(k0) ++ cache IndexInvalidate_I, 64(k0) ++ cache IndexInvalidate_I, 96(k0) ++ .set mips0 ++ ++ bne k0, k1, 1b ++ addu k0, k0, 128 ++ /* done */ ++ ++ move a0, s8 /* load address */ ++ move a1, t1 /* length in words */ ++ move a2, t0 /* checksum */ ++ move a3, sp ++ ++ la ra, 1f ++ la k0, decompress_kernel ++ jr k0 ++ nop ++1: ++ ++ move a0, s0 ++ move a1, s1 ++ move a2, s2 ++ move a3, s3 ++ li k0, KERNEL_ENTRY ++ jr k0 ++ nop ++3: ++ b 3b ++ END(start) ++ ++ LEAF(udelay) ++udelay: ++ END(udelay) ++ ++ ++ LEAF(FlushCache) ++ li k0, 0x80000000 # start address ++ li k1, 0x80004000 # end address (16KB I-Cache) ++ subu k1, 128 ++ ++1: ++ .set mips3 ++ cache IndexWriteBack_D, 0(k0) ++ cache IndexWriteBack_D, 32(k0) ++ cache IndexWriteBack_D, 64(k0) ++ cache IndexWriteBack_D, 96(k0) ++ cache IndexInvalidate_I, 0(k0) ++ cache IndexInvalidate_I, 32(k0) ++ cache IndexInvalidate_I, 64(k0) ++ cache IndexInvalidate_I, 96(k0) ++ .set mips0 ++ ++ bne k0, k1, 1b ++ addu k0, k0, 128 ++ jr ra ++ nop ++ END(FlushCache) ++ ++ .comm .stack,4096*2,4 +diff -Naru linux/arch/mips/zboot/pb1xxx/Makefile linux.spi/arch/mips/zboot/pb1xxx/Makefile +--- linux/arch/mips/zboot/pb1xxx/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/pb1xxx/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,135 @@ ++# arch/mips/zboot/pb1xxx/Makefile ++# ++# Makefile for Alchemy Semiconductor Pb1[015]00 boards. ++# All of the boot loader code was derived from the ppc ++# boot code. ++# ++# Copyright 2001,2002 MontaVista Software Inc. ++# ++# Author: Mark A. Greer ++# mgreer@mvista.com ++# Ported and modified for mips support by ++# Pete Popov ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation; either version 2 of the License, or (at your ++# option) any later version. ++ ++.c.s: ++ $(CC) $(CFLAGS) -S -o $*.s $< ++.s.o: ++ $(AS) -o $*.o $< ++.c.o: ++ $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $< ++.S.s: ++ $(CPP) $(AFLAGS) -o $*.o $< ++.S.o: ++ $(CC) $(AFLAGS) -c -o $*.o $< ++ ++######################################################################### ++# START BOARD SPECIFIC VARIABLES ++ifdef CONFIG_MIPS_PB1000 ++BNAME=pb1000 ++endif ++ ++ifdef CONFIG_MIPS_PB1100 ++BNAME=pb1100 ++endif ++ ++ifdef CONFIG_MIPS_PB1500 ++BNAME=pb1500 ++endif ++ ++ifdef CONFIG_MIPS_PB1550 ++BNAME=pb1550 ++endif ++ ++ifdef CONFIG_MIPS_DB1000 ++BNAME=db1000 ++endif ++ ++ifdef CONFIG_MIPS_DB1100 ++BNAME=db1100 ++endif ++ ++ifdef CONFIG_MIPS_DB1500 ++BNAME=db1500 ++endif ++ ++ifdef CONFIG_MIPS_BOSPORUS ++BNAME=bosporus ++endif ++ ++ifdef CONFIG_MIPS_MIRAGE ++BNAME=mirage ++endif ++ ++ifdef CONFIG_MIPS_MTX2 ++BNAME=mtx-2 ++endif ++ ++# These two variables control where the zImage is stored ++# in flash and loaded in memory. It only controls how the srec ++# file is generated, the code is the same. ++RAM_RUN_ADDR = 0x81000000 ++FLASH_LOAD_ADDR = 0xBFD00000 ++ ++# These two variables specify the free ram region ++# that can be used for temporary malloc area ++AVAIL_RAM_START=0x80400000 ++AVAIL_RAM_END=0x80800000 ++ ++# This one must match the LOADADDR in arch/mips/Makefile! ++LOADADDR=0x80100000 ++# END BOARD SPECIFIC VARIABLES ++######################################################################### ++ ++OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \ ++ ../common/au1k_uart.o ../common/string.o ../common/ctype.o ++LIBS := ../lib/zlib.a ++ ++ENTRY := ../utils/entry ++OFFSET := ../utils/offset ++SIZE := ../utils/size ++ ++LD_ARGS := -T ../ld.script -Ttext $(RAM_RUN_ADDR) -Bstatic ++OBJCOPY_ARGS = -O elf32-tradlittlemips ++ ++all: zImage ++ ++clean: ++ rm -rf *.o vmlinux* zvmlinux.* ../images/*.srec ++ ++head.o: head.S $(TOPDIR)/vmlinux ++ $(CC) $(AFLAGS) \ ++ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) \ ++ -c -o $*.o $< ++ ++../common/misc-simple.o: ++ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ ++ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \ ++ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \ ++ -DLOADADDR=$(LOADADDR) \ ++ -DZIMAGE_SIZE=0 -c -o $@ $*.c ++ ++zvmlinux: $(OBJECTS) $(LIBS) ../ld.script ../images/vmlinux.gz ../common/dummy.o ++ $(OBJCOPY) \ ++ --add-section=.image=../images/vmlinux.gz \ ++ --set-section-flags=.image=contents,alloc,load,readonly,data \ ++ ../common/dummy.o image.o ++ $(LD) $(LD_ARGS) -o $@ $(OBJECTS) image.o $(LIBS) ++ $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr \ ++ -R .initrd -R .sysmap ++ ++# Here we manipulate the image in order to get it the necessary ++# srecord file we need. ++zImage: zvmlinux ++ mv zvmlinux ../images/zImage.$(BNAME) ++ $(OBJCOPY) -O srec ../images/zImage.$(BNAME) ../images/$(BNAME).srec ++ ++zImage.flash: zImage ++ $(OBJCOPY) -O srec --adjust-vma 0x3ed00000 \ ++ ../images/zImage.$(BNAME) ../images/$(BNAME).flash.srec ++ ++include $(TOPDIR)/Rules.make +diff -Naru linux/arch/mips/zboot/utils/entry linux.spi/arch/mips/zboot/utils/entry +--- linux/arch/mips/zboot/utils/entry 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/utils/entry 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,12 @@ ++#!/bin/sh ++ ++# grab the kernel_entry address from the vmlinux elf image ++entry=`$1 $2 | grep kernel_entry` ++ ++fs=`echo $entry | grep ffffffff` # check toolchain output ++ ++if [ -n "$fs" ]; then ++ echo "0x"`$1 $2 | grep kernel_entry | cut -c9- | awk '{print $1}'` ++else ++ echo "0x"`$1 $2 | grep kernel_entry | cut -c1- | awk '{print $1}'` ++fi +diff -Naru linux/arch/mips/zboot/utils/offset linux.spi/arch/mips/zboot/utils/offset +--- linux/arch/mips/zboot/utils/offset 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/utils/offset 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,3 @@ ++#!/bin/sh ++ ++echo "0x"`$1 -h $2 | grep $3 | grep -v zvmlinux| awk '{print $6}'` +diff -Naru linux/arch/mips/zboot/utils/size linux.spi/arch/mips/zboot/utils/size +--- linux/arch/mips/zboot/utils/size 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/utils/size 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,4 @@ ++#!/bin/sh ++ ++OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $3}'` ++echo "0x"$OFFSET +diff -Naru linux/arch/mips/zboot/xxs1500/head.S linux.spi/arch/mips/zboot/xxs1500/head.S +--- linux/arch/mips/zboot/xxs1500/head.S 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/xxs1500/head.S 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,137 @@ ++/* ++ * arch/mips/kernel/head.S ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 1994, 1995 Waldorf Electronics ++ * Written by Ralf Baechle and Andreas Busse ++ * Copyright (C) 1995 - 1999 Ralf Baechle ++ * Copyright (C) 1996 Paul M. Antoine ++ * Modified for DECStation and hence R3000 support by Paul M. Antoine ++ * Further modifications by David S. Miller and Harald Koerfgen ++ * Copyright (C) 1999 Silicon Graphics, Inc. ++ * ++ * Head.S contains the MIPS exception handler and startup code. ++ * ++ ************************************************************************** ++ * 9 Nov, 2000. ++ * Added Cache Error exception handler and SBDDP EJTAG debug exception. ++ * ++ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. ++ ************************************************************************** ++ */ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define IndexInvalidate_I 0x00 ++ ++ .set noreorder ++ .cprestore ++ LEAF(start) ++start: ++ ++locate: ++ la sp, .stack ++ move s0, a0 ++ move s1, a1 ++ move s2, a2 ++ move s3, a3 ++ ++ la a0, start ++ ++ li a1, FLASH_LOAD_ADDR ++ la a2, _edata ++ subu t1, a2, a0 ++ srl t1, t1, 2 ++ ++ /* copy text section */ ++ li t0, 0 ++1: lw v0, 0(a1) ++ nop ++ sw v0, 0(a0) ++ xor t0, t0, v0 ++ addu a0, 4 ++ bne a2, a0, 1b ++ addu a1, 4 ++ ++ /* Clear BSS */ ++ la a0, _edata ++ la a2, _end ++2: sw zero, 0(a0) ++ bne a2, a0, 2b ++ addu a0, 4 ++ ++ /* flush the I-Cache */ ++ li k0, 0x80000000 # start address ++ li k1, 0x80004000 # end address (16KB I-Cache) ++ subu k1, 128 ++ ++1: ++ .set mips3 ++ cache IndexInvalidate_I, 0(k0) ++ cache IndexInvalidate_I, 32(k0) ++ cache IndexInvalidate_I, 64(k0) ++ cache IndexInvalidate_I, 96(k0) ++ .set mips0 ++ ++ bne k0, k1, 1b ++ addu k0, k0, 128 ++ /* done */ ++ ++ li a0, FLASH_LOAD_ADDR /* load address */ ++ move a1, t1 /* length in words */ ++ move a2, t0 /* checksum */ ++ move a3, sp ++ ++ la ra, 1f ++ la k0, decompress_kernel ++ jr k0 ++ nop ++1: ++ ++ move a0, s0 ++ move a1, s1 ++ move a2, s2 ++ move a3, s3 ++ li k0, KERNEL_ENTRY ++ jr k0 ++ nop ++3: ++ b 3b ++ END(start) ++ ++ LEAF(udelay) ++udelay: ++ END(udelay) ++ ++ ++ LEAF(FlushCache) ++ li k0, 0x80000000 # start address ++ li k1, 0x80004000 # end address (16KB I-Cache) ++ subu k1, 128 ++ ++1: ++ .set mips3 ++ cache IndexInvalidate_I, 0(k0) ++ cache IndexInvalidate_I, 32(k0) ++ cache IndexInvalidate_I, 64(k0) ++ cache IndexInvalidate_I, 96(k0) ++ .set mips0 ++ ++ bne k0, k1, 1b ++ addu k0, k0, 128 ++ jr ra ++ nop ++ END(FlushCache) ++ ++ .comm .stack,4096*2,4 +diff -Naru linux/arch/mips/zboot/xxs1500/ld.script linux.spi/arch/mips/zboot/xxs1500/ld.script +--- linux/arch/mips/zboot/xxs1500/ld.script 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/xxs1500/ld.script 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,147 @@ ++OUTPUT_ARCH(mips) ++ENTRY(start) ++SECTIONS ++{ ++ /* Read-only sections, merged into text segment: */ ++ /* . = 0x81000000; */ ++ .init : { *(.init) } =0 ++ .text : ++ { ++ _ftext = . ; ++ *(.text) ++ *(.rodata) ++ *(.rodata1) ++ /* .gnu.warning sections are handled specially by elf32.em. */ ++ *(.gnu.warning) ++ } =0 ++ .kstrtab : { *(.kstrtab) } ++ ++ . = ALIGN(16); /* Exception table */ ++ __start___ex_table = .; ++ __ex_table : { *(__ex_table) } ++ __stop___ex_table = .; ++ ++ __start___dbe_table = .; /* Exception table for data bus errors */ ++ __dbe_table : { *(__dbe_table) } ++ __stop___dbe_table = .; ++ ++ __start___ksymtab = .; /* Kernel symbol table */ ++ __ksymtab : { *(__ksymtab) } ++ __stop___ksymtab = .; ++ ++ _etext = .; ++ ++ . = ALIGN(8192); ++ .data.init_task : { *(.data.init_task) } ++ ++ /* Startup code */ ++ . = ALIGN(4096); ++ __init_begin = .; ++ .text.init : { *(.text.init) } ++ .data.init : { *(.data.init) } ++ . = ALIGN(16); ++ __setup_start = .; ++ .setup.init : { *(.setup.init) } ++ __setup_end = .; ++ __initcall_start = .; ++ .initcall.init : { *(.initcall.init) } ++ __initcall_end = .; ++ . = ALIGN(4096); /* Align double page for init_task_union */ ++ __init_end = .; ++ ++ . = ALIGN(4096); ++ .data.page_aligned : { *(.data.idt) } ++ ++ . = ALIGN(32); ++ .data.cacheline_aligned : { *(.data.cacheline_aligned) } ++ ++ .fini : { *(.fini) } =0 ++ .reginfo : { *(.reginfo) } ++ /* Adjust the address for the data segment. We want to adjust up to ++ the same address within the page on the next page up. It would ++ be more correct to do this: ++ . = .; ++ The current expression does not correctly handle the case of a ++ text segment ending precisely at the end of a page; it causes the ++ data segment to skip a page. The above expression does not have ++ this problem, but it will currently (2/95) cause BFD to allocate ++ a single segment, combining both text and data, for this case. ++ This will prevent the text segment from being shared among ++ multiple executions of the program; I think that is more ++ important than losing a page of the virtual address space (note ++ that no actual memory is lost; the page which is skipped can not ++ be referenced). */ ++ . = .; ++ .data : ++ { ++ _fdata = . ; ++ *(.data) ++ ++ /* Align the initial ramdisk image (INITRD) on page boundaries. */ ++ . = ALIGN(4096); ++ __rd_start = .; ++ *(.initrd) ++ __rd_end = .; ++ . = ALIGN(4096); ++ ++ CONSTRUCTORS ++ } ++ .data1 : { *(.data1) } ++ _gp = . + 0x8000; ++ .lit8 : { *(.lit8) } ++ .lit4 : { *(.lit4) } ++ .ctors : { *(.ctors) } ++ .dtors : { *(.dtors) } ++ .got : { *(.got.plt) *(.got) } ++ .dynamic : { *(.dynamic) } ++ /* We want the small data sections together, so single-instruction offsets ++ can access them all, and initialized data all before uninitialized, so ++ we can shorten the on-disk segment size. */ ++ .sdata : { *(.sdata) } ++ . = ALIGN(4); ++ _edata = .; ++ PROVIDE (edata = .); ++ ++ __bss_start = .; ++ _fbss = .; ++ .sbss : { *(.sbss) *(.scommon) } ++ .bss : ++ { ++ *(.dynbss) ++ *(.bss) ++ *(COMMON) ++ . = ALIGN(4); ++ _end = . ; ++ PROVIDE (end = .); ++ } ++ ++ /* Sections to be discarded */ ++ /DISCARD/ : ++ { ++ *(.text.exit) ++ *(.data.exit) ++ *(.exitcall.exit) ++ } ++ ++ /* This is the MIPS specific mdebug section. */ ++ .mdebug : { *(.mdebug) } ++ /* These are needed for ELF backends which have not yet been ++ converted to the new style linker. */ ++ .stab 0 : { *(.stab) } ++ .stabstr 0 : { *(.stabstr) } ++ /* DWARF debug sections. ++ Symbols in the .debug DWARF section are relative to the beginning of the ++ section so we begin .debug at 0. It's not clear yet what needs to happen ++ for the others. */ ++ .debug 0 : { *(.debug) } ++ .debug_srcinfo 0 : { *(.debug_srcinfo) } ++ .debug_aranges 0 : { *(.debug_aranges) } ++ .debug_pubnames 0 : { *(.debug_pubnames) } ++ .debug_sfnames 0 : { *(.debug_sfnames) } ++ .line 0 : { *(.line) } ++ /* These must appear regardless of . */ ++ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } ++ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } ++ .comment : { *(.comment) } ++ .note : { *(.note) } ++} +diff -Naru linux/arch/mips/zboot/xxs1500/Makefile linux.spi/arch/mips/zboot/xxs1500/Makefile +--- linux/arch/mips/zboot/xxs1500/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ linux.spi/arch/mips/zboot/xxs1500/Makefile 2004-05-11 23:19:24.000000000 -0400 +@@ -0,0 +1,123 @@ ++# arch/mips/compressed/alchemy/Makefile ++# ++# Makefile for Alchemy Semiconductor Pb1[015]00 boards. ++# All of the boot loader code was derived from the ppc ++# boot code. ++# ++# Copyright 2001,2002 MontaVista Software Inc. ++# ++# Author: Mark A. Greer ++# mgreer@mvista.com ++# Ported and modified for mips support by ++# Pete Popov ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation; either version 2 of the License, or (at your ++# option) any later version. ++ ++.c.s: ++ $(CC) $(CFLAGS) -S -o $*.s $< ++.s.o: ++ $(AS) -o $*.o $< ++.c.o: ++ $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $< ++.S.s: ++ $(CPP) $(AFLAGS) -o $*.o $< ++.S.o: ++ $(CC) $(AFLAGS) -c -o $*.o $< ++ ++######################################################################### ++# START BOARD SPECIFIC VARIABLES ++BNAME=xxs1500 ++ ++ ++# These two variables control where the zImage is stored ++# in flash and loaded in memory. If you change either one, ++# be sure to make the appropriate change to the zImage ++# rule. ++RAM_LOAD_ADDR = 0x81000000 ++FLASH_LOAD_ADDR = 0xBF000000 ++ ++# These two variables specify the free ram region ++# that can be used for temporary malloc area ++AVAIL_RAM_START=0x80400000 ++AVAIL_RAM_END=0x80800000 ++ ++# This one must match the LOADADDR in arch/mips/Makefile! ++LOADADDR=0x80100000 ++# END BOARD SPECIFIC VARIABLES ++######################################################################### ++ ++ZLINKFLAGS = -T ld.script -Ttext $(RAM_LOAD_ADDR) ++ ++OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \ ++ ../common/au1k_uart.o ../common/string.o ../common/ctype.o ++LIBS := ../lib/zlib.a ++ ++ENTRY := ../utils/entry ++OFFSET := ../utils/offset ++SIZE := ../utils/size ++ ++all: zImage ++ ++clean: ++ rm -rf *.o vmlinux* zvmlinux.* ++ ++head.o: head.S $(TOPDIR)/vmlinux ++ $(CC) -DFLASH_LOAD_ADDR=$(FLASH_LOAD_ADDR) $(AFLAGS) \ ++ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) \ ++ -c -o $*.o $< ++ ++../common/misc-simple.o: ++ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ ++ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \ ++ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \ ++ -DLOADADDR=$(LOADADDR) \ ++ -DZIMAGE_SIZE=0 -c -o $@ $*.c ++ ++# This is the first pass at building the boot loader image, ++# without knowing the file offset where the vmlinuz.gz ++# kernel will end up. We build this image, check the offset, ++# and then rebuild it with the correct offset and size ++# passed to mips-simple.c ++zvmlinux.no: $(OBJECTS) $(LIBS) ../images/vmlinux.gz ++ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) ++ $(OBJCOPY) -R .comment \ ++ --add-section=image=../images/vmlinux.gz \ ++ $@.tmp $@ ++ # rm -f $@.tmp ++ ++ ++# This is the final image we build, now that we know what ++# the vmlinuz.gz offset is. ++zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz zvmlinux.no ++ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ ++ -DZIMAGE_OFFSET=$(shell sh $(OFFSET) $(OBJDUMP) $@.no image) \ ++ -DZIMAGE_SIZE=$(shell sh $(SIZE) $(OBJDUMP) $@.no image) \ ++ -D__BOOTER__ \ ++ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \ ++ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \ ++ -DLOADADDR=$(LOADADDR) \ ++ -c -o ../common/misc-simple.o ../common/misc-simple.c ++ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) ++ $(OBJCOPY) -R .comment \ ++ --add-section=image=../images/vmlinux.gz \ ++ $@.tmp $@ ++ $(OBJCOPY) --adjust-section-vma=image+$(RAM_LOAD_ADDR) $@ ++ $(OBJCOPY) --adjust-section-vma=image+$(shell sh $(OFFSET) \ ++ $(OBJDUMP) $@.no image ) $@ ++ # rm -f $@.tmp ++ # rm -f $@.no ++ ++ ++# Here we manipulate the image in order to get it the necessary ++# srecord file we need. ++zImage: zvmlinux ++ mv zvmlinux ../images/$@.$(BNAME) ++ $(OBJCOPY) --set-section-flags=image=alloc,load,code ../images/$@.$(BNAME) ++ $(OBJCOPY) -O srec --adjust-vma 0x3e000000 \ ++ ../images/$@.$(BNAME) ../images/$@.$(BNAME).srec ++ # rm ../images/vmlinux.gz ++ ++include $(TOPDIR)/Rules.make diff --git a/packages/linux/linux-mtx-2-2.4.27/07-zboot-zimage-flash-bin.diff b/packages/linux/linux-mtx-2-2.4.27/07-zboot-zimage-flash-bin.diff new file mode 100644 index 0000000000..97cb57630b --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/07-zboot-zimage-flash-bin.diff @@ -0,0 +1,11 @@ +diff -Nurb oe/tmp/work/linux-mtx-2-2.4.27-r0/linux/arch/mips/zboot/pb1xxx/Makefile linux.m/arch/mips/zboot/pb1xxx/Makefile +--- linux-old/arch/mips/zboot/pb1xxx/Makefile 2004-10-13 21:08:49.840408328 +0200 ++++ linux/arch/mips/zboot/pb1xxx/Makefile 2004-10-13 21:08:29.736464592 +0200 +@@ -131,5 +131,7 @@ + zImage.flash: zImage + $(OBJCOPY) -O srec --adjust-vma 0x3ed00000 \ + ../images/zImage.$(BNAME) ../images/$(BNAME).flash.srec ++ $(OBJCOPY) -O binary --adjust-vma 0x3ed00000 \ ++ ../images/zImage.$(BNAME) ../images/$(BNAME).flash.bin + + include $(TOPDIR)/Rules.make diff --git a/packages/linux/linux-mtx-2-2.4.27/08-usb-nonpci-2.4.24.patch b/packages/linux/linux-mtx-2-2.4.27/08-usb-nonpci-2.4.24.patch new file mode 100644 index 0000000000..ca093e1a67 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/08-usb-nonpci-2.4.24.patch @@ -0,0 +1,3185 @@ +diff -Nurb linux-mips-2.4.27/drivers/usb/host/Config.in linux/drivers/usb/host/Config.in +--- linux-mips-2.4.27/drivers/usb/host/Config.in 2003-11-17 02:07:42.000000000 +0100 ++++ linux/drivers/usb/host/Config.in 2004-11-23 11:24:10.599627448 +0100 +@@ -17,3 +17,4 @@ + dep_tristate ' SL811HS Alternate (x86, StrongARM, isosynchronous mode)' CONFIG_USB_SL811HS_ALT $CONFIG_USB $CONFIG_EXPERIMENTAL + dep_tristate ' SL811HS (x86, StrongARM) support, old driver' CONFIG_USB_SL811HS $CONFIG_USB $CONFIG_EXPERIMENTAL + fi ++dep_tristate ' Non-PCI OHCI support' CONFIG_USB_NON_PCI_OHCI $CONFIG_USB_OHCI +diff -Nurb linux-mips-2.4.27/drivers/usb/host/usb-ohci.c linux/drivers/usb/host/usb-ohci.c +--- linux-mips-2.4.27/drivers/usb/host/usb-ohci.c 2004-04-16 05:14:18.000000000 +0200 ++++ linux/drivers/usb/host/usb-ohci.c 2004-11-23 11:24:10.602626992 +0100 +@@ -2564,6 +2564,7 @@ + hc_release_ohci (ohci); + return ret; + } ++#ifndef CONFIG_USB_NON_PCI_OHCI + ohci->flags = id->driver_data; + + /* Check for NSC87560. We have to look at the bridge (fn1) to identify +@@ -2582,6 +2583,7 @@ + printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n"); + if (ohci->flags & OHCI_QUIRK_AMD756) + printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n"); ++#endif + + if (hc_reset (ohci) < 0) { + hc_release_ohci (ohci); +@@ -2627,8 +2629,10 @@ + int temp; + int i; + ++#ifndef CONFIG_USB_NON_PCI_OHCI + if (ohci->pci_latency) + pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, ohci->pci_latency); ++#endif + + ohci->disabled = 1; + ohci->sleeping = 0; +@@ -2658,6 +2662,7 @@ + + /*-------------------------------------------------------------------------*/ + ++#ifndef CONFIG_USB_NON_PCI_OHCI + /* configured so that an OHCI device is always provided */ + /* always called with process context; sleeping is OK */ + +@@ -2705,6 +2710,88 @@ + } + return status; + } ++#else /* CONFIG_USB_NON_PCI_OHCI */ ++ ++// Boot options ++static int ohci_base=0, ohci_len=0; ++static int ohci_irq=-1; ++ ++MODULE_PARM(ohci_base, "i"); ++MODULE_PARM(ohci_len, "i"); ++MODULE_PARM(ohci_irq, "i"); ++MODULE_PARM_DESC(ohci_base, "IO Base address of OHCI Oper. registers"); ++MODULE_PARM_DESC(ohci_len, "IO length of OHCI Oper. registers"); ++MODULE_PARM_DESC(ohci_irq, "IRQ for OHCI interrupts"); ++ ++// bogus pci_dev ++static struct pci_dev bogus_pcidev; ++ ++static struct pci_driver ohci_pci_driver = { ++ name: "usb-ohci", ++}; ++ ++static int __devinit ++ohci_non_pci_init (void) ++{ ++ void *mem_base; ++ ++ if (!ohci_base || !ohci_len || (ohci_irq < 0)) ++ return -ENODEV; ++ ++ if (!request_mem_region (ohci_base, ohci_len, ohci_pci_driver.name)) { ++ dbg ("controller already in use"); ++ return -EBUSY; ++ } ++ ++ mem_base = ioremap_nocache (ohci_base, ohci_len); ++ if (!mem_base) { ++ err("Error mapping OHCI memory"); ++ return -EFAULT; ++ } ++ ++ /* ++ * Fill in the bogus pci_dev. Only those members actually ++ * dereferenced in this driver are initialized. ++ */ ++ memset(&bogus_pcidev, 0, sizeof(struct pci_dev)); ++ strcpy(bogus_pcidev.name, "non-PCI OHCI"); ++ strcpy(bogus_pcidev.slot_name, "builtin"); ++ bogus_pcidev.resource[0].name = "OHCI Operational Registers"; ++ bogus_pcidev.resource[0].start = ohci_base; ++ bogus_pcidev.resource[0].end = ohci_base + ohci_len; ++ bogus_pcidev.resource[0].flags = 0; ++ bogus_pcidev.irq = ohci_irq; ++ ++ return hc_found_ohci (&bogus_pcidev, bogus_pcidev.irq, mem_base, NULL); ++} ++ ++#ifndef MODULE ++ ++static int __init ++ohci_setup (char* options) ++{ ++ char* this_opt; ++ ++ if (!options || !*options) ++ return 0; ++ ++ for(this_opt=strtok(options,",");this_opt;this_opt=strtok(NULL,",")) { ++ if (!strncmp(this_opt, "base:", 5)) { ++ ohci_base = simple_strtoul(this_opt+5, NULL, 0); ++ } else if (!strncmp(this_opt, "len:", 4)) { ++ ohci_len = simple_strtoul(this_opt+4, NULL, 0); ++ } else if (!strncmp(this_opt, "irq:", 4)) { ++ ohci_irq = simple_strtoul(this_opt+4, NULL, 0); ++ } ++ } ++ return 0; ++} ++ ++__setup("usb_ohci=", ohci_setup); ++ ++#endif /* !MODULE */ ++ ++#endif /* CONFIG_USB_NON_PCI_OHCI */ + + /*-------------------------------------------------------------------------*/ + +@@ -2745,6 +2832,7 @@ + } + + ++#ifndef CONFIG_USB_NON_PCI_OHCI + #ifdef CONFIG_PM + + /*-------------------------------------------------------------------------*/ +@@ -2983,20 +3071,29 @@ + resume: ohci_pci_resume, + #endif /* PM */ + }; ++#endif /* CONFIG_USB_NON_PCI_OHCI */ + + + /*-------------------------------------------------------------------------*/ + + static int __init ohci_hcd_init (void) + { ++#ifndef CONFIG_USB_NON_PCI_OHCI + return pci_module_init (&ohci_pci_driver); ++#else ++ return ohci_non_pci_init(); ++#endif + } + + /*-------------------------------------------------------------------------*/ + + static void __exit ohci_hcd_cleanup (void) + { ++#ifndef CONFIG_USB_NON_PCI_OHCI + pci_unregister_driver (&ohci_pci_driver); ++#else ++ ohci_pci_remove(&bogus_pcidev); ++#endif + } + + module_init (ohci_hcd_init); +diff -Nurb linux-mips-2.4.27/drivers/usb/host/usb-ohci.c.orig linux/drivers/usb/host/usb-ohci.c.orig +--- linux-mips-2.4.27/drivers/usb/host/usb-ohci.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/usb/host/usb-ohci.c.orig 2004-11-23 11:21:54.984244120 +0100 +@@ -0,0 +1,3008 @@ ++/* ++ * URB OHCI HCD (Host Controller Driver) for USB. ++ * ++ * (C) Copyright 1999 Roman Weissgaerber ++ * (C) Copyright 2000-2001 David Brownell ++ * ++ * [ Initialisation is based on Linus' ] ++ * [ uhci code and gregs ohci fragments ] ++ * [ (C) Copyright 1999 Linus Torvalds ] ++ * [ (C) Copyright 1999 Gregory P. Smith] ++ * ++ * ++ * History: ++ * ++ * 2002/10/22 OHCI_USB_OPER for ALi lockup in IBM i1200 (ALEX ) ++ * 2002/03/08 interrupt unlink fix (Matt Hughes), better cleanup on ++ * load failure (Matthew Frederickson) ++ * 2002/01/20 async unlink fixes: return -EINPROGRESS (per spec) and ++ * make interrupt unlink-in-completion work (db) ++ * 2001/09/19 USB_ZERO_PACKET support (Jean Tourrilhes) ++ * 2001/07/17 power management and pmac cleanup (Benjamin Herrenschmidt) ++ * 2001/03/24 td/ed hashing to remove bus_to_virt (Steve Longerbeam); ++ pci_map_single (db) ++ * 2001/03/21 td and dev/ed allocation uses new pci_pool API (db) ++ * 2001/03/07 hcca allocation uses pci_alloc_consistent (Steve Longerbeam) ++ * ++ * 2000/09/26 fixed races in removing the private portion of the urb ++ * 2000/09/07 disable bulk and control lists when unlinking the last ++ * endpoint descriptor in order to avoid unrecoverable errors on ++ * the Lucent chips. (rwc@sgi) ++ * 2000/08/29 use bandwidth claiming hooks (thanks Randy!), fix some ++ * urb unlink probs, indentation fixes ++ * 2000/08/11 various oops fixes mostly affecting iso and cleanup from ++ * device unplugs. ++ * 2000/06/28 use PCI hotplug framework, for better power management ++ * and for Cardbus support (David Brownell) ++ * 2000/earlier: fixes for NEC/Lucent chips; suspend/resume handling ++ * when the controller loses power; handle UE; cleanup; ... ++ * ++ * v5.2 1999/12/07 URB 3rd preview, ++ * v5.1 1999/11/30 URB 2nd preview, cpia, (usb-scsi) ++ * v5.0 1999/11/22 URB Technical preview, Paul Mackerras powerbook susp/resume ++ * i386: HUB, Keyboard, Mouse, Printer ++ * ++ * v4.3 1999/10/27 multiple HCs, bulk_request ++ * v4.2 1999/09/05 ISO API alpha, new dev alloc, neg Error-codes ++ * v4.1 1999/08/27 Randy Dunlap's - ISO API first impl. ++ * v4.0 1999/08/18 ++ * v3.0 1999/06/25 ++ * v2.1 1999/05/09 code clean up ++ * v2.0 1999/05/04 ++ * v1.0 1999/04/27 initial release ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* for in_interrupt() */ ++#undef DEBUG ++#include ++ ++#include ++#include ++#include ++#include ++ ++#define OHCI_USE_NPS // force NoPowerSwitching mode ++// #define OHCI_VERBOSE_DEBUG /* not always helpful */ ++ ++#include "usb-ohci.h" ++ ++#include "../hcd.h" ++ ++#ifdef CONFIG_PMAC_PBOOK ++#include ++#include ++#include ++#ifndef CONFIG_PM ++#define CONFIG_PM ++#endif ++#endif ++ ++ ++/* ++ * Version Information ++ */ ++#define DRIVER_VERSION "v5.3" ++#define DRIVER_AUTHOR "Roman Weissgaerber , David Brownell" ++#define DRIVER_DESC "USB OHCI Host Controller Driver" ++ ++/* For initializing controller (mask in an HCFS mode too) */ ++#define OHCI_CONTROL_INIT \ ++ (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE ++ ++#define OHCI_UNLINK_TIMEOUT (HZ / 10) ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* AMD-756 (D2 rev) reports corrupt register contents in some cases. ++ * The erratum (#4) description is incorrect. AMD's workaround waits ++ * till some bits (mostly reserved) are clear; ok for all revs. ++ */ ++#define read_roothub(hc, register, mask) ({ \ ++ u32 temp = readl (&hc->regs->roothub.register); \ ++ if (hc->flags & OHCI_QUIRK_AMD756) \ ++ while (temp & mask) \ ++ temp = readl (&hc->regs->roothub.register); \ ++ temp; }) ++ ++static u32 roothub_a (struct ohci *hc) ++ { return read_roothub (hc, a, 0xfc0fe000); } ++static inline u32 roothub_b (struct ohci *hc) ++ { return readl (&hc->regs->roothub.b); } ++static inline u32 roothub_status (struct ohci *hc) ++ { return readl (&hc->regs->roothub.status); } ++static u32 roothub_portstatus (struct ohci *hc, int i) ++ { return read_roothub (hc, portstatus [i], 0xffe0fce0); } ++ ++ ++/*-------------------------------------------------------------------------* ++ * URB support functions ++ *-------------------------------------------------------------------------*/ ++ ++static void ohci_complete_add(struct ohci *ohci, struct urb *urb) ++{ ++ ++ if (urb->hcpriv != NULL) { ++ printk("completing with non-null priv!\n"); ++ return; ++ } ++ ++ if (ohci->complete_tail == NULL) { ++ ohci->complete_head = urb; ++ ohci->complete_tail = urb; ++ } else { ++ ohci->complete_head->hcpriv = urb; ++ ohci->complete_tail = urb; ++ } ++} ++ ++static inline struct urb *ohci_complete_get(struct ohci *ohci) ++{ ++ struct urb *urb; ++ ++ if ((urb = ohci->complete_head) == NULL) ++ return NULL; ++ if (urb == ohci->complete_tail) { ++ ohci->complete_tail = NULL; ++ ohci->complete_head = NULL; ++ } else { ++ ohci->complete_head = urb->hcpriv; ++ } ++ urb->hcpriv = NULL; ++ return urb; ++} ++ ++static inline void ohci_complete(struct ohci *ohci) ++{ ++ struct urb *urb; ++ ++ spin_lock(&ohci->ohci_lock); ++ while ((urb = ohci_complete_get(ohci)) != NULL) { ++ spin_unlock(&ohci->ohci_lock); ++ if (urb->dev) { ++ usb_dec_dev_use (urb->dev); ++ urb->dev = NULL; ++ } ++ if (urb->complete) ++ (*urb->complete)(urb); ++ spin_lock(&ohci->ohci_lock); ++ } ++ spin_unlock(&ohci->ohci_lock); ++} ++ ++/* free HCD-private data associated with this URB */ ++ ++static void urb_free_priv (struct ohci *hc, urb_priv_t * urb_priv) ++{ ++ int i; ++ int last = urb_priv->length - 1; ++ int len; ++ int dir; ++ struct td *td; ++ ++ if (last >= 0) { ++ ++ /* ISOC, BULK, INTR data buffer starts at td 0 ++ * CTRL setup starts at td 0 */ ++ td = urb_priv->td [0]; ++ ++ len = td->urb->transfer_buffer_length, ++ dir = usb_pipeout (td->urb->pipe) ++ ? PCI_DMA_TODEVICE ++ : PCI_DMA_FROMDEVICE; ++ ++ /* unmap CTRL URB setup */ ++ if (usb_pipecontrol (td->urb->pipe)) { ++ pci_unmap_single (hc->ohci_dev, ++ td->data_dma, 8, PCI_DMA_TODEVICE); ++ ++ /* CTRL data buffer starts at td 1 if len > 0 */ ++ if (len && last > 0) ++ td = urb_priv->td [1]; ++ } ++ ++ /* unmap data buffer */ ++ if (len && td->data_dma) ++ pci_unmap_single (hc->ohci_dev, td->data_dma, len, dir); ++ ++ for (i = 0; i <= last; i++) { ++ td = urb_priv->td [i]; ++ if (td) ++ td_free (hc, td); ++ } ++ } ++ ++ kfree (urb_priv); ++} ++ ++static void urb_rm_priv_locked (struct urb * urb) ++{ ++ urb_priv_t * urb_priv = urb->hcpriv; ++ ++ if (urb_priv) { ++ urb->hcpriv = NULL; ++ ++#ifdef DO_TIMEOUTS ++ if (urb->timeout) { ++ list_del (&urb->urb_list); ++ urb->timeout -= jiffies; ++ } ++#endif ++ ++ /* Release int/iso bandwidth */ ++ if (urb->bandwidth) { ++ switch (usb_pipetype(urb->pipe)) { ++ case PIPE_INTERRUPT: ++ usb_release_bandwidth (urb->dev, urb, 0); ++ break; ++ case PIPE_ISOCHRONOUS: ++ usb_release_bandwidth (urb->dev, urb, 1); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ urb_free_priv ((struct ohci *)urb->dev->bus->hcpriv, urb_priv); ++ } else { ++ if (urb->dev != NULL) { ++ err ("Non-null dev at rm_priv time"); ++ // urb->dev = NULL; ++ } ++ } ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++#ifdef DEBUG ++static int sohci_get_current_frame_number (struct usb_device * dev); ++ ++/* debug| print the main components of an URB ++ * small: 0) header + data packets 1) just header */ ++ ++static void urb_print (struct urb * urb, char * str, int small) ++{ ++ unsigned int pipe= urb->pipe; ++ ++ if (!urb->dev || !urb->dev->bus) { ++ dbg("%s URB: no dev", str); ++ return; ++ } ++ ++#ifndef OHCI_VERBOSE_DEBUG ++ if (urb->status != 0) ++#endif ++ dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,flags:%4x,len:%d/%d,stat:%d(%x)", ++ str, ++ sohci_get_current_frame_number (urb->dev), ++ usb_pipedevice (pipe), ++ usb_pipeendpoint (pipe), ++ usb_pipeout (pipe)? 'O': 'I', ++ usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"): ++ (usb_pipecontrol (pipe)? "CTRL": "BULK"), ++ urb->transfer_flags, ++ urb->actual_length, ++ urb->transfer_buffer_length, ++ urb->status, urb->status); ++#ifdef OHCI_VERBOSE_DEBUG ++ if (!small) { ++ int i, len; ++ ++ if (usb_pipecontrol (pipe)) { ++ printk (KERN_DEBUG __FILE__ ": cmd(8):"); ++ for (i = 0; i < 8 ; i++) ++ printk (" %02x", ((__u8 *) urb->setup_packet) [i]); ++ printk ("\n"); ++ } ++ if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) { ++ printk (KERN_DEBUG __FILE__ ": data(%d/%d):", ++ urb->actual_length, ++ urb->transfer_buffer_length); ++ len = usb_pipeout (pipe)? ++ urb->transfer_buffer_length: urb->actual_length; ++ for (i = 0; i < 16 && i < len; i++) ++ printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]); ++ printk ("%s stat:%d\n", i < len? "...": "", urb->status); ++ } ++ } ++#endif ++} ++ ++/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/ ++void ep_print_int_eds (ohci_t * ohci, char * str) { ++ int i, j; ++ __u32 * ed_p; ++ for (i= 0; i < 32; i++) { ++ j = 5; ++ ed_p = &(ohci->hcca->int_table [i]); ++ if (*ed_p == 0) ++ continue; ++ printk (KERN_DEBUG __FILE__ ": %s branch int %2d(%2x):", str, i, i); ++ while (*ed_p != 0 && j--) { ++ ed_t *ed = dma_to_ed (ohci, le32_to_cpup(ed_p)); ++ printk (" ed: %4x;", ed->hwINFO); ++ ed_p = &ed->hwNextED; ++ } ++ printk ("\n"); ++ } ++} ++ ++ ++static void ohci_dump_intr_mask (char *label, __u32 mask) ++{ ++ dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s", ++ label, ++ mask, ++ (mask & OHCI_INTR_MIE) ? " MIE" : "", ++ (mask & OHCI_INTR_OC) ? " OC" : "", ++ (mask & OHCI_INTR_RHSC) ? " RHSC" : "", ++ (mask & OHCI_INTR_FNO) ? " FNO" : "", ++ (mask & OHCI_INTR_UE) ? " UE" : "", ++ (mask & OHCI_INTR_RD) ? " RD" : "", ++ (mask & OHCI_INTR_SF) ? " SF" : "", ++ (mask & OHCI_INTR_WDH) ? " WDH" : "", ++ (mask & OHCI_INTR_SO) ? " SO" : "" ++ ); ++} ++ ++static void maybe_print_eds (char *label, __u32 value) ++{ ++ if (value) ++ dbg ("%s %08x", label, value); ++} ++ ++static char *hcfs2string (int state) ++{ ++ switch (state) { ++ case OHCI_USB_RESET: return "reset"; ++ case OHCI_USB_RESUME: return "resume"; ++ case OHCI_USB_OPER: return "operational"; ++ case OHCI_USB_SUSPEND: return "suspend"; ++ } ++ return "?"; ++} ++ ++// dump control and status registers ++static void ohci_dump_status (ohci_t *controller) ++{ ++ struct ohci_regs *regs = controller->regs; ++ __u32 temp; ++ ++ temp = readl (®s->revision) & 0xff; ++ if (temp != 0x10) ++ dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f)); ++ ++ temp = readl (®s->control); ++ dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, ++ (temp & OHCI_CTRL_RWE) ? " RWE" : "", ++ (temp & OHCI_CTRL_RWC) ? " RWC" : "", ++ (temp & OHCI_CTRL_IR) ? " IR" : "", ++ hcfs2string (temp & OHCI_CTRL_HCFS), ++ (temp & OHCI_CTRL_BLE) ? " BLE" : "", ++ (temp & OHCI_CTRL_CLE) ? " CLE" : "", ++ (temp & OHCI_CTRL_IE) ? " IE" : "", ++ (temp & OHCI_CTRL_PLE) ? " PLE" : "", ++ temp & OHCI_CTRL_CBSR ++ ); ++ ++ temp = readl (®s->cmdstatus); ++ dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, ++ (temp & OHCI_SOC) >> 16, ++ (temp & OHCI_OCR) ? " OCR" : "", ++ (temp & OHCI_BLF) ? " BLF" : "", ++ (temp & OHCI_CLF) ? " CLF" : "", ++ (temp & OHCI_HCR) ? " HCR" : "" ++ ); ++ ++ ohci_dump_intr_mask ("intrstatus", readl (®s->intrstatus)); ++ ohci_dump_intr_mask ("intrenable", readl (®s->intrenable)); ++ // intrdisable always same as intrenable ++ // ohci_dump_intr_mask ("intrdisable", readl (®s->intrdisable)); ++ ++ maybe_print_eds ("ed_periodcurrent", readl (®s->ed_periodcurrent)); ++ ++ maybe_print_eds ("ed_controlhead", readl (®s->ed_controlhead)); ++ maybe_print_eds ("ed_controlcurrent", readl (®s->ed_controlcurrent)); ++ ++ maybe_print_eds ("ed_bulkhead", readl (®s->ed_bulkhead)); ++ maybe_print_eds ("ed_bulkcurrent", readl (®s->ed_bulkcurrent)); ++ ++ maybe_print_eds ("donehead", readl (®s->donehead)); ++} ++ ++static void ohci_dump_roothub (ohci_t *controller, int verbose) ++{ ++ __u32 temp, ndp, i; ++ ++ temp = roothub_a (controller); ++ if (temp == ~(u32)0) ++ return; ++ ndp = (temp & RH_A_NDP); ++ ++ if (verbose) { ++ dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp, ++ ((temp & RH_A_POTPGT) >> 24) & 0xff, ++ (temp & RH_A_NOCP) ? " NOCP" : "", ++ (temp & RH_A_OCPM) ? " OCPM" : "", ++ (temp & RH_A_DT) ? " DT" : "", ++ (temp & RH_A_NPS) ? " NPS" : "", ++ (temp & RH_A_PSM) ? " PSM" : "", ++ ndp ++ ); ++ temp = roothub_b (controller); ++ dbg ("roothub.b: %08x PPCM=%04x DR=%04x", ++ temp, ++ (temp & RH_B_PPCM) >> 16, ++ (temp & RH_B_DR) ++ ); ++ temp = roothub_status (controller); ++ dbg ("roothub.status: %08x%s%s%s%s%s%s", ++ temp, ++ (temp & RH_HS_CRWE) ? " CRWE" : "", ++ (temp & RH_HS_OCIC) ? " OCIC" : "", ++ (temp & RH_HS_LPSC) ? " LPSC" : "", ++ (temp & RH_HS_DRWE) ? " DRWE" : "", ++ (temp & RH_HS_OCI) ? " OCI" : "", ++ (temp & RH_HS_LPS) ? " LPS" : "" ++ ); ++ } ++ ++ for (i = 0; i < ndp; i++) { ++ temp = roothub_portstatus (controller, i); ++ dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s", ++ i, ++ temp, ++ (temp & RH_PS_PRSC) ? " PRSC" : "", ++ (temp & RH_PS_OCIC) ? " OCIC" : "", ++ (temp & RH_PS_PSSC) ? " PSSC" : "", ++ (temp & RH_PS_PESC) ? " PESC" : "", ++ (temp & RH_PS_CSC) ? " CSC" : "", ++ ++ (temp & RH_PS_LSDA) ? " LSDA" : "", ++ (temp & RH_PS_PPS) ? " PPS" : "", ++ (temp & RH_PS_PRS) ? " PRS" : "", ++ (temp & RH_PS_POCI) ? " POCI" : "", ++ (temp & RH_PS_PSS) ? " PSS" : "", ++ ++ (temp & RH_PS_PES) ? " PES" : "", ++ (temp & RH_PS_CCS) ? " CCS" : "" ++ ); ++ } ++} ++ ++static void ohci_dump (ohci_t *controller, int verbose) ++{ ++ dbg ("OHCI controller usb-%s state", controller->ohci_dev->slot_name); ++ ++ // dumps some of the state we know about ++ ohci_dump_status (controller); ++ if (verbose) ++ ep_print_int_eds (controller, "hcca"); ++ dbg ("hcca frame #%04x", controller->hcca->frame_no); ++ ohci_dump_roothub (controller, 1); ++} ++ ++ ++#endif ++ ++/*-------------------------------------------------------------------------* ++ * Interface functions (URB) ++ *-------------------------------------------------------------------------*/ ++ ++/* return a request to the completion handler */ ++ ++static int sohci_return_urb (struct ohci *hc, struct urb * urb) ++{ ++ urb_priv_t * urb_priv = urb->hcpriv; ++ struct urb * urbt; ++ int i; ++ ++ if (!urb_priv) ++ return -1; /* urb already unlinked */ ++ ++ /* just to be sure */ ++ if (!urb->complete) { ++ urb_rm_priv_locked (urb); ++ ohci_complete_add(hc, urb); /* Just usb_dec_dev_use */ ++ return -1; ++ } ++ ++#ifdef DEBUG ++ urb_print (urb, "RET", usb_pipeout (urb->pipe)); ++#endif ++ ++ switch (usb_pipetype (urb->pipe)) { ++ case PIPE_INTERRUPT: ++ pci_unmap_single (hc->ohci_dev, ++ urb_priv->td [0]->data_dma, ++ urb->transfer_buffer_length, ++ usb_pipeout (urb->pipe) ++ ? PCI_DMA_TODEVICE ++ : PCI_DMA_FROMDEVICE); ++ if (urb->interval) { ++ urb->complete (urb); ++ ++ /* implicitly requeued */ ++ urb->actual_length = 0; ++ urb->status = -EINPROGRESS; ++ td_submit_urb (urb); ++ } else { ++ urb_rm_priv_locked (urb); ++ ohci_complete_add(hc, urb); ++ } ++ break; ++ ++ case PIPE_ISOCHRONOUS: ++ for (urbt = urb->next; urbt && (urbt != urb); urbt = urbt->next); ++ if (urbt) { /* send the reply and requeue URB */ ++ pci_unmap_single (hc->ohci_dev, ++ urb_priv->td [0]->data_dma, ++ urb->transfer_buffer_length, ++ usb_pipeout (urb->pipe) ++ ? PCI_DMA_TODEVICE ++ : PCI_DMA_FROMDEVICE); ++ urb->complete (urb); ++ urb->actual_length = 0; ++ urb->status = USB_ST_URB_PENDING; ++ urb->start_frame = urb_priv->ed->last_iso + 1; ++ if (urb_priv->state != URB_DEL) { ++ for (i = 0; i < urb->number_of_packets; i++) { ++ urb->iso_frame_desc[i].actual_length = 0; ++ urb->iso_frame_desc[i].status = -EXDEV; ++ } ++ td_submit_urb (urb); ++ } ++ ++ } else { /* unlink URB, call complete */ ++ urb_rm_priv_locked (urb); ++ ohci_complete_add(hc, urb); ++ } ++ break; ++ ++ case PIPE_BULK: ++ case PIPE_CONTROL: /* unlink URB, call complete */ ++ urb_rm_priv_locked (urb); ++ ohci_complete_add(hc, urb); ++ break; ++ } ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* get a transfer request */ ++ ++static int sohci_submit_urb (struct urb * urb) ++{ ++ ohci_t * ohci; ++ ed_t * ed; ++ urb_priv_t * urb_priv; ++ unsigned int pipe = urb->pipe; ++ int maxps = usb_maxpacket (urb->dev, pipe, usb_pipeout (pipe)); ++ int i, size = 0; ++ unsigned long flags; ++ int bustime = 0; ++ int mem_flags = GFP_ATOMIC; ++ ++ if (!urb->dev || !urb->dev->bus) ++ return -ENODEV; ++ ++ if (urb->hcpriv) /* urb already in use */ ++ return -EINVAL; ++ ++// if(usb_endpoint_halted (urb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe))) ++// return -EPIPE; ++ ++ usb_inc_dev_use (urb->dev); ++ ohci = (ohci_t *) urb->dev->bus->hcpriv; ++ ++#ifdef DEBUG ++ urb_print (urb, "SUB", usb_pipein (pipe)); ++#endif ++ ++ /* handle a request to the virtual root hub */ ++ if (usb_pipedevice (pipe) == ohci->rh.devnum) ++ return rh_submit_urb (urb); ++ ++ spin_lock_irqsave(&ohci->ohci_lock, flags); ++ ++ /* when controller's hung, permit only roothub cleanup attempts ++ * such as powering down ports */ ++ if (ohci->disabled) { ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ usb_dec_dev_use (urb->dev); ++ return -ESHUTDOWN; ++ } ++ ++ /* every endpoint has a ed, locate and fill it */ ++ if (!(ed = ep_add_ed (urb->dev, pipe, urb->interval, 1, mem_flags))) { ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ usb_dec_dev_use (urb->dev); ++ return -ENOMEM; ++ } ++ ++ /* for the private part of the URB we need the number of TDs (size) */ ++ switch (usb_pipetype (pipe)) { ++ case PIPE_BULK: /* one TD for every 4096 Byte */ ++ size = (urb->transfer_buffer_length - 1) / 4096 + 1; ++ ++ /* If the transfer size is multiple of the pipe mtu, ++ * we may need an extra TD to create a empty frame ++ * Jean II */ ++ if ((urb->transfer_flags & USB_ZERO_PACKET) && ++ usb_pipeout (pipe) && ++ (urb->transfer_buffer_length != 0) && ++ ((urb->transfer_buffer_length % maxps) == 0)) ++ size++; ++ break; ++ case PIPE_ISOCHRONOUS: /* number of packets from URB */ ++ size = urb->number_of_packets; ++ if (size <= 0) { ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ usb_dec_dev_use (urb->dev); ++ return -EINVAL; ++ } ++ for (i = 0; i < urb->number_of_packets; i++) { ++ urb->iso_frame_desc[i].actual_length = 0; ++ urb->iso_frame_desc[i].status = -EXDEV; ++ } ++ break; ++ case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ ++ size = (urb->transfer_buffer_length == 0)? 2: ++ (urb->transfer_buffer_length - 1) / 4096 + 3; ++ break; ++ case PIPE_INTERRUPT: /* one TD */ ++ size = 1; ++ break; ++ } ++ ++ /* allocate the private part of the URB */ ++ urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), ++ GFP_ATOMIC); ++ if (!urb_priv) { ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ usb_dec_dev_use (urb->dev); ++ return -ENOMEM; ++ } ++ memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (td_t *)); ++ ++ /* fill the private part of the URB */ ++ urb_priv->length = size; ++ urb_priv->ed = ed; ++ ++ /* allocate the TDs (updating hash chains) */ ++ for (i = 0; i < size; i++) { ++ urb_priv->td[i] = td_alloc (ohci, SLAB_ATOMIC); ++ if (!urb_priv->td[i]) { ++ urb_priv->length = i; ++ urb_free_priv (ohci, urb_priv); ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ usb_dec_dev_use (urb->dev); ++ return -ENOMEM; ++ } ++ } ++ ++ if (ed->state == ED_NEW || (ed->state & ED_DEL)) { ++ urb_free_priv (ohci, urb_priv); ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ usb_dec_dev_use (urb->dev); ++ return -EINVAL; ++ } ++ ++ /* allocate and claim bandwidth if needed; ISO ++ * needs start frame index if it was't provided. ++ */ ++ switch (usb_pipetype (pipe)) { ++ case PIPE_ISOCHRONOUS: ++ if (urb->transfer_flags & USB_ISO_ASAP) { ++ urb->start_frame = ((ed->state == ED_OPER) ++ ? (ed->last_iso + 1) ++ : (le16_to_cpu (ohci->hcca->frame_no) + 10)) & 0xffff; ++ } ++ /* FALLTHROUGH */ ++ case PIPE_INTERRUPT: ++ if (urb->bandwidth == 0) { ++ bustime = usb_check_bandwidth (urb->dev, urb); ++ } ++ if (bustime < 0) { ++ urb_free_priv (ohci, urb_priv); ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ usb_dec_dev_use (urb->dev); ++ return bustime; ++ } ++ usb_claim_bandwidth (urb->dev, urb, bustime, usb_pipeisoc (urb->pipe)); ++#ifdef DO_TIMEOUTS ++ urb->timeout = 0; ++#endif ++ } ++ ++ urb->actual_length = 0; ++ urb->hcpriv = urb_priv; ++ urb->status = USB_ST_URB_PENDING; ++ ++ /* link the ed into a chain if is not already */ ++ if (ed->state != ED_OPER) ++ ep_link (ohci, ed); ++ ++ /* fill the TDs and link it to the ed */ ++ td_submit_urb (urb); ++ ++#ifdef DO_TIMEOUTS ++ /* maybe add to ordered list of timeouts */ ++ if (urb->timeout) { ++ struct list_head *entry; ++ ++ urb->timeout += jiffies; ++ ++ list_for_each (entry, &ohci->timeout_list) { ++ struct urb *next_urb; ++ ++ next_urb = list_entry (entry, struct urb, urb_list); ++ if (time_after_eq (urb->timeout, next_urb->timeout)) ++ break; ++ } ++ list_add (&urb->urb_list, entry); ++ ++ /* drive timeouts by SF (messy, but works) */ ++ writel (OHCI_INTR_SF, &ohci->regs->intrenable); ++ (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ ++ } ++#endif ++ ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* deactivate all TDs and remove the private part of the URB */ ++/* interrupt callers must use async unlink mode */ ++ ++static int sohci_unlink_urb (struct urb * urb) ++{ ++ unsigned long flags; ++ ohci_t * ohci; ++ ++ if (!urb) /* just to be sure */ ++ return -EINVAL; ++ ++ if (!urb->dev || !urb->dev->bus) ++ return -ENODEV; ++ ++ ohci = (ohci_t *) urb->dev->bus->hcpriv; ++ ++#ifdef DEBUG ++ urb_print (urb, "UNLINK", 1); ++#endif ++ ++ /* handle a request to the virtual root hub */ ++ if (usb_pipedevice (urb->pipe) == ohci->rh.devnum) ++ return rh_unlink_urb (urb); ++ ++ spin_lock_irqsave(&ohci->ohci_lock, flags); ++ if (urb->hcpriv && (urb->status == USB_ST_URB_PENDING)) { ++ if (!ohci->disabled) { ++ urb_priv_t * urb_priv; ++ ++ /* interrupt code may not sleep; it must use ++ * async status return to unlink pending urbs. ++ */ ++ if (!(urb->transfer_flags & USB_ASYNC_UNLINK) ++ && in_interrupt ()) { ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ err ("bug in call from %p; use async!", ++ __builtin_return_address(0)); ++ return -EWOULDBLOCK; ++ } ++ ++ /* flag the urb and its TDs for deletion in some ++ * upcoming SF interrupt delete list processing ++ */ ++ urb_priv = urb->hcpriv; ++ ++ if (!urb_priv || (urb_priv->state == URB_DEL)) { ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ return 0; ++ } ++ ++ urb_priv->state = URB_DEL; ++ ep_rm_ed (urb->dev, urb_priv->ed); ++ urb_priv->ed->state |= ED_URB_DEL; ++ ++ if (!(urb->transfer_flags & USB_ASYNC_UNLINK)) { ++ DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); ++ DECLARE_WAITQUEUE (wait, current); ++ int timeout = OHCI_UNLINK_TIMEOUT; ++ ++ add_wait_queue (&unlink_wakeup, &wait); ++ urb_priv->wait = &unlink_wakeup; ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ ++ /* wait until all TDs are deleted */ ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ while (timeout && (urb->status == USB_ST_URB_PENDING)) { ++ timeout = schedule_timeout (timeout); ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ } ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue (&unlink_wakeup, &wait); ++ if (urb->status == USB_ST_URB_PENDING) { ++ err ("unlink URB timeout"); ++ return -ETIMEDOUT; ++ } ++ ++ usb_dec_dev_use (urb->dev); ++ urb->dev = NULL; ++ if (urb->complete) ++ urb->complete (urb); ++ } else { ++ /* usb_dec_dev_use done in dl_del_list() */ ++ urb->status = -EINPROGRESS; ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ return -EINPROGRESS; ++ } ++ } else { ++ urb_rm_priv_locked (urb); ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ usb_dec_dev_use (urb->dev); ++ urb->dev = NULL; ++ if (urb->transfer_flags & USB_ASYNC_UNLINK) { ++ urb->status = -ECONNRESET; ++ if (urb->complete) ++ urb->complete (urb); ++ } else ++ urb->status = -ENOENT; ++ } ++ } else { ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ } ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* allocate private data space for a usb device */ ++ ++static int sohci_alloc_dev (struct usb_device *usb_dev) ++{ ++ struct ohci_device * dev; ++ ++ dev = dev_alloc ((struct ohci *) usb_dev->bus->hcpriv, ALLOC_FLAGS); ++ if (!dev) ++ return -ENOMEM; ++ ++ usb_dev->hcpriv = dev; ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* may be called from interrupt context */ ++/* frees private data space of usb device */ ++ ++static int sohci_free_dev (struct usb_device * usb_dev) ++{ ++ unsigned long flags; ++ int i, cnt = 0; ++ ed_t * ed; ++ struct ohci_device * dev = usb_to_ohci (usb_dev); ++ ohci_t * ohci = usb_dev->bus->hcpriv; ++ ++ if (!dev) ++ return 0; ++ ++ if (usb_dev->devnum >= 0) { ++ ++ /* driver disconnects should have unlinked all urbs ++ * (freeing all the TDs, unlinking EDs) but we need ++ * to defend against bugs that prevent that. ++ */ ++ spin_lock_irqsave(&ohci->ohci_lock, flags); ++ for(i = 0; i < NUM_EDS; i++) { ++ ed = &(dev->ed[i]); ++ if (ed->state != ED_NEW) { ++ if (ed->state == ED_OPER) { ++ /* driver on that interface didn't unlink an urb */ ++ dbg ("driver usb-%s dev %d ed 0x%x unfreed URB", ++ ohci->ohci_dev->slot_name, usb_dev->devnum, i); ++ ep_unlink (ohci, ed); ++ } ++ ep_rm_ed (usb_dev, ed); ++ ed->state = ED_DEL; ++ cnt++; ++ } ++ } ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ ++ /* if the controller is running, tds for those unlinked ++ * urbs get freed by dl_del_list at the next SF interrupt ++ */ ++ if (cnt > 0) { ++ ++ if (ohci->disabled) { ++ /* FIXME: Something like this should kick in, ++ * though it's currently an exotic case ... ++ * the controller won't ever be touching ++ * these lists again!! ++ dl_del_list (ohci, ++ le16_to_cpu (ohci->hcca->frame_no) & 1); ++ */ ++ warn ("TD leak, %d", cnt); ++ ++ } else if (!in_interrupt ()) { ++ DECLARE_WAIT_QUEUE_HEAD (freedev_wakeup); ++ DECLARE_WAITQUEUE (wait, current); ++ int timeout = OHCI_UNLINK_TIMEOUT; ++ ++ /* SF interrupt handler calls dl_del_list */ ++ add_wait_queue (&freedev_wakeup, &wait); ++ dev->wait = &freedev_wakeup; ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ while (timeout && dev->ed_cnt) ++ timeout = schedule_timeout (timeout); ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue (&freedev_wakeup, &wait); ++ if (dev->ed_cnt) { ++ err ("free device %d timeout", usb_dev->devnum); ++ return -ETIMEDOUT; ++ } ++ } else { ++ /* likely some interface's driver has a refcount bug */ ++ err ("bus %s devnum %d deletion in interrupt", ++ ohci->ohci_dev->slot_name, usb_dev->devnum); ++ BUG (); ++ } ++ } ++ } ++ ++ /* free device, and associated EDs */ ++ dev_free (ohci, dev); ++ ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* tell us the current USB frame number */ ++ ++static int sohci_get_current_frame_number (struct usb_device *usb_dev) ++{ ++ ohci_t * ohci = usb_dev->bus->hcpriv; ++ ++ return le16_to_cpu (ohci->hcca->frame_no); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++struct usb_operations sohci_device_operations = { ++ sohci_alloc_dev, ++ sohci_free_dev, ++ sohci_get_current_frame_number, ++ sohci_submit_urb, ++ sohci_unlink_urb ++}; ++ ++/*-------------------------------------------------------------------------* ++ * ED handling functions ++ *-------------------------------------------------------------------------*/ ++ ++/* search for the right branch to insert an interrupt ed into the int tree ++ * do some load ballancing; ++ * returns the branch and ++ * sets the interval to interval = 2^integer (ld (interval)) */ ++ ++static int ep_int_ballance (ohci_t * ohci, int interval, int load) ++{ ++ int i, branch = 0; ++ ++ /* search for the least loaded interrupt endpoint branch of all 32 branches */ ++ for (i = 0; i < 32; i++) ++ if (ohci->ohci_int_load [branch] > ohci->ohci_int_load [i]) branch = i; ++ ++ branch = branch % interval; ++ for (i = branch; i < 32; i += interval) ohci->ohci_int_load [i] += load; ++ ++ return branch; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* 2^int( ld (inter)) */ ++ ++static int ep_2_n_interval (int inter) ++{ ++ int i; ++ for (i = 0; ((inter >> i) > 1 ) && (i < 5); i++); ++ return 1 << i; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* the int tree is a binary tree ++ * in order to process it sequentially the indexes of the branches have to be mapped ++ * the mapping reverses the bits of a word of num_bits length */ ++ ++static int ep_rev (int num_bits, int word) ++{ ++ int i, wout = 0; ++ ++ for (i = 0; i < num_bits; i++) wout |= (((word >> i) & 1) << (num_bits - i - 1)); ++ return wout; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* link an ed into one of the HC chains */ ++ ++static int ep_link (ohci_t * ohci, ed_t * edi) ++{ ++ int int_branch; ++ int i; ++ int inter; ++ int interval; ++ int load; ++ __u32 * ed_p; ++ volatile ed_t * ed = edi; ++ ++ ed->state = ED_OPER; ++ ++ switch (ed->type) { ++ case PIPE_CONTROL: ++ ed->hwNextED = 0; ++ if (ohci->ed_controltail == NULL) { ++ writel (ed->dma, &ohci->regs->ed_controlhead); ++ } else { ++ ohci->ed_controltail->hwNextED = cpu_to_le32 (ed->dma); ++ } ++ ed->ed_prev = ohci->ed_controltail; ++ if (!ohci->ed_controltail && !ohci->ed_rm_list[0] && ++ !ohci->ed_rm_list[1] && !ohci->sleeping) { ++ ohci->hc_control |= OHCI_CTRL_CLE; ++ writel (ohci->hc_control, &ohci->regs->control); ++ } ++ ohci->ed_controltail = edi; ++ break; ++ ++ case PIPE_BULK: ++ ed->hwNextED = 0; ++ if (ohci->ed_bulktail == NULL) { ++ writel (ed->dma, &ohci->regs->ed_bulkhead); ++ } else { ++ ohci->ed_bulktail->hwNextED = cpu_to_le32 (ed->dma); ++ } ++ ed->ed_prev = ohci->ed_bulktail; ++ if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] && ++ !ohci->ed_rm_list[1] && !ohci->sleeping) { ++ ohci->hc_control |= OHCI_CTRL_BLE; ++ writel (ohci->hc_control, &ohci->regs->control); ++ } ++ ohci->ed_bulktail = edi; ++ break; ++ ++ case PIPE_INTERRUPT: ++ load = ed->int_load; ++ interval = ep_2_n_interval (ed->int_period); ++ ed->int_interval = interval; ++ int_branch = ep_int_ballance (ohci, interval, load); ++ ed->int_branch = int_branch; ++ ++ for (i = 0; i < ep_rev (6, interval); i += inter) { ++ inter = 1; ++ for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i) + int_branch]); ++ (*ed_p != 0) && ((dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval >= interval); ++ ed_p = &((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED)) ++ inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval); ++ ed->hwNextED = *ed_p; ++ *ed_p = cpu_to_le32 (ed->dma); ++ } ++#ifdef DEBUG ++ ep_print_int_eds (ohci, "LINK_INT"); ++#endif ++ break; ++ ++ case PIPE_ISOCHRONOUS: ++ ed->hwNextED = 0; ++ ed->int_interval = 1; ++ if (ohci->ed_isotail != NULL) { ++ ohci->ed_isotail->hwNextED = cpu_to_le32 (ed->dma); ++ ed->ed_prev = ohci->ed_isotail; ++ } else { ++ for ( i = 0; i < 32; i += inter) { ++ inter = 1; ++ for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i)]); ++ *ed_p != 0; ++ ed_p = &((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED)) ++ inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval); ++ *ed_p = cpu_to_le32 (ed->dma); ++ } ++ ed->ed_prev = NULL; ++ } ++ ohci->ed_isotail = edi; ++#ifdef DEBUG ++ ep_print_int_eds (ohci, "LINK_ISO"); ++#endif ++ break; ++ } ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* scan the periodic table to find and unlink this ED */ ++static void periodic_unlink ( ++ struct ohci *ohci, ++ struct ed *ed, ++ unsigned index, ++ unsigned period ++) { ++ for (; index < NUM_INTS; index += period) { ++ __u32 *ed_p = &ohci->hcca->int_table [index]; ++ ++ /* ED might have been unlinked through another path */ ++ while (*ed_p != 0) { ++ if ((dma_to_ed (ohci, le32_to_cpup (ed_p))) == ed) { ++ *ed_p = ed->hwNextED; ++ break; ++ } ++ ed_p = & ((dma_to_ed (ohci, ++ le32_to_cpup (ed_p)))->hwNextED); ++ } ++ } ++} ++ ++/* unlink an ed from one of the HC chains. ++ * just the link to the ed is unlinked. ++ * the link from the ed still points to another operational ed or 0 ++ * so the HC can eventually finish the processing of the unlinked ed */ ++ ++static int ep_unlink (ohci_t * ohci, ed_t * ed) ++{ ++ int i; ++ ++ ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP); ++ ++ switch (ed->type) { ++ case PIPE_CONTROL: ++ if (ed->ed_prev == NULL) { ++ if (!ed->hwNextED) { ++ ohci->hc_control &= ~OHCI_CTRL_CLE; ++ writel (ohci->hc_control, &ohci->regs->control); ++ } ++ writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_controlhead); ++ } else { ++ ed->ed_prev->hwNextED = ed->hwNextED; ++ } ++ if (ohci->ed_controltail == ed) { ++ ohci->ed_controltail = ed->ed_prev; ++ } else { ++ (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev; ++ } ++ break; ++ ++ case PIPE_BULK: ++ if (ed->ed_prev == NULL) { ++ if (!ed->hwNextED) { ++ ohci->hc_control &= ~OHCI_CTRL_BLE; ++ writel (ohci->hc_control, &ohci->regs->control); ++ } ++ writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_bulkhead); ++ } else { ++ ed->ed_prev->hwNextED = ed->hwNextED; ++ } ++ if (ohci->ed_bulktail == ed) { ++ ohci->ed_bulktail = ed->ed_prev; ++ } else { ++ (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev; ++ } ++ break; ++ ++ case PIPE_INTERRUPT: ++ periodic_unlink (ohci, ed, 0, 1); ++ for (i = ed->int_branch; i < 32; i += ed->int_interval) ++ ohci->ohci_int_load[i] -= ed->int_load; ++#ifdef DEBUG ++ ep_print_int_eds (ohci, "UNLINK_INT"); ++#endif ++ break; ++ ++ case PIPE_ISOCHRONOUS: ++ if (ohci->ed_isotail == ed) ++ ohci->ed_isotail = ed->ed_prev; ++ if (ed->hwNextED != 0) ++ (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED))) ++ ->ed_prev = ed->ed_prev; ++ ++ if (ed->ed_prev != NULL) ++ ed->ed_prev->hwNextED = ed->hwNextED; ++ else ++ periodic_unlink (ohci, ed, 0, 1); ++#ifdef DEBUG ++ ep_print_int_eds (ohci, "UNLINK_ISO"); ++#endif ++ break; ++ } ++ ed->state = ED_UNLINK; ++ return 0; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* add/reinit an endpoint; this should be done once at the usb_set_configuration command, ++ * but the USB stack is a little bit stateless so we do it at every transaction ++ * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK ++ * in all other cases the state is left unchanged ++ * the ed info fields are setted anyway even though most of them should not change */ ++ ++static ed_t * ep_add_ed ( ++ struct usb_device * usb_dev, ++ unsigned int pipe, ++ int interval, ++ int load, ++ int mem_flags ++) ++{ ++ ohci_t * ohci = usb_dev->bus->hcpriv; ++ td_t * td; ++ ed_t * ed_ret; ++ volatile ed_t * ed; ++ ++ ed = ed_ret = &(usb_to_ohci (usb_dev)->ed[(usb_pipeendpoint (pipe) << 1) | ++ (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))]); ++ ++ if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) { ++ /* pending delete request */ ++ return NULL; ++ } ++ ++ if (ed->state == ED_NEW) { ++ ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */ ++ /* dummy td; end of td list for ed */ ++ td = td_alloc (ohci, SLAB_ATOMIC); ++ /* hash the ed for later reverse mapping */ ++ if (!td || !hash_add_ed (ohci, (ed_t *)ed)) { ++ /* out of memory */ ++ if (td) ++ td_free(ohci, td); ++ return NULL; ++ } ++ ed->hwTailP = cpu_to_le32 (td->td_dma); ++ ed->hwHeadP = ed->hwTailP; ++ ed->state = ED_UNLINK; ++ ed->type = usb_pipetype (pipe); ++ usb_to_ohci (usb_dev)->ed_cnt++; ++ } ++ ++ ohci->dev[usb_pipedevice (pipe)] = usb_dev; ++ ++ ed->hwINFO = cpu_to_le32 (usb_pipedevice (pipe) ++ | usb_pipeendpoint (pipe) << 7 ++ | (usb_pipeisoc (pipe)? 0x8000: 0) ++ | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000)) ++ | usb_pipeslow (pipe) << 13 ++ | usb_maxpacket (usb_dev, pipe, usb_pipeout (pipe)) << 16); ++ ++ if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) { ++ ed->int_period = interval; ++ ed->int_load = load; ++ } ++ ++ return ed_ret; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* request the removal of an endpoint ++ * put the ep on the rm_list and request a stop of the bulk or ctrl list ++ * real removal is done at the next start frame (SF) hardware interrupt */ ++ ++static void ep_rm_ed (struct usb_device * usb_dev, ed_t * ed) ++{ ++ unsigned int frame; ++ ohci_t * ohci = usb_dev->bus->hcpriv; ++ ++ if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) ++ return; ++ ++ ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP); ++ ++ if (!ohci->disabled) { ++ switch (ed->type) { ++ case PIPE_CONTROL: /* stop control list */ ++ ohci->hc_control &= ~OHCI_CTRL_CLE; ++ writel (ohci->hc_control, &ohci->regs->control); ++ break; ++ case PIPE_BULK: /* stop bulk list */ ++ ohci->hc_control &= ~OHCI_CTRL_BLE; ++ writel (ohci->hc_control, &ohci->regs->control); ++ break; ++ } ++ } ++ ++ frame = le16_to_cpu (ohci->hcca->frame_no) & 0x1; ++ ed->ed_rm_list = ohci->ed_rm_list[frame]; ++ ohci->ed_rm_list[frame] = ed; ++ ++ if (!ohci->disabled && !ohci->sleeping) { ++ /* enable SOF interrupt */ ++ writel (OHCI_INTR_SF, &ohci->regs->intrstatus); ++ writel (OHCI_INTR_SF, &ohci->regs->intrenable); ++ (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ ++ } ++} ++ ++/*-------------------------------------------------------------------------* ++ * TD handling functions ++ *-------------------------------------------------------------------------*/ ++ ++/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ ++ ++static void ++td_fill (ohci_t * ohci, unsigned int info, ++ dma_addr_t data, int len, ++ struct urb * urb, int index) ++{ ++ volatile td_t * td, * td_pt; ++ urb_priv_t * urb_priv = urb->hcpriv; ++ ++ if (index >= urb_priv->length) { ++ err("internal OHCI error: TD index > length"); ++ return; ++ } ++ ++ /* use this td as the next dummy */ ++ td_pt = urb_priv->td [index]; ++ td_pt->hwNextTD = 0; ++ ++ /* fill the old dummy TD */ ++ td = urb_priv->td [index] = dma_to_td (ohci, ++ le32_to_cpup (&urb_priv->ed->hwTailP) & ~0xf); ++ ++ td->ed = urb_priv->ed; ++ td->next_dl_td = NULL; ++ td->index = index; ++ td->urb = urb; ++ td->data_dma = data; ++ if (!len) ++ data = 0; ++ ++ td->hwINFO = cpu_to_le32 (info); ++ if ((td->ed->type) == PIPE_ISOCHRONOUS) { ++ td->hwCBP = cpu_to_le32 (data & 0xFFFFF000); ++ td->ed->last_iso = info & 0xffff; ++ } else { ++ td->hwCBP = cpu_to_le32 (data); ++ } ++ if (data) ++ td->hwBE = cpu_to_le32 (data + len - 1); ++ else ++ td->hwBE = 0; ++ td->hwNextTD = cpu_to_le32 (td_pt->td_dma); ++ td->hwPSW [0] = cpu_to_le16 ((data & 0x0FFF) | 0xE000); ++ ++ /* append to queue */ ++ wmb(); ++ td->ed->hwTailP = td->hwNextTD; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* prepare all TDs of a transfer */ ++ ++static void td_submit_urb (struct urb * urb) ++{ ++ urb_priv_t * urb_priv = urb->hcpriv; ++ ohci_t * ohci = (ohci_t *) urb->dev->bus->hcpriv; ++ dma_addr_t data; ++ int data_len = urb->transfer_buffer_length; ++ int maxps = usb_maxpacket (urb->dev, urb->pipe, usb_pipeout (urb->pipe)); ++ int cnt = 0; ++ __u32 info = 0; ++ unsigned int toggle = 0; ++ ++ /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */ ++ if(usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe))) { ++ toggle = TD_T_TOGGLE; ++ } else { ++ toggle = TD_T_DATA0; ++ usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 1); ++ } ++ ++ urb_priv->td_cnt = 0; ++ ++ if (data_len) { ++ data = pci_map_single (ohci->ohci_dev, ++ urb->transfer_buffer, data_len, ++ usb_pipeout (urb->pipe) ++ ? PCI_DMA_TODEVICE ++ : PCI_DMA_FROMDEVICE ++ ); ++ } else ++ data = 0; ++ ++ switch (usb_pipetype (urb->pipe)) { ++ case PIPE_BULK: ++ info = usb_pipeout (urb->pipe)? ++ TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ; ++ while(data_len > 4096) { ++ td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, urb, cnt); ++ data += 4096; data_len -= 4096; cnt++; ++ } ++ info = usb_pipeout (urb->pipe)? ++ TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ; ++ td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, urb, cnt); ++ cnt++; ++ ++ /* If the transfer size is multiple of the pipe mtu, ++ * we may need an extra TD to create a empty frame ++ * Note : another way to check this condition is ++ * to test if(urb_priv->length > cnt) - Jean II */ ++ if ((urb->transfer_flags & USB_ZERO_PACKET) && ++ usb_pipeout (urb->pipe) && ++ (urb->transfer_buffer_length != 0) && ++ ((urb->transfer_buffer_length % maxps) == 0)) { ++ td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), 0, 0, urb, cnt); ++ cnt++; ++ } ++ ++ if (!ohci->sleeping) { ++ wmb(); ++ writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ ++ (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ ++ } ++ break; ++ ++ case PIPE_INTERRUPT: ++ info = usb_pipeout (urb->pipe)? ++ TD_CC | TD_DP_OUT | toggle: TD_CC | TD_R | TD_DP_IN | toggle; ++ td_fill (ohci, info, data, data_len, urb, cnt++); ++ break; ++ ++ case PIPE_CONTROL: ++ info = TD_CC | TD_DP_SETUP | TD_T_DATA0; ++ td_fill (ohci, info, ++ pci_map_single (ohci->ohci_dev, ++ urb->setup_packet, 8, ++ PCI_DMA_TODEVICE), ++ 8, urb, cnt++); ++ if (data_len > 0) { ++ info = usb_pipeout (urb->pipe)? ++ TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; ++ /* NOTE: mishandles transfers >8K, some >4K */ ++ td_fill (ohci, info, data, data_len, urb, cnt++); ++ } ++ info = usb_pipeout (urb->pipe)? ++ TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1; ++ td_fill (ohci, info, data, 0, urb, cnt++); ++ if (!ohci->sleeping) { ++ wmb(); ++ writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ ++ (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ ++ } ++ break; ++ ++ case PIPE_ISOCHRONOUS: ++ for (cnt = 0; cnt < urb->number_of_packets; cnt++) { ++ td_fill (ohci, TD_CC|TD_ISO | ((urb->start_frame + cnt) & 0xffff), ++ data + urb->iso_frame_desc[cnt].offset, ++ urb->iso_frame_desc[cnt].length, urb, cnt); ++ } ++ break; ++ } ++ if (urb_priv->length != cnt) ++ dbg("TD LENGTH %d != CNT %d", urb_priv->length, cnt); ++} ++ ++/*-------------------------------------------------------------------------* ++ * Done List handling functions ++ *-------------------------------------------------------------------------*/ ++ ++ ++/* calculate the transfer length and update the urb */ ++ ++static void dl_transfer_length(td_t * td) ++{ ++ __u32 tdINFO, tdBE, tdCBP; ++ __u16 tdPSW; ++ struct urb * urb = td->urb; ++ urb_priv_t * urb_priv = urb->hcpriv; ++ int dlen = 0; ++ int cc = 0; ++ ++ tdINFO = le32_to_cpup (&td->hwINFO); ++ tdBE = le32_to_cpup (&td->hwBE); ++ tdCBP = le32_to_cpup (&td->hwCBP); ++ ++ ++ if (tdINFO & TD_ISO) { ++ tdPSW = le16_to_cpu (td->hwPSW[0]); ++ cc = (tdPSW >> 12) & 0xF; ++ if (cc < 0xE) { ++ if (usb_pipeout(urb->pipe)) { ++ dlen = urb->iso_frame_desc[td->index].length; ++ } else { ++ dlen = tdPSW & 0x3ff; ++ } ++ urb->actual_length += dlen; ++ urb->iso_frame_desc[td->index].actual_length = dlen; ++ if (!(urb->transfer_flags & USB_DISABLE_SPD) && (cc == TD_DATAUNDERRUN)) ++ cc = TD_CC_NOERROR; ++ ++ urb->iso_frame_desc[td->index].status = cc_to_error[cc]; ++ } ++ } else { /* BULK, INT, CONTROL DATA */ ++ if (!(usb_pipetype (urb->pipe) == PIPE_CONTROL && ++ ((td->index == 0) || (td->index == urb_priv->length - 1)))) { ++ if (tdBE != 0) { ++ if (td->hwCBP == 0) ++ urb->actual_length += tdBE - td->data_dma + 1; ++ else ++ urb->actual_length += tdCBP - td->data_dma; ++ } ++ } ++ } ++} ++ ++/* handle an urb that is being unlinked */ ++ ++static void dl_del_urb (ohci_t *ohci, struct urb * urb) ++{ ++ wait_queue_head_t * wait_head = ((urb_priv_t *)(urb->hcpriv))->wait; ++ ++ urb_rm_priv_locked (urb); ++ ++ if (urb->transfer_flags & USB_ASYNC_UNLINK) { ++ urb->status = -ECONNRESET; ++ ohci_complete_add(ohci, urb); ++ } else { ++ urb->status = -ENOENT; ++ ++ /* unblock sohci_unlink_urb */ ++ if (wait_head) ++ wake_up (wait_head); ++ } ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* replies to the request have to be on a FIFO basis so ++ * we reverse the reversed done-list */ ++ ++static td_t * dl_reverse_done_list (ohci_t * ohci) ++{ ++ __u32 td_list_hc; ++ td_t * td_rev = NULL; ++ td_t * td_list = NULL; ++ urb_priv_t * urb_priv = NULL; ++ ++ td_list_hc = le32_to_cpup (&ohci->hcca->done_head) & 0xfffffff0; ++ ohci->hcca->done_head = 0; ++ ++ while (td_list_hc) { ++ td_list = dma_to_td (ohci, td_list_hc); ++ ++ if (TD_CC_GET (le32_to_cpup (&td_list->hwINFO))) { ++ urb_priv = (urb_priv_t *) td_list->urb->hcpriv; ++ dbg(" USB-error/status: %x : %p", ++ TD_CC_GET (le32_to_cpup (&td_list->hwINFO)), td_list); ++ if (td_list->ed->hwHeadP & cpu_to_le32 (0x1)) { ++ if (urb_priv && ((td_list->index + 1) < urb_priv->length)) { ++ td_list->ed->hwHeadP = ++ (urb_priv->td[urb_priv->length - 1]->hwNextTD & cpu_to_le32 (0xfffffff0)) | ++ (td_list->ed->hwHeadP & cpu_to_le32 (0x2)); ++ urb_priv->td_cnt += urb_priv->length - td_list->index - 1; ++ } else ++ td_list->ed->hwHeadP &= cpu_to_le32 (0xfffffff2); ++ } ++ } ++ ++ td_list->next_dl_td = td_rev; ++ td_rev = td_list; ++ td_list_hc = le32_to_cpup (&td_list->hwNextTD) & 0xfffffff0; ++ } ++ return td_list; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* there are some pending requests to remove ++ * - some of the eds (if ed->state & ED_DEL (set by sohci_free_dev) ++ * - some URBs/TDs if urb_priv->state == URB_DEL */ ++ ++static void dl_del_list (ohci_t * ohci, unsigned int frame) ++{ ++ ed_t * ed; ++ __u32 edINFO; ++ __u32 tdINFO; ++ td_t * td = NULL, * td_next = NULL, * tdHeadP = NULL, * tdTailP; ++ __u32 * td_p; ++ int ctrl = 0, bulk = 0; ++ ++ for (ed = ohci->ed_rm_list[frame]; ed != NULL; ed = ed->ed_rm_list) { ++ ++ tdTailP = dma_to_td (ohci, le32_to_cpup (&ed->hwTailP) & 0xfffffff0); ++ tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP) & 0xfffffff0); ++ edINFO = le32_to_cpup (&ed->hwINFO); ++ td_p = &ed->hwHeadP; ++ ++ for (td = tdHeadP; td != tdTailP; td = td_next) { ++ struct urb * urb = td->urb; ++ urb_priv_t * urb_priv = td->urb->hcpriv; ++ ++ td_next = dma_to_td (ohci, le32_to_cpup (&td->hwNextTD) & 0xfffffff0); ++ if ((urb_priv->state == URB_DEL) || (ed->state & ED_DEL)) { ++ tdINFO = le32_to_cpup (&td->hwINFO); ++ if (TD_CC_GET (tdINFO) < 0xE) ++ dl_transfer_length (td); ++ *td_p = td->hwNextTD | (*td_p & cpu_to_le32 (0x3)); ++ ++ /* URB is done; clean up */ ++ if (++(urb_priv->td_cnt) == urb_priv->length) ++ dl_del_urb (ohci, urb); ++ } else { ++ td_p = &td->hwNextTD; ++ } ++ } ++ ++ if (ed->state & ED_DEL) { /* set by sohci_free_dev */ ++ struct ohci_device * dev = usb_to_ohci (ohci->dev[edINFO & 0x7F]); ++ td_free (ohci, tdTailP); /* free dummy td */ ++ ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); ++ ed->state = ED_NEW; ++ hash_free_ed(ohci, ed); ++ /* if all eds are removed wake up sohci_free_dev */ ++ if (!--dev->ed_cnt) { ++ wait_queue_head_t *wait_head = dev->wait; ++ ++ dev->wait = 0; ++ if (wait_head) ++ wake_up (wait_head); ++ } ++ } else { ++ ed->state &= ~ED_URB_DEL; ++ tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP) & 0xfffffff0); ++ ++ if (tdHeadP == tdTailP) { ++ if (ed->state == ED_OPER) ++ ep_unlink(ohci, ed); ++ } else ++ ed->hwINFO &= ~cpu_to_le32 (OHCI_ED_SKIP); ++ } ++ ++ switch (ed->type) { ++ case PIPE_CONTROL: ++ ctrl = 1; ++ break; ++ case PIPE_BULK: ++ bulk = 1; ++ break; ++ } ++ } ++ ++ /* maybe reenable control and bulk lists */ ++ if (!ohci->disabled) { ++ if (ctrl) /* reset control list */ ++ writel (0, &ohci->regs->ed_controlcurrent); ++ if (bulk) /* reset bulk list */ ++ writel (0, &ohci->regs->ed_bulkcurrent); ++ if (!ohci->ed_rm_list[!frame] && !ohci->sleeping) { ++ if (ohci->ed_controltail) ++ ohci->hc_control |= OHCI_CTRL_CLE; ++ if (ohci->ed_bulktail) ++ ohci->hc_control |= OHCI_CTRL_BLE; ++ writel (ohci->hc_control, &ohci->regs->control); ++ } ++ } ++ ++ ohci->ed_rm_list[frame] = NULL; ++} ++ ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* td done list */ ++ ++static void dl_done_list (ohci_t * ohci, td_t * td_list) ++{ ++ td_t * td_list_next = NULL; ++ ed_t * ed; ++ int cc = 0; ++ struct urb * urb; ++ urb_priv_t * urb_priv; ++ __u32 tdINFO, edHeadP, edTailP; ++ ++ while (td_list) { ++ td_list_next = td_list->next_dl_td; ++ ++ urb = td_list->urb; ++ urb_priv = urb->hcpriv; ++ tdINFO = le32_to_cpup (&td_list->hwINFO); ++ ++ ed = td_list->ed; ++ ++ dl_transfer_length(td_list); ++ ++ /* error code of transfer */ ++ cc = TD_CC_GET (tdINFO); ++ if (cc == TD_CC_STALL) ++ usb_endpoint_halt(urb->dev, ++ usb_pipeendpoint(urb->pipe), ++ usb_pipeout(urb->pipe)); ++ ++ if (!(urb->transfer_flags & USB_DISABLE_SPD) ++ && (cc == TD_DATAUNDERRUN)) ++ cc = TD_CC_NOERROR; ++ ++ if (++(urb_priv->td_cnt) == urb_priv->length) { ++ if ((ed->state & (ED_OPER | ED_UNLINK)) ++ && (urb_priv->state != URB_DEL)) { ++ urb->status = cc_to_error[cc]; ++ sohci_return_urb (ohci, urb); ++ } else { ++ dl_del_urb (ohci, urb); ++ } ++ } ++ ++ if (ed->state != ED_NEW) { ++ edHeadP = le32_to_cpup (&ed->hwHeadP) & 0xfffffff0; ++ edTailP = le32_to_cpup (&ed->hwTailP); ++ ++ /* unlink eds if they are not busy */ ++ if ((edHeadP == edTailP) && (ed->state == ED_OPER)) ++ ep_unlink (ohci, ed); ++ } ++ ++ td_list = td_list_next; ++ } ++} ++ ++ ++ ++ ++/*-------------------------------------------------------------------------* ++ * Virtual Root Hub ++ *-------------------------------------------------------------------------*/ ++ ++/* Device descriptor */ ++static __u8 root_hub_dev_des[] = ++{ ++ 0x12, /* __u8 bLength; */ ++ 0x01, /* __u8 bDescriptorType; Device */ ++ 0x10, /* __u16 bcdUSB; v1.1 */ ++ 0x01, ++ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ ++ 0x00, /* __u8 bDeviceSubClass; */ ++ 0x00, /* __u8 bDeviceProtocol; */ ++ 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ ++ 0x00, /* __u16 idVendor; */ ++ 0x00, ++ 0x00, /* __u16 idProduct; */ ++ 0x00, ++ 0x00, /* __u16 bcdDevice; */ ++ 0x00, ++ 0x00, /* __u8 iManufacturer; */ ++ 0x02, /* __u8 iProduct; */ ++ 0x01, /* __u8 iSerialNumber; */ ++ 0x01 /* __u8 bNumConfigurations; */ ++}; ++ ++ ++/* Configuration descriptor */ ++static __u8 root_hub_config_des[] = ++{ ++ 0x09, /* __u8 bLength; */ ++ 0x02, /* __u8 bDescriptorType; Configuration */ ++ 0x19, /* __u16 wTotalLength; */ ++ 0x00, ++ 0x01, /* __u8 bNumInterfaces; */ ++ 0x01, /* __u8 bConfigurationValue; */ ++ 0x00, /* __u8 iConfiguration; */ ++ 0x40, /* __u8 bmAttributes; ++ Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ ++ 0x00, /* __u8 MaxPower; */ ++ ++ /* interface */ ++ 0x09, /* __u8 if_bLength; */ ++ 0x04, /* __u8 if_bDescriptorType; Interface */ ++ 0x00, /* __u8 if_bInterfaceNumber; */ ++ 0x00, /* __u8 if_bAlternateSetting; */ ++ 0x01, /* __u8 if_bNumEndpoints; */ ++ 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ ++ 0x00, /* __u8 if_bInterfaceSubClass; */ ++ 0x00, /* __u8 if_bInterfaceProtocol; */ ++ 0x00, /* __u8 if_iInterface; */ ++ ++ /* endpoint */ ++ 0x07, /* __u8 ep_bLength; */ ++ 0x05, /* __u8 ep_bDescriptorType; Endpoint */ ++ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ ++ 0x03, /* __u8 ep_bmAttributes; Interrupt */ ++ 0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */ ++ 0x00, ++ 0xff /* __u8 ep_bInterval; 255 ms */ ++}; ++ ++/* Hub class-specific descriptor is constructed dynamically */ ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* prepare Interrupt pipe data; HUB INTERRUPT ENDPOINT */ ++ ++static int rh_send_irq (ohci_t * ohci, void * rh_data, int rh_len) ++{ ++ int num_ports; ++ int i; ++ int ret; ++ int len; ++ ++ __u8 data[8]; ++ ++ num_ports = roothub_a (ohci) & RH_A_NDP; ++ if (num_ports > MAX_ROOT_PORTS) { ++ err ("bogus NDP=%d for OHCI usb-%s", num_ports, ++ ohci->ohci_dev->slot_name); ++ err ("rereads as NDP=%d", ++ readl (&ohci->regs->roothub.a) & RH_A_NDP); ++ /* retry later; "should not happen" */ ++ return 0; ++ } ++ *(__u8 *) data = (roothub_status (ohci) & (RH_HS_LPSC | RH_HS_OCIC)) ++ ? 1: 0; ++ ret = *(__u8 *) data; ++ ++ for ( i = 0; i < num_ports; i++) { ++ *(__u8 *) (data + (i + 1) / 8) |= ++ ((roothub_portstatus (ohci, i) & ++ (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC | RH_PS_PRSC)) ++ ? 1: 0) << ((i + 1) % 8); ++ ret += *(__u8 *) (data + (i + 1) / 8); ++ } ++ len = i/8 + 1; ++ ++ if (ret > 0) { ++ memcpy(rh_data, data, ++ min_t(unsigned int, len, ++ min_t(unsigned int, rh_len, sizeof(data)))); ++ return len; ++ } ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* Virtual Root Hub INTs are polled by this timer every "interval" ms */ ++ ++static void rh_int_timer_do (unsigned long ptr) ++{ ++ int len; ++ ++ struct urb * urb = (struct urb *) ptr; ++ ohci_t * ohci = urb->dev->bus->hcpriv; ++ ++ if (ohci->disabled) ++ return; ++ ++ /* ignore timers firing during PM suspend, etc */ ++ if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) ++ goto out; ++ ++ if(ohci->rh.send) { ++ len = rh_send_irq (ohci, urb->transfer_buffer, urb->transfer_buffer_length); ++ if (len > 0) { ++ urb->actual_length = len; ++#ifdef DEBUG ++ urb_print (urb, "RET-t(rh)", usb_pipeout (urb->pipe)); ++#endif ++ if (urb->complete) ++ urb->complete (urb); ++ } ++ } ++ out: ++ rh_init_int_timer (urb); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* Root Hub INTs are polled by this timer */ ++ ++static int rh_init_int_timer (struct urb * urb) ++{ ++ ohci_t * ohci = urb->dev->bus->hcpriv; ++ ++ ohci->rh.interval = urb->interval; ++ init_timer (&ohci->rh.rh_int_timer); ++ ohci->rh.rh_int_timer.function = rh_int_timer_do; ++ ohci->rh.rh_int_timer.data = (unsigned long) urb; ++ ohci->rh.rh_int_timer.expires = ++ jiffies + (HZ * (urb->interval < 30? 30: urb->interval)) / 1000; ++ add_timer (&ohci->rh.rh_int_timer); ++ ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++#define OK(x) len = (x); break ++#define WR_RH_STAT(x) writel((x), &ohci->regs->roothub.status) ++#define WR_RH_PORTSTAT(x) writel((x), &ohci->regs->roothub.portstatus[wIndex-1]) ++#define RD_RH_STAT roothub_status(ohci) ++#define RD_RH_PORTSTAT roothub_portstatus(ohci,wIndex-1) ++ ++/* request to virtual root hub */ ++ ++static int rh_submit_urb (struct urb * urb) ++{ ++ struct usb_device * usb_dev = urb->dev; ++ ohci_t * ohci = usb_dev->bus->hcpriv; ++ unsigned int pipe = urb->pipe; ++ struct usb_ctrlrequest * cmd = (struct usb_ctrlrequest *) urb->setup_packet; ++ void * data = urb->transfer_buffer; ++ int leni = urb->transfer_buffer_length; ++ int len = 0; ++ int status = TD_CC_NOERROR; ++ unsigned long flags; ++ ++ __u32 datab[4]; ++ __u8 * data_buf = (__u8 *) datab; ++ ++ __u16 bmRType_bReq; ++ __u16 wValue; ++ __u16 wIndex; ++ __u16 wLength; ++ ++ spin_lock_irqsave(&ohci->ohci_lock, flags); ++ ++ if (usb_pipeint(pipe)) { ++ ohci->rh.urb = urb; ++ ohci->rh.send = 1; ++ ohci->rh.interval = urb->interval; ++ rh_init_int_timer(urb); ++ urb->status = cc_to_error [TD_CC_NOERROR]; ++ ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ return 0; ++ } ++ ++ bmRType_bReq = cmd->bRequestType | (cmd->bRequest << 8); ++ wValue = le16_to_cpu (cmd->wValue); ++ wIndex = le16_to_cpu (cmd->wIndex); ++ wLength = le16_to_cpu (cmd->wLength); ++ ++ switch (bmRType_bReq) { ++ /* Request Destination: ++ without flags: Device, ++ RH_INTERFACE: interface, ++ RH_ENDPOINT: endpoint, ++ RH_CLASS means HUB here, ++ RH_OTHER | RH_CLASS almost ever means HUB_PORT here ++ */ ++ ++ case RH_GET_STATUS: ++ *(__u16 *) data_buf = cpu_to_le16 (1); OK (2); ++ case RH_GET_STATUS | RH_INTERFACE: ++ *(__u16 *) data_buf = cpu_to_le16 (0); OK (2); ++ case RH_GET_STATUS | RH_ENDPOINT: ++ *(__u16 *) data_buf = cpu_to_le16 (0); OK (2); ++ case RH_GET_STATUS | RH_CLASS: ++ *(__u32 *) data_buf = cpu_to_le32 ( ++ RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE)); ++ OK (4); ++ case RH_GET_STATUS | RH_OTHER | RH_CLASS: ++ *(__u32 *) data_buf = cpu_to_le32 (RD_RH_PORTSTAT); OK (4); ++ ++ case RH_CLEAR_FEATURE | RH_ENDPOINT: ++ switch (wValue) { ++ case (RH_ENDPOINT_STALL): OK (0); ++ } ++ break; ++ ++ case RH_CLEAR_FEATURE | RH_CLASS: ++ switch (wValue) { ++ case RH_C_HUB_LOCAL_POWER: ++ OK(0); ++ case (RH_C_HUB_OVER_CURRENT): ++ WR_RH_STAT(RH_HS_OCIC); OK (0); ++ } ++ break; ++ ++ case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: ++ switch (wValue) { ++ case (RH_PORT_ENABLE): ++ WR_RH_PORTSTAT (RH_PS_CCS ); OK (0); ++ case (RH_PORT_SUSPEND): ++ WR_RH_PORTSTAT (RH_PS_POCI); OK (0); ++ case (RH_PORT_POWER): ++ WR_RH_PORTSTAT (RH_PS_LSDA); OK (0); ++ case (RH_C_PORT_CONNECTION): ++ WR_RH_PORTSTAT (RH_PS_CSC ); OK (0); ++ case (RH_C_PORT_ENABLE): ++ WR_RH_PORTSTAT (RH_PS_PESC); OK (0); ++ case (RH_C_PORT_SUSPEND): ++ WR_RH_PORTSTAT (RH_PS_PSSC); OK (0); ++ case (RH_C_PORT_OVER_CURRENT): ++ WR_RH_PORTSTAT (RH_PS_OCIC); OK (0); ++ case (RH_C_PORT_RESET): ++ WR_RH_PORTSTAT (RH_PS_PRSC); OK (0); ++ } ++ break; ++ ++ case RH_SET_FEATURE | RH_OTHER | RH_CLASS: ++ switch (wValue) { ++ case (RH_PORT_SUSPEND): ++ WR_RH_PORTSTAT (RH_PS_PSS ); OK (0); ++ case (RH_PORT_RESET): /* BUG IN HUP CODE *********/ ++ if (RD_RH_PORTSTAT & RH_PS_CCS) ++ WR_RH_PORTSTAT (RH_PS_PRS); ++ OK (0); ++ case (RH_PORT_POWER): ++ WR_RH_PORTSTAT (RH_PS_PPS ); OK (0); ++ case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/ ++ if (RD_RH_PORTSTAT & RH_PS_CCS) ++ WR_RH_PORTSTAT (RH_PS_PES ); ++ OK (0); ++ } ++ break; ++ ++ case RH_SET_ADDRESS: ohci->rh.devnum = wValue; OK(0); ++ ++ case RH_GET_DESCRIPTOR: ++ switch ((wValue & 0xff00) >> 8) { ++ case (0x01): /* device descriptor */ ++ len = min_t(unsigned int, ++ leni, ++ min_t(unsigned int, ++ sizeof (root_hub_dev_des), ++ wLength)); ++ data_buf = root_hub_dev_des; OK(len); ++ case (0x02): /* configuration descriptor */ ++ len = min_t(unsigned int, ++ leni, ++ min_t(unsigned int, ++ sizeof (root_hub_config_des), ++ wLength)); ++ data_buf = root_hub_config_des; OK(len); ++ case (0x03): /* string descriptors */ ++ len = usb_root_hub_string (wValue & 0xff, ++ (int)(long) ohci->regs, "OHCI", ++ data, wLength); ++ if (len > 0) { ++ data_buf = data; ++ OK(min_t(int, leni, len)); ++ } ++ // else fallthrough ++ default: ++ status = TD_CC_STALL; ++ } ++ break; ++ ++ case RH_GET_DESCRIPTOR | RH_CLASS: ++ { ++ __u32 temp = roothub_a (ohci); ++ ++ data_buf [0] = 9; // min length; ++ data_buf [1] = 0x29; ++ data_buf [2] = temp & RH_A_NDP; ++ data_buf [3] = 0; ++ if (temp & RH_A_PSM) /* per-port power switching? */ ++ data_buf [3] |= 0x1; ++ if (temp & RH_A_NOCP) /* no overcurrent reporting? */ ++ data_buf [3] |= 0x10; ++ else if (temp & RH_A_OCPM) /* per-port overcurrent reporting? */ ++ data_buf [3] |= 0x8; ++ ++ datab [1] = 0; ++ data_buf [5] = (temp & RH_A_POTPGT) >> 24; ++ temp = roothub_b (ohci); ++ data_buf [7] = temp & RH_B_DR; ++ if (data_buf [2] < 7) { ++ data_buf [8] = 0xff; ++ } else { ++ data_buf [0] += 2; ++ data_buf [8] = (temp & RH_B_DR) >> 8; ++ data_buf [10] = data_buf [9] = 0xff; ++ } ++ ++ len = min_t(unsigned int, leni, ++ min_t(unsigned int, data_buf [0], wLength)); ++ OK (len); ++ } ++ ++ case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1); ++ ++ case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0); ++ ++ default: ++ dbg ("unsupported root hub command"); ++ status = TD_CC_STALL; ++ } ++ ++#ifdef DEBUG ++ // ohci_dump_roothub (ohci, 0); ++#endif ++ ++ len = min_t(int, len, leni); ++ if (data != data_buf) ++ memcpy (data, data_buf, len); ++ urb->actual_length = len; ++ urb->status = cc_to_error [status]; ++ ++#ifdef DEBUG ++ urb_print (urb, "RET(rh)", usb_pipeout (urb->pipe)); ++#endif ++ ++ urb->hcpriv = NULL; ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ usb_dec_dev_use (usb_dev); ++ urb->dev = NULL; ++ if (urb->complete) ++ urb->complete (urb); ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int rh_unlink_urb (struct urb * urb) ++{ ++ ohci_t * ohci = urb->dev->bus->hcpriv; ++ unsigned int flags; ++ ++ spin_lock_irqsave(&ohci->ohci_lock, flags); ++ if (ohci->rh.urb == urb) { ++ ohci->rh.send = 0; ++ del_timer (&ohci->rh.rh_int_timer); ++ ohci->rh.urb = NULL; ++ ++ urb->hcpriv = NULL; ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ usb_dec_dev_use(urb->dev); ++ urb->dev = NULL; ++ if (urb->transfer_flags & USB_ASYNC_UNLINK) { ++ urb->status = -ECONNRESET; ++ if (urb->complete) ++ urb->complete (urb); ++ } else ++ urb->status = -ENOENT; ++ } else { ++ spin_unlock_irqrestore(&ohci->ohci_lock, flags); ++ } ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------* ++ * HC functions ++ *-------------------------------------------------------------------------*/ ++ ++/* reset the HC and BUS */ ++ ++static int hc_reset (ohci_t * ohci) ++{ ++ int timeout = 30; ++ int smm_timeout = 50; /* 0,5 sec */ ++ ++#ifndef __hppa__ ++ /* PA-RISC doesn't have SMM, but PDC might leave IR set */ ++ if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */ ++ writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */ ++ dbg("USB HC TakeOver from SMM"); ++ while (readl (&ohci->regs->control) & OHCI_CTRL_IR) { ++ wait_ms (10); ++ if (--smm_timeout == 0) { ++ err("USB HC TakeOver failed!"); ++ return -1; ++ } ++ } ++ } ++#endif ++ ++ /* Disable HC interrupts */ ++ writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); ++ ++ dbg("USB HC reset_hc usb-%s: ctrl = 0x%x ;", ++ ohci->ohci_dev->slot_name, ++ readl (&ohci->regs->control)); ++ ++ /* Reset USB (needed by some controllers) */ ++ writel (0, &ohci->regs->control); ++ ++ /* Force a state change from USBRESET to USBOPERATIONAL for ALi */ ++ (void) readl (&ohci->regs->control); /* PCI posting */ ++ writel (ohci->hc_control = OHCI_USB_OPER, &ohci->regs->control); ++ ++ /* HC Reset requires max 10 ms delay */ ++ writel (OHCI_HCR, &ohci->regs->cmdstatus); ++ while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { ++ if (--timeout == 0) { ++ err("USB HC reset timed out!"); ++ return -1; ++ } ++ udelay (1); ++ } ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* Start an OHCI controller, set the BUS operational ++ * enable interrupts ++ * connect the virtual root hub */ ++ ++static int hc_start (ohci_t * ohci) ++{ ++ __u32 mask; ++ unsigned int fminterval; ++ struct usb_device * usb_dev; ++ struct ohci_device * dev; ++ ++ ohci->disabled = 1; ++ ++ /* Tell the controller where the control and bulk lists are ++ * The lists are empty now. */ ++ ++ writel (0, &ohci->regs->ed_controlhead); ++ writel (0, &ohci->regs->ed_bulkhead); ++ ++ writel (ohci->hcca_dma, &ohci->regs->hcca); /* a reset clears this */ ++ ++ fminterval = 0x2edf; ++ writel ((fminterval * 9) / 10, &ohci->regs->periodicstart); ++ fminterval |= ((((fminterval - 210) * 6) / 7) << 16); ++ writel (fminterval, &ohci->regs->fminterval); ++ writel (0x628, &ohci->regs->lsthresh); ++ ++ /* start controller operations */ ++ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; ++ ohci->disabled = 0; ++ writel (ohci->hc_control, &ohci->regs->control); ++ ++ /* Choose the interrupts we care about now, others later on demand */ ++ mask = OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; ++ writel (mask, &ohci->regs->intrenable); ++ writel (mask, &ohci->regs->intrstatus); ++ ++#ifdef OHCI_USE_NPS ++ if(ohci->flags & OHCI_QUIRK_SUCKYIO) ++ { ++ /* NSC 87560 at least requires different setup .. */ ++ writel ((roothub_a (ohci) | RH_A_NOCP) & ++ ~(RH_A_OCPM | RH_A_POTPGT | RH_A_PSM | RH_A_NPS), ++ &ohci->regs->roothub.a); ++ } ++ else ++ { ++ /* required for AMD-756 and some Mac platforms */ ++ writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM, ++ &ohci->regs->roothub.a); ++ } ++ writel (RH_HS_LPSC, &ohci->regs->roothub.status); ++#endif /* OHCI_USE_NPS */ ++ ++ (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ ++ ++ // POTPGT delay is bits 24-31, in 2 ms units. ++ mdelay ((roothub_a (ohci) >> 23) & 0x1fe); ++ ++ /* connect the virtual root hub */ ++ ohci->rh.devnum = 0; ++ usb_dev = usb_alloc_dev (NULL, ohci->bus); ++ if (!usb_dev) { ++ ohci->disabled = 1; ++ return -ENOMEM; ++ } ++ ++ dev = usb_to_ohci (usb_dev); ++ ohci->bus->root_hub = usb_dev; ++ usb_connect (usb_dev); ++ if (usb_new_device (usb_dev) != 0) { ++ usb_free_dev (usb_dev); ++ ohci->disabled = 1; ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* called only from interrupt handler */ ++ ++static void check_timeouts (struct ohci *ohci) ++{ ++ spin_lock (&ohci->ohci_lock); ++ while (!list_empty (&ohci->timeout_list)) { ++ struct urb *urb; ++ ++ urb = list_entry (ohci->timeout_list.next, struct urb, urb_list); ++ if (time_after (jiffies, urb->timeout)) ++ break; ++ ++ list_del_init (&urb->urb_list); ++ if (urb->status != -EINPROGRESS) ++ continue; ++ ++ urb->transfer_flags |= USB_TIMEOUT_KILLED | USB_ASYNC_UNLINK; ++ spin_unlock (&ohci->ohci_lock); ++ ++ // outside the interrupt handler (in a timer...) ++ // this reference would race interrupts ++ sohci_unlink_urb (urb); ++ ++ spin_lock (&ohci->ohci_lock); ++ } ++ spin_unlock (&ohci->ohci_lock); ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* an interrupt happens */ ++ ++static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r) ++{ ++ ohci_t * ohci = __ohci; ++ struct ohci_regs * regs = ohci->regs; ++ int ints; ++ ++ spin_lock (&ohci->ohci_lock); ++ ++ /* avoid (slow) readl if only WDH happened */ ++ if ((ohci->hcca->done_head != 0) ++ && !(le32_to_cpup (&ohci->hcca->done_head) & 0x01)) { ++ ints = OHCI_INTR_WDH; ++ ++ /* cardbus/... hardware gone before remove() */ ++ } else if ((ints = readl (®s->intrstatus)) == ~(u32)0) { ++ ohci->disabled++; ++ spin_unlock (&ohci->ohci_lock); ++ err ("%s device removed!", ohci->ohci_dev->slot_name); ++ return; ++ ++ /* interrupt for some other device? */ ++ } else if ((ints &= readl (®s->intrenable)) == 0) { ++ spin_unlock (&ohci->ohci_lock); ++ return; ++ } ++ ++ // dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); ++ ++ if (ints & OHCI_INTR_UE) { ++ ohci->disabled++; ++ err ("OHCI Unrecoverable Error, controller usb-%s disabled", ++ ohci->ohci_dev->slot_name); ++ // e.g. due to PCI Master/Target Abort ++ ++#ifdef DEBUG ++ ohci_dump (ohci, 1); ++#else ++ // FIXME: be optimistic, hope that bug won't repeat often. ++ // Make some non-interrupt context restart the controller. ++ // Count and limit the retries though; either hardware or ++ // software errors can go forever... ++#endif ++ hc_reset (ohci); ++ } ++ ++ if (ints & OHCI_INTR_WDH) { ++ writel (OHCI_INTR_WDH, ®s->intrdisable); ++ (void)readl (®s->intrdisable); /* PCI posting flush */ ++ dl_done_list (ohci, dl_reverse_done_list (ohci)); ++ writel (OHCI_INTR_WDH, ®s->intrenable); ++ (void)readl (®s->intrdisable); /* PCI posting flush */ ++ } ++ ++ if (ints & OHCI_INTR_SO) { ++ dbg("USB Schedule overrun"); ++ writel (OHCI_INTR_SO, ®s->intrenable); ++ (void)readl (®s->intrdisable); /* PCI posting flush */ ++ } ++ ++ // FIXME: this assumes SOF (1/ms) interrupts don't get lost... ++ if (ints & OHCI_INTR_SF) { ++ unsigned int frame = le16_to_cpu (ohci->hcca->frame_no) & 1; ++ writel (OHCI_INTR_SF, ®s->intrdisable); ++ (void)readl (®s->intrdisable); /* PCI posting flush */ ++ if (ohci->ed_rm_list[!frame] != NULL) { ++ dl_del_list (ohci, !frame); ++ } ++ if (ohci->ed_rm_list[frame] != NULL) { ++ writel (OHCI_INTR_SF, ®s->intrenable); ++ (void)readl (®s->intrdisable); /* PCI posting flush */ ++ } ++ } ++ ++ /* ++ * Finally, we are done with trashing about our hardware lists ++ * and other CPUs are allowed in. The festive flipping of the lock ++ * ensues as we struggle with the check_timeouts disaster. ++ */ ++ spin_unlock (&ohci->ohci_lock); ++ ++ if (!list_empty (&ohci->timeout_list)) { ++ check_timeouts (ohci); ++// FIXME: enable SF as needed in a timer; ++// don't make lots of 1ms interrupts ++// On unloaded USB, think 4k ~= 4-5msec ++ if (!list_empty (&ohci->timeout_list)) ++ writel (OHCI_INTR_SF, ®s->intrenable); ++ } ++ ++ writel (ints, ®s->intrstatus); ++ writel (OHCI_INTR_MIE, ®s->intrenable); ++ (void)readl (®s->intrdisable); /* PCI posting flush */ ++ ++ ohci_complete(ohci); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* allocate OHCI */ ++ ++static ohci_t * __devinit hc_alloc_ohci (struct pci_dev *dev, void * mem_base) ++{ ++ ohci_t * ohci; ++ ++ ohci = (ohci_t *) kmalloc (sizeof *ohci, GFP_KERNEL); ++ if (!ohci) ++ return NULL; ++ ++ memset (ohci, 0, sizeof (ohci_t)); ++ ++ ohci->hcca = pci_alloc_consistent (dev, sizeof *ohci->hcca, ++ &ohci->hcca_dma); ++ if (!ohci->hcca) { ++ kfree (ohci); ++ return NULL; ++ } ++ memset (ohci->hcca, 0, sizeof (struct ohci_hcca)); ++ ++ ohci->disabled = 1; ++ ohci->sleeping = 0; ++ ohci->irq = -1; ++ ohci->regs = mem_base; ++ ++ ohci->ohci_dev = dev; ++ pci_set_drvdata(dev, ohci); ++ ++ INIT_LIST_HEAD (&ohci->timeout_list); ++ spin_lock_init(&ohci->ohci_lock); ++ ++ ohci->bus = usb_alloc_bus (&sohci_device_operations); ++ if (!ohci->bus) { ++ pci_set_drvdata (dev, NULL); ++ pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca, ++ ohci->hcca, ohci->hcca_dma); ++ kfree (ohci); ++ return NULL; ++ } ++ ohci->bus->bus_name = dev->slot_name; ++ ohci->bus->hcpriv = (void *) ohci; ++ ++ return ohci; ++} ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* De-allocate all resources.. */ ++ ++static void hc_release_ohci (ohci_t * ohci) ++{ ++ dbg ("USB HC release ohci usb-%s", ohci->ohci_dev->slot_name); ++ ++ /* disconnect all devices */ ++ if (ohci->bus->root_hub) ++ usb_disconnect (&ohci->bus->root_hub); ++ ++ if (!ohci->disabled) ++ hc_reset (ohci); ++ ++ if (ohci->irq >= 0) { ++ free_irq (ohci->irq, ohci); ++ ohci->irq = -1; ++ } ++ pci_set_drvdata(ohci->ohci_dev, NULL); ++ if (ohci->bus) { ++ if (ohci->bus->busnum != -1) ++ usb_deregister_bus (ohci->bus); ++ ++ usb_free_bus (ohci->bus); ++ } ++ ++ ohci_mem_cleanup (ohci); ++ ++ /* unmap the IO address space */ ++ iounmap (ohci->regs); ++ ++ pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca, ++ ohci->hcca, ohci->hcca_dma); ++ kfree (ohci); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* Increment the module usage count, start the control thread and ++ * return success. */ ++ ++static struct pci_driver ohci_pci_driver; ++ ++static int __devinit ++hc_found_ohci (struct pci_dev *dev, int irq, ++ void *mem_base, const struct pci_device_id *id) ++{ ++ ohci_t * ohci; ++ char buf[8], *bufp = buf; ++ int ret; ++ ++#ifndef __sparc__ ++ sprintf(buf, "%d", irq); ++#else ++ bufp = __irq_itoa(irq); ++#endif ++ printk(KERN_INFO __FILE__ ": USB OHCI at membase 0x%lx, IRQ %s\n", ++ (unsigned long) mem_base, bufp); ++ printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name); ++ ++ ohci = hc_alloc_ohci (dev, mem_base); ++ if (!ohci) { ++ return -ENOMEM; ++ } ++ if ((ret = ohci_mem_init (ohci)) < 0) { ++ hc_release_ohci (ohci); ++ return ret; ++ } ++ ohci->flags = id->driver_data; ++ ++ /* Check for NSC87560. We have to look at the bridge (fn1) to identify ++ the USB (fn2). This quirk might apply to more or even all NSC stuff ++ I don't know.. */ ++ ++ if(dev->vendor == PCI_VENDOR_ID_NS) ++ { ++ struct pci_dev *fn1 = pci_find_slot(dev->bus->number, PCI_DEVFN(PCI_SLOT(dev->devfn), 1)); ++ if(fn1 && fn1->vendor == PCI_VENDOR_ID_NS && fn1->device == PCI_DEVICE_ID_NS_87560_LIO) ++ ohci->flags |= OHCI_QUIRK_SUCKYIO; ++ ++ } ++ ++ if (ohci->flags & OHCI_QUIRK_SUCKYIO) ++ printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n"); ++ if (ohci->flags & OHCI_QUIRK_AMD756) ++ printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n"); ++ ++ if (hc_reset (ohci) < 0) { ++ hc_release_ohci (ohci); ++ return -ENODEV; ++ } ++ ++ /* FIXME this is a second HC reset; why?? */ ++ writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control); ++ (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ ++ wait_ms (10); ++ ++ usb_register_bus (ohci->bus); ++ ++ if (request_irq (irq, hc_interrupt, SA_SHIRQ, ++ ohci_pci_driver.name, ohci) != 0) { ++ err ("request interrupt %s failed", bufp); ++ hc_release_ohci (ohci); ++ return -EBUSY; ++ } ++ ohci->irq = irq; ++ ++ if (hc_start (ohci) < 0) { ++ err ("can't start usb-%s", dev->slot_name); ++ hc_release_ohci (ohci); ++ return -EBUSY; ++ } ++ ++#ifdef DEBUG ++ ohci_dump (ohci, 1); ++#endif ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++#ifdef CONFIG_PM ++ ++/* controller died; cleanup debris, then restart */ ++/* must not be called from interrupt context */ ++ ++static void hc_restart (ohci_t *ohci) ++{ ++ int temp; ++ int i; ++ ++ if (ohci->pci_latency) ++ pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, ohci->pci_latency); ++ ++ ohci->disabled = 1; ++ ohci->sleeping = 0; ++ if (ohci->bus->root_hub) ++ usb_disconnect (&ohci->bus->root_hub); ++ ++ /* empty the interrupt branches */ ++ for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0; ++ for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table[i] = 0; ++ ++ /* no EDs to remove */ ++ ohci->ed_rm_list [0] = NULL; ++ ohci->ed_rm_list [1] = NULL; ++ ++ /* empty control and bulk lists */ ++ ohci->ed_isotail = NULL; ++ ohci->ed_controltail = NULL; ++ ohci->ed_bulktail = NULL; ++ ++ if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) { ++ err ("can't restart usb-%s, %d", ohci->ohci_dev->slot_name, temp); ++ } else ++ dbg ("restart usb-%s completed", ohci->ohci_dev->slot_name); ++} ++ ++#endif /* CONFIG_PM */ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* configured so that an OHCI device is always provided */ ++/* always called with process context; sleeping is OK */ ++ ++static int __devinit ++ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ unsigned long mem_resource, mem_len; ++ void *mem_base; ++ int status; ++ ++ if (pci_enable_device(dev) < 0) ++ return -ENODEV; ++ ++ if (!dev->irq) { ++ err("found OHCI device with no IRQ assigned. check BIOS settings!"); ++ pci_disable_device (dev); ++ return -ENODEV; ++ } ++ ++ /* we read its hardware registers as memory */ ++ mem_resource = pci_resource_start(dev, 0); ++ mem_len = pci_resource_len(dev, 0); ++ if (!request_mem_region (mem_resource, mem_len, ohci_pci_driver.name)) { ++ dbg ("controller already in use"); ++ pci_disable_device (dev); ++ return -EBUSY; ++ } ++ ++ mem_base = ioremap_nocache (mem_resource, mem_len); ++ if (!mem_base) { ++ err("Error mapping OHCI memory"); ++ release_mem_region (mem_resource, mem_len); ++ pci_disable_device (dev); ++ return -EFAULT; ++ } ++ ++ /* controller writes into our memory */ ++ pci_set_master (dev); ++ ++ status = hc_found_ohci (dev, dev->irq, mem_base, id); ++ if (status < 0) { ++ iounmap (mem_base); ++ release_mem_region (mem_resource, mem_len); ++ pci_disable_device (dev); ++ } ++ return status; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* may be called from interrupt context [interface spec] */ ++/* may be called without controller present */ ++/* may be called with controller, bus, and devices active */ ++ ++static void __devexit ++ohci_pci_remove (struct pci_dev *dev) ++{ ++ ohci_t *ohci = pci_get_drvdata(dev); ++ ++ dbg ("remove %s controller usb-%s%s%s", ++ hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS), ++ dev->slot_name, ++ ohci->disabled ? " (disabled)" : "", ++ in_interrupt () ? " in interrupt" : "" ++ ); ++#ifdef DEBUG ++ ohci_dump (ohci, 1); ++#endif ++ ++ /* don't wake up sleeping controllers, or block in interrupt context */ ++ if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER || in_interrupt ()) { ++ dbg ("controller being disabled"); ++ ohci->disabled = 1; ++ } ++ ++ /* on return, USB will always be reset (if present) */ ++ if (ohci->disabled) ++ writel (ohci->hc_control = OHCI_USB_RESET, ++ &ohci->regs->control); ++ ++ hc_release_ohci (ohci); ++ ++ release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0)); ++ pci_disable_device (dev); ++} ++ ++ ++#ifdef CONFIG_PM ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int ++ohci_pci_suspend (struct pci_dev *dev, u32 state) ++{ ++ ohci_t *ohci = pci_get_drvdata(dev); ++ unsigned long flags; ++ u16 cmd; ++ ++ if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) { ++ dbg ("can't suspend usb-%s (state is %s)", dev->slot_name, ++ hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS)); ++ return -EIO; ++ } ++ ++ /* act as if usb suspend can always be used */ ++ info ("USB suspend: usb-%s", dev->slot_name); ++ ohci->sleeping = 1; ++ ++ /* First stop processing */ ++ spin_lock_irqsave (&ohci->ohci_lock, flags); ++ ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE); ++ writel (ohci->hc_control, &ohci->regs->control); ++ writel (OHCI_INTR_SF, &ohci->regs->intrstatus); ++ (void) readl (&ohci->regs->intrstatus); ++ spin_unlock_irqrestore (&ohci->ohci_lock, flags); ++ ++ /* Wait a frame or two */ ++ mdelay(1); ++ if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF) ++ mdelay (1); ++ ++#ifdef CONFIG_PMAC_PBOOK ++ if (_machine == _MACH_Pmac) ++ disable_irq (ohci->irq); ++ /* else, 2.4 assumes shared irqs -- don't disable */ ++#endif ++ /* Enable remote wakeup */ ++ writel (readl(&ohci->regs->intrenable) | OHCI_INTR_RD, &ohci->regs->intrenable); ++ ++ /* Suspend chip and let things settle down a bit */ ++ ohci->hc_control = OHCI_USB_SUSPEND; ++ writel (ohci->hc_control, &ohci->regs->control); ++ (void) readl (&ohci->regs->control); ++ mdelay (500); /* No schedule here ! */ ++ switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) { ++ case OHCI_USB_RESET: ++ dbg("Bus in reset phase ???"); ++ break; ++ case OHCI_USB_RESUME: ++ dbg("Bus in resume phase ???"); ++ break; ++ case OHCI_USB_OPER: ++ dbg("Bus in operational phase ???"); ++ break; ++ case OHCI_USB_SUSPEND: ++ dbg("Bus suspended"); ++ break; ++ } ++ /* In some rare situations, Apple's OHCI have happily trashed ++ * memory during sleep. We disable it's bus master bit during ++ * suspend ++ */ ++ pci_read_config_word (dev, PCI_COMMAND, &cmd); ++ cmd &= ~PCI_COMMAND_MASTER; ++ pci_write_config_word (dev, PCI_COMMAND, cmd); ++#ifdef CONFIG_PMAC_PBOOK ++ { ++ struct device_node *of_node; ++ ++ /* Disable USB PAD & cell clock */ ++ of_node = pci_device_to_OF_node (ohci->ohci_dev); ++ if (of_node) ++ pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0); ++ } ++#endif ++ return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int ++ohci_pci_resume (struct pci_dev *dev) ++{ ++ ohci_t *ohci = pci_get_drvdata(dev); ++ int temp; ++ unsigned long flags; ++ ++ /* guard against multiple resumes */ ++ atomic_inc (&ohci->resume_count); ++ if (atomic_read (&ohci->resume_count) != 1) { ++ err ("concurrent PCI resumes for usb-%s", dev->slot_name); ++ atomic_dec (&ohci->resume_count); ++ return 0; ++ } ++ ++#ifdef CONFIG_PMAC_PBOOK ++ { ++ struct device_node *of_node; ++ ++ /* Re-enable USB PAD & cell clock */ ++ of_node = pci_device_to_OF_node (ohci->ohci_dev); ++ if (of_node) ++ pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 1); ++ } ++#endif ++ ++ /* did we suspend, or were we powered off? */ ++ ohci->hc_control = readl (&ohci->regs->control); ++ temp = ohci->hc_control & OHCI_CTRL_HCFS; ++ ++#ifdef DEBUG ++ /* the registers may look crazy here */ ++ ohci_dump_status (ohci); ++#endif ++ ++ /* Re-enable bus mastering */ ++ pci_set_master(ohci->ohci_dev); ++ ++ switch (temp) { ++ ++ case OHCI_USB_RESET: // lost power ++ info ("USB restart: usb-%s", dev->slot_name); ++ hc_restart (ohci); ++ break; ++ ++ case OHCI_USB_SUSPEND: // host wakeup ++ case OHCI_USB_RESUME: // remote wakeup ++ info ("USB continue: usb-%s from %s wakeup", dev->slot_name, ++ (temp == OHCI_USB_SUSPEND) ++ ? "host" : "remote"); ++ ohci->hc_control = OHCI_USB_RESUME; ++ writel (ohci->hc_control, &ohci->regs->control); ++ (void) readl (&ohci->regs->control); ++ mdelay (20); /* no schedule here ! */ ++ /* Some controllers (lucent) need a longer delay here */ ++ mdelay (15); ++ temp = readl (&ohci->regs->control); ++ temp = ohci->hc_control & OHCI_CTRL_HCFS; ++ if (temp != OHCI_USB_RESUME) { ++ err ("controller usb-%s won't resume", dev->slot_name); ++ ohci->disabled = 1; ++ return -EIO; ++ } ++ ++ /* Some chips likes being resumed first */ ++ writel (OHCI_USB_OPER, &ohci->regs->control); ++ (void) readl (&ohci->regs->control); ++ mdelay (3); ++ ++ /* Then re-enable operations */ ++ spin_lock_irqsave (&ohci->ohci_lock, flags); ++ ohci->disabled = 0; ++ ohci->sleeping = 0; ++ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; ++ if (!ohci->ed_rm_list[0] && !ohci->ed_rm_list[1]) { ++ if (ohci->ed_controltail) ++ ohci->hc_control |= OHCI_CTRL_CLE; ++ if (ohci->ed_bulktail) ++ ohci->hc_control |= OHCI_CTRL_BLE; ++ } ++ writel (ohci->hc_control, &ohci->regs->control); ++ writel (OHCI_INTR_SF, &ohci->regs->intrstatus); ++ writel (OHCI_INTR_SF, &ohci->regs->intrenable); ++ /* Check for a pending done list */ ++ writel (OHCI_INTR_WDH, &ohci->regs->intrdisable); ++ (void) readl (&ohci->regs->intrdisable); ++#ifdef CONFIG_PMAC_PBOOK ++ if (_machine == _MACH_Pmac) ++ enable_irq (ohci->irq); ++#endif ++ if (ohci->hcca->done_head) ++ dl_done_list (ohci, dl_reverse_done_list (ohci)); ++ writel (OHCI_INTR_WDH, &ohci->regs->intrenable); ++ writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ ++ writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ ++ spin_unlock_irqrestore (&ohci->ohci_lock, flags); ++ break; ++ ++ default: ++ warn ("odd PCI resume for usb-%s", dev->slot_name); ++ } ++ ++ /* controller is operational, extra resumes are harmless */ ++ atomic_dec (&ohci->resume_count); ++ ++ return 0; ++} ++ ++#endif /* CONFIG_PM */ ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static const struct pci_device_id __devinitdata ohci_pci_ids [] = { { ++ ++ /* ++ * AMD-756 [Viper] USB has a serious erratum when used with ++ * lowspeed devices like mice. ++ */ ++ vendor: 0x1022, ++ device: 0x740c, ++ subvendor: PCI_ANY_ID, ++ subdevice: PCI_ANY_ID, ++ ++ driver_data: OHCI_QUIRK_AMD756, ++ ++} , { ++ ++ /* handle any USB OHCI controller */ ++ class: ((PCI_CLASS_SERIAL_USB << 8) | 0x10), ++ class_mask: ~0, ++ ++ /* no matter who makes it */ ++ vendor: PCI_ANY_ID, ++ device: PCI_ANY_ID, ++ subvendor: PCI_ANY_ID, ++ subdevice: PCI_ANY_ID, ++ ++ }, { /* end: all zeroes */ } ++}; ++ ++MODULE_DEVICE_TABLE (pci, ohci_pci_ids); ++ ++static struct pci_driver ohci_pci_driver = { ++ name: "usb-ohci", ++ id_table: &ohci_pci_ids [0], ++ ++ probe: ohci_pci_probe, ++ remove: __devexit_p(ohci_pci_remove), ++ ++#ifdef CONFIG_PM ++ suspend: ohci_pci_suspend, ++ resume: ohci_pci_resume, ++#endif /* PM */ ++}; ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int __init ohci_hcd_init (void) ++{ ++ return pci_module_init (&ohci_pci_driver); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void __exit ohci_hcd_cleanup (void) ++{ ++ pci_unregister_driver (&ohci_pci_driver); ++} ++ ++module_init (ohci_hcd_init); ++module_exit (ohci_hcd_cleanup); ++ ++ ++MODULE_AUTHOR( DRIVER_AUTHOR ); ++MODULE_DESCRIPTION( DRIVER_DESC ); ++MODULE_LICENSE("GPL"); diff --git a/packages/linux/linux-mtx-2-2.4.27/10-iw-max-spy-32.diff b/packages/linux/linux-mtx-2-2.4.27/10-iw-max-spy-32.diff new file mode 100644 index 0000000000..e782d3d3dc --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/10-iw-max-spy-32.diff @@ -0,0 +1,11 @@ +--- linux-mips-2.4.24-pre2/include/linux/wireless.h 2004-11-17 18:05:09.000000000 +0100 ++++ linux/include/linux/wireless.h 2004-11-17 19:02:44.370081592 +0100 +@@ -334,7 +334,7 @@ + * a few of them in the struct iw_range. */ + + /* Maximum of address that you may set with SPY */ +-#define IW_MAX_SPY 8 ++#define IW_MAX_SPY 32 + + /* Maximum of address that you may get in the + list of access points in range */ diff --git a/packages/linux/linux-mtx-2-2.4.27/11-mtd-proc-partition-rw.diff b/packages/linux/linux-mtx-2-2.4.27/11-mtd-proc-partition-rw.diff new file mode 100644 index 0000000000..54ba5fff98 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/11-mtd-proc-partition-rw.diff @@ -0,0 +1,173 @@ +diff -Nurb linux/drivers/mtd/mtdcore.c linux-mtd-rw/drivers/mtd/mtdcore.c +--- linux/drivers/mtd/mtdcore.c 2004-11-18 13:16:00.000000000 +0100 ++++ linux-mtd-rw/drivers/mtd/mtdcore.c 2004-11-18 15:27:13.130036616 +0100 +@@ -25,6 +25,10 @@ + + #include + ++/* this symbol is exported by the procfs. */ ++extern struct proc_dir_entry *proc_sys_root; ++ ++ + /* These are exported solely for the purpose of mtd_blkdevs.c. You + should not use them for _anything_ else */ + DECLARE_MUTEX(mtd_table_mutex); +@@ -336,8 +340,83 @@ + + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) + static struct proc_dir_entry *proc_mtd; ++ ++static struct proc_dir_entry *proc_sys_mtd; ++static struct proc_dir_entry *proc_sys_mtd_partition[MAX_MTD_DEVICES]; ++static struct proc_dir_entry *proc_sys_mtd_partition_rw[MAX_MTD_DEVICES]; + #endif + ++/*===================================0 ++ * mtdproc_read_partition_access ++ */ ++static int mtdproc_read_partition_access ( char *page, char **start, off_t off,int count, ++ int *eof, void *data ++ ) ++{ ++ int partid = (unsigned int)data; ++ int len = 0; ++ ++ // NO RETURN FROM HERE UNTIL "up(&mtd_table_mutex)". ++ down(&mtd_table_mutex); ++ ++ if (partid < MAX_MTD_DEVICES) ++ { ++ struct mtd_info *this = mtd_table[partid]; ++ if (this) ++ { ++ page[len] = (this->flags & MTD_WRITEABLE) ? '1' : '0'; ++ len++; ++ } ++ } ++ ++ up(&mtd_table_mutex); ++ ++ if (off >= len) ++ return 0; ++ *start = page + off; ++ return ((count < len-off) ? count : len-off); ++} ++ ++ ++static int mtdproc_write_partition_access (struct file *file, const char *buffer, ++ unsigned long count, void *data) ++{ ++ int partid = (unsigned int)data; ++ int len = 0; ++ ++ // NO RETURN FROM HERE UNTIL "up(&mtd_table_mutex)". ++ down(&mtd_table_mutex); ++ ++ if (partid < MAX_MTD_DEVICES) ++ { ++ struct mtd_info *this = mtd_table[partid]; ++ if (this && count > 0) ++ { ++ switch (*buffer) ++ { ++ case '0': ++ this->flags &= ~(this->master_flags & MTD_WRITEABLE); ++ break; ++ ++ case '1': ++ this->flags |= ~(this->master_flags & MTD_WRITEABLE); ++ break; ++ ++ default: ++ break; ++ } ++ } ++ } ++ ++ up(&mtd_table_mutex); ++ ++ return count; ++} ++ ++ ++ ++ ++ + static inline int mtd_proc_info (char *buf, int i) + { + struct mtd_info *this = mtd_table[i]; +@@ -349,6 +428,7 @@ + this->erasesize, this->name); + } + ++ + static int mtd_read_proc ( char *page, char **start, off_t off,int count + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) + ,int *eof, void *data_unused +@@ -404,12 +484,31 @@ + /*====================================================================*/ + /* Init code */ + ++ + int __init init_mtd(void) + { + #ifdef CONFIG_PROC_FS + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) ++ int i; ++ + if ((proc_mtd = create_proc_entry( "mtd", 0, 0 ))) + proc_mtd->read_proc = mtd_read_proc; ++ ++ proc_sys_mtd = proc_mkdir("mtd", proc_sys_root); ++ for (i=0; iread_proc = mtdproc_read_partition_access; ++ proc_sys_mtd_partition_rw[i]->write_proc = mtdproc_write_partition_access; ++ proc_sys_mtd_partition_rw[i]->data = (void *)i; ++ } ++ } + #else + proc_register_dynamic(&proc_root,&mtd_proc_entry); + #endif +@@ -425,6 +524,8 @@ + return 0; + } + ++ ++ + static void __exit cleanup_mtd(void) + { + #ifdef CONFIG_PM +diff -Nurb linux/drivers/mtd/mtdpart.c linux-mtd-rw/drivers/mtd/mtdpart.c +--- linux/drivers/mtd/mtdpart.c 2004-11-18 13:16:00.000000000 +0100 ++++ linux-mtd-rw/drivers/mtd/mtdpart.c 2004-11-18 15:27:13.131036464 +0100 +@@ -341,6 +341,9 @@ + /* set up the MTD object for this partition */ + slave->mtd.type = master->type; + slave->mtd.flags = master->flags & ~parts[i].mask_flags; ++ slave->mtd.master_flags = master->flags; ++ slave->mtd.mask_flags = parts[i].mask_flags; ++ + slave->mtd.size = parts[i].size; + slave->mtd.oobblock = master->oobblock; + slave->mtd.oobsize = master->oobsize; +diff -Nurb linux/include/linux/mtd/mtd.h linux-mtd-rw/include/linux/mtd/mtd.h +--- linux/include/linux/mtd/mtd.h 2004-11-18 13:16:31.000000000 +0100 ++++ linux-mtd-rw/include/linux/mtd/mtd.h 2004-11-18 15:27:13.000000000 +0100 +@@ -232,6 +232,9 @@ + + struct module *owner; + int usecount; ++ ++ u_int32_t master_flags; ++ u_int32_t mask_flags; + }; + + diff --git a/packages/linux/linux-mtx-2-2.4.27/12-openswan-2.2.0-nat-t.diff b/packages/linux/linux-mtx-2-2.4.27/12-openswan-2.2.0-nat-t.diff new file mode 100644 index 0000000000..2a18d605bf --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/12-openswan-2.2.0-nat-t.diff @@ -0,0 +1,143 @@ +diff -Nurb linux-08/include/net/sock.h linux/include/net/sock.h +--- linux-08/include/net/sock.h 2004-11-19 11:37:23.376715120 +0100 ++++ linux/include/net/sock.h 2004-11-19 11:39:29.874484536 +0100 +@@ -256,6 +256,13 @@ + __u32 end_seq; + }; + ++#if 1 ++#define UDP_OPT_IN_SOCK 1 ++struct udp_opt { ++ __u32 esp_in_udp; ++}; ++#endif ++ + struct tcp_opt { + int tcp_header_len; /* Bytes of tcp header to send */ + +@@ -648,6 +655,9 @@ + #if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE) + struct spx_opt af_spx; + #endif /* CONFIG_SPX */ ++#if 1 ++ struct udp_opt af_udp; ++#endif + + } tp_pinfo; + +diff -Nurb linux-08/net/Config.in linux/net/Config.in +--- linux-08/net/Config.in 2004-11-19 11:37:23.770655232 +0100 ++++ linux/net/Config.in 2004-11-19 11:39:29.874484536 +0100 +@@ -102,4 +102,6 @@ + dep_tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN $CONFIG_PROC_FS + endmenu + ++bool 'IPSEC NAT-Traversal' CONFIG_IPSEC_NAT_TRAVERSAL ++ + endmenu +diff -Nurb linux-08/net/ipv4/udp.c linux/net/ipv4/udp.c +--- linux-08/net/ipv4/udp.c 2004-11-19 11:37:23.897635928 +0100 ++++ linux/net/ipv4/udp.c 2004-11-19 11:39:29.875484384 +0100 +@@ -810,6 +810,9 @@ + + static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) + { ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ struct udp_opt *tp = &(sk->tp_pinfo.af_udp); ++#endif + /* + * Charge it to the socket, dropping if the queue is full. + */ +@@ -827,6 +830,40 @@ + } + #endif + ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ if (tp->esp_in_udp) { ++ /* ++ * Set skb->sk and xmit packet to ipsec_rcv. ++ * ++ * If ret != 0, ipsec_rcv refused the packet (not ESPinUDP), ++ * restore skb->sk and fall back to sock_queue_rcv_skb ++ */ ++ struct inet_protocol *esp = NULL; ++ ++#if defined(CONFIG_IPSEC) && !defined(CONFIG_IPSEC_MODULE) ++ /* optomize only when we know it is statically linked */ ++ extern struct inet_protocol esp_protocol; ++ esp = &esp_protocol; ++#else ++ for (esp = (struct inet_protocol *)inet_protos[IPPROTO_ESP & (MAX_INET_PROTOS - 1)]; ++ (esp) && (esp->protocol != IPPROTO_ESP); ++ esp = esp->next); ++#endif ++ ++ if (esp && esp->handler) { ++ struct sock *sav_sk = skb->sk; ++ skb->sk = sk; ++ if (esp->handler(skb) == 0) { ++ skb->sk = sav_sk; ++ /*not sure we might count ESPinUDP as UDP...*/ ++ UDP_INC_STATS_BH(UdpInDatagrams); ++ return 0; ++ } ++ skb->sk = sav_sk; ++ } ++ } ++#endif ++ + if (sock_queue_rcv_skb(sk,skb)<0) { + UDP_INC_STATS_BH(UdpInErrors); + IP_INC_STATS_BH(IpInDiscards); +@@ -1050,13 +1087,49 @@ + return len; + } + ++static int udp_setsockopt(struct sock *sk, int level, int optname, ++ char *optval, int optlen) ++{ ++ struct udp_opt *tp = &(sk->tp_pinfo.af_udp); ++ int val; ++ int err = 0; ++ ++ if (level != SOL_UDP) ++ return ip_setsockopt(sk, level, optname, optval, optlen); ++ ++ if(optlenesp_in_udp = val; ++ break; ++#endif ++ default: ++ err = -ENOPROTOOPT; ++ break; ++ } ++ ++ release_sock(sk); ++ return err; ++} ++ + struct proto udp_prot = { + name: "UDP", + close: udp_close, + connect: udp_connect, + disconnect: udp_disconnect, + ioctl: udp_ioctl, +- setsockopt: ip_setsockopt, ++ setsockopt: udp_setsockopt, + getsockopt: ip_getsockopt, + sendmsg: udp_sendmsg, + recvmsg: udp_recvmsg, + diff --git a/packages/linux/linux-mtx-2-2.4.27/13-openswan-2.2.0.patch b/packages/linux/linux-mtx-2-2.4.27/13-openswan-2.2.0.patch new file mode 100644 index 0000000000..a6fba5d3f9 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/13-openswan-2.2.0.patch @@ -0,0 +1,61293 @@ +make[1]: Entering directory `/data/mtx/oe/tmp/work/openswan-2.2.0-r0/openswan-2.2.0' +packaging/utils/kernelpatch 2.4 +--- linux/Documentation/Configure.help.orig Fri Dec 21 12:41:53 2001 ++++ linux/Documentation/Configure.help Mon Jul 29 16:35:32 2002 +@@ -24237,5 +24237,65 @@ + +-# ++IP Security Protocol (IPSEC) (EXPERIMENTAL) ++CONFIG_IPSEC ++ This unit is experimental code. ++ Pick 'y' for static linking, 'm' for module support or 'n' for none. ++ This option adds support for network layer packet encryption and/or ++ authentication with participating hosts. The standards start with: ++ RFCs 2411, 2407 and 2401. Others are mentioned where they refer to ++ specific features below. There are more pending which can be found ++ at: ftp://ftp.ietf.org/internet-drafts/draft-ietf-ipsec-*. ++ A description of each document can also be found at: ++ http://ietf.org/ids.by.wg/ipsec.html. ++ Their charter can be found at: ++ http://www.ietf.org/html.charters/ipsec-charter.html ++ Snapshots and releases of the current work can be found at: ++ http://www.freeswan.org/ ++ ++IPSEC: IP-in-IP encapsulation ++CONFIG_IPSEC_IPIP ++ This option provides support for tunnel mode IPSEC. It is recommended ++ to enable this. ++ ++IPSEC: Authentication Header ++CONFIG_IPSEC_AH ++ This option provides support for the IPSEC Authentication Header ++ (IP protocol 51) which provides packet layer sender and content ++ authentication. It is recommended to enable this. RFC2402 ++ ++HMAC-MD5 algorithm ++CONFIG_IPSEC_AUTH_HMAC_MD5 ++ Provides support for authentication using the HMAC MD5 ++ algorithm with 96 bits of hash used as the authenticator. RFC2403 ++ ++HMAC-SHA1 algorithm ++CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ Provides support for Authentication Header using the HMAC SHA1 ++ algorithm with 96 bits of hash used as the authenticator. RFC2404 ++ ++IPSEC: Encapsulating Security Payload ++CONFIG_IPSEC_ESP ++ This option provides support for the IPSEC Encapsulation Security ++ Payload (IP protocol 50) which provides packet layer content ++ hiding. It is recommended to enable this. RFC2406 ++ ++3DES algorithm ++CONFIG_IPSEC_ENC_3DES ++ Provides support for Encapsulation Security Payload protocol, using ++ the triple DES encryption algorithm. RFC2451 ++ ++IPSEC Debugging Option ++CONFIG_IPSEC_DEBUG ++ Enables IPSEC kernel debugging. It is further controlled by the ++ user space utility 'klipsdebug'. ++ ++IPSEC Regression Testing option ++CONFIG_IPSEC_REGRESS ++ Enables IPSEC regression testing. Creates a number of switches in ++ /proc/sys/net/ipsec which cause various failure modes in KLIPS. ++ For more details see FreeSWAN source under ++ testing/doc/regression_options.txt. ++ ++# + # A couple of things I keep forgetting: + # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, + # Intel, IRQ, ISDN, Linux, MSDOS, NetWare, NetWinder, +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/README.openswan-2 Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,112 @@ ++* ++* RCSID $Id: README.openswan-2,v 1.1 2003/12/10 01:07:49 mcr Exp $ ++* ++ ++ **************************************** ++ * IPSEC for Linux, Release 2.xx series * ++ **************************************** ++ ++ ++ ++1. Files ++ ++The contents of linux/net/ipsec/ (see below) join the linux kernel source tree. ++as provided for higher up. ++ ++The programs/ directory contains the user-level utilities which you need ++to run IPSEC. See the top-level top/INSTALL to compile and install them. ++ ++The testing/ directory contains test scripts. ++ ++The doc/ directory contains -- what else -- documentation. ++ ++1.1. Kernel files ++ ++The following are found in net/ipsec/: ++ ++Makefile The Makefile ++Config.in The configuration script for make menuconfig ++defconfig Configuration defaults for first time. ++ ++radij.c General-purpose radix-tree operations ++ ++ipsec_ipcomp.c IPCOMP encapsulate/decapsulate code. ++ipsec_ah.c Authentication Header (AH) encapsulate/decapsulate code. ++ipsec_esp.c Encapsulated Security Payload (ESP) encap/decap code. ++ ++pfkey_v2.c PF_KEYv2 socket interface code. ++pfkey_v2_parser.c PF_KEYv2 message parsing and processing code. ++ ++ipsec_init.c Initialization code, /proc interface. ++ipsec_radij.c Interface with the radix tree code. ++ipsec_netlink.c Interface with the netlink code. ++ipsec_xform.c Routines and structures common to transforms. ++ipsec_tunnel.c The outgoing packet processing code. ++ipsec_rcv.c The incoming packet processing code. ++ipsec_md5c.c Somewhat modified RSADSI MD5 C code. ++ipsec_sha1.c Somewhat modified Steve Reid SHA-1 C code. ++ ++sysctl_net_ipsec.c /proc/sys/net/ipsec/* variable definitions. ++ ++version.c symbolic link to project version. ++ ++radij.h Headers for radij.c ++ ++ipcomp.h Headers used by IPCOMP code. ++ ++ipsec_radij.h Interface with the radix tree code. ++ipsec_netlink.h Headers used by the netlink interface. ++ipsec_encap.h Headers defining encapsulation structures. ++ipsec_xform.h Transform headers. ++ipsec_tunnel.h Headers used by tunneling code. ++ipsec_ipe4.h Headers for the IP-in-IP code. ++ipsec_ah.h Headers common to AH transforms. ++ipsec_md5h.h RSADSI MD5 headers. ++ipsec_sha1.h SHA-1 headers. ++ipsec_esp.h Headers common to ESP transfroms. ++ipsec_rcv.h Headers for incoming packet processing code. ++ ++1.2. User-level files. ++ ++The following are found in utils/: ++ ++eroute.c Create an "extended route" source code ++spi.c Set up Security Associations source code ++spigrp.c Link SPIs together source code. ++tncfg.c Configure the tunneling features of the virtual interface ++ source code ++klipsdebug.c Set/reset klips debugging features source code. ++version.c symbolic link to project version. ++ ++eroute.8 Create an "extended route" manual page ++spi.8 Set up Security Associations manual page ++spigrp.8 Link SPIs together manual page ++tncfg.8 Configure the tunneling features of the virtual interface ++ manual page ++klipsdebug.8 Set/reset klips debugging features manual page ++ ++eroute.5 /proc/net/ipsec_eroute format manual page ++spi.5 /proc/net/ipsec_spi format manual page ++spigrp.5 /proc/net/ipsec_spigrp format manual page ++tncfg.5 /proc/net/ipsec_tncfg format manual page ++klipsdebug.5 /proc/net/ipsec_klipsdebug format manual page ++version.5 /proc/net/ipsec_version format manual page ++pf_key.5 /proc/net/pf_key format manual page ++ ++Makefile Utilities makefile. ++ ++*.8 Manpages for the respective utils. ++ ++ ++1.3. Test files ++ ++The test scripts are locate in testing/ and and documentation is found ++at doc/src/umltesting.html. Automated testing via "make check" is available ++provided that the User-Mode-Linux patches are available. ++ ++* ++* $Log: README.openswan-2,v $ ++* Revision 1.1 2003/12/10 01:07:49 mcr ++* documentation for additions. ++* ++* +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/aes/Makefile.objs Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,13 @@ ++ ++ASM-$(ARCH_ASM):=1 ++ASM_X86:=$(ASM-i586)$(ASM-i686) ++ ++ifneq ($(strip $(ASM_X86)),) ++obj-$(CONFIG_IPSEC_ENC_AES) += aes-i586.o ++else ++obj-$(CONFIG_IPSEC_ENC_AES) += aes.o ++endif ++ ++obj-$(CONFIG_IPSEC_ENC_AES) += aes_cbc.o ++obj-$(CONFIG_IPSEC_ENC_AES) += aes_xcbc_mac.o ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/aes/aes-i586.S Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,892 @@ ++// ++// Copyright (c) 2001, Dr Brian Gladman , Worcester, UK. ++// All rights reserved. ++// ++// TERMS ++// ++// Redistribution and use in source and binary forms, with or without ++// modification, are permitted subject to the following conditions: ++// ++// 1. Redistributions of source code must retain the above copyright ++// notice, this list of conditions and the following disclaimer. ++// ++// 2. Redistributions in binary form must reproduce the above copyright ++// notice, this list of conditions and the following disclaimer in the ++// documentation and/or other materials provided with the distribution. ++// ++// 3. The copyright holder's name must not be used to endorse or promote ++// any products derived from this software without his specific prior ++// written permission. ++// ++// This software is provided 'as is' with no express or implied warranties ++// of correctness or fitness for purpose. ++ ++// Modified by Jari Ruusu, December 24 2001 ++// - Converted syntax to GNU CPP/assembler syntax ++// - C programming interface converted back to "old" API ++// - Minor portability cleanups and speed optimizations ++ ++// An AES (Rijndael) implementation for the Pentium. This version only ++// implements the standard AES block length (128 bits, 16 bytes). This code ++// does not preserve the eax, ecx or edx registers or the artihmetic status ++// flags. However, the ebx, esi, edi, and ebp registers are preserved across ++// calls. ++ ++// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f) ++// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[]) ++// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[]) ++ ++#if defined(USE_UNDERLINE) ++# define aes_set_key _aes_set_key ++# define aes_encrypt _aes_encrypt ++# define aes_decrypt _aes_decrypt ++#endif ++#if !defined(ALIGN32BYTES) ++# define ALIGN32BYTES 32 ++#endif ++ ++ .file "aes-i586.S" ++ .globl aes_set_key ++ .globl aes_encrypt ++ .globl aes_decrypt ++ ++#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words) ++ ++// offsets to parameters with one register pushed onto stack ++ ++#define ctx 8 // AES context structure ++#define in_blk 12 // input byte array address parameter ++#define out_blk 16 // output byte array address parameter ++ ++// offsets in context structure ++ ++#define nkey 0 // key length, size 4 ++#define nrnd 4 // number of rounds, size 4 ++#define ekey 8 // encryption key schedule base address, size 256 ++#define dkey 264 // decryption key schedule base address, size 256 ++ ++// This macro performs a forward encryption cycle. It is entered with ++// the first previous round column values in %eax, %ebx, %esi and %edi and ++// exits with the final values in the same registers. ++ ++#define fwd_rnd(p1,p2) \ ++ mov %ebx,(%esp) ;\ ++ movzbl %al,%edx ;\ ++ mov %eax,%ecx ;\ ++ mov p2(%ebp),%eax ;\ ++ mov %edi,4(%esp) ;\ ++ mov p2+12(%ebp),%edi ;\ ++ xor p1(,%edx,4),%eax ;\ ++ movzbl %ch,%edx ;\ ++ shr $16,%ecx ;\ ++ mov p2+4(%ebp),%ebx ;\ ++ xor p1+tlen(,%edx,4),%edi ;\ ++ movzbl %cl,%edx ;\ ++ movzbl %ch,%ecx ;\ ++ xor p1+3*tlen(,%ecx,4),%ebx ;\ ++ mov %esi,%ecx ;\ ++ mov p1+2*tlen(,%edx,4),%esi ;\ ++ movzbl %cl,%edx ;\ ++ xor p1(,%edx,4),%esi ;\ ++ movzbl %ch,%edx ;\ ++ shr $16,%ecx ;\ ++ xor p1+tlen(,%edx,4),%ebx ;\ ++ movzbl %cl,%edx ;\ ++ movzbl %ch,%ecx ;\ ++ xor p1+2*tlen(,%edx,4),%eax ;\ ++ mov (%esp),%edx ;\ ++ xor p1+3*tlen(,%ecx,4),%edi ;\ ++ movzbl %dl,%ecx ;\ ++ xor p2+8(%ebp),%esi ;\ ++ xor p1(,%ecx,4),%ebx ;\ ++ movzbl %dh,%ecx ;\ ++ shr $16,%edx ;\ ++ xor p1+tlen(,%ecx,4),%eax ;\ ++ movzbl %dl,%ecx ;\ ++ movzbl %dh,%edx ;\ ++ xor p1+2*tlen(,%ecx,4),%edi ;\ ++ mov 4(%esp),%ecx ;\ ++ xor p1+3*tlen(,%edx,4),%esi ;\ ++ movzbl %cl,%edx ;\ ++ xor p1(,%edx,4),%edi ;\ ++ movzbl %ch,%edx ;\ ++ shr $16,%ecx ;\ ++ xor p1+tlen(,%edx,4),%esi ;\ ++ movzbl %cl,%edx ;\ ++ movzbl %ch,%ecx ;\ ++ xor p1+2*tlen(,%edx,4),%ebx ;\ ++ xor p1+3*tlen(,%ecx,4),%eax ++ ++// This macro performs an inverse encryption cycle. It is entered with ++// the first previous round column values in %eax, %ebx, %esi and %edi and ++// exits with the final values in the same registers. ++ ++#define inv_rnd(p1,p2) \ ++ movzbl %al,%edx ;\ ++ mov %ebx,(%esp) ;\ ++ mov %eax,%ecx ;\ ++ mov p2(%ebp),%eax ;\ ++ mov %edi,4(%esp) ;\ ++ mov p2+4(%ebp),%ebx ;\ ++ xor p1(,%edx,4),%eax ;\ ++ movzbl %ch,%edx ;\ ++ shr $16,%ecx ;\ ++ mov p2+12(%ebp),%edi ;\ ++ xor p1+tlen(,%edx,4),%ebx ;\ ++ movzbl %cl,%edx ;\ ++ movzbl %ch,%ecx ;\ ++ xor p1+3*tlen(,%ecx,4),%edi ;\ ++ mov %esi,%ecx ;\ ++ mov p1+2*tlen(,%edx,4),%esi ;\ ++ movzbl %cl,%edx ;\ ++ xor p1(,%edx,4),%esi ;\ ++ movzbl %ch,%edx ;\ ++ shr $16,%ecx ;\ ++ xor p1+tlen(,%edx,4),%edi ;\ ++ movzbl %cl,%edx ;\ ++ movzbl %ch,%ecx ;\ ++ xor p1+2*tlen(,%edx,4),%eax ;\ ++ mov (%esp),%edx ;\ ++ xor p1+3*tlen(,%ecx,4),%ebx ;\ ++ movzbl %dl,%ecx ;\ ++ xor p2+8(%ebp),%esi ;\ ++ xor p1(,%ecx,4),%ebx ;\ ++ movzbl %dh,%ecx ;\ ++ shr $16,%edx ;\ ++ xor p1+tlen(,%ecx,4),%esi ;\ ++ movzbl %dl,%ecx ;\ ++ movzbl %dh,%edx ;\ ++ xor p1+2*tlen(,%ecx,4),%edi ;\ ++ mov 4(%esp),%ecx ;\ ++ xor p1+3*tlen(,%edx,4),%eax ;\ ++ movzbl %cl,%edx ;\ ++ xor p1(,%edx,4),%edi ;\ ++ movzbl %ch,%edx ;\ ++ shr $16,%ecx ;\ ++ xor p1+tlen(,%edx,4),%eax ;\ ++ movzbl %cl,%edx ;\ ++ movzbl %ch,%ecx ;\ ++ xor p1+2*tlen(,%edx,4),%ebx ;\ ++ xor p1+3*tlen(,%ecx,4),%esi ++ ++// AES (Rijndael) Encryption Subroutine ++ ++ .text ++ .align ALIGN32BYTES ++aes_encrypt: ++ push %ebp ++ mov ctx(%esp),%ebp // pointer to context ++ mov in_blk(%esp),%ecx ++ push %ebx ++ push %esi ++ push %edi ++ mov nrnd(%ebp),%edx // number of rounds ++ lea ekey+16(%ebp),%ebp // key pointer ++ ++// input four columns and xor in first round key ++ ++ mov (%ecx),%eax ++ mov 4(%ecx),%ebx ++ mov 8(%ecx),%esi ++ mov 12(%ecx),%edi ++ xor -16(%ebp),%eax ++ xor -12(%ebp),%ebx ++ xor -8(%ebp),%esi ++ xor -4(%ebp),%edi ++ ++ sub $8,%esp // space for register saves on stack ++ ++ sub $10,%edx ++ je aes_15 ++ add $32,%ebp ++ sub $2,%edx ++ je aes_13 ++ add $32,%ebp ++ ++ fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key ++ fwd_rnd(aes_ft_tab,-48) ++aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key ++ fwd_rnd(aes_ft_tab,-16) ++aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key ++ fwd_rnd(aes_ft_tab,16) ++ fwd_rnd(aes_ft_tab,32) ++ fwd_rnd(aes_ft_tab,48) ++ fwd_rnd(aes_ft_tab,64) ++ fwd_rnd(aes_ft_tab,80) ++ fwd_rnd(aes_ft_tab,96) ++ fwd_rnd(aes_ft_tab,112) ++ fwd_rnd(aes_ft_tab,128) ++ fwd_rnd(aes_fl_tab,144) // last round uses a different table ++ ++// move final values to the output array. ++ ++ mov out_blk+20(%esp),%ebp ++ add $8,%esp ++ mov %eax,(%ebp) ++ mov %ebx,4(%ebp) ++ mov %esi,8(%ebp) ++ mov %edi,12(%ebp) ++ pop %edi ++ pop %esi ++ pop %ebx ++ pop %ebp ++ ret ++ ++ ++// AES (Rijndael) Decryption Subroutine ++ ++ .align ALIGN32BYTES ++aes_decrypt: ++ push %ebp ++ mov ctx(%esp),%ebp // pointer to context ++ mov in_blk(%esp),%ecx ++ push %ebx ++ push %esi ++ push %edi ++ mov nrnd(%ebp),%edx // number of rounds ++ lea dkey+16(%ebp),%ebp // key pointer ++ ++// input four columns and xor in first round key ++ ++ mov (%ecx),%eax ++ mov 4(%ecx),%ebx ++ mov 8(%ecx),%esi ++ mov 12(%ecx),%edi ++ xor -16(%ebp),%eax ++ xor -12(%ebp),%ebx ++ xor -8(%ebp),%esi ++ xor -4(%ebp),%edi ++ ++ sub $8,%esp // space for register saves on stack ++ ++ sub $10,%edx ++ je aes_25 ++ add $32,%ebp ++ sub $2,%edx ++ je aes_23 ++ add $32,%ebp ++ ++ inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key ++ inv_rnd(aes_it_tab,-48) ++aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key ++ inv_rnd(aes_it_tab,-16) ++aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key ++ inv_rnd(aes_it_tab,16) ++ inv_rnd(aes_it_tab,32) ++ inv_rnd(aes_it_tab,48) ++ inv_rnd(aes_it_tab,64) ++ inv_rnd(aes_it_tab,80) ++ inv_rnd(aes_it_tab,96) ++ inv_rnd(aes_it_tab,112) ++ inv_rnd(aes_it_tab,128) ++ inv_rnd(aes_il_tab,144) // last round uses a different table ++ ++// move final values to the output array. ++ ++ mov out_blk+20(%esp),%ebp ++ add $8,%esp ++ mov %eax,(%ebp) ++ mov %ebx,4(%ebp) ++ mov %esi,8(%ebp) ++ mov %edi,12(%ebp) ++ pop %edi ++ pop %esi ++ pop %ebx ++ pop %ebp ++ ret ++ ++// AES (Rijndael) Key Schedule Subroutine ++ ++// input/output parameters ++ ++#define aes_cx 12 // AES context ++#define in_key 16 // key input array address ++#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256) ++#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only ++ ++// offsets for locals ++ ++#define cnt -4 ++#define kpf -8 ++#define slen 8 ++ ++// This macro performs a column mixing operation on an input 32-bit ++// word to give a 32-bit result. It uses each of the 4 bytes in the ++// the input column to index 4 different tables of 256 32-bit words ++// that are xored together to form the output value. ++ ++#define mix_col(p1) \ ++ movzbl %bl,%ecx ;\ ++ mov p1(,%ecx,4),%eax ;\ ++ movzbl %bh,%ecx ;\ ++ ror $16,%ebx ;\ ++ xor p1+tlen(,%ecx,4),%eax ;\ ++ movzbl %bl,%ecx ;\ ++ xor p1+2*tlen(,%ecx,4),%eax ;\ ++ movzbl %bh,%ecx ;\ ++ xor p1+3*tlen(,%ecx,4),%eax ++ ++// Key Schedule Macros ++ ++#define ksc4(p1) \ ++ rol $24,%ebx ;\ ++ mix_col(aes_fl_tab) ;\ ++ ror $8,%ebx ;\ ++ xor 4*p1+aes_rcon_tab,%eax ;\ ++ xor %eax,%esi ;\ ++ xor %esi,%ebp ;\ ++ mov %esi,16*p1(%edi) ;\ ++ mov %ebp,16*p1+4(%edi) ;\ ++ xor %ebp,%edx ;\ ++ xor %edx,%ebx ;\ ++ mov %edx,16*p1+8(%edi) ;\ ++ mov %ebx,16*p1+12(%edi) ++ ++#define ksc6(p1) \ ++ rol $24,%ebx ;\ ++ mix_col(aes_fl_tab) ;\ ++ ror $8,%ebx ;\ ++ xor 4*p1+aes_rcon_tab,%eax ;\ ++ xor 24*p1-24(%edi),%eax ;\ ++ mov %eax,24*p1(%edi) ;\ ++ xor 24*p1-20(%edi),%eax ;\ ++ mov %eax,24*p1+4(%edi) ;\ ++ xor %eax,%esi ;\ ++ xor %esi,%ebp ;\ ++ mov %esi,24*p1+8(%edi) ;\ ++ mov %ebp,24*p1+12(%edi) ;\ ++ xor %ebp,%edx ;\ ++ xor %edx,%ebx ;\ ++ mov %edx,24*p1+16(%edi) ;\ ++ mov %ebx,24*p1+20(%edi) ++ ++#define ksc8(p1) \ ++ rol $24,%ebx ;\ ++ mix_col(aes_fl_tab) ;\ ++ ror $8,%ebx ;\ ++ xor 4*p1+aes_rcon_tab,%eax ;\ ++ xor 32*p1-32(%edi),%eax ;\ ++ mov %eax,32*p1(%edi) ;\ ++ xor 32*p1-28(%edi),%eax ;\ ++ mov %eax,32*p1+4(%edi) ;\ ++ xor 32*p1-24(%edi),%eax ;\ ++ mov %eax,32*p1+8(%edi) ;\ ++ xor 32*p1-20(%edi),%eax ;\ ++ mov %eax,32*p1+12(%edi) ;\ ++ push %ebx ;\ ++ mov %eax,%ebx ;\ ++ mix_col(aes_fl_tab) ;\ ++ pop %ebx ;\ ++ xor %eax,%esi ;\ ++ xor %esi,%ebp ;\ ++ mov %esi,32*p1+16(%edi) ;\ ++ mov %ebp,32*p1+20(%edi) ;\ ++ xor %ebp,%edx ;\ ++ xor %edx,%ebx ;\ ++ mov %edx,32*p1+24(%edi) ;\ ++ mov %ebx,32*p1+28(%edi) ++ ++ .align ALIGN32BYTES ++aes_set_key: ++ pushfl ++ push %ebp ++ mov %esp,%ebp ++ sub $slen,%esp ++ push %ebx ++ push %esi ++ push %edi ++ ++ mov aes_cx(%ebp),%edx // edx -> AES context ++ ++ mov key_ln(%ebp),%ecx // key length ++ cmpl $128,%ecx ++ jb aes_30 ++ shr $3,%ecx ++aes_30: cmpl $32,%ecx ++ je aes_32 ++ cmpl $24,%ecx ++ je aes_32 ++ mov $16,%ecx ++aes_32: shr $2,%ecx ++ mov %ecx,nkey(%edx) ++ ++ lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length ++ mov %eax,nrnd(%edx) ++ ++ mov in_key(%ebp),%esi // key input array ++ lea ekey(%edx),%edi // key position in AES context ++ cld ++ push %ebp ++ mov %ecx,%eax // save key length in eax ++ rep ; movsl // words in the key schedule ++ mov -4(%esi),%ebx // put some values in registers ++ mov -8(%esi),%edx // to allow faster code ++ mov -12(%esi),%ebp ++ mov -16(%esi),%esi ++ ++ cmpl $4,%eax // jump on key size ++ je aes_36 ++ cmpl $6,%eax ++ je aes_35 ++ ++ ksc8(0) ++ ksc8(1) ++ ksc8(2) ++ ksc8(3) ++ ksc8(4) ++ ksc8(5) ++ ksc8(6) ++ jmp aes_37 ++aes_35: ksc6(0) ++ ksc6(1) ++ ksc6(2) ++ ksc6(3) ++ ksc6(4) ++ ksc6(5) ++ ksc6(6) ++ ksc6(7) ++ jmp aes_37 ++aes_36: ksc4(0) ++ ksc4(1) ++ ksc4(2) ++ ksc4(3) ++ ksc4(4) ++ ksc4(5) ++ ksc4(6) ++ ksc4(7) ++ ksc4(8) ++ ksc4(9) ++aes_37: pop %ebp ++ mov aes_cx(%ebp),%edx // edx -> AES context ++ cmpl $0,ed_flg(%ebp) ++ jne aes_39 ++ ++// compile decryption key schedule from encryption schedule - reverse ++// order and do mix_column operation on round keys except first and last ++ ++ mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd ++ shl $2,%eax ++ lea dkey(%edx,%eax,4),%edi ++ lea ekey(%edx),%esi // kf = cx->e_key ++ ++ movsl // copy first round key (unmodified) ++ movsl ++ movsl ++ movsl ++ sub $32,%edi ++ movl $1,cnt(%ebp) ++aes_38: // do mix column on each column of ++ lodsl // each round key ++ mov %eax,%ebx ++ mix_col(aes_im_tab) ++ stosl ++ lodsl ++ mov %eax,%ebx ++ mix_col(aes_im_tab) ++ stosl ++ lodsl ++ mov %eax,%ebx ++ mix_col(aes_im_tab) ++ stosl ++ lodsl ++ mov %eax,%ebx ++ mix_col(aes_im_tab) ++ stosl ++ sub $32,%edi ++ ++ incl cnt(%ebp) ++ mov cnt(%ebp),%eax ++ cmp nrnd(%edx),%eax ++ jb aes_38 ++ ++ movsl // copy last round key (unmodified) ++ movsl ++ movsl ++ movsl ++aes_39: pop %edi ++ pop %esi ++ pop %ebx ++ mov %ebp,%esp ++ pop %ebp ++ popfl ++ ret ++ ++ ++// finite field multiplies by {02}, {04} and {08} ++ ++#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b)) ++#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b)) ++#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b)) ++ ++// finite field multiplies required in table generation ++ ++#define f3(x) (f2(x) ^ x) ++#define f9(x) (f8(x) ^ x) ++#define fb(x) (f8(x) ^ f2(x) ^ x) ++#define fd(x) (f8(x) ^ f4(x) ^ x) ++#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) ++ ++// These defines generate the forward table entries ++ ++#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x)) ++#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x)) ++#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x) ++#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x) ++ ++// These defines generate the inverse table entries ++ ++#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x)) ++#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x)) ++#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x)) ++#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x)) ++ ++// These defines generate entries for the last round tables ++ ++#define w0(x) (x) ++#define w1(x) (x << 8) ++#define w2(x) (x << 16) ++#define w3(x) (x << 24) ++ ++// macro to generate inverse mix column tables (needed for the key schedule) ++ ++#define im_data0(p1) \ ++ .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\ ++ .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\ ++ .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\ ++ .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f) ++#define im_data1(p1) \ ++ .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\ ++ .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\ ++ .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\ ++ .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f) ++#define im_data2(p1) \ ++ .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\ ++ .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\ ++ .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\ ++ .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f) ++#define im_data3(p1) \ ++ .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\ ++ .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\ ++ .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\ ++ .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f) ++#define im_data4(p1) \ ++ .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\ ++ .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\ ++ .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\ ++ .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f) ++#define im_data5(p1) \ ++ .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\ ++ .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\ ++ .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\ ++ .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf) ++#define im_data6(p1) \ ++ .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\ ++ .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\ ++ .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\ ++ .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf) ++#define im_data7(p1) \ ++ .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\ ++ .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\ ++ .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\ ++ .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff) ++ ++// S-box data - 256 entries ++ ++#define sb_data0(p1) \ ++ .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\ ++ .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\ ++ .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\ ++ .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0) ++#define sb_data1(p1) \ ++ .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\ ++ .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\ ++ .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\ ++ .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75) ++#define sb_data2(p1) \ ++ .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\ ++ .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\ ++ .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\ ++ .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf) ++#define sb_data3(p1) \ ++ .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\ ++ .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\ ++ .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\ ++ .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2) ++#define sb_data4(p1) \ ++ .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\ ++ .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\ ++ .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\ ++ .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb) ++#define sb_data5(p1) \ ++ .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\ ++ .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\ ++ .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\ ++ .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08) ++#define sb_data6(p1) \ ++ .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\ ++ .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\ ++ .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\ ++ .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e) ++#define sb_data7(p1) \ ++ .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\ ++ .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\ ++ .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\ ++ .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16) ++ ++// Inverse S-box data - 256 entries ++ ++#define ib_data0(p1) \ ++ .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\ ++ .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\ ++ .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\ ++ .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb) ++#define ib_data1(p1) \ ++ .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\ ++ .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\ ++ .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\ ++ .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25) ++#define ib_data2(p1) \ ++ .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\ ++ .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\ ++ .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\ ++ .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84) ++#define ib_data3(p1) \ ++ .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\ ++ .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\ ++ .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\ ++ .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b) ++#define ib_data4(p1) \ ++ .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\ ++ .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\ ++ .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\ ++ .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e) ++#define ib_data5(p1) \ ++ .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\ ++ .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\ ++ .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\ ++ .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4) ++#define ib_data6(p1) \ ++ .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\ ++ .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\ ++ .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\ ++ .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef) ++#define ib_data7(p1) \ ++ .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\ ++ .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\ ++ .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\ ++ .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d) ++ ++// The rcon_table (needed for the key schedule) ++// ++// Here is original Dr Brian Gladman's source code: ++// _rcon_tab: ++// %assign x 1 ++// %rep 29 ++// dd x ++// %assign x f2(x) ++// %endrep ++// ++// Here is precomputed output (it's more portable this way): ++ ++ .align ALIGN32BYTES ++aes_rcon_tab: ++ .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 ++ .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f ++ .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4 ++ .long 0xb3,0x7d,0xfa,0xef,0xc5 ++ ++// The forward xor tables ++ ++ .align ALIGN32BYTES ++aes_ft_tab: ++ sb_data0(u0) ++ sb_data1(u0) ++ sb_data2(u0) ++ sb_data3(u0) ++ sb_data4(u0) ++ sb_data5(u0) ++ sb_data6(u0) ++ sb_data7(u0) ++ ++ sb_data0(u1) ++ sb_data1(u1) ++ sb_data2(u1) ++ sb_data3(u1) ++ sb_data4(u1) ++ sb_data5(u1) ++ sb_data6(u1) ++ sb_data7(u1) ++ ++ sb_data0(u2) ++ sb_data1(u2) ++ sb_data2(u2) ++ sb_data3(u2) ++ sb_data4(u2) ++ sb_data5(u2) ++ sb_data6(u2) ++ sb_data7(u2) ++ ++ sb_data0(u3) ++ sb_data1(u3) ++ sb_data2(u3) ++ sb_data3(u3) ++ sb_data4(u3) ++ sb_data5(u3) ++ sb_data6(u3) ++ sb_data7(u3) ++ ++ .align ALIGN32BYTES ++aes_fl_tab: ++ sb_data0(w0) ++ sb_data1(w0) ++ sb_data2(w0) ++ sb_data3(w0) ++ sb_data4(w0) ++ sb_data5(w0) ++ sb_data6(w0) ++ sb_data7(w0) ++ ++ sb_data0(w1) ++ sb_data1(w1) ++ sb_data2(w1) ++ sb_data3(w1) ++ sb_data4(w1) ++ sb_data5(w1) ++ sb_data6(w1) ++ sb_data7(w1) ++ ++ sb_data0(w2) ++ sb_data1(w2) ++ sb_data2(w2) ++ sb_data3(w2) ++ sb_data4(w2) ++ sb_data5(w2) ++ sb_data6(w2) ++ sb_data7(w2) ++ ++ sb_data0(w3) ++ sb_data1(w3) ++ sb_data2(w3) ++ sb_data3(w3) ++ sb_data4(w3) ++ sb_data5(w3) ++ sb_data6(w3) ++ sb_data7(w3) ++ ++// The inverse xor tables ++ ++ .align ALIGN32BYTES ++aes_it_tab: ++ ib_data0(v0) ++ ib_data1(v0) ++ ib_data2(v0) ++ ib_data3(v0) ++ ib_data4(v0) ++ ib_data5(v0) ++ ib_data6(v0) ++ ib_data7(v0) ++ ++ ib_data0(v1) ++ ib_data1(v1) ++ ib_data2(v1) ++ ib_data3(v1) ++ ib_data4(v1) ++ ib_data5(v1) ++ ib_data6(v1) ++ ib_data7(v1) ++ ++ ib_data0(v2) ++ ib_data1(v2) ++ ib_data2(v2) ++ ib_data3(v2) ++ ib_data4(v2) ++ ib_data5(v2) ++ ib_data6(v2) ++ ib_data7(v2) ++ ++ ib_data0(v3) ++ ib_data1(v3) ++ ib_data2(v3) ++ ib_data3(v3) ++ ib_data4(v3) ++ ib_data5(v3) ++ ib_data6(v3) ++ ib_data7(v3) ++ ++ .align ALIGN32BYTES ++aes_il_tab: ++ ib_data0(w0) ++ ib_data1(w0) ++ ib_data2(w0) ++ ib_data3(w0) ++ ib_data4(w0) ++ ib_data5(w0) ++ ib_data6(w0) ++ ib_data7(w0) ++ ++ ib_data0(w1) ++ ib_data1(w1) ++ ib_data2(w1) ++ ib_data3(w1) ++ ib_data4(w1) ++ ib_data5(w1) ++ ib_data6(w1) ++ ib_data7(w1) ++ ++ ib_data0(w2) ++ ib_data1(w2) ++ ib_data2(w2) ++ ib_data3(w2) ++ ib_data4(w2) ++ ib_data5(w2) ++ ib_data6(w2) ++ ib_data7(w2) ++ ++ ib_data0(w3) ++ ib_data1(w3) ++ ib_data2(w3) ++ ib_data3(w3) ++ ib_data4(w3) ++ ib_data5(w3) ++ ib_data6(w3) ++ ib_data7(w3) ++ ++// The inverse mix column tables ++ ++ .align ALIGN32BYTES ++aes_im_tab: ++ im_data0(v0) ++ im_data1(v0) ++ im_data2(v0) ++ im_data3(v0) ++ im_data4(v0) ++ im_data5(v0) ++ im_data6(v0) ++ im_data7(v0) ++ ++ im_data0(v1) ++ im_data1(v1) ++ im_data2(v1) ++ im_data3(v1) ++ im_data4(v1) ++ im_data5(v1) ++ im_data6(v1) ++ im_data7(v1) ++ ++ im_data0(v2) ++ im_data1(v2) ++ im_data2(v2) ++ im_data3(v2) ++ im_data4(v2) ++ im_data5(v2) ++ im_data6(v2) ++ im_data7(v2) ++ ++ im_data0(v3) ++ im_data1(v3) ++ im_data2(v3) ++ im_data3(v3) ++ im_data4(v3) ++ im_data5(v3) ++ im_data6(v3) ++ im_data7(v3) +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/aes/aes.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,1415 @@ ++// I retain copyright in this code but I encourage its free use provided ++// that I don't carry any responsibility for the results. I am especially ++// happy to see it used in free and open source software. If you do use ++// it I would appreciate an acknowledgement of its origin in the code or ++// the product that results and I would also appreciate knowing a little ++// about the use to which it is being put. I am grateful to Frank Yellin ++// for some ideas that are used in this implementation. ++// ++// Dr B. R. Gladman 6th April 2001. ++// ++// This is an implementation of the AES encryption algorithm (Rijndael) ++// designed by Joan Daemen and Vincent Rijmen. This version is designed ++// to provide both fixed and dynamic block and key lengths and can also ++// run with either big or little endian internal byte order (see aes.h). ++// It inputs block and key lengths in bytes with the legal values being ++// 16, 24 and 32. ++ ++/* ++ * Modified by Jari Ruusu, May 1 2001 ++ * - Fixed some compile warnings, code was ok but gcc warned anyway. ++ * - Changed basic types: byte -> unsigned char, word -> u_int32_t ++ * - Major name space cleanup: Names visible to outside now begin ++ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c ++ * - Removed C++ and DLL support as part of name space cleanup. ++ * - Eliminated unnecessary recomputation of tables. (actual bug fix) ++ * - Merged precomputed constant tables to aes.c file. ++ * - Removed data alignment restrictions for portability reasons. ++ * - Made block and key lengths accept bit count (128/192/256) ++ * as well byte count (16/24/32). ++ * - Removed all error checks. This change also eliminated the need ++ * to preinitialize the context struct to zero. ++ * - Removed some totally unused constants. ++ */ ++ ++#include "crypto/aes.h" ++ ++// CONFIGURATION OPTIONS (see also aes.h) ++// ++// 1. Define UNROLL for full loop unrolling in encryption and decryption. ++// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption. ++// 3. Define FIXED_TABLES for compiled rather than dynamic tables. ++// 4. Define FF_TABLES to use tables for field multiplies and inverses. ++// Do not enable this without understanding stack space requirements. ++// 5. Define ARRAYS to use arrays to hold the local state block. If this ++// is not defined, individually declared 32-bit words are used. ++// 6. Define FAST_VARIABLE if a high speed variable block implementation ++// is needed (essentially three separate fixed block size code sequences) ++// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven ++// version using 1 table (2 kbytes of table space) or 4 tables (8 ++// kbytes of table space) for higher speed. ++// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed ++// increase by using tables for the last rounds but with more table ++// space (2 or 8 kbytes extra). ++// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but ++// slower version is provided. ++// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE ++// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra). ++ ++#define UNROLL ++//#define PARTIAL_UNROLL ++ ++#define FIXED_TABLES ++//#define FF_TABLES ++//#define ARRAYS ++#define FAST_VARIABLE ++ ++//#define ONE_TABLE ++#define FOUR_TABLES ++ ++//#define ONE_LR_TABLE ++#define FOUR_LR_TABLES ++ ++//#define ONE_IM_TABLE ++#define FOUR_IM_TABLES ++ ++#if defined(UNROLL) && defined (PARTIAL_UNROLL) ++#error both UNROLL and PARTIAL_UNROLL are defined ++#endif ++ ++#if defined(ONE_TABLE) && defined (FOUR_TABLES) ++#error both ONE_TABLE and FOUR_TABLES are defined ++#endif ++ ++#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES) ++#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined ++#endif ++ ++#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES) ++#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined ++#endif ++ ++#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32 ++#error an illegal block size has been specified ++#endif ++ ++// upr(x,n): rotates bytes within words by n positions, moving bytes ++// to higher index positions with wrap around into low positions ++// ups(x,n): moves bytes by n positions to higher index positions in ++// words but without wrap around ++// bval(x,n): extracts a byte from a word ++ ++#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n)))) ++#define ups(x,n) ((x) << 8 * (n)) ++#define bval(x,n) ((unsigned char)((x) >> 8 * (n))) ++#define bytes2word(b0, b1, b2, b3) \ ++ ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0)) ++ ++ ++/* little endian processor without data alignment restrictions: AES_LE_OK */ ++/* original code: i386 */ ++#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386) ++#define AES_LE_OK 1 ++/* added (tested): alpha --jjo */ ++#elif defined(__alpha__)|| defined (__alpha) ++#define AES_LE_OK 1 ++/* added (tested): ia64 --jjo */ ++#elif defined(__ia64__)|| defined (__ia64) ++#define AES_LE_OK 1 ++#endif ++ ++#ifdef AES_LE_OK ++/* little endian processor without data alignment restrictions */ ++#define word_in(x) *(u_int32_t*)(x) ++#define const_word_in(x) *(const u_int32_t*)(x) ++#define word_out(x,v) *(u_int32_t*)(x) = (v) ++#define const_word_out(x,v) *(const u_int32_t*)(x) = (v) ++#else ++/* slower but generic big endian or with data alignment restrictions */ ++/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */ ++#define word_in(x) ((u_int32_t)(((unsigned char *)(x))[0])|((u_int32_t)(((unsigned char *)(x))[1])<<8)|((u_int32_t)(((unsigned char *)(x))[2])<<16)|((u_int32_t)(((unsigned char *)(x))[3])<<24)) ++#define const_word_in(x) ((const u_int32_t)(((const unsigned char *)(x))[0])|((const u_int32_t)(((const unsigned char *)(x))[1])<<8)|((const u_int32_t)(((const unsigned char *)(x))[2])<<16)|((const u_int32_t)(((const unsigned char *)(x))[3])<<24)) ++#define word_out(x,v) ((unsigned char *)(x))[0]=(v),((unsigned char *)(x))[1]=((v)>>8),((unsigned char *)(x))[2]=((v)>>16),((unsigned char *)(x))[3]=((v)>>24) ++#define const_word_out(x,v) ((const unsigned char *)(x))[0]=(v),((const unsigned char *)(x))[1]=((v)>>8),((const unsigned char *)(x))[2]=((v)>>16),((const unsigned char *)(x))[3]=((v)>>24) ++#endif ++ ++// Disable at least some poor combinations of options ++ ++#if !defined(ONE_TABLE) && !defined(FOUR_TABLES) ++#define FIXED_TABLES ++#undef UNROLL ++#undef ONE_LR_TABLE ++#undef FOUR_LR_TABLES ++#undef ONE_IM_TABLE ++#undef FOUR_IM_TABLES ++#elif !defined(FOUR_TABLES) ++#ifdef FOUR_LR_TABLES ++#undef FOUR_LR_TABLES ++#define ONE_LR_TABLE ++#endif ++#ifdef FOUR_IM_TABLES ++#undef FOUR_IM_TABLES ++#define ONE_IM_TABLE ++#endif ++#elif !defined(AES_BLOCK_SIZE) ++#if defined(UNROLL) ++#define PARTIAL_UNROLL ++#undef UNROLL ++#endif ++#endif ++ ++// the finite field modular polynomial and elements ++ ++#define ff_poly 0x011b ++#define ff_hi 0x80 ++ ++// multiply four bytes in GF(2^8) by 'x' {02} in parallel ++ ++#define m1 0x80808080 ++#define m2 0x7f7f7f7f ++#define m3 0x0000001b ++#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3)) ++ ++// The following defines provide alternative definitions of FFmulX that might ++// give improved performance if a fast 32-bit multiply is not available. Note ++// that a temporary variable u needs to be defined where FFmulX is used. ++ ++// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6)) ++// #define m4 0x1b1b1b1b ++// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4) ++ ++// perform column mix operation on four bytes in parallel ++ ++#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1)) ++ ++#if defined(FIXED_TABLES) ++ ++// the S-Box table ++ ++static const unsigned char s_box[256] = ++{ ++ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, ++ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, ++ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, ++ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, ++ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, ++ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, ++ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, ++ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, ++ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, ++ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, ++ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, ++ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, ++ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, ++ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, ++ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, ++ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, ++ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, ++ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, ++ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, ++ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, ++ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, ++ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, ++ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, ++ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, ++ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, ++ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, ++ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, ++ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, ++ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, ++ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, ++ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, ++ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ++}; ++ ++// the inverse S-Box table ++ ++static const unsigned char inv_s_box[256] = ++{ ++ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, ++ 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, ++ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, ++ 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, ++ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, ++ 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, ++ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, ++ 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, ++ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, ++ 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, ++ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, ++ 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, ++ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, ++ 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, ++ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, ++ 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, ++ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, ++ 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, ++ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, ++ 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, ++ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, ++ 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, ++ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, ++ 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, ++ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, ++ 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, ++ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, ++ 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, ++ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, ++ 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, ++ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, ++ 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d ++}; ++ ++#define w0(p) 0x000000##p ++ ++// Number of elements required in this table for different ++// block and key lengths is: ++// ++// Nk = 4 6 8 ++// ---------- ++// Nb = 4 | 10 8 7 ++// 6 | 19 12 11 ++// 8 | 29 19 14 ++// ++// this table can be a table of bytes if the key schedule ++// code is adjusted accordingly ++ ++static const u_int32_t rcon_tab[29] = ++{ ++ w0(01), w0(02), w0(04), w0(08), ++ w0(10), w0(20), w0(40), w0(80), ++ w0(1b), w0(36), w0(6c), w0(d8), ++ w0(ab), w0(4d), w0(9a), w0(2f), ++ w0(5e), w0(bc), w0(63), w0(c6), ++ w0(97), w0(35), w0(6a), w0(d4), ++ w0(b3), w0(7d), w0(fa), w0(ef), ++ w0(c5) ++}; ++ ++#undef w0 ++ ++#define r0(p,q,r,s) 0x##p##q##r##s ++#define r1(p,q,r,s) 0x##q##r##s##p ++#define r2(p,q,r,s) 0x##r##s##p##q ++#define r3(p,q,r,s) 0x##s##p##q##r ++#define w0(p) 0x000000##p ++#define w1(p) 0x0000##p##00 ++#define w2(p) 0x00##p##0000 ++#define w3(p) 0x##p##000000 ++ ++#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES)) ++ ++// data for forward tables (other than last round) ++ ++#define f_table \ ++ r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\ ++ r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\ ++ r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\ ++ r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\ ++ r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\ ++ r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\ ++ r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\ ++ r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\ ++ r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\ ++ r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\ ++ r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\ ++ r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\ ++ r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\ ++ r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\ ++ r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\ ++ r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\ ++ r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\ ++ r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\ ++ r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\ ++ r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\ ++ r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\ ++ r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\ ++ r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\ ++ r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\ ++ r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\ ++ r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\ ++ r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\ ++ r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\ ++ r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\ ++ r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\ ++ r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\ ++ r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\ ++ r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\ ++ r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\ ++ r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\ ++ r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\ ++ r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\ ++ r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\ ++ r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\ ++ r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\ ++ r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\ ++ r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\ ++ r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\ ++ r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\ ++ r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\ ++ r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\ ++ r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\ ++ r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\ ++ r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\ ++ r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\ ++ r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\ ++ r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\ ++ r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\ ++ r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\ ++ r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\ ++ r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\ ++ r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\ ++ r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\ ++ r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\ ++ r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\ ++ r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\ ++ r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\ ++ r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\ ++ r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c) ++ ++// data for inverse tables (other than last round) ++ ++#define i_table \ ++ r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\ ++ r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\ ++ r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\ ++ r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\ ++ r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\ ++ r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\ ++ r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\ ++ r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\ ++ r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\ ++ r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\ ++ r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\ ++ r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\ ++ r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\ ++ r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\ ++ r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\ ++ r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\ ++ r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\ ++ r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\ ++ r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\ ++ r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\ ++ r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\ ++ r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\ ++ r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\ ++ r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\ ++ r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\ ++ r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\ ++ r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\ ++ r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\ ++ r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\ ++ r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\ ++ r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\ ++ r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\ ++ r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\ ++ r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\ ++ r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\ ++ r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\ ++ r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\ ++ r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\ ++ r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\ ++ r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\ ++ r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\ ++ r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\ ++ r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\ ++ r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\ ++ r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\ ++ r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\ ++ r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\ ++ r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\ ++ r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\ ++ r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\ ++ r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\ ++ r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\ ++ r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\ ++ r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\ ++ r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\ ++ r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\ ++ r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\ ++ r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\ ++ r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\ ++ r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\ ++ r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\ ++ r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\ ++ r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\ ++ r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0) ++ ++// generate the required tables in the desired endian format ++ ++#undef r ++#define r r0 ++ ++#if defined(ONE_TABLE) ++static const u_int32_t ft_tab[256] = ++ { f_table }; ++#elif defined(FOUR_TABLES) ++static const u_int32_t ft_tab[4][256] = ++{ { f_table }, ++#undef r ++#define r r1 ++ { f_table }, ++#undef r ++#define r r2 ++ { f_table }, ++#undef r ++#define r r3 ++ { f_table } ++}; ++#endif ++ ++#undef r ++#define r r0 ++#if defined(ONE_TABLE) ++static const u_int32_t it_tab[256] = ++ { i_table }; ++#elif defined(FOUR_TABLES) ++static const u_int32_t it_tab[4][256] = ++{ { i_table }, ++#undef r ++#define r r1 ++ { i_table }, ++#undef r ++#define r r2 ++ { i_table }, ++#undef r ++#define r r3 ++ { i_table } ++}; ++#endif ++ ++#endif ++ ++#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES)) ++ ++// data for inverse tables (last round) ++ ++#define li_table \ ++ w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\ ++ w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\ ++ w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\ ++ w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\ ++ w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\ ++ w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\ ++ w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\ ++ w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\ ++ w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\ ++ w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\ ++ w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\ ++ w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\ ++ w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\ ++ w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\ ++ w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\ ++ w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\ ++ w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\ ++ w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\ ++ w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\ ++ w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\ ++ w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\ ++ w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\ ++ w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\ ++ w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\ ++ w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\ ++ w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\ ++ w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\ ++ w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\ ++ w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\ ++ w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\ ++ w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\ ++ w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d), ++ ++// generate the required tables in the desired endian format ++ ++#undef r ++#define r(p,q,r,s) w0(q) ++#if defined(ONE_LR_TABLE) ++static const u_int32_t fl_tab[256] = ++ { f_table }; ++#elif defined(FOUR_LR_TABLES) ++static const u_int32_t fl_tab[4][256] = ++{ { f_table }, ++#undef r ++#define r(p,q,r,s) w1(q) ++ { f_table }, ++#undef r ++#define r(p,q,r,s) w2(q) ++ { f_table }, ++#undef r ++#define r(p,q,r,s) w3(q) ++ { f_table } ++}; ++#endif ++ ++#undef w ++#define w w0 ++#if defined(ONE_LR_TABLE) ++static const u_int32_t il_tab[256] = ++ { li_table }; ++#elif defined(FOUR_LR_TABLES) ++static const u_int32_t il_tab[4][256] = ++{ { li_table }, ++#undef w ++#define w w1 ++ { li_table }, ++#undef w ++#define w w2 ++ { li_table }, ++#undef w ++#define w w3 ++ { li_table } ++}; ++#endif ++ ++#endif ++ ++#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES)) ++ ++#define m_table \ ++ r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\ ++ r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\ ++ r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\ ++ r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\ ++ r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\ ++ r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\ ++ r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\ ++ r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\ ++ r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\ ++ r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\ ++ r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\ ++ r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\ ++ r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\ ++ r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\ ++ r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\ ++ r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\ ++ r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\ ++ r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\ ++ r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\ ++ r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\ ++ r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\ ++ r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\ ++ r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\ ++ r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\ ++ r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\ ++ r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\ ++ r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\ ++ r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\ ++ r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\ ++ r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\ ++ r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\ ++ r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\ ++ r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\ ++ r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\ ++ r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\ ++ r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\ ++ r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\ ++ r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\ ++ r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\ ++ r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\ ++ r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\ ++ r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\ ++ r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\ ++ r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\ ++ r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\ ++ r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\ ++ r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\ ++ r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\ ++ r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\ ++ r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\ ++ r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\ ++ r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\ ++ r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\ ++ r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\ ++ r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\ ++ r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\ ++ r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\ ++ r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\ ++ r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\ ++ r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\ ++ r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\ ++ r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\ ++ r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\ ++ r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d) ++ ++#undef r ++#define r r0 ++ ++#if defined(ONE_IM_TABLE) ++static const u_int32_t im_tab[256] = ++ { m_table }; ++#elif defined(FOUR_IM_TABLES) ++static const u_int32_t im_tab[4][256] = ++{ { m_table }, ++#undef r ++#define r r1 ++ { m_table }, ++#undef r ++#define r r2 ++ { m_table }, ++#undef r ++#define r r3 ++ { m_table } ++}; ++#endif ++ ++#endif ++ ++#else ++ ++static int tab_gen = 0; ++ ++static unsigned char s_box[256]; // the S box ++static unsigned char inv_s_box[256]; // the inverse S box ++static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants ++ ++#if defined(ONE_TABLE) ++static u_int32_t ft_tab[256]; ++static u_int32_t it_tab[256]; ++#elif defined(FOUR_TABLES) ++static u_int32_t ft_tab[4][256]; ++static u_int32_t it_tab[4][256]; ++#endif ++ ++#if defined(ONE_LR_TABLE) ++static u_int32_t fl_tab[256]; ++static u_int32_t il_tab[256]; ++#elif defined(FOUR_LR_TABLES) ++static u_int32_t fl_tab[4][256]; ++static u_int32_t il_tab[4][256]; ++#endif ++ ++#if defined(ONE_IM_TABLE) ++static u_int32_t im_tab[256]; ++#elif defined(FOUR_IM_TABLES) ++static u_int32_t im_tab[4][256]; ++#endif ++ ++// Generate the tables for the dynamic table option ++ ++#if !defined(FF_TABLES) ++ ++// It will generally be sensible to use tables to compute finite ++// field multiplies and inverses but where memory is scarse this ++// code might sometimes be better. ++ ++// return 2 ^ (n - 1) where n is the bit number of the highest bit ++// set in x with x in the range 1 < x < 0x00000200. This form is ++// used so that locals within FFinv can be bytes rather than words ++ ++static unsigned char hibit(const u_int32_t x) ++{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2)); ++ ++ r |= (r >> 2); ++ r |= (r >> 4); ++ return (r + 1) >> 1; ++} ++ ++// return the inverse of the finite field element x ++ ++static unsigned char FFinv(const unsigned char x) ++{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; ++ ++ if(x < 2) return x; ++ ++ for(;;) ++ { ++ if(!n1) return v1; ++ ++ while(n2 >= n1) ++ { ++ n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2); ++ } ++ ++ if(!n2) return v2; ++ ++ while(n1 >= n2) ++ { ++ n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1); ++ } ++ } ++} ++ ++// define the finite field multiplies required for Rijndael ++ ++#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0)) ++#define FFmul03(x) ((x) ^ FFmul02(x)) ++#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x)))) ++#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x)))) ++#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x)))) ++#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x))) ++ ++#else ++ ++#define FFinv(x) ((x) ? pow[255 - log[x]]: 0) ++ ++#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0) ++#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0) ++#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0) ++#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0) ++#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0) ++#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0) ++ ++#endif ++ ++// The forward and inverse affine transformations used in the S-box ++ ++#define fwd_affine(x) \ ++ (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8))) ++ ++#define inv_affine(x) \ ++ (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8))) ++ ++static void gen_tabs(void) ++{ u_int32_t i, w; ++ ++#if defined(FF_TABLES) ++ ++ unsigned char pow[512], log[256]; ++ ++ // log and power tables for GF(2^8) finite field with ++ // 0x011b as modular polynomial - the simplest primitive ++ // root is 0x03, used here to generate the tables ++ ++ i = 0; w = 1; ++ do ++ { ++ pow[i] = (unsigned char)w; ++ pow[i + 255] = (unsigned char)w; ++ log[w] = (unsigned char)i++; ++ w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0); ++ } ++ while (w != 1); ++ ++#endif ++ ++ for(i = 0, w = 1; i < AES_RC_LENGTH; ++i) ++ { ++ rcon_tab[i] = bytes2word(w, 0, 0, 0); ++ w = (w << 1) ^ (w & ff_hi ? ff_poly : 0); ++ } ++ ++ for(i = 0; i < 256; ++i) ++ { unsigned char b; ++ ++ s_box[i] = b = fwd_affine(FFinv((unsigned char)i)); ++ ++ w = bytes2word(b, 0, 0, 0); ++#if defined(ONE_LR_TABLE) ++ fl_tab[i] = w; ++#elif defined(FOUR_LR_TABLES) ++ fl_tab[0][i] = w; ++ fl_tab[1][i] = upr(w,1); ++ fl_tab[2][i] = upr(w,2); ++ fl_tab[3][i] = upr(w,3); ++#endif ++ w = bytes2word(FFmul02(b), b, b, FFmul03(b)); ++#if defined(ONE_TABLE) ++ ft_tab[i] = w; ++#elif defined(FOUR_TABLES) ++ ft_tab[0][i] = w; ++ ft_tab[1][i] = upr(w,1); ++ ft_tab[2][i] = upr(w,2); ++ ft_tab[3][i] = upr(w,3); ++#endif ++ inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i)); ++ ++ w = bytes2word(b, 0, 0, 0); ++#if defined(ONE_LR_TABLE) ++ il_tab[i] = w; ++#elif defined(FOUR_LR_TABLES) ++ il_tab[0][i] = w; ++ il_tab[1][i] = upr(w,1); ++ il_tab[2][i] = upr(w,2); ++ il_tab[3][i] = upr(w,3); ++#endif ++ w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b)); ++#if defined(ONE_TABLE) ++ it_tab[i] = w; ++#elif defined(FOUR_TABLES) ++ it_tab[0][i] = w; ++ it_tab[1][i] = upr(w,1); ++ it_tab[2][i] = upr(w,2); ++ it_tab[3][i] = upr(w,3); ++#endif ++#if defined(ONE_IM_TABLE) ++ im_tab[b] = w; ++#elif defined(FOUR_IM_TABLES) ++ im_tab[0][b] = w; ++ im_tab[1][b] = upr(w,1); ++ im_tab[2][b] = upr(w,2); ++ im_tab[3][b] = upr(w,3); ++#endif ++ ++ } ++} ++ ++#endif ++ ++#define no_table(x,box,vf,rf,c) bytes2word( \ ++ box[bval(vf(x,0,c),rf(0,c))], \ ++ box[bval(vf(x,1,c),rf(1,c))], \ ++ box[bval(vf(x,2,c),rf(2,c))], \ ++ box[bval(vf(x,3,c),rf(3,c))]) ++ ++#define one_table(x,op,tab,vf,rf,c) \ ++ ( tab[bval(vf(x,0,c),rf(0,c))] \ ++ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \ ++ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \ ++ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3)) ++ ++#define four_tables(x,tab,vf,rf,c) \ ++ ( tab[0][bval(vf(x,0,c),rf(0,c))] \ ++ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \ ++ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \ ++ ^ tab[3][bval(vf(x,3,c),rf(3,c))]) ++ ++#define vf1(x,r,c) (x) ++#define rf1(r,c) (r) ++#define rf2(r,c) ((r-c)&3) ++ ++#if defined(FOUR_LR_TABLES) ++#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c) ++#elif defined(ONE_LR_TABLE) ++#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c) ++#else ++#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c) ++#endif ++ ++#if defined(FOUR_IM_TABLES) ++#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0) ++#elif defined(ONE_IM_TABLE) ++#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0) ++#else ++#define inv_mcol(x) \ ++ (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \ ++ f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1)) ++#endif ++ ++// Subroutine to set the block size (if variable) in bytes, legal ++// values being 16, 24 and 32. ++ ++#if defined(AES_BLOCK_SIZE) ++#define nc (AES_BLOCK_SIZE / 4) ++#else ++#define nc (cx->aes_Ncol) ++ ++void aes_set_blk(aes_context *cx, int n_bytes) ++{ ++#if !defined(FIXED_TABLES) ++ if(!tab_gen) { gen_tabs(); tab_gen = 1; } ++#endif ++ ++ switch(n_bytes) { ++ case 32: /* bytes */ ++ case 256: /* bits */ ++ nc = 8; ++ break; ++ case 24: /* bytes */ ++ case 192: /* bits */ ++ nc = 6; ++ break; ++ case 16: /* bytes */ ++ case 128: /* bits */ ++ default: ++ nc = 4; ++ break; ++ } ++} ++ ++#endif ++ ++// Initialise the key schedule from the user supplied key. The key ++// length is now specified in bytes - 16, 24 or 32 as appropriate. ++// This corresponds to bit lengths of 128, 192 and 256 bits, and ++// to Nk values of 4, 6 and 8 respectively. ++ ++#define mx(t,f) (*t++ = inv_mcol(*f),f++) ++#define cp(t,f) *t++ = *f++ ++ ++#if AES_BLOCK_SIZE == 16 ++#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s) ++#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s) ++#elif AES_BLOCK_SIZE == 24 ++#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \ ++ cp(d,s); cp(d,s) ++#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \ ++ mx(d,s); mx(d,s) ++#elif AES_BLOCK_SIZE == 32 ++#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \ ++ cp(d,s); cp(d,s); cp(d,s); cp(d,s) ++#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \ ++ mx(d,s); mx(d,s); mx(d,s); mx(d,s) ++#else ++ ++#define cpy(d,s) \ ++switch(nc) \ ++{ case 8: cp(d,s); cp(d,s); \ ++ case 6: cp(d,s); cp(d,s); \ ++ case 4: cp(d,s); cp(d,s); \ ++ cp(d,s); cp(d,s); \ ++} ++ ++#define mix(d,s) \ ++switch(nc) \ ++{ case 8: mx(d,s); mx(d,s); \ ++ case 6: mx(d,s); mx(d,s); \ ++ case 4: mx(d,s); mx(d,s); \ ++ mx(d,s); mx(d,s); \ ++} ++ ++#endif ++ ++void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f) ++{ u_int32_t *kf, *kt, rci; ++ ++#if !defined(FIXED_TABLES) ++ if(!tab_gen) { gen_tabs(); tab_gen = 1; } ++#endif ++ ++ switch(n_bytes) { ++ case 32: /* bytes */ ++ case 256: /* bits */ ++ cx->aes_Nkey = 8; ++ break; ++ case 24: /* bytes */ ++ case 192: /* bits */ ++ cx->aes_Nkey = 6; ++ break; ++ case 16: /* bytes */ ++ case 128: /* bits */ ++ default: ++ cx->aes_Nkey = 4; ++ break; ++ } ++ ++ cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6; ++ ++ cx->aes_e_key[0] = const_word_in(in_key ); ++ cx->aes_e_key[1] = const_word_in(in_key + 4); ++ cx->aes_e_key[2] = const_word_in(in_key + 8); ++ cx->aes_e_key[3] = const_word_in(in_key + 12); ++ ++ kf = cx->aes_e_key; ++ kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey; ++ rci = 0; ++ ++ switch(cx->aes_Nkey) ++ { ++ case 4: do ++ { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++]; ++ kf[5] = kf[1] ^ kf[4]; ++ kf[6] = kf[2] ^ kf[5]; ++ kf[7] = kf[3] ^ kf[6]; ++ kf += 4; ++ } ++ while(kf < kt); ++ break; ++ ++ case 6: cx->aes_e_key[4] = const_word_in(in_key + 16); ++ cx->aes_e_key[5] = const_word_in(in_key + 20); ++ do ++ { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++]; ++ kf[ 7] = kf[1] ^ kf[ 6]; ++ kf[ 8] = kf[2] ^ kf[ 7]; ++ kf[ 9] = kf[3] ^ kf[ 8]; ++ kf[10] = kf[4] ^ kf[ 9]; ++ kf[11] = kf[5] ^ kf[10]; ++ kf += 6; ++ } ++ while(kf < kt); ++ break; ++ ++ case 8: cx->aes_e_key[4] = const_word_in(in_key + 16); ++ cx->aes_e_key[5] = const_word_in(in_key + 20); ++ cx->aes_e_key[6] = const_word_in(in_key + 24); ++ cx->aes_e_key[7] = const_word_in(in_key + 28); ++ do ++ { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++]; ++ kf[ 9] = kf[1] ^ kf[ 8]; ++ kf[10] = kf[2] ^ kf[ 9]; ++ kf[11] = kf[3] ^ kf[10]; ++ kf[12] = kf[4] ^ ls_box(kf[11],0); ++ kf[13] = kf[5] ^ kf[12]; ++ kf[14] = kf[6] ^ kf[13]; ++ kf[15] = kf[7] ^ kf[14]; ++ kf += 8; ++ } ++ while (kf < kt); ++ break; ++ } ++ ++ if(!f) ++ { u_int32_t i; ++ ++ kt = cx->aes_d_key + nc * cx->aes_Nrnd; ++ kf = cx->aes_e_key; ++ ++ cpy(kt, kf); kt -= 2 * nc; ++ ++ for(i = 1; i < cx->aes_Nrnd; ++i) ++ { ++#if defined(ONE_TABLE) || defined(FOUR_TABLES) ++#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES) ++ u_int32_t f2, f4, f8, f9; ++#endif ++ mix(kt, kf); ++#else ++ cpy(kt, kf); ++#endif ++ kt -= 2 * nc; ++ } ++ ++ cpy(kt, kf); ++ } ++} ++ ++// y = output word, x = input word, r = row, c = column ++// for r = 0, 1, 2 and 3 = column accessed for row r ++ ++#if defined(ARRAYS) ++#define s(x,c) x[c] ++#else ++#define s(x,c) x##c ++#endif ++ ++// I am grateful to Frank Yellin for the following constructions ++// which, given the column (c) of the output state variable that ++// is being computed, return the input state variables which are ++// needed for each row (r) of the state ++ ++// For the fixed block size options, compilers reduce these two ++// expressions to fixed variable references. For variable block ++// size code conditional clauses will sometimes be returned ++ ++#define unused 77 // Sunset Strip ++ ++#define fwd_var(x,r,c) \ ++ ( r==0 ? \ ++ ( c==0 ? s(x,0) \ ++ : c==1 ? s(x,1) \ ++ : c==2 ? s(x,2) \ ++ : c==3 ? s(x,3) \ ++ : c==4 ? s(x,4) \ ++ : c==5 ? s(x,5) \ ++ : c==6 ? s(x,6) \ ++ : s(x,7)) \ ++ : r==1 ? \ ++ ( c==0 ? s(x,1) \ ++ : c==1 ? s(x,2) \ ++ : c==2 ? s(x,3) \ ++ : c==3 ? nc==4 ? s(x,0) : s(x,4) \ ++ : c==4 ? s(x,5) \ ++ : c==5 ? nc==8 ? s(x,6) : s(x,0) \ ++ : c==6 ? s(x,7) \ ++ : s(x,0)) \ ++ : r==2 ? \ ++ ( c==0 ? nc==8 ? s(x,3) : s(x,2) \ ++ : c==1 ? nc==8 ? s(x,4) : s(x,3) \ ++ : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \ ++ : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \ ++ : c==4 ? nc==8 ? s(x,7) : s(x,0) \ ++ : c==5 ? nc==8 ? s(x,0) : s(x,1) \ ++ : c==6 ? s(x,1) \ ++ : s(x,2)) \ ++ : \ ++ ( c==0 ? nc==8 ? s(x,4) : s(x,3) \ ++ : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \ ++ : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \ ++ : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \ ++ : c==4 ? nc==8 ? s(x,0) : s(x,1) \ ++ : c==5 ? nc==8 ? s(x,1) : s(x,2) \ ++ : c==6 ? s(x,2) \ ++ : s(x,3))) ++ ++#define inv_var(x,r,c) \ ++ ( r==0 ? \ ++ ( c==0 ? s(x,0) \ ++ : c==1 ? s(x,1) \ ++ : c==2 ? s(x,2) \ ++ : c==3 ? s(x,3) \ ++ : c==4 ? s(x,4) \ ++ : c==5 ? s(x,5) \ ++ : c==6 ? s(x,6) \ ++ : s(x,7)) \ ++ : r==1 ? \ ++ ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \ ++ : c==1 ? s(x,0) \ ++ : c==2 ? s(x,1) \ ++ : c==3 ? s(x,2) \ ++ : c==4 ? s(x,3) \ ++ : c==5 ? s(x,4) \ ++ : c==6 ? s(x,5) \ ++ : s(x,6)) \ ++ : r==2 ? \ ++ ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \ ++ : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \ ++ : c==2 ? nc==8 ? s(x,7) : s(x,0) \ ++ : c==3 ? nc==8 ? s(x,0) : s(x,1) \ ++ : c==4 ? nc==8 ? s(x,1) : s(x,2) \ ++ : c==5 ? nc==8 ? s(x,2) : s(x,3) \ ++ : c==6 ? s(x,3) \ ++ : s(x,4)) \ ++ : \ ++ ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \ ++ : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \ ++ : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \ ++ : c==3 ? nc==8 ? s(x,7) : s(x,0) \ ++ : c==4 ? nc==8 ? s(x,0) : s(x,1) \ ++ : c==5 ? nc==8 ? s(x,1) : s(x,2) \ ++ : c==6 ? s(x,2) \ ++ : s(x,3))) ++ ++#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c] ++#define so(y,x,c) word_out(y + 4 * c, s(x,c)) ++ ++#if defined(FOUR_TABLES) ++#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c) ++#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c) ++#elif defined(ONE_TABLE) ++#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c) ++#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c) ++#else ++#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c] ++#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]) ++#endif ++ ++#if defined(FOUR_LR_TABLES) ++#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c) ++#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c) ++#elif defined(ONE_LR_TABLE) ++#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c) ++#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c) ++#else ++#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c] ++#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c] ++#endif ++ ++#if AES_BLOCK_SIZE == 16 ++ ++#if defined(ARRAYS) ++#define locals(y,x) x[4],y[4] ++#else ++#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3 ++// the following defines prevent the compiler requiring the declaration ++// of generated but unused variables in the fwd_var and inv_var macros ++#define b04 unused ++#define b05 unused ++#define b06 unused ++#define b07 unused ++#define b14 unused ++#define b15 unused ++#define b16 unused ++#define b17 unused ++#endif ++#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ ++ s(y,2) = s(x,2); s(y,3) = s(x,3); ++#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3) ++#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3) ++#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3) ++ ++#elif AES_BLOCK_SIZE == 24 ++ ++#if defined(ARRAYS) ++#define locals(y,x) x[6],y[6] ++#else ++#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \ ++ y##0,y##1,y##2,y##3,y##4,y##5 ++#define b06 unused ++#define b07 unused ++#define b16 unused ++#define b17 unused ++#endif ++#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ ++ s(y,2) = s(x,2); s(y,3) = s(x,3); \ ++ s(y,4) = s(x,4); s(y,5) = s(x,5); ++#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \ ++ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5) ++#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \ ++ so(y,x,3); so(y,x,4); so(y,x,5) ++#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \ ++ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5) ++#else ++ ++#if defined(ARRAYS) ++#define locals(y,x) x[8],y[8] ++#else ++#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \ ++ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7 ++#endif ++#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ ++ s(y,2) = s(x,2); s(y,3) = s(x,3); \ ++ s(y,4) = s(x,4); s(y,5) = s(x,5); \ ++ s(y,6) = s(x,6); s(y,7) = s(x,7); ++ ++#if AES_BLOCK_SIZE == 32 ++ ++#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \ ++ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7) ++#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \ ++ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7) ++#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \ ++ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7) ++#else ++ ++#define state_in(y,x,k) \ ++switch(nc) \ ++{ case 8: si(y,x,k,7); si(y,x,k,6); \ ++ case 6: si(y,x,k,5); si(y,x,k,4); \ ++ case 4: si(y,x,k,3); si(y,x,k,2); \ ++ si(y,x,k,1); si(y,x,k,0); \ ++} ++ ++#define state_out(y,x) \ ++switch(nc) \ ++{ case 8: so(y,x,7); so(y,x,6); \ ++ case 6: so(y,x,5); so(y,x,4); \ ++ case 4: so(y,x,3); so(y,x,2); \ ++ so(y,x,1); so(y,x,0); \ ++} ++ ++#if defined(FAST_VARIABLE) ++ ++#define round(rm,y,x,k) \ ++switch(nc) \ ++{ case 8: rm(y,x,k,7); rm(y,x,k,6); \ ++ rm(y,x,k,5); rm(y,x,k,4); \ ++ rm(y,x,k,3); rm(y,x,k,2); \ ++ rm(y,x,k,1); rm(y,x,k,0); \ ++ break; \ ++ case 6: rm(y,x,k,5); rm(y,x,k,4); \ ++ rm(y,x,k,3); rm(y,x,k,2); \ ++ rm(y,x,k,1); rm(y,x,k,0); \ ++ break; \ ++ case 4: rm(y,x,k,3); rm(y,x,k,2); \ ++ rm(y,x,k,1); rm(y,x,k,0); \ ++ break; \ ++} ++#else ++ ++#define round(rm,y,x,k) \ ++switch(nc) \ ++{ case 8: rm(y,x,k,7); rm(y,x,k,6); \ ++ case 6: rm(y,x,k,5); rm(y,x,k,4); \ ++ case 4: rm(y,x,k,3); rm(y,x,k,2); \ ++ rm(y,x,k,1); rm(y,x,k,0); \ ++} ++ ++#endif ++ ++#endif ++#endif ++ ++void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[]) ++{ u_int32_t locals(b0, b1); ++ const u_int32_t *kp = cx->aes_e_key; ++ ++#if !defined(ONE_TABLE) && !defined(FOUR_TABLES) ++ u_int32_t f2; ++#endif ++ ++ state_in(b0, in_blk, kp); kp += nc; ++ ++#if defined(UNROLL) ++ ++ switch(cx->aes_Nrnd) ++ { ++ case 14: round(fwd_rnd, b1, b0, kp ); ++ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc; ++ case 12: round(fwd_rnd, b1, b0, kp ); ++ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc; ++ case 10: round(fwd_rnd, b1, b0, kp ); ++ round(fwd_rnd, b0, b1, kp + nc); ++ round(fwd_rnd, b1, b0, kp + 2 * nc); ++ round(fwd_rnd, b0, b1, kp + 3 * nc); ++ round(fwd_rnd, b1, b0, kp + 4 * nc); ++ round(fwd_rnd, b0, b1, kp + 5 * nc); ++ round(fwd_rnd, b1, b0, kp + 6 * nc); ++ round(fwd_rnd, b0, b1, kp + 7 * nc); ++ round(fwd_rnd, b1, b0, kp + 8 * nc); ++ round(fwd_lrnd, b0, b1, kp + 9 * nc); ++ } ++ ++#elif defined(PARTIAL_UNROLL) ++ { u_int32_t rnd; ++ ++ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd) ++ { ++ round(fwd_rnd, b1, b0, kp); ++ round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc; ++ } ++ ++ round(fwd_rnd, b1, b0, kp); ++ round(fwd_lrnd, b0, b1, kp + nc); ++ } ++#else ++ { u_int32_t rnd; ++ ++ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd) ++ { ++ round(fwd_rnd, b1, b0, kp); ++ l_copy(b0, b1); kp += nc; ++ } ++ ++ round(fwd_lrnd, b0, b1, kp); ++ } ++#endif ++ ++ state_out(out_blk, b0); ++} ++ ++void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[]) ++{ u_int32_t locals(b0, b1); ++ const u_int32_t *kp = cx->aes_d_key; ++ ++#if !defined(ONE_TABLE) && !defined(FOUR_TABLES) ++ u_int32_t f2, f4, f8, f9; ++#endif ++ ++ state_in(b0, in_blk, kp); kp += nc; ++ ++#if defined(UNROLL) ++ ++ switch(cx->aes_Nrnd) ++ { ++ case 14: round(inv_rnd, b1, b0, kp ); ++ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc; ++ case 12: round(inv_rnd, b1, b0, kp ); ++ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc; ++ case 10: round(inv_rnd, b1, b0, kp ); ++ round(inv_rnd, b0, b1, kp + nc); ++ round(inv_rnd, b1, b0, kp + 2 * nc); ++ round(inv_rnd, b0, b1, kp + 3 * nc); ++ round(inv_rnd, b1, b0, kp + 4 * nc); ++ round(inv_rnd, b0, b1, kp + 5 * nc); ++ round(inv_rnd, b1, b0, kp + 6 * nc); ++ round(inv_rnd, b0, b1, kp + 7 * nc); ++ round(inv_rnd, b1, b0, kp + 8 * nc); ++ round(inv_lrnd, b0, b1, kp + 9 * nc); ++ } ++ ++#elif defined(PARTIAL_UNROLL) ++ { u_int32_t rnd; ++ ++ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd) ++ { ++ round(inv_rnd, b1, b0, kp); ++ round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc; ++ } ++ ++ round(inv_rnd, b1, b0, kp); ++ round(inv_lrnd, b0, b1, kp + nc); ++ } ++#else ++ { u_int32_t rnd; ++ ++ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd) ++ { ++ round(inv_rnd, b1, b0, kp); ++ l_copy(b0, b1); kp += nc; ++ } ++ ++ round(inv_lrnd, b0, b1, kp); ++ } ++#endif ++ ++ state_out(out_blk, b0); ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/aes/aes_cbc.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,43 @@ ++/* ++// I retain copyright in this code but I encourage its free use provided ++// that I don't carry any responsibility for the results. I am especially ++// happy to see it used in free and open source software. If you do use ++// it I would appreciate an acknowledgement of its origin in the code or ++// the product that results and I would also appreciate knowing a little ++// about the use to which it is being put. I am grateful to Frank Yellin ++// for some ideas that are used in this implementation. ++// ++// Dr B. R. Gladman 6th April 2001. ++// ++// This is an implementation of the AES encryption algorithm (Rijndael) ++// designed by Joan Daemen and Vincent Rijmen. This version is designed ++// to provide both fixed and dynamic block and key lengths and can also ++// run with either big or little endian internal byte order (see aes.h). ++// It inputs block and key lengths in bytes with the legal values being ++// 16, 24 and 32. ++* ++*/ ++ ++#ifdef __KERNEL__ ++#include ++#else ++#include ++#endif ++#include "crypto/aes_cbc.h" ++#include "crypto/cbc_generic.h" ++ ++/* returns bool success */ ++int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) { ++ aes_set_key(aes_ctx, key, keysize, 0); ++ return 1; ++} ++CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt); ++ ++ ++/* ++ * $Log: aes_cbc.c,v $ ++ * Revision 1.1 2004/04/06 02:48:12 mcr ++ * pullup of AES cipher from alg-branch. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/aes/aes_xcbc_mac.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,67 @@ ++#ifdef __KERNEL__ ++#include ++#include ++#define DEBUG(x) ++#else ++#include ++#include ++#define DEBUG(x) x ++#endif ++ ++#include "crypto/aes.h" ++#include "crypto/aes_xcbc_mac.h" ++ ++int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen) ++{ ++ int ret=1; ++ aes_block kn[3] = { ++ { 0x01010101, 0x01010101, 0x01010101, 0x01010101 }, ++ { 0x02020202, 0x02020202, 0x02020202, 0x02020202 }, ++ { 0x03030303, 0x03030303, 0x03030303, 0x03030303 }, ++ }; ++ aes_set_key(&ctxm->ctx_k1, key, keylen, 0); ++ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]); ++ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2); ++ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3); ++ aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0); ++ return ret; ++} ++static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) { ++ int pos=0; ++ for (pos=1; pos <= 16; pos++, in++, out++) { ++ if (pos <= len) ++ *out ^= *in; ++ if (pos > len) { ++ DEBUG(printf("put 0x80 at pos=%d\n", pos)); ++ *out ^= 0x80; ++ break; ++ } ++ } ++} ++static void xor_block(aes_block res, const aes_block op) { ++ res[0] ^= op[0]; ++ res[1] ^= op[1]; ++ res[2] ^= op[2]; ++ res[3] ^= op[3]; ++} ++int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) { ++ int ret=ilen; ++ u_int32_t out[4] = { 0, 0, 0, 0 }; ++ for (; ilen > 16 ; ilen-=16) { ++ xor_block(out, (const u_int32_t*) &in[0]); ++ aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]); ++ in+=16; ++ } ++ do_pad_xor((u_int8_t *)&out, in, ilen); ++ if (ilen==16) { ++ DEBUG(printf("using k3\n")); ++ xor_block(out, ctxm->k3); ++ } ++ else ++ { ++ DEBUG(printf("using k2\n")); ++ xor_block(out, ctxm->k2); ++ } ++ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash); ++ return ret; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/aes/test_main.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,41 @@ ++#include ++#include ++#include ++#include "aes_cbc.h" ++#define AES_BLOCK_SIZE 16 ++#define KEY_SIZE 128 /* bits */ ++#define KEY "1234567890123456" ++#define STR "hola guaso como estaisss ... 012" ++#define STRSZ (sizeof(STR)-1) ++ ++#define EMT_AESCBC_BLKLEN AES_BLOCK_SIZE ++#define AES_CONTEXT_T aes_context ++#define EMT_ESPAES_KEY_SZ 16 ++int pretty_print(const unsigned char *buf, int count) { ++ int i=0; ++ for (;i ++#include ++#include ++#include "aes.h" ++#include "aes_xcbc_mac.h" ++#define STR "Hola guasssso c|mo estais ...012" ++void print_hash(const __u8 *hash) { ++ printf("%08x %08x %08x %08x\n", ++ *(__u32*)(&hash[0]), ++ *(__u32*)(&hash[4]), ++ *(__u32*)(&hash[8]), ++ *(__u32*)(&hash[12])); ++} ++int main(int argc, char *argv[]) { ++ aes_block key= { 0xdeadbeef, 0xceedcaca, 0xcafebabe, 0xff010204 }; ++ __u8 hash[16]; ++ char *str = argv[1]; ++ aes_context_mac ctx; ++ if (str==NULL) { ++ fprintf(stderr, "pasame el str\n"); ++ return 255; ++ } ++ AES_xcbc_mac_set_key(&ctx, (__u8 *)&key, sizeof(key)); ++ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash); ++ print_hash(hash); ++ str[2]='x'; ++ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash); ++ print_hash(hash); ++ return 0; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/COPYRIGHT Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,50 @@ ++Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++All rights reserved. ++ ++This package is an DES implementation written by Eric Young (eay@cryptsoft.com). ++The implementation was written so as to conform with MIT's libdes. ++ ++This library is free for commercial and non-commercial use as long as ++the following conditions are aheared to. The following conditions ++apply to all code found in this distribution. ++ ++Copyright remains Eric Young's, and as such any Copyright notices in ++the code are not to be removed. ++If this package is used in a product, Eric Young should be given attribution ++as the author of that the SSL library. This can be in the form of a textual ++message at program startup or in documentation (online or textual) provided ++with the package. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions ++are met: ++1. Redistributions of source code must retain the copyright ++ notice, this list of conditions and the following disclaimer. ++2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++3. All advertising materials mentioning features or use of this software ++ must display the following acknowledgement: ++ This product includes software developed by Eric Young (eay@cryptsoft.com) ++ ++THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++SUCH DAMAGE. ++ ++The license and distribution terms for any publically available version or ++derivative of this code cannot be changed. i.e. this code cannot simply be ++copied and put under another distrubution license ++[including the GNU Public License.] ++ ++The reason behind this being stated in this direct manner is past ++experience in code simply being copied and the attribution removed ++from it and then being distributed as part of other packages. This ++implementation was a non-trivial and unpaid effort. +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/INSTALL Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,69 @@ ++Check the CC and CFLAGS lines in the makefile ++ ++If your C library does not support the times(3) function, change the ++#define TIMES to ++#undef TIMES in speed.c ++If it does, check the HZ value for the times(3) function. ++If your system does not define CLK_TCK it will be assumed to ++be 100.0. ++ ++If possible use gcc v 2.7.? ++Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc) ++In recent times, some system compilers give better performace. ++ ++type 'make' ++ ++run './destest' to check things are ok. ++run './rpw' to check the tty code for reading passwords works. ++run './speed' to see how fast those optimisations make the library run :-) ++run './des_opts' to determin the best compile time options. ++ ++The output from des_opts should be put in the makefile options and des_enc.c ++should be rebuilt. For 64 bit computers, do not use the DES_PTR option. ++For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int' ++and then you can use the 'DES_PTR' option. ++ ++The file options.txt has the options listed for best speed on quite a ++few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then ++turn on the relevent option in the Makefile ++ ++There are some special Makefile targets that make life easier. ++make cc - standard cc build ++make gcc - standard gcc build ++make x86-elf - x86 assembler (elf), linux-elf. ++make x86-out - x86 assembler (a.out), FreeBSD ++make x86-solaris- x86 assembler ++make x86-bsdi - x86 assembler (a.out with primative assembler). ++ ++If at all possible use the assembler (for Windows NT/95, use ++asm/win32.obj to link with). The x86 assembler is very very fast. ++ ++A make install will by default install ++libdes.a in /usr/local/lib/libdes.a ++des in /usr/local/bin/des ++des_crypt.man in /usr/local/man/man3/des_crypt.3 ++des.man in /usr/local/man/man1/des.1 ++des.h in /usr/include/des.h ++ ++des(1) should be compatible with sunOS's but I have been unable to ++test it. ++ ++These routines should compile on MSDOS, most 32bit and 64bit version ++of Unix (BSD and SYSV) and VMS, without modification. ++The only problems should be #include files that are in the wrong places. ++ ++These routines can be compiled under MSDOS. ++I have successfully encrypted files using des(1) under MSDOS and then ++decrypted the files on a SparcStation. ++I have been able to compile and test the routines with ++Microsoft C v 5.1 and Turbo C v 2.0. ++The code in this library is in no way optimised for the 16bit ++operation of MSDOS. ++ ++When building for glibc, ignore all of the above and just unpack into ++glibc-1.??/des and then gmake as per normal. ++ ++As a final note on performace. Certain CPUs like sparcs and Alpha often give ++a %10 speed difference depending on the link order. It is rather anoying ++when one program reports 'x' DES encrypts a second and another reports ++'x*0.9' the speed. +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/Makefile.objs Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,20 @@ ++obj-$(CONFIG_IPSEC_ENC_3DES) += cbc_enc.o ++#obj-$(CONFIG_IPSEC_ENC_3DES) += des_opts.o ++obj-$(CONFIG_IPSEC_ENC_3DES) += ecb_enc.o ++#obj-$(CONFIG_IPSEC_ENC_3DES) += fcrypt.o ++obj-$(CONFIG_IPSEC_ENC_3DES) += set_key.o ++ ++ifeq ($(strip ${SUBARCH}),) ++SUBARCH:=${ARCH} ++endif ++ ++ifeq (${SUBARCH},i386) ++obj-$(CONFIG_IPSEC_ENC_3DES) += dx86unix.o ++else ++obj-$(CONFIG_IPSEC_ENC_3DES) += des_enc.o ++endif ++ ++ ++ ++ ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/README Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,54 @@ ++ ++ libdes, Version 4.01 10-Jan-97 ++ ++ Copyright (c) 1997, Eric Young ++ All rights reserved. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms specified in COPYRIGHT. ++ ++-- ++The primary ftp site for this library is ++ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz ++libdes is now also shipped with SSLeay. Primary ftp site of ++ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz ++ ++The best way to build this library is to build it as part of SSLeay. ++ ++This kit builds a DES encryption library and a DES encryption program. ++It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb, ++triple cfb, desx, and MIT's pcbc encryption modes and also has a fast ++implementation of crypt(3). ++It contains support routines to read keys from a terminal, ++generate a random key, generate a key from an arbitrary length string, ++read/write encrypted data from/to a file descriptor. ++ ++The implementation was written so as to conform with the manual entry ++for the des_crypt(3) library routines from MIT's project Athena. ++ ++destest should be run after compilation to test the des routines. ++rpw should be run after compilation to test the read password routines. ++The des program is a replacement for the sun des command. I believe it ++conforms to the sun version. ++ ++The Imakefile is setup for use in the kerberos distribution. ++ ++These routines are best compiled with gcc or any other good ++optimising compiler. ++Just turn you optimiser up to the highest settings and run destest ++after the build to make sure everything works. ++ ++I believe these routines are close to the fastest and most portable DES ++routines that use small lookup tables (4.5k) that are publicly available. ++The fcrypt routine is faster than ufc's fcrypt (when compiling with ++gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines ++(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size. ++[ 10-Jan-97 and a function of an incorrect speed testing program in ++ ufc which gave much better test figures that reality ]. ++ ++It is worth noting that on sparc and Alpha CPUs, performance of the DES ++library can vary by upto %10 due to the positioning of files after application ++linkage. ++ ++Eric Young (eay@cryptsoft.com) ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/README.freeswan Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,33 @@ ++The only changes the FreeS/WAN project has made to libdes-lite 4.04b are: ++ ++We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient ++on the Alpha, instead of just noting the issue in a comment. ++ ++We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't ++use it, and its call to sprintf() can cause subtle difficulties when KLIPS ++is built as a module (depending on details of Linux configuration options). ++ ++We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make ++it cope better with Linux kernel Makefile stupidities, and took out an ++explicit CC=gcc (unwise on systems with strange compilers). ++ ++We deleted some references to and , and a declaration ++of one function found only in the full libdes (not in libdes-lite), to ++avoid dragging in bits of stdio/stdlib unnecessarily. (Our thanks to Hans ++Schultz for spotting this and pointing out the fixes.) ++ ++We deleted a couple of .obj files in the asm subdirectory, which appear to ++have been included in the original library by accident. ++ ++We have added an include of our Makefile.inc file, to permit overriding ++things like choice of compiler (although the libdes Makefile would ++probably need some work to make this effective). ++ ++ ++ ++Note that Eric Young is no longer at the email address listed in these ++files, and is (alas) no longer working on free crypto software. ++ ++ ++ ++This file is RCSID $Id: README.freeswan,v 1.11 2002/04/24 07:36:37 mcr Exp $ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/VERSION Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,406 @@ ++Version 4.04 ++ Fixed a few tests in destest. Also added x86 assember for ++ des_ncbc_encrypt() which is the standard cbc mode function. ++ This makes a very very large performace difference. ++ Ariel Glenn ariel@columbia.edu reports that the terminal ++ 'turn echo off' can return (errno == EINVAL) under solaris ++ when redirection is used. So I now catch that as well as ENOTTY. ++ ++ ++Version 4.03 ++ Left a static out of enc_write.c, which caused to buffer to be ++ continiously malloc()ed. Does anyone use these functions? I keep ++ on feeling like removing them since I only had these in there ++ for a version of kerberised login. Anyway, this was pointed out ++ by Theo de Raadt ++ The 'n' bit ofb code was wrong, it was not shifting the shift ++ register. It worked correctly for n == 64. Thanks to ++ Gigi Ankeny for pointing this one out. ++ ++Version 4.02 ++ I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)' ++ when checking for weak keys which is wrong :-(, pointed out by ++ Markus F.X.J. Oberhumer . ++ ++Version 4.01 ++ Even faster inner loop in the DES assembler for x86 and a modification ++ for IP/FP which is faster on x86. Both of these changes are ++ from Svend Olaf Mikkelsen . His ++ changes make the assembler run %40 faster on a pentium. This is just ++ a case of getting the instruction sequence 'just right'. ++ All credit to 'Svend' :-) ++ Quite a few special x86 'make' targets. ++ A libdes-l (lite) distribution. ++ ++Version 4.00 ++ After a bit of a pause, I'll up the major version number since this ++ is mostly a performace release. I've added x86 assembler and ++ added more options for performance. A %28 speedup for gcc ++ on a pentium and the assembler is a %50 speedup. ++ MIPS CPU's, sparc and Alpha are the main CPU's with speedups. ++ Run des_opts to work out which options should be used. ++ DES_RISC1/DES_RISC2 use alternative inner loops which use ++ more registers but should give speedups on any CPU that does ++ dual issue (pentium). DES_UNROLL unrolls the inner loop, ++ which costs in code size. ++ ++Version 3.26 ++ I've finally removed one of the shifts in D_ENCRYPT. This ++ meant I've changed the des_SPtrans table (spr.h), the set_key() ++ function and some things in des_enc.c. This has definitly ++ made things faster :-). I've known about this one for some ++ time but I've been too lazy to follow it up :-). ++ Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^.. ++ instead of L^=((..)|(..)|(..).. This should save a register at ++ least. ++ Assember for x86. The file to replace is des_enc.c, which is replaced ++ by one of the assembler files found in asm. Look at des/asm/readme ++ for more info. ++ ++ /* Modification to fcrypt so it can be compiled to support ++ HPUX 10.x's long password format, define -DLONGCRYPT to use this. ++ Thanks to Jens Kupferschmidt . */ ++ ++ SIGWINCH case put in des_read_passwd() so the function does not ++ 'exit' if this function is recieved. ++ ++Version 3.25 17/07/96 ++ Modified read_pwd.c so that stdin can be read if not a tty. ++ Thanks to Jeff Barber for the patches. ++ des_init_random_number_generator() shortened due to VMS linker ++ limits. ++ Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2 ++ 8 byte quantites xored before and after encryption. ++ des_xcbc_encryption() - the name is funny to preserve the des_ ++ prefix on all functions. ++ ++Version 3.24 20/04/96 ++ The DES_PTR macro option checked and used by SSLeay configuration ++ ++Version 3.23 11/04/96 ++ Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha, ++ it gives a %20 speedup :-) ++ Fixed the problem with des.pl under perl5. The patches were ++ sent by Ed Kubaitis (ejk@uiuc.edu). ++ if fcrypt.c, changed values to handle illegal salt values the way ++ normal crypt() implementations do. Some programs apparently use ++ them :-(. The patch was sent by Bjorn Gronvall ++ ++Version 3.22 29/11/95 ++ Bug in des(1), an error with the uuencoding stuff when the ++ 'data' is small, thanks to Geoff Keating ++ for the patch. ++ ++Version 3.21 22/11/95 ++ After some emailing back and forth with ++ Colin Plumb , I've tweaked a few things ++ and in a future version I will probably put in some of the ++ optimisation he suggested for use with the DES_USE_PTR option. ++ Extra routines from Mark Murray for use in ++ freeBSD. They mostly involve random number generation for use ++ with kerberos. They involve evil machine specific system calls ++ etc so I would normally suggest pushing this stuff into the ++ application and/or using RAND_seed()/RAND_bytes() if you are ++ using this DES library as part of SSLeay. ++ Redone the read_pw() function so that it is cleaner and ++ supports termios, thanks to Sameer Parekh ++ for the initial patches for this. ++ Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been ++ done just to make things more consistent. ++ I have also now added triple DES versions of cfb and ofb. ++ ++Version 3.20 ++ Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com, ++ my des_random_seed() function was only copying 4 bytes of the ++ passed seed into the init structure. It is now fixed to copy 8. ++ My own suggestion is to used something like MD5 :-) ++ ++Version 3.19 ++ While looking at my code one day, I though, why do I keep on ++ calling des_encrypt(in,out,ks,enc) when every function that ++ calls it has in and out the same. So I dropped the 'out' ++ parameter, people should not be using this function. ++ ++Version 3.18 30/08/95 ++ Fixed a few bit with the distribution and the filenames. ++ 3.17 had been munged via a move to DOS and back again. ++ NO CODE CHANGES ++ ++Version 3.17 14/07/95 ++ Fixed ede3 cbc which I had broken in 3.16. I have also ++ removed some unneeded variables in 7-8 of the routines. ++ ++Version 3.16 26/06/95 ++ Added des_encrypt2() which does not use IP/FP, used by triple ++ des routines. Tweaked things a bit elsewhere. %13 speedup on ++ sparc and %6 on a R4400 for ede3 cbc mode. ++ ++Version 3.15 06/06/95 ++ Added des_ncbc_encrypt(), it is des_cbc mode except that it is ++ 'normal' and copies the new iv value back over the top of the ++ passed parameter. ++ CHANGED des_ede3_cbc_encrypt() so that it too now overwrites ++ the iv. THIS WILL BREAK EXISTING CODE, but since this function ++ only new, I feel I can change it, not so with des_cbc_encrypt :-(. ++ I need to update the documentation. ++ ++Version 3.14 31/05/95 ++ New release upon the world, as part of my SSL implementation. ++ New copyright and usage stuff. Basically free for all to use ++ as long as you say it came from me :-) ++ ++Version 3.13 31/05/95 ++ A fix in speed.c, if HZ is not defined, I set it to 100.0 ++ which is reasonable for most unixes except SunOS 4.x. ++ I now have a #ifdef sun but timing for SunOS 4.x looked very ++ good :-(. At my last job where I used SunOS 4.x, it was ++ defined to be 60.0 (look at the old INSTALL documentation), at ++ the last release had it changed to 100.0 since I now work with ++ Solaris2 and SVR4 boxes. ++ Thanks to Rory Chisholm for pointing this ++ one out. ++ ++Version 3.12 08/05/95 ++ As pointed out by The Crypt Keeper , ++ my D_ENCRYPT macro in crypt() had an un-necessary variable. ++ It has been removed. ++ ++Version 3.11 03/05/95 ++ Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys ++ and one iv. It is a standard and I needed it for my SSL code. ++ It makes more sense to use this for triple DES than ++ 3cbc_encrypt(). I have also added (or should I say tested :-) ++ cfb64_encrypt() which is cfb64 but it will encrypt a partial ++ number of bytes - 3 bytes in 3 bytes out. Again this is for ++ my SSL library, as a form of encryption to use with SSL ++ telnet. ++ ++Version 3.10 22/03/95 ++ Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls ++ to cbc3_encrypt, the 2 iv values that were being returned to ++ be used in the next call were reversed :-(. ++ Many thanks to Bill Wade for pointing out ++ this error. ++ ++Version 3.09 01/02/95 ++ Fixed des_random_key to far more random, it was rather feeble ++ with regards to picking the initial seed. The problem was ++ pointed out by Olaf Kirch . ++ ++Version 3.08 14/12/94 ++ Added Makefile.PL so libdes can be built into perl5. ++ Changed des_locl.h so RAND is always defined. ++ ++Version 3.07 05/12/94 ++ Added GNUmake and stuff so the library can be build with ++ glibc. ++ ++Version 3.06 30/08/94 ++ Added rpc_enc.c which contains _des_crypt. This is for use in ++ secure_rpc v 4.0 ++ Finally fixed the cfb_enc problems. ++ Fixed a few parameter parsing bugs in des (-3 and -b), thanks ++ to Rob McMillan ++ ++Version 3.05 21/04/94 ++ for unsigned long l; gcc does not produce ((l>>34) == 0) ++ This causes bugs in cfb_enc. ++ Thanks to Hadmut Danisch ++ ++Version 3.04 20/04/94 ++ Added a version number to des.c and libdes.a ++ ++Version 3.03 12/01/94 ++ Fixed a bug in non zero iv in 3cbc_enc. ++ ++Version 3.02 29/10/93 ++ I now work in a place where there are 6+ architectures and 14+ ++ OS versions :-). ++ Fixed TERMIO definition so the most sys V boxes will work :-) ++ ++Release upon comp.sources.misc ++Version 3.01 08/10/93 ++ Added des_3cbc_encrypt() ++ ++Version 3.00 07/10/93 ++ Fixed up documentation. ++ quad_cksum definitely compatible with MIT's now. ++ ++Version 2.30 24/08/93 ++ Triple DES now defaults to triple cbc but can do triple ecb ++ with the -b flag. ++ Fixed some MSDOS uuen/uudecoding problems, thanks to ++ Added prototypes. ++ ++Version 2.22 29/06/93 ++ Fixed a bug in des_is_weak_key() which stopped it working :-( ++ thanks to engineering@MorningStar.Com. ++ ++Version 2.21 03/06/93 ++ des(1) with no arguments gives quite a bit of help. ++ Added -c (generate ckecksum) flag to des(1). ++ Added -3 (triple DES) flag to des(1). ++ Added cfb and ofb routines to the library. ++ ++Version 2.20 11/03/93 ++ Added -u (uuencode) flag to des(1). ++ I have been playing with byte order in quad_cksum to make it ++ compatible with MIT's version. All I can say is avid this ++ function if possible since MIT's output is endian dependent. ++ ++Version 2.12 14/10/92 ++ Added MSDOS specific macro in ecb_encrypt which gives a %70 ++ speed up when the code is compiled with turbo C. ++ ++Version 2.11 12/10/92 ++ Speedup in set_key (recoding of PC-1) ++ I now do it in 47 simple operations, down from 60. ++ Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) ++ for motivating me to look for a faster system :-) ++ The speedup is probably less that 1% but it is still 13 ++ instructions less :-). ++ ++Version 2.10 06/10/92 ++ The code now works on the 64bit ETA10 and CRAY without modifications or ++ #defines. I believe the code should work on any machine that ++ defines long, int or short to be 8 bytes long. ++ Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu) ++ for helping me fix the code to run on 64bit machines (he had ++ access to an ETA10). ++ Thanks also to John Fletcher ++ for testing the routines on a CRAY. ++ read_password.c has been renamed to read_passwd.c ++ string_to_key.c has been renamed to string2key.c ++ ++Version 2.00 14/09/92 ++ Made mods so that the library should work on 64bit CPU's. ++ Removed all my uchar and ulong defs. To many different ++ versions of unix define them in their header files in too many ++ different combinations :-) ++ IRIX - Sillicon Graphics mods (mostly in read_password.c). ++ Thanks to Andrew Daviel (advax@erich.triumf.ca) ++ ++Version 1.99 26/08/92 ++ Fixed a bug or 2 in enc_read.c ++ Fixed a bug in enc_write.c ++ Fixed a pseudo bug in fcrypt.c (very obscure). ++ ++Version 1.98 31/07/92 ++ Support for the ETA10. This is a strange machine that defines ++ longs and ints as 8 bytes and shorts as 4 bytes. ++ Since I do evil things with long * that assume that they are 4 ++ bytes. Look in the Makefile for the option to compile for ++ this machine. quad_cksum appears to have problems but I ++ will don't have the time to fix it right now, and this is not ++ a function that uses DES and so will not effect the main uses ++ of the library. ++ ++Version 1.97 20/05/92 eay ++ Fixed the Imakefile and made some changes to des.h to fix some ++ problems when building this package with Kerberos v 4. ++ ++Version 1.96 18/05/92 eay ++ Fixed a small bug in string_to_key() where problems could ++ occur if des_check_key was set to true and the string ++ generated a weak key. ++ ++Patch2 posted to comp.sources.misc ++Version 1.95 13/05/92 eay ++ Added an alternative version of the D_ENCRYPT macro in ++ ecb_encrypt and fcrypt. Depending on the compiler, one version or the ++ other will be faster. This was inspired by ++ Dana How , and her pointers about doing the ++ *(ulong *)((uchar *)ptr+(value&0xfc)) ++ vs ++ ptr[value&0x3f] ++ to stop the C compiler doing a <<2 to convert the long array index. ++ ++Version 1.94 05/05/92 eay ++ Fixed an incompatibility between my string_to_key and the MIT ++ version. When the key is longer than 8 chars, I was wrapping ++ with a different method. To use the old version, define ++ OLD_STR_TO_KEY in the makefile. Thanks to ++ viktor@newsu.shearson.com (Viktor Dukhovni). ++ ++Version 1.93 28/04/92 eay ++ Fixed the VMS mods so that echo is now turned off in ++ read_password. Thanks again to brennan@coco.cchs.su.oz.AU. ++ MSDOS support added. The routines can be compiled with ++ Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined. ++ ++Patch1 posted to comp.sources.misc ++Version 1.92 13/04/92 eay ++ Changed D_ENCRYPT so that the rotation of R occurs outside of ++ the loop. This required rotating all the longs in sp.h (now ++ called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM> ++ speed.c has been changed so it will work without SIGALRM. If ++ times(3) is not present it will try to use ftime() instead. ++ ++Version 1.91 08/04/92 eay ++ Added -E/-D options to des(1) so it can use string_to_key. ++ Added SVR4 mods suggested by witr@rwwa.COM ++ Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If ++ anyone knows how to turn of tty echo in VMS please tell me or ++ implement it yourself :-). ++ Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS ++ does not like IN/OUT being used. ++ ++Libdes posted to comp.sources.misc ++Version 1.9 24/03/92 eay ++ Now contains a fast small crypt replacement. ++ Added des(1) command. ++ Added des_rw_mode so people can use cbc encryption with ++ enc_read and enc_write. ++ ++Version 1.8 15/10/91 eay ++ Bug in cbc_cksum. ++ Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this ++ one out. ++ ++Version 1.7 24/09/91 eay ++ Fixed set_key :-) ++ set_key is 4 times faster and takes less space. ++ There are a few minor changes that could be made. ++ ++Version 1.6 19/09/1991 eay ++ Finally go IP and FP finished. ++ Now I need to fix set_key. ++ This version is quite a bit faster that 1.51 ++ ++Version 1.52 15/06/1991 eay ++ 20% speedup in ecb_encrypt by changing the E bit selection ++ to use 2 32bit words. This also required modification of the ++ sp table. There is still a way to speedup the IP and IP-1 ++ (hints from outer@sq.com) still working on this one :-(. ++ ++Version 1.51 07/06/1991 eay ++ Faster des_encrypt by loop unrolling ++ Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu) ++ ++Version 1.50 28/05/1991 eay ++ Optimised the code a bit more for the sparc. I have improved the ++ speed of the inner des_encrypt by speeding up the initial and ++ final permutations. ++ ++Version 1.40 23/10/1990 eay ++ Fixed des_random_key, it did not produce a random key :-( ++ ++Version 1.30 2/10/1990 eay ++ Have made des_quad_cksum the same as MIT's, the full package ++ should be compatible with MIT's ++ Have tested on a DECstation 3100 ++ Still need to fix des_set_key (make it faster). ++ Does des_cbc_encrypts at 70.5k/sec on a 3100. ++ ++Version 1.20 18/09/1990 eay ++ Fixed byte order dependencies. ++ Fixed (I hope) all the word alignment problems. ++ Speedup in des_ecb_encrypt. ++ ++Version 1.10 11/09/1990 eay ++ Added des_enc_read and des_enc_write. ++ Still need to fix des_quad_cksum. ++ Still need to document des_enc_read and des_enc_write. ++ ++Version 1.00 27/08/1990 eay ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/asm/crypt586.pl Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,204 @@ ++#!/usr/bin/perl ++# ++# The inner loop instruction sequence and the IP/FP modifications are from ++# Svend Olaf Mikkelsen ++# I've added the stuff needed for crypt() but I've not worried about making ++# things perfect. ++# ++ ++push(@INC,"perlasm","../../perlasm"); ++require "x86asm.pl"; ++ ++&asm_init($ARGV[0],"crypt586.pl"); ++ ++$L="edi"; ++$R="esi"; ++ ++&external_label("des_SPtrans"); ++&fcrypt_body("fcrypt_body"); ++&asm_finish(); ++ ++sub fcrypt_body ++ { ++ local($name,$do_ip)=@_; ++ ++ &function_begin($name,"EXTRN _des_SPtrans:DWORD"); ++ ++ &comment(""); ++ &comment("Load the 2 words"); ++ $ks="ebp"; ++ ++ &xor( $L, $L); ++ &xor( $R, $R); ++ &mov($ks,&wparam(1)); ++ ++ &push(25); # add a variable ++ ++ &set_label("start"); ++ for ($i=0; $i<16; $i+=2) ++ { ++ &comment(""); ++ &comment("Round $i"); ++ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); ++ ++ &comment(""); ++ &comment("Round ".sprintf("%d",$i+1)); ++ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); ++ } ++ &mov("ebx", &swtmp(0)); ++ &mov("eax", $L); ++ &dec("ebx"); ++ &mov($L, $R); ++ &mov($R, "eax"); ++ &mov(&swtmp(0), "ebx"); ++ &jnz(&label("start")); ++ ++ &comment(""); ++ &comment("FP"); ++ &mov("edx",&wparam(0)); ++ ++ &FP_new($R,$L,"eax",3); ++ &mov(&DWP(0,"edx","",0),"eax"); ++ &mov(&DWP(4,"edx","",0),$L); ++ ++ &pop("ecx"); # remove variable ++ ++ &function_end($name); ++ } ++ ++sub D_ENCRYPT ++ { ++ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_; ++ ++ &mov( $u, &wparam(2)); # 2 ++ &mov( $t, $R); ++ &shr( $t, 16); # 1 ++ &mov( $tmp2, &wparam(3)); # 2 ++ &xor( $t, $R); # 1 ++ ++ &and( $u, $t); # 2 ++ &and( $t, $tmp2); # 2 ++ ++ &mov( $tmp1, $u); ++ &shl( $tmp1, 16); # 1 ++ &mov( $tmp2, $t); ++ &shl( $tmp2, 16); # 1 ++ &xor( $u, $tmp1); # 2 ++ &xor( $t, $tmp2); # 2 ++ &mov( $tmp1, &DWP(&n2a($S*4),$ks,"",0)); # 2 ++ &xor( $u, $tmp1); ++ &mov( $tmp2, &DWP(&n2a(($S+1)*4),$ks,"",0)); # 2 ++ &xor( $u, $R); ++ &xor( $t, $R); ++ &xor( $t, $tmp2); ++ ++ &and( $u, "0xfcfcfcfc" ); # 2 ++ &xor( $tmp1, $tmp1); # 1 ++ &and( $t, "0xcfcfcfcf" ); # 2 ++ &xor( $tmp2, $tmp2); ++ &movb( &LB($tmp1), &LB($u) ); ++ &movb( &LB($tmp2), &HB($u) ); ++ &rotr( $t, 4 ); ++ &mov( $ks, &DWP(" $desSP",$tmp1,"",0)); ++ &movb( &LB($tmp1), &LB($t) ); ++ &xor( $L, $ks); ++ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0)); ++ &xor( $L, $ks); ++ &movb( &LB($tmp2), &HB($t) ); ++ &shr( $u, 16); ++ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0)); ++ &xor( $L, $ks); ++ &movb( &LB($tmp1), &HB($u) ); ++ &shr( $t, 16); ++ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0)); ++ &xor( $L, $ks); ++ &mov( $ks, &wparam(1)); ++ &movb( &LB($tmp2), &HB($t) ); ++ &and( $u, "0xff" ); ++ &and( $t, "0xff" ); ++ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0)); ++ &xor( $L, $tmp1); ++ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0)); ++ &xor( $L, $tmp1); ++ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0)); ++ &xor( $L, $tmp1); ++ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0)); ++ &xor( $L, $tmp1); ++ } ++ ++sub n2a ++ { ++ sprintf("%d",$_[0]); ++ } ++ ++# now has a side affect of rotating $a by $shift ++sub R_PERM_OP ++ { ++ local($a,$b,$tt,$shift,$mask,$last)=@_; ++ ++ &rotl( $a, $shift ) if ($shift != 0); ++ &mov( $tt, $a ); ++ &xor( $a, $b ); ++ &and( $a, $mask ); ++ if ($notlast eq $b) ++ { ++ &xor( $b, $a ); ++ &xor( $tt, $a ); ++ } ++ else ++ { ++ &xor( $tt, $a ); ++ &xor( $b, $a ); ++ } ++ &comment(""); ++ } ++ ++sub IP_new ++ { ++ local($l,$r,$tt,$lr)=@_; ++ ++ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l); ++ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l); ++ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r); ++ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r); ++ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r); ++ ++ if ($lr != 3) ++ { ++ if (($lr-3) < 0) ++ { &rotr($tt, 3-$lr); } ++ else { &rotl($tt, $lr-3); } ++ } ++ if ($lr != 2) ++ { ++ if (($lr-2) < 0) ++ { &rotr($r, 2-$lr); } ++ else { &rotl($r, $lr-2); } ++ } ++ } ++ ++sub FP_new ++ { ++ local($l,$r,$tt,$lr)=@_; ++ ++ if ($lr != 2) ++ { ++ if (($lr-2) < 0) ++ { &rotl($r, 2-$lr); } ++ else { &rotr($r, $lr-2); } ++ } ++ if ($lr != 3) ++ { ++ if (($lr-3) < 0) ++ { &rotl($l, 3-$lr); } ++ else { &rotr($l, $lr-3); } ++ } ++ ++ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r); ++ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r); ++ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l); ++ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l); ++ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r); ++ &rotr($tt , 4); ++ } ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/asm/des-586.pl Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,251 @@ ++#!/usr/bin/perl ++# ++# The inner loop instruction sequence and the IP/FP modifications are from ++# Svend Olaf Mikkelsen ++# ++ ++push(@INC,"perlasm","../../perlasm"); ++require "x86asm.pl"; ++require "cbc.pl"; ++require "desboth.pl"; ++ ++# base code is in microsft ++# op dest, source ++# format. ++# ++ ++&asm_init($ARGV[0],"des-586.pl"); ++ ++$L="edi"; ++$R="esi"; ++ ++&external_label("des_SPtrans"); ++&des_encrypt("des_encrypt",1); ++&des_encrypt("des_encrypt2",0); ++&des_encrypt3("des_encrypt3",1); ++&des_encrypt3("des_decrypt3",0); ++&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1); ++&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5); ++ ++&asm_finish(); ++ ++sub des_encrypt ++ { ++ local($name,$do_ip)=@_; ++ ++ &function_begin_B($name,"EXTRN _des_SPtrans:DWORD"); ++ ++ &push("esi"); ++ &push("edi"); ++ ++ &comment(""); ++ &comment("Load the 2 words"); ++ $ks="ebp"; ++ ++ if ($do_ip) ++ { ++ &mov($R,&wparam(0)); ++ &xor( "ecx", "ecx" ); ++ ++ &push("ebx"); ++ &push("ebp"); ++ ++ &mov("eax",&DWP(0,$R,"",0)); ++ &mov("ebx",&wparam(2)); # get encrypt flag ++ &mov($L,&DWP(4,$R,"",0)); ++ &comment(""); ++ &comment("IP"); ++ &IP_new("eax",$L,$R,3); ++ } ++ else ++ { ++ &mov("eax",&wparam(0)); ++ &xor( "ecx", "ecx" ); ++ ++ &push("ebx"); ++ &push("ebp"); ++ ++ &mov($R,&DWP(0,"eax","",0)); ++ &mov("ebx",&wparam(2)); # get encrypt flag ++ &rotl($R,3); ++ &mov($L,&DWP(4,"eax","",0)); ++ &rotl($L,3); ++ } ++ ++ &mov( $ks, &wparam(1) ); ++ &cmp("ebx","0"); ++ &je(&label("start_decrypt")); ++ ++ for ($i=0; $i<16; $i+=2) ++ { ++ &comment(""); ++ &comment("Round $i"); ++ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); ++ ++ &comment(""); ++ &comment("Round ".sprintf("%d",$i+1)); ++ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); ++ } ++ &jmp(&label("end")); ++ ++ &set_label("start_decrypt"); ++ ++ for ($i=15; $i>0; $i-=2) ++ { ++ &comment(""); ++ &comment("Round $i"); ++ &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); ++ &comment(""); ++ &comment("Round ".sprintf("%d",$i-1)); ++ &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); ++ } ++ ++ &set_label("end"); ++ ++ if ($do_ip) ++ { ++ &comment(""); ++ &comment("FP"); ++ &mov("edx",&wparam(0)); ++ &FP_new($L,$R,"eax",3); ++ ++ &mov(&DWP(0,"edx","",0),"eax"); ++ &mov(&DWP(4,"edx","",0),$R); ++ } ++ else ++ { ++ &comment(""); ++ &comment("Fixup"); ++ &rotr($L,3); # r ++ &mov("eax",&wparam(0)); ++ &rotr($R,3); # l ++ &mov(&DWP(0,"eax","",0),$L); ++ &mov(&DWP(4,"eax","",0),$R); ++ } ++ ++ &pop("ebp"); ++ &pop("ebx"); ++ &pop("edi"); ++ &pop("esi"); ++ &ret(); ++ ++ &function_end_B($name); ++ } ++ ++sub D_ENCRYPT ++ { ++ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_; ++ ++ &mov( $u, &DWP(&n2a($S*4),$ks,"",0)); ++ &xor( $tmp1, $tmp1); ++ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0)); ++ &xor( $u, $R); ++ &xor( $t, $R); ++ &and( $u, "0xfcfcfcfc" ); ++ &and( $t, "0xcfcfcfcf" ); ++ &movb( &LB($tmp1), &LB($u) ); ++ &movb( &LB($tmp2), &HB($u) ); ++ &rotr( $t, 4 ); ++ &mov( $ks, &DWP(" $desSP",$tmp1,"",0)); ++ &movb( &LB($tmp1), &LB($t) ); ++ &xor( $L, $ks); ++ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0)); ++ &xor( $L, $ks); ###### ++ &movb( &LB($tmp2), &HB($t) ); ++ &shr( $u, 16); ++ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0)); ++ &xor( $L, $ks); ###### ++ &movb( &LB($tmp1), &HB($u) ); ++ &shr( $t, 16); ++ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0)); ++ &xor( $L, $ks); ++ &mov( $ks, &wparam(1) ); ++ &movb( &LB($tmp2), &HB($t) ); ++ &and( $u, "0xff" ); ++ &and( $t, "0xff" ); ++ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0)); ++ &xor( $L, $tmp1); ++ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0)); ++ &xor( $L, $tmp1); ++ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0)); ++ &xor( $L, $tmp1); ++ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0)); ++ &xor( $L, $tmp1); ++ } ++ ++sub n2a ++ { ++ sprintf("%d",$_[0]); ++ } ++ ++# now has a side affect of rotating $a by $shift ++sub R_PERM_OP ++ { ++ local($a,$b,$tt,$shift,$mask,$last)=@_; ++ ++ &rotl( $a, $shift ) if ($shift != 0); ++ &mov( $tt, $a ); ++ &xor( $a, $b ); ++ &and( $a, $mask ); ++ if (!$last eq $b) ++ { ++ &xor( $b, $a ); ++ &xor( $tt, $a ); ++ } ++ else ++ { ++ &xor( $tt, $a ); ++ &xor( $b, $a ); ++ } ++ &comment(""); ++ } ++ ++sub IP_new ++ { ++ local($l,$r,$tt,$lr)=@_; ++ ++ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l); ++ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l); ++ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r); ++ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r); ++ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r); ++ ++ if ($lr != 3) ++ { ++ if (($lr-3) < 0) ++ { &rotr($tt, 3-$lr); } ++ else { &rotl($tt, $lr-3); } ++ } ++ if ($lr != 2) ++ { ++ if (($lr-2) < 0) ++ { &rotr($r, 2-$lr); } ++ else { &rotl($r, $lr-2); } ++ } ++ } ++ ++sub FP_new ++ { ++ local($l,$r,$tt,$lr)=@_; ++ ++ if ($lr != 2) ++ { ++ if (($lr-2) < 0) ++ { &rotl($r, 2-$lr); } ++ else { &rotr($r, $lr-2); } ++ } ++ if ($lr != 3) ++ { ++ if (($lr-3) < 0) ++ { &rotl($l, 3-$lr); } ++ else { &rotr($l, $lr-3); } ++ } ++ ++ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r); ++ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r); ++ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l); ++ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l); ++ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r); ++ &rotr($tt , 4); ++ } ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/asm/des686.pl Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,230 @@ ++#!/usr/bin/perl ++ ++$prog="des686.pl"; ++ ++# base code is in microsft ++# op dest, source ++# format. ++# ++ ++# WILL NOT WORK ANYMORE WITH desboth.pl ++require "desboth.pl"; ++ ++if ( ($ARGV[0] eq "elf")) ++ { require "x86unix.pl"; } ++elsif ( ($ARGV[0] eq "a.out")) ++ { $aout=1; require "x86unix.pl"; } ++elsif ( ($ARGV[0] eq "sol")) ++ { $sol=1; require "x86unix.pl"; } ++elsif ( ($ARGV[0] eq "cpp")) ++ { $cpp=1; require "x86unix.pl"; } ++elsif ( ($ARGV[0] eq "win32")) ++ { require "x86ms.pl"; } ++else ++ { ++ print STDERR <<"EOF"; ++Pick one target type from ++ elf - linux, FreeBSD etc ++ a.out - old linux ++ sol - x86 solaris ++ cpp - format so x86unix.cpp can be used ++ win32 - Windows 95/Windows NT ++EOF ++ exit(1); ++ } ++ ++&comment("Don't even think of reading this code"); ++&comment("It was automatically generated by $prog"); ++&comment("Which is a perl program used to generate the x86 assember for"); ++&comment("any of elf, a.out, Win32, or Solaris"); ++&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+"); ++&comment("eric "); ++&comment(""); ++ ++&file("dx86xxxx"); ++ ++$L="edi"; ++$R="esi"; ++ ++&des_encrypt("des_encrypt",1); ++&des_encrypt("des_encrypt2",0); ++ ++&des_encrypt3("des_encrypt3",1); ++&des_encrypt3("des_decrypt3",0); ++ ++&file_end(); ++ ++sub des_encrypt ++ { ++ local($name,$do_ip)=@_; ++ ++ &function_begin($name,"EXTRN _des_SPtrans:DWORD"); ++ ++ &comment(""); ++ &comment("Load the 2 words"); ++ &mov("eax",&wparam(0)); ++ &mov($L,&DWP(0,"eax","",0)); ++ &mov($R,&DWP(4,"eax","",0)); ++ ++ $ksp=&wparam(1); ++ ++ if ($do_ip) ++ { ++ &comment(""); ++ &comment("IP"); ++ &IP_new($L,$R,"eax"); ++ } ++ ++ &comment(""); ++ &comment("fixup rotate"); ++ &rotl($R,3); ++ &rotl($L,3); ++ &exch($L,$R); ++ ++ &comment(""); ++ &comment("load counter, key_schedule and enc flag"); ++ &mov("eax",&wparam(2)); # get encrypt flag ++ &mov("ebp",&wparam(1)); # get ks ++ &cmp("eax","0"); ++ &je(&label("start_decrypt")); ++ ++ # encrypting part ++ ++ for ($i=0; $i<16; $i+=2) ++ { ++ &comment(""); ++ &comment("Round $i"); ++ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); ++ ++ &comment(""); ++ &comment("Round ".sprintf("%d",$i+1)); ++ &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); ++ } ++ &jmp(&label("end")); ++ ++ &set_label("start_decrypt"); ++ ++ for ($i=15; $i>0; $i-=2) ++ { ++ &comment(""); ++ &comment("Round $i"); ++ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); ++ &comment(""); ++ &comment("Round ".sprintf("%d",$i-1)); ++ &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); ++ } ++ ++ &set_label("end"); ++ ++ &comment(""); ++ &comment("Fixup"); ++ &rotr($L,3); # r ++ &rotr($R,3); # l ++ ++ if ($do_ip) ++ { ++ &comment(""); ++ &comment("FP"); ++ &FP_new($R,$L,"eax"); ++ } ++ ++ &mov("eax",&wparam(0)); ++ &mov(&DWP(0,"eax","",0),$L); ++ &mov(&DWP(4,"eax","",0),$R); ++ ++ &function_end($name); ++ } ++ ++ ++# The logic is to load R into 2 registers and operate on both at the same time. ++# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte' ++# while also masking the other copy and doing a lookup. We then also accumulate the ++# L value in 2 registers then combine them at the end. ++sub D_ENCRYPT ++ { ++ local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_; ++ ++ &mov( $u, &DWP(&n2a($S*4),$ks,"",0)); ++ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0)); ++ &xor( $u, $R ); ++ &xor( $t, $R ); ++ &rotr( $t, 4 ); ++ ++ # the numbers at the end of the line are origional instruction order ++ &mov( $tmp2, $u ); # 1 2 ++ &mov( $tmp1, $t ); # 1 1 ++ &and( $tmp2, "0xfc" ); # 1 4 ++ &and( $tmp1, "0xfc" ); # 1 3 ++ &shr( $t, 8 ); # 1 5 ++ &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7 ++ &shr( $u, 8 ); # 1 6 ++ &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8 ++ ++ &mov( $tmp2, $u ); # 2 2 ++ &xor( $L, $tmp1 ); # 1 9 ++ &and( $tmp2, "0xfc" ); # 2 4 ++ &mov( $tmp1, $t ); # 2 1 ++ &and( $tmp1, "0xfc" ); # 2 3 ++ &shr( $t, 8 ); # 2 5 ++ &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7 ++ &shr( $u, 8 ); # 2 6 ++ &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8 ++ &mov( $tmp2, $u ); # 3 2 ++ ++ &xor( $L, $tmp1 ); # 2 9 ++ &and( $tmp2, "0xfc" ); # 3 4 ++ ++ &mov( $tmp1, $t ); # 3 1 ++ &shr( $u, 8 ); # 3 6 ++ &and( $tmp1, "0xfc" ); # 3 3 ++ &shr( $t, 8 ); # 3 5 ++ &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7 ++ &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8 ++ ++ &and( $t, "0xfc" ); # 4 1 ++ &xor( $L, $tmp1 ); # 3 9 ++ ++ &and( $u, "0xfc" ); # 4 2 ++ &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3 ++ &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4 ++ } ++ ++sub PERM_OP ++ { ++ local($a,$b,$tt,$shift,$mask)=@_; ++ ++ &mov( $tt, $a ); ++ &shr( $tt, $shift ); ++ &xor( $tt, $b ); ++ &and( $tt, $mask ); ++ &xor( $b, $tt ); ++ &shl( $tt, $shift ); ++ &xor( $a, $tt ); ++ } ++ ++sub IP_new ++ { ++ local($l,$r,$tt)=@_; ++ ++ &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f"); ++ &PERM_OP($l,$r,$tt,16,"0x0000ffff"); ++ &PERM_OP($r,$l,$tt, 2,"0x33333333"); ++ &PERM_OP($l,$r,$tt, 8,"0x00ff00ff"); ++ &PERM_OP($r,$l,$tt, 1,"0x55555555"); ++ } ++ ++sub FP_new ++ { ++ local($l,$r,$tt)=@_; ++ ++ &PERM_OP($l,$r,$tt, 1,"0x55555555"); ++ &PERM_OP($r,$l,$tt, 8,"0x00ff00ff"); ++ &PERM_OP($l,$r,$tt, 2,"0x33333333"); ++ &PERM_OP($r,$l,$tt,16,"0x0000ffff"); ++ &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f"); ++ } ++ ++sub n2a ++ { ++ sprintf("%d",$_[0]); ++ } +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/asm/desboth.pl Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,79 @@ ++#!/usr/bin/perl ++ ++$L="edi"; ++$R="esi"; ++ ++sub des_encrypt3 ++ { ++ local($name,$enc)=@_; ++ ++ &function_begin_B($name,""); ++ &push("ebx"); ++ &mov("ebx",&wparam(0)); ++ ++ &push("ebp"); ++ &push("esi"); ++ ++ &push("edi"); ++ ++ &comment(""); ++ &comment("Load the data words"); ++ &mov($L,&DWP(0,"ebx","",0)); ++ &mov($R,&DWP(4,"ebx","",0)); ++ &stack_push(3); ++ ++ &comment(""); ++ &comment("IP"); ++ &IP_new($L,$R,"edx",0); ++ ++ # put them back ++ ++ if ($enc) ++ { ++ &mov(&DWP(4,"ebx","",0),$R); ++ &mov("eax",&wparam(1)); ++ &mov(&DWP(0,"ebx","",0),"edx"); ++ &mov("edi",&wparam(2)); ++ &mov("esi",&wparam(3)); ++ } ++ else ++ { ++ &mov(&DWP(4,"ebx","",0),$R); ++ &mov("esi",&wparam(1)); ++ &mov(&DWP(0,"ebx","",0),"edx"); ++ &mov("edi",&wparam(2)); ++ &mov("eax",&wparam(3)); ++ } ++ &mov(&swtmp(2), (($enc)?"1":"0")); ++ &mov(&swtmp(1), "eax"); ++ &mov(&swtmp(0), "ebx"); ++ &call("des_encrypt2"); ++ &mov(&swtmp(2), (($enc)?"0":"1")); ++ &mov(&swtmp(1), "edi"); ++ &mov(&swtmp(0), "ebx"); ++ &call("des_encrypt2"); ++ &mov(&swtmp(2), (($enc)?"1":"0")); ++ &mov(&swtmp(1), "esi"); ++ &mov(&swtmp(0), "ebx"); ++ &call("des_encrypt2"); ++ ++ &stack_pop(3); ++ &mov($L,&DWP(0,"ebx","",0)); ++ &mov($R,&DWP(4,"ebx","",0)); ++ ++ &comment(""); ++ &comment("FP"); ++ &FP_new($L,$R,"eax",0); ++ ++ &mov(&DWP(0,"ebx","",0),"eax"); ++ &mov(&DWP(4,"ebx","",0),$R); ++ ++ &pop("edi"); ++ &pop("esi"); ++ &pop("ebp"); ++ &pop("ebx"); ++ &ret(); ++ &function_end_B($name); ++ } ++ ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/asm/perlasm/cbc.pl Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,342 @@ ++#!/usr/bin/perl ++ ++# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc) ++# des_cblock (*input); ++# des_cblock (*output); ++# long length; ++# des_key_schedule schedule; ++# des_cblock (*ivec); ++# int enc; ++# ++# calls ++# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); ++# ++ ++#&cbc("des_ncbc_encrypt","des_encrypt",0); ++#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt", ++# 1,4,5,3,5,-1); ++#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt", ++# 0,4,5,3,5,-1); ++#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3", ++# 0,6,7,3,4,5); ++# ++# When doing a cipher that needs bigendian order, ++# for encrypt, the iv is kept in bigendian form, ++# while for decrypt, it is kept in little endian. ++sub cbc ++ { ++ local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_; ++ # name is the function name ++ # enc_func and dec_func and the functions to call for encrypt/decrypt ++ # swap is true if byte order needs to be reversed ++ # iv_off is parameter number for the iv ++ # enc_off is parameter number for the encrypt/decrypt flag ++ # p1,p2,p3 are the offsets for parameters to be passed to the ++ # underlying calls. ++ ++ &function_begin_B($name,""); ++ &comment(""); ++ ++ $in="esi"; ++ $out="edi"; ++ $count="ebp"; ++ ++ &push("ebp"); ++ &push("ebx"); ++ &push("esi"); ++ &push("edi"); ++ ++ $data_off=4; ++ $data_off+=4 if ($p1 > 0); ++ $data_off+=4 if ($p2 > 0); ++ $data_off+=4 if ($p3 > 0); ++ ++ &mov($count, &wparam(2)); # length ++ ++ &comment("getting iv ptr from parameter $iv_off"); ++ &mov("ebx", &wparam($iv_off)); # Get iv ptr ++ ++ &mov($in, &DWP(0,"ebx","",0));# iv[0] ++ &mov($out, &DWP(4,"ebx","",0));# iv[1] ++ ++ &push($out); ++ &push($in); ++ &push($out); # used in decrypt for iv[1] ++ &push($in); # used in decrypt for iv[0] ++ ++ &mov("ebx", "esp"); # This is the address of tin[2] ++ ++ &mov($in, &wparam(0)); # in ++ &mov($out, &wparam(1)); # out ++ ++ # We have loaded them all, how lets push things ++ &comment("getting encrypt flag from parameter $enc_off"); ++ &mov("ecx", &wparam($enc_off)); # Get enc flag ++ if ($p3 > 0) ++ { ++ &comment("get and push parameter $p3"); ++ if ($enc_off != $p3) ++ { &mov("eax", &wparam($p3)); &push("eax"); } ++ else { &push("ecx"); } ++ } ++ if ($p2 > 0) ++ { ++ &comment("get and push parameter $p2"); ++ if ($enc_off != $p2) ++ { &mov("eax", &wparam($p2)); &push("eax"); } ++ else { &push("ecx"); } ++ } ++ if ($p1 > 0) ++ { ++ &comment("get and push parameter $p1"); ++ if ($enc_off != $p1) ++ { &mov("eax", &wparam($p1)); &push("eax"); } ++ else { &push("ecx"); } ++ } ++ &push("ebx"); # push data/iv ++ ++ &cmp("ecx",0); ++ &jz(&label("decrypt")); ++ ++ &and($count,0xfffffff8); ++ &mov("eax", &DWP($data_off,"esp","",0)); # load iv[0] ++ &mov("ebx", &DWP($data_off+4,"esp","",0)); # load iv[1] ++ ++ &jz(&label("encrypt_finish")); ++ ++ ############################################################# ++ ++ &set_label("encrypt_loop"); ++ # encrypt start ++ # "eax" and "ebx" hold iv (or the last cipher text) ++ ++ &mov("ecx", &DWP(0,$in,"",0)); # load first 4 bytes ++ &mov("edx", &DWP(4,$in,"",0)); # second 4 bytes ++ ++ &xor("eax", "ecx"); ++ &xor("ebx", "edx"); ++ ++ &bswap("eax") if $swap; ++ &bswap("ebx") if $swap; ++ ++ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call ++ &mov(&DWP($data_off+4,"esp","",0), "ebx"); # ++ ++ &call($enc_func); ++ ++ &mov("eax", &DWP($data_off,"esp","",0)); ++ &mov("ebx", &DWP($data_off+4,"esp","",0)); ++ ++ &bswap("eax") if $swap; ++ &bswap("ebx") if $swap; ++ ++ &mov(&DWP(0,$out,"",0),"eax"); ++ &mov(&DWP(4,$out,"",0),"ebx"); ++ ++ # eax and ebx are the next iv. ++ ++ &add($in, 8); ++ &add($out, 8); ++ ++ &sub($count, 8); ++ &jnz(&label("encrypt_loop")); ++ ++###################################################################3 ++ &set_label("encrypt_finish"); ++ &mov($count, &wparam(2)); # length ++ &and($count, 7); ++ &jz(&label("finish")); ++ &xor("ecx","ecx"); ++ &xor("edx","edx"); ++ &mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4)); ++ &jmp_ptr($count); ++ ++&set_label("ej7"); ++ &xor("edx", "edx") if $ppro; # ppro friendly ++ &movb(&HB("edx"), &BP(6,$in,"",0)); ++ &shl("edx",8); ++&set_label("ej6"); ++ &movb(&HB("edx"), &BP(5,$in,"",0)); ++&set_label("ej5"); ++ &movb(&LB("edx"), &BP(4,$in,"",0)); ++&set_label("ej4"); ++ &mov("ecx", &DWP(0,$in,"",0)); ++ &jmp(&label("ejend")); ++&set_label("ej3"); ++ &movb(&HB("ecx"), &BP(2,$in,"",0)); ++ &xor("ecx", "ecx") if $ppro; # ppro friendly ++ &shl("ecx",8); ++&set_label("ej2"); ++ &movb(&HB("ecx"), &BP(1,$in,"",0)); ++&set_label("ej1"); ++ &movb(&LB("ecx"), &BP(0,$in,"",0)); ++&set_label("ejend"); ++ ++ &xor("eax", "ecx"); ++ &xor("ebx", "edx"); ++ ++ &bswap("eax") if $swap; ++ &bswap("ebx") if $swap; ++ ++ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call ++ &mov(&DWP($data_off+4,"esp","",0), "ebx"); # ++ ++ &call($enc_func); ++ ++ &mov("eax", &DWP($data_off,"esp","",0)); ++ &mov("ebx", &DWP($data_off+4,"esp","",0)); ++ ++ &bswap("eax") if $swap; ++ &bswap("ebx") if $swap; ++ ++ &mov(&DWP(0,$out,"",0),"eax"); ++ &mov(&DWP(4,$out,"",0),"ebx"); ++ ++ &jmp(&label("finish")); ++ ++ ############################################################# ++ ############################################################# ++ &set_label("decrypt",1); ++ # decrypt start ++ &and($count,0xfffffff8); ++ # The next 2 instructions are only for if the jz is taken ++ &mov("eax", &DWP($data_off+8,"esp","",0)); # get iv[0] ++ &mov("ebx", &DWP($data_off+12,"esp","",0)); # get iv[1] ++ &jz(&label("decrypt_finish")); ++ ++ &set_label("decrypt_loop"); ++ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes ++ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes ++ ++ &bswap("eax") if $swap; ++ &bswap("ebx") if $swap; ++ ++ &mov(&DWP($data_off,"esp","",0), "eax"); # put back ++ &mov(&DWP($data_off+4,"esp","",0), "ebx"); # ++ ++ &call($dec_func); ++ ++ &mov("eax", &DWP($data_off,"esp","",0)); # get return ++ &mov("ebx", &DWP($data_off+4,"esp","",0)); # ++ ++ &bswap("eax") if $swap; ++ &bswap("ebx") if $swap; ++ ++ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] ++ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] ++ ++ &xor("ecx", "eax"); ++ &xor("edx", "ebx"); ++ ++ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, ++ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually ++ ++ &mov(&DWP(0,$out,"",0),"ecx"); ++ &mov(&DWP(4,$out,"",0),"edx"); ++ ++ &mov(&DWP($data_off+8,"esp","",0), "eax"); # save iv ++ &mov(&DWP($data_off+12,"esp","",0), "ebx"); # ++ ++ &add($in, 8); ++ &add($out, 8); ++ ++ &sub($count, 8); ++ &jnz(&label("decrypt_loop")); ++############################ ENDIT #######################3 ++ &set_label("decrypt_finish"); ++ &mov($count, &wparam(2)); # length ++ &and($count, 7); ++ &jz(&label("finish")); ++ ++ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes ++ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes ++ ++ &bswap("eax") if $swap; ++ &bswap("ebx") if $swap; ++ ++ &mov(&DWP($data_off,"esp","",0), "eax"); # put back ++ &mov(&DWP($data_off+4,"esp","",0), "ebx"); # ++ ++ &call($dec_func); ++ ++ &mov("eax", &DWP($data_off,"esp","",0)); # get return ++ &mov("ebx", &DWP($data_off+4,"esp","",0)); # ++ ++ &bswap("eax") if $swap; ++ &bswap("ebx") if $swap; ++ ++ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] ++ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] ++ ++ &xor("ecx", "eax"); ++ &xor("edx", "ebx"); ++ ++ # this is for when we exit ++ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, ++ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually ++ ++&set_label("dj7"); ++ &rotr("edx", 16); ++ &movb(&BP(6,$out,"",0), &LB("edx")); ++ &shr("edx",16); ++&set_label("dj6"); ++ &movb(&BP(5,$out,"",0), &HB("edx")); ++&set_label("dj5"); ++ &movb(&BP(4,$out,"",0), &LB("edx")); ++&set_label("dj4"); ++ &mov(&DWP(0,$out,"",0), "ecx"); ++ &jmp(&label("djend")); ++&set_label("dj3"); ++ &rotr("ecx", 16); ++ &movb(&BP(2,$out,"",0), &LB("ecx")); ++ &shl("ecx",16); ++&set_label("dj2"); ++ &movb(&BP(1,$in,"",0), &HB("ecx")); ++&set_label("dj1"); ++ &movb(&BP(0,$in,"",0), &LB("ecx")); ++&set_label("djend"); ++ ++ # final iv is still in eax:ebx ++ &jmp(&label("finish")); ++ ++ ++############################ FINISH #######################3 ++ &set_label("finish",1); ++ &mov("ecx", &wparam($iv_off)); # Get iv ptr ++ ++ ################################################# ++ $total=16+4; ++ $total+=4 if ($p1 > 0); ++ $total+=4 if ($p2 > 0); ++ $total+=4 if ($p3 > 0); ++ &add("esp",$total); ++ ++ &mov(&DWP(0,"ecx","",0), "eax"); # save iv ++ &mov(&DWP(4,"ecx","",0), "ebx"); # save iv ++ ++ &function_end_A($name); ++ ++ &set_label("cbc_enc_jmp_table",1); ++ &data_word("0"); ++ &data_word(&label("ej1")); ++ &data_word(&label("ej2")); ++ &data_word(&label("ej3")); ++ &data_word(&label("ej4")); ++ &data_word(&label("ej5")); ++ &data_word(&label("ej6")); ++ &data_word(&label("ej7")); ++ &set_label("cbc_dec_jmp_table",1); ++ &data_word("0"); ++ &data_word(&label("dj1")); ++ &data_word(&label("dj2")); ++ &data_word(&label("dj3")); ++ &data_word(&label("dj4")); ++ &data_word(&label("dj5")); ++ &data_word(&label("dj6")); ++ &data_word(&label("dj7")); ++ ++ &function_end_B($name); ++ ++ } ++ ++1; +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/asm/perlasm/readme Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,124 @@ ++The perl scripts in this directory are my 'hack' to generate ++multiple different assembler formats via the one origional script. ++ ++The way to use this library is to start with adding the path to this directory ++and then include it. ++ ++push(@INC,"perlasm","../../perlasm"); ++require "x86asm.pl"; ++ ++The first thing we do is setup the file and type of assember ++ ++&asm_init($ARGV[0],$0); ++ ++The first argument is the 'type'. Currently ++'cpp', 'sol', 'a.out', 'elf' or 'win32'. ++Argument 2 is the file name. ++ ++The reciprocal function is ++&asm_finish() which should be called at the end. ++ ++There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler, ++and x86unix.pl which is the unix (gas) version. ++ ++Functions of interest are: ++&external_label("des_SPtrans"); declare and external variable ++&LB(reg); Low byte for a register ++&HB(reg); High byte for a register ++&BP(off,base,index,scale) Byte pointer addressing ++&DWP(off,base,index,scale) Word pointer addressing ++&stack_push(num) Basically a 'sub esp, num*4' with extra ++&stack_pop(num) inverse of stack_push ++&function_begin(name,extra) Start a function with pushing of ++ edi, esi, ebx and ebp. extra is extra win32 ++ external info that may be required. ++&function_begin_B(name,extra) Same as norma function_begin but no pushing. ++&function_end(name) Call at end of function. ++&function_end_A(name) Standard pop and ret, for use inside functions ++&function_end_B(name) Call at end but with poping or 'ret'. ++&swtmp(num) Address on stack temp word. ++&wparam(num) Parameter number num, that was push ++ in C convention. This all works over pushes ++ and pops. ++&comment("hello there") Put in a comment. ++&label("loop") Refer to a label, normally a jmp target. ++&set_label("loop") Set a label at this point. ++&data_word(word) Put in a word of data. ++ ++So how does this all hold together? Given ++ ++int calc(int len, int *data) ++ { ++ int i,j=0; ++ ++ for (i=0; i"); ++&comment(""); ++ ++ $filename =~ s/\.pl$//; ++ &file($filename); ++ } ++ ++sub asm_finish_cpp ++ { ++ return unless $cpp; ++ ++ local($tmp,$i); ++ foreach $i (&get_labels()) ++ { ++ $tmp.="#define $i _$i\n"; ++ } ++ print <<"EOF"; ++/* Run the C pre-processor over this file with one of the following defined ++ * ELF - elf object files, ++ * OUT - a.out object files, ++ * BSDI - BSDI style a.out object files ++ * SOL - Solaris style elf ++ */ ++ ++#define TYPE(a,b) .type a,b ++#define SIZE(a,b) .size a,b ++ ++#if defined(OUT) || defined(BSDI) ++$tmp ++#endif ++ ++#ifdef OUT ++#define OK 1 ++#define ALIGN 4 ++#endif ++ ++#ifdef BSDI ++#define OK 1 ++#define ALIGN 4 ++#undef SIZE ++#undef TYPE ++#endif ++ ++#if defined(ELF) || defined(SOL) ++#define OK 1 ++#define ALIGN 16 ++#endif ++ ++#ifndef OK ++You need to define one of ++ELF - elf systems - linux-elf, NetBSD and DG-UX ++OUT - a.out systems - linux-a.out and FreeBSD ++SOL - solaris systems, which are elf with strange comment lines ++BSDI - a.out with a very primative version of as. ++#endif ++ ++/* Let the Assembler begin :-) */ ++EOF ++ } ++ ++1; +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/asm/perlasm/x86ms.pl Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,345 @@ ++#!/usr/bin/perl ++ ++package x86ms; ++ ++$label="L000"; ++ ++%lb=( 'eax', 'al', ++ 'ebx', 'bl', ++ 'ecx', 'cl', ++ 'edx', 'dl', ++ 'ax', 'al', ++ 'bx', 'bl', ++ 'cx', 'cl', ++ 'dx', 'dl', ++ ); ++ ++%hb=( 'eax', 'ah', ++ 'ebx', 'bh', ++ 'ecx', 'ch', ++ 'edx', 'dh', ++ 'ax', 'ah', ++ 'bx', 'bh', ++ 'cx', 'ch', ++ 'dx', 'dh', ++ ); ++ ++sub main'asm_init_output { @out=(); } ++sub main'asm_get_output { return(@out); } ++sub main'get_labels { return(@labels); } ++sub main'external_label { push(@labels,@_); } ++ ++sub main'LB ++ { ++ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n"; ++ return($lb{$_[0]}); ++ } ++ ++sub main'HB ++ { ++ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n"; ++ return($hb{$_[0]}); ++ } ++ ++sub main'BP ++ { ++ &get_mem("BYTE",@_); ++ } ++ ++sub main'DWP ++ { ++ &get_mem("DWORD",@_); ++ } ++ ++sub main'stack_push ++ { ++ local($num)=@_; ++ $stack+=$num*4; ++ &main'sub("esp",$num*4); ++ } ++ ++sub main'stack_pop ++ { ++ local($num)=@_; ++ $stack-=$num*4; ++ &main'add("esp",$num*4); ++ } ++ ++sub get_mem ++ { ++ local($size,$addr,$reg1,$reg2,$idx)=@_; ++ local($t,$post); ++ local($ret)="$size PTR "; ++ ++ $addr =~ s/^\s+//; ++ if ($addr =~ /^(.+)\+(.+)$/) ++ { ++ $reg2=&conv($1); ++ $addr="_$2"; ++ } ++ elsif ($addr =~ /^[_a-zA-Z]/) ++ { ++ $addr="_$addr"; ++ } ++ ++ $reg1="$regs{$reg1}" if defined($regs{$reg1}); ++ $reg2="$regs{$reg2}" if defined($regs{$reg2}); ++ if (($addr ne "") && ($addr ne 0)) ++ { ++ if ($addr !~ /^-/) ++ { $ret.=$addr; } ++ else { $post=$addr; } ++ } ++ if ($reg2 ne "") ++ { ++ $t=""; ++ $t="*$idx" if ($idx != 0); ++ $reg1="+".$reg1 if ("$reg1$post" ne ""); ++ $ret.="[$reg2$t$reg1$post]"; ++ } ++ else ++ { ++ $ret.="[$reg1$post]" ++ } ++ return($ret); ++ } ++ ++sub main'mov { &out2("mov",@_); } ++sub main'movb { &out2("mov",@_); } ++sub main'and { &out2("and",@_); } ++sub main'or { &out2("or",@_); } ++sub main'shl { &out2("shl",@_); } ++sub main'shr { &out2("shr",@_); } ++sub main'xor { &out2("xor",@_); } ++sub main'xorb { &out2("xor",@_); } ++sub main'add { &out2("add",@_); } ++sub main'adc { &out2("adc",@_); } ++sub main'sub { &out2("sub",@_); } ++sub main'rotl { &out2("rol",@_); } ++sub main'rotr { &out2("ror",@_); } ++sub main'exch { &out2("xchg",@_); } ++sub main'cmp { &out2("cmp",@_); } ++sub main'lea { &out2("lea",@_); } ++sub main'mul { &out1("mul",@_); } ++sub main'div { &out1("div",@_); } ++sub main'dec { &out1("dec",@_); } ++sub main'inc { &out1("inc",@_); } ++sub main'jmp { &out1("jmp",@_); } ++sub main'jmp_ptr { &out1p("jmp",@_); } ++sub main'je { &out1("je",@_); } ++sub main'jle { &out1("jle",@_); } ++sub main'jz { &out1("jz",@_); } ++sub main'jge { &out1("jge",@_); } ++sub main'jl { &out1("jl",@_); } ++sub main'jb { &out1("jb",@_); } ++sub main'jnz { &out1("jnz",@_); } ++sub main'jne { &out1("jne",@_); } ++sub main'push { &out1("push",@_); $stack+=4; } ++sub main'pop { &out1("pop",@_); $stack-=4; } ++sub main'bswap { &out1("bswap",@_); &using486(); } ++sub main'not { &out1("not",@_); } ++sub main'call { &out1("call",'_'.$_[0]); } ++sub main'ret { &out0("ret"); } ++sub main'nop { &out0("nop"); } ++ ++sub out2 ++ { ++ local($name,$p1,$p2)=@_; ++ local($l,$t); ++ ++ push(@out,"\t$name\t"); ++ $t=&conv($p1).","; ++ $l=length($t); ++ push(@out,$t); ++ $l=4-($l+9)/8; ++ push(@out,"\t" x $l); ++ push(@out,&conv($p2)); ++ push(@out,"\n"); ++ } ++ ++sub out0 ++ { ++ local($name)=@_; ++ ++ push(@out,"\t$name\n"); ++ } ++ ++sub out1 ++ { ++ local($name,$p1)=@_; ++ local($l,$t); ++ ++ push(@out,"\t$name\t".&conv($p1)."\n"); ++ } ++ ++sub conv ++ { ++ local($p)=@_; ++ ++ $p =~ s/0x([0-9A-Fa-f]+)/0$1h/; ++ return $p; ++ } ++ ++sub using486 ++ { ++ return if $using486; ++ $using486++; ++ grep(s/\.386/\.486/,@out); ++ } ++ ++sub main'file ++ { ++ local($file)=@_; ++ ++ local($tmp)=<<"EOF"; ++ TITLE $file.asm ++ .386 ++.model FLAT ++EOF ++ push(@out,$tmp); ++ } ++ ++sub main'function_begin ++ { ++ local($func,$extra)=@_; ++ ++ push(@labels,$func); ++ ++ local($tmp)=<<"EOF"; ++_TEXT SEGMENT ++PUBLIC _$func ++$extra ++_$func PROC NEAR ++ push ebp ++ push ebx ++ push esi ++ push edi ++EOF ++ push(@out,$tmp); ++ $stack=20; ++ } ++ ++sub main'function_begin_B ++ { ++ local($func,$extra)=@_; ++ ++ local($tmp)=<<"EOF"; ++_TEXT SEGMENT ++PUBLIC _$func ++$extra ++_$func PROC NEAR ++EOF ++ push(@out,$tmp); ++ $stack=4; ++ } ++ ++sub main'function_end ++ { ++ local($func)=@_; ++ ++ local($tmp)=<<"EOF"; ++ pop edi ++ pop esi ++ pop ebx ++ pop ebp ++ ret ++_$func ENDP ++_TEXT ENDS ++EOF ++ push(@out,$tmp); ++ $stack=0; ++ %label=(); ++ } ++ ++sub main'function_end_B ++ { ++ local($func)=@_; ++ ++ local($tmp)=<<"EOF"; ++_$func ENDP ++_TEXT ENDS ++EOF ++ push(@out,$tmp); ++ $stack=0; ++ %label=(); ++ } ++ ++sub main'function_end_A ++ { ++ local($func)=@_; ++ ++ local($tmp)=<<"EOF"; ++ pop edi ++ pop esi ++ pop ebx ++ pop ebp ++ ret ++EOF ++ push(@out,$tmp); ++ } ++ ++sub main'file_end ++ { ++ push(@out,"END\n"); ++ } ++ ++sub main'wparam ++ { ++ local($num)=@_; ++ ++ return(&main'DWP($stack+$num*4,"esp","",0)); ++ } ++ ++sub main'swtmp ++ { ++ return(&main'DWP($_[0]*4,"esp","",0)); ++ } ++ ++# Should use swtmp, which is above esp. Linix can trash the stack above esp ++#sub main'wtmp ++# { ++# local($num)=@_; ++# ++# return(&main'DWP(-(($num+1)*4),"esp","",0)); ++# } ++ ++sub main'comment ++ { ++ foreach (@_) ++ { ++ push(@out,"\t; $_\n"); ++ } ++ } ++ ++sub main'label ++ { ++ if (!defined($label{$_[0]})) ++ { ++ $label{$_[0]}="\$${label}${_[0]}"; ++ $label++; ++ } ++ return($label{$_[0]}); ++ } ++ ++sub main'set_label ++ { ++ if (!defined($label{$_[0]})) ++ { ++ $label{$_[0]}="${label}${_[0]}"; ++ $label++; ++ } ++ push(@out,"$label{$_[0]}:\n"); ++ } ++ ++sub main'data_word ++ { ++ push(@out,"\tDD\t$_[0]\n"); ++ } ++ ++sub out1p ++ { ++ local($name,$p1)=@_; ++ local($l,$t); ++ ++ push(@out,"\t$name\t ".&conv($p1)."\n"); ++ } +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/asm/perlasm/x86unix.pl Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,403 @@ ++#!/usr/bin/perl ++ ++package x86unix; ++ ++$label="L000"; ++ ++$align=($main'aout)?"4":"16"; ++$under=($main'aout)?"_":""; ++$com_start=($main'sol)?"/":"#"; ++ ++sub main'asm_init_output { @out=(); } ++sub main'asm_get_output { return(@out); } ++sub main'get_labels { return(@labels); } ++sub main'external_label { push(@labels,@_); } ++ ++if ($main'cpp) ++ { ++ $align="ALIGN"; ++ $under=""; ++ $com_start='/*'; ++ $com_end='*/'; ++ } ++ ++%lb=( 'eax', '%al', ++ 'ebx', '%bl', ++ 'ecx', '%cl', ++ 'edx', '%dl', ++ 'ax', '%al', ++ 'bx', '%bl', ++ 'cx', '%cl', ++ 'dx', '%dl', ++ ); ++ ++%hb=( 'eax', '%ah', ++ 'ebx', '%bh', ++ 'ecx', '%ch', ++ 'edx', '%dh', ++ 'ax', '%ah', ++ 'bx', '%bh', ++ 'cx', '%ch', ++ 'dx', '%dh', ++ ); ++ ++%regs=( 'eax', '%eax', ++ 'ebx', '%ebx', ++ 'ecx', '%ecx', ++ 'edx', '%edx', ++ 'esi', '%esi', ++ 'edi', '%edi', ++ 'ebp', '%ebp', ++ 'esp', '%esp', ++ ); ++ ++%reg_val=( ++ 'eax', 0x00, ++ 'ebx', 0x03, ++ 'ecx', 0x01, ++ 'edx', 0x02, ++ 'esi', 0x06, ++ 'edi', 0x07, ++ 'ebp', 0x05, ++ 'esp', 0x04, ++ ); ++ ++sub main'LB ++ { ++ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n"; ++ return($lb{$_[0]}); ++ } ++ ++sub main'HB ++ { ++ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n"; ++ return($hb{$_[0]}); ++ } ++ ++sub main'DWP ++ { ++ local($addr,$reg1,$reg2,$idx)=@_; ++ ++ $ret=""; ++ $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/; ++ $reg1="$regs{$reg1}" if defined($regs{$reg1}); ++ $reg2="$regs{$reg2}" if defined($regs{$reg2}); ++ $ret.=$addr if ($addr ne "") && ($addr ne 0); ++ if ($reg2 ne "") ++ { $ret.="($reg1,$reg2,$idx)"; } ++ else ++ { $ret.="($reg1)" } ++ return($ret); ++ } ++ ++sub main'BP ++ { ++ return(&main'DWP(@_)); ++ } ++ ++#sub main'BP ++# { ++# local($addr,$reg1,$reg2,$idx)=@_; ++# ++# $ret=""; ++# ++# $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/; ++# $reg1="$regs{$reg1}" if defined($regs{$reg1}); ++# $reg2="$regs{$reg2}" if defined($regs{$reg2}); ++# $ret.=$addr if ($addr ne "") && ($addr ne 0); ++# if ($reg2 ne "") ++# { $ret.="($reg1,$reg2,$idx)"; } ++# else ++# { $ret.="($reg1)" } ++# return($ret); ++# } ++ ++sub main'mov { &out2("movl",@_); } ++sub main'movb { &out2("movb",@_); } ++sub main'and { &out2("andl",@_); } ++sub main'or { &out2("orl",@_); } ++sub main'shl { &out2("sall",@_); } ++sub main'shr { &out2("shrl",@_); } ++sub main'xor { &out2("xorl",@_); } ++sub main'xorb { &out2("xorb",@_); } ++sub main'add { &out2("addl",@_); } ++sub main'adc { &out2("adcl",@_); } ++sub main'sub { &out2("subl",@_); } ++sub main'rotl { &out2("roll",@_); } ++sub main'rotr { &out2("rorl",@_); } ++sub main'exch { &out2("xchg",@_); } ++sub main'cmp { &out2("cmpl",@_); } ++sub main'lea { &out2("leal",@_); } ++sub main'mul { &out1("mull",@_); } ++sub main'div { &out1("divl",@_); } ++sub main'jmp { &out1("jmp",@_); } ++sub main'jmp_ptr { &out1p("jmp",@_); } ++sub main'je { &out1("je",@_); } ++sub main'jle { &out1("jle",@_); } ++sub main'jne { &out1("jne",@_); } ++sub main'jnz { &out1("jnz",@_); } ++sub main'jz { &out1("jz",@_); } ++sub main'jge { &out1("jge",@_); } ++sub main'jl { &out1("jl",@_); } ++sub main'jb { &out1("jb",@_); } ++sub main'dec { &out1("decl",@_); } ++sub main'inc { &out1("incl",@_); } ++sub main'push { &out1("pushl",@_); $stack+=4; } ++sub main'pop { &out1("popl",@_); $stack-=4; } ++sub main'bswap { &out1("bswapl",@_); } ++sub main'not { &out1("notl",@_); } ++sub main'call { &out1("call",$under.$_[0]); } ++sub main'ret { &out0("ret"); } ++sub main'nop { &out0("nop"); } ++ ++sub out2 ++ { ++ local($name,$p1,$p2)=@_; ++ local($l,$ll,$t); ++ local(%special)=( "roll",0xD1C0,"rorl",0xD1C8, ++ "rcll",0xD1D0,"rcrl",0xD1D8, ++ "shll",0xD1E0,"shrl",0xD1E8, ++ "sarl",0xD1F8); ++ ++ if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1)) ++ { ++ $op=$special{$name}|$reg_val{$p1}; ++ $tmp1=sprintf ".byte %d\n",($op>>8)&0xff; ++ $tmp2=sprintf ".byte %d\t",$op &0xff; ++ push(@out,$tmp1); ++ push(@out,$tmp2); ++ ++ $p2=&conv($p2); ++ $p1=&conv($p1); ++ &main'comment("$name $p2 $p1"); ++ return; ++ } ++ ++ push(@out,"\t$name\t"); ++ $t=&conv($p2).","; ++ $l=length($t); ++ push(@out,$t); ++ $ll=4-($l+9)/8; ++ $tmp1=sprintf "\t" x $ll; ++ push(@out,$tmp1); ++ push(@out,&conv($p1)."\n"); ++ } ++ ++sub out1 ++ { ++ local($name,$p1)=@_; ++ local($l,$t); ++ ++ push(@out,"\t$name\t".&conv($p1)."\n"); ++ } ++ ++sub out1p ++ { ++ local($name,$p1)=@_; ++ local($l,$t); ++ ++ push(@out,"\t$name\t*".&conv($p1)."\n"); ++ } ++ ++sub out0 ++ { ++ push(@out,"\t$_[0]\n"); ++ } ++ ++sub conv ++ { ++ local($p)=@_; ++ ++# $p =~ s/0x([0-9A-Fa-f]+)/0$1h/; ++ ++ $p=$regs{$p} if (defined($regs{$p})); ++ ++ $p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/; ++ $p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/; ++ return $p; ++ } ++ ++sub main'file ++ { ++ local($file)=@_; ++ ++ local($tmp)=<<"EOF"; ++ .file "$file.s" ++ .version "01.01" ++gcc2_compiled.: ++EOF ++ push(@out,$tmp); ++ } ++ ++sub main'function_begin ++ { ++ local($func)=@_; ++ ++ $func=$under.$func; ++ ++ local($tmp)=<<"EOF"; ++.text ++ .align $align ++.globl $func ++EOF ++ push(@out,$tmp); ++ if ($main'cpp) ++ { $tmp=push(@out,"\tTYPE($func,\@function)\n"); } ++ else { $tmp=push(@out,"\t.type\t$func,\@function\n"); } ++ push(@out,"$func:\n"); ++ $tmp=<<"EOF"; ++ pushl %ebp ++ pushl %ebx ++ pushl %esi ++ pushl %edi ++ ++EOF ++ push(@out,$tmp); ++ $stack=20; ++ } ++ ++sub main'function_begin_B ++ { ++ local($func,$extra)=@_; ++ ++ $func=$under.$func; ++ ++ local($tmp)=<<"EOF"; ++.text ++ .align $align ++.globl $func ++EOF ++ push(@out,$tmp); ++ if ($main'cpp) ++ { push(@out,"\tTYPE($func,\@function)\n"); } ++ else { push(@out,"\t.type $func,\@function\n"); } ++ push(@out,"$func:\n"); ++ $stack=4; ++ } ++ ++sub main'function_end ++ { ++ local($func)=@_; ++ ++ $func=$under.$func; ++ ++ local($tmp)=<<"EOF"; ++ popl %edi ++ popl %esi ++ popl %ebx ++ popl %ebp ++ ret ++.${func}_end: ++EOF ++ push(@out,$tmp); ++ if ($main'cpp) ++ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); } ++ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); } ++ push(@out,".ident \"$func\"\n"); ++ $stack=0; ++ %label=(); ++ } ++ ++sub main'function_end_A ++ { ++ local($func)=@_; ++ ++ local($tmp)=<<"EOF"; ++ popl %edi ++ popl %esi ++ popl %ebx ++ popl %ebp ++ ret ++EOF ++ push(@out,$tmp); ++ } ++ ++sub main'function_end_B ++ { ++ local($func)=@_; ++ ++ $func=$under.$func; ++ ++ push(@out,".${func}_end:\n"); ++ if ($main'cpp) ++ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); } ++ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); } ++ push(@out,".ident \"desasm.pl\"\n"); ++ $stack=0; ++ %label=(); ++ } ++ ++sub main'wparam ++ { ++ local($num)=@_; ++ ++ return(&main'DWP($stack+$num*4,"esp","",0)); ++ } ++ ++sub main'stack_push ++ { ++ local($num)=@_; ++ $stack+=$num*4; ++ &main'sub("esp",$num*4); ++ } ++ ++sub main'stack_pop ++ { ++ local($num)=@_; ++ $stack-=$num*4; ++ &main'add("esp",$num*4); ++ } ++ ++sub main'swtmp ++ { ++ return(&main'DWP($_[0]*4,"esp","",0)); ++ } ++ ++# Should use swtmp, which is above esp. Linix can trash the stack above esp ++#sub main'wtmp ++# { ++# local($num)=@_; ++# ++# return(&main'DWP(-($num+1)*4,"esp","",0)); ++# } ++ ++sub main'comment ++ { ++ foreach (@_) ++ { ++ if (/^\s*$/) ++ { push(@out,"\n"); } ++ else ++ { push(@out,"\t$com_start $_ $com_end\n"); } ++ } ++ } ++ ++sub main'label ++ { ++ if (!defined($label{$_[0]})) ++ { ++ $label{$_[0]}=".${label}${_[0]}"; ++ $label++; ++ } ++ return($label{$_[0]}); ++ } ++ ++sub main'set_label ++ { ++ if (!defined($label{$_[0]})) ++ { ++ $label{$_[0]}=".${label}${_[0]}"; ++ $label++; ++ } ++ push(@out,".align $align\n") if ($_[1] != 0); ++ push(@out,"$label{$_[0]}:\n"); ++ } ++ ++sub main'file_end ++ { ++ } ++ ++sub main'data_word ++ { ++ push(@out,"\t.long $_[0]\n"); ++ } +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/asm/readme Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,131 @@ ++First up, let me say I don't like writing in assembler. It is not portable, ++dependant on the particular CPU architecture release and is generally a pig ++to debug and get right. Having said that, the x86 architecture is probably ++the most important for speed due to number of boxes and since ++it appears to be the worst architecture to to get ++good C compilers for. So due to this, I have lowered myself to do ++assembler for the inner DES routines in libdes :-). ++ ++The file to implement in assembler is des_enc.c. Replace the following ++4 functions ++des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt); ++des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt); ++des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3); ++des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3); ++ ++They encrypt/decrypt the 64 bits held in 'data' using ++the 'ks' key schedules. The only difference between the 4 functions is that ++des_encrypt2() does not perform IP() or FP() on the data (this is an ++optimization for when doing triple DES and des_encrypt3() and des_decrypt3() ++perform triple des. The triple DES routines are in here because it does ++make a big difference to have them located near the des_encrypt2 function ++at link time.. ++ ++Now as we all know, there are lots of different operating systems running on ++x86 boxes, and unfortunately they normally try to make sure their assembler ++formating is not the same as the other peoples. ++The 4 main formats I know of are ++Microsoft Windows 95/Windows NT ++Elf Includes Linux and FreeBSD(?). ++a.out The older Linux. ++Solaris Same as Elf but different comments :-(. ++ ++Now I was not overly keen to write 4 different copies of the same code, ++so I wrote a few perl routines to output the correct assembler, given ++a target assembler type. This code is ugly and is just a hack. ++The libraries are x86unix.pl and x86ms.pl. ++des586.pl, des686.pl and des-som[23].pl are the programs to actually ++generate the assembler. ++ ++So to generate elf assembler ++perl des-som3.pl elf >dx86-elf.s ++For Windows 95/NT ++perl des-som2.pl win32 >win32.asm ++ ++[ update 4 Jan 1996 ] ++I have added another way to do things. ++perl des-som3.pl cpp >dx86-cpp.s ++generates a file that will be included by dx86unix.cpp when it is compiled. ++To build for elf, a.out, solaris, bsdi etc, ++cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o ++cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o ++cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o ++cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o ++This was done to cut down the number of files in the distribution. ++ ++Now the ugly part. I acquired my copy of Intels ++"Optimization's For Intel's 32-Bit Processors" and found a few interesting ++things. First, the aim of the exersize is to 'extract' one byte at a time ++from a word and do an array lookup. This involves getting the byte from ++the 4 locations in the word and moving it to a new word and doing the lookup. ++The most obvious way to do this is ++xor eax, eax # clear word ++movb al, cl # get low byte ++xor edi DWORD PTR 0x100+des_SP[eax] # xor in word ++movb al, ch # get next byte ++xor edi DWORD PTR 0x300+des_SP[eax] # xor in word ++shr ecx 16 ++which seems ok. For the pentium, this system appears to be the best. ++One has to do instruction interleaving to keep both functional units ++operating, but it is basically very efficient. ++ ++Now the crunch. When a full register is used after a partial write, eg. ++mov al, cl ++xor edi, DWORD PTR 0x100+des_SP[eax] ++386 - 1 cycle stall ++486 - 1 cycle stall ++586 - 0 cycle stall ++686 - at least 7 cycle stall (page 22 of the above mentioned document). ++ ++So the technique that produces the best results on a pentium, according to ++the documentation, will produce hideous results on a pentium pro. ++ ++To get around this, des686.pl will generate code that is not as fast on ++a pentium, should be very good on a pentium pro. ++mov eax, ecx # copy word ++shr ecx, 8 # line up next byte ++and eax, 0fch # mask byte ++xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup ++mov eax, ecx # get word ++shr ecx 8 # line up next byte ++and eax, 0fch # mask byte ++xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup ++ ++Due to the execution units in the pentium, this actually works quite well. ++For a pentium pro it should be very good. This is the type of output ++Visual C++ generates. ++ ++There is a third option. instead of using ++mov al, ch ++which is bad on the pentium pro, one may be able to use ++movzx eax, ch ++which may not incur the partial write penalty. On the pentium, ++this instruction takes 4 cycles so is not worth using but on the ++pentium pro it appears it may be worth while. I need access to one to ++experiment :-). ++ ++eric (20 Oct 1996) ++ ++22 Nov 1996 - I have asked people to run the 2 different version on pentium ++pros and it appears that the intel documentation is wrong. The ++mov al,bh is still faster on a pentium pro, so just use the des586.pl ++install des686.pl ++ ++3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these ++functions into des_enc.c because it does make a massive performance ++difference on some boxes to have the functions code located close to ++the des_encrypt2() function. ++ ++9 Jan 1997 - des-som2.pl is now the correct perl script to use for ++pentiums. It contains an inner loop from ++Svend Olaf Mikkelsen which does raw ecb DES calls at ++273,000 per second. He had a previous version at 250,000 and the best ++I was able to get was 203,000. The content has not changed, this is all ++due to instruction sequencing (and actual instructions choice) which is able ++to keep both functional units of the pentium going. ++We may have lost the ugly register usage restrictions when x86 went 32 bit ++but for the pentium it has been replaced by evil instruction ordering tricks. ++ ++13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf. ++raw DES at 281,000 per second on a pentium 100. ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/cbc_enc.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,135 @@ ++/* crypto/des/cbc_enc.c */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++#include "des_locl.h" ++ ++void des_cbc_encrypt(input, output, length, schedule, ivec, enc) ++des_cblock (*input); ++des_cblock (*output); ++long length; ++des_key_schedule schedule; ++des_cblock (*ivec); ++int enc; ++ { ++ register DES_LONG tin0,tin1; ++ register DES_LONG tout0,tout1,xor0,xor1; ++ register unsigned char *in,*out; ++ register long l=length; ++ DES_LONG tin[2]; ++ unsigned char *iv; ++ ++ in=(unsigned char *)input; ++ out=(unsigned char *)output; ++ iv=(unsigned char *)ivec; ++ ++ if (enc) ++ { ++ c2l(iv,tout0); ++ c2l(iv,tout1); ++ for (l-=8; l>=0; l-=8) ++ { ++ c2l(in,tin0); ++ c2l(in,tin1); ++ tin0^=tout0; tin[0]=tin0; ++ tin1^=tout1; tin[1]=tin1; ++ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); ++ tout0=tin[0]; l2c(tout0,out); ++ tout1=tin[1]; l2c(tout1,out); ++ } ++ if (l != -8) ++ { ++ c2ln(in,tin0,tin1,l+8); ++ tin0^=tout0; tin[0]=tin0; ++ tin1^=tout1; tin[1]=tin1; ++ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); ++ tout0=tin[0]; l2c(tout0,out); ++ tout1=tin[1]; l2c(tout1,out); ++ } ++ } ++ else ++ { ++ c2l(iv,xor0); ++ c2l(iv,xor1); ++ for (l-=8; l>=0; l-=8) ++ { ++ c2l(in,tin0); tin[0]=tin0; ++ c2l(in,tin1); tin[1]=tin1; ++ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT); ++ tout0=tin[0]^xor0; ++ tout1=tin[1]^xor1; ++ l2c(tout0,out); ++ l2c(tout1,out); ++ xor0=tin0; ++ xor1=tin1; ++ } ++ if (l != -8) ++ { ++ c2l(in,tin0); tin[0]=tin0; ++ c2l(in,tin1); tin[1]=tin1; ++ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT); ++ tout0=tin[0]^xor0; ++ tout1=tin[1]^xor1; ++ l2cn(tout0,tout1,out,l+8); ++ /* xor0=tin0; ++ xor1=tin1; */ ++ } ++ } ++ tin0=tin1=tout0=tout1=xor0=xor1=0; ++ tin[0]=tin[1]=0; ++ } ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/des.doc Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,505 @@ ++The DES library. ++ ++Please note that this library was originally written to operate with ++eBones, a version of Kerberos that had had encryption removed when it left ++the USA and then put back in. As such there are some routines that I will ++advise not using but they are still in the library for historical reasons. ++For all calls that have an 'input' and 'output' variables, they can be the ++same. ++ ++This library requires the inclusion of 'des.h'. ++ ++All of the encryption functions take what is called a des_key_schedule as an ++argument. A des_key_schedule is an expanded form of the des key. ++A des_key is 8 bytes of odd parity, the type used to hold the key is a ++des_cblock. A des_cblock is an array of 8 bytes, often in this library ++description I will refer to input bytes when the function specifies ++des_cblock's as input or output, this just means that the variable should ++be a multiple of 8 bytes. ++ ++The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to ++specify decryption. The functions and global variable are as follows: ++ ++int des_check_key; ++ DES keys are supposed to be odd parity. If this variable is set to ++ a non-zero value, des_set_key() will check that the key has odd ++ parity and is not one of the known weak DES keys. By default this ++ variable is turned off; ++ ++void des_set_odd_parity( ++des_cblock *key ); ++ This function takes a DES key (8 bytes) and sets the parity to odd. ++ ++int des_is_weak_key( ++des_cblock *key ); ++ This function returns a non-zero value if the DES key passed is a ++ weak, DES key. If it is a weak key, don't use it, try a different ++ one. If you are using 'random' keys, the chances of hitting a weak ++ key are 1/2^52 so it is probably not worth checking for them. ++ ++int des_set_key( ++des_cblock *key, ++des_key_schedule schedule); ++ Des_set_key converts an 8 byte DES key into a des_key_schedule. ++ A des_key_schedule is an expanded form of the key which is used to ++ perform actual encryption. It can be regenerated from the DES key ++ so it only needs to be kept when encryption or decryption is about ++ to occur. Don't save or pass around des_key_schedule's since they ++ are CPU architecture dependent, DES keys are not. If des_check_key ++ is non zero, zero is returned if the key has the wrong parity or ++ the key is a weak key, else 1 is returned. ++ ++int des_key_sched( ++des_cblock *key, ++des_key_schedule schedule); ++ An alternative name for des_set_key(). ++ ++int des_rw_mode; /* defaults to DES_PCBC_MODE */ ++ This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default). ++ This specifies the function to use in the enc_read() and enc_write() ++ functions. ++ ++void des_encrypt( ++unsigned long *data, ++des_key_schedule ks, ++int enc); ++ This is the DES encryption function that gets called by just about ++ every other DES routine in the library. You should not use this ++ function except to implement 'modes' of DES. I say this because the ++ functions that call this routine do the conversion from 'char *' to ++ long, and this needs to be done to make sure 'non-aligned' memory ++ access do not occur. The characters are loaded 'little endian', ++ have a look at my source code for more details on how I use this ++ function. ++ Data is a pointer to 2 unsigned long's and ks is the ++ des_key_schedule to use. enc, is non zero specifies encryption, ++ zero if decryption. ++ ++void des_encrypt2( ++unsigned long *data, ++des_key_schedule ks, ++int enc); ++ This functions is the same as des_encrypt() except that the DES ++ initial permutation (IP) and final permutation (FP) have been left ++ out. As for des_encrypt(), you should not use this function. ++ It is used by the routines in my library that implement triple DES. ++ IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same ++ as des_encrypt() des_encrypt() des_encrypt() except faster :-). ++ ++void des_ecb_encrypt( ++des_cblock *input, ++des_cblock *output, ++des_key_schedule ks, ++int enc); ++ This is the basic Electronic Code Book form of DES, the most basic ++ form. Input is encrypted into output using the key represented by ++ ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise ++ decryption occurs. Input is 8 bytes long and output is 8 bytes. ++ (the des_cblock structure is 8 chars). ++ ++void des_ecb3_encrypt( ++des_cblock *input, ++des_cblock *output, ++des_key_schedule ks1, ++des_key_schedule ks2, ++des_key_schedule ks3, ++int enc); ++ This is the 3 key EDE mode of ECB DES. What this means is that ++ the 8 bytes of input is encrypted with ks1, decrypted with ks2 and ++ then encrypted again with ks3, before being put into output; ++ C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt() ++ that only takes 2 des_key_schedules that implements, ++ C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1. ++ ++void des_cbc_encrypt( ++des_cblock *input, ++des_cblock *output, ++long length, ++des_key_schedule ks, ++des_cblock *ivec, ++int enc); ++ This routine implements DES in Cipher Block Chaining mode. ++ Input, which should be a multiple of 8 bytes is encrypted ++ (or decrypted) to output which will also be a multiple of 8 bytes. ++ The number of bytes is in length (and from what I've said above, ++ should be a multiple of 8). If length is not a multiple of 8, I'm ++ not being held responsible :-). ivec is the initialisation vector. ++ This function does not modify this variable. To correctly implement ++ cbc mode, you need to do one of 2 things; copy the last 8 bytes of ++ cipher text for use as the next ivec in your application, ++ or use des_ncbc_encrypt(). ++ Only this routine has this problem with updating the ivec, all ++ other routines that are implementing cbc mode update ivec. ++ ++void des_ncbc_encrypt( ++des_cblock *input, ++des_cblock *output, ++long length, ++des_key_schedule sk, ++des_cblock *ivec, ++int enc); ++ For historical reasons, des_cbc_encrypt() did not update the ++ ivec with the value requires so that subsequent calls to ++ des_cbc_encrypt() would 'chain'. This was needed so that the same ++ 'length' values would not need to be used when decrypting. ++ des_ncbc_encrypt() does the right thing. It is the same as ++ des_cbc_encrypt accept that ivec is updates with the correct value ++ to pass in subsequent calls to des_ncbc_encrypt(). I advise using ++ des_ncbc_encrypt() instead of des_cbc_encrypt(); ++ ++void des_xcbc_encrypt( ++des_cblock *input, ++des_cblock *output, ++long length, ++des_key_schedule sk, ++des_cblock *ivec, ++des_cblock *inw, ++des_cblock *outw, ++int enc); ++ This is RSA's DESX mode of DES. It uses inw and outw to ++ 'whiten' the encryption. inw and outw are secret (unlike the iv) ++ and are as such, part of the key. So the key is sort of 24 bytes. ++ This is much better than cbc des. ++ ++void des_3cbc_encrypt( ++des_cblock *input, ++des_cblock *output, ++long length, ++des_key_schedule sk1, ++des_key_schedule sk2, ++des_cblock *ivec1, ++des_cblock *ivec2, ++int enc); ++ This function is flawed, do not use it. I have left it in the ++ library because it is used in my des(1) program and will function ++ correctly when used by des(1). If I removed the function, people ++ could end up unable to decrypt files. ++ This routine implements outer triple cbc encryption using 2 ks and ++ 2 ivec's. Use des_ede2_cbc_encrypt() instead. ++ ++void des_ede3_cbc_encrypt( ++des_cblock *input, ++des_cblock *output, ++long length, ++des_key_schedule ks1, ++des_key_schedule ks2, ++des_key_schedule ks3, ++des_cblock *ivec, ++int enc); ++ This function implements inner triple CBC DES encryption with 3 ++ keys. What this means is that each 'DES' operation ++ inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))). ++ Again, this is cbc mode so an ivec is requires. ++ This mode is used by SSL. ++ There is also a des_ede2_cbc_encrypt() that only uses 2 ++ des_key_schedule's, the first being reused for the final ++ encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES ++ is used by the RSAref library. ++ ++void des_pcbc_encrypt( ++des_cblock *input, ++des_cblock *output, ++long length, ++des_key_schedule ks, ++des_cblock *ivec, ++int enc); ++ This is Propagating Cipher Block Chaining mode of DES. It is used ++ by Kerberos v4. It's parameters are the same as des_ncbc_encrypt(). ++ ++void des_cfb_encrypt( ++unsigned char *in, ++unsigned char *out, ++int numbits, ++long length, ++des_key_schedule ks, ++des_cblock *ivec, ++int enc); ++ Cipher Feedback Back mode of DES. This implementation 'feeds back' ++ in numbit blocks. The input (and output) is in multiples of numbits ++ bits. numbits should to be a multiple of 8 bits. Length is the ++ number of bytes input. If numbits is not a multiple of 8 bits, ++ the extra bits in the bytes will be considered padding. So if ++ numbits is 12, for each 2 input bytes, the 4 high bits of the ++ second byte will be ignored. So to encode 72 bits when using ++ a numbits of 12 take 12 bytes. To encode 72 bits when using ++ numbits of 9 will take 16 bytes. To encode 80 bits when using ++ numbits of 16 will take 10 bytes. etc, etc. This padding will ++ apply to both input and output. ++ ++ ++void des_cfb64_encrypt( ++unsigned char *in, ++unsigned char *out, ++long length, ++des_key_schedule ks, ++des_cblock *ivec, ++int *num, ++int enc); ++ This is one of the more useful functions in this DES library, it ++ implements CFB mode of DES with 64bit feedback. Why is this ++ useful you ask? Because this routine will allow you to encrypt an ++ arbitrary number of bytes, no 8 byte padding. Each call to this ++ routine will encrypt the input bytes to output and then update ivec ++ and num. num contains 'how far' we are though ivec. If this does ++ not make much sense, read more about cfb mode of DES :-). ++ ++void des_ede3_cfb64_encrypt( ++unsigned char *in, ++unsigned char *out, ++long length, ++des_key_schedule ks1, ++des_key_schedule ks2, ++des_key_schedule ks3, ++des_cblock *ivec, ++int *num, ++int enc); ++ Same as des_cfb64_encrypt() accept that the DES operation is ++ triple DES. As usual, there is a macro for ++ des_ede2_cfb64_encrypt() which reuses ks1. ++ ++void des_ofb_encrypt( ++unsigned char *in, ++unsigned char *out, ++int numbits, ++long length, ++des_key_schedule ks, ++des_cblock *ivec); ++ This is a implementation of Output Feed Back mode of DES. It is ++ the same as des_cfb_encrypt() in that numbits is the size of the ++ units dealt with during input and output (in bits). ++ ++void des_ofb64_encrypt( ++unsigned char *in, ++unsigned char *out, ++long length, ++des_key_schedule ks, ++des_cblock *ivec, ++int *num); ++ The same as des_cfb64_encrypt() except that it is Output Feed Back ++ mode. ++ ++void des_ede3_ofb64_encrypt( ++unsigned char *in, ++unsigned char *out, ++long length, ++des_key_schedule ks1, ++des_key_schedule ks2, ++des_key_schedule ks3, ++des_cblock *ivec, ++int *num); ++ Same as des_ofb64_encrypt() accept that the DES operation is ++ triple DES. As usual, there is a macro for ++ des_ede2_ofb64_encrypt() which reuses ks1. ++ ++int des_read_pw_string( ++char *buf, ++int length, ++char *prompt, ++int verify); ++ This routine is used to get a password from the terminal with echo ++ turned off. Buf is where the string will end up and length is the ++ size of buf. Prompt is a string presented to the 'user' and if ++ verify is set, the key is asked for twice and unless the 2 copies ++ match, an error is returned. A return code of -1 indicates a ++ system error, 1 failure due to use interaction, and 0 is success. ++ ++unsigned long des_cbc_cksum( ++des_cblock *input, ++des_cblock *output, ++long length, ++des_key_schedule ks, ++des_cblock *ivec); ++ This function produces an 8 byte checksum from input that it puts in ++ output and returns the last 4 bytes as a long. The checksum is ++ generated via cbc mode of DES in which only the last 8 byes are ++ kept. I would recommend not using this function but instead using ++ the EVP_Digest routines, or at least using MD5 or SHA. This ++ function is used by Kerberos v4 so that is why it stays in the ++ library. ++ ++char *des_fcrypt( ++const char *buf, ++const char *salt ++char *ret); ++ This is my fast version of the unix crypt(3) function. This version ++ takes only a small amount of space relative to other fast ++ crypt() implementations. This is different to the normal crypt ++ in that the third parameter is the buffer that the return value ++ is written into. It needs to be at least 14 bytes long. This ++ function is thread safe, unlike the normal crypt. ++ ++char *crypt( ++const char *buf, ++const char *salt); ++ This function calls des_fcrypt() with a static array passed as the ++ third parameter. This emulates the normal non-thread safe semantics ++ of crypt(3). ++ ++void des_string_to_key( ++char *str, ++des_cblock *key); ++ This function takes str and converts it into a DES key. I would ++ recommend using MD5 instead and use the first 8 bytes of output. ++ When I wrote the first version of these routines back in 1990, MD5 ++ did not exist but I feel these routines are still sound. This ++ routines is compatible with the one in MIT's libdes. ++ ++void des_string_to_2keys( ++char *str, ++des_cblock *key1, ++des_cblock *key2); ++ This function takes str and converts it into 2 DES keys. ++ I would recommend using MD5 and using the 16 bytes as the 2 keys. ++ I have nothing against these 2 'string_to_key' routines, it's just ++ that if you say that your encryption key is generated by using the ++ 16 bytes of an MD5 hash, every-one knows how you generated your ++ keys. ++ ++int des_read_password( ++des_cblock *key, ++char *prompt, ++int verify); ++ This routine combines des_read_pw_string() with des_string_to_key(). ++ ++int des_read_2passwords( ++des_cblock *key1, ++des_cblock *key2, ++char *prompt, ++int verify); ++ This routine combines des_read_pw_string() with des_string_to_2key(). ++ ++void des_random_seed( ++des_cblock key); ++ This routine sets a starting point for des_random_key(). ++ ++void des_random_key( ++des_cblock ret); ++ This function return a random key. Make sure to 'seed' the random ++ number generator (with des_random_seed()) before using this function. ++ I personally now use a MD5 based random number system. ++ ++int des_enc_read( ++int fd, ++char *buf, ++int len, ++des_key_schedule ks, ++des_cblock *iv); ++ This function will write to a file descriptor the encrypted data ++ from buf. This data will be preceded by a 4 byte 'byte count' and ++ will be padded out to 8 bytes. The encryption is either CBC of ++ PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE, ++ pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use ++ DES_PCBC_MODE. ++ ++int des_enc_write( ++int fd, ++char *buf, ++int len, ++des_key_schedule ks, ++des_cblock *iv); ++ This routines read stuff written by des_enc_read() and decrypts it. ++ I have used these routines quite a lot but I don't believe they are ++ suitable for non-blocking io. If you are after a full ++ authentication/encryption over networks, have a look at SSL instead. ++ ++unsigned long des_quad_cksum( ++des_cblock *input, ++des_cblock *output, ++long length, ++int out_count, ++des_cblock *seed); ++ This is a function from Kerberos v4 that is not anything to do with ++ DES but was needed. It is a cksum that is quicker to generate than ++ des_cbc_cksum(); I personally would use MD5 routines now. ++===== ++Modes of DES ++Quite a bit of the following information has been taken from ++ AS 2805.5.2 ++ Australian Standard ++ Electronic funds transfer - Requirements for interfaces, ++ Part 5.2: Modes of operation for an n-bit block cipher algorithm ++ Appendix A ++ ++There are several different modes in which DES can be used, they are ++as follows. ++ ++Electronic Codebook Mode (ECB) (des_ecb_encrypt()) ++- 64 bits are enciphered at a time. ++- The order of the blocks can be rearranged without detection. ++- The same plaintext block always produces the same ciphertext block ++ (for the same key) making it vulnerable to a 'dictionary attack'. ++- An error will only affect one ciphertext block. ++ ++Cipher Block Chaining Mode (CBC) (des_cbc_encrypt()) ++- a multiple of 64 bits are enciphered at a time. ++- The CBC mode produces the same ciphertext whenever the same ++ plaintext is encrypted using the same key and starting variable. ++- The chaining operation makes the ciphertext blocks dependent on the ++ current and all preceding plaintext blocks and therefore blocks can not ++ be rearranged. ++- The use of different starting variables prevents the same plaintext ++ enciphering to the same ciphertext. ++- An error will affect the current and the following ciphertext blocks. ++ ++Cipher Feedback Mode (CFB) (des_cfb_encrypt()) ++- a number of bits (j) <= 64 are enciphered at a time. ++- The CFB mode produces the same ciphertext whenever the same ++ plaintext is encrypted using the same key and starting variable. ++- The chaining operation makes the ciphertext variables dependent on the ++ current and all preceding variables and therefore j-bit variables are ++ chained together and can not be rearranged. ++- The use of different starting variables prevents the same plaintext ++ enciphering to the same ciphertext. ++- The strength of the CFB mode depends on the size of k (maximal if ++ j == k). In my implementation this is always the case. ++- Selection of a small value for j will require more cycles through ++ the encipherment algorithm per unit of plaintext and thus cause ++ greater processing overheads. ++- Only multiples of j bits can be enciphered. ++- An error will affect the current and the following ciphertext variables. ++ ++Output Feedback Mode (OFB) (des_ofb_encrypt()) ++- a number of bits (j) <= 64 are enciphered at a time. ++- The OFB mode produces the same ciphertext whenever the same ++ plaintext enciphered using the same key and starting variable. More ++ over, in the OFB mode the same key stream is produced when the same ++ key and start variable are used. Consequently, for security reasons ++ a specific start variable should be used only once for a given key. ++- The absence of chaining makes the OFB more vulnerable to specific attacks. ++- The use of different start variables values prevents the same ++ plaintext enciphering to the same ciphertext, by producing different ++ key streams. ++- Selection of a small value for j will require more cycles through ++ the encipherment algorithm per unit of plaintext and thus cause ++ greater processing overheads. ++- Only multiples of j bits can be enciphered. ++- OFB mode of operation does not extend ciphertext errors in the ++ resultant plaintext output. Every bit error in the ciphertext causes ++ only one bit to be in error in the deciphered plaintext. ++- OFB mode is not self-synchronising. If the two operation of ++ encipherment and decipherment get out of synchronism, the system needs ++ to be re-initialised. ++- Each re-initialisation should use a value of the start variable ++ different from the start variable values used before with the same ++ key. The reason for this is that an identical bit stream would be ++ produced each time from the same parameters. This would be ++ susceptible to a ' known plaintext' attack. ++ ++Triple ECB Mode (des_ecb3_encrypt()) ++- Encrypt with key1, decrypt with key2 and encrypt with key3 again. ++- As for ECB encryption but increases the key length to 168 bits. ++ There are theoretic attacks that can be used that make the effective ++ key length 112 bits, but this attack also requires 2^56 blocks of ++ memory, not very likely, even for the NSA. ++- If both keys are the same it is equivalent to encrypting once with ++ just one key. ++- If the first and last key are the same, the key length is 112 bits. ++ There are attacks that could reduce the key space to 55 bit's but it ++ requires 2^56 blocks of memory. ++- If all 3 keys are the same, this is effectively the same as normal ++ ecb mode. ++ ++Triple CBC Mode (des_ede3_cbc_encrypt()) ++- Encrypt with key1, decrypt with key2 and then encrypt with key3. ++- As for CBC encryption but increases the key length to 168 bits with ++ the same restrictions as for triple ecb mode. +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/des_crypt.man Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,508 @@ ++.TH DES_CRYPT 3 ++.SH NAME ++des_read_password, des_read_2password, ++des_string_to_key, des_string_to_2key, des_read_pw_string, ++des_random_key, des_set_key, ++des_key_sched, des_ecb_encrypt, des_ecb3_encrypt, des_cbc_encrypt, ++des_3cbc_encrypt, ++des_pcbc_encrypt, des_cfb_encrypt, des_ofb_encrypt, ++des_cbc_cksum, des_quad_cksum, ++des_enc_read, des_enc_write, des_set_odd_parity, ++des_is_weak_key, crypt \- (non USA) DES encryption ++.SH SYNOPSIS ++.nf ++.nj ++.ft B ++#include ++.PP ++.B int des_read_password(key,prompt,verify) ++des_cblock *key; ++char *prompt; ++int verify; ++.PP ++.B int des_read_2password(key1,key2,prompt,verify) ++des_cblock *key1,*key2; ++char *prompt; ++int verify; ++.PP ++.B int des_string_to_key(str,key) ++char *str; ++des_cblock *key; ++.PP ++.B int des_string_to_2keys(str,key1,key2) ++char *str; ++des_cblock *key1,*key2; ++.PP ++.B int des_read_pw_string(buf,length,prompt,verify) ++char *buf; ++int length; ++char *prompt; ++int verify; ++.PP ++.B int des_random_key(key) ++des_cblock *key; ++.PP ++.B int des_set_key(key,schedule) ++des_cblock *key; ++des_key_schedule schedule; ++.PP ++.B int des_key_sched(key,schedule) ++des_cblock *key; ++des_key_schedule schedule; ++.PP ++.B int des_ecb_encrypt(input,output,schedule,encrypt) ++des_cblock *input; ++des_cblock *output; ++des_key_schedule schedule; ++int encrypt; ++.PP ++.B int des_ecb3_encrypt(input,output,ks1,ks2,encrypt) ++des_cblock *input; ++des_cblock *output; ++des_key_schedule ks1,ks2; ++int encrypt; ++.PP ++.B int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt) ++des_cblock *input; ++des_cblock *output; ++long length; ++des_key_schedule schedule; ++des_cblock *ivec; ++int encrypt; ++.PP ++.B int des_3cbc_encrypt(input,output,length,sk1,sk2,ivec1,ivec2,encrypt) ++des_cblock *input; ++des_cblock *output; ++long length; ++des_key_schedule sk1; ++des_key_schedule sk2; ++des_cblock *ivec1; ++des_cblock *ivec2; ++int encrypt; ++.PP ++.B int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt) ++des_cblock *input; ++des_cblock *output; ++long length; ++des_key_schedule schedule; ++des_cblock *ivec; ++int encrypt; ++.PP ++.B int des_cfb_encrypt(input,output,numbits,length,schedule,ivec,encrypt) ++unsigned char *input; ++unsigned char *output; ++int numbits; ++long length; ++des_key_schedule schedule; ++des_cblock *ivec; ++int encrypt; ++.PP ++.B int des_ofb_encrypt(input,output,numbits,length,schedule,ivec) ++unsigned char *input,*output; ++int numbits; ++long length; ++des_key_schedule schedule; ++des_cblock *ivec; ++.PP ++.B unsigned long des_cbc_cksum(input,output,length,schedule,ivec) ++des_cblock *input; ++des_cblock *output; ++long length; ++des_key_schedule schedule; ++des_cblock *ivec; ++.PP ++.B unsigned long des_quad_cksum(input,output,length,out_count,seed) ++des_cblock *input; ++des_cblock *output; ++long length; ++int out_count; ++des_cblock *seed; ++.PP ++.B int des_check_key; ++.PP ++.B int des_enc_read(fd,buf,len,sched,iv) ++int fd; ++char *buf; ++int len; ++des_key_schedule sched; ++des_cblock *iv; ++.PP ++.B int des_enc_write(fd,buf,len,sched,iv) ++int fd; ++char *buf; ++int len; ++des_key_schedule sched; ++des_cblock *iv; ++.PP ++.B extern int des_rw_mode; ++.PP ++.B void des_set_odd_parity(key) ++des_cblock *key; ++.PP ++.B int des_is_weak_key(key) ++des_cblock *key; ++.PP ++.B char *crypt(passwd,salt) ++char *passwd; ++char *salt; ++.PP ++.fi ++.SH DESCRIPTION ++This library contains a fast implementation of the DES encryption ++algorithm. ++.PP ++There are two phases to the use of DES encryption. ++The first is the generation of a ++.I des_key_schedule ++from a key, ++the second is the actual encryption. ++A des key is of type ++.I des_cblock. ++This type is made from 8 characters with odd parity. ++The least significant bit in the character is the parity bit. ++The key schedule is an expanded form of the key; it is used to speed the ++encryption process. ++.PP ++.I des_read_password ++writes the string specified by prompt to the standard output, ++turns off echo and reads an input string from standard input ++until terminated with a newline. ++If verify is non-zero, it prompts and reads the input again and verifies ++that both entered passwords are the same. ++The entered string is converted into a des key by using the ++.I des_string_to_key ++routine. ++The new key is placed in the ++.I des_cblock ++that was passed (by reference) to the routine. ++If there were no errors, ++.I des_read_password ++returns 0, ++-1 is returned if there was a terminal error and 1 is returned for ++any other error. ++.PP ++.I des_read_2password ++operates in the same way as ++.I des_read_password ++except that it generates 2 keys by using the ++.I des_string_to_2key ++function. ++.PP ++.I des_read_pw_string ++is called by ++.I des_read_password ++to read and verify a string from a terminal device. ++The string is returned in ++.I buf. ++The size of ++.I buf ++is passed to the routine via the ++.I length ++parameter. ++.PP ++.I des_string_to_key ++converts a string into a valid des key. ++.PP ++.I des_string_to_2key ++converts a string into 2 valid des keys. ++This routine is best suited for used to generate keys for use with ++.I des_ecb3_encrypt. ++.PP ++.I des_random_key ++returns a random key that is made of a combination of process id, ++time and an increasing counter. ++.PP ++Before a des key can be used it is converted into a ++.I des_key_schedule ++via the ++.I des_set_key ++routine. ++If the ++.I des_check_key ++flag is non-zero, ++.I des_set_key ++will check that the key passed is of odd parity and is not a week or ++semi-weak key. ++If the parity is wrong, ++then -1 is returned. ++If the key is a weak key, ++then -2 is returned. ++If an error is returned, ++the key schedule is not generated. ++.PP ++.I des_key_sched ++is another name for the ++.I des_set_key ++function. ++.PP ++The following routines mostly operate on an input and output stream of ++.I des_cblock's. ++.PP ++.I des_ecb_encrypt ++is the basic DES encryption routine that encrypts or decrypts a single 8-byte ++.I des_cblock ++in ++.I electronic code book ++mode. ++It always transforms the input data, pointed to by ++.I input, ++into the output data, ++pointed to by the ++.I output ++argument. ++If the ++.I encrypt ++argument is non-zero (DES_ENCRYPT), ++the ++.I input ++(cleartext) is encrypted in to the ++.I output ++(ciphertext) using the key_schedule specified by the ++.I schedule ++argument, ++previously set via ++.I des_set_key. ++If ++.I encrypt ++is zero (DES_DECRYPT), ++the ++.I input ++(now ciphertext) ++is decrypted into the ++.I output ++(now cleartext). ++Input and output may overlap. ++No meaningful value is returned. ++.PP ++.I des_ecb3_encrypt ++encrypts/decrypts the ++.I input ++block by using triple ecb DES encryption. ++This involves encrypting the input with ++.I ks1, ++decryption with the key schedule ++.I ks2, ++and then encryption with the first again. ++This routine greatly reduces the chances of brute force breaking of ++DES and has the advantage of if ++.I ks1 ++and ++.I ks2 ++are the same, it is equivalent to just encryption using ecb mode and ++.I ks1 ++as the key. ++.PP ++.I des_cbc_encrypt ++encrypts/decrypts using the ++.I cipher-block-chaining ++mode of DES. ++If the ++.I encrypt ++argument is non-zero, ++the routine cipher-block-chain encrypts the cleartext data pointed to by the ++.I input ++argument into the ciphertext pointed to by the ++.I output ++argument, ++using the key schedule provided by the ++.I schedule ++argument, ++and initialisation vector provided by the ++.I ivec ++argument. ++If the ++.I length ++argument is not an integral multiple of eight bytes, ++the last block is copied to a temporary area and zero filled. ++The output is always ++an integral multiple of eight bytes. ++To make multiple cbc encrypt calls on a large amount of data appear to ++be one ++.I des_cbc_encrypt ++call, the ++.I ivec ++of subsequent calls should be the last 8 bytes of the output. ++.PP ++.I des_3cbc_encrypt ++encrypts/decrypts the ++.I input ++block by using triple cbc DES encryption. ++This involves encrypting the input with key schedule ++.I ks1, ++decryption with the key schedule ++.I ks2, ++and then encryption with the first again. ++2 initialisation vectors are required, ++.I ivec1 ++and ++.I ivec2. ++Unlike ++.I des_cbc_encrypt, ++these initialisation vectors are modified by the subroutine. ++This routine greatly reduces the chances of brute force breaking of ++DES and has the advantage of if ++.I ks1 ++and ++.I ks2 ++are the same, it is equivalent to just encryption using cbc mode and ++.I ks1 ++as the key. ++.PP ++.I des_pcbc_encrypt ++encrypt/decrypts using a modified block chaining mode. ++It provides better error propagation characteristics than cbc ++encryption. ++.PP ++.I des_cfb_encrypt ++encrypt/decrypts using cipher feedback mode. This method takes an ++array of characters as input and outputs and array of characters. It ++does not require any padding to 8 character groups. Note: the ivec ++variable is changed and the new changed value needs to be passed to ++the next call to this function. Since this function runs a complete ++DES ecb encryption per numbits, this function is only suggested for ++use when sending small numbers of characters. ++.PP ++.I des_ofb_encrypt ++encrypt using output feedback mode. This method takes an ++array of characters as input and outputs and array of characters. It ++does not require any padding to 8 character groups. Note: the ivec ++variable is changed and the new changed value needs to be passed to ++the next call to this function. Since this function runs a complete ++DES ecb encryption per numbits, this function is only suggested for ++use when sending small numbers of characters. ++.PP ++.I des_cbc_cksum ++produces an 8 byte checksum based on the input stream (via cbc encryption). ++The last 4 bytes of the checksum is returned and the complete 8 bytes is ++placed in ++.I output. ++.PP ++.I des_quad_cksum ++returns a 4 byte checksum from the input bytes. ++The algorithm can be iterated over the input, ++depending on ++.I out_count, ++1, 2, 3 or 4 times. ++If ++.I output ++is non-NULL, ++the 8 bytes generated by each pass are written into ++.I output. ++.PP ++.I des_enc_write ++is used to write ++.I len ++bytes ++to file descriptor ++.I fd ++from buffer ++.I buf. ++The data is encrypted via ++.I pcbc_encrypt ++(default) using ++.I sched ++for the key and ++.I iv ++as a starting vector. ++The actual data send down ++.I fd ++consists of 4 bytes (in network byte order) containing the length of the ++following encrypted data. The encrypted data then follows, padded with random ++data out to a multiple of 8 bytes. ++.PP ++.I des_enc_read ++is used to read ++.I len ++bytes ++from file descriptor ++.I fd ++into buffer ++.I buf. ++The data being read from ++.I fd ++is assumed to have come from ++.I des_enc_write ++and is decrypted using ++.I sched ++for the key schedule and ++.I iv ++for the initial vector. ++The ++.I des_enc_read/des_enc_write ++pair can be used to read/write to files, pipes and sockets. ++I have used them in implementing a version of rlogin in which all ++data is encrypted. ++.PP ++.I des_rw_mode ++is used to specify the encryption mode to use with ++.I des_enc_read ++and ++.I des_end_write. ++If set to ++.I DES_PCBC_MODE ++(the default), des_pcbc_encrypt is used. ++If set to ++.I DES_CBC_MODE ++des_cbc_encrypt is used. ++These two routines and the variable are not part of the normal MIT library. ++.PP ++.I des_set_odd_parity ++sets the parity of the passed ++.I key ++to odd. This routine is not part of the standard MIT library. ++.PP ++.I des_is_weak_key ++returns 1 is the passed key is a weak key (pick again :-), ++0 if it is ok. ++This routine is not part of the standard MIT library. ++.PP ++.I crypt ++is a replacement for the normal system crypt. ++It is much faster than the system crypt. ++.PP ++.SH FILES ++/usr/include/des.h ++.br ++/usr/lib/libdes.a ++.PP ++The encryption routines have been tested on 16bit, 32bit and 64bit ++machines of various endian and even works under VMS. ++.PP ++.SH BUGS ++.PP ++If you think this manual is sparse, ++read the des_crypt(3) manual from the MIT kerberos (or bones outside ++of the USA) distribution. ++.PP ++.I des_cfb_encrypt ++and ++.I des_ofb_encrypt ++operates on input of 8 bits. What this means is that if you set ++numbits to 12, and length to 2, the first 12 bits will come from the 1st ++input byte and the low half of the second input byte. The second 12 ++bits will have the low 8 bits taken from the 3rd input byte and the ++top 4 bits taken from the 4th input byte. The same holds for output. ++This function has been implemented this way because most people will ++be using a multiple of 8 and because once you get into pulling bytes input ++bytes apart things get ugly! ++.PP ++.I des_read_pw_string ++is the most machine/OS dependent function and normally generates the ++most problems when porting this code. ++.PP ++.I des_string_to_key ++is probably different from the MIT version since there are lots ++of fun ways to implement one-way encryption of a text string. ++.PP ++The routines are optimised for 32 bit machines and so are not efficient ++on IBM PCs. ++.PP ++NOTE: extensive work has been done on this library since this document ++was origionally written. Please try to read des.doc from the libdes ++distribution since it is far more upto date and documents more of the ++functions. Libdes is now also being shipped as part of SSLeay, a ++general cryptographic library that amonst other things implements ++netscapes SSL protocoll. The most recent version can be found in ++SSLeay distributions. ++.SH AUTHOR ++Eric Young (eay@cryptsoft.com) +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/des_enc.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,502 @@ ++/* crypto/des/des_enc.c */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++#include "des_locl.h" ++ ++void des_encrypt(data, ks, enc) ++DES_LONG *data; ++des_key_schedule ks; ++int enc; ++ { ++ register DES_LONG l,r,t,u; ++#ifdef DES_PTR ++ register unsigned char *des_SP=(unsigned char *)des_SPtrans; ++#endif ++#ifndef DES_UNROLL ++ register int i; ++#endif ++ register DES_LONG *s; ++ ++ r=data[0]; ++ l=data[1]; ++ ++ IP(r,l); ++ /* Things have been modified so that the initial rotate is ++ * done outside the loop. This required the ++ * des_SPtrans values in sp.h to be rotated 1 bit to the right. ++ * One perl script later and things have a 5% speed up on a sparc2. ++ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM> ++ * for pointing this out. */ ++ /* clear the top bits on machines with 8byte longs */ ++ /* shift left by 2 */ ++ r=ROTATE(r,29)&0xffffffffL; ++ l=ROTATE(l,29)&0xffffffffL; ++ ++ s=(DES_LONG *)ks; ++ /* I don't know if it is worth the effort of loop unrolling the ++ * inner loop */ ++ if (enc) ++ { ++#ifdef DES_UNROLL ++ D_ENCRYPT(l,r, 0); /* 1 */ ++ D_ENCRYPT(r,l, 2); /* 2 */ ++ D_ENCRYPT(l,r, 4); /* 3 */ ++ D_ENCRYPT(r,l, 6); /* 4 */ ++ D_ENCRYPT(l,r, 8); /* 5 */ ++ D_ENCRYPT(r,l,10); /* 6 */ ++ D_ENCRYPT(l,r,12); /* 7 */ ++ D_ENCRYPT(r,l,14); /* 8 */ ++ D_ENCRYPT(l,r,16); /* 9 */ ++ D_ENCRYPT(r,l,18); /* 10 */ ++ D_ENCRYPT(l,r,20); /* 11 */ ++ D_ENCRYPT(r,l,22); /* 12 */ ++ D_ENCRYPT(l,r,24); /* 13 */ ++ D_ENCRYPT(r,l,26); /* 14 */ ++ D_ENCRYPT(l,r,28); /* 15 */ ++ D_ENCRYPT(r,l,30); /* 16 */ ++#else ++ for (i=0; i<32; i+=8) ++ { ++ D_ENCRYPT(l,r,i+0); /* 1 */ ++ D_ENCRYPT(r,l,i+2); /* 2 */ ++ D_ENCRYPT(l,r,i+4); /* 3 */ ++ D_ENCRYPT(r,l,i+6); /* 4 */ ++ } ++#endif ++ } ++ else ++ { ++#ifdef DES_UNROLL ++ D_ENCRYPT(l,r,30); /* 16 */ ++ D_ENCRYPT(r,l,28); /* 15 */ ++ D_ENCRYPT(l,r,26); /* 14 */ ++ D_ENCRYPT(r,l,24); /* 13 */ ++ D_ENCRYPT(l,r,22); /* 12 */ ++ D_ENCRYPT(r,l,20); /* 11 */ ++ D_ENCRYPT(l,r,18); /* 10 */ ++ D_ENCRYPT(r,l,16); /* 9 */ ++ D_ENCRYPT(l,r,14); /* 8 */ ++ D_ENCRYPT(r,l,12); /* 7 */ ++ D_ENCRYPT(l,r,10); /* 6 */ ++ D_ENCRYPT(r,l, 8); /* 5 */ ++ D_ENCRYPT(l,r, 6); /* 4 */ ++ D_ENCRYPT(r,l, 4); /* 3 */ ++ D_ENCRYPT(l,r, 2); /* 2 */ ++ D_ENCRYPT(r,l, 0); /* 1 */ ++#else ++ for (i=30; i>0; i-=8) ++ { ++ D_ENCRYPT(l,r,i-0); /* 16 */ ++ D_ENCRYPT(r,l,i-2); /* 15 */ ++ D_ENCRYPT(l,r,i-4); /* 14 */ ++ D_ENCRYPT(r,l,i-6); /* 13 */ ++ } ++#endif ++ } ++ ++ /* rotate and clear the top bits on machines with 8byte longs */ ++ l=ROTATE(l,3)&0xffffffffL; ++ r=ROTATE(r,3)&0xffffffffL; ++ ++ FP(r,l); ++ data[0]=l; ++ data[1]=r; ++ l=r=t=u=0; ++ } ++ ++void des_encrypt2(data, ks, enc) ++DES_LONG *data; ++des_key_schedule ks; ++int enc; ++ { ++ register DES_LONG l,r,t,u; ++#ifdef DES_PTR ++ register unsigned char *des_SP=(unsigned char *)des_SPtrans; ++#endif ++#ifndef DES_UNROLL ++ register int i; ++#endif ++ register DES_LONG *s; ++ ++ r=data[0]; ++ l=data[1]; ++ ++ /* Things have been modified so that the initial rotate is ++ * done outside the loop. This required the ++ * des_SPtrans values in sp.h to be rotated 1 bit to the right. ++ * One perl script later and things have a 5% speed up on a sparc2. ++ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM> ++ * for pointing this out. */ ++ /* clear the top bits on machines with 8byte longs */ ++ r=ROTATE(r,29)&0xffffffffL; ++ l=ROTATE(l,29)&0xffffffffL; ++ ++ s=(DES_LONG *)ks; ++ /* I don't know if it is worth the effort of loop unrolling the ++ * inner loop */ ++ if (enc) ++ { ++#ifdef DES_UNROLL ++ D_ENCRYPT(l,r, 0); /* 1 */ ++ D_ENCRYPT(r,l, 2); /* 2 */ ++ D_ENCRYPT(l,r, 4); /* 3 */ ++ D_ENCRYPT(r,l, 6); /* 4 */ ++ D_ENCRYPT(l,r, 8); /* 5 */ ++ D_ENCRYPT(r,l,10); /* 6 */ ++ D_ENCRYPT(l,r,12); /* 7 */ ++ D_ENCRYPT(r,l,14); /* 8 */ ++ D_ENCRYPT(l,r,16); /* 9 */ ++ D_ENCRYPT(r,l,18); /* 10 */ ++ D_ENCRYPT(l,r,20); /* 11 */ ++ D_ENCRYPT(r,l,22); /* 12 */ ++ D_ENCRYPT(l,r,24); /* 13 */ ++ D_ENCRYPT(r,l,26); /* 14 */ ++ D_ENCRYPT(l,r,28); /* 15 */ ++ D_ENCRYPT(r,l,30); /* 16 */ ++#else ++ for (i=0; i<32; i+=8) ++ { ++ D_ENCRYPT(l,r,i+0); /* 1 */ ++ D_ENCRYPT(r,l,i+2); /* 2 */ ++ D_ENCRYPT(l,r,i+4); /* 3 */ ++ D_ENCRYPT(r,l,i+6); /* 4 */ ++ } ++#endif ++ } ++ else ++ { ++#ifdef DES_UNROLL ++ D_ENCRYPT(l,r,30); /* 16 */ ++ D_ENCRYPT(r,l,28); /* 15 */ ++ D_ENCRYPT(l,r,26); /* 14 */ ++ D_ENCRYPT(r,l,24); /* 13 */ ++ D_ENCRYPT(l,r,22); /* 12 */ ++ D_ENCRYPT(r,l,20); /* 11 */ ++ D_ENCRYPT(l,r,18); /* 10 */ ++ D_ENCRYPT(r,l,16); /* 9 */ ++ D_ENCRYPT(l,r,14); /* 8 */ ++ D_ENCRYPT(r,l,12); /* 7 */ ++ D_ENCRYPT(l,r,10); /* 6 */ ++ D_ENCRYPT(r,l, 8); /* 5 */ ++ D_ENCRYPT(l,r, 6); /* 4 */ ++ D_ENCRYPT(r,l, 4); /* 3 */ ++ D_ENCRYPT(l,r, 2); /* 2 */ ++ D_ENCRYPT(r,l, 0); /* 1 */ ++#else ++ for (i=30; i>0; i-=8) ++ { ++ D_ENCRYPT(l,r,i-0); /* 16 */ ++ D_ENCRYPT(r,l,i-2); /* 15 */ ++ D_ENCRYPT(l,r,i-4); /* 14 */ ++ D_ENCRYPT(r,l,i-6); /* 13 */ ++ } ++#endif ++ } ++ /* rotate and clear the top bits on machines with 8byte longs */ ++ data[0]=ROTATE(l,3)&0xffffffffL; ++ data[1]=ROTATE(r,3)&0xffffffffL; ++ l=r=t=u=0; ++ } ++ ++void des_encrypt3(data,ks1,ks2,ks3) ++DES_LONG *data; ++des_key_schedule ks1; ++des_key_schedule ks2; ++des_key_schedule ks3; ++ { ++ register DES_LONG l,r; ++ ++ l=data[0]; ++ r=data[1]; ++ IP(l,r); ++ data[0]=l; ++ data[1]=r; ++ des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT); ++ des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT); ++ des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT); ++ l=data[0]; ++ r=data[1]; ++ FP(r,l); ++ data[0]=l; ++ data[1]=r; ++ } ++ ++void des_decrypt3(data,ks1,ks2,ks3) ++DES_LONG *data; ++des_key_schedule ks1; ++des_key_schedule ks2; ++des_key_schedule ks3; ++ { ++ register DES_LONG l,r; ++ ++ l=data[0]; ++ r=data[1]; ++ IP(l,r); ++ data[0]=l; ++ data[1]=r; ++ des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT); ++ des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT); ++ des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT); ++ l=data[0]; ++ r=data[1]; ++ FP(r,l); ++ data[0]=l; ++ data[1]=r; ++ } ++ ++#ifndef DES_DEFAULT_OPTIONS ++ ++void des_ncbc_encrypt(input, output, length, schedule, ivec, enc) ++des_cblock (*input); ++des_cblock (*output); ++long length; ++des_key_schedule schedule; ++des_cblock (*ivec); ++int enc; ++ { ++ register DES_LONG tin0,tin1; ++ register DES_LONG tout0,tout1,xor0,xor1; ++ register unsigned char *in,*out; ++ register long l=length; ++ DES_LONG tin[2]; ++ unsigned char *iv; ++ ++ in=(unsigned char *)input; ++ out=(unsigned char *)output; ++ iv=(unsigned char *)ivec; ++ ++ if (enc) ++ { ++ c2l(iv,tout0); ++ c2l(iv,tout1); ++ for (l-=8; l>=0; l-=8) ++ { ++ c2l(in,tin0); ++ c2l(in,tin1); ++ tin0^=tout0; tin[0]=tin0; ++ tin1^=tout1; tin[1]=tin1; ++ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); ++ tout0=tin[0]; l2c(tout0,out); ++ tout1=tin[1]; l2c(tout1,out); ++ } ++ if (l != -8) ++ { ++ c2ln(in,tin0,tin1,l+8); ++ tin0^=tout0; tin[0]=tin0; ++ tin1^=tout1; tin[1]=tin1; ++ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); ++ tout0=tin[0]; l2c(tout0,out); ++ tout1=tin[1]; l2c(tout1,out); ++ } ++ iv=(unsigned char *)ivec; ++ l2c(tout0,iv); ++ l2c(tout1,iv); ++ } ++ else ++ { ++ c2l(iv,xor0); ++ c2l(iv,xor1); ++ for (l-=8; l>=0; l-=8) ++ { ++ c2l(in,tin0); tin[0]=tin0; ++ c2l(in,tin1); tin[1]=tin1; ++ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT); ++ tout0=tin[0]^xor0; ++ tout1=tin[1]^xor1; ++ l2c(tout0,out); ++ l2c(tout1,out); ++ xor0=tin0; ++ xor1=tin1; ++ } ++ if (l != -8) ++ { ++ c2l(in,tin0); tin[0]=tin0; ++ c2l(in,tin1); tin[1]=tin1; ++ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT); ++ tout0=tin[0]^xor0; ++ tout1=tin[1]^xor1; ++ l2cn(tout0,tout1,out,l+8); ++ xor0=tin0; ++ xor1=tin1; ++ } ++ ++ iv=(unsigned char *)ivec; ++ l2c(xor0,iv); ++ l2c(xor1,iv); ++ } ++ tin0=tin1=tout0=tout1=xor0=xor1=0; ++ tin[0]=tin[1]=0; ++ } ++ ++void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc) ++des_cblock (*input); ++des_cblock (*output); ++long length; ++des_key_schedule ks1; ++des_key_schedule ks2; ++des_key_schedule ks3; ++des_cblock (*ivec); ++int enc; ++ { ++ register DES_LONG tin0,tin1; ++ register DES_LONG tout0,tout1,xor0,xor1; ++ register unsigned char *in,*out; ++ register long l=length; ++ DES_LONG tin[2]; ++ unsigned char *iv; ++ ++ in=(unsigned char *)input; ++ out=(unsigned char *)output; ++ iv=(unsigned char *)ivec; ++ ++ if (enc) ++ { ++ c2l(iv,tout0); ++ c2l(iv,tout1); ++ for (l-=8; l>=0; l-=8) ++ { ++ c2l(in,tin0); ++ c2l(in,tin1); ++ tin0^=tout0; ++ tin1^=tout1; ++ ++ tin[0]=tin0; ++ tin[1]=tin1; ++ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3); ++ tout0=tin[0]; ++ tout1=tin[1]; ++ ++ l2c(tout0,out); ++ l2c(tout1,out); ++ } ++ if (l != -8) ++ { ++ c2ln(in,tin0,tin1,l+8); ++ tin0^=tout0; ++ tin1^=tout1; ++ ++ tin[0]=tin0; ++ tin[1]=tin1; ++ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3); ++ tout0=tin[0]; ++ tout1=tin[1]; ++ ++ l2c(tout0,out); ++ l2c(tout1,out); ++ } ++ iv=(unsigned char *)ivec; ++ l2c(tout0,iv); ++ l2c(tout1,iv); ++ } ++ else ++ { ++ register DES_LONG t0,t1; ++ ++ c2l(iv,xor0); ++ c2l(iv,xor1); ++ for (l-=8; l>=0; l-=8) ++ { ++ c2l(in,tin0); ++ c2l(in,tin1); ++ ++ t0=tin0; ++ t1=tin1; ++ ++ tin[0]=tin0; ++ tin[1]=tin1; ++ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3); ++ tout0=tin[0]; ++ tout1=tin[1]; ++ ++ tout0^=xor0; ++ tout1^=xor1; ++ l2c(tout0,out); ++ l2c(tout1,out); ++ xor0=t0; ++ xor1=t1; ++ } ++ if (l != -8) ++ { ++ c2l(in,tin0); ++ c2l(in,tin1); ++ ++ t0=tin0; ++ t1=tin1; ++ ++ tin[0]=tin0; ++ tin[1]=tin1; ++ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3); ++ tout0=tin[0]; ++ tout1=tin[1]; ++ ++ tout0^=xor0; ++ tout1^=xor1; ++ l2cn(tout0,tout1,out,l+8); ++ xor0=t0; ++ xor1=t1; ++ } ++ ++ iv=(unsigned char *)ivec; ++ l2c(xor0,iv); ++ l2c(xor1,iv); ++ } ++ tin0=tin1=tout0=tout1=xor0=xor1=0; ++ tin[0]=tin[1]=0; ++ } ++ ++#endif /* DES_DEFAULT_OPTIONS */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/des_locl.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,515 @@ ++/* crypto/des/des_locl.org */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ++ * ++ * Always modify des_locl.org since des_locl.h is automatically generated from ++ * it during SSLeay configuration. ++ * ++ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ++ */ ++ ++#ifndef HEADER_DES_LOCL_H ++#define HEADER_DES_LOCL_H ++ ++#if defined(WIN32) || defined(WIN16) ++#ifndef MSDOS ++#define MSDOS ++#endif ++#endif ++ ++#include "crypto/des.h" ++ ++#ifndef DES_DEFAULT_OPTIONS ++/* the following is tweaked from a config script, that is why it is a ++ * protected undef/define */ ++#ifndef DES_PTR ++#define DES_PTR ++#endif ++ ++/* This helps C compiler generate the correct code for multiple functional ++ * units. It reduces register dependancies at the expense of 2 more ++ * registers */ ++#ifndef DES_RISC1 ++#define DES_RISC1 ++#endif ++ ++#ifndef DES_RISC2 ++#undef DES_RISC2 ++#endif ++ ++#if defined(DES_RISC1) && defined(DES_RISC2) ++YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! ++#endif ++ ++/* Unroll the inner loop, this sometimes helps, sometimes hinders. ++ * Very mucy CPU dependant */ ++#ifndef DES_UNROLL ++#define DES_UNROLL ++#endif ++ ++/* These default values were supplied by ++ * Peter Gutman ++ * They are only used if nothing else has been defined */ ++#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) ++/* Special defines which change the way the code is built depending on the ++ CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find ++ even newer MIPS CPU's, but at the moment one size fits all for ++ optimization options. Older Sparc's work better with only UNROLL, but ++ there's no way to tell at compile time what it is you're running on */ ++ ++#if defined( sun ) /* Newer Sparc's */ ++ #define DES_PTR ++ #define DES_RISC1 ++ #define DES_UNROLL ++#elif defined( __ultrix ) /* Older MIPS */ ++ #define DES_PTR ++ #define DES_RISC2 ++ #define DES_UNROLL ++#elif defined( __osf1__ ) /* Alpha */ ++ #define DES_PTR ++ #define DES_RISC2 ++#elif defined ( _AIX ) /* RS6000 */ ++ /* Unknown */ ++#elif defined( __hpux ) /* HP-PA */ ++ /* Unknown */ ++#elif defined( __aux ) /* 68K */ ++ /* Unknown */ ++#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ ++ #define DES_UNROLL ++#elif defined( __sgi ) /* Newer MIPS */ ++ #define DES_PTR ++ #define DES_RISC2 ++ #define DES_UNROLL ++#elif defined( i386 ) /* x86 boxes, should be gcc */ ++ #define DES_PTR ++ #define DES_RISC1 ++ #define DES_UNROLL ++#endif /* Systems-specific speed defines */ ++#endif ++ ++#endif /* DES_DEFAULT_OPTIONS */ ++ ++#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */ ++#include ++#include ++#include ++#include ++#ifndef RAND ++#define RAND ++#endif ++#undef NOPROTO ++#endif ++ ++#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS) ++#ifndef __KERNEL__ ++#include ++#else ++#include ++#endif ++#endif ++ ++#ifndef RAND ++#define RAND ++#endif ++ ++#ifdef linux ++#undef RAND ++#endif ++ ++#ifdef MSDOS ++#define getpid() 2 ++#define RAND ++#undef NOPROTO ++#endif ++ ++#if defined(NOCONST) ++#define const ++#endif ++ ++#ifdef __STDC__ ++#undef NOPROTO ++#endif ++ ++#ifdef RAND ++#define srandom(s) srand(s) ++#define random rand ++#endif ++ ++#define ITERATIONS 16 ++#define HALF_ITERATIONS 8 ++ ++/* used in des_read and des_write */ ++#define MAXWRITE (1024*16) ++#define BSIZE (MAXWRITE+4) ++ ++#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ ++ l|=((DES_LONG)(*((c)++)))<< 8L, \ ++ l|=((DES_LONG)(*((c)++)))<<16L, \ ++ l|=((DES_LONG)(*((c)++)))<<24L) ++ ++/* NOTE - c is not incremented as per c2l */ ++#define c2ln(c,l1,l2,n) { \ ++ c+=n; \ ++ l1=l2=0; \ ++ switch (n) { \ ++ case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ ++ case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ ++ case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ ++ case 5: l2|=((DES_LONG)(*(--(c)))); \ ++ case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ ++ case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ ++ case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ ++ case 1: l1|=((DES_LONG)(*(--(c)))); \ ++ } \ ++ } ++ ++#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ ++ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>>24L)&0xff)) ++ ++/* replacements for htonl and ntohl since I have no idea what to do ++ * when faced with machines with 8 byte longs. */ ++#define HDRSIZE 4 ++ ++#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \ ++ l|=((DES_LONG)(*((c)++)))<<16L, \ ++ l|=((DES_LONG)(*((c)++)))<< 8L, \ ++ l|=((DES_LONG)(*((c)++)))) ++ ++#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ ++ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ ++ *((c)++)=(unsigned char)(((l) )&0xff)) ++ ++/* NOTE - c is not incremented as per l2c */ ++#define l2cn(l1,l2,c,n) { \ ++ c+=n; \ ++ switch (n) { \ ++ case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ ++ case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ ++ case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ ++ case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ ++ case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ ++ case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ ++ case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ ++ case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ ++ } \ ++ } ++ ++#if defined(WIN32) ++#define ROTATE(a,n) (_lrotr(a,n)) ++#else ++#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n)))) ++#endif ++ ++/* Don't worry about the LOAD_DATA() stuff, that is used by ++ * fcrypt() to add it's little bit to the front */ ++ ++#ifdef DES_FCRYPT ++ ++#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \ ++ { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); } ++ ++#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ ++ t=R^(R>>16L); \ ++ u=t&E0; t&=E1; \ ++ tmp=(u<<16); u^=R^s[S ]; u^=tmp; \ ++ tmp=(t<<16); t^=R^s[S+1]; t^=tmp ++#else ++#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g) ++#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ ++ u=R^s[S ]; \ ++ t=R^s[S+1] ++#endif ++ ++/* The changes to this macro may help or hinder, depending on the ++ * compiler and the achitecture. gcc2 always seems to do well :-). ++ * Inspired by Dana How ++ * DO NOT use the alternative version on machines with 8 byte longs. ++ * It does not seem to work on the Alpha, even when DES_LONG is 4 ++ * bytes, probably an issue of accessing non-word aligned objects :-( */ ++#ifdef DES_PTR ++ ++/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there ++ * is no reason to not xor all the sub items together. This potentially ++ * saves a register since things can be xored directly into L */ ++ ++#if defined(DES_RISC1) || defined(DES_RISC2) ++#ifdef DES_RISC1 ++#define D_ENCRYPT(LL,R,S) { \ ++ unsigned int u1,u2,u3; \ ++ LOAD_DATA(R,S,u,t,E0,E1,u1); \ ++ u2=(int)u>>8L; \ ++ u1=(int)u&0xfc; \ ++ u2&=0xfc; \ ++ t=ROTATE(t,4); \ ++ u>>=16L; \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \ ++ u3=(int)(u>>8L); \ ++ u1=(int)u&0xfc; \ ++ u3&=0xfc; \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \ ++ u2=(int)t>>8L; \ ++ u1=(int)t&0xfc; \ ++ u2&=0xfc; \ ++ t>>=16L; \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \ ++ u3=(int)t>>8L; \ ++ u1=(int)t&0xfc; \ ++ u3&=0xfc; \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); } ++#endif ++#ifdef DES_RISC2 ++#define D_ENCRYPT(LL,R,S) { \ ++ unsigned int u1,u2,s1,s2; \ ++ LOAD_DATA(R,S,u,t,E0,E1,u1); \ ++ u2=(int)u>>8L; \ ++ u1=(int)u&0xfc; \ ++ u2&=0xfc; \ ++ t=ROTATE(t,4); \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \ ++ s1=(int)(u>>16L); \ ++ s2=(int)(u>>24L); \ ++ s1&=0xfc; \ ++ s2&=0xfc; \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \ ++ u2=(int)t>>8L; \ ++ u1=(int)t&0xfc; \ ++ u2&=0xfc; \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \ ++ s1=(int)(t>>16L); \ ++ s2=(int)(t>>24L); \ ++ s1&=0xfc; \ ++ s2&=0xfc; \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \ ++ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); } ++#endif ++#else ++#define D_ENCRYPT(LL,R,S) { \ ++ LOAD_DATA_tmp(R,S,u,t,E0,E1); \ ++ t=ROTATE(t,4); \ ++ LL^= \ ++ *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \ ++ *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \ ++ *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \ ++ *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \ ++ *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \ ++ *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \ ++ *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \ ++ *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); } ++#endif ++ ++#else /* original version */ ++ ++#if defined(DES_RISC1) || defined(DES_RISC2) ++#ifdef DES_RISC1 ++#define D_ENCRYPT(LL,R,S) {\ ++ unsigned int u1,u2,u3; \ ++ LOAD_DATA(R,S,u,t,E0,E1,u1); \ ++ u>>=2L; \ ++ t=ROTATE(t,6); \ ++ u2=(int)u>>8L; \ ++ u1=(int)u&0x3f; \ ++ u2&=0x3f; \ ++ u>>=16L; \ ++ LL^=des_SPtrans[0][u1]; \ ++ LL^=des_SPtrans[2][u2]; \ ++ u3=(int)u>>8L; \ ++ u1=(int)u&0x3f; \ ++ u3&=0x3f; \ ++ LL^=des_SPtrans[4][u1]; \ ++ LL^=des_SPtrans[6][u3]; \ ++ u2=(int)t>>8L; \ ++ u1=(int)t&0x3f; \ ++ u2&=0x3f; \ ++ t>>=16L; \ ++ LL^=des_SPtrans[1][u1]; \ ++ LL^=des_SPtrans[3][u2]; \ ++ u3=(int)t>>8L; \ ++ u1=(int)t&0x3f; \ ++ u3&=0x3f; \ ++ LL^=des_SPtrans[5][u1]; \ ++ LL^=des_SPtrans[7][u3]; } ++#endif ++#ifdef DES_RISC2 ++#define D_ENCRYPT(LL,R,S) {\ ++ unsigned int u1,u2,s1,s2; \ ++ LOAD_DATA(R,S,u,t,E0,E1,u1); \ ++ u>>=2L; \ ++ t=ROTATE(t,6); \ ++ u2=(int)u>>8L; \ ++ u1=(int)u&0x3f; \ ++ u2&=0x3f; \ ++ LL^=des_SPtrans[0][u1]; \ ++ LL^=des_SPtrans[2][u2]; \ ++ s1=(int)u>>16L; \ ++ s2=(int)u>>24L; \ ++ s1&=0x3f; \ ++ s2&=0x3f; \ ++ LL^=des_SPtrans[4][s1]; \ ++ LL^=des_SPtrans[6][s2]; \ ++ u2=(int)t>>8L; \ ++ u1=(int)t&0x3f; \ ++ u2&=0x3f; \ ++ LL^=des_SPtrans[1][u1]; \ ++ LL^=des_SPtrans[3][u2]; \ ++ s1=(int)t>>16; \ ++ s2=(int)t>>24L; \ ++ s1&=0x3f; \ ++ s2&=0x3f; \ ++ LL^=des_SPtrans[5][s1]; \ ++ LL^=des_SPtrans[7][s2]; } ++#endif ++ ++#else ++ ++#define D_ENCRYPT(LL,R,S) {\ ++ LOAD_DATA_tmp(R,S,u,t,E0,E1); \ ++ t=ROTATE(t,4); \ ++ LL^=\ ++ des_SPtrans[0][(u>> 2L)&0x3f]^ \ ++ des_SPtrans[2][(u>>10L)&0x3f]^ \ ++ des_SPtrans[4][(u>>18L)&0x3f]^ \ ++ des_SPtrans[6][(u>>26L)&0x3f]^ \ ++ des_SPtrans[1][(t>> 2L)&0x3f]^ \ ++ des_SPtrans[3][(t>>10L)&0x3f]^ \ ++ des_SPtrans[5][(t>>18L)&0x3f]^ \ ++ des_SPtrans[7][(t>>26L)&0x3f]; } ++#endif ++#endif ++ ++ /* IP and FP ++ * The problem is more of a geometric problem that random bit fiddling. ++ 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 ++ 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 ++ 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 ++ 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 ++ ++ 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 ++ 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 ++ 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 ++ 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 ++ ++ The output has been subject to swaps of the form ++ 0 1 -> 3 1 but the odd and even bits have been put into ++ 2 3 2 0 ++ different words. The main trick is to remember that ++ t=((l>>size)^r)&(mask); ++ r^=t; ++ l^=(t<>(n))^(b))&(m)),\ ++ (b)^=(t),\ ++ (a)^=((t)<<(n))) ++ ++#define IP(l,r) \ ++ { \ ++ register DES_LONG tt; \ ++ PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ ++ PERM_OP(l,r,tt,16,0x0000ffffL); \ ++ PERM_OP(r,l,tt, 2,0x33333333L); \ ++ PERM_OP(l,r,tt, 8,0x00ff00ffL); \ ++ PERM_OP(r,l,tt, 1,0x55555555L); \ ++ } ++ ++#define FP(l,r) \ ++ { \ ++ register DES_LONG tt; \ ++ PERM_OP(l,r,tt, 1,0x55555555L); \ ++ PERM_OP(r,l,tt, 8,0x00ff00ffL); \ ++ PERM_OP(l,r,tt, 2,0x33333333L); \ ++ PERM_OP(r,l,tt,16,0x0000ffffL); \ ++ PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ ++ } ++ ++extern const DES_LONG des_SPtrans[8][64]; ++ ++#ifndef NOPROTO ++void fcrypt_body(DES_LONG *out,des_key_schedule ks, ++ DES_LONG Eswap0, DES_LONG Eswap1); ++#else ++void fcrypt_body(); ++#endif ++ ++#endif +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/des_opts.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,620 @@ ++/* crypto/des/des_opts.c */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++/* define PART1, PART2, PART3 or PART4 to build only with a few of the options. ++ * This is for machines with 64k code segment size restrictions. */ ++ ++#ifndef MSDOS ++#define TIMES ++#endif ++ ++#include ++#ifndef MSDOS ++#include ++#else ++#include ++extern void exit(); ++#endif ++#include ++#ifndef VMS ++#ifndef _IRIX ++#include ++#endif ++#ifdef TIMES ++#include ++#include ++#endif ++#else /* VMS */ ++#include ++struct tms { ++ time_t tms_utime; ++ time_t tms_stime; ++ time_t tms_uchild; /* I dunno... */ ++ time_t tms_uchildsys; /* so these names are a guess :-) */ ++ } ++#endif ++#ifndef TIMES ++#include ++#endif ++ ++#ifdef sun ++#include ++#include ++#endif ++ ++#include "des_locl.h" ++#include "spr.h" ++ ++#define DES_DEFAULT_OPTIONS ++ ++#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4) ++#define PART1 ++#define PART2 ++#define PART3 ++#define PART4 ++#endif ++ ++#ifdef PART1 ++ ++#undef DES_UNROLL ++#undef DES_RISC1 ++#undef DES_RISC2 ++#undef DES_PTR ++#undef D_ENCRYPT ++#define des_encrypt des_encrypt_u4_cisc_idx ++#define des_encrypt2 des_encrypt2_u4_cisc_idx ++#define des_encrypt3 des_encrypt3_u4_cisc_idx ++#define des_decrypt3 des_decrypt3_u4_cisc_idx ++#undef HEADER_DES_LOCL_H ++#include "des_enc.c" ++ ++#define DES_UNROLL ++#undef DES_RISC1 ++#undef DES_RISC2 ++#undef DES_PTR ++#undef D_ENCRYPT ++#undef des_encrypt ++#undef des_encrypt2 ++#undef des_encrypt3 ++#undef des_decrypt3 ++#define des_encrypt des_encrypt_u16_cisc_idx ++#define des_encrypt2 des_encrypt2_u16_cisc_idx ++#define des_encrypt3 des_encrypt3_u16_cisc_idx ++#define des_decrypt3 des_decrypt3_u16_cisc_idx ++#undef HEADER_DES_LOCL_H ++#include "des_enc.c" ++ ++#undef DES_UNROLL ++#define DES_RISC1 ++#undef DES_RISC2 ++#undef DES_PTR ++#undef D_ENCRYPT ++#undef des_encrypt ++#undef des_encrypt2 ++#undef des_encrypt3 ++#undef des_decrypt3 ++#define des_encrypt des_encrypt_u4_risc1_idx ++#define des_encrypt2 des_encrypt2_u4_risc1_idx ++#define des_encrypt3 des_encrypt3_u4_risc1_idx ++#define des_decrypt3 des_decrypt3_u4_risc1_idx ++#undef HEADER_DES_LOCL_H ++#include "des_enc.c" ++ ++#endif ++ ++#ifdef PART2 ++ ++#undef DES_UNROLL ++#undef DES_RISC1 ++#define DES_RISC2 ++#undef DES_PTR ++#undef D_ENCRYPT ++#undef des_encrypt ++#undef des_encrypt2 ++#undef des_encrypt3 ++#undef des_decrypt3 ++#define des_encrypt des_encrypt_u4_risc2_idx ++#define des_encrypt2 des_encrypt2_u4_risc2_idx ++#define des_encrypt3 des_encrypt3_u4_risc2_idx ++#define des_decrypt3 des_decrypt3_u4_risc2_idx ++#undef HEADER_DES_LOCL_H ++#include "des_enc.c" ++ ++#define DES_UNROLL ++#define DES_RISC1 ++#undef DES_RISC2 ++#undef DES_PTR ++#undef D_ENCRYPT ++#undef des_encrypt ++#undef des_encrypt2 ++#undef des_encrypt3 ++#undef des_decrypt3 ++#define des_encrypt des_encrypt_u16_risc1_idx ++#define des_encrypt2 des_encrypt2_u16_risc1_idx ++#define des_encrypt3 des_encrypt3_u16_risc1_idx ++#define des_decrypt3 des_decrypt3_u16_risc1_idx ++#undef HEADER_DES_LOCL_H ++#include "des_enc.c" ++ ++#define DES_UNROLL ++#undef DES_RISC1 ++#define DES_RISC2 ++#undef DES_PTR ++#undef D_ENCRYPT ++#undef des_encrypt ++#undef des_encrypt2 ++#undef des_encrypt3 ++#undef des_decrypt3 ++#define des_encrypt des_encrypt_u16_risc2_idx ++#define des_encrypt2 des_encrypt2_u16_risc2_idx ++#define des_encrypt3 des_encrypt3_u16_risc2_idx ++#define des_decrypt3 des_decrypt3_u16_risc2_idx ++#undef HEADER_DES_LOCL_H ++#include "des_enc.c" ++ ++#endif ++ ++#ifdef PART3 ++ ++#undef DES_UNROLL ++#undef DES_RISC1 ++#undef DES_RISC2 ++#define DES_PTR ++#undef D_ENCRYPT ++#undef des_encrypt ++#undef des_encrypt2 ++#undef des_encrypt3 ++#undef des_decrypt3 ++#define des_encrypt des_encrypt_u4_cisc_ptr ++#define des_encrypt2 des_encrypt2_u4_cisc_ptr ++#define des_encrypt3 des_encrypt3_u4_cisc_ptr ++#define des_decrypt3 des_decrypt3_u4_cisc_ptr ++#undef HEADER_DES_LOCL_H ++#include "des_enc.c" ++ ++#define DES_UNROLL ++#undef DES_RISC1 ++#undef DES_RISC2 ++#define DES_PTR ++#undef D_ENCRYPT ++#undef des_encrypt ++#undef des_encrypt2 ++#undef des_encrypt3 ++#undef des_decrypt3 ++#define des_encrypt des_encrypt_u16_cisc_ptr ++#define des_encrypt2 des_encrypt2_u16_cisc_ptr ++#define des_encrypt3 des_encrypt3_u16_cisc_ptr ++#define des_decrypt3 des_decrypt3_u16_cisc_ptr ++#undef HEADER_DES_LOCL_H ++#include "des_enc.c" ++ ++#undef DES_UNROLL ++#define DES_RISC1 ++#undef DES_RISC2 ++#define DES_PTR ++#undef D_ENCRYPT ++#undef des_encrypt ++#undef des_encrypt2 ++#undef des_encrypt3 ++#undef des_decrypt3 ++#define des_encrypt des_encrypt_u4_risc1_ptr ++#define des_encrypt2 des_encrypt2_u4_risc1_ptr ++#define des_encrypt3 des_encrypt3_u4_risc1_ptr ++#define des_decrypt3 des_decrypt3_u4_risc1_ptr ++#undef HEADER_DES_LOCL_H ++#include "des_enc.c" ++ ++#endif ++ ++#ifdef PART4 ++ ++#undef DES_UNROLL ++#undef DES_RISC1 ++#define DES_RISC2 ++#define DES_PTR ++#undef D_ENCRYPT ++#undef des_encrypt ++#undef des_encrypt2 ++#undef des_encrypt3 ++#undef des_decrypt3 ++#define des_encrypt des_encrypt_u4_risc2_ptr ++#define des_encrypt2 des_encrypt2_u4_risc2_ptr ++#define des_encrypt3 des_encrypt3_u4_risc2_ptr ++#define des_decrypt3 des_decrypt3_u4_risc2_ptr ++#undef HEADER_DES_LOCL_H ++#include "des_enc.c" ++ ++#define DES_UNROLL ++#define DES_RISC1 ++#undef DES_RISC2 ++#define DES_PTR ++#undef D_ENCRYPT ++#undef des_encrypt ++#undef des_encrypt2 ++#undef des_encrypt3 ++#undef des_decrypt3 ++#define des_encrypt des_encrypt_u16_risc1_ptr ++#define des_encrypt2 des_encrypt2_u16_risc1_ptr ++#define des_encrypt3 des_encrypt3_u16_risc1_ptr ++#define des_decrypt3 des_decrypt3_u16_risc1_ptr ++#undef HEADER_DES_LOCL_H ++#include "des_enc.c" ++ ++#define DES_UNROLL ++#undef DES_RISC1 ++#define DES_RISC2 ++#define DES_PTR ++#undef D_ENCRYPT ++#undef des_encrypt ++#undef des_encrypt2 ++#undef des_encrypt3 ++#undef des_decrypt3 ++#define des_encrypt des_encrypt_u16_risc2_ptr ++#define des_encrypt2 des_encrypt2_u16_risc2_ptr ++#define des_encrypt3 des_encrypt3_u16_risc2_ptr ++#define des_decrypt3 des_decrypt3_u16_risc2_ptr ++#undef HEADER_DES_LOCL_H ++#include "des_enc.c" ++ ++#endif ++ ++/* The following if from times(3) man page. It may need to be changed */ ++#ifndef HZ ++# ifndef CLK_TCK ++# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */ ++# ifndef VMS ++# define HZ 100.0 ++# else /* VMS */ ++# define HZ 100.0 ++# endif ++# else /* _BSD_CLK_TCK_ */ ++# define HZ ((double)_BSD_CLK_TCK_) ++# endif ++# else /* CLK_TCK */ ++# define HZ ((double)CLK_TCK) ++# endif ++#endif ++ ++#define BUFSIZE ((long)1024) ++long run=0; ++ ++#ifndef NOPROTO ++double Time_F(int s); ++#else ++double Time_F(); ++#endif ++ ++#ifdef SIGALRM ++#if defined(__STDC__) || defined(sgi) ++#define SIGRETTYPE void ++#else ++#define SIGRETTYPE int ++#endif ++ ++#ifndef NOPROTO ++SIGRETTYPE sig_done(int sig); ++#else ++SIGRETTYPE sig_done(); ++#endif ++ ++SIGRETTYPE sig_done(sig) ++int sig; ++ { ++ signal(SIGALRM,sig_done); ++ run=0; ++#ifdef LINT ++ sig=sig; ++#endif ++ } ++#endif ++ ++#define START 0 ++#define STOP 1 ++ ++double Time_F(s) ++int s; ++ { ++ double ret; ++#ifdef TIMES ++ static struct tms tstart,tend; ++ ++ if (s == START) ++ { ++ times(&tstart); ++ return(0); ++ } ++ else ++ { ++ times(&tend); ++ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ; ++ return((ret == 0.0)?1e-6:ret); ++ } ++#else /* !times() */ ++ static struct timeb tstart,tend; ++ long i; ++ ++ if (s == START) ++ { ++ ftime(&tstart); ++ return(0); ++ } ++ else ++ { ++ ftime(&tend); ++ i=(long)tend.millitm-(long)tstart.millitm; ++ ret=((double)(tend.time-tstart.time))+((double)i)/1000.0; ++ return((ret == 0.0)?1e-6:ret); ++ } ++#endif ++ } ++ ++#ifdef SIGALRM ++#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10); ++#else ++#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb); ++#endif ++ ++#define time_it(func,name,index) \ ++ print_name(name); \ ++ Time_F(START); \ ++ for (count=0,run=1; COND(cb); count++) \ ++ { \ ++ unsigned long d[2]; \ ++ func(d,&(sch[0]),DES_ENCRYPT); \ ++ } \ ++ tm[index]=Time_F(STOP); \ ++ fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \ ++ tm[index]=((double)COUNT(cb))/tm[index]; ++ ++#define print_it(name,index) \ ++ fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \ ++ tm[index]*8,1.0e6/tm[index]); ++ ++int main(argc,argv) ++int argc; ++char **argv; ++ { ++ long count; ++ static unsigned char buf[BUFSIZE]; ++ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}; ++ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12}; ++ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34}; ++ des_key_schedule sch,sch2,sch3; ++ double d,tm[16],max=0; ++ int rank[16]; ++ char *str[16]; ++ int max_idx=0,i,num=0,j; ++#ifndef SIGALARM ++ long ca,cb,cc,cd,ce; ++#endif ++ ++ for (i=0; i<12; i++) ++ { ++ tm[i]=0.0; ++ rank[i]=0; ++ } ++ ++#ifndef TIMES ++ fprintf(stderr,"To get the most acurate results, try to run this\n"); ++ fprintf(stderr,"program when this computer is idle.\n"); ++#endif ++ ++ des_set_key((C_Block *)key,sch); ++ des_set_key((C_Block *)key2,sch2); ++ des_set_key((C_Block *)key3,sch3); ++ ++#ifndef SIGALRM ++ fprintf(stderr,"First we calculate the approximate speed ...\n"); ++ des_set_key((C_Block *)key,sch); ++ count=10; ++ do { ++ long i; ++ unsigned long data[2]; ++ ++ count*=2; ++ Time_F(START); ++ for (i=count; i; i--) ++ des_encrypt(data,&(sch[0]),DES_ENCRYPT); ++ d=Time_F(STOP); ++ } while (d < 3.0); ++ ca=count; ++ cb=count*3; ++ cc=count*3*8/BUFSIZE+1; ++ cd=count*8/BUFSIZE+1; ++ ++ ce=count/20+1; ++#define COND(d) (count != (d)) ++#define COUNT(d) (d) ++#else ++#define COND(c) (run) ++#define COUNT(d) (count) ++ signal(SIGALRM,sig_done); ++ alarm(10); ++#endif ++ ++#ifdef PART1 ++ time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0); ++ time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1); ++ time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2); ++ num+=3; ++#endif ++#ifdef PART2 ++ time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3); ++ time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4); ++ time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5); ++ num+=3; ++#endif ++#ifdef PART3 ++ time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6); ++ time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7); ++ time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8); ++ num+=3; ++#endif ++#ifdef PART4 ++ time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9); ++ time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10); ++ time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11); ++ num+=3; ++#endif ++ ++#ifdef PART1 ++ str[0]=" 4 c i"; ++ print_it("des_encrypt_u4_cisc_idx ",0); ++ max=tm[0]; ++ max_idx=0; ++ str[1]="16 c i"; ++ print_it("des_encrypt_u16_cisc_idx ",1); ++ if (max < tm[1]) { max=tm[1]; max_idx=1; } ++ str[2]=" 4 r1 i"; ++ print_it("des_encrypt_u4_risc1_idx ",2); ++ if (max < tm[2]) { max=tm[2]; max_idx=2; } ++#endif ++#ifdef PART2 ++ str[3]="16 r1 i"; ++ print_it("des_encrypt_u16_risc1_idx",3); ++ if (max < tm[3]) { max=tm[3]; max_idx=3; } ++ str[4]=" 4 r2 i"; ++ print_it("des_encrypt_u4_risc2_idx ",4); ++ if (max < tm[4]) { max=tm[4]; max_idx=4; } ++ str[5]="16 r2 i"; ++ print_it("des_encrypt_u16_risc2_idx",5); ++ if (max < tm[5]) { max=tm[5]; max_idx=5; } ++#endif ++#ifdef PART3 ++ str[6]=" 4 c p"; ++ print_it("des_encrypt_u4_cisc_ptr ",6); ++ if (max < tm[6]) { max=tm[6]; max_idx=6; } ++ str[7]="16 c p"; ++ print_it("des_encrypt_u16_cisc_ptr ",7); ++ if (max < tm[7]) { max=tm[7]; max_idx=7; } ++ str[8]=" 4 r1 p"; ++ print_it("des_encrypt_u4_risc1_ptr ",8); ++ if (max < tm[8]) { max=tm[8]; max_idx=8; } ++#endif ++#ifdef PART4 ++ str[9]="16 r1 p"; ++ print_it("des_encrypt_u16_risc1_ptr",9); ++ if (max < tm[9]) { max=tm[9]; max_idx=9; } ++ str[10]=" 4 r2 p"; ++ print_it("des_encrypt_u4_risc2_ptr ",10); ++ if (max < tm[10]) { max=tm[10]; max_idx=10; } ++ str[11]="16 r2 p"; ++ print_it("des_encrypt_u16_risc2_ptr",11); ++ if (max < tm[11]) { max=tm[11]; max_idx=11; } ++#endif ++ printf("options des ecb/s\n"); ++ printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]); ++ d=tm[max_idx]; ++ tm[max_idx]= -2.0; ++ max= -1.0; ++ for (;;) ++ { ++ for (i=0; i<12; i++) ++ { ++ if (max < tm[i]) { max=tm[i]; j=i; } ++ } ++ if (max < 0.0) break; ++ printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0); ++ tm[j]= -2.0; ++ max= -1.0; ++ } ++ ++ switch (max_idx) ++ { ++ case 0: ++ printf("-DDES_DEFAULT_OPTIONS\n"); ++ break; ++ case 1: ++ printf("-DDES_UNROLL\n"); ++ break; ++ case 2: ++ printf("-DDES_RISC1\n"); ++ break; ++ case 3: ++ printf("-DDES_UNROLL -DDES_RISC1\n"); ++ break; ++ case 4: ++ printf("-DDES_RISC2\n"); ++ break; ++ case 5: ++ printf("-DDES_UNROLL -DDES_RISC2\n"); ++ break; ++ case 6: ++ printf("-DDES_PTR\n"); ++ break; ++ case 7: ++ printf("-DDES_UNROLL -DDES_PTR\n"); ++ break; ++ case 8: ++ printf("-DDES_RISC1 -DDES_PTR\n"); ++ break; ++ case 9: ++ printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n"); ++ break; ++ case 10: ++ printf("-DDES_RISC2 -DDES_PTR\n"); ++ break; ++ case 11: ++ printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n"); ++ break; ++ } ++ exit(0); ++#if defined(LINT) || defined(MSDOS) ++ return(0); ++#endif ++ } +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/des_ver.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,60 @@ ++/* crypto/des/des_ver.h */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++extern char *DES_version; /* SSLeay version string */ ++extern char *libdes_version; /* old libdes version string */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/destest.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,871 @@ ++/* crypto/des/destest.c */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++#if defined(WIN32) || defined(WIN16) || defined(WINDOWS) ++#ifndef MSDOS ++#define MSDOS ++#endif ++#endif ++ ++#include ++#include ++#ifndef MSDOS ++#include ++#else ++#include ++#endif ++#include ++#include "des_locl.h" ++ ++/* tisk tisk - the test keys don't all have odd parity :-( */ ++/* test data */ ++#define NUM_TESTS 34 ++static unsigned char key_data[NUM_TESTS][8]={ ++ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, ++ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, ++ {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, ++ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, ++ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, ++ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, ++ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, ++ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}, ++ {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57}, ++ {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E}, ++ {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86}, ++ {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E}, ++ {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6}, ++ {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE}, ++ {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6}, ++ {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE}, ++ {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16}, ++ {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F}, ++ {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46}, ++ {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E}, ++ {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76}, ++ {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07}, ++ {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F}, ++ {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7}, ++ {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF}, ++ {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6}, ++ {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF}, ++ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, ++ {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E}, ++ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, ++ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, ++ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, ++ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, ++ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}}; ++ ++static unsigned char plain_data[NUM_TESTS][8]={ ++ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, ++ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, ++ {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, ++ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, ++ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, ++ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, ++ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, ++ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, ++ {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42}, ++ {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA}, ++ {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72}, ++ {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A}, ++ {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2}, ++ {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A}, ++ {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2}, ++ {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A}, ++ {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02}, ++ {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A}, ++ {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32}, ++ {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA}, ++ {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62}, ++ {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2}, ++ {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA}, ++ {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92}, ++ {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A}, ++ {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2}, ++ {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A}, ++ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, ++ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, ++ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, ++ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, ++ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, ++ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, ++ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}; ++ ++static unsigned char cipher_data[NUM_TESTS][8]={ ++ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, ++ {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58}, ++ {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B}, ++ {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33}, ++ {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D}, ++ {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD}, ++ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, ++ {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4}, ++ {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B}, ++ {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71}, ++ {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A}, ++ {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A}, ++ {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95}, ++ {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B}, ++ {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09}, ++ {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A}, ++ {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F}, ++ {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88}, ++ {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77}, ++ {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A}, ++ {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56}, ++ {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56}, ++ {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56}, ++ {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC}, ++ {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A}, ++ {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41}, ++ {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93}, ++ {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00}, ++ {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06}, ++ {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7}, ++ {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51}, ++ {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE}, ++ {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D}, ++ {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}}; ++ ++static unsigned char cipher_ecb2[NUM_TESTS-1][8]={ ++ {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E}, ++ {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16}, ++ {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27}, ++ {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6}, ++ {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25}, ++ {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A}, ++ {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74}, ++ {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6}, ++ {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67}, ++ {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10}, ++ {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85}, ++ {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA}, ++ {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3}, ++ {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3}, ++ {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A}, ++ {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69}, ++ {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1}, ++ {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7}, ++ {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F}, ++ {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87}, ++ {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A}, ++ {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE}, ++ {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3}, ++ {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD}, ++ {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84}, ++ {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85}, ++ {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC}, ++ {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89}, ++ {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E}, ++ {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89}, ++ {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7}, ++ {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8}, ++ {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}}; ++ ++static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; ++static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87}; ++static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; ++static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; ++static char cbc_data[40]="7654321 Now is the time for \0001"; ++ ++static unsigned char cbc_ok[32]={ ++ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, ++ 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb, ++ 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68, ++ 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; ++ ++static unsigned char xcbc_ok[32]={ ++ 0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48, ++ 0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD, ++ 0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76, ++ 0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2, ++ }; ++ ++static unsigned char cbc3_ok[32]={ ++ 0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0, ++ 0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC, ++ 0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4, ++ 0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75}; ++ ++static unsigned char pcbc_ok[32]={ ++ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, ++ 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15, ++ 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f, ++ 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88}; ++ ++static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; ++static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; ++static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8]; ++static unsigned char plain[24]= ++ { ++ 0x4e,0x6f,0x77,0x20,0x69,0x73, ++ 0x20,0x74,0x68,0x65,0x20,0x74, ++ 0x69,0x6d,0x65,0x20,0x66,0x6f, ++ 0x72,0x20,0x61,0x6c,0x6c,0x20 ++ }; ++static unsigned char cfb_cipher8[24]= { ++ 0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8, ++ 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 }; ++static unsigned char cfb_cipher16[24]={ ++ 0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70, ++ 0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B }; ++static unsigned char cfb_cipher32[24]={ ++ 0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD, ++ 0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 }; ++static unsigned char cfb_cipher48[24]={ ++ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85, ++ 0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F }; ++static unsigned char cfb_cipher64[24]={ ++ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B, ++ 0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 }; ++ ++static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; ++static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; ++static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8]; ++static unsigned char ofb_cipher[24]= ++ { ++ 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51, ++ 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f, ++ 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3 ++ }; ++ ++DES_LONG cbc_cksum_ret=0xB462FEF7L; ++unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; ++ ++#ifndef NOPROTO ++static char *pt(unsigned char *p); ++static int cfb_test(int bits, unsigned char *cfb_cipher); ++static int cfb64_test(unsigned char *cfb_cipher); ++static int ede_cfb64_test(unsigned char *cfb_cipher); ++#else ++static char *pt(); ++static int cfb_test(); ++static int cfb64_test(); ++static int ede_cfb64_test(); ++#endif ++ ++int main(argc,argv) ++int argc; ++char *argv[]; ++ { ++ int i,j,err=0; ++ des_cblock in,out,outin,iv3; ++ des_key_schedule ks,ks2,ks3; ++ unsigned char cbc_in[40]; ++ unsigned char cbc_out[40]; ++ DES_LONG cs; ++ unsigned char qret[4][4],cret[8]; ++ DES_LONG lqret[4]; ++ int num; ++ char *str; ++ ++ printf("Doing ecb\n"); ++ for (i=0; i>4)&0xf]; ++ ret[i*2+1]=f[p[i]&0xf]; ++ } ++ ret[16]='\0'; ++ return(ret); ++ } ++ ++#ifndef LIBDES_LIT ++ ++static int cfb_test(bits, cfb_cipher) ++int bits; ++unsigned char *cfb_cipher; ++ { ++ des_key_schedule ks; ++ int i,err=0; ++ ++ des_key_sched((C_Block *)cfb_key,ks); ++ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); ++ des_cfb_encrypt(plain,cfb_buf1,bits,(long)sizeof(plain),ks, ++ (C_Block *)cfb_tmp,DES_ENCRYPT); ++ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) ++ { ++ err=1; ++ printf("cfb_encrypt encrypt error\n"); ++ for (i=0; i<24; i+=8) ++ printf("%s\n",pt(&(cfb_buf1[i]))); ++ } ++ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); ++ des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,(long)sizeof(plain),ks, ++ (C_Block *)cfb_tmp,DES_DECRYPT); ++ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) ++ { ++ err=1; ++ printf("cfb_encrypt decrypt error\n"); ++ for (i=0; i<24; i+=8) ++ printf("%s\n",pt(&(cfb_buf1[i]))); ++ } ++ return(err); ++ } ++ ++static int cfb64_test(cfb_cipher) ++unsigned char *cfb_cipher; ++ { ++ des_key_schedule ks; ++ int err=0,i,n; ++ ++ des_key_sched((C_Block *)cfb_key,ks); ++ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); ++ n=0; ++ des_cfb64_encrypt(plain,cfb_buf1,(long)12,ks, ++ (C_Block *)cfb_tmp,&n,DES_ENCRYPT); ++ des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]), ++ (long)sizeof(plain)-12,ks, ++ (C_Block *)cfb_tmp,&n,DES_ENCRYPT); ++ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) ++ { ++ err=1; ++ printf("cfb_encrypt encrypt error\n"); ++ for (i=0; i<24; i+=8) ++ printf("%s\n",pt(&(cfb_buf1[i]))); ++ } ++ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); ++ n=0; ++ des_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks, ++ (C_Block *)cfb_tmp,&n,DES_DECRYPT); ++ des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]), ++ (long)sizeof(plain)-17,ks, ++ (C_Block *)cfb_tmp,&n,DES_DECRYPT); ++ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) ++ { ++ err=1; ++ printf("cfb_encrypt decrypt error\n"); ++ for (i=0; i<24; i+=8) ++ printf("%s\n",pt(&(cfb_buf2[i]))); ++ } ++ return(err); ++ } ++ ++static int ede_cfb64_test(cfb_cipher) ++unsigned char *cfb_cipher; ++ { ++ des_key_schedule ks; ++ int err=0,i,n; ++ ++ des_key_sched((C_Block *)cfb_key,ks); ++ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); ++ n=0; ++ des_ede3_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,ks,ks, ++ (C_Block *)cfb_tmp,&n,DES_ENCRYPT); ++ des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]), ++ (long)sizeof(plain)-12,ks,ks,ks, ++ (C_Block *)cfb_tmp,&n,DES_ENCRYPT); ++ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) ++ { ++ err=1; ++ printf("ede_cfb_encrypt encrypt error\n"); ++ for (i=0; i<24; i+=8) ++ printf("%s\n",pt(&(cfb_buf1[i]))); ++ } ++ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); ++ n=0; ++ des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks, ++ (C_Block *)cfb_tmp,&n,DES_DECRYPT); ++ des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]), ++ (long)sizeof(plain)-17,ks,ks,ks, ++ (C_Block *)cfb_tmp,&n,DES_DECRYPT); ++ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) ++ { ++ err=1; ++ printf("ede_cfb_encrypt decrypt error\n"); ++ for (i=0; i<24; i+=8) ++ printf("%s\n",pt(&(cfb_buf2[i]))); ++ } ++ return(err); ++ } ++ ++#endif ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/dx86unix.S Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,3160 @@ ++/* ++ * This file was originally generated by Michael Richardson ++ * via the perl scripts found in the ASM subdir. It remains copyright of ++ * Eric Young, see the file COPYRIGHT. ++ * ++ * This was last done on October 9, 2002. ++ * ++ * While this file does not need to go through cpp, we pass it through ++ * CPP by naming it dx86unix.S instead of dx86unix.s because there is ++ * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS ++ * which may contain stuff that AS doesn't understand instead of ++ * referencing EXTRA_AFLAGS. ++ */ ++ ++ .file "dx86unix.S" ++ .version "01.01" ++.text ++ .align 16 ++.globl des_encrypt ++ .type des_encrypt , @function ++des_encrypt: ++ pushl %esi ++ pushl %edi ++ ++ ++ movl 12(%esp), %esi ++ xorl %ecx, %ecx ++ pushl %ebx ++ pushl %ebp ++ movl (%esi), %eax ++ movl 28(%esp), %ebx ++ movl 4(%esi), %edi ++ ++ ++ roll $4, %eax ++ movl %eax, %esi ++ xorl %edi, %eax ++ andl $0xf0f0f0f0, %eax ++ xorl %eax, %esi ++ xorl %eax, %edi ++ ++ roll $20, %edi ++ movl %edi, %eax ++ xorl %esi, %edi ++ andl $0xfff0000f, %edi ++ xorl %edi, %eax ++ xorl %edi, %esi ++ ++ roll $14, %eax ++ movl %eax, %edi ++ xorl %esi, %eax ++ andl $0x33333333, %eax ++ xorl %eax, %edi ++ xorl %eax, %esi ++ ++ roll $22, %esi ++ movl %esi, %eax ++ xorl %edi, %esi ++ andl $0x03fc03fc, %esi ++ xorl %esi, %eax ++ xorl %esi, %edi ++ ++ roll $9, %eax ++ movl %eax, %esi ++ xorl %edi, %eax ++ andl $0xaaaaaaaa, %eax ++ xorl %eax, %esi ++ xorl %eax, %edi ++ ++.byte 209 ++.byte 199 ++ movl 24(%esp), %ebp ++ cmpl $0, %ebx ++ je .L000start_decrypt ++ ++ ++ movl (%ebp), %eax ++ xorl %ebx, %ebx ++ movl 4(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 8(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 12(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 16(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 20(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 24(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 28(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 32(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 36(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 40(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 44(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 48(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 52(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 56(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 60(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 64(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 68(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 72(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 76(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 80(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 84(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 88(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 92(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 96(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 100(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 104(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 108(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 112(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 116(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 120(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 124(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ jmp .L001end ++.L000start_decrypt: ++ ++ ++ movl 120(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 124(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 112(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 116(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 104(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 108(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 96(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 100(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 88(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 92(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 80(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 84(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 72(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 76(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 64(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 68(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 56(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 60(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 48(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 52(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 40(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 44(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 32(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 36(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 24(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 28(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 16(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 20(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 8(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 12(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl (%ebp), %eax ++ xorl %ebx, %ebx ++ movl 4(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++.L001end: ++ ++ ++ movl 20(%esp), %edx ++.byte 209 ++.byte 206 ++ movl %edi, %eax ++ xorl %esi, %edi ++ andl $0xaaaaaaaa, %edi ++ xorl %edi, %eax ++ xorl %edi, %esi ++ ++ roll $23, %eax ++ movl %eax, %edi ++ xorl %esi, %eax ++ andl $0x03fc03fc, %eax ++ xorl %eax, %edi ++ xorl %eax, %esi ++ ++ roll $10, %edi ++ movl %edi, %eax ++ xorl %esi, %edi ++ andl $0x33333333, %edi ++ xorl %edi, %eax ++ xorl %edi, %esi ++ ++ roll $18, %esi ++ movl %esi, %edi ++ xorl %eax, %esi ++ andl $0xfff0000f, %esi ++ xorl %esi, %edi ++ xorl %esi, %eax ++ ++ roll $12, %edi ++ movl %edi, %esi ++ xorl %eax, %edi ++ andl $0xf0f0f0f0, %edi ++ xorl %edi, %esi ++ xorl %edi, %eax ++ ++ rorl $4, %eax ++ movl %eax, (%edx) ++ movl %esi, 4(%edx) ++ popl %ebp ++ popl %ebx ++ popl %edi ++ popl %esi ++ ret ++.des_encrypt_end: ++ .size des_encrypt , .des_encrypt_end-des_encrypt ++.ident "desasm.pl" ++.text ++ .align 16 ++.globl des_encrypt2 ++ .type des_encrypt2 , @function ++des_encrypt2: ++ pushl %esi ++ pushl %edi ++ ++ ++ movl 12(%esp), %eax ++ xorl %ecx, %ecx ++ pushl %ebx ++ pushl %ebp ++ movl (%eax), %esi ++ movl 28(%esp), %ebx ++ roll $3, %esi ++ movl 4(%eax), %edi ++ roll $3, %edi ++ movl 24(%esp), %ebp ++ cmpl $0, %ebx ++ je .L002start_decrypt ++ ++ ++ movl (%ebp), %eax ++ xorl %ebx, %ebx ++ movl 4(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 8(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 12(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 16(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 20(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 24(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 28(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 32(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 36(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 40(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 44(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 48(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 52(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 56(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 60(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 64(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 68(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 72(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 76(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 80(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 84(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 88(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 92(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 96(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 100(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 104(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 108(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 112(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 116(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 120(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 124(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ jmp .L003end ++.L002start_decrypt: ++ ++ ++ movl 120(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 124(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 112(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 116(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 104(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 108(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 96(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 100(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 88(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 92(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 80(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 84(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 72(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 76(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 64(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 68(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 56(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 60(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 48(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 52(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 40(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 44(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 32(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 36(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 24(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 28(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl 16(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 20(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++ ++ ++ movl 8(%ebp), %eax ++ xorl %ebx, %ebx ++ movl 12(%ebp), %edx ++ xorl %esi, %eax ++ xorl %esi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %edi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %edi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %edi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %edi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %edi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %edi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %edi ++ ++ ++ movl (%ebp), %eax ++ xorl %ebx, %ebx ++ movl 4(%ebp), %edx ++ xorl %edi, %eax ++ xorl %edi, %edx ++ andl $0xfcfcfcfc, %eax ++ andl $0xcfcfcfcf, %edx ++ movb %al, %bl ++ movb %ah, %cl ++ rorl $4, %edx ++ movl des_SPtrans(%ebx),%ebp ++ movb %dl, %bl ++ xorl %ebp, %esi ++ movl 0x200+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movb %dh, %cl ++ shrl $16, %eax ++ movl 0x100+des_SPtrans(%ebx),%ebp ++ xorl %ebp, %esi ++ movb %ah, %bl ++ shrl $16, %edx ++ movl 0x300+des_SPtrans(%ecx),%ebp ++ xorl %ebp, %esi ++ movl 24(%esp), %ebp ++ movb %dh, %cl ++ andl $0xff, %eax ++ andl $0xff, %edx ++ movl 0x600+des_SPtrans(%ebx),%ebx ++ xorl %ebx, %esi ++ movl 0x700+des_SPtrans(%ecx),%ebx ++ xorl %ebx, %esi ++ movl 0x400+des_SPtrans(%eax),%ebx ++ xorl %ebx, %esi ++ movl 0x500+des_SPtrans(%edx),%ebx ++ xorl %ebx, %esi ++.L003end: ++ ++ ++ rorl $3, %edi ++ movl 20(%esp), %eax ++ rorl $3, %esi ++ movl %edi, (%eax) ++ movl %esi, 4(%eax) ++ popl %ebp ++ popl %ebx ++ popl %edi ++ popl %esi ++ ret ++.des_encrypt2_end: ++ .size des_encrypt2 , .des_encrypt2_end-des_encrypt2 ++.ident "desasm.pl" ++.text ++ .align 16 ++.globl des_encrypt3 ++ .type des_encrypt3 , @function ++des_encrypt3: ++ pushl %ebx ++ movl 8(%esp), %ebx ++ pushl %ebp ++ pushl %esi ++ pushl %edi ++ ++ ++ movl (%ebx), %edi ++ movl 4(%ebx), %esi ++ subl $12, %esp ++ ++ ++ roll $4, %edi ++ movl %edi, %edx ++ xorl %esi, %edi ++ andl $0xf0f0f0f0, %edi ++ xorl %edi, %edx ++ xorl %edi, %esi ++ ++ roll $20, %esi ++ movl %esi, %edi ++ xorl %edx, %esi ++ andl $0xfff0000f, %esi ++ xorl %esi, %edi ++ xorl %esi, %edx ++ ++ roll $14, %edi ++ movl %edi, %esi ++ xorl %edx, %edi ++ andl $0x33333333, %edi ++ xorl %edi, %esi ++ xorl %edi, %edx ++ ++ roll $22, %edx ++ movl %edx, %edi ++ xorl %esi, %edx ++ andl $0x03fc03fc, %edx ++ xorl %edx, %edi ++ xorl %edx, %esi ++ ++ roll $9, %edi ++ movl %edi, %edx ++ xorl %esi, %edi ++ andl $0xaaaaaaaa, %edi ++ xorl %edi, %edx ++ xorl %edi, %esi ++ ++ rorl $3, %edx ++ rorl $2, %esi ++ movl %esi, 4(%ebx) ++ movl 36(%esp), %eax ++ movl %edx, (%ebx) ++ movl 40(%esp), %edi ++ movl 44(%esp), %esi ++ movl $1, 8(%esp) ++ movl %eax, 4(%esp) ++ movl %ebx, (%esp) ++ call des_encrypt2 ++ movl $0, 8(%esp) ++ movl %edi, 4(%esp) ++ movl %ebx, (%esp) ++ call des_encrypt2 ++ movl $1, 8(%esp) ++ movl %esi, 4(%esp) ++ movl %ebx, (%esp) ++ call des_encrypt2 ++ addl $12, %esp ++ movl (%ebx), %edi ++ movl 4(%ebx), %esi ++ ++ ++ roll $2, %esi ++ roll $3, %edi ++ movl %edi, %eax ++ xorl %esi, %edi ++ andl $0xaaaaaaaa, %edi ++ xorl %edi, %eax ++ xorl %edi, %esi ++ ++ roll $23, %eax ++ movl %eax, %edi ++ xorl %esi, %eax ++ andl $0x03fc03fc, %eax ++ xorl %eax, %edi ++ xorl %eax, %esi ++ ++ roll $10, %edi ++ movl %edi, %eax ++ xorl %esi, %edi ++ andl $0x33333333, %edi ++ xorl %edi, %eax ++ xorl %edi, %esi ++ ++ roll $18, %esi ++ movl %esi, %edi ++ xorl %eax, %esi ++ andl $0xfff0000f, %esi ++ xorl %esi, %edi ++ xorl %esi, %eax ++ ++ roll $12, %edi ++ movl %edi, %esi ++ xorl %eax, %edi ++ andl $0xf0f0f0f0, %edi ++ xorl %edi, %esi ++ xorl %edi, %eax ++ ++ rorl $4, %eax ++ movl %eax, (%ebx) ++ movl %esi, 4(%ebx) ++ popl %edi ++ popl %esi ++ popl %ebp ++ popl %ebx ++ ret ++.des_encrypt3_end: ++ .size des_encrypt3 , .des_encrypt3_end-des_encrypt3 ++.ident "desasm.pl" ++.text ++ .align 16 ++.globl des_decrypt3 ++ .type des_decrypt3 , @function ++des_decrypt3: ++ pushl %ebx ++ movl 8(%esp), %ebx ++ pushl %ebp ++ pushl %esi ++ pushl %edi ++ ++ ++ movl (%ebx), %edi ++ movl 4(%ebx), %esi ++ subl $12, %esp ++ ++ ++ roll $4, %edi ++ movl %edi, %edx ++ xorl %esi, %edi ++ andl $0xf0f0f0f0, %edi ++ xorl %edi, %edx ++ xorl %edi, %esi ++ ++ roll $20, %esi ++ movl %esi, %edi ++ xorl %edx, %esi ++ andl $0xfff0000f, %esi ++ xorl %esi, %edi ++ xorl %esi, %edx ++ ++ roll $14, %edi ++ movl %edi, %esi ++ xorl %edx, %edi ++ andl $0x33333333, %edi ++ xorl %edi, %esi ++ xorl %edi, %edx ++ ++ roll $22, %edx ++ movl %edx, %edi ++ xorl %esi, %edx ++ andl $0x03fc03fc, %edx ++ xorl %edx, %edi ++ xorl %edx, %esi ++ ++ roll $9, %edi ++ movl %edi, %edx ++ xorl %esi, %edi ++ andl $0xaaaaaaaa, %edi ++ xorl %edi, %edx ++ xorl %edi, %esi ++ ++ rorl $3, %edx ++ rorl $2, %esi ++ movl %esi, 4(%ebx) ++ movl 36(%esp), %esi ++ movl %edx, (%ebx) ++ movl 40(%esp), %edi ++ movl 44(%esp), %eax ++ movl $0, 8(%esp) ++ movl %eax, 4(%esp) ++ movl %ebx, (%esp) ++ call des_encrypt2 ++ movl $1, 8(%esp) ++ movl %edi, 4(%esp) ++ movl %ebx, (%esp) ++ call des_encrypt2 ++ movl $0, 8(%esp) ++ movl %esi, 4(%esp) ++ movl %ebx, (%esp) ++ call des_encrypt2 ++ addl $12, %esp ++ movl (%ebx), %edi ++ movl 4(%ebx), %esi ++ ++ ++ roll $2, %esi ++ roll $3, %edi ++ movl %edi, %eax ++ xorl %esi, %edi ++ andl $0xaaaaaaaa, %edi ++ xorl %edi, %eax ++ xorl %edi, %esi ++ ++ roll $23, %eax ++ movl %eax, %edi ++ xorl %esi, %eax ++ andl $0x03fc03fc, %eax ++ xorl %eax, %edi ++ xorl %eax, %esi ++ ++ roll $10, %edi ++ movl %edi, %eax ++ xorl %esi, %edi ++ andl $0x33333333, %edi ++ xorl %edi, %eax ++ xorl %edi, %esi ++ ++ roll $18, %esi ++ movl %esi, %edi ++ xorl %eax, %esi ++ andl $0xfff0000f, %esi ++ xorl %esi, %edi ++ xorl %esi, %eax ++ ++ roll $12, %edi ++ movl %edi, %esi ++ xorl %eax, %edi ++ andl $0xf0f0f0f0, %edi ++ xorl %edi, %esi ++ xorl %edi, %eax ++ ++ rorl $4, %eax ++ movl %eax, (%ebx) ++ movl %esi, 4(%ebx) ++ popl %edi ++ popl %esi ++ popl %ebp ++ popl %ebx ++ ret ++.des_decrypt3_end: ++ .size des_decrypt3 , .des_decrypt3_end-des_decrypt3 ++.ident "desasm.pl" ++.text ++ .align 16 ++.globl des_ncbc_encrypt ++ .type des_ncbc_encrypt , @function ++des_ncbc_encrypt: ++ ++ pushl %ebp ++ pushl %ebx ++ pushl %esi ++ pushl %edi ++ movl 28(%esp), %ebp ++ ++ movl 36(%esp), %ebx ++ movl (%ebx), %esi ++ movl 4(%ebx), %edi ++ pushl %edi ++ pushl %esi ++ pushl %edi ++ pushl %esi ++ movl %esp, %ebx ++ movl 36(%esp), %esi ++ movl 40(%esp), %edi ++ ++ movl 56(%esp), %ecx ++ ++ pushl %ecx ++ ++ movl 52(%esp), %eax ++ pushl %eax ++ pushl %ebx ++ cmpl $0, %ecx ++ jz .L004decrypt ++ andl $4294967288, %ebp ++ movl 12(%esp), %eax ++ movl 16(%esp), %ebx ++ jz .L005encrypt_finish ++.L006encrypt_loop: ++ movl (%esi), %ecx ++ movl 4(%esi), %edx ++ xorl %ecx, %eax ++ xorl %edx, %ebx ++ movl %eax, 12(%esp) ++ movl %ebx, 16(%esp) ++ call des_encrypt ++ movl 12(%esp), %eax ++ movl 16(%esp), %ebx ++ movl %eax, (%edi) ++ movl %ebx, 4(%edi) ++ addl $8, %esi ++ addl $8, %edi ++ subl $8, %ebp ++ jnz .L006encrypt_loop ++.L005encrypt_finish: ++ movl 56(%esp), %ebp ++ andl $7, %ebp ++ jz .L007finish ++ xorl %ecx, %ecx ++ xorl %edx, %edx ++ movl .L008cbc_enc_jmp_table(,%ebp,4),%ebp ++ jmp *%ebp ++.L009ej7: ++ movb 6(%esi), %dh ++ sall $8, %edx ++.L010ej6: ++ movb 5(%esi), %dh ++.L011ej5: ++ movb 4(%esi), %dl ++.L012ej4: ++ movl (%esi), %ecx ++ jmp .L013ejend ++.L014ej3: ++ movb 2(%esi), %ch ++ sall $8, %ecx ++.L015ej2: ++ movb 1(%esi), %ch ++.L016ej1: ++ movb (%esi), %cl ++.L013ejend: ++ xorl %ecx, %eax ++ xorl %edx, %ebx ++ movl %eax, 12(%esp) ++ movl %ebx, 16(%esp) ++ call des_encrypt ++ movl 12(%esp), %eax ++ movl 16(%esp), %ebx ++ movl %eax, (%edi) ++ movl %ebx, 4(%edi) ++ jmp .L007finish ++.align 16 ++.L004decrypt: ++ andl $4294967288, %ebp ++ movl 20(%esp), %eax ++ movl 24(%esp), %ebx ++ jz .L017decrypt_finish ++.L018decrypt_loop: ++ movl (%esi), %eax ++ movl 4(%esi), %ebx ++ movl %eax, 12(%esp) ++ movl %ebx, 16(%esp) ++ call des_encrypt ++ movl 12(%esp), %eax ++ movl 16(%esp), %ebx ++ movl 20(%esp), %ecx ++ movl 24(%esp), %edx ++ xorl %eax, %ecx ++ xorl %ebx, %edx ++ movl (%esi), %eax ++ movl 4(%esi), %ebx ++ movl %ecx, (%edi) ++ movl %edx, 4(%edi) ++ movl %eax, 20(%esp) ++ movl %ebx, 24(%esp) ++ addl $8, %esi ++ addl $8, %edi ++ subl $8, %ebp ++ jnz .L018decrypt_loop ++.L017decrypt_finish: ++ movl 56(%esp), %ebp ++ andl $7, %ebp ++ jz .L007finish ++ movl (%esi), %eax ++ movl 4(%esi), %ebx ++ movl %eax, 12(%esp) ++ movl %ebx, 16(%esp) ++ call des_encrypt ++ movl 12(%esp), %eax ++ movl 16(%esp), %ebx ++ movl 20(%esp), %ecx ++ movl 24(%esp), %edx ++ xorl %eax, %ecx ++ xorl %ebx, %edx ++ movl (%esi), %eax ++ movl 4(%esi), %ebx ++.L019dj7: ++ rorl $16, %edx ++ movb %dl, 6(%edi) ++ shrl $16, %edx ++.L020dj6: ++ movb %dh, 5(%edi) ++.L021dj5: ++ movb %dl, 4(%edi) ++.L022dj4: ++ movl %ecx, (%edi) ++ jmp .L023djend ++.L024dj3: ++ rorl $16, %ecx ++ movb %cl, 2(%edi) ++ sall $16, %ecx ++.L025dj2: ++ movb %ch, 1(%esi) ++.L026dj1: ++ movb %cl, (%esi) ++.L023djend: ++ jmp .L007finish ++.align 16 ++.L007finish: ++ movl 64(%esp), %ecx ++ addl $28, %esp ++ movl %eax, (%ecx) ++ movl %ebx, 4(%ecx) ++ popl %edi ++ popl %esi ++ popl %ebx ++ popl %ebp ++ ret ++.align 16 ++.L008cbc_enc_jmp_table: ++ .long 0 ++ .long .L016ej1 ++ .long .L015ej2 ++ .long .L014ej3 ++ .long .L012ej4 ++ .long .L011ej5 ++ .long .L010ej6 ++ .long .L009ej7 ++.align 16 ++.L027cbc_dec_jmp_table: ++ .long 0 ++ .long .L026dj1 ++ .long .L025dj2 ++ .long .L024dj3 ++ .long .L022dj4 ++ .long .L021dj5 ++ .long .L020dj6 ++ .long .L019dj7 ++.des_ncbc_encrypt_end: ++ .size des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt ++.ident "desasm.pl" ++.text ++ .align 16 ++.globl des_ede3_cbc_encrypt ++ .type des_ede3_cbc_encrypt , @function ++des_ede3_cbc_encrypt: ++ ++ pushl %ebp ++ pushl %ebx ++ pushl %esi ++ pushl %edi ++ movl 28(%esp), %ebp ++ ++ movl 44(%esp), %ebx ++ movl (%ebx), %esi ++ movl 4(%ebx), %edi ++ pushl %edi ++ pushl %esi ++ pushl %edi ++ pushl %esi ++ movl %esp, %ebx ++ movl 36(%esp), %esi ++ movl 40(%esp), %edi ++ ++ movl 64(%esp), %ecx ++ ++ movl 56(%esp), %eax ++ pushl %eax ++ ++ movl 56(%esp), %eax ++ pushl %eax ++ ++ movl 56(%esp), %eax ++ pushl %eax ++ pushl %ebx ++ cmpl $0, %ecx ++ jz .L028decrypt ++ andl $4294967288, %ebp ++ movl 16(%esp), %eax ++ movl 20(%esp), %ebx ++ jz .L029encrypt_finish ++.L030encrypt_loop: ++ movl (%esi), %ecx ++ movl 4(%esi), %edx ++ xorl %ecx, %eax ++ xorl %edx, %ebx ++ movl %eax, 16(%esp) ++ movl %ebx, 20(%esp) ++ call des_encrypt3 ++ movl 16(%esp), %eax ++ movl 20(%esp), %ebx ++ movl %eax, (%edi) ++ movl %ebx, 4(%edi) ++ addl $8, %esi ++ addl $8, %edi ++ subl $8, %ebp ++ jnz .L030encrypt_loop ++.L029encrypt_finish: ++ movl 60(%esp), %ebp ++ andl $7, %ebp ++ jz .L031finish ++ xorl %ecx, %ecx ++ xorl %edx, %edx ++ movl .L032cbc_enc_jmp_table(,%ebp,4),%ebp ++ jmp *%ebp ++.L033ej7: ++ movb 6(%esi), %dh ++ sall $8, %edx ++.L034ej6: ++ movb 5(%esi), %dh ++.L035ej5: ++ movb 4(%esi), %dl ++.L036ej4: ++ movl (%esi), %ecx ++ jmp .L037ejend ++.L038ej3: ++ movb 2(%esi), %ch ++ sall $8, %ecx ++.L039ej2: ++ movb 1(%esi), %ch ++.L040ej1: ++ movb (%esi), %cl ++.L037ejend: ++ xorl %ecx, %eax ++ xorl %edx, %ebx ++ movl %eax, 16(%esp) ++ movl %ebx, 20(%esp) ++ call des_encrypt3 ++ movl 16(%esp), %eax ++ movl 20(%esp), %ebx ++ movl %eax, (%edi) ++ movl %ebx, 4(%edi) ++ jmp .L031finish ++.align 16 ++.L028decrypt: ++ andl $4294967288, %ebp ++ movl 24(%esp), %eax ++ movl 28(%esp), %ebx ++ jz .L041decrypt_finish ++.L042decrypt_loop: ++ movl (%esi), %eax ++ movl 4(%esi), %ebx ++ movl %eax, 16(%esp) ++ movl %ebx, 20(%esp) ++ call des_decrypt3 ++ movl 16(%esp), %eax ++ movl 20(%esp), %ebx ++ movl 24(%esp), %ecx ++ movl 28(%esp), %edx ++ xorl %eax, %ecx ++ xorl %ebx, %edx ++ movl (%esi), %eax ++ movl 4(%esi), %ebx ++ movl %ecx, (%edi) ++ movl %edx, 4(%edi) ++ movl %eax, 24(%esp) ++ movl %ebx, 28(%esp) ++ addl $8, %esi ++ addl $8, %edi ++ subl $8, %ebp ++ jnz .L042decrypt_loop ++.L041decrypt_finish: ++ movl 60(%esp), %ebp ++ andl $7, %ebp ++ jz .L031finish ++ movl (%esi), %eax ++ movl 4(%esi), %ebx ++ movl %eax, 16(%esp) ++ movl %ebx, 20(%esp) ++ call des_decrypt3 ++ movl 16(%esp), %eax ++ movl 20(%esp), %ebx ++ movl 24(%esp), %ecx ++ movl 28(%esp), %edx ++ xorl %eax, %ecx ++ xorl %ebx, %edx ++ movl (%esi), %eax ++ movl 4(%esi), %ebx ++.L043dj7: ++ rorl $16, %edx ++ movb %dl, 6(%edi) ++ shrl $16, %edx ++.L044dj6: ++ movb %dh, 5(%edi) ++.L045dj5: ++ movb %dl, 4(%edi) ++.L046dj4: ++ movl %ecx, (%edi) ++ jmp .L047djend ++.L048dj3: ++ rorl $16, %ecx ++ movb %cl, 2(%edi) ++ sall $16, %ecx ++.L049dj2: ++ movb %ch, 1(%esi) ++.L050dj1: ++ movb %cl, (%esi) ++.L047djend: ++ jmp .L031finish ++.align 16 ++.L031finish: ++ movl 76(%esp), %ecx ++ addl $32, %esp ++ movl %eax, (%ecx) ++ movl %ebx, 4(%ecx) ++ popl %edi ++ popl %esi ++ popl %ebx ++ popl %ebp ++ ret ++.align 16 ++.L032cbc_enc_jmp_table: ++ .long 0 ++ .long .L040ej1 ++ .long .L039ej2 ++ .long .L038ej3 ++ .long .L036ej4 ++ .long .L035ej5 ++ .long .L034ej6 ++ .long .L033ej7 ++.align 16 ++.L051cbc_dec_jmp_table: ++ .long 0 ++ .long .L050dj1 ++ .long .L049dj2 ++ .long .L048dj3 ++ .long .L046dj4 ++ .long .L045dj5 ++ .long .L044dj6 ++ .long .L043dj7 ++.des_ede3_cbc_encrypt_end: ++ .size des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt ++.ident "desasm.pl" +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/ecb_enc.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,128 @@ ++/* crypto/des/ecb_enc.c */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++#include "des_locl.h" ++#include "spr.h" ++ ++char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay"; ++char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998"; ++ ++/* RCSID $Id: ecb_enc.c,v 1.6 2002/04/24 07:36:38 mcr Exp $ */ ++/* This function ifdef'ed out for FreeS/WAN project. */ ++#ifdef notdef ++char *des_options() ++ { ++ static int init=1; ++ static char buf[32]; ++ ++ if (init) ++ { ++ char *ptr,*unroll,*risc,*size; ++ ++ init=0; ++#ifdef DES_PTR ++ ptr="ptr"; ++#else ++ ptr="idx"; ++#endif ++#if defined(DES_RISC1) || defined(DES_RISC2) ++#ifdef DES_RISC1 ++ risc="risc1"; ++#endif ++#ifdef DES_RISC2 ++ risc="risc2"; ++#endif ++#else ++ risc="cisc"; ++#endif ++#ifdef DES_UNROLL ++ unroll="16"; ++#else ++ unroll="4"; ++#endif ++ if (sizeof(DES_LONG) != sizeof(long)) ++ size="int"; ++ else ++ size="long"; ++ sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size); ++ } ++ return(buf); ++ } ++#endif ++ ++ ++void des_ecb_encrypt(input, output, ks, enc) ++des_cblock (*input); ++des_cblock (*output); ++des_key_schedule ks; ++int enc; ++ { ++ register DES_LONG l; ++ register unsigned char *in,*out; ++ DES_LONG ll[2]; ++ ++ in=(unsigned char *)input; ++ out=(unsigned char *)output; ++ c2l(in,l); ll[0]=l; ++ c2l(in,l); ll[1]=l; ++ des_encrypt(ll,ks,enc); ++ l=ll[0]; l2c(l,out); ++ l=ll[1]; l2c(l,out); ++ l=ll[0]=ll[1]=0; ++ } ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/fcrypt.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,152 @@ ++/* NOCW */ ++ ++/* This version of crypt has been developed from my MIT compatable ++ * DES library. ++ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au ++ * Eric Young (eay@cryptsoft.com) ++ */ ++ ++/* Modification by Jens Kupferschmidt (Cu) ++ * I have included directive PARA for shared memory computers. ++ * I have included a directive LONGCRYPT to using this routine to cipher ++ * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN ++ * definition is the maximum of lenght of password and can changed. I have ++ * defined 24. ++ */ ++ ++#include "des_locl.h" ++ ++/* Added more values to handle illegal salt values the way normal ++ * crypt() implementations do. The patch was sent by ++ * Bjorn Gronvall ++ */ ++static unsigned const char con_salt[128]={ ++0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9, ++0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1, ++0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9, ++0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1, ++0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9, ++0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01, ++0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, ++0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A, ++0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12, ++0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A, ++0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22, ++0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24, ++0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C, ++0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34, ++0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C, ++0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44, ++}; ++ ++static unsigned const char cov_2char[64]={ ++0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35, ++0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44, ++0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C, ++0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54, ++0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62, ++0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A, ++0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72, ++0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A ++}; ++ ++#ifndef NOPROTO ++void fcrypt_body(DES_LONG *out,des_key_schedule ks, ++ DES_LONG Eswap0, DES_LONG Eswap1); ++ ++#ifdef PERL5 ++char *des_crypt(const char *buf,const char *salt); ++#else ++char *crypt(const char *buf,const char *salt); ++#endif ++#else ++void fcrypt_body(); ++#ifdef PERL5 ++char *des_crypt(); ++#else ++char *crypt(); ++#endif ++#endif ++ ++#ifdef PERL5 ++char *des_crypt(buf,salt) ++#else ++char *crypt(buf,salt) ++#endif ++const char *buf; ++const char *salt; ++ { ++ static char buff[14]; ++ ++ return(des_fcrypt(buf,salt,buff)); ++ } ++ ++ ++char *des_fcrypt(buf,salt,ret) ++const char *buf; ++const char *salt; ++char *ret; ++ { ++ unsigned int i,j,x,y; ++ DES_LONG Eswap0,Eswap1; ++ DES_LONG out[2],ll; ++ des_cblock key; ++ des_key_schedule ks; ++ unsigned char bb[9]; ++ unsigned char *b=bb; ++ unsigned char c,u; ++ ++ /* eay 25/08/92 ++ * If you call crypt("pwd","*") as often happens when you ++ * have * as the pwd field in /etc/passwd, the function ++ * returns *\0XXXXXXXXX ++ * The \0 makes the string look like * so the pwd "*" would ++ * crypt to "*". This was found when replacing the crypt in ++ * our shared libraries. People found that the disbled ++ * accounts effectivly had no passwd :-(. */ ++ x=ret[0]=((salt[0] == '\0')?'A':salt[0]); ++ Eswap0=con_salt[x]<<2; ++ x=ret[1]=((salt[1] == '\0')?'A':salt[1]); ++ Eswap1=con_salt[x]<<6; ++ ++/* EAY ++r=strlen(buf); ++r=(r+7)/8; ++*/ ++ for (i=0; i<8; i++) ++ { ++ c= *(buf++); ++ if (!c) break; ++ key[i]=(c<<1); ++ } ++ for (; i<8; i++) ++ key[i]=0; ++ ++ des_set_key((des_cblock *)(key),ks); ++ fcrypt_body(&(out[0]),ks,Eswap0,Eswap1); ++ ++ ll=out[0]; l2c(ll,b); ++ ll=out[1]; l2c(ll,b); ++ y=0; ++ u=0x80; ++ bb[8]=0; ++ for (i=2; i<13; i++) ++ { ++ c=0; ++ for (j=0; j<6; j++) ++ { ++ c<<=1; ++ if (bb[y] & u) c|=1; ++ u>>=1; ++ if (!u) ++ { ++ y++; ++ u=0x80; ++ } ++ } ++ ret[i]=cov_2char[c]; ++ } ++ ret[13]='\0'; ++ return(ret); ++ } ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/fcrypt_b.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,148 @@ ++/* crypto/des/fcrypt_b.c */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++/* #include */ ++ ++/* This version of crypt has been developed from my MIT compatable ++ * DES library. ++ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au ++ * Eric Young (eay@cryptsoft.com) ++ */ ++ ++#define DES_FCRYPT ++#include "des_locl.h" ++#undef DES_FCRYPT ++ ++#undef PERM_OP ++#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ ++ (b)^=(t),\ ++ (a)^=((t)<<(n))) ++ ++#undef HPERM_OP ++#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ ++ (a)=(a)^(t)^(t>>(16-(n))))\ ++ ++void fcrypt_body(out, ks, Eswap0, Eswap1) ++DES_LONG *out; ++des_key_schedule ks; ++DES_LONG Eswap0; ++DES_LONG Eswap1; ++ { ++ register DES_LONG l,r,t,u; ++#ifdef DES_PTR ++ register unsigned char *des_SP=(unsigned char *)des_SPtrans; ++#endif ++ register DES_LONG *s; ++ register int j; ++ register DES_LONG E0,E1; ++ ++ l=0; ++ r=0; ++ ++ s=(DES_LONG *)ks; ++ E0=Eswap0; ++ E1=Eswap1; ++ ++ for (j=0; j<25; j++) ++ { ++#ifdef DES_UNROLL ++ register int i; ++ ++ for (i=0; i<32; i+=8) ++ { ++ D_ENCRYPT(l,r,i+0); /* 1 */ ++ D_ENCRYPT(r,l,i+2); /* 2 */ ++ D_ENCRYPT(l,r,i+4); /* 1 */ ++ D_ENCRYPT(r,l,i+6); /* 2 */ ++ } ++#else ++ D_ENCRYPT(l,r, 0); /* 1 */ ++ D_ENCRYPT(r,l, 2); /* 2 */ ++ D_ENCRYPT(l,r, 4); /* 3 */ ++ D_ENCRYPT(r,l, 6); /* 4 */ ++ D_ENCRYPT(l,r, 8); /* 5 */ ++ D_ENCRYPT(r,l,10); /* 6 */ ++ D_ENCRYPT(l,r,12); /* 7 */ ++ D_ENCRYPT(r,l,14); /* 8 */ ++ D_ENCRYPT(l,r,16); /* 9 */ ++ D_ENCRYPT(r,l,18); /* 10 */ ++ D_ENCRYPT(l,r,20); /* 11 */ ++ D_ENCRYPT(r,l,22); /* 12 */ ++ D_ENCRYPT(l,r,24); /* 13 */ ++ D_ENCRYPT(r,l,26); /* 14 */ ++ D_ENCRYPT(l,r,28); /* 15 */ ++ D_ENCRYPT(r,l,30); /* 16 */ ++#endif ++ ++ t=l; ++ l=r; ++ r=t; ++ } ++ l=ROTATE(l,3)&0xffffffffL; ++ r=ROTATE(r,3)&0xffffffffL; ++ ++ PERM_OP(l,r,t, 1,0x55555555L); ++ PERM_OP(r,l,t, 8,0x00ff00ffL); ++ PERM_OP(l,r,t, 2,0x33333333L); ++ PERM_OP(r,l,t,16,0x0000ffffL); ++ PERM_OP(l,r,t, 4,0x0f0f0f0fL); ++ ++ out[0]=r; ++ out[1]=l; ++ } ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/options.txt Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,39 @@ ++Note that the UNROLL option makes the 'inner' des loop unroll all 16 rounds ++instead of the default 4. ++RISC1 and RISC2 are 2 alternatives for the inner loop and ++PTR means to use pointers arithmatic instead of arrays. ++ ++FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - assembler 577,000 4620k/s ++IRIX 6.2 - R10000 195mhz - cc (-O3 -n32) - UNROLL RISC2 PTR 496,000 3968k/s ++solaris 2.5.1 usparc 167mhz?? - SC4.0 - UNROLL RISC1 PTR [1] 459,400 3672k/s ++FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - UNROLL RISC1 433,000 3468k/s ++solaris 2.5.1 usparc 167mhz?? - gcc 2.7.2 - UNROLL 380,000 3041k/s ++linux - pentium 100mhz - gcc 2.7.0 - assembler 281,000 2250k/s ++NT 4.0 - pentium 100mhz - VC 4.2 - assembler 281,000 2250k/s ++AIX 4.1? - PPC604 100mhz - cc - UNROLL 275,000 2200k/s ++IRIX 5.3 - R4400 200mhz - gcc 2.6.3 - UNROLL RISC2 PTR 235,300 1882k/s ++IRIX 5.3 - R4400 200mhz - cc - UNROLL RISC2 PTR 233,700 1869k/s ++NT 4.0 - pentium 100mhz - VC 4.2 - UNROLL RISC1 PTR 191,000 1528k/s ++DEC Alpha 165mhz?? - cc - RISC2 PTR [2] 181,000 1448k/s ++linux - pentium 100mhz - gcc 2.7.0 - UNROLL RISC1 PTR 158,500 1268k/s ++HPUX 10 - 9000/887 - cc - UNROLL [3] 148,000 1190k/s ++solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2 - UNROLL 123,600 989k/s ++IRIX 5.3 - R4000 100mhz - cc - UNROLL RISC2 PTR 101,000 808k/s ++DGUX - 88100 50mhz(?) - gcc 2.6.3 - UNROLL 81,000 648k/s ++solaris 2.4 486 50mhz - gcc 2.6.3 - assembler 65,000 522k/s ++HPUX 10 - 9000/887 - k&r cc (default compiler) - UNROLL PTR 76,000 608k/s ++solaris 2.4 486 50mhz - gcc 2.6.3 - UNROLL RISC2 43,500 344k/s ++AIX - old slow one :-) - cc - 39,000 312k/s ++ ++Notes. ++[1] For the ultra sparc, SunC 4.0 ++ cc -xtarget=ultra -xarch=v8plus -Xa -xO5, running 'des_opts' ++ gives a speed of 344,000 des/s while 'speed' gives 459,000 des/s. ++ I'll record the higher since it is coming from the library but it ++ is all rather weird. ++[2] Similar to the ultra sparc ([1]), 181,000 for 'des_opts' vs 175,000. ++[3] I was unable to get access to this machine when it was not heavily loaded. ++ As such, my timing program was never able to get more that %30 of the CPU. ++ This would cause the program to give much lower speed numbers because ++ it would be 'fighting' to stay in the cache with the other CPU burning ++ processes. +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/podd.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,75 @@ ++/* crypto/des/podd.h */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++static const unsigned char odd_parity[256]={ ++ 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, ++ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31, ++ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47, ++ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62, ++ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79, ++ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94, ++ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110, ++112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127, ++128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143, ++145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158, ++161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174, ++176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191, ++193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206, ++208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223, ++224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239, ++241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254}; +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/set_key.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,246 @@ ++/* crypto/des/set_key.c */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++/* set_key.c v 1.4 eay 24/9/91 ++ * 1.4 Speed up by 400% :-) ++ * 1.3 added register declarations. ++ * 1.2 unrolled make_key_sched a bit more ++ * 1.1 added norm_expand_bits ++ * 1.0 First working version ++ */ ++#include "des_locl.h" ++#include "podd.h" ++#include "sk.h" ++ ++#ifndef NOPROTO ++static int check_parity(des_cblock (*key)); ++#else ++static int check_parity(); ++#endif ++ ++int des_check_key=0; ++ ++void des_set_odd_parity(key) ++des_cblock (*key); ++ { ++ int i; ++ ++ for (i=0; i>(n))^(b))&(m)),\ ++ * (b)^=(t),\ ++ * (a)=((a)^((t)<<(n)))) ++ */ ++ ++#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ ++ (a)=(a)^(t)^(t>>(16-(n)))) ++ ++/* return 0 if key parity is odd (correct), ++ * return -1 if key parity error, ++ * return -2 if illegal weak key. ++ */ ++int des_set_key(key, schedule) ++des_cblock (*key); ++des_key_schedule schedule; ++ { ++ static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; ++ register DES_LONG c,d,t,s,t2; ++ register unsigned char *in; ++ register DES_LONG *k; ++ register int i; ++ ++ if (des_check_key) ++ { ++ if (!check_parity(key)) ++ return(-1); ++ ++ if (des_is_weak_key(key)) ++ return(-2); ++ } ++ ++ k=(DES_LONG *)schedule; ++ in=(unsigned char *)key; ++ ++ c2l(in,c); ++ c2l(in,d); ++ ++ /* do PC1 in 60 simple operations */ ++/* PERM_OP(d,c,t,4,0x0f0f0f0fL); ++ HPERM_OP(c,t,-2, 0xcccc0000L); ++ HPERM_OP(c,t,-1, 0xaaaa0000L); ++ HPERM_OP(c,t, 8, 0x00ff0000L); ++ HPERM_OP(c,t,-1, 0xaaaa0000L); ++ HPERM_OP(d,t,-8, 0xff000000L); ++ HPERM_OP(d,t, 8, 0x00ff0000L); ++ HPERM_OP(d,t, 2, 0x33330000L); ++ d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L); ++ d=(d>>8)|((c&0xf0000000L)>>4); ++ c&=0x0fffffffL; */ ++ ++ /* I now do it in 47 simple operations :-) ++ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) ++ * for the inspiration. :-) */ ++ PERM_OP (d,c,t,4,0x0f0f0f0fL); ++ HPERM_OP(c,t,-2,0xcccc0000L); ++ HPERM_OP(d,t,-2,0xcccc0000L); ++ PERM_OP (d,c,t,1,0x55555555L); ++ PERM_OP (c,d,t,8,0x00ff00ffL); ++ PERM_OP (d,c,t,1,0x55555555L); ++ d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) | ++ ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L)); ++ c&=0x0fffffffL; ++ ++ for (i=0; i>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); } ++ else ++ { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); } ++ c&=0x0fffffffL; ++ d&=0x0fffffffL; ++ /* could be a few less shifts but I am to lazy at this ++ * point in time to investigate */ ++ s= des_skb[0][ (c )&0x3f ]| ++ des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]| ++ des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]| ++ des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) | ++ ((c>>22L)&0x38)]; ++ t= des_skb[4][ (d )&0x3f ]| ++ des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]| ++ des_skb[6][ (d>>15L)&0x3f ]| ++ des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)]; ++ ++ /* table contained 0213 4657 */ ++ t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL; ++ *(k++)=ROTATE(t2,30)&0xffffffffL; ++ ++ t2=((s>>16L)|(t&0xffff0000L)); ++ *(k++)=ROTATE(t2,26)&0xffffffffL; ++ } ++ return(0); ++ } ++ ++int des_key_sched(key, schedule) ++des_cblock (*key); ++des_key_schedule schedule; ++ { ++ return(des_set_key(key,schedule)); ++ } +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/sk.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,204 @@ ++/* crypto/des/sk.h */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++static const DES_LONG des_skb[8][64]={ ++{ ++/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ ++0x00000000L,0x00000010L,0x20000000L,0x20000010L, ++0x00010000L,0x00010010L,0x20010000L,0x20010010L, ++0x00000800L,0x00000810L,0x20000800L,0x20000810L, ++0x00010800L,0x00010810L,0x20010800L,0x20010810L, ++0x00000020L,0x00000030L,0x20000020L,0x20000030L, ++0x00010020L,0x00010030L,0x20010020L,0x20010030L, ++0x00000820L,0x00000830L,0x20000820L,0x20000830L, ++0x00010820L,0x00010830L,0x20010820L,0x20010830L, ++0x00080000L,0x00080010L,0x20080000L,0x20080010L, ++0x00090000L,0x00090010L,0x20090000L,0x20090010L, ++0x00080800L,0x00080810L,0x20080800L,0x20080810L, ++0x00090800L,0x00090810L,0x20090800L,0x20090810L, ++0x00080020L,0x00080030L,0x20080020L,0x20080030L, ++0x00090020L,0x00090030L,0x20090020L,0x20090030L, ++0x00080820L,0x00080830L,0x20080820L,0x20080830L, ++0x00090820L,0x00090830L,0x20090820L,0x20090830L, ++},{ ++/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */ ++0x00000000L,0x02000000L,0x00002000L,0x02002000L, ++0x00200000L,0x02200000L,0x00202000L,0x02202000L, ++0x00000004L,0x02000004L,0x00002004L,0x02002004L, ++0x00200004L,0x02200004L,0x00202004L,0x02202004L, ++0x00000400L,0x02000400L,0x00002400L,0x02002400L, ++0x00200400L,0x02200400L,0x00202400L,0x02202400L, ++0x00000404L,0x02000404L,0x00002404L,0x02002404L, ++0x00200404L,0x02200404L,0x00202404L,0x02202404L, ++0x10000000L,0x12000000L,0x10002000L,0x12002000L, ++0x10200000L,0x12200000L,0x10202000L,0x12202000L, ++0x10000004L,0x12000004L,0x10002004L,0x12002004L, ++0x10200004L,0x12200004L,0x10202004L,0x12202004L, ++0x10000400L,0x12000400L,0x10002400L,0x12002400L, ++0x10200400L,0x12200400L,0x10202400L,0x12202400L, ++0x10000404L,0x12000404L,0x10002404L,0x12002404L, ++0x10200404L,0x12200404L,0x10202404L,0x12202404L, ++},{ ++/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */ ++0x00000000L,0x00000001L,0x00040000L,0x00040001L, ++0x01000000L,0x01000001L,0x01040000L,0x01040001L, ++0x00000002L,0x00000003L,0x00040002L,0x00040003L, ++0x01000002L,0x01000003L,0x01040002L,0x01040003L, ++0x00000200L,0x00000201L,0x00040200L,0x00040201L, ++0x01000200L,0x01000201L,0x01040200L,0x01040201L, ++0x00000202L,0x00000203L,0x00040202L,0x00040203L, ++0x01000202L,0x01000203L,0x01040202L,0x01040203L, ++0x08000000L,0x08000001L,0x08040000L,0x08040001L, ++0x09000000L,0x09000001L,0x09040000L,0x09040001L, ++0x08000002L,0x08000003L,0x08040002L,0x08040003L, ++0x09000002L,0x09000003L,0x09040002L,0x09040003L, ++0x08000200L,0x08000201L,0x08040200L,0x08040201L, ++0x09000200L,0x09000201L,0x09040200L,0x09040201L, ++0x08000202L,0x08000203L,0x08040202L,0x08040203L, ++0x09000202L,0x09000203L,0x09040202L,0x09040203L, ++},{ ++/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */ ++0x00000000L,0x00100000L,0x00000100L,0x00100100L, ++0x00000008L,0x00100008L,0x00000108L,0x00100108L, ++0x00001000L,0x00101000L,0x00001100L,0x00101100L, ++0x00001008L,0x00101008L,0x00001108L,0x00101108L, ++0x04000000L,0x04100000L,0x04000100L,0x04100100L, ++0x04000008L,0x04100008L,0x04000108L,0x04100108L, ++0x04001000L,0x04101000L,0x04001100L,0x04101100L, ++0x04001008L,0x04101008L,0x04001108L,0x04101108L, ++0x00020000L,0x00120000L,0x00020100L,0x00120100L, ++0x00020008L,0x00120008L,0x00020108L,0x00120108L, ++0x00021000L,0x00121000L,0x00021100L,0x00121100L, ++0x00021008L,0x00121008L,0x00021108L,0x00121108L, ++0x04020000L,0x04120000L,0x04020100L,0x04120100L, ++0x04020008L,0x04120008L,0x04020108L,0x04120108L, ++0x04021000L,0x04121000L,0x04021100L,0x04121100L, ++0x04021008L,0x04121008L,0x04021108L,0x04121108L, ++},{ ++/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ ++0x00000000L,0x10000000L,0x00010000L,0x10010000L, ++0x00000004L,0x10000004L,0x00010004L,0x10010004L, ++0x20000000L,0x30000000L,0x20010000L,0x30010000L, ++0x20000004L,0x30000004L,0x20010004L,0x30010004L, ++0x00100000L,0x10100000L,0x00110000L,0x10110000L, ++0x00100004L,0x10100004L,0x00110004L,0x10110004L, ++0x20100000L,0x30100000L,0x20110000L,0x30110000L, ++0x20100004L,0x30100004L,0x20110004L,0x30110004L, ++0x00001000L,0x10001000L,0x00011000L,0x10011000L, ++0x00001004L,0x10001004L,0x00011004L,0x10011004L, ++0x20001000L,0x30001000L,0x20011000L,0x30011000L, ++0x20001004L,0x30001004L,0x20011004L,0x30011004L, ++0x00101000L,0x10101000L,0x00111000L,0x10111000L, ++0x00101004L,0x10101004L,0x00111004L,0x10111004L, ++0x20101000L,0x30101000L,0x20111000L,0x30111000L, ++0x20101004L,0x30101004L,0x20111004L,0x30111004L, ++},{ ++/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */ ++0x00000000L,0x08000000L,0x00000008L,0x08000008L, ++0x00000400L,0x08000400L,0x00000408L,0x08000408L, ++0x00020000L,0x08020000L,0x00020008L,0x08020008L, ++0x00020400L,0x08020400L,0x00020408L,0x08020408L, ++0x00000001L,0x08000001L,0x00000009L,0x08000009L, ++0x00000401L,0x08000401L,0x00000409L,0x08000409L, ++0x00020001L,0x08020001L,0x00020009L,0x08020009L, ++0x00020401L,0x08020401L,0x00020409L,0x08020409L, ++0x02000000L,0x0A000000L,0x02000008L,0x0A000008L, ++0x02000400L,0x0A000400L,0x02000408L,0x0A000408L, ++0x02020000L,0x0A020000L,0x02020008L,0x0A020008L, ++0x02020400L,0x0A020400L,0x02020408L,0x0A020408L, ++0x02000001L,0x0A000001L,0x02000009L,0x0A000009L, ++0x02000401L,0x0A000401L,0x02000409L,0x0A000409L, ++0x02020001L,0x0A020001L,0x02020009L,0x0A020009L, ++0x02020401L,0x0A020401L,0x02020409L,0x0A020409L, ++},{ ++/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */ ++0x00000000L,0x00000100L,0x00080000L,0x00080100L, ++0x01000000L,0x01000100L,0x01080000L,0x01080100L, ++0x00000010L,0x00000110L,0x00080010L,0x00080110L, ++0x01000010L,0x01000110L,0x01080010L,0x01080110L, ++0x00200000L,0x00200100L,0x00280000L,0x00280100L, ++0x01200000L,0x01200100L,0x01280000L,0x01280100L, ++0x00200010L,0x00200110L,0x00280010L,0x00280110L, ++0x01200010L,0x01200110L,0x01280010L,0x01280110L, ++0x00000200L,0x00000300L,0x00080200L,0x00080300L, ++0x01000200L,0x01000300L,0x01080200L,0x01080300L, ++0x00000210L,0x00000310L,0x00080210L,0x00080310L, ++0x01000210L,0x01000310L,0x01080210L,0x01080310L, ++0x00200200L,0x00200300L,0x00280200L,0x00280300L, ++0x01200200L,0x01200300L,0x01280200L,0x01280300L, ++0x00200210L,0x00200310L,0x00280210L,0x00280310L, ++0x01200210L,0x01200310L,0x01280210L,0x01280310L, ++},{ ++/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */ ++0x00000000L,0x04000000L,0x00040000L,0x04040000L, ++0x00000002L,0x04000002L,0x00040002L,0x04040002L, ++0x00002000L,0x04002000L,0x00042000L,0x04042000L, ++0x00002002L,0x04002002L,0x00042002L,0x04042002L, ++0x00000020L,0x04000020L,0x00040020L,0x04040020L, ++0x00000022L,0x04000022L,0x00040022L,0x04040022L, ++0x00002020L,0x04002020L,0x00042020L,0x04042020L, ++0x00002022L,0x04002022L,0x00042022L,0x04042022L, ++0x00000800L,0x04000800L,0x00040800L,0x04040800L, ++0x00000802L,0x04000802L,0x00040802L,0x04040802L, ++0x00002800L,0x04002800L,0x00042800L,0x04042800L, ++0x00002802L,0x04002802L,0x00042802L,0x04042802L, ++0x00000820L,0x04000820L,0x00040820L,0x04040820L, ++0x00000822L,0x04000822L,0x00040822L,0x04040822L, ++0x00002820L,0x04002820L,0x00042820L,0x04042820L, ++0x00002822L,0x04002822L,0x00042822L,0x04042822L, ++}}; +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/speed.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,329 @@ ++/* crypto/des/speed.c */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */ ++/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */ ++ ++#ifndef MSDOS ++#define TIMES ++#endif ++ ++#include ++#ifndef MSDOS ++#include ++#else ++#include ++extern int exit(); ++#endif ++#include ++#ifndef VMS ++#ifndef _IRIX ++#include ++#endif ++#ifdef TIMES ++#include ++#include ++#endif ++#else /* VMS */ ++#include ++struct tms { ++ time_t tms_utime; ++ time_t tms_stime; ++ time_t tms_uchild; /* I dunno... */ ++ time_t tms_uchildsys; /* so these names are a guess :-) */ ++ } ++#endif ++#ifndef TIMES ++#include ++#endif ++ ++#ifdef sun ++#include ++#include ++#endif ++ ++#include "des_locl.h" ++ ++/* The following if from times(3) man page. It may need to be changed */ ++#ifndef HZ ++# ifndef CLK_TCK ++# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */ ++# ifndef VMS ++# define HZ 100.0 ++# else /* VMS */ ++# define HZ 100.0 ++# endif ++# else /* _BSD_CLK_TCK_ */ ++# define HZ ((double)_BSD_CLK_TCK_) ++# endif ++# else /* CLK_TCK */ ++# define HZ ((double)CLK_TCK) ++# endif ++#endif ++ ++#define BUFSIZE ((long)1024) ++long run=0; ++ ++#ifndef NOPROTO ++double Time_F(int s); ++#else ++double Time_F(); ++#endif ++ ++#ifdef SIGALRM ++#if defined(__STDC__) || defined(sgi) || defined(_AIX) ++#define SIGRETTYPE void ++#else ++#define SIGRETTYPE int ++#endif ++ ++#ifndef NOPROTO ++SIGRETTYPE sig_done(int sig); ++#else ++SIGRETTYPE sig_done(); ++#endif ++ ++SIGRETTYPE sig_done(sig) ++int sig; ++ { ++ signal(SIGALRM,sig_done); ++ run=0; ++#ifdef LINT ++ sig=sig; ++#endif ++ } ++#endif ++ ++#define START 0 ++#define STOP 1 ++ ++double Time_F(s) ++int s; ++ { ++ double ret; ++#ifdef TIMES ++ static struct tms tstart,tend; ++ ++ if (s == START) ++ { ++ times(&tstart); ++ return(0); ++ } ++ else ++ { ++ times(&tend); ++ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ; ++ return((ret == 0.0)?1e-6:ret); ++ } ++#else /* !times() */ ++ static struct timeb tstart,tend; ++ long i; ++ ++ if (s == START) ++ { ++ ftime(&tstart); ++ return(0); ++ } ++ else ++ { ++ ftime(&tend); ++ i=(long)tend.millitm-(long)tstart.millitm; ++ ret=((double)(tend.time-tstart.time))+((double)i)/1e3; ++ return((ret == 0.0)?1e-6:ret); ++ } ++#endif ++ } ++ ++int main(argc,argv) ++int argc; ++char **argv; ++ { ++ long count; ++ static unsigned char buf[BUFSIZE]; ++ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}; ++ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12}; ++ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34}; ++ des_key_schedule sch,sch2,sch3; ++ double a,b,c,d,e; ++#ifndef SIGALRM ++ long ca,cb,cc,cd,ce; ++#endif ++ ++#ifndef TIMES ++ printf("To get the most acurate results, try to run this\n"); ++ printf("program when this computer is idle.\n"); ++#endif ++ ++ des_set_key((C_Block *)key2,sch2); ++ des_set_key((C_Block *)key3,sch3); ++ ++#ifndef SIGALRM ++ printf("First we calculate the approximate speed ...\n"); ++ des_set_key((C_Block *)key,sch); ++ count=10; ++ do { ++ long i; ++ DES_LONG data[2]; ++ ++ count*=2; ++ Time_F(START); ++ for (i=count; i; i--) ++ des_encrypt(data,&(sch[0]),DES_ENCRYPT); ++ d=Time_F(STOP); ++ } while (d < 3.0); ++ ca=count; ++ cb=count*3; ++ cc=count*3*8/BUFSIZE+1; ++ cd=count*8/BUFSIZE+1; ++ ce=count/20+1; ++ printf("Doing set_key %ld times\n",ca); ++#define COND(d) (count != (d)) ++#define COUNT(d) (d) ++#else ++#define COND(c) (run) ++#define COUNT(d) (count) ++ signal(SIGALRM,sig_done); ++ printf("Doing set_key for 10 seconds\n"); ++ alarm(10); ++#endif ++ ++ Time_F(START); ++ for (count=0,run=1; COND(ca); count++) ++ des_set_key((C_Block *)key,sch); ++ d=Time_F(STOP); ++ printf("%ld set_key's in %.2f seconds\n",count,d); ++ a=((double)COUNT(ca))/d; ++ ++#ifdef SIGALRM ++ printf("Doing des_encrypt's for 10 seconds\n"); ++ alarm(10); ++#else ++ printf("Doing des_encrypt %ld times\n",cb); ++#endif ++ Time_F(START); ++ for (count=0,run=1; COND(cb); count++) ++ { ++ DES_LONG data[2]; ++ ++ des_encrypt(data,&(sch[0]),DES_ENCRYPT); ++ } ++ d=Time_F(STOP); ++ printf("%ld des_encrypt's in %.2f second\n",count,d); ++ b=((double)COUNT(cb)*8)/d; ++ ++#ifdef SIGALRM ++ printf("Doing des_cbc_encrypt on %ld byte blocks for 10 seconds\n", ++ BUFSIZE); ++ alarm(10); ++#else ++ printf("Doing des_cbc_encrypt %ld times on %ld byte blocks\n",cc, ++ BUFSIZE); ++#endif ++ Time_F(START); ++ for (count=0,run=1; COND(cc); count++) ++ des_ncbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,&(sch[0]), ++ (C_Block *)&(key[0]),DES_ENCRYPT); ++ d=Time_F(STOP); ++ printf("%ld des_cbc_encrypt's of %ld byte blocks in %.2f second\n", ++ count,BUFSIZE,d); ++ c=((double)COUNT(cc)*BUFSIZE)/d; ++ ++#ifdef SIGALRM ++ printf("Doing des_ede_cbc_encrypt on %ld byte blocks for 10 seconds\n", ++ BUFSIZE); ++ alarm(10); ++#else ++ printf("Doing des_ede_cbc_encrypt %ld times on %ld byte blocks\n",cd, ++ BUFSIZE); ++#endif ++ Time_F(START); ++ for (count=0,run=1; COND(cd); count++) ++ des_ede3_cbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE, ++ &(sch[0]), ++ &(sch2[0]), ++ &(sch3[0]), ++ (C_Block *)&(key[0]), ++ DES_ENCRYPT); ++ d=Time_F(STOP); ++ printf("%ld des_ede_cbc_encrypt's of %ld byte blocks in %.2f second\n", ++ count,BUFSIZE,d); ++ d=((double)COUNT(cd)*BUFSIZE)/d; ++ ++#ifdef SIGALRM ++ printf("Doing crypt for 10 seconds\n"); ++ alarm(10); ++#else ++ printf("Doing crypt %ld times\n",ce); ++#endif ++ Time_F(START); ++ for (count=0,run=1; COND(ce); count++) ++ crypt("testing1","ef"); ++ e=Time_F(STOP); ++ printf("%ld crypts in %.2f second\n",count,e); ++ e=((double)COUNT(ce))/e; ++ ++ printf("set_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a); ++ printf("DES raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b); ++ printf("DES cbc bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c); ++ printf("DES ede cbc bytes per sec = %12.2f (%9.3fuS)\n",d,8.0e6/d); ++ printf("crypt per sec = %12.2f (%9.3fuS)\n",e,1.0e6/e); ++ exit(0); ++#if defined(LINT) || defined(MSDOS) ++ return(0); ++#endif ++ } +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/crypto/ciphers/des/spr.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,204 @@ ++/* crypto/des/spr.h */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++const DES_LONG des_SPtrans[8][64]={ ++{ ++/* nibble 0 */ ++0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, ++0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L, ++0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L, ++0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L, ++0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, ++0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, ++0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L, ++0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L, ++0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L, ++0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, ++0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, ++0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L, ++0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L, ++0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L, ++0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, ++0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L, ++},{ ++/* nibble 1 */ ++0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, ++0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L, ++0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L, ++0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L, ++0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, ++0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, ++0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L, ++0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L, ++0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L, ++0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, ++0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, ++0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L, ++0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L, ++0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L, ++0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, ++0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L, ++},{ ++/* nibble 2 */ ++0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, ++0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L, ++0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L, ++0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L, ++0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, ++0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, ++0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L, ++0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L, ++0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L, ++0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, ++0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, ++0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L, ++0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L, ++0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L, ++0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, ++0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L, ++},{ ++/* nibble 3 */ ++0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, ++0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L, ++0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L, ++0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L, ++0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, ++0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, ++0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L, ++0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L, ++0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L, ++0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, ++0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, ++0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L, ++0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L, ++0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L, ++0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, ++0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L, ++},{ ++/* nibble 4 */ ++0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, ++0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L, ++0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L, ++0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L, ++0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, ++0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, ++0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L, ++0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L, ++0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L, ++0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, ++0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, ++0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L, ++0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L, ++0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L, ++0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, ++0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L, ++},{ ++/* nibble 5 */ ++0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, ++0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L, ++0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L, ++0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L, ++0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, ++0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, ++0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L, ++0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L, ++0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L, ++0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, ++0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, ++0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L, ++0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L, ++0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L, ++0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, ++0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, ++},{ ++/* nibble 6 */ ++0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, ++0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L, ++0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L, ++0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L, ++0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, ++0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, ++0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L, ++0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L, ++0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L, ++0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, ++0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, ++0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L, ++0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L, ++0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L, ++0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, ++0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, ++},{ ++/* nibble 7 */ ++0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, ++0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L, ++0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L, ++0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L, ++0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, ++0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, ++0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L, ++0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L, ++0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L, ++0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, ++0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, ++0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L, ++0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L, ++0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L, ++0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, ++0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, ++}}; +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/crypto/aes.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,97 @@ ++// I retain copyright in this code but I encourage its free use provided ++// that I don't carry any responsibility for the results. I am especially ++// happy to see it used in free and open source software. If you do use ++// it I would appreciate an acknowledgement of its origin in the code or ++// the product that results and I would also appreciate knowing a little ++// about the use to which it is being put. I am grateful to Frank Yellin ++// for some ideas that are used in this implementation. ++// ++// Dr B. R. Gladman 6th April 2001. ++// ++// This is an implementation of the AES encryption algorithm (Rijndael) ++// designed by Joan Daemen and Vincent Rijmen. This version is designed ++// to provide both fixed and dynamic block and key lengths and can also ++// run with either big or little endian internal byte order (see aes.h). ++// It inputs block and key lengths in bytes with the legal values being ++// 16, 24 and 32. ++ ++/* ++ * Modified by Jari Ruusu, May 1 2001 ++ * - Fixed some compile warnings, code was ok but gcc warned anyway. ++ * - Changed basic types: byte -> unsigned char, word -> u_int32_t ++ * - Major name space cleanup: Names visible to outside now begin ++ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c ++ * - Removed C++ and DLL support as part of name space cleanup. ++ * - Eliminated unnecessary recomputation of tables. (actual bug fix) ++ * - Merged precomputed constant tables to aes.c file. ++ * - Removed data alignment restrictions for portability reasons. ++ * - Made block and key lengths accept bit count (128/192/256) ++ * as well byte count (16/24/32). ++ * - Removed all error checks. This change also eliminated the need ++ * to preinitialize the context struct to zero. ++ * - Removed some totally unused constants. ++ */ ++ ++#ifndef _AES_H ++#define _AES_H ++ ++#if defined(__linux__) && defined(__KERNEL__) ++# include ++#else ++# include ++#endif ++ ++// CONFIGURATION OPTIONS (see also aes.c) ++// ++// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or ++// leave this undefined for dynamically variable block size (this will ++// result in much slower code). ++// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If ++// left undefined a slower version providing variable block length is compiled ++ ++#define AES_BLOCK_SIZE 16 ++ ++// The number of key schedule words for different block and key lengths ++// allowing for method of computation which requires the length to be a ++// multiple of the key length ++// ++// Nk = 4 6 8 ++// ------------- ++// Nb = 4 | 60 60 64 ++// 6 | 96 90 96 ++// 8 | 120 120 120 ++ ++#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32) ++#define AES_KS_LENGTH 120 ++#define AES_RC_LENGTH 29 ++#else ++#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE ++#define AES_RC_LENGTH (9 * AES_BLOCK_SIZE) / 8 - 8 ++#endif ++ ++typedef struct ++{ ++ u_int32_t aes_Nkey; // the number of words in the key input block ++ u_int32_t aes_Nrnd; // the number of cipher rounds ++ u_int32_t aes_e_key[AES_KS_LENGTH]; // the encryption key schedule ++ u_int32_t aes_d_key[AES_KS_LENGTH]; // the decryption key schedule ++#if !defined(AES_BLOCK_SIZE) ++ u_int32_t aes_Ncol; // the number of columns in the cipher state ++#endif ++} aes_context; ++ ++// THE CIPHER INTERFACE ++ ++#if !defined(AES_BLOCK_SIZE) ++extern void aes_set_blk(aes_context *, const int); ++#endif ++extern void aes_set_key(aes_context *, const unsigned char [], const int, const int); ++extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []); ++extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []); ++ ++// The block length inputs to aes_set_block and aes_set_key are in numbers ++// of bytes or bits. The calls to subroutines must be made in the above ++// order but multiple calls can be made without repeating earlier calls ++// if their parameters have not changed. ++ ++#endif // _AES_H +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/crypto/aes_cbc.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,4 @@ ++/* Glue header */ ++#include "aes.h" ++int AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize); ++int AES_cbc_encrypt(aes_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt); +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/crypto/aes_xcbc_mac.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,12 @@ ++#ifndef _AES_XCBC_MAC_H ++#define _AES_XCBC_MAC_H ++ ++typedef u_int32_t aes_block[4]; ++typedef struct { ++ aes_context ctx_k1; ++ aes_block k2; ++ aes_block k3; ++} aes_context_mac; ++int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen); ++int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]); ++#endif /* _AES_XCBC_MAC_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/crypto/cbc_generic.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,110 @@ ++#ifndef _CBC_GENERIC_H ++#define _CBC_GENERIC_H ++/* ++ * CBC macro helpers ++ * ++ * Author: JuanJo Ciarlante ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ */ ++ ++/* ++ * Heavily inspired in loop_AES ++ */ ++#define CBC_IMPL_BLK16(name, ctx_type, addr_type, enc_func, dec_func) \ ++int name(ctx_type *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \ ++ int ret=ilen, pos; \ ++ const u_int32_t *iv_i; \ ++ if ((ilen) % 16) return 0; \ ++ if (encrypt) { \ ++ pos=0; \ ++ while(pos=0) { \ ++ dec_func(ctx, (const addr_type) in, (addr_type) out); \ ++ if (pos==0) \ ++ iv_i=(const u_int32_t*) (iv); \ ++ else \ ++ iv_i=(const u_int32_t*) (in-16); \ ++ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \ ++ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \ ++ *((u_int32_t *)(&out[ 8])) ^= iv_i[2]; \ ++ *((u_int32_t *)(&out[12])) ^= iv_i[3]; \ ++ in-=16; \ ++ out-=16; \ ++ pos-=16; \ ++ } \ ++ } \ ++ return ret; \ ++} ++#define CBC_IMPL_BLK8(name, ctx_type, addr_type, enc_func, dec_func) \ ++int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \ ++ int ret=ilen, pos; \ ++ const u_int32_t *iv_i; \ ++ if ((ilen) % 8) return 0; \ ++ if (encrypt) { \ ++ pos=0; \ ++ while(pos=0) { \ ++ dec_func(ctx, (const addr_type)in, (addr_type)out); \ ++ if (pos==0) \ ++ iv_i=(const u_int32_t*) (iv); \ ++ else \ ++ iv_i=(const u_int32_t*) (in-8); \ ++ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \ ++ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \ ++ in-=8; \ ++ out-=8; \ ++ pos-=8; \ ++ } \ ++ } \ ++ return ret; \ ++} ++#define CBC_DECL(name, ctx_type) \ ++int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) ++/* ++Eg.: ++CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt); ++CBC_DECL(AES_cbc_encrypt, aes_context); ++*/ ++#endif /* _CBC_GENERIC_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/crypto/des.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,298 @@ ++/* crypto/des/des.org */ ++/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) ++ * All rights reserved. ++ * ++ * This package is an SSL implementation written ++ * by Eric Young (eay@cryptsoft.com). ++ * The implementation was written so as to conform with Netscapes SSL. ++ * ++ * This library is free for commercial and non-commercial use as long as ++ * the following conditions are aheared to. The following conditions ++ * apply to all code found in this distribution, be it the RC4, RSA, ++ * lhash, DES, etc., code; not just the SSL code. The SSL documentation ++ * included with this distribution is covered by the same copyright terms ++ * except that the holder is Tim Hudson (tjh@cryptsoft.com). ++ * ++ * Copyright remains Eric Young's, and as such any Copyright notices in ++ * the code are not to be removed. ++ * If this package is used in a product, Eric Young should be given attribution ++ * as the author of the parts of the library used. ++ * This can be in the form of a textual message at program startup or ++ * in documentation (online or textual) provided with the package. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * "This product includes cryptographic software written by ++ * Eric Young (eay@cryptsoft.com)" ++ * The word 'cryptographic' can be left out if the rouines from the library ++ * being used are not cryptographic related :-). ++ * 4. If you include any Windows specific code (or a derivative thereof) from ++ * the apps directory (application code) you must include an acknowledgement: ++ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * The licence and distribution terms for any publically available version or ++ * derivative of this code cannot be changed. i.e. this code cannot simply be ++ * copied and put under another distribution licence ++ * [including the GNU Public Licence.] ++ */ ++ ++/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ++ * ++ * Always modify des.org since des.h is automatically generated from ++ * it during SSLeay configuration. ++ * ++ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ++ */ ++ ++#ifndef HEADER_DES_H ++#define HEADER_DES_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a ++ * %20 speed up (longs are 8 bytes, int's are 4). */ ++/* Must be unsigned int on ia64/Itanium or DES breaks badly */ ++ ++#ifdef __KERNEL__ ++#include ++#else ++#include ++#endif ++ ++#ifndef DES_LONG ++#define DES_LONG u_int32_t ++#endif ++ ++typedef unsigned char des_cblock[8]; ++typedef struct { des_cblock ks; } des_key_schedule[16]; ++ ++#define DES_KEY_SZ (sizeof(des_cblock)) ++#define DES_SCHEDULE_SZ (sizeof(des_key_schedule)) ++ ++#define DES_ENCRYPT 1 ++#define DES_DECRYPT 0 ++ ++#define DES_CBC_MODE 0 ++#define DES_PCBC_MODE 1 ++ ++#define des_ecb2_encrypt(i,o,k1,k2,e) \ ++ des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) ++ ++#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ ++ des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) ++ ++#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ ++ des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) ++ ++#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ ++ des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) ++ ++#define C_Block des_cblock ++#define Key_schedule des_key_schedule ++#ifdef KERBEROS ++#define ENCRYPT DES_ENCRYPT ++#define DECRYPT DES_DECRYPT ++#endif ++#define KEY_SZ DES_KEY_SZ ++#define string_to_key des_string_to_key ++#define read_pw_string des_read_pw_string ++#define random_key des_random_key ++#define pcbc_encrypt des_pcbc_encrypt ++#define set_key des_set_key ++#define key_sched des_key_sched ++#define ecb_encrypt des_ecb_encrypt ++#define cbc_encrypt des_cbc_encrypt ++#define ncbc_encrypt des_ncbc_encrypt ++#define xcbc_encrypt des_xcbc_encrypt ++#define cbc_cksum des_cbc_cksum ++#define quad_cksum des_quad_cksum ++ ++/* For compatibility with the MIT lib - eay 20/05/92 */ ++typedef des_key_schedule bit_64; ++#define des_fixup_key_parity des_set_odd_parity ++#define des_check_key_parity check_parity ++ ++extern int des_check_key; /* defaults to false */ ++extern int des_rw_mode; /* defaults to DES_PCBC_MODE */ ++ ++/* The next line is used to disable full ANSI prototypes, if your ++ * compiler has problems with the prototypes, make sure this line always ++ * evaluates to true :-) */ ++#if defined(MSDOS) || defined(__STDC__) ++#undef NOPROTO ++#endif ++#ifndef NOPROTO ++char *des_options(void); ++void des_ecb3_encrypt(des_cblock *input,des_cblock *output, ++ des_key_schedule ks1,des_key_schedule ks2, ++ des_key_schedule ks3, int enc); ++DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output, ++ long length,des_key_schedule schedule,des_cblock *ivec); ++void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length, ++ des_key_schedule schedule,des_cblock *ivec,int enc); ++void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length, ++ des_key_schedule schedule,des_cblock *ivec,int enc); ++void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length, ++ des_key_schedule schedule,des_cblock *ivec, ++ des_cblock *inw,des_cblock *outw,int enc); ++void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits, ++ long length,des_key_schedule schedule,des_cblock *ivec,int enc); ++void des_ecb_encrypt(des_cblock *input,des_cblock *output, ++ des_key_schedule ks,int enc); ++void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc); ++void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc); ++void des_encrypt3(DES_LONG *data, des_key_schedule ks1, ++ des_key_schedule ks2, des_key_schedule ks3); ++void des_decrypt3(DES_LONG *data, des_key_schedule ks1, ++ des_key_schedule ks2, des_key_schedule ks3); ++void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, ++ long length, des_key_schedule ks1, des_key_schedule ks2, ++ des_key_schedule ks3, des_cblock *ivec, int enc); ++void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out, ++ long length, des_key_schedule ks1, des_key_schedule ks2, ++ des_key_schedule ks3, des_cblock *ivec, int *num, int enc); ++void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out, ++ long length, des_key_schedule ks1, des_key_schedule ks2, ++ des_key_schedule ks3, des_cblock *ivec, int *num); ++ ++void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white), ++ des_cblock (*out_white)); ++ ++int des_enc_read(int fd,char *buf,int len,des_key_schedule sched, ++ des_cblock *iv); ++int des_enc_write(int fd,char *buf,int len,des_key_schedule sched, ++ des_cblock *iv); ++char *des_fcrypt(const char *buf,const char *salt, char *ret); ++#ifdef PERL5 ++char *des_crypt(const char *buf,const char *salt); ++#else ++/* some stupid compilers complain because I have declared char instead ++ * of const char */ ++#ifndef __KERNEL__ ++#ifdef HEADER_DES_LOCL_H ++char *crypt(const char *buf,const char *salt); ++#else /* HEADER_DES_LOCL_H */ ++char *crypt(void); ++#endif /* HEADER_DES_LOCL_H */ ++#endif /* __KERNEL__ */ ++#endif /* PERL5 */ ++void des_ofb_encrypt(unsigned char *in,unsigned char *out, ++ int numbits,long length,des_key_schedule schedule,des_cblock *ivec); ++void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length, ++ des_key_schedule schedule,des_cblock *ivec,int enc); ++DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output, ++ long length,int out_count,des_cblock *seed); ++void des_random_seed(des_cblock key); ++void des_random_key(des_cblock ret); ++int des_read_password(des_cblock *key,char *prompt,int verify); ++int des_read_2passwords(des_cblock *key1,des_cblock *key2, ++ char *prompt,int verify); ++int des_read_pw_string(char *buf,int length,char *prompt,int verify); ++void des_set_odd_parity(des_cblock *key); ++int des_is_weak_key(des_cblock *key); ++int des_set_key(des_cblock *key,des_key_schedule schedule); ++int des_key_sched(des_cblock *key,des_key_schedule schedule); ++void des_string_to_key(char *str,des_cblock *key); ++void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2); ++void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length, ++ des_key_schedule schedule, des_cblock *ivec, int *num, int enc); ++void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length, ++ des_key_schedule schedule, des_cblock *ivec, int *num); ++int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify); ++ ++/* Extra functions from Mark Murray */ ++/* The following functions are not in the normal unix build or the ++ * SSLeay build. When using the SSLeay build, use RAND_seed() ++ * and RAND_bytes() instead. */ ++int des_new_random_key(des_cblock *key); ++void des_init_random_number_generator(des_cblock *key); ++void des_set_random_generator_seed(des_cblock *key); ++void des_set_sequence_number(des_cblock new_sequence_number); ++void des_generate_random_block(des_cblock *block); ++ ++#else ++ ++char *des_options(); ++void des_ecb3_encrypt(); ++DES_LONG des_cbc_cksum(); ++void des_cbc_encrypt(); ++void des_ncbc_encrypt(); ++void des_xcbc_encrypt(); ++void des_cfb_encrypt(); ++void des_ede3_cfb64_encrypt(); ++void des_ede3_ofb64_encrypt(); ++void des_ecb_encrypt(); ++void des_encrypt(); ++void des_encrypt2(); ++void des_encrypt3(); ++void des_decrypt3(); ++void des_ede3_cbc_encrypt(); ++int des_enc_read(); ++int des_enc_write(); ++char *des_fcrypt(); ++#ifdef PERL5 ++char *des_crypt(); ++#else ++char *crypt(); ++#endif ++void des_ofb_encrypt(); ++void des_pcbc_encrypt(); ++DES_LONG des_quad_cksum(); ++void des_random_seed(); ++void des_random_key(); ++int des_read_password(); ++int des_read_2passwords(); ++int des_read_pw_string(); ++void des_set_odd_parity(); ++int des_is_weak_key(); ++int des_set_key(); ++int des_key_sched(); ++void des_string_to_key(); ++void des_string_to_2keys(); ++void des_cfb64_encrypt(); ++void des_ofb64_encrypt(); ++int des_read_pw(); ++void des_xwhite_in2out(); ++ ++/* Extra functions from Mark Murray */ ++/* The following functions are not in the normal unix build or the ++ * SSLeay build. When using the SSLeay build, use RAND_seed() ++ * and RAND_bytes() instead. */ ++#ifdef FreeBSD ++int des_new_random_key(); ++void des_init_random_number_generator(); ++void des_set_random_generator_seed(); ++void des_set_sequence_number(); ++void des_generate_random_block(); ++#endif ++ ++#endif ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/mast.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,33 @@ ++struct mast_callbacks { ++ int (*packet_encap)(struct device *mast, void *context, ++ struct sk_buff *skb, int flowref); ++ int (*link_inquire)(struct device *mast, void *context); ++}; ++ ++ ++struct device *mast_init (int family, ++ struct mast_callbacks *callbacks, ++ unsigned int flags, ++ unsigned int desired_unit, ++ unsigned int max_flowref, ++ void *context); ++ ++int mast_destroy(struct device *mast); ++ ++int mast_recv(struct device *mast, struct sk_buff *skb, int flowref); ++ ++/* free this skb as being useless, increment failure count. */ ++int mast_toast(struct device *mast, struct sk_buff *skb, int flowref); ++ ++int mast_linkstat (struct device *mast, int flowref, ++ int status); ++ ++int mast_setreference (struct device *mast, ++ int defaultSA); ++ ++int mast_setneighbor (struct device *mast, ++ struct sockaddr *source, ++ struct sockaddr *destination, ++ int flowref); ++ ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,513 @@ ++#ifndef _OPENSWAN_H ++/* ++ * header file for FreeS/WAN library functions ++ * Copyright (C) 1998, 1999, 2000 Henry Spencer. ++ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: openswan.h,v 1.89 2004/06/08 00:53:13 mcr Exp $ ++ */ ++#define _OPENSWAN_H /* seen it, no need to see it again */ ++ ++ ++ ++/* ++ * We've just got to have some datatypes defined... And annoyingly, just ++ * where we get them depends on whether we're in userland or not. ++ */ ++/* things that need to come from one place or the other, depending */ ++#ifdef __KERNEL__ ++#include ++#include ++#include ++#include ++#include ++#define assert(foo) /* nothing */ ++#else ++#include ++#include ++#include ++#include ++#include ++#include ++ ++# define uint8_t u_int8_t ++# define uint16_t u_int16_t ++# define uint32_t u_int32_t ++# define uint64_t u_int64_t ++ ++ ++# define DEBUG_NO_STATIC static ++ ++#endif ++ ++#include ++ ++ ++/* ++ * Grab the kernel version to see if we have NET_21, and therefore ++ * IPv6. Some of this is repeated from ipsec_kversions.h. Of course, ++ * we aren't really testing if the kernel has IPv6, but rather if the ++ * the include files do. ++ */ ++#include ++#ifndef KERNEL_VERSION ++#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) ++#define NET_21 ++#endif ++ ++#ifndef IPPROTO_COMP ++# define IPPROTO_COMP 108 ++#endif /* !IPPROTO_COMP */ ++ ++#ifndef IPPROTO_INT ++# define IPPROTO_INT 61 ++#endif /* !IPPROTO_INT */ ++ ++#ifdef CONFIG_IPSEC_DEBUG ++#ifndef DEBUG_NO_STATIC ++# define DEBUG_NO_STATIC ++#endif ++#else /* CONFIG_IPSEC_DEBUG */ ++#ifndef DEBUG_NO_STATIC ++# define DEBUG_NO_STATIC static ++#endif ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL /* KERNEL ifdef */ ++#ifndef NAT_TRAVERSAL ++#define NAT_TRAVERSAL ++#endif ++#endif ++#ifdef NAT_TRAVERSAL ++#define ESPINUDP_WITH_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */ ++#define ESPINUDP_WITH_NON_ESP 2 /* draft-ietf-ipsec-nat-t-ike-02 */ ++#endif ++ ++/* ++ * Basic data types for the address-handling functions. ++ * ip_address and ip_subnet are supposed to be opaque types; do not ++ * use their definitions directly, they are subject to change! ++ */ ++ ++/* first, some quick fakes in case we're on an old system with no IPv6 */ ++#ifndef s6_addr16 ++struct in6_addr { ++ union ++ { ++ __u8 u6_addr8[16]; ++ __u16 u6_addr16[8]; ++ __u32 u6_addr32[4]; ++ } in6_u; ++#define s6_addr in6_u.u6_addr8 ++#define s6_addr16 in6_u.u6_addr16 ++#define s6_addr32 in6_u.u6_addr32 ++}; ++struct sockaddr_in6 { ++ unsigned short int sin6_family; /* AF_INET6 */ ++ __u16 sin6_port; /* Transport layer port # */ ++ __u32 sin6_flowinfo; /* IPv6 flow information */ ++ struct in6_addr sin6_addr; /* IPv6 address */ ++ __u32 sin6_scope_id; /* scope id (new in RFC2553) */ ++}; ++#endif /* !s6_addr16 */ ++ ++/* then the main types */ ++typedef struct { ++ union { ++ struct sockaddr_in v4; ++ struct sockaddr_in6 v6; ++ } u; ++} ip_address; ++typedef struct { ++ ip_address addr; ++ int maskbits; ++} ip_subnet; ++ ++/* and the SA ID stuff */ ++#ifdef __KERNEL__ ++typedef __u32 ipsec_spi_t; ++#else ++typedef u_int32_t ipsec_spi_t; ++#endif ++typedef struct { /* to identify an SA, we need: */ ++ ip_address dst; /* A. destination host */ ++ ipsec_spi_t spi; /* B. 32-bit SPI, assigned by dest. host */ ++# define SPI_PASS 256 /* magic values... */ ++# define SPI_DROP 257 /* ...for use... */ ++# define SPI_REJECT 258 /* ...with SA_INT */ ++# define SPI_HOLD 259 ++# define SPI_TRAP 260 ++# define SPI_TRAPSUBNET 261 ++ int proto; /* C. protocol */ ++# define SA_ESP 50 /* IPPROTO_ESP */ ++# define SA_AH 51 /* IPPROTO_AH */ ++# define SA_IPIP 4 /* IPPROTO_IPIP */ ++# define SA_COMP 108 /* IPPROTO_COMP */ ++# define SA_INT 61 /* IANA reserved for internal use */ ++} ip_said; ++ ++/* misc */ ++typedef const char *err_t; /* error message, or NULL for success */ ++struct prng { /* pseudo-random-number-generator guts */ ++ unsigned char sbox[256]; ++ int i, j; ++ unsigned long count; ++}; ++ ++ ++/* ++ * definitions for user space, taken from freeswan/ipsec_sa.h ++ */ ++typedef uint32_t IPsecSAref_t; ++ ++#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t)) ++ ++#define IPsecSAref2NFmark(x) ((x) << (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH)) ++#define NFmark2IPsecSAref(x) ((x) >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH)) ++ ++#define IPSEC_SAREF_NULL (~((IPsecSAref_t)0)) ++ ++/* GCC magic for use in function definitions! */ ++#ifdef GCC_LINT ++# define PRINTF_LIKE(n) __attribute__ ((format(printf, n, n+1))) ++# define NEVER_RETURNS __attribute__ ((noreturn)) ++# define UNUSED __attribute__ ((unused)) ++# define BLANK_FORMAT " " /* GCC_LINT whines about empty formats */ ++#else ++# define PRINTF_LIKE(n) /* ignore */ ++# define NEVER_RETURNS /* ignore */ ++# define UNUSED /* ignore */ ++# define BLANK_FORMAT "" ++#endif ++ ++ ++ ++ ++ ++/* ++ * new IPv6-compatible functions ++ */ ++ ++/* text conversions */ ++err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst); ++size_t ultot(unsigned long src, int format, char *buf, size_t buflen); ++#define ULTOT_BUF (22+1) /* holds 64 bits in octal */ ++err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst); ++err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst); ++size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen); ++/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */ ++#define ADDRTOT_BUF (32*2 + 3 + 1 + 3 + 1 + 1) ++err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst); ++size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen); ++#define SUBNETTOT_BUF (ADDRTOT_BUF + 1 + 3) ++size_t subnetporttot(const ip_subnet *src, int format, char *buf, size_t buflen); ++#define SUBNETPROTOTOT_BUF (SUBNETTOTO_BUF + ULTOT_BUF) ++err_t ttosa(const char *src, size_t srclen, ip_said *dst); ++size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen); ++#define SATOT_BUF (5 + ULTOA_BUF + 1 + ADDRTOT_BUF) ++err_t ttodata(const char *src, size_t srclen, int base, char *buf, ++ size_t buflen, size_t *needed); ++err_t ttodatav(const char *src, size_t srclen, int base, ++ char *buf, size_t buflen, size_t *needed, ++ char *errp, size_t errlen, unsigned int flags); ++#define TTODATAV_BUF 40 /* ttodatav's largest non-literal message */ ++#define TTODATAV_IGNORESPACE (1<<1) /* ignore spaces in base64 encodings*/ ++#define TTODATAV_SPACECOUNTS 0 /* do not ignore spaces in base64 */ ++ ++size_t datatot(const char *src, size_t srclen, int format, char *buf, ++ size_t buflen); ++size_t keyblobtoid(const unsigned char *src, size_t srclen, char *dst, ++ size_t dstlen); ++size_t splitkeytoid(const unsigned char *e, size_t elen, const unsigned char *m, ++ size_t mlen, char *dst, size_t dstlen); ++#define KEYID_BUF 10 /* up to 9 text digits plus NUL */ ++err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port, ++ int *has_port_wildcard); ++ ++/* initializations */ ++void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst); ++err_t loopbackaddr(int af, ip_address *dst); ++err_t unspecaddr(int af, ip_address *dst); ++err_t anyaddr(int af, ip_address *dst); ++err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst); ++err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst); ++err_t addrtosubnet(const ip_address *addr, ip_subnet *dst); ++ ++/* misc. conversions and related */ ++err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst); ++int addrtypeof(const ip_address *src); ++int subnettypeof(const ip_subnet *src); ++size_t addrlenof(const ip_address *src); ++size_t addrbytesptr(const ip_address *src, const unsigned char **dst); ++size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen); ++int masktocount(const ip_address *src); ++void networkof(const ip_subnet *src, ip_address *dst); ++void maskof(const ip_subnet *src, ip_address *dst); ++ ++/* tests */ ++int sameaddr(const ip_address *a, const ip_address *b); ++int addrcmp(const ip_address *a, const ip_address *b); ++int samesubnet(const ip_subnet *a, const ip_subnet *b); ++int addrinsubnet(const ip_address *a, const ip_subnet *s); ++int subnetinsubnet(const ip_subnet *a, const ip_subnet *b); ++int subnetishost(const ip_subnet *s); ++int samesaid(const ip_said *a, const ip_said *b); ++int sameaddrtype(const ip_address *a, const ip_address *b); ++int samesubnettype(const ip_subnet *a, const ip_subnet *b); ++int isanyaddr(const ip_address *src); ++int isunspecaddr(const ip_address *src); ++int isloopbackaddr(const ip_address *src); ++ ++/* low-level grot */ ++int portof(const ip_address *src); ++void setportof(int port, ip_address *dst); ++struct sockaddr *sockaddrof(ip_address *src); ++size_t sockaddrlenof(const ip_address *src); ++ ++/* PRNG */ ++void prng_init(struct prng *prng, const unsigned char *key, size_t keylen); ++void prng_bytes(struct prng *prng, unsigned char *dst, size_t dstlen); ++unsigned long prng_count(struct prng *prng); ++void prng_final(struct prng *prng); ++ ++/* odds and ends */ ++const char *ipsec_version_code(void); ++const char *ipsec_version_string(void); ++const char **ipsec_copyright_notice(void); ++ ++const char *dns_string_rr(int rr, char *buf, int bufsize); ++const char *dns_string_datetime(time_t seconds, ++ char *buf, ++ int bufsize); ++ ++ ++/* ++ * old functions, to be deleted eventually ++ */ ++ ++/* unsigned long */ ++const char * /* NULL for success, else string literal */ ++atoul( ++ const char *src, ++ size_t srclen, /* 0 means strlen(src) */ ++ int base, /* 0 means figure it out */ ++ unsigned long *resultp ++); ++size_t /* space needed for full conversion */ ++ultoa( ++ unsigned long n, ++ int base, ++ char *dst, ++ size_t dstlen ++); ++#define ULTOA_BUF 21 /* just large enough for largest result, */ ++ /* assuming 64-bit unsigned long! */ ++ ++/* Internet addresses */ ++const char * /* NULL for success, else string literal */ ++atoaddr( ++ const char *src, ++ size_t srclen, /* 0 means strlen(src) */ ++ struct in_addr *addr ++); ++size_t /* space needed for full conversion */ ++addrtoa( ++ struct in_addr addr, ++ int format, /* character; 0 means default */ ++ char *dst, ++ size_t dstlen ++); ++#define ADDRTOA_BUF 16 /* just large enough for largest result */ ++ ++/* subnets */ ++const char * /* NULL for success, else string literal */ ++atosubnet( ++ const char *src, ++ size_t srclen, /* 0 means strlen(src) */ ++ struct in_addr *addr, ++ struct in_addr *mask ++); ++size_t /* space needed for full conversion */ ++subnettoa( ++ struct in_addr addr, ++ struct in_addr mask, ++ int format, /* character; 0 means default */ ++ char *dst, ++ size_t dstlen ++); ++#define SUBNETTOA_BUF 32 /* large enough for worst case result */ ++ ++/* ranges */ ++const char * /* NULL for success, else string literal */ ++atoasr( ++ const char *src, ++ size_t srclen, /* 0 means strlen(src) */ ++ char *type, /* 'a', 's', 'r' */ ++ struct in_addr *addrs /* two-element array */ ++); ++size_t /* space needed for full conversion */ ++rangetoa( ++ struct in_addr *addrs, /* two-element array */ ++ int format, /* character; 0 means default */ ++ char *dst, ++ size_t dstlen ++); ++#define RANGETOA_BUF 34 /* large enough for worst case result */ ++ ++/* data types for SA conversion functions */ ++ ++/* generic data, e.g. keys */ ++const char * /* NULL for success, else string literal */ ++atobytes( ++ const char *src, ++ size_t srclen, /* 0 means strlen(src) */ ++ char *dst, ++ size_t dstlen, ++ size_t *lenp /* NULL means don't bother telling me */ ++); ++size_t /* 0 failure, else true size */ ++bytestoa( ++ const char *src, ++ size_t srclen, ++ int format, /* character; 0 means default */ ++ char *dst, ++ size_t dstlen ++); ++ ++/* old versions of generic-data functions; deprecated */ ++size_t /* 0 failure, else true size */ ++atodata( ++ const char *src, ++ size_t srclen, /* 0 means strlen(src) */ ++ char *dst, ++ size_t dstlen ++); ++size_t /* 0 failure, else true size */ ++datatoa( ++ const char *src, ++ size_t srclen, ++ int format, /* character; 0 means default */ ++ char *dst, ++ size_t dstlen ++); ++ ++/* part extraction and special addresses */ ++struct in_addr ++subnetof( ++ struct in_addr addr, ++ struct in_addr mask ++); ++struct in_addr ++hostof( ++ struct in_addr addr, ++ struct in_addr mask ++); ++struct in_addr ++broadcastof( ++ struct in_addr addr, ++ struct in_addr mask ++); ++ ++/* mask handling */ ++int ++goodmask( ++ struct in_addr mask ++); ++int ++masktobits( ++ struct in_addr mask ++); ++struct in_addr ++bitstomask( ++ int n ++); ++ ++ ++ ++/* ++ * general utilities ++ */ ++ ++#ifndef __KERNEL__ ++/* option pickup from files (userland only because of use of FILE) */ ++const char *optionsfrom(const char *filename, int *argcp, char ***argvp, ++ int optind, FILE *errorreport); ++ ++/* sanitize a string */ ++extern size_t sanitize_string(char *buf, size_t size); ++ ++#endif ++ ++ ++/* ++ * ENUM of klips debugging values. Not currently used in klips. ++ * debug flag is actually 32 -bits, but only one bit is ever used, ++ * so we can actually pack it all into a single 32-bit word. ++ */ ++enum klips_debug_flags { ++ KDF_VERBOSE = 0, ++ KDF_XMIT = 1, ++ KDF_NETLINK = 2, /* obsolete */ ++ KDF_XFORM = 3, ++ KDF_EROUTE = 4, ++ KDF_SPI = 5, ++ KDF_RADIJ = 6, ++ KDF_ESP = 7, ++ KDF_AH = 8, /* obsolete */ ++ KDF_RCV = 9, ++ KDF_TUNNEL = 10, ++ KDF_PFKEY = 11, ++ KDF_COMP = 12 ++}; ++ ++ ++/* ++ * Debugging levels for pfkey_lib_debug ++ */ ++#define PF_KEY_DEBUG_PARSE_NONE 0 ++#define PF_KEY_DEBUG_PARSE_PROBLEM 1 ++#define PF_KEY_DEBUG_PARSE_STRUCT 2 ++#define PF_KEY_DEBUG_PARSE_FLOW 4 ++#define PF_KEY_DEBUG_BUILD 8 ++#define PF_KEY_DEBUG_PARSE_MAX 15 ++ ++extern unsigned int pfkey_lib_debug; /* bits selecting what to report */ ++ ++/* ++ * pluto and lwdnsq need to know the maximum size of the commands to, ++ * and replies from lwdnsq. ++ */ ++ ++#define LWDNSQ_CMDBUF_LEN 1024 ++#define LWDNSQ_RESULT_LEN_MAX 4096 ++ ++ ++/* syntax for passthrough SA */ ++#ifndef PASSTHROUGHNAME ++#define PASSTHROUGHNAME "%passthrough" ++#define PASSTHROUGH4NAME "%passthrough4" ++#define PASSTHROUGH6NAME "%passthrough6" ++#define PASSTHROUGHIS "tun0@0.0.0.0" ++#define PASSTHROUGH4IS "tun0@0.0.0.0" ++#define PASSTHROUGH6IS "tun0@::" ++#define PASSTHROUGHTYPE "tun" ++#define PASSTHROUGHSPI 0 ++#define PASSTHROUGHDST 0 ++#endif ++ ++ ++ ++#endif /* _OPENSWAN_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipcomp.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,61 @@ ++/* ++ * IPCOMP zlib interface code. ++ * Copyright (C) 2000 Svenning Soerensen ++ * Copyright (C) 2000, 2001 Richard Guy Briggs ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ ++ RCSID $Id: ipcomp.h,v 1.13 2004/04/05 19:55:04 mcr Exp $ ++ ++ */ ++ ++/* SSS */ ++ ++#ifndef _IPCOMP_H ++#define _IPCOMP_H ++ ++/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */ ++#ifndef IPCOMP_PREFIX ++#define IPCOMP_PREFIX ++#endif /* IPCOMP_PREFIX */ ++ ++#ifndef IPPROTO_COMP ++#define IPPROTO_COMP 108 ++#endif /* IPPROTO_COMP */ ++ ++#ifdef CONFIG_IPSEC_DEBUG ++extern int sysctl_ipsec_debug_ipcomp; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++struct ipcomphdr { /* IPCOMP header */ ++ __u8 ipcomp_nh; /* Next header (protocol) */ ++ __u8 ipcomp_flags; /* Reserved, must be 0 */ ++ __u16 ipcomp_cpi; /* Compression Parameter Index */ ++}; ++ ++extern struct inet_protocol comp_protocol; ++extern int sysctl_ipsec_debug_ipcomp; ++ ++#define IPCOMP_UNCOMPRESSABLE 0x000000001 ++#define IPCOMP_COMPRESSIONERROR 0x000000002 ++#define IPCOMP_PARMERROR 0x000000004 ++#define IPCOMP_DECOMPRESSIONERROR 0x000000008 ++ ++#define IPCOMP_ADAPT_INITIAL_TRIES 8 ++#define IPCOMP_ADAPT_INITIAL_SKIP 4 ++#define IPCOMP_ADAPT_SUBSEQ_TRIES 2 ++#define IPCOMP_ADAPT_SUBSEQ_SKIP 8 ++ ++/* Function prototypes */ ++struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags); ++struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags); ++ ++#endif /* _IPCOMP_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_ah.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,190 @@ ++/* ++ * Authentication Header declarations ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_ah.h,v 1.23 2004/04/05 19:55:04 mcr Exp $ ++ */ ++ ++#include "ipsec_md5h.h" ++#include "ipsec_sha1.h" ++ ++#ifndef IPPROTO_AH ++#define IPPROTO_AH 51 ++#endif /* IPPROTO_AH */ ++ ++#include "ipsec_auth.h" ++ ++#ifdef __KERNEL__ ++ ++extern struct inet_protocol ah_protocol; ++ ++struct options; ++ ++struct ahhdr /* Generic AH header */ ++{ ++ __u8 ah_nh; /* Next header (protocol) */ ++ __u8 ah_hl; /* AH length, in 32-bit words */ ++ __u16 ah_rv; /* reserved, must be 0 */ ++ __u32 ah_spi; /* Security Parameters Index */ ++ __u32 ah_rpl; /* Replay prevention */ ++ __u8 ah_data[AHHMAC_HASHLEN];/* Authentication hash */ ++}; ++#define AH_BASIC_LEN 8 /* basic AH header is 8 bytes, nh,hl,rv,spi ++ * and the ah_hl, says how many bytes after that ++ * to cover. */ ++ ++extern struct xform_functions ah_xform_funcs[]; ++ ++#ifdef CONFIG_IPSEC_DEBUG ++extern int debug_ah; ++#endif /* CONFIG_IPSEC_DEBUG */ ++#endif /* __KERNEL__ */ ++ ++/* ++ * $Log: ipsec_ah.h,v $ ++ * Revision 1.23 2004/04/05 19:55:04 mcr ++ * Moved from linux/include/freeswan/ipsec_ah.h,v ++ * ++ * Revision 1.22 2004/04/05 19:41:05 mcr ++ * merged alg-branch code. ++ * ++ * Revision 1.21 2003/12/13 19:10:16 mcr ++ * refactored rcv and xmit code - same as FS 2.05. ++ * ++ * Revision 1.22 2003/12/11 20:14:58 mcr ++ * refactored the xmit code, to move all encapsulation ++ * code into protocol functions. Note that all functions ++ * are essentially done by a single function, which is probably ++ * wrong. ++ * the rcv_functions structures are renamed xform_functions. ++ * ++ * Revision 1.21 2003/12/06 21:21:19 mcr ++ * split up receive path into per-transform files, for ++ * easier later removal. ++ * ++ * Revision 1.20.8.1 2003/12/22 15:25:52 jjo ++ * Merged algo-0.8.1-rc11-test1 into alg-branch ++ * ++ * Revision 1.20 2003/02/06 02:21:34 rgb ++ * ++ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h . ++ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr". ++ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code. ++ * ++ * Revision 1.19 2002/09/16 21:19:13 mcr ++ * fixes for west-ah-icmp-01 - length of AH header must be ++ * calculated properly, and next_header field properly copied. ++ * ++ * Revision 1.18 2002/05/14 02:37:02 rgb ++ * Change reference from _TDB to _IPSA. ++ * ++ * Revision 1.17 2002/04/24 07:36:46 mcr ++ * Moved from ./klips/net/ipsec/ipsec_ah.h,v ++ * ++ * Revision 1.16 2002/02/20 01:27:06 rgb ++ * Ditched a pile of structs only used by the old Netlink interface. ++ * ++ * Revision 1.15 2001/12/11 02:35:57 rgb ++ * Change "struct net_device" to "struct device" for 2.2 compatibility. ++ * ++ * Revision 1.14 2001/11/26 09:23:47 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.13.2.1 2001/09/25 02:18:24 mcr ++ * replace "struct device" with "struct netdevice" ++ * ++ * Revision 1.13 2001/06/14 19:35:08 rgb ++ * Update copyright date. ++ * ++ * Revision 1.12 2000/09/12 03:21:20 rgb ++ * Cleared out unused htonq. ++ * ++ * Revision 1.11 2000/09/08 19:12:55 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * ++ * Revision 1.10 2000/01/21 06:13:10 rgb ++ * Tidied up spacing. ++ * Added macros for HMAC padding magic numbers.(kravietz) ++ * ++ * Revision 1.9 1999/12/07 18:16:23 rgb ++ * Fixed comments at end of #endif lines. ++ * ++ * Revision 1.8 1999/04/11 00:28:56 henry ++ * GPL boilerplate ++ * ++ * Revision 1.7 1999/04/06 04:54:25 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.6 1999/01/26 02:06:01 rgb ++ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. ++ * ++ * Revision 1.5 1999/01/22 06:17:49 rgb ++ * Updated macro comments. ++ * Added context types to support algorithm switch code. ++ * 64-bit clean-up -- converting 'u long long' to __u64. ++ * ++ * Revision 1.4 1998/07/14 15:54:56 rgb ++ * Add #ifdef __KERNEL__ to protect kernel-only structures. ++ * ++ * Revision 1.3 1998/06/30 18:05:16 rgb ++ * Comment out references to htonq. ++ * ++ * Revision 1.2 1998/06/25 19:33:46 rgb ++ * Add prototype for protocol receive function. ++ * Rearrange for more logical layout. ++ * ++ * Revision 1.1 1998/06/18 21:27:43 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid ++ * kernel-build scripts happier in the presence of symlinks ++ * ++ * Revision 1.4 1998/05/18 22:28:43 rgb ++ * Disable key printing facilities from /proc/net/ipsec_*. ++ * ++ * Revision 1.3 1998/04/21 21:29:07 rgb ++ * Rearrange debug switches to change on the fly debug output from user ++ * space. Only kernel changes checked in at this time. radij.c was also ++ * changed to temporarily remove buggy debugging code in rj_delete causing ++ * an OOPS and hence, netlink device open errors. ++ * ++ * Revision 1.2 1998/04/12 22:03:17 rgb ++ * Updated ESP-3DES-HMAC-MD5-96, ++ * ESP-DES-HMAC-MD5-96, ++ * AH-HMAC-MD5-96, ++ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository ++ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. ++ * ++ * Fixed eroute references in /proc/net/ipsec*. ++ * ++ * Started to patch module unloading memory leaks in ipsec_netlink and ++ * radij tree unloading. ++ * ++ * Revision 1.1 1998/04/09 03:05:55 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:02 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * Added definitions for new AH transforms. ++ * ++ * Revision 0.3 1996/11/20 14:35:48 ji ++ * Minor Cleanup. ++ * Rationalized debugging code. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_alg.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,260 @@ ++/* ++ * Modular extensions service and registration functions interface ++ * ++ * Author: JuanJo Ciarlante ++ * ++ * ipsec_alg.h,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp ++ * ++ */ ++/* ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ */ ++#ifndef IPSEC_ALG_H ++#define IPSEC_ALG_H ++ ++/* ++ * gcc >= 3.2 has removed __FUNCTION__, replaced by C99 __func__ ++ * *BUT* its a compiler variable. ++ */ ++#if (__GNUC__ >= 3) ++#ifndef __FUNCTION__ ++#define __FUNCTION__ __func__ ++#endif ++#endif ++ ++/* Version 0.8.1-0 */ ++#define IPSEC_ALG_VERSION 0x00080100 ++ ++#include ++#include ++#include ++/* ++ * The following structs are used via pointers in ipsec_alg object to ++ * avoid ipsec_alg.h coupling with freeswan headers, thus simplifying ++ * module development ++ */ ++struct ipsec_sa; ++struct esp; ++ ++/************************************** ++ * ++ * Main registration object ++ * ++ *************************************/ ++#define IPSEC_ALG_VERSION_QUAD(v) \ ++ (v>>24),((v>>16)&0xff),((v>>8)&0xff),(v&0xff) ++/* ++ * Main ipsec_alg objects: "OOPrograming wannabe" ++ * Hierachy (carefully handled with _minimal_ cast'ing): ++ * ++ * ipsec_alg+ ++ * +->ipsec_alg_enc (ixt_alg_type=SADB_EXT_SUPPORTED_ENCRYPT) ++ * +->ipsec_alg_auth (ixt_alg_type=SADB_EXT_SUPPORTED_AUTH) ++ */ ++ ++/*************************************************************** ++ * ++ * INTERFACE object: struct ipsec_alg ++ * ++ ***************************************************************/ ++ ++/* ++ * common part for every struct ipsec_alg_* ++ * (sortof poor's man OOP) ++ */ ++#define IPSEC_ALG_STRUCT_COMMON \ ++ unsigned ixt_version; /* only allow this version (or 'near')*/ \ ++ struct list_head ixt_list; /* dlinked list */ \ ++ struct module *ixt_module; /* THIS_MODULE */ \ ++ unsigned ixt_state; /* state flags */ \ ++ atomic_t ixt_refcnt; /* ref. count when pointed from ipsec_sa */ \ ++ char ixt_name[16]; /* descriptive short name, eg. "3des" */ \ ++ void *ixt_data; /* private for algo implementation */ \ ++ uint8_t ixt_blocksize; /* blocksize in bytes */ \ ++ \ ++ /* THIS IS A COPY of struct supported (lib/pfkey.h) \ ++ * please keep in sync until we migrate 'supported' stuff \ ++ * to ipsec_alg \ ++ */ \ ++ uint16_t ixt_alg_type; /* correspond to IPSEC_ALG_{ENCRYPT,AUTH} */ \ ++ uint8_t ixt_alg_id; /* enc. alg. number, eg. ESP_3DES */ \ ++ uint8_t ixt_ivlen; /* ivlen in bits, expected to be multiple of 8! */ \ ++ uint16_t ixt_keyminbits;/* min. keybits (of entropy) */ \ ++ uint16_t ixt_keymaxbits;/* max. keybits (of entropy) */ ++ ++#define ixt_support ixt_alg_type ++ ++#define IPSEC_ALG_ST_SUPP 0x01 ++#define IPSEC_ALG_ST_REGISTERED 0x02 ++#define IPSEC_ALG_ST_EXCL 0x04 ++struct ipsec_alg { ++ IPSEC_ALG_STRUCT_COMMON ++}; ++/* ++ * Note the const in cbc_encrypt IV arg: ++ * some ciphers like to toast passed IV (eg. 3DES): make a local IV copy ++ */ ++struct ipsec_alg_enc { ++ IPSEC_ALG_STRUCT_COMMON ++ unsigned ixt_e_keylen; /* raw key length in bytes */ ++ unsigned ixt_e_ctx_size; /* sa_p->key_e_size */ ++ int (*ixt_e_set_key)(struct ipsec_alg_enc *alg, __u8 *key_e, const __u8 *key, size_t keysize); ++ __u8 *(*ixt_e_new_key)(struct ipsec_alg_enc *alg, const __u8 *key, size_t keysize); ++ void (*ixt_e_destroy_key)(struct ipsec_alg_enc *alg, __u8 *key_e); ++ int (*ixt_e_cbc_encrypt)(struct ipsec_alg_enc *alg, __u8 *key_e, __u8 *in, int ilen, const __u8 *iv, int encrypt); ++}; ++struct ipsec_alg_auth { ++ IPSEC_ALG_STRUCT_COMMON ++ unsigned ixt_a_keylen; /* raw key length in bytes */ ++ unsigned ixt_a_ctx_size; /* sa_p->key_a_size */ ++ unsigned ixt_a_authlen; /* 'natural' auth. hash len (bytes) */ ++ int (*ixt_a_hmac_set_key)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *key, int keylen); ++ int (*ixt_a_hmac_hash)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *dat, int len, __u8 *hash, int hashlen); ++}; ++/* ++ * These are _copies_ of SADB_EXT_SUPPORTED_{AUTH,ENCRYPT}, ++ * to avoid header coupling for true constants ++ * about headers ... "cp is your friend" --Linus ++ */ ++#define IPSEC_ALG_TYPE_AUTH 14 ++#define IPSEC_ALG_TYPE_ENCRYPT 15 ++ ++/*************************************************************** ++ * ++ * INTERFACE for module loading,testing, and unloading ++ * ++ ***************************************************************/ ++/* - registration calls */ ++int register_ipsec_alg(struct ipsec_alg *); ++int unregister_ipsec_alg(struct ipsec_alg *); ++/* - optional (simple test) for algos */ ++int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int testparm); ++/* inline wrappers (usefull for type validation */ ++static inline int register_ipsec_alg_enc(struct ipsec_alg_enc *ixt) { ++ return register_ipsec_alg((struct ipsec_alg*)ixt); ++} ++static inline int unregister_ipsec_alg_enc(struct ipsec_alg_enc *ixt) { ++ return unregister_ipsec_alg((struct ipsec_alg*)ixt); ++} ++static inline int register_ipsec_alg_auth(struct ipsec_alg_auth *ixt) { ++ return register_ipsec_alg((struct ipsec_alg*)ixt); ++} ++static inline int unregister_ipsec_alg_auth(struct ipsec_alg_auth *ixt) { ++ return unregister_ipsec_alg((struct ipsec_alg*)ixt); ++} ++ ++/***************************************************************** ++ * ++ * INTERFACE for ENC services: key creation, encrypt function ++ * ++ *****************************************************************/ ++ ++#define IPSEC_ALG_ENCRYPT 1 ++#define IPSEC_ALG_DECRYPT 0 ++ ++/* encryption key context creation function */ ++int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p); ++/* ++ * ipsec_alg_esp_encrypt(): encrypt ilen bytes in idat returns ++ * 0 or ERR<0 ++ */ ++int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 *idat, int ilen, const __u8 *iv, int action); ++ ++/*************************************************************** ++ * ++ * INTERFACE for AUTH services: key creation, hash functions ++ * ++ ***************************************************************/ ++int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p); ++int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) ; ++#define ipsec_alg_sa_esp_update(c,k,l) ipsec_alg_sa_esp_hash(c,k,l,NULL,0) ++ ++/* only called from ipsec_init.c */ ++int ipsec_alg_init(void); ++ ++/* algo module glue for static algos */ ++void ipsec_alg_static_init(void); ++typedef int (*ipsec_alg_init_func_t) (void); ++ ++/********************************************** ++ * ++ * INTERFACE for ipsec_sa init and wipe ++ * ++ **********************************************/ ++ ++/* returns true if ipsec_sa has ipsec_alg obj attached */ ++/* ++ * Initializes ipsec_sa's ipsec_alg object, using already loaded ++ * proto, authalg, encalg.; links ipsec_alg objects (enc, auth) ++ */ ++int ipsec_alg_sa_init(struct ipsec_sa *sa_p); ++/* ++ * Destroys ipsec_sa's ipsec_alg object ++ * unlinking ipsec_alg objects ++ */ ++int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p); ++ ++#define IPSEC_ALG_MODULE_INIT_MOD( func_name ) \ ++ static int func_name(void); \ ++ module_init(func_name); \ ++ static int __init func_name(void) ++#define IPSEC_ALG_MODULE_EXIT_MOD( func_name ) \ ++ static void func_name(void); \ ++ module_exit(func_name); \ ++ static void __exit func_name(void) ++ ++#define IPSEC_ALG_MODULE_INIT_STATIC( func_name ) \ ++ extern int func_name(void); \ ++ int func_name(void) ++#define IPSEC_ALG_MODULE_EXIT_STATIC( func_name ) \ ++ extern void func_name(void); \ ++ void func_name(void) ++ ++/********************************************** ++ * ++ * 2.2 backport for some 2.4 useful module stuff ++ * ++ **********************************************/ ++#ifdef MODULE ++#ifndef THIS_MODULE ++#define THIS_MODULE (&__this_module) ++#endif ++#ifndef module_init ++typedef int (*__init_module_func_t)(void); ++typedef void (*__cleanup_module_func_t)(void); ++ ++#define module_init(x) \ ++ int init_module(void) __attribute__((alias(#x))); \ ++ static inline __init_module_func_t __init_module_inline(void) \ ++ { return x; } ++#define module_exit(x) \ ++ void cleanup_module(void) __attribute__((alias(#x))); \ ++ static inline __cleanup_module_func_t __cleanup_module_inline(void) \ ++ { return x; } ++#endif ++#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_MOD( func_name ) ++#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_MOD( func_name ) ++ ++#else /* not MODULE */ ++#ifndef THIS_MODULE ++#define THIS_MODULE NULL ++#endif ++/* ++ * I only want module_init() magic ++ * when algo.c file *is THE MODULE*, in all other ++ * cases, initialization is called explicitely from ipsec_alg_init() ++ */ ++#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_STATIC(func_name) ++#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_STATIC(func_name) ++#endif ++ ++#endif /* IPSEC_ALG_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_auth.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,100 @@ ++/* ++ * Authentication Header declarations ++ * Copyright (C) 2003 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_auth.h,v 1.3 2004/04/06 02:49:08 mcr Exp $ ++ */ ++ ++#include "ipsec_md5h.h" ++#include "ipsec_sha1.h" ++ ++#ifndef IPSEC_AUTH_H ++#define IPSEC_AUTH_H ++ ++#define AH_FLENGTH 12 /* size of fixed part */ ++#define AHMD5_KMAX 64 /* MD5 max 512 bits key */ ++#define AHMD5_AMAX 12 /* MD5 96 bits of authenticator */ ++ ++#define AHMD596_KLEN 16 /* MD5 128 bits key */ ++#define AHSHA196_KLEN 20 /* SHA1 160 bits key */ ++ ++#define AHMD596_ALEN 16 /* MD5 128 bits authentication length */ ++#define AHSHA196_ALEN 20 /* SHA1 160 bits authentication length */ ++ ++#define AHMD596_BLKLEN 64 /* MD5 block length */ ++#define AHSHA196_BLKLEN 64 /* SHA1 block length */ ++#define AHSHA2_256_BLKLEN 64 /* SHA2-256 block length */ ++#define AHSHA2_384_BLKLEN 128 /* SHA2-384 block length (?) */ ++#define AHSHA2_512_BLKLEN 128 /* SHA2-512 block length */ ++ ++#define AH_BLKLEN_MAX 128 /* keep up to date! */ ++ ++ ++#define AH_AMAX AHSHA196_ALEN /* keep up to date! */ ++#define AHHMAC_HASHLEN 12 /* authenticator length of 96bits */ ++#define AHHMAC_RPLLEN 4 /* 32 bit replay counter */ ++ ++#define DB_AH_PKTRX 0x0001 ++#define DB_AH_PKTRX2 0x0002 ++#define DB_AH_DMP 0x0004 ++#define DB_AH_IPSA 0x0010 ++#define DB_AH_XF 0x0020 ++#define DB_AH_INAU 0x0040 ++#define DB_AH_REPLAY 0x0100 ++ ++#ifdef __KERNEL__ ++ ++/* General HMAC algorithm is described in RFC 2104 */ ++ ++#define HMAC_IPAD 0x36 ++#define HMAC_OPAD 0x5C ++ ++struct md5_ctx { ++ MD5_CTX ictx; /* context after H(K XOR ipad) */ ++ MD5_CTX octx; /* context after H(K XOR opad) */ ++}; ++ ++struct sha1_ctx { ++ SHA1_CTX ictx; /* context after H(K XOR ipad) */ ++ SHA1_CTX octx; /* context after H(K XOR opad) */ ++}; ++ ++struct auth_alg { ++ void (*init)(void *ctx); ++ void (*update)(void *ctx, unsigned char *bytes, __u32 len); ++ void (*final)(unsigned char *hash, void *ctx); ++ int hashlen; ++}; ++ ++struct options; ++ ++#endif /* __KERNEL__ */ ++#endif /* IPSEC_AUTH_H */ ++ ++/* ++ * $Log: ipsec_auth.h,v $ ++ * Revision 1.3 2004/04/06 02:49:08 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.2 2004/04/05 19:55:04 mcr ++ * Moved from linux/include/freeswan/ipsec_auth.h,v ++ * ++ * Revision 1.1 2003/12/13 19:10:16 mcr ++ * refactored rcv and xmit code - same as FS 2.05. ++ * ++ * Revision 1.1 2003/12/06 21:21:19 mcr ++ * split up receive path into per-transform files, for ++ * easier later removal. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_encap.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,149 @@ ++/* ++ * declarations relevant to encapsulation-like operations ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_encap.h,v 1.19 2004/04/05 19:55:04 mcr Exp $ ++ */ ++ ++#ifndef _IPSEC_ENCAP_H_ ++ ++#define SENT_IP4 16 /* data is two struct in_addr + proto + ports*/ ++ /* (2 * sizeof(struct in_addr)) */ ++ /* sizeof(struct sockaddr_encap) ++ - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */ ++ ++struct sockaddr_encap ++{ ++ __u8 sen_len; /* length */ ++ __u8 sen_family; /* AF_ENCAP */ ++ __u16 sen_type; /* see SENT_* */ ++ union ++ { ++ struct /* SENT_IP4 */ ++ { ++ struct in_addr Src; ++ struct in_addr Dst; ++ __u8 Proto; ++ __u16 Sport; ++ __u16 Dport; ++ } Sip4; ++ } Sen; ++}; ++ ++#define sen_ip_src Sen.Sip4.Src ++#define sen_ip_dst Sen.Sip4.Dst ++#define sen_proto Sen.Sip4.Proto ++#define sen_sport Sen.Sip4.Sport ++#define sen_dport Sen.Sip4.Dport ++ ++#ifndef AF_ENCAP ++#define AF_ENCAP 26 ++#endif /* AF_ENCAP */ ++ ++#define _IPSEC_ENCAP_H_ ++#endif /* _IPSEC_ENCAP_H_ */ ++ ++/* ++ * $Log: ipsec_encap.h,v $ ++ * Revision 1.19 2004/04/05 19:55:04 mcr ++ * Moved from linux/include/freeswan/ipsec_encap.h,v ++ * ++ * Revision 1.18 2003/10/31 02:27:05 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.17.30.1 2003/09/21 13:59:38 mcr ++ * pre-liminary X.509 patch - does not yet pass tests. ++ * ++ * Revision 1.17 2002/04/24 07:36:46 mcr ++ * Moved from ./klips/net/ipsec/ipsec_encap.h,v ++ * ++ * Revision 1.16 2001/11/26 09:23:47 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.15.2.1 2001/09/25 02:18:54 mcr ++ * struct eroute moved to ipsec_eroute.h ++ * ++ * Revision 1.15 2001/09/14 16:58:36 rgb ++ * Added support for storing the first and last packets through a HOLD. ++ * ++ * Revision 1.14 2001/09/08 21:13:31 rgb ++ * Added pfkey ident extension support for ISAKMPd. (NetCelo) ++ * ++ * Revision 1.13 2001/06/14 19:35:08 rgb ++ * Update copyright date. ++ * ++ * Revision 1.12 2001/05/27 06:12:10 rgb ++ * Added structures for pid, packet count and last access time to eroute. ++ * Added packet count to beginning of /proc/net/ipsec_eroute. ++ * ++ * Revision 1.11 2000/09/08 19:12:56 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * ++ * Revision 1.10 2000/03/22 16:15:36 rgb ++ * Fixed renaming of dev_get (MB). ++ * ++ * Revision 1.9 2000/01/21 06:13:26 rgb ++ * Added a macro for AF_ENCAP ++ * ++ * Revision 1.8 1999/12/31 14:56:55 rgb ++ * MB fix for 2.3 dev-use-count. ++ * ++ * Revision 1.7 1999/11/18 04:09:18 rgb ++ * Replaced all kernel version macros to shorter, readable form. ++ * ++ * Revision 1.6 1999/09/24 00:34:13 rgb ++ * Add Marc Boucher's support for 2.3.xx+. ++ * ++ * Revision 1.5 1999/04/11 00:28:57 henry ++ * GPL boilerplate ++ * ++ * Revision 1.4 1999/04/06 04:54:25 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.3 1998/10/19 14:44:28 rgb ++ * Added inclusion of freeswan.h. ++ * sa_id structure implemented and used: now includes protocol. ++ * ++ * Revision 1.2 1998/07/14 18:19:33 rgb ++ * Added #ifdef __KERNEL__ directives to restrict scope of header. ++ * ++ * Revision 1.1 1998/06/18 21:27:44 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid ++ * kernel-build scripts happier in the presence of symlinks ++ * ++ * Revision 1.2 1998/04/21 21:29:10 rgb ++ * Rearrange debug switches to change on the fly debug output from user ++ * space. Only kernel changes checked in at this time. radij.c was also ++ * changed to temporarily remove buggy debugging code in rj_delete causing ++ * an OOPS and hence, netlink device open errors. ++ * ++ * Revision 1.1 1998/04/09 03:05:58 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:02 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * Minor cosmetic changes. ++ * ++ * Revision 0.3 1996/11/20 14:35:48 ji ++ * Minor Cleanup. ++ * Rationalized debugging code. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_eroute.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,112 @@ ++/* ++ * @(#) declarations of eroute structures ++ * ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs ++ * Copyright (C) 2001 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_eroute.h,v 1.5 2004/04/05 19:55:05 mcr Exp $ ++ * ++ * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr. ++ * ++ */ ++ ++#ifndef _IPSEC_EROUTE_H_ ++ ++#include "radij.h" ++#include "ipsec_encap.h" ++#include "ipsec_radij.h" ++ ++/* ++ * The "type" is really part of the address as far as the routing ++ * system is concerned. By using only one bit in the type field ++ * for each type, we sort-of make sure that different types of ++ * encapsulation addresses won't be matched against the wrong type. ++ */ ++ ++/* ++ * An entry in the radix tree ++ */ ++ ++struct rjtentry ++{ ++ struct radij_node rd_nodes[2]; /* tree glue, and other values */ ++#define rd_key(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_key)) ++#define rd_mask(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_mask)) ++ short rd_flags; ++ short rd_count; ++}; ++ ++struct ident ++{ ++ __u16 type; /* identity type */ ++ __u64 id; /* identity id */ ++ __u8 len; /* identity len */ ++ caddr_t data; /* identity data */ ++}; ++ ++/* ++ * An encapsulation route consists of a pointer to a ++ * radix tree entry and a SAID (a destination_address/SPI/protocol triple). ++ */ ++ ++struct eroute ++{ ++ struct rjtentry er_rjt; ++ ip_said er_said; ++ uint32_t er_pid; ++ uint32_t er_count; ++ uint64_t er_lasttime; ++ struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/ ++ struct sockaddr_encap er_emask; ++ struct ident er_ident_s; ++ struct ident er_ident_d; ++ struct sk_buff* er_first; ++ struct sk_buff* er_last; ++}; ++ ++#define er_dst er_said.dst ++#define er_spi er_said.spi ++ ++#define _IPSEC_EROUTE_H_ ++#endif /* _IPSEC_EROUTE_H_ */ ++ ++/* ++ * $Log: ipsec_eroute.h,v $ ++ * Revision 1.5 2004/04/05 19:55:05 mcr ++ * Moved from linux/include/freeswan/ipsec_eroute.h,v ++ * ++ * Revision 1.4 2003/10/31 02:27:05 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.3.30.2 2003/10/29 01:10:19 mcr ++ * elimited "struct sa_id" ++ * ++ * Revision 1.3.30.1 2003/09/21 13:59:38 mcr ++ * pre-liminary X.509 patch - does not yet pass tests. ++ * ++ * Revision 1.3 2002/04/24 07:36:46 mcr ++ * Moved from ./klips/net/ipsec/ipsec_eroute.h,v ++ * ++ * Revision 1.2 2001/11/26 09:16:13 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.1.2.1 2001/09/25 02:18:54 mcr ++ * struct eroute moved to ipsec_eroute.h ++ * ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_errs.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,53 @@ ++/* ++ * @(#) definition of ipsec_errs structure ++ * ++ * Copyright (C) 2001 Richard Guy Briggs ++ * and Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_errs.h,v 1.4 2004/04/05 19:55:05 mcr Exp $ ++ * ++ */ ++ ++/* ++ * This file describes the errors/statistics that FreeSWAN collects. ++ * ++ */ ++ ++struct ipsec_errs { ++ __u32 ips_alg_errs; /* number of algorithm errors */ ++ __u32 ips_auth_errs; /* # of authentication errors */ ++ __u32 ips_encsize_errs; /* # of encryption size errors*/ ++ __u32 ips_encpad_errs; /* # of encryption pad errors*/ ++ __u32 ips_replaywin_errs; /* # of pkt sequence errors */ ++}; ++ ++/* ++ * $Log: ipsec_errs.h,v $ ++ * Revision 1.4 2004/04/05 19:55:05 mcr ++ * Moved from linux/include/freeswan/ipsec_errs.h,v ++ * ++ * Revision 1.3 2002/04/24 07:36:46 mcr ++ * Moved from ./klips/net/ipsec/ipsec_errs.h,v ++ * ++ * Revision 1.2 2001/11/26 09:16:13 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr ++ * lifetime structure created and common functions created. ++ * ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_esp.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,147 @@ ++/* ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_esp.h,v 1.25 2004/04/06 02:49:08 mcr Exp $ ++ */ ++ ++#include "openswan/ipsec_md5h.h" ++#include "openswan/ipsec_sha1.h" ++ ++#include "crypto/des.h" ++ ++#ifndef IPPROTO_ESP ++#define IPPROTO_ESP 50 ++#endif /* IPPROTO_ESP */ ++ ++#define ESP_HEADER_LEN 8 /* 64 bits header (spi+rpl)*/ ++ ++#define EMT_ESPDESCBC_ULEN 20 /* coming from user mode */ ++#define EMT_ESPDES_KMAX 64 /* 512 bit secret key enough? */ ++#define EMT_ESPDES_KEY_SZ 8 /* 56 bit secret key with parity = 64 bits */ ++#define EMT_ESP3DES_KEY_SZ 24 /* 168 bit secret key with parity = 192 bits */ ++#define EMT_ESPDES_IV_SZ 8 /* IV size */ ++#define ESP_DESCBC_BLKLEN 8 /* DES-CBC block size */ ++ ++#define ESP_IV_MAXSZ 16 /* This is _critical_ */ ++#define ESP_IV_MAXSZ_INT (ESP_IV_MAXSZ/sizeof(int)) ++ ++#define DB_ES_PKTRX 0x0001 ++#define DB_ES_PKTRX2 0x0002 ++#define DB_ES_IPSA 0x0010 ++#define DB_ES_XF 0x0020 ++#define DB_ES_IPAD 0x0040 ++#define DB_ES_INAU 0x0080 ++#define DB_ES_OINFO 0x0100 ++#define DB_ES_OINFO2 0x0200 ++#define DB_ES_OH 0x0400 ++#define DB_ES_REPLAY 0x0800 ++ ++#ifdef __KERNEL__ ++struct des_eks { ++ des_key_schedule ks; ++}; ++ ++extern struct inet_protocol esp_protocol; ++ ++struct options; ++ ++struct esphdr ++{ ++ __u32 esp_spi; /* Security Parameters Index */ ++ __u32 esp_rpl; /* Replay counter */ ++ __u8 esp_iv[8]; /* iv */ ++}; ++ ++extern struct xform_functions esp_xform_funcs[]; ++ ++#ifdef CONFIG_IPSEC_DEBUG ++extern int debug_esp; ++#endif /* CONFIG_IPSEC_DEBUG */ ++#endif /* __KERNEL__ */ ++ ++/* ++ * $Log: ipsec_esp.h,v $ ++ * Revision 1.25 2004/04/06 02:49:08 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.24 2004/04/05 19:55:05 mcr ++ * Moved from linux/include/freeswan/ipsec_esp.h,v ++ * ++ * Revision 1.23 2004/04/05 19:41:05 mcr ++ * merged alg-branch code. ++ * ++ * Revision 1.22 2003/12/13 19:10:16 mcr ++ * refactored rcv and xmit code - same as FS 2.05. ++ * ++ * Revision 1.23 2003/12/11 20:14:58 mcr ++ * refactored the xmit code, to move all encapsulation ++ * code into protocol functions. Note that all functions ++ * are essentially done by a single function, which is probably ++ * wrong. ++ * the rcv_functions structures are renamed xform_functions. ++ * ++ * Revision 1.22 2003/12/06 21:21:19 mcr ++ * split up receive path into per-transform files, for ++ * easier later removal. ++ * ++ * Revision 1.21.8.1 2003/12/22 15:25:52 jjo ++ * Merged algo-0.8.1-rc11-test1 into alg-branch ++ * ++ * Revision 1.21 2003/02/06 02:21:34 rgb ++ * ++ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h . ++ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr". ++ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code. ++ * ++ * Revision 1.20 2002/05/14 02:37:02 rgb ++ * Change reference from _TDB to _IPSA. ++ * ++ * Revision 1.19 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.18 2002/04/24 07:36:46 mcr ++ * Moved from ./klips/net/ipsec/ipsec_esp.h,v ++ * ++ * Revision 1.17 2002/02/20 01:27:07 rgb ++ * Ditched a pile of structs only used by the old Netlink interface. ++ * ++ * Revision 1.16 2001/12/11 02:35:57 rgb ++ * Change "struct net_device" to "struct device" for 2.2 compatibility. ++ * ++ * Revision 1.15 2001/11/26 09:23:48 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.14.2.3 2001/10/23 04:16:42 mcr ++ * get definition of des_key_schedule from des.h ++ * ++ * Revision 1.14.2.2 2001/10/22 20:33:13 mcr ++ * use "des_key_schedule" structure instead of cooking our own. ++ * ++ * Revision 1.14.2.1 2001/09/25 02:18:25 mcr ++ * replace "struct device" with "struct netdevice" ++ * ++ * Revision 1.14 2001/06/14 19:35:08 rgb ++ * Update copyright date. ++ * ++ * Revision 1.13 2000/09/08 19:12:56 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * ++ * Revision 1.12 2000/08/01 14:51:50 rgb ++ * Removed _all_ remaining traces of DES. ++ * ++ * Revision 1.11 2000/01/10 16:36:20 rgb ++ * Ditch last of EME option flags, including initiator. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_ipcomp.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,91 @@ ++/* ++ * IP compression header declations ++ * ++ * Copyright (C) 2003 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_ipcomp.h,v 1.3 2004/04/06 02:49:08 mcr Exp $ ++ */ ++ ++#ifndef IPSEC_IPCOMP_H ++#define IPSEC_IPCOMP_H ++ ++#include "openswan/ipsec_auth.h" ++ ++/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */ ++#ifndef IPCOMP_PREFIX ++#define IPCOMP_PREFIX ++#endif /* IPCOMP_PREFIX */ ++ ++#ifndef IPPROTO_COMP ++#define IPPROTO_COMP 108 ++#endif /* IPPROTO_COMP */ ++ ++#ifdef CONFIG_IPSEC_DEBUG ++extern int sysctl_ipsec_debug_ipcomp; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++struct ipcomphdr { /* IPCOMP header */ ++ __u8 ipcomp_nh; /* Next header (protocol) */ ++ __u8 ipcomp_flags; /* Reserved, must be 0 */ ++ __u16 ipcomp_cpi; /* Compression Parameter Index */ ++}; ++ ++extern struct inet_protocol comp_protocol; ++extern int sysctl_ipsec_debug_ipcomp; ++ ++#define IPCOMP_UNCOMPRESSABLE 0x000000001 ++#define IPCOMP_COMPRESSIONERROR 0x000000002 ++#define IPCOMP_PARMERROR 0x000000004 ++#define IPCOMP_DECOMPRESSIONERROR 0x000000008 ++ ++#define IPCOMP_ADAPT_INITIAL_TRIES 8 ++#define IPCOMP_ADAPT_INITIAL_SKIP 4 ++#define IPCOMP_ADAPT_SUBSEQ_TRIES 2 ++#define IPCOMP_ADAPT_SUBSEQ_SKIP 8 ++ ++/* Function prototypes */ ++struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags); ++struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags); ++ ++extern struct xform_functions ipcomp_xform_funcs[]; ++ ++#endif /* IPSEC_IPCOMP_H */ ++ ++/* ++ * $Log: ipsec_ipcomp.h,v $ ++ * Revision 1.3 2004/04/06 02:49:08 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.2 2004/04/05 19:55:05 mcr ++ * Moved from linux/include/freeswan/ipsec_ipcomp.h,v ++ * ++ * Revision 1.1 2003/12/13 19:10:16 mcr ++ * refactored rcv and xmit code - same as FS 2.05. ++ * ++ * Revision 1.2 2003/12/11 20:14:58 mcr ++ * refactored the xmit code, to move all encapsulation ++ * code into protocol functions. Note that all functions ++ * are essentially done by a single function, which is probably ++ * wrong. ++ * the rcv_functions structures are renamed xform_functions. ++ * ++ * Revision 1.1 2003/12/06 21:21:19 mcr ++ * split up receive path into per-transform files, for ++ * easier later removal. ++ * ++ * ++ * ++ */ ++ ++ ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_ipe4.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,68 @@ ++/* ++ * IP-in-IP Header declarations ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_ipe4.h,v 1.6 2004/04/05 19:55:05 mcr Exp $ ++ */ ++ ++/* The packet header is an IP header! */ ++ ++struct ipe4_xdata /* transform table data */ ++{ ++ struct in_addr i4_src; ++ struct in_addr i4_dst; ++}; ++ ++#define EMT_IPE4_ULEN 8 /* coming from user mode */ ++ ++ ++/* ++ * $Log: ipsec_ipe4.h,v $ ++ * Revision 1.6 2004/04/05 19:55:05 mcr ++ * Moved from linux/include/freeswan/ipsec_ipe4.h,v ++ * ++ * Revision 1.5 2002/04/24 07:36:46 mcr ++ * Moved from ./klips/net/ipsec/ipsec_ipe4.h,v ++ * ++ * Revision 1.4 2001/06/14 19:35:08 rgb ++ * Update copyright date. ++ * ++ * Revision 1.3 1999/04/11 00:28:57 henry ++ * GPL boilerplate ++ * ++ * Revision 1.2 1999/04/06 04:54:25 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.1 1998/06/18 21:27:47 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid ++ * kernel-build scripts happier in the presence of symlinks ++ * ++ * Revision 1.1 1998/04/09 03:06:07 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:03 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * No changes. ++ * ++ * Revision 0.3 1996/11/20 14:48:53 ji ++ * Release update only. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_ipip.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (C) 2003 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_ipip.h,v 1.2 2004/04/05 19:55:05 mcr Exp $ ++ */ ++ ++#ifndef _IPSEC_IPIP_H_ ++ ++#ifndef IPPROTO_IPIP ++#define IPPROTO_IPIP 4 ++#endif /* IPPROTO_ESP */ ++ ++extern struct xform_functions ipip_xform_funcs[]; ++ ++#define _IPSEC_IPIP_H_ ++ ++#endif /* _IPSEC_IPIP_H_ */ ++ ++/* ++ * $Log: ipsec_ipip.h,v $ ++ * Revision 1.2 2004/04/05 19:55:05 mcr ++ * Moved from linux/include/freeswan/ipsec_ipip.h,v ++ * ++ * Revision 1.1 2003/12/13 19:10:16 mcr ++ * refactored rcv and xmit code - same as FS 2.05. ++ * ++ * Revision 1.1 2003/12/11 20:14:58 mcr ++ * refactored the xmit code, to move all encapsulation ++ * code into protocol functions. Note that all functions ++ * are essentially done by a single function, which is probably ++ * wrong. ++ * the rcv_functions structures are renamed xform_functions. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_kversion.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,239 @@ ++#ifndef _FREESWAN_KVERSIONS_H ++/* ++ * header file for FreeS/WAN library functions ++ * Copyright (C) 1998, 1999, 2000 Henry Spencer. ++ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: ipsec_kversion.h,v 1.9 2004/04/05 19:55:05 mcr Exp $ ++ */ ++#define _FREESWAN_KVERSIONS_H /* seen it, no need to see it again */ ++ ++/* ++ * this file contains a series of atomic defines that depend upon ++ * kernel version numbers. The kernel versions are arranged ++ * in version-order number (which is often not chronological) ++ * and each clause enables or disables a feature. ++ */ ++ ++/* ++ * First, assorted kernel-version-dependent trickery. ++ */ ++#include ++#ifndef KERNEL_VERSION ++#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) ++#define HEADER_CACHE_BIND_21 ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) ++#define SPINLOCK ++#define PROC_FS_21 ++#define NETLINK_SOCK ++#define NET_21 ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19) ++#define net_device_stats enet_statistics ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) ++#define SPINLOCK_23 ++#define NETDEV_23 ++# ifndef CONFIG_IP_ALIAS ++# define CONFIG_IP_ALIAS ++# endif ++#include ++#include ++#include ++# ifdef NETLINK_XFRM ++# define NETDEV_25 ++# endif ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25) ++#define PROC_FS_2325 ++#undef PROC_FS_21 ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30) ++#define PROC_NO_DUMMY ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35) ++#define SKB_COPY_EXPAND ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37) ++#define IP_SELECT_IDENT ++#endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER) ++#define SKB_RESET_NFCT ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2) ++#define IP_SELECT_IDENT_NEW ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) ++#define IPH_is_SKB_PULLED ++#define SKB_COW_NEW ++#define PROTO_HANDLER_SINGLE_PARM ++#define IP_FRAGMENT_LINEARIZE 1 ++#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */ ++# ifdef REDHAT_BOGOSITY ++# define IP_SELECT_IDENT_NEW ++# define IPH_is_SKB_PULLED ++# define SKB_COW_NEW ++# define PROTO_HANDLER_SINGLE_PARM ++# endif /* REDHAT_BOGOSITY */ ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */ ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9) ++#define MALLOC_SLAB ++#define LINUX_KERNEL_HAS_SNPRINTF ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++#define HAVE_NETDEV_PRINTK 1 ++#endif ++ ++#ifdef NET_21 ++# include ++#else ++ /* old kernel in.h has some IPv6 stuff, but not quite enough */ ++# define s6_addr16 s6_addr ++# define AF_INET6 10 ++# define uint8_t __u8 ++# define uint16_t __u16 ++# define uint32_t __u32 ++# define uint64_t __u64 ++#endif ++ ++#ifdef NET_21 ++# define ipsec_kfree_skb(a) kfree_skb(a) ++#else /* NET_21 */ ++# define ipsec_kfree_skb(a) kfree_skb(a, FREE_WRITE) ++#endif /* NET_21 */ ++ ++#ifdef NETDEV_23 ++# define device net_device ++# define ipsec_dev_get dev_get_by_name ++# define __ipsec_dev_get __dev_get_by_name ++# define ipsec_dev_put(x) dev_put(x) ++# define __ipsec_dev_put(x) __dev_put(x) ++# define ipsec_dev_hold(x) dev_hold(x) ++#else /* NETDEV_23 */ ++# define ipsec_dev_get dev_get ++# define __ipsec_dev_put(x) ++# define ipsec_dev_put(x) ++# define ipsec_dev_hold(x) ++#endif /* NETDEV_23 */ ++ ++#ifndef SPINLOCK ++# include ++ /* simulate spin locks and read/write locks */ ++ typedef struct { ++ volatile char lock; ++ } spinlock_t; ++ ++ typedef struct { ++ volatile unsigned int lock; ++ } rwlock_t; ++ ++# define spin_lock_init(x) { (x)->lock = 0;} ++# define rw_lock_init(x) { (x)->lock = 0; } ++ ++# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;} ++# define spin_lock_irq(x) { cli(); spin_lock(x);} ++# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);} ++ ++# define spin_unlock(x) { (x)->lock=0;} ++# define spin_unlock_irq(x) { spin_unlock(x); sti();} ++# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);} ++ ++# define read_lock(x) spin_lock(x) ++# define read_lock_irq(x) spin_lock_irq(x) ++# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags) ++ ++# define read_unlock(x) spin_unlock(x) ++# define read_unlock_irq(x) spin_unlock_irq(x) ++# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags) ++ ++# define write_lock(x) spin_lock(x) ++# define write_lock_irq(x) spin_lock_irq(x) ++# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags) ++ ++# define write_unlock(x) spin_unlock(x) ++# define write_unlock_irq(x) spin_unlock_irq(x) ++# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags) ++#endif /* !SPINLOCK */ ++ ++#ifndef SPINLOCK_23 ++# define spin_lock_bh(x) spin_lock_irq(x) ++# define spin_unlock_bh(x) spin_unlock_irq(x) ++ ++# define read_lock_bh(x) read_lock_irq(x) ++# define read_unlock_bh(x) read_unlock_irq(x) ++ ++# define write_lock_bh(x) write_lock_irq(x) ++# define write_unlock_bh(x) write_unlock_irq(x) ++#endif /* !SPINLOCK_23 */ ++ ++#ifndef HAVE_NETDEV_PRINTK ++#define netdev_printk(sevlevel, netdev, msglevel, format, arg...) \ ++ printk(sevlevel "%s: " format , netdev->name , ## arg) ++#endif ++ ++#endif /* _FREESWAN_KVERSIONS_H */ ++ ++/* ++ * $Log: ipsec_kversion.h,v $ ++ * Revision 1.9 2004/04/05 19:55:05 mcr ++ * Moved from linux/include/freeswan/ipsec_kversion.h,v ++ * ++ * Revision 1.8 2003/12/13 19:10:16 mcr ++ * refactored rcv and xmit code - same as FS 2.05. ++ * ++ * Revision 1.7 2003/07/31 22:48:08 mcr ++ * derive NET25-ness from presence of NETLINK_XFRM macro. ++ * ++ * Revision 1.6 2003/06/24 20:22:32 mcr ++ * added new global: ipsecdevices[] so that we can keep track of ++ * the ipsecX devices. They will be referenced with dev_hold(), ++ * so 2.2 may need this as well. ++ * ++ * Revision 1.5 2003/04/03 17:38:09 rgb ++ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. ++ * ++ * Revision 1.4 2002/04/24 07:36:46 mcr ++ * Moved from ./klips/net/ipsec/ipsec_kversion.h,v ++ * ++ * Revision 1.3 2002/04/12 03:21:17 mcr ++ * three parameter version of ip_select_ident appears first ++ * in 2.4.2 (RH7.1) not 2.4.4. ++ * ++ * Revision 1.2 2002/03/08 21:35:22 rgb ++ * Defined LINUX_KERNEL_HAS_SNPRINTF to shut up compiler warnings after ++ * 2.4.9. (Andreas Piesk). ++ * ++ * Revision 1.1 2002/01/29 02:11:42 mcr ++ * removal of kversions.h - sources that needed it now use ipsec_param.h. ++ * updating of IPv6 structures to match latest in6.h version. ++ * removed dead code from freeswan.h that also duplicated kversions.h ++ * code. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_life.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,112 @@ ++/* ++ * Definitions relevant to IPSEC lifetimes ++ * Copyright (C) 2001 Richard Guy Briggs ++ * and Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_life.h,v 1.4 2004/04/05 19:55:05 mcr Exp $ ++ * ++ * This file derived from ipsec_xform.h on 2001/9/18 by mcr. ++ * ++ */ ++ ++/* ++ * This file describes the book keeping fields for the ++ * IPsec Security Association Structure. ("ipsec_sa") ++ * ++ * This structure is never allocated directly by kernel code, ++ * (it is always a static/auto or is part of a structure) ++ * so it does not have a reference count. ++ * ++ */ ++ ++#ifndef _IPSEC_LIFE_H_ ++ ++/* ++ * _count is total count. ++ * _hard is hard limit (kill SA after this number) ++ * _soft is soft limit (try to renew SA after this number) ++ * _last is used in some special cases. ++ * ++ */ ++ ++struct ipsec_lifetime64 ++{ ++ __u64 ipl_count; ++ __u64 ipl_soft; ++ __u64 ipl_hard; ++ __u64 ipl_last; ++}; ++ ++struct ipsec_lifetimes ++{ ++ /* number of bytes processed */ ++ struct ipsec_lifetime64 ipl_bytes; ++ ++ /* number of packets processed */ ++ struct ipsec_lifetime64 ipl_packets; ++ ++ /* time since SA was added */ ++ struct ipsec_lifetime64 ipl_addtime; ++ ++ /* time since SA was first used */ ++ struct ipsec_lifetime64 ipl_usetime; ++ ++ /* from rfc2367: ++ * For CURRENT, the number of different connections, ++ * endpoints, or flows that the association has been ++ * allocated towards. For HARD and SOFT, the number of ++ * these the association may be allocated towards ++ * before it expires. The concept of a connection, ++ * flow, or endpoint is system specific. ++ * ++ * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN. ++ * They are maintained for PF_KEY compatibility. ++ */ ++ struct ipsec_lifetime64 ipl_allocations; ++}; ++ ++enum ipsec_life_alive { ++ ipsec_life_harddied = -1, ++ ipsec_life_softdied = 0, ++ ipsec_life_okay = 1 ++}; ++ ++enum ipsec_life_type { ++ ipsec_life_timebased = 1, ++ ipsec_life_countbased= 0 ++}; ++ ++#define _IPSEC_LIFE_H_ ++#endif /* _IPSEC_LIFE_H_ */ ++ ++ ++/* ++ * $Log: ipsec_life.h,v $ ++ * Revision 1.4 2004/04/05 19:55:05 mcr ++ * Moved from linux/include/freeswan/ipsec_life.h,v ++ * ++ * Revision 1.3 2002/04/24 07:36:46 mcr ++ * Moved from ./klips/net/ipsec/ipsec_life.h,v ++ * ++ * Revision 1.2 2001/11/26 09:16:14 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.1.2.1 2001/09/25 02:25:58 mcr ++ * lifetime structure created and common functions created. ++ * ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_md5h.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,140 @@ ++/* ++ * RCSID $Id: ipsec_md5h.h,v 1.9 2004/04/05 19:55:05 mcr Exp $ ++ */ ++ ++/* ++ * The rest of this file is Copyright RSA DSI. See the following comments ++ * for the full Copyright notice. ++ */ ++ ++#ifndef _IPSEC_MD5H_H_ ++#define _IPSEC_MD5H_H_ ++ ++/* GLOBAL.H - RSAREF types and constants ++ */ ++ ++/* PROTOTYPES should be set to one if and only if the compiler supports ++ function argument prototyping. ++ The following makes PROTOTYPES default to 0 if it has not already ++ been defined with C compiler flags. ++ */ ++#ifndef PROTOTYPES ++#define PROTOTYPES 1 ++#endif /* !PROTOTYPES */ ++ ++/* POINTER defines a generic pointer type */ ++typedef __u8 *POINTER; ++ ++/* UINT2 defines a two byte word */ ++typedef __u16 UINT2; ++ ++/* UINT4 defines a four byte word */ ++typedef __u32 UINT4; ++ ++/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. ++ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it ++ returns an empty list. ++ */ ++ ++#if PROTOTYPES ++#define PROTO_LIST(list) list ++#else /* PROTOTYPES */ ++#define PROTO_LIST(list) () ++#endif /* PROTOTYPES */ ++ ++ ++/* MD5.H - header file for MD5C.C ++ */ ++ ++/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All ++rights reserved. ++ ++License to copy and use this software is granted provided that it ++is identified as the "RSA Data Security, Inc. MD5 Message-Digest ++Algorithm" in all material mentioning or referencing this software ++or this function. ++ ++License is also granted to make and use derivative works provided ++that such works are identified as "derived from the RSA Data ++Security, Inc. MD5 Message-Digest Algorithm" in all material ++mentioning or referencing the derived work. ++ ++RSA Data Security, Inc. makes no representations concerning either ++the merchantability of this software or the suitability of this ++software for any particular purpose. It is provided "as is" ++without express or implied warranty of any kind. ++ ++These notices must be retained in any copies of any part of this ++documentation and/or software. ++ */ ++ ++/* MD5 context. */ ++typedef struct { ++ UINT4 state[4]; /* state (ABCD) */ ++ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ ++ unsigned char buffer[64]; /* input buffer */ ++} MD5_CTX; ++ ++void MD5Init PROTO_LIST ((void *)); ++void MD5Update PROTO_LIST ++ ((void *, unsigned char *, __u32)); ++void MD5Final PROTO_LIST ((unsigned char [16], void *)); ++ ++#endif /* _IPSEC_MD5H_H_ */ ++ ++/* ++ * $Log: ipsec_md5h.h,v $ ++ * Revision 1.9 2004/04/05 19:55:05 mcr ++ * Moved from linux/include/freeswan/ipsec_md5h.h,v ++ * ++ * Revision 1.8 2002/09/10 01:45:09 mcr ++ * changed type of MD5_CTX and SHA1_CTX to void * so that ++ * the function prototypes would match, and could be placed ++ * into a pointer to a function. ++ * ++ * Revision 1.7 2002/04/24 07:36:46 mcr ++ * Moved from ./klips/net/ipsec/ipsec_md5h.h,v ++ * ++ * Revision 1.6 1999/12/13 13:59:13 rgb ++ * Quick fix to argument size to Update bugs. ++ * ++ * Revision 1.5 1999/12/07 18:16:23 rgb ++ * Fixed comments at end of #endif lines. ++ * ++ * Revision 1.4 1999/04/06 04:54:26 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.3 1999/01/22 06:19:58 rgb ++ * 64-bit clean-up. ++ * ++ * Revision 1.2 1998/11/30 13:22:54 rgb ++ * Rationalised all the klips kernel file headers. They are much shorter ++ * now and won't conflict under RH5.2. ++ * ++ * Revision 1.1 1998/06/18 21:27:48 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid ++ * kernel-build scripts happier in the presence of symlinks ++ * ++ * Revision 1.2 1998/04/23 20:54:03 rgb ++ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when ++ * verified. ++ * ++ * Revision 1.1 1998/04/09 03:04:21 henry ++ * sources moved up from linux/net/ipsec ++ * these two include files modified not to include others except in kernel ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:03 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * No changes. ++ * ++ * Revision 0.3 1996/11/20 14:48:53 ji ++ * Release update only. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_param.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,333 @@ ++/* ++ * @(#) FreeSWAN tunable paramaters ++ * ++ * Copyright (C) 2001 Richard Guy Briggs ++ * and Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_param.h,v 1.24 2004/04/05 19:55:06 mcr Exp $ ++ * ++ */ ++ ++/* ++ * This file provides a set of #define's which may be tuned by various ++ * people/configurations. It keeps all compile-time tunables in one place. ++ * ++ * This file should be included before all other IPsec kernel-only files. ++ * ++ */ ++ ++#ifndef _IPSEC_PARAM_H_ ++ ++#ifdef __KERNEL__ ++#include "ipsec_kversion.h" ++ ++/* Set number of ipsecX virtual devices here. */ ++/* This must be < exp(field width of IPSEC_DEV_FORMAT) */ ++/* It must also be reasonable so as not to overload the memory and CPU */ ++/* constraints of the host. */ ++#define IPSEC_NUM_IF 4 ++/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */ ++/* With "ipsec" being 5 characters, that means 10 is the max field width */ ++/* but machine memory and CPU constraints are not likely to tollerate */ ++/* more than 3 digits. The default is one digit. */ ++/* Update: userland scripts get upset if they can't find "ipsec0", so */ ++/* for now, no "0"-padding should be used (which would have been helpful */ ++/* to make text-searches work */ ++#define IPSEC_DEV_FORMAT "ipsec%d" ++/* For, say, 500 virtual ipsec devices, I would recommend: */ ++/* #define IPSEC_NUM_IF 500 */ ++/* #define IPSEC_DEV_FORMAT "ipsec%03d" */ ++/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */ ++ ++/* use dynamic ipsecX device allocation */ ++#ifndef CONFIG_IPSEC_DYNDEV ++#define CONFIG_IPSEC_DYNDEV 1 ++#endif /* CONFIG_IPSEC_DYNDEV */ ++ ++ ++#ifdef CONFIG_IPSEC_BIGGATE ++# define SADB_HASHMOD 8069 ++#else /* CONFIG_IPSEC_BIGGATE */ ++# define SADB_HASHMOD 257 ++#endif /* CONFIG_IPSEC_BIGGATE */ ++#endif /* __KERNEL__ */ ++ ++/* ++ * This is for the SA reference table. This number is related to the ++ * maximum number of SAs that KLIPS can concurrently deal with, plus enough ++ * space for keeping expired SAs around. ++ * ++ * TABLE_MAX_WIDTH is the number of bits that we will use. ++ * MAIN_TABLE_WIDTH is the number of bits used for the primary index table. ++ * ++ */ ++#ifndef IPSEC_SA_REF_TABLE_IDX_WIDTH ++# define IPSEC_SA_REF_TABLE_IDX_WIDTH 16 ++#endif ++ ++#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH ++# define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4 ++#endif ++ ++#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES ++# define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256 ++#endif ++ ++#ifndef IPSEC_SA_REF_CODE ++# define IPSEC_SA_REF_CODE 1 ++#endif ++ ++#ifdef __KERNEL__ ++/* This is defined for 2.4, but not 2.2.... */ ++#ifndef ARPHRD_VOID ++# define ARPHRD_VOID 0xFFFF ++#endif ++ ++/* ++ * Worry about PROC_FS stuff ++ */ ++#if defined(PROC_FS_2325) ++/* kernel 2.4 */ ++# define IPSEC_PROC_LAST_ARG ,int *eof,void *data ++# define IPSEC_PROCFS_DEBUG_NO_STATIC ++# define IPSEC_PROC_SUBDIRS ++#else ++/* kernel <2.4 */ ++# define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC ++ ++# ifndef PROC_NO_DUMMY ++# define IPSEC_PROC_LAST_ARG , int dummy ++# else ++# define IPSEC_PROC_LAST_ARG ++# endif /* !PROC_NO_DUMMY */ ++#endif /* PROC_FS_2325 */ ++ ++#if !defined(LINUX_KERNEL_HAS_SNPRINTF) ++/* GNU CPP specific! */ ++# define snprintf(buf, len, fmt...) sprintf(buf, ##fmt) ++#endif /* !LINUX_KERNEL_HAS_SNPRINTF */ ++ ++#ifdef SPINLOCK ++# ifdef SPINLOCK_23 ++# include /* *lock* */ ++# else /* SPINLOCK_23 */ ++# include /* *lock* */ ++# endif /* SPINLOCK_23 */ ++#endif /* SPINLOCK */ ++ ++#ifndef KLIPS_FIXES_DES_PARITY ++# define KLIPS_FIXES_DES_PARITY 1 ++#endif /* !KLIPS_FIXES_DES_PARITY */ ++ ++/* we don't really want to print these unless there are really big problems */ ++#ifndef KLIPS_DIVULGE_CYPHER_KEY ++# define KLIPS_DIVULGE_CYPHER_KEY 0 ++#endif /* !KLIPS_DIVULGE_CYPHER_KEY */ ++ ++#ifndef KLIPS_DIVULGE_HMAC_KEY ++# define KLIPS_DIVULGE_HMAC_KEY 0 ++#endif /* !KLIPS_DIVULGE_HMAC_KEY */ ++ ++#ifndef IPSEC_DISALLOW_IPOPTIONS ++# define IPSEC_DISALLOW_IPOPTIONS 1 ++#endif /* !KLIPS_DIVULGE_HMAC_KEY */ ++ ++/* extra toggles for regression testing */ ++#ifdef CONFIG_IPSEC_REGRESS ++ ++/* ++ * should pfkey_acquire() become 100% lossy? ++ * ++ */ ++extern int sysctl_ipsec_regress_pfkey_lossage; ++#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE ++# ifdef CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE ++# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100 ++# else /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */ ++/* not by default! */ ++# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0 ++# endif /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */ ++#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */ ++ ++#endif /* CONFIG_IPSEC_REGRESS */ ++ ++ ++/* ++ * debugging routines. ++ */ ++#ifdef CONFIG_IPSEC_DEBUG ++extern void ipsec_print_ip(struct iphdr *ip); ++ ++ #define KLIPS_PRINT(flag, format, args...) \ ++ ((flag) ? printk(KERN_INFO format , ## args) : 0) ++ #define KLIPS_PRINTMORE(flag, format, args...) \ ++ ((flag) ? printk(format , ## args) : 0) ++ #define KLIPS_IP_PRINT(flag, ip) \ ++ ((flag) ? ipsec_print_ip(ip) : 0) ++#else /* CONFIG_IPSEC_DEBUG */ ++ #define KLIPS_PRINT(flag, format, args...) do ; while(0) ++ #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0) ++ #define KLIPS_IP_PRINT(flag, ip) do ; while(0) ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ ++/* ++ * Stupid kernel API differences in APIs. Not only do some ++ * kernels not have ip_select_ident, but some have differing APIs, ++ * and SuSE has one with one parameter, but no way of checking to ++ * see what is really what. ++ */ ++ ++#ifdef SUSE_LINUX_2_4_19_IS_STUPID ++#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph) ++#else ++ ++/* simplest case, nothing */ ++#if !defined(IP_SELECT_IDENT) ++#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0) ++#endif ++ ++/* kernels > 2.3.37-ish */ ++#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW) ++#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst) ++#endif ++ ++/* kernels > 2.4.2 */ ++#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW) ++#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL) ++#endif ++ ++#endif /* SUSE_LINUX_2_4_19_IS_STUPID */ ++ ++/* ++ * make klips fail test:east-espiv-01. ++ * exploit is at testing/attacks/espiv ++ * ++ */ ++#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0 ++ ++ ++/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */ ++#ifndef IP_FRAGMENT_LINEARIZE ++# define IP_FRAGMENT_LINEARIZE 0 ++#endif /* IP_FRAGMENT_LINEARIZE */ ++#endif /* __KERNEL__ */ ++ ++#define _IPSEC_PARAM_H_ ++#endif /* _IPSEC_PARAM_H_ */ ++ ++/* ++ * $Log: ipsec_param.h,v $ ++ * Revision 1.24 2004/04/05 19:55:06 mcr ++ * Moved from linux/include/freeswan/ipsec_param.h,v ++ * ++ * Revision 1.23 2003/12/13 19:10:16 mcr ++ * refactored rcv and xmit code - same as FS 2.05. ++ * ++ * Revision 1.22 2003/10/31 02:27:05 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.21.4.1 2003/10/29 01:10:19 mcr ++ * elimited "struct sa_id" ++ * ++ * Revision 1.21 2003/04/03 17:38:18 rgb ++ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. ++ * Change indentation for readability. ++ * ++ * Revision 1.20 2003/03/14 08:09:26 rgb ++ * Fixed up CONFIG_IPSEC_DYNDEV definitions. ++ * ++ * Revision 1.19 2003/01/30 02:31:43 rgb ++ * ++ * Rename SAref table macro names for clarity. ++ * ++ * Revision 1.18 2002/09/30 19:06:26 rgb ++ * Reduce default table to 16 bits width. ++ * ++ * Revision 1.17 2002/09/20 15:40:29 rgb ++ * Define switch to activate new SAref code. ++ * Prefix macros with "IPSEC_". ++ * Rework saref freelist. ++ * Restrict some bits to kernel context for use to klips utils. ++ * ++ * Revision 1.16 2002/09/20 05:00:31 rgb ++ * Define switch to divulge hmac keys for debugging. ++ * Added IPOPTIONS switch. ++ * ++ * Revision 1.15 2002/09/19 02:34:24 mcr ++ * define IPSEC_PROC_SUBDIRS if we are 2.4, and use that in ipsec_proc.c ++ * to decide if we are to create /proc/net/ipsec/. ++ * ++ * Revision 1.14 2002/08/30 01:20:54 mcr ++ * reorganized 2.0/2.2/2.4 procfs support macro so match ++ * 2.4 values/typedefs. ++ * ++ * Revision 1.13 2002/07/28 22:03:28 mcr ++ * added some documentation to SA_REF_* ++ * turned on fix for ESPIV attack, now that we have the attack code. ++ * ++ * Revision 1.12 2002/07/26 08:48:31 rgb ++ * Added SA ref table code. ++ * ++ * Revision 1.11 2002/07/23 02:57:45 rgb ++ * Define ARPHRD_VOID for < 2.4 kernels. ++ * ++ * Revision 1.10 2002/05/27 21:37:28 rgb ++ * Set the defaults sanely for those adventurous enough to try more than 1 ++ * digit of ipsec devices. ++ * ++ * Revision 1.9 2002/05/27 18:56:07 rgb ++ * Convert to dynamic ipsec device allocation. ++ * ++ * Revision 1.8 2002/04/24 07:36:47 mcr ++ * Moved from ./klips/net/ipsec/ipsec_param.h,v ++ * ++ * Revision 1.7 2002/04/20 00:12:25 rgb ++ * Added esp IV CBC attack fix, disabled. ++ * ++ * Revision 1.6 2002/01/29 02:11:42 mcr ++ * removal of kversions.h - sources that needed it now use ipsec_param.h. ++ * updating of IPv6 structures to match latest in6.h version. ++ * removed dead code from freeswan.h that also duplicated kversions.h ++ * code. ++ * ++ * Revision 1.5 2002/01/28 19:22:01 mcr ++ * by default, turn off LINEARIZE option ++ * (let kversions.h turn it on) ++ * ++ * Revision 1.4 2002/01/20 20:19:36 mcr ++ * renamed option to IP_FRAGMENT_LINEARIZE. ++ * ++ * Revision 1.3 2002/01/12 02:57:25 mcr ++ * first regression test causes acquire messages to be lost ++ * 100% of the time. This is to help testing of pluto. ++ * ++ * Revision 1.2 2001/11/26 09:16:14 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.1.2.3 2001/10/23 04:40:16 mcr ++ * added #define for DIVULGING session keys in debug output. ++ * ++ * Revision 1.1.2.2 2001/10/22 20:53:25 mcr ++ * added a define to control forcing of DES parity. ++ * ++ * Revision 1.1.2.1 2001/09/25 02:20:19 mcr ++ * many common kernel configuration questions centralized. ++ * more things remain that should be moved from freeswan.h. ++ * ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_policy.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,216 @@ ++#ifndef _IPSEC_POLICY_H ++/* ++ * policy interface file between pluto and applications ++ * Copyright (C) 2003 Michael Richardson ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: ipsec_policy.h,v 1.5 2004/06/17 04:23:33 mcr Exp $ ++ */ ++#define _IPSEC_POLICY_H /* seen it, no need to see it again */ ++ ++ ++/* ++ * this file defines an interface between an application (or rather an ++ * application library) and a key/policy daemon. It provides for inquiries ++ * as to the current state of a connected socket, as well as for general ++ * questions. ++ * ++ * In general, the interface is defined as a series of functional interfaces, ++ * and the policy messages should be internal. However, because this is in ++ * fact an ABI between pieces of the system that may get compiled and revised ++ * seperately, this ABI must be public and revision controlled. ++ * ++ * It is expected that the daemon will always support previous versions. ++ */ ++ ++#define IPSEC_POLICY_MSG_REVISION (unsigned)200305061 ++ ++enum ipsec_policy_command { ++ IPSEC_CMD_QUERY_FD = 1, ++ IPSEC_CMD_QUERY_HOSTPAIR = 2, ++ IPSEC_CMD_QUERY_DSTONLY = 3, ++}; ++ ++struct ipsec_policy_msg_head { ++ u_int32_t ipm_version; ++ u_int32_t ipm_msg_len; ++ u_int32_t ipm_msg_type; ++ u_int32_t ipm_msg_seq; ++}; ++ ++enum ipsec_privacy_quality { ++ IPSEC_PRIVACY_NONE = 0, ++ IPSEC_PRIVACY_INTEGRAL = 4, /* not private at all. AH-like */ ++ IPSEC_PRIVACY_UNKNOWN = 8, /* something is claimed, but details unavail */ ++ IPSEC_PRIVACY_ROT13 = 12, /* trivially breakable, i.e. 1DES */ ++ IPSEC_PRIVACY_GAK = 16, /* known eavesdroppers */ ++ IPSEC_PRIVACY_PRIVATE = 32, /* secure for at least a decade */ ++ IPSEC_PRIVACY_STRONG = 64, /* ridiculously secure */ ++ IPSEC_PRIVACY_TORTOISE = 192, /* even stronger, but very slow */ ++ IPSEC_PRIVACY_OTP = 224, /* some kind of *true* one time pad */ ++}; ++ ++enum ipsec_bandwidth_quality { ++ IPSEC_QOS_UNKNOWN = 0, /* unknown bandwidth */ ++ IPSEC_QOS_INTERACTIVE = 16, /* reasonably moderate jitter, moderate fast. ++ Good enough for telnet/ssh. */ ++ IPSEC_QOS_VOIP = 32, /* faster crypto, predicable jitter */ ++ IPSEC_QOS_FTP = 64, /* higher throughput crypto, perhaps hardware ++ offloaded, but latency/jitter may be bad */ ++ IPSEC_QOS_WIRESPEED = 128, /* expect to be able to fill your pipe */ ++}; ++ ++/* moved from programs/pluto/constants.h */ ++/* IPsec AH transform values ++ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3 ++ * and in http://www.iana.org/assignments/isakmp-registry ++ */ ++enum ipsec_authentication_algo { ++ AH_MD5=2, ++ AH_SHA=3, ++ AH_DES=4, ++ AH_SHA2_256=5, ++ AH_SHA2_384=6, ++ AH_SHA2_512=7 ++}; ++ ++/* IPsec ESP transform values ++ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4 ++ * and from http://www.iana.org/assignments/isakmp-registry ++ */ ++ ++enum ipsec_cipher_algo { ++ ESP_reserved=0, ++ ESP_DES_IV64=1, ++ ESP_DES=2, ++ ESP_3DES=3, ++ ESP_RC5=4, ++ ESP_IDEA=5, ++ ESP_CAST=6, ++ ESP_BLOWFISH=7, ++ ESP_3IDEA=8, ++ ESP_DES_IV32=9, ++ ESP_RC4=10, ++ ESP_NULL=11, ++ ESP_AES=12, ++}; ++ ++/* IPCOMP transform values ++ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5 ++ */ ++ ++enum ipsec_comp_algo { ++ IPCOMP_OUI= 1, ++ IPCOMP_DEFLATE= 2, ++ IPCOMP_LZS= 3, ++ IPCOMP_V42BIS= 4 ++}; ++ ++/* Identification type values ++ * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1 ++ */ ++ ++enum ipsec_id_type { ++ ID_IMPOSSIBLE= (-2), /* private to Pluto */ ++ ID_MYID= (-1), /* private to Pluto */ ++ ID_NONE= 0, /* private to Pluto */ ++ ID_IPV4_ADDR= 1, ++ ID_FQDN= 2, ++ ID_USER_FQDN= 3, ++ ID_IPV4_ADDR_SUBNET= 4, ++ ID_IPV6_ADDR= 5, ++ ID_IPV6_ADDR_SUBNET= 6, ++ ID_IPV4_ADDR_RANGE= 7, ++ ID_IPV6_ADDR_RANGE= 8, ++ ID_DER_ASN1_DN= 9, ++ ID_DER_ASN1_GN= 10, ++ ID_KEY_ID= 11 ++}; ++ ++/* Certificate type values ++ * RFC 2408 ISAKMP, chapter 3.9 ++ */ ++enum ipsec_cert_type { ++ CERT_NONE= 0, /* none, or guess from file contents */ ++ CERT_PKCS7_WRAPPED_X509= 1, /* self-signed certificate from disk */ ++ CERT_PGP= 2, ++ CERT_DNS_SIGNED_KEY= 3, /* KEY RR from DNS */ ++ CERT_X509_SIGNATURE= 4, ++ CERT_X509_KEY_EXCHANGE= 5, ++ CERT_KERBEROS_TOKENS= 6, ++ CERT_CRL= 7, ++ CERT_ARL= 8, ++ CERT_SPKI= 9, ++ CERT_X509_ATTRIBUTE= 10, ++ CERT_RAW_RSA= 11, /* raw RSA from config file */ ++}; ++ ++/* a SIG record in ASCII */ ++struct ipsec_dns_sig { ++ char fqdn[256]; ++ char dns_sig[768]; /* empty string if not signed */ ++}; ++ ++struct ipsec_raw_key { ++ char id_name[256]; ++ char fs_keyid[8]; ++}; ++ ++struct ipsec_identity { ++ enum ipsec_id_type ii_type; ++ enum ipsec_cert_type ii_format; ++ union { ++ struct ipsec_dns_sig ipsec_dns_signed; ++ /* some thing for PGP */ ++ /* some thing for PKIX */ ++ struct ipsec_raw_key ipsec_raw_key; ++ } ii_credential; ++}; ++ ++#define IPSEC_MAX_CREDENTIALS 32 ++ ++struct ipsec_policy_cmd_query { ++ struct ipsec_policy_msg_head head; ++ ++ /* Query section */ ++ ip_address query_local; /* us */ ++ ip_address query_remote; /* them */ ++ u_short src_port, dst_port; ++ ++ /* Answer section */ ++ enum ipsec_privacy_quality strength; ++ enum ipsec_bandwidth_quality bandwidth; ++ enum ipsec_authentication_algo auth_detail; ++ enum ipsec_cipher_algo esp_detail; ++ enum ipsec_comp_algo comp_detail; ++ ++ int credential_count; ++ ++ struct ipsec_identity credentials[IPSEC_MAX_CREDENTIALS]; ++}; ++ ++#define IPSEC_POLICY_SOCKET "/var/run/pluto.info" ++ ++/* prototypes */ ++extern err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result); ++extern err_t ipsec_policy_init(void); ++extern err_t ipsec_policy_final(void); ++extern err_t ipsec_policy_readmsg(int policysock, ++ unsigned char *buf, size_t buflen); ++extern err_t ipsec_policy_sendrecv(unsigned char *buf, size_t buflen); ++extern err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result); ++ ++ ++extern const char *ipsec_policy_version_code(void); ++extern const char *ipsec_policy_version_string(void); ++ ++#endif /* _IPSEC_POLICY_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_proto.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,151 @@ ++/* ++ * @(#) prototypes for FreeSWAN functions ++ * ++ * Copyright (C) 2001 Richard Guy Briggs ++ * and Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_proto.h,v 1.8 2004/04/05 19:55:06 mcr Exp $ ++ * ++ */ ++ ++#ifndef _IPSEC_PROTO_H_ ++ ++#include "ipsec_param.h" ++ ++/* ++ * This file is a kernel only file that declares prototypes for ++ * all intra-module function calls and global data structures. ++ * ++ * Include this file last. ++ * ++ */ ++ ++/* ipsec_init.c */ ++extern struct prng ipsec_prng; ++ ++/* ipsec_sa.c */ ++extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD]; ++extern spinlock_t tdb_lock; ++extern int ipsec_sadb_init(void); ++ ++extern struct ipsec_sa *ipsec_sa_getbyid(ip_said *); ++extern int ipsec_sa_put(struct ipsec_sa *); ++extern /* void */ int ipsec_sa_del(struct ipsec_sa *); ++extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *); ++extern /* void */ int ipsec_sa_add(struct ipsec_sa *); ++ ++extern int ipsec_sadb_cleanup(__u8); ++extern int ipsec_sa_wipe(struct ipsec_sa *); ++ ++/* debug declarations */ ++ ++/* ipsec_proc.c */ ++extern int ipsec_proc_init(void); ++extern void ipsec_proc_cleanup(void); ++ ++/* ipsec_radij.c */ ++extern int ipsec_makeroute(struct sockaddr_encap *ea, ++ struct sockaddr_encap *em, ++ ip_said said, ++ uint32_t pid, ++ struct sk_buff *skb, ++ struct ident *ident_s, ++ struct ident *ident_d); ++ ++extern int ipsec_breakroute(struct sockaddr_encap *ea, ++ struct sockaddr_encap *em, ++ struct sk_buff **first, ++ struct sk_buff **last); ++ ++int ipsec_radijinit(void); ++int ipsec_cleareroutes(void); ++int ipsec_radijcleanup(void); ++ ++/* ipsec_life.c */ ++extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64, ++ const char *lifename, ++ const char *saname, ++ enum ipsec_life_type ilt, ++ enum ipsec_direction idir, ++ struct ipsec_sa *ips); ++ ++ ++extern int ipsec_lifetime_format(char *buffer, ++ int buflen, ++ char *lifename, ++ enum ipsec_life_type timebaselife, ++ struct ipsec_lifetime64 *lifetime); ++ ++extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime, ++ __u64 newvalue); ++ ++extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime, ++ __u64 newvalue); ++ ++ ++ ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ ++extern int debug_xform; ++extern int debug_eroute; ++extern int debug_spi; ++extern int debug_netlink; ++ ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ ++ ++ ++#define _IPSEC_PROTO_H ++#endif /* _IPSEC_PROTO_H_ */ ++ ++/* ++ * $Log: ipsec_proto.h,v $ ++ * Revision 1.8 2004/04/05 19:55:06 mcr ++ * Moved from linux/include/freeswan/ipsec_proto.h,v ++ * ++ * Revision 1.7 2003/10/31 02:27:05 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.6.30.1 2003/10/29 01:10:19 mcr ++ * elimited "struct sa_id" ++ * ++ * Revision 1.6 2002/05/23 07:13:48 rgb ++ * Added ipsec_sa_put() for releasing an ipsec_sa refcount. ++ * ++ * Revision 1.5 2002/05/14 02:36:40 rgb ++ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion ++ * with "put" usage in the kernel. ++ * ++ * Revision 1.4 2002/04/24 07:36:47 mcr ++ * Moved from ./klips/net/ipsec/ipsec_proto.h,v ++ * ++ * Revision 1.3 2002/04/20 00:12:25 rgb ++ * Added esp IV CBC attack fix, disabled. ++ * ++ * Revision 1.2 2001/11/26 09:16:15 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.1.2.1 2001/09/25 02:21:01 mcr ++ * ipsec_proto.h created to keep prototypes rather than deal with ++ * cyclic dependancies of structures and prototypes in .h files. ++ * ++ * ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_radij.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,176 @@ ++/* ++ * @(#) Definitions relevant to the IPSEC <> radij tree interfacing ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_radij.h,v 1.21 2004/04/29 11:06:42 ken Exp $ ++ */ ++ ++#ifndef _IPSEC_RADIJ_H ++ ++#include ++ ++int ipsec_walk(char *); ++ ++int ipsec_rj_walker_procprint(struct radij_node *, void *); ++int ipsec_rj_walker_delete(struct radij_node *, void *); ++ ++/* This structure is used to pass information between ++ * ipsec_eroute_get_info and ipsec_rj_walker_procprint ++ * (through rj_walktree) and between calls of ipsec_rj_walker_procprint. ++ */ ++struct wsbuf ++{ ++ /* from caller of ipsec_eroute_get_info: */ ++ char *const buffer; /* start of buffer provided */ ++ const int length; /* length of buffer provided */ ++ const off_t offset; /* file position of first character of interest */ ++ /* accumulated by ipsec_rj_walker_procprint: */ ++ int len; /* number of character filled into buffer */ ++ off_t begin; /* file position contained in buffer[0] (<=offset) */ ++}; ++ ++extern struct radij_node_head *rnh; ++extern spinlock_t eroute_lock; ++ ++struct eroute * ipsec_findroute(struct sockaddr_encap *); ++ ++#define O1(x) (int)(((x)>>24)&0xff) ++#define O2(x) (int)(((x)>>16)&0xff) ++#define O3(x) (int)(((x)>>8)&0xff) ++#define O4(x) (int)(((x))&0xff) ++ ++#ifdef CONFIG_IPSEC_DEBUG ++extern int debug_radij; ++void rj_dumptrees(void); ++ ++#define DB_RJ_DUMPTREES 0x0001 ++#define DB_RJ_FINDROUTE 0x0002 ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++#define _IPSEC_RADIJ_H ++#endif ++ ++/* ++ * $Log: ipsec_radij.h,v $ ++ * Revision 1.21 2004/04/29 11:06:42 ken ++ * Last bits from 2.06 procfs updates ++ * ++ * Revision 1.20 2004/04/06 02:49:08 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.19 2004/04/05 19:55:06 mcr ++ * Moved from linux/include/freeswan/ipsec_radij.h,v ++ * ++ * Revision 1.18 2002/04/24 07:36:47 mcr ++ * Moved from ./klips/net/ipsec/ipsec_radij.h,v ++ * ++ * Revision 1.17 2001/11/26 09:23:49 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.16.2.1 2001/09/25 02:21:17 mcr ++ * ipsec_proto.h created to keep prototypes rather than deal with ++ * cyclic dependancies of structures and prototypes in .h files. ++ * ++ * Revision 1.16 2001/09/15 16:24:04 rgb ++ * Re-inject first and last HOLD packet when an eroute REPLACE is done. ++ * ++ * Revision 1.15 2001/09/14 16:58:37 rgb ++ * Added support for storing the first and last packets through a HOLD. ++ * ++ * Revision 1.14 2001/09/08 21:13:32 rgb ++ * Added pfkey ident extension support for ISAKMPd. (NetCelo) ++ * ++ * Revision 1.13 2001/06/14 19:35:09 rgb ++ * Update copyright date. ++ * ++ * Revision 1.12 2001/05/27 06:12:11 rgb ++ * Added structures for pid, packet count and last access time to eroute. ++ * Added packet count to beginning of /proc/net/ipsec_eroute. ++ * ++ * Revision 1.11 2000/09/08 19:12:56 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * ++ * Revision 1.10 1999/11/17 15:53:39 rgb ++ * Changed all occurrences of #include "../../../lib/freeswan.h" ++ * to #include which works due to -Ilibfreeswan in the ++ * klips/net/ipsec/Makefile. ++ * ++ * Revision 1.9 1999/10/01 00:01:23 rgb ++ * Added eroute structure locking. ++ * ++ * Revision 1.8 1999/04/11 00:28:59 henry ++ * GPL boilerplate ++ * ++ * Revision 1.7 1999/04/06 04:54:26 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.6 1999/01/22 06:23:26 rgb ++ * Cruft clean-out. ++ * ++ * Revision 1.5 1998/10/25 02:42:08 rgb ++ * Change return type on ipsec_breakroute and ipsec_makeroute and add an ++ * argument to be able to transmit more infomation about errors. ++ * ++ * Revision 1.4 1998/10/19 14:44:29 rgb ++ * Added inclusion of freeswan.h. ++ * sa_id structure implemented and used: now includes protocol. ++ * ++ * Revision 1.3 1998/07/28 00:03:31 rgb ++ * Comment out temporary inet_nto4u() kluge. ++ * ++ * Revision 1.2 1998/07/14 18:22:00 rgb ++ * Add function to clear the eroute table. ++ * ++ * Revision 1.1 1998/06/18 21:27:49 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid ++ * kernel-build scripts happier in the presence of symlinks ++ * ++ * Revision 1.5 1998/05/25 20:30:38 rgb ++ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions. ++ * ++ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and ++ * add ipsec_rj_walker_delete. ++ * ++ * Revision 1.4 1998/05/21 13:02:56 rgb ++ * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k ++ * limit fix. ++ * ++ * Revision 1.3 1998/04/21 21:29:09 rgb ++ * Rearrange debug switches to change on the fly debug output from user ++ * space. Only kernel changes checked in at this time. radij.c was also ++ * changed to temporarily remove buggy debugging code in rj_delete causing ++ * an OOPS and hence, netlink device open errors. ++ * ++ * Revision 1.2 1998/04/14 17:30:39 rgb ++ * Fix up compiling errors for radij tree memory reclamation. ++ * ++ * Revision 1.1 1998/04/09 03:06:10 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:04 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * No changes. ++ * ++ * Revision 0.3 1996/11/20 14:39:04 ji ++ * Minor cleanups. ++ * Rationalized debugging code. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_rcv.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,279 @@ ++/* ++ * ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_rcv.h,v 1.21 2004/04/06 02:49:08 mcr Exp $ ++ */ ++ ++#ifndef IPSEC_RCV_H ++#define IPSEC_RCV_H ++ ++#include "openswan/ipsec_auth.h" ++ ++#define DB_RX_PKTRX 0x0001 ++#define DB_RX_PKTRX2 0x0002 ++#define DB_RX_DMP 0x0004 ++#define DB_RX_IPSA 0x0010 ++#define DB_RX_XF 0x0020 ++#define DB_RX_IPAD 0x0040 ++#define DB_RX_INAU 0x0080 ++#define DB_RX_OINFO 0x0100 ++#define DB_RX_OINFO2 0x0200 ++#define DB_RX_OH 0x0400 ++#define DB_RX_REPLAY 0x0800 ++ ++#ifdef __KERNEL__ ++/* struct options; */ ++ ++#define __NO_VERSION__ ++#include ++#include /* for CONFIG_IP_FORWARD */ ++#include ++#include ++ ++#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256 ++ ++struct ipsec_birth_reply { ++ int packet_template_len; ++ unsigned char packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN]; ++}; ++ ++extern struct ipsec_birth_reply ipsec_ipv4_birth_packet; ++extern struct ipsec_birth_reply ipsec_ipv6_birth_packet; ++ ++enum ipsec_rcv_value { ++ IPSEC_RCV_LASTPROTO=1, ++ IPSEC_RCV_OK=0, ++ IPSEC_RCV_BADPROTO=-1, ++ IPSEC_RCV_BADLEN=-2, ++ IPSEC_RCV_ESP_BADALG=-3, ++ IPSEC_RCV_3DES_BADBLOCKING=-4, ++ IPSEC_RCV_ESP_DECAPFAIL=-5, ++ IPSEC_RCV_DECAPFAIL=-6, ++ IPSEC_RCV_SAIDNOTFOUND=-7, ++ IPSEC_RCV_IPCOMPALONE=-8, ++ IPSEC_RCV_IPCOMPFAILED=-10, ++ IPSEC_RCV_SAIDNOTLIVE=-11, ++ IPSEC_RCV_FAILEDINBOUND=-12, ++ IPSEC_RCV_LIFETIMEFAILED=-13, ++ IPSEC_RCV_BADAUTH=-14, ++ IPSEC_RCV_REPLAYFAILED=-15, ++ IPSEC_RCV_AUTHFAILED=-16, ++ IPSEC_RCV_REPLAYROLLED=-17, ++ IPSEC_RCV_BAD_DECRYPT=-18 ++}; ++ ++struct ipsec_rcv_state { ++ struct sk_buff *skb; ++ struct net_device_stats *stats; ++ struct iphdr *ipp; ++ struct ipsec_sa *ipsp; ++ int len; ++ int ilen; ++ int authlen; ++ int hard_header_len; ++ int iphlen; ++ struct auth_alg *authfuncs; ++ ip_said said; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ __u8 next_header; ++ __u8 hash[AH_AMAX]; ++ char ipsaddr_txt[ADDRTOA_BUF]; ++ char ipdaddr_txt[ADDRTOA_BUF]; ++ __u8 *octx; ++ __u8 *ictx; ++ int ictx_len; ++ int octx_len; ++ union { ++ struct { ++ struct esphdr *espp; ++ } espstuff; ++ struct { ++ struct ahhdr *ahp; ++ } ahstuff; ++ struct { ++ struct ipcomphdr *compp; ++ } ipcompstuff; ++ } protostuff; ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ __u8 natt_type; ++ __u16 natt_sport; ++ __u16 natt_dport; ++ int natt_len; ++#endif ++}; ++ ++extern int ++#ifdef PROTO_HANDLER_SINGLE_PARM ++ipsec_rcv(struct sk_buff *skb); ++#else /* PROTO_HANDLER_SINGLE_PARM */ ++ipsec_rcv(struct sk_buff *skb, ++#ifdef NET_21 ++ unsigned short xlen); ++#else /* NET_21 */ ++ struct device *dev, ++ struct options *opt, ++ __u32 daddr, ++ unsigned short len, ++ __u32 saddr, ++ int redo, ++ struct inet_protocol *protocol); ++#endif /* NET_21 */ ++#endif /* PROTO_HANDLER_SINGLE_PARM */ ++ ++#ifdef CONFIG_IPSEC_DEBUG ++extern int debug_rcv; ++#endif /* CONFIG_IPSEC_DEBUG */ ++#define ipsec_rcv_dmp(_x,_y, _z) if (debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp(_x,_y,_z) ++ ++extern int sysctl_ipsec_inbound_policy_check; ++#endif /* __KERNEL__ */ ++ ++#endif /* IPSEC_RCV_H */ ++ ++/* ++ * $Log: ipsec_rcv.h,v $ ++ * Revision 1.21 2004/04/06 02:49:08 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.20 2004/04/05 19:55:06 mcr ++ * Moved from linux/include/freeswan/ipsec_rcv.h,v ++ * ++ * Revision 1.19 2003/12/15 18:13:09 mcr ++ * when compiling with NAT traversal, don't assume that the ++ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP ++ * is set. ++ * ++ * Revision 1.18 2003/12/13 19:10:16 mcr ++ * refactored rcv and xmit code - same as FS 2.05. ++ * ++ * Revision 1.17 2002/09/03 16:32:32 mcr ++ * definitions of ipsec_birth_reply. ++ * ++ * Revision 1.16 2002/05/14 02:36:00 rgb ++ * Change references to _TDB to _IPSA. ++ * ++ * Revision 1.15 2002/04/24 07:36:47 mcr ++ * Moved from ./klips/net/ipsec/ipsec_rcv.h,v ++ * ++ * Revision 1.14 2001/09/07 22:15:48 rgb ++ * Fix for removal of transport layer protocol handler arg in 2.4.4. ++ * ++ * Revision 1.13 2001/06/14 19:35:09 rgb ++ * Update copyright date. ++ * ++ * Revision 1.12 2001/03/16 07:36:44 rgb ++ * Fixed #endif comment to sate compiler. ++ * ++ * Revision 1.11 2000/09/21 04:34:21 rgb ++ * Moved declaration of sysctl_ipsec_inbound_policy_check outside ++ * CONFIG_IPSEC_DEBUG. (MB) ++ * ++ * Revision 1.10 2000/09/18 02:36:10 rgb ++ * Exported sysctl_ipsec_inbound_policy_check for skb_decompress(). ++ * ++ * Revision 1.9 2000/09/08 19:12:56 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * ++ * Revision 1.8 1999/11/18 04:09:19 rgb ++ * Replaced all kernel version macros to shorter, readable form. ++ * ++ * Revision 1.7 1999/05/25 01:45:37 rgb ++ * Fix version macros for 2.0.x as a module. ++ * ++ * Revision 1.6 1999/05/08 21:24:27 rgb ++ * Add includes for 2.2.x include into net/ipv4/protocol.c ++ * ++ * Revision 1.5 1999/05/05 22:02:32 rgb ++ * Add a quick and dirty port to 2.2 kernels by Marc Boucher . ++ * ++ * Revision 1.4 1999/04/11 00:28:59 henry ++ * GPL boilerplate ++ * ++ * Revision 1.3 1999/04/06 04:54:27 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.2 1999/01/22 20:06:59 rgb ++ * Fixed cut-and-paste error from ipsec_esp.h. ++ * ++ * Revision 1.1 1999/01/21 20:29:12 rgb ++ * Converted from transform switching to algorithm switching. ++ * ++ * Log: ipsec_esp.h,v ++ * Revision 1.4 1998/08/12 00:07:32 rgb ++ * Added data structures for new xforms: null, {,3}dessha1. ++ * ++ * Revision 1.3 1998/07/14 15:57:01 rgb ++ * Add #ifdef __KERNEL__ to protect kernel-only structures. ++ * ++ * Revision 1.2 1998/06/25 19:33:46 rgb ++ * Add prototype for protocol receive function. ++ * Rearrange for more logical layout. ++ * ++ * Revision 1.1 1998/06/18 21:27:45 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid ++ * kernel-build scripts happier in the presence of symlinks ++ * ++ * Revision 1.6 1998/06/05 02:28:08 rgb ++ * Minor comment fix. ++ * ++ * Revision 1.5 1998/05/27 22:34:00 rgb ++ * Changed structures to accomodate key separation. ++ * ++ * Revision 1.4 1998/05/18 22:28:43 rgb ++ * Disable key printing facilities from /proc/net/ipsec_*. ++ * ++ * Revision 1.3 1998/04/21 21:29:07 rgb ++ * Rearrange debug switches to change on the fly debug output from user ++ * space. Only kernel changes checked in at this time. radij.c was also ++ * changed to temporarily remove buggy debugging code in rj_delete causing ++ * an OOPS and hence, netlink device open errors. ++ * ++ * Revision 1.2 1998/04/12 22:03:20 rgb ++ * Updated ESP-3DES-HMAC-MD5-96, ++ * ESP-DES-HMAC-MD5-96, ++ * AH-HMAC-MD5-96, ++ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository ++ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. ++ * ++ * Fixed eroute references in /proc/net/ipsec*. ++ * ++ * Started to patch module unloading memory leaks in ipsec_netlink and ++ * radij tree unloading. ++ * ++ * Revision 1.1 1998/04/09 03:06:00 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:02 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.5 1997/06/03 04:24:48 ji ++ * Added ESP-3DES-MD5-96 transform. ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * Added definitions for new ESP transforms. ++ * ++ * Revision 0.3 1996/11/20 14:35:48 ji ++ * Minor Cleanup. ++ * Rationalized debugging code. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * ++ */ ++ ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_sa.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,341 @@ ++/* ++ * @(#) Definitions of IPsec Security Association (ipsec_sa) ++ * ++ * Copyright (C) 2001, 2002, 2003 ++ * Richard Guy Briggs ++ * and Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_sa.h,v 1.19 2004/04/05 19:55:06 mcr Exp $ ++ * ++ * This file derived from ipsec_xform.h on 2001/9/18 by mcr. ++ * ++ */ ++ ++/* ++ * This file describes the IPsec Security Association Structure. ++ * ++ * This structure keeps track of a single transform that may be done ++ * to a set of packets. It can describe applying the transform or ++ * apply the reverse. (e.g. compression vs expansion). However, it ++ * only describes one at a time. To describe both, two structures would ++ * be used, but since the sides of the transform are performed ++ * on different machines typically it is usual to have only one side ++ * of each association. ++ * ++ */ ++ ++#ifndef _IPSEC_SA_H_ ++ ++#ifdef __KERNEL__ ++#include "ipsec_stats.h" ++#include "ipsec_life.h" ++#include "ipsec_eroute.h" ++#endif /* __KERNEL__ */ ++#include "ipsec_param.h" ++ ++ ++/* SAs are held in a table. ++ * Entries in this table are referenced by IPsecSAref_t values. ++ * IPsecSAref_t values are conceptually subscripts. Because ++ * we want to allocate the table piece-meal, the subscripting ++ * is implemented with two levels, a bit like paged virtual memory. ++ * This representation mechanism is known as an Iliffe Vector. ++ * ++ * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH ++ * pointers to subtables. ++ * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which ++ * is a pointer to an SA. ++ * ++ * An IPsecSAref_t contains either an exceptional value (signified by the ++ * high-order bit being on) or a reference to a table entry. A table entry ++ * reference has the subtable subscript in the low-order ++ * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript ++ * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits. ++ * ++ * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is ++ * IPsecSAref2table(x). It is of type struct IPsecSArefSubTable *. ++ * ++ * The pointer to the SA for x is IPsecSAref2SA(x). It is of type ++ * struct ipsec_sa*. The macro definition clearly shows the two-level ++ * access needed to find the SA pointer. ++ * ++ * The Maintable is allocated when IPsec is initialized. ++ * Each subtable is allocated when needed, but the first is allocated ++ * when IPsec is initialized. ++ * ++ * IPsecSAref_t is designed to be smaller than an NFmark so that ++ * they can be stored in NFmarks and still leave a few bits for other ++ * purposes. The spare bits are in the low order of the NFmark ++ * but in the high order of the IPsecSAref_t, so conversion is required. ++ * We pick the upper bits of NFmark on the theory that they are less likely to ++ * interfere with more pedestrian uses of nfmark. ++ */ ++ ++ ++typedef unsigned short int IPsecRefTableUnusedCount; ++ ++#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH) ++ ++#ifdef __KERNEL__ ++#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0) ++#error "IPSEC_SA_REF_TABLE_IDX_WIDTH("IPSEC_SA_REF_TABLE_IDX_WIDTH") MUST be < 1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH("IPSEC_SA_REF_MAINTABLE_IDX_WIDTH")" ++#endif ++ ++#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH) ++ ++#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH) ++#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) ++ ++#ifdef CONFIG_NETFILTER ++#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark ++#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL)) ++#else /* CONFIG_NETFILTER */ ++/* just make it work for now, it doesn't matter, since there is no nfmark */ ++#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long ++#endif /* CONFIG_NETFILTER */ ++#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE)) ++#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t)) ++ ++#define IPSEC_SA_REF_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH)) ++#define IPSEC_SA_REF_TABLE_MASK ((IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) ++#define IPSEC_SA_REF_ENTRY_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)) ++ ++#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) ++#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK) ++#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y)) ++ ++#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)]) ++#define IPsecSA2SAref(x) ((x)->ips_ref) ++ ++#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */ ++ ++/* 'struct ipsec_sa' should be 64bit aligned when allocated. */ ++struct ipsec_sa ++{ ++ IPsecSAref_t ips_ref; /* reference table entry number */ ++ atomic_t ips_refcount; /* reference count for this struct */ ++ struct ipsec_sa *ips_hnext; /* next in hash chain */ ++ struct ipsec_sa *ips_inext; /* pointer to next xform */ ++ struct ipsec_sa *ips_onext; /* pointer to prev xform */ ++ ++ struct ifnet *ips_rcvif; /* related rcv encap interface */ ++ ++ ip_said ips_said; /* SA ID */ ++ ++ __u32 ips_seq; /* seq num of msg that initiated this SA */ ++ __u32 ips_pid; /* PID of process that initiated this SA */ ++ __u8 ips_authalg; /* auth algorithm for this SA */ ++ __u8 ips_encalg; /* enc algorithm for this SA */ ++ ++ struct ipsec_stats ips_errs; ++ ++ __u8 ips_replaywin; /* replay window size */ ++ __u8 ips_state; /* state of SA */ ++ __u32 ips_replaywin_lastseq; /* last pkt sequence num */ ++ __u64 ips_replaywin_bitmap; /* bitmap of received pkts */ ++ __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */ ++ ++ __u32 ips_flags; /* generic xform flags */ ++ ++ ++ struct ipsec_lifetimes ips_life; /* lifetime records */ ++ ++ /* selector information */ ++ __u8 ips_transport_protocol; /* protocol for this SA, if ports are involved */ ++ struct sockaddr*ips_addr_s; /* src sockaddr */ ++ struct sockaddr*ips_addr_d; /* dst sockaddr */ ++ struct sockaddr*ips_addr_p; /* proxy sockaddr */ ++ __u16 ips_addr_s_size; ++ __u16 ips_addr_d_size; ++ __u16 ips_addr_p_size; ++ ip_address ips_flow_s; ++ ip_address ips_flow_d; ++ ip_address ips_mask_s; ++ ip_address ips_mask_d; ++ ++ __u16 ips_key_bits_a; /* size of authkey in bits */ ++ __u16 ips_auth_bits; /* size of authenticator in bits */ ++ __u16 ips_key_bits_e; /* size of enckey in bits */ ++ __u16 ips_iv_bits; /* size of IV in bits */ ++ __u8 ips_iv_size; ++ __u16 ips_key_a_size; ++ __u16 ips_key_e_size; ++ ++ caddr_t ips_key_a; /* authentication key */ ++ caddr_t ips_key_e; /* encryption key */ ++ caddr_t ips_iv; /* Initialisation Vector */ ++ ++ struct ident ips_ident_s; /* identity src */ ++ struct ident ips_ident_d; /* identity dst */ ++ ++#ifdef CONFIG_IPSEC_IPCOMP ++ __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */ ++ __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */ ++ __u64 ips_comp_ratio_cbytes; /* compressed bytes */ ++ __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */ ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ __u8 ips_natt_type; ++ __u8 ips_natt_reserved[3]; ++ __u16 ips_natt_sport; ++ __u16 ips_natt_dport; ++ ++ struct sockaddr *ips_natt_oa; ++ __u16 ips_natt_oa_size; ++ __u16 ips_natt_reserved2; ++#endif ++ ++#if 0 ++ __u32 ips_sens_dpd; ++ __u8 ips_sens_sens_level; ++ __u8 ips_sens_sens_len; ++ __u64* ips_sens_sens_bitmap; ++ __u8 ips_sens_integ_level; ++ __u8 ips_sens_integ_len; ++ __u64* ips_sens_integ_bitmap; ++#endif ++ struct ipsec_alg_enc *ips_alg_enc; ++ struct ipsec_alg_auth *ips_alg_auth; ++ IPsecSAref_t ips_ref_rel; ++}; ++ ++struct IPsecSArefSubTable ++{ ++ struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES]; ++}; ++ ++struct ipsec_sadb { ++ struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES]; ++ IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES]; ++ int refFreeListHead; ++ int refFreeListTail; ++ IPsecSAref_t refFreeListCont; ++ IPsecSAref_t said_hash[SADB_HASHMOD]; ++ spinlock_t sadb_lock; ++}; ++ ++extern struct ipsec_sadb ipsec_sadb; ++ ++extern int ipsec_SAref_recycle(void); ++extern int ipsec_SArefSubTable_alloc(unsigned table); ++extern int ipsec_saref_freelist_init(void); ++extern int ipsec_sadb_init(void); ++extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */ ++extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */ ++extern int ipsec_sa_free(struct ipsec_sa* ips); ++extern int ipsec_sa_put(struct ipsec_sa *ips); ++extern int ipsec_sa_add(struct ipsec_sa *ips); ++extern int ipsec_sa_del(struct ipsec_sa *ips); ++extern int ipsec_sa_delchain(struct ipsec_sa *ips); ++extern int ipsec_sadb_cleanup(__u8 proto); ++extern int ipsec_sadb_free(void); ++extern int ipsec_sa_wipe(struct ipsec_sa *ips); ++#endif /* __KERNEL__ */ ++ ++enum ipsec_direction { ++ ipsec_incoming = 1, ++ ipsec_outgoing = 2 ++}; ++ ++#define _IPSEC_SA_H_ ++#endif /* _IPSEC_SA_H_ */ ++ ++/* ++ * $Log: ipsec_sa.h,v $ ++ * Revision 1.19 2004/04/05 19:55:06 mcr ++ * Moved from linux/include/freeswan/ipsec_sa.h,v ++ * ++ * Revision 1.18 2004/04/05 19:41:05 mcr ++ * merged alg-branch code. ++ * ++ * Revision 1.17.2.1 2003/12/22 15:25:52 jjo ++ * . Merged algo-0.8.1-rc11-test1 into alg-branch ++ * ++ * Revision 1.17 2003/12/10 01:20:06 mcr ++ * NAT-traversal patches to KLIPS. ++ * ++ * Revision 1.16 2003/10/31 02:27:05 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.15.4.1 2003/10/29 01:10:19 mcr ++ * elimited "struct sa_id" ++ * ++ * Revision 1.15 2003/05/11 00:53:09 mcr ++ * IPsecSAref_t and macros were moved to freeswan.h. ++ * ++ * Revision 1.14 2003/02/12 19:31:55 rgb ++ * Fixed bug in "file seen" machinery. ++ * Updated copyright year. ++ * ++ * Revision 1.13 2003/01/30 02:31:52 rgb ++ * ++ * Re-wrote comments describing SAref system for accuracy. ++ * Rename SAref table macro names for clarity. ++ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. ++ * Transmit error code through to caller from callee for better diagnosis of problems. ++ * Enclose all macro arguments in parens to avoid any possible obscrure bugs. ++ * ++ * Revision 1.12 2002/10/07 18:31:19 rgb ++ * Change comment to reflect the flexible nature of the main and sub-table widths. ++ * Added a counter for the number of unused entries in each subtable. ++ * Further break up host field type macro to host field. ++ * Move field width sanity checks to ipsec_sa.c ++ * Define a mask for an entire saref. ++ * ++ * Revision 1.11 2002/09/20 15:40:33 rgb ++ * Re-write most of the SAref macros and types to eliminate any pointer references to Entrys. ++ * Fixed SAref/nfmark macros. ++ * Rework saref freeslist. ++ * Place all ipsec sadb globals into one struct. ++ * Restrict some bits to kernel context for use to klips utils. ++ * ++ * Revision 1.10 2002/09/20 05:00:34 rgb ++ * Update copyright date. ++ * ++ * Revision 1.9 2002/09/17 17:19:29 mcr ++ * make it compile even if there is no netfilter - we lost ++ * functionality, but it works, especially on 2.2. ++ * ++ * Revision 1.8 2002/07/28 22:59:53 mcr ++ * clarified/expanded one comment. ++ * ++ * Revision 1.7 2002/07/26 08:48:31 rgb ++ * Added SA ref table code. ++ * ++ * Revision 1.6 2002/05/31 17:27:48 rgb ++ * Comment fix. ++ * ++ * Revision 1.5 2002/05/27 18:55:03 rgb ++ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. ++ * ++ * Revision 1.4 2002/05/23 07:13:36 rgb ++ * Convert "usecount" to "refcount" to remove ambiguity. ++ * ++ * Revision 1.3 2002/04/24 07:36:47 mcr ++ * Moved from ./klips/net/ipsec/ipsec_sa.h,v ++ * ++ * Revision 1.2 2001/11/26 09:16:15 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.1.2.1 2001/09/25 02:24:58 mcr ++ * struct tdb -> struct ipsec_sa. ++ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c ++ * ipsec_xform.c removed. header file still contains useful things. ++ * ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_sha1.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,79 @@ ++/* ++ * RCSID $Id: ipsec_sha1.h,v 1.8 2004/04/05 19:55:07 mcr Exp $ ++ */ ++ ++/* ++ * Here is the original comment from the distribution: ++ ++SHA-1 in C ++By Steve Reid ++100% Public Domain ++ ++ * Adapted for use by the IPSEC code by John Ioannidis ++ */ ++ ++ ++#ifndef _IPSEC_SHA1_H_ ++#define _IPSEC_SHA1_H_ ++ ++typedef struct ++{ ++ __u32 state[5]; ++ __u32 count[2]; ++ __u8 buffer[64]; ++} SHA1_CTX; ++ ++void SHA1Transform(__u32 state[5], __u8 buffer[64]); ++void SHA1Init(void *context); ++void SHA1Update(void *context, unsigned char *data, __u32 len); ++void SHA1Final(unsigned char digest[20], void *context); ++ ++ ++#endif /* _IPSEC_SHA1_H_ */ ++ ++/* ++ * $Log: ipsec_sha1.h,v $ ++ * Revision 1.8 2004/04/05 19:55:07 mcr ++ * Moved from linux/include/freeswan/ipsec_sha1.h,v ++ * ++ * Revision 1.7 2002/09/10 01:45:09 mcr ++ * changed type of MD5_CTX and SHA1_CTX to void * so that ++ * the function prototypes would match, and could be placed ++ * into a pointer to a function. ++ * ++ * Revision 1.6 2002/04/24 07:36:47 mcr ++ * Moved from ./klips/net/ipsec/ipsec_sha1.h,v ++ * ++ * Revision 1.5 1999/12/13 13:59:13 rgb ++ * Quick fix to argument size to Update bugs. ++ * ++ * Revision 1.4 1999/12/07 18:16:23 rgb ++ * Fixed comments at end of #endif lines. ++ * ++ * Revision 1.3 1999/04/06 04:54:27 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.2 1998/11/30 13:22:54 rgb ++ * Rationalised all the klips kernel file headers. They are much shorter ++ * now and won't conflict under RH5.2. ++ * ++ * Revision 1.1 1998/06/18 21:27:50 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid ++ * kernel-build scripts happier in the presence of symlinks ++ * ++ * Revision 1.2 1998/04/23 20:54:05 rgb ++ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when ++ * verified. ++ * ++ * Revision 1.1 1998/04/09 03:04:21 henry ++ * sources moved up from linux/net/ipsec ++ * these two include files modified not to include others except in kernel ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:04 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * New transform ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_stats.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,75 @@ ++/* ++ * @(#) definition of ipsec_stats structure ++ * ++ * Copyright (C) 2001 Richard Guy Briggs ++ * and Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_stats.h,v 1.6 2004/04/05 19:55:07 mcr Exp $ ++ * ++ */ ++ ++/* ++ * This file describes the errors/statistics that FreeSWAN collects. ++ */ ++ ++#ifndef _IPSEC_STATS_H_ ++ ++struct ipsec_stats { ++ __u32 ips_alg_errs; /* number of algorithm errors */ ++ __u32 ips_auth_errs; /* # of authentication errors */ ++ __u32 ips_encsize_errs; /* # of encryption size errors*/ ++ __u32 ips_encpad_errs; /* # of encryption pad errors*/ ++ __u32 ips_replaywin_errs; /* # of pkt sequence errors */ ++}; ++ ++extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...); ++ ++#define _IPSEC_STATS_H_ ++#endif /* _IPSEC_STATS_H_ */ ++ ++/* ++ * $Log: ipsec_stats.h,v $ ++ * Revision 1.6 2004/04/05 19:55:07 mcr ++ * Moved from linux/include/freeswan/ipsec_stats.h,v ++ * ++ * Revision 1.5 2004/04/05 19:41:05 mcr ++ * merged alg-branch code. ++ * ++ * Revision 1.4 2004/03/28 20:27:19 paul ++ * Included tested and confirmed fixes mcr made and dhr verified for ++ * snprint statements. Changed one other snprintf to use ipsec_snprintf ++ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with ++ * dhr. (thanks dhr!) ++ * ++ * Revision 1.4 2004/03/24 01:58:31 mcr ++ * sprintf->snprintf for formatting into proc buffer. ++ * ++ * Revision 1.3.34.1 2004/04/05 04:30:46 mcr ++ * patches for alg-branch to compile/work with 2.x openswan ++ * ++ * Revision 1.3 2002/04/24 07:36:47 mcr ++ * Moved from ./klips/net/ipsec/ipsec_stats.h,v ++ * ++ * Revision 1.2 2001/11/26 09:16:16 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.1.2.1 2001/09/25 02:27:00 mcr ++ * statistics moved to seperate structure. ++ * ++ * ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_tunnel.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,265 @@ ++/* ++ * IPSEC tunneling code ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_tunnel.h,v 1.29 2004/04/05 19:55:07 mcr Exp $ ++ */ ++ ++ ++#ifdef NET_21 ++# define DEV_QUEUE_XMIT(skb, device, pri) {\ ++ skb->dev = device; \ ++ neigh_compat_output(skb); \ ++ /* skb->dst->output(skb); */ \ ++ } ++# define ICMP_SEND(skb_in, type, code, info, dev) \ ++ icmp_send(skb_in, type, code, htonl(info)) ++# define IP_SEND(skb, dev) \ ++ ip_send(skb); ++#else /* NET_21 */ ++# define DEV_QUEUE_XMIT(skb, device, pri) {\ ++ dev_queue_xmit(skb, device, pri); \ ++ } ++# define ICMP_SEND(skb_in, type, code, info, dev) \ ++ icmp_send(skb_in, type, code, info, dev) ++# define IP_SEND(skb, dev) \ ++ if(ntohs(iph->tot_len) > physmtu) { \ ++ ip_fragment(NULL, skb, dev, 0); \ ++ ipsec_kfree_skb(skb); \ ++ } else { \ ++ dev_queue_xmit(skb, dev, SOPRI_NORMAL); \ ++ } ++#endif /* NET_21 */ ++ ++ ++/* ++ * Heavily based on drivers/net/new_tunnel.c. Lots ++ * of ideas also taken from the 2.1.x version of drivers/net/shaper.c ++ */ ++ ++struct ipsectunnelconf ++{ ++ __u32 cf_cmd; ++ union ++ { ++ char cfu_name[12]; ++ } cf_u; ++#define cf_name cf_u.cfu_name ++}; ++ ++#define IPSEC_SET_DEV (SIOCDEVPRIVATE) ++#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1) ++#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2) ++ ++#ifdef __KERNEL__ ++#include ++#ifndef KERNEL_VERSION ++# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) ++#endif ++struct ipsecpriv ++{ ++ struct sk_buff_head sendq; ++ struct device *dev; ++ struct wait_queue *wait_queue; ++ char locked; ++ int (*hard_start_xmit) (struct sk_buff *skb, ++ struct device *dev); ++ int (*hard_header) (struct sk_buff *skb, ++ struct device *dev, ++ unsigned short type, ++ void *daddr, ++ void *saddr, ++ unsigned len); ++#ifdef NET_21 ++ int (*rebuild_header)(struct sk_buff *skb); ++#else /* NET_21 */ ++ int (*rebuild_header)(void *buff, struct device *dev, ++ unsigned long raddr, struct sk_buff *skb); ++#endif /* NET_21 */ ++ int (*set_mac_address)(struct device *dev, void *addr); ++#ifndef NET_21 ++ void (*header_cache_bind)(struct hh_cache **hhp, struct device *dev, ++ unsigned short htype, __u32 daddr); ++#endif /* !NET_21 */ ++ void (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char * haddr); ++ struct net_device_stats *(*get_stats)(struct device *dev); ++ struct net_device_stats mystats; ++ int mtu; /* What is the desired MTU? */ ++}; ++ ++extern char ipsec_tunnel_c_version[]; ++ ++extern struct device *ipsecdevices[IPSEC_NUM_IF]; ++ ++int ipsec_tunnel_init_devices(void); ++ ++/* void */ int ipsec_tunnel_cleanup_devices(void); ++ ++extern /* void */ int ipsec_init(void); ++ ++extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev); ++ ++#ifdef CONFIG_IPSEC_DEBUG ++extern int debug_tunnel; ++extern int sysctl_ipsec_debug_verbose; ++#endif /* CONFIG_IPSEC_DEBUG */ ++#endif /* __KERNEL__ */ ++ ++#ifdef CONFIG_IPSEC_DEBUG ++#define DB_TN_INIT 0x0001 ++#define DB_TN_PROCFS 0x0002 ++#define DB_TN_XMIT 0x0010 ++#define DB_TN_OHDR 0x0020 ++#define DB_TN_CROUT 0x0040 ++#define DB_TN_OXFS 0x0080 ++#define DB_TN_REVEC 0x0100 ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++/* ++ * $Log: ipsec_tunnel.h,v $ ++ * Revision 1.29 2004/04/05 19:55:07 mcr ++ * Moved from linux/include/freeswan/ipsec_tunnel.h,v ++ * ++ * Revision 1.28 2003/06/24 20:22:32 mcr ++ * added new global: ipsecdevices[] so that we can keep track of ++ * the ipsecX devices. They will be referenced with dev_hold(), ++ * so 2.2 may need this as well. ++ * ++ * Revision 1.27 2003/04/03 17:38:09 rgb ++ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. ++ * ++ * Revision 1.26 2003/02/12 19:32:20 rgb ++ * Updated copyright year. ++ * ++ * Revision 1.25 2002/05/27 18:56:07 rgb ++ * Convert to dynamic ipsec device allocation. ++ * ++ * Revision 1.24 2002/04/24 07:36:48 mcr ++ * Moved from ./klips/net/ipsec/ipsec_tunnel.h,v ++ * ++ * Revision 1.23 2001/11/06 19:50:44 rgb ++ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for ++ * use also by pfkey_v2_parser.c ++ * ++ * Revision 1.22 2001/09/15 16:24:05 rgb ++ * Re-inject first and last HOLD packet when an eroute REPLACE is done. ++ * ++ * Revision 1.21 2001/06/14 19:35:10 rgb ++ * Update copyright date. ++ * ++ * Revision 1.20 2000/09/15 11:37:02 rgb ++ * Merge in heavily modified Svenning Soerensen's ++ * IPCOMP zlib deflate code. ++ * ++ * Revision 1.19 2000/09/08 19:12:56 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * ++ * Revision 1.18 2000/07/28 13:50:54 rgb ++ * Changed enet_statistics to net_device_stats and added back compatibility ++ * for pre-2.1.19. ++ * ++ * Revision 1.17 1999/11/19 01:12:15 rgb ++ * Purge unneeded proc_info prototypes, now that static linking uses ++ * dynamic proc_info registration. ++ * ++ * Revision 1.16 1999/11/18 18:51:00 rgb ++ * Changed all device registrations for static linking to ++ * dynamic to reduce the number and size of patches. ++ * ++ * Revision 1.15 1999/11/18 04:14:21 rgb ++ * Replaced all kernel version macros to shorter, readable form. ++ * Added CONFIG_PROC_FS compiler directives in case it is shut off. ++ * Added Marc Boucher's 2.3.25 proc patches. ++ * ++ * Revision 1.14 1999/05/25 02:50:10 rgb ++ * Fix kernel version macros for 2.0.x static linking. ++ * ++ * Revision 1.13 1999/05/25 02:41:06 rgb ++ * Add ipsec_klipsdebug support for static linking. ++ * ++ * Revision 1.12 1999/05/05 22:02:32 rgb ++ * Add a quick and dirty port to 2.2 kernels by Marc Boucher . ++ * ++ * Revision 1.11 1999/04/29 15:19:50 rgb ++ * Add return values to init and cleanup functions. ++ * ++ * Revision 1.10 1999/04/16 16:02:39 rgb ++ * Bump up macro to 4 ipsec I/Fs. ++ * ++ * Revision 1.9 1999/04/15 15:37:25 rgb ++ * Forward check changes from POST1_00 branch. ++ * ++ * Revision 1.5.2.1 1999/04/02 04:26:14 rgb ++ * Backcheck from HEAD, pre1.0. ++ * ++ * Revision 1.8 1999/04/11 00:29:01 henry ++ * GPL boilerplate ++ * ++ * Revision 1.7 1999/04/06 04:54:28 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.6 1999/03/31 05:44:48 rgb ++ * Keep PMTU reduction private. ++ * ++ * Revision 1.5 1999/02/10 22:31:20 rgb ++ * Change rebuild_header member to reflect generality of link layer. ++ * ++ * Revision 1.4 1998/12/01 13:22:04 rgb ++ * Added support for debug printing of version info. ++ * ++ * Revision 1.3 1998/07/29 20:42:46 rgb ++ * Add a macro for clearing all tunnel devices. ++ * Rearrange structures and declarations for sharing with userspace. ++ * ++ * Revision 1.2 1998/06/25 20:01:45 rgb ++ * Make prototypes available for ipsec_init and ipsec proc_dir_entries ++ * for static linking. ++ * ++ * Revision 1.1 1998/06/18 21:27:50 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid ++ * kernel-build scripts happier in the presence of symlinks ++ * ++ * Revision 1.3 1998/05/18 21:51:50 rgb ++ * Added macros for num of I/F's and a procfs debug switch. ++ * ++ * Revision 1.2 1998/04/21 21:29:09 rgb ++ * Rearrange debug switches to change on the fly debug output from user ++ * space. Only kernel changes checked in at this time. radij.c was also ++ * changed to temporarily remove buggy debugging code in rj_delete causing ++ * an OOPS and hence, netlink device open errors. ++ * ++ * Revision 1.1 1998/04/09 03:06:13 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:05 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.5 1997/06/03 04:24:48 ji ++ * Added transport mode. ++ * Changed the way routing is done. ++ * Lots of bug fixes. ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * No changes. ++ * ++ * Revision 0.3 1996/11/20 14:39:04 ji ++ * Minor cleanups. ++ * Rationalized debugging code. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_xform.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,254 @@ ++/* ++ * Definitions relevant to IPSEC transformations ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. ++ * COpyright (C) 2003 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_xform.h,v 1.40 2004/04/06 02:49:08 mcr Exp $ ++ */ ++ ++#ifndef _IPSEC_XFORM_H_ ++ ++#include ++ ++#define XF_NONE 0 /* No transform set */ ++#define XF_IP4 1 /* IPv4 inside IPv4 */ ++#define XF_AHMD5 2 /* AH MD5 */ ++#define XF_AHSHA 3 /* AH SHA */ ++#define XF_ESP3DES 5 /* ESP DES3-CBC */ ++#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */ ++#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */ ++#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */ ++#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */ ++#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */ ++#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */ ++#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */ ++#define XF_IP6 15 /* IPv6 inside IPv6 */ ++#define XF_COMPDEFLATE 16 /* IPCOMP deflate */ ++ ++#define XF_CLR 126 /* Clear SA table */ ++#define XF_DEL 127 /* Delete SA */ ++ ++/* IPsec AH transform values ++ * RFC 2407 ++ * draft-ietf-ipsec-doi-tc-mib-02.txt ++ */ ++ ++#define AH_NONE 0 ++#define AH_MD5 2 ++#define AH_SHA 3 ++/* draft-ietf-ipsec-ciph-aes-cbc-03.txt */ ++#define AH_SHA2_256 5 ++#define AH_SHA2_384 6 ++#define AH_SHA2_512 7 ++#define AH_RIPEMD 8 ++#define AH_MAX 15 ++ ++/* IPsec ESP transform values */ ++ ++#define ESP_NONE 0 ++#define ESP_DES 2 ++#define ESP_3DES 3 ++#define ESP_RC5 4 ++#define ESP_IDEA 5 ++#define ESP_CAST 6 ++#define ESP_BLOWFISH 7 ++#define ESP_3IDEA 8 ++#define ESP_RC4 10 ++#define ESP_NULL 11 ++#define ESP_AES 12 ++ ++/* as draft-ietf-ipsec-ciph-aes-cbc-02.txt */ ++#define ESP_MARS 249 ++#define ESP_RC6 250 ++#define ESP_SERPENT 252 ++#define ESP_TWOFISH 253 ++ ++/* IPCOMP transform values */ ++ ++#define IPCOMP_NONE 0 ++#define IPCOMP_OUI 1 ++#define IPCOMP_DEFLAT 2 ++#define IPCOMP_LZS 3 ++#define IPCOMP_V42BIS 4 ++ ++#define XFT_AUTH 0x0001 ++#define XFT_CONF 0x0100 ++ ++/* available if CONFIG_IPSEC_DEBUG is defined */ ++#define DB_XF_INIT 0x0001 ++ ++#define PROTO2TXT(x) \ ++ (x) == IPPROTO_AH ? "AH" : \ ++ (x) == IPPROTO_ESP ? "ESP" : \ ++ (x) == IPPROTO_IPIP ? "IPIP" : \ ++ (x) == IPPROTO_COMP ? "COMP" : \ ++ "UNKNOWN_proto" ++static inline const char *enc_name_id (unsigned id) { ++ static char buf[16]; ++ snprintf(buf, sizeof(buf), "_ID%d", id); ++ return buf; ++} ++static inline const char *auth_name_id (unsigned id) { ++ static char buf[16]; ++ snprintf(buf, sizeof(buf), "_ID%d", id); ++ return buf; ++} ++#define IPS_XFORM_NAME(x) \ ++ PROTO2TXT((x)->ips_said.proto), \ ++ (x)->ips_said.proto == IPPROTO_COMP ? \ ++ ((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \ ++ "_DEFLATE" : "_UNKNOWN_comp") : \ ++ (x)->ips_encalg == ESP_NONE ? "" : \ ++ (x)->ips_encalg == ESP_3DES ? "_3DES" : \ ++ (x)->ips_encalg == ESP_AES ? "_AES" : \ ++ (x)->ips_encalg == ESP_SERPENT ? "_SERPENT" : \ ++ (x)->ips_encalg == ESP_TWOFISH ? "_TWOFISH" : \ ++ enc_name_id(x->ips_encalg)/* "_UNKNOWN_encr" */, \ ++ (x)->ips_authalg == AH_NONE ? "" : \ ++ (x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \ ++ (x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \ ++ (x)->ips_authalg == AH_SHA2_256 ? "_HMAC_SHA2_256" : \ ++ (x)->ips_authalg == AH_SHA2_384 ? "_HMAC_SHA2_384" : \ ++ (x)->ips_authalg == AH_SHA2_512 ? "_HMAC_SHA2_512" : \ ++ auth_name_id(x->ips_authalg) /* "_UNKNOWN_auth" */ \ ++ ++#ifdef __KERNEL__ ++struct ipsec_rcv_state; ++struct ipsec_xmit_state; ++ ++struct xform_functions { ++ enum ipsec_rcv_value (*rcv_checks)(struct ipsec_rcv_state *irs, ++ struct sk_buff *skb); ++ enum ipsec_rcv_value (*rcv_decrypt)(struct ipsec_rcv_state *irs); ++ ++ enum ipsec_rcv_value (*rcv_setup_auth)(struct ipsec_rcv_state *irs, ++ struct sk_buff *skb, ++ __u32 *replay, ++ unsigned char **authenticator); ++ enum ipsec_rcv_value (*rcv_calc_auth)(struct ipsec_rcv_state *irs, ++ struct sk_buff *skb); ++ ++ enum ipsec_xmit_value (*xmit_setup)(struct ipsec_xmit_state *ixs); ++ enum ipsec_xmit_value (*xmit_encrypt)(struct ipsec_xmit_state *ixs); ++ ++ enum ipsec_xmit_value (*xmit_setup_auth)(struct ipsec_xmit_state *ixs, ++ struct sk_buff *skb, ++ __u32 *replay, ++ unsigned char **authenticator); ++ enum ipsec_xmit_value (*xmit_calc_auth)(struct ipsec_xmit_state *ixs, ++ struct sk_buff *skb); ++ int xmit_headroom; ++ int xmit_needtailroom; ++}; ++ ++#endif /* __KERNEL__ */ ++ ++#ifdef CONFIG_IPSEC_DEBUG ++extern void ipsec_dmp(char *s, caddr_t bb, int len); ++#else /* CONFIG_IPSEC_DEBUG */ ++#define ipsec_dmp(_x, _y, _z) ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ ++#define _IPSEC_XFORM_H_ ++#endif /* _IPSEC_XFORM_H_ */ ++ ++/* ++ * $Log: ipsec_xform.h,v $ ++ * Revision 1.40 2004/04/06 02:49:08 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.39 2004/04/05 19:55:07 mcr ++ * Moved from linux/include/freeswan/ipsec_xform.h,v ++ * ++ * Revision 1.38 2004/04/05 19:41:05 mcr ++ * merged alg-branch code. ++ * ++ * Revision 1.37 2003/12/13 19:10:16 mcr ++ * refactored rcv and xmit code - same as FS 2.05. ++ * ++ * Revision 1.36.34.1 2003/12/22 15:25:52 jjo ++ * Merged algo-0.8.1-rc11-test1 into alg-branch ++ * ++ * Revision 1.36 2002/04/24 07:36:48 mcr ++ * Moved from ./klips/net/ipsec/ipsec_xform.h,v ++ * ++ * Revision 1.35 2001/11/26 09:23:51 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.33.2.1 2001/09/25 02:24:58 mcr ++ * struct tdb -> struct ipsec_sa. ++ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c ++ * ipsec_xform.c removed. header file still contains useful things. ++ * ++ * Revision 1.34 2001/11/06 19:47:17 rgb ++ * Changed lifetime_packets to uint32 from uint64. ++ * ++ * Revision 1.33 2001/09/08 21:13:34 rgb ++ * Added pfkey ident extension support for ISAKMPd. (NetCelo) ++ * ++ * Revision 1.32 2001/07/06 07:40:01 rgb ++ * Reformatted for readability. ++ * Added inbound policy checking fields for use with IPIP SAs. ++ * ++ * Revision 1.31 2001/06/14 19:35:11 rgb ++ * Update copyright date. ++ * ++ * Revision 1.30 2001/05/30 08:14:03 rgb ++ * Removed vestiges of esp-null transforms. ++ * ++ * Revision 1.29 2001/01/30 23:42:47 rgb ++ * Allow pfkey msgs from pid other than user context required for ACQUIRE ++ * and subsequent ADD or UDATE. ++ * ++ * Revision 1.28 2000/11/06 04:30:40 rgb ++ * Add Svenning's adaptive content compression. ++ * ++ * Revision 1.27 2000/09/19 00:38:25 rgb ++ * Fixed algorithm name bugs introduced for ipcomp. ++ * ++ * Revision 1.26 2000/09/17 21:36:48 rgb ++ * Added proto2txt macro. ++ * ++ * Revision 1.25 2000/09/17 18:56:47 rgb ++ * Added IPCOMP support. ++ * ++ * Revision 1.24 2000/09/12 19:34:12 rgb ++ * Defined XF_IP6 from Gerhard for ipv6 tunnel support. ++ * ++ * Revision 1.23 2000/09/12 03:23:14 rgb ++ * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb. ++ * ++ * Revision 1.22 2000/09/08 19:12:56 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * ++ * Revision 1.21 2000/09/01 18:32:43 rgb ++ * Added (disabled) sensitivity members to tdb struct. ++ * ++ * Revision 1.20 2000/08/30 05:31:01 rgb ++ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst. ++ * Kill remainder of tdb_xform, tdb_xdata, xformsw. ++ * ++ * Revision 1.19 2000/08/01 14:51:52 rgb ++ * Removed _all_ remaining traces of DES. ++ * ++ * Revision 1.18 2000/01/21 06:17:45 rgb ++ * Tidied up spacing. ++ * ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/ipsec_xmit.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,176 @@ ++/* ++ * IPSEC tunneling code ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_xmit.h,v 1.9 2004/04/06 02:49:08 mcr Exp $ ++ */ ++ ++#include "openswan/ipsec_sa.h" ++ ++enum ipsec_xmit_value ++{ ++ IPSEC_XMIT_STOLEN=2, ++ IPSEC_XMIT_PASS=1, ++ IPSEC_XMIT_OK=0, ++ IPSEC_XMIT_ERRMEMALLOC=-1, ++ IPSEC_XMIT_ESP_BADALG=-2, ++ IPSEC_XMIT_BADPROTO=-3, ++ IPSEC_XMIT_ESP_PUSHPULLERR=-4, ++ IPSEC_XMIT_BADLEN=-5, ++ IPSEC_XMIT_AH_BADALG=-6, ++ IPSEC_XMIT_SAIDNOTFOUND=-7, ++ IPSEC_XMIT_SAIDNOTLIVE=-8, ++ IPSEC_XMIT_REPLAYROLLED=-9, ++ IPSEC_XMIT_LIFETIMEFAILED=-10, ++ IPSEC_XMIT_CANNOTFRAG=-11, ++ IPSEC_XMIT_MSSERR=-12, ++ IPSEC_XMIT_ERRSKBALLOC=-13, ++ IPSEC_XMIT_ENCAPFAIL=-14, ++ IPSEC_XMIT_NODEV=-15, ++ IPSEC_XMIT_NOPRIVDEV=-16, ++ IPSEC_XMIT_NOPHYSDEV=-17, ++ IPSEC_XMIT_NOSKB=-18, ++ IPSEC_XMIT_NOIPV6=-19, ++ IPSEC_XMIT_NOIPOPTIONS=-20, ++ IPSEC_XMIT_TTLEXPIRED=-21, ++ IPSEC_XMIT_BADHHLEN=-22, ++ IPSEC_XMIT_PUSHPULLERR=-23, ++ IPSEC_XMIT_ROUTEERR=-24, ++ IPSEC_XMIT_RECURSDETECT=-25, ++ IPSEC_XMIT_IPSENDFAILURE=-26, ++ IPSEC_XMIT_ESPUDP=-27, ++ IPSEC_XMIT_ESPUDP_BADTYPE=-28, ++}; ++ ++struct ipsec_xmit_state ++{ ++ struct sk_buff *skb; /* working skb pointer */ ++ struct device *dev; /* working dev pointer */ ++ struct ipsecpriv *prv; /* Our device' private space */ ++ struct sk_buff *oskb; /* Original skb pointer */ ++ struct net_device_stats *stats; /* This device's statistics */ ++ struct iphdr *iph; /* Our new IP header */ ++ __u32 newdst; /* The other SG's IP address */ ++ __u32 orgdst; /* Original IP destination address */ ++ __u32 orgedst; /* 1st SG's IP address */ ++ __u32 newsrc; /* The new source SG's IP address */ ++ __u32 orgsrc; /* Original IP source address */ ++ __u32 innersrc; /* Innermost IP source address */ ++ int iphlen; /* IP header length */ ++ int pyldsz; /* upper protocol payload size */ ++ int headroom; ++ int tailroom; ++ int authlen; ++ int max_headroom; /* The extra header space needed */ ++ int max_tailroom; /* The extra stuffing needed */ ++ int ll_headroom; /* The extra link layer hard_header space needed */ ++ int tot_headroom; /* The total header space needed */ ++ int tot_tailroom; /* The totalstuffing needed */ ++ __u8 *saved_header; /* saved copy of the hard header */ ++ unsigned short sport, dport; ++ ++ struct sockaddr_encap matcher; /* eroute search key */ ++ struct eroute *eroute; ++ struct ipsec_sa *ipsp, *ipsq; /* ipsec_sa pointers */ ++ char sa_txt[SATOT_BUF]; ++ size_t sa_len; ++ int hard_header_stripped; /* has the hard header been removed yet? */ ++ int hard_header_len; ++ struct device *physdev; ++/* struct device *virtdev; */ ++ short physmtu; ++ short mtudiff; ++#ifdef NET_21 ++ struct rtable *route; ++#endif /* NET_21 */ ++ ip_said outgoing_said; ++#ifdef NET_21 ++ int pass; ++#endif /* NET_21 */ ++ int error; ++ uint32_t eroute_pid; ++ struct ipsec_sa ips; ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ uint8_t natt_type; ++ uint8_t natt_head; ++ uint16_t natt_sport; ++ uint16_t natt_dport; ++#endif ++}; ++ ++enum ipsec_xmit_value ++ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs); ++ ++enum ipsec_xmit_value ++ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs); ++ ++enum ipsec_xmit_value ++ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs); ++ ++extern void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er); ++ ++ ++extern int ipsec_xmit_trap_count; ++extern int ipsec_xmit_trap_sendcount; ++ ++#ifdef CONFIG_IPSEC_DEBUG ++extern int debug_tunnel; ++extern int sysctl_ipsec_debug_verbose; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++#define debug_xmit debug_tunnel ++ ++#define ipsec_xmit_dmp(_x,_y, _z) if (debug_xmit && sysctl_ipsec_debug_verbose) ipsec_dmp(_x,_y,_z) ++ ++extern int sysctl_ipsec_icmp; ++extern int sysctl_ipsec_tos; ++ ++ ++/* ++ * $Log: ipsec_xmit.h,v $ ++ * Revision 1.9 2004/04/06 02:49:08 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.8 2004/04/05 19:55:07 mcr ++ * Moved from linux/include/freeswan/ipsec_xmit.h,v ++ * ++ * Revision 1.7 2004/02/03 03:11:40 mcr ++ * new xmit type if the UDP encapsulation is wrong. ++ * ++ * Revision 1.6 2003/12/13 19:10:16 mcr ++ * refactored rcv and xmit code - same as FS 2.05. ++ * ++ * Revision 1.5 2003/12/10 01:20:06 mcr ++ * NAT-traversal patches to KLIPS. ++ * ++ * Revision 1.4 2003/12/06 16:37:04 mcr ++ * 1.4.7a X.509 patch applied. ++ * ++ * Revision 1.3 2003/10/31 02:27:05 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.2.4.2 2003/10/29 01:10:19 mcr ++ * elimited "struct sa_id" ++ * ++ * Revision 1.2.4.1 2003/09/21 13:59:38 mcr ++ * pre-liminary X.509 patch - does not yet pass tests. ++ * ++ * Revision 1.2 2003/06/20 01:42:13 mcr ++ * added counters to measure how many ACQUIREs we send to pluto, ++ * and how many are successfully sent. ++ * ++ * Revision 1.1 2003/02/12 19:31:03 rgb ++ * Refactored from ipsec_tunnel.c ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/passert.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,64 @@ ++/* ++ * sanitize a string into a printable format. ++ * ++ * Copyright (C) 1998-2002 D. Hugh Redelmeier. ++ * Copyright (C) 2003 Michael Richardson ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: passert.h,v 1.4 2004/04/06 02:49:08 mcr Exp $ ++ */ ++ ++#include "openswan.h" ++ ++/* our versions of assert: log result */ ++ ++#ifdef DEBUG ++ ++extern void passert_fail(const char *pred_str ++ , const char *file_str, unsigned long line_no) NEVER_RETURNS; ++ ++extern void pexpect_log(const char *pred_str ++ , const char *file_str, unsigned long line_no); ++ ++# define impossible() passert_fail("impossible", __FILE__, __LINE__) ++ ++extern void switch_fail(int n ++ , const char *file_str, unsigned long line_no) NEVER_RETURNS; ++ ++# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__) ++ ++# define passert(pred) { \ ++ if (!(pred)) \ ++ passert_fail(#pred, __FILE__, __LINE__); \ ++ } ++ ++# define pexpect(pred) { \ ++ if (!(pred)) \ ++ pexpect_log(#pred, __FILE__, __LINE__); \ ++ } ++ ++/* assert that an err_t is NULL; evaluate exactly once */ ++# define happy(x) { \ ++ err_t ugh = x; \ ++ if (ugh != NULL) \ ++ passert_fail(ugh, __FILE__, __LINE__); \ ++ } ++ ++#else /*!DEBUG*/ ++ ++# define impossible() abort() ++# define bad_case(n) abort() ++# define passert(pred) { } /* do nothing */ ++# define happy(x) { (void) x; } /* evaluate non-judgementally */ ++ ++#endif /*!DEBUG*/ ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/pfkey_debug.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,54 @@ ++/* ++ * sanitize a string into a printable format. ++ * ++ * Copyright (C) 1998-2002 D. Hugh Redelmeier. ++ * Copyright (C) 2003 Michael Richardson ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: pfkey_debug.h,v 1.3 2004/04/05 19:55:07 mcr Exp $ ++ */ ++ ++#ifndef _FREESWAN_PFKEY_DEBUG_H ++#define _FREESWAN_PFKEY_DEBUG_H ++ ++#ifdef __KERNEL__ ++ ++/* note, kernel version ignores pfkey levels */ ++# define DEBUGGING(level,args...) \ ++ KLIPS_PRINT(debug_pfkey, "klips_debug:" args) ++ ++# define ERROR(args...) printk(KERN_ERR "klips:" args) ++ ++#else ++ ++extern unsigned int pfkey_lib_debug; ++ ++extern void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1); ++extern void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1); ++ ++#define DEBUGGING(level,args...) if(pfkey_lib_debug & level) { \ ++ if(pfkey_debug_func != NULL) { \ ++ (*pfkey_debug_func)("pfkey_lib_debug:" args); \ ++ } else { \ ++ printf("pfkey_lib_debug:" args); \ ++ } } ++ ++#define ERROR(args...) if(pfkey_error_func != NULL) { \ ++ (*pfkey_error_func)("pfkey_lib_debug:" args); \ ++ } ++ ++# define MALLOC(size) malloc(size) ++# define FREE(obj) free(obj) ++ ++#endif ++ ++#endif +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/openswan/radij.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,280 @@ ++/* ++ * RCSID $Id: radij.h,v 1.13 2004/04/05 19:55:08 mcr Exp $ ++ */ ++ ++/* ++ * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite ++ * ++ * Variable and procedure names have been modified so that they don't ++ * conflict with the original BSD code, as a small number of modifications ++ * have been introduced and we may want to reuse this code in BSD. ++ * ++ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek ++ * chi or a German ch sound (as `doch', not as in `milch'), or even a ++ * spanish j as in Juan. It is not as far back in the throat like ++ * the corresponding Hebrew sound, nor is it a soft breath like the English h. ++ * It has nothing to do with the Dutch ij sound. ++ * ++ * Here is the appropriate copyright notice: ++ */ ++ ++/* ++ * Copyright (c) 1988, 1989, 1993 ++ * The Regents of the University of California. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * This product includes software developed by the University of ++ * California, Berkeley and its contributors. ++ * 4. Neither the name of the University nor the names of its contributors ++ * may be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * @(#)radix.h 8.1 (Berkeley) 6/10/93 ++ */ ++ ++#ifndef _RADIJ_H_ ++#define _RADIJ_H_ ++ ++/* ++#define RJ_DEBUG ++*/ ++ ++#ifdef __KERNEL__ ++ ++#ifndef __P ++#ifdef __STDC__ ++#define __P(x) x ++#else ++#define __P(x) () ++#endif ++#endif ++ ++/* ++ * Radix search tree node layout. ++ */ ++ ++struct radij_node ++{ ++ struct radij_mask *rj_mklist; /* list of masks contained in subtree */ ++ struct radij_node *rj_p; /* parent */ ++ short rj_b; /* bit offset; -1-index(netmask) */ ++ char rj_bmask; /* node: mask for bit test*/ ++ u_char rj_flags; /* enumerated next */ ++#define RJF_NORMAL 1 /* leaf contains normal route */ ++#define RJF_ROOT 2 /* leaf is root leaf for tree */ ++#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */ ++ union { ++ struct { /* leaf only data: */ ++ caddr_t rj_Key; /* object of search */ ++ caddr_t rj_Mask; /* netmask, if present */ ++ struct radij_node *rj_Dupedkey; ++ } rj_leaf; ++ struct { /* node only data: */ ++ int rj_Off; /* where to start compare */ ++ struct radij_node *rj_L;/* progeny */ ++ struct radij_node *rj_R;/* progeny */ ++ }rj_node; ++ } rj_u; ++#ifdef RJ_DEBUG ++ int rj_info; ++ struct radij_node *rj_twin; ++ struct radij_node *rj_ybro; ++#endif ++}; ++ ++#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey ++#define rj_key rj_u.rj_leaf.rj_Key ++#define rj_mask rj_u.rj_leaf.rj_Mask ++#define rj_off rj_u.rj_node.rj_Off ++#define rj_l rj_u.rj_node.rj_L ++#define rj_r rj_u.rj_node.rj_R ++ ++/* ++ * Annotations to tree concerning potential routes applying to subtrees. ++ */ ++ ++extern struct radij_mask { ++ short rm_b; /* bit offset; -1-index(netmask) */ ++ char rm_unused; /* cf. rj_bmask */ ++ u_char rm_flags; /* cf. rj_flags */ ++ struct radij_mask *rm_mklist; /* more masks to try */ ++ caddr_t rm_mask; /* the mask */ ++ int rm_refs; /* # of references to this struct */ ++} *rj_mkfreelist; ++ ++#define MKGet(m) {\ ++ if (rj_mkfreelist) {\ ++ m = rj_mkfreelist; \ ++ rj_mkfreelist = (m)->rm_mklist; \ ++ } else \ ++ R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\ ++ ++#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);} ++ ++struct radij_node_head { ++ struct radij_node *rnh_treetop; ++ int rnh_addrsize; /* permit, but not require fixed keys */ ++ int rnh_pktsize; /* permit, but not require fixed keys */ ++#if 0 ++ struct radij_node *(*rnh_addaddr) /* add based on sockaddr */ ++ __P((void *v, void *mask, ++ struct radij_node_head *head, struct radij_node nodes[])); ++#endif ++ int (*rnh_addaddr) /* add based on sockaddr */ ++ __P((void *v, void *mask, ++ struct radij_node_head *head, struct radij_node nodes[])); ++ struct radij_node *(*rnh_addpkt) /* add based on packet hdr */ ++ __P((void *v, void *mask, ++ struct radij_node_head *head, struct radij_node nodes[])); ++#if 0 ++ struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */ ++ __P((void *v, void *mask, struct radij_node_head *head)); ++#endif ++ int (*rnh_deladdr) /* remove based on sockaddr */ ++ __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node)); ++ struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */ ++ __P((void *v, void *mask, struct radij_node_head *head)); ++ struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */ ++ __P((void *v, struct radij_node_head *head)); ++ struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */ ++ __P((void *v, struct radij_node_head *head)); ++ int (*rnh_walktree) /* traverse tree */ ++ __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w)); ++ struct radij_node rnh_nodes[3]; /* empty tree for common case */ ++}; ++ ++ ++#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n)) ++#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n)) ++#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n)) ++#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n))) ++#define Free(p) kfree((caddr_t)p); ++ ++void rj_init __P((void)); ++int rj_inithead __P((void **, int)); ++int rj_refines __P((void *, void *)); ++int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w)); ++struct radij_node ++ *rj_addmask __P((void *, int, int)) /* , rgb */ ; ++int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *, ++ struct radij_node [2])) /* , rgb */ ; ++int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ; ++struct radij_node /* rgb */ ++ *rj_insert __P((void *, struct radij_node_head *, int *, ++ struct radij_node [2])), ++ *rj_match __P((void *, struct radij_node_head *)), ++ *rj_newpair __P((void *, int, struct radij_node[2])), ++ *rj_search __P((void *, struct radij_node *)), ++ *rj_search_m __P((void *, struct radij_node *, void *)); ++ ++void rj_deltree(struct radij_node_head *); ++void rj_delnodes(struct radij_node *); ++void rj_free_mkfreelist(void); ++int radijcleartree(void); ++int radijcleanup(void); ++ ++extern struct radij_node_head *mask_rjhead; ++extern int maj_keylen; ++#endif /* __KERNEL__ */ ++ ++#endif /* _RADIJ_H_ */ ++ ++ ++/* ++ * $Log: radij.h,v $ ++ * Revision 1.13 2004/04/05 19:55:08 mcr ++ * Moved from linux/include/freeswan/radij.h,v ++ * ++ * Revision 1.12 2002/04/24 07:36:48 mcr ++ * Moved from ./klips/net/ipsec/radij.h,v ++ * ++ * Revision 1.11 2001/09/20 15:33:00 rgb ++ * Min/max cleanup. ++ * ++ * Revision 1.10 1999/11/18 04:09:20 rgb ++ * Replaced all kernel version macros to shorter, readable form. ++ * ++ * Revision 1.9 1999/05/05 22:02:33 rgb ++ * Add a quick and dirty port to 2.2 kernels by Marc Boucher . ++ * ++ * Revision 1.8 1999/04/29 15:24:58 rgb ++ * Add check for existence of macros min/max. ++ * ++ * Revision 1.7 1999/04/11 00:29:02 henry ++ * GPL boilerplate ++ * ++ * Revision 1.6 1999/04/06 04:54:29 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.5 1999/01/22 06:30:32 rgb ++ * 64-bit clean-up. ++ * ++ * Revision 1.4 1998/11/30 13:22:55 rgb ++ * Rationalised all the klips kernel file headers. They are much shorter ++ * now and won't conflict under RH5.2. ++ * ++ * Revision 1.3 1998/10/25 02:43:27 rgb ++ * Change return type on rj_addroute and rj_delete and add and argument ++ * to the latter to be able to transmit more infomation about errors. ++ * ++ * Revision 1.2 1998/07/14 18:09:51 rgb ++ * Add a routine to clear eroute table. ++ * Added #ifdef __KERNEL__ directives to restrict scope of header. ++ * ++ * Revision 1.1 1998/06/18 21:30:22 henry ++ * move sources from klips/src to klips/net/ipsec to keep stupid kernel ++ * build scripts happier about symlinks ++ * ++ * Revision 1.4 1998/05/25 20:34:16 rgb ++ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions. ++ * ++ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and ++ * add ipsec_rj_walker_delete. ++ * ++ * Recover memory for eroute table on unload of module. ++ * ++ * Revision 1.3 1998/04/22 16:51:37 rgb ++ * Tidy up radij debug code from recent rash of modifications to debug code. ++ * ++ * Revision 1.2 1998/04/14 17:30:38 rgb ++ * Fix up compiling errors for radij tree memory reclamation. ++ * ++ * Revision 1.1 1998/04/09 03:06:16 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:04 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * No changes. ++ * ++ * Revision 0.3 1996/11/20 14:44:45 ji ++ * Release update only. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/pfkey.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,509 @@ ++/* ++ * FreeS/WAN specific PF_KEY headers ++ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: pfkey.h,v 1.45 2004/04/06 02:49:00 mcr Exp $ ++ */ ++ ++#ifndef __NET_IPSEC_PF_KEY_H ++#define __NET_IPSEC_PF_KEY_H ++#ifdef __KERNEL__ ++extern struct proto_ops pfkey_proto_ops; ++typedef struct sock pfkey_sock; ++extern int debug_pfkey; ++ ++extern /* void */ int pfkey_init(void); ++extern /* void */ int pfkey_cleanup(void); ++ ++extern struct sock *pfkey_sock_list; ++struct socket_list ++{ ++ struct socket *socketp; ++ struct socket_list *next; ++}; ++extern int pfkey_list_insert_socket(struct socket*, struct socket_list**); ++extern int pfkey_list_remove_socket(struct socket*, struct socket_list**); ++extern struct socket_list *pfkey_open_sockets; ++extern struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1]; ++ ++struct supported ++{ ++ uint16_t supported_alg_exttype; ++ uint8_t supported_alg_id; ++ uint8_t supported_alg_ivlen; ++ uint16_t supported_alg_minbits; ++ uint16_t supported_alg_maxbits; ++}; ++ ++extern struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1]; ++struct supported_list ++{ ++ struct supported *supportedp; ++ struct supported_list *next; ++}; ++extern int pfkey_list_insert_supported(struct supported*, struct supported_list**); ++extern int pfkey_list_remove_supported(struct supported*, struct supported_list**); ++ ++struct sockaddr_key ++{ ++ uint16_t key_family; /* PF_KEY */ ++ uint16_t key_pad; /* not used */ ++ uint32_t key_pid; /* process ID */ ++}; ++ ++struct pfkey_extracted_data ++{ ++ struct ipsec_sa* ips; ++ struct ipsec_sa* ips2; ++ struct eroute *eroute; ++}; ++ ++extern int ++pfkey_alloc_eroute(struct eroute** eroute); ++ ++extern int ++pfkey_sa_process(struct sadb_ext *pfkey_ext, ++ struct pfkey_extracted_data* extr); ++ ++extern int ++pfkey_lifetime_process(struct sadb_ext *pfkey_ext, ++ struct pfkey_extracted_data* extr); ++ ++extern int ++pfkey_address_process(struct sadb_ext *pfkey_ext, ++ struct pfkey_extracted_data* extr); ++ ++extern int ++pfkey_key_process(struct sadb_ext *pfkey_ext, ++ struct pfkey_extracted_data* extr); ++ ++extern int ++pfkey_ident_process(struct sadb_ext *pfkey_ext, ++ struct pfkey_extracted_data* extr); ++ ++extern int ++pfkey_sens_process(struct sadb_ext *pfkey_ext, ++ struct pfkey_extracted_data* extr); ++ ++extern int ++pfkey_prop_process(struct sadb_ext *pfkey_ext, ++ struct pfkey_extracted_data* extr); ++ ++extern int ++pfkey_supported_process(struct sadb_ext *pfkey_ext, ++ struct pfkey_extracted_data* extr); ++ ++extern int ++pfkey_spirange_process(struct sadb_ext *pfkey_ext, ++ struct pfkey_extracted_data* extr); ++ ++extern int ++pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, ++ struct pfkey_extracted_data* extr); ++ ++extern int ++pfkey_x_satype_process(struct sadb_ext *pfkey_ext, ++ struct pfkey_extracted_data* extr); ++ ++extern int ++pfkey_x_debug_process(struct sadb_ext *pfkey_ext, ++ struct pfkey_extracted_data* extr); ++ ++extern int pfkey_upmsg(struct socket *, struct sadb_msg *); ++extern int pfkey_expire(struct ipsec_sa *, int); ++extern int pfkey_acquire(struct ipsec_sa *); ++#else /* ! __KERNEL__ */ ++ ++extern void (*pfkey_debug_func)(const char *message, ...); ++extern void (*pfkey_error_func)(const char *message, ...); ++extern void pfkey_print(struct sadb_msg *msg, FILE *out); ++ ++ ++#endif /* __KERNEL__ */ ++ ++extern uint8_t satype2proto(uint8_t satype); ++extern uint8_t proto2satype(uint8_t proto); ++extern char* satype2name(uint8_t satype); ++extern char* proto2name(uint8_t proto); ++ ++struct key_opt ++{ ++ uint32_t key_pid; /* process ID */ ++ struct sock *sk; ++}; ++ ++#define key_pid(sk) ((struct key_opt*)&((sk)->protinfo))->key_pid ++ ++/* XXX-mcr this is not an alignment, this is because the count is in 64-bit ++ * words. ++ */ ++#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t)) ++#define BITS_PER_OCTET 8 ++#define OCTETBITS 8 ++#define PFKEYBITS 64 ++#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */ ++#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */ ++ ++#define IPSEC_PFKEYv2_LEN(x) ((x) * IPSEC_PFKEYv2_ALIGN) ++#define IPSEC_PFKEYv2_WORDS(x) ((x) / IPSEC_PFKEYv2_ALIGN) ++ ++ ++#define PFKEYv2_MAX_MSGSIZE 4096 ++ ++/* ++ * PF_KEYv2 permitted and required extensions in and out bitmaps ++ */ ++struct pf_key_ext_parsers_def { ++ int (*parser)(struct sadb_ext*); ++ char *parser_name; ++}; ++ ++ ++extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/]; ++#define EXT_BITS_IN 0 ++#define EXT_BITS_OUT 1 ++#define EXT_BITS_PERM 0 ++#define EXT_BITS_REQ 1 ++ ++extern void pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1]); ++extern void pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1]); ++extern void pfkey_msg_free(struct sadb_msg **pfkey_msg); ++ ++extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg, ++ struct pf_key_ext_parsers_def *ext_parsers[], ++ struct sadb_ext **extensions, ++ int dir); ++ ++extern int pfkey_register_reply(int satype, struct sadb_msg *sadb_msg); ++ ++/* ++ * PF_KEYv2 build function prototypes ++ */ ++ ++int ++pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext, ++ uint8_t msg_type, ++ uint8_t satype, ++ uint8_t msg_errno, ++ uint32_t seq, ++ uint32_t pid); ++ ++int ++pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext, ++ uint16_t exttype, ++ uint32_t spi, /* in network order */ ++ uint8_t replay_window, ++ uint8_t sa_state, ++ uint8_t auth, ++ uint8_t encrypt, ++ uint32_t flags, ++ uint32_t/*IPsecSAref_t*/ ref); ++ ++int ++pfkey_sa_build(struct sadb_ext ** pfkey_ext, ++ uint16_t exttype, ++ uint32_t spi, /* in network order */ ++ uint8_t replay_window, ++ uint8_t sa_state, ++ uint8_t auth, ++ uint8_t encrypt, ++ uint32_t flags); ++ ++int ++pfkey_lifetime_build(struct sadb_ext ** pfkey_ext, ++ uint16_t exttype, ++ uint32_t allocations, ++ uint64_t bytes, ++ uint64_t addtime, ++ uint64_t usetime, ++ uint32_t packets); ++ ++int ++pfkey_address_build(struct sadb_ext** pfkey_ext, ++ uint16_t exttype, ++ uint8_t proto, ++ uint8_t prefixlen, ++ struct sockaddr* address); ++ ++int ++pfkey_key_build(struct sadb_ext** pfkey_ext, ++ uint16_t exttype, ++ uint16_t key_bits, ++ char* key); ++ ++int ++pfkey_ident_build(struct sadb_ext** pfkey_ext, ++ uint16_t exttype, ++ uint16_t ident_type, ++ uint64_t ident_id, ++ uint8_t ident_len, ++ char* ident_string); ++ ++#ifdef NAT_TRAVERSAL ++#ifdef __KERNEL__ ++extern int pfkey_nat_t_new_mapping(struct ipsec_sa *, struct sockaddr *, __u16); ++extern int pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr); ++extern int pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr); ++#endif /* __KERNEL__ */ ++int ++pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext, ++ uint8_t type); ++int ++pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext, ++ uint16_t exttype, ++ uint16_t port); ++#endif ++ ++int ++pfkey_sens_build(struct sadb_ext** pfkey_ext, ++ uint32_t dpd, ++ uint8_t sens_level, ++ uint8_t sens_len, ++ uint64_t* sens_bitmap, ++ uint8_t integ_level, ++ uint8_t integ_len, ++ uint64_t* integ_bitmap); ++ ++int pfkey_x_protocol_build(struct sadb_ext **, uint8_t); ++ ++ ++int ++pfkey_prop_build(struct sadb_ext** pfkey_ext, ++ uint8_t replay, ++ unsigned int comb_num, ++ struct sadb_comb* comb); ++ ++int ++pfkey_supported_build(struct sadb_ext** pfkey_ext, ++ uint16_t exttype, ++ unsigned int alg_num, ++ struct sadb_alg* alg); ++ ++int ++pfkey_spirange_build(struct sadb_ext** pfkey_ext, ++ uint16_t exttype, ++ uint32_t min, ++ uint32_t max); ++ ++int ++pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext); ++ ++int ++pfkey_x_satype_build(struct sadb_ext** pfkey_ext, ++ uint8_t satype); ++ ++int ++pfkey_x_debug_build(struct sadb_ext** pfkey_ext, ++ uint32_t tunnel, ++ uint32_t netlink, ++ uint32_t xform, ++ uint32_t eroute, ++ uint32_t spi, ++ uint32_t radij, ++ uint32_t esp, ++ uint32_t ah, ++ uint32_t rcv, ++ uint32_t pfkey, ++ uint32_t ipcomp, ++ uint32_t verbose); ++ ++int ++pfkey_msg_build(struct sadb_msg** pfkey_msg, ++ struct sadb_ext* extensions[], ++ int dir); ++ ++/* in pfkey_v2_debug.c - routines to decode numbers -> strings */ ++const char * ++pfkey_v2_sadb_ext_string(int extnum); ++ ++const char * ++pfkey_v2_sadb_type_string(int sadb_type); ++ ++ ++#endif /* __NET_IPSEC_PF_KEY_H */ ++ ++/* ++ * $Log: pfkey.h,v $ ++ * Revision 1.45 2004/04/06 02:49:00 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.44 2003/12/10 01:20:01 mcr ++ * NAT-traversal patches to KLIPS. ++ * ++ * Revision 1.43 2003/10/31 02:26:44 mcr ++ * pulled up port-selector patches. ++ * ++ * Revision 1.42.2.2 2003/10/29 01:09:32 mcr ++ * added debugging for pfkey library. ++ * ++ * Revision 1.42.2.1 2003/09/21 13:59:34 mcr ++ * pre-liminary X.509 patch - does not yet pass tests. ++ * ++ * Revision 1.42 2003/08/25 22:08:19 mcr ++ * removed pfkey_proto_init() from pfkey.h for 2.6 support. ++ * ++ * Revision 1.41 2003/05/07 17:28:57 mcr ++ * new function pfkey_debug_func added for us in debugging from ++ ++ * pfkey library. ++ * ++ * Revision 1.40 2003/01/30 02:31:34 rgb ++ * ++ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. ++ * ++ * Revision 1.39 2002/09/20 15:40:21 rgb ++ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc(). ++ * Added ref parameter to pfkey_sa_build(). ++ * Cleaned out unused cruft. ++ * ++ * Revision 1.38 2002/05/14 02:37:24 rgb ++ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, ++ * ipsec_sa or ipsec_sa. ++ * Added function prototypes for the functions moved to ++ * pfkey_v2_ext_process.c. ++ * ++ * Revision 1.37 2002/04/24 07:36:49 mcr ++ * Moved from ./lib/pfkey.h,v ++ * ++ * Revision 1.36 2002/01/20 20:34:49 mcr ++ * added pfkey_v2_sadb_type_string to decode sadb_type to string. ++ * ++ * Revision 1.35 2001/11/27 05:27:47 mcr ++ * pfkey parses are now maintained by a structure ++ * that includes their name for debug purposes. ++ * ++ * Revision 1.34 2001/11/26 09:23:53 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.33 2001/11/06 19:47:47 rgb ++ * Added packet parameter to lifetime and comb structures. ++ * ++ * Revision 1.32 2001/09/08 21:13:34 rgb ++ * Added pfkey ident extension support for ISAKMPd. (NetCelo) ++ * ++ * Revision 1.31 2001/06/14 19:35:16 rgb ++ * Update copyright date. ++ * ++ * Revision 1.30 2001/02/27 07:04:52 rgb ++ * Added satype2name prototype. ++ * ++ * Revision 1.29 2001/02/26 19:59:33 rgb ++ * Ditch unused sadb_satype2proto[], replaced by satype2proto(). ++ * ++ * Revision 1.28 2000/10/10 20:10:19 rgb ++ * Added support for debug_ipcomp and debug_verbose to klipsdebug. ++ * ++ * Revision 1.27 2000/09/21 04:20:45 rgb ++ * Fixed array size off-by-one error. (Thanks Svenning!) ++ * ++ * Revision 1.26 2000/09/12 03:26:05 rgb ++ * Added pfkey_acquire prototype. ++ * ++ * Revision 1.25 2000/09/08 19:21:28 rgb ++ * Fix pfkey_prop_build() parameter to be only single indirection. ++ * ++ * Revision 1.24 2000/09/01 18:46:42 rgb ++ * Added a supported algorithms array lists, one per satype and registered ++ * existing algorithms. ++ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to ++ * list. ++ * ++ * Revision 1.23 2000/08/27 01:55:26 rgb ++ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code. ++ * ++ * Revision 1.22 2000/08/20 21:39:23 rgb ++ * Added kernel prototypes for kernel funcitions pfkey_upmsg() and ++ * pfkey_expire(). ++ * ++ * Revision 1.21 2000/08/15 17:29:23 rgb ++ * Fixes from SZI to untested pfkey_prop_build(). ++ * ++ * Revision 1.20 2000/05/10 20:14:19 rgb ++ * Fleshed out sensitivity, proposal and supported extensions. ++ * ++ * Revision 1.19 2000/03/16 14:07:23 rgb ++ * Renamed ALIGN macro to avoid fighting with others in kernel. ++ * ++ * Revision 1.18 2000/01/22 23:24:06 rgb ++ * Added prototypes for proto2satype(), satype2proto() and proto2name(). ++ * ++ * Revision 1.17 2000/01/21 06:26:59 rgb ++ * Converted from double tdb arguments to one structure (extr) ++ * containing pointers to all temporary information structures. ++ * Added klipsdebug switching capability. ++ * Dropped unused argument to pfkey_x_satype_build(). ++ * ++ * Revision 1.16 1999/12/29 21:17:41 rgb ++ * Changed pfkey_msg_build() I/F to include a struct sadb_msg** ++ * parameter for cleaner manipulation of extensions[] and to guard ++ * against potential memory leaks. ++ * Changed the I/F to pfkey_msg_free() for the same reason. ++ * ++ * Revision 1.15 1999/12/09 23:12:54 rgb ++ * Added macro for BITS_PER_OCTET. ++ * Added argument to pfkey_sa_build() to do eroutes. ++ * ++ * Revision 1.14 1999/12/08 20:33:25 rgb ++ * Changed sa_family_t to uint16_t for 2.0.xx compatibility. ++ * ++ * Revision 1.13 1999/12/07 19:53:40 rgb ++ * Removed unused first argument from extension parsers. ++ * Changed __u* types to uint* to avoid use of asm/types.h and ++ * sys/types.h in userspace code. ++ * Added function prototypes for pfkey message and extensions ++ * initialisation and cleanup. ++ * ++ * Revision 1.12 1999/12/01 22:19:38 rgb ++ * Change pfkey_sa_build to accept an SPI in network byte order. ++ * ++ * Revision 1.11 1999/11/27 11:55:26 rgb ++ * Added extern sadb_satype2proto to enable moving protocol lookup table ++ * to lib/pfkey_v2_parse.c. ++ * Delete unused, moved typedefs. ++ * Add argument to pfkey_msg_parse() for direction. ++ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. ++ * ++ * Revision 1.10 1999/11/23 22:29:21 rgb ++ * This file has been moved in the distribution from klips/net/ipsec to ++ * lib. ++ * Add macros for dealing with alignment and rounding up more opaquely. ++ * The uint_t type defines have been moved to freeswan.h to avoid ++ * chicken-and-egg problems. ++ * Add macros for dealing with alignment and rounding up more opaque. ++ * Added prototypes for using extention header bitmaps. ++ * Added prototypes of all the build functions. ++ * ++ * Revision 1.9 1999/11/20 21:59:48 rgb ++ * Moved socketlist type declarations and prototypes for shared use. ++ * Slightly modified scope of sockaddr_key declaration. ++ * ++ * Revision 1.8 1999/11/17 14:34:25 rgb ++ * Protect sa_family_t from being used in userspace with GLIBC<2. ++ * ++ * Revision 1.7 1999/10/27 19:40:35 rgb ++ * Add a maximum PFKEY packet size macro. ++ * ++ * Revision 1.6 1999/10/26 16:58:58 rgb ++ * Created a sockaddr_key and key_opt socket extension structures. ++ * ++ * Revision 1.5 1999/06/10 05:24:41 rgb ++ * Renamed variables to reduce confusion. ++ * ++ * Revision 1.4 1999/04/29 15:21:11 rgb ++ * Add pfkey support to debugging. ++ * Add return values to init and cleanup functions. ++ * ++ * Revision 1.3 1999/04/15 17:58:07 rgb ++ * Add RCSID labels. ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/pfkeyv2.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,467 @@ ++/* ++ * RCSID $Id: pfkeyv2.h,v 1.30 2004/04/06 02:49:00 mcr Exp $ ++ */ ++ ++/* ++RFC 2367 PF_KEY Key Management API July 1998 ++ ++ ++Appendix D: Sample Header File ++ ++This file defines structures and symbols for the PF_KEY Version 2 ++key management interface. It was written at the U.S. Naval Research ++Laboratory. This file is in the public domain. The authors ask that ++you leave this credit intact on any copies of this file. ++*/ ++#ifndef __PFKEY_V2_H ++#define __PFKEY_V2_H 1 ++ ++#define PF_KEY_V2 2 ++#define PFKEYV2_REVISION 199806L ++ ++#define SADB_RESERVED 0 ++#define SADB_GETSPI 1 ++#define SADB_UPDATE 2 ++#define SADB_ADD 3 ++#define SADB_DELETE 4 ++#define SADB_GET 5 ++#define SADB_ACQUIRE 6 ++#define SADB_REGISTER 7 ++#define SADB_EXPIRE 8 ++#define SADB_FLUSH 9 ++#define SADB_DUMP 10 ++#define SADB_X_PROMISC 11 ++#define SADB_X_PCHANGE 12 ++#define SADB_X_GRPSA 13 ++#define SADB_X_ADDFLOW 14 ++#define SADB_X_DELFLOW 15 ++#define SADB_X_DEBUG 16 ++#define SADB_X_NAT_T_NEW_MAPPING 17 ++#define SADB_MAX 17 ++ ++struct sadb_msg { ++ uint8_t sadb_msg_version; ++ uint8_t sadb_msg_type; ++ uint8_t sadb_msg_errno; ++ uint8_t sadb_msg_satype; ++ uint16_t sadb_msg_len; ++ uint16_t sadb_msg_reserved; ++ uint32_t sadb_msg_seq; ++ uint32_t sadb_msg_pid; ++}; ++ ++struct sadb_ext { ++ uint16_t sadb_ext_len; ++ uint16_t sadb_ext_type; ++}; ++ ++struct sadb_sa { ++ uint16_t sadb_sa_len; ++ uint16_t sadb_sa_exttype; ++ uint32_t sadb_sa_spi; ++ uint8_t sadb_sa_replay; ++ uint8_t sadb_sa_state; ++ uint8_t sadb_sa_auth; ++ uint8_t sadb_sa_encrypt; ++ uint32_t sadb_sa_flags; ++ uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */ ++ uint8_t sadb_x_reserved[4]; ++}; ++ ++struct sadb_sa_v1 { ++ uint16_t sadb_sa_len; ++ uint16_t sadb_sa_exttype; ++ uint32_t sadb_sa_spi; ++ uint8_t sadb_sa_replay; ++ uint8_t sadb_sa_state; ++ uint8_t sadb_sa_auth; ++ uint8_t sadb_sa_encrypt; ++ uint32_t sadb_sa_flags; ++}; ++ ++struct sadb_lifetime { ++ uint16_t sadb_lifetime_len; ++ uint16_t sadb_lifetime_exttype; ++ uint32_t sadb_lifetime_allocations; ++ uint64_t sadb_lifetime_bytes; ++ uint64_t sadb_lifetime_addtime; ++ uint64_t sadb_lifetime_usetime; ++ uint32_t sadb_x_lifetime_packets; ++ uint32_t sadb_x_lifetime_reserved; ++}; ++ ++struct sadb_address { ++ uint16_t sadb_address_len; ++ uint16_t sadb_address_exttype; ++ uint8_t sadb_address_proto; ++ uint8_t sadb_address_prefixlen; ++ uint16_t sadb_address_reserved; ++}; ++ ++struct sadb_key { ++ uint16_t sadb_key_len; ++ uint16_t sadb_key_exttype; ++ uint16_t sadb_key_bits; ++ uint16_t sadb_key_reserved; ++}; ++ ++struct sadb_ident { ++ uint16_t sadb_ident_len; ++ uint16_t sadb_ident_exttype; ++ uint16_t sadb_ident_type; ++ uint16_t sadb_ident_reserved; ++ uint64_t sadb_ident_id; ++}; ++ ++struct sadb_sens { ++ uint16_t sadb_sens_len; ++ uint16_t sadb_sens_exttype; ++ uint32_t sadb_sens_dpd; ++ uint8_t sadb_sens_sens_level; ++ uint8_t sadb_sens_sens_len; ++ uint8_t sadb_sens_integ_level; ++ uint8_t sadb_sens_integ_len; ++ uint32_t sadb_sens_reserved; ++}; ++ ++struct sadb_prop { ++ uint16_t sadb_prop_len; ++ uint16_t sadb_prop_exttype; ++ uint8_t sadb_prop_replay; ++ uint8_t sadb_prop_reserved[3]; ++}; ++ ++struct sadb_comb { ++ uint8_t sadb_comb_auth; ++ uint8_t sadb_comb_encrypt; ++ uint16_t sadb_comb_flags; ++ uint16_t sadb_comb_auth_minbits; ++ uint16_t sadb_comb_auth_maxbits; ++ uint16_t sadb_comb_encrypt_minbits; ++ uint16_t sadb_comb_encrypt_maxbits; ++ uint32_t sadb_comb_reserved; ++ uint32_t sadb_comb_soft_allocations; ++ uint32_t sadb_comb_hard_allocations; ++ uint64_t sadb_comb_soft_bytes; ++ uint64_t sadb_comb_hard_bytes; ++ uint64_t sadb_comb_soft_addtime; ++ uint64_t sadb_comb_hard_addtime; ++ uint64_t sadb_comb_soft_usetime; ++ uint64_t sadb_comb_hard_usetime; ++ uint32_t sadb_x_comb_soft_packets; ++ uint32_t sadb_x_comb_hard_packets; ++}; ++ ++struct sadb_supported { ++ uint16_t sadb_supported_len; ++ uint16_t sadb_supported_exttype; ++ uint32_t sadb_supported_reserved; ++}; ++ ++struct sadb_alg { ++ uint8_t sadb_alg_id; ++ uint8_t sadb_alg_ivlen; ++ uint16_t sadb_alg_minbits; ++ uint16_t sadb_alg_maxbits; ++ uint16_t sadb_alg_reserved; ++}; ++ ++struct sadb_spirange { ++ uint16_t sadb_spirange_len; ++ uint16_t sadb_spirange_exttype; ++ uint32_t sadb_spirange_min; ++ uint32_t sadb_spirange_max; ++ uint32_t sadb_spirange_reserved; ++}; ++ ++struct sadb_x_kmprivate { ++ uint16_t sadb_x_kmprivate_len; ++ uint16_t sadb_x_kmprivate_exttype; ++ uint32_t sadb_x_kmprivate_reserved; ++}; ++ ++struct sadb_x_satype { ++ uint16_t sadb_x_satype_len; ++ uint16_t sadb_x_satype_exttype; ++ uint8_t sadb_x_satype_satype; ++ uint8_t sadb_x_satype_reserved[3]; ++}; ++ ++struct sadb_x_policy { ++ uint16_t sadb_x_policy_len; ++ uint16_t sadb_x_policy_exttype; ++ uint16_t sadb_x_policy_type; ++ uint8_t sadb_x_policy_dir; ++ uint8_t sadb_x_policy_reserved; ++ uint32_t sadb_x_policy_id; ++ uint32_t sadb_x_policy_reserved2; ++}; ++ ++struct sadb_x_debug { ++ uint16_t sadb_x_debug_len; ++ uint16_t sadb_x_debug_exttype; ++ uint32_t sadb_x_debug_tunnel; ++ uint32_t sadb_x_debug_netlink; ++ uint32_t sadb_x_debug_xform; ++ uint32_t sadb_x_debug_eroute; ++ uint32_t sadb_x_debug_spi; ++ uint32_t sadb_x_debug_radij; ++ uint32_t sadb_x_debug_esp; ++ uint32_t sadb_x_debug_ah; ++ uint32_t sadb_x_debug_rcv; ++ uint32_t sadb_x_debug_pfkey; ++ uint32_t sadb_x_debug_ipcomp; ++ uint32_t sadb_x_debug_verbose; ++ uint8_t sadb_x_debug_reserved[4]; ++}; ++ ++struct sadb_x_nat_t_type { ++ uint16_t sadb_x_nat_t_type_len; ++ uint16_t sadb_x_nat_t_type_exttype; ++ uint8_t sadb_x_nat_t_type_type; ++ uint8_t sadb_x_nat_t_type_reserved[3]; ++}; ++struct sadb_x_nat_t_port { ++ uint16_t sadb_x_nat_t_port_len; ++ uint16_t sadb_x_nat_t_port_exttype; ++ uint16_t sadb_x_nat_t_port_port; ++ uint16_t sadb_x_nat_t_port_reserved; ++}; ++ ++/* ++ * A protocol structure for passing through the transport level ++ * protocol. It contains more fields than are actually used/needed ++ * but it is this way to be compatible with the structure used in ++ * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h) ++ */ ++struct sadb_protocol { ++ uint16_t sadb_protocol_len; ++ uint16_t sadb_protocol_exttype; ++ uint8_t sadb_protocol_proto; ++ uint8_t sadb_protocol_direction; ++ uint8_t sadb_protocol_flags; ++ uint8_t sadb_protocol_reserved2; ++}; ++ ++#define SADB_EXT_RESERVED 0 ++#define SADB_EXT_SA 1 ++#define SADB_EXT_LIFETIME_CURRENT 2 ++#define SADB_EXT_LIFETIME_HARD 3 ++#define SADB_EXT_LIFETIME_SOFT 4 ++#define SADB_EXT_ADDRESS_SRC 5 ++#define SADB_EXT_ADDRESS_DST 6 ++#define SADB_EXT_ADDRESS_PROXY 7 ++#define SADB_EXT_KEY_AUTH 8 ++#define SADB_EXT_KEY_ENCRYPT 9 ++#define SADB_EXT_IDENTITY_SRC 10 ++#define SADB_EXT_IDENTITY_DST 11 ++#define SADB_EXT_SENSITIVITY 12 ++#define SADB_EXT_PROPOSAL 13 ++#define SADB_EXT_SUPPORTED_AUTH 14 ++#define SADB_EXT_SUPPORTED_ENCRYPT 15 ++#define SADB_EXT_SPIRANGE 16 ++#define SADB_X_EXT_KMPRIVATE 17 ++#define SADB_X_EXT_SATYPE2 18 ++#ifdef KERNEL26_HAS_KAME_DUPLICATES ++#define SADB_X_EXT_POLICY 18 ++#endif ++#define SADB_X_EXT_SA2 19 ++#define SADB_X_EXT_ADDRESS_DST2 20 ++#define SADB_X_EXT_ADDRESS_SRC_FLOW 21 ++#define SADB_X_EXT_ADDRESS_DST_FLOW 22 ++#define SADB_X_EXT_ADDRESS_SRC_MASK 23 ++#define SADB_X_EXT_ADDRESS_DST_MASK 24 ++#define SADB_X_EXT_DEBUG 25 ++#define SADB_X_EXT_PROTOCOL 26 ++#define SADB_X_EXT_NAT_T_TYPE 27 ++#define SADB_X_EXT_NAT_T_SPORT 28 ++#define SADB_X_EXT_NAT_T_DPORT 29 ++#define SADB_X_EXT_NAT_T_OA 30 ++#define SADB_EXT_MAX 30 ++ ++/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */ ++#define SADB_X_EXT_ADDRESS_DELFLOW \ ++ ( (1<adler to the adler32 checksum of all input read ++ so far (that is, total_in bytes). ++ ++ deflate() may update data_type if it can make a good guess about ++ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered ++ binary. This field is only for information purposes and does not affect ++ the compression algorithm in any manner. ++ ++ deflate() returns Z_OK if some progress has been made (more input ++ processed or more output produced), Z_STREAM_END if all input has been ++ consumed and all output has been produced (only when flush is set to ++ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example ++ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible ++ (for example avail_in or avail_out was zero). ++*/ ++ ++ ++ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); ++/* ++ All dynamically allocated data structures for this stream are freed. ++ This function discards any unprocessed input and does not flush any ++ pending output. ++ ++ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the ++ stream state was inconsistent, Z_DATA_ERROR if the stream was freed ++ prematurely (some input or output was discarded). In the error case, ++ msg may be set but then points to a static string (which must not be ++ deallocated). ++*/ ++ ++ ++/* ++ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); ++ ++ Initializes the internal stream state for decompression. The fields ++ next_in, avail_in, zalloc, zfree and opaque must be initialized before by ++ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact ++ value depends on the compression method), inflateInit determines the ++ compression method from the zlib header and allocates all data structures ++ accordingly; otherwise the allocation will be deferred to the first call of ++ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to ++ use default allocation functions. ++ ++ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough ++ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the ++ version assumed by the caller. msg is set to null if there is no error ++ message. inflateInit does not perform any decompression apart from reading ++ the zlib header if present: this will be done by inflate(). (So next_in and ++ avail_in may be modified, but next_out and avail_out are unchanged.) ++*/ ++ ++ ++ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); ++/* ++ inflate decompresses as much data as possible, and stops when the input ++ buffer becomes empty or the output buffer becomes full. It may some ++ introduce some output latency (reading input without producing any output) ++ except when forced to flush. ++ ++ The detailed semantics are as follows. inflate performs one or both of the ++ following actions: ++ ++ - Decompress more input starting at next_in and update next_in and avail_in ++ accordingly. If not all input can be processed (because there is not ++ enough room in the output buffer), next_in is updated and processing ++ will resume at this point for the next call of inflate(). ++ ++ - Provide more output starting at next_out and update next_out and avail_out ++ accordingly. inflate() provides as much output as possible, until there ++ is no more input data or no more space in the output buffer (see below ++ about the flush parameter). ++ ++ Before the call of inflate(), the application should ensure that at least ++ one of the actions is possible, by providing more input and/or consuming ++ more output, and updating the next_* and avail_* values accordingly. ++ The application can consume the uncompressed output when it wants, for ++ example when the output buffer is full (avail_out == 0), or after each ++ call of inflate(). If inflate returns Z_OK and with zero avail_out, it ++ must be called again after making room in the output buffer because there ++ might be more output pending. ++ ++ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much ++ output as possible to the output buffer. The flushing behavior of inflate is ++ not specified for values of the flush parameter other than Z_SYNC_FLUSH ++ and Z_FINISH, but the current implementation actually flushes as much output ++ as possible anyway. ++ ++ inflate() should normally be called until it returns Z_STREAM_END or an ++ error. However if all decompression is to be performed in a single step ++ (a single call of inflate), the parameter flush should be set to ++ Z_FINISH. In this case all pending input is processed and all pending ++ output is flushed; avail_out must be large enough to hold all the ++ uncompressed data. (The size of the uncompressed data may have been saved ++ by the compressor for this purpose.) The next operation on this stream must ++ be inflateEnd to deallocate the decompression state. The use of Z_FINISH ++ is never required, but can be used to inform inflate that a faster routine ++ may be used for the single inflate() call. ++ ++ If a preset dictionary is needed at this point (see inflateSetDictionary ++ below), inflate sets strm-adler to the adler32 checksum of the ++ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise ++ it sets strm->adler to the adler32 checksum of all output produced ++ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or ++ an error code as described below. At the end of the stream, inflate() ++ checks that its computed adler32 checksum is equal to that saved by the ++ compressor and returns Z_STREAM_END only if the checksum is correct. ++ ++ inflate() returns Z_OK if some progress has been made (more input processed ++ or more output produced), Z_STREAM_END if the end of the compressed data has ++ been reached and all uncompressed output has been produced, Z_NEED_DICT if a ++ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was ++ corrupted (input stream not conforming to the zlib format or incorrect ++ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent ++ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not ++ enough memory, Z_BUF_ERROR if no progress is possible or if there was not ++ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR ++ case, the application may then call inflateSync to look for a good ++ compression block. ++*/ ++ ++ ++ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); ++/* ++ All dynamically allocated data structures for this stream are freed. ++ This function discards any unprocessed input and does not flush any ++ pending output. ++ ++ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state ++ was inconsistent. In the error case, msg may be set but then points to a ++ static string (which must not be deallocated). ++*/ ++ ++ /* Advanced functions */ ++ ++/* ++ The following functions are needed only in some special applications. ++*/ ++ ++/* ++ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, ++ int level, ++ int method, ++ int windowBits, ++ int memLevel, ++ int strategy)); ++ ++ This is another version of deflateInit with more compression options. The ++ fields next_in, zalloc, zfree and opaque must be initialized before by ++ the caller. ++ ++ The method parameter is the compression method. It must be Z_DEFLATED in ++ this version of the library. ++ ++ The windowBits parameter is the base two logarithm of the window size ++ (the size of the history buffer). It should be in the range 8..15 for this ++ version of the library. Larger values of this parameter result in better ++ compression at the expense of memory usage. The default value is 15 if ++ deflateInit is used instead. ++ ++ The memLevel parameter specifies how much memory should be allocated ++ for the internal compression state. memLevel=1 uses minimum memory but ++ is slow and reduces compression ratio; memLevel=9 uses maximum memory ++ for optimal speed. The default value is 8. See zconf.h for total memory ++ usage as a function of windowBits and memLevel. ++ ++ The strategy parameter is used to tune the compression algorithm. Use the ++ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a ++ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no ++ string match). Filtered data consists mostly of small values with a ++ somewhat random distribution. In this case, the compression algorithm is ++ tuned to compress them better. The effect of Z_FILTERED is to force more ++ Huffman coding and less string matching; it is somewhat intermediate ++ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects ++ the compression ratio but not the correctness of the compressed output even ++ if it is not set appropriately. ++ ++ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough ++ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid ++ method). msg is set to null if there is no error message. deflateInit2 does ++ not perform any compression: this will be done by deflate(). ++*/ ++ ++ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, ++ const Bytef *dictionary, ++ uInt dictLength)); ++/* ++ Initializes the compression dictionary from the given byte sequence ++ without producing any compressed output. This function must be called ++ immediately after deflateInit, deflateInit2 or deflateReset, before any ++ call of deflate. The compressor and decompressor must use exactly the same ++ dictionary (see inflateSetDictionary). ++ ++ The dictionary should consist of strings (byte sequences) that are likely ++ to be encountered later in the data to be compressed, with the most commonly ++ used strings preferably put towards the end of the dictionary. Using a ++ dictionary is most useful when the data to be compressed is short and can be ++ predicted with good accuracy; the data can then be compressed better than ++ with the default empty dictionary. ++ ++ Depending on the size of the compression data structures selected by ++ deflateInit or deflateInit2, a part of the dictionary may in effect be ++ discarded, for example if the dictionary is larger than the window size in ++ deflate or deflate2. Thus the strings most likely to be useful should be ++ put at the end of the dictionary, not at the front. ++ ++ Upon return of this function, strm->adler is set to the Adler32 value ++ of the dictionary; the decompressor may later use this value to determine ++ which dictionary has been used by the compressor. (The Adler32 value ++ applies to the whole dictionary even if only a subset of the dictionary is ++ actually used by the compressor.) ++ ++ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a ++ parameter is invalid (such as NULL dictionary) or the stream state is ++ inconsistent (for example if deflate has already been called for this stream ++ or if the compression method is bsort). deflateSetDictionary does not ++ perform any compression: this will be done by deflate(). ++*/ ++ ++ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, ++ z_streamp source)); ++/* ++ Sets the destination stream as a complete copy of the source stream. ++ ++ This function can be useful when several compression strategies will be ++ tried, for example when there are several ways of pre-processing the input ++ data with a filter. The streams that will be discarded should then be freed ++ by calling deflateEnd. Note that deflateCopy duplicates the internal ++ compression state which can be quite large, so this strategy is slow and ++ can consume lots of memory. ++ ++ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not ++ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent ++ (such as zalloc being NULL). msg is left unchanged in both source and ++ destination. ++*/ ++ ++ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); ++/* ++ This function is equivalent to deflateEnd followed by deflateInit, ++ but does not free and reallocate all the internal compression state. ++ The stream will keep the same compression level and any other attributes ++ that may have been set by deflateInit2. ++ ++ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source ++ stream state was inconsistent (such as zalloc or state being NULL). ++*/ ++ ++ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, ++ int level, ++ int strategy)); ++/* ++ Dynamically update the compression level and compression strategy. The ++ interpretation of level and strategy is as in deflateInit2. This can be ++ used to switch between compression and straight copy of the input data, or ++ to switch to a different kind of input data requiring a different ++ strategy. If the compression level is changed, the input available so far ++ is compressed with the old level (and may be flushed); the new level will ++ take effect only at the next call of deflate(). ++ ++ Before the call of deflateParams, the stream state must be set as for ++ a call of deflate(), since the currently available input may have to ++ be compressed and flushed. In particular, strm->avail_out must be non-zero. ++ ++ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source ++ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR ++ if strm->avail_out was zero. ++*/ ++ ++/* ++ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, ++ int windowBits)); ++ ++ This is another version of inflateInit with an extra parameter. The ++ fields next_in, avail_in, zalloc, zfree and opaque must be initialized ++ before by the caller. ++ ++ The windowBits parameter is the base two logarithm of the maximum window ++ size (the size of the history buffer). It should be in the range 8..15 for ++ this version of the library. The default value is 15 if inflateInit is used ++ instead. If a compressed stream with a larger window size is given as ++ input, inflate() will return with the error code Z_DATA_ERROR instead of ++ trying to allocate a larger window. ++ ++ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough ++ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative ++ memLevel). msg is set to null if there is no error message. inflateInit2 ++ does not perform any decompression apart from reading the zlib header if ++ present: this will be done by inflate(). (So next_in and avail_in may be ++ modified, but next_out and avail_out are unchanged.) ++*/ ++ ++ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, ++ const Bytef *dictionary, ++ uInt dictLength)); ++/* ++ Initializes the decompression dictionary from the given uncompressed byte ++ sequence. This function must be called immediately after a call of inflate ++ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor ++ can be determined from the Adler32 value returned by this call of ++ inflate. The compressor and decompressor must use exactly the same ++ dictionary (see deflateSetDictionary). ++ ++ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a ++ parameter is invalid (such as NULL dictionary) or the stream state is ++ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the ++ expected one (incorrect Adler32 value). inflateSetDictionary does not ++ perform any decompression: this will be done by subsequent calls of ++ inflate(). ++*/ ++ ++ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); ++/* ++ Skips invalid compressed data until a full flush point (see above the ++ description of deflate with Z_FULL_FLUSH) can be found, or until all ++ available input is skipped. No output is provided. ++ ++ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR ++ if no more input was provided, Z_DATA_ERROR if no flush point has been found, ++ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success ++ case, the application may save the current current value of total_in which ++ indicates where valid compressed data was found. In the error case, the ++ application may repeatedly call inflateSync, providing more input each time, ++ until success or end of the input data. ++*/ ++ ++ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); ++/* ++ This function is equivalent to inflateEnd followed by inflateInit, ++ but does not free and reallocate all the internal decompression state. ++ The stream will keep attributes that may have been set by inflateInit2. ++ ++ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source ++ stream state was inconsistent (such as zalloc or state being NULL). ++*/ ++ ++ ++ /* utility functions */ ++ ++/* ++ The following utility functions are implemented on top of the ++ basic stream-oriented functions. To simplify the interface, some ++ default options are assumed (compression level and memory usage, ++ standard memory allocation functions). The source code of these ++ utility functions can easily be modified if you need special options. ++*/ ++ ++ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, ++ const Bytef *source, uLong sourceLen)); ++/* ++ Compresses the source buffer into the destination buffer. sourceLen is ++ the byte length of the source buffer. Upon entry, destLen is the total ++ size of the destination buffer, which must be at least 0.1% larger than ++ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the ++ compressed buffer. ++ This function can be used to compress a whole file at once if the ++ input file is mmap'ed. ++ compress returns Z_OK if success, Z_MEM_ERROR if there was not ++ enough memory, Z_BUF_ERROR if there was not enough room in the output ++ buffer. ++*/ ++ ++ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, ++ const Bytef *source, uLong sourceLen, ++ int level)); ++/* ++ Compresses the source buffer into the destination buffer. The level ++ parameter has the same meaning as in deflateInit. sourceLen is the byte ++ length of the source buffer. Upon entry, destLen is the total size of the ++ destination buffer, which must be at least 0.1% larger than sourceLen plus ++ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. ++ ++ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough ++ memory, Z_BUF_ERROR if there was not enough room in the output buffer, ++ Z_STREAM_ERROR if the level parameter is invalid. ++*/ ++ ++ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, ++ const Bytef *source, uLong sourceLen)); ++/* ++ Decompresses the source buffer into the destination buffer. sourceLen is ++ the byte length of the source buffer. Upon entry, destLen is the total ++ size of the destination buffer, which must be large enough to hold the ++ entire uncompressed data. (The size of the uncompressed data must have ++ been saved previously by the compressor and transmitted to the decompressor ++ by some mechanism outside the scope of this compression library.) ++ Upon exit, destLen is the actual size of the compressed buffer. ++ This function can be used to decompress a whole file at once if the ++ input file is mmap'ed. ++ ++ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not ++ enough memory, Z_BUF_ERROR if there was not enough room in the output ++ buffer, or Z_DATA_ERROR if the input data was corrupted. ++*/ ++ ++ ++typedef voidp gzFile; ++ ++ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); ++/* ++ Opens a gzip (.gz) file for reading or writing. The mode parameter ++ is as in fopen ("rb" or "wb") but can also include a compression level ++ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for ++ Huffman only compression as in "wb1h". (See the description ++ of deflateInit2 for more information about the strategy parameter.) ++ ++ gzopen can be used to read a file which is not in gzip format; in this ++ case gzread will directly read from the file without decompression. ++ ++ gzopen returns NULL if the file could not be opened or if there was ++ insufficient memory to allocate the (de)compression state; errno ++ can be checked to distinguish the two cases (if errno is zero, the ++ zlib error is Z_MEM_ERROR). */ ++ ++ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); ++/* ++ gzdopen() associates a gzFile with the file descriptor fd. File ++ descriptors are obtained from calls like open, dup, creat, pipe or ++ fileno (in the file has been previously opened with fopen). ++ The mode parameter is as in gzopen. ++ The next call of gzclose on the returned gzFile will also close the ++ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file ++ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). ++ gzdopen returns NULL if there was insufficient memory to allocate ++ the (de)compression state. ++*/ ++ ++ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); ++/* ++ Dynamically update the compression level or strategy. See the description ++ of deflateInit2 for the meaning of these parameters. ++ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not ++ opened for writing. ++*/ ++ ++ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); ++/* ++ Reads the given number of uncompressed bytes from the compressed file. ++ If the input file was not in gzip format, gzread copies the given number ++ of bytes into the buffer. ++ gzread returns the number of uncompressed bytes actually read (0 for ++ end of file, -1 for error). */ ++ ++ZEXTERN int ZEXPORT gzwrite OF((gzFile file, ++ const voidp buf, unsigned len)); ++/* ++ Writes the given number of uncompressed bytes into the compressed file. ++ gzwrite returns the number of uncompressed bytes actually written ++ (0 in case of error). ++*/ ++ ++ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); ++/* ++ Converts, formats, and writes the args to the compressed file under ++ control of the format string, as in fprintf. gzprintf returns the number of ++ uncompressed bytes actually written (0 in case of error). ++*/ ++ ++ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); ++/* ++ Writes the given null-terminated string to the compressed file, excluding ++ the terminating null character. ++ gzputs returns the number of characters written, or -1 in case of error. ++*/ ++ ++ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); ++/* ++ Reads bytes from the compressed file until len-1 characters are read, or ++ a newline character is read and transferred to buf, or an end-of-file ++ condition is encountered. The string is then terminated with a null ++ character. ++ gzgets returns buf, or Z_NULL in case of error. ++*/ ++ ++ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); ++/* ++ Writes c, converted to an unsigned char, into the compressed file. ++ gzputc returns the value that was written, or -1 in case of error. ++*/ ++ ++ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); ++/* ++ Reads one byte from the compressed file. gzgetc returns this byte ++ or -1 in case of end of file or error. ++*/ ++ ++ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); ++/* ++ Flushes all pending output into the compressed file. The parameter ++ flush is as in the deflate() function. The return value is the zlib ++ error number (see function gzerror below). gzflush returns Z_OK if ++ the flush parameter is Z_FINISH and all output could be flushed. ++ gzflush should be called only when strictly necessary because it can ++ degrade compression. ++*/ ++ ++ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, ++ z_off_t offset, int whence)); ++/* ++ Sets the starting position for the next gzread or gzwrite on the ++ given compressed file. The offset represents a number of bytes in the ++ uncompressed data stream. The whence parameter is defined as in lseek(2); ++ the value SEEK_END is not supported. ++ If the file is opened for reading, this function is emulated but can be ++ extremely slow. If the file is opened for writing, only forward seeks are ++ supported; gzseek then compresses a sequence of zeroes up to the new ++ starting position. ++ ++ gzseek returns the resulting offset location as measured in bytes from ++ the beginning of the uncompressed stream, or -1 in case of error, in ++ particular if the file is opened for writing and the new starting position ++ would be before the current position. ++*/ ++ ++ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); ++/* ++ Rewinds the given file. This function is supported only for reading. ++ ++ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) ++*/ ++ ++ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); ++/* ++ Returns the starting position for the next gzread or gzwrite on the ++ given compressed file. This position represents a number of bytes in the ++ uncompressed data stream. ++ ++ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) ++*/ ++ ++ZEXTERN int ZEXPORT gzeof OF((gzFile file)); ++/* ++ Returns 1 when EOF has previously been detected reading the given ++ input stream, otherwise zero. ++*/ ++ ++ZEXTERN int ZEXPORT gzclose OF((gzFile file)); ++/* ++ Flushes all pending output if necessary, closes the compressed file ++ and deallocates all the (de)compression state. The return value is the zlib ++ error number (see function gzerror below). ++*/ ++ ++ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); ++/* ++ Returns the error message for the last error which occurred on the ++ given compressed file. errnum is set to zlib error number. If an ++ error occurred in the file system and not in the compression library, ++ errnum is set to Z_ERRNO and the application may consult errno ++ to get the exact error code. ++*/ ++ ++ /* checksum functions */ ++ ++/* ++ These functions are not related to compression but are exported ++ anyway because they might be useful in applications using the ++ compression library. ++*/ ++ ++ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); ++ ++/* ++ Update a running Adler-32 checksum with the bytes buf[0..len-1] and ++ return the updated checksum. If buf is NULL, this function returns ++ the required initial value for the checksum. ++ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed ++ much faster. Usage example: ++ ++ uLong adler = adler32(0L, Z_NULL, 0); ++ ++ while (read_buffer(buffer, length) != EOF) { ++ adler = adler32(adler, buffer, length); ++ } ++ if (adler != original_adler) error(); ++*/ ++ ++ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); ++/* ++ Update a running crc with the bytes buf[0..len-1] and return the updated ++ crc. If buf is NULL, this function returns the required initial value ++ for the crc. Pre- and post-conditioning (one's complement) is performed ++ within this function so it shouldn't be done by the application. ++ Usage example: ++ ++ uLong crc = crc32(0L, Z_NULL, 0); ++ ++ while (read_buffer(buffer, length) != EOF) { ++ crc = crc32(crc, buffer, length); ++ } ++ if (crc != original_crc) error(); ++*/ ++ ++ ++ /* various hacks, don't look :) */ ++ ++/* deflateInit and inflateInit are macros to allow checking the zlib version ++ * and the compiler's view of z_stream: ++ */ ++ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, ++ const char *version, int stream_size)); ++ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, ++ const char *version, int stream_size)); ++ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, ++ int windowBits, int memLevel, ++ int strategy, const char *version, ++ int stream_size)); ++ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, ++ const char *version, int stream_size)); ++#define deflateInit(strm, level) \ ++ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) ++#define inflateInit(strm) \ ++ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) ++#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ ++ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ ++ (strategy), ZLIB_VERSION, sizeof(z_stream)) ++#define inflateInit2(strm, windowBits) \ ++ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) ++ ++ ++#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) ++ struct internal_state {int dummy;}; /* hack for buggy compilers */ ++#endif ++ ++ZEXTERN const char * ZEXPORT zError OF((int err)); ++ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); ++ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _ZLIB_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/include/zlib/zutil.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,225 @@ ++/* zutil.h -- internal interface and configuration of the compression library ++ * Copyright (C) 1995-2002 Jean-loup Gailly. ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++/* @(#) $Id: zutil.h,v 1.4 2002/04/24 07:36:48 mcr Exp $ */ ++ ++#ifndef _Z_UTIL_H ++#define _Z_UTIL_H ++ ++#include "zlib.h" ++ ++#include ++#define HAVE_MEMCPY ++ ++#if 0 // #ifdef STDC ++# include ++# include ++# include ++#endif ++#ifndef __KERNEL__ ++#ifdef NO_ERRNO_H ++ extern int errno; ++#else ++# include ++#endif ++#endif ++ ++#ifndef local ++# define local static ++#endif ++/* compile with -Dlocal if your debugger can't find static symbols */ ++ ++typedef unsigned char uch; ++typedef uch FAR uchf; ++typedef unsigned short ush; ++typedef ush FAR ushf; ++typedef unsigned long ulg; ++ ++extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ ++/* (size given to avoid silly warnings with Visual C++) */ ++ ++#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] ++ ++#define ERR_RETURN(strm,err) \ ++ return (strm->msg = ERR_MSG(err), (err)) ++/* To be used only when the state is known to be valid */ ++ ++ /* common constants */ ++ ++#ifndef DEF_WBITS ++# define DEF_WBITS MAX_WBITS ++#endif ++/* default windowBits for decompression. MAX_WBITS is for compression only */ ++ ++#if MAX_MEM_LEVEL >= 8 ++# define DEF_MEM_LEVEL 8 ++#else ++# define DEF_MEM_LEVEL MAX_MEM_LEVEL ++#endif ++/* default memLevel */ ++ ++#define STORED_BLOCK 0 ++#define STATIC_TREES 1 ++#define DYN_TREES 2 ++/* The three kinds of block type */ ++ ++#define MIN_MATCH 3 ++#define MAX_MATCH 258 ++/* The minimum and maximum match lengths */ ++ ++#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ ++ ++ /* target dependencies */ ++ ++#ifdef MSDOS ++# define OS_CODE 0x00 ++# if defined(__TURBOC__) || defined(__BORLANDC__) ++# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) ++ /* Allow compilation with ANSI keywords only enabled */ ++ void _Cdecl farfree( void *block ); ++ void *_Cdecl farmalloc( unsigned long nbytes ); ++# else ++# include ++# endif ++# else /* MSC or DJGPP */ ++# include ++# endif ++#endif ++ ++#ifdef OS2 ++# define OS_CODE 0x06 ++#endif ++ ++#ifdef WIN32 /* Window 95 & Windows NT */ ++# define OS_CODE 0x0b ++#endif ++ ++#if defined(VAXC) || defined(VMS) ++# define OS_CODE 0x02 ++# define F_OPEN(name, mode) \ ++ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") ++#endif ++ ++#ifdef AMIGA ++# define OS_CODE 0x01 ++#endif ++ ++#if defined(ATARI) || defined(atarist) ++# define OS_CODE 0x05 ++#endif ++ ++#if defined(MACOS) || defined(TARGET_OS_MAC) ++# define OS_CODE 0x07 ++# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os ++# include /* for fdopen */ ++# else ++# ifndef fdopen ++# define fdopen(fd,mode) NULL /* No fdopen() */ ++# endif ++# endif ++#endif ++ ++#ifdef __50SERIES /* Prime/PRIMOS */ ++# define OS_CODE 0x0F ++#endif ++ ++#ifdef TOPS20 ++# define OS_CODE 0x0a ++#endif ++ ++#if defined(_BEOS_) || defined(RISCOS) ++# define fdopen(fd,mode) NULL /* No fdopen() */ ++#endif ++ ++#if (defined(_MSC_VER) && (_MSC_VER > 600)) ++# define fdopen(fd,type) _fdopen(fd,type) ++#endif ++ ++ ++ /* Common defaults */ ++ ++#ifndef OS_CODE ++# define OS_CODE 0x03 /* assume Unix */ ++#endif ++ ++#ifndef F_OPEN ++# define F_OPEN(name, mode) fopen((name), (mode)) ++#endif ++ ++ /* functions */ ++ ++#ifdef HAVE_STRERROR ++ extern char *strerror OF((int)); ++# define zstrerror(errnum) strerror(errnum) ++#else ++# define zstrerror(errnum) "" ++#endif ++ ++#if defined(pyr) ++# define NO_MEMCPY ++#endif ++#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) ++ /* Use our own functions for small and medium model with MSC <= 5.0. ++ * You may have to use the same strategy for Borland C (untested). ++ * The __SC__ check is for Symantec. ++ */ ++# define NO_MEMCPY ++#endif ++#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) ++# define HAVE_MEMCPY ++#endif ++#ifdef HAVE_MEMCPY ++# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ ++# define zmemcpy _fmemcpy ++# define zmemcmp _fmemcmp ++# define zmemzero(dest, len) _fmemset(dest, 0, len) ++# else ++# define zmemcpy memcpy ++# define zmemcmp memcmp ++# define zmemzero(dest, len) memset(dest, 0, len) ++# endif ++#else ++ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); ++ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); ++ extern void zmemzero OF((Bytef* dest, uInt len)); ++#endif ++ ++/* Diagnostic functions */ ++#ifdef DEBUG ++# include ++ extern int z_verbose; ++ extern void z_error OF((char *m)); ++# define Assert(cond,msg) {if(!(cond)) z_error(msg);} ++# define Trace(x) {if (z_verbose>=0) fprintf x ;} ++# define Tracev(x) {if (z_verbose>0) fprintf x ;} ++# define Tracevv(x) {if (z_verbose>1) fprintf x ;} ++# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} ++# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} ++#else ++# define Assert(cond,msg) ++# define Trace(x) ++# define Tracev(x) ++# define Tracevv(x) ++# define Tracec(c,x) ++# define Tracecv(c,x) ++#endif ++ ++ ++typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf, ++ uInt len)); ++voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); ++void zcfree OF((voidpf opaque, voidpf ptr)); ++ ++#define ZALLOC(strm, items, size) \ ++ (*((strm)->zalloc))((strm)->opaque, (items), (size)) ++#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) ++#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} ++ ++#endif /* _Z_UTIL_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/Makefile.objs Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,21 @@ ++obj-y += satot.o ++obj-y += addrtot.o ++obj-y += ultot.o ++obj-y += addrtypeof.o ++obj-y += anyaddr.o ++obj-y += initaddr.o ++obj-y += ultoa.o ++obj-y += addrtoa.o ++obj-y += subnettoa.o ++obj-y += subnetof.o ++obj-y += goodmask.o ++obj-y += datatot.o ++obj-y += rangetoa.o ++obj-y += prng.o ++obj-y += pfkey_v2_parse.o ++obj-y += pfkey_v2_build.o ++obj-y += pfkey_v2_debug.o ++obj-y += pfkey_v2_ext_bits.o ++ ++#version.c: ${LIBFREESWANDIR}/version.in.c ${OPENSWANSRCDIR}/Makefile.ver ++# sed '/"/s/xxx/$(IPSECVERSION)/' ${LIBFREESWANDIR}/version.in.c >$@ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/addrtoa.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,67 @@ ++/* ++ * addresses to ASCII ++ * Copyright (C) 1998, 1999 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: addrtoa.c,v 1.9 2004/04/11 17:39:25 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++#define NBYTES 4 /* bytes in an address */ ++#define PERBYTE 4 /* three digits plus a dot or NUL */ ++#define BUFLEN (NBYTES*PERBYTE) ++ ++#if BUFLEN != ADDRTOA_BUF ++#error "ADDRTOA_BUF in openswan.h inconsistent with addrtoa() code" ++#endif ++ ++/* ++ - addrtoa - convert binary address to ASCII dotted decimal ++ */ ++size_t /* space needed for full conversion */ ++addrtoa(addr, format, dst, dstlen) ++struct in_addr addr; ++int format; /* character */ ++char *dst; /* need not be valid if dstlen is 0 */ ++size_t dstlen; ++{ ++ unsigned long a = ntohl(addr.s_addr); ++ int i; ++ size_t n; ++ unsigned long byte; ++ char buf[BUFLEN]; ++ char *p; ++ ++ switch (format) { ++ case 0: ++ break; ++ default: ++ return 0; ++ break; ++ } ++ ++ p = buf; ++ for (i = NBYTES-1; i >= 0; i--) { ++ byte = (a >> (i*8)) & 0xff; ++ p += ultoa(byte, 10, p, PERBYTE); ++ if (i != 0) ++ *(p-1) = '.'; ++ } ++ n = p - buf; ++ ++ if (dstlen > 0) { ++ if (n > dstlen) ++ buf[dstlen - 1] = '\0'; ++ strcpy(dst, buf); ++ } ++ return n; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/addrtot.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,334 @@ ++/* ++ * addresses to text ++ * Copyright (C) 2000 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: addrtot.c,v 1.15 2004/04/11 17:39:25 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++#define IP4BYTES 4 /* bytes in an IPv4 address */ ++#define PERBYTE 4 /* three digits plus a dot or NUL */ ++#define IP6BYTES 16 /* bytes in an IPv6 address */ ++ ++/* forwards */ ++static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp); ++static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish); ++static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp); ++static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp); ++ ++/* ++ - addrtot - convert binary address to text (dotted decimal or IPv6 string) ++ */ ++size_t /* space needed for full conversion */ ++addrtot(src, format, dst, dstlen) ++const ip_address *src; ++int format; /* character */ ++char *dst; /* need not be valid if dstlen is 0 */ ++size_t dstlen; ++{ ++ const unsigned char *b; ++ size_t n; ++ char buf[1+ADDRTOT_BUF+1]; /* :address: */ ++ char *p; ++ int t = addrtypeof(src); ++# define TF(t, f) (((t)<<8) | (f)) ++ ++ n = addrbytesptr(src, &b); ++ if (n == 0) { ++ bad: ++ dst[0]='\0'; ++ strncat(dst, "", dstlen); ++ return sizeof(""); ++ } ++ ++ switch (TF(t, format)) { ++ case TF(AF_INET, 0): ++ n = normal4(b, n, buf, &p); ++ break; ++ case TF(AF_INET6, 0): ++ n = normal6(b, n, buf, &p, 1); ++ break; ++ case TF(AF_INET, 'Q'): ++ n = normal4(b, n, buf, &p); ++ break; ++ case TF(AF_INET6, 'Q'): ++ n = normal6(b, n, buf, &p, 0); ++ break; ++ case TF(AF_INET, 'r'): ++ n = reverse4(b, n, buf, &p); ++ break; ++ case TF(AF_INET6, 'r'): ++ n = reverse6(b, n, buf, &p); ++ break; ++ default: /* including (AF_INET, 'R') */ ++ goto bad; ++ break; ++ } ++ ++ if (dstlen > 0) { ++ if (dstlen < n) ++ p[dstlen - 1] = '\0'; ++ strcpy(dst, p); ++ } ++ return n; ++} ++ ++/* ++ - normal4 - normal IPv4 address-text conversion ++ */ ++static size_t /* size of text, including NUL */ ++normal4(srcp, srclen, buf, dstp) ++const unsigned char *srcp; ++size_t srclen; ++char *buf; /* guaranteed large enough */ ++char **dstp; /* where to put result pointer */ ++{ ++ int i; ++ char *p; ++ ++ if (srclen != IP4BYTES) /* "can't happen" */ ++ return 0; ++ p = buf; ++ for (i = 0; i < IP4BYTES; i++) { ++ p += ultot(srcp[i], 10, p, PERBYTE); ++ if (i != IP4BYTES - 1) ++ *(p-1) = '.'; /* overwrites the NUL */ ++ } ++ *dstp = buf; ++ return p - buf; ++} ++ ++/* ++ - normal6 - normal IPv6 address-text conversion ++ */ ++static size_t /* size of text, including NUL */ ++normal6(srcp, srclen, buf, dstp, squish) ++const unsigned char *srcp; ++size_t srclen; ++char *buf; /* guaranteed large enough, plus 2 */ ++char **dstp; /* where to put result pointer */ ++int squish; /* whether to squish out 0:0 */ ++{ ++ int i; ++ unsigned long piece; ++ char *p; ++ char *q; ++ ++ if (srclen != IP6BYTES) /* "can't happen" */ ++ return 0; ++ p = buf; ++ *p++ = ':'; ++ for (i = 0; i < IP6BYTES/2; i++) { ++ piece = (srcp[2*i] << 8) + srcp[2*i + 1]; ++ p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */ ++ *(p-1) = ':'; /* overwrites the NUL */ ++ } ++ *p = '\0'; ++ q = strstr(buf, ":0:0:"); ++ if (squish && q != NULL) { /* zero squishing is possible */ ++ p = q + 1; ++ while (*p == '0' && *(p+1) == ':') ++ p += 2; ++ q++; ++ *q++ = ':'; /* overwrite first 0 */ ++ while (*p != '\0') ++ *q++ = *p++; ++ *q = '\0'; ++ if (!(*(q-1) == ':' && *(q-2) == ':')) ++ *--q = '\0'; /* strip final : unless :: */ ++ p = buf; ++ if (!(*p == ':' && *(p+1) == ':')) ++ p++; /* skip initial : unless :: */ ++ } else { ++ q = p; ++ *--q = '\0'; /* strip final : */ ++ p = buf + 1; /* skip initial : */ ++ } ++ *dstp = p; ++ return q - p + 1; ++} ++ ++/* ++ - reverse4 - IPv4 reverse-lookup conversion ++ */ ++static size_t /* size of text, including NUL */ ++reverse4(srcp, srclen, buf, dstp) ++const unsigned char *srcp; ++size_t srclen; ++char *buf; /* guaranteed large enough */ ++char **dstp; /* where to put result pointer */ ++{ ++ int i; ++ char *p; ++ ++ if (srclen != IP4BYTES) /* "can't happen" */ ++ return 0; ++ p = buf; ++ for (i = IP4BYTES-1; i >= 0; i--) { ++ p += ultot(srcp[i], 10, p, PERBYTE); ++ *(p-1) = '.'; /* overwrites the NUL */ ++ } ++ strcpy(p, "IN-ADDR.ARPA."); ++ *dstp = buf; ++ return strlen(buf) + 1; ++} ++ ++/* ++ - reverse6 - IPv6 reverse-lookup conversion (RFC 1886) ++ * A trifle inefficient, really shouldn't use ultot... ++ */ ++static size_t /* size of text, including NUL */ ++reverse6(srcp, srclen, buf, dstp) ++const unsigned char *srcp; ++size_t srclen; ++char *buf; /* guaranteed large enough */ ++char **dstp; /* where to put result pointer */ ++{ ++ int i; ++ unsigned long piece; ++ char *p; ++ ++ if (srclen != IP6BYTES) /* "can't happen" */ ++ return 0; ++ p = buf; ++ for (i = IP6BYTES-1; i >= 0; i--) { ++ piece = srcp[i]; ++ p += ultot(piece&0xf, 16, p, 2); ++ *(p-1) = '.'; ++ p += ultot(piece>>4, 16, p, 2); ++ *(p-1) = '.'; ++ } ++ strcpy(p, "IP6.ARPA."); ++ *dstp = buf; ++ return strlen(buf) + 1; ++} ++ ++/* ++ - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874) ++ * this version removed as it was obsoleted in the end. ++ */ ++ ++#ifdef ADDRTOT_MAIN ++ ++#include ++#include ++#include ++#include ++ ++void regress(void); ++ ++int ++main(int argc, char *argv[]) ++{ ++ if (argc < 2) { ++ fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n", ++ argv[0]); ++ exit(2); ++ } ++ ++ if (strcmp(argv[1], "-r") == 0) { ++ regress(); ++ fprintf(stderr, "regress() returned?!?\n"); ++ exit(1); ++ } ++ exit(0); ++} ++ ++struct rtab { ++ char *input; ++ char format; ++ char *output; /* NULL means error expected */ ++} rtab[] = { ++ {"1.2.3.0", 0, "1.2.3.0"}, ++ {"1:2::3:4", 0, "1:2::3:4"}, ++ {"1:2::3:4", 'Q', "1:2:0:0:0:0:3:4"}, ++ {"1:2:0:0:3:4:0:0", 0, "1:2::3:4:0:0"}, ++ {"1.2.3.4", 'r' , "4.3.2.1.IN-ADDR.ARPA."}, ++ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f */ ++ {"1:2::3:4", 'r', "4.0.0.0.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.1.0.0.0.IP6.ARPA."}, ++ {NULL, 0, NULL} ++}; ++ ++void ++regress() ++{ ++ struct rtab *r; ++ int status = 0; ++ ip_address a; ++ char in[100]; ++ char buf[100]; ++ const char *oops; ++ size_t n; ++ ++ for (r = rtab; r->input != NULL; r++) { ++ strcpy(in, r->input); ++ ++ /* convert it *to* internal format */ ++ oops = ttoaddr(in, strlen(in), 0, &a); ++ ++ /* now convert it back */ ++ ++ n = addrtot(&a, r->format, buf, sizeof(buf)); ++ ++ if (n == 0 && r->output == NULL) ++ {} /* okay, error expected */ ++ ++ else if (n == 0) { ++ printf("`%s' atoasr failed\n", r->input); ++ status = 1; ++ ++ } else if (r->output == NULL) { ++ printf("`%s' atoasr succeeded unexpectedly '%c'\n", ++ r->input, r->format); ++ status = 1; ++ } else { ++ if (strcasecmp(r->output, buf) != 0) { ++ printf("`%s' '%c' gave `%s', expected `%s'\n", ++ r->input, r->format, buf, r->output); ++ status = 1; ++ } ++ } ++ } ++ exit(status); ++} ++ ++#endif /* ADDRTOT_MAIN */ ++ ++/* ++ * $Log: addrtot.c,v $ ++ * Revision 1.15 2004/04/11 17:39:25 mcr ++ * removed internal.h requirements. ++ * ++ * Revision 1.14 2004/03/08 01:59:08 ken ++ * freeswan.h -> openswan.h ++ * ++ * Revision 1.13 2004/01/05 23:21:05 mcr ++ * if the address type is invalid, then return length of ++ * string! ++ * ++ * Revision 1.12 2003/12/30 06:42:48 mcr ++ * added $Log: addrtot.c,v $ ++ * added Revision 1.15 2004/04/11 17:39:25 mcr ++ * added removed internal.h requirements. ++ * added ++ * added Revision 1.14 2004/03/08 01:59:08 ken ++ * added freeswan.h -> openswan.h ++ * added ++ * added Revision 1.13 2004/01/05 23:21:05 mcr ++ * added if the address type is invalid, then return length of ++ * added string! ++ * added ++ * ++ * ++ */ ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/addrtypeof.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,93 @@ ++/* ++ * extract parts of an ip_address ++ * Copyright (C) 2000 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: addrtypeof.c,v 1.9 2004/04/11 17:39:25 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++/* ++ - addrtypeof - get the type of an ip_address ++ */ ++int ++addrtypeof(src) ++const ip_address *src; ++{ ++ return src->u.v4.sin_family; ++} ++ ++/* ++ - addrbytesptr - get pointer to the address bytes of an ip_address ++ */ ++size_t /* 0 for error */ ++addrbytesptr(src, dstp) ++const ip_address *src; ++const unsigned char **dstp; /* NULL means just a size query */ ++{ ++ const unsigned char *p; ++ size_t n; ++ ++ switch (src->u.v4.sin_family) { ++ case AF_INET: ++ p = (const unsigned char *)&src->u.v4.sin_addr.s_addr; ++ n = 4; ++ break; ++ case AF_INET6: ++ p = (const unsigned char *)&src->u.v6.sin6_addr; ++ n = 16; ++ break; ++ default: ++ return 0; ++ break; ++ } ++ ++ if (dstp != NULL) ++ *dstp = p; ++ return n; ++} ++ ++/* ++ - addrlenof - get length of the address bytes of an ip_address ++ */ ++size_t /* 0 for error */ ++addrlenof(src) ++const ip_address *src; ++{ ++ return addrbytesptr(src, NULL); ++} ++ ++/* ++ - addrbytesof - get the address bytes of an ip_address ++ */ ++size_t /* 0 for error */ ++addrbytesof(src, dst, dstlen) ++const ip_address *src; ++unsigned char *dst; ++size_t dstlen; ++{ ++ const unsigned char *p; ++ size_t n; ++ size_t ncopy; ++ ++ n = addrbytesptr(src, &p); ++ if (n == 0) ++ return 0; ++ ++ if (dstlen > 0) { ++ ncopy = n; ++ if (ncopy > dstlen) ++ ncopy = dstlen; ++ memcpy(dst, p, ncopy); ++ } ++ return n; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/anyaddr.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,145 @@ ++/* ++ * special addresses ++ * Copyright (C) 2000 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: anyaddr.c,v 1.9 2004/04/11 17:39:25 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++/* these are mostly fallbacks for the no-IPv6-support-in-library case */ ++#ifndef IN6ADDR_ANY_INIT ++#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}} ++#endif ++#ifndef IN6ADDR_LOOPBACK_INIT ++#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}} ++#endif ++ ++static struct in6_addr v6any = IN6ADDR_ANY_INIT; ++static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT; ++ ++/* ++ - anyaddr - initialize to the any-address value ++ */ ++err_t /* NULL for success, else string literal */ ++anyaddr(af, dst) ++int af; /* address family */ ++ip_address *dst; ++{ ++ uint32_t v4any = htonl(INADDR_ANY); ++ ++ switch (af) { ++ case AF_INET: ++ return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst); ++ break; ++ case AF_INET6: ++ return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst); ++ break; ++ default: ++ return "unknown address family in anyaddr/unspecaddr"; ++ break; ++ } ++} ++ ++/* ++ - unspecaddr - initialize to the unspecified-address value ++ */ ++err_t /* NULL for success, else string literal */ ++unspecaddr(af, dst) ++int af; /* address family */ ++ip_address *dst; ++{ ++ return anyaddr(af, dst); ++} ++ ++/* ++ - loopbackaddr - initialize to the loopback-address value ++ */ ++err_t /* NULL for success, else string literal */ ++loopbackaddr(af, dst) ++int af; /* address family */ ++ip_address *dst; ++{ ++ uint32_t v4loop = htonl(INADDR_LOOPBACK); ++ ++ switch (af) { ++ case AF_INET: ++ return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst); ++ break; ++ case AF_INET6: ++ return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst); ++ break; ++ default: ++ return "unknown address family in loopbackaddr"; ++ break; ++ } ++} ++ ++/* ++ - isanyaddr - test for the any-address value ++ */ ++int ++isanyaddr(src) ++const ip_address *src; ++{ ++ uint32_t v4any = htonl(INADDR_ANY); ++ int cmp; ++ ++ switch (src->u.v4.sin_family) { ++ case AF_INET: ++ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any)); ++ break; ++ case AF_INET6: ++ cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any)); ++ break; ++ default: ++ return 0; ++ break; ++ } ++ ++ return (cmp == 0) ? 1 : 0; ++} ++ ++/* ++ - isunspecaddr - test for the unspecified-address value ++ */ ++int ++isunspecaddr(src) ++const ip_address *src; ++{ ++ return isanyaddr(src); ++} ++ ++/* ++ - isloopbackaddr - test for the loopback-address value ++ */ ++int ++isloopbackaddr(src) ++const ip_address *src; ++{ ++ uint32_t v4loop = htonl(INADDR_LOOPBACK); ++ int cmp; ++ ++ switch (src->u.v4.sin_family) { ++ case AF_INET: ++ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop)); ++ break; ++ case AF_INET6: ++ cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop)); ++ break; ++ default: ++ return 0; ++ break; ++ } ++ ++ return (cmp == 0) ? 1 : 0; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/datatot.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,232 @@ ++/* ++ * convert from binary data (e.g. key) to text form ++ * Copyright (C) 2000 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: datatot.c,v 1.5 2004/04/11 17:39:25 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++static void convert(const char *src, size_t nreal, int format, char *out); ++ ++/* ++ - datatot - convert data bytes to text ++ */ ++size_t /* true length (with NUL) for success */ ++datatot(src, srclen, format, dst, dstlen) ++const char *src; ++size_t srclen; ++int format; /* character indicating what format */ ++char *dst; /* need not be valid if dstlen is 0 */ ++size_t dstlen; ++{ ++ size_t inblocksize; /* process this many bytes at a time */ ++ size_t outblocksize; /* producing this many */ ++ size_t breakevery; /* add a _ every this many (0 means don't) */ ++ size_t sincebreak; /* output bytes since last _ */ ++ char breakchar; /* character used to break between groups */ ++ char inblock[10]; /* enough for any format */ ++ char outblock[10]; /* enough for any format */ ++ char fake[1]; /* fake output area for dstlen == 0 */ ++ size_t needed; /* return value */ ++ char *stop; /* where the terminating NUL will go */ ++ size_t ntodo; /* remaining input */ ++ size_t nreal; ++ char *out; ++ char *prefix; ++ ++ breakevery = 0; ++ breakchar = '_'; ++ ++ switch (format) { ++ case 0: ++ case 'h': ++ format = 'x'; ++ breakevery = 8; ++ /* FALLTHROUGH */ ++ case 'x': ++ inblocksize = 1; ++ outblocksize = 2; ++ prefix = "0x"; ++ break; ++ case ':': ++ format = 'x'; ++ breakevery = 2; ++ breakchar = ':'; ++ /* FALLTHROUGH */ ++ case 16: ++ inblocksize = 1; ++ outblocksize = 2; ++ prefix = ""; ++ format = 'x'; ++ break; ++ case 's': ++ inblocksize = 3; ++ outblocksize = 4; ++ prefix = "0s"; ++ break; ++ case 64: /* beware, equals ' ' */ ++ inblocksize = 3; ++ outblocksize = 4; ++ prefix = ""; ++ format = 's'; ++ break; ++ default: ++ return 0; ++ break; ++ } ++ assert(inblocksize < sizeof(inblock)); ++ assert(outblocksize < sizeof(outblock)); ++ assert(breakevery % outblocksize == 0); ++ ++ if (srclen == 0) ++ return 0; ++ ntodo = srclen; ++ ++ if (dstlen == 0) { /* dispose of awkward special case */ ++ dst = fake; ++ dstlen = 1; ++ } ++ stop = dst + dstlen - 1; ++ ++ nreal = strlen(prefix); ++ needed = nreal; /* for starters */ ++ if (dstlen <= nreal) { /* prefix won't fit */ ++ strncpy(dst, prefix, dstlen - 1); ++ dst += dstlen - 1; ++ } else { ++ strcpy(dst, prefix); ++ dst += nreal; ++ } ++ assert(dst <= stop); ++ sincebreak = 0; ++ ++ while (ntodo > 0) { ++ if (ntodo < inblocksize) { /* incomplete input */ ++ memset(inblock, 0, sizeof(inblock)); ++ memcpy(inblock, src, ntodo); ++ src = inblock; ++ nreal = ntodo; ++ ntodo = inblocksize; ++ } else ++ nreal = inblocksize; ++ out = (outblocksize > stop - dst) ? outblock : dst; ++ ++ convert(src, nreal, format, out); ++ needed += outblocksize; ++ sincebreak += outblocksize; ++ if (dst < stop) { ++ if (out != dst) { ++ assert(outblocksize > stop - dst); ++ memcpy(dst, out, stop - dst); ++ dst = stop; ++ } else ++ dst += outblocksize; ++ } ++ ++ src += inblocksize; ++ ntodo -= inblocksize; ++ if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) { ++ if (dst < stop) ++ *dst++ = breakchar; ++ needed++; ++ sincebreak = 0; ++ } ++ } ++ ++ assert(dst <= stop); ++ *dst++ = '\0'; ++ needed++; ++ ++ return needed; ++} ++ ++/* ++ - convert - convert one input block to one output block ++ */ ++static void ++convert(src, nreal, format, out) ++const char *src; ++size_t nreal; /* how much of the input block is real */ ++int format; ++char *out; ++{ ++ static char hex[] = "0123456789abcdef"; ++ static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ++ "abcdefghijklmnopqrstuvwxyz" ++ "0123456789+/"; ++ unsigned char c; ++ unsigned char c1, c2, c3; ++ ++ assert(nreal > 0); ++ switch (format) { ++ case 'x': ++ assert(nreal == 1); ++ c = (unsigned char)*src; ++ *out++ = hex[c >> 4]; ++ *out++ = hex[c & 0xf]; ++ break; ++ case 's': ++ c1 = (unsigned char)*src++; ++ c2 = (unsigned char)*src++; ++ c3 = (unsigned char)*src++; ++ *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */ ++ c = (c1 & 0x3) << 4; /* bottom 2 of c1... */ ++ c |= c2 >> 4; /* ...top 4 of c2 */ ++ *out++ = base64[c]; ++ if (nreal == 1) ++ *out++ = '='; ++ else { ++ c = (c2 & 0xf) << 2; /* bottom 4 of c2... */ ++ c |= c3 >> 6; /* ...top 2 of c3 */ ++ *out++ = base64[c]; ++ } ++ if (nreal <= 2) ++ *out++ = '='; ++ else ++ *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */ ++ break; ++ default: ++ assert(nreal == 0); /* unknown format */ ++ break; ++ } ++} ++ ++/* ++ - datatoa - convert data to ASCII ++ * backward-compatibility synonym for datatot ++ */ ++size_t /* true length (with NUL) for success */ ++datatoa(src, srclen, format, dst, dstlen) ++const char *src; ++size_t srclen; ++int format; /* character indicating what format */ ++char *dst; /* need not be valid if dstlen is 0 */ ++size_t dstlen; ++{ ++ return datatot(src, srclen, format, dst, dstlen); ++} ++ ++/* ++ - bytestoa - convert data bytes to ASCII ++ * backward-compatibility synonym for datatot ++ */ ++size_t /* true length (with NUL) for success */ ++bytestoa(src, srclen, format, dst, dstlen) ++const char *src; ++size_t srclen; ++int format; /* character indicating what format */ ++char *dst; /* need not be valid if dstlen is 0 */ ++size_t dstlen; ++{ ++ return datatot(src, srclen, format, dst, dstlen); ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/goodmask.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,100 @@ ++/* ++ * minor utilities for subnet-mask manipulation ++ * Copyright (C) 1998, 1999 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: goodmask.c,v 1.11 2004/04/11 19:43:48 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++#ifndef ABITS ++#define ABITS 32 /* bits in an IPv4 address */ ++#endif ++ ++/* ++ - goodmask - is this a good (^1*0*$) subnet mask? ++ * You are not expected to understand this. See Henry S. Warren Jr, ++ * "Functions realizable with word-parallel logical and two's-complement ++ * addition instructions", CACM 20.6 (June 1977), p.439. ++ */ ++int /* predicate */ ++goodmask(mask) ++struct in_addr mask; ++{ ++ unsigned long x = ntohl(mask.s_addr); ++ /* clear rightmost contiguous string of 1-bits */ ++# define CRCS1B(x) (((x|(x-1))+1)&x) ++# define TOPBIT (1UL << 31) ++ ++ /* either zero, or has one string of 1-bits which is left-justified */ ++ if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT))) ++ return 1; ++ return 0; ++} ++ ++/* ++ - masktobits - how many bits in this mask? ++ * The algorithm is essentially a binary search, but highly optimized ++ * for this particular task. ++ */ ++int /* -1 means !goodmask() */ ++masktobits(mask) ++struct in_addr mask; ++{ ++ unsigned long m = ntohl(mask.s_addr); ++ int masklen; ++ ++ if (!goodmask(mask)) ++ return -1; ++ ++ if (m&0x00000001UL) ++ return 32; ++ masklen = 0; ++ if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */ ++ masklen |= 0x10; ++ m <<= 16; ++ } ++ if (m&(0x00ff0000UL<<1)) { ++ masklen |= 0x08; ++ m <<= 8; ++ } ++ if (m&(0x0f000000UL<<1)) { ++ masklen |= 0x04; ++ m <<= 4; ++ } ++ if (m&(0x30000000UL<<1)) { ++ masklen |= 0x02; ++ m <<= 2; ++ } ++ if (m&(0x40000000UL<<1)) ++ masklen |= 0x01; ++ ++ return masklen; ++} ++ ++/* ++ - bitstomask - return a mask with this many high bits on ++ */ ++struct in_addr ++bitstomask(n) ++int n; ++{ ++ struct in_addr result; ++ ++ if (n > 0 && n <= ABITS) ++ result.s_addr = htonl(~((1UL << (ABITS - n)) - 1)); ++ else if (n == 0) ++ result.s_addr = 0; ++ else ++ result.s_addr = 0; /* best error report we can do */ ++ return result; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/initaddr.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,50 @@ ++/* ++ * initialize address structure ++ * Copyright (C) 2000 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: initaddr.c,v 1.5 2004/04/11 17:39:25 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++/* ++ - initaddr - initialize ip_address from bytes ++ */ ++err_t /* NULL for success, else string literal */ ++initaddr(src, srclen, af, dst) ++const unsigned char *src; ++size_t srclen; ++int af; /* address family */ ++ip_address *dst; ++{ ++ switch (af) { ++ case AF_INET: ++ if (srclen != 4) ++ return "IPv4 address must be exactly 4 bytes"; ++ dst->u.v4.sin_family = af; ++ dst->u.v4.sin_port = 0; /* unused */ ++ memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen); ++ break; ++ case AF_INET6: ++ if (srclen != 16) ++ return "IPv6 address must be exactly 16 bytes"; ++ dst->u.v6.sin6_family = af; ++ dst->u.v6.sin6_flowinfo = 0; /* unused */ ++ dst->u.v6.sin6_port = 0; /* unused */ ++ memcpy((char *)&dst->u.v6.sin6_addr, src, srclen); ++ break; ++ default: ++ return "unknown address family in initaddr"; ++ break; ++ } ++ return NULL; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/pfkey_v2_build.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,1559 @@ ++/* ++ * RFC2367 PF_KEYv2 Key management API message parser ++ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: pfkey_v2_build.c,v 1.49 2004/04/12 02:59:06 mcr Exp $ ++ */ ++ ++/* ++ * Template from klips/net/ipsec/ipsec/ipsec_parser.c. ++ */ ++ ++char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c,v 1.49 2004/04/12 02:59:06 mcr Exp $"; ++ ++/* ++ * Some ugly stuff to allow consistent debugging code for use in the ++ * kernel and in user space ++*/ ++ ++#ifdef __KERNEL__ ++ ++# include /* for printk */ ++ ++# include "openswan/ipsec_kversion.h" /* for malloc switch */ ++# ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++# else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++# endif /* MALLOC_SLAB */ ++# include /* error codes */ ++# include /* size_t */ ++# include /* mark_bh */ ++ ++# include /* struct device, and other headers */ ++# include /* eth_type_trans */ ++# include /* struct iphdr */ ++# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++# include /* struct ipv6hdr */ ++# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ ++ ++# define MALLOC(size) kmalloc(size, GFP_ATOMIC) ++# define FREE(obj) kfree(obj) ++# include ++#else /* __KERNEL__ */ ++ ++# include ++# include ++# include ++# include ++# include /* memset */ ++ ++# include ++ ++#endif /* __KERNEL__ */ ++ ++#include ++#include ++ ++#ifdef __KERNEL__ ++#include "openswan/radij.h" /* rd_nodes */ ++#include "openswan/ipsec_encap.h" /* sockaddr_encap */ ++#endif /* __KERNEL__ */ ++ ++ ++#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */ ++#include "openswan/pfkey_debug.h" ++ ++ ++#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) ++ ++void ++pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1]) ++{ ++ int i; ++ ++ for (i = 0; i != SADB_EXT_MAX + 1; i++) { ++ extensions[i] = NULL; ++ } ++} ++ ++void ++pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1]) ++{ ++ int i; ++ ++ if(!extensions) { ++ return; ++ } ++ ++ if(extensions[0]) { ++ memset(extensions[0], 0, sizeof(struct sadb_msg)); ++ FREE(extensions[0]); ++ extensions[0] = NULL; ++ } ++ ++ for (i = 1; i != SADB_EXT_MAX + 1; i++) { ++ if(extensions[i]) { ++ memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN); ++ FREE(extensions[i]); ++ extensions[i] = NULL; ++ } ++ } ++} ++ ++void ++pfkey_msg_free(struct sadb_msg **pfkey_msg) ++{ ++ if(*pfkey_msg) { ++ memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); ++ FREE(*pfkey_msg); ++ *pfkey_msg = NULL; ++ } ++} ++ ++/* Default extension builders taken from the KLIPS code */ ++ ++int ++pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext, ++ uint8_t msg_type, ++ uint8_t satype, ++ uint8_t msg_errno, ++ uint32_t seq, ++ uint32_t pid) ++{ ++ int error = 0; ++ struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext; ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_msg_hdr_build:\n"); ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_msg_hdr_build: " ++ "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n", ++ &pfkey_ext, ++ pfkey_ext, ++ *pfkey_ext); ++ /* sanity checks... */ ++ if(pfkey_msg) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_msg_hdr_build: " ++ "why is pfkey_msg already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(!msg_type) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_msg_hdr_build: " ++ "msg type not set, must be non-zero..\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(msg_type > SADB_MAX) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_msg_hdr_build: " ++ "msg type too large:%d.\n", ++ msg_type); ++ SENDERR(EINVAL); ++ } ++ ++ if(satype > SADB_SATYPE_MAX) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_msg_hdr_build: " ++ "satype %d > max %d\n", ++ satype, SADB_SATYPE_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ if(!(*pfkey_ext = (struct sadb_ext*) ++ pfkey_msg = (struct sadb_msg*) ++ MALLOC(sizeof(struct sadb_msg)))) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_msg_hdr_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ memset(pfkey_msg, 0, sizeof(struct sadb_msg)); ++ ++ pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; ++ ++ pfkey_msg->sadb_msg_type = msg_type; ++ pfkey_msg->sadb_msg_satype = satype; ++ ++ pfkey_msg->sadb_msg_version = PF_KEY_V2; ++ pfkey_msg->sadb_msg_errno = msg_errno; ++ pfkey_msg->sadb_msg_reserved = 0; ++ pfkey_msg->sadb_msg_seq = seq; ++ pfkey_msg->sadb_msg_pid = pid; ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_msg_hdr_build: " ++ "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n", ++ &pfkey_ext, ++ pfkey_ext, ++ *pfkey_ext); ++errlab: ++ return error; ++} ++ ++int ++pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext, ++ uint16_t exttype, ++ uint32_t spi, ++ uint8_t replay_window, ++ uint8_t sa_state, ++ uint8_t auth, ++ uint8_t encrypt, ++ uint32_t flags, ++ uint32_t/*IPsecSAref_t*/ ref) ++{ ++ int error = 0; ++ struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext; ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_sa_build: " ++ "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n", ++ ntohl(spi), /* in network order */ ++ replay_window, ++ sa_state, ++ auth, ++ encrypt, ++ flags); ++ /* sanity checks... */ ++ if(pfkey_sa) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_sa_build: " ++ "why is pfkey_sa already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(exttype != SADB_EXT_SA && ++ exttype != SADB_X_EXT_SA2) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_sa_build: " ++ "invalid exttype=%d.\n", ++ exttype); ++ SENDERR(EINVAL); ++ } ++ ++ if(replay_window > 64) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_sa_build: " ++ "replay window size: %d -- must be 0 <= size <= 64\n", ++ replay_window); ++ SENDERR(EINVAL); ++ } ++ ++ if(auth > SADB_AALG_MAX) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_sa_build: " ++ "auth=%d > SADB_AALG_MAX=%d.\n", ++ auth, ++ SADB_AALG_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ if(encrypt > SADB_EALG_MAX) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_sa_build: " ++ "encrypt=%d > SADB_EALG_MAX=%d.\n", ++ encrypt, ++ SADB_EALG_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ if(sa_state > SADB_SASTATE_MAX) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_sa_build: " ++ "sa_state=%d exceeds MAX=%d.\n", ++ sa_state, ++ SADB_SASTATE_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ if(sa_state == SADB_SASTATE_DEAD) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_sa_build: " ++ "sa_state=%d is DEAD=%d is not allowed.\n", ++ sa_state, ++ SADB_SASTATE_DEAD); ++ SENDERR(EINVAL); ++ } ++ ++ if((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_sa_build: " ++ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n", ++ ref, ++ IPSEC_SAREF_NULL, ++ IPSEC_SA_REF_TABLE_NUM_ENTRIES); ++ SENDERR(EINVAL); ++ } ++ ++ if(!(*pfkey_ext = (struct sadb_ext*) ++ pfkey_sa = (struct sadb_sa*) ++ MALLOC(sizeof(struct sadb_sa)))) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_sa_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ memset(pfkey_sa, 0, sizeof(struct sadb_sa)); ++ ++ pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN; ++ pfkey_sa->sadb_sa_exttype = exttype; ++ pfkey_sa->sadb_sa_spi = spi; ++ pfkey_sa->sadb_sa_replay = replay_window; ++ pfkey_sa->sadb_sa_state = sa_state; ++ pfkey_sa->sadb_sa_auth = auth; ++ pfkey_sa->sadb_sa_encrypt = encrypt; ++ pfkey_sa->sadb_sa_flags = flags; ++ pfkey_sa->sadb_x_sa_ref = ref; ++ ++errlab: ++ return error; ++} ++ ++int ++pfkey_sa_build(struct sadb_ext ** pfkey_ext, ++ uint16_t exttype, ++ uint32_t spi, ++ uint8_t replay_window, ++ uint8_t sa_state, ++ uint8_t auth, ++ uint8_t encrypt, ++ uint32_t flags) ++{ ++ return pfkey_sa_ref_build(pfkey_ext, ++ exttype, ++ spi, ++ replay_window, ++ sa_state, ++ auth, ++ encrypt, ++ flags, ++ IPSEC_SAREF_NULL); ++} ++ ++int ++pfkey_lifetime_build(struct sadb_ext ** pfkey_ext, ++ uint16_t exttype, ++ uint32_t allocations, ++ uint64_t bytes, ++ uint64_t addtime, ++ uint64_t usetime, ++ uint32_t packets) ++{ ++ int error = 0; ++ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext; ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_lifetime_build:\n"); ++ /* sanity checks... */ ++ if(pfkey_lifetime) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_lifetime_build: " ++ "why is pfkey_lifetime already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(exttype != SADB_EXT_LIFETIME_CURRENT && ++ exttype != SADB_EXT_LIFETIME_HARD && ++ exttype != SADB_EXT_LIFETIME_SOFT) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_lifetime_build: " ++ "invalid exttype=%d.\n", ++ exttype); ++ SENDERR(EINVAL); ++ } ++ ++ if(!(*pfkey_ext = (struct sadb_ext*) ++ pfkey_lifetime = (struct sadb_lifetime*) ++ MALLOC(sizeof(struct sadb_lifetime)))) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_lifetime_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime)); ++ ++ pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN; ++ pfkey_lifetime->sadb_lifetime_exttype = exttype; ++ pfkey_lifetime->sadb_lifetime_allocations = allocations; ++ pfkey_lifetime->sadb_lifetime_bytes = bytes; ++ pfkey_lifetime->sadb_lifetime_addtime = addtime; ++ pfkey_lifetime->sadb_lifetime_usetime = usetime; ++ pfkey_lifetime->sadb_x_lifetime_packets = packets; ++ ++errlab: ++ return error; ++} ++ ++int ++pfkey_address_build(struct sadb_ext** pfkey_ext, ++ uint16_t exttype, ++ uint8_t proto, ++ uint8_t prefixlen, ++ struct sockaddr* address) ++{ ++ int error = 0; ++ int saddr_len = 0; ++ char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/]; ++ struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext; ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_address_build: " ++ "exttype=%d proto=%d prefixlen=%d\n", ++ exttype, ++ proto, ++ prefixlen); ++ /* sanity checks... */ ++ if(pfkey_address) { ++ ERROR("pfkey_address_build: " ++ "why is pfkey_address already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if (!address) { ++ ERROR("pfkey_address_build: " "address is NULL\n"); ++ SENDERR(EINVAL); ++ } ++ ++ switch(exttype) { ++ case SADB_EXT_ADDRESS_SRC: ++ case SADB_EXT_ADDRESS_DST: ++ case SADB_EXT_ADDRESS_PROXY: ++ case SADB_X_EXT_ADDRESS_DST2: ++ case SADB_X_EXT_ADDRESS_SRC_FLOW: ++ case SADB_X_EXT_ADDRESS_DST_FLOW: ++ case SADB_X_EXT_ADDRESS_SRC_MASK: ++ case SADB_X_EXT_ADDRESS_DST_MASK: ++#ifdef NAT_TRAVERSAL ++ case SADB_X_EXT_NAT_T_OA: ++#endif ++ break; ++ default: ++ ERROR("pfkey_address_build: " ++ "unrecognised ext_type=%d.\n", ++ exttype); ++ SENDERR(EINVAL); ++ } ++ ++ switch(address->sa_family) { ++ case AF_INET: ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_address_build: " ++ "found address family AF_INET.\n"); ++ saddr_len = sizeof(struct sockaddr_in); ++ sprintf(ipaddr_txt, "%d.%d.%d.%d:%d" ++ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF ++ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF ++ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF ++ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF ++ , ntohs(((struct sockaddr_in*)address)->sin_port)); ++ break; ++ case AF_INET6: ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_address_build: " ++ "found address family AF_INET6.\n"); ++ saddr_len = sizeof(struct sockaddr_in6); ++ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x" ++ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0]) ++ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1]) ++ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2]) ++ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3]) ++ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4]) ++ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5]) ++ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6]) ++ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7]) ++ , ntohs(((struct sockaddr_in6*)address)->sin6_port)); ++ break; ++ default: ++ ERROR("pfkey_address_build: " ++ "address->sa_family=%d not supported.\n", ++ address->sa_family); ++ SENDERR(EPFNOSUPPORT); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_address_build: " ++ "found address=%s.\n", ++ ipaddr_txt); ++ if(prefixlen != 0) { ++ ERROR("pfkey_address_build: " ++ "address prefixes not supported yet.\n"); ++ SENDERR(EAFNOSUPPORT); /* not supported yet */ ++ } ++ ++ /* allocate some memory for the extension */ ++ pfkey_address = (struct sadb_address*) ++ MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)); ++ *pfkey_ext = (struct sadb_ext*)pfkey_address; ++ ++ if(pfkey_address == NULL ) { ++ ERROR("pfkey_lifetime_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ memset(pfkey_address, ++ 0, ++ ALIGN_N(sizeof(struct sadb_address) + saddr_len, ++ IPSEC_PFKEYv2_ALIGN)); ++ ++ pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len, ++ IPSEC_PFKEYv2_ALIGN); ++ ++ pfkey_address->sadb_address_exttype = exttype; ++ pfkey_address->sadb_address_proto = proto; ++ pfkey_address->sadb_address_prefixlen = prefixlen; ++ pfkey_address->sadb_address_reserved = 0; ++ ++ memcpy((char*)pfkey_address + sizeof(struct sadb_address), ++ address, ++ saddr_len); ++ ++#if 0 ++ for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) { ++ pfkey_address_s_ska.sin_zero[i] = 0; ++ } ++#endif ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_address_build: " ++ "successful created len: %d.\n", pfkey_address->sadb_address_len); ++ ++ errlab: ++ return error; ++} ++ ++int ++pfkey_key_build(struct sadb_ext** pfkey_ext, ++ uint16_t exttype, ++ uint16_t key_bits, ++ char* key) ++{ ++ int error = 0; ++ struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext; ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_key_build:\n"); ++ /* sanity checks... */ ++ if(pfkey_key) { ++ ERROR("pfkey_key_build: " ++ "why is pfkey_key already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(!key_bits) { ++ ERROR("pfkey_key_build: " ++ "key_bits is zero, it must be non-zero.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) { ++ ERROR("pfkey_key_build: " ++ "unsupported extension type=%d.\n", ++ exttype); ++ SENDERR(EINVAL); ++ } ++ ++ if(!(*pfkey_ext = (struct sadb_ext*) ++ pfkey_key = (struct sadb_key*) ++ MALLOC(sizeof(struct sadb_key) + ++ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN))) { ++ ERROR("pfkey_key_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ memset(pfkey_key, ++ 0, ++ sizeof(struct sadb_key) + ++ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN); ++ ++ pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits, ++ 64); ++ pfkey_key->sadb_key_exttype = exttype; ++ pfkey_key->sadb_key_bits = key_bits; ++ pfkey_key->sadb_key_reserved = 0; ++ memcpy((char*)pfkey_key + sizeof(struct sadb_key), ++ key, ++ DIVUP(key_bits, 8)); ++ ++errlab: ++ return error; ++} ++ ++int ++pfkey_ident_build(struct sadb_ext** pfkey_ext, ++ uint16_t exttype, ++ uint16_t ident_type, ++ uint64_t ident_id, ++ uint8_t ident_len, ++ char* ident_string) ++{ ++ int error = 0; ++ struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext; ++ int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_ident_build:\n"); ++ /* sanity checks... */ ++ if(pfkey_ident) { ++ ERROR("pfkey_ident_build: " ++ "why is pfkey_ident already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if( ! ((exttype == SADB_EXT_IDENTITY_SRC) || ++ (exttype == SADB_EXT_IDENTITY_DST))) { ++ ERROR("pfkey_ident_build: " ++ "unsupported extension type=%d.\n", ++ exttype); ++ SENDERR(EINVAL); ++ } ++ ++ if((ident_type == SADB_IDENTTYPE_RESERVED)) { ++ ERROR("pfkey_ident_build: " ++ "ident_type must be non-zero.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(ident_type > SADB_IDENTTYPE_MAX) { ++ ERROR("pfkey_ident_build: " ++ "identtype=%d out of range.\n", ++ ident_type); ++ SENDERR(EINVAL); ++ } ++ ++ if(((ident_type == SADB_IDENTTYPE_PREFIX) || ++ (ident_type == SADB_IDENTTYPE_FQDN)) && ++ !ident_string) { ++ ERROR("pfkey_ident_build: " ++ "string required to allocate size of extension.\n"); ++ SENDERR(EINVAL); ++ } ++ ++#if 0 ++ if((ident_type == SADB_IDENTTYPE_USERFQDN) ) { ++ } ++#endif ++ ++ if(!(*pfkey_ext = (struct sadb_ext*) ++ pfkey_ident = (struct sadb_ident*) ++ MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN))) { ++ ERROR("pfkey_ident_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN); ++ ++ pfkey_ident->sadb_ident_len = ident_len; ++ pfkey_ident->sadb_ident_exttype = exttype; ++ pfkey_ident->sadb_ident_type = ident_type; ++ pfkey_ident->sadb_ident_reserved = 0; ++ pfkey_ident->sadb_ident_id = ident_id; ++ memcpy((char*)pfkey_ident + sizeof(struct sadb_ident), ++ ident_string, ++ data_len); ++ ++errlab: ++ return error; ++} ++ ++int ++pfkey_sens_build(struct sadb_ext** pfkey_ext, ++ uint32_t dpd, ++ uint8_t sens_level, ++ uint8_t sens_len, ++ uint64_t* sens_bitmap, ++ uint8_t integ_level, ++ uint8_t integ_len, ++ uint64_t* integ_bitmap) ++{ ++ int error = 0; ++ struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext; ++ int i; ++ uint64_t* bitmap; ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_sens_build:\n"); ++ /* sanity checks... */ ++ if(pfkey_sens) { ++ ERROR("pfkey_sens_build: " ++ "why is pfkey_sens already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_sens_build: " ++ "Sorry, I can't build exttype=%d yet.\n", ++ (*pfkey_ext)->sadb_ext_type); ++ SENDERR(EINVAL); /* don't process these yet */ ++ ++ if(!(*pfkey_ext = (struct sadb_ext*) ++ pfkey_sens = (struct sadb_sens*) ++ MALLOC(sizeof(struct sadb_sens) + ++ (sens_len + integ_len) * sizeof(uint64_t)))) { ++ ERROR("pfkey_sens_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ memset(pfkey_sens, ++ 0, ++ sizeof(struct sadb_sens) + ++ (sens_len + integ_len) * sizeof(uint64_t)); ++ ++ pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) + ++ (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN; ++ pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY; ++ pfkey_sens->sadb_sens_dpd = dpd; ++ pfkey_sens->sadb_sens_sens_level = sens_level; ++ pfkey_sens->sadb_sens_sens_len = sens_len; ++ pfkey_sens->sadb_sens_integ_level = integ_level; ++ pfkey_sens->sadb_sens_integ_len = integ_len; ++ pfkey_sens->sadb_sens_reserved = 0; ++ ++ bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens)); ++ for(i = 0; i < sens_len; i++) { ++ *bitmap = sens_bitmap[i]; ++ bitmap++; ++ } ++ for(i = 0; i < integ_len; i++) { ++ *bitmap = integ_bitmap[i]; ++ bitmap++; ++ } ++ ++errlab: ++ return error; ++} ++ ++int ++pfkey_prop_build(struct sadb_ext** pfkey_ext, ++ uint8_t replay, ++ unsigned int comb_num, ++ struct sadb_comb* comb) ++{ ++ int error = 0; ++ int i; ++ struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext; ++ struct sadb_comb *combp; ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_prop_build:\n"); ++ /* sanity checks... */ ++ if(pfkey_prop) { ++ ERROR("pfkey_prop_build: " ++ "why is pfkey_prop already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(!(*pfkey_ext = (struct sadb_ext*) ++ pfkey_prop = (struct sadb_prop*) ++ MALLOC(sizeof(struct sadb_prop) + ++ comb_num * sizeof(struct sadb_comb)))) { ++ ERROR("pfkey_prop_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ memset(pfkey_prop, ++ 0, ++ sizeof(struct sadb_prop) + ++ comb_num * sizeof(struct sadb_comb)); ++ ++ pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) + ++ comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN; ++ ++ pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL; ++ pfkey_prop->sadb_prop_replay = replay; ++ ++ for(i=0; i<3; i++) { ++ pfkey_prop->sadb_prop_reserved[i] = 0; ++ } ++ ++ combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop)); ++ for(i = 0; i < comb_num; i++) { ++ memcpy (combp, &(comb[i]), sizeof(struct sadb_comb)); ++ combp++; ++ } ++ ++#if 0 ++ uint8_t sadb_comb_auth; ++ uint8_t sadb_comb_encrypt; ++ uint16_t sadb_comb_flags; ++ uint16_t sadb_comb_auth_minbits; ++ uint16_t sadb_comb_auth_maxbits; ++ uint16_t sadb_comb_encrypt_minbits; ++ uint16_t sadb_comb_encrypt_maxbits; ++ uint32_t sadb_comb_reserved; ++ uint32_t sadb_comb_soft_allocations; ++ uint32_t sadb_comb_hard_allocations; ++ uint64_t sadb_comb_soft_bytes; ++ uint64_t sadb_comb_hard_bytes; ++ uint64_t sadb_comb_soft_addtime; ++ uint64_t sadb_comb_hard_addtime; ++ uint64_t sadb_comb_soft_usetime; ++ uint64_t sadb_comb_hard_usetime; ++ uint32_t sadb_comb_soft_packets; ++ uint32_t sadb_comb_hard_packets; ++#endif ++errlab: ++ return error; ++} ++ ++int ++pfkey_supported_build(struct sadb_ext** pfkey_ext, ++ uint16_t exttype, ++ unsigned int alg_num, ++ struct sadb_alg* alg) ++{ ++ int error = 0; ++ unsigned int i; ++ struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext; ++ struct sadb_alg *pfkey_alg; ++ ++ /* sanity checks... */ ++ if(pfkey_supported) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_supported_build: " ++ "why is pfkey_supported already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_supported_build: " ++ "unsupported extension type=%d.\n", ++ exttype); ++ SENDERR(EINVAL); ++ } ++ ++ if(!(*pfkey_ext = (struct sadb_ext*) ++ pfkey_supported = (struct sadb_supported*) ++ MALLOC(sizeof(struct sadb_supported) + ++ alg_num * ++ sizeof(struct sadb_alg)))) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_supported_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ memset(pfkey_supported, ++ 0, ++ sizeof(struct sadb_supported) + ++ alg_num * ++ sizeof(struct sadb_alg)); ++ ++ pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) + ++ alg_num * ++ sizeof(struct sadb_alg)) / ++ IPSEC_PFKEYv2_ALIGN; ++ pfkey_supported->sadb_supported_exttype = exttype; ++ pfkey_supported->sadb_supported_reserved = 0; ++ ++ pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported)); ++ for(i = 0; i < alg_num; i++) { ++ memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg)); ++ pfkey_alg->sadb_alg_reserved = 0; ++ pfkey_alg++; ++ } ++ ++#if 0 ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_supported_build: " ++ "Sorry, I can't build exttype=%d yet.\n", ++ (*pfkey_ext)->sadb_ext_type); ++ SENDERR(EINVAL); /* don't process these yet */ ++ ++ uint8_t sadb_alg_id; ++ uint8_t sadb_alg_ivlen; ++ uint16_t sadb_alg_minbits; ++ uint16_t sadb_alg_maxbits; ++ uint16_t sadb_alg_reserved; ++#endif ++errlab: ++ return error; ++} ++ ++int ++pfkey_spirange_build(struct sadb_ext** pfkey_ext, ++ uint16_t exttype, ++ uint32_t min, /* in network order */ ++ uint32_t max) /* in network order */ ++{ ++ int error = 0; ++ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext; ++ ++ /* sanity checks... */ ++ if(pfkey_spirange) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_spirange_build: " ++ "why is pfkey_spirange already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(ntohl(max) < ntohl(min)) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_spirange_build: " ++ "minspi=%08x must be < maxspi=%08x.\n", ++ ntohl(min), ++ ntohl(max)); ++ SENDERR(EINVAL); ++ } ++ ++ if(ntohl(min) <= 255) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_spirange_build: " ++ "minspi=%08x must be > 255.\n", ++ ntohl(min)); ++ SENDERR(EEXIST); ++ } ++ ++ if(!(*pfkey_ext = (struct sadb_ext*) ++ pfkey_spirange = (struct sadb_spirange*) ++ MALLOC(sizeof(struct sadb_spirange)))) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_spirange_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ memset(pfkey_spirange, ++ 0, ++ sizeof(struct sadb_spirange)); ++ ++ pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN; ++ ++ pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE; ++ pfkey_spirange->sadb_spirange_min = min; ++ pfkey_spirange->sadb_spirange_max = max; ++ pfkey_spirange->sadb_spirange_reserved = 0; ++ errlab: ++ return error; ++} ++ ++int ++pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext) ++{ ++ int error = 0; ++ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext; ++ ++ /* sanity checks... */ ++ if(pfkey_x_kmprivate) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_kmprivate_build: " ++ "why is pfkey_x_kmprivate already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0; ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_kmprivate_build: " ++ "Sorry, I can't build exttype=%d yet.\n", ++ (*pfkey_ext)->sadb_ext_type); ++ SENDERR(EINVAL); /* don't process these yet */ ++ ++ if(!(*pfkey_ext = (struct sadb_ext*) ++ pfkey_x_kmprivate = (struct sadb_x_kmprivate*) ++ MALLOC(sizeof(struct sadb_x_kmprivate)))) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_kmprivate_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ memset(pfkey_x_kmprivate, ++ 0, ++ sizeof(struct sadb_x_kmprivate)); ++ ++ pfkey_x_kmprivate->sadb_x_kmprivate_len = ++ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN; ++ ++ pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE; ++ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0; ++errlab: ++ return error; ++} ++ ++int ++pfkey_x_satype_build(struct sadb_ext** pfkey_ext, ++ uint8_t satype) ++{ ++ int error = 0; ++ int i; ++ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext; ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_satype_build:\n"); ++ /* sanity checks... */ ++ if(pfkey_x_satype) { ++ ERROR("pfkey_x_satype_build: " ++ "why is pfkey_x_satype already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(!satype) { ++ ERROR("pfkey_x_satype_build: " ++ "SA type not set, must be non-zero.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(satype > SADB_SATYPE_MAX) { ++ ERROR("pfkey_x_satype_build: " ++ "satype %d > max %d\n", ++ satype, SADB_SATYPE_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_satype = (struct sadb_x_satype*) ++ MALLOC(sizeof(struct sadb_x_satype)))) { ++ ERROR("pfkey_x_satype_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ memset(pfkey_x_satype, ++ 0, ++ sizeof(struct sadb_x_satype)); ++ ++ pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN; ++ ++ pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2; ++ pfkey_x_satype->sadb_x_satype_satype = satype; ++ for(i=0; i<3; i++) { ++ pfkey_x_satype->sadb_x_satype_reserved[i] = 0; ++ } ++ ++errlab: ++ return error; ++} ++ ++int ++pfkey_x_debug_build(struct sadb_ext** pfkey_ext, ++ uint32_t tunnel, ++ uint32_t netlink, ++ uint32_t xform, ++ uint32_t eroute, ++ uint32_t spi, ++ uint32_t radij, ++ uint32_t esp, ++ uint32_t ah, ++ uint32_t rcv, ++ uint32_t pfkey, ++ uint32_t ipcomp, ++ uint32_t verbose) ++{ ++ int error = 0; ++ int i; ++ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext; ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_debug_build:\n"); ++ /* sanity checks... */ ++ if(pfkey_x_debug) { ++ ERROR("pfkey_x_debug_build: " ++ "why is pfkey_x_debug already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_debug_build: " ++ "tunnel=%x netlink=%x xform=%x eroute=%x spi=%x radij=%x esp=%x ah=%x rcv=%x pfkey=%x ipcomp=%x verbose=%x?\n", ++ tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose); ++ ++ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_debug = (struct sadb_x_debug*) ++ MALLOC(sizeof(struct sadb_x_debug)))) { ++ ERROR("pfkey_x_debug_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++#if 0 ++ memset(pfkey_x_debug, ++ 0, ++ sizeof(struct sadb_x_debug)); ++#endif ++ ++ pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN; ++ pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG; ++ ++ pfkey_x_debug->sadb_x_debug_tunnel = tunnel; ++ pfkey_x_debug->sadb_x_debug_netlink = netlink; ++ pfkey_x_debug->sadb_x_debug_xform = xform; ++ pfkey_x_debug->sadb_x_debug_eroute = eroute; ++ pfkey_x_debug->sadb_x_debug_spi = spi; ++ pfkey_x_debug->sadb_x_debug_radij = radij; ++ pfkey_x_debug->sadb_x_debug_esp = esp; ++ pfkey_x_debug->sadb_x_debug_ah = ah; ++ pfkey_x_debug->sadb_x_debug_rcv = rcv; ++ pfkey_x_debug->sadb_x_debug_pfkey = pfkey; ++ pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp; ++ pfkey_x_debug->sadb_x_debug_verbose = verbose; ++ ++ for(i=0; i<4; i++) { ++ pfkey_x_debug->sadb_x_debug_reserved[i] = 0; ++ } ++ ++errlab: ++ return error; ++} ++ ++int ++pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext, ++ uint8_t type) ++{ ++ int error = 0; ++ int i; ++ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext; ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_nat_t_type_build:\n"); ++ /* sanity checks... */ ++ if(pfkey_x_nat_t_type) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_nat_t_type_build: " ++ "why is pfkey_x_nat_t_type already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_nat_t_type_build: " ++ "type=%d\n", type); ++ ++ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*) ++ MALLOC(sizeof(struct sadb_x_nat_t_type)))) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_nat_t_type_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ ++ pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN; ++ pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; ++ pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type; ++ for(i=0; i<3; i++) { ++ pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0; ++ } ++ ++errlab: ++ return error; ++} ++int ++pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext, ++ uint16_t exttype, ++ uint16_t port) ++{ ++ int error = 0; ++ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext; ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_nat_t_port_build:\n"); ++ /* sanity checks... */ ++ if(pfkey_x_nat_t_port) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_nat_t_port_build: " ++ "why is pfkey_x_nat_t_port already pointing to something?\n"); ++ SENDERR(EINVAL); ++ } ++ ++ switch(exttype) { ++ case SADB_X_EXT_NAT_T_SPORT: ++ case SADB_X_EXT_NAT_T_DPORT: ++ break; ++ default: ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_nat_t_port_build: " ++ "unrecognised ext_type=%d.\n", ++ exttype); ++ SENDERR(EINVAL); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_nat_t_port_build: " ++ "ext=%d, port=%d\n", exttype, port); ++ ++ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*) ++ MALLOC(sizeof(struct sadb_x_nat_t_port)))) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_x_nat_t_port_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ ++ pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN; ++ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype; ++ pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port; ++ pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0; ++ ++errlab: ++ return error; ++} ++ ++int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext, ++ uint8_t protocol) ++{ ++ int error = 0; ++ struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext; ++ DEBUGGING(PF_KEY_DEBUG_BUILD,"pfkey_x_protocol_build: protocol=%u\n", protocol); ++ /* sanity checks... */ ++ if (p != 0) { ++ ERROR("pfkey_x_protocol_build: bogus protocol pointer\n"); ++ SENDERR(EINVAL); ++ } ++ if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) { ++ ERROR("pfkey_build: memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ *pfkey_ext = (struct sadb_ext *)p; ++ p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t); ++ p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL; ++ p->sadb_protocol_proto = protocol; ++ p->sadb_protocol_flags = 0; ++ p->sadb_protocol_reserved2 = 0; ++ errlab: ++ return error; ++} ++ ++ ++#if I_DONT_THINK_THIS_WILL_BE_USEFUL ++int (*ext_default_builders[SADB_EXT_MAX +1])(struct sadb_msg*, struct sadb_ext*) ++ = ++{ ++ NULL, /* pfkey_msg_build, */ ++ pfkey_sa_build, ++ pfkey_lifetime_build, ++ pfkey_lifetime_build, ++ pfkey_lifetime_build, ++ pfkey_address_build, ++ pfkey_address_build, ++ pfkey_address_build, ++ pfkey_key_build, ++ pfkey_key_build, ++ pfkey_ident_build, ++ pfkey_ident_build, ++ pfkey_sens_build, ++ pfkey_prop_build, ++ pfkey_supported_build, ++ pfkey_supported_build, ++ pfkey_spirange_build, ++ pfkey_x_kmprivate_build, ++ pfkey_x_satype_build, ++ pfkey_sa_build, ++ pfkey_address_build, ++ pfkey_address_build, ++ pfkey_address_build, ++ pfkey_address_build, ++ pfkey_address_build, ++ pfkey_x_ext_debug_build ++}; ++#endif ++ ++int ++pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir) ++{ ++ int error = 0; ++ unsigned ext; ++ unsigned total_size; ++ struct sadb_ext *pfkey_ext; ++ int extensions_seen = 0; ++#ifndef __KERNEL__ ++ struct sadb_ext *extensions_check[SADB_EXT_MAX + 1]; ++#endif ++ ++ if(!extensions[0]) { ++ ERROR("pfkey_msg_build: " ++ "extensions[0] must be specified (struct sadb_msg).\n"); ++ SENDERR(EINVAL); ++ } ++ ++ /* figure out the total size for all the requested extensions */ ++ total_size = IPSEC_PFKEYv2_WORDS(sizeof(struct sadb_msg)); ++ for(ext = 1; ext <= SADB_EXT_MAX; ext++) { ++ if(extensions[ext]) { ++ total_size += (extensions[ext])->sadb_ext_len; ++ } ++ } ++ ++ /* allocate that much space */ ++ *pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN); ++ if(*pfkey_msg == NULL) { ++ ERROR("pfkey_msg_build: " ++ "memory allocation failed\n"); ++ SENDERR(ENOMEM); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_msg_build: " ++ "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n", ++ *pfkey_msg, ++ (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN), ++ &(extensions[0])); ++ ++ memcpy(*pfkey_msg, ++ extensions[0], ++ sizeof(struct sadb_msg)); ++ (*pfkey_msg)->sadb_msg_len = total_size; ++ (*pfkey_msg)->sadb_msg_reserved = 0; ++ extensions_seen = 1 ; ++ ++ /* ++ * point pfkey_ext to immediately after the space for the header, ++ * i.e. at the first extension location. ++ */ ++ pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg)); ++ ++ for(ext = 1; ext <= SADB_EXT_MAX; ext++) { ++ /* copy from extension[ext] to buffer */ ++ if(extensions[ext]) { ++ /* Is this type of extension permitted for this type of message? */ ++ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] & ++ 1<sadb_msg_type], ++ 1<sadb_ext_len * IPSEC_PFKEYv2_ALIGN), ++ ext, ++ extensions[ext]->sadb_ext_type); ++ ++ memcpy(pfkey_ext, ++ extensions[ext], ++ (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN); ++ ((char*)pfkey_ext) += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN; ++ /* Mark that we have seen this extension and remember the header location */ ++ extensions_seen |= ( 1 << ext ); ++ } ++ } ++ ++ /* check required extensions */ ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_msg_build: " ++ "extensions permitted=%08x, seen=%08x, required=%08x.\n", ++ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type], ++ extensions_seen, ++ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]); ++ ++ if((extensions_seen & ++ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) != ++ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) { ++ DEBUGGING(PF_KEY_DEBUG_BUILD, ++ "pfkey_msg_build: " ++ "required extensions missing:%08x.\n", ++ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] - ++ (extensions_seen & ++ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) ); ++ SENDERR(EINVAL); ++ } ++ ++#ifndef __KERNEL__ ++/* ++ * this is silly, there is no need to reparse the message that we just built. ++ * ++ */ ++ if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) { ++ ERROR( ++ "pfkey_msg_build: " ++ "Trouble parsing newly built pfkey message, error=%d.\n", ++ error); ++ SENDERR(-error); ++ } ++#endif ++ ++errlab: ++ ++ return error; ++} ++ ++/* ++ * $Log: pfkey_v2_build.c,v $ ++ * Revision 1.49 2004/04/12 02:59:06 mcr ++ * erroneously moved pfkey_v2_build.c ++ * ++ * Revision 1.48 2004/04/09 18:00:40 mcr ++ * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v ++ * ++ * Revision 1.47 2004/03/08 01:59:08 ken ++ * freeswan.h -> openswan.h ++ * ++ * Revision 1.46 2003/12/10 01:20:19 mcr ++ * NAT-traversal patches to KLIPS. ++ * ++ * Revision 1.45 2003/12/04 23:01:12 mcr ++ * removed ipsec_netlink.h ++ * ++ * Revision 1.44 2003/10/31 02:27:12 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.43.4.2 2003/10/29 01:11:32 mcr ++ * added debugging for pfkey library. ++ * ++ * Revision 1.43.4.1 2003/09/21 13:59:44 mcr ++ * pre-liminary X.509 patch - does not yet pass tests. ++ * ++ * Revision 1.43 2003/05/07 17:29:17 mcr ++ * new function pfkey_debug_func added for us in debugging from ++ * pfkey library. ++ * ++ * Revision 1.42 2003/01/30 02:32:09 rgb ++ * ++ * Rename SAref table macro names for clarity. ++ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. ++ * ++ * Revision 1.41 2002/12/13 18:16:02 mcr ++ * restored sa_ref code ++ * ++ * Revision 1.40 2002/12/13 18:06:52 mcr ++ * temporarily removed sadb_x_sa_ref reference for 2.xx ++ * ++ * Revision 1.39 2002/12/13 17:43:28 mcr ++ * commented out access to sadb_x_sa_ref for 2.xx branch ++ * ++ * Revision 1.38 2002/10/09 03:12:05 dhr ++ * ++ * [kenb+dhr] 64-bit fixes ++ * ++ * Revision 1.37 2002/09/20 15:40:39 rgb ++ * Added new function pfkey_sa_ref_build() to accomodate saref parameter. ++ * ++ * Revision 1.36 2002/09/20 05:01:22 rgb ++ * Generalise for platform independance: fix (ia64) using unsigned for sizes. ++ * ++ * Revision 1.35 2002/07/24 18:44:54 rgb ++ * Type fiddling to tame ia64 compiler. ++ * ++ * Revision 1.34 2002/05/23 07:14:11 rgb ++ * Cleaned up %p variants to 0p%p for test suite cleanup. ++ * ++ * Revision 1.33 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.32 2002/04/24 07:36:40 mcr ++ * Moved from ./lib/pfkey_v2_build.c,v ++ * ++ * Revision 1.31 2002/01/29 22:25:35 rgb ++ * Re-add ipsec_kversion.h to keep MALLOC happy. ++ * ++ * Revision 1.30 2002/01/29 01:59:09 mcr ++ * removal of kversions.h - sources that needed it now use ipsec_param.h. ++ * updating of IPv6 structures to match latest in6.h version. ++ * removed dead code from openswan.h that also duplicated kversions.h ++ * code. ++ * ++ * Revision 1.29 2001/12/19 21:06:09 rgb ++ * Added port numbers to pfkey_address_build() debugging. ++ * ++ * Revision 1.28 2001/11/06 19:47:47 rgb ++ * Added packet parameter to lifetime and comb structures. ++ * ++ * Revision 1.27 2001/10/18 04:45:24 rgb ++ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, ++ * lib/openswan.h version macros moved to lib/kversions.h. ++ * Other compiler directive cleanups. ++ * ++ * Revision 1.26 2001/09/08 21:13:34 rgb ++ * Added pfkey ident extension support for ISAKMPd. (NetCelo) ++ * ++ * Revision 1.25 2001/06/14 19:35:16 rgb ++ * Update copyright date. ++ * ++ * Revision 1.24 2001/03/20 03:49:45 rgb ++ * Ditch superfluous debug_pfkey declaration. ++ * Move misplaced openswan.h inclusion for kernel case. ++ * ++ * Revision 1.23 2001/03/16 07:41:50 rgb ++ * Put openswan.h include before pluto includes. ++ * ++ * Revision 1.22 2001/02/27 22:24:56 rgb ++ * Re-formatting debug output (line-splitting, joining, 1arg/line). ++ * Check for satoa() return codes. ++ * ++ * Revision 1.21 2000/11/17 18:10:30 rgb ++ * Fixed bugs mostly relating to spirange, to treat all spi variables as ++ * network byte order since this is the way PF_KEYv2 stored spis. ++ * ++ * Revision 1.20 2000/10/12 00:02:39 rgb ++ * Removed 'format, ##' nonsense from debug macros for RH7.0. ++ * ++ * Revision 1.19 2000/10/10 20:10:20 rgb ++ * Added support for debug_ipcomp and debug_verbose to klipsdebug. ++ * ++ * Revision 1.18 2000/09/12 18:59:54 rgb ++ * Added Gerhard's IPv6 support to pfkey parts of libopenswan. ++ * ++ * Revision 1.17 2000/09/12 03:27:00 rgb ++ * Moved DEBUGGING definition to compile kernel with debug off. ++ * ++ * Revision 1.16 2000/09/08 19:22:12 rgb ++ * Fixed pfkey_prop_build() parameter to be only single indirection. ++ * Fixed struct alg copy. ++ * ++ * Revision 1.15 2000/08/20 21:40:01 rgb ++ * Added an address parameter sanity check to pfkey_address_build(). ++ * ++ * Revision 1.14 2000/08/15 17:29:23 rgb ++ * Fixes from SZI to untested pfkey_prop_build(). ++ * ++ * Revision 1.13 2000/06/02 22:54:14 rgb ++ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support. ++ * ++ * Revision 1.12 2000/05/10 19:24:01 rgb ++ * Fleshed out sensitivity, proposal and supported extensions. ++ * ++ * Revision 1.11 2000/03/16 14:07:23 rgb ++ * Renamed ALIGN macro to avoid fighting with others in kernel. ++ * ++ * Revision 1.10 2000/01/24 21:14:35 rgb ++ * Added disabled pluto pfkey lib debug flag. ++ * ++ * Revision 1.9 2000/01/21 06:27:32 rgb ++ * Added address cases for eroute flows. ++ * Removed unused code. ++ * Dropped unused argument to pfkey_x_satype_build(). ++ * Indented compiler directives for readability. ++ * Added klipsdebug switching capability. ++ * Fixed SADB_EXT_MAX bug not permitting last extension access. ++ * ++ * Revision 1.8 1999/12/29 21:17:41 rgb ++ * Changed pfkey_msg_build() I/F to include a struct sadb_msg** ++ * parameter for cleaner manipulation of extensions[] and to guard ++ * against potential memory leaks. ++ * Changed the I/F to pfkey_msg_free() for the same reason. ++ * ++ * Revision 1.7 1999/12/09 23:12:20 rgb ++ * Removed unused cruft. ++ * Added argument to pfkey_sa_build() to do eroutes. ++ * Fixed exttype check in as yet unused pfkey_lifetime_build(). ++ * ++ * Revision 1.6 1999/12/07 19:54:29 rgb ++ * Removed static pluto debug flag. ++ * Added functions for pfkey message and extensions initialisation ++ * and cleanup. ++ * ++ * Revision 1.5 1999/12/01 22:20:06 rgb ++ * Changed pfkey_sa_build to accept an SPI in network byte order. ++ * Added to quiet userspace compiler. ++ * Moved pfkey_lib_debug variable into the library. ++ * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work. ++ * Added extension assembly debugging. ++ * Isolated assignment with brackets to be sure of scope. ++ * ++ * Revision 1.4 1999/11/27 11:57:35 rgb ++ * Added ipv6 headers. ++ * Remove over-zealous algorithm sanity checkers from pfkey_sa_build. ++ * Debugging error messages added. ++ * Fixed missing auth and encrypt assignment bug. ++ * Add argument to pfkey_msg_parse() for direction. ++ * Move parse-after-build check inside pfkey_msg_build(). ++ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. ++ * Add CVS log entry to bottom of file. ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/pfkey_v2_debug.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,176 @@ ++/* ++ * @(#) pfkey version 2 debugging messages ++ * ++ * Copyright (C) 2001 Richard Guy Briggs ++ * and Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: pfkey_v2_debug.c,v 1.9 2004/03/08 01:59:08 ken Exp $ ++ * ++ */ ++ ++#ifdef __KERNEL__ ++ ++# include /* for printk */ ++ ++# include "openswan/ipsec_kversion.h" /* for malloc switch */ ++# ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++# else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++# endif /* MALLOC_SLAB */ ++# include /* error codes */ ++# include /* size_t */ ++# include /* mark_bh */ ++ ++# include /* struct device, and other headers */ ++# include /* eth_type_trans */ ++extern int debug_pfkey; ++ ++#else /* __KERNEL__ */ ++ ++# include ++# include ++# include ++ ++#endif /* __KERNEL__ */ ++ ++#include "openswan.h" ++#include "pfkeyv2.h" ++#include "pfkey.h" ++ ++/* ++ * This file provides ASCII translations of PF_KEY magic numbers. ++ * ++ */ ++ ++static char *pfkey_sadb_ext_strings[]={ ++ "reserved", /* SADB_EXT_RESERVED 0 */ ++ "security-association", /* SADB_EXT_SA 1 */ ++ "lifetime-current", /* SADB_EXT_LIFETIME_CURRENT 2 */ ++ "lifetime-hard", /* SADB_EXT_LIFETIME_HARD 3 */ ++ "lifetime-soft", /* SADB_EXT_LIFETIME_SOFT 4 */ ++ "source-address", /* SADB_EXT_ADDRESS_SRC 5 */ ++ "destination-address", /* SADB_EXT_ADDRESS_DST 6 */ ++ "proxy-address", /* SADB_EXT_ADDRESS_PROXY 7 */ ++ "authentication-key", /* SADB_EXT_KEY_AUTH 8 */ ++ "cipher-key", /* SADB_EXT_KEY_ENCRYPT 9 */ ++ "source-identity", /* SADB_EXT_IDENTITY_SRC 10 */ ++ "destination-identity", /* SADB_EXT_IDENTITY_DST 11 */ ++ "sensitivity-label", /* SADB_EXT_SENSITIVITY 12 */ ++ "proposal", /* SADB_EXT_PROPOSAL 13 */ ++ "supported-auth", /* SADB_EXT_SUPPORTED_AUTH 14 */ ++ "supported-cipher", /* SADB_EXT_SUPPORTED_ENCRYPT 15 */ ++ "spi-range", /* SADB_EXT_SPIRANGE 16 */ ++ "X-kmpprivate", /* SADB_X_EXT_KMPRIVATE 17 */ ++ "X-satype2", /* SADB_X_EXT_SATYPE2 18 */ ++ "X-security-association", /* SADB_X_EXT_SA2 19 */ ++ "X-destination-address2", /* SADB_X_EXT_ADDRESS_DST2 20 */ ++ "X-source-flow-address", /* SADB_X_EXT_ADDRESS_SRC_FLOW 21 */ ++ "X-dest-flow-address", /* SADB_X_EXT_ADDRESS_DST_FLOW 22 */ ++ "X-source-mask", /* SADB_X_EXT_ADDRESS_SRC_MASK 23 */ ++ "X-dest-mask", /* SADB_X_EXT_ADDRESS_DST_MASK 24 */ ++ "X-set-debug", /* SADB_X_EXT_DEBUG 25 */ ++#ifdef NAT_TRAVERSAL ++ "X-NAT-T-type", /* SADB_X_EXT_NAT_T_TYPE 26 */ ++ "X-NAT-T-sport", /* SADB_X_EXT_NAT_T_SPORT 27 */ ++ "X-NAT-T-dport", /* SADB_X_EXT_NAT_T_DPORT 28 */ ++ "X-NAT-T-OA", /* SADB_X_EXT_NAT_T_OA 29 */ ++#endif ++}; ++ ++const char * ++pfkey_v2_sadb_ext_string(int ext) ++{ ++ if(ext <= SADB_EXT_MAX) { ++ return pfkey_sadb_ext_strings[ext]; ++ } else { ++ return "unknown-ext"; ++ } ++} ++ ++ ++static char *pfkey_sadb_type_strings[]={ ++ "reserved", /* SADB_RESERVED */ ++ "getspi", /* SADB_GETSPI */ ++ "update", /* SADB_UPDATE */ ++ "add", /* SADB_ADD */ ++ "delete", /* SADB_DELETE */ ++ "get", /* SADB_GET */ ++ "acquire", /* SADB_ACQUIRE */ ++ "register", /* SADB_REGISTER */ ++ "expire", /* SADB_EXPIRE */ ++ "flush", /* SADB_FLUSH */ ++ "dump", /* SADB_DUMP */ ++ "x-promisc", /* SADB_X_PROMISC */ ++ "x-pchange", /* SADB_X_PCHANGE */ ++ "x-groupsa", /* SADB_X_GRPSA */ ++ "x-addflow(eroute)", /* SADB_X_ADDFLOW */ ++ "x-delflow(eroute)", /* SADB_X_DELFLOW */ ++ "x-debug", /* SADB_X_DEBUG */ ++}; ++ ++const char * ++pfkey_v2_sadb_type_string(int sadb_type) ++{ ++ if(sadb_type <= SADB_MAX) { ++ return pfkey_sadb_type_strings[sadb_type]; ++ } else { ++ return "unknown-sadb-type"; ++ } ++} ++ ++ ++ ++ ++/* ++ * $Log: pfkey_v2_debug.c,v $ ++ * Revision 1.9 2004/03/08 01:59:08 ken ++ * freeswan.h -> openswan.h ++ * ++ * Revision 1.8 2003/12/10 01:20:19 mcr ++ * NAT-traversal patches to KLIPS. ++ * ++ * Revision 1.7 2002/09/20 05:01:26 rgb ++ * Fixed limit inclusion error in both type and ext string conversion. ++ * ++ * Revision 1.6 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.5 2002/04/24 07:36:40 mcr ++ * Moved from ./lib/pfkey_v2_debug.c,v ++ * ++ * Revision 1.4 2002/01/29 22:25:36 rgb ++ * Re-add ipsec_kversion.h to keep MALLOC happy. ++ * ++ * Revision 1.3 2002/01/29 01:59:09 mcr ++ * removal of kversions.h - sources that needed it now use ipsec_param.h. ++ * updating of IPv6 structures to match latest in6.h version. ++ * removed dead code from openswan.h that also duplicated kversions.h ++ * code. ++ * ++ * Revision 1.2 2002/01/20 20:34:50 mcr ++ * added pfkey_v2_sadb_type_string to decode sadb_type to string. ++ * ++ * Revision 1.1 2001/11/27 05:30:06 mcr ++ * initial set of debug strings for pfkey debugging. ++ * this will eventually only be included for debug builds. ++ * ++ * Revision 1.1 2001/09/21 04:12:03 mcr ++ * first compilable version. ++ * ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/pfkey_v2_ext_bits.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,808 @@ ++/* ++ * RFC2367 PF_KEYv2 Key management API message parser ++ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: pfkey_v2_ext_bits.c,v 1.20 2004/03/08 01:59:08 ken Exp $ ++ */ ++ ++/* ++ * Template from klips/net/ipsec/ipsec/ipsec_parse.c. ++ */ ++ ++char pfkey_v2_ext_bits_c_version[] = "$Id: pfkey_v2_ext_bits.c,v 1.20 2004/03/08 01:59:08 ken Exp $"; ++ ++/* ++ * Some ugly stuff to allow consistent debugging code for use in the ++ * kernel and in user space ++*/ ++ ++#ifdef __KERNEL__ ++ ++# include /* for printk */ ++ ++# include "openswan/ipsec_kversion.h" /* for malloc switch */ ++# ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++# else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++# endif /* MALLOC_SLAB */ ++# include /* error codes */ ++# include /* size_t */ ++# include /* mark_bh */ ++ ++# include /* struct device, and other headers */ ++# include /* eth_type_trans */ ++# include /* struct iphdr */ ++# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++# include ++# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ ++ ++#else /* __KERNEL__ */ ++ ++# include ++# include ++# include ++#endif ++ ++#include ++#include ++#include ++ ++unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/] = { ++ ++/* INBOUND EXTENSIONS */ ++{ ++ ++/* PERMITTED IN */ ++{ ++/* SADB_RESERVED */ ++0 ++, ++/* SADB_GETSPI */ ++1< openswan.h ++ * ++ * Revision 1.19 2003/12/22 21:38:13 mcr ++ * removed extraenous #endif. ++ * ++ * Revision 1.18 2003/12/22 19:34:41 mcr ++ * added 0.6c NAT-T patch. ++ * ++ * Revision 1.17 2003/12/10 01:20:19 mcr ++ * NAT-traversal patches to KLIPS. ++ * ++ * Revision 1.16 2003/10/31 02:27:12 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.15.30.1 2003/09/21 13:59:44 mcr ++ * pre-liminary X.509 patch - does not yet pass tests. ++ * ++ * Revision 1.15 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.14 2002/04/24 07:36:40 mcr ++ * Moved from ./lib/pfkey_v2_ext_bits.c,v ++ * ++ * Revision 1.13 2002/01/29 22:25:36 rgb ++ * Re-add ipsec_kversion.h to keep MALLOC happy. ++ * ++ * Revision 1.12 2002/01/29 01:59:10 mcr ++ * removal of kversions.h - sources that needed it now use ipsec_param.h. ++ * updating of IPv6 structures to match latest in6.h version. ++ * removed dead code from openswan.h that also duplicated kversions.h ++ * code. ++ * ++ * Revision 1.11 2001/10/18 04:45:24 rgb ++ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, ++ * lib/openswan.h version macros moved to lib/kversions.h. ++ * Other compiler directive cleanups. ++ * ++ * Revision 1.10 2001/09/08 21:13:35 rgb ++ * Added pfkey ident extension support for ISAKMPd. (NetCelo) ++ * ++ * Revision 1.9 2001/06/14 19:35:16 rgb ++ * Update copyright date. ++ * ++ * Revision 1.8 2001/03/26 23:07:36 rgb ++ * Remove requirement for auth and enc key from UPDATE. ++ * ++ * Revision 1.7 2000/09/12 22:35:37 rgb ++ * Restructured to remove unused extensions from CLEARFLOW messages. ++ * ++ * Revision 1.6 2000/09/09 06:39:01 rgb ++ * Added comments for clarity. ++ * ++ * Revision 1.5 2000/06/02 22:54:14 rgb ++ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support. ++ * ++ * Revision 1.4 2000/01/21 06:27:56 rgb ++ * Added address cases for eroute flows. ++ * Added comments for each message type. ++ * Added klipsdebug switching capability. ++ * Fixed GRPSA bitfields. ++ * ++ * Revision 1.3 1999/12/01 22:20:27 rgb ++ * Remove requirement for a proxy address in an incoming getspi message. ++ * ++ * Revision 1.2 1999/11/27 11:57:06 rgb ++ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. ++ * Add CVS log entry to bottom of file. ++ * Cleaned out unused bits. ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/pfkey_v2_parse.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,1820 @@ ++/* ++ * RFC2367 PF_KEYv2 Key management API message parser ++ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: pfkey_v2_parse.c,v 1.59 2004/04/18 03:03:49 mcr Exp $ ++ */ ++ ++/* ++ * Template from klips/net/ipsec/ipsec/ipsec_parser.c. ++ */ ++ ++char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.59 2004/04/18 03:03:49 mcr Exp $"; ++ ++/* ++ * Some ugly stuff to allow consistent debugging code for use in the ++ * kernel and in user space ++*/ ++ ++#ifdef __KERNEL__ ++ ++# include /* for printk */ ++ ++#include "openswan/ipsec_kversion.h" /* for malloc switch */ ++ ++# ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++# else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++# endif /* MALLOC_SLAB */ ++# include /* error codes */ ++# include /* size_t */ ++# include /* mark_bh */ ++ ++# include /* struct device, and other headers */ ++# include /* eth_type_trans */ ++# include /* struct iphdr */ ++# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++# include /* struct ipv6hdr */ ++# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ ++extern int debug_pfkey; ++ ++# include ++ ++#include "openswan/ipsec_encap.h" ++ ++#else /* __KERNEL__ */ ++ ++# include ++# include ++# include ++ ++# include ++# include "constants.h" ++# include "programs/pluto/defs.h" /* for PRINTF_LIKE */ ++ ++#endif /* __KERNEL__ */ ++ ++ ++#include ++#include ++ ++#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */ ++ ++/* ++ * how to handle debugging for pfkey. ++ */ ++#include ++ ++unsigned int pfkey_lib_debug = PF_KEY_DEBUG_PARSE_NONE; ++void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1); ++void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1); ++ ++ ++#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) ++ ++struct satype_tbl { ++ uint8_t proto; ++ uint8_t satype; ++ char* name; ++} static satype_tbl[] = { ++#ifdef __KERNEL__ ++ { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" }, ++ { IPPROTO_AH, SADB_SATYPE_AH, "AH" }, ++ { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" }, ++#ifdef CONFIG_IPSEC_IPCOMP ++ { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" }, ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" }, ++#else /* __KERNEL__ */ ++ { SA_ESP, SADB_SATYPE_ESP, "ESP" }, ++ { SA_AH, SADB_SATYPE_AH, "AH" }, ++ { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" }, ++ { SA_COMP, SADB_X_SATYPE_COMP, "COMP" }, ++ { SA_INT, SADB_X_SATYPE_INT, "INT" }, ++#endif /* __KERNEL__ */ ++ { 0, 0, "UNKNOWN" } ++}; ++ ++uint8_t ++satype2proto(uint8_t satype) ++{ ++ int i =0; ++ ++ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) { ++ i++; ++ } ++ return satype_tbl[i].proto; ++} ++ ++uint8_t ++proto2satype(uint8_t proto) ++{ ++ int i = 0; ++ ++ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) { ++ i++; ++ } ++ return satype_tbl[i].satype; ++} ++ ++char* ++satype2name(uint8_t satype) ++{ ++ int i = 0; ++ ++ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) { ++ i++; ++ } ++ return satype_tbl[i].name; ++} ++ ++char* ++proto2name(uint8_t proto) ++{ ++ int i = 0; ++ ++ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) { ++ i++; ++ } ++ return satype_tbl[i].name; ++} ++ ++/* Default extension parsers taken from the KLIPS code */ ++ ++DEBUG_NO_STATIC int ++pfkey_sa_parse(struct sadb_ext *pfkey_ext) ++{ ++ int error = 0; ++ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext; ++#if 0 ++ struct sadb_sa sav2; ++#endif ++ ++ /* sanity checks... */ ++ if(!pfkey_sa) { ++ ERROR("pfkey_sa_parse: " ++ "NULL pointer passed in.\n"); ++ SENDERR(EINVAL); ++ } ++ ++#if 0 ++ /* check if this structure is short, and if so, fix it up. ++ * XXX this is NOT the way to do things. ++ */ ++ if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) { ++ ++ /* yes, so clear out a temporary structure, and copy first */ ++ memset(&sav2, 0, sizeof(sav2)); ++ memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1)); ++ sav2.sadb_x_sa_ref=-1; ++ sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN; ++ ++ pfkey_sa = &sav2; ++ } ++#endif ++ ++ ++ if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) { ++ ERROR( ++ "pfkey_sa_parse: " ++ "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n", ++ pfkey_sa->sadb_sa_len, ++ (int)sizeof(struct sadb_sa)); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) { ++ ERROR( ++ "pfkey_sa_parse: " ++ "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n", ++ pfkey_sa->sadb_sa_encrypt, ++ SADB_EALG_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) { ++ ERROR( ++ "pfkey_sa_parse: " ++ "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n", ++ pfkey_sa->sadb_sa_auth, ++ SADB_AALG_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) { ++ ERROR( ++ "pfkey_sa_parse: " ++ "state=%d exceeds MAX=%d.\n", ++ pfkey_sa->sadb_sa_state, ++ SADB_SASTATE_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) { ++ ERROR( ++ "pfkey_sa_parse: " ++ "state=%d is DEAD=%d.\n", ++ pfkey_sa->sadb_sa_state, ++ SADB_SASTATE_DEAD); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_sa->sadb_sa_replay > 64) { ++ ERROR( ++ "pfkey_sa_parse: " ++ "replay window size: %d -- must be 0 <= size <= 64\n", ++ pfkey_sa->sadb_sa_replay); ++ SENDERR(EINVAL); ++ } ++ ++ if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) || ++ (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2))) ++ { ++ ERROR( ++ "pfkey_sa_parse: " ++ "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n", ++ pfkey_sa->sadb_sa_exttype, ++ SADB_EXT_SA, ++ SADB_X_EXT_SA2); ++ SENDERR(EINVAL); ++ } ++ ++ if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) { ++ ERROR( ++ "pfkey_sa_parse: " ++ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n", ++ pfkey_sa->sadb_x_sa_ref, ++ IPSEC_SAREF_NULL, ++ IPSEC_SA_REF_TABLE_NUM_ENTRIES); ++ SENDERR(EINVAL); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, ++ "pfkey_sa_parse: " ++ "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n", ++ pfkey_sa->sadb_sa_len, ++ pfkey_sa->sadb_sa_exttype, ++ pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype), ++ (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi), ++ pfkey_sa->sadb_sa_replay, ++ pfkey_sa->sadb_sa_state, ++ pfkey_sa->sadb_sa_auth, ++ pfkey_sa->sadb_sa_encrypt, ++ pfkey_sa->sadb_sa_flags, ++ pfkey_sa->sadb_x_sa_ref); ++ ++ errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_lifetime_parse(struct sadb_ext *pfkey_ext) ++{ ++ int error = 0; ++ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext; ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, ++ "pfkey_lifetime_parse:enter\n"); ++ /* sanity checks... */ ++ if(!pfkey_lifetime) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_lifetime_parse: " ++ "NULL pointer passed in.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_lifetime->sadb_lifetime_len != ++ sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_lifetime_parse: " ++ "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n", ++ pfkey_lifetime->sadb_lifetime_len, ++ (int)sizeof(struct sadb_lifetime)); ++ SENDERR(EINVAL); ++ } ++ ++ if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) && ++ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) && ++ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_lifetime_parse: " ++ "unexpected ext_type=%d.\n", ++ pfkey_lifetime->sadb_lifetime_exttype); ++ SENDERR(EINVAL); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, ++ "pfkey_lifetime_parse: " ++ "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n", ++ pfkey_lifetime->sadb_lifetime_exttype, ++ pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype), ++ pfkey_lifetime->sadb_lifetime_allocations, ++ (unsigned)pfkey_lifetime->sadb_lifetime_bytes, ++ (unsigned)pfkey_lifetime->sadb_lifetime_addtime, ++ (unsigned)pfkey_lifetime->sadb_lifetime_usetime, ++ pfkey_lifetime->sadb_x_lifetime_packets); ++errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_address_parse(struct sadb_ext *pfkey_ext) ++{ ++ int error = 0; ++ int saddr_len = 0; ++ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext; ++ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address)); ++ char ipaddr_txt[ADDRTOT_BUF]; ++ ++ /* sanity checks... */ ++ if(!pfkey_address) { ++ ERROR( ++ "pfkey_address_parse: " ++ "NULL pointer passed in.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_address->sadb_address_len < ++ (sizeof(struct sadb_address) + sizeof(struct sockaddr))/ ++ IPSEC_PFKEYv2_ALIGN) { ++ ERROR("pfkey_address_parse: " ++ "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n", ++ pfkey_address->sadb_address_len, ++ (int)sizeof(struct sadb_address), ++ (int)sizeof(struct sockaddr)); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_address->sadb_address_reserved) { ++ ERROR("pfkey_address_parse: " ++ "res=%d, must be zero.\n", ++ pfkey_address->sadb_address_reserved); ++ SENDERR(EINVAL); ++ } ++ ++ switch(pfkey_address->sadb_address_exttype) { ++ case SADB_EXT_ADDRESS_SRC: ++ case SADB_EXT_ADDRESS_DST: ++ case SADB_EXT_ADDRESS_PROXY: ++ case SADB_X_EXT_ADDRESS_DST2: ++ case SADB_X_EXT_ADDRESS_SRC_FLOW: ++ case SADB_X_EXT_ADDRESS_DST_FLOW: ++ case SADB_X_EXT_ADDRESS_SRC_MASK: ++ case SADB_X_EXT_ADDRESS_DST_MASK: ++#ifdef NAT_TRAVERSAL ++ case SADB_X_EXT_NAT_T_OA: ++#endif ++ break; ++ default: ++ ERROR( ++ "pfkey_address_parse: " ++ "unexpected ext_type=%d.\n", ++ pfkey_address->sadb_address_exttype); ++ SENDERR(EINVAL); ++ } ++ ++ switch(s->sa_family) { ++ case AF_INET: ++ saddr_len = sizeof(struct sockaddr_in); ++ sprintf(ipaddr_txt, "%d.%d.%d.%d" ++ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF ++ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF ++ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF ++ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF); ++ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, ++ "pfkey_address_parse: " ++ "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n", ++ pfkey_address->sadb_address_exttype, ++ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype), ++ s->sa_family, ++ ipaddr_txt, ++ pfkey_address->sadb_address_proto, ++ ntohs(((struct sockaddr_in*)s)->sin_port)); ++ break; ++ case AF_INET6: ++ saddr_len = sizeof(struct sockaddr_in6); ++ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x" ++ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0]) ++ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1]) ++ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2]) ++ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3]) ++ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4]) ++ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5]) ++ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6]) ++ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7])); ++ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, ++ "pfkey_address_parse: " ++ "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n", ++ pfkey_address->sadb_address_exttype, ++ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype), ++ s->sa_family, ++ ipaddr_txt, ++ pfkey_address->sadb_address_proto, ++ ((struct sockaddr_in6*)s)->sin6_port); ++ break; ++ default: ++ ERROR( ++ "pfkey_address_parse: " ++ "s->sa_family=%d not supported.\n", ++ s->sa_family); ++ SENDERR(EPFNOSUPPORT); ++ } ++ ++ if(pfkey_address->sadb_address_len != ++ DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) { ++ ERROR( ++ "pfkey_address_parse: " ++ "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n", ++ pfkey_address->sadb_address_len, ++ (int)sizeof(struct sadb_address), ++ saddr_len); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_address->sadb_address_prefixlen != 0) { ++ ERROR( ++ "pfkey_address_parse: " ++ "address prefixes not supported yet.\n"); ++ SENDERR(EAFNOSUPPORT); /* not supported yet */ ++ } ++ ++ /* XXX check if port!=0 */ ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, ++ "pfkey_address_parse: successful.\n"); ++ errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_key_parse(struct sadb_ext *pfkey_ext) ++{ ++ int error = 0; ++ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext; ++ ++ /* sanity checks... */ ++ ++ if(!pfkey_key) { ++ ERROR( ++ "pfkey_key_parse: " ++ "NULL pointer passed in.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) { ++ ERROR( ++ "pfkey_key_parse: " ++ "size wrong ext_len=%d, key_ext_len=%d.\n", ++ pfkey_key->sadb_key_len, ++ (int)sizeof(struct sadb_key)); ++ SENDERR(EINVAL); ++ } ++ ++ if(!pfkey_key->sadb_key_bits) { ++ ERROR( ++ "pfkey_key_parse: " ++ "key length set to zero, must be non-zero.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_key->sadb_key_len != ++ DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits, ++ PFKEYBITS)) { ++ ERROR( ++ "pfkey_key_parse: " ++ "key length=%d does not agree with extension length=%d.\n", ++ pfkey_key->sadb_key_bits, ++ pfkey_key->sadb_key_len); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_key->sadb_key_reserved) { ++ ERROR( ++ "pfkey_key_parse: " ++ "res=%d, must be zero.\n", ++ pfkey_key->sadb_key_reserved); ++ SENDERR(EINVAL); ++ } ++ ++ if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) || ++ (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) { ++ ERROR( ++ "pfkey_key_parse: " ++ "expecting extension type AUTH or ENCRYPT, got %d.\n", ++ pfkey_key->sadb_key_exttype); ++ SENDERR(EINVAL); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, ++ "pfkey_key_parse: " ++ "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n", ++ pfkey_key->sadb_key_len, ++ pfkey_key->sadb_key_exttype, ++ pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype), ++ pfkey_key->sadb_key_bits, ++ pfkey_key->sadb_key_reserved); ++ ++errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_ident_parse(struct sadb_ext *pfkey_ext) ++{ ++ int error = 0; ++ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext; ++ ++ /* sanity checks... */ ++ if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) { ++ ERROR( ++ "pfkey_ident_parse: " ++ "size wrong ext_len=%d, key_ext_len=%d.\n", ++ pfkey_ident->sadb_ident_len, ++ (int)sizeof(struct sadb_ident)); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) { ++ ERROR( ++ "pfkey_ident_parse: " ++ "ident_type=%d out of range, must be less than %d.\n", ++ pfkey_ident->sadb_ident_type, ++ SADB_IDENTTYPE_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_ident->sadb_ident_reserved) { ++ ERROR( ++ "pfkey_ident_parse: " ++ "res=%d, must be zero.\n", ++ pfkey_ident->sadb_ident_reserved); ++ SENDERR(EINVAL); ++ } ++ ++ /* string terminator/padding must be zero */ ++ if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) { ++ if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) { ++ ERROR( ++ "pfkey_ident_parse: " ++ "string padding must be zero, last is 0x%02x.\n", ++ *((char*)pfkey_ident + ++ pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)); ++ SENDERR(EINVAL); ++ } ++ } ++ ++ if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) || ++ (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) { ++ ERROR( ++ "pfkey_key_parse: " ++ "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n", ++ pfkey_ident->sadb_ident_exttype); ++ SENDERR(EINVAL); ++ } ++ ++errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_sens_parse(struct sadb_ext *pfkey_ext) ++{ ++ int error = 0; ++ struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext; ++ ++ /* sanity checks... */ ++ if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_sens_parse: " ++ "size wrong ext_len=%d, key_ext_len=%d.\n", ++ pfkey_sens->sadb_sens_len, ++ (int)sizeof(struct sadb_sens)); ++ SENDERR(EINVAL); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_sens_parse: " ++ "Sorry, I can't parse exttype=%d yet.\n", ++ pfkey_ext->sadb_ext_type); ++#if 0 ++ SENDERR(EINVAL); /* don't process these yet */ ++#endif ++ ++errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_prop_parse(struct sadb_ext *pfkey_ext) ++{ ++ int error = 0; ++ int i, num_comb; ++ struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext; ++ struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop)); ++ ++ /* sanity checks... */ ++ if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) || ++ (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n", ++ pfkey_prop->sadb_prop_len, ++ (int)sizeof(struct sadb_prop), ++ (int)sizeof(struct sadb_comb)); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_prop->sadb_prop_replay > 64) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "replay window size: %d -- must be 0 <= size <= 64\n", ++ pfkey_prop->sadb_prop_replay); ++ SENDERR(EINVAL); ++ } ++ ++ for(i=0; i<3; i++) { ++ if(pfkey_prop->sadb_prop_reserved[i]) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "res[%d]=%d, must be zero.\n", ++ i, pfkey_prop->sadb_prop_reserved[i]); ++ SENDERR(EINVAL); ++ } ++ } ++ ++ num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb); ++ ++ for(i = 0; i < num_comb; i++) { ++ if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n", ++ i, ++ pfkey_comb->sadb_comb_auth, ++ SADB_AALG_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_comb->sadb_comb_auth) { ++ if(!pfkey_comb->sadb_comb_auth_minbits) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n", ++ i); ++ SENDERR(EINVAL); ++ } ++ if(!pfkey_comb->sadb_comb_auth_maxbits) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n", ++ i); ++ SENDERR(EINVAL); ++ } ++ if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n", ++ i, ++ pfkey_comb->sadb_comb_auth_minbits, ++ pfkey_comb->sadb_comb_auth_maxbits); ++ SENDERR(EINVAL); ++ } ++ } else { ++ if(pfkey_comb->sadb_comb_auth_minbits) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n", ++ i, ++ pfkey_comb->sadb_comb_auth_minbits); ++ SENDERR(EINVAL); ++ } ++ if(pfkey_comb->sadb_comb_auth_maxbits) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n", ++ i, ++ pfkey_comb->sadb_comb_auth_maxbits); ++ SENDERR(EINVAL); ++ } ++ } ++ ++ if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_comb_parse: " ++ "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n", ++ i, ++ pfkey_comb->sadb_comb_encrypt, ++ SADB_EALG_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_comb->sadb_comb_encrypt) { ++ if(!pfkey_comb->sadb_comb_encrypt_minbits) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n", ++ i); ++ SENDERR(EINVAL); ++ } ++ if(!pfkey_comb->sadb_comb_encrypt_maxbits) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n", ++ i); ++ SENDERR(EINVAL); ++ } ++ if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n", ++ i, ++ pfkey_comb->sadb_comb_encrypt_minbits, ++ pfkey_comb->sadb_comb_encrypt_maxbits); ++ SENDERR(EINVAL); ++ } ++ } else { ++ if(pfkey_comb->sadb_comb_encrypt_minbits) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n", ++ i, ++ pfkey_comb->sadb_comb_encrypt_minbits); ++ SENDERR(EINVAL); ++ } ++ if(pfkey_comb->sadb_comb_encrypt_maxbits) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n", ++ i, ++ pfkey_comb->sadb_comb_encrypt_maxbits); ++ SENDERR(EINVAL); ++ } ++ } ++ ++ /* XXX do sanity check on flags */ ++ ++ if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n", ++ i, ++ pfkey_comb->sadb_comb_soft_allocations, ++ pfkey_comb->sadb_comb_hard_allocations); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n", ++ i, ++ (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes, ++ (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n", ++ i, ++ (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime, ++ (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n", ++ i, ++ (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime, ++ (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n", ++ i, ++ pfkey_comb->sadb_x_comb_soft_packets, ++ pfkey_comb->sadb_x_comb_hard_packets); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_comb->sadb_comb_reserved) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_prop_parse: " ++ "comb[%d].res=%d, must be zero.\n", ++ i, ++ pfkey_comb->sadb_comb_reserved); ++ SENDERR(EINVAL); ++ } ++ pfkey_comb++; ++ } ++ ++errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_supported_parse(struct sadb_ext *pfkey_ext) ++{ ++ int error = 0; ++ unsigned int i, num_alg; ++ struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext; ++ struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported)); ++ ++ /* sanity checks... */ ++ if((pfkey_supported->sadb_supported_len < ++ sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) || ++ (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - ++ sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) { ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_supported_parse: " ++ "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n", ++ pfkey_supported->sadb_supported_len, ++ (int)sizeof(struct sadb_supported), ++ (int)sizeof(struct sadb_alg)); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_supported->sadb_supported_reserved) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_supported_parse: " ++ "res=%d, must be zero.\n", ++ pfkey_supported->sadb_supported_reserved); ++ SENDERR(EINVAL); ++ } ++ ++ num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg); ++ ++ for(i = 0; i < num_alg; i++) { ++ /* process algo description */ ++ if(pfkey_alg->sadb_alg_reserved) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_supported_parse: " ++ "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n", ++ i, ++ pfkey_alg->sadb_alg_id, ++ pfkey_alg->sadb_alg_ivlen, ++ pfkey_alg->sadb_alg_minbits, ++ pfkey_alg->sadb_alg_maxbits, ++ pfkey_alg->sadb_alg_reserved); ++ SENDERR(EINVAL); ++ } ++ ++ /* XXX can alg_id auth/enc be determined from info given? ++ Yes, but OpenBSD's method does not iteroperate with rfc2367. ++ rgb, 2000-04-06 */ ++ ++ switch(pfkey_supported->sadb_supported_exttype) { ++ case SADB_EXT_SUPPORTED_AUTH: ++ if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_supported_parse: " ++ "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n", ++ i, ++ pfkey_alg->sadb_alg_id, ++ SADB_AALG_MAX); ++ SENDERR(EINVAL); ++ } ++ break; ++ case SADB_EXT_SUPPORTED_ENCRYPT: ++ if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_supported_parse: " ++ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n", ++ i, ++ pfkey_alg->sadb_alg_id, ++ SADB_EALG_MAX); ++ SENDERR(EINVAL); ++ } ++ break; ++ default: ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_supported_parse: " ++ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n", ++ i, ++ pfkey_alg->sadb_alg_id, ++ SADB_EALG_MAX); ++ SENDERR(EINVAL); ++ } ++ pfkey_alg++; ++ } ++ ++ errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_spirange_parse(struct sadb_ext *pfkey_ext) ++{ ++ int error = 0; ++ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext; ++ ++ /* sanity checks... */ ++ if(pfkey_spirange->sadb_spirange_len != ++ sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_spirange_parse: " ++ "size wrong ext_len=%d, key_ext_len=%d.\n", ++ pfkey_spirange->sadb_spirange_len, ++ (int)sizeof(struct sadb_spirange)); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_spirange->sadb_spirange_reserved) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_spirange_parse: " ++ "reserved=%d must be set to zero.\n", ++ pfkey_spirange->sadb_spirange_reserved); ++ SENDERR(EINVAL); ++ } ++ ++ if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_spirange_parse: " ++ "minspi=%08x must be < maxspi=%08x.\n", ++ ntohl(pfkey_spirange->sadb_spirange_min), ++ ntohl(pfkey_spirange->sadb_spirange_max)); ++ SENDERR(EINVAL); ++ } ++ ++ if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_spirange_parse: " ++ "minspi=%08x must be > 255.\n", ++ ntohl(pfkey_spirange->sadb_spirange_min)); ++ SENDERR(EEXIST); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, ++ "pfkey_spirange_parse: " ++ "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n", ++ pfkey_spirange->sadb_spirange_len, ++ pfkey_spirange->sadb_spirange_exttype, ++ pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype), ++ pfkey_spirange->sadb_spirange_min, ++ pfkey_spirange->sadb_spirange_max, ++ pfkey_spirange->sadb_spirange_reserved); ++ errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext) ++{ ++ int error = 0; ++ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext; ++ ++ /* sanity checks... */ ++ if(pfkey_x_kmprivate->sadb_x_kmprivate_len < ++ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_x_kmprivate_parse: " ++ "size wrong ext_len=%d, key_ext_len=%d.\n", ++ pfkey_x_kmprivate->sadb_x_kmprivate_len, ++ (int)sizeof(struct sadb_x_kmprivate)); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_x_kmprivate_parse: " ++ "reserved=%d must be set to zero.\n", ++ pfkey_x_kmprivate->sadb_x_kmprivate_reserved); ++ SENDERR(EINVAL); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_x_kmprivate_parse: " ++ "Sorry, I can't parse exttype=%d yet.\n", ++ pfkey_ext->sadb_ext_type); ++ SENDERR(EINVAL); /* don't process these yet */ ++ ++errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_x_satype_parse(struct sadb_ext *pfkey_ext) ++{ ++ int error = 0; ++ int i; ++ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext; ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, ++ "pfkey_x_satype_parse: enter\n"); ++ /* sanity checks... */ ++ if(pfkey_x_satype->sadb_x_satype_len != ++ sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_x_satype_parse: " ++ "size wrong ext_len=%d, key_ext_len=%d.\n", ++ pfkey_x_satype->sadb_x_satype_len, ++ (int)sizeof(struct sadb_x_satype)); ++ SENDERR(EINVAL); ++ } ++ ++ if(!pfkey_x_satype->sadb_x_satype_satype) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_x_satype_parse: " ++ "satype is zero, must be non-zero.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_x_satype_parse: " ++ "satype %d > max %d, invalid.\n", ++ pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_x_satype_parse: " ++ "proto lookup from satype=%d failed.\n", ++ pfkey_x_satype->sadb_x_satype_satype); ++ SENDERR(EINVAL); ++ } ++ ++ for(i = 0; i < 3; i++) { ++ if(pfkey_x_satype->sadb_x_satype_reserved[i]) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_x_satype_parse: " ++ "reserved[%d]=%d must be set to zero.\n", ++ i, pfkey_x_satype->sadb_x_satype_reserved[i]); ++ SENDERR(EINVAL); ++ } ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, ++ "pfkey_x_satype_parse: " ++ "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n", ++ pfkey_x_satype->sadb_x_satype_len, ++ pfkey_x_satype->sadb_x_satype_exttype, ++ pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype), ++ pfkey_x_satype->sadb_x_satype_satype, ++ satype2name(pfkey_x_satype->sadb_x_satype_satype), ++ pfkey_x_satype->sadb_x_satype_reserved[0], ++ pfkey_x_satype->sadb_x_satype_reserved[1], ++ pfkey_x_satype->sadb_x_satype_reserved[2]); ++errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext) ++{ ++ int error = 0; ++ int i; ++ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext; ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, ++ "pfkey_x_debug_parse: enter\n"); ++ /* sanity checks... */ ++ if(pfkey_x_debug->sadb_x_debug_len != ++ sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_x_debug_parse: " ++ "size wrong ext_len=%d, key_ext_len=%d.\n", ++ pfkey_x_debug->sadb_x_debug_len, ++ (int)sizeof(struct sadb_x_debug)); ++ SENDERR(EINVAL); ++ } ++ ++ for(i = 0; i < 4; i++) { ++ if(pfkey_x_debug->sadb_x_debug_reserved[i]) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_x_debug_parse: " ++ "reserved[%d]=%d must be set to zero.\n", ++ i, pfkey_x_debug->sadb_x_debug_reserved[i]); ++ SENDERR(EINVAL); ++ } ++ } ++ ++errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext) ++{ ++ int error = 0; ++ struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext; ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n"); ++ /* sanity checks... */ ++ ++ if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n", ++ p->sadb_protocol_len, (int)sizeof(*p)); ++ SENDERR(EINVAL); ++ } ++ ++ if (p->sadb_protocol_reserved2 != 0) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_protocol_parse: res=%d, must be zero.\n", ++ p->sadb_protocol_reserved2); ++ SENDERR(EINVAL); ++ } ++ ++ errlab: ++ return error; ++} ++ ++#ifdef NAT_TRAVERSAL ++DEBUG_NO_STATIC int ++pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext) ++{ ++ return 0; ++} ++DEBUG_NO_STATIC int ++pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext) ++{ ++ return 0; ++} ++#endif ++ ++#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME}; ++ ++DEFINEPARSER(pfkey_sa_parse); ++DEFINEPARSER(pfkey_lifetime_parse); ++DEFINEPARSER(pfkey_address_parse); ++DEFINEPARSER(pfkey_key_parse); ++DEFINEPARSER(pfkey_ident_parse); ++DEFINEPARSER(pfkey_sens_parse); ++DEFINEPARSER(pfkey_prop_parse); ++DEFINEPARSER(pfkey_supported_parse); ++DEFINEPARSER(pfkey_spirange_parse); ++DEFINEPARSER(pfkey_x_kmprivate_parse); ++DEFINEPARSER(pfkey_x_satype_parse); ++DEFINEPARSER(pfkey_x_ext_debug_parse); ++DEFINEPARSER(pfkey_x_ext_protocol_parse); ++#ifdef NAT_TRAVERSAL ++DEFINEPARSER(pfkey_x_ext_nat_t_type_parse); ++DEFINEPARSER(pfkey_x_ext_nat_t_port_parse); ++#endif ++ ++struct pf_key_ext_parsers_def *ext_default_parsers[]= ++{ ++ NULL, /* pfkey_msg_parse, */ ++ &pfkey_sa_parse_def, ++ &pfkey_lifetime_parse_def, ++ &pfkey_lifetime_parse_def, ++ &pfkey_lifetime_parse_def, ++ &pfkey_address_parse_def, ++ &pfkey_address_parse_def, ++ &pfkey_address_parse_def, ++ &pfkey_key_parse_def, ++ &pfkey_key_parse_def, ++ &pfkey_ident_parse_def, ++ &pfkey_ident_parse_def, ++ &pfkey_sens_parse_def, ++ &pfkey_prop_parse_def, ++ &pfkey_supported_parse_def, ++ &pfkey_supported_parse_def, ++ &pfkey_spirange_parse_def, ++ &pfkey_x_kmprivate_parse_def, ++ &pfkey_x_satype_parse_def, ++ &pfkey_sa_parse_def, ++ &pfkey_address_parse_def, ++ &pfkey_address_parse_def, ++ &pfkey_address_parse_def, ++ &pfkey_address_parse_def, ++ &pfkey_address_parse_def, ++ &pfkey_x_ext_debug_parse_def, ++ &pfkey_x_ext_protocol_parse_def ++#ifdef NAT_TRAVERSAL ++ , ++ &pfkey_x_ext_nat_t_type_parse_def, ++ &pfkey_x_ext_nat_t_port_parse_def, ++ &pfkey_x_ext_nat_t_port_parse_def, ++ &pfkey_address_parse_def ++#endif ++}; ++ ++int ++pfkey_msg_parse(struct sadb_msg *pfkey_msg, ++ struct pf_key_ext_parsers_def *ext_parsers[], ++ struct sadb_ext *extensions[], ++ int dir) ++{ ++ int error = 0; ++ int remain; ++ struct sadb_ext *pfkey_ext; ++ int extensions_seen = 0; ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, ++ "pfkey_msg_parse: " ++ "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n", ++ pfkey_msg->sadb_msg_version, ++ pfkey_msg->sadb_msg_type, ++ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type), ++ pfkey_msg->sadb_msg_errno, ++ pfkey_msg->sadb_msg_satype, ++ satype2name(pfkey_msg->sadb_msg_satype), ++ pfkey_msg->sadb_msg_len, ++ pfkey_msg->sadb_msg_reserved, ++ pfkey_msg->sadb_msg_seq, ++ pfkey_msg->sadb_msg_pid); ++ ++ if(ext_parsers == NULL) ext_parsers = ext_default_parsers; ++ ++ pfkey_extensions_init(extensions); ++ ++ remain = pfkey_msg->sadb_msg_len; ++ remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; ++ ++ pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg + ++ sizeof(struct sadb_msg)); ++ ++ extensions[0] = (struct sadb_ext *) pfkey_msg; ++ ++ ++ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) { ++ ERROR("pfkey_msg_parse: " ++ "not PF_KEY_V2 msg, found %d, should be %d.\n", ++ pfkey_msg->sadb_msg_version, ++ PF_KEY_V2); ++ SENDERR(EINVAL); ++ } ++ ++ if(!pfkey_msg->sadb_msg_type) { ++ ERROR("pfkey_msg_parse: " ++ "msg type not set, must be non-zero..\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(pfkey_msg->sadb_msg_type > SADB_MAX) { ++ ERROR("pfkey_msg_parse: " ++ "msg type=%d > max=%d.\n", ++ pfkey_msg->sadb_msg_type, ++ SADB_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ switch(pfkey_msg->sadb_msg_type) { ++ case SADB_GETSPI: ++ case SADB_UPDATE: ++ case SADB_ADD: ++ case SADB_DELETE: ++ case SADB_GET: ++ case SADB_X_GRPSA: ++ case SADB_X_ADDFLOW: ++ if(!satype2proto(pfkey_msg->sadb_msg_satype)) { ++ ERROR("pfkey_msg_parse: " ++ "satype %d conversion to proto failed for msg_type %d (%s).\n", ++ pfkey_msg->sadb_msg_satype, ++ pfkey_msg->sadb_msg_type, ++ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); ++ SENDERR(EINVAL); ++ } else { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n", ++ pfkey_msg->sadb_msg_satype, ++ satype2name(pfkey_msg->sadb_msg_satype), ++ satype2proto(pfkey_msg->sadb_msg_satype), ++ pfkey_msg->sadb_msg_type, ++ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); ++ } ++ case SADB_ACQUIRE: ++ case SADB_REGISTER: ++ case SADB_EXPIRE: ++ if(!pfkey_msg->sadb_msg_satype) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "satype is zero, must be non-zero for msg_type %d(%s).\n", ++ pfkey_msg->sadb_msg_type, ++ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); ++ SENDERR(EINVAL); ++ } ++ default: ++ break; ++ } ++ ++ /* errno must not be set in downward messages */ ++ /* this is not entirely true... a response to an ACQUIRE could return an error */ ++ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "errno set to %d.\n", ++ pfkey_msg->sadb_msg_errno); ++ SENDERR(EINVAL); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, ++ "pfkey_msg_parse: " ++ "remain=%d, ext_type=%d(%s), ext_len=%d.\n", ++ remain, ++ pfkey_ext->sadb_ext_type, ++ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), ++ pfkey_ext->sadb_ext_len); ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, ++ "pfkey_msg_parse: " ++ "extensions permitted=%08x, required=%08x.\n", ++ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], ++ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]); ++ ++ extensions_seen = 1; ++ ++ while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) { ++ /* Is there enough message left to support another extension header? */ ++ if(remain < pfkey_ext->sadb_ext_len) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "remain %d less than ext len %d.\n", ++ remain, pfkey_ext->sadb_ext_len); ++ SENDERR(EINVAL); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, ++ "pfkey_msg_parse: " ++ "parsing ext type=%d(%s) remain=%d.\n", ++ pfkey_ext->sadb_ext_type, ++ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), ++ remain); ++ ++ /* Is the extension header type valid? */ ++ if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n", ++ pfkey_ext->sadb_ext_type, ++ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), ++ SADB_EXT_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ /* Have we already seen this type of extension? */ ++ if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0) ++ { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "ext type %d(%s) already seen.\n", ++ pfkey_ext->sadb_ext_type, ++ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type)); ++ SENDERR(EINVAL); ++ } ++ ++ /* Do I even know about this type of extension? */ ++ if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "ext type %d(%s) unknown, ignoring.\n", ++ pfkey_ext->sadb_ext_type, ++ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type)); ++ goto next_ext; ++ } ++ ++ /* Is this type of extension permitted for this type of message? */ ++ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] & ++ 1<sadb_ext_type)) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<sadb_ext_type, ++ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), ++ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], ++ 1<sadb_ext_type); ++ SENDERR(EINVAL); ++ } ++ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, ++ "pfkey_msg_parse: " ++ "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n", ++ remain, ++ pfkey_ext->sadb_ext_type, ++ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), ++ pfkey_ext->sadb_ext_len, ++ pfkey_ext, ++ ext_parsers[pfkey_ext->sadb_ext_type]->parser_name); ++ ++ /* Parse the extension */ ++ if((error = ++ (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "extension parsing for type %d(%s) failed with error %d.\n", ++ pfkey_ext->sadb_ext_type, ++ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), ++ error); ++ SENDERR(-error); ++ } ++ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, ++ "pfkey_msg_parse: " ++ "Extension %d(%s) parsed.\n", ++ pfkey_ext->sadb_ext_type, ++ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type)); ++ ++ /* Mark that we have seen this extension and remember the header location */ ++ extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type ); ++ extensions[pfkey_ext->sadb_ext_type] = pfkey_ext; ++ ++ next_ext: ++ /* Calculate how much message remains */ ++ remain -= pfkey_ext->sadb_ext_len; ++ ++ if(!remain) { ++ break; ++ } ++ /* Find the next extension header */ ++ pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext + ++ pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN); ++ } ++ ++ if(remain) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "unexpected remainder of %d.\n", ++ remain); ++ /* why is there still something remaining? */ ++ SENDERR(EINVAL); ++ } ++ ++ /* check required extensions */ ++ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, ++ "pfkey_msg_parse: " ++ "extensions permitted=%08x, seen=%08x, required=%08x.\n", ++ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], ++ extensions_seen, ++ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]); ++ ++ /* don't check further if it is an error return message since it ++ may not have a body */ ++ if(pfkey_msg->sadb_msg_errno) { ++ SENDERR(-error); ++ } ++ ++ if((extensions_seen & ++ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) != ++ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "required extensions missing:%08x.\n", ++ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] - ++ (extensions_seen & ++ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type])); ++ SENDERR(EINVAL); ++ } ++ ++ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW) ++ && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW) ++ != SADB_X_EXT_ADDRESS_DELFLOW) ++ && (((extensions_seen & (1<sadb_sa_flags ++ & SADB_X_SAFLAGS_CLEARFLOW) ++ != SADB_X_SAFLAGS_CLEARFLOW))) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n", ++ SADB_X_EXT_ADDRESS_DELFLOW ++ - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW), ++ (1<sadb_msg_type) { ++ case SADB_ADD: ++ case SADB_UPDATE: ++ /* check maturity */ ++ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != ++ SADB_SASTATE_MATURE) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "state=%d for add or update should be MATURE=%d.\n", ++ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, ++ SADB_SASTATE_MATURE); ++ SENDERR(EINVAL); ++ } ++ ++ /* check AH and ESP */ ++ switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) { ++ case SADB_SATYPE_AH: ++ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && ++ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth != ++ SADB_AALG_NONE)) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "auth alg is zero, must be non-zero for AH SAs.\n"); ++ SENDERR(EINVAL); ++ } ++ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt != ++ SADB_EALG_NONE) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "AH handed encalg=%d, must be zero.\n", ++ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt); ++ SENDERR(EINVAL); ++ } ++ break; ++ case SADB_SATYPE_ESP: ++ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && ++ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt != ++ SADB_EALG_NONE)) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n", ++ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); ++ SENDERR(EINVAL); ++ } ++ if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt == ++ SADB_EALG_NULL) && ++ (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth == ++ SADB_AALG_NONE) ) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "ESP handed encNULL+authNONE, illegal combination.\n"); ++ SENDERR(EINVAL); ++ } ++ break; ++ case SADB_X_SATYPE_COMP: ++ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && ++ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt != ++ SADB_EALG_NONE)) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n", ++ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); ++ SENDERR(EINVAL); ++ } ++ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth != ++ SADB_AALG_NONE) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "COMP handed auth=%d, must be zero.\n", ++ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth); ++ SENDERR(EINVAL); ++ } ++ break; ++ default: ++ break; ++ } ++ if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) { ++ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, ++ "pfkey_msg_parse: " ++ "spi=%08x must be > 255.\n", ++ ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi)); ++ SENDERR(EINVAL); ++ } ++ default: ++ break; ++ } ++errlab: ++ ++ return error; ++} ++ ++/* ++ * $Log: pfkey_v2_parse.c,v $ ++ * Revision 1.59 2004/04/18 03:03:49 mcr ++ * renamed common include files from pluto directory. ++ * ++ * Revision 1.58 2004/03/08 01:59:08 ken ++ * freeswan.h -> openswan.h ++ * ++ * Revision 1.57 2003/12/10 01:20:19 mcr ++ * NAT-traversal patches to KLIPS. ++ * ++ * Revision 1.56 2003/12/04 23:01:12 mcr ++ * removed ipsec_netlink.h ++ * ++ * Revision 1.55 2003/11/07 01:30:37 ken ++ * Cast sizeof() to int to keep things 64bit clean ++ * ++ * Revision 1.54 2003/10/31 02:27:12 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.53.20.2 2003/10/29 01:11:32 mcr ++ * added debugging for pfkey library. ++ * ++ * Revision 1.53.20.1 2003/09/21 13:59:44 mcr ++ * pre-liminary X.509 patch - does not yet pass tests. ++ * ++ * Revision 1.53 2003/01/30 02:32:09 rgb ++ * ++ * Rename SAref table macro names for clarity. ++ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. ++ * ++ * Revision 1.52 2002/12/30 06:53:07 mcr ++ * deal with short SA structures... #if 0 out for now. Probably ++ * not quite the right way. ++ * ++ * Revision 1.51 2002/12/13 18:16:02 mcr ++ * restored sa_ref code ++ * ++ * Revision 1.50 2002/12/13 18:06:52 mcr ++ * temporarily removed sadb_x_sa_ref reference for 2.xx ++ * ++ * Revision 1.49 2002/10/05 05:02:58 dhr ++ * ++ * C labels go on statements ++ * ++ * Revision 1.48 2002/09/20 15:40:45 rgb ++ * Added sadb_x_sa_ref to struct sadb_sa. ++ * ++ * Revision 1.47 2002/09/20 05:01:31 rgb ++ * Fixed usage of pfkey_lib_debug. ++ * Format for function declaration style consistency. ++ * Added text labels to elucidate numeric values presented. ++ * Re-organised debug output to reduce noise in output. ++ * ++ * Revision 1.46 2002/07/24 18:44:54 rgb ++ * Type fiddling to tame ia64 compiler. ++ * ++ * Revision 1.45 2002/05/23 07:14:11 rgb ++ * Cleaned up %p variants to 0p%p for test suite cleanup. ++ * ++ * Revision 1.44 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.43 2002/04/24 07:36:40 mcr ++ * Moved from ./lib/pfkey_v2_parse.c,v ++ * ++ * Revision 1.42 2002/01/29 22:25:36 rgb ++ * Re-add ipsec_kversion.h to keep MALLOC happy. ++ * ++ * Revision 1.41 2002/01/29 01:59:10 mcr ++ * removal of kversions.h - sources that needed it now use ipsec_param.h. ++ * updating of IPv6 structures to match latest in6.h version. ++ * removed dead code from openswan.h that also duplicated kversions.h ++ * code. ++ * ++ * Revision 1.40 2002/01/20 20:34:50 mcr ++ * added pfkey_v2_sadb_type_string to decode sadb_type to string. ++ * ++ * Revision 1.39 2001/11/27 05:29:22 mcr ++ * pfkey parses are now maintained by a structure ++ * that includes their name for debug purposes. ++ * DEBUGGING() macro changed so that it takes a debug ++ * level so that pf_key() can use this to decode the ++ * structures without innundanting humans. ++ * Also uses pfkey_v2_sadb_ext_string() in messages. ++ * ++ * Revision 1.38 2001/11/06 19:47:47 rgb ++ * Added packet parameter to lifetime and comb structures. ++ * ++ * Revision 1.37 2001/10/18 04:45:24 rgb ++ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, ++ * lib/openswan.h version macros moved to lib/kversions.h. ++ * Other compiler directive cleanups. ++ * ++ * Revision 1.36 2001/06/14 19:35:16 rgb ++ * Update copyright date. ++ * ++ * Revision 1.35 2001/05/03 19:44:51 rgb ++ * Standardise on SENDERR() macro. ++ * ++ * Revision 1.34 2001/03/16 07:41:51 rgb ++ * Put openswan.h include before pluto includes. ++ * ++ * Revision 1.33 2001/02/27 07:13:51 rgb ++ * Added satype2name() function. ++ * Added text to default satype_tbl entry. ++ * Added satype2name() conversions for most satype debug output. ++ * ++ * Revision 1.32 2001/02/26 20:01:09 rgb ++ * Added internal IP protocol 61 for magic SAs. ++ * Ditch unused sadb_satype2proto[], replaced by satype2proto(). ++ * Re-formatted debug output (split lines, consistent spacing). ++ * Removed acquire, register and expire requirements for a known satype. ++ * Changed message type checking to a switch structure. ++ * Verify expected NULL auth for IPCOMP. ++ * Enforced spi > 0x100 requirement, now that pass uses a magic SA for ++ * appropriate message types. ++ * ++ * Revision 1.31 2000/12/01 07:09:00 rgb ++ * Added ipcomp sanity check to require encalgo is set. ++ * ++ * Revision 1.30 2000/11/17 18:10:30 rgb ++ * Fixed bugs mostly relating to spirange, to treat all spi variables as ++ * network byte order since this is the way PF_KEYv2 stored spis. ++ * ++ * Revision 1.29 2000/10/12 00:02:39 rgb ++ * Removed 'format, ##' nonsense from debug macros for RH7.0. ++ * ++ * Revision 1.28 2000/09/20 16:23:04 rgb ++ * Remove over-paranoid extension check in the presence of sadb_msg_errno. ++ * ++ * Revision 1.27 2000/09/20 04:04:21 rgb ++ * Changed static functions to DEBUG_NO_STATIC to reveal function names in ++ * oopsen. ++ * ++ * Revision 1.26 2000/09/15 11:37:02 rgb ++ * Merge in heavily modified Svenning Soerensen's ++ * IPCOMP zlib deflate code. ++ * ++ * Revision 1.25 2000/09/12 22:35:37 rgb ++ * Restructured to remove unused extensions from CLEARFLOW messages. ++ * ++ * Revision 1.24 2000/09/12 18:59:54 rgb ++ * Added Gerhard's IPv6 support to pfkey parts of libopenswan. ++ * ++ * Revision 1.23 2000/09/12 03:27:00 rgb ++ * Moved DEBUGGING definition to compile kernel with debug off. ++ * ++ * Revision 1.22 2000/09/09 06:39:27 rgb ++ * Restrict pfkey errno check to downward messages only. ++ * ++ * Revision 1.21 2000/09/08 19:22:34 rgb ++ * Enabled pfkey_sens_parse(). ++ * Added check for errno on downward acquire messages only. ++ * ++ * Revision 1.20 2000/09/01 18:48:23 rgb ++ * Fixed reserved check bug and added debug output in ++ * pfkey_supported_parse(). ++ * Fixed debug output label bug in pfkey_ident_parse(). ++ * ++ * Revision 1.19 2000/08/27 01:55:26 rgb ++ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code. ++ * ++ * Revision 1.18 2000/08/24 17:00:36 rgb ++ * Ignore unknown extensions instead of failing. ++ * ++ * Revision 1.17 2000/06/02 22:54:14 rgb ++ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support. ++ * ++ * Revision 1.16 2000/05/10 19:25:11 rgb ++ * Fleshed out proposal and supported extensions. ++ * ++ * Revision 1.15 2000/01/24 21:15:31 rgb ++ * Added disabled pluto pfkey lib debug flag. ++ * Added algo debugging reporting. ++ * ++ * Revision 1.14 2000/01/22 23:24:29 rgb ++ * Added new functions proto2satype() and satype2proto() and lookup ++ * table satype_tbl. Also added proto2name() since it was easy. ++ * ++ * Revision 1.13 2000/01/21 09:43:59 rgb ++ * Cast ntohl(spi) as (unsigned long int) to shut up compiler. ++ * ++ * Revision 1.12 2000/01/21 06:28:19 rgb ++ * Added address cases for eroute flows. ++ * Indented compiler directives for readability. ++ * Added klipsdebug switching capability. ++ * ++ * Revision 1.11 1999/12/29 21:14:59 rgb ++ * Fixed debug text cut and paste typo. ++ * ++ * Revision 1.10 1999/12/10 17:45:24 rgb ++ * Added address debugging. ++ * ++ * Revision 1.9 1999/12/09 23:11:42 rgb ++ * Ditched include since we no longer use memset(). ++ * Use new pfkey_extensions_init() instead of memset(). ++ * Added check for SATYPE in pfkey_msg_build(). ++ * Tidy up comments and debugging comments. ++ * ++ * Revision 1.8 1999/12/07 19:55:26 rgb ++ * Removed unused first argument from extension parsers. ++ * Removed static pluto debug flag. ++ * Moved message type and state checking to pfkey_msg_parse(). ++ * Changed print[fk] type from lx to x to quiet compiler. ++ * Removed redundant remain check. ++ * Changed __u* types to uint* to avoid use of asm/types.h and ++ * sys/types.h in userspace code. ++ * ++ * Revision 1.7 1999/12/01 22:20:51 rgb ++ * Moved pfkey_lib_debug variable into the library. ++ * Added pfkey version check into header parsing. ++ * Added check for SATYPE only for those extensions that require a ++ * non-zero value. ++ * ++ * Revision 1.6 1999/11/27 11:58:05 rgb ++ * Added ipv6 headers. ++ * Moved sadb_satype2proto protocol lookup table from ++ * klips/net/ipsec/pfkey_v2_parser.c. ++ * Enable lifetime_current checking. ++ * Debugging error messages added. ++ * Add argument to pfkey_msg_parse() for direction. ++ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. ++ * Add CVS log entry to bottom of file. ++ * Moved auth and enc alg check to pfkey_msg_parse(). ++ * Enable accidentally disabled spirange parsing. ++ * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/prng.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,201 @@ ++/* ++ * crypto-class pseudorandom number generator ++ * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397 ++ * Copyright (C) 2002 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: prng.c,v 1.6 2004/04/11 17:39:25 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++/* ++ - prng_init - initialize PRNG from a key ++ */ ++void ++prng_init(prng, key, keylen) ++struct prng *prng; ++const unsigned char *key; ++size_t keylen; ++{ ++ unsigned char k[256]; ++ int i, j; ++ unsigned const char *p; ++ unsigned const char *keyend = key + keylen; ++ unsigned char t; ++ ++ for (i = 0; i <= 255; i++) ++ prng->sbox[i] = i; ++ p = key; ++ for (i = 0; i <= 255; i++) { ++ k[i] = *p++; ++ if (p >= keyend) ++ p = key; ++ } ++ j = 0; ++ for (i = 0; i <= 255; i++) { ++ j = (j + prng->sbox[i] + k[i]) & 0xff; ++ t = prng->sbox[i]; ++ prng->sbox[i] = prng->sbox[j]; ++ prng->sbox[j] = t; ++ k[i] = 0; /* clear out key memory */ ++ } ++ prng->i = 0; ++ prng->j = 0; ++ prng->count = 0; ++} ++ ++/* ++ - prng_bytes - get some pseudorandom bytes from PRNG ++ */ ++void ++prng_bytes(prng, dst, dstlen) ++struct prng *prng; ++unsigned char *dst; ++size_t dstlen; ++{ ++ int i, j, t; ++ unsigned char *p = dst; ++ size_t remain = dstlen; ++# define MAX 4000000000ul ++ ++ while (remain > 0) { ++ i = (prng->i + 1) & 0xff; ++ prng->i = i; ++ j = (prng->j + prng->sbox[i]) & 0xff; ++ prng->j = j; ++ t = prng->sbox[i]; ++ prng->sbox[i] = prng->sbox[j]; ++ prng->sbox[j] = t; ++ t = (t + prng->sbox[i]) & 0xff; ++ *p++ = prng->sbox[t]; ++ remain--; ++ } ++ if (prng->count < MAX - dstlen) ++ prng->count += dstlen; ++ else ++ prng->count = MAX; ++} ++ ++/* ++ - prnt_count - how many bytes have been extracted from PRNG so far? ++ */ ++unsigned long ++prng_count(prng) ++struct prng *prng; ++{ ++ return prng->count; ++} ++ ++/* ++ - prng_final - clear out PRNG to ensure nothing left in memory ++ */ ++void ++prng_final(prng) ++struct prng *prng; ++{ ++ int i; ++ ++ for (i = 0; i <= 255; i++) ++ prng->sbox[i] = 0; ++ prng->i = 0; ++ prng->j = 0; ++ prng->count = 0; /* just for good measure */ ++} ++ ++ ++ ++#ifdef PRNG_MAIN ++ ++#include ++ ++void regress(); ++ ++int ++main(argc, argv) ++int argc; ++char *argv[]; ++{ ++ struct prng pr; ++ unsigned char buf[100]; ++ unsigned char *p; ++ size_t n; ++ ++ if (argc < 2) { ++ fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]); ++ exit(2); ++ } ++ ++ if (strcmp(argv[1], "-r") == 0) { ++ regress(); ++ fprintf(stderr, "regress() returned?!?\n"); ++ exit(1); ++ } ++ ++ prng_init(&pr, argv[1], strlen(argv[1])); ++ prng_bytes(&pr, buf, 32); ++ printf("0x"); ++ for (p = buf, n = 32; n > 0; p++, n--) ++ printf("%02x", *p); ++ printf("\n%lu bytes\n", prng_count(&pr)); ++ prng_final(&pr); ++ exit(0); ++} ++ ++void ++regress() ++{ ++ struct prng pr; ++ unsigned char buf[100]; ++ unsigned char *p; ++ size_t n; ++ /* somewhat non-random sample key */ ++ unsigned char key[] = "here we go gathering nuts in May"; ++ /* first thirty bytes of output from that key */ ++ unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c" ++ "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71" ++ "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28"; ++ int nzero, none; ++ int show = 0; ++ ++ prng_init(&pr, key, strlen(key)); ++ prng_bytes(&pr, buf, sizeof(buf)); ++ for (p = buf, n = sizeof(buf); n > 0; p++, n--) { ++ if (*p == 0) ++ nzero++; ++ if (*p == 255) ++ none++; ++ } ++ if (nzero > 3 || none > 3) { ++ fprintf(stderr, "suspiciously non-random output!\n"); ++ show = 1; ++ } ++ if (memcmp(buf, good, strlen(good)) != 0) { ++ fprintf(stderr, "incorrect output!\n"); ++ show = 1; ++ } ++ if (show) { ++ fprintf(stderr, "0x"); ++ for (p = buf, n = sizeof(buf); n > 0; p++, n--) ++ fprintf(stderr, "%02x", *p); ++ fprintf(stderr, "\n"); ++ exit(1); ++ } ++ if (prng_count(&pr) != sizeof(buf)) { ++ fprintf(stderr, "got %u bytes, but count is %lu\n", ++ sizeof(buf), prng_count(&pr)); ++ exit(1); ++ } ++ prng_final(&pr); ++ exit(0); ++} ++ ++#endif /* PRNG_MAIN */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/rangetoa.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,60 @@ ++/* ++ * convert binary form of address range to ASCII ++ * Copyright (C) 1998, 1999 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: rangetoa.c,v 1.8 2004/04/11 17:39:25 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++/* ++ - rangetoa - convert address range to ASCII ++ */ ++size_t /* space needed for full conversion */ ++rangetoa(addrs, format, dst, dstlen) ++struct in_addr addrs[2]; ++int format; /* character */ ++char *dst; /* need not be valid if dstlen is 0 */ ++size_t dstlen; ++{ ++ size_t len; ++ size_t rest; ++ int n; ++ char *p; ++ ++ switch (format) { ++ case 0: ++ break; ++ default: ++ return 0; ++ break; ++ } ++ ++ len = addrtoa(addrs[0], 0, dst, dstlen); ++ if (len < dstlen) ++ for (p = dst + len - 1, n = 3; len < dstlen && n > 0; ++ p++, len++, n--) ++ *p = '.'; ++ else ++ p = NULL; ++ if (len < dstlen) ++ rest = dstlen - len; ++ else { ++ if (dstlen > 0) ++ *(dst + dstlen - 1) = '\0'; ++ rest = 0; ++ } ++ ++ len += addrtoa(addrs[1], 0, p, rest); ++ ++ return len; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/satot.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,133 @@ ++/* ++ * convert from binary form of SA ID to text ++ * Copyright (C) 2000, 2001 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: satot.c,v 1.12 2004/04/11 17:10:21 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++static struct typename { ++ char type; ++ char *name; ++} typenames[] = { ++ { SA_AH, "ah" }, ++ { SA_ESP, "esp" }, ++ { SA_IPIP, "tun" }, ++ { SA_COMP, "comp" }, ++ { SA_INT, "int" }, ++ { 0, NULL } ++}; ++ ++/* ++ - satot - convert SA to text "ah507@1.2.3.4" ++ */ ++size_t /* space needed for full conversion */ ++satot(sa, format, dst, dstlen) ++const ip_said *sa; ++int format; /* character */ ++char *dst; /* need not be valid if dstlen is 0 */ ++size_t dstlen; ++{ ++ size_t len = 0; /* 0 means "not recognized yet" */ ++ int base; ++ int showversion; /* use delimiter to show IP version? */ ++ struct typename *tn; ++ char *p; ++ char *pre; ++ char buf[10+1+ULTOT_BUF+ADDRTOT_BUF]; ++ char unk[10]; ++ ++ switch (format) { ++ case 0: ++ base = 16; ++ showversion = 1; ++ break; ++ case 'f': ++ base = 17; ++ showversion = 1; ++ break; ++ case 'x': ++ base = 'x'; ++ showversion = 0; ++ break; ++ case 'd': ++ base = 10; ++ showversion = 0; ++ break; ++ default: ++ return 0; ++ break; ++ } ++ ++ memset(buf, 0, sizeof(buf)); ++ ++ pre = NULL; ++ for (tn = typenames; tn->name != NULL; tn++) ++ if (sa->proto == tn->type) { ++ pre = tn->name; ++ break; /* NOTE BREAK OUT */ ++ } ++ if (pre == NULL) { /* unknown protocol */ ++ strcpy(unk, "unk"); ++ (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk), ++ sizeof(unk)-strlen(unk)); ++ pre = unk; ++ } ++ ++ if (strcmp(pre, PASSTHROUGHTYPE) == 0 && ++ sa->spi == PASSTHROUGHSPI && ++ isunspecaddr(&sa->dst)) { ++ strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ? ++ PASSTHROUGH4NAME : ++ PASSTHROUGH6NAME); ++ len = strlen(buf); ++ } ++ ++ if (sa->proto == SA_INT) { ++ switch (ntohl(sa->spi)) { ++ case SPI_PASS: p = "%pass"; break; ++ case SPI_DROP: p = "%drop"; break; ++ case SPI_REJECT: p = "%reject"; break; ++ case SPI_HOLD: p = "%hold"; break; ++ case SPI_TRAP: p = "%trap"; break; ++ case SPI_TRAPSUBNET: p = "%trapsubnet"; break; ++ default: p = NULL; break; ++ } ++ if (p != NULL) { ++ strcpy(buf, p); ++ len = strlen(buf); ++ } ++ } ++ ++ if (len == 0) { /* general case needed */ ++ strcpy(buf, pre); ++ len = strlen(buf); ++ if (showversion) { ++ *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' : ++ ':'; ++ len++; ++ *(buf+len) = '\0'; ++ } ++ len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len); ++ *(buf+len-1) = '@'; ++ len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len); ++ *(buf+len) = '\0'; ++ } ++ ++ if (dst != NULL) { ++ if (len > dstlen) ++ *(buf+dstlen-1) = '\0'; ++ strcpy(dst, buf); ++ } ++ return len; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/subnetof.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,59 @@ ++/* ++ * minor network-address manipulation utilities ++ * Copyright (C) 1998, 1999 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: subnetof.c,v 1.7 2004/04/11 17:39:25 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++/* ++ - subnetof - given address and mask, return subnet part ++ */ ++struct in_addr ++subnetof(addr, mask) ++struct in_addr addr; ++struct in_addr mask; ++{ ++ struct in_addr result; ++ ++ result.s_addr = addr.s_addr & mask.s_addr; ++ return result; ++} ++ ++/* ++ - hostof - given address and mask, return host part ++ */ ++struct in_addr ++hostof(addr, mask) ++struct in_addr addr; ++struct in_addr mask; ++{ ++ struct in_addr result; ++ ++ result.s_addr = addr.s_addr & ~mask.s_addr; ++ return result; ++} ++ ++/* ++ - broadcastof - given (network) address and mask, return broadcast address ++ */ ++struct in_addr ++broadcastof(addr, mask) ++struct in_addr addr; ++struct in_addr mask; ++{ ++ struct in_addr result; ++ ++ result.s_addr = addr.s_addr | ~mask.s_addr; ++ return result; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/subnettoa.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,61 @@ ++/* ++ * convert binary form of subnet description to ASCII ++ * Copyright (C) 1998, 1999 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: subnettoa.c,v 1.10 2004/04/11 17:39:25 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++/* ++ - subnettoa - convert address and mask to ASCII "addr/mask" ++ * Output expresses the mask as a bit count if possible, else dotted decimal. ++ */ ++size_t /* space needed for full conversion */ ++subnettoa(addr, mask, format, dst, dstlen) ++struct in_addr addr; ++struct in_addr mask; ++int format; /* character */ ++char *dst; /* need not be valid if dstlen is 0 */ ++size_t dstlen; ++{ ++ size_t len; ++ size_t rest; ++ int n; ++ char *p; ++ ++ switch (format) { ++ case 0: ++ break; ++ default: ++ return 0; ++ break; ++ } ++ ++ len = addrtoa(addr, 0, dst, dstlen); ++ if (len < dstlen) { ++ dst[len - 1] = '/'; ++ p = dst + len; ++ rest = dstlen - len; ++ } else { ++ p = NULL; ++ rest = 0; ++ } ++ ++ n = masktobits(mask); ++ if (n >= 0) ++ len += ultoa((unsigned long)n, 10, p, rest); ++ else ++ len += addrtoa(mask, 0, p, rest); ++ ++ return len; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/ultoa.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,66 @@ ++/* ++ * convert unsigned long to ASCII ++ * Copyright (C) 1998, 1999 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: ultoa.c,v 1.9 2004/04/11 17:39:25 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++/* ++ - ultoa - convert unsigned long to decimal ASCII ++ */ ++size_t /* length required for full conversion */ ++ultoa(n, base, dst, dstlen) ++unsigned long n; ++int base; ++char *dst; /* need not be valid if dstlen is 0 */ ++size_t dstlen; ++{ ++ char buf[3*sizeof(unsigned long) + 1]; ++ char *bufend = buf + sizeof(buf); ++ size_t len; ++ char *p; ++ static char hex[] = "0123456789abcdef"; ++ ++ p = bufend; ++ *--p = '\0'; ++ if (base == 10) { ++ do { ++ *--p = n%10 + '0'; ++ n /= 10; ++ } while (n != 0); ++ } else if (base == 16) { ++ do { ++ *--p = hex[n&0xf]; ++ n >>= 4; ++ } while (n != 0); ++ *--p = 'x'; ++ *--p = '0'; ++ } else if (base == 8) { ++ do { ++ *--p = (n&07) + '0'; ++ n >>= 3; ++ } while (n != 0); ++ *--p = '0'; ++ } else ++ *--p = '?'; ++ ++ len = bufend - p; ++ ++ if (dstlen > 0) { ++ if (len > dstlen) ++ *(p + dstlen - 1) = '\0'; ++ strcpy(dst, p); ++ } ++ return len; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/libfreeswan/ultot.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,82 @@ ++/* ++ * convert unsigned long to text ++ * Copyright (C) 2000 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: ultot.c,v 1.4 2004/04/11 17:39:25 mcr Exp $ ++ */ ++#include "openswan.h" ++ ++/* ++ - ultot - convert unsigned long to text ++ */ ++size_t /* length required for full conversion */ ++ultot(n, base, dst, dstlen) ++unsigned long n; ++int base; ++char *dst; /* need not be valid if dstlen is 0 */ ++size_t dstlen; ++{ ++ char buf[3*sizeof(unsigned long) + 1]; ++ char *bufend = buf + sizeof(buf); ++ size_t len; ++ char *p; ++ static char hex[] = "0123456789abcdef"; ++# define HEX32 (32/4) ++ ++ p = bufend; ++ *--p = '\0'; ++ switch (base) { ++ case 10: ++ case 'd': ++ do { ++ *--p = n%10 + '0'; ++ n /= 10; ++ } while (n != 0); ++ break; ++ case 16: ++ case 17: ++ case 'x': ++ do { ++ *--p = hex[n&0xf]; ++ n >>= 4; ++ } while (n != 0); ++ if (base == 17) ++ while (bufend - p < HEX32 + 1) ++ *--p = '0'; ++ if (base == 'x') { ++ *--p = 'x'; ++ *--p = '0'; ++ } ++ break; ++ case 8: ++ case 'o': ++ do { ++ *--p = (n&07) + '0'; ++ n >>= 3; ++ } while (n != 0); ++ if (base == 'o') ++ *--p = '0'; ++ break; ++ default: ++ return 0; ++ break; ++ } ++ ++ len = bufend - p; ++ if (dstlen > 0) { ++ if (len > dstlen) ++ *(p + dstlen - 1) = '\0'; ++ strcpy(dst, p); ++ } ++ return len; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/Makefile Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,118 @@ ++# (kernel) Makefile for IPCOMP zlib deflate code ++# Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. ++# Copyright (C) 2000 Svenning Soerensen ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation; either version 2 of the License, or (at your ++# option) any later version. See . ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# RCSID $Id: Makefile,v 1.9 2002/04/24 07:55:32 mcr Exp $ ++# ++ ++ ++ ++include ../Makefile.inc ++ ++ ++ ++ifndef TOPDIR ++TOPDIR := /usr/src/linux ++endif ++ ++ ++L_TARGET := zlib.a ++ ++obj-y := ++ ++include Makefile.objs ++ ++EXTRA_CFLAGS += $(KLIPSCOMPILE) ++ ++EXTRA_CFLAGS += -Wall ++#EXTRA_CFLAGS += -Wconversion ++#EXTRA_CFLAGS += -Wmissing-prototypes ++EXTRA_CFLAGS += -Wpointer-arith ++#EXTRA_CFLAGS += -Wcast-qual ++#EXTRA_CFLAGS += -Wmissing-declarations ++EXTRA_CFLAGS += -Wstrict-prototypes ++#EXTRA_CFLAGS += -pedantic ++#EXTRA_CFLAGS += -W ++#EXTRA_CFLAGS += -Wwrite-strings ++EXTRA_CFLAGS += -Wbad-function-cast ++EXTRA_CFLAGS += -DIPCOMP_PREFIX ++ ++.S.o: ++ $(CC) -D__ASSEMBLY__ -DNO_UNDERLINE -traditional -c $< -o $*.o ++ ++asm-obj-$(CONFIG_M586) += match586.o ++asm-obj-$(CONFIG_M586TSC) += match586.o ++asm-obj-$(CONFIG_M586MMX) += match586.o ++asm-obj-$(CONFIG_M686) += match686.o ++asm-obj-$(CONFIG_MPENTIUMIII) += match686.o ++asm-obj-$(CONFIG_MPENTIUM4) += match686.o ++asm-obj-$(CONFIG_MK6) += match586.o ++asm-obj-$(CONFIG_MK7) += match686.o ++asm-obj-$(CONFIG_MCRUSOE) += match586.o ++asm-obj-$(CONFIG_MWINCHIPC6) += match586.o ++asm-obj-$(CONFIG_MWINCHIP2) += match686.o ++asm-obj-$(CONFIG_MWINCHIP3D) += match686.o ++ ++obj-y += $(asm-obj-y) ++ifneq ($(strip $(asm-obj-y)),) ++ EXTRA_CFLAGS += -DASMV ++endif ++ ++active-objs := $(sort $(obj-y) $(obj-m)) ++L_OBJS := $(obj-y) ++M_OBJS := $(obj-m) ++MIX_OBJS := $(filter $(export-objs), $(active-objs)) ++ ++include $(TOPDIR)/Rules.make ++ ++$(obj-y) : $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h ++ ++ ++clean: ++ -rm -f *.o *.a ++ ++checkprograms: ++programs: $(L_TARGET) ++ ++# ++# $Log: Makefile,v $ ++# Revision 1.9 2002/04/24 07:55:32 mcr ++# #include patches and Makefiles for post-reorg compilation. ++# ++# Revision 1.8 2002/04/24 07:36:44 mcr ++# Moved from ./zlib/Makefile,v ++# ++# Revision 1.7 2002/03/27 23:34:35 mcr ++# added programs: target ++# ++# Revision 1.6 2001/12/05 20:19:08 henry ++# use new compile-control variable ++# ++# Revision 1.5 2001/11/27 16:38:08 mcr ++# added new "checkprograms" target to deal with programs that ++# are required for "make check", but that may not be ready to ++# build for every user due to external dependancies. ++# ++# Revision 1.4 2001/10/24 14:46:24 henry ++# Makefile.inc ++# ++# Revision 1.3 2001/04/21 23:05:24 rgb ++# Update asm directives for 2.4 style makefiles. ++# ++# Revision 1.2 2001/01/29 22:22:00 rgb ++# Convert to 2.4 new style with back compat. ++# ++# Revision 1.1.1.1 2000/09/29 18:51:33 rgb ++# zlib_beginnings ++# ++# +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/Makefile.objs Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,27 @@ ++obj-$(CONFIG_IPSEC_IPCOMP) += adler32.o ++obj-$(CONFIG_IPSEC_IPCOMP) += deflate.o ++obj-$(CONFIG_IPSEC_IPCOMP) += infblock.o ++obj-$(CONFIG_IPSEC_IPCOMP) += infcodes.o ++obj-$(CONFIG_IPSEC_IPCOMP) += inffast.o ++obj-$(CONFIG_IPSEC_IPCOMP) += inflate.o ++obj-$(CONFIG_IPSEC_IPCOMP) += inftrees.o ++obj-$(CONFIG_IPSEC_IPCOMP) += infutil.o ++obj-$(CONFIG_IPSEC_IPCOMP) += trees.o ++obj-$(CONFIG_IPSEC_IPCOMP) += zutil.o ++ ++asm-obj-$(CONFIG_M586) += ${LIBZLIBSRCDIR}/match586.o ++asm-obj-$(CONFIG_M586TSC) += ${LIBZLIBSRCDIR}/match586.o ++asm-obj-$(CONFIG_M586MMX) += ${LIBZLIBSRCDIR}/match586.o ++asm-obj-$(CONFIG_M686) += ${LIBZLIBSRCDIR}/match686.o ++asm-obj-$(CONFIG_MPENTIUMIII) += ${LIBZLIBSRCDIR}/match686.o ++asm-obj-$(CONFIG_MPENTIUM4) += ${LIBZLIBSRCDIR}/match686.o ++asm-obj-$(CONFIG_MK6) += ${LIBZLIBSRCDIR}/match586.o ++asm-obj-$(CONFIG_MK7) += ${LIBZLIBSRCDIR}/match686.o ++asm-obj-$(CONFIG_MCRUSOE) += ${LIBZLIBSRCDIR}/match586.o ++asm-obj-$(CONFIG_MWINCHIPC6) += ${LIBZLIBSRCDIR}/match586.o ++asm-obj-$(CONFIG_MWINCHIP2) += ${LIBZLIBSRCDIR}/match686.o ++asm-obj-$(CONFIG_MWINCHIP3D) += ${LIBZLIBSRCDIR}/match686.o ++ ++EXTRA_CFLAGS += -DIPCOMP_PREFIX ++ ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/README Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,147 @@ ++zlib 1.1.4 is a general purpose data compression library. All the code ++is thread safe. The data format used by the zlib library ++is described by RFCs (Request for Comments) 1950 to 1952 in the files ++http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate ++format) and rfc1952.txt (gzip format). These documents are also available in ++other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html ++ ++All functions of the compression library are documented in the file zlib.h ++(volunteer to write man pages welcome, contact jloup@gzip.org). A usage ++example of the library is given in the file example.c which also tests that ++the library is working correctly. Another example is given in the file ++minigzip.c. The compression library itself is composed of all source files ++except example.c and minigzip.c. ++ ++To compile all files and run the test program, follow the instructions ++given at the top of Makefile. In short "make test; make install" ++should work for most machines. For Unix: "./configure; make test; make install" ++For MSDOS, use one of the special makefiles such as Makefile.msc. ++For VMS, use Make_vms.com or descrip.mms. ++ ++Questions about zlib should be sent to , or to ++Gilles Vollant for the Windows DLL version. ++The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/ ++Before reporting a problem, please check this site to verify that ++you have the latest version of zlib; otherwise get the latest version and ++check whether the problem still exists or not. ++ ++PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html ++before asking for help. ++ ++Mark Nelson wrote an article about zlib for the Jan. 1997 ++issue of Dr. Dobb's Journal; a copy of the article is available in ++http://dogma.net/markn/articles/zlibtool/zlibtool.htm ++ ++The changes made in version 1.1.4 are documented in the file ChangeLog. ++The only changes made since 1.1.3 are bug corrections: ++ ++- ZFREE was repeated on same allocation on some error conditions. ++ This creates a security problem described in ++ http://www.zlib.org/advisory-2002-03-11.txt ++- Returned incorrect error (Z_MEM_ERROR) on some invalid data ++- Avoid accesses before window for invalid distances with inflate window ++ less than 32K. ++- force windowBits > 8 to avoid a bug in the encoder for a window size ++ of 256 bytes. (A complete fix will be available in 1.1.5). ++ ++The beta version 1.1.5beta includes many more changes. A new official ++version 1.1.5 will be released as soon as extensive testing has been ++completed on it. ++ ++ ++Unsupported third party contributions are provided in directory "contrib". ++ ++A Java implementation of zlib is available in the Java Development Kit ++http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html ++See the zlib home page http://www.zlib.org for details. ++ ++A Perl interface to zlib written by Paul Marquess ++is in the CPAN (Comprehensive Perl Archive Network) sites ++http://www.cpan.org/modules/by-module/Compress/ ++ ++A Python interface to zlib written by A.M. Kuchling ++is available in Python 1.5 and later versions, see ++http://www.python.org/doc/lib/module-zlib.html ++ ++A zlib binding for TCL written by Andreas Kupries ++is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html ++ ++An experimental package to read and write files in .zip format, ++written on top of zlib by Gilles Vollant , is ++available at http://www.winimage.com/zLibDll/unzip.html ++and also in the contrib/minizip directory of zlib. ++ ++ ++Notes for some targets: ++ ++- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc ++ and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL ++ The zlib DLL support was initially done by Alessandro Iacopetti and is ++ now maintained by Gilles Vollant . Check the zlib DLL ++ home page at http://www.winimage.com/zLibDll ++ ++ From Visual Basic, you can call the DLL functions which do not take ++ a structure as argument: compress, uncompress and all gz* functions. ++ See contrib/visual-basic.txt for more information, or get ++ http://www.tcfb.com/dowseware/cmp-z-it.zip ++ ++- For 64-bit Irix, deflate.c must be compiled without any optimization. ++ With -O, one libpng test fails. The test works in 32 bit mode (with ++ the -n32 compiler flag). The compiler bug has been reported to SGI. ++ ++- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 ++ it works when compiled with cc. ++ ++- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 ++ is necessary to get gzprintf working correctly. This is done by configure. ++ ++- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works ++ with other compilers. Use "make test" to check your compiler. ++ ++- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. ++ ++- For Turbo C the small model is supported only with reduced performance to ++ avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 ++ ++- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html ++ Per Harald Myrvang ++ ++ ++Acknowledgments: ++ ++ The deflate format used by zlib was defined by Phil Katz. The deflate ++ and zlib specifications were written by L. Peter Deutsch. Thanks to all the ++ people who reported problems and suggested various improvements in zlib; ++ they are too numerous to cite here. ++ ++Copyright notice: ++ ++ (C) 1995-2002 Jean-loup Gailly and Mark Adler ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++ ++ Jean-loup Gailly Mark Adler ++ jloup@gzip.org madler@alumni.caltech.edu ++ ++If you use the zlib library in a product, we would appreciate *not* ++receiving lengthy legal documents to sign. The sources are provided ++for free but without warranty of any kind. The library has been ++entirely written by Jean-loup Gailly and Mark Adler; it does not ++include third-party code. ++ ++If you redistribute modified sources, we would appreciate that you include ++in the file ChangeLog history information documenting your changes. +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/README.freeswan Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,13 @@ ++The only changes made to these files for use in FreeS/WAN are: ++ ++ - In zconf.h, macros are defined to prefix global symbols with "ipcomp_" ++ (or "_ipcomp"), when compiled with -DIPCOMP_PREFIX. ++ - The copyright strings are defined local (static) ++ ++ The above changes are made to avoid name collisions with ppp_deflate ++ and ext2compr. ++ ++ - Files not needed for FreeS/WAN have been removed ++ ++ See the "README" file for information about where to obtain the complete ++ zlib package. +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/adler32.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,49 @@ ++/* adler32.c -- compute the Adler-32 checksum of a data stream ++ * Copyright (C) 1995-2002 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* @(#) $Id: adler32.c,v 1.4 2002/04/24 07:55:32 mcr Exp $ */ ++ ++#include ++#include "zconf.h" ++ ++#define BASE 65521L /* largest prime smaller than 65536 */ ++#define NMAX 5552 ++/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ ++ ++#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} ++#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); ++#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); ++#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); ++#define DO16(buf) DO8(buf,0); DO8(buf,8); ++ ++/* ========================================================================= */ ++uLong ZEXPORT adler32(adler, buf, len) ++ uLong adler; ++ const Bytef *buf; ++ uInt len; ++{ ++ unsigned long s1 = adler & 0xffff; ++ unsigned long s2 = (adler >> 16) & 0xffff; ++ int k; ++ ++ if (buf == Z_NULL) return 1L; ++ ++ while (len > 0) { ++ k = len < NMAX ? len : NMAX; ++ len -= k; ++ while (k >= 16) { ++ DO16(buf); ++ buf += 16; ++ k -= 16; ++ } ++ if (k != 0) do { ++ s1 += *buf++; ++ s2 += s1; ++ } while (--k); ++ s1 %= BASE; ++ s2 %= BASE; ++ } ++ return (s2 << 16) | s1; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/deflate.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,1351 @@ ++/* deflate.c -- compress data using the deflation algorithm ++ * Copyright (C) 1995-2002 Jean-loup Gailly. ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* ++ * ALGORITHM ++ * ++ * The "deflation" process depends on being able to identify portions ++ * of the input text which are identical to earlier input (within a ++ * sliding window trailing behind the input currently being processed). ++ * ++ * The most straightforward technique turns out to be the fastest for ++ * most input files: try all possible matches and select the longest. ++ * The key feature of this algorithm is that insertions into the string ++ * dictionary are very simple and thus fast, and deletions are avoided ++ * completely. Insertions are performed at each input character, whereas ++ * string matches are performed only when the previous match ends. So it ++ * is preferable to spend more time in matches to allow very fast string ++ * insertions and avoid deletions. The matching algorithm for small ++ * strings is inspired from that of Rabin & Karp. A brute force approach ++ * is used to find longer strings when a small match has been found. ++ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze ++ * (by Leonid Broukhis). ++ * A previous version of this file used a more sophisticated algorithm ++ * (by Fiala and Greene) which is guaranteed to run in linear amortized ++ * time, but has a larger average cost, uses more memory and is patented. ++ * However the F&G algorithm may be faster for some highly redundant ++ * files if the parameter max_chain_length (described below) is too large. ++ * ++ * ACKNOWLEDGEMENTS ++ * ++ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and ++ * I found it in 'freeze' written by Leonid Broukhis. ++ * Thanks to many people for bug reports and testing. ++ * ++ * REFERENCES ++ * ++ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". ++ * Available in ftp://ds.internic.net/rfc/rfc1951.txt ++ * ++ * A description of the Rabin and Karp algorithm is given in the book ++ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. ++ * ++ * Fiala,E.R., and Greene,D.H. ++ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 ++ * ++ */ ++ ++/* @(#) $Id: deflate.c,v 1.3 2002/04/24 07:36:44 mcr Exp $ */ ++ ++#include "deflate.h" ++ ++local const char deflate_copyright[] = ++ " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly "; ++/* ++ If you use the zlib library in a product, an acknowledgment is welcome ++ in the documentation of your product. If for some reason you cannot ++ include such an acknowledgment, I would appreciate that you keep this ++ copyright string in the executable of your product. ++ */ ++ ++/* =========================================================================== ++ * Function prototypes. ++ */ ++typedef enum { ++ need_more, /* block not completed, need more input or more output */ ++ block_done, /* block flush performed */ ++ finish_started, /* finish started, need only more output at next deflate */ ++ finish_done /* finish done, accept no more input or output */ ++} block_state; ++ ++typedef block_state (*compress_func) OF((deflate_state *s, int flush)); ++/* Compression function. Returns the block state after the call. */ ++ ++local void fill_window OF((deflate_state *s)); ++local block_state deflate_stored OF((deflate_state *s, int flush)); ++local block_state deflate_fast OF((deflate_state *s, int flush)); ++local block_state deflate_slow OF((deflate_state *s, int flush)); ++local void lm_init OF((deflate_state *s)); ++local void putShortMSB OF((deflate_state *s, uInt b)); ++local void flush_pending OF((z_streamp strm)); ++local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); ++#ifdef ASMV ++ void match_init OF((void)); /* asm code initialization */ ++ uInt longest_match OF((deflate_state *s, IPos cur_match)); ++#else ++local uInt longest_match OF((deflate_state *s, IPos cur_match)); ++#endif ++ ++#ifdef DEBUG ++local void check_match OF((deflate_state *s, IPos start, IPos match, ++ int length)); ++#endif ++ ++/* =========================================================================== ++ * Local data ++ */ ++ ++#define NIL 0 ++/* Tail of hash chains */ ++ ++#ifndef TOO_FAR ++# define TOO_FAR 4096 ++#endif ++/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ ++ ++#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) ++/* Minimum amount of lookahead, except at the end of the input file. ++ * See deflate.c for comments about the MIN_MATCH+1. ++ */ ++ ++/* Values for max_lazy_match, good_match and max_chain_length, depending on ++ * the desired pack level (0..9). The values given below have been tuned to ++ * exclude worst case performance for pathological files. Better values may be ++ * found for specific files. ++ */ ++typedef struct config_s { ++ ush good_length; /* reduce lazy search above this match length */ ++ ush max_lazy; /* do not perform lazy search above this match length */ ++ ush nice_length; /* quit search above this match length */ ++ ush max_chain; ++ compress_func func; ++} config; ++ ++local const config configuration_table[10] = { ++/* good lazy nice chain */ ++/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ ++/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ ++/* 2 */ {4, 5, 16, 8, deflate_fast}, ++/* 3 */ {4, 6, 32, 32, deflate_fast}, ++ ++/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ ++/* 5 */ {8, 16, 32, 32, deflate_slow}, ++/* 6 */ {8, 16, 128, 128, deflate_slow}, ++/* 7 */ {8, 32, 128, 256, deflate_slow}, ++/* 8 */ {32, 128, 258, 1024, deflate_slow}, ++/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ ++ ++/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 ++ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different ++ * meaning. ++ */ ++ ++#define EQUAL 0 ++/* result of memcmp for equal strings */ ++ ++struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ ++ ++/* =========================================================================== ++ * Update a hash value with the given input byte ++ * IN assertion: all calls to to UPDATE_HASH are made with consecutive ++ * input characters, so that a running hash key can be computed from the ++ * previous key instead of complete recalculation each time. ++ */ ++#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) ++ ++ ++/* =========================================================================== ++ * Insert string str in the dictionary and set match_head to the previous head ++ * of the hash chain (the most recent string with same hash key). Return ++ * the previous length of the hash chain. ++ * If this file is compiled with -DFASTEST, the compression level is forced ++ * to 1, and no hash chains are maintained. ++ * IN assertion: all calls to to INSERT_STRING are made with consecutive ++ * input characters and the first MIN_MATCH bytes of str are valid ++ * (except for the last MIN_MATCH-1 bytes of the input file). ++ */ ++#ifdef FASTEST ++#define INSERT_STRING(s, str, match_head) \ ++ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ ++ match_head = s->head[s->ins_h], \ ++ s->head[s->ins_h] = (Pos)(str)) ++#else ++#define INSERT_STRING(s, str, match_head) \ ++ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ ++ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ ++ s->head[s->ins_h] = (Pos)(str)) ++#endif ++ ++/* =========================================================================== ++ * Initialize the hash table (avoiding 64K overflow for 16 bit systems). ++ * prev[] will be initialized on the fly. ++ */ ++#define CLEAR_HASH(s) \ ++ s->head[s->hash_size-1] = NIL; \ ++ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); ++ ++/* ========================================================================= */ ++int ZEXPORT deflateInit_(strm, level, version, stream_size) ++ z_streamp strm; ++ int level; ++ const char *version; ++ int stream_size; ++{ ++ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, ++ Z_DEFAULT_STRATEGY, version, stream_size); ++ /* To do: ignore strm->next_in if we use it as window */ ++} ++ ++/* ========================================================================= */ ++int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, ++ version, stream_size) ++ z_streamp strm; ++ int level; ++ int method; ++ int windowBits; ++ int memLevel; ++ int strategy; ++ const char *version; ++ int stream_size; ++{ ++ deflate_state *s; ++ int noheader = 0; ++ static const char* my_version = ZLIB_VERSION; ++ ++ ushf *overlay; ++ /* We overlay pending_buf and d_buf+l_buf. This works since the average ++ * output size for (length,distance) codes is <= 24 bits. ++ */ ++ ++ if (version == Z_NULL || version[0] != my_version[0] || ++ stream_size != sizeof(z_stream)) { ++ return Z_VERSION_ERROR; ++ } ++ if (strm == Z_NULL) return Z_STREAM_ERROR; ++ ++ strm->msg = Z_NULL; ++ if (strm->zalloc == Z_NULL) { ++ return Z_STREAM_ERROR; ++/* strm->zalloc = zcalloc; ++ strm->opaque = (voidpf)0;*/ ++ } ++ if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */ ++ ++ if (level == Z_DEFAULT_COMPRESSION) level = 6; ++#ifdef FASTEST ++ level = 1; ++#endif ++ ++ if (windowBits < 0) { /* undocumented feature: suppress zlib header */ ++ noheader = 1; ++ windowBits = -windowBits; ++ } ++ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || ++ windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || ++ strategy < 0 || strategy > Z_HUFFMAN_ONLY) { ++ return Z_STREAM_ERROR; ++ } ++ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); ++ if (s == Z_NULL) return Z_MEM_ERROR; ++ strm->state = (struct internal_state FAR *)s; ++ s->strm = strm; ++ ++ s->noheader = noheader; ++ s->w_bits = windowBits; ++ s->w_size = 1 << s->w_bits; ++ s->w_mask = s->w_size - 1; ++ ++ s->hash_bits = memLevel + 7; ++ s->hash_size = 1 << s->hash_bits; ++ s->hash_mask = s->hash_size - 1; ++ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); ++ ++ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); ++ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); ++ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); ++ ++ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ ++ ++ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); ++ s->pending_buf = (uchf *) overlay; ++ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); ++ ++ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || ++ s->pending_buf == Z_NULL) { ++ strm->msg = ERR_MSG(Z_MEM_ERROR); ++ deflateEnd (strm); ++ return Z_MEM_ERROR; ++ } ++ s->d_buf = overlay + s->lit_bufsize/sizeof(ush); ++ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; ++ ++ s->level = level; ++ s->strategy = strategy; ++ s->method = (Byte)method; ++ ++ return deflateReset(strm); ++} ++ ++/* ========================================================================= */ ++int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) ++ z_streamp strm; ++ const Bytef *dictionary; ++ uInt dictLength; ++{ ++ deflate_state *s; ++ uInt length = dictLength; ++ uInt n; ++ IPos hash_head = 0; ++ ++ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || ++ strm->state->status != INIT_STATE) return Z_STREAM_ERROR; ++ ++ s = strm->state; ++ strm->adler = adler32(strm->adler, dictionary, dictLength); ++ ++ if (length < MIN_MATCH) return Z_OK; ++ if (length > MAX_DIST(s)) { ++ length = MAX_DIST(s); ++#ifndef USE_DICT_HEAD ++ dictionary += dictLength - length; /* use the tail of the dictionary */ ++#endif ++ } ++ zmemcpy(s->window, dictionary, length); ++ s->strstart = length; ++ s->block_start = (long)length; ++ ++ /* Insert all strings in the hash table (except for the last two bytes). ++ * s->lookahead stays null, so s->ins_h will be recomputed at the next ++ * call of fill_window. ++ */ ++ s->ins_h = s->window[0]; ++ UPDATE_HASH(s, s->ins_h, s->window[1]); ++ for (n = 0; n <= length - MIN_MATCH; n++) { ++ INSERT_STRING(s, n, hash_head); ++ } ++ if (hash_head) hash_head = 0; /* to make compiler happy */ ++ return Z_OK; ++} ++ ++/* ========================================================================= */ ++int ZEXPORT deflateReset (strm) ++ z_streamp strm; ++{ ++ deflate_state *s; ++ ++ if (strm == Z_NULL || strm->state == Z_NULL || ++ strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; ++ ++ strm->total_in = strm->total_out = 0; ++ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ ++ strm->data_type = Z_UNKNOWN; ++ ++ s = (deflate_state *)strm->state; ++ s->pending = 0; ++ s->pending_out = s->pending_buf; ++ ++ if (s->noheader < 0) { ++ s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ ++ } ++ s->status = s->noheader ? BUSY_STATE : INIT_STATE; ++ strm->adler = 1; ++ s->last_flush = Z_NO_FLUSH; ++ ++ _tr_init(s); ++ lm_init(s); ++ ++ return Z_OK; ++} ++ ++/* ========================================================================= */ ++int ZEXPORT deflateParams(strm, level, strategy) ++ z_streamp strm; ++ int level; ++ int strategy; ++{ ++ deflate_state *s; ++ compress_func func; ++ int err = Z_OK; ++ ++ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; ++ s = strm->state; ++ ++ if (level == Z_DEFAULT_COMPRESSION) { ++ level = 6; ++ } ++ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { ++ return Z_STREAM_ERROR; ++ } ++ func = configuration_table[s->level].func; ++ ++ if (func != configuration_table[level].func && strm->total_in != 0) { ++ /* Flush the last buffer: */ ++ err = deflate(strm, Z_PARTIAL_FLUSH); ++ } ++ if (s->level != level) { ++ s->level = level; ++ s->max_lazy_match = configuration_table[level].max_lazy; ++ s->good_match = configuration_table[level].good_length; ++ s->nice_match = configuration_table[level].nice_length; ++ s->max_chain_length = configuration_table[level].max_chain; ++ } ++ s->strategy = strategy; ++ return err; ++} ++ ++/* ========================================================================= ++ * Put a short in the pending buffer. The 16-bit value is put in MSB order. ++ * IN assertion: the stream state is correct and there is enough room in ++ * pending_buf. ++ */ ++local void putShortMSB (s, b) ++ deflate_state *s; ++ uInt b; ++{ ++ put_byte(s, (Byte)(b >> 8)); ++ put_byte(s, (Byte)(b & 0xff)); ++} ++ ++/* ========================================================================= ++ * Flush as much pending output as possible. All deflate() output goes ++ * through this function so some applications may wish to modify it ++ * to avoid allocating a large strm->next_out buffer and copying into it. ++ * (See also read_buf()). ++ */ ++local void flush_pending(strm) ++ z_streamp strm; ++{ ++ unsigned len = strm->state->pending; ++ ++ if (len > strm->avail_out) len = strm->avail_out; ++ if (len == 0) return; ++ ++ zmemcpy(strm->next_out, strm->state->pending_out, len); ++ strm->next_out += len; ++ strm->state->pending_out += len; ++ strm->total_out += len; ++ strm->avail_out -= len; ++ strm->state->pending -= len; ++ if (strm->state->pending == 0) { ++ strm->state->pending_out = strm->state->pending_buf; ++ } ++} ++ ++/* ========================================================================= */ ++int ZEXPORT deflate (strm, flush) ++ z_streamp strm; ++ int flush; ++{ ++ int old_flush; /* value of flush param for previous deflate call */ ++ deflate_state *s; ++ ++ if (strm == Z_NULL || strm->state == Z_NULL || ++ flush > Z_FINISH || flush < 0) { ++ return Z_STREAM_ERROR; ++ } ++ s = strm->state; ++ ++ if (strm->next_out == Z_NULL || ++ (strm->next_in == Z_NULL && strm->avail_in != 0) || ++ (s->status == FINISH_STATE && flush != Z_FINISH)) { ++ ERR_RETURN(strm, Z_STREAM_ERROR); ++ } ++ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); ++ ++ s->strm = strm; /* just in case */ ++ old_flush = s->last_flush; ++ s->last_flush = flush; ++ ++ /* Write the zlib header */ ++ if (s->status == INIT_STATE) { ++ ++ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; ++ uInt level_flags = (s->level-1) >> 1; ++ ++ if (level_flags > 3) level_flags = 3; ++ header |= (level_flags << 6); ++ if (s->strstart != 0) header |= PRESET_DICT; ++ header += 31 - (header % 31); ++ ++ s->status = BUSY_STATE; ++ putShortMSB(s, header); ++ ++ /* Save the adler32 of the preset dictionary: */ ++ if (s->strstart != 0) { ++ putShortMSB(s, (uInt)(strm->adler >> 16)); ++ putShortMSB(s, (uInt)(strm->adler & 0xffff)); ++ } ++ strm->adler = 1L; ++ } ++ ++ /* Flush as much pending output as possible */ ++ if (s->pending != 0) { ++ flush_pending(strm); ++ if (strm->avail_out == 0) { ++ /* Since avail_out is 0, deflate will be called again with ++ * more output space, but possibly with both pending and ++ * avail_in equal to zero. There won't be anything to do, ++ * but this is not an error situation so make sure we ++ * return OK instead of BUF_ERROR at next call of deflate: ++ */ ++ s->last_flush = -1; ++ return Z_OK; ++ } ++ ++ /* Make sure there is something to do and avoid duplicate consecutive ++ * flushes. For repeated and useless calls with Z_FINISH, we keep ++ * returning Z_STREAM_END instead of Z_BUFF_ERROR. ++ */ ++ } else if (strm->avail_in == 0 && flush <= old_flush && ++ flush != Z_FINISH) { ++ ERR_RETURN(strm, Z_BUF_ERROR); ++ } ++ ++ /* User must not provide more input after the first FINISH: */ ++ if (s->status == FINISH_STATE && strm->avail_in != 0) { ++ ERR_RETURN(strm, Z_BUF_ERROR); ++ } ++ ++ /* Start a new block or continue the current one. ++ */ ++ if (strm->avail_in != 0 || s->lookahead != 0 || ++ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { ++ block_state bstate; ++ ++ bstate = (*(configuration_table[s->level].func))(s, flush); ++ ++ if (bstate == finish_started || bstate == finish_done) { ++ s->status = FINISH_STATE; ++ } ++ if (bstate == need_more || bstate == finish_started) { ++ if (strm->avail_out == 0) { ++ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ ++ } ++ return Z_OK; ++ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call ++ * of deflate should use the same flush parameter to make sure ++ * that the flush is complete. So we don't have to output an ++ * empty block here, this will be done at next call. This also ++ * ensures that for a very small output buffer, we emit at most ++ * one empty block. ++ */ ++ } ++ if (bstate == block_done) { ++ if (flush == Z_PARTIAL_FLUSH) { ++ _tr_align(s); ++ } else { /* FULL_FLUSH or SYNC_FLUSH */ ++ _tr_stored_block(s, (char*)0, 0L, 0); ++ /* For a full flush, this empty block will be recognized ++ * as a special marker by inflate_sync(). ++ */ ++ if (flush == Z_FULL_FLUSH) { ++ CLEAR_HASH(s); /* forget history */ ++ } ++ } ++ flush_pending(strm); ++ if (strm->avail_out == 0) { ++ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ ++ return Z_OK; ++ } ++ } ++ } ++ Assert(strm->avail_out > 0, "bug2"); ++ ++ if (flush != Z_FINISH) return Z_OK; ++ if (s->noheader) return Z_STREAM_END; ++ ++ /* Write the zlib trailer (adler32) */ ++ putShortMSB(s, (uInt)(strm->adler >> 16)); ++ putShortMSB(s, (uInt)(strm->adler & 0xffff)); ++ flush_pending(strm); ++ /* If avail_out is zero, the application will call deflate again ++ * to flush the rest. ++ */ ++ s->noheader = -1; /* write the trailer only once! */ ++ return s->pending != 0 ? Z_OK : Z_STREAM_END; ++} ++ ++/* ========================================================================= */ ++int ZEXPORT deflateEnd (strm) ++ z_streamp strm; ++{ ++ int status; ++ ++ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; ++ ++ status = strm->state->status; ++ if (status != INIT_STATE && status != BUSY_STATE && ++ status != FINISH_STATE) { ++ return Z_STREAM_ERROR; ++ } ++ ++ /* Deallocate in reverse order of allocations: */ ++ TRY_FREE(strm, strm->state->pending_buf); ++ TRY_FREE(strm, strm->state->head); ++ TRY_FREE(strm, strm->state->prev); ++ TRY_FREE(strm, strm->state->window); ++ ++ ZFREE(strm, strm->state); ++ strm->state = Z_NULL; ++ ++ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; ++} ++ ++/* ========================================================================= ++ * Copy the source state to the destination state. ++ * To simplify the source, this is not supported for 16-bit MSDOS (which ++ * doesn't have enough memory anyway to duplicate compression states). ++ */ ++int ZEXPORT deflateCopy (dest, source) ++ z_streamp dest; ++ z_streamp source; ++{ ++#ifdef MAXSEG_64K ++ return Z_STREAM_ERROR; ++#else ++ deflate_state *ds; ++ deflate_state *ss; ++ ushf *overlay; ++ ++ ++ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { ++ return Z_STREAM_ERROR; ++ } ++ ++ ss = source->state; ++ ++ *dest = *source; ++ ++ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); ++ if (ds == Z_NULL) return Z_MEM_ERROR; ++ dest->state = (struct internal_state FAR *) ds; ++ *ds = *ss; ++ ds->strm = dest; ++ ++ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ++ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ++ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); ++ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); ++ ds->pending_buf = (uchf *) overlay; ++ ++ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ++ ds->pending_buf == Z_NULL) { ++ deflateEnd (dest); ++ return Z_MEM_ERROR; ++ } ++ /* following zmemcpy do not work for 16-bit MSDOS */ ++ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); ++ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); ++ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); ++ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); ++ ++ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); ++ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); ++ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; ++ ++ ds->l_desc.dyn_tree = ds->dyn_ltree; ++ ds->d_desc.dyn_tree = ds->dyn_dtree; ++ ds->bl_desc.dyn_tree = ds->bl_tree; ++ ++ return Z_OK; ++#endif ++} ++ ++/* =========================================================================== ++ * Read a new buffer from the current input stream, update the adler32 ++ * and total number of bytes read. All deflate() input goes through ++ * this function so some applications may wish to modify it to avoid ++ * allocating a large strm->next_in buffer and copying from it. ++ * (See also flush_pending()). ++ */ ++local int read_buf(strm, buf, size) ++ z_streamp strm; ++ Bytef *buf; ++ unsigned size; ++{ ++ unsigned len = strm->avail_in; ++ ++ if (len > size) len = size; ++ if (len == 0) return 0; ++ ++ strm->avail_in -= len; ++ ++ if (!strm->state->noheader) { ++ strm->adler = adler32(strm->adler, strm->next_in, len); ++ } ++ zmemcpy(buf, strm->next_in, len); ++ strm->next_in += len; ++ strm->total_in += len; ++ ++ return (int)len; ++} ++ ++/* =========================================================================== ++ * Initialize the "longest match" routines for a new zlib stream ++ */ ++local void lm_init (s) ++ deflate_state *s; ++{ ++ s->window_size = (ulg)2L*s->w_size; ++ ++ CLEAR_HASH(s); ++ ++ /* Set the default configuration parameters: ++ */ ++ s->max_lazy_match = configuration_table[s->level].max_lazy; ++ s->good_match = configuration_table[s->level].good_length; ++ s->nice_match = configuration_table[s->level].nice_length; ++ s->max_chain_length = configuration_table[s->level].max_chain; ++ ++ s->strstart = 0; ++ s->block_start = 0L; ++ s->lookahead = 0; ++ s->match_length = s->prev_length = MIN_MATCH-1; ++ s->match_available = 0; ++ s->ins_h = 0; ++#ifdef ASMV ++ match_init(); /* initialize the asm code */ ++#endif ++} ++ ++/* =========================================================================== ++ * Set match_start to the longest match starting at the given string and ++ * return its length. Matches shorter or equal to prev_length are discarded, ++ * in which case the result is equal to prev_length and match_start is ++ * garbage. ++ * IN assertions: cur_match is the head of the hash chain for the current ++ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 ++ * OUT assertion: the match length is not greater than s->lookahead. ++ */ ++#ifndef ASMV ++/* For 80x86 and 680x0, an optimized version will be provided in match.asm or ++ * match.S. The code will be functionally equivalent. ++ */ ++#ifndef FASTEST ++local uInt longest_match(s, cur_match) ++ deflate_state *s; ++ IPos cur_match; /* current match */ ++{ ++ unsigned chain_length = s->max_chain_length;/* max hash chain length */ ++ register Bytef *scan = s->window + s->strstart; /* current string */ ++ register Bytef *match; /* matched string */ ++ register int len; /* length of current match */ ++ int best_len = s->prev_length; /* best match length so far */ ++ int nice_match = s->nice_match; /* stop if match long enough */ ++ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? ++ s->strstart - (IPos)MAX_DIST(s) : NIL; ++ /* Stop when cur_match becomes <= limit. To simplify the code, ++ * we prevent matches with the string of window index 0. ++ */ ++ Posf *prev = s->prev; ++ uInt wmask = s->w_mask; ++ ++#ifdef UNALIGNED_OK ++ /* Compare two bytes at a time. Note: this is not always beneficial. ++ * Try with and without -DUNALIGNED_OK to check. ++ */ ++ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; ++ register ush scan_start = *(ushf*)scan; ++ register ush scan_end = *(ushf*)(scan+best_len-1); ++#else ++ register Bytef *strend = s->window + s->strstart + MAX_MATCH; ++ register Byte scan_end1 = scan[best_len-1]; ++ register Byte scan_end = scan[best_len]; ++#endif ++ ++ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. ++ * It is easy to get rid of this optimization if necessary. ++ */ ++ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); ++ ++ /* Do not waste too much time if we already have a good match: */ ++ if (s->prev_length >= s->good_match) { ++ chain_length >>= 2; ++ } ++ /* Do not look for matches beyond the end of the input. This is necessary ++ * to make deflate deterministic. ++ */ ++ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; ++ ++ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); ++ ++ do { ++ Assert(cur_match < s->strstart, "no future"); ++ match = s->window + cur_match; ++ ++ /* Skip to next match if the match length cannot increase ++ * or if the match length is less than 2: ++ */ ++#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) ++ /* This code assumes sizeof(unsigned short) == 2. Do not use ++ * UNALIGNED_OK if your compiler uses a different size. ++ */ ++ if (*(ushf*)(match+best_len-1) != scan_end || ++ *(ushf*)match != scan_start) continue; ++ ++ /* It is not necessary to compare scan[2] and match[2] since they are ++ * always equal when the other bytes match, given that the hash keys ++ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at ++ * strstart+3, +5, ... up to strstart+257. We check for insufficient ++ * lookahead only every 4th comparison; the 128th check will be made ++ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is ++ * necessary to put more guard bytes at the end of the window, or ++ * to check more often for insufficient lookahead. ++ */ ++ Assert(scan[2] == match[2], "scan[2]?"); ++ scan++, match++; ++ do { ++ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && ++ *(ushf*)(scan+=2) == *(ushf*)(match+=2) && ++ *(ushf*)(scan+=2) == *(ushf*)(match+=2) && ++ *(ushf*)(scan+=2) == *(ushf*)(match+=2) && ++ scan < strend); ++ /* The funny "do {}" generates better code on most compilers */ ++ ++ /* Here, scan <= window+strstart+257 */ ++ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); ++ if (*scan == *match) scan++; ++ ++ len = (MAX_MATCH - 1) - (int)(strend-scan); ++ scan = strend - (MAX_MATCH-1); ++ ++#else /* UNALIGNED_OK */ ++ ++ if (match[best_len] != scan_end || ++ match[best_len-1] != scan_end1 || ++ *match != *scan || ++ *++match != scan[1]) continue; ++ ++ /* The check at best_len-1 can be removed because it will be made ++ * again later. (This heuristic is not always a win.) ++ * It is not necessary to compare scan[2] and match[2] since they ++ * are always equal when the other bytes match, given that ++ * the hash keys are equal and that HASH_BITS >= 8. ++ */ ++ scan += 2, match++; ++ Assert(*scan == *match, "match[2]?"); ++ ++ /* We check for insufficient lookahead only every 8th comparison; ++ * the 256th check will be made at strstart+258. ++ */ ++ do { ++ } while (*++scan == *++match && *++scan == *++match && ++ *++scan == *++match && *++scan == *++match && ++ *++scan == *++match && *++scan == *++match && ++ *++scan == *++match && *++scan == *++match && ++ scan < strend); ++ ++ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); ++ ++ len = MAX_MATCH - (int)(strend - scan); ++ scan = strend - MAX_MATCH; ++ ++#endif /* UNALIGNED_OK */ ++ ++ if (len > best_len) { ++ s->match_start = cur_match; ++ best_len = len; ++ if (len >= nice_match) break; ++#ifdef UNALIGNED_OK ++ scan_end = *(ushf*)(scan+best_len-1); ++#else ++ scan_end1 = scan[best_len-1]; ++ scan_end = scan[best_len]; ++#endif ++ } ++ } while ((cur_match = prev[cur_match & wmask]) > limit ++ && --chain_length != 0); ++ ++ if ((uInt)best_len <= s->lookahead) return (uInt)best_len; ++ return s->lookahead; ++} ++ ++#else /* FASTEST */ ++/* --------------------------------------------------------------------------- ++ * Optimized version for level == 1 only ++ */ ++local uInt longest_match(s, cur_match) ++ deflate_state *s; ++ IPos cur_match; /* current match */ ++{ ++ register Bytef *scan = s->window + s->strstart; /* current string */ ++ register Bytef *match; /* matched string */ ++ register int len; /* length of current match */ ++ register Bytef *strend = s->window + s->strstart + MAX_MATCH; ++ ++ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. ++ * It is easy to get rid of this optimization if necessary. ++ */ ++ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); ++ ++ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); ++ ++ Assert(cur_match < s->strstart, "no future"); ++ ++ match = s->window + cur_match; ++ ++ /* Return failure if the match length is less than 2: ++ */ ++ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; ++ ++ /* The check at best_len-1 can be removed because it will be made ++ * again later. (This heuristic is not always a win.) ++ * It is not necessary to compare scan[2] and match[2] since they ++ * are always equal when the other bytes match, given that ++ * the hash keys are equal and that HASH_BITS >= 8. ++ */ ++ scan += 2, match += 2; ++ Assert(*scan == *match, "match[2]?"); ++ ++ /* We check for insufficient lookahead only every 8th comparison; ++ * the 256th check will be made at strstart+258. ++ */ ++ do { ++ } while (*++scan == *++match && *++scan == *++match && ++ *++scan == *++match && *++scan == *++match && ++ *++scan == *++match && *++scan == *++match && ++ *++scan == *++match && *++scan == *++match && ++ scan < strend); ++ ++ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); ++ ++ len = MAX_MATCH - (int)(strend - scan); ++ ++ if (len < MIN_MATCH) return MIN_MATCH - 1; ++ ++ s->match_start = cur_match; ++ return len <= s->lookahead ? len : s->lookahead; ++} ++#endif /* FASTEST */ ++#endif /* ASMV */ ++ ++#ifdef DEBUG ++/* =========================================================================== ++ * Check that the match at match_start is indeed a match. ++ */ ++local void check_match(s, start, match, length) ++ deflate_state *s; ++ IPos start, match; ++ int length; ++{ ++ /* check that the match is indeed a match */ ++ if (zmemcmp(s->window + match, ++ s->window + start, length) != EQUAL) { ++ fprintf(stderr, " start %u, match %u, length %d\n", ++ start, match, length); ++ do { ++ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); ++ } while (--length != 0); ++ z_error("invalid match"); ++ } ++ if (z_verbose > 1) { ++ fprintf(stderr,"\\[%d,%d]", start-match, length); ++ do { putc(s->window[start++], stderr); } while (--length != 0); ++ } ++} ++#else ++# define check_match(s, start, match, length) ++#endif ++ ++/* =========================================================================== ++ * Fill the window when the lookahead becomes insufficient. ++ * Updates strstart and lookahead. ++ * ++ * IN assertion: lookahead < MIN_LOOKAHEAD ++ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD ++ * At least one byte has been read, or avail_in == 0; reads are ++ * performed for at least two bytes (required for the zip translate_eol ++ * option -- not supported here). ++ */ ++local void fill_window(s) ++ deflate_state *s; ++{ ++ register unsigned n, m; ++ register Posf *p; ++ unsigned more; /* Amount of free space at the end of the window. */ ++ uInt wsize = s->w_size; ++ ++ do { ++ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); ++ ++ /* Deal with !@#$% 64K limit: */ ++ if (more == 0 && s->strstart == 0 && s->lookahead == 0) { ++ more = wsize; ++ ++ } else if (more == (unsigned)(-1)) { ++ /* Very unlikely, but possible on 16 bit machine if strstart == 0 ++ * and lookahead == 1 (input done one byte at time) ++ */ ++ more--; ++ ++ /* If the window is almost full and there is insufficient lookahead, ++ * move the upper half to the lower one to make room in the upper half. ++ */ ++ } else if (s->strstart >= wsize+MAX_DIST(s)) { ++ ++ zmemcpy(s->window, s->window+wsize, (unsigned)wsize); ++ s->match_start -= wsize; ++ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ ++ s->block_start -= (long) wsize; ++ ++ /* Slide the hash table (could be avoided with 32 bit values ++ at the expense of memory usage). We slide even when level == 0 ++ to keep the hash table consistent if we switch back to level > 0 ++ later. (Using level 0 permanently is not an optimal usage of ++ zlib, so we don't care about this pathological case.) ++ */ ++ n = s->hash_size; ++ p = &s->head[n]; ++ do { ++ m = *--p; ++ *p = (Pos)(m >= wsize ? m-wsize : NIL); ++ } while (--n); ++ ++ n = wsize; ++#ifndef FASTEST ++ p = &s->prev[n]; ++ do { ++ m = *--p; ++ *p = (Pos)(m >= wsize ? m-wsize : NIL); ++ /* If n is not on any hash chain, prev[n] is garbage but ++ * its value will never be used. ++ */ ++ } while (--n); ++#endif ++ more += wsize; ++ } ++ if (s->strm->avail_in == 0) return; ++ ++ /* If there was no sliding: ++ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && ++ * more == window_size - lookahead - strstart ++ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) ++ * => more >= window_size - 2*WSIZE + 2 ++ * In the BIG_MEM or MMAP case (not yet supported), ++ * window_size == input_size + MIN_LOOKAHEAD && ++ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. ++ * Otherwise, window_size == 2*WSIZE so more >= 2. ++ * If there was sliding, more >= WSIZE. So in all cases, more >= 2. ++ */ ++ Assert(more >= 2, "more < 2"); ++ ++ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); ++ s->lookahead += n; ++ ++ /* Initialize the hash value now that we have some input: */ ++ if (s->lookahead >= MIN_MATCH) { ++ s->ins_h = s->window[s->strstart]; ++ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); ++#if MIN_MATCH != 3 ++ Call UPDATE_HASH() MIN_MATCH-3 more times ++#endif ++ } ++ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, ++ * but this is not important since only literal bytes will be emitted. ++ */ ++ ++ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); ++} ++ ++/* =========================================================================== ++ * Flush the current block, with given end-of-file flag. ++ * IN assertion: strstart is set to the end of the current match. ++ */ ++#define FLUSH_BLOCK_ONLY(s, eof) { \ ++ _tr_flush_block(s, (s->block_start >= 0L ? \ ++ (charf *)&s->window[(unsigned)s->block_start] : \ ++ (charf *)Z_NULL), \ ++ (ulg)((long)s->strstart - s->block_start), \ ++ (eof)); \ ++ s->block_start = s->strstart; \ ++ flush_pending(s->strm); \ ++ Tracev((stderr,"[FLUSH]")); \ ++} ++ ++/* Same but force premature exit if necessary. */ ++#define FLUSH_BLOCK(s, eof) { \ ++ FLUSH_BLOCK_ONLY(s, eof); \ ++ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ ++} ++ ++/* =========================================================================== ++ * Copy without compression as much as possible from the input stream, return ++ * the current block state. ++ * This function does not insert new strings in the dictionary since ++ * uncompressible data is probably not useful. This function is used ++ * only for the level=0 compression option. ++ * NOTE: this function should be optimized to avoid extra copying from ++ * window to pending_buf. ++ */ ++local block_state deflate_stored(s, flush) ++ deflate_state *s; ++ int flush; ++{ ++ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited ++ * to pending_buf_size, and each stored block has a 5 byte header: ++ */ ++ ulg max_block_size = 0xffff; ++ ulg max_start; ++ ++ if (max_block_size > s->pending_buf_size - 5) { ++ max_block_size = s->pending_buf_size - 5; ++ } ++ ++ /* Copy as much as possible from input to output: */ ++ for (;;) { ++ /* Fill the window as much as possible: */ ++ if (s->lookahead <= 1) { ++ ++ Assert(s->strstart < s->w_size+MAX_DIST(s) || ++ s->block_start >= (long)s->w_size, "slide too late"); ++ ++ fill_window(s); ++ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; ++ ++ if (s->lookahead == 0) break; /* flush the current block */ ++ } ++ Assert(s->block_start >= 0L, "block gone"); ++ ++ s->strstart += s->lookahead; ++ s->lookahead = 0; ++ ++ /* Emit a stored block if pending_buf will be full: */ ++ max_start = s->block_start + max_block_size; ++ if (s->strstart == 0 || (ulg)s->strstart >= max_start) { ++ /* strstart == 0 is possible when wraparound on 16-bit machine */ ++ s->lookahead = (uInt)(s->strstart - max_start); ++ s->strstart = (uInt)max_start; ++ FLUSH_BLOCK(s, 0); ++ } ++ /* Flush if we may have to slide, otherwise block_start may become ++ * negative and the data will be gone: ++ */ ++ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { ++ FLUSH_BLOCK(s, 0); ++ } ++ } ++ FLUSH_BLOCK(s, flush == Z_FINISH); ++ return flush == Z_FINISH ? finish_done : block_done; ++} ++ ++/* =========================================================================== ++ * Compress as much as possible from the input stream, return the current ++ * block state. ++ * This function does not perform lazy evaluation of matches and inserts ++ * new strings in the dictionary only for unmatched strings or for short ++ * matches. It is used only for the fast compression options. ++ */ ++local block_state deflate_fast(s, flush) ++ deflate_state *s; ++ int flush; ++{ ++ IPos hash_head = NIL; /* head of the hash chain */ ++ int bflush; /* set if current block must be flushed */ ++ ++ for (;;) { ++ /* Make sure that we always have enough lookahead, except ++ * at the end of the input file. We need MAX_MATCH bytes ++ * for the next match, plus MIN_MATCH bytes to insert the ++ * string following the next match. ++ */ ++ if (s->lookahead < MIN_LOOKAHEAD) { ++ fill_window(s); ++ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { ++ return need_more; ++ } ++ if (s->lookahead == 0) break; /* flush the current block */ ++ } ++ ++ /* Insert the string window[strstart .. strstart+2] in the ++ * dictionary, and set hash_head to the head of the hash chain: ++ */ ++ if (s->lookahead >= MIN_MATCH) { ++ INSERT_STRING(s, s->strstart, hash_head); ++ } ++ ++ /* Find the longest match, discarding those <= prev_length. ++ * At this point we have always match_length < MIN_MATCH ++ */ ++ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { ++ /* To simplify the code, we prevent matches with the string ++ * of window index 0 (in particular we have to avoid a match ++ * of the string with itself at the start of the input file). ++ */ ++ if (s->strategy != Z_HUFFMAN_ONLY) { ++ s->match_length = longest_match (s, hash_head); ++ } ++ /* longest_match() sets match_start */ ++ } ++ if (s->match_length >= MIN_MATCH) { ++ check_match(s, s->strstart, s->match_start, s->match_length); ++ ++ _tr_tally_dist(s, s->strstart - s->match_start, ++ s->match_length - MIN_MATCH, bflush); ++ ++ s->lookahead -= s->match_length; ++ ++ /* Insert new strings in the hash table only if the match length ++ * is not too large. This saves time but degrades compression. ++ */ ++#ifndef FASTEST ++ if (s->match_length <= s->max_insert_length && ++ s->lookahead >= MIN_MATCH) { ++ s->match_length--; /* string at strstart already in hash table */ ++ do { ++ s->strstart++; ++ INSERT_STRING(s, s->strstart, hash_head); ++ /* strstart never exceeds WSIZE-MAX_MATCH, so there are ++ * always MIN_MATCH bytes ahead. ++ */ ++ } while (--s->match_length != 0); ++ s->strstart++; ++ } else ++#endif ++ { ++ s->strstart += s->match_length; ++ s->match_length = 0; ++ s->ins_h = s->window[s->strstart]; ++ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); ++#if MIN_MATCH != 3 ++ Call UPDATE_HASH() MIN_MATCH-3 more times ++#endif ++ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not ++ * matter since it will be recomputed at next deflate call. ++ */ ++ } ++ } else { ++ /* No match, output a literal byte */ ++ Tracevv((stderr,"%c", s->window[s->strstart])); ++ _tr_tally_lit (s, s->window[s->strstart], bflush); ++ s->lookahead--; ++ s->strstart++; ++ } ++ if (bflush) FLUSH_BLOCK(s, 0); ++ } ++ FLUSH_BLOCK(s, flush == Z_FINISH); ++ return flush == Z_FINISH ? finish_done : block_done; ++} ++ ++/* =========================================================================== ++ * Same as above, but achieves better compression. We use a lazy ++ * evaluation for matches: a match is finally adopted only if there is ++ * no better match at the next window position. ++ */ ++local block_state deflate_slow(s, flush) ++ deflate_state *s; ++ int flush; ++{ ++ IPos hash_head = NIL; /* head of hash chain */ ++ int bflush; /* set if current block must be flushed */ ++ ++ /* Process the input block. */ ++ for (;;) { ++ /* Make sure that we always have enough lookahead, except ++ * at the end of the input file. We need MAX_MATCH bytes ++ * for the next match, plus MIN_MATCH bytes to insert the ++ * string following the next match. ++ */ ++ if (s->lookahead < MIN_LOOKAHEAD) { ++ fill_window(s); ++ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { ++ return need_more; ++ } ++ if (s->lookahead == 0) break; /* flush the current block */ ++ } ++ ++ /* Insert the string window[strstart .. strstart+2] in the ++ * dictionary, and set hash_head to the head of the hash chain: ++ */ ++ if (s->lookahead >= MIN_MATCH) { ++ INSERT_STRING(s, s->strstart, hash_head); ++ } ++ ++ /* Find the longest match, discarding those <= prev_length. ++ */ ++ s->prev_length = s->match_length, s->prev_match = s->match_start; ++ s->match_length = MIN_MATCH-1; ++ ++ if (hash_head != NIL && s->prev_length < s->max_lazy_match && ++ s->strstart - hash_head <= MAX_DIST(s)) { ++ /* To simplify the code, we prevent matches with the string ++ * of window index 0 (in particular we have to avoid a match ++ * of the string with itself at the start of the input file). ++ */ ++ if (s->strategy != Z_HUFFMAN_ONLY) { ++ s->match_length = longest_match (s, hash_head); ++ } ++ /* longest_match() sets match_start */ ++ ++ if (s->match_length <= 5 && (s->strategy == Z_FILTERED || ++ (s->match_length == MIN_MATCH && ++ s->strstart - s->match_start > TOO_FAR))) { ++ ++ /* If prev_match is also MIN_MATCH, match_start is garbage ++ * but we will ignore the current match anyway. ++ */ ++ s->match_length = MIN_MATCH-1; ++ } ++ } ++ /* If there was a match at the previous step and the current ++ * match is not better, output the previous match: ++ */ ++ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { ++ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; ++ /* Do not insert strings in hash table beyond this. */ ++ ++ check_match(s, s->strstart-1, s->prev_match, s->prev_length); ++ ++ _tr_tally_dist(s, s->strstart -1 - s->prev_match, ++ s->prev_length - MIN_MATCH, bflush); ++ ++ /* Insert in hash table all strings up to the end of the match. ++ * strstart-1 and strstart are already inserted. If there is not ++ * enough lookahead, the last two strings are not inserted in ++ * the hash table. ++ */ ++ s->lookahead -= s->prev_length-1; ++ s->prev_length -= 2; ++ do { ++ if (++s->strstart <= max_insert) { ++ INSERT_STRING(s, s->strstart, hash_head); ++ } ++ } while (--s->prev_length != 0); ++ s->match_available = 0; ++ s->match_length = MIN_MATCH-1; ++ s->strstart++; ++ ++ if (bflush) FLUSH_BLOCK(s, 0); ++ ++ } else if (s->match_available) { ++ /* If there was no match at the previous position, output a ++ * single literal. If there was a match but the current match ++ * is longer, truncate the previous match to a single literal. ++ */ ++ Tracevv((stderr,"%c", s->window[s->strstart-1])); ++ _tr_tally_lit(s, s->window[s->strstart-1], bflush); ++ if (bflush) { ++ FLUSH_BLOCK_ONLY(s, 0); ++ } ++ s->strstart++; ++ s->lookahead--; ++ if (s->strm->avail_out == 0) return need_more; ++ } else { ++ /* There is no previous match to compare with, wait for ++ * the next step to decide. ++ */ ++ s->match_available = 1; ++ s->strstart++; ++ s->lookahead--; ++ } ++ } ++ Assert (flush != Z_NO_FLUSH, "no flush?"); ++ if (s->match_available) { ++ Tracevv((stderr,"%c", s->window[s->strstart-1])); ++ _tr_tally_lit(s, s->window[s->strstart-1], bflush); ++ s->match_available = 0; ++ } ++ FLUSH_BLOCK(s, flush == Z_FINISH); ++ return flush == Z_FINISH ? finish_done : block_done; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/deflate.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,318 @@ ++/* deflate.h -- internal compression state ++ * Copyright (C) 1995-2002 Jean-loup Gailly ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++/* @(#) $Id: deflate.h,v 1.4 2002/04/24 07:55:32 mcr Exp $ */ ++ ++#ifndef _DEFLATE_H ++#define _DEFLATE_H ++ ++#include "zlib/zutil.h" ++ ++/* =========================================================================== ++ * Internal compression state. ++ */ ++ ++#define LENGTH_CODES 29 ++/* number of length codes, not counting the special END_BLOCK code */ ++ ++#define LITERALS 256 ++/* number of literal bytes 0..255 */ ++ ++#define L_CODES (LITERALS+1+LENGTH_CODES) ++/* number of Literal or Length codes, including the END_BLOCK code */ ++ ++#define D_CODES 30 ++/* number of distance codes */ ++ ++#define BL_CODES 19 ++/* number of codes used to transfer the bit lengths */ ++ ++#define HEAP_SIZE (2*L_CODES+1) ++/* maximum heap size */ ++ ++#define MAX_BITS 15 ++/* All codes must not exceed MAX_BITS bits */ ++ ++#define INIT_STATE 42 ++#define BUSY_STATE 113 ++#define FINISH_STATE 666 ++/* Stream status */ ++ ++ ++/* Data structure describing a single value and its code string. */ ++typedef struct ct_data_s { ++ union { ++ ush freq; /* frequency count */ ++ ush code; /* bit string */ ++ } fc; ++ union { ++ ush dad; /* father node in Huffman tree */ ++ ush len; /* length of bit string */ ++ } dl; ++} FAR ct_data; ++ ++#define Freq fc.freq ++#define Code fc.code ++#define Dad dl.dad ++#define Len dl.len ++ ++typedef struct static_tree_desc_s static_tree_desc; ++ ++typedef struct tree_desc_s { ++ ct_data *dyn_tree; /* the dynamic tree */ ++ int max_code; /* largest code with non zero frequency */ ++ static_tree_desc *stat_desc; /* the corresponding static tree */ ++} FAR tree_desc; ++ ++typedef ush Pos; ++typedef Pos FAR Posf; ++typedef unsigned IPos; ++ ++/* A Pos is an index in the character window. We use short instead of int to ++ * save space in the various tables. IPos is used only for parameter passing. ++ */ ++ ++typedef struct internal_state { ++ z_streamp strm; /* pointer back to this zlib stream */ ++ int status; /* as the name implies */ ++ Bytef *pending_buf; /* output still pending */ ++ ulg pending_buf_size; /* size of pending_buf */ ++ Bytef *pending_out; /* next pending byte to output to the stream */ ++ int pending; /* nb of bytes in the pending buffer */ ++ int noheader; /* suppress zlib header and adler32 */ ++ Byte data_type; /* UNKNOWN, BINARY or ASCII */ ++ Byte method; /* STORED (for zip only) or DEFLATED */ ++ int last_flush; /* value of flush param for previous deflate call */ ++ ++ /* used by deflate.c: */ ++ ++ uInt w_size; /* LZ77 window size (32K by default) */ ++ uInt w_bits; /* log2(w_size) (8..16) */ ++ uInt w_mask; /* w_size - 1 */ ++ ++ Bytef *window; ++ /* Sliding window. Input bytes are read into the second half of the window, ++ * and move to the first half later to keep a dictionary of at least wSize ++ * bytes. With this organization, matches are limited to a distance of ++ * wSize-MAX_MATCH bytes, but this ensures that IO is always ++ * performed with a length multiple of the block size. Also, it limits ++ * the window size to 64K, which is quite useful on MSDOS. ++ * To do: use the user input buffer as sliding window. ++ */ ++ ++ ulg window_size; ++ /* Actual size of window: 2*wSize, except when the user input buffer ++ * is directly used as sliding window. ++ */ ++ ++ Posf *prev; ++ /* Link to older string with same hash index. To limit the size of this ++ * array to 64K, this link is maintained only for the last 32K strings. ++ * An index in this array is thus a window index modulo 32K. ++ */ ++ ++ Posf *head; /* Heads of the hash chains or NIL. */ ++ ++ uInt ins_h; /* hash index of string to be inserted */ ++ uInt hash_size; /* number of elements in hash table */ ++ uInt hash_bits; /* log2(hash_size) */ ++ uInt hash_mask; /* hash_size-1 */ ++ ++ uInt hash_shift; ++ /* Number of bits by which ins_h must be shifted at each input ++ * step. It must be such that after MIN_MATCH steps, the oldest ++ * byte no longer takes part in the hash key, that is: ++ * hash_shift * MIN_MATCH >= hash_bits ++ */ ++ ++ long block_start; ++ /* Window position at the beginning of the current output block. Gets ++ * negative when the window is moved backwards. ++ */ ++ ++ uInt match_length; /* length of best match */ ++ IPos prev_match; /* previous match */ ++ int match_available; /* set if previous match exists */ ++ uInt strstart; /* start of string to insert */ ++ uInt match_start; /* start of matching string */ ++ uInt lookahead; /* number of valid bytes ahead in window */ ++ ++ uInt prev_length; ++ /* Length of the best match at previous step. Matches not greater than this ++ * are discarded. This is used in the lazy match evaluation. ++ */ ++ ++ uInt max_chain_length; ++ /* To speed up deflation, hash chains are never searched beyond this ++ * length. A higher limit improves compression ratio but degrades the ++ * speed. ++ */ ++ ++ uInt max_lazy_match; ++ /* Attempt to find a better match only when the current match is strictly ++ * smaller than this value. This mechanism is used only for compression ++ * levels >= 4. ++ */ ++# define max_insert_length max_lazy_match ++ /* Insert new strings in the hash table only if the match length is not ++ * greater than this length. This saves time but degrades compression. ++ * max_insert_length is used only for compression levels <= 3. ++ */ ++ ++ int level; /* compression level (1..9) */ ++ int strategy; /* favor or force Huffman coding*/ ++ ++ uInt good_match; ++ /* Use a faster search when the previous match is longer than this */ ++ ++ int nice_match; /* Stop searching when current match exceeds this */ ++ ++ /* used by trees.c: */ ++ /* Didn't use ct_data typedef below to supress compiler warning */ ++ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ ++ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ ++ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ ++ ++ struct tree_desc_s l_desc; /* desc. for literal tree */ ++ struct tree_desc_s d_desc; /* desc. for distance tree */ ++ struct tree_desc_s bl_desc; /* desc. for bit length tree */ ++ ++ ush bl_count[MAX_BITS+1]; ++ /* number of codes at each bit length for an optimal tree */ ++ ++ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ ++ int heap_len; /* number of elements in the heap */ ++ int heap_max; /* element of largest frequency */ ++ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. ++ * The same heap array is used to build all trees. ++ */ ++ ++ uch depth[2*L_CODES+1]; ++ /* Depth of each subtree used as tie breaker for trees of equal frequency ++ */ ++ ++ uchf *l_buf; /* buffer for literals or lengths */ ++ ++ uInt lit_bufsize; ++ /* Size of match buffer for literals/lengths. There are 4 reasons for ++ * limiting lit_bufsize to 64K: ++ * - frequencies can be kept in 16 bit counters ++ * - if compression is not successful for the first block, all input ++ * data is still in the window so we can still emit a stored block even ++ * when input comes from standard input. (This can also be done for ++ * all blocks if lit_bufsize is not greater than 32K.) ++ * - if compression is not successful for a file smaller than 64K, we can ++ * even emit a stored file instead of a stored block (saving 5 bytes). ++ * This is applicable only for zip (not gzip or zlib). ++ * - creating new Huffman trees less frequently may not provide fast ++ * adaptation to changes in the input data statistics. (Take for ++ * example a binary file with poorly compressible code followed by ++ * a highly compressible string table.) Smaller buffer sizes give ++ * fast adaptation but have of course the overhead of transmitting ++ * trees more frequently. ++ * - I can't count above 4 ++ */ ++ ++ uInt last_lit; /* running index in l_buf */ ++ ++ ushf *d_buf; ++ /* Buffer for distances. To simplify the code, d_buf and l_buf have ++ * the same number of elements. To use different lengths, an extra flag ++ * array would be necessary. ++ */ ++ ++ ulg opt_len; /* bit length of current block with optimal trees */ ++ ulg static_len; /* bit length of current block with static trees */ ++ uInt matches; /* number of string matches in current block */ ++ int last_eob_len; /* bit length of EOB code for last block */ ++ ++#ifdef DEBUG ++ ulg compressed_len; /* total bit length of compressed file mod 2^32 */ ++ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ ++#endif ++ ++ ush bi_buf; ++ /* Output buffer. bits are inserted starting at the bottom (least ++ * significant bits). ++ */ ++ int bi_valid; ++ /* Number of valid bits in bi_buf. All bits above the last valid bit ++ * are always zero. ++ */ ++ ++} FAR deflate_state; ++ ++/* Output a byte on the stream. ++ * IN assertion: there is enough room in pending_buf. ++ */ ++#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} ++ ++ ++#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) ++/* Minimum amount of lookahead, except at the end of the input file. ++ * See deflate.c for comments about the MIN_MATCH+1. ++ */ ++ ++#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) ++/* In order to simplify the code, particularly on 16 bit machines, match ++ * distances are limited to MAX_DIST instead of WSIZE. ++ */ ++ ++ /* in trees.c */ ++void _tr_init OF((deflate_state *s)); ++int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); ++void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, ++ int eof)); ++void _tr_align OF((deflate_state *s)); ++void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, ++ int eof)); ++ ++#define d_code(dist) \ ++ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) ++/* Mapping from a distance to a distance code. dist is the distance - 1 and ++ * must not have side effects. _dist_code[256] and _dist_code[257] are never ++ * used. ++ */ ++ ++#ifndef DEBUG ++/* Inline versions of _tr_tally for speed: */ ++ ++#if defined(GEN_TREES_H) || !defined(STDC) ++ extern uch _length_code[]; ++ extern uch _dist_code[]; ++#else ++ extern const uch _length_code[]; ++ extern const uch _dist_code[]; ++#endif ++ ++# define _tr_tally_lit(s, c, flush) \ ++ { uch cc = (c); \ ++ s->d_buf[s->last_lit] = 0; \ ++ s->l_buf[s->last_lit++] = cc; \ ++ s->dyn_ltree[cc].Freq++; \ ++ flush = (s->last_lit == s->lit_bufsize-1); \ ++ } ++# define _tr_tally_dist(s, distance, length, flush) \ ++ { uch len = (length); \ ++ ush dist = (distance); \ ++ s->d_buf[s->last_lit] = dist; \ ++ s->l_buf[s->last_lit++] = len; \ ++ dist--; \ ++ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ ++ s->dyn_dtree[d_code(dist)].Freq++; \ ++ flush = (s->last_lit == s->lit_bufsize-1); \ ++ } ++#else ++# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) ++# define _tr_tally_dist(s, distance, length, flush) \ ++ flush = _tr_tally(s, distance, length) ++#endif ++ ++#endif /* _DEFLATE_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/infblock.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,403 @@ ++/* infblock.c -- interpret and process block types to last block ++ * Copyright (C) 1995-2002 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++#include ++#include "infblock.h" ++#include "inftrees.h" ++#include "infcodes.h" ++#include "infutil.h" ++ ++struct inflate_codes_state {int dummy;}; /* for buggy compilers */ ++ ++/* simplify the use of the inflate_huft type with some defines */ ++#define exop word.what.Exop ++#define bits word.what.Bits ++ ++/* Table for deflate from PKZIP's appnote.txt. */ ++local const uInt border[] = { /* Order of the bit length code lengths */ ++ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; ++ ++/* ++ Notes beyond the 1.93a appnote.txt: ++ ++ 1. Distance pointers never point before the beginning of the output ++ stream. ++ 2. Distance pointers can point back across blocks, up to 32k away. ++ 3. There is an implied maximum of 7 bits for the bit length table and ++ 15 bits for the actual data. ++ 4. If only one code exists, then it is encoded using one bit. (Zero ++ would be more efficient, but perhaps a little confusing.) If two ++ codes exist, they are coded using one bit each (0 and 1). ++ 5. There is no way of sending zero distance codes--a dummy must be ++ sent if there are none. (History: a pre 2.0 version of PKZIP would ++ store blocks with no distance codes, but this was discovered to be ++ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow ++ zero distance codes, which is sent as one code of zero bits in ++ length. ++ 6. There are up to 286 literal/length codes. Code 256 represents the ++ end-of-block. Note however that the static length tree defines ++ 288 codes just to fill out the Huffman codes. Codes 286 and 287 ++ cannot be used though, since there is no length base or extra bits ++ defined for them. Similarily, there are up to 30 distance codes. ++ However, static trees define 32 codes (all 5 bits) to fill out the ++ Huffman codes, but the last two had better not show up in the data. ++ 7. Unzip can check dynamic Huffman blocks for complete code sets. ++ The exception is that a single code would not be complete (see #4). ++ 8. The five bits following the block type is really the number of ++ literal codes sent minus 257. ++ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits ++ (1+6+6). Therefore, to output three times the length, you output ++ three codes (1+1+1), whereas to output four times the same length, ++ you only need two codes (1+3). Hmm. ++ 10. In the tree reconstruction algorithm, Code = Code + Increment ++ only if BitLength(i) is not zero. (Pretty obvious.) ++ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) ++ 12. Note: length code 284 can represent 227-258, but length code 285 ++ really is 258. The last length deserves its own, short code ++ since it gets used a lot in very redundant files. The length ++ 258 is special since 258 - 3 (the min match length) is 255. ++ 13. The literal/length and distance code bit lengths are read as a ++ single stream of lengths. It is possible (and advantageous) for ++ a repeat code (16, 17, or 18) to go across the boundary between ++ the two sets of lengths. ++ */ ++ ++ ++void inflate_blocks_reset(s, z, c) ++inflate_blocks_statef *s; ++z_streamp z; ++uLongf *c; ++{ ++ if (c != Z_NULL) ++ *c = s->check; ++ if (s->mode == BTREE || s->mode == DTREE) ++ ZFREE(z, s->sub.trees.blens); ++ if (s->mode == CODES) ++ inflate_codes_free(s->sub.decode.codes, z); ++ s->mode = TYPE; ++ s->bitk = 0; ++ s->bitb = 0; ++ s->read = s->write = s->window; ++ if (s->checkfn != Z_NULL) ++ z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); ++ Tracev((stderr, "inflate: blocks reset\n")); ++} ++ ++ ++inflate_blocks_statef *inflate_blocks_new(z, c, w) ++z_streamp z; ++check_func c; ++uInt w; ++{ ++ inflate_blocks_statef *s; ++ ++ if ((s = (inflate_blocks_statef *)ZALLOC ++ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) ++ return s; ++ if ((s->hufts = ++ (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) ++ { ++ ZFREE(z, s); ++ return Z_NULL; ++ } ++ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) ++ { ++ ZFREE(z, s->hufts); ++ ZFREE(z, s); ++ return Z_NULL; ++ } ++ s->end = s->window + w; ++ s->checkfn = c; ++ s->mode = TYPE; ++ Tracev((stderr, "inflate: blocks allocated\n")); ++ inflate_blocks_reset(s, z, Z_NULL); ++ return s; ++} ++ ++ ++int inflate_blocks(s, z, r) ++inflate_blocks_statef *s; ++z_streamp z; ++int r; ++{ ++ uInt t; /* temporary storage */ ++ uLong b; /* bit buffer */ ++ uInt k; /* bits in bit buffer */ ++ Bytef *p; /* input data pointer */ ++ uInt n; /* bytes available there */ ++ Bytef *q; /* output window write pointer */ ++ uInt m; /* bytes to end of window or read pointer */ ++ ++ /* copy input/output information to locals (UPDATE macro restores) */ ++ LOAD ++ ++ /* process input based on current state */ ++ while (1) switch (s->mode) ++ { ++ case TYPE: ++ NEEDBITS(3) ++ t = (uInt)b & 7; ++ s->last = t & 1; ++ switch (t >> 1) ++ { ++ case 0: /* stored */ ++ Tracev((stderr, "inflate: stored block%s\n", ++ s->last ? " (last)" : "")); ++ DUMPBITS(3) ++ t = k & 7; /* go to byte boundary */ ++ DUMPBITS(t) ++ s->mode = LENS; /* get length of stored block */ ++ break; ++ case 1: /* fixed */ ++ Tracev((stderr, "inflate: fixed codes block%s\n", ++ s->last ? " (last)" : "")); ++ { ++ uInt bl, bd; ++ inflate_huft *tl, *td; ++ ++ inflate_trees_fixed(&bl, &bd, &tl, &td, z); ++ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); ++ if (s->sub.decode.codes == Z_NULL) ++ { ++ r = Z_MEM_ERROR; ++ LEAVE ++ } ++ } ++ DUMPBITS(3) ++ s->mode = CODES; ++ break; ++ case 2: /* dynamic */ ++ Tracev((stderr, "inflate: dynamic codes block%s\n", ++ s->last ? " (last)" : "")); ++ DUMPBITS(3) ++ s->mode = TABLE; ++ break; ++ case 3: /* illegal */ ++ DUMPBITS(3) ++ s->mode = BAD; ++ z->msg = (char*)"invalid block type"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ } ++ break; ++ case LENS: ++ NEEDBITS(32) ++ if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) ++ { ++ s->mode = BAD; ++ z->msg = (char*)"invalid stored block lengths"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ } ++ s->sub.left = (uInt)b & 0xffff; ++ b = k = 0; /* dump bits */ ++ Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); ++ s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); ++ break; ++ case STORED: ++ if (n == 0) ++ LEAVE ++ NEEDOUT ++ t = s->sub.left; ++ if (t > n) t = n; ++ if (t > m) t = m; ++ zmemcpy(q, p, t); ++ p += t; n -= t; ++ q += t; m -= t; ++ if ((s->sub.left -= t) != 0) ++ break; ++ Tracev((stderr, "inflate: stored end, %lu total out\n", ++ z->total_out + (q >= s->read ? q - s->read : ++ (s->end - s->read) + (q - s->window)))); ++ s->mode = s->last ? DRY : TYPE; ++ break; ++ case TABLE: ++ NEEDBITS(14) ++ s->sub.trees.table = t = (uInt)b & 0x3fff; ++#ifndef PKZIP_BUG_WORKAROUND ++ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) ++ { ++ s->mode = BAD; ++ z->msg = (char*)"too many length or distance symbols"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ } ++#endif ++ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); ++ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) ++ { ++ r = Z_MEM_ERROR; ++ LEAVE ++ } ++ DUMPBITS(14) ++ s->sub.trees.index = 0; ++ Tracev((stderr, "inflate: table sizes ok\n")); ++ s->mode = BTREE; ++ case BTREE: ++ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) ++ { ++ NEEDBITS(3) ++ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; ++ DUMPBITS(3) ++ } ++ while (s->sub.trees.index < 19) ++ s->sub.trees.blens[border[s->sub.trees.index++]] = 0; ++ s->sub.trees.bb = 7; ++ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, ++ &s->sub.trees.tb, s->hufts, z); ++ if (t != Z_OK) ++ { ++ r = t; ++ if (r == Z_DATA_ERROR) ++ { ++ ZFREE(z, s->sub.trees.blens); ++ s->mode = BAD; ++ } ++ LEAVE ++ } ++ s->sub.trees.index = 0; ++ Tracev((stderr, "inflate: bits tree ok\n")); ++ s->mode = DTREE; ++ case DTREE: ++ while (t = s->sub.trees.table, ++ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) ++ { ++ inflate_huft *h; ++ uInt i, j, c; ++ ++ t = s->sub.trees.bb; ++ NEEDBITS(t) ++ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); ++ t = h->bits; ++ c = h->base; ++ if (c < 16) ++ { ++ DUMPBITS(t) ++ s->sub.trees.blens[s->sub.trees.index++] = c; ++ } ++ else /* c == 16..18 */ ++ { ++ i = c == 18 ? 7 : c - 14; ++ j = c == 18 ? 11 : 3; ++ NEEDBITS(t + i) ++ DUMPBITS(t) ++ j += (uInt)b & inflate_mask[i]; ++ DUMPBITS(i) ++ i = s->sub.trees.index; ++ t = s->sub.trees.table; ++ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || ++ (c == 16 && i < 1)) ++ { ++ ZFREE(z, s->sub.trees.blens); ++ s->mode = BAD; ++ z->msg = (char*)"invalid bit length repeat"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ } ++ c = c == 16 ? s->sub.trees.blens[i - 1] : 0; ++ do { ++ s->sub.trees.blens[i++] = c; ++ } while (--j); ++ s->sub.trees.index = i; ++ } ++ } ++ s->sub.trees.tb = Z_NULL; ++ { ++ uInt bl, bd; ++ inflate_huft *tl, *td; ++ inflate_codes_statef *c; ++ ++ bl = 9; /* must be <= 9 for lookahead assumptions */ ++ bd = 6; /* must be <= 9 for lookahead assumptions */ ++ t = s->sub.trees.table; ++ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), ++ s->sub.trees.blens, &bl, &bd, &tl, &td, ++ s->hufts, z); ++ if (t != Z_OK) ++ { ++ if (t == (uInt)Z_DATA_ERROR) ++ { ++ ZFREE(z, s->sub.trees.blens); ++ s->mode = BAD; ++ } ++ r = t; ++ LEAVE ++ } ++ Tracev((stderr, "inflate: trees ok\n")); ++ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) ++ { ++ r = Z_MEM_ERROR; ++ LEAVE ++ } ++ s->sub.decode.codes = c; ++ } ++ ZFREE(z, s->sub.trees.blens); ++ s->mode = CODES; ++ case CODES: ++ UPDATE ++ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) ++ return inflate_flush(s, z, r); ++ r = Z_OK; ++ inflate_codes_free(s->sub.decode.codes, z); ++ LOAD ++ Tracev((stderr, "inflate: codes end, %lu total out\n", ++ z->total_out + (q >= s->read ? q - s->read : ++ (s->end - s->read) + (q - s->window)))); ++ if (!s->last) ++ { ++ s->mode = TYPE; ++ break; ++ } ++ s->mode = DRY; ++ case DRY: ++ FLUSH ++ if (s->read != s->write) ++ LEAVE ++ s->mode = DONE; ++ case DONE: ++ r = Z_STREAM_END; ++ LEAVE ++ case BAD: ++ r = Z_DATA_ERROR; ++ LEAVE ++ default: ++ r = Z_STREAM_ERROR; ++ LEAVE ++ } ++} ++ ++ ++int inflate_blocks_free(s, z) ++inflate_blocks_statef *s; ++z_streamp z; ++{ ++ inflate_blocks_reset(s, z, Z_NULL); ++ ZFREE(z, s->window); ++ ZFREE(z, s->hufts); ++ ZFREE(z, s); ++ Tracev((stderr, "inflate: blocks freed\n")); ++ return Z_OK; ++} ++ ++ ++void inflate_set_dictionary(s, d, n) ++inflate_blocks_statef *s; ++const Bytef *d; ++uInt n; ++{ ++ zmemcpy(s->window, d, n); ++ s->read = s->write = s->window + n; ++} ++ ++ ++/* Returns true if inflate is currently at the end of a block generated ++ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. ++ * IN assertion: s != Z_NULL ++ */ ++int inflate_blocks_sync_point(s) ++inflate_blocks_statef *s; ++{ ++ return s->mode == LENS; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/infblock.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,39 @@ ++/* infblock.h -- header to use infblock.c ++ * Copyright (C) 1995-2002 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++struct inflate_blocks_state; ++typedef struct inflate_blocks_state FAR inflate_blocks_statef; ++ ++extern inflate_blocks_statef * inflate_blocks_new OF(( ++ z_streamp z, ++ check_func c, /* check function */ ++ uInt w)); /* window size */ ++ ++extern int inflate_blocks OF(( ++ inflate_blocks_statef *, ++ z_streamp , ++ int)); /* initial return code */ ++ ++extern void inflate_blocks_reset OF(( ++ inflate_blocks_statef *, ++ z_streamp , ++ uLongf *)); /* check value on output */ ++ ++extern int inflate_blocks_free OF(( ++ inflate_blocks_statef *, ++ z_streamp)); ++ ++extern void inflate_set_dictionary OF(( ++ inflate_blocks_statef *s, ++ const Bytef *d, /* dictionary */ ++ uInt n)); /* dictionary length */ ++ ++extern int inflate_blocks_sync_point OF(( ++ inflate_blocks_statef *s)); +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/infcodes.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,251 @@ ++/* infcodes.c -- process literals and length/distance pairs ++ * Copyright (C) 1995-2002 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++#include ++#include "inftrees.h" ++#include "infblock.h" ++#include "infcodes.h" ++#include "infutil.h" ++#include "inffast.h" ++ ++/* simplify the use of the inflate_huft type with some defines */ ++#define exop word.what.Exop ++#define bits word.what.Bits ++ ++typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ ++ START, /* x: set up for LEN */ ++ LEN, /* i: get length/literal/eob next */ ++ LENEXT, /* i: getting length extra (have base) */ ++ DIST, /* i: get distance next */ ++ DISTEXT, /* i: getting distance extra */ ++ COPY, /* o: copying bytes in window, waiting for space */ ++ LIT, /* o: got literal, waiting for output space */ ++ WASH, /* o: got eob, possibly still output waiting */ ++ END, /* x: got eob and all data flushed */ ++ BADCODE} /* x: got error */ ++inflate_codes_mode; ++ ++/* inflate codes private state */ ++struct inflate_codes_state { ++ ++ /* mode */ ++ inflate_codes_mode mode; /* current inflate_codes mode */ ++ ++ /* mode dependent information */ ++ uInt len; ++ union { ++ struct { ++ inflate_huft *tree; /* pointer into tree */ ++ uInt need; /* bits needed */ ++ } code; /* if LEN or DIST, where in tree */ ++ uInt lit; /* if LIT, literal */ ++ struct { ++ uInt get; /* bits to get for extra */ ++ uInt dist; /* distance back to copy from */ ++ } copy; /* if EXT or COPY, where and how much */ ++ } sub; /* submode */ ++ ++ /* mode independent information */ ++ Byte lbits; /* ltree bits decoded per branch */ ++ Byte dbits; /* dtree bits decoder per branch */ ++ inflate_huft *ltree; /* literal/length/eob tree */ ++ inflate_huft *dtree; /* distance tree */ ++ ++}; ++ ++ ++inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) ++uInt bl, bd; ++inflate_huft *tl; ++inflate_huft *td; /* need separate declaration for Borland C++ */ ++z_streamp z; ++{ ++ inflate_codes_statef *c; ++ ++ if ((c = (inflate_codes_statef *) ++ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) ++ { ++ c->mode = START; ++ c->lbits = (Byte)bl; ++ c->dbits = (Byte)bd; ++ c->ltree = tl; ++ c->dtree = td; ++ Tracev((stderr, "inflate: codes new\n")); ++ } ++ return c; ++} ++ ++ ++int inflate_codes(s, z, r) ++inflate_blocks_statef *s; ++z_streamp z; ++int r; ++{ ++ uInt j; /* temporary storage */ ++ inflate_huft *t; /* temporary pointer */ ++ uInt e; /* extra bits or operation */ ++ uLong b; /* bit buffer */ ++ uInt k; /* bits in bit buffer */ ++ Bytef *p; /* input data pointer */ ++ uInt n; /* bytes available there */ ++ Bytef *q; /* output window write pointer */ ++ uInt m; /* bytes to end of window or read pointer */ ++ Bytef *f; /* pointer to copy strings from */ ++ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ ++ ++ /* copy input/output information to locals (UPDATE macro restores) */ ++ LOAD ++ ++ /* process input and output based on current state */ ++ while (1) switch (c->mode) ++ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ ++ case START: /* x: set up for LEN */ ++#ifndef SLOW ++ if (m >= 258 && n >= 10) ++ { ++ UPDATE ++ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); ++ LOAD ++ if (r != Z_OK) ++ { ++ c->mode = r == Z_STREAM_END ? WASH : BADCODE; ++ break; ++ } ++ } ++#endif /* !SLOW */ ++ c->sub.code.need = c->lbits; ++ c->sub.code.tree = c->ltree; ++ c->mode = LEN; ++ case LEN: /* i: get length/literal/eob next */ ++ j = c->sub.code.need; ++ NEEDBITS(j) ++ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); ++ DUMPBITS(t->bits) ++ e = (uInt)(t->exop); ++ if (e == 0) /* literal */ ++ { ++ c->sub.lit = t->base; ++ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? ++ "inflate: literal '%c'\n" : ++ "inflate: literal 0x%02x\n", t->base)); ++ c->mode = LIT; ++ break; ++ } ++ if (e & 16) /* length */ ++ { ++ c->sub.copy.get = e & 15; ++ c->len = t->base; ++ c->mode = LENEXT; ++ break; ++ } ++ if ((e & 64) == 0) /* next table */ ++ { ++ c->sub.code.need = e; ++ c->sub.code.tree = t + t->base; ++ break; ++ } ++ if (e & 32) /* end of block */ ++ { ++ Tracevv((stderr, "inflate: end of block\n")); ++ c->mode = WASH; ++ break; ++ } ++ c->mode = BADCODE; /* invalid code */ ++ z->msg = (char*)"invalid literal/length code"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ case LENEXT: /* i: getting length extra (have base) */ ++ j = c->sub.copy.get; ++ NEEDBITS(j) ++ c->len += (uInt)b & inflate_mask[j]; ++ DUMPBITS(j) ++ c->sub.code.need = c->dbits; ++ c->sub.code.tree = c->dtree; ++ Tracevv((stderr, "inflate: length %u\n", c->len)); ++ c->mode = DIST; ++ case DIST: /* i: get distance next */ ++ j = c->sub.code.need; ++ NEEDBITS(j) ++ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); ++ DUMPBITS(t->bits) ++ e = (uInt)(t->exop); ++ if (e & 16) /* distance */ ++ { ++ c->sub.copy.get = e & 15; ++ c->sub.copy.dist = t->base; ++ c->mode = DISTEXT; ++ break; ++ } ++ if ((e & 64) == 0) /* next table */ ++ { ++ c->sub.code.need = e; ++ c->sub.code.tree = t + t->base; ++ break; ++ } ++ c->mode = BADCODE; /* invalid code */ ++ z->msg = (char*)"invalid distance code"; ++ r = Z_DATA_ERROR; ++ LEAVE ++ case DISTEXT: /* i: getting distance extra */ ++ j = c->sub.copy.get; ++ NEEDBITS(j) ++ c->sub.copy.dist += (uInt)b & inflate_mask[j]; ++ DUMPBITS(j) ++ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); ++ c->mode = COPY; ++ case COPY: /* o: copying bytes in window, waiting for space */ ++ f = q - c->sub.copy.dist; ++ while (f < s->window) /* modulo window size-"while" instead */ ++ f += s->end - s->window; /* of "if" handles invalid distances */ ++ while (c->len) ++ { ++ NEEDOUT ++ OUTBYTE(*f++) ++ if (f == s->end) ++ f = s->window; ++ c->len--; ++ } ++ c->mode = START; ++ break; ++ case LIT: /* o: got literal, waiting for output space */ ++ NEEDOUT ++ OUTBYTE(c->sub.lit) ++ c->mode = START; ++ break; ++ case WASH: /* o: got eob, possibly more output */ ++ if (k > 7) /* return unused byte, if any */ ++ { ++ Assert(k < 16, "inflate_codes grabbed too many bytes") ++ k -= 8; ++ n++; ++ p--; /* can always return one */ ++ } ++ FLUSH ++ if (s->read != s->write) ++ LEAVE ++ c->mode = END; ++ case END: ++ r = Z_STREAM_END; ++ LEAVE ++ case BADCODE: /* x: got error */ ++ r = Z_DATA_ERROR; ++ LEAVE ++ default: ++ r = Z_STREAM_ERROR; ++ LEAVE ++ } ++#ifdef NEED_DUMMY_RETURN ++ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ ++#endif ++} ++ ++ ++void inflate_codes_free(c, z) ++inflate_codes_statef *c; ++z_streamp z; ++{ ++ ZFREE(z, c); ++ Tracev((stderr, "inflate: codes free\n")); ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/infcodes.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,31 @@ ++/* infcodes.h -- header to use infcodes.c ++ * Copyright (C) 1995-2002 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++#ifndef _INFCODES_H ++#define _INFCODES_H ++ ++struct inflate_codes_state; ++typedef struct inflate_codes_state FAR inflate_codes_statef; ++ ++extern inflate_codes_statef *inflate_codes_new OF(( ++ uInt, uInt, ++ inflate_huft *, inflate_huft *, ++ z_streamp )); ++ ++extern int inflate_codes OF(( ++ inflate_blocks_statef *, ++ z_streamp , ++ int)); ++ ++extern void inflate_codes_free OF(( ++ inflate_codes_statef *, ++ z_streamp )); ++ ++#endif /* _INFCODES_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/inffast.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,183 @@ ++/* inffast.c -- process literals and length/distance pairs fast ++ * Copyright (C) 1995-2002 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++#include ++#include "inftrees.h" ++#include "infblock.h" ++#include "infcodes.h" ++#include "infutil.h" ++#include "inffast.h" ++ ++struct inflate_codes_state {int dummy;}; /* for buggy compilers */ ++ ++/* simplify the use of the inflate_huft type with some defines */ ++#define exop word.what.Exop ++#define bits word.what.Bits ++ ++/* macros for bit input with no checking and for returning unused bytes */ ++#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3;} ++ ++/* Called with number of bytes left to write in window at least 258 ++ (the maximum string length) and number of input bytes available ++ at least ten. The ten bytes are six bytes for the longest length/ ++ distance pair plus four bytes for overloading the bit buffer. */ ++ ++int inflate_fast(bl, bd, tl, td, s, z) ++uInt bl, bd; ++inflate_huft *tl; ++inflate_huft *td; /* need separate declaration for Borland C++ */ ++inflate_blocks_statef *s; ++z_streamp z; ++{ ++ inflate_huft *t; /* temporary pointer */ ++ uInt e; /* extra bits or operation */ ++ uLong b; /* bit buffer */ ++ uInt k; /* bits in bit buffer */ ++ Bytef *p; /* input data pointer */ ++ uInt n; /* bytes available there */ ++ Bytef *q; /* output window write pointer */ ++ uInt m; /* bytes to end of window or read pointer */ ++ uInt ml; /* mask for literal/length tree */ ++ uInt md; /* mask for distance tree */ ++ uInt c; /* bytes to copy */ ++ uInt d; /* distance back to copy from */ ++ Bytef *r; /* copy source pointer */ ++ ++ /* load input, output, bit values */ ++ LOAD ++ ++ /* initialize masks */ ++ ml = inflate_mask[bl]; ++ md = inflate_mask[bd]; ++ ++ /* do until not enough input or output space for fast loop */ ++ do { /* assume called with m >= 258 && n >= 10 */ ++ /* get literal/length code */ ++ GRABBITS(20) /* max bits for literal/length code */ ++ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) ++ { ++ DUMPBITS(t->bits) ++ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? ++ "inflate: * literal '%c'\n" : ++ "inflate: * literal 0x%02x\n", t->base)); ++ *q++ = (Byte)t->base; ++ m--; ++ continue; ++ } ++ do { ++ DUMPBITS(t->bits) ++ if (e & 16) ++ { ++ /* get extra bits for length */ ++ e &= 15; ++ c = t->base + ((uInt)b & inflate_mask[e]); ++ DUMPBITS(e) ++ Tracevv((stderr, "inflate: * length %u\n", c)); ++ ++ /* decode distance base of block to copy */ ++ GRABBITS(15); /* max bits for distance code */ ++ e = (t = td + ((uInt)b & md))->exop; ++ do { ++ DUMPBITS(t->bits) ++ if (e & 16) ++ { ++ /* get extra bits to add to distance base */ ++ e &= 15; ++ GRABBITS(e) /* get extra bits (up to 13) */ ++ d = t->base + ((uInt)b & inflate_mask[e]); ++ DUMPBITS(e) ++ Tracevv((stderr, "inflate: * distance %u\n", d)); ++ ++ /* do the copy */ ++ m -= c; ++ r = q - d; ++ if (r < s->window) /* wrap if needed */ ++ { ++ do { ++ r += s->end - s->window; /* force pointer in window */ ++ } while (r < s->window); /* covers invalid distances */ ++ e = s->end - r; ++ if (c > e) ++ { ++ c -= e; /* wrapped copy */ ++ do { ++ *q++ = *r++; ++ } while (--e); ++ r = s->window; ++ do { ++ *q++ = *r++; ++ } while (--c); ++ } ++ else /* normal copy */ ++ { ++ *q++ = *r++; c--; ++ *q++ = *r++; c--; ++ do { ++ *q++ = *r++; ++ } while (--c); ++ } ++ } ++ else /* normal copy */ ++ { ++ *q++ = *r++; c--; ++ *q++ = *r++; c--; ++ do { ++ *q++ = *r++; ++ } while (--c); ++ } ++ break; ++ } ++ else if ((e & 64) == 0) ++ { ++ t += t->base; ++ e = (t += ((uInt)b & inflate_mask[e]))->exop; ++ } ++ else ++ { ++ z->msg = (char*)"invalid distance code"; ++ UNGRAB ++ UPDATE ++ return Z_DATA_ERROR; ++ } ++ } while (1); ++ break; ++ } ++ if ((e & 64) == 0) ++ { ++ t += t->base; ++ if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) ++ { ++ DUMPBITS(t->bits) ++ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? ++ "inflate: * literal '%c'\n" : ++ "inflate: * literal 0x%02x\n", t->base)); ++ *q++ = (Byte)t->base; ++ m--; ++ break; ++ } ++ } ++ else if (e & 32) ++ { ++ Tracevv((stderr, "inflate: * end of block\n")); ++ UNGRAB ++ UPDATE ++ return Z_STREAM_END; ++ } ++ else ++ { ++ z->msg = (char*)"invalid literal/length code"; ++ UNGRAB ++ UPDATE ++ return Z_DATA_ERROR; ++ } ++ } while (1); ++ } while (m >= 258 && n >= 10); ++ ++ /* not enough input or output--restore pointers and return */ ++ UNGRAB ++ UPDATE ++ return Z_OK; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/inffast.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,22 @@ ++/* inffast.h -- header to use inffast.c ++ * Copyright (C) 1995-2002 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++#ifndef _INFFAST_H ++#define _INFFAST_H ++ ++extern int inflate_fast OF(( ++ uInt, ++ uInt, ++ inflate_huft *, ++ inflate_huft *, ++ inflate_blocks_statef *, ++ z_streamp )); ++ ++#endif /* _INFFAST_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/inffixed.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,151 @@ ++/* inffixed.h -- table for decoding fixed codes ++ * Generated automatically by the maketree.c program ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++local uInt fixed_bl = 9; ++local uInt fixed_bd = 5; ++local inflate_huft fixed_tl[] = { ++ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, ++ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, ++ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, ++ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, ++ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, ++ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, ++ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, ++ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, ++ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, ++ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, ++ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, ++ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, ++ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, ++ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, ++ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, ++ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, ++ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, ++ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, ++ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, ++ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, ++ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, ++ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, ++ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, ++ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, ++ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, ++ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, ++ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, ++ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, ++ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, ++ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, ++ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, ++ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, ++ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, ++ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, ++ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, ++ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, ++ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, ++ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, ++ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, ++ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, ++ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, ++ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, ++ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, ++ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, ++ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, ++ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, ++ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, ++ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, ++ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, ++ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, ++ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, ++ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, ++ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, ++ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, ++ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, ++ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, ++ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, ++ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, ++ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, ++ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, ++ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, ++ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, ++ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, ++ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, ++ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, ++ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, ++ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, ++ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, ++ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, ++ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, ++ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, ++ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, ++ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, ++ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, ++ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, ++ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, ++ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, ++ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, ++ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, ++ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, ++ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, ++ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, ++ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, ++ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, ++ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, ++ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, ++ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, ++ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, ++ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, ++ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, ++ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, ++ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, ++ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, ++ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, ++ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, ++ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, ++ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, ++ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, ++ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, ++ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, ++ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, ++ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, ++ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, ++ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, ++ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, ++ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, ++ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, ++ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, ++ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, ++ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, ++ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, ++ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, ++ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, ++ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, ++ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, ++ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, ++ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, ++ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, ++ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, ++ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, ++ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, ++ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, ++ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, ++ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, ++ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, ++ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, ++ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, ++ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} ++ }; ++local inflate_huft fixed_td[] = { ++ {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, ++ {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, ++ {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, ++ {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, ++ {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, ++ {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, ++ {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, ++ {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} ++ }; +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/inflate.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,368 @@ ++/* inflate.c -- zlib interface to inflate modules ++ * Copyright (C) 1995-2002 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++#include ++#include "infblock.h" ++ ++struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ ++ ++typedef enum { ++ METHOD, /* waiting for method byte */ ++ FLAG, /* waiting for flag byte */ ++ DICT4, /* four dictionary check bytes to go */ ++ DICT3, /* three dictionary check bytes to go */ ++ DICT2, /* two dictionary check bytes to go */ ++ DICT1, /* one dictionary check byte to go */ ++ DICT0, /* waiting for inflateSetDictionary */ ++ BLOCKS, /* decompressing blocks */ ++ CHECK4, /* four check bytes to go */ ++ CHECK3, /* three check bytes to go */ ++ CHECK2, /* two check bytes to go */ ++ CHECK1, /* one check byte to go */ ++ DONE, /* finished check, done */ ++ BAD} /* got an error--stay here */ ++inflate_mode; ++ ++/* inflate private state */ ++struct internal_state { ++ ++ /* mode */ ++ inflate_mode mode; /* current inflate mode */ ++ ++ /* mode dependent information */ ++ union { ++ uInt method; /* if FLAGS, method byte */ ++ struct { ++ uLong was; /* computed check value */ ++ uLong need; /* stream check value */ ++ } check; /* if CHECK, check values to compare */ ++ uInt marker; /* if BAD, inflateSync's marker bytes count */ ++ } sub; /* submode */ ++ ++ /* mode independent information */ ++ int nowrap; /* flag for no wrapper */ ++ uInt wbits; /* log2(window size) (8..15, defaults to 15) */ ++ inflate_blocks_statef ++ *blocks; /* current inflate_blocks state */ ++ ++}; ++ ++ ++int ZEXPORT inflateReset(z) ++z_streamp z; ++{ ++ if (z == Z_NULL || z->state == Z_NULL) ++ return Z_STREAM_ERROR; ++ z->total_in = z->total_out = 0; ++ z->msg = Z_NULL; ++ z->state->mode = z->state->nowrap ? BLOCKS : METHOD; ++ inflate_blocks_reset(z->state->blocks, z, Z_NULL); ++ Tracev((stderr, "inflate: reset\n")); ++ return Z_OK; ++} ++ ++ ++int ZEXPORT inflateEnd(z) ++z_streamp z; ++{ ++ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) ++ return Z_STREAM_ERROR; ++ if (z->state->blocks != Z_NULL) ++ inflate_blocks_free(z->state->blocks, z); ++ ZFREE(z, z->state); ++ z->state = Z_NULL; ++ Tracev((stderr, "inflate: end\n")); ++ return Z_OK; ++} ++ ++ ++int ZEXPORT inflateInit2_(z, w, version, stream_size) ++z_streamp z; ++int w; ++const char *version; ++int stream_size; ++{ ++ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || ++ stream_size != sizeof(z_stream)) ++ return Z_VERSION_ERROR; ++ ++ /* initialize state */ ++ if (z == Z_NULL) ++ return Z_STREAM_ERROR; ++ z->msg = Z_NULL; ++ if (z->zalloc == Z_NULL) ++ { ++ return Z_STREAM_ERROR; ++/* z->zalloc = zcalloc; ++ z->opaque = (voidpf)0; ++*/ ++ } ++ if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */ ++ if ((z->state = (struct internal_state FAR *) ++ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) ++ return Z_MEM_ERROR; ++ z->state->blocks = Z_NULL; ++ ++ /* handle undocumented nowrap option (no zlib header or check) */ ++ z->state->nowrap = 0; ++ if (w < 0) ++ { ++ w = - w; ++ z->state->nowrap = 1; ++ } ++ ++ /* set window size */ ++ if (w < 8 || w > 15) ++ { ++ inflateEnd(z); ++ return Z_STREAM_ERROR; ++ } ++ z->state->wbits = (uInt)w; ++ ++ /* create inflate_blocks state */ ++ if ((z->state->blocks = ++ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) ++ == Z_NULL) ++ { ++ inflateEnd(z); ++ return Z_MEM_ERROR; ++ } ++ Tracev((stderr, "inflate: allocated\n")); ++ ++ /* reset state */ ++ inflateReset(z); ++ return Z_OK; ++} ++ ++ ++int ZEXPORT inflateInit_(z, version, stream_size) ++z_streamp z; ++const char *version; ++int stream_size; ++{ ++ return inflateInit2_(z, DEF_WBITS, version, stream_size); ++} ++ ++ ++#define NEEDBYTE {if(z->avail_in==0)return r;r=f;} ++#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) ++ ++int ZEXPORT inflate(z, f) ++z_streamp z; ++int f; ++{ ++ int r; ++ uInt b; ++ ++ if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) ++ return Z_STREAM_ERROR; ++ f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; ++ r = Z_BUF_ERROR; ++ while (1) switch (z->state->mode) ++ { ++ case METHOD: ++ NEEDBYTE ++ if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) ++ { ++ z->state->mode = BAD; ++ z->msg = (char*)"unknown compression method"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ if ((z->state->sub.method >> 4) + 8 > z->state->wbits) ++ { ++ z->state->mode = BAD; ++ z->msg = (char*)"invalid window size"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ z->state->mode = FLAG; ++ case FLAG: ++ NEEDBYTE ++ b = NEXTBYTE; ++ if (((z->state->sub.method << 8) + b) % 31) ++ { ++ z->state->mode = BAD; ++ z->msg = (char*)"incorrect header check"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ Tracev((stderr, "inflate: zlib header ok\n")); ++ if (!(b & PRESET_DICT)) ++ { ++ z->state->mode = BLOCKS; ++ break; ++ } ++ z->state->mode = DICT4; ++ case DICT4: ++ NEEDBYTE ++ z->state->sub.check.need = (uLong)NEXTBYTE << 24; ++ z->state->mode = DICT3; ++ case DICT3: ++ NEEDBYTE ++ z->state->sub.check.need += (uLong)NEXTBYTE << 16; ++ z->state->mode = DICT2; ++ case DICT2: ++ NEEDBYTE ++ z->state->sub.check.need += (uLong)NEXTBYTE << 8; ++ z->state->mode = DICT1; ++ case DICT1: ++ NEEDBYTE ++ z->state->sub.check.need += (uLong)NEXTBYTE; ++ z->adler = z->state->sub.check.need; ++ z->state->mode = DICT0; ++ return Z_NEED_DICT; ++ case DICT0: ++ z->state->mode = BAD; ++ z->msg = (char*)"need dictionary"; ++ z->state->sub.marker = 0; /* can try inflateSync */ ++ return Z_STREAM_ERROR; ++ case BLOCKS: ++ r = inflate_blocks(z->state->blocks, z, r); ++ if (r == Z_DATA_ERROR) ++ { ++ z->state->mode = BAD; ++ z->state->sub.marker = 0; /* can try inflateSync */ ++ break; ++ } ++ if (r == Z_OK) ++ r = f; ++ if (r != Z_STREAM_END) ++ return r; ++ r = f; ++ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); ++ if (z->state->nowrap) ++ { ++ z->state->mode = DONE; ++ break; ++ } ++ z->state->mode = CHECK4; ++ case CHECK4: ++ NEEDBYTE ++ z->state->sub.check.need = (uLong)NEXTBYTE << 24; ++ z->state->mode = CHECK3; ++ case CHECK3: ++ NEEDBYTE ++ z->state->sub.check.need += (uLong)NEXTBYTE << 16; ++ z->state->mode = CHECK2; ++ case CHECK2: ++ NEEDBYTE ++ z->state->sub.check.need += (uLong)NEXTBYTE << 8; ++ z->state->mode = CHECK1; ++ case CHECK1: ++ NEEDBYTE ++ z->state->sub.check.need += (uLong)NEXTBYTE; ++ ++ if (z->state->sub.check.was != z->state->sub.check.need) ++ { ++ z->state->mode = BAD; ++ z->msg = (char*)"incorrect data check"; ++ z->state->sub.marker = 5; /* can't try inflateSync */ ++ break; ++ } ++ Tracev((stderr, "inflate: zlib check ok\n")); ++ z->state->mode = DONE; ++ case DONE: ++ return Z_STREAM_END; ++ case BAD: ++ return Z_DATA_ERROR; ++ default: ++ return Z_STREAM_ERROR; ++ } ++#ifdef NEED_DUMMY_RETURN ++ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ ++#endif ++} ++ ++ ++int ZEXPORT inflateSetDictionary(z, dictionary, dictLength) ++z_streamp z; ++const Bytef *dictionary; ++uInt dictLength; ++{ ++ uInt length = dictLength; ++ ++ if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) ++ return Z_STREAM_ERROR; ++ ++ if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; ++ z->adler = 1L; ++ ++ if (length >= ((uInt)1<state->wbits)) ++ { ++ length = (1<state->wbits)-1; ++ dictionary += dictLength - length; ++ } ++ inflate_set_dictionary(z->state->blocks, dictionary, length); ++ z->state->mode = BLOCKS; ++ return Z_OK; ++} ++ ++ ++int ZEXPORT inflateSync(z) ++z_streamp z; ++{ ++ uInt n; /* number of bytes to look at */ ++ Bytef *p; /* pointer to bytes */ ++ uInt m; /* number of marker bytes found in a row */ ++ uLong r, w; /* temporaries to save total_in and total_out */ ++ ++ /* set up */ ++ if (z == Z_NULL || z->state == Z_NULL) ++ return Z_STREAM_ERROR; ++ if (z->state->mode != BAD) ++ { ++ z->state->mode = BAD; ++ z->state->sub.marker = 0; ++ } ++ if ((n = z->avail_in) == 0) ++ return Z_BUF_ERROR; ++ p = z->next_in; ++ m = z->state->sub.marker; ++ ++ /* search */ ++ while (n && m < 4) ++ { ++ static const Byte mark[4] = {0, 0, 0xff, 0xff}; ++ if (*p == mark[m]) ++ m++; ++ else if (*p) ++ m = 0; ++ else ++ m = 4 - m; ++ p++, n--; ++ } ++ ++ /* restore */ ++ z->total_in += p - z->next_in; ++ z->next_in = p; ++ z->avail_in = n; ++ z->state->sub.marker = m; ++ ++ /* return no joy or set up to restart on a new block */ ++ if (m != 4) ++ return Z_DATA_ERROR; ++ r = z->total_in; w = z->total_out; ++ inflateReset(z); ++ z->total_in = r; z->total_out = w; ++ z->state->mode = BLOCKS; ++ return Z_OK; ++} ++ ++ ++/* Returns true if inflate is currently at the end of a block generated ++ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP ++ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH ++ * but removes the length bytes of the resulting empty stored block. When ++ * decompressing, PPP checks that at the end of input packet, inflate is ++ * waiting for these length bytes. ++ */ ++int ZEXPORT inflateSyncPoint(z) ++z_streamp z; ++{ ++ if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) ++ return Z_STREAM_ERROR; ++ return inflate_blocks_sync_point(z->state->blocks); ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/inftrees.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,454 @@ ++/* inftrees.c -- generate Huffman trees for efficient decoding ++ * Copyright (C) 1995-2002 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++#include ++#include "inftrees.h" ++ ++#if !defined(BUILDFIXED) && !defined(STDC) ++# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */ ++#endif ++ ++local const char inflate_copyright[] = ++ " inflate 1.1.4 Copyright 1995-2002 Mark Adler "; ++/* ++ If you use the zlib library in a product, an acknowledgment is welcome ++ in the documentation of your product. If for some reason you cannot ++ include such an acknowledgment, I would appreciate that you keep this ++ copyright string in the executable of your product. ++ */ ++struct internal_state {int dummy;}; /* for buggy compilers */ ++ ++/* simplify the use of the inflate_huft type with some defines */ ++#define exop word.what.Exop ++#define bits word.what.Bits ++ ++ ++local int huft_build OF(( ++ uIntf *, /* code lengths in bits */ ++ uInt, /* number of codes */ ++ uInt, /* number of "simple" codes */ ++ const uIntf *, /* list of base values for non-simple codes */ ++ const uIntf *, /* list of extra bits for non-simple codes */ ++ inflate_huft * FAR*,/* result: starting table */ ++ uIntf *, /* maximum lookup bits (returns actual) */ ++ inflate_huft *, /* space for trees */ ++ uInt *, /* hufts used in space */ ++ uIntf * )); /* space for values */ ++ ++/* Tables for deflate from PKZIP's appnote.txt. */ ++local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ ++ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, ++ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; ++ /* see note #13 above about 258 */ ++local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, ++ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ ++local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ ++ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, ++ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, ++ 8193, 12289, 16385, 24577}; ++local const uInt cpdext[30] = { /* Extra bits for distance codes */ ++ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, ++ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, ++ 12, 12, 13, 13}; ++ ++/* ++ Huffman code decoding is performed using a multi-level table lookup. ++ The fastest way to decode is to simply build a lookup table whose ++ size is determined by the longest code. However, the time it takes ++ to build this table can also be a factor if the data being decoded ++ is not very long. The most common codes are necessarily the ++ shortest codes, so those codes dominate the decoding time, and hence ++ the speed. The idea is you can have a shorter table that decodes the ++ shorter, more probable codes, and then point to subsidiary tables for ++ the longer codes. The time it costs to decode the longer codes is ++ then traded against the time it takes to make longer tables. ++ ++ This results of this trade are in the variables lbits and dbits ++ below. lbits is the number of bits the first level table for literal/ ++ length codes can decode in one step, and dbits is the same thing for ++ the distance codes. Subsequent tables are also less than or equal to ++ those sizes. These values may be adjusted either when all of the ++ codes are shorter than that, in which case the longest code length in ++ bits is used, or when the shortest code is *longer* than the requested ++ table size, in which case the length of the shortest code in bits is ++ used. ++ ++ There are two different values for the two tables, since they code a ++ different number of possibilities each. The literal/length table ++ codes 286 possible values, or in a flat code, a little over eight ++ bits. The distance table codes 30 possible values, or a little less ++ than five bits, flat. The optimum values for speed end up being ++ about one bit more than those, so lbits is 8+1 and dbits is 5+1. ++ The optimum values may differ though from machine to machine, and ++ possibly even between compilers. Your mileage may vary. ++ */ ++ ++ ++/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ ++#define BMAX 15 /* maximum bit length of any code */ ++ ++local int huft_build(b, n, s, d, e, t, m, hp, hn, v) ++uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ ++uInt n; /* number of codes (assumed <= 288) */ ++uInt s; /* number of simple-valued codes (0..s-1) */ ++const uIntf *d; /* list of base values for non-simple codes */ ++const uIntf *e; /* list of extra bits for non-simple codes */ ++inflate_huft * FAR *t; /* result: starting table */ ++uIntf *m; /* maximum lookup bits, returns actual */ ++inflate_huft *hp; /* space for trees */ ++uInt *hn; /* hufts used in space */ ++uIntf *v; /* working area: values in order of bit length */ ++/* Given a list of code lengths and a maximum table size, make a set of ++ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR ++ if the given code set is incomplete (the tables are still built in this ++ case), or Z_DATA_ERROR if the input is invalid. */ ++{ ++ ++ uInt a; /* counter for codes of length k */ ++ uInt c[BMAX+1]; /* bit length count table */ ++ uInt f; /* i repeats in table every f entries */ ++ int g; /* maximum code length */ ++ int h; /* table level */ ++ register uInt i; /* counter, current code */ ++ register uInt j; /* counter */ ++ register int k; /* number of bits in current code */ ++ int l; /* bits per table (returned in m) */ ++ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ ++ register uIntf *p; /* pointer into c[], b[], or v[] */ ++ inflate_huft *q; /* points to current table */ ++ struct inflate_huft_s r; /* table entry for structure assignment */ ++ inflate_huft *u[BMAX]; /* table stack */ ++ register int w; /* bits before this table == (l * h) */ ++ uInt x[BMAX+1]; /* bit offsets, then code stack */ ++ uIntf *xp; /* pointer into x */ ++ int y; /* number of dummy codes added */ ++ uInt z; /* number of entries in current table */ ++ ++ ++ /* Generate counts for each bit length */ ++ p = c; ++#define C0 *p++ = 0; ++#define C2 C0 C0 C0 C0 ++#define C4 C2 C2 C2 C2 ++ C4 /* clear c[]--assume BMAX+1 is 16 */ ++ p = b; i = n; ++ do { ++ c[*p++]++; /* assume all entries <= BMAX */ ++ } while (--i); ++ if (c[0] == n) /* null input--all zero length codes */ ++ { ++ *t = (inflate_huft *)Z_NULL; ++ *m = 0; ++ return Z_OK; ++ } ++ ++ ++ /* Find minimum and maximum length, bound *m by those */ ++ l = *m; ++ for (j = 1; j <= BMAX; j++) ++ if (c[j]) ++ break; ++ k = j; /* minimum code length */ ++ if ((uInt)l < j) ++ l = j; ++ for (i = BMAX; i; i--) ++ if (c[i]) ++ break; ++ g = i; /* maximum code length */ ++ if ((uInt)l > i) ++ l = i; ++ *m = l; ++ ++ ++ /* Adjust last length count to fill out codes, if needed */ ++ for (y = 1 << j; j < i; j++, y <<= 1) ++ if ((y -= c[j]) < 0) ++ return Z_DATA_ERROR; ++ if ((y -= c[i]) < 0) ++ return Z_DATA_ERROR; ++ c[i] += y; ++ ++ ++ /* Generate starting offsets into the value table for each length */ ++ x[1] = j = 0; ++ p = c + 1; xp = x + 2; ++ while (--i) { /* note that i == g from above */ ++ *xp++ = (j += *p++); ++ } ++ ++ ++ /* Make a table of values in order of bit lengths */ ++ p = b; i = 0; ++ do { ++ if ((j = *p++) != 0) ++ v[x[j]++] = i; ++ } while (++i < n); ++ n = x[g]; /* set n to length of v */ ++ ++ ++ /* Generate the Huffman codes and for each, make the table entries */ ++ x[0] = i = 0; /* first Huffman code is zero */ ++ p = v; /* grab values in bit order */ ++ h = -1; /* no tables yet--level -1 */ ++ w = -l; /* bits decoded == (l * h) */ ++ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ ++ q = (inflate_huft *)Z_NULL; /* ditto */ ++ z = 0; /* ditto */ ++ ++ /* go through the bit lengths (k already is bits in shortest code) */ ++ for (; k <= g; k++) ++ { ++ a = c[k]; ++ while (a--) ++ { ++ /* here i is the Huffman code of length k bits for value *p */ ++ /* make tables up to required level */ ++ while (k > w + l) ++ { ++ h++; ++ w += l; /* previous table always l bits */ ++ ++ /* compute minimum size table less than or equal to l bits */ ++ z = g - w; ++ z = z > (uInt)l ? l : z; /* table size upper limit */ ++ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ ++ { /* too few codes for k-w bit table */ ++ f -= a + 1; /* deduct codes from patterns left */ ++ xp = c + k; ++ if (j < z) ++ while (++j < z) /* try smaller tables up to z bits */ ++ { ++ if ((f <<= 1) <= *++xp) ++ break; /* enough codes to use up j bits */ ++ f -= *xp; /* else deduct codes from patterns */ ++ } ++ } ++ z = 1 << j; /* table entries for j-bit table */ ++ ++ /* allocate new table */ ++ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ ++ return Z_DATA_ERROR; /* overflow of MANY */ ++ u[h] = q = hp + *hn; ++ *hn += z; ++ ++ /* connect to last table, if there is one */ ++ if (h) ++ { ++ x[h] = i; /* save pattern for backing up */ ++ r.bits = (Byte)l; /* bits to dump before this table */ ++ r.exop = (Byte)j; /* bits in this table */ ++ j = i >> (w - l); ++ r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ ++ u[h-1][j] = r; /* connect to last table */ ++ } ++ else ++ *t = q; /* first table is returned result */ ++ } ++ ++ /* set up table entry in r */ ++ r.bits = (Byte)(k - w); ++ if (p >= v + n) ++ r.exop = 128 + 64; /* out of values--invalid code */ ++ else if (*p < s) ++ { ++ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ ++ r.base = *p++; /* simple code is just the value */ ++ } ++ else ++ { ++ r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ ++ r.base = d[*p++ - s]; ++ } ++ ++ /* fill code-like entries with r */ ++ f = 1 << (k - w); ++ for (j = i >> w; j < z; j += f) ++ q[j] = r; ++ ++ /* backwards increment the k-bit code i */ ++ for (j = 1 << (k - 1); i & j; j >>= 1) ++ i ^= j; ++ i ^= j; ++ ++ /* backup over finished tables */ ++ mask = (1 << w) - 1; /* needed on HP, cc -O bug */ ++ while ((i & mask) != x[h]) ++ { ++ h--; /* don't need to update q */ ++ w -= l; ++ mask = (1 << w) - 1; ++ } ++ } ++ } ++ ++ ++ /* Return Z_BUF_ERROR if we were given an incomplete table */ ++ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; ++} ++ ++ ++int inflate_trees_bits(c, bb, tb, hp, z) ++uIntf *c; /* 19 code lengths */ ++uIntf *bb; /* bits tree desired/actual depth */ ++inflate_huft * FAR *tb; /* bits tree result */ ++inflate_huft *hp; /* space for trees */ ++z_streamp z; /* for messages */ ++{ ++ int r; ++ uInt hn = 0; /* hufts used in space */ ++ uIntf *v; /* work area for huft_build */ ++ ++ if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) ++ return Z_MEM_ERROR; ++ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, ++ tb, bb, hp, &hn, v); ++ if (r == Z_DATA_ERROR) ++ z->msg = (char*)"oversubscribed dynamic bit lengths tree"; ++ else if (r == Z_BUF_ERROR || *bb == 0) ++ { ++ z->msg = (char*)"incomplete dynamic bit lengths tree"; ++ r = Z_DATA_ERROR; ++ } ++ ZFREE(z, v); ++ return r; ++} ++ ++ ++int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z) ++uInt nl; /* number of literal/length codes */ ++uInt nd; /* number of distance codes */ ++uIntf *c; /* that many (total) code lengths */ ++uIntf *bl; /* literal desired/actual bit depth */ ++uIntf *bd; /* distance desired/actual bit depth */ ++inflate_huft * FAR *tl; /* literal/length tree result */ ++inflate_huft * FAR *td; /* distance tree result */ ++inflate_huft *hp; /* space for trees */ ++z_streamp z; /* for messages */ ++{ ++ int r; ++ uInt hn = 0; /* hufts used in space */ ++ uIntf *v; /* work area for huft_build */ ++ ++ /* allocate work area */ ++ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) ++ return Z_MEM_ERROR; ++ ++ /* build literal/length tree */ ++ r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); ++ if (r != Z_OK || *bl == 0) ++ { ++ if (r == Z_DATA_ERROR) ++ z->msg = (char*)"oversubscribed literal/length tree"; ++ else if (r != Z_MEM_ERROR) ++ { ++ z->msg = (char*)"incomplete literal/length tree"; ++ r = Z_DATA_ERROR; ++ } ++ ZFREE(z, v); ++ return r; ++ } ++ ++ /* build distance tree */ ++ r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); ++ if (r != Z_OK || (*bd == 0 && nl > 257)) ++ { ++ if (r == Z_DATA_ERROR) ++ z->msg = (char*)"oversubscribed distance tree"; ++ else if (r == Z_BUF_ERROR) { ++#ifdef PKZIP_BUG_WORKAROUND ++ r = Z_OK; ++ } ++#else ++ z->msg = (char*)"incomplete distance tree"; ++ r = Z_DATA_ERROR; ++ } ++ else if (r != Z_MEM_ERROR) ++ { ++ z->msg = (char*)"empty distance tree with lengths"; ++ r = Z_DATA_ERROR; ++ } ++ ZFREE(z, v); ++ return r; ++#endif ++ } ++ ++ /* done */ ++ ZFREE(z, v); ++ return Z_OK; ++} ++ ++ ++/* build fixed tables only once--keep them here */ ++#ifdef BUILDFIXED ++local int fixed_built = 0; ++#define FIXEDH 544 /* number of hufts used by fixed tables */ ++local inflate_huft fixed_mem[FIXEDH]; ++local uInt fixed_bl; ++local uInt fixed_bd; ++local inflate_huft *fixed_tl; ++local inflate_huft *fixed_td; ++#else ++#include "inffixed.h" ++#endif ++ ++ ++int inflate_trees_fixed(bl, bd, tl, td, z) ++uIntf *bl; /* literal desired/actual bit depth */ ++uIntf *bd; /* distance desired/actual bit depth */ ++inflate_huft * FAR *tl; /* literal/length tree result */ ++inflate_huft * FAR *td; /* distance tree result */ ++z_streamp z; /* for memory allocation */ ++{ ++#ifdef BUILDFIXED ++ /* build fixed tables if not already */ ++ if (!fixed_built) ++ { ++ int k; /* temporary variable */ ++ uInt f = 0; /* number of hufts used in fixed_mem */ ++ uIntf *c; /* length list for huft_build */ ++ uIntf *v; /* work area for huft_build */ ++ ++ /* allocate memory */ ++ if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) ++ return Z_MEM_ERROR; ++ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) ++ { ++ ZFREE(z, c); ++ return Z_MEM_ERROR; ++ } ++ ++ /* literal table */ ++ for (k = 0; k < 144; k++) ++ c[k] = 8; ++ for (; k < 256; k++) ++ c[k] = 9; ++ for (; k < 280; k++) ++ c[k] = 7; ++ for (; k < 288; k++) ++ c[k] = 8; ++ fixed_bl = 9; ++ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, ++ fixed_mem, &f, v); ++ ++ /* distance table */ ++ for (k = 0; k < 30; k++) ++ c[k] = 5; ++ fixed_bd = 5; ++ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, ++ fixed_mem, &f, v); ++ ++ /* done */ ++ ZFREE(z, v); ++ ZFREE(z, c); ++ fixed_built = 1; ++ } ++#endif ++ *bl = fixed_bl; ++ *bd = fixed_bd; ++ *tl = fixed_tl; ++ *td = fixed_td; ++ return Z_OK; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/inftrees.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,63 @@ ++/* inftrees.h -- header to use inftrees.c ++ * Copyright (C) 1995-2002 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++/* Huffman code lookup table entry--this entry is four bytes for machines ++ that have 16-bit pointers (e.g. PC's in the small or medium model). */ ++ ++#ifndef _INFTREES_H ++#define _INFTREES_H ++ ++typedef struct inflate_huft_s FAR inflate_huft; ++ ++struct inflate_huft_s { ++ union { ++ struct { ++ Byte Exop; /* number of extra bits or operation */ ++ Byte Bits; /* number of bits in this code or subcode */ ++ } what; ++ uInt pad; /* pad structure to a power of 2 (4 bytes for */ ++ } word; /* 16-bit, 8 bytes for 32-bit int's) */ ++ uInt base; /* literal, length base, distance base, ++ or table offset */ ++}; ++ ++/* Maximum size of dynamic tree. The maximum found in a long but non- ++ exhaustive search was 1004 huft structures (850 for length/literals ++ and 154 for distances, the latter actually the result of an ++ exhaustive search). The actual maximum is not known, but the ++ value below is more than safe. */ ++#define MANY 1440 ++ ++extern int inflate_trees_bits OF(( ++ uIntf *, /* 19 code lengths */ ++ uIntf *, /* bits tree desired/actual depth */ ++ inflate_huft * FAR *, /* bits tree result */ ++ inflate_huft *, /* space for trees */ ++ z_streamp)); /* for messages */ ++ ++extern int inflate_trees_dynamic OF(( ++ uInt, /* number of literal/length codes */ ++ uInt, /* number of distance codes */ ++ uIntf *, /* that many (total) code lengths */ ++ uIntf *, /* literal desired/actual bit depth */ ++ uIntf *, /* distance desired/actual bit depth */ ++ inflate_huft * FAR *, /* literal/length tree result */ ++ inflate_huft * FAR *, /* distance tree result */ ++ inflate_huft *, /* space for trees */ ++ z_streamp)); /* for messages */ ++ ++extern int inflate_trees_fixed OF(( ++ uIntf *, /* literal desired/actual bit depth */ ++ uIntf *, /* distance desired/actual bit depth */ ++ inflate_huft * FAR *, /* literal/length tree result */ ++ inflate_huft * FAR *, /* distance tree result */ ++ z_streamp)); /* for memory allocation */ ++ ++#endif /* _INFTREES_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/infutil.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,87 @@ ++/* inflate_util.c -- data and routines common to blocks and codes ++ * Copyright (C) 1995-2002 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++#include ++#include "infblock.h" ++#include "inftrees.h" ++#include "infcodes.h" ++#include "infutil.h" ++ ++struct inflate_codes_state {int dummy;}; /* for buggy compilers */ ++ ++/* And'ing with mask[n] masks the lower n bits */ ++uInt inflate_mask[17] = { ++ 0x0000, ++ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, ++ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff ++}; ++ ++ ++/* copy as much as possible from the sliding window to the output area */ ++int inflate_flush(s, z, r) ++inflate_blocks_statef *s; ++z_streamp z; ++int r; ++{ ++ uInt n; ++ Bytef *p; ++ Bytef *q; ++ ++ /* local copies of source and destination pointers */ ++ p = z->next_out; ++ q = s->read; ++ ++ /* compute number of bytes to copy as far as end of window */ ++ n = (uInt)((q <= s->write ? s->write : s->end) - q); ++ if (n > z->avail_out) n = z->avail_out; ++ if (n && r == Z_BUF_ERROR) r = Z_OK; ++ ++ /* update counters */ ++ z->avail_out -= n; ++ z->total_out += n; ++ ++ /* update check information */ ++ if (s->checkfn != Z_NULL) ++ z->adler = s->check = (*s->checkfn)(s->check, q, n); ++ ++ /* copy as far as end of window */ ++ zmemcpy(p, q, n); ++ p += n; ++ q += n; ++ ++ /* see if more to copy at beginning of window */ ++ if (q == s->end) ++ { ++ /* wrap pointers */ ++ q = s->window; ++ if (s->write == s->end) ++ s->write = s->window; ++ ++ /* compute bytes to copy */ ++ n = (uInt)(s->write - q); ++ if (n > z->avail_out) n = z->avail_out; ++ if (n && r == Z_BUF_ERROR) r = Z_OK; ++ ++ /* update counters */ ++ z->avail_out -= n; ++ z->total_out += n; ++ ++ /* update check information */ ++ if (s->checkfn != Z_NULL) ++ z->adler = s->check = (*s->checkfn)(s->check, q, n); ++ ++ /* copy */ ++ zmemcpy(p, q, n); ++ p += n; ++ q += n; ++ } ++ ++ /* update pointers */ ++ z->next_out = p; ++ s->read = q; ++ ++ /* done */ ++ return r; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/infutil.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,98 @@ ++/* infutil.h -- types and macros common to blocks and codes ++ * Copyright (C) 1995-2002 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* WARNING: this file should *not* be used by applications. It is ++ part of the implementation of the compression library and is ++ subject to change. Applications should only use zlib.h. ++ */ ++ ++#ifndef _INFUTIL_H ++#define _INFUTIL_H ++ ++typedef enum { ++ TYPE, /* get type bits (3, including end bit) */ ++ LENS, /* get lengths for stored */ ++ STORED, /* processing stored block */ ++ TABLE, /* get table lengths */ ++ BTREE, /* get bit lengths tree for a dynamic block */ ++ DTREE, /* get length, distance trees for a dynamic block */ ++ CODES, /* processing fixed or dynamic block */ ++ DRY, /* output remaining window bytes */ ++ DONE, /* finished last block, done */ ++ BAD} /* got a data error--stuck here */ ++inflate_block_mode; ++ ++/* inflate blocks semi-private state */ ++struct inflate_blocks_state { ++ ++ /* mode */ ++ inflate_block_mode mode; /* current inflate_block mode */ ++ ++ /* mode dependent information */ ++ union { ++ uInt left; /* if STORED, bytes left to copy */ ++ struct { ++ uInt table; /* table lengths (14 bits) */ ++ uInt index; /* index into blens (or border) */ ++ uIntf *blens; /* bit lengths of codes */ ++ uInt bb; /* bit length tree depth */ ++ inflate_huft *tb; /* bit length decoding tree */ ++ } trees; /* if DTREE, decoding info for trees */ ++ struct { ++ inflate_codes_statef ++ *codes; ++ } decode; /* if CODES, current state */ ++ } sub; /* submode */ ++ uInt last; /* true if this block is the last block */ ++ ++ /* mode independent information */ ++ uInt bitk; /* bits in bit buffer */ ++ uLong bitb; /* bit buffer */ ++ inflate_huft *hufts; /* single malloc for tree space */ ++ Bytef *window; /* sliding window */ ++ Bytef *end; /* one byte after sliding window */ ++ Bytef *read; /* window read pointer */ ++ Bytef *write; /* window write pointer */ ++ check_func checkfn; /* check function */ ++ uLong check; /* check on output */ ++ ++}; ++ ++ ++/* defines for inflate input/output */ ++/* update pointers and return */ ++#define UPDBITS {s->bitb=b;s->bitk=k;} ++#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} ++#define UPDOUT {s->write=q;} ++#define UPDATE {UPDBITS UPDIN UPDOUT} ++#define LEAVE {UPDATE return inflate_flush(s,z,r);} ++/* get bytes and bits */ ++#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} ++#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} ++#define NEXTBYTE (n--,*p++) ++#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} ++/* output bytes */ ++#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) ++#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} ++#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} ++#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} ++#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} ++#define OUTBYTE(a) {*q++=(Byte)(a);m--;} ++/* load local pointers */ ++#define LOAD {LOADIN LOADOUT} ++ ++/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ ++extern uInt inflate_mask[17]; ++ ++/* copy as much as possible from the sliding window to the output area */ ++extern int inflate_flush OF(( ++ inflate_blocks_statef *, ++ z_streamp , ++ int)); ++ ++struct internal_state {int dummy;}; /* for buggy compilers */ ++ ++#endif /* _INFUTIL_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/match586.S Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,357 @@ ++/* match.s -- Pentium-optimized version of longest_match() ++ * Written for zlib 1.1.2 ++ * Copyright (C) 1998 Brian Raiter ++ * ++ * This is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License. ++ */ ++ ++#ifndef NO_UNDERLINE ++#define match_init _ipcomp_match_init ++#define longest_match _ipcomp_longest_match ++#else ++#define match_init ipcomp_match_init ++#define longest_match ipcomp_longest_match ++#endif ++ ++#define MAX_MATCH (258) ++#define MIN_MATCH (3) ++#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) ++#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) ++ ++/* stack frame offsets */ ++ ++#define wmask 0 /* local copy of s->wmask */ ++#define window 4 /* local copy of s->window */ ++#define windowbestlen 8 /* s->window + bestlen */ ++#define chainlenscanend 12 /* high word: current chain len */ ++ /* low word: last bytes sought */ ++#define scanstart 16 /* first two bytes of string */ ++#define scanalign 20 /* dword-misalignment of string */ ++#define nicematch 24 /* a good enough match size */ ++#define bestlen 28 /* size of best match so far */ ++#define scan 32 /* ptr to string wanting match */ ++ ++#define LocalVarsSize (36) ++/* saved ebx 36 */ ++/* saved edi 40 */ ++/* saved esi 44 */ ++/* saved ebp 48 */ ++/* return address 52 */ ++#define deflatestate 56 /* the function arguments */ ++#define curmatch 60 ++ ++/* Offsets for fields in the deflate_state structure. These numbers ++ * are calculated from the definition of deflate_state, with the ++ * assumption that the compiler will dword-align the fields. (Thus, ++ * changing the definition of deflate_state could easily cause this ++ * program to crash horribly, without so much as a warning at ++ * compile time. Sigh.) ++ */ ++#define dsWSize 36 ++#define dsWMask 44 ++#define dsWindow 48 ++#define dsPrev 56 ++#define dsMatchLen 88 ++#define dsPrevMatch 92 ++#define dsStrStart 100 ++#define dsMatchStart 104 ++#define dsLookahead 108 ++#define dsPrevLen 112 ++#define dsMaxChainLen 116 ++#define dsGoodMatch 132 ++#define dsNiceMatch 136 ++ ++ ++.file "match.S" ++ ++.globl match_init, longest_match ++ ++.text ++ ++/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ ++ ++longest_match: ++ ++/* Save registers that the compiler may be using, and adjust %esp to */ ++/* make room for our stack frame. */ ++ ++ pushl %ebp ++ pushl %edi ++ pushl %esi ++ pushl %ebx ++ subl $LocalVarsSize, %esp ++ ++/* Retrieve the function arguments. %ecx will hold cur_match */ ++/* throughout the entire function. %edx will hold the pointer to the */ ++/* deflate_state structure during the function's setup (before */ ++/* entering the main loop). */ ++ ++ movl deflatestate(%esp), %edx ++ movl curmatch(%esp), %ecx ++ ++/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ ++ ++ movl dsNiceMatch(%edx), %eax ++ movl dsLookahead(%edx), %ebx ++ cmpl %eax, %ebx ++ jl LookaheadLess ++ movl %eax, %ebx ++LookaheadLess: movl %ebx, nicematch(%esp) ++ ++/* register Bytef *scan = s->window + s->strstart; */ ++ ++ movl dsWindow(%edx), %esi ++ movl %esi, window(%esp) ++ movl dsStrStart(%edx), %ebp ++ lea (%esi,%ebp), %edi ++ movl %edi, scan(%esp) ++ ++/* Determine how many bytes the scan ptr is off from being */ ++/* dword-aligned. */ ++ ++ movl %edi, %eax ++ negl %eax ++ andl $3, %eax ++ movl %eax, scanalign(%esp) ++ ++/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ ++/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ ++ ++ movl dsWSize(%edx), %eax ++ subl $MIN_LOOKAHEAD, %eax ++ subl %eax, %ebp ++ jg LimitPositive ++ xorl %ebp, %ebp ++LimitPositive: ++ ++/* unsigned chain_length = s->max_chain_length; */ ++/* if (s->prev_length >= s->good_match) { */ ++/* chain_length >>= 2; */ ++/* } */ ++ ++ movl dsPrevLen(%edx), %eax ++ movl dsGoodMatch(%edx), %ebx ++ cmpl %ebx, %eax ++ movl dsMaxChainLen(%edx), %ebx ++ jl LastMatchGood ++ shrl $2, %ebx ++LastMatchGood: ++ ++/* chainlen is decremented once beforehand so that the function can */ ++/* use the sign flag instead of the zero flag for the exit test. */ ++/* It is then shifted into the high word, to make room for the scanend */ ++/* scanend value, which it will always accompany. */ ++ ++ decl %ebx ++ shll $16, %ebx ++ ++/* int best_len = s->prev_length; */ ++ ++ movl dsPrevLen(%edx), %eax ++ movl %eax, bestlen(%esp) ++ ++/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ ++ ++ addl %eax, %esi ++ movl %esi, windowbestlen(%esp) ++ ++/* register ush scan_start = *(ushf*)scan; */ ++/* register ush scan_end = *(ushf*)(scan+best_len-1); */ ++ ++ movw (%edi), %bx ++ movw %bx, scanstart(%esp) ++ movw -1(%edi,%eax), %bx ++ movl %ebx, chainlenscanend(%esp) ++ ++/* Posf *prev = s->prev; */ ++/* uInt wmask = s->w_mask; */ ++ ++ movl dsPrev(%edx), %edi ++ movl dsWMask(%edx), %edx ++ mov %edx, wmask(%esp) ++ ++/* Jump into the main loop. */ ++ ++ jmp LoopEntry ++ ++.balign 16 ++ ++/* do { ++ * match = s->window + cur_match; ++ * if (*(ushf*)(match+best_len-1) != scan_end || ++ * *(ushf*)match != scan_start) continue; ++ * [...] ++ * } while ((cur_match = prev[cur_match & wmask]) > limit ++ * && --chain_length != 0); ++ * ++ * Here is the inner loop of the function. The function will spend the ++ * majority of its time in this loop, and majority of that time will ++ * be spent in the first ten instructions. ++ * ++ * Within this loop: ++ * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend) ++ * %ecx = curmatch ++ * %edx = curmatch & wmask ++ * %esi = windowbestlen - i.e., (window + bestlen) ++ * %edi = prev ++ * %ebp = limit ++ * ++ * Two optimization notes on the choice of instructions: ++ * ++ * The first instruction uses a 16-bit address, which costs an extra, ++ * unpairable cycle. This is cheaper than doing a 32-bit access and ++ * zeroing the high word, due to the 3-cycle misalignment penalty which ++ * would occur half the time. This also turns out to be cheaper than ++ * doing two separate 8-bit accesses, as the memory is so rarely in the ++ * L1 cache. ++ * ++ * The window buffer, however, apparently spends a lot of time in the ++ * cache, and so it is faster to retrieve the word at the end of the ++ * match string with two 8-bit loads. The instructions that test the ++ * word at the beginning of the match string, however, are executed ++ * much less frequently, and there it was cheaper to use 16-bit ++ * instructions, which avoided the necessity of saving off and ++ * subsequently reloading one of the other registers. ++ */ ++LookupLoop: ++ /* 1 U & V */ ++ movw (%edi,%edx,2), %cx /* 2 U pipe */ ++ movl wmask(%esp), %edx /* 2 V pipe */ ++ cmpl %ebp, %ecx /* 3 U pipe */ ++ jbe LeaveNow /* 3 V pipe */ ++ subl $0x00010000, %ebx /* 4 U pipe */ ++ js LeaveNow /* 4 V pipe */ ++LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */ ++ andl %ecx, %edx /* 5 V pipe */ ++ cmpb %bl, %al /* 6 U pipe */ ++ jnz LookupLoop /* 6 V pipe */ ++ movb (%esi,%ecx), %ah ++ cmpb %bh, %ah ++ jnz LookupLoop ++ movl window(%esp), %eax ++ movw (%eax,%ecx), %ax ++ cmpw scanstart(%esp), %ax ++ jnz LookupLoop ++ ++/* Store the current value of chainlen. */ ++ ++ movl %ebx, chainlenscanend(%esp) ++ ++/* Point %edi to the string under scrutiny, and %esi to the string we */ ++/* are hoping to match it up with. In actuality, %esi and %edi are */ ++/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ ++/* initialized to -(MAX_MATCH_8 - scanalign). */ ++ ++ movl window(%esp), %esi ++ movl scan(%esp), %edi ++ addl %ecx, %esi ++ movl scanalign(%esp), %eax ++ movl $(-MAX_MATCH_8), %edx ++ lea MAX_MATCH_8(%edi,%eax), %edi ++ lea MAX_MATCH_8(%esi,%eax), %esi ++ ++/* Test the strings for equality, 8 bytes at a time. At the end, ++ * adjust %edx so that it is offset to the exact byte that mismatched. ++ * ++ * We already know at this point that the first three bytes of the ++ * strings match each other, and they can be safely passed over before ++ * starting the compare loop. So what this code does is skip over 0-3 ++ * bytes, as much as necessary in order to dword-align the %edi ++ * pointer. (%esi will still be misaligned three times out of four.) ++ * ++ * It should be confessed that this loop usually does not represent ++ * much of the total running time. Replacing it with a more ++ * straightforward "rep cmpsb" would not drastically degrade ++ * performance. ++ */ ++LoopCmps: ++ movl (%esi,%edx), %eax ++ movl (%edi,%edx), %ebx ++ xorl %ebx, %eax ++ jnz LeaveLoopCmps ++ movl 4(%esi,%edx), %eax ++ movl 4(%edi,%edx), %ebx ++ xorl %ebx, %eax ++ jnz LeaveLoopCmps4 ++ addl $8, %edx ++ jnz LoopCmps ++ jmp LenMaximum ++LeaveLoopCmps4: addl $4, %edx ++LeaveLoopCmps: testl $0x0000FFFF, %eax ++ jnz LenLower ++ addl $2, %edx ++ shrl $16, %eax ++LenLower: subb $1, %al ++ adcl $0, %edx ++ ++/* Calculate the length of the match. If it is longer than MAX_MATCH, */ ++/* then automatically accept it as the best possible match and leave. */ ++ ++ lea (%edi,%edx), %eax ++ movl scan(%esp), %edi ++ subl %edi, %eax ++ cmpl $MAX_MATCH, %eax ++ jge LenMaximum ++ ++/* If the length of the match is not longer than the best match we */ ++/* have so far, then forget it and return to the lookup loop. */ ++ ++ movl deflatestate(%esp), %edx ++ movl bestlen(%esp), %ebx ++ cmpl %ebx, %eax ++ jg LongerMatch ++ movl chainlenscanend(%esp), %ebx ++ movl windowbestlen(%esp), %esi ++ movl dsPrev(%edx), %edi ++ movl wmask(%esp), %edx ++ andl %ecx, %edx ++ jmp LookupLoop ++ ++/* s->match_start = cur_match; */ ++/* best_len = len; */ ++/* if (len >= nice_match) break; */ ++/* scan_end = *(ushf*)(scan+best_len-1); */ ++ ++LongerMatch: movl nicematch(%esp), %ebx ++ movl %eax, bestlen(%esp) ++ movl %ecx, dsMatchStart(%edx) ++ cmpl %ebx, %eax ++ jge LeaveNow ++ movl window(%esp), %esi ++ addl %eax, %esi ++ movl %esi, windowbestlen(%esp) ++ movl chainlenscanend(%esp), %ebx ++ movw -1(%edi,%eax), %bx ++ movl dsPrev(%edx), %edi ++ movl %ebx, chainlenscanend(%esp) ++ movl wmask(%esp), %edx ++ andl %ecx, %edx ++ jmp LookupLoop ++ ++/* Accept the current string, with the maximum possible length. */ ++ ++LenMaximum: movl deflatestate(%esp), %edx ++ movl $MAX_MATCH, bestlen(%esp) ++ movl %ecx, dsMatchStart(%edx) ++ ++/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ ++/* return s->lookahead; */ ++ ++LeaveNow: ++ movl deflatestate(%esp), %edx ++ movl bestlen(%esp), %ebx ++ movl dsLookahead(%edx), %eax ++ cmpl %eax, %ebx ++ jg LookaheadRet ++ movl %ebx, %eax ++LookaheadRet: ++ ++/* Restore the stack and return from whence we came. */ ++ ++ addl $LocalVarsSize, %esp ++ popl %ebx ++ popl %esi ++ popl %edi ++ popl %ebp ++match_init: ret +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/match686.S Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,330 @@ ++/* match.s -- Pentium-Pro-optimized version of longest_match() ++ * Written for zlib 1.1.2 ++ * Copyright (C) 1998 Brian Raiter ++ * ++ * This is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License. ++ */ ++ ++#ifndef NO_UNDERLINE ++#define match_init _ipcomp_match_init ++#define longest_match _ipcomp_longest_match ++#else ++#define match_init ipcomp_match_init ++#define longest_match ipcomp_longest_match ++#endif ++ ++#define MAX_MATCH (258) ++#define MIN_MATCH (3) ++#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) ++#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) ++ ++/* stack frame offsets */ ++ ++#define chainlenwmask 0 /* high word: current chain len */ ++ /* low word: s->wmask */ ++#define window 4 /* local copy of s->window */ ++#define windowbestlen 8 /* s->window + bestlen */ ++#define scanstart 16 /* first two bytes of string */ ++#define scanend 12 /* last two bytes of string */ ++#define scanalign 20 /* dword-misalignment of string */ ++#define nicematch 24 /* a good enough match size */ ++#define bestlen 28 /* size of best match so far */ ++#define scan 32 /* ptr to string wanting match */ ++ ++#define LocalVarsSize (36) ++/* saved ebx 36 */ ++/* saved edi 40 */ ++/* saved esi 44 */ ++/* saved ebp 48 */ ++/* return address 52 */ ++#define deflatestate 56 /* the function arguments */ ++#define curmatch 60 ++ ++/* Offsets for fields in the deflate_state structure. These numbers ++ * are calculated from the definition of deflate_state, with the ++ * assumption that the compiler will dword-align the fields. (Thus, ++ * changing the definition of deflate_state could easily cause this ++ * program to crash horribly, without so much as a warning at ++ * compile time. Sigh.) ++ */ ++#define dsWSize 36 ++#define dsWMask 44 ++#define dsWindow 48 ++#define dsPrev 56 ++#define dsMatchLen 88 ++#define dsPrevMatch 92 ++#define dsStrStart 100 ++#define dsMatchStart 104 ++#define dsLookahead 108 ++#define dsPrevLen 112 ++#define dsMaxChainLen 116 ++#define dsGoodMatch 132 ++#define dsNiceMatch 136 ++ ++ ++.file "match.S" ++ ++.globl match_init, longest_match ++ ++.text ++ ++/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ ++ ++longest_match: ++ ++/* Save registers that the compiler may be using, and adjust %esp to */ ++/* make room for our stack frame. */ ++ ++ pushl %ebp ++ pushl %edi ++ pushl %esi ++ pushl %ebx ++ subl $LocalVarsSize, %esp ++ ++/* Retrieve the function arguments. %ecx will hold cur_match */ ++/* throughout the entire function. %edx will hold the pointer to the */ ++/* deflate_state structure during the function's setup (before */ ++/* entering the main loop). */ ++ ++ movl deflatestate(%esp), %edx ++ movl curmatch(%esp), %ecx ++ ++/* uInt wmask = s->w_mask; */ ++/* unsigned chain_length = s->max_chain_length; */ ++/* if (s->prev_length >= s->good_match) { */ ++/* chain_length >>= 2; */ ++/* } */ ++ ++ movl dsPrevLen(%edx), %eax ++ movl dsGoodMatch(%edx), %ebx ++ cmpl %ebx, %eax ++ movl dsWMask(%edx), %eax ++ movl dsMaxChainLen(%edx), %ebx ++ jl LastMatchGood ++ shrl $2, %ebx ++LastMatchGood: ++ ++/* chainlen is decremented once beforehand so that the function can */ ++/* use the sign flag instead of the zero flag for the exit test. */ ++/* It is then shifted into the high word, to make room for the wmask */ ++/* value, which it will always accompany. */ ++ ++ decl %ebx ++ shll $16, %ebx ++ orl %eax, %ebx ++ movl %ebx, chainlenwmask(%esp) ++ ++/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ ++ ++ movl dsNiceMatch(%edx), %eax ++ movl dsLookahead(%edx), %ebx ++ cmpl %eax, %ebx ++ jl LookaheadLess ++ movl %eax, %ebx ++LookaheadLess: movl %ebx, nicematch(%esp) ++ ++/* register Bytef *scan = s->window + s->strstart; */ ++ ++ movl dsWindow(%edx), %esi ++ movl %esi, window(%esp) ++ movl dsStrStart(%edx), %ebp ++ lea (%esi,%ebp), %edi ++ movl %edi, scan(%esp) ++ ++/* Determine how many bytes the scan ptr is off from being */ ++/* dword-aligned. */ ++ ++ movl %edi, %eax ++ negl %eax ++ andl $3, %eax ++ movl %eax, scanalign(%esp) ++ ++/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ ++/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ ++ ++ movl dsWSize(%edx), %eax ++ subl $MIN_LOOKAHEAD, %eax ++ subl %eax, %ebp ++ jg LimitPositive ++ xorl %ebp, %ebp ++LimitPositive: ++ ++/* int best_len = s->prev_length; */ ++ ++ movl dsPrevLen(%edx), %eax ++ movl %eax, bestlen(%esp) ++ ++/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ ++ ++ addl %eax, %esi ++ movl %esi, windowbestlen(%esp) ++ ++/* register ush scan_start = *(ushf*)scan; */ ++/* register ush scan_end = *(ushf*)(scan+best_len-1); */ ++/* Posf *prev = s->prev; */ ++ ++ movzwl (%edi), %ebx ++ movl %ebx, scanstart(%esp) ++ movzwl -1(%edi,%eax), %ebx ++ movl %ebx, scanend(%esp) ++ movl dsPrev(%edx), %edi ++ ++/* Jump into the main loop. */ ++ ++ movl chainlenwmask(%esp), %edx ++ jmp LoopEntry ++ ++.balign 16 ++ ++/* do { ++ * match = s->window + cur_match; ++ * if (*(ushf*)(match+best_len-1) != scan_end || ++ * *(ushf*)match != scan_start) continue; ++ * [...] ++ * } while ((cur_match = prev[cur_match & wmask]) > limit ++ * && --chain_length != 0); ++ * ++ * Here is the inner loop of the function. The function will spend the ++ * majority of its time in this loop, and majority of that time will ++ * be spent in the first ten instructions. ++ * ++ * Within this loop: ++ * %ebx = scanend ++ * %ecx = curmatch ++ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) ++ * %esi = windowbestlen - i.e., (window + bestlen) ++ * %edi = prev ++ * %ebp = limit ++ */ ++LookupLoop: ++ andl %edx, %ecx ++ movzwl (%edi,%ecx,2), %ecx ++ cmpl %ebp, %ecx ++ jbe LeaveNow ++ subl $0x00010000, %edx ++ js LeaveNow ++LoopEntry: movzwl -1(%esi,%ecx), %eax ++ cmpl %ebx, %eax ++ jnz LookupLoop ++ movl window(%esp), %eax ++ movzwl (%eax,%ecx), %eax ++ cmpl scanstart(%esp), %eax ++ jnz LookupLoop ++ ++/* Store the current value of chainlen. */ ++ ++ movl %edx, chainlenwmask(%esp) ++ ++/* Point %edi to the string under scrutiny, and %esi to the string we */ ++/* are hoping to match it up with. In actuality, %esi and %edi are */ ++/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ ++/* initialized to -(MAX_MATCH_8 - scanalign). */ ++ ++ movl window(%esp), %esi ++ movl scan(%esp), %edi ++ addl %ecx, %esi ++ movl scanalign(%esp), %eax ++ movl $(-MAX_MATCH_8), %edx ++ lea MAX_MATCH_8(%edi,%eax), %edi ++ lea MAX_MATCH_8(%esi,%eax), %esi ++ ++/* Test the strings for equality, 8 bytes at a time. At the end, ++ * adjust %edx so that it is offset to the exact byte that mismatched. ++ * ++ * We already know at this point that the first three bytes of the ++ * strings match each other, and they can be safely passed over before ++ * starting the compare loop. So what this code does is skip over 0-3 ++ * bytes, as much as necessary in order to dword-align the %edi ++ * pointer. (%esi will still be misaligned three times out of four.) ++ * ++ * It should be confessed that this loop usually does not represent ++ * much of the total running time. Replacing it with a more ++ * straightforward "rep cmpsb" would not drastically degrade ++ * performance. ++ */ ++LoopCmps: ++ movl (%esi,%edx), %eax ++ xorl (%edi,%edx), %eax ++ jnz LeaveLoopCmps ++ movl 4(%esi,%edx), %eax ++ xorl 4(%edi,%edx), %eax ++ jnz LeaveLoopCmps4 ++ addl $8, %edx ++ jnz LoopCmps ++ jmp LenMaximum ++LeaveLoopCmps4: addl $4, %edx ++LeaveLoopCmps: testl $0x0000FFFF, %eax ++ jnz LenLower ++ addl $2, %edx ++ shrl $16, %eax ++LenLower: subb $1, %al ++ adcl $0, %edx ++ ++/* Calculate the length of the match. If it is longer than MAX_MATCH, */ ++/* then automatically accept it as the best possible match and leave. */ ++ ++ lea (%edi,%edx), %eax ++ movl scan(%esp), %edi ++ subl %edi, %eax ++ cmpl $MAX_MATCH, %eax ++ jge LenMaximum ++ ++/* If the length of the match is not longer than the best match we */ ++/* have so far, then forget it and return to the lookup loop. */ ++ ++ movl deflatestate(%esp), %edx ++ movl bestlen(%esp), %ebx ++ cmpl %ebx, %eax ++ jg LongerMatch ++ movl windowbestlen(%esp), %esi ++ movl dsPrev(%edx), %edi ++ movl scanend(%esp), %ebx ++ movl chainlenwmask(%esp), %edx ++ jmp LookupLoop ++ ++/* s->match_start = cur_match; */ ++/* best_len = len; */ ++/* if (len >= nice_match) break; */ ++/* scan_end = *(ushf*)(scan+best_len-1); */ ++ ++LongerMatch: movl nicematch(%esp), %ebx ++ movl %eax, bestlen(%esp) ++ movl %ecx, dsMatchStart(%edx) ++ cmpl %ebx, %eax ++ jge LeaveNow ++ movl window(%esp), %esi ++ addl %eax, %esi ++ movl %esi, windowbestlen(%esp) ++ movzwl -1(%edi,%eax), %ebx ++ movl dsPrev(%edx), %edi ++ movl %ebx, scanend(%esp) ++ movl chainlenwmask(%esp), %edx ++ jmp LookupLoop ++ ++/* Accept the current string, with the maximum possible length. */ ++ ++LenMaximum: movl deflatestate(%esp), %edx ++ movl $MAX_MATCH, bestlen(%esp) ++ movl %ecx, dsMatchStart(%edx) ++ ++/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ ++/* return s->lookahead; */ ++ ++LeaveNow: ++ movl deflatestate(%esp), %edx ++ movl bestlen(%esp), %ebx ++ movl dsLookahead(%edx), %eax ++ cmpl %eax, %ebx ++ jg LookaheadRet ++ movl %ebx, %eax ++LookaheadRet: ++ ++/* Restore the stack and return from whence we came. */ ++ ++ addl $LocalVarsSize, %esp ++ popl %ebx ++ popl %esi ++ popl %edi ++ popl %ebp ++match_init: ret +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/trees.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,1214 @@ ++/* trees.c -- output deflated data using Huffman coding ++ * Copyright (C) 1995-2002 Jean-loup Gailly ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* ++ * ALGORITHM ++ * ++ * The "deflation" process uses several Huffman trees. The more ++ * common source values are represented by shorter bit sequences. ++ * ++ * Each code tree is stored in a compressed form which is itself ++ * a Huffman encoding of the lengths of all the code strings (in ++ * ascending order by source values). The actual code strings are ++ * reconstructed from the lengths in the inflate process, as described ++ * in the deflate specification. ++ * ++ * REFERENCES ++ * ++ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". ++ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc ++ * ++ * Storer, James A. ++ * Data Compression: Methods and Theory, pp. 49-50. ++ * Computer Science Press, 1988. ISBN 0-7167-8156-5. ++ * ++ * Sedgewick, R. ++ * Algorithms, p290. ++ * Addison-Wesley, 1983. ISBN 0-201-06672-6. ++ */ ++ ++/* @(#) $Id: trees.c,v 1.3 2002/04/24 07:36:45 mcr Exp $ */ ++ ++/* #define GEN_TREES_H */ ++ ++#include "deflate.h" ++ ++#ifdef DEBUG ++# include ++#endif ++ ++/* =========================================================================== ++ * Constants ++ */ ++ ++#define MAX_BL_BITS 7 ++/* Bit length codes must not exceed MAX_BL_BITS bits */ ++ ++#define END_BLOCK 256 ++/* end of block literal code */ ++ ++#define REP_3_6 16 ++/* repeat previous bit length 3-6 times (2 bits of repeat count) */ ++ ++#define REPZ_3_10 17 ++/* repeat a zero length 3-10 times (3 bits of repeat count) */ ++ ++#define REPZ_11_138 18 ++/* repeat a zero length 11-138 times (7 bits of repeat count) */ ++ ++local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ ++ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; ++ ++local const int extra_dbits[D_CODES] /* extra bits for each distance code */ ++ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; ++ ++local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ ++ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; ++ ++local const uch bl_order[BL_CODES] ++ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; ++/* The lengths of the bit length codes are sent in order of decreasing ++ * probability, to avoid transmitting the lengths for unused bit length codes. ++ */ ++ ++#define Buf_size (8 * 2*sizeof(char)) ++/* Number of bits used within bi_buf. (bi_buf might be implemented on ++ * more than 16 bits on some systems.) ++ */ ++ ++/* =========================================================================== ++ * Local data. These are initialized only once. ++ */ ++ ++#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ ++ ++#if defined(GEN_TREES_H) || !defined(STDC) ++/* non ANSI compilers may not accept trees.h */ ++ ++local ct_data static_ltree[L_CODES+2]; ++/* The static literal tree. Since the bit lengths are imposed, there is no ++ * need for the L_CODES extra codes used during heap construction. However ++ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init ++ * below). ++ */ ++ ++local ct_data static_dtree[D_CODES]; ++/* The static distance tree. (Actually a trivial tree since all codes use ++ * 5 bits.) ++ */ ++ ++uch _dist_code[DIST_CODE_LEN]; ++/* Distance codes. The first 256 values correspond to the distances ++ * 3 .. 258, the last 256 values correspond to the top 8 bits of ++ * the 15 bit distances. ++ */ ++ ++uch _length_code[MAX_MATCH-MIN_MATCH+1]; ++/* length code for each normalized match length (0 == MIN_MATCH) */ ++ ++local int base_length[LENGTH_CODES]; ++/* First normalized length for each code (0 = MIN_MATCH) */ ++ ++local int base_dist[D_CODES]; ++/* First normalized distance for each code (0 = distance of 1) */ ++ ++#else ++# include "trees.h" ++#endif /* GEN_TREES_H */ ++ ++struct static_tree_desc_s { ++ const ct_data *static_tree; /* static tree or NULL */ ++ const intf *extra_bits; /* extra bits for each code or NULL */ ++ int extra_base; /* base index for extra_bits */ ++ int elems; /* max number of elements in the tree */ ++ int max_length; /* max bit length for the codes */ ++}; ++ ++local static_tree_desc static_l_desc = ++{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; ++ ++local static_tree_desc static_d_desc = ++{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; ++ ++local static_tree_desc static_bl_desc = ++{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; ++ ++/* =========================================================================== ++ * Local (static) routines in this file. ++ */ ++ ++local void tr_static_init OF((void)); ++local void init_block OF((deflate_state *s)); ++local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); ++local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); ++local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); ++local void build_tree OF((deflate_state *s, tree_desc *desc)); ++local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); ++local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); ++local int build_bl_tree OF((deflate_state *s)); ++local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, ++ int blcodes)); ++local void compress_block OF((deflate_state *s, const ct_data *ltree, ++ const ct_data *dtree)); ++local void set_data_type OF((deflate_state *s)); ++local unsigned bi_reverse OF((unsigned value, int length)); ++local void bi_windup OF((deflate_state *s)); ++local void bi_flush OF((deflate_state *s)); ++local void copy_block OF((deflate_state *s, charf *buf, unsigned len, ++ int header)); ++ ++#ifdef GEN_TREES_H ++local void gen_trees_header OF((void)); ++#endif ++ ++#ifndef DEBUG ++# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) ++ /* Send a code of the given tree. c and tree must not have side effects */ ++ ++#else /* DEBUG */ ++# define send_code(s, c, tree) \ ++ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ ++ send_bits(s, tree[c].Code, tree[c].Len); } ++#endif ++ ++/* =========================================================================== ++ * Output a short LSB first on the stream. ++ * IN assertion: there is enough room in pendingBuf. ++ */ ++#define put_short(s, w) { \ ++ put_byte(s, (uch)((w) & 0xff)); \ ++ put_byte(s, (uch)((ush)(w) >> 8)); \ ++} ++ ++/* =========================================================================== ++ * Send a value on a given number of bits. ++ * IN assertion: length <= 16 and value fits in length bits. ++ */ ++#ifdef DEBUG ++local void send_bits OF((deflate_state *s, int value, int length)); ++ ++local void send_bits(s, value, length) ++ deflate_state *s; ++ int value; /* value to send */ ++ int length; /* number of bits */ ++{ ++ Tracevv((stderr," l %2d v %4x ", length, value)); ++ Assert(length > 0 && length <= 15, "invalid length"); ++ s->bits_sent += (ulg)length; ++ ++ /* If not enough room in bi_buf, use (valid) bits from bi_buf and ++ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) ++ * unused bits in value. ++ */ ++ if (s->bi_valid > (int)Buf_size - length) { ++ s->bi_buf |= (value << s->bi_valid); ++ put_short(s, s->bi_buf); ++ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); ++ s->bi_valid += length - Buf_size; ++ } else { ++ s->bi_buf |= value << s->bi_valid; ++ s->bi_valid += length; ++ } ++} ++#else /* !DEBUG */ ++ ++#define send_bits(s, value, length) \ ++{ int len = length;\ ++ if (s->bi_valid > (int)Buf_size - len) {\ ++ int val = value;\ ++ s->bi_buf |= (val << s->bi_valid);\ ++ put_short(s, s->bi_buf);\ ++ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ ++ s->bi_valid += len - Buf_size;\ ++ } else {\ ++ s->bi_buf |= (value) << s->bi_valid;\ ++ s->bi_valid += len;\ ++ }\ ++} ++#endif /* DEBUG */ ++ ++ ++#define MAX(a,b) (a >= b ? a : b) ++/* the arguments must not have side effects */ ++ ++/* =========================================================================== ++ * Initialize the various 'constant' tables. ++ */ ++local void tr_static_init() ++{ ++#if defined(GEN_TREES_H) || !defined(STDC) ++ static int static_init_done = 0; ++ int n; /* iterates over tree elements */ ++ int bits; /* bit counter */ ++ int length; /* length value */ ++ int code; /* code value */ ++ int dist; /* distance index */ ++ ush bl_count[MAX_BITS+1]; ++ /* number of codes at each bit length for an optimal tree */ ++ ++ if (static_init_done) return; ++ ++ /* For some embedded targets, global variables are not initialized: */ ++ static_l_desc.static_tree = static_ltree; ++ static_l_desc.extra_bits = extra_lbits; ++ static_d_desc.static_tree = static_dtree; ++ static_d_desc.extra_bits = extra_dbits; ++ static_bl_desc.extra_bits = extra_blbits; ++ ++ /* Initialize the mapping length (0..255) -> length code (0..28) */ ++ length = 0; ++ for (code = 0; code < LENGTH_CODES-1; code++) { ++ base_length[code] = length; ++ for (n = 0; n < (1< dist code (0..29) */ ++ dist = 0; ++ for (code = 0 ; code < 16; code++) { ++ base_dist[code] = dist; ++ for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ ++ for ( ; code < D_CODES; code++) { ++ base_dist[code] = dist << 7; ++ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { ++ _dist_code[256 + dist++] = (uch)code; ++ } ++ } ++ Assert (dist == 256, "tr_static_init: 256+dist != 512"); ++ ++ /* Construct the codes of the static literal tree */ ++ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; ++ n = 0; ++ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; ++ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; ++ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; ++ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; ++ /* Codes 286 and 287 do not exist, but we must include them in the ++ * tree construction to get a canonical Huffman tree (longest code ++ * all ones) ++ */ ++ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); ++ ++ /* The static distance tree is trivial: */ ++ for (n = 0; n < D_CODES; n++) { ++ static_dtree[n].Len = 5; ++ static_dtree[n].Code = bi_reverse((unsigned)n, 5); ++ } ++ static_init_done = 1; ++ ++# ifdef GEN_TREES_H ++ gen_trees_header(); ++# endif ++#endif /* defined(GEN_TREES_H) || !defined(STDC) */ ++} ++ ++/* =========================================================================== ++ * Genererate the file trees.h describing the static trees. ++ */ ++#ifdef GEN_TREES_H ++# ifndef DEBUG ++# include ++# endif ++ ++# define SEPARATOR(i, last, width) \ ++ ((i) == (last)? "\n};\n\n" : \ ++ ((i) % (width) == (width)-1 ? ",\n" : ", ")) ++ ++void gen_trees_header() ++{ ++ FILE *header = fopen("trees.h", "w"); ++ int i; ++ ++ Assert (header != NULL, "Can't open trees.h"); ++ fprintf(header, ++ "/* header created automatically with -DGEN_TREES_H */\n\n"); ++ ++ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); ++ for (i = 0; i < L_CODES+2; i++) { ++ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, ++ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); ++ } ++ ++ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); ++ for (i = 0; i < D_CODES; i++) { ++ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, ++ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); ++ } ++ ++ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); ++ for (i = 0; i < DIST_CODE_LEN; i++) { ++ fprintf(header, "%2u%s", _dist_code[i], ++ SEPARATOR(i, DIST_CODE_LEN-1, 20)); ++ } ++ ++ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); ++ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { ++ fprintf(header, "%2u%s", _length_code[i], ++ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); ++ } ++ ++ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); ++ for (i = 0; i < LENGTH_CODES; i++) { ++ fprintf(header, "%1u%s", base_length[i], ++ SEPARATOR(i, LENGTH_CODES-1, 20)); ++ } ++ ++ fprintf(header, "local const int base_dist[D_CODES] = {\n"); ++ for (i = 0; i < D_CODES; i++) { ++ fprintf(header, "%5u%s", base_dist[i], ++ SEPARATOR(i, D_CODES-1, 10)); ++ } ++ ++ fclose(header); ++} ++#endif /* GEN_TREES_H */ ++ ++/* =========================================================================== ++ * Initialize the tree data structures for a new zlib stream. ++ */ ++void _tr_init(s) ++ deflate_state *s; ++{ ++ tr_static_init(); ++ ++ s->l_desc.dyn_tree = s->dyn_ltree; ++ s->l_desc.stat_desc = &static_l_desc; ++ ++ s->d_desc.dyn_tree = s->dyn_dtree; ++ s->d_desc.stat_desc = &static_d_desc; ++ ++ s->bl_desc.dyn_tree = s->bl_tree; ++ s->bl_desc.stat_desc = &static_bl_desc; ++ ++ s->bi_buf = 0; ++ s->bi_valid = 0; ++ s->last_eob_len = 8; /* enough lookahead for inflate */ ++#ifdef DEBUG ++ s->compressed_len = 0L; ++ s->bits_sent = 0L; ++#endif ++ ++ /* Initialize the first block of the first file: */ ++ init_block(s); ++} ++ ++/* =========================================================================== ++ * Initialize a new block. ++ */ ++local void init_block(s) ++ deflate_state *s; ++{ ++ int n; /* iterates over tree elements */ ++ ++ /* Initialize the trees. */ ++ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; ++ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; ++ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; ++ ++ s->dyn_ltree[END_BLOCK].Freq = 1; ++ s->opt_len = s->static_len = 0L; ++ s->last_lit = s->matches = 0; ++} ++ ++#define SMALLEST 1 ++/* Index within the heap array of least frequent node in the Huffman tree */ ++ ++ ++/* =========================================================================== ++ * Remove the smallest element from the heap and recreate the heap with ++ * one less element. Updates heap and heap_len. ++ */ ++#define pqremove(s, tree, top) \ ++{\ ++ top = s->heap[SMALLEST]; \ ++ s->heap[SMALLEST] = s->heap[s->heap_len--]; \ ++ pqdownheap(s, tree, SMALLEST); \ ++} ++ ++/* =========================================================================== ++ * Compares to subtrees, using the tree depth as tie breaker when ++ * the subtrees have equal frequency. This minimizes the worst case length. ++ */ ++#define smaller(tree, n, m, depth) \ ++ (tree[n].Freq < tree[m].Freq || \ ++ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) ++ ++/* =========================================================================== ++ * Restore the heap property by moving down the tree starting at node k, ++ * exchanging a node with the smallest of its two sons if necessary, stopping ++ * when the heap property is re-established (each father smaller than its ++ * two sons). ++ */ ++local void pqdownheap(s, tree, k) ++ deflate_state *s; ++ ct_data *tree; /* the tree to restore */ ++ int k; /* node to move down */ ++{ ++ int v = s->heap[k]; ++ int j = k << 1; /* left son of k */ ++ while (j <= s->heap_len) { ++ /* Set j to the smallest of the two sons: */ ++ if (j < s->heap_len && ++ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { ++ j++; ++ } ++ /* Exit if v is smaller than both sons */ ++ if (smaller(tree, v, s->heap[j], s->depth)) break; ++ ++ /* Exchange v with the smallest son */ ++ s->heap[k] = s->heap[j]; k = j; ++ ++ /* And continue down the tree, setting j to the left son of k */ ++ j <<= 1; ++ } ++ s->heap[k] = v; ++} ++ ++/* =========================================================================== ++ * Compute the optimal bit lengths for a tree and update the total bit length ++ * for the current block. ++ * IN assertion: the fields freq and dad are set, heap[heap_max] and ++ * above are the tree nodes sorted by increasing frequency. ++ * OUT assertions: the field len is set to the optimal bit length, the ++ * array bl_count contains the frequencies for each bit length. ++ * The length opt_len is updated; static_len is also updated if stree is ++ * not null. ++ */ ++local void gen_bitlen(s, desc) ++ deflate_state *s; ++ tree_desc *desc; /* the tree descriptor */ ++{ ++ ct_data *tree = desc->dyn_tree; ++ int max_code = desc->max_code; ++ const ct_data *stree = desc->stat_desc->static_tree; ++ const intf *extra = desc->stat_desc->extra_bits; ++ int base = desc->stat_desc->extra_base; ++ int max_length = desc->stat_desc->max_length; ++ int h; /* heap index */ ++ int n, m; /* iterate over the tree elements */ ++ int bits; /* bit length */ ++ int xbits; /* extra bits */ ++ ush f; /* frequency */ ++ int overflow = 0; /* number of elements with bit length too large */ ++ ++ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; ++ ++ /* In a first pass, compute the optimal bit lengths (which may ++ * overflow in the case of the bit length tree). ++ */ ++ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ ++ ++ for (h = s->heap_max+1; h < HEAP_SIZE; h++) { ++ n = s->heap[h]; ++ bits = tree[tree[n].Dad].Len + 1; ++ if (bits > max_length) bits = max_length, overflow++; ++ tree[n].Len = (ush)bits; ++ /* We overwrite tree[n].Dad which is no longer needed */ ++ ++ if (n > max_code) continue; /* not a leaf node */ ++ ++ s->bl_count[bits]++; ++ xbits = 0; ++ if (n >= base) xbits = extra[n-base]; ++ f = tree[n].Freq; ++ s->opt_len += (ulg)f * (bits + xbits); ++ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); ++ } ++ if (overflow == 0) return; ++ ++ Trace((stderr,"\nbit length overflow\n")); ++ /* This happens for example on obj2 and pic of the Calgary corpus */ ++ ++ /* Find the first bit length which could increase: */ ++ do { ++ bits = max_length-1; ++ while (s->bl_count[bits] == 0) bits--; ++ s->bl_count[bits]--; /* move one leaf down the tree */ ++ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ ++ s->bl_count[max_length]--; ++ /* The brother of the overflow item also moves one step up, ++ * but this does not affect bl_count[max_length] ++ */ ++ overflow -= 2; ++ } while (overflow > 0); ++ ++ /* Now recompute all bit lengths, scanning in increasing frequency. ++ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all ++ * lengths instead of fixing only the wrong ones. This idea is taken ++ * from 'ar' written by Haruhiko Okumura.) ++ */ ++ for (bits = max_length; bits != 0; bits--) { ++ n = s->bl_count[bits]; ++ while (n != 0) { ++ m = s->heap[--h]; ++ if (m > max_code) continue; ++ if (tree[m].Len != (unsigned) bits) { ++ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); ++ s->opt_len += ((long)bits - (long)tree[m].Len) ++ *(long)tree[m].Freq; ++ tree[m].Len = (ush)bits; ++ } ++ n--; ++ } ++ } ++} ++ ++/* =========================================================================== ++ * Generate the codes for a given tree and bit counts (which need not be ++ * optimal). ++ * IN assertion: the array bl_count contains the bit length statistics for ++ * the given tree and the field len is set for all tree elements. ++ * OUT assertion: the field code is set for all tree elements of non ++ * zero code length. ++ */ ++local void gen_codes (tree, max_code, bl_count) ++ ct_data *tree; /* the tree to decorate */ ++ int max_code; /* largest code with non zero frequency */ ++ ushf *bl_count; /* number of codes at each bit length */ ++{ ++ ush next_code[MAX_BITS+1]; /* next code value for each bit length */ ++ ush code = 0; /* running code value */ ++ int bits; /* bit index */ ++ int n; /* code index */ ++ ++ /* The distribution counts are first used to generate the code values ++ * without bit reversal. ++ */ ++ for (bits = 1; bits <= MAX_BITS; bits++) { ++ next_code[bits] = code = (code + bl_count[bits-1]) << 1; ++ } ++ /* Check that the bit counts in bl_count are consistent. The last code ++ * must be all ones. ++ */ ++ Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; ++ const ct_data *stree = desc->stat_desc->static_tree; ++ int elems = desc->stat_desc->elems; ++ int n, m; /* iterate over heap elements */ ++ int max_code = -1; /* largest code with non zero frequency */ ++ int node; /* new node being created */ ++ ++ /* Construct the initial heap, with least frequent element in ++ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. ++ * heap[0] is not used. ++ */ ++ s->heap_len = 0, s->heap_max = HEAP_SIZE; ++ ++ for (n = 0; n < elems; n++) { ++ if (tree[n].Freq != 0) { ++ s->heap[++(s->heap_len)] = max_code = n; ++ s->depth[n] = 0; ++ } else { ++ tree[n].Len = 0; ++ } ++ } ++ ++ /* The pkzip format requires that at least one distance code exists, ++ * and that at least one bit should be sent even if there is only one ++ * possible code. So to avoid special checks later on we force at least ++ * two codes of non zero frequency. ++ */ ++ while (s->heap_len < 2) { ++ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); ++ tree[node].Freq = 1; ++ s->depth[node] = 0; ++ s->opt_len--; if (stree) s->static_len -= stree[node].Len; ++ /* node is 0 or 1 so it does not have extra bits */ ++ } ++ desc->max_code = max_code; ++ ++ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, ++ * establish sub-heaps of increasing lengths: ++ */ ++ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); ++ ++ /* Construct the Huffman tree by repeatedly combining the least two ++ * frequent nodes. ++ */ ++ node = elems; /* next internal node of the tree */ ++ do { ++ pqremove(s, tree, n); /* n = node of least frequency */ ++ m = s->heap[SMALLEST]; /* m = node of next least frequency */ ++ ++ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ ++ s->heap[--(s->heap_max)] = m; ++ ++ /* Create a new node father of n and m */ ++ tree[node].Freq = tree[n].Freq + tree[m].Freq; ++ s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); ++ tree[n].Dad = tree[m].Dad = (ush)node; ++#ifdef DUMP_BL_TREE ++ if (tree == s->bl_tree) { ++ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", ++ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); ++ } ++#endif ++ /* and insert the new node in the heap */ ++ s->heap[SMALLEST] = node++; ++ pqdownheap(s, tree, SMALLEST); ++ ++ } while (s->heap_len >= 2); ++ ++ s->heap[--(s->heap_max)] = s->heap[SMALLEST]; ++ ++ /* At this point, the fields freq and dad are set. We can now ++ * generate the bit lengths. ++ */ ++ gen_bitlen(s, (tree_desc *)desc); ++ ++ /* The field len is now set, we can generate the bit codes */ ++ gen_codes ((ct_data *)tree, max_code, s->bl_count); ++} ++ ++/* =========================================================================== ++ * Scan a literal or distance tree to determine the frequencies of the codes ++ * in the bit length tree. ++ */ ++local void scan_tree (s, tree, max_code) ++ deflate_state *s; ++ ct_data *tree; /* the tree to be scanned */ ++ int max_code; /* and its largest code of non zero frequency */ ++{ ++ int n; /* iterates over all tree elements */ ++ int prevlen = -1; /* last emitted length */ ++ int curlen; /* length of current code */ ++ int nextlen = tree[0].Len; /* length of next code */ ++ int count = 0; /* repeat count of the current code */ ++ int max_count = 7; /* max repeat count */ ++ int min_count = 4; /* min repeat count */ ++ ++ if (nextlen == 0) max_count = 138, min_count = 3; ++ tree[max_code+1].Len = (ush)0xffff; /* guard */ ++ ++ for (n = 0; n <= max_code; n++) { ++ curlen = nextlen; nextlen = tree[n+1].Len; ++ if (++count < max_count && curlen == nextlen) { ++ continue; ++ } else if (count < min_count) { ++ s->bl_tree[curlen].Freq += count; ++ } else if (curlen != 0) { ++ if (curlen != prevlen) s->bl_tree[curlen].Freq++; ++ s->bl_tree[REP_3_6].Freq++; ++ } else if (count <= 10) { ++ s->bl_tree[REPZ_3_10].Freq++; ++ } else { ++ s->bl_tree[REPZ_11_138].Freq++; ++ } ++ count = 0; prevlen = curlen; ++ if (nextlen == 0) { ++ max_count = 138, min_count = 3; ++ } else if (curlen == nextlen) { ++ max_count = 6, min_count = 3; ++ } else { ++ max_count = 7, min_count = 4; ++ } ++ } ++} ++ ++/* =========================================================================== ++ * Send a literal or distance tree in compressed form, using the codes in ++ * bl_tree. ++ */ ++local void send_tree (s, tree, max_code) ++ deflate_state *s; ++ ct_data *tree; /* the tree to be scanned */ ++ int max_code; /* and its largest code of non zero frequency */ ++{ ++ int n; /* iterates over all tree elements */ ++ int prevlen = -1; /* last emitted length */ ++ int curlen; /* length of current code */ ++ int nextlen = tree[0].Len; /* length of next code */ ++ int count = 0; /* repeat count of the current code */ ++ int max_count = 7; /* max repeat count */ ++ int min_count = 4; /* min repeat count */ ++ ++ /* tree[max_code+1].Len = -1; */ /* guard already set */ ++ if (nextlen == 0) max_count = 138, min_count = 3; ++ ++ for (n = 0; n <= max_code; n++) { ++ curlen = nextlen; nextlen = tree[n+1].Len; ++ if (++count < max_count && curlen == nextlen) { ++ continue; ++ } else if (count < min_count) { ++ do { send_code(s, curlen, s->bl_tree); } while (--count != 0); ++ ++ } else if (curlen != 0) { ++ if (curlen != prevlen) { ++ send_code(s, curlen, s->bl_tree); count--; ++ } ++ Assert(count >= 3 && count <= 6, " 3_6?"); ++ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); ++ ++ } else if (count <= 10) { ++ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); ++ ++ } else { ++ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); ++ } ++ count = 0; prevlen = curlen; ++ if (nextlen == 0) { ++ max_count = 138, min_count = 3; ++ } else if (curlen == nextlen) { ++ max_count = 6, min_count = 3; ++ } else { ++ max_count = 7, min_count = 4; ++ } ++ } ++} ++ ++/* =========================================================================== ++ * Construct the Huffman tree for the bit lengths and return the index in ++ * bl_order of the last bit length code to send. ++ */ ++local int build_bl_tree(s) ++ deflate_state *s; ++{ ++ int max_blindex; /* index of last bit length code of non zero freq */ ++ ++ /* Determine the bit length frequencies for literal and distance trees */ ++ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); ++ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); ++ ++ /* Build the bit length tree: */ ++ build_tree(s, (tree_desc *)(&(s->bl_desc))); ++ /* opt_len now includes the length of the tree representations, except ++ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. ++ */ ++ ++ /* Determine the number of bit length codes to send. The pkzip format ++ * requires that at least 4 bit length codes be sent. (appnote.txt says ++ * 3 but the actual value used is 4.) ++ */ ++ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { ++ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; ++ } ++ /* Update opt_len to include the bit length tree and counts */ ++ s->opt_len += 3*(max_blindex+1) + 5+5+4; ++ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", ++ s->opt_len, s->static_len)); ++ ++ return max_blindex; ++} ++ ++/* =========================================================================== ++ * Send the header for a block using dynamic Huffman trees: the counts, the ++ * lengths of the bit length codes, the literal tree and the distance tree. ++ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. ++ */ ++local void send_all_trees(s, lcodes, dcodes, blcodes) ++ deflate_state *s; ++ int lcodes, dcodes, blcodes; /* number of codes for each tree */ ++{ ++ int rank; /* index in bl_order */ ++ ++ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); ++ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, ++ "too many codes"); ++ Tracev((stderr, "\nbl counts: ")); ++ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ ++ send_bits(s, dcodes-1, 5); ++ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ ++ for (rank = 0; rank < blcodes; rank++) { ++ Tracev((stderr, "\nbl code %2d ", bl_order[rank])); ++ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); ++ } ++ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); ++ ++ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ ++ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); ++ ++ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ ++ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); ++} ++ ++/* =========================================================================== ++ * Send a stored block ++ */ ++void _tr_stored_block(s, buf, stored_len, eof) ++ deflate_state *s; ++ charf *buf; /* input block */ ++ ulg stored_len; /* length of input block */ ++ int eof; /* true if this is the last block for a file */ ++{ ++ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ ++#ifdef DEBUG ++ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; ++ s->compressed_len += (stored_len + 4) << 3; ++#endif ++ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ ++} ++ ++/* =========================================================================== ++ * Send one empty static block to give enough lookahead for inflate. ++ * This takes 10 bits, of which 7 may remain in the bit buffer. ++ * The current inflate code requires 9 bits of lookahead. If the ++ * last two codes for the previous block (real code plus EOB) were coded ++ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode ++ * the last real code. In this case we send two empty static blocks instead ++ * of one. (There are no problems if the previous block is stored or fixed.) ++ * To simplify the code, we assume the worst case of last real code encoded ++ * on one bit only. ++ */ ++void _tr_align(s) ++ deflate_state *s; ++{ ++ send_bits(s, STATIC_TREES<<1, 3); ++ send_code(s, END_BLOCK, static_ltree); ++#ifdef DEBUG ++ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ ++#endif ++ bi_flush(s); ++ /* Of the 10 bits for the empty block, we have already sent ++ * (10 - bi_valid) bits. The lookahead for the last real code (before ++ * the EOB of the previous block) was thus at least one plus the length ++ * of the EOB plus what we have just sent of the empty static block. ++ */ ++ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { ++ send_bits(s, STATIC_TREES<<1, 3); ++ send_code(s, END_BLOCK, static_ltree); ++#ifdef DEBUG ++ s->compressed_len += 10L; ++#endif ++ bi_flush(s); ++ } ++ s->last_eob_len = 7; ++} ++ ++/* =========================================================================== ++ * Determine the best encoding for the current block: dynamic trees, static ++ * trees or store, and output the encoded block to the zip file. ++ */ ++void _tr_flush_block(s, buf, stored_len, eof) ++ deflate_state *s; ++ charf *buf; /* input block, or NULL if too old */ ++ ulg stored_len; /* length of input block */ ++ int eof; /* true if this is the last block for a file */ ++{ ++ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ ++ int max_blindex = 0; /* index of last bit length code of non zero freq */ ++ ++ /* Build the Huffman trees unless a stored block is forced */ ++ if (s->level > 0) { ++ ++ /* Check if the file is ascii or binary */ ++ if (s->data_type == Z_UNKNOWN) set_data_type(s); ++ ++ /* Construct the literal and distance trees */ ++ build_tree(s, (tree_desc *)(&(s->l_desc))); ++ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, ++ s->static_len)); ++ ++ build_tree(s, (tree_desc *)(&(s->d_desc))); ++ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, ++ s->static_len)); ++ /* At this point, opt_len and static_len are the total bit lengths of ++ * the compressed block data, excluding the tree representations. ++ */ ++ ++ /* Build the bit length tree for the above two trees, and get the index ++ * in bl_order of the last bit length code to send. ++ */ ++ max_blindex = build_bl_tree(s); ++ ++ /* Determine the best encoding. Compute first the block length in bytes*/ ++ opt_lenb = (s->opt_len+3+7)>>3; ++ static_lenb = (s->static_len+3+7)>>3; ++ ++ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", ++ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, ++ s->last_lit)); ++ ++ if (static_lenb <= opt_lenb) opt_lenb = static_lenb; ++ ++ } else { ++ Assert(buf != (char*)0, "lost buf"); ++ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ ++ } ++ ++#ifdef FORCE_STORED ++ if (buf != (char*)0) { /* force stored block */ ++#else ++ if (stored_len+4 <= opt_lenb && buf != (char*)0) { ++ /* 4: two words for the lengths */ ++#endif ++ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. ++ * Otherwise we can't have processed more than WSIZE input bytes since ++ * the last block flush, because compression would have been ++ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to ++ * transform a block into a stored block. ++ */ ++ _tr_stored_block(s, buf, stored_len, eof); ++ ++#ifdef FORCE_STATIC ++ } else if (static_lenb >= 0) { /* force static trees */ ++#else ++ } else if (static_lenb == opt_lenb) { ++#endif ++ send_bits(s, (STATIC_TREES<<1)+eof, 3); ++ compress_block(s, static_ltree, static_dtree); ++#ifdef DEBUG ++ s->compressed_len += 3 + s->static_len; ++#endif ++ } else { ++ send_bits(s, (DYN_TREES<<1)+eof, 3); ++ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, ++ max_blindex+1); ++ compress_block(s, s->dyn_ltree, s->dyn_dtree); ++#ifdef DEBUG ++ s->compressed_len += 3 + s->opt_len; ++#endif ++ } ++ Assert (s->compressed_len == s->bits_sent, "bad compressed size"); ++ /* The above check is made mod 2^32, for files larger than 512 MB ++ * and uLong implemented on 32 bits. ++ */ ++ init_block(s); ++ ++ if (eof) { ++ bi_windup(s); ++#ifdef DEBUG ++ s->compressed_len += 7; /* align on byte boundary */ ++#endif ++ } ++ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, ++ s->compressed_len-7*eof)); ++} ++ ++/* =========================================================================== ++ * Save the match info and tally the frequency counts. Return true if ++ * the current block must be flushed. ++ */ ++int _tr_tally (s, dist, lc) ++ deflate_state *s; ++ unsigned dist; /* distance of matched string */ ++ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ ++{ ++ s->d_buf[s->last_lit] = (ush)dist; ++ s->l_buf[s->last_lit++] = (uch)lc; ++ if (dist == 0) { ++ /* lc is the unmatched char */ ++ s->dyn_ltree[lc].Freq++; ++ } else { ++ s->matches++; ++ /* Here, lc is the match length - MIN_MATCH */ ++ dist--; /* dist = match distance - 1 */ ++ Assert((ush)dist < (ush)MAX_DIST(s) && ++ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && ++ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); ++ ++ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; ++ s->dyn_dtree[d_code(dist)].Freq++; ++ } ++ ++#ifdef TRUNCATE_BLOCK ++ /* Try to guess if it is profitable to stop the current block here */ ++ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { ++ /* Compute an upper bound for the compressed length */ ++ ulg out_length = (ulg)s->last_lit*8L; ++ ulg in_length = (ulg)((long)s->strstart - s->block_start); ++ int dcode; ++ for (dcode = 0; dcode < D_CODES; dcode++) { ++ out_length += (ulg)s->dyn_dtree[dcode].Freq * ++ (5L+extra_dbits[dcode]); ++ } ++ out_length >>= 3; ++ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", ++ s->last_lit, in_length, out_length, ++ 100L - out_length*100L/in_length)); ++ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; ++ } ++#endif ++ return (s->last_lit == s->lit_bufsize-1); ++ /* We avoid equality with lit_bufsize because of wraparound at 64K ++ * on 16 bit machines and because stored blocks are restricted to ++ * 64K-1 bytes. ++ */ ++} ++ ++/* =========================================================================== ++ * Send the block data compressed using the given Huffman trees ++ */ ++local void compress_block(s, ltree, dtree) ++ deflate_state *s; ++ const ct_data *ltree; /* literal tree */ ++ const ct_data *dtree; /* distance tree */ ++{ ++ unsigned dist; /* distance of matched string */ ++ int lc; /* match length or unmatched char (if dist == 0) */ ++ unsigned lx = 0; /* running index in l_buf */ ++ unsigned code; /* the code to send */ ++ int extra; /* number of extra bits to send */ ++ ++ if (s->last_lit != 0) do { ++ dist = s->d_buf[lx]; ++ lc = s->l_buf[lx++]; ++ if (dist == 0) { ++ send_code(s, lc, ltree); /* send a literal byte */ ++ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); ++ } else { ++ /* Here, lc is the match length - MIN_MATCH */ ++ code = _length_code[lc]; ++ send_code(s, code+LITERALS+1, ltree); /* send the length code */ ++ extra = extra_lbits[code]; ++ if (extra != 0) { ++ lc -= base_length[code]; ++ send_bits(s, lc, extra); /* send the extra length bits */ ++ } ++ dist--; /* dist is now the match distance - 1 */ ++ code = d_code(dist); ++ Assert (code < D_CODES, "bad d_code"); ++ ++ send_code(s, code, dtree); /* send the distance code */ ++ extra = extra_dbits[code]; ++ if (extra != 0) { ++ dist -= base_dist[code]; ++ send_bits(s, dist, extra); /* send the extra distance bits */ ++ } ++ } /* literal or match pair ? */ ++ ++ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ ++ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); ++ ++ } while (lx < s->last_lit); ++ ++ send_code(s, END_BLOCK, ltree); ++ s->last_eob_len = ltree[END_BLOCK].Len; ++} ++ ++/* =========================================================================== ++ * Set the data type to ASCII or BINARY, using a crude approximation: ++ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. ++ * IN assertion: the fields freq of dyn_ltree are set and the total of all ++ * frequencies does not exceed 64K (to fit in an int on 16 bit machines). ++ */ ++local void set_data_type(s) ++ deflate_state *s; ++{ ++ int n = 0; ++ unsigned ascii_freq = 0; ++ unsigned bin_freq = 0; ++ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; ++ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; ++ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; ++ s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); ++} ++ ++/* =========================================================================== ++ * Reverse the first len bits of a code, using straightforward code (a faster ++ * method would use a table) ++ * IN assertion: 1 <= len <= 15 ++ */ ++local unsigned bi_reverse(code, len) ++ unsigned code; /* the value to invert */ ++ int len; /* its bit length */ ++{ ++ register unsigned res = 0; ++ do { ++ res |= code & 1; ++ code >>= 1, res <<= 1; ++ } while (--len > 0); ++ return res >> 1; ++} ++ ++/* =========================================================================== ++ * Flush the bit buffer, keeping at most 7 bits in it. ++ */ ++local void bi_flush(s) ++ deflate_state *s; ++{ ++ if (s->bi_valid == 16) { ++ put_short(s, s->bi_buf); ++ s->bi_buf = 0; ++ s->bi_valid = 0; ++ } else if (s->bi_valid >= 8) { ++ put_byte(s, (Byte)s->bi_buf); ++ s->bi_buf >>= 8; ++ s->bi_valid -= 8; ++ } ++} ++ ++/* =========================================================================== ++ * Flush the bit buffer and align the output on a byte boundary ++ */ ++local void bi_windup(s) ++ deflate_state *s; ++{ ++ if (s->bi_valid > 8) { ++ put_short(s, s->bi_buf); ++ } else if (s->bi_valid > 0) { ++ put_byte(s, (Byte)s->bi_buf); ++ } ++ s->bi_buf = 0; ++ s->bi_valid = 0; ++#ifdef DEBUG ++ s->bits_sent = (s->bits_sent+7) & ~7; ++#endif ++} ++ ++/* =========================================================================== ++ * Copy a stored block, storing first the length and its ++ * one's complement if requested. ++ */ ++local void copy_block(s, buf, len, header) ++ deflate_state *s; ++ charf *buf; /* the input data */ ++ unsigned len; /* its length */ ++ int header; /* true if block header must be written */ ++{ ++ bi_windup(s); /* align on byte boundary */ ++ s->last_eob_len = 8; /* enough lookahead for inflate */ ++ ++ if (header) { ++ put_short(s, (ush)len); ++ put_short(s, (ush)~len); ++#ifdef DEBUG ++ s->bits_sent += 2*16; ++#endif ++ } ++#ifdef DEBUG ++ s->bits_sent += (ulg)len<<3; ++#endif ++ while (len--) { ++ put_byte(s, *buf++); ++ } ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/trees.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,128 @@ ++/* header created automatically with -DGEN_TREES_H */ ++ ++local const ct_data static_ltree[L_CODES+2] = { ++{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, ++{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, ++{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, ++{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, ++{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, ++{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, ++{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, ++{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, ++{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, ++{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, ++{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, ++{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, ++{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, ++{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, ++{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, ++{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, ++{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, ++{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, ++{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, ++{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, ++{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, ++{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, ++{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, ++{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, ++{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, ++{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, ++{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, ++{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, ++{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, ++{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, ++{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, ++{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, ++{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, ++{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, ++{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, ++{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, ++{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, ++{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, ++{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, ++{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, ++{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, ++{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, ++{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, ++{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, ++{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, ++{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, ++{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, ++{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, ++{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, ++{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, ++{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, ++{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, ++{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, ++{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, ++{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, ++{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, ++{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, ++{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} ++}; ++ ++local const ct_data static_dtree[D_CODES] = { ++{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, ++{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, ++{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, ++{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, ++{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, ++{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} ++}; ++ ++const uch _dist_code[DIST_CODE_LEN] = { ++ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, ++ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, ++10, 10, 10, 10, 10, 10, 10, 10, 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, 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, 13, 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, 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, 15, 15, 15, 15, 15, 15, 15, 15, ++15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, ++15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, ++15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, ++18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, ++23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, ++24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, ++26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, ++27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, ++27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, ++28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, ++28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, ++28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, ++29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, ++29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, ++29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 ++}; ++ ++const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { ++ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, ++13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, ++17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, ++19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, ++21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, ++22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, ++23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, ++24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, ++25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, ++25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, ++26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, ++26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, ++27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 ++}; ++ ++local const int base_length[LENGTH_CODES] = { ++0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, ++64, 80, 96, 112, 128, 160, 192, 224, 0 ++}; ++ ++local const int base_dist[D_CODES] = { ++ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, ++ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, ++ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 ++}; ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/zconf.h Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,309 @@ ++/* zconf.h -- configuration of the zlib compression library ++ * Copyright (C) 1995-2002 Jean-loup Gailly. ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* @(#) $Id: zconf.h,v 1.3 2002/04/24 07:36:45 mcr Exp $ */ ++ ++#ifndef _ZCONF_H ++#define _ZCONF_H ++ ++/* ++ * If you *really* need a unique prefix for all types and library functions, ++ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. ++ */ ++#ifdef IPCOMP_PREFIX ++# define deflateInit_ ipcomp_deflateInit_ ++# define deflate ipcomp_deflate ++# define deflateEnd ipcomp_deflateEnd ++# define inflateInit_ ipcomp_inflateInit_ ++# define inflate ipcomp_inflate ++# define inflateEnd ipcomp_inflateEnd ++# define deflateInit2_ ipcomp_deflateInit2_ ++# define deflateSetDictionary ipcomp_deflateSetDictionary ++# define deflateCopy ipcomp_deflateCopy ++# define deflateReset ipcomp_deflateReset ++# define deflateParams ipcomp_deflateParams ++# define inflateInit2_ ipcomp_inflateInit2_ ++# define inflateSetDictionary ipcomp_inflateSetDictionary ++# define inflateSync ipcomp_inflateSync ++# define inflateSyncPoint ipcomp_inflateSyncPoint ++# define inflateReset ipcomp_inflateReset ++# define compress ipcomp_compress ++# define compress2 ipcomp_compress2 ++# define uncompress ipcomp_uncompress ++# define adler32 ipcomp_adler32 ++# define crc32 ipcomp_crc32 ++# define get_crc_table ipcomp_get_crc_table ++/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */ ++# define inflate_blocks ipcomp_deflate_blocks ++# define inflate_blocks_free ipcomp_deflate_blocks_free ++# define inflate_blocks_new ipcomp_inflate_blocks_new ++# define inflate_blocks_reset ipcomp_inflate_blocks_reset ++# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point ++# define inflate_set_dictionary ipcomp_inflate_set_dictionary ++# define inflate_codes ipcomp_inflate_codes ++# define inflate_codes_free ipcomp_inflate_codes_free ++# define inflate_codes_new ipcomp_inflate_codes_new ++# define inflate_fast ipcomp_inflate_fast ++# define inflate_trees_bits ipcomp_inflate_trees_bits ++# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic ++# define inflate_trees_fixed ipcomp_inflate_trees_fixed ++# define inflate_flush ipcomp_inflate_flush ++# define inflate_mask ipcomp_inflate_mask ++# define _dist_code _ipcomp_dist_code ++# define _length_code _ipcomp_length_code ++# define _tr_align _ipcomp_tr_align ++# define _tr_flush_block _ipcomp_tr_flush_block ++# define _tr_init _ipcomp_tr_init ++# define _tr_stored_block _ipcomp_tr_stored_block ++# define _tr_tally _ipcomp_tr_tally ++# define zError ipcomp_zError ++# define z_errmsg ipcomp_z_errmsg ++# define zlibVersion ipcomp_zlibVersion ++# define match_init ipcomp_match_init ++# define longest_match ipcomp_longest_match ++#endif ++ ++#ifdef Z_PREFIX ++# define Byte z_Byte ++# define uInt z_uInt ++# define uLong z_uLong ++# define Bytef z_Bytef ++# define charf z_charf ++# define intf z_intf ++# define uIntf z_uIntf ++# define uLongf z_uLongf ++# define voidpf z_voidpf ++# define voidp z_voidp ++#endif ++ ++#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) ++# define WIN32 ++#endif ++#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) ++# ifndef __32BIT__ ++# define __32BIT__ ++# endif ++#endif ++#if defined(__MSDOS__) && !defined(MSDOS) ++# define MSDOS ++#endif ++ ++/* ++ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more ++ * than 64k bytes at a time (needed on systems with 16-bit int). ++ */ ++#if defined(MSDOS) && !defined(__32BIT__) ++# define MAXSEG_64K ++#endif ++#ifdef MSDOS ++# define UNALIGNED_OK ++#endif ++ ++#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) ++# define STDC ++#endif ++#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) ++# ifndef STDC ++# define STDC ++# endif ++#endif ++ ++#ifndef STDC ++# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ ++# define const ++# endif ++#endif ++ ++/* Some Mac compilers merge all .h files incorrectly: */ ++#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) ++# define NO_DUMMY_DECL ++#endif ++ ++/* Old Borland C incorrectly complains about missing returns: */ ++#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) ++# define NEED_DUMMY_RETURN ++#endif ++ ++ ++/* Maximum value for memLevel in deflateInit2 */ ++#ifndef MAX_MEM_LEVEL ++# ifdef MAXSEG_64K ++# define MAX_MEM_LEVEL 8 ++# else ++# define MAX_MEM_LEVEL 9 ++# endif ++#endif ++ ++/* Maximum value for windowBits in deflateInit2 and inflateInit2. ++ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files ++ * created by gzip. (Files created by minigzip can still be extracted by ++ * gzip.) ++ */ ++#ifndef MAX_WBITS ++# define MAX_WBITS 15 /* 32K LZ77 window */ ++#endif ++ ++/* The memory requirements for deflate are (in bytes): ++ (1 << (windowBits+2)) + (1 << (memLevel+9)) ++ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) ++ plus a few kilobytes for small objects. For example, if you want to reduce ++ the default memory requirements from 256K to 128K, compile with ++ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" ++ Of course this will generally degrade compression (there's no free lunch). ++ ++ The memory requirements for inflate are (in bytes) 1 << windowBits ++ that is, 32K for windowBits=15 (default value) plus a few kilobytes ++ for small objects. ++*/ ++ ++ /* Type declarations */ ++ ++#ifndef OF /* function prototypes */ ++# ifdef STDC ++# define OF(args) args ++# else ++# define OF(args) () ++# endif ++#endif ++ ++/* The following definitions for FAR are needed only for MSDOS mixed ++ * model programming (small or medium model with some far allocations). ++ * This was tested only with MSC; for other MSDOS compilers you may have ++ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, ++ * just define FAR to be empty. ++ */ ++#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) ++ /* MSC small or medium model */ ++# define SMALL_MEDIUM ++# ifdef _MSC_VER ++# define FAR _far ++# else ++# define FAR far ++# endif ++#endif ++#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) ++# ifndef __32BIT__ ++# define SMALL_MEDIUM ++# define FAR _far ++# endif ++#endif ++ ++/* Compile with -DZLIB_DLL for Windows DLL support */ ++#if defined(ZLIB_DLL) ++# if defined(_WINDOWS) || defined(WINDOWS) ++# ifdef FAR ++# undef FAR ++# endif ++# include ++# define ZEXPORT WINAPI ++# ifdef WIN32 ++# define ZEXPORTVA WINAPIV ++# else ++# define ZEXPORTVA FAR _cdecl _export ++# endif ++# endif ++# if defined (__BORLANDC__) ++# if (__BORLANDC__ >= 0x0500) && defined (WIN32) ++# include ++# define ZEXPORT __declspec(dllexport) WINAPI ++# define ZEXPORTRVA __declspec(dllexport) WINAPIV ++# else ++# if defined (_Windows) && defined (__DLL__) ++# define ZEXPORT _export ++# define ZEXPORTVA _export ++# endif ++# endif ++# endif ++#endif ++ ++#if defined (__BEOS__) ++# if defined (ZLIB_DLL) ++# define ZEXTERN extern __declspec(dllexport) ++# else ++# define ZEXTERN extern __declspec(dllimport) ++# endif ++#endif ++ ++#ifndef ZEXPORT ++# define ZEXPORT ++#endif ++#ifndef ZEXPORTVA ++# define ZEXPORTVA ++#endif ++#ifndef ZEXTERN ++# define ZEXTERN extern ++#endif ++ ++#ifndef FAR ++# define FAR ++#endif ++ ++#if !defined(MACOS) && !defined(TARGET_OS_MAC) ++typedef unsigned char Byte; /* 8 bits */ ++#endif ++typedef unsigned int uInt; /* 16 bits or more */ ++typedef unsigned long uLong; /* 32 bits or more */ ++ ++#ifdef SMALL_MEDIUM ++ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ ++# define Bytef Byte FAR ++#else ++ typedef Byte FAR Bytef; ++#endif ++typedef char FAR charf; ++typedef int FAR intf; ++typedef uInt FAR uIntf; ++typedef uLong FAR uLongf; ++ ++#ifdef STDC ++ typedef void FAR *voidpf; ++ typedef void *voidp; ++#else ++ typedef Byte FAR *voidpf; ++ typedef Byte *voidp; ++#endif ++ ++#ifdef HAVE_UNISTD_H ++# include /* for off_t */ ++# include /* for SEEK_* and off_t */ ++# define z_off_t off_t ++#endif ++#ifndef SEEK_SET ++# define SEEK_SET 0 /* Seek from beginning of file. */ ++# define SEEK_CUR 1 /* Seek from current position. */ ++# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ ++#endif ++#ifndef z_off_t ++# define z_off_t long ++#endif ++ ++/* MVS linker does not support external names larger than 8 bytes */ ++#if defined(__MVS__) ++# pragma map(deflateInit_,"DEIN") ++# pragma map(deflateInit2_,"DEIN2") ++# pragma map(deflateEnd,"DEEND") ++# pragma map(inflateInit_,"ININ") ++# pragma map(inflateInit2_,"ININ2") ++# pragma map(inflateEnd,"INEND") ++# pragma map(inflateSync,"INSY") ++# pragma map(inflateSetDictionary,"INSEDI") ++# pragma map(inflate_blocks,"INBL") ++# pragma map(inflate_blocks_new,"INBLNE") ++# pragma map(inflate_blocks_free,"INBLFR") ++# pragma map(inflate_blocks_reset,"INBLRE") ++# pragma map(inflate_codes_free,"INCOFR") ++# pragma map(inflate_codes,"INCO") ++# pragma map(inflate_fast,"INFA") ++# pragma map(inflate_flush,"INFLU") ++# pragma map(inflate_mask,"INMA") ++# pragma map(inflate_set_dictionary,"INSEDI2") ++# pragma map(ipcomp_inflate_copyright,"INCOPY") ++# pragma map(inflate_trees_bits,"INTRBI") ++# pragma map(inflate_trees_dynamic,"INTRDY") ++# pragma map(inflate_trees_fixed,"INTRFI") ++# pragma map(inflate_trees_free,"INTRFR") ++#endif ++ ++#endif /* _ZCONF_H */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/lib/zlib/zutil.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,227 @@ ++/* zutil.c -- target dependent utility functions for the compression library ++ * Copyright (C) 1995-2002 Jean-loup Gailly. ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* @(#) $Id: zutil.c,v 1.4 2002/04/24 07:55:32 mcr Exp $ */ ++ ++#include ++ ++#define MY_ZCALLOC ++ ++struct internal_state {int dummy;}; /* for buggy compilers */ ++ ++#ifndef STDC ++extern void exit OF((int)); ++#endif ++ ++const char *z_errmsg[10] = { ++"need dictionary", /* Z_NEED_DICT 2 */ ++"stream end", /* Z_STREAM_END 1 */ ++"", /* Z_OK 0 */ ++"file error", /* Z_ERRNO (-1) */ ++"stream error", /* Z_STREAM_ERROR (-2) */ ++"data error", /* Z_DATA_ERROR (-3) */ ++"insufficient memory", /* Z_MEM_ERROR (-4) */ ++"buffer error", /* Z_BUF_ERROR (-5) */ ++"incompatible version",/* Z_VERSION_ERROR (-6) */ ++""}; ++ ++ ++const char * ZEXPORT zlibVersion() ++{ ++ return ZLIB_VERSION; ++} ++ ++#ifdef DEBUG ++ ++# ifndef verbose ++# define verbose 0 ++# endif ++int z_verbose = verbose; ++ ++void z_error (m) ++ char *m; ++{ ++ fprintf(stderr, "%s\n", m); ++ exit(1); ++} ++#endif ++ ++/* exported to allow conversion of error code to string for compress() and ++ * uncompress() ++ */ ++const char * ZEXPORT zError(err) ++ int err; ++{ ++ return ERR_MSG(err); ++} ++ ++ ++#ifndef HAVE_MEMCPY ++ ++void zmemcpy(dest, source, len) ++ Bytef* dest; ++ const Bytef* source; ++ uInt len; ++{ ++ if (len == 0) return; ++ do { ++ *dest++ = *source++; /* ??? to be unrolled */ ++ } while (--len != 0); ++} ++ ++int zmemcmp(s1, s2, len) ++ const Bytef* s1; ++ const Bytef* s2; ++ uInt len; ++{ ++ uInt j; ++ ++ for (j = 0; j < len; j++) { ++ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; ++ } ++ return 0; ++} ++ ++void zmemzero(dest, len) ++ Bytef* dest; ++ uInt len; ++{ ++ if (len == 0) return; ++ do { ++ *dest++ = 0; /* ??? to be unrolled */ ++ } while (--len != 0); ++} ++#endif ++ ++#ifdef __TURBOC__ ++#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) ++/* Small and medium model in Turbo C are for now limited to near allocation ++ * with reduced MAX_WBITS and MAX_MEM_LEVEL ++ */ ++# define MY_ZCALLOC ++ ++/* Turbo C malloc() does not allow dynamic allocation of 64K bytes ++ * and farmalloc(64K) returns a pointer with an offset of 8, so we ++ * must fix the pointer. Warning: the pointer must be put back to its ++ * original form in order to free it, use zcfree(). ++ */ ++ ++#define MAX_PTR 10 ++/* 10*64K = 640K */ ++ ++local int next_ptr = 0; ++ ++typedef struct ptr_table_s { ++ voidpf org_ptr; ++ voidpf new_ptr; ++} ptr_table; ++ ++local ptr_table table[MAX_PTR]; ++/* This table is used to remember the original form of pointers ++ * to large buffers (64K). Such pointers are normalized with a zero offset. ++ * Since MSDOS is not a preemptive multitasking OS, this table is not ++ * protected from concurrent access. This hack doesn't work anyway on ++ * a protected system like OS/2. Use Microsoft C instead. ++ */ ++ ++voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) ++{ ++ voidpf buf = opaque; /* just to make some compilers happy */ ++ ulg bsize = (ulg)items*size; ++ ++ /* If we allocate less than 65520 bytes, we assume that farmalloc ++ * will return a usable pointer which doesn't have to be normalized. ++ */ ++ if (bsize < 65520L) { ++ buf = farmalloc(bsize); ++ if (*(ush*)&buf != 0) return buf; ++ } else { ++ buf = farmalloc(bsize + 16L); ++ } ++ if (buf == NULL || next_ptr >= MAX_PTR) return NULL; ++ table[next_ptr].org_ptr = buf; ++ ++ /* Normalize the pointer to seg:0 */ ++ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; ++ *(ush*)&buf = 0; ++ table[next_ptr++].new_ptr = buf; ++ return buf; ++} ++ ++void zcfree (voidpf opaque, voidpf ptr) ++{ ++ int n; ++ if (*(ush*)&ptr != 0) { /* object < 64K */ ++ farfree(ptr); ++ return; ++ } ++ /* Find the original pointer */ ++ for (n = 0; n < next_ptr; n++) { ++ if (ptr != table[n].new_ptr) continue; ++ ++ farfree(table[n].org_ptr); ++ while (++n < next_ptr) { ++ table[n-1] = table[n]; ++ } ++ next_ptr--; ++ return; ++ } ++ ptr = opaque; /* just to make some compilers happy */ ++ Assert(0, "zcfree: ptr not found"); ++} ++#endif ++#endif /* __TURBOC__ */ ++ ++ ++#if defined(M_I86) && !defined(__32BIT__) ++/* Microsoft C in 16-bit mode */ ++ ++# define MY_ZCALLOC ++ ++#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) ++# define _halloc halloc ++# define _hfree hfree ++#endif ++ ++voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) ++{ ++ if (opaque) opaque = 0; /* to make compiler happy */ ++ return _halloc((long)items, size); ++} ++ ++void zcfree (voidpf opaque, voidpf ptr) ++{ ++ if (opaque) opaque = 0; /* to make compiler happy */ ++ _hfree(ptr); ++} ++ ++#endif /* MSC */ ++ ++ ++#ifndef MY_ZCALLOC /* Any system without a special alloc function */ ++ ++#ifndef STDC ++extern voidp calloc OF((uInt items, uInt size)); ++extern void free OF((voidpf ptr)); ++#endif ++ ++voidpf zcalloc (opaque, items, size) ++ voidpf opaque; ++ unsigned items; ++ unsigned size; ++{ ++ if (opaque) items += size - size; /* make compiler happy */ ++ return (voidpf)calloc(items, size); ++} ++ ++void zcfree (opaque, ptr) ++ voidpf opaque; ++ voidpf ptr; ++{ ++ free(ptr); ++ if (opaque) return; /* make compiler happy */ ++} ++ ++#endif /* MY_ZCALLOC */ +--- linux/net/Config.in.orig Fri Feb 9 14:34:13 2001 ++++ linux/net/Config.in Thu Feb 22 19:40:08 2001 +@@ -88,4 +88,9 @@ + #bool 'Network code profiler' CONFIG_NET_PROFILE + endmenu + ++tristate 'IP Security Protocol (FreeS/WAN IPSEC)' CONFIG_IPSEC ++if [ "$CONFIG_IPSEC" != "n" ]; then ++ source net/ipsec/Config.in ++fi ++ + endmenu +RCSID $Id: Makefile.fs2_4.patch,v 1.7 2002/07/28 23:12:39 mcr Exp $ +--- linux/net/Makefile.preipsec Mon Jun 11 22:15:27 2001 ++++ linux/net/Makefile Tue Nov 6 21:07:43 2001 +@@ -17,6 +17,7 @@ + subdir-$(CONFIG_NET) += 802 sched + subdir-$(CONFIG_INET) += ipv4 + subdir-$(CONFIG_NETFILTER) += ipv4/netfilter ++subdir-$(CONFIG_IPSEC) += ipsec + subdir-$(CONFIG_UNIX) += unix + subdir-$(CONFIG_IPV6) += ipv6 + +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/Config.in Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,76 @@ ++# ++# IPSEC configuration ++# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs. ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation; either version 2 of the License, or (at your ++# option) any later version. See . ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# RCSID $Id: Config.in,v 1.30 2004/06/23 09:49:37 ken Exp $ ++ ++comment 'IPSec options (Openswan)' ++ ++bool ' IPSEC: IP-in-IP encapsulation (tunnel mode)' CONFIG_IPSEC_IPIP ++ ++bool ' IPSEC: Authentication Header' CONFIG_IPSEC_AH ++if [ "$CONFIG_IPSEC_AH" = "y" -o "$CONFIG_IPSEC_ESP" = "y" ]; then ++ bool ' HMAC-MD5 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_MD5 ++ bool ' HMAC-SHA1 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_SHA1 ++fi ++ ++bool ' IPSEC: Encapsulating Security Payload' CONFIG_IPSEC_ESP ++if [ "$CONFIG_IPSEC_ESP" = "y" ]; then ++ bool ' 3DES encryption algorithm' CONFIG_IPSEC_ENC_3DES ++ bool ' AES encryption algorithm' CONFIG_IPSEC_ENC_AES ++fi ++ ++bool ' IPSEC Modular Extensions' CONFIG_IPSEC_ALG ++if [ "$CONFIG_IPSEC_ALG" != "n" ]; then ++ source net/ipsec/alg/Config.in ++fi ++ ++bool ' IPSEC: IP Compression' CONFIG_IPSEC_IPCOMP ++ ++bool ' IPSEC Debugging Option' CONFIG_IPSEC_DEBUG ++ ++# ++# ++# $Log: Config.in,v $ ++# Revision 1.30 2004/06/23 09:49:37 ken ++# Free -> Open ++# ++# Revision 1.29 2004/04/06 02:49:25 mcr ++# pullup of algo code from alg-branch. ++# ++# Revision 1.28 2004/02/03 03:12:26 mcr ++# remove NAT-traversal option from IPsec config, ++# as it should be in the kernel configuration if ++# the NAT-T patch is installed. ++# ++# Revision 1.27.2.2 2004/04/05 04:30:46 mcr ++# patches for alg-branch to compile/work with 2.x openswan ++# ++# Revision 1.27.2.1 2003/12/23 12:48:25 jjo ++# Added missing alg part to linux/net/ipsec/Config.in ++# ++# Revision 1.27 2003/12/10 01:14:27 mcr ++# NAT-traversal patches to KLIPS. ++# ++# Revision 1.26 2002/04/24 07:36:26 mcr ++# Moved from ./klips/net/ipsec/Config.in,v ++# ++# Revision 1.25 2002/02/21 19:55:12 mcr ++# removed all traces of IPSEC_CONFIG_REGRESS because it ++# screwed up 2.2's "make menuconfig" scripts. ++# ++# Revision 1.24 2002/01/28 20:24:31 mcr ++# commented out IPSEC_REGRESS option from user visible config. ++# ++# ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/Makefile Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,337 @@ ++# Makefile for KLIPS kernel code as a module ++# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs. ++# Copyright (C) 2002 Michael Richardson ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation; either version 2 of the License, or (at your ++# option) any later version. See . ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# RCSID $Id: Makefile,v 1.72 2004/06/22 14:44:07 ken Exp $ ++# ++# Note! Dependencies are done automagically by 'make dep', which also ++# removes any old dependencies. DON'T put your own dependencies here ++# unless it's something special (ie not a .c file). ++# ++ ++ifeq ($(strip $(KLIPSMODULE)),) ++OPENSWANSRCDIR=. ++else ++OPENSWANSRCDIR=../../.. ++endif ++-include ${OPENSWANSRCDIR}/Makefile.ver ++ ++ifeq ($(strip $(KLIPS_TOP)),) ++KLIPS_TOP=../.. ++endif ++ ++ifneq ($(strip $(KLIPSMODULE)),) ++ ++ifndef TOPDIR ++TOPDIR:=/usr/src/linux ++endif ++export TOPDIR ++ ++endif ++ ++# ++# This magic from User-Mode-Linux list. It gets list of -I options, as ++# UML needs some extra, that varry by revision. ++# ++KERNEL_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(CFLAGS)' ) ++ ++MODULE_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(MODFLAGS)' ) ++ ++subdir- := ++subdir-n := ++subdir-y := ++subdir-m := ++ ++ ++MOD_DESTDIR:=net/ipsec ++ ++export TOPDIR ++ ++all: ipsec.o ++ ++foo: ++ echo KERNEL: ${KERNEL_CFLAGS} ++ echo MODULE: ${MODULE_CFLAGS} ++ ++ipsec.o: foo ++ ++O_TARGET := ipsec.o ++obj-y := ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o ++obj-y += ipsec_life.o ipsec_proc.o ++obj-y += ipsec_tunnel.o ipsec_xmit.o ipsec_rcv.o ipsec_ipip.o ++obj-y += sysctl_net_ipsec.o ++obj-y += pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o ++obj-y += version.o ++obj-$(CONFIG_IPSEC_AH) += ipsec_ah.o ++obj-$(CONFIG_IPSEC_ESP) += ipsec_esp.o ++obj-$(CONFIG_IPSEC_IPCOMP)+= ipsec_ipcomp.o ++ ++CFLAGS_ipsec_alg.o += -DEXPORT_SYMTAB ++obj-$(CONFIG_IPSEC_ALG) += ipsec_alg.o ++obj-$(CONFIG_IPSEC_ENC_AES) += ipsec_alg_aes.o ++obj-$(CONFIG_IPSEC_ENC_CRYPTOAPI) += ipsec_alg_cryptoapi.o ++ ++export-objs += ipsec_alg.o ++ ++ ++LIBDESDIR=${KLIPS_TOP}/crypto/ciphers/des ++VPATH+= ${LIBDESDIR} ++ ++include ${LIBDESDIR}/Makefile.objs ++ ++LIBFREESWANDIR=${KLIPS_TOP}/lib/libfreeswan ++VPATH+=${LIBFREESWANDIR} ++ ++include ${LIBFREESWANDIR}/Makefile.objs ++ ++# IPcomp stuff ++obj-$(CONFIG_IPSEC_IPCOMP) += ipcomp.o ++ ++LIBZLIBSRCDIR=${KLIPS_TOP}/lib/zlib ++VPATH+=${LIBZLIBSRCDIR} ++ ++LIBAESDIR=$(KLIPS_TOP)/crypto/ciphers/aes ++VPATH+=${LIBAESDIR} ++include ${LIBAESDIR}/Makefile.objs ++ ++# CFLAGS='$(CFLAGS)' \ ++# MODULE_CFLAGS='$(MODULE_CFLAGS)' KERNEL_CFLAGS='$(KERNEL_CFLAGS)' \ ++# ++include ${LIBZLIBSRCDIR}/Makefile.objs ++ ++export-objs := radij.o ++ ++EXTRA_CFLAGS += $(ALGO_FLAGS) ++ ++ ++# include file with .h-style macros that would otherwise be created by ++# config. Must occur before other includes. ++ifneq ($(strip $(MODULE_DEF_INCLUDE)),) ++EXTRA_CFLAGS += -include ${MODULE_DEF_INCLUDE} ++endif ++ ++# 'override CFLAGS' should really be 'EXTRA_CFLAGS' ++#EXTRA_CFLAGS += -nostdinc ++EXTRA_CFLAGS += -I${KLIPS_TOP}/include ++ ++EXTRA_CFLAGS += -I${TOPDIR}/include ++EXTRA_CFLAGS += -I${LIBZLIBSRCDIR} ++ ++ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.2-2) ++EXTRA_CFLAGS += -DREDHAT_BOGOSITY ++endif ++ ++ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.3-12) ++EXTRA_CFLAGS += -DREDHAT_BOGOSITY ++endif ++ ++ ++#ifeq ($(CONFIG_IPSEC_DEBUG),y) ++#EXTRA_CFLAGS += -g ++#endif ++ ++#ifeq ($(CONFIG_IPSEC_ALG), y) ++EXTRA_CFLAGS += -DCONFIG_IPSEC_ALG ++#endif ++# MOST of these flags are in KERNEL_CFLAGS already! ++ ++EXTRA_CFLAGS += $(KLIPSCOMPILE) ++EXTRA_CFLAGS += -Wall ++#EXTRA_CFLAGS += -Werror ++#EXTRA_CFLAGS += -Wconversion ++#EXTRA_CFLAGS += -Wmissing-prototypes ++# cannot use both -Wpointer-arith and -Werror with CONFIG_HIGHMEM ++# include/linux/highmem.h has an inline function definition that uses void* arithmentic. ++ifeq ($(CONFIG_NOHIGHMEM),y) ++EXTRA_CFLAGS += -Wpointer-arith ++endif ++#EXTRA_CFLAGS += -Wcast-qual ++#EXTRA_CFLAGS += -Wmissing-declarations ++#EXTRA_CFLAGS += -Wstrict-prototypes ++#EXTRA_CFLAGS += -pedantic ++#EXTRA_CFLAGS += -O3 ++#EXTRA_CFLAGS += -W ++#EXTRA_CFLAGS += -Wwrite-strings ++#EXTRA_CFLAGS += -Wbad-function-cast ++ ++ifneq ($(strip $(KLIPSMODULE)),) ++# for when we aren't building in the kernel tree ++EXTRA_CFLAGS += -DARCH=${ARCH} ++EXTRA_CFLAGS += -DMODVERSIONS ++EXTRA_CFLAGS += -include ${TOPDIR}/include/linux/modversions.h ++EXTRA_CFLAGS += ${MODULE_CFLAGS} ++endif ++ ++EXTRA_CFLAGS += ${KERNEL_CFLAGS} ++ ++#EXTRA_CFLAGS += -DRJ_DEBUG -DRJ_DEBUG2 ++ ++ ++# GCC 3.2 (and we presume any other 3.x) wants -falign-functions ++# in place of the traditional -malign-functions. Getting this ++# wrong leads to a warning, which is fatal due to our use of -Werror. ++ifeq ($(patsubst 3.%,3,$(shell $(CC) -dumpversion)),3) ++override CFLAGS:=$(subst -malign-functions=,-falign-functions=,$(CFLAGS)) ++endif ++ ++ ++obj-$(CONFIG_IPSEC_AUTH_HMAC_MD5) += ipsec_md5c.o ++obj-$(CONFIG_IPSEC_AUTH_HMAC_SHA1) += ipsec_sha1.o ++ ++### ++### Pre Rules.make ++### ++# undo O_TARGET, obj-y if no static ++ifneq ($(CONFIG_IPSEC),y) ++O_TARGET := ++ipsec_obj-y := $(obj-y) ++obj-y := ++subdir-y := ++endif ++ ++# Define obj-m if modular ipsec ++ifeq ($(CONFIG_IPSEC),m) ++obj-m += ipsec.o ++endif ++ ++ ++# These rules translate from new to old makefile rules ++# Translate to Rules.make lists. ++multi-used := $(filter $(list-multi), $(obj-y) $(obj-m)) ++multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs)) ++active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m)) ++O_OBJS := $(obj-y) ++M_OBJS := $(obj-m) ++MIX_OBJS := $(filter $(export-objs), $(active-objs)) ++OX_OBJS := $(export-objs) ++SUB_DIRS := $(subdir-y) ++ALL_SUB_DIRS := $(subdir-y) $(subdir-m) ++MOD_SUB_DIRS := $(subdir-m) ++ ++# dunno why, but some 2.2 setups may need explicit -DEXPORT_SYMTAB ++# uncomment next line if ipsec_alg.c compilation fails with ++# "parse error before `EXPORT_SYMTAB_not_defined'" --Juanjo ++ ++include $(TOPDIR)/Rules.make ++ ++### ++### Post Rules.make ++### ++# for modular ipsec, no O_TARGET defined => define ipsec.o creation rules ++ifeq ($(CONFIG_IPSEC),m) ++ipsec.o : $(ipsec_obj-y) ++ rm -f $@ ++ $(LD) $(LD_EXTRAFLAGS) -r $(ipsec_obj-y) -o $@ ++endif ++ ++$(ipsec_obj-y) $(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h ++ ++#$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h ++ ++USE_STANDARD_AS_RULE=true ++ ++clean: ++ $(MAKE) -C alg clean ++ -rm -f *.o ++ -rm -f .*.o.flags ++ -rm -f version.c ++ ++tags TAGS: *.c *.h libfreeswan/*.c libfreeswan/*.h ++ etags *.c ../../include/*.h ../../include/freeswan/*.h ++ ctags *.c ../../include/*.h ../../include/freeswan/*.h ++ ++tar: ++ tar -cvf /dev/f1 . ++ ++# ++# $Log: Makefile,v $ ++# Revision 1.72 2004/06/22 14:44:07 ken ++# Merge nice version of Nate's CryptoAPI patch ++# ++# Revision 1.71 2004/04/18 03:04:21 mcr ++# removed duplicate version.o reference. ++# ++# Revision 1.70 2004/04/14 05:09:39 ken ++# We need to link version.o ++# ++# Revision 1.69 2004/04/12 04:02:39 ken ++# version.o no longer exists ++# ++# Revision 1.68 2004/04/11 17:08:41 mcr ++# moved PASSTHROUGH definitions to openswan.h ++# requirement for internal.h removed. ++# version.c is now generated by patch at patch-time. ++# ++# Revision 1.67 2004/04/06 02:49:25 mcr ++# pullup of algo code from alg-branch. ++# ++# Revision 1.66 2004/04/03 19:44:41 ken ++# FREESWANSRCDIR -> OPENSWANSRCDIR (patch by folken) ++# ++# Revision 1.65 2004/02/09 16:22:07 paul ++# Added -f to rm version.c in clean target to prevent bogus error ++# ++# Revision 1.64 2003/12/22 19:40:57 mcr ++# NAT-T patches 0.6c. ++# ++# Revision 1.63 2003/12/13 19:10:21 mcr ++# refactored rcv and xmit code - same as FS 2.05. ++# ++# Revision 1.62.4.2 2004/04/05 04:30:46 mcr ++# patches for alg-branch to compile/work with 2.x openswan ++# ++# Revision 1.62.4.1 2003/12/22 15:25:52 jjo ++# Merged algo-0.8.1-rc11-test1 into alg-branch ++# ++# Revision 1.62 2003/10/31 02:27:55 mcr ++# pulled up port-selector patches and sa_id elimination. ++# ++# Revision 1.61.4.1 2003/10/29 01:30:41 mcr ++# elimited "struct sa_id". ++# ++# Revision 1.61 2003/06/22 21:07:46 mcr ++# adjusted TAGS target in makefile to be useful in 2.00 source layout. ++# ++# Revision 1.60 2003/05/03 23:45:23 mcr ++# rm .o.flags and generated version.c file. ++# ++# Revision 1.59 2003/02/12 19:32:47 rgb ++# Added ipsec_xmit to the list of object files. ++# ++# Revision 1.58 2003/01/03 00:36:44 rgb ++# ++# Added emacs compile-command. ++# ++# Revision 1.57 2002/11/08 23:49:53 mcr ++# use KERNEL_CFLAGS and MODULE_CFLAGS to get proper list ++# of include directories. ++# This also eliminates some of the guesswork in the kernel ++# configuration file. ++# ++# Revision 1.56 2002/11/08 23:23:18 mcr ++# attempt to guess kernel compilation flags (i.e. list of -I) ++# by using some magic targets in the kernel makefile. ++# ++# Revision 1.55 2002/11/08 10:13:33 mcr ++# added additional include directories for module builds for 2.4.19. ++# ++# Revision 1.54 2002/10/20 06:10:30 build ++# CONFIG_NOHIGHMEM for -Wpointer-arith RPM building issues. ++# ++# (elided rest of log) ++# ++# Local Variables: ++# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)" ++# End Variables: ++# ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/alg/Config.alg_aes.in Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,3 @@ ++if [ "$CONFIG_IPSEC_ALG" = "y" ]; then ++ tristate ' AES encryption algorithm' CONFIG_IPSEC_ALG_AES ++fi +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/alg/Config.alg_cryptoapi.in Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,6 @@ ++if [ "$CONFIG_IPSEC_ALG" = "y" ]; then ++ dep_tristate ' CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO ++ if [ "$CONFIG_IPSEC_ALG_CRYPTOAPI" != "n" ]; then ++ bool ' CRYPTOAPI proprietary ciphers ' CONFIG_IPSEC_ALG_NON_LIBRE ++ fi ++fi +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/alg/Config.in Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,3 @@ ++#Placeholder ++source net/ipsec/alg/Config.alg_aes.in ++source net/ipsec/alg/Config.alg_cryptoapi.in +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/alg/Makefile Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,112 @@ ++# Makefile,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp ++ifeq ($(strip $(KLIPSMODULE)),) ++FREESWANSRCDIR=. ++else ++FREESWANSRCDIR=../../../.. ++endif ++ifeq ($(strip $(KLIPS_TOP)),) ++KLIPS_TOP=../../.. ++override EXTRA_CFLAGS += -I$(KLIPS_TOP)/include ++endif ++ ++ifeq ($(CONFIG_IPSEC_DEBUG),y) ++override EXTRA_CFLAGS += -g ++endif ++ ++# LIBCRYPTO normally comes as an argument from "parent" Makefile ++# (this applies both to FS' "make module" and eg. Linux' "make modules" ++# But make dep doest follow same evaluations, so we need this default: ++LIBCRYPTO=$(TOPDIR)/lib/libcrypto ++ ++override EXTRA_CFLAGS += -I$(LIBCRYPTO)/include ++override EXTRA_CFLAGS += -Wall -Wpointer-arith -Wstrict-prototypes ++ ++MOD_LIST_NAME := NET_MISC_MODULES ++ ++#O_TARGET := static_init.o ++ ++subdir- := ++subdir-n := ++subdir-y := ++subdir-m := ++ ++obj-y := static_init.o ++ ++ARCH_ASM-y := ++ARCH_ASM-$(CONFIG_M586) := i586 ++ARCH_ASM-$(CONFIG_M586TSC) := i586 ++ARCH_ASM-$(CONFIG_M586MMX) := i586 ++ARCH_ASM-$(CONFIG_MK6) := i586 ++ARCH_ASM-$(CONFIG_M686) := i686 ++ARCH_ASM-$(CONFIG_MPENTIUMIII) := i686 ++ARCH_ASM-$(CONFIG_MPENTIUM4) := i686 ++ARCH_ASM-$(CONFIG_MK7) := i686 ++ARCH_ASM-$(CONFIG_MCRUSOE) := i586 ++ARCH_ASM-$(CONFIG_MWINCHIPC6) := i586 ++ARCH_ASM-$(CONFIG_MWINCHIP2) := i586 ++ARCH_ASM-$(CONFIG_MWINCHIP3D) := i586 ++ARCH_ASM-$(CONFIG_USERMODE) := i586 ++ ++ARCH_ASM :=$(ARCH_ASM-y) ++ifdef NO_ASM ++ARCH_ASM := ++endif ++ ++# The algorithm makefiles may put dependences, short-circuit them ++null: ++ ++makefiles=$(filter-out %.preipsec, $(wildcard Makefile.alg_*)) ++ifneq ($(makefiles),) ++#include Makefile.alg_aes ++#include Makefile.alg_aes-opt ++include $(makefiles) ++endif ++ ++# These rules translate from new to old makefile rules ++# Translate to Rules.make lists. ++multi-used := $(filter $(list-multi), $(obj-y) $(obj-m)) ++multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs)) ++active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m)) ++O_OBJS := $(obj-y) ++M_OBJS := $(obj-m) ++MIX_OBJS := $(filter $(export-objs), $(active-objs)) ++#OX_OBJS := $(export-objs) ++SUB_DIRS := $(subdir-y) ++ALL_SUB_DIRS := $(subdir-y) $(subdir-m) ++MOD_SUB_DIRS := $(subdir-m) ++ ++ ++static_init_mod.o: $(obj-y) ++ rm -f $@ ++ $(LD) $(LD_EXTRAFLAGS) $(obj-y) -r -o $@ ++ ++perlasm: $(LIBCRYPTO)/perlasm ++ ln -sf $? $@ ++ ++$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h ++$(alg_obj-y) $(alg_obj-m): perlasm $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h ++ ++ ++all_alg_modules: perlasm $(ALG_MODULES) ++ @echo "ALG_MODULES=$(ALG_MODULES)" ++ ++ ++# ++# Construct alg. init. function: call ipsec_ALGO_init() for every static algo ++# Needed when there are static algos (with static or modular ipsec.o) ++# ++static_init.c: $(TOPDIR)/include/linux/autoconf.h Makefile $(makefiles) scripts/mk-static_init.c.sh ++ @echo "Re-creating $@" ++ $(SHELL) scripts/mk-static_init.c.sh $(static_init-func-y) > $@ ++ ++clean: ++ @for i in $(ALG_SUBDIRS);do test -d $$i && make -C $$i clean;done;exit 0 ++ @find . -type l -exec rm -f {} \; ++ -rm -f perlasm ++ -rm -rf $(ALG_SUBDIRS) ++ -rm -f *.o static_init.c ++ ++ifdef TOPDIR ++include $(TOPDIR)/Rules.make ++endif ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/alg/Makefile.alg_aes Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,23 @@ ++MOD_AES := ipsec_aes.o ++ ++ALG_MODULES += $(MOD_AES) ++ALG_SUBDIRS += libaes ++ ++obj-$(CONFIG_IPSEC_ALG_AES) += $(MOD_AES) ++static_init-func-$(CONFIG_IPSEC_ALG_AES)+= ipsec_aes_init ++alg_obj-$(CONFIG_IPSEC_ALG_AES) += ipsec_alg_aes.o ++ ++AES_OBJS := ipsec_alg_aes.o libaes/libaes.a ++ ++$(MOD_AES): libaes $(AES_OBJS) ++ $(LD) $(EXTRA_LDFLAGS) -r $(AES_OBJS) -o $@ ++ ++libaes: $(LIBCRYPTO)/libaes ++ test -d $@ || mkdir $@ ;exit 0 ++ test -d $@/asm || mkdir $@/asm;exit 0 ++ cd $@ && ln -sf $?/Makefile $?/*.[chS] . ++ cd $@/asm && ln -sf $?/asm/*.S . ++ ++libaes/libaes.a: libaes ++ ( cd libaes && \ ++ $(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' libaes.a ;) +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/alg/Makefile.alg_cryptoapi Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,14 @@ ++MOD_CRYPTOAPI := ipsec_cryptoapi.o ++ ++ifneq ($(wildcard $(TOPDIR)/include/linux/crypto.h),) ++ALG_MODULES += $(MOD_CRYPTOAPI) ++obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += $(MOD_CRYPTOAPI) ++static_init-func-$(CONFIG_IPSEC_ALG_CRYPTOAPI)+= ipsec_cryptoapi_init ++alg_obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += ipsec_alg_cryptoapi.o ++else ++$(warning "Linux CryptoAPI (2.4.22+ or 2.6.x) not found, not building ipsec_cryptoapi.o") ++endif ++ ++CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o ++$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS) ++ $(LD) -r $(CRYPTOAPI_OBJS) -o $@ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/alg/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,253 @@ ++/* ++ * ipsec_alg AES cipher stubs ++ * ++ * Author: JuanJo Ciarlante ++ * ++ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * Fixes by: ++ * PK: Pawel Krawczyk ++ * Fixes list: ++ * PK: make XCBC comply with latest draft (keylength) ++ * ++ */ ++#include ++#include ++ ++/* ++ * special case: ipsec core modular with this static algo inside: ++ * must avoid MODULE magic for this file ++ */ ++#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_AES ++#undef MODULE ++#endif ++ ++#include ++#include ++ ++#include /* printk() */ ++#include /* error codes */ ++#include /* size_t */ ++#include ++ ++/* Check if __exit is defined, if not null it */ ++#ifndef __exit ++#define __exit ++#endif ++ ++/* Low freeswan header coupling */ ++#include "freeswan/ipsec_alg.h" ++#include "libaes/aes_cbc.h" ++ ++#define CONFIG_IPSEC_ALG_AES_MAC 1 ++ ++#define AES_CONTEXT_T aes_context ++MODULE_AUTHOR("JuanJo Ciarlante "); ++static int debug=0; ++MODULE_PARM(debug, "i"); ++static int test=0; ++MODULE_PARM(test, "i"); ++static int excl=0; ++MODULE_PARM(excl, "i"); ++static int keyminbits=0; ++MODULE_PARM(keyminbits, "i"); ++static int keymaxbits=0; ++MODULE_PARM(keymaxbits, "i"); ++ ++#if CONFIG_IPSEC_ALG_AES_MAC ++#include "libaes/aes_xcbc_mac.h" ++ ++/* ++ * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt). ++ * We use 9 for non-modular algorithm and none for modular, thus ++ * forcing user to specify one on module load. -kravietz ++ */ ++#ifdef MODULE ++static int auth_id=0; ++#else ++static int auth_id=9; ++#endif ++MODULE_PARM(auth_id, "i"); ++#endif ++ ++#define ESP_AES 12 /* truely _constant_ :) */ ++ ++/* 128, 192 or 256 */ ++#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */ ++#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */ ++#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */ ++ ++/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt ++ * -kravietz ++ */ ++#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */ ++#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */ ++ ++static int _aes_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) { ++ int ret; ++ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e; ++ ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL; ++ if (debug > 0) ++ printk(KERN_DEBUG "klips_debug:_aes_set_key:" ++ "ret=%d key_e=%p key=%p keysize=%d\n", ++ ret, key_e, key, keysize); ++ return ret; ++} ++static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { ++ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e; ++ if (debug > 0) ++ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:" ++ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n", ++ key_e, in, ilen, iv, encrypt); ++ return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt); ++} ++#if CONFIG_IPSEC_ALG_AES_MAC ++static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) { ++ aes_context_mac *ctxm=(aes_context_mac *)key_a; ++ return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL; ++} ++static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) { ++ int ret; ++ char hash_buf[16]; ++ aes_context_mac *ctxm=(aes_context_mac *)key_a; ++ ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf); ++ memcpy(hash, hash_buf, hashlen); ++ return ret; ++} ++static struct ipsec_alg_auth ipsec_alg_AES_MAC = { ++ ixt_version: IPSEC_ALG_VERSION, ++ ixt_module: THIS_MODULE, ++ ixt_refcnt: ATOMIC_INIT(0), ++ ixt_alg_type: IPSEC_ALG_TYPE_AUTH, ++ ixt_alg_id: 0, ++ ixt_name: "aes_mac", ++ ixt_blocksize: ESP_AES_MAC_BLK_LEN, ++ ixt_keyminbits: ESP_AES_MAC_KEY_SZ*8, ++ ixt_keymaxbits: ESP_AES_MAC_KEY_SZ*8, ++ ixt_a_keylen: ESP_AES_MAC_KEY_SZ, ++ ixt_a_ctx_size: sizeof(aes_context_mac), ++ ixt_a_hmac_set_key: _aes_mac_set_key, ++ ixt_a_hmac_hash:_aes_mac_hash, ++}; ++#endif /* CONFIG_IPSEC_ALG_AES_MAC */ ++static struct ipsec_alg_enc ipsec_alg_AES = { ++ ixt_version: IPSEC_ALG_VERSION, ++ ixt_module: THIS_MODULE, ++ ixt_refcnt: ATOMIC_INIT(0), ++ ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT, ++ ixt_alg_id: ESP_AES, ++ ixt_name: "aes", ++ ixt_blocksize: ESP_AES_CBC_BLK_LEN, ++ ixt_keyminbits: ESP_AES_KEY_SZ_MIN*8, ++ ixt_keymaxbits: ESP_AES_KEY_SZ_MAX*8, ++ ixt_e_keylen: ESP_AES_KEY_SZ_MAX, ++ ixt_e_ctx_size: sizeof(AES_CONTEXT_T), ++ ixt_e_set_key: _aes_set_key, ++ ixt_e_cbc_encrypt:_aes_cbc_encrypt, ++}; ++ ++IPSEC_ALG_MODULE_INIT( ipsec_aes_init ) ++{ ++ int ret, test_ret; ++ if (keyminbits) ++ ipsec_alg_AES.ixt_keyminbits=keyminbits; ++ if (keymaxbits) { ++ ipsec_alg_AES.ixt_keymaxbits=keymaxbits; ++ if (keymaxbits*8>ipsec_alg_AES.ixt_keymaxbits) ++ ipsec_alg_AES.ixt_e_keylen=keymaxbits*8; ++ } ++ if (excl) ipsec_alg_AES.ixt_state |= IPSEC_ALG_ST_EXCL; ++ ret=register_ipsec_alg_enc(&ipsec_alg_AES); ++ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", ++ ipsec_alg_AES.ixt_alg_type, ++ ipsec_alg_AES.ixt_alg_id, ++ ipsec_alg_AES.ixt_name, ++ ret); ++ if (ret==0 && test) { ++ test_ret=ipsec_alg_test( ++ ipsec_alg_AES.ixt_alg_type, ++ ipsec_alg_AES.ixt_alg_id, ++ test); ++ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", ++ ipsec_alg_AES.ixt_alg_type, ++ ipsec_alg_AES.ixt_alg_id, ++ test_ret); ++ } ++#if CONFIG_IPSEC_ALG_AES_MAC ++ if (auth_id!=0){ ++ int ret; ++ ipsec_alg_AES_MAC.ixt_alg_id=auth_id; ++ ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC); ++ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", ++ ipsec_alg_AES_MAC.ixt_alg_type, ++ ipsec_alg_AES_MAC.ixt_alg_id, ++ ipsec_alg_AES_MAC.ixt_name, ++ ret); ++ if (ret==0 && test) { ++ test_ret=ipsec_alg_test( ++ ipsec_alg_AES_MAC.ixt_alg_type, ++ ipsec_alg_AES_MAC.ixt_alg_id, ++ test); ++ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", ++ ipsec_alg_AES_MAC.ixt_alg_type, ++ ipsec_alg_AES_MAC.ixt_alg_id, ++ test_ret); ++ } ++ } else { ++ printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id); ++ } ++#endif /* CONFIG_IPSEC_ALG_AES_MAC */ ++ return ret; ++} ++IPSEC_ALG_MODULE_EXIT( ipsec_aes_fini ) ++{ ++#if CONFIG_IPSEC_ALG_AES_MAC ++ if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC); ++#endif /* CONFIG_IPSEC_ALG_AES_MAC */ ++ unregister_ipsec_alg_enc(&ipsec_alg_AES); ++ return; ++} ++#ifdef MODULE_LICENSE ++MODULE_LICENSE("GPL"); ++#endif ++ ++#if 0+NOT_YET ++#ifndef MODULE ++/* ++ * This is intended for static module setups, currently ++ * doesn't work for modular ipsec.o with static algos inside ++ */ ++static int setup_keybits(const char *str) ++{ ++ unsigned aux; ++ char *end; ++ ++ aux = simple_strtoul(str,&end,0); ++ if (aux != 128 && aux != 192 && aux != 256) ++ return 0; ++ keyminbits = aux; ++ ++ if (*end == 0 || *end != ',') ++ return 1; ++ str=end+1; ++ aux = simple_strtoul(str, NULL, 0); ++ if (aux != 128 && aux != 192 && aux != 256) ++ return 0; ++ if (aux >= keyminbits) ++ keymaxbits = aux; ++ return 1; ++} ++__setup("ipsec_aes_keybits=", setup_keybits); ++#endif ++#endif ++EXPORT_NO_SYMBOLS; +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/alg/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,421 @@ ++/* ++ * ipsec_alg to linux cryptoapi GLUE ++ * ++ * Authors: CODE.ar TEAM ++ * Harpo MAxx ++ * JuanJo Ciarlante ++ * Luciano Ruete ++ * ++ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * Example usage: ++ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos) ++ * modprobe ipsec_cryptoapi ++ * modprobe ipsec_cryptoapi test=1 ++ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo) ++ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers) ++ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens) ++ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES) ++ */ ++#include ++#include ++ ++/* ++ * special case: ipsec core modular with this static algo inside: ++ * must avoid MODULE magic for this file ++ */ ++#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI ++#undef MODULE ++#endif ++ ++#include ++#include ++ ++#include /* printk() */ ++#include /* error codes */ ++#include /* size_t */ ++#include ++ ++/* Check if __exit is defined, if not null it */ ++#ifndef __exit ++#define __exit ++#endif ++ ++/* warn the innocent */ ++#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE) ++#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x" ++#define NO_CRYPTOAPI_SUPPORT ++#endif ++/* Low freeswan header coupling */ ++#include "freeswan/ipsec_alg.h" ++ ++#include ++#ifdef CRYPTO_API_VERSION_CODE ++#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported" ++#define NO_CRYPTOAPI_SUPPORT ++#endif ++ ++#ifdef NO_CRYPTOAPI_SUPPORT ++#warning "Building an unusable module :P" ++/* Catch old CryptoAPI by not allowing module to load */ ++IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init ) ++{ ++ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n"); ++ return -EINVAL; ++} ++#else ++#include ++#include ++#include ++ ++#define CIPHERNAME_AES "aes" ++#define CIPHERNAME_3DES "des3_ede" ++#define CIPHERNAME_BLOWFISH "blowfish" ++#define CIPHERNAME_CAST "cast5" ++#define CIPHERNAME_SERPENT "serpent" ++#define CIPHERNAME_TWOFISH "twofish" ++ ++#define ESP_3DES 3 ++#define ESP_AES 12 ++#define ESP_BLOWFISH 7 /* truely _constant_ :) */ ++#define ESP_CAST 6 /* quite constant :) */ ++#define ESP_SERPENT 252 /* from ipsec drafts */ ++#define ESP_TWOFISH 253 /* from ipsec drafts */ ++ ++#define AH_MD5 2 ++#define AH_SHA 3 ++#define DIGESTNAME_MD5 "md5" ++#define DIGESTNAME_SHA1 "sha1" ++ ++MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete"); ++static int debug=0; ++MODULE_PARM(debug, "i"); ++static int test=0; ++MODULE_PARM(test, "i"); ++static int excl=0; ++MODULE_PARM(excl, "i"); ++ ++static int noauto = 0; ++MODULE_PARM(noauto,"i"); ++MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones"); ++ ++static int des_ede3[] = {-1, -1}; ++static int aes[] = {-1, -1}; ++static int blowfish[] = {-1, -1}; ++static int cast[] = {-1, -1}; ++static int serpent[] = {-1, -1}; ++static int twofish[] = {-1, -1}; ++ ++MODULE_PARM(des_ede3,"1-2i"); ++MODULE_PARM(aes,"1-2i"); ++MODULE_PARM(blowfish,"1-2i"); ++MODULE_PARM(cast,"1-2i"); ++MODULE_PARM(serpent,"1-2i"); ++MODULE_PARM(twofish,"1-2i"); ++MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse"); ++MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens"); ++MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens"); ++MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens"); ++MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens"); ++MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens"); ++ ++struct ipsec_alg_capi_cipher { ++ const char *ciphername; /* cryptoapi's ciphername */ ++ unsigned blocksize; ++ unsigned short minbits; ++ unsigned short maxbits; ++ int *parm; /* lkm param for this cipher */ ++ struct ipsec_alg_enc alg; /* note it's not a pointer */ ++}; ++static struct ipsec_alg_capi_cipher alg_capi_carray[] = { ++ { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }}, ++ { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }}, ++ { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }}, ++ { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }}, ++ { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }}, ++ { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }}, ++ { NULL, 0, 0, 0, NULL, {} } ++}; ++#ifdef NOT_YET ++struct ipsec_alg_capi_digest { ++ const char *digestname; /* cryptoapi's digestname */ ++ struct digest_implementation *di; ++ struct ipsec_alg_auth alg; /* note it's not a pointer */ ++}; ++static struct ipsec_alg_capi_cipher alg_capi_darray[] = { ++ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }}, ++ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }}, ++ { NULL, NULL, {} } ++}; ++#endif ++/* ++ * "generic" linux cryptoapi setup_cipher() function ++ */ ++int setup_cipher(const char *ciphername) ++{ ++ return crypto_alg_available(ciphername, 0); ++} ++ ++/* ++ * setups ipsec_alg_capi_cipher "hyper" struct components, calling ++ * register_ipsec_alg for cointaned ipsec_alg object ++ */ ++static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e); ++static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen); ++static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt); ++ ++static int ++setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr) ++{ ++ int ret; ++ cptr->alg.ixt_version = IPSEC_ALG_VERSION; ++ cptr->alg.ixt_module = THIS_MODULE; ++ atomic_set (& cptr->alg.ixt_refcnt, 0); ++ strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name)); ++ ++ cptr->alg.ixt_blocksize=cptr->blocksize; ++ cptr->alg.ixt_keyminbits=cptr->minbits; ++ cptr->alg.ixt_keymaxbits=cptr->maxbits; ++ cptr->alg.ixt_state = 0; ++ if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL; ++ cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8; ++ cptr->alg.ixt_e_ctx_size = 0; ++ cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT; ++ cptr->alg.ixt_e_new_key = _capi_new_key; ++ cptr->alg.ixt_e_destroy_key = _capi_destroy_key; ++ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt; ++ cptr->alg.ixt_data = cptr; ++ ++ ret=register_ipsec_alg_enc(&cptr->alg); ++ printk("setup_ipsec_alg_capi_cipher(): " ++ "alg_type=%d alg_id=%d name=%s " ++ "keyminbits=%d keymaxbits=%d, ret=%d\n", ++ cptr->alg.ixt_alg_type, ++ cptr->alg.ixt_alg_id, ++ cptr->alg.ixt_name, ++ cptr->alg.ixt_keyminbits, ++ cptr->alg.ixt_keymaxbits, ++ ret); ++ return ret; ++} ++/* ++ * called in ipsec_sa_wipe() time, will destroy key contexts ++ * and do 1 unbind() ++ */ ++static void ++_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e) ++{ ++ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e; ++ ++ if (debug > 0) ++ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:" ++ "name=%s key_e=%p \n", ++ alg->ixt_name, key_e); ++ if (!key_e) { ++ printk(KERN_ERR "klips_debug: _capi_destroy_key:" ++ "name=%s NULL key_e!\n", ++ alg->ixt_name); ++ return; ++ } ++ crypto_free_tfm(tfm); ++} ++ ++/* ++ * create new key context, need alg->ixt_data to know which ++ * (of many) cipher inside this module is the target ++ */ ++static __u8 * ++_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen) ++{ ++ struct ipsec_alg_capi_cipher *cptr; ++ struct crypto_tfm *tfm=NULL; ++ ++ cptr = alg->ixt_data; ++ if (!cptr) { ++ printk(KERN_ERR "_capi_new_key(): " ++ "NULL ixt_data (?!) for \"%s\" algo\n" ++ , alg->ixt_name); ++ goto err; ++ } ++ if (debug > 0) ++ printk(KERN_DEBUG "klips_debug:_capi_new_key:" ++ "name=%s cptr=%p key=%p keysize=%d\n", ++ alg->ixt_name, cptr, key, keylen); ++ ++ /* ++ * alloc tfm ++ */ ++ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC); ++ if (!tfm) { ++ printk(KERN_ERR "_capi_new_key(): " ++ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n" ++ , alg->ixt_name, cptr->ciphername); ++ goto err; ++ } ++ if (crypto_cipher_setkey(tfm, key, keylen) < 0) { ++ printk(KERN_ERR "_capi_new_key(): " ++ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n" ++ , alg->ixt_name, keylen); ++ crypto_free_tfm(tfm); ++ tfm=NULL; ++ } ++err: ++ if (debug > 0) ++ printk(KERN_DEBUG "klips_debug:_capi_new_key:" ++ "name=%s key=%p keylen=%d tfm=%p\n", ++ alg->ixt_name, key, keylen, tfm); ++ return (__u8 *) tfm; ++} ++/* ++ * core encryption function: will use cx->ci to call actual cipher's ++ * cbc function ++ */ ++static int ++_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { ++ int error =0; ++ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e; ++ struct scatterlist sg = { ++ .page = virt_to_page(in), ++ .offset = (unsigned long)(in) % PAGE_SIZE, ++ .length=ilen, ++ }; ++ if (debug > 1) ++ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:" ++ "key_e=%p " ++ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n" ++ , key_e ++ , in, in, ilen, iv, encrypt); ++ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm)); ++ if (encrypt) ++ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen); ++ else ++ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen); ++ if (debug > 1) ++ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:" ++ "error=%d\n" ++ , error); ++ return (error<0)? error : ilen; ++} ++/* ++ * main initialization loop: for each cipher in list, do ++ * 1) setup cryptoapi cipher else continue ++ * 2) register ipsec_alg object ++ */ ++static int ++setup_cipher_list (struct ipsec_alg_capi_cipher* clist) ++{ ++ struct ipsec_alg_capi_cipher *cptr; ++ /* foreach cipher in list ... */ ++ for (cptr=clist;cptr->ciphername;cptr++) { ++ /* ++ * see if cipher has been disabled (0) or ++ * if noauto set and not enabled (1) ++ */ ++ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) { ++ if (debug>0) ++ printk(KERN_INFO "setup_cipher_list(): " ++ "ciphername=%s skipped at user request: " ++ "noauto=%d parm[0]=%d parm[1]=%d\n" ++ , cptr->ciphername ++ , noauto ++ , cptr->parm[0] ++ , cptr->parm[1]); ++ continue; ++ } ++ /* ++ * use a local ci to avoid touching cptr->ci, ++ * if register ipsec_alg success then bind cipher ++ */ ++ if( setup_cipher(cptr->ciphername) ) { ++ if (debug > 0) ++ printk(KERN_DEBUG "klips_debug:" ++ "setup_cipher_list():" ++ "ciphername=%s found\n" ++ , cptr->ciphername); ++ if (setup_ipsec_alg_capi_cipher(cptr) == 0) { ++ ++ ++ } else { ++ printk(KERN_ERR "klips_debug:" ++ "setup_cipher_list():" ++ "ciphername=%s failed ipsec_alg_register\n" ++ , cptr->ciphername); ++ } ++ } else { ++ if (debug>0) ++ printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n", ++ cptr->ciphername); ++ } ++ } ++ return 0; ++} ++/* ++ * deregister ipsec_alg objects and unbind ciphers ++ */ ++static int ++unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist) ++{ ++ struct ipsec_alg_capi_cipher *cptr; ++ /* foreach cipher in list ... */ ++ for (cptr=clist;cptr->ciphername;cptr++) { ++ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) { ++ unregister_ipsec_alg_enc(&cptr->alg); ++ } ++ } ++ return 0; ++} ++/* ++ * test loop for registered algos ++ */ ++static int ++test_cipher_list (struct ipsec_alg_capi_cipher* clist) ++{ ++ int test_ret; ++ struct ipsec_alg_capi_cipher *cptr; ++ /* foreach cipher in list ... */ ++ for (cptr=clist;cptr->ciphername;cptr++) { ++ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) { ++ test_ret=ipsec_alg_test( ++ cptr->alg.ixt_alg_type, ++ cptr->alg.ixt_alg_id, ++ test); ++ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n", ++ cptr->alg.ixt_alg_type, ++ cptr->alg.ixt_alg_id, ++ test_ret); ++ } ++ } ++ return 0; ++} ++ ++IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init ) ++{ ++ int ret, test_ret; ++ if ((ret=setup_cipher_list(alg_capi_carray)) < 0) ++ return -EPROTONOSUPPORT; ++ if (ret==0 && test) { ++ test_ret=test_cipher_list(alg_capi_carray); ++ } ++ return ret; ++} ++IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini ) ++{ ++ unsetup_cipher_list(alg_capi_carray); ++ return; ++} ++#ifdef MODULE_LICENSE ++MODULE_LICENSE("GPL"); ++#endif ++ ++EXPORT_NO_SYMBOLS; ++#endif /* NO_CRYPTOAPI_SUPPORT */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/alg/scripts/mk-static_init.c.sh Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,18 @@ ++#!/bin/sh ++cat << EOF ++#include ++#include ++#include "freeswan/ipsec_alg.h" ++$(for i in $*; do ++ test -z "$i" && continue ++ echo "extern int $i(void);" ++done) ++void ipsec_alg_static_init(void){ ++ int __attribute__ ((unused)) err=0; ++$(for i in $*; do ++ test -z "$i" && continue ++ echo " if ((err=$i()) < 0)" ++ echo " printk(KERN_WARNING \"$i() returned %d\", err);" ++done) ++} ++EOF +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/defconfig Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,146 @@ ++ ++# ++# RCSID $Id: defconfig,v 1.25 2004/07/05 01:03:53 mcr Exp $ ++# ++ ++# ++# FreeS/WAN IPSec implementation, KLIPS kernel config defaults ++# ++ ++# ++# First, lets override stuff already set or not in the kernel config. ++# ++# We can't even think about leaving this off... ++CONFIG_INET=y ++ ++# ++# This must be on for subnet protection. ++CONFIG_IP_FORWARD=y ++ ++# Shut off IPSEC masquerading if it has been enabled, since it will ++# break the compile. IPPROTO_ESP and IPPROTO_AH were included in ++# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h. ++CONFIG_IP_MASQUERADE_IPSEC=n ++ ++# ++# Next, lets set the recommended FreeS/WAN configuration. ++# ++ ++# To config as static (preferred), 'y'. To config as module, 'm'. ++CONFIG_IPSEC=y ++ ++# To do tunnel mode IPSec, this must be enabled. ++CONFIG_IPSEC_IPIP=y ++ ++# To enable authentication, say 'y'. (Highly recommended) ++CONFIG_IPSEC_AH=y ++ ++# Authentication algorithm(s): ++CONFIG_IPSEC_AUTH_HMAC_MD5=y ++CONFIG_IPSEC_AUTH_HMAC_SHA1=y ++ ++# To enable encryption, say 'y'. (Highly recommended) ++CONFIG_IPSEC_ESP=y ++ ++# Encryption algorithm(s): ++CONFIG_IPSEC_ENC_3DES=y ++CONFIG_IPSEC_ENC_AES=y ++ ++# modular algo extensions (and new ALGOs) ++CONFIG_IPSEC_ALG=y ++CONFIG_IPSEC_ENC_3DES=y ++CONFIG_IPSEC_ENC_AES=y ++ ++CONFIG_IPSEC_ALG_TWOFISH=m ++CONFIG_IPSEC_ALG_BLOWFISH=m ++CONFIG_IPSEC_ALG_SERPENT=m ++CONFIG_IPSEC_ALG_MD5=m ++CONFIG_IPSEC_ALG_SHA1=m ++CONFIG_IPSEC_ALG_SHA2=m ++#CONFIG_IPSEC_ALG_CAST=n ++#CONFIG_IPSEC_ALG_NULL=n ++ ++# Use CryptoAPI for ALG? - by default, no. ++CONFIG_IPSEC_ENC_CRYPTOAPI=n ++ ++ ++# IP Compression: new, probably still has minor bugs. ++CONFIG_IPSEC_IPCOMP=y ++ ++# To enable userspace-switchable KLIPS debugging, say 'y'. ++CONFIG_IPSEC_DEBUG=y ++ ++# NAT Traversal ++CONFIG_IPSEC_NAT_TRAVERSAL=y ++ ++# ++# ++# $Log: defconfig,v $ ++# Revision 1.25 2004/07/05 01:03:53 mcr ++# fix for adding cryptoapi code. ++# keep it off for now, since UMLs do not have it yet. ++# ++# Revision 1.24 2004/04/06 02:49:25 mcr ++# pullup of algo code from alg-branch. ++# ++# Revision 1.23.2.2 2004/04/05 04:30:46 mcr ++# patches for alg-branch to compile/work with 2.x openswan ++# ++# Revision 1.23.2.1 2003/12/22 15:25:52 jjo ++# . Merged algo-0.8.1-rc11-test1 into alg-branch ++# ++# Revision 1.23 2003/12/10 01:14:27 mcr ++# NAT-traversal patches to KLIPS. ++# ++# Revision 1.22 2003/02/24 19:37:27 mcr ++# changed default compilation mode to static. ++# ++# Revision 1.21 2002/04/24 07:36:27 mcr ++# Moved from ./klips/net/ipsec/defconfig,v ++# ++# Revision 1.20 2002/04/02 04:07:40 mcr ++# default build is now 'm'odule for KLIPS ++# ++# Revision 1.19 2002/03/08 18:57:17 rgb ++# Added a blank line at the beginning of the file to make it easier for ++# other projects to patch ./arch/i386/defconfig, for example ++# LIDS+grSecurity requested by Jason Pattie. ++# ++# Revision 1.18 2000/11/30 17:26:56 rgb ++# Cleaned out unused options and enabled ipcomp by default. ++# ++# Revision 1.17 2000/09/15 11:37:01 rgb ++# Merge in heavily modified Svenning Soerensen's ++# IPCOMP zlib deflate code. ++# ++# Revision 1.16 2000/09/08 19:12:55 rgb ++# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++# ++# Revision 1.15 2000/05/24 19:37:13 rgb ++# *** empty log message *** ++# ++# Revision 1.14 2000/05/11 21:14:57 henry ++# just commenting the FOOBAR=y lines out is not enough ++# ++# Revision 1.13 2000/05/10 20:17:58 rgb ++# Comment out netlink defaults, which are no longer needed. ++# ++# Revision 1.12 2000/05/10 19:13:38 rgb ++# Added configure option to shut off no eroute passthrough. ++# ++# Revision 1.11 2000/03/16 07:09:46 rgb ++# Hardcode PF_KEYv2 support. ++# Disable IPSEC_ICMP by default. ++# Remove DES config option from defaults file. ++# ++# Revision 1.10 2000/01/11 03:09:42 rgb ++# Added a default of 'y' to PF_KEYv2 keying I/F. ++# ++# Revision 1.9 1999/05/08 21:23:12 rgb ++# Added support for 2.2.x kernels. ++# ++# Revision 1.8 1999/04/06 04:54:25 rgb ++# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++# patch shell fixes. ++# ++# +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipcomp.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,725 @@ ++/* ++ * IPCOMP zlib interface code. ++ * Copyright (C) 2000 Svenning Soerensen ++ * Copyright (C) 2000, 2001 Richard Guy Briggs ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ */ ++ ++char ipcomp_c_version[] = "RCSID $Id: ipcomp.c,v 1.36 2004/04/06 02:49:25 mcr Exp $"; ++ ++/* SSS */ ++ ++#include ++#include ++ ++#define __NO_VERSION__ ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include ++#include ++#include ++#include ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include ++ ++#include ++ ++#ifdef NET_21 ++# include ++# include ++# include ++# define proto_priv cb ++#endif /* NET21 */ ++#include ++#include ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_sa.h" ++ ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_tunnel.h" ++#include "openswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */ ++#include "openswan/ipcomp.h" ++#include "zlib/zlib.h" ++#include "zlib/zutil.h" ++ ++#include /* SADB_X_CALG_DEFLATE */ ++ ++#ifdef CONFIG_IPSEC_DEBUG ++int sysctl_ipsec_debug_ipcomp = 0; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++static ++struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask); ++ ++static ++voidpf my_zcalloc(voidpf opaque, uInt items, uInt size) ++{ ++ return (voidpf) kmalloc(items*size, GFP_ATOMIC); ++} ++ ++static ++void my_zfree(voidpf opaque, voidpf address) ++{ ++ kfree(address); ++} ++ ++struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags) ++{ ++ struct iphdr *iph; ++ unsigned int iphlen, pyldsz, cpyldsz; ++ unsigned char *buffer; ++ z_stream zs; ++ int zresult; ++ ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_compress: .\n"); ++ ++ if(skb == NULL) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_compress: " ++ "passed in NULL skb, returning ERROR.\n"); ++ if(flags != NULL) { ++ *flags |= IPCOMP_PARMERROR; ++ } ++ return skb; ++ } ++ ++ if(ips == NULL) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_compress: " ++ "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n"); ++ if(flags) { ++ *flags |= IPCOMP_PARMERROR; ++ } ++ return skb; ++ } ++ ++ if (flags == NULL) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_compress: " ++ "passed in NULL flags, returning ERROR.\n"); ++ ipsec_kfree_skb(skb); ++ return NULL; ++ } ++ ++#ifdef NET_21 ++ iph = skb->nh.iph; ++#else /* NET_21 */ ++ iph = skb->ip_hdr; ++#endif /* NET_21 */ ++ ++ switch (iph->protocol) { ++ case IPPROTO_COMP: ++ case IPPROTO_AH: ++ case IPPROTO_ESP: ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_compress: " ++ "skipping compression of packet with ip protocol %d.\n", ++ iph->protocol); ++ *flags |= IPCOMP_UNCOMPRESSABLE; ++ return skb; ++ } ++ ++ /* Don't compress packets already fragmented */ ++ if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_compress: " ++ "skipping compression of fragmented packet.\n"); ++ *flags |= IPCOMP_UNCOMPRESSABLE; ++ return skb; ++ } ++ ++ iphlen = iph->ihl << 2; ++ pyldsz = ntohs(iph->tot_len) - iphlen; ++ ++ /* Don't compress less than 90 bytes (rfc 2394) */ ++ if (pyldsz < 90) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_compress: " ++ "skipping compression of tiny packet, len=%d.\n", ++ pyldsz); ++ *flags |= IPCOMP_UNCOMPRESSABLE; ++ return skb; ++ } ++ ++ /* Adaptive decision */ ++ if (ips->ips_comp_adapt_skip) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_compress: " ++ "skipping compression: ips_comp_adapt_skip=%d.\n", ++ ips->ips_comp_adapt_skip); ++ ips->ips_comp_adapt_skip--; ++ *flags |= IPCOMP_UNCOMPRESSABLE; ++ return skb; ++ } ++ ++ zs.zalloc = my_zcalloc; ++ zs.zfree = my_zfree; ++ zs.opaque = 0; ++ ++ /* We want to use deflateInit2 because we don't want the adler ++ header. */ ++ zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11, ++ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); ++ if (zresult != Z_OK) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_error:skb_compress: " ++ "deflateInit2() returned error %d (%s), " ++ "skipping compression.\n", ++ zresult, ++ zs.msg ? zs.msg : zError(zresult)); ++ *flags |= IPCOMP_COMPRESSIONERROR; ++ return skb; ++ } ++ ++ ++ /* Max output size. Result should be max this size. ++ * Implementation specific tweak: ++ * If it's not at least 32 bytes and 6.25% smaller than ++ * the original packet, it's probably not worth wasting ++ * the receiver's CPU cycles decompressing it. ++ * Your mileage may vary. ++ */ ++ cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4); ++ ++ buffer = kmalloc(cpyldsz, GFP_ATOMIC); ++ if (!buffer) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_error:skb_compress: " ++ "unable to kmalloc(%d, GFP_ATOMIC), " ++ "skipping compression.\n", ++ cpyldsz); ++ *flags |= IPCOMP_COMPRESSIONERROR; ++ deflateEnd(&zs); ++ return skb; ++ } ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { ++ __u8 *c; ++ int i; ++ ++ c = (__u8*)iph + iphlen; ++ for(i = 0; i < pyldsz; i++, c++) { ++ if(!(i % 16)) { ++ printk(KERN_INFO "skb_compress: before:"); ++ } ++ printk("%02x ", *c); ++ if(!((i + 1) % 16)) { ++ printk("\n"); ++ } ++ } ++ if(i % 16) { ++ printk("\n"); ++ } ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ zs.next_in = (char *) iph + iphlen; /* start of payload */ ++ zs.avail_in = pyldsz; ++ zs.next_out = buffer; /* start of compressed payload */ ++ zs.avail_out = cpyldsz; ++ ++ /* Finish compression in one step */ ++ zresult = deflate(&zs, Z_FINISH); ++ ++ /* Free all dynamically allocated buffers */ ++ deflateEnd(&zs); ++ if (zresult != Z_STREAM_END) { ++ *flags |= IPCOMP_UNCOMPRESSABLE; ++ kfree(buffer); ++ ++ /* Adjust adaptive counters */ ++ if (++(ips->ips_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_compress: " ++ "first %d packets didn't compress, " ++ "skipping next %d\n", ++ IPCOMP_ADAPT_INITIAL_TRIES, ++ IPCOMP_ADAPT_INITIAL_SKIP); ++ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP; ++ } ++ else if (ips->ips_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_compress: " ++ "next %d packets didn't compress, " ++ "skipping next %d\n", ++ IPCOMP_ADAPT_SUBSEQ_TRIES, ++ IPCOMP_ADAPT_SUBSEQ_SKIP); ++ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP; ++ ips->ips_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES; ++ } ++ ++ return skb; ++ } ++ ++ /* resulting compressed size */ ++ cpyldsz -= zs.avail_out; ++ ++ /* Insert IPCOMP header */ ++ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol; ++ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0; ++ /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are ++ for internal reference only. */ ++ ((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(ips->ips_said.spi) & 0x0000ffff)); ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_compress: " ++ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n", ++ ntohl(ips->ips_said.spi), ++ ntohl(ips->ips_said.spi) & 0x0000ffff, ++ ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi), ++ pyldsz, ++ cpyldsz); ++ ++ /* Update IP header */ ++ iph->protocol = IPPROTO_COMP; ++ iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz); ++#if 1 /* XXX checksum is done by ipsec_tunnel ? */ ++ iph->check = 0; ++ iph->check = ip_fast_csum((char *) iph, iph->ihl); ++#endif ++ ++ /* Copy compressed payload */ ++ memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr), ++ buffer, ++ cpyldsz); ++ kfree(buffer); ++ ++ /* Update skb length/tail by "unputting" the shrinkage */ ++ skb_put(skb, ++ cpyldsz + sizeof(struct ipcomphdr) - pyldsz); ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { ++ __u8 *c; ++ int i; ++ ++ c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr); ++ for(i = 0; i < cpyldsz; i++, c++) { ++ if(!(i % 16)) { ++ printk(KERN_INFO "skb_compress: result:"); ++ } ++ printk("%02x ", *c); ++ if(!((i + 1) % 16)) { ++ printk("\n"); ++ } ++ } ++ if(i % 16) { ++ printk("\n"); ++ } ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ ips->ips_comp_adapt_skip = 0; ++ ips->ips_comp_adapt_tries = 0; ++ ++ return skb; ++} ++ ++struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags) ++{ ++ struct sk_buff *nskb = NULL; ++ ++ /* original ip header */ ++ struct iphdr *oiph, *iph; ++ unsigned int iphlen, pyldsz, cpyldsz; ++ z_stream zs; ++ int zresult; ++ ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_decompress: .\n"); ++ ++ if(!skb) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_error:skb_decompress: " ++ "passed in NULL skb, returning ERROR.\n"); ++ if (flags) *flags |= IPCOMP_PARMERROR; ++ return skb; ++ } ++ ++ if(!ips && sysctl_ipsec_inbound_policy_check) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_error:skb_decompress: " ++ "passed in NULL ipsec_sa needed for comp alg, returning ERROR.\n"); ++ if (flags) *flags |= IPCOMP_PARMERROR; ++ return skb; ++ } ++ ++ if (!flags) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_error:skb_decompress: " ++ "passed in NULL flags, returning ERROR.\n"); ++ ipsec_kfree_skb(skb); ++ return NULL; ++ } ++ ++#ifdef NET_21 ++ oiph = skb->nh.iph; ++#else /* NET_21 */ ++ oiph = skb->ip_hdr; ++#endif /* NET_21 */ ++ ++ iphlen = oiph->ihl << 2; ++ ++ if (oiph->protocol != IPPROTO_COMP) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_error:skb_decompress: " ++ "called with non-IPCOMP packet (protocol=%d)," ++ "skipping decompression.\n", ++ oiph->protocol); ++ *flags |= IPCOMP_PARMERROR; ++ return skb; ++ } ++ ++ if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0) ++ || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi ++ != htons(SADB_X_CALG_DEFLATE)) ++ && sysctl_ipsec_inbound_policy_check ++ && (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_error:skb_decompress: " ++ "called with incompatible IPCOMP packet (flags=%d, " ++ "cpi=%d), ips-compalg=%d, skipping decompression.\n", ++ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags), ++ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi), ++ ips ? ips->ips_encalg : 0); ++ *flags |= IPCOMP_PARMERROR; ++ ++ return skb; ++ } ++ ++ if (ntohs(oiph->frag_off) & ~0x4000) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_error:skb_decompress: " ++ "called with fragmented IPCOMP packet, " ++ "skipping decompression.\n"); ++ *flags |= IPCOMP_PARMERROR; ++ return skb; ++ } ++ ++ /* original compressed payload size */ ++ cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr); ++ ++ zs.zalloc = my_zcalloc; ++ zs.zfree = my_zfree; ++ zs.opaque = 0; ++ ++ zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr); ++ zs.avail_in = cpyldsz; ++ ++ /* Maybe we should be a bit conservative about memory ++ requirements and use inflateInit2 */ ++ /* Beware, that this might make us unable to decompress packets ++ from other implementations - HINT: check PGPnet source code */ ++ /* We want to use inflateInit2 because we don't want the adler ++ header. */ ++ zresult = inflateInit2(&zs, -15); ++ if (zresult != Z_OK) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_error:skb_decompress: " ++ "inflateInit2() returned error %d (%s), " ++ "skipping decompression.\n", ++ zresult, ++ zs.msg ? zs.msg : zError(zresult)); ++ *flags |= IPCOMP_DECOMPRESSIONERROR; ++ ++ return skb; ++ } ++ ++ /* We have no way of knowing the exact length of the resulting ++ decompressed output before we have actually done the decompression. ++ For now, we guess that the packet will not be bigger than the ++ attached ipsec device's mtu or 16260, whichever is biggest. ++ This may be wrong, since the sender's mtu may be bigger yet. ++ XXX This must be dealt with later XXX ++ */ ++ ++ /* max payload size */ ++ pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu) ++ : (65520 - iphlen); ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_decompress: " ++ "max payload size: %d\n", pyldsz); ++ ++ while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) && ++ (nskb = skb_copy_ipcomp(skb, ++ pyldsz - cpyldsz - sizeof(struct ipcomphdr), ++ GFP_ATOMIC)) == NULL) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_error:skb_decompress: " ++ "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), " ++ "trying with less payload size.\n", ++ (int)(pyldsz - cpyldsz - sizeof(struct ipcomphdr))); ++ pyldsz >>=1; ++ } ++ ++ if (!nskb) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_error:skb_decompress: " ++ "unable to allocate memory, dropping packet.\n"); ++ *flags |= IPCOMP_DECOMPRESSIONERROR; ++ inflateEnd(&zs); ++ ++ return skb; ++ } ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { ++ __u8 *c; ++ int i; ++ ++ c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr); ++ for(i = 0; i < cpyldsz; i++, c++) { ++ if(!(i % 16)) { ++ printk(KERN_INFO "skb_decompress: before:"); ++ } ++ printk("%02x ", *c); ++ if(!((i + 1) % 16)) { ++ printk("\n"); ++ } ++ } ++ if(i % 16) { ++ printk("\n"); ++ } ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++#ifdef NET_21 ++ iph = nskb->nh.iph; ++#else /* NET_21 */ ++ iph = nskb->ip_hdr; ++#endif /* NET_21 */ ++ zs.next_out = (char *)iph + iphlen; ++ zs.avail_out = pyldsz; ++ ++ zresult = inflate(&zs, Z_SYNC_FLUSH); ++ ++ /* work around a bug in zlib, which sometimes wants to taste an extra ++ * byte when being used in the (undocumented) raw deflate mode. ++ */ ++ if (zresult == Z_OK && !zs.avail_in && zs.avail_out) { ++ __u8 zerostuff = 0; ++ ++ zs.next_in = &zerostuff; ++ zs.avail_in = 1; ++ zresult = inflate(&zs, Z_FINISH); ++ } ++ ++ inflateEnd(&zs); ++ if (zresult != Z_STREAM_END) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_error:skb_decompress: " ++ "inflate() returned error %d (%s), " ++ "skipping decompression.\n", ++ zresult, ++ zs.msg ? zs.msg : zError(zresult)); ++ *flags |= IPCOMP_DECOMPRESSIONERROR; ++ ipsec_kfree_skb(nskb); ++ ++ return skb; ++ } ++ ++ /* Update IP header */ ++ /* resulting decompressed size */ ++ pyldsz -= zs.avail_out; ++ iph->tot_len = htons(iphlen + pyldsz); ++ iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh; ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_decompress: " ++ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n", ++ ips ? ntohl(ips->ips_said.spi) : 0, ++ ips ? ntohl(ips->ips_said.spi) & 0x0000ffff : 0, ++ ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi), ++ cpyldsz, ++ pyldsz, ++ iph->protocol); ++ ++#if 1 /* XXX checksum is done by ipsec_rcv ? */ ++ iph->check = 0; ++ iph->check = ip_fast_csum((char*) iph, iph->ihl); ++#endif ++ ++ /* Update skb length/tail by "unputting" the unused data area */ ++ skb_put(nskb, -zs.avail_out); ++ ++ ipsec_kfree_skb(skb); ++ ++ if (iph->protocol == IPPROTO_COMP) ++ { ++#ifdef CONFIG_IPSEC_DEBUG ++ if(sysctl_ipsec_debug_ipcomp) ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_decompress: " ++ "Eh? inner packet is also compressed, dropping.\n"); ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ ipsec_kfree_skb(nskb); ++ return NULL; ++ } ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { ++ __u8 *c; ++ int i; ++ ++ c = (__u8*)iph + iphlen; ++ for(i = 0; i < pyldsz; i++, c++) { ++ if(!(i % 16)) { ++ printk(KERN_INFO "skb_decompress: result:"); ++ } ++ printk("%02x ", *c); ++ if(!((i + 1) % 16)) { ++ printk("\n"); ++ } ++ } ++ if(i % 16) { ++ printk("\n"); ++ } ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ return nskb; ++} ++ ++ ++/* this is derived from skb_copy() in linux 2.2.14 */ ++/* May be incompatible with other kernel versions!! */ ++static ++struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask) ++{ ++ struct sk_buff *n; ++ struct iphdr *iph; ++ unsigned long offset; ++ unsigned int iphlen; ++ ++ if(!skb) { ++ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, ++ "klips_debug:skb_copy_ipcomp: " ++ "passed in NULL skb, returning NULL.\n"); ++ return NULL; ++ } ++ ++ /* ++ * Allocate the copy buffer ++ */ ++ ++#ifdef NET_21 ++ iph = skb->nh.iph; ++#else /* NET_21 */ ++ iph = skb->ip_hdr; ++#endif /* NET_21 */ ++ if (!iph) return NULL; ++ iphlen = iph->ihl << 2; ++ ++ n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask); ++ if(n==NULL) ++ return NULL; ++ ++ /* ++ * Shift between the two data areas in bytes ++ */ ++ ++ offset=n->head-skb->head; ++ ++ /* Set the data pointer */ ++ skb_reserve(n,skb->data-skb->head); ++ /* Set the tail pointer and length */ ++ skb_put(n,skb->len+data_growth); ++ /* Copy the bytes up to and including the ip header */ ++ memcpy(n->head, ++ skb->head, ++ ((char *)iph - (char *)skb->head) + iphlen); ++ n->list=NULL; ++ n->next=NULL; ++ n->prev=NULL; ++ n->sk=NULL; ++ n->dev=skb->dev; ++ if (skb->h.raw) ++ n->h.raw=skb->h.raw+offset; ++ else ++ n->h.raw=NULL; ++ n->protocol=skb->protocol; ++#ifdef NET_21 ++ n->csum = 0; ++ n->priority=skb->priority; ++ n->dst=dst_clone(skb->dst); ++ n->nh.raw=skb->nh.raw+offset; ++#ifndef NETDEV_23 ++ n->is_clone=0; ++#endif /* NETDEV_23 */ ++ atomic_set(&n->users, 1); ++ n->destructor = NULL; ++ n->security=skb->security; ++ memcpy(n->cb, skb->cb, sizeof(skb->cb)); ++#ifdef CONFIG_IP_FIREWALL ++ n->fwmark = skb->fwmark; ++#endif ++#else /* NET_21 */ ++ n->link3=NULL; ++ n->when=skb->when; ++ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset); ++ n->saddr=skb->saddr; ++ n->daddr=skb->daddr; ++ n->raddr=skb->raddr; ++ n->seq=skb->seq; ++ n->end_seq=skb->end_seq; ++ n->ack_seq=skb->ack_seq; ++ n->acked=skb->acked; ++ n->free=1; ++ n->arp=skb->arp; ++ n->tries=0; ++ n->lock=0; ++ n->users=0; ++ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv)); ++#endif /* NET_21 */ ++ if (skb->mac.raw) ++ n->mac.raw=skb->mac.raw+offset; ++ else ++ n->mac.raw=NULL; ++#ifndef NETDEV_23 ++ n->used=skb->used; ++#endif /* !NETDEV_23 */ ++ n->pkt_type=skb->pkt_type; ++#ifndef NETDEV_23 ++ n->pkt_bridged=skb->pkt_bridged; ++#endif /* NETDEV_23 */ ++ n->ip_summed=0; ++ n->stamp=skb->stamp; ++#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */ ++#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) ++ n->shapelatency=skb->shapelatency; /* Latency on frame */ ++ n->shapeclock=skb->shapeclock; /* Time it should go out */ ++ n->shapelen=skb->shapelen; /* Frame length in clocks */ ++ n->shapestamp=skb->shapestamp; /* Stamp for shaper */ ++ n->shapepend=skb->shapepend; /* Pending */ ++#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */ ++#endif /* NETDEV_23 */ ++#ifdef CONFIG_HIPPI ++ n->private.ifield=skb->private.ifield; ++#endif /* CONFIG_HIPPI */ ++ ++ return n; ++} +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_ah.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,363 @@ ++/* ++ * processing code for AH ++ * Copyright (C) 2003-2004 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ */ ++ ++char ipsec_ah_c_version[] = "RCSID $Id: ipsec_ah.c,v 1.2 2004/04/06 02:49:25 mcr Exp $"; ++#include ++#include ++ ++#define __NO_VERSION__ ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include ++#include ++#ifdef SPINLOCK ++# ifdef SPINLOCK_23 ++# include /* *lock* */ ++# else /* SPINLOCK_23 */ ++# include /* *lock* */ ++# endif /* SPINLOCK_23 */ ++#endif /* SPINLOCK */ ++#ifdef NET_21 ++# include ++# include ++# define proto_priv cb ++#endif /* NET21 */ ++#include ++#include ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_sa.h" ++ ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_tunnel.h" ++#include "openswan/ipsec_rcv.h" ++#include "openswan/ipsec_xmit.h" ++ ++#include "openswan/ipsec_auth.h" ++ ++#ifdef CONFIG_IPSEC_AH ++#include "openswan/ipsec_ah.h" ++#endif /* CONFIG_IPSEC_AH */ ++ ++#include "openswan/ipsec_proto.h" ++ ++#ifdef CONFIG_IPSEC_DEBUG ++int debug_ah = 0; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++__u32 zeroes[AH_AMAX]; ++ ++#ifdef CONFIG_IPSEC_AH ++enum ipsec_rcv_value ++ipsec_rcv_ah_checks(struct ipsec_rcv_state *irs, ++ struct sk_buff *skb) ++{ ++ int ahminlen; ++ ++ ahminlen = irs->hard_header_len + sizeof(struct iphdr); ++ ++ /* take care not to deref this pointer until we check the minlen though */ ++ irs->protostuff.ahstuff.ahp = (struct ahhdr *) (skb->data + irs->iphlen); ++ ++ if((skb->len < ahminlen+sizeof(struct ahhdr)) || ++ (skb->len < ahminlen+(irs->protostuff.ahstuff.ahp->ah_hl << 2))) { ++ KLIPS_PRINT(debug_rcv & DB_RX_INAU, ++ "klips_debug:ipsec_rcv: " ++ "runt ah packet of skb->len=%d received from %s, dropped.\n", ++ skb->len, ++ irs->ipsaddr_txt); ++ if(irs->stats) { ++ irs->stats->rx_errors++; ++ } ++ return IPSEC_RCV_BADLEN; ++ } ++ ++ irs->said.spi = irs->protostuff.ahstuff.ahp->ah_spi; ++ ++ /* XXX we only support the one 12-byte authenticator for now */ ++ if(irs->protostuff.ahstuff.ahp->ah_hl != ((AHHMAC_HASHLEN+AHHMAC_RPLLEN) >> 2)) { ++ KLIPS_PRINT(debug_rcv & DB_RX_INAU, ++ "klips_debug:ipsec_rcv: " ++ "bad authenticator length %ld, expected %lu from %s.\n", ++ (long)(irs->protostuff.ahstuff.ahp->ah_hl << 2), ++ (unsigned long) sizeof(struct ahhdr), ++ irs->ipsaddr_txt); ++ if(irs->stats) { ++ irs->stats->rx_errors++; ++ } ++ return IPSEC_RCV_BADLEN; ++ } ++ ++ return IPSEC_RCV_OK; ++} ++ ++ ++enum ipsec_rcv_value ++ipsec_rcv_ah_setup_auth(struct ipsec_rcv_state *irs, ++ struct sk_buff *skb, ++ __u32 *replay, ++ unsigned char **authenticator) ++{ ++ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp; ++ ++ *replay = ntohl(ahp->ah_rpl); ++ *authenticator = ahp->ah_data; ++ ++ return IPSEC_RCV_OK; ++} ++ ++enum ipsec_rcv_value ++ipsec_rcv_ah_authcalc(struct ipsec_rcv_state *irs, ++ struct sk_buff *skb) ++{ ++ struct auth_alg *aa; ++ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp; ++ union { ++ MD5_CTX md5; ++ SHA1_CTX sha1; ++ } tctx; ++ struct iphdr ipo; ++ int ahhlen; ++ ++ aa = irs->authfuncs; ++ ++ /* copy the initialized keying material */ ++ memcpy(&tctx, irs->ictx, irs->ictx_len); ++ ++ ipo = *irs->ipp; ++ ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */ ++ ipo.frag_off = 0; ++ ipo.ttl = 0; ++ ipo.check = 0; ++ ++ ++ /* do the sanitized header */ ++ (*aa->update)((void*)&tctx, (caddr_t)&ipo, sizeof(struct iphdr)); ++ ++ /* XXX we didn't do the options here! */ ++ ++ /* now do the AH header itself */ ++ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2); ++ (*aa->update)((void*)&tctx, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN); ++ ++ /* now, do some zeroes */ ++ (*aa->update)((void*)&tctx, (caddr_t)zeroes, AHHMAC_HASHLEN); ++ ++ /* finally, do the packet contents themselves */ ++ (*aa->update)((void*)&tctx, ++ (caddr_t)skb->data + irs->iphlen + ahhlen, ++ skb->len - irs->iphlen - ahhlen); ++ ++ (*aa->final)(irs->hash, (void *)&tctx); ++ ++ memcpy(&tctx, irs->octx, irs->octx_len); ++ ++ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen); ++ (*aa->final)(irs->hash, (void *)&tctx); ++ ++ return IPSEC_RCV_OK; ++} ++ ++enum ipsec_rcv_value ++ipsec_rcv_ah_decap(struct ipsec_rcv_state *irs) ++{ ++ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp; ++ struct sk_buff *skb; ++ int ahhlen; ++ ++ skb=irs->skb; ++ ++ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2); ++ ++ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - ahhlen); ++ irs->next_header = ahp->ah_nh; ++ ++ /* ++ * move the IP header forward by the size of the AH header, which ++ * will remove the the AH header from the packet. ++ */ ++ memmove((void *)(skb->data + ahhlen), ++ (void *)(skb->data), irs->iphlen); ++ ++ ipsec_rcv_dmp("ah postmove", skb->data, skb->len); ++ ++ /* skb_pull below, will move up by ahhlen */ ++ ++ /* XXX not clear how this can happen, as the message indicates */ ++ if(skb->len < ahhlen) { ++ printk(KERN_WARNING ++ "klips_error:ipsec_rcv: " ++ "tried to skb_pull ahhlen=%d, %d available. This should never happen, please report.\n", ++ ahhlen, ++ (int)(skb->len)); ++ return IPSEC_RCV_DECAPFAIL; ++ } ++ skb_pull(skb, ahhlen); ++ ++ irs->ipp = (struct iphdr *)skb->data; ++ ++ ipsec_rcv_dmp("ah postpull", skb->data, skb->len); ++ ++ return IPSEC_RCV_OK; ++} ++ ++enum ipsec_xmit_value ++ipsec_xmit_ah_setup(struct ipsec_xmit_state *ixs) ++{ ++ struct iphdr ipo; ++ struct ahhdr *ahp; ++ __u8 hash[AH_AMAX]; ++ union { ++#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ MD5_CTX md5; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ SHA1_CTX sha1; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++ } tctx; ++ unsigned char *dat = (unsigned char *)ixs->iph; ++ ++ ahp = (struct ahhdr *)(dat + ixs->iphlen); ++ ahp->ah_spi = ixs->ipsp->ips_said.spi; ++ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq)); ++ ahp->ah_rv = 0; ++ ahp->ah_nh = ixs->iph->protocol; ++ ahp->ah_hl = (sizeof(struct ahhdr) >> 2) - sizeof(__u64)/sizeof(__u32); ++ ixs->iph->protocol = IPPROTO_AH; ++ ipsec_xmit_dmp("ahp", (char*)ahp, sizeof(*ahp)); ++ ++ ipo = *ixs->iph; ++ ipo.tos = 0; ++ ipo.frag_off = 0; ++ ipo.ttl = 0; ++ ipo.check = 0; ++ ipsec_xmit_dmp("ipo", (char*)&ipo, sizeof(ipo)); ++ ++ switch(ixs->ipsp->ips_authalg) { ++#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ case AH_MD5: ++ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx; ++ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr)); ++ ipsec_xmit_dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, (unsigned char *)ahp, ++ sizeof(struct ahhdr) - sizeof(ahp->ah_data)); ++ ipsec_xmit_dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN); ++ ipsec_xmit_dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, dat + ixs->iphlen + sizeof(struct ahhdr), ++ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr)); ++ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Final(hash, &tctx.md5); ++ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash)); ++ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx; ++ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, hash, AHMD596_ALEN); ++ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Final(hash, &tctx.md5); ++ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash)); ++ ++ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN); ++ ++ /* paranoid */ ++ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5)); ++ memset((caddr_t)hash, 0, sizeof(*hash)); ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ case AH_SHA: ++ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx; ++ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr)); ++ SHA1Update(&tctx.sha1, (unsigned char *)ahp, sizeof(struct ahhdr) - sizeof(ahp->ah_data)); ++ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN); ++ SHA1Update(&tctx.sha1, dat + ixs->iphlen + sizeof(struct ahhdr), ++ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr)); ++ SHA1Final(hash, &tctx.sha1); ++ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx; ++ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); ++ SHA1Final(hash, &tctx.sha1); ++ ++ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN); ++ ++ /* paranoid */ ++ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1)); ++ memset((caddr_t)hash, 0, sizeof(*hash)); ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_AH_BADALG; ++ } ++#ifdef NET_21 ++ ixs->skb->h.raw = (unsigned char*)ahp; ++#endif /* NET_21 */ ++ ++ return IPSEC_XMIT_OK; ++} ++ ++struct xform_functions ah_xform_funcs[]={ ++ { rcv_checks: ipsec_rcv_ah_checks, ++ rcv_setup_auth: ipsec_rcv_ah_setup_auth, ++ rcv_calc_auth: ipsec_rcv_ah_authcalc, ++ rcv_decrypt: ipsec_rcv_ah_decap, ++ ++ xmit_setup: ipsec_xmit_ah_setup, ++ xmit_headroom: sizeof(struct ahhdr), ++ xmit_needtailroom: 0, ++ }, ++}; ++ ++struct inet_protocol ah_protocol = ++{ ++ ipsec_rcv, /* AH handler */ ++ NULL, /* TUNNEL error control */ ++#ifdef NETDEV_25 ++ 1, /* no policy */ ++#else ++ 0, /* next */ ++ IPPROTO_AH, /* protocol ID */ ++ 0, /* copy */ ++ NULL, /* data */ ++ "AH" /* name */ ++#endif ++}; ++ ++#endif /* CONFIG_IPSEC_AH */ ++ ++/* ++ * $Log: ipsec_ah.c,v $ ++ * Revision 1.2 2004/04/06 02:49:25 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_alg.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,953 @@ ++/* ++ * Modular extensions service and registration functions ++ * ++ * Author: JuanJo Ciarlante ++ * ++ * Version: 0.8.1 ++ * ++ * ipsec_alg.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ */ ++#ifdef CONFIG_IPSEC_ALG ++#define __NO_VERSION__ ++#include ++#include /* printk() */ ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include ++#include ++#include ++#include ++#include /* memcmp() */ ++#include /* get_random_bytes() */ ++#include /* error codes */ ++#ifdef SPINLOCK ++# ifdef SPINLOCK_23 ++# include /* *lock* */ ++# else /* SPINLOCK_23 */ ++# include /* *lock* */ ++# endif /* SPINLOCK_23 */ ++#endif /* SPINLOCK */ ++#ifdef NET_21 ++# include ++# include ++# define proto_priv cb ++#endif /* NET21 */ ++#include "openswan/ipsec_param.h" ++#include ++#include "openswan/ipsec_sa.h" ++#include "openswan/radij.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_tunnel.h" ++#include "openswan/ipsec_rcv.h" ++#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) ++# include "openswan/ipsec_ah.h" ++#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */ ++#ifdef CONFIG_IPSEC_ESP ++# include "openswan/ipsec_esp.h" ++#endif /* !CONFIG_IPSEC_ESP */ ++#ifdef CONFIG_IPSEC_IPCOMP ++# include "openswan/ipcomp.h" ++#endif /* CONFIG_IPSEC_COMP */ ++ ++#include ++#include ++ ++#include "openswan/ipsec_alg.h" ++ ++#ifndef CONFIG_IPSEC_ALG ++#error This file _MUST_ be compiled with CONFIG_IPSEC_ALG enabled ! ++#endif ++#if SADB_EALG_MAX < 255 ++#warning Compiling with limited ESP support ( SADB_EALG_MAX < 256 ) ++#endif ++ ++static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED; ++#define IPSEC_ALG_HASHSZ 16 /* must be power of 2, even 2^0=1 */ ++static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ]; ++ ++/* Old gcc's will fail here */ ++#define barf_out(fmt, args...) do { printk(KERN_ERR "%s: (%s) " fmt, __FUNCTION__, ixt->ixt_name , ## args)\ ++ ; goto out; } while(0) ++ ++/* ++ * Must be already protected by lock ++ */ ++static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) { ++ if (ixt->ixt_module) ++ __MOD_INC_USE_COUNT(ixt->ixt_module); ++ atomic_inc(&ixt->ixt_refcnt); ++} ++static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) { ++ atomic_dec(&ixt->ixt_refcnt); ++ if (ixt->ixt_module) ++ __MOD_DEC_USE_COUNT(ixt->ixt_module); ++} ++/* ++ * simple hash function, optimized for 0-hash (1 list) special ++ * case ++ */ ++#if IPSEC_ALG_HASHSZ > 1 ++static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) { ++ return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1)); ++} ++#else ++#define ipsec_alg_hashfn(x,y) (0) ++#endif ++ ++/***************************************************************** ++ * ++ * INTERNAL table handling: insert, delete, find ++ * ++ *****************************************************************/ ++ ++/* ++ * hash table initialization, called from ipsec_alg_init() ++ */ ++static void ipsec_alg_hash_init(void) { ++ struct list_head *head = ipsec_alg_hash_table; ++ int i = IPSEC_ALG_HASHSZ; ++ do { ++ INIT_LIST_HEAD(head); ++ head++; ++ i--; ++ } while (i); ++} ++/* ++ * hash list lookup by {alg_type, alg_id} and table head, ++ * must be already protected by lock ++ */ ++static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) { ++ struct list_head *p; ++ struct ipsec_alg *ixt=NULL; ++ for (p=head->next; p!=head; p=p->next) { ++ ixt = list_entry(p, struct ipsec_alg, ixt_list); ++ if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) { ++ goto out; ++ } ++ } ++ ixt=NULL; ++out: ++ return ixt; ++} ++/* ++ * inserts (in front) a new entry in hash table, ++ * called from ipsec_alg_register() when new algorithm is registered. ++ */ ++static int ipsec_alg_insert(struct ipsec_alg *ixt) { ++ int ret=-EINVAL; ++ unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id); ++ struct list_head *head= ipsec_alg_hash_table + hashval; ++ struct ipsec_alg *ixt_cur; ++ /* new element must be virgin ... */ ++ if (ixt->ixt_list.next != &ixt->ixt_list || ++ ixt->ixt_list.prev != &ixt->ixt_list) { ++ printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" " ++ "list head not initialized\n", ++ ixt->ixt_name); ++ return ret; ++ } ++ write_lock_bh(&ipsec_alg_lock); ++ ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head); ++ /* if previous (current) ipsec_alg found check excl flag of _anyone_ */ ++ if (ixt_cur && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL)) ++ barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. " ++ "Not loaded (ret=%d).\n", ++ ixt->ixt_alg_type, ++ ixt->ixt_alg_id, ret=-EEXIST); ++ list_add(&ixt->ixt_list, head); ++ ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED; ++ ret=0; ++out: ++ write_unlock_bh(&ipsec_alg_lock); ++ return ret; ++} ++/* ++ * deletes an existing entry in hash table, ++ * called from ipsec_alg_unregister() when algorithm is unregistered. ++ */ ++static int ipsec_alg_delete(struct ipsec_alg *ixt) { ++ write_lock_bh(&ipsec_alg_lock); ++ list_del(&ixt->ixt_list); ++ write_unlock_bh(&ipsec_alg_lock); ++ return 0; ++} ++/* ++ * here @user context (read-only when @kernel bh context) ++ * -> no bh disabling ++ * ++ * called from ipsec_sa_init() -> ipsec_alg_sa_init() ++ */ ++static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id) { ++ unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id); ++ struct list_head *head= ipsec_alg_hash_table + hashval; ++ struct ipsec_alg *ixt; ++ read_lock(&ipsec_alg_lock); ++ ixt=__ipsec_alg_find(alg_type, alg_id, head); ++ if (ixt) __ipsec_alg_usage_inc(ixt); ++ read_unlock(&ipsec_alg_lock); ++ return ixt; ++} ++ ++static void ipsec_alg_put(struct ipsec_alg *ixt) { ++ __ipsec_alg_usage_dec((struct ipsec_alg *)ixt); ++} ++ ++/***************************************************************** ++ * ++ * INTERFACE for ENC services: key creation, encrypt function ++ * ++ *****************************************************************/ ++ ++/* ++ * main encrypt service entry point ++ * called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and ++ * ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT ++ */ ++int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat, int ilen, const __u8 * iv, int encrypt) { ++ int ret; ++ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc; ++ KLIPS_PRINT(debug_rcv||debug_tunnel, ++ "klips_debug:ipsec_alg_esp_encrypt: " ++ "entering with encalg=%d, ixt_e=%p\n", ++ sa_p->ips_encalg, ixt_e); ++ if (!ixt_e) { ++ KLIPS_PRINT(debug_rcv||debug_tunnel, ++ "klips_debug:ipsec_alg_esp_encrypt: " ++ "NULL ipsec_alg_enc object\n"); ++ return -1; ++ } ++ KLIPS_PRINT(debug_rcv||debug_tunnel, ++ "klips_debug:ipsec_alg_esp_encrypt: " ++ "calling cbc_encrypt encalg=%d " ++ "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n", ++ sa_p->ips_encalg, ++ sa_p->ips_key_e, idat, ilen, iv, encrypt); ++ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat, ilen, iv, encrypt); ++ KLIPS_PRINT(debug_rcv||debug_tunnel, ++ "klips_debug:ipsec_alg_esp_encrypt: " ++ "returned ret=%d\n", ++ ret); ++ return ret; ++} ++/* ++ * encryption key context creation function ++ * called from pfkey_v2_parser.c:pfkey_ips_init() ++ */ ++int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) { ++ int ret=-EINVAL; ++ int keyminbits, keymaxbits; ++ caddr_t ekp; ++ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:ipsec_alg_enc_key_create: " ++ "entering with encalg=%d ixt_e=%p\n", ++ sa_p->ips_encalg, ixt_e); ++ if (!ixt_e) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:ipsec_alg_enc_key_create: " ++ "NULL ipsec_alg_enc object\n"); ++ return -EPROTO; ++ } ++ ++ /* ++ * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo ++ */ ++ switch(ixt_e->ixt_alg_id) { ++ case ESP_3DES: ++ keyminbits=keymaxbits=192;break; ++ case ESP_DES: ++ keyminbits=keymaxbits=64;break; ++ default: ++ keyminbits=ixt_e->ixt_keyminbits; ++ keymaxbits=ixt_e->ixt_keymaxbits; ++ } ++ if(sa_p->ips_key_bits_eips_key_bits_e>keymaxbits) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:ipsec_alg_enc_key_create: " ++ "incorrect encryption key size for id=%d: %d bits -- " ++ "must be between %d,%d bits\n" /*octets (bytes)\n"*/, ++ ixt_e->ixt_alg_id, ++ sa_p->ips_key_bits_e, keyminbits, keymaxbits); ++ ret=-EINVAL; ++ goto ixt_out; ++ } ++ /* save encryption key pointer */ ++ ekp = sa_p->ips_key_e; ++ ++ ++ if (ixt_e->ixt_e_new_key) { ++ sa_p->ips_key_e = ixt_e->ixt_e_new_key(ixt_e, ++ ekp, sa_p->ips_key_bits_e/8); ++ ret = (sa_p->ips_key_e)? 0 : -EINVAL; ++ } else { ++ if((sa_p->ips_key_e = (caddr_t) ++ kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size), ++ GFP_ATOMIC)) == NULL) { ++ ret=-ENOMEM; ++ goto ixt_out; ++ } ++ /* zero-out key_e */ ++ memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size); ++ ++ /* I cast here to allow more decoupling in alg module */ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:ipsec_alg_enc_key_create: about to call:" ++ "set_key(key_e=%p, ekp=%p, key_size=%d)\n", ++ (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8); ++ ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8); ++ } ++ /* paranoid */ ++ memset(ekp, 0, sa_p->ips_key_bits_e/8); ++ kfree(ekp); ++ixt_out: ++ return ret; ++} ++ ++/*************************************************************** ++ * ++ * INTERFACE for AUTH services: key creation, hash functions ++ * ++ ***************************************************************/ ++ ++/* ++ * auth key context creation function ++ * called from pfkey_v2_parser.c:pfkey_ips_init() ++ */ ++int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) { ++ int ret=-EINVAL; ++ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth; ++ int keyminbits, keymaxbits; ++ unsigned char *akp; ++ unsigned int aks; ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:ipsec_alg_auth_key_create: " ++ "entering with authalg=%d ixt_a=%p\n", ++ sa_p->ips_authalg, ixt_a); ++ if (!ixt_a) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:ipsec_alg_auth_key_create: " ++ "NULL ipsec_alg_auth object\n"); ++ return -EPROTO; ++ } ++ keyminbits=ixt_a->ixt_keyminbits; ++ keymaxbits=ixt_a->ixt_keymaxbits; ++ if(sa_p->ips_key_bits_aips_key_bits_a>keymaxbits) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:ipsec_alg_auth_key_create: incorrect auth" ++ "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/, ++ sa_p->ips_key_bits_a, keyminbits, keymaxbits); ++ ret=-EINVAL; ++ goto ixt_out; ++ } ++ /* save auth key pointer */ ++ sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */ ++ akp = sa_p->ips_key_a; ++ aks = sa_p->ips_key_a_size; ++ ++ /* will hold: 2 ctx and a blocksize buffer: kb */ ++ sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size; ++ if((sa_p->ips_key_a = ++ (caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) { ++ ret=-ENOMEM; ++ goto ixt_out; ++ } ++ ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */ ++ ret=0; ++ memset(akp, 0, aks); ++ kfree(akp); ++ ++ixt_out: ++ return ret; ++} ++ ++ ++int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) { ++ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth; ++ if (!ixt_a) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:ipsec_sa_esp_hash: " ++ "NULL ipsec_alg_auth object\n"); ++ return -EPROTO; ++ } ++ KLIPS_PRINT(debug_tunnel|debug_rcv, ++ "klips_debug:ipsec_sa_esp_hash: " ++ "hashing %p (%d bytes) to %p (%d bytes)\n", ++ espp, len, ++ hash, hashlen); ++ ixt_a->ixt_a_hmac_hash(ixt_a, ++ sa_p->ips_key_a, ++ espp, len, ++ hash, hashlen); ++ return 0; ++} ++ ++/*************************************************************** ++ * ++ * INTERFACE for module loading,testing, and unloading ++ * ++ ***************************************************************/ ++ ++/* validation for registering (enc) module */ ++static int check_enc(struct ipsec_alg_enc *ixt) { ++ int ret=-EINVAL; ++ if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_EALG_MAX) ++ barf_out("invalid alg_id=%d >= %d\n", ixt->ixt_alg_id, SADB_EALG_MAX); ++ if (ixt->ixt_blocksize==0) /* || ixt->ixt_blocksize%2) need for ESP_NULL */ ++ barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize); ++ if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_e_keylen==0) ++ goto zero_key_ok; ++ if (ixt->ixt_keyminbits==0) ++ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits); ++ if (ixt->ixt_keymaxbits==0) ++ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits); ++ if (ixt->ixt_e_keylen==0) ++ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen); ++zero_key_ok: ++ if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL) ++ barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size); ++ if (ixt->ixt_e_cbc_encrypt==NULL) ++ barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n"); ++ ret=0; ++out: ++ return ret; ++} ++ ++/* validation for registering (auth) module */ ++static int check_auth(struct ipsec_alg_auth *ixt) ++{ ++ int ret=-EINVAL; ++ if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_AALG_MAX) ++ barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n", ixt->ixt_alg_id, SADB_AALG_MAX); ++ if (ixt->ixt_blocksize==0 || ixt->ixt_blocksize%2) ++ barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize); ++ if (ixt->ixt_blocksize>AH_BLKLEN_MAX) ++ barf_out(KERN_ERR "sorry blocksize=%d > %d. " ++ "Please increase AH_BLKLEN_MAX and recompile\n", ++ ixt->ixt_blocksize, ++ AH_BLKLEN_MAX); ++ if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_a_keylen==0) ++ goto zero_key_ok; ++ if (ixt->ixt_keyminbits==0) ++ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits); ++ if (ixt->ixt_keymaxbits==0) ++ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits); ++ if (ixt->ixt_keymaxbits!=ixt->ixt_keyminbits) ++ barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n"); ++ if (ixt->ixt_a_keylen==0) ++ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen); ++zero_key_ok: ++ if (ixt->ixt_a_ctx_size==0) ++ barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size); ++ if (ixt->ixt_a_hmac_set_key==NULL) ++ barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n"); ++ if (ixt->ixt_a_hmac_hash==NULL) ++ barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n"); ++ ret=0; ++out: ++ return ret; ++} ++ ++/* ++ * Generic (enc, auth) registration entry point ++ */ ++int register_ipsec_alg(struct ipsec_alg *ixt) { ++ int ret=-EINVAL; ++ /* Validation */ ++ if (ixt==NULL) ++ barf_out("NULL ipsec_alg object passed\n"); ++ if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00)) ++ barf_out("incorrect version: %d.%d.%d-%d, " ++ "must be %d.%d.%d[-%d]\n", ++ IPSEC_ALG_VERSION_QUAD(ixt->ixt_version), ++ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION)); ++ switch(ixt->ixt_alg_type) { ++ case IPSEC_ALG_TYPE_AUTH: ++ if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0)) ++ goto out; ++ break; ++ case IPSEC_ALG_TYPE_ENCRYPT: ++ if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0)) ++ goto out; ++ /* ++ * Adapted two lines below: ++ * ivlen == 0 is possible (NULL enc has blocksize==1) ++ * ++ * fixed NULL support by David De Reu ++ */ ++ if (ixt->ixt_ivlen == 0 && ixt->ixt_blocksize > 1) ++ ixt->ixt_ivlen = ixt->ixt_blocksize*8; ++ break; ++ default: ++ barf_out("alg_type=%d not supported\n", ixt->ixt_alg_type); ++ } ++ INIT_LIST_HEAD(&ixt->ixt_list); ++ ret = ipsec_alg_insert(ixt); ++ if (ret<0) ++ barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed." ++ "Not loaded (ret=%d).\n", ++ ixt->ixt_alg_id, ret); ++ ++ ret = pfkey_list_insert_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP])); ++ if (ret==0) { ++ ixt->ixt_state |= IPSEC_ALG_ST_SUPP; ++ /* send register event to userspace */ ++ pfkey_register_reply(SADB_SATYPE_ESP, NULL); ++ } else ++ printk(KERN_ERR "pfkey_list_insert_supported returned %d. " ++ "Loading anyway.\n", ret); ++ ret=0; ++out: ++ return ret; ++} ++ ++/* ++ * unregister ipsec_alg object from own tables, if ++ * success => calls pfkey_list_remove_supported() ++ */ ++int unregister_ipsec_alg(struct ipsec_alg *ixt) { ++ int ret= -EINVAL; ++ switch(ixt->ixt_alg_type) { ++ case IPSEC_ALG_TYPE_AUTH: ++ case IPSEC_ALG_TYPE_ENCRYPT: ++ break; ++ default: ++ /* this is not a typo :) */ ++ barf_out("frog found in list (\"%s\"): ixt_p=NULL\n", ++ ixt->ixt_name); ++ } ++ ++ ret=ipsec_alg_delete(ixt); ++ if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) { ++ ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP; ++ pfkey_list_remove_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP])); ++ /* send register event to userspace */ ++ pfkey_register_reply(SADB_SATYPE_ESP, NULL); ++ } ++ ++out: ++ return ret; ++} ++ ++/* ++ * Must be called from user context ++ * used at module load type for testing algo implementation ++ */ ++static int ipsec_alg_test_encrypt(int enc_alg, int test) { ++ int ret; ++ caddr_t buf = NULL; ++ int iv_size, keysize, key_e_size; ++ struct ipsec_alg_enc *ixt_e; ++ void *tmp_key_e = NULL; ++ #define BUFSZ 1024 ++ #define MARGIN 0 ++ #define test_enc (buf+MARGIN) ++ #define test_dec (test_enc+BUFSZ+MARGIN) ++ #define test_tmp (test_dec+BUFSZ+MARGIN) ++ #define test_key_e (test_tmp+BUFSZ+MARGIN) ++ #define test_iv (test_key_e+key_e_size+MARGIN) ++ #define test_key (test_iv+iv_size+MARGIN) ++ #define test_size (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7) ++ ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg); ++ if (ixt_e==NULL) { ++ KLIPS_PRINT(1, ++ "klips_debug: ipsec_alg_test_encrypt: " ++ "encalg=%d object not found\n", ++ enc_alg); ++ ret=-EINVAL; ++ goto out; ++ } ++ iv_size=ixt_e->ixt_ivlen / 8; ++ key_e_size=ixt_e->ixt_e_ctx_size; ++ keysize=ixt_e->ixt_e_keylen; ++ KLIPS_PRINT(1, ++ "klips_debug: ipsec_alg_test_encrypt: " ++ "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n", ++ enc_alg, iv_size, key_e_size, keysize); ++ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) { ++ ret= -ENOMEM; ++ goto out; ++ } ++ get_random_bytes(test_key, keysize); ++ get_random_bytes(test_iv, iv_size); ++ if (ixt_e->ixt_e_new_key) { ++ tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize); ++ ret = tmp_key_e ? 0 : -EINVAL; ++ } else { ++ tmp_key_e = test_key_e; ++ ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize); ++ } ++ if (ret < 0) ++ goto out; ++ get_random_bytes(test_enc, BUFSZ); ++ memcpy(test_tmp, test_enc, BUFSZ); ++ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1); ++ printk(KERN_INFO ++ "klips_info: ipsec_alg_test_encrypt: " ++ "cbc_encrypt=1 ret=%d\n", ++ ret); ++ ret=memcmp(test_enc, test_tmp, BUFSZ); ++ printk(KERN_INFO ++ "klips_info: ipsec_alg_test_encrypt: " ++ "memcmp(enc, tmp) ret=%d: %s\n", ret, ++ ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" ); ++ memcpy(test_dec, test_enc, BUFSZ); ++ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0); ++ printk(KERN_INFO ++ "klips_info: ipsec_alg_test_encrypt: " ++ "cbc_encrypt=0 ret=%d\n", ret); ++ ret=memcmp(test_dec, test_tmp, BUFSZ); ++ printk(KERN_INFO ++ "klips_info: ipsec_alg_test_encrypt: " ++ "memcmp(dec,tmp) ret=%d: %s\n", ret, ++ ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" ); ++ { ++ /* Shamelessly taken from drivers/md sources O:) */ ++ unsigned long now; ++ int i, count, max=0; ++ int encrypt, speed; ++ for (encrypt=0; encrypt <2;encrypt ++) { ++ for (i = 0; i < 5; i++) { ++ now = jiffies; ++ count = 0; ++ while (jiffies == now) { ++ mb(); ++ ixt_e->ixt_e_cbc_encrypt(ixt_e, ++ tmp_key_e, test_tmp, ++ BUFSZ, test_iv, encrypt); ++ mb(); ++ count++; ++ mb(); ++ } ++ if (count > max) ++ max = count; ++ } ++ speed = max * (HZ * BUFSZ / 1024); ++ printk(KERN_INFO ++ "klips_info: ipsec_alg_test_encrypt: " ++ "%s %s speed=%d KB/s\n", ++ ixt_e->ixt_name, ++ encrypt? "encrypt": "decrypt", speed); ++ } ++ } ++out: ++ if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e); ++ if (buf) kfree(buf); ++ if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e); ++ return ret; ++ #undef test_enc ++ #undef test_dec ++ #undef test_tmp ++ #undef test_key_e ++ #undef test_iv ++ #undef test_key ++ #undef test_size ++} ++ ++/* ++ * Must be called from user context ++ * used at module load type for testing algo implementation ++ */ ++static int ipsec_alg_test_auth(int auth_alg, int test) { ++ int ret; ++ caddr_t buf = NULL; ++ int blocksize, keysize, key_a_size; ++ struct ipsec_alg_auth *ixt_a; ++ #define BUFSZ 1024 ++ #define MARGIN 0 ++ #define test_auth (buf+MARGIN) ++ #define test_key_a (test_auth+BUFSZ+MARGIN) ++ #define test_key (test_key_a+key_a_size+MARGIN) ++ #define test_hash (test_key+keysize+MARGIN) ++ #define test_size (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4) ++ ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg); ++ if (ixt_a==NULL) { ++ KLIPS_PRINT(1, ++ "klips_debug: ipsec_alg_test_auth: " ++ "encalg=%d object not found\n", ++ auth_alg); ++ ret=-EINVAL; ++ goto out; ++ } ++ blocksize=ixt_a->ixt_blocksize; ++ key_a_size=ixt_a->ixt_a_ctx_size; ++ keysize=ixt_a->ixt_a_keylen; ++ KLIPS_PRINT(1, ++ "klips_debug: ipsec_alg_test_auth: " ++ "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n", ++ auth_alg, blocksize, key_a_size, keysize); ++ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) { ++ ret= -ENOMEM; ++ goto out; ++ } ++ get_random_bytes(test_key, keysize); ++ ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize); ++ if (ret < 0 ) ++ goto out; ++ get_random_bytes(test_auth, BUFSZ); ++ ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN); ++ printk(KERN_INFO ++ "klips_info: ipsec_alg_test_auth: " ++ "ret=%d\n", ret); ++ { ++ /* Shamelessly taken from drivers/md sources O:) */ ++ unsigned long now; ++ int i, count, max=0; ++ int speed; ++ for (i = 0; i < 5; i++) { ++ now = jiffies; ++ count = 0; ++ while (jiffies == now) { ++ mb(); ++ ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN); ++ mb(); ++ count++; ++ mb(); ++ } ++ if (count > max) ++ max = count; ++ } ++ speed = max * (HZ * BUFSZ / 1024); ++ printk(KERN_INFO ++ "klips_info: ipsec_alg_test_auth: " ++ "%s hash speed=%d KB/s\n", ++ ixt_a->ixt_name, ++ speed); ++ } ++out: ++ if (buf) kfree(buf); ++ if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a); ++ return ret; ++ #undef test_auth ++ #undef test_key_a ++ #undef test_key ++ #undef test_hash ++ #undef test_size ++} ++ ++int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) { ++ switch(alg_type) { ++ case IPSEC_ALG_TYPE_ENCRYPT: ++ return ipsec_alg_test_encrypt(alg_id, test); ++ break; ++ case IPSEC_ALG_TYPE_AUTH: ++ return ipsec_alg_test_auth(alg_id, test); ++ break; ++ } ++ printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: " ++ "alg_type=%d alg_id=%d\n", ++ alg_type, alg_id); ++ return -EINVAL; ++} ++ ++int ipsec_alg_init(void) { ++ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: " ++ "KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n", ++ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION), ++ SADB_EALG_MAX, SADB_AALG_MAX); ++ /* Initialize tables */ ++ write_lock_bh(&ipsec_alg_lock); ++ ipsec_alg_hash_init(); ++ write_unlock_bh(&ipsec_alg_lock); ++ ++ /* Initialize static algos */ ++ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: " ++ "calling ipsec_alg_static_init()\n"); ++ ++ /* If we are suppose to use our AES, and don't have CryptoAPI enabled... */ ++#if defined(CONFIG_IPSEC_ENC_AES) && CONFIG_IPSEC_ENC_AES && !defined(CONFIG_IPSEC_ENC_AES_MODULE) && !CONFIG_IPSEC_ENC_CRYPTOAPI && !defined(CONFIG_IPSEC_ENC_CRYPTOAPI_MODULE) ++ { ++ extern int ipsec_aes_init(void); ++ ipsec_aes_init(); ++ } ++#endif ++ ++ /* If we are doing CryptoAPI, then init */ ++#if defined(CONFIG_IPSEC_ENC_CRYPTOAPI) && CONFIG_IPSEC_ENC_CRYPTOAPI && !defined(CONFIG_IPSEC_ENC_CRYPTOAPI_MODULE) ++ { ++ extern int ipsec_cryptoapi_init(void); ++ ipsec_cryptoapi_init(); ++ } ++#endif ++ ++ ++ return 0; ++} ++ ++/********************************************** ++ * ++ * INTERFACE for ipsec_sa init and wipe ++ * ++ **********************************************/ ++ ++/* ++ * Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init() ++ */ ++int ipsec_alg_sa_init(struct ipsec_sa *sa_p) { ++ struct ipsec_alg_enc *ixt_e; ++ struct ipsec_alg_auth *ixt_a; ++ ++ /* Only ESP for now ... */ ++ if (sa_p->ips_said.proto != IPPROTO_ESP) ++ return -EPROTONOSUPPORT; ++ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :" ++ "entering for encalg=%d, authalg=%d\n", ++ sa_p->ips_encalg, sa_p->ips_authalg); ++ if ((ixt_e=(struct ipsec_alg_enc *) ++ ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug: ipsec_alg_sa_init() :" ++ "found ipsec_alg (ixt_e=%p) for encalg=%d\n", ++ ixt_e, sa_p->ips_encalg); ++ sa_p->ips_alg_enc=ixt_e; ++ } ++ if ((ixt_a=(struct ipsec_alg_auth *) ++ ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug: ipsec_alg_sa_init() :" ++ "found ipsec_alg (ixt_a=%p) for auth=%d\n", ++ ixt_a, sa_p->ips_authalg); ++ sa_p->ips_alg_auth=ixt_a; ++ } ++ return 0; ++} ++ ++/* ++ * Called from pluto -> ipsec_sa.c:ipsec_sa_delchain() ++ */ ++int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) { ++ struct ipsec_alg *ixt; ++ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :" ++ "unlinking for encalg=%d\n", ++ ixt->ixt_alg_id); ++ ipsec_alg_put(ixt); ++ } ++ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :" ++ "unlinking for authalg=%d\n", ++ ixt->ixt_alg_id); ++ ipsec_alg_put(ixt); ++ } ++ return 0; ++} ++ ++IPSEC_PROCFS_DEBUG_NO_STATIC ++int ++ipsec_xform_get_info(char *buffer, ++ char **start, ++ off_t offset, ++ int length IPSEC_PROC_LAST_ARG) ++{ ++ int len = 0; ++ off_t begin = 0; ++ int i; ++ struct list_head *head; ++ struct ipsec_alg *ixt; ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, ++ "klips_debug:ipsec_tncfg_get_info: " ++ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", ++ buffer, ++ *start, ++ (int)offset, ++ length); ++ ++ for(i = 0, head = ipsec_alg_hash_table; i< IPSEC_ALG_HASHSZ; i++, head++) ++ { ++ struct list_head *p; ++ for (p=head->next; p!=head; p=p->next) ++ { ++ ixt = list_entry(p, struct ipsec_alg, ixt_list); ++ len += ipsec_snprintf(buffer+len, length-len, ++ "VERSION=%d TYPE=%d ID=%d NAME=%s REFCNT=%d ", ++ ixt->ixt_version, ixt->ixt_alg_type, ixt->ixt_alg_id, ++ ixt->ixt_name, ixt->ixt_refcnt); ++ ++ len += ipsec_snprintf(buffer+len, length-len, ++ "STATE=%08x BLOCKSIZE=%d IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ", ++ ixt->ixt_state, ixt->ixt_blocksize, ++ ixt->ixt_ivlen, ixt->ixt_keyminbits, ixt->ixt_keymaxbits); ++ ++ len += ipsec_snprintf(buffer+len, length-len, ++ "IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ", ++ ixt->ixt_ivlen, ixt->ixt_keyminbits, ixt->ixt_keymaxbits); ++ ++ switch(ixt->ixt_alg_type) ++ { ++ case IPSEC_ALG_TYPE_AUTH: ++ { ++ struct ipsec_alg_auth *auth = (struct ipsec_alg_auth *)ixt; ++ ++ len += ipsec_snprintf(buffer+len, length-len, ++ "KEYLEN=%d CTXSIZE=%d AUTHLEN=%d ", ++ auth->ixt_a_keylen, auth->ixt_a_ctx_size, ++ auth->ixt_a_authlen); ++ break; ++ } ++ case IPSEC_ALG_TYPE_ENCRYPT: ++ { ++ struct ipsec_alg_enc *enc = (struct ipsec_alg_enc *)ixt; ++ len += ipsec_snprintf(buffer+len, length-len, ++ "KEYLEN=%d CTXSIZE=%d ", ++ enc->ixt_e_keylen, enc->ixt_e_ctx_size); ++ ++ break; ++ } ++ } ++ ++ len += ipsec_snprintf(buffer+len, length-len, "\n"); ++ } ++ } ++ ++ *start = buffer + (offset - begin); /* Start of wanted data */ ++ len -= (offset - begin); /* Start slop */ ++ if (len > length) ++ len = length; ++ return len; ++} ++ ++ ++/* ++ * As the author of this module, I ONLY ALLOW using it from ++ * GPL (or same LICENSE TERMS as kernel source) modules. ++ * ++ * In respect to hardware crypto engines this means: ++ * * Closed-source device drivers ARE NOT ALLOWED to use ++ * this interface. ++ * * Closed-source VHDL/Verilog firmware running on ++ * the crypto hardware device IS ALLOWED to use this interface ++ * via a GPL (or same LICENSE TERMS as kernel source) device driver. ++ * --Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording) ++ */ ++ ++/* ++ * These symbols can only be used from GPL modules ++ * for now, I'm disabling this because it creates false ++ * symbol problems for old modutils. ++ */ ++ ++/* #ifndef EXPORT_SYMBOL_GPL */ ++#undef EXPORT_SYMBOL_GPL ++#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL ++/* #endif */ ++EXPORT_SYMBOL_GPL(register_ipsec_alg); ++EXPORT_SYMBOL_GPL(unregister_ipsec_alg); ++EXPORT_SYMBOL_GPL(ipsec_alg_test); ++#endif /* CONFIG_IPSEC_ALG */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,263 @@ ++/* ++ * ipsec_alg AES cipher stubs ++ * ++ * Author: JuanJo Ciarlante ++ * ++ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * Fixes by: ++ * PK: Pawel Krawczyk ++ * Fixes list: ++ * PK: make XCBC comply with latest draft (keylength) ++ * ++ */ ++#include ++#include ++ ++/* ++ * special case: ipsec core modular with this static algo inside: ++ * must avoid MODULE magic for this file ++ */ ++#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_AES ++#undef MODULE ++#endif ++ ++#include ++#include ++ ++#include /* printk() */ ++#include /* error codes */ ++#include /* size_t */ ++#include ++ ++/* Check if __exit is defined, if not null it */ ++#ifndef __exit ++#define __exit ++#endif ++ ++/* Low freeswan header coupling */ ++#include "openswan/ipsec_alg.h" ++#include "crypto/aes_cbc.h" ++ ++#define CONFIG_IPSEC_ALG_AES_MAC 1 ++ ++#define AES_CONTEXT_T aes_context ++MODULE_AUTHOR("JuanJo Ciarlante "); ++static int debug=0; ++MODULE_PARM(debug, "i"); ++static int test=0; ++MODULE_PARM(test, "i"); ++static int excl=0; ++MODULE_PARM(excl, "i"); ++static int keyminbits=0; ++MODULE_PARM(keyminbits, "i"); ++static int keymaxbits=0; ++MODULE_PARM(keymaxbits, "i"); ++ ++#if CONFIG_IPSEC_ALG_AES_MAC ++#include "crypto/aes_xcbc_mac.h" ++ ++/* ++ * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt). ++ * We use 9 for non-modular algorithm and none for modular, thus ++ * forcing user to specify one on module load. -kravietz ++ */ ++#ifdef MODULE ++static int auth_id=0; ++#else ++static int auth_id=9; ++#endif ++MODULE_PARM(auth_id, "i"); ++#endif ++ ++#define ESP_AES 12 /* truely _constant_ :) */ ++ ++/* 128, 192 or 256 */ ++#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */ ++#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */ ++#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */ ++ ++/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt ++ * -kravietz ++ */ ++#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */ ++#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */ ++ ++static int _aes_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) { ++ int ret; ++ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e; ++ ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL; ++ if (debug > 0) ++ printk(KERN_DEBUG "klips_debug:_aes_set_key:" ++ "ret=%d key_e=%p key=%p keysize=%d\n", ++ ret, key_e, key, keysize); ++ return ret; ++} ++static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { ++ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e; ++ if (debug > 0) ++ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:" ++ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n", ++ key_e, in, ilen, iv, encrypt); ++ return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt); ++} ++#if CONFIG_IPSEC_ALG_AES_MAC ++static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) { ++ aes_context_mac *ctxm=(aes_context_mac *)key_a; ++ return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL; ++} ++static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) { ++ int ret; ++ char hash_buf[16]; ++ aes_context_mac *ctxm=(aes_context_mac *)key_a; ++ ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf); ++ memcpy(hash, hash_buf, hashlen); ++ return ret; ++} ++static struct ipsec_alg_auth ipsec_alg_AES_MAC = { ++ ixt_version: IPSEC_ALG_VERSION, ++ ixt_module: THIS_MODULE, ++ ixt_refcnt: ATOMIC_INIT(0), ++ ixt_alg_type: IPSEC_ALG_TYPE_AUTH, ++ ixt_alg_id: 0, ++ ixt_name: "aes_mac", ++ ixt_blocksize: ESP_AES_MAC_BLK_LEN, ++ ixt_keyminbits: ESP_AES_MAC_KEY_SZ*8, ++ ixt_keymaxbits: ESP_AES_MAC_KEY_SZ*8, ++ ixt_a_keylen: ESP_AES_MAC_KEY_SZ, ++ ixt_a_ctx_size: sizeof(aes_context_mac), ++ ixt_a_hmac_set_key: _aes_mac_set_key, ++ ixt_a_hmac_hash:_aes_mac_hash, ++}; ++#endif /* CONFIG_IPSEC_ALG_AES_MAC */ ++static struct ipsec_alg_enc ipsec_alg_AES = { ++ ixt_version: IPSEC_ALG_VERSION, ++ ixt_module: THIS_MODULE, ++ ixt_refcnt: ATOMIC_INIT(0), ++ ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT, ++ ixt_alg_id: ESP_AES, ++ ixt_name: "aes", ++ ixt_blocksize: ESP_AES_CBC_BLK_LEN, ++ ixt_keyminbits: ESP_AES_KEY_SZ_MIN*8, ++ ixt_keymaxbits: ESP_AES_KEY_SZ_MAX*8, ++ ixt_e_keylen: ESP_AES_KEY_SZ_MAX, ++ ixt_e_ctx_size: sizeof(AES_CONTEXT_T), ++ ixt_e_set_key: _aes_set_key, ++ ixt_e_cbc_encrypt:_aes_cbc_encrypt, ++}; ++ ++#if defined(CONFIG_IPSEC_ENC_AES_MODULE) ++IPSEC_ALG_MODULE_INIT_MOD( ipsec_aes_init ) ++#else ++IPSEC_ALG_MODULE_INIT_STATIC( ipsec_aes_init ) ++#endif ++{ ++ int ret, test_ret; ++ ++ if (keyminbits) ++ ipsec_alg_AES.ixt_keyminbits=keyminbits; ++ if (keymaxbits) { ++ ipsec_alg_AES.ixt_keymaxbits=keymaxbits; ++ if (keymaxbits*8>ipsec_alg_AES.ixt_keymaxbits) ++ ipsec_alg_AES.ixt_e_keylen=keymaxbits*8; ++ } ++ if (excl) ipsec_alg_AES.ixt_state |= IPSEC_ALG_ST_EXCL; ++ ret=register_ipsec_alg_enc(&ipsec_alg_AES); ++ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", ++ ipsec_alg_AES.ixt_alg_type, ++ ipsec_alg_AES.ixt_alg_id, ++ ipsec_alg_AES.ixt_name, ++ ret); ++ if (ret==0 && test) { ++ test_ret=ipsec_alg_test( ++ ipsec_alg_AES.ixt_alg_type, ++ ipsec_alg_AES.ixt_alg_id, ++ test); ++ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", ++ ipsec_alg_AES.ixt_alg_type, ++ ipsec_alg_AES.ixt_alg_id, ++ test_ret); ++ } ++#if CONFIG_IPSEC_ALG_AES_MAC ++ if (auth_id!=0){ ++ int ret; ++ ipsec_alg_AES_MAC.ixt_alg_id=auth_id; ++ ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC); ++ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", ++ ipsec_alg_AES_MAC.ixt_alg_type, ++ ipsec_alg_AES_MAC.ixt_alg_id, ++ ipsec_alg_AES_MAC.ixt_name, ++ ret); ++ if (ret==0 && test) { ++ test_ret=ipsec_alg_test( ++ ipsec_alg_AES_MAC.ixt_alg_type, ++ ipsec_alg_AES_MAC.ixt_alg_id, ++ test); ++ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", ++ ipsec_alg_AES_MAC.ixt_alg_type, ++ ipsec_alg_AES_MAC.ixt_alg_id, ++ test_ret); ++ } ++ } else { ++ printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id); ++ } ++#endif /* CONFIG_IPSEC_ALG_AES_MAC */ ++ return ret; ++} ++ ++#if defined(CONFIG_IPSEC_ENC_AES_MODULE) ++IPSEC_ALG_MODULE_EXIT_MOD( ipsec_aes_fini ) ++#else ++IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_aes_fini ) ++#endif ++{ ++#if CONFIG_IPSEC_ALG_AES_MAC ++ if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC); ++#endif /* CONFIG_IPSEC_ALG_AES_MAC */ ++ unregister_ipsec_alg_enc(&ipsec_alg_AES); ++ return; ++} ++#ifdef MODULE_LICENSE ++MODULE_LICENSE("GPL"); ++#endif ++ ++#if 0+NOT_YET ++#ifndef MODULE ++/* ++ * This is intended for static module setups, currently ++ * doesn't work for modular ipsec.o with static algos inside ++ */ ++static int setup_keybits(const char *str) ++{ ++ unsigned aux; ++ char *end; ++ ++ aux = simple_strtoul(str,&end,0); ++ if (aux != 128 && aux != 192 && aux != 256) ++ return 0; ++ keyminbits = aux; ++ ++ if (*end == 0 || *end != ',') ++ return 1; ++ str=end+1; ++ aux = simple_strtoul(str, NULL, 0); ++ if (aux != 128 && aux != 192 && aux != 256) ++ return 0; ++ if (aux >= keyminbits) ++ keymaxbits = aux; ++ return 1; ++} ++__setup("ipsec_aes_keybits=", setup_keybits); ++#endif ++#endif ++EXPORT_NO_SYMBOLS; +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,421 @@ ++/* ++ * ipsec_alg to linux cryptoapi GLUE ++ * ++ * Authors: CODE.ar TEAM ++ * Harpo MAxx ++ * JuanJo Ciarlante ++ * Luciano Ruete ++ * ++ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * Example usage: ++ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos) ++ * modprobe ipsec_cryptoapi ++ * modprobe ipsec_cryptoapi test=1 ++ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo) ++ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers) ++ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens) ++ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES) ++ */ ++#include ++#include ++ ++/* ++ * special case: ipsec core modular with this static algo inside: ++ * must avoid MODULE magic for this file ++ */ ++#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI ++#undef MODULE ++#endif ++ ++#include ++#include ++ ++#include /* printk() */ ++#include /* error codes */ ++#include /* size_t */ ++#include ++ ++/* Check if __exit is defined, if not null it */ ++#ifndef __exit ++#define __exit ++#endif ++ ++/* warn the innocent */ ++#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE) ++#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x" ++#define NO_CRYPTOAPI_SUPPORT ++#endif ++/* Low Openswan header coupling */ ++#include "openswan/ipsec_alg.h" ++ ++#include ++#ifdef CRYPTO_API_VERSION_CODE ++#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported" ++#define NO_CRYPTOAPI_SUPPORT ++#endif ++ ++#ifdef NO_CRYPTOAPI_SUPPORT ++#warning "Building an unusable module :P" ++/* Catch old CryptoAPI by not allowing module to load */ ++IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init ) ++{ ++ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n"); ++ return -EINVAL; ++} ++#else ++#include ++#include ++#include ++ ++#define CIPHERNAME_AES "aes" ++#define CIPHERNAME_3DES "des3_ede" ++#define CIPHERNAME_BLOWFISH "blowfish" ++#define CIPHERNAME_CAST "cast5" ++#define CIPHERNAME_SERPENT "serpent" ++#define CIPHERNAME_TWOFISH "twofish" ++ ++#define ESP_3DES 3 ++#define ESP_AES 12 ++#define ESP_BLOWFISH 7 /* truely _constant_ :) */ ++#define ESP_CAST 6 /* quite constant :) */ ++#define ESP_SERPENT 252 /* from ipsec drafts */ ++#define ESP_TWOFISH 253 /* from ipsec drafts */ ++ ++#define AH_MD5 2 ++#define AH_SHA 3 ++#define DIGESTNAME_MD5 "md5" ++#define DIGESTNAME_SHA1 "sha1" ++ ++MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete"); ++static int debug=0; ++MODULE_PARM(debug, "i"); ++static int test=0; ++MODULE_PARM(test, "i"); ++static int excl=0; ++MODULE_PARM(excl, "i"); ++ ++static int noauto = 0; ++MODULE_PARM(noauto,"i"); ++MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones"); ++ ++static int des_ede3[] = {-1, -1}; ++static int aes[] = {-1, -1}; ++static int blowfish[] = {-1, -1}; ++static int cast[] = {-1, -1}; ++static int serpent[] = {-1, -1}; ++static int twofish[] = {-1, -1}; ++ ++MODULE_PARM(des_ede3,"1-2i"); ++MODULE_PARM(aes,"1-2i"); ++MODULE_PARM(blowfish,"1-2i"); ++MODULE_PARM(cast,"1-2i"); ++MODULE_PARM(serpent,"1-2i"); ++MODULE_PARM(twofish,"1-2i"); ++MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse"); ++MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens"); ++MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens"); ++MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens"); ++MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens"); ++MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens"); ++ ++struct ipsec_alg_capi_cipher { ++ const char *ciphername; /* cryptoapi's ciphername */ ++ unsigned blocksize; ++ unsigned short minbits; ++ unsigned short maxbits; ++ int *parm; /* lkm param for this cipher */ ++ struct ipsec_alg_enc alg; /* note it's not a pointer */ ++}; ++static struct ipsec_alg_capi_cipher alg_capi_carray[] = { ++ { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }}, ++ { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }}, ++ { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }}, ++ { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }}, ++ { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }}, ++ { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }}, ++ { NULL, 0, 0, 0, NULL, {} } ++}; ++#ifdef NOT_YET ++struct ipsec_alg_capi_digest { ++ const char *digestname; /* cryptoapi's digestname */ ++ struct digest_implementation *di; ++ struct ipsec_alg_auth alg; /* note it's not a pointer */ ++}; ++static struct ipsec_alg_capi_cipher alg_capi_darray[] = { ++ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }}, ++ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }}, ++ { NULL, NULL, {} } ++}; ++#endif ++/* ++ * "generic" linux cryptoapi setup_cipher() function ++ */ ++int setup_cipher(const char *ciphername) ++{ ++ return crypto_alg_available(ciphername, 0); ++} ++ ++/* ++ * setups ipsec_alg_capi_cipher "hyper" struct components, calling ++ * register_ipsec_alg for cointaned ipsec_alg object ++ */ ++static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e); ++static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen); ++static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt); ++ ++static int ++setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr) ++{ ++ int ret; ++ cptr->alg.ixt_version = IPSEC_ALG_VERSION; ++ cptr->alg.ixt_module = THIS_MODULE; ++ atomic_set (& cptr->alg.ixt_refcnt, 0); ++ strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name)); ++ ++ cptr->alg.ixt_blocksize=cptr->blocksize; ++ cptr->alg.ixt_keyminbits=cptr->minbits; ++ cptr->alg.ixt_keymaxbits=cptr->maxbits; ++ cptr->alg.ixt_state = 0; ++ if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL; ++ cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8; ++ cptr->alg.ixt_e_ctx_size = 0; ++ cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT; ++ cptr->alg.ixt_e_new_key = _capi_new_key; ++ cptr->alg.ixt_e_destroy_key = _capi_destroy_key; ++ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt; ++ cptr->alg.ixt_data = cptr; ++ ++ ret=register_ipsec_alg_enc(&cptr->alg); ++ printk("setup_ipsec_alg_capi_cipher(): " ++ "alg_type=%d alg_id=%d name=%s " ++ "keyminbits=%d keymaxbits=%d, ret=%d\n", ++ cptr->alg.ixt_alg_type, ++ cptr->alg.ixt_alg_id, ++ cptr->alg.ixt_name, ++ cptr->alg.ixt_keyminbits, ++ cptr->alg.ixt_keymaxbits, ++ ret); ++ return ret; ++} ++/* ++ * called in ipsec_sa_wipe() time, will destroy key contexts ++ * and do 1 unbind() ++ */ ++static void ++_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e) ++{ ++ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e; ++ ++ if (debug > 0) ++ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:" ++ "name=%s key_e=%p \n", ++ alg->ixt_name, key_e); ++ if (!key_e) { ++ printk(KERN_ERR "klips_debug: _capi_destroy_key:" ++ "name=%s NULL key_e!\n", ++ alg->ixt_name); ++ return; ++ } ++ crypto_free_tfm(tfm); ++} ++ ++/* ++ * create new key context, need alg->ixt_data to know which ++ * (of many) cipher inside this module is the target ++ */ ++static __u8 * ++_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen) ++{ ++ struct ipsec_alg_capi_cipher *cptr; ++ struct crypto_tfm *tfm=NULL; ++ ++ cptr = alg->ixt_data; ++ if (!cptr) { ++ printk(KERN_ERR "_capi_new_key(): " ++ "NULL ixt_data (?!) for \"%s\" algo\n" ++ , alg->ixt_name); ++ goto err; ++ } ++ if (debug > 0) ++ printk(KERN_DEBUG "klips_debug:_capi_new_key:" ++ "name=%s cptr=%p key=%p keysize=%d\n", ++ alg->ixt_name, cptr, key, keylen); ++ ++ /* ++ * alloc tfm ++ */ ++ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC); ++ if (!tfm) { ++ printk(KERN_ERR "_capi_new_key(): " ++ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n" ++ , alg->ixt_name, cptr->ciphername); ++ goto err; ++ } ++ if (crypto_cipher_setkey(tfm, key, keylen) < 0) { ++ printk(KERN_ERR "_capi_new_key(): " ++ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n" ++ , alg->ixt_name, keylen); ++ crypto_free_tfm(tfm); ++ tfm=NULL; ++ } ++err: ++ if (debug > 0) ++ printk(KERN_DEBUG "klips_debug:_capi_new_key:" ++ "name=%s key=%p keylen=%d tfm=%p\n", ++ alg->ixt_name, key, keylen, tfm); ++ return (__u8 *) tfm; ++} ++/* ++ * core encryption function: will use cx->ci to call actual cipher's ++ * cbc function ++ */ ++static int ++_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { ++ int error =0; ++ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e; ++ struct scatterlist sg = { ++ .page = virt_to_page(in), ++ .offset = (unsigned long)(in) % PAGE_SIZE, ++ .length=ilen, ++ }; ++ if (debug > 1) ++ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:" ++ "key_e=%p " ++ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n" ++ , key_e ++ , in, in, ilen, iv, encrypt); ++ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm)); ++ if (encrypt) ++ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen); ++ else ++ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen); ++ if (debug > 1) ++ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:" ++ "error=%d\n" ++ , error); ++ return (error<0)? error : ilen; ++} ++/* ++ * main initialization loop: for each cipher in list, do ++ * 1) setup cryptoapi cipher else continue ++ * 2) register ipsec_alg object ++ */ ++static int ++setup_cipher_list (struct ipsec_alg_capi_cipher* clist) ++{ ++ struct ipsec_alg_capi_cipher *cptr; ++ /* foreach cipher in list ... */ ++ for (cptr=clist;cptr->ciphername;cptr++) { ++ /* ++ * see if cipher has been disabled (0) or ++ * if noauto set and not enabled (1) ++ */ ++ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) { ++ if (debug>0) ++ printk(KERN_INFO "setup_cipher_list(): " ++ "ciphername=%s skipped at user request: " ++ "noauto=%d parm[0]=%d parm[1]=%d\n" ++ , cptr->ciphername ++ , noauto ++ , cptr->parm[0] ++ , cptr->parm[1]); ++ continue; ++ } ++ /* ++ * use a local ci to avoid touching cptr->ci, ++ * if register ipsec_alg success then bind cipher ++ */ ++ if( setup_cipher(cptr->ciphername) ) { ++ if (debug > 0) ++ printk(KERN_DEBUG "klips_debug:" ++ "setup_cipher_list():" ++ "ciphername=%s found\n" ++ , cptr->ciphername); ++ if (setup_ipsec_alg_capi_cipher(cptr) == 0) { ++ ++ ++ } else { ++ printk(KERN_ERR "klips_debug:" ++ "setup_cipher_list():" ++ "ciphername=%s failed ipsec_alg_register\n" ++ , cptr->ciphername); ++ } ++ } else { ++ if (debug>0) ++ printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n", ++ cptr->ciphername); ++ } ++ } ++ return 0; ++} ++/* ++ * deregister ipsec_alg objects and unbind ciphers ++ */ ++static int ++unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist) ++{ ++ struct ipsec_alg_capi_cipher *cptr; ++ /* foreach cipher in list ... */ ++ for (cptr=clist;cptr->ciphername;cptr++) { ++ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) { ++ unregister_ipsec_alg_enc(&cptr->alg); ++ } ++ } ++ return 0; ++} ++/* ++ * test loop for registered algos ++ */ ++static int ++test_cipher_list (struct ipsec_alg_capi_cipher* clist) ++{ ++ int test_ret; ++ struct ipsec_alg_capi_cipher *cptr; ++ /* foreach cipher in list ... */ ++ for (cptr=clist;cptr->ciphername;cptr++) { ++ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) { ++ test_ret=ipsec_alg_test( ++ cptr->alg.ixt_alg_type, ++ cptr->alg.ixt_alg_id, ++ test); ++ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n", ++ cptr->alg.ixt_alg_type, ++ cptr->alg.ixt_alg_id, ++ test_ret); ++ } ++ } ++ return 0; ++} ++ ++IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init ) ++{ ++ int ret, test_ret; ++ if ((ret=setup_cipher_list(alg_capi_carray)) < 0) ++ return -EPROTONOSUPPORT; ++ if (ret==0 && test) { ++ test_ret=test_cipher_list(alg_capi_carray); ++ } ++ return ret; ++} ++IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_cryptoapi_fini ) ++{ ++ unsetup_cipher_list(alg_capi_carray); ++ return; ++} ++#ifdef MODULE_LICENSE ++MODULE_LICENSE("GPL"); ++#endif ++ ++EXPORT_NO_SYMBOLS; ++#endif /* NO_CRYPTOAPI_SUPPORT */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_esp.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,558 @@ ++/* ++ * processing code for ESP ++ * Copyright (C) 2003 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ */ ++ ++char ipsec_esp_c_version[] = "RCSID $Id: ipsec_esp.c,v 1.2 2004/04/06 02:49:25 mcr Exp $"; ++#include ++#include ++ ++#define __NO_VERSION__ ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include ++#include ++#ifdef SPINLOCK ++# ifdef SPINLOCK_23 ++# include /* *lock* */ ++# else /* SPINLOCK_23 */ ++# include /* *lock* */ ++# endif /* SPINLOCK_23 */ ++#endif /* SPINLOCK */ ++#ifdef NET_21 ++# include ++# include ++# define proto_priv cb ++#endif /* NET21 */ ++#include ++#include ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_sa.h" ++ ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_tunnel.h" ++#include "openswan/ipsec_rcv.h" ++#include "openswan/ipsec_xmit.h" ++ ++#include "openswan/ipsec_auth.h" ++ ++#ifdef CONFIG_IPSEC_ESP ++#include "openswan/ipsec_esp.h" ++#endif /* CONFIG_IPSEC_ESP */ ++ ++#include "openswan/ipsec_proto.h" ++#include "openswan/ipsec_alg.h" ++ ++#ifdef CONFIG_IPSEC_DEBUG ++int debug_esp = 0; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ ++#ifdef CONFIG_IPSEC_ESP ++enum ipsec_rcv_value ++ipsec_rcv_esp_checks(struct ipsec_rcv_state *irs, ++ struct sk_buff *skb) ++{ ++ __u8 proto; ++ int len; /* packet length */ ++ ++ len = skb->len; ++ proto = irs->ipp->protocol; ++ ++ /* XXX this will need to be 8 for IPv6 */ ++ if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) { ++ printk("klips_error:ipsec_rcv: " ++ "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n", ++ len - irs->iphlen, ++ irs->ipsaddr_txt); ++ if(irs->stats) { ++ irs->stats->rx_errors++; ++ } ++ return IPSEC_RCV_BADLEN; ++ } ++ ++ if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esphdr))) { ++ KLIPS_PRINT(debug_rcv & DB_RX_INAU, ++ "klips_debug:ipsec_rcv: " ++ "runt esp packet of skb->len=%d received from %s, dropped.\n", ++ skb->len, ++ irs->ipsaddr_txt); ++ if(irs->stats) { ++ irs->stats->rx_errors++; ++ } ++ return IPSEC_RCV_BADLEN; ++ } ++ ++ irs->protostuff.espstuff.espp = (struct esphdr *)(skb->data + irs->iphlen); ++ irs->said.spi = irs->protostuff.espstuff.espp->esp_spi; ++ ++ return IPSEC_RCV_OK; ++} ++ ++enum ipsec_rcv_value ++ipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs, ++ struct sk_buff *skb, ++ __u32 *replay, ++ unsigned char **authenticator) ++{ ++ struct esphdr *espp = irs->protostuff.espstuff.espp; ++ ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n", ++ irs->ipsaddr_txt, ++ (__u32)ntohl(espp->esp_rpl), ++ (__u32)ntohl(*((__u32 *)(espp->esp_iv) )), ++ (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)), ++ irs->len, ++ irs->ilen, ++ irs->sa_len ? irs->sa : " (error)"); ++ ++ *replay = ntohl(espp->esp_rpl); ++ *authenticator = &(skb->data[irs->len - irs->authlen]); ++ ++ return IPSEC_RCV_OK; ++} ++ ++enum ipsec_rcv_value ++ipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs, ++ struct sk_buff *skb) ++{ ++ struct auth_alg *aa; ++ struct esphdr *espp = irs->protostuff.espstuff.espp; ++ union { ++ MD5_CTX md5; ++ SHA1_CTX sha1; ++ } tctx; ++ ++#ifdef CONFIG_IPSEC_ALG ++ if (irs->ipsp->ips_alg_auth) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "ipsec_alg hashing proto=%d... ", ++ irs->said.proto); ++ if(irs->said.proto == IPPROTO_ESP) { ++ ipsec_alg_sa_esp_hash(irs->ipsp, ++ (caddr_t)espp, irs->ilen, ++ irs->hash, AHHMAC_HASHLEN); ++ return IPSEC_RCV_OK; ++ } ++ return IPSEC_RCV_BADPROTO; ++ } ++#endif ++ aa = irs->authfuncs; ++ ++ /* copy the initialized keying material */ ++ memcpy(&tctx, irs->ictx, irs->ictx_len); ++ ++ (*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen); ++ ++ (*aa->final)(irs->hash, (void *)&tctx); ++ ++ memcpy(&tctx, irs->octx, irs->octx_len); ++ ++ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen); ++ (*aa->final)(irs->hash, (void *)&tctx); ++ ++ return IPSEC_RCV_OK; ++} ++ ++ ++enum ipsec_rcv_value ++ipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs) ++{ ++ struct ipsec_sa *ipsp = irs->ipsp; ++ struct esphdr *espp = irs->protostuff.espstuff.espp; ++ int esphlen = 0; ++ __u8 *idat; /* pointer to content to be decrypted/authenticated */ ++ __u32 iv[2]; ++ int pad = 0, padlen; ++ int badpad = 0; ++ int i; ++ struct sk_buff *skb; ++#ifdef CONFIG_IPSEC_ALG ++ struct ipsec_alg_enc *ixt_e=NULL; ++#endif /* CONFIG_IPSEC_ALG */ ++ ++ skb=irs->skb; ++ ++ idat = skb->data + irs->iphlen; ++ ++#ifdef CONFIG_IPSEC_ALG ++ if ((ixt_e=ipsp->ips_alg_enc)) { ++ esphlen = ESP_HEADER_LEN + ixt_e->ixt_ivlen/8; ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "encalg=%d esphlen=%d\n", ++ ipsp->ips_encalg, esphlen); ++ } else ++#endif /* CONFIG_IPSEC_ALG */ ++ switch(ipsp->ips_encalg) { ++ case ESP_3DES: ++ iv[0] = *((__u32 *)(espp->esp_iv) ); ++ iv[1] = *((__u32 *)(espp->esp_iv) + 1); ++ esphlen = sizeof(struct esphdr); ++ break; ++ default: ++ ipsp->ips_errs.ips_alg_errs += 1; ++ if(irs->stats) { ++ irs->stats->rx_errors++; ++ } ++ return IPSEC_RCV_ESP_BADALG; ++ } ++ ++ idat += esphlen; ++ irs->ilen -= esphlen; ++ ++#ifdef CONFIG_IPSEC_ALG ++ if (ixt_e) ++ { ++ if (ipsec_alg_esp_encrypt(ipsp, ++ idat, irs->ilen, espp->esp_iv, ++ IPSEC_ALG_DECRYPT) <= 0) ++ { ++ printk("klips_error:ipsec_rcv: " ++ "got packet with esplen = %d " ++ "from %s -- should be on " ++ "ENC(%d) octet boundary, " ++ "packet dropped\n", ++ irs->ilen, ++ irs->ipsaddr_txt, ++ ipsp->ips_encalg); ++ if(irs->stats) { ++ irs->stats->rx_errors++; ++ } ++ return IPSEC_RCV_BAD_DECRYPT; ++ } ++ } else ++#endif /* CONFIG_IPSEC_ALG */ ++ switch(ipsp->ips_encalg) { ++ case ESP_3DES: ++ if ((irs->ilen) % 8) { ++ ipsp->ips_errs.ips_encsize_errs += 1; ++ printk("klips_error:ipsec_rcv: " ++ "got packet with esplen = %d from %s -- should be on 8 octet boundary, packet dropped\n", ++ irs->ilen, ++ irs->ipsaddr_txt); ++ if(irs->stats) { ++ irs->stats->rx_errors++; ++ } ++ return IPSEC_RCV_3DES_BADBLOCKING; ++ } ++ des_ede3_cbc_encrypt((des_cblock *)idat, ++ (des_cblock *)idat, ++ irs->ilen, ++ ((struct des_eks *)(ipsp->ips_key_e))[0].ks, ++ ((struct des_eks *)(ipsp->ips_key_e))[1].ks, ++ ((struct des_eks *)(ipsp->ips_key_e))[2].ks, ++ (des_cblock *)iv, 0); ++ break; ++ } ++ ++ ipsec_rcv_dmp("postdecrypt", skb->data, skb->len); ++ ++ irs->next_header = idat[irs->ilen - 1]; ++ padlen = idat[irs->ilen - 2]; ++ pad = padlen + 2 + irs->authlen; ++ ++ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, ++ "klips_debug:ipsec_rcv: " ++ "padlen=%d, contents: 0x: 0x 0x ...\n", ++ padlen); ++ ++ for (i = 1; i <= padlen; i++) { ++ if((i % 16) == 1) { ++ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, ++ "klips_debug: %02x:", ++ i - 1); ++ } ++ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, ++ " %02x", ++ idat[irs->ilen - 2 - padlen + i - 1]); ++ if(i != idat[irs->ilen - 2 - padlen + i - 1]) { ++ badpad = 1; ++ } ++ if((i % 16) == 0) { ++ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, ++ "\n"); ++ } ++ } ++ if((i % 16) != 1) { ++ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, ++ "\n"); ++ } ++ if(badpad) { ++ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, ++ "klips_debug:ipsec_rcv: " ++ "warning, decrypted packet from %s has bad padding\n", ++ irs->ipsaddr_txt); ++ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, ++ "klips_debug:ipsec_rcv: " ++ "...may be bad decryption -- not dropped\n"); ++ ipsp->ips_errs.ips_encpad_errs += 1; ++ } ++ ++ KLIPS_PRINT(debug_rcv & DB_RX_IPAD, ++ "klips_debug:ipsec_rcv: " ++ "packet decrypted from %s: next_header = %d, padding = %d\n", ++ irs->ipsaddr_txt, ++ irs->next_header, ++ pad - 2 - irs->authlen); ++ ++ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (esphlen + pad)); ++ ++ /* ++ * move the IP header forward by the size of the ESP header, which ++ * will remove the the ESP header from the packet. ++ */ ++ memmove((void *)(skb->data + esphlen), ++ (void *)(skb->data), irs->iphlen); ++ ++ ipsec_rcv_dmp("esp postmove", skb->data, skb->len); ++ ++ /* skb_pull below, will move up by esphlen */ ++ ++ /* XXX not clear how this can happen, as the message indicates */ ++ if(skb->len < esphlen) { ++ printk(KERN_WARNING ++ "klips_error:ipsec_rcv: " ++ "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n", ++ esphlen, (int)(skb->len)); ++ return IPSEC_RCV_ESP_DECAPFAIL; ++ } ++ skb_pull(skb, esphlen); ++ ++ irs->ipp = (struct iphdr *)skb->data; ++ ++ ipsec_rcv_dmp("esp postpull", skb->data, skb->len); ++ ++ /* now, trip off the padding from the end */ ++ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, ++ "klips_debug:ipsec_rcv: " ++ "trimming to %d.\n", ++ irs->len - esphlen - pad); ++ if(pad + esphlen <= irs->len) { ++ skb_trim(skb, irs->len - esphlen - pad); ++ } else { ++ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, ++ "klips_debug:ipsec_rcv: " ++ "bogus packet, size is zero or negative, dropping.\n"); ++ return IPSEC_RCV_DECAPFAIL; ++ } ++ ++ return IPSEC_RCV_OK; ++} ++ ++enum ipsec_xmit_value ++ipsec_xmit_esp_setup(struct ipsec_xmit_state *ixs) ++{ ++ __u32 iv[2]; ++ struct esphdr *espp; ++ int ilen = 0; ++ int padlen = 0, i; ++ unsigned char *dat; ++ unsigned char *idat, *pad; ++ __u8 hash[AH_AMAX]; ++ union { ++#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ MD5_CTX md5; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ SHA1_CTX sha1; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++ } tctx; ++ ++ dat = (unsigned char *)ixs->iph; ++ ++ espp = (struct esphdr *)(dat + ixs->iphlen); ++ espp->esp_spi = ixs->ipsp->ips_said.spi; ++ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq)); ++ ++ switch(ixs->ipsp->ips_encalg) { ++#if defined(CONFIG_IPSEC_ENC_3DES) ++#ifdef CONFIG_IPSEC_ENC_3DES ++ case ESP_3DES: ++#endif /* CONFIG_IPSEC_ENC_3DES */ ++ iv[0] = *((__u32*)&(espp->esp_iv) ) = ++ ((__u32*)(ixs->ipsp->ips_iv))[0]; ++ iv[1] = *((__u32*)&(espp->esp_iv) + 1) = ++ ((__u32*)(ixs->ipsp->ips_iv))[1]; ++ break; ++#endif /* defined(CONFIG_IPSEC_ENC_3DES) */ ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_ESP_BADALG; ++ } ++ ++ idat = dat + ixs->iphlen + sizeof(struct esphdr); ++ ilen = ixs->skb->len - (ixs->iphlen + sizeof(struct esphdr) + ixs->authlen); ++ ++ /* Self-describing padding */ ++ pad = &dat[ixs->skb->len - ixs->tailroom]; ++ padlen = ixs->tailroom - 2 - ixs->authlen; ++ for (i = 0; i < padlen; i++) { ++ pad[i] = i + 1; ++ } ++ dat[ixs->skb->len - ixs->authlen - 2] = padlen; ++ ++ dat[ixs->skb->len - ixs->authlen - 1] = ixs->iph->protocol; ++ ixs->iph->protocol = IPPROTO_ESP; ++ ++ switch(ixs->ipsp->ips_encalg) { ++#ifdef CONFIG_IPSEC_ENC_3DES ++ case ESP_3DES: ++ des_ede3_cbc_encrypt((des_cblock *)idat, ++ (des_cblock *)idat, ++ ilen, ++ ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks, ++ ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks, ++ ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks, ++ (des_cblock *)iv, 1); ++ break; ++#endif /* CONFIG_IPSEC_ENC_3DES */ ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_ESP_BADALG; ++ } ++ ++ switch(ixs->ipsp->ips_encalg) { ++#if defined(CONFIG_IPSEC_ENC_3DES) ++#ifdef CONFIG_IPSEC_ENC_3DES ++ case ESP_3DES: ++#endif /* CONFIG_IPSEC_ENC_3DES */ ++ /* XXX update IV with the last 8 octets of the encryption */ ++#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK ++ ((__u32*)(ixs->ipsp->ips_iv))[0] = ++ ((__u32 *)(idat))[(ilen >> 2) - 2]; ++ ((__u32*)(ixs->ipsp->ips_iv))[1] = ++ ((__u32 *)(idat))[(ilen >> 2) - 1]; ++#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */ ++ prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ); ++#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */ ++ break; ++#endif /* defined(CONFIG_IPSEC_ENC_3DES) */ ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_ESP_BADALG; ++ } ++ ++ switch(ixs->ipsp->ips_authalg) { ++#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ case AH_MD5: ++ ipsec_xmit_dmp("espp", (char*)espp, ixs->skb->len - ixs->iphlen - ixs->authlen); ++ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx; ++ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen); ++ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Final(hash, &tctx.md5); ++ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash)); ++ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx; ++ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, hash, AHMD596_ALEN); ++ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Final(hash, &tctx.md5); ++ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash)); ++ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen); ++ ++ /* paranoid */ ++ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5)); ++ memset((caddr_t)hash, 0, sizeof(*hash)); ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ case AH_SHA: ++ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx; ++ SHA1Update(&tctx.sha1, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen); ++ SHA1Final(hash, &tctx.sha1); ++ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx; ++ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); ++ SHA1Final(hash, &tctx.sha1); ++ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen); ++ ++ /* paranoid */ ++ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1)); ++ memset((caddr_t)hash, 0, sizeof(*hash)); ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++ case AH_NONE: ++ break; ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_AH_BADALG; ++ } ++#ifdef NET_21 ++ ixs->skb->h.raw = (unsigned char*)espp; ++#endif /* NET_21 */ ++ ++ return IPSEC_XMIT_OK; ++} ++ ++ ++struct xform_functions esp_xform_funcs[]={ ++ { rcv_checks: ipsec_rcv_esp_checks, ++ rcv_setup_auth: ipsec_rcv_esp_decrypt_setup, ++ rcv_calc_auth: ipsec_rcv_esp_authcalc, ++ rcv_decrypt: ipsec_rcv_esp_decrypt, ++ ++ xmit_setup: ipsec_xmit_esp_setup, ++ xmit_headroom: sizeof(struct esphdr), ++ xmit_needtailroom: 1, ++ }, ++}; ++ ++struct inet_protocol esp_protocol = ++{ ++ ipsec_rcv, /* ESP handler */ ++ NULL, /* TUNNEL error control */ ++#ifdef NETDEV_25 ++ 1, /* no policy */ ++#else ++ 0, /* next */ ++ IPPROTO_ESP, /* protocol ID */ ++ 0, /* copy */ ++ NULL, /* data */ ++ "ESP" /* name */ ++#endif ++}; ++ ++ ++ ++#endif /* !CONFIG_IPSEC_ESP */ ++ ++ ++/* ++ * $Log: ipsec_esp.c,v $ ++ * Revision 1.2 2004/04/06 02:49:25 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_init.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,531 @@ ++/* ++ * @(#) Initialization code. ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998 - 2002 Richard Guy Briggs ++ * 2001 - 2004 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * /proc system code was split out into ipsec_proc.c after rev. 1.70. ++ * ++ */ ++ ++char ipsec_init_c_version[] = "RCSID $Id: ipsec_init.c,v 1.93 2004/04/06 02:49:26 mcr Exp $"; ++ ++#include ++#include ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include /* struct sockaddr_in */ ++#include ++#include /* get_random_bytes() */ ++#include ++ ++#ifdef SPINLOCK ++# ifdef SPINLOCK_23 ++# include /* *lock* */ ++# else /* 23_SPINLOCK */ ++# include /* *lock* */ ++# endif /* 23_SPINLOCK */ ++#endif /* SPINLOCK */ ++ ++#ifdef NET_21 ++# include ++# include ++#endif /* NET_21 */ ++ ++#include ++#include ++ ++#ifdef CONFIG_PROC_FS ++# include ++#endif /* CONFIG_PROC_FS */ ++ ++#ifdef NETLINK_SOCK ++# include ++#else ++# include ++#endif ++ ++#include "openswan/radij.h" ++ ++#include "openswan/ipsec_life.h" ++#include "openswan/ipsec_stats.h" ++#include "openswan/ipsec_sa.h" ++ ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_tunnel.h" ++ ++#include "openswan/ipsec_rcv.h" ++#include "openswan/ipsec_ah.h" ++#include "openswan/ipsec_esp.h" ++ ++#ifdef CONFIG_IPSEC_IPCOMP ++# include "openswan/ipcomp.h" ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ ++#include "openswan/ipsec_proto.h" ++#include "openswan/ipsec_alg.h" ++ ++#include ++#include ++ ++#if !defined(CONFIG_IPSEC_ESP) && !defined(CONFIG_IPSEC_AH) ++#error "kernel configuration must include ESP or AH" ++#endif ++ ++/* ++ * seems to be present in 2.4.10 (Linus), but also in some RH and other ++ * distro kernels of a lower number. ++ */ ++#ifdef MODULE_LICENSE ++MODULE_LICENSE("GPL"); ++#endif ++ ++#ifdef CONFIG_IPSEC_DEBUG ++int debug_eroute = 0; ++int debug_spi = 0; ++int debug_netlink = 0; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++struct prng ipsec_prng; ++ ++extern int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr); ++/* ++ * the following structure is required so that we receive ++ * event notifications when network devices are enabled and ++ * disabled (ifconfig up and down). ++ */ ++static struct notifier_block ipsec_dev_notifier={ ++ ipsec_device_event, ++ NULL, ++ 0 ++}; ++ ++#ifdef CONFIG_SYSCTL ++extern int ipsec_sysctl_register(void); ++extern void ipsec_sysctl_unregister(void); ++#endif ++ ++static inline int ++openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol) ++{ ++#ifdef NETDEV_25 ++ return inet_add_protocol(prot, protocol); ++#else ++ inet_add_protocol(prot); ++ return 0; ++#endif ++} ++ ++static inline int ++openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol) ++{ ++#ifdef NETDEV_25 ++ return inet_del_protocol(prot, protocol); ++#else ++ inet_del_protocol(prot); ++ return 0; ++#endif ++} ++ ++/* void */ ++int ++ipsec_init(void) ++{ ++ int error = 0; ++ unsigned char seed[256]; ++#ifdef CONFIG_IPSEC_ENC_3DES ++ extern int des_check_key; ++ ++ /* turn off checking of keys */ ++ des_check_key=0; ++#endif /* CONFIG_IPSEC_ENC_3DES */ ++ ++ KLIPS_PRINT(1, "klips_info:ipsec_init: " ++ "KLIPS startup, Openswan KLIPS IPsec stack version: %s\n", ++ ipsec_version_code()); ++ ++ error |= ipsec_proc_init(); ++ ++#ifdef SPINLOCK ++ ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED; ++#else /* SPINLOCK */ ++ ipsec_sadb.sadb_lock = 0; ++#endif /* SPINLOCK */ ++ ++#ifndef SPINLOCK ++ tdb_lock.lock = 0; ++ eroute_lock.lock = 0; ++#endif /* !SPINLOCK */ ++ ++ error |= ipsec_sadb_init(); ++ error |= ipsec_radijinit(); ++ ++ error |= pfkey_init(); ++ ++ error |= register_netdevice_notifier(&ipsec_dev_notifier); ++ ++#ifdef CONFIG_IPSEC_ESP ++ openswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP); ++#endif /* CONFIG_IPSEC_ESP */ ++ ++#ifdef CONFIG_IPSEC_AH ++ openswan_inet_add_protocol(&ah_protocol, IPPROTO_AH); ++#endif /* CONFIG_IPSEC_AH */ ++ ++/* we never actually link IPCOMP to the stack */ ++#ifdef IPCOMP_USED_ALONE ++#ifdef CONFIG_IPSEC_IPCOMP ++ openswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP); ++#endif /* CONFIG_IPSEC_IPCOMP */ ++#endif ++ ++ error |= ipsec_tunnel_init_devices(); ++ ++ ++#ifdef CONFIG_SYSCTL ++ error |= ipsec_sysctl_register(); ++#endif ++ ++#ifdef CONFIG_IPSEC_ALG ++ ipsec_alg_init(); ++#endif ++ ++ get_random_bytes((void *)seed, sizeof(seed)); ++ prng_init(&ipsec_prng, seed, sizeof(seed)); ++ ++ return error; ++} ++ ++ ++/* void */ ++int ++ipsec_cleanup(void) ++{ ++ int error = 0; ++ ++#ifdef CONFIG_SYSCTL ++ ipsec_sysctl_unregister(); ++#endif ++ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ ++ "klips_debug:ipsec_cleanup: " ++ "calling ipsec_tunnel_cleanup_devices.\n"); ++ error |= ipsec_tunnel_cleanup_devices(); ++ ++ KLIPS_PRINT(debug_netlink, "called ipsec_tunnel_cleanup_devices"); ++ ++/* we never actually link IPCOMP to the stack */ ++#ifdef IPCOMP_USED_ALONE ++#ifdef CONFIG_IPSEC_IPCOMP ++ if (openswan_inet_del_protocol(&comp_protocol, IPPROTO_COMP) < 0) ++ printk(KERN_INFO "klips_debug:ipsec_cleanup: " ++ "comp close: can't remove protocol\n"); ++#endif /* CONFIG_IPSEC_IPCOMP */ ++#endif /* IPCOMP_USED_ALONE */ ++ ++#ifdef CONFIG_IPSEC_AH ++ if (openswan_inet_del_protocol(&ah_protocol, IPPROTO_AH) < 0) ++ printk(KERN_INFO "klips_debug:ipsec_cleanup: " ++ "ah close: can't remove protocol\n"); ++#endif /* CONFIG_IPSEC_AH */ ++ ++#ifdef CONFIG_IPSEC_ESP ++ if (openswan_inet_del_protocol(&esp_protocol, IPPROTO_ESP) < 0) ++ printk(KERN_INFO "klips_debug:ipsec_cleanup: " ++ "esp close: can't remove protocol\n"); ++#endif /* CONFIG_IPSEC_ESP */ ++ ++ error |= unregister_netdevice_notifier(&ipsec_dev_notifier); ++ ++ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ ++ "klips_debug:ipsec_cleanup: " ++ "calling ipsec_sadb_cleanup.\n"); ++ error |= ipsec_sadb_cleanup(0); ++ error |= ipsec_sadb_free(); ++ ++ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ ++ "klips_debug:ipsec_cleanup: " ++ "calling ipsec_radijcleanup.\n"); ++ error |= ipsec_radijcleanup(); ++ ++ KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */ ++ "klips_debug:ipsec_cleanup: " ++ "calling pfkey_cleanup.\n"); ++ error |= pfkey_cleanup(); ++ ++ ipsec_proc_cleanup(); ++ ++ prng_final(&ipsec_prng); ++ ++ return error; ++} ++ ++#ifdef MODULE ++int ++init_module(void) ++{ ++ int error = 0; ++ ++ error |= ipsec_init(); ++ ++ return error; ++} ++ ++int ++cleanup_module(void) ++{ ++ int error = 0; ++ ++ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ ++ "klips_debug:cleanup_module: " ++ "calling ipsec_cleanup.\n"); ++ ++ error |= ipsec_cleanup(); ++ ++ KLIPS_PRINT(1, "klips_info:cleanup_module: " ++ "ipsec module unloaded.\n"); ++ ++ return error; ++} ++#endif /* MODULE */ ++ ++/* ++ * $Log: ipsec_init.c,v $ ++ * Revision 1.93 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.92 2004/03/30 15:30:39 ken ++ * Proper Capitalization ++ * ++ * Revision 1.91 2004/03/22 01:51:51 ken ++ * We are open ++ * ++ * Revision 1.90.4.2 2004/04/05 04:30:46 mcr ++ * patches for alg-branch to compile/work with 2.x openswan ++ * ++ * Revision 1.90.4.1 2003/12/22 15:25:52 jjo ++ * Merged algo-0.8.1-rc11-test1 into alg-branch ++ * ++ * Revision 1.90 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.89.4.1 2003/10/29 01:30:41 mcr ++ * elimited "struct sa_id". ++ * ++ * Revision 1.89 2003/07/31 22:47:16 mcr ++ * preliminary (untested by FS-team) 2.5 patches. ++ * ++ * Revision 1.88 2003/06/22 20:05:36 mcr ++ * clarified why IPCOMP was not being registered, and put a new ++ * #ifdef in rather than #if 0. ++ * ++ * Revision 1.87 2002/09/20 15:40:51 rgb ++ * Added a lock to the global ipsec_sadb struct for future use. ++ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem ++ * of freeing newly created structures when clearing the reftable upon startup ++ * to start from a known state. ++ * ++ * Revision 1.86 2002/08/15 18:39:15 rgb ++ * Move ipsec_prng outside debug code. ++ * ++ * Revision 1.85 2002/05/14 02:35:29 rgb ++ * Change reference to tdb to ipsa. ++ * ++ * Revision 1.84 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.83 2002/04/24 07:36:28 mcr ++ * Moved from ./klips/net/ipsec/ipsec_init.c,v ++ * ++ * Revision 1.82 2002/04/20 00:12:25 rgb ++ * Added esp IV CBC attack fix, disabled. ++ * ++ * Revision 1.81 2002/04/09 16:13:32 mcr ++ * switch license to straight GPL. ++ * ++ * Revision 1.80 2002/03/24 07:34:08 rgb ++ * Sanity check for at least one of AH or ESP configured. ++ * ++ * Revision 1.79 2002/02/05 22:55:15 mcr ++ * added MODULE_LICENSE declaration. ++ * This macro does not appear in all kernel versions (see comment). ++ * ++ * Revision 1.78 2002/01/29 17:17:55 mcr ++ * moved include of ipsec_param.h to after include of linux/kernel.h ++ * otherwise, it seems that some option that is set in ipsec_param.h ++ * screws up something subtle in the include path to kernel.h, and ++ * it complains on the snprintf() prototype. ++ * ++ * Revision 1.77 2002/01/29 04:00:51 mcr ++ * more excise of kversions.h header. ++ * ++ * Revision 1.76 2002/01/29 02:13:17 mcr ++ * introduction of ipsec_kversion.h means that include of ++ * ipsec_param.h must preceed any decisions about what files to ++ * include to deal with differences in kernel source. ++ * ++ * Revision 1.75 2001/11/26 09:23:48 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.74 2001/11/22 05:44:11 henry ++ * new version stuff ++ * ++ * Revision 1.71.2.2 2001/10/22 20:51:00 mcr ++ * explicitely set des_check_key. ++ * ++ * Revision 1.71.2.1 2001/09/25 02:19:39 mcr ++ * /proc manipulation code moved to new ipsec_proc.c ++ * ++ * Revision 1.73 2001/11/06 19:47:17 rgb ++ * Changed lifetime_packets to uint32 from uint64. ++ * ++ * Revision 1.72 2001/10/18 04:45:19 rgb ++ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, ++ * lib/freeswan.h version macros moved to lib/kversions.h. ++ * Other compiler directive cleanups. ++ * ++ * Revision 1.71 2001/09/20 15:32:45 rgb ++ * Minor pfkey lifetime fixes. ++ * ++ * Revision 1.70 2001/07/06 19:51:21 rgb ++ * Added inbound policy checking code for IPIP SAs. ++ * ++ * Revision 1.69 2001/06/14 19:33:26 rgb ++ * Silence startup message for console, but allow it to be logged. ++ * Update copyright date. ++ * ++ * Revision 1.68 2001/05/29 05:14:36 rgb ++ * Added PMTU to /proc/net/ipsec_tncfg output. See 'man 5 ipsec_tncfg'. ++ * ++ * Revision 1.67 2001/05/04 16:34:52 rgb ++ * Rremove erroneous checking of return codes for proc_net_* in 2.4. ++ * ++ * Revision 1.66 2001/05/03 19:40:34 rgb ++ * Check error return codes in startup and shutdown. ++ * ++ * Revision 1.65 2001/02/28 05:03:27 rgb ++ * Clean up and rationalise startup messages. ++ * ++ * Revision 1.64 2001/02/27 22:24:53 rgb ++ * Re-formatting debug output (line-splitting, joining, 1arg/line). ++ * Check for satoa() return codes. ++ * ++ * Revision 1.63 2000/11/29 20:14:06 rgb ++ * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP. ++ * ++ * Revision 1.62 2000/11/06 04:31:24 rgb ++ * Ditched spin_lock_irqsave in favour of spin_lock_bh. ++ * Fixed longlong for pre-2.4 kernels (Svenning). ++ * Add Svenning's adaptive content compression. ++ * Disabled registration of ipcomp handler. ++ * ++ * Revision 1.61 2000/10/11 13:37:54 rgb ++ * #ifdef out debug print that causes proc/net/ipsec_version to oops. ++ * ++ * Revision 1.60 2000/09/20 03:59:01 rgb ++ * Change static info functions to DEBUG_NO_STATIC to reveal function names ++ * in oopsen. ++ * ++ * Revision 1.59 2000/09/16 01:06:26 rgb ++ * Added cast of var to silence compiler warning about long fed to int ++ * format. ++ * ++ * Revision 1.58 2000/09/15 11:37:01 rgb ++ * Merge in heavily modified Svenning Soerensen's ++ * IPCOMP zlib deflate code. ++ * ++ * Revision 1.57 2000/09/12 03:21:50 rgb ++ * Moved radij_c_version printing to ipsec_version_get_info(). ++ * Reformatted ipsec_version_get_info(). ++ * Added sysctl_{,un}register() calls. ++ * ++ * Revision 1.56 2000/09/08 19:16:50 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * Removed all references to CONFIG_IPSEC_PFKEYv2. ++ * ++ * Revision 1.55 2000/08/30 05:19:03 rgb ++ * Cleaned up no longer used spi_next, netlink register/unregister, other ++ * minor cleanup. ++ * Removed cruft replaced by TDB_XFORM_NAME. ++ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst. ++ * Moved debug version strings to printk when /proc/net/ipsec_version is ++ * called. ++ * ++ * Revision 1.54 2000/08/20 18:31:05 rgb ++ * Changed cosmetic alignment in spi_info. ++ * Changed addtime and usetime to use actual value which is relative ++ * anyways, as intended. (Momchil) ++ * ++ * Revision 1.53 2000/08/18 17:37:03 rgb ++ * Added an (int) cast to shut up the compiler... ++ * ++ * Revision 1.52 2000/08/01 14:51:50 rgb ++ * Removed _all_ remaining traces of DES. ++ * ++ * Revision 1.51 2000/07/25 20:41:22 rgb ++ * Removed duplicate parameter in spi_getinfo. ++ * ++ * Revision 1.50 2000/07/17 03:21:45 rgb ++ * Removed /proc/net/ipsec_spinew. ++ * ++ * Revision 1.49 2000/06/28 05:46:51 rgb ++ * Renamed ivlen to iv_bits for consistency. ++ * Changed output of add and use times to be relative to now. ++ * ++ * Revision 1.48 2000/05/11 18:26:10 rgb ++ * Commented out calls to netlink_attach/detach to avoid activating netlink ++ * in the kenrel config. ++ * ++ * Revision 1.47 2000/05/10 22:35:26 rgb ++ * Comment out most of the startup version information. ++ * ++ * Revision 1.46 2000/03/22 16:15:36 rgb ++ * Fixed renaming of dev_get (MB). ++ * ++ * Revision 1.45 2000/03/16 06:40:48 rgb ++ * Hardcode PF_KEYv2 support. ++ * ++ * Revision 1.44 2000/01/22 23:19:20 rgb ++ * Simplified code to use existing macro TDB_XFORM_NAME(). ++ * ++ * Revision 1.43 2000/01/21 06:14:04 rgb ++ * Print individual stats only if non-zero. ++ * Removed 'bits' from each keylength for brevity. ++ * Shortened lifetimes legend for brevity. ++ * Changed wording from 'last_used' to the clearer 'idle'. ++ * ++ * Revision 1.42 1999/12/31 14:57:19 rgb ++ * MB fix for new dummy-less proc_get_info in 2.3.35. ++ * ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_ipcomp.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,276 @@ ++/* ++ * processing code for IPCOMP ++ * Copyright (C) 2003 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ */ ++ ++char ipsec_ipcomp_c_version[] = "RCSID $Id: ipsec_ipcomp.c,v 1.2 2004/04/06 02:49:26 mcr Exp $"; ++#include ++#include ++ ++#define __NO_VERSION__ ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include ++#include ++#ifdef SPINLOCK ++# ifdef SPINLOCK_23 ++# include /* *lock* */ ++# else /* SPINLOCK_23 */ ++# include /* *lock* */ ++# endif /* SPINLOCK_23 */ ++#endif /* SPINLOCK */ ++#ifdef NET_21 ++# include ++# include ++# define proto_priv cb ++#endif /* NET21 */ ++#include ++#include ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_sa.h" ++ ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_tunnel.h" ++#include "openswan/ipsec_rcv.h" ++#include "openswan/ipsec_xmit.h" ++ ++#include "openswan/ipsec_auth.h" ++ ++#ifdef CONFIG_IPSEC_IPCOMP ++#include "openswan/ipsec_ipcomp.h" ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ ++#include "openswan/ipsec_proto.h" ++ ++#ifdef CONFIG_IPSEC_DEBUG ++int debug_ipcomp = 0; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ ++#ifdef CONFIG_IPSEC_IPCOMP ++enum ipsec_rcv_value ++ipsec_rcv_ipcomp_checks(struct ipsec_rcv_state *irs, ++ struct sk_buff *skb) ++{ ++ int ipcompminlen; ++ ++ ipcompminlen = irs->hard_header_len + sizeof(struct iphdr); ++ ++ if(skb->len < (ipcompminlen + sizeof(struct ipcomphdr))) { ++ KLIPS_PRINT(debug_rcv & DB_RX_INAU, ++ "klips_debug:ipsec_rcv: " ++ "runt comp packet of skb->len=%d received from %s, dropped.\n", ++ skb->len, ++ irs->ipsaddr_txt); ++ if(irs->stats) { ++ irs->stats->rx_errors++; ++ } ++ return IPSEC_RCV_BADLEN; ++ } ++ ++ irs->protostuff.ipcompstuff.compp = (struct ipcomphdr *)(skb->data + irs->iphlen); ++ irs->said.spi = htonl((__u32)ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi)); ++ return IPSEC_RCV_OK; ++} ++ ++enum ipsec_rcv_value ++ipsec_rcv_ipcomp_decomp(struct ipsec_rcv_state *irs) ++{ ++ unsigned int flags = 0; ++ struct ipsec_sa *ipsp = irs->ipsp; ++ struct sk_buff *skb; ++ ++ skb=irs->skb; ++ ++ ipsec_xmit_dmp("ipcomp", skb->data, skb->len); ++ ++ if(ipsp == NULL) { ++ return IPSEC_RCV_SAIDNOTFOUND; ++ } ++ ++#if 0 ++ /* we want to check that this wasn't the first SA on the list, because ++ * we don't support bare IPCOMP, for unexplained reasons. MCR ++ */ ++ if (ipsp->ips_onext != NULL) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "Incoming packet with outer IPCOMP header SA:%s: not yet supported by KLIPS, dropped\n", ++ irs->sa_len ? irs->sa : " (error)"); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ ++ return IPSEC_RCV_IPCOMPALONE; ++ } ++#endif ++ ++ if(sysctl_ipsec_inbound_policy_check && ++ ((((ntohl(ipsp->ips_said.spi) & 0x0000ffff) != ntohl(irs->said.spi)) && ++ (ipsp->ips_encalg != ntohl(irs->said.spi)) /* this is a workaround for peer non-compliance with rfc2393 */ ++ ))) { ++ char sa2[SATOT_BUF]; ++ size_t sa_len2 = 0; ++ ++ sa_len2 = satot(&ipsp->ips_said, 0, sa2, sizeof(sa2)); ++ ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "Incoming packet with SA(IPCA):%s does not match policy SA(IPCA):%s cpi=%04x cpi->spi=%08x spi=%08x, spi->cpi=%04x for SA grouping, dropped.\n", ++ irs->sa_len ? irs->sa : " (error)", ++ ipsp != NULL ? (sa_len2 ? sa2 : " (error)") : "NULL", ++ ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi), ++ (__u32)ntohl(irs->said.spi), ++ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0, ++ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ return IPSEC_RCV_SAIDNOTFOUND; ++ } ++ ++ ipsp->ips_comp_ratio_cbytes += ntohs(irs->ipp->tot_len); ++ irs->next_header = irs->protostuff.ipcompstuff.compp->ipcomp_nh; ++ ++ skb = skb_decompress(skb, ipsp, &flags); ++ if (!skb || flags) { ++ spin_unlock(&tdb_lock); ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "skb_decompress() returned error flags=%x, dropped.\n", ++ flags); ++ if (irs->stats) { ++ if (flags) ++ irs->stats->rx_errors++; ++ else ++ irs->stats->rx_dropped++; ++ } ++ return IPSEC_RCV_IPCOMPFAILED; ++ } ++ ++ /* make sure we update the pointer */ ++ irs->skb = skb; ++ ++#ifdef NET_21 ++ irs->ipp = skb->nh.iph; ++#else /* NET_21 */ ++ irs->ipp = skb->ip_hdr; ++#endif /* NET_21 */ ++ ++ ipsp->ips_comp_ratio_dbytes += ntohs(irs->ipp->tot_len); ++ ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n", ++ irs->sa_len ? irs->sa : " (error)", ++ (__u32)ntohl(irs->said.spi), ++ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0, ++ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0, ++ irs->next_header); ++ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, irs->ipp); ++ ++ return IPSEC_RCV_OK; ++} ++ ++enum ipsec_xmit_value ++ipsec_xmit_ipcomp_setup(struct ipsec_xmit_state *ixs) ++{ ++ unsigned int flags = 0; ++#ifdef CONFIG_IPSEC_DEBUG ++ unsigned int old_tot_len = ntohs(ixs->iph->tot_len); ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len); ++ ++ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags); ++ ++#ifdef NET_21 ++ ixs->iph = ixs->skb->nh.iph; ++#else /* NET_21 */ ++ ixs->iph = ixs->skb->ip_hdr; ++#endif /* NET_21 */ ++ ++ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len); ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if (debug_tunnel & DB_TN_CROUT) ++ { ++ if (old_tot_len > ntohs(ixs->iph->tot_len)) ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_once: " ++ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n", ++ old_tot_len, ntohs(ixs->iph->tot_len), ++ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi), ++ ntohl(ixs->ipsp->ips_said.spi), ++ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff)); ++ else ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_once: " ++ "packet did not compress (flags = %d).\n", ++ flags); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ return IPSEC_XMIT_OK; ++} ++ ++struct xform_functions ipcomp_xform_funcs[]={ ++ {rcv_checks: ipsec_rcv_ipcomp_checks, ++ rcv_decrypt: ipsec_rcv_ipcomp_decomp, ++ xmit_setup: ipsec_xmit_ipcomp_setup, ++ xmit_headroom: 0, ++ xmit_needtailroom: 0, ++ }, ++}; ++ ++#if 0 ++/* We probably don't want to install a pure IPCOMP protocol handler, but ++ only want to handle IPCOMP if it is encapsulated inside an ESP payload ++ (which is already handled) */ ++#ifdef CONFIG_IPSEC_IPCOMP ++struct inet_protocol comp_protocol = ++{ ++ ipsec_rcv, /* COMP handler */ ++ NULL, /* COMP error control */ ++#ifdef NETDEV_25 ++ 1, /* no policy */ ++#else ++ 0, /* next */ ++ IPPROTO_COMP, /* protocol ID */ ++ 0, /* copy */ ++ NULL, /* data */ ++ "COMP" /* name */ ++#endif ++}; ++#endif /* CONFIG_IPSEC_IPCOMP */ ++#endif ++ ++#endif /* CONFIG_IPSEC_IPCOMP */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_ipip.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,133 @@ ++/* ++ * processing code for IPIP ++ * Copyright (C) 2003 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ */ ++ ++char ipsec_ipip_c_version[] = "RCSID $Id: ipsec_ipip.c,v 1.2 2004/04/06 02:49:26 mcr Exp $"; ++#include ++#include ++ ++#define __NO_VERSION__ ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include ++#include ++#ifdef SPINLOCK ++# ifdef SPINLOCK_23 ++# include /* *lock* */ ++# else /* SPINLOCK_23 */ ++# include /* *lock* */ ++# endif /* SPINLOCK_23 */ ++#endif /* SPINLOCK */ ++#ifdef NET_21 ++# include ++# include ++# define proto_priv cb ++#endif /* NET21 */ ++#include ++#include ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_sa.h" ++ ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_tunnel.h" ++#include "openswan/ipsec_rcv.h" ++#include "openswan/ipsec_xmit.h" ++ ++#include "openswan/ipsec_auth.h" ++#include "openswan/ipsec_ipip.h" ++#include "openswan/ipsec_param.h" ++ ++#include "openswan/ipsec_proto.h" ++ ++enum ipsec_xmit_value ++ipsec_xmit_ipip_setup(struct ipsec_xmit_state *ixs) ++{ ++ ixs->iph->version = 4; ++ ++ switch(sysctl_ipsec_tos) { ++ case 0: ++#ifdef NET_21 ++ ixs->iph->tos = ixs->skb->nh.iph->tos; ++#else /* NET_21 */ ++ ixs->iph->tos = ixs->skb->ip_hdr->tos; ++#endif /* NET_21 */ ++ break; ++ case 1: ++ ixs->iph->tos = 0; ++ break; ++ default: ++ break; ++ } ++#ifdef NET_21 ++#ifdef NETDEV_23 ++ ixs->iph->ttl = sysctl_ip_default_ttl; ++#else /* NETDEV_23 */ ++ ixs->iph->ttl = ip_statistics.IpDefaultTTL; ++#endif /* NETDEV_23 */ ++#else /* NET_21 */ ++ ixs->iph->ttl = 64; /* ip_statistics.IpDefaultTTL; */ ++#endif /* NET_21 */ ++ ixs->iph->frag_off = 0; ++ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr; ++ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr; ++ ixs->iph->protocol = IPPROTO_IPIP; ++ ixs->iph->ihl = sizeof(struct iphdr) >> 2; ++ ++ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb); ++ ++ ixs->newdst = (__u32)ixs->iph->daddr; ++ ixs->newsrc = (__u32)ixs->iph->saddr; ++ ++#ifdef NET_21 ++ ixs->skb->h.ipiph = ixs->skb->nh.iph; ++#endif /* NET_21 */ ++ return IPSEC_XMIT_OK; ++} ++ ++struct xform_functions ipip_xform_funcs[]={ ++ { rcv_checks: NULL, ++ rcv_setup_auth: NULL, ++ rcv_calc_auth: NULL, ++ rcv_decrypt: NULL, ++ ++ xmit_setup: ipsec_xmit_ipip_setup, ++ xmit_headroom: sizeof(struct iphdr), ++ xmit_needtailroom: 0, ++ }, ++}; ++ ++ ++ ++ ++ ++ ++ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_life.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,263 @@ ++/* ++ * @(#) lifetime structure utilities ++ * ++ * Copyright (C) 2001 Richard Guy Briggs ++ * and Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_life.c,v 1.12 2004/04/23 20:44:35 ken Exp $ ++ * ++ */ ++ ++/* ++ * This provides series of utility functions for dealing with lifetime ++ * structures. ++ * ++ * ipsec_check_lifetime - returns -1 hard lifetime exceeded ++ * 0 soft lifetime exceeded ++ * 1 everything is okay ++ * based upon whether or not the count exceeds hard/soft ++ * ++ */ ++ ++#define __NO_VERSION__ ++#include ++#include /* for CONFIG_IP_FORWARD */ ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#include /* struct device, struct net_device_stats and other headers */ ++#include /* eth_type_trans */ ++#include ++#include ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_life.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_eroute.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_radij.h" ++ ++#include "openswan/ipsec_sa.h" ++#include "openswan/ipsec_tunnel.h" ++#include "openswan/ipsec_ipe4.h" ++#include "openswan/ipsec_ah.h" ++#include "openswan/ipsec_esp.h" ++ ++#ifdef CONFIG_IPSEC_IPCOMP ++#include "openswan/ipcomp.h" ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ ++#include ++#include ++ ++#include "openswan/ipsec_proto.h" ++ ++ ++enum ipsec_life_alive ++ipsec_lifetime_check(struct ipsec_lifetime64 *il64, ++ const char *lifename, ++ const char *saname, ++ enum ipsec_life_type ilt, ++ enum ipsec_direction idir, ++ struct ipsec_sa *ips) ++{ ++ __u64 count; ++ const char *dir; ++ ++ if(saname == NULL) { ++ saname = "unknown-SA"; ++ } ++ ++ if(idir == ipsec_incoming) { ++ dir = "incoming"; ++ } else { ++ dir = "outgoing"; ++ } ++ ++ ++ if(ilt == ipsec_life_timebased) { ++ count = jiffies/HZ - il64->ipl_count; ++ } else { ++ count = il64->ipl_count; ++ } ++ ++ if(il64->ipl_hard && ++ (count > il64->ipl_hard)) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_lifetime_check: " ++ "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, " ++ "%s packet dropped.\n", ++ lifename, ++ IPS_XFORM_NAME(ips), ++ saname, ++ dir); ++ ++ pfkey_expire(ips, 1); ++ return ipsec_life_harddied; ++ } ++ ++ if(il64->ipl_soft && ++ (count > il64->ipl_soft)) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_lifetime_check: " ++ "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, " ++ "soft expire message sent up, %s packet still processed.\n", ++ lifename, ++ IPS_XFORM_NAME(ips), ++ saname, ++ dir); ++ ++ if(ips->ips_state != SADB_SASTATE_DYING) { ++ pfkey_expire(ips, 0); ++ } ++ ips->ips_state = SADB_SASTATE_DYING; ++ ++ return ipsec_life_softdied; ++ } ++ return ipsec_life_okay; ++} ++ ++ ++/* ++ * This function takes a buffer (with length), a lifetime name and type, ++ * and formats a string to represent the current values of the lifetime. ++ * ++ * It returns the number of bytes that the format took (or would take, ++ * if the buffer were large enough: snprintf semantics). ++ * This is used in /proc routines and in debug output. ++ */ ++int ++ipsec_lifetime_format(char *buffer, ++ int buflen, ++ char *lifename, ++ enum ipsec_life_type timebaselife, ++ struct ipsec_lifetime64 *lifetime) ++{ ++ int len = 0; ++ __u64 count; ++ ++ if(timebaselife == ipsec_life_timebased) { ++ count = jiffies/HZ - lifetime->ipl_count; ++ } else { ++ count = lifetime->ipl_count; ++ } ++ ++ if(lifetime->ipl_count > 1 || ++ lifetime->ipl_soft || ++ lifetime->ipl_hard) { ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) ++ len = ipsec_snprintf(buffer, buflen, ++ "%s(%Lu,%Lu,%Lu)", ++ lifename, ++ count, ++ lifetime->ipl_soft, ++ lifetime->ipl_hard); ++#else /* XXX high 32 bits are not displayed */ ++ len = ipsec_snprintf(buffer, buflen, ++ "%s(%lu,%lu,%lu)", ++ lifename, ++ (unsigned long)count, ++ (unsigned long)lifetime->ipl_soft, ++ (unsigned long)lifetime->ipl_hard); ++#endif ++ } ++ ++ return len; ++} ++ ++void ++ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime, ++ __u64 newvalue) ++{ ++ if(newvalue && ++ (!lifetime->ipl_hard || ++ (newvalue < lifetime->ipl_hard))) { ++ lifetime->ipl_hard = newvalue; ++ ++ if(!lifetime->ipl_soft && ++ (lifetime->ipl_hard < lifetime->ipl_soft)) { ++ lifetime->ipl_soft = lifetime->ipl_hard; ++ } ++ } ++} ++ ++void ++ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime, ++ __u64 newvalue) ++{ ++ if(newvalue && ++ (!lifetime->ipl_soft || ++ (newvalue < lifetime->ipl_soft))) { ++ lifetime->ipl_soft = newvalue; ++ ++ if(lifetime->ipl_hard && ++ (lifetime->ipl_hard < lifetime->ipl_soft)) { ++ lifetime->ipl_soft = lifetime->ipl_hard; ++ } ++ } ++} ++ ++ ++/* ++ * $Log: ipsec_life.c,v $ ++ * Revision 1.12 2004/04/23 20:44:35 ken ++ * Update comments ++ * ++ * Revision 1.11 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.10 2004/03/30 11:03:10 paul ++ * two more occurances of snprintf, found by Sam from a users oops msg. ++ * ++ * Revision 1.9 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.8.4.1 2003/10/29 01:30:41 mcr ++ * elimited "struct sa_id". ++ * ++ * Revision 1.8 2003/02/06 02:00:10 rgb ++ * Fixed incorrect debugging text label ++ * ++ * Revision 1.7 2002/05/23 07:16:26 rgb ++ * Fixed absolute/relative reference to lifetime count printout. ++ * ++ * Revision 1.6 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.5 2002/04/24 07:36:28 mcr ++ * Moved from ./klips/net/ipsec/ipsec_life.c,v ++ * ++ * Revision 1.4 2002/01/29 17:17:55 mcr ++ * moved include of ipsec_param.h to after include of linux/kernel.h ++ * otherwise, it seems that some option that is set in ipsec_param.h ++ * screws up something subtle in the include path to kernel.h, and ++ * it complains on the snprintf() prototype. ++ * ++ * Revision 1.3 2002/01/29 02:13:17 mcr ++ * introduction of ipsec_kversion.h means that include of ++ * ipsec_param.h must preceed any decisions about what files to ++ * include to deal with differences in kernel source. ++ * ++ * Revision 1.2 2001/11/26 09:16:14 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr ++ * lifetime structure created and common functions created. ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_mast.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,1080 @@ ++/* ++ * IPSEC MAST code. ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ */ ++ ++char ipsec_mast_c_version[] = "RCSID $Id: ipsec_mast.c,v 1.3 2003/10/31 02:27:55 mcr Exp $"; ++ ++#define __NO_VERSION__ ++#include ++#include /* for CONFIG_IP_FORWARD */ ++#include ++#include /* printk() */ ++ ++#include "freeswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include /* struct tcphdr */ ++#include /* struct udphdr */ ++#include ++#include ++#include ++#include ++#include ++#undef dev_kfree_skb ++#define dev_kfree_skb(a,b) kfree_skb(a) ++#define PHYSDEV_TYPE ++#include ++#include /* icmp_send() */ ++#include ++#include ++ ++#include ++ ++#include "freeswan/radij.h" ++#include "freeswan/ipsec_life.h" ++#include "freeswan/ipsec_xform.h" ++#include "freeswan/ipsec_eroute.h" ++#include "freeswan/ipsec_encap.h" ++#include "freeswan/ipsec_radij.h" ++#include "freeswan/ipsec_sa.h" ++#include "freeswan/ipsec_tunnel.h" ++#include "freeswan/ipsec_mast.h" ++#include "freeswan/ipsec_ipe4.h" ++#include "freeswan/ipsec_ah.h" ++#include "freeswan/ipsec_esp.h" ++ ++#include ++#include ++ ++#include "freeswan/ipsec_proto.h" ++ ++int ipsec_maxdevice_count = -1; ++ ++DEBUG_NO_STATIC int ++ipsec_mast_open(struct device *dev) ++{ ++ struct ipsecpriv *prv = dev->priv; ++ ++ /* ++ * Can't open until attached. ++ */ ++ ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_open: " ++ "dev = %s, prv->dev = %s\n", ++ dev->name, prv->dev?prv->dev->name:"NONE"); ++ ++ if (prv->dev == NULL) ++ return -ENODEV; ++ ++ MOD_INC_USE_COUNT; ++ return 0; ++} ++ ++DEBUG_NO_STATIC int ++ipsec_mast_close(struct device *dev) ++{ ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++static inline int ipsec_mast_xmit2(struct sk_buff *skb) ++{ ++ return ip_send(skb); ++} ++ ++enum ipsec_xmit_value ++ipsec_mast_send(struct ipsec_xmit_state*ixs) ++{ ++ /* new route/dst cache code from James Morris */ ++ ixs->skb->dev = ixs->physdev; ++ /*skb_orphan(ixs->skb);*/ ++ if((ixs->error = ip_route_output(&ixs->route, ++ ixs->skb->nh.iph->daddr, ++ ixs->pass ? 0 : ixs->skb->nh.iph->saddr, ++ RT_TOS(ixs->skb->nh.iph->tos), ++ ixs->physdev->iflink /* rgb: should this be 0? */))) { ++ ixs->stats->tx_errors++; ++ KLIPS_PRINT(debug_mast & DB_MAST_XMIT, ++ "klips_debug:ipsec_xmit_send: " ++ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n", ++ ixs->error, ++ ixs->route->u.dst.dev->name); ++ return IPSEC_XMIT_ROUTEERR; ++ } ++ if(ixs->dev == ixs->route->u.dst.dev) { ++ ip_rt_put(ixs->route); ++ /* This is recursion, drop it. */ ++ ixs->stats->tx_errors++; ++ KLIPS_PRINT(debug_mast & DB_MAST_XMIT, ++ "klips_debug:ipsec_xmit_send: " ++ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n", ++ ixs->dev->name); ++ return IPSEC_XMIT_RECURSDETECT; ++ } ++ dst_release(ixs->skb->dst); ++ ixs->skb->dst = &ixs->route->u.dst; ++ ixs->stats->tx_bytes += ixs->skb->len; ++ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) { ++ ixs->stats->tx_errors++; ++ printk(KERN_WARNING ++ "klips_error:ipsec_xmit_send: " ++ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n", ++ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data), ++ ixs->skb->len); ++ return IPSEC_XMIT_PUSHPULLERR; ++ } ++ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data); ++#ifdef SKB_RESET_NFCT ++ nf_conntrack_put(ixs->skb->nfct); ++ ixs->skb->nfct = NULL; ++#ifdef CONFIG_NETFILTER_DEBUG ++ ixs->skb->nf_debug = 0; ++#endif /* CONFIG_NETFILTER_DEBUG */ ++#endif /* SKB_RESET_NFCT */ ++ KLIPS_PRINT(debug_mast & DB_MAST_XMIT, ++ "klips_debug:ipsec_xmit_send: " ++ "...done, calling ip_send() on device:%s\n", ++ ixs->skb->dev ? ixs->skb->dev->name : "NULL"); ++ KLIPS_IP_PRINT(debug_mast & DB_MAST_XMIT, ixs->skb->nh.iph); ++ { ++ int err; ++ ++ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev, ++ ipsec_mast_xmit2); ++ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) { ++ if(net_ratelimit()) ++ printk(KERN_ERR ++ "klips_error:ipsec_xmit_send: " ++ "ip_send() failed, err=%d\n", ++ -err); ++ ixs->stats->tx_errors++; ++ ixs->stats->tx_aborted_errors++; ++ ixs->skb = NULL; ++ return IPSEC_XMIT_IPSENDFAILURE; ++ } ++ } ++ ixs->stats->tx_packets++; ++ ++ ixs->skb = NULL; ++ ++ return IPSEC_XMIT_OK; ++} ++ ++void ++ipsec_mast_cleanup(struct ipsec_xmit_state*ixs) ++{ ++#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) ++ netif_wake_queue(ixs->dev); ++#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ ++ ixs->dev->tbusy = 0; ++#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ ++ if(ixs->saved_header) { ++ kfree(ixs->saved_header); ++ } ++ if(ixs->skb) { ++ dev_kfree_skb(ixs->skb, FREE_WRITE); ++ } ++ if(ixs->oskb) { ++ dev_kfree_skb(ixs->oskb, FREE_WRITE); ++ } ++ if (ixs->ips.ips_ident_s.data) { ++ kfree(ixs->ips.ips_ident_s.data); ++ } ++ if (ixs->ips.ips_ident_d.data) { ++ kfree(ixs->ips.ips_ident_d.data); ++ } ++} ++ ++#if 0 ++/* ++ * This function assumes it is being called from dev_queue_xmit() ++ * and that skb is filled properly by that function. ++ */ ++int ++ipsec_mast_start_xmit(struct sk_buff *skb, struct device *dev, IPsecSAref_t SAref) ++{ ++ struct ipsec_xmit_state ixs_mem; ++ struct ipsec_xmit_state *ixs = &ixs_mem; ++ enum ipsec_xmit_value stat = IPSEC_XMIT_OK; ++ ++ /* dev could be a mast device, but should be optional, I think... */ ++ /* SAref is also optional, but one of the two must be present. */ ++ /* I wonder if it could accept no device or saref and guess? */ ++ ++/* ipsec_xmit_sanity_check_dev(ixs); */ ++ ++ ipsec_xmit_sanity_check_skb(ixs); ++ ++ ipsec_xmit_adjust_hard_header(ixs); ++ ++ stat = ipsec_xmit_encap_bundle(ixs); ++ if(stat != IPSEC_XMIT_OK) { ++ /* SA processing failed */ ++ } ++ ++ ipsec_xmit_hard_header_restore(); ++} ++#endif ++ ++DEBUG_NO_STATIC struct net_device_stats * ++ipsec_mast_get_stats(struct device *dev) ++{ ++ return &(((struct ipsecpriv *)(dev->priv))->mystats); ++} ++ ++/* ++ * Revectored calls. ++ * For each of these calls, a field exists in our private structure. ++ */ ++ ++DEBUG_NO_STATIC int ++ipsec_mast_hard_header(struct sk_buff *skb, struct device *dev, ++ unsigned short type, void *daddr, void *saddr, unsigned len) ++{ ++ struct ipsecpriv *prv = dev->priv; ++ struct device *tmp; ++ int ret; ++ struct net_device_stats *stats; /* This device's statistics */ ++ ++ if(skb == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_hard_header: " ++ "no skb...\n"); ++ return -ENODATA; ++ } ++ ++ if(dev == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_hard_header: " ++ "no device...\n"); ++ return -ENODEV; ++ } ++ ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_hard_header: " ++ "skb->dev=%s dev=%s.\n", ++ skb->dev ? skb->dev->name : "NULL", ++ dev->name); ++ ++ if(prv == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_hard_header: " ++ "no private space associated with dev=%s\n", ++ dev->name ? dev->name : "NULL"); ++ return -ENODEV; ++ } ++ ++ stats = (struct net_device_stats *) &(prv->mystats); ++ ++ if(prv->dev == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_hard_header: " ++ "no physical device associated with dev=%s\n", ++ dev->name ? dev->name : "NULL"); ++ stats->tx_dropped++; ++ return -ENODEV; ++ } ++ ++ /* check if we have to send a IPv6 packet. It might be a Router ++ Solicitation, where the building of the packet happens in ++ reverse order: ++ 1. ll hdr, ++ 2. IPv6 hdr, ++ 3. ICMPv6 hdr ++ -> skb->nh.raw is still uninitialized when this function is ++ called!! If this is no IPv6 packet, we can print debugging ++ messages, otherwise we skip all debugging messages and just ++ build the ll header */ ++ if(type != ETH_P_IPV6) { ++ /* execute this only, if we don't have to build the ++ header for a IPv6 packet */ ++ if(!prv->hard_header) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_hard_header: " ++ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ", ++ saddr, ++ daddr, ++ len, ++ type, ++ dev->name); ++ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC, ++ "ip=%08x->%08x\n", ++ (__u32)ntohl(skb->nh.iph->saddr), ++ (__u32)ntohl(skb->nh.iph->daddr) ); ++ stats->tx_dropped++; ++ return -ENODEV; ++ } ++ ++#define da ((struct device *)(prv->dev))->dev_addr ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_hard_header: " ++ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ", ++ saddr, ++ daddr, ++ len, ++ type, ++ dev->name, ++ prv->dev->name, ++ da[0], da[1], da[2], da[3], da[4], da[5]); ++ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC, ++ "ip=%08x->%08x\n", ++ (__u32)ntohl(skb->nh.iph->saddr), ++ (__u32)ntohl(skb->nh.iph->daddr) ); ++ } else { ++ KLIPS_PRINT(debug_mast, ++ "klips_debug:ipsec_mast_hard_header: " ++ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n"); ++ } ++ tmp = skb->dev; ++ skb->dev = prv->dev; ++ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len); ++ skb->dev = tmp; ++ return ret; ++} ++ ++DEBUG_NO_STATIC int ++ipsec_mast_rebuild_header(struct sk_buff *skb) ++{ ++ struct ipsecpriv *prv = skb->dev->priv; ++ struct device *tmp; ++ int ret; ++ struct net_device_stats *stats; /* This device's statistics */ ++ ++ if(skb->dev == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_rebuild_header: " ++ "no device..."); ++ return -ENODEV; ++ } ++ ++ if(prv == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_rebuild_header: " ++ "no private space associated with dev=%s", ++ skb->dev->name ? skb->dev->name : "NULL"); ++ return -ENODEV; ++ } ++ ++ stats = (struct net_device_stats *) &(prv->mystats); ++ ++ if(prv->dev == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_rebuild_header: " ++ "no physical device associated with dev=%s", ++ skb->dev->name ? skb->dev->name : "NULL"); ++ stats->tx_dropped++; ++ return -ENODEV; ++ } ++ ++ if(!prv->rebuild_header) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_rebuild_header: " ++ "physical device has been detached, packet dropped skb->dev=%s->NULL ", ++ skb->dev->name); ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "ip=%08x->%08x\n", ++ (__u32)ntohl(skb->nh.iph->saddr), ++ (__u32)ntohl(skb->nh.iph->daddr) ); ++ stats->tx_dropped++; ++ return -ENODEV; ++ } ++ ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast: " ++ "Revectored rebuild_header dev=%s->%s ", ++ skb->dev->name, prv->dev->name); ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "ip=%08x->%08x\n", ++ (__u32)ntohl(skb->nh.iph->saddr), ++ (__u32)ntohl(skb->nh.iph->daddr) ); ++ tmp = skb->dev; ++ skb->dev = prv->dev; ++ ++ ret = prv->rebuild_header(skb); ++ skb->dev = tmp; ++ return ret; ++} ++ ++DEBUG_NO_STATIC int ++ipsec_mast_set_mac_address(struct device *dev, void *addr) ++{ ++ struct ipsecpriv *prv = dev->priv; ++ ++ struct net_device_stats *stats; /* This device's statistics */ ++ ++ if(dev == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_set_mac_address: " ++ "no device..."); ++ return -ENODEV; ++ } ++ ++ if(prv == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_set_mac_address: " ++ "no private space associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ return -ENODEV; ++ } ++ ++ stats = (struct net_device_stats *) &(prv->mystats); ++ ++ if(prv->dev == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_set_mac_address: " ++ "no physical device associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ stats->tx_dropped++; ++ return -ENODEV; ++ } ++ ++ if(!prv->set_mac_address) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_set_mac_address: " ++ "physical device has been detached, cannot set - skb->dev=%s->NULL\n", ++ dev->name); ++ return -ENODEV; ++ } ++ ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_set_mac_address: " ++ "Revectored dev=%s->%s addr=0p%p\n", ++ dev->name, prv->dev->name, addr); ++ return prv->set_mac_address(prv->dev, addr); ++ ++} ++ ++DEBUG_NO_STATIC void ++ipsec_mast_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr) ++{ ++ struct ipsecpriv *prv = dev->priv; ++ ++ struct net_device_stats *stats; /* This device's statistics */ ++ ++ if(dev == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_cache_update: " ++ "no device..."); ++ return; ++ } ++ ++ if(prv == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_cache_update: " ++ "no private space associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ return; ++ } ++ ++ stats = (struct net_device_stats *) &(prv->mystats); ++ ++ if(prv->dev == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_cache_update: " ++ "no physical device associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ stats->tx_dropped++; ++ return; ++ } ++ ++ if(!prv->header_cache_update) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_cache_update: " ++ "physical device has been detached, cannot set - skb->dev=%s->NULL\n", ++ dev->name); ++ return; ++ } ++ ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast: " ++ "Revectored cache_update\n"); ++ prv->header_cache_update(hh, prv->dev, haddr); ++ return; ++} ++ ++DEBUG_NO_STATIC int ++ipsec_mast_neigh_setup(struct neighbour *n) ++{ ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_neigh_setup:\n"); ++ ++ if (n->nud_state == NUD_NONE) { ++ n->ops = &arp_broken_ops; ++ n->output = n->ops->output; ++ } ++ return 0; ++} ++ ++DEBUG_NO_STATIC int ++ipsec_mast_neigh_setup_dev(struct device *dev, struct neigh_parms *p) ++{ ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_neigh_setup_dev: " ++ "setting up %s\n", ++ dev ? dev->name : "NULL"); ++ ++ if (p->tbl->family == AF_INET) { ++ p->neigh_setup = ipsec_mast_neigh_setup; ++ p->ucast_probes = 0; ++ p->mcast_probes = 0; ++ } ++ return 0; ++} ++ ++/* ++ * We call the attach routine to attach another device. ++ */ ++ ++DEBUG_NO_STATIC int ++ipsec_mast_attach(struct device *dev, struct device *physdev) ++{ ++ int i; ++ struct ipsecpriv *prv = dev->priv; ++ ++ if(dev == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_attach: " ++ "no device..."); ++ return -ENODEV; ++ } ++ ++ if(prv == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_attach: " ++ "no private space associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ return -ENODATA; ++ } ++ ++ prv->dev = physdev; ++ prv->hard_start_xmit = physdev->hard_start_xmit; ++ prv->get_stats = physdev->get_stats; ++ ++ if (physdev->hard_header) { ++ prv->hard_header = physdev->hard_header; ++ dev->hard_header = ipsec_mast_hard_header; ++ } else ++ dev->hard_header = NULL; ++ ++ if (physdev->rebuild_header) { ++ prv->rebuild_header = physdev->rebuild_header; ++ dev->rebuild_header = ipsec_mast_rebuild_header; ++ } else ++ dev->rebuild_header = NULL; ++ ++ if (physdev->set_mac_address) { ++ prv->set_mac_address = physdev->set_mac_address; ++ dev->set_mac_address = ipsec_mast_set_mac_address; ++ } else ++ dev->set_mac_address = NULL; ++ ++ if (physdev->header_cache_update) { ++ prv->header_cache_update = physdev->header_cache_update; ++ dev->header_cache_update = ipsec_mast_cache_update; ++ } else ++ dev->header_cache_update = NULL; ++ ++ dev->hard_header_len = physdev->hard_header_len; ++ ++/* prv->neigh_setup = physdev->neigh_setup; */ ++ dev->neigh_setup = ipsec_mast_neigh_setup_dev; ++ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */ ++ prv->mtu = physdev->mtu; ++ ++#ifdef PHYSDEV_TYPE ++ dev->type = physdev->type; /* ARPHRD_MAST; */ ++#endif /* PHYSDEV_TYPE */ ++ ++ dev->addr_len = physdev->addr_len; ++ for (i=0; iaddr_len; i++) { ++ dev->dev_addr[i] = physdev->dev_addr[i]; ++ } ++#ifdef CONFIG_IPSEC_DEBUG ++ if(debug_mast & DB_MAST_INIT) { ++ printk(KERN_INFO "klips_debug:ipsec_mast_attach: " ++ "physical device %s being attached has HW address: %2x", ++ physdev->name, physdev->dev_addr[0]); ++ for (i=1; i < physdev->addr_len; i++) { ++ printk(":%02x", physdev->dev_addr[i]); ++ } ++ printk("\n"); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ return 0; ++} ++ ++/* ++ * We call the detach routine to detach the ipsec mast from another device. ++ */ ++ ++DEBUG_NO_STATIC int ++ipsec_mast_detach(struct device *dev) ++{ ++ int i; ++ struct ipsecpriv *prv = dev->priv; ++ ++ if(dev == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_detach: " ++ "no device..."); ++ return -ENODEV; ++ } ++ ++ if(prv == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_REVEC, ++ "klips_debug:ipsec_mast_detach: " ++ "no private space associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ return -ENODATA; ++ } ++ ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_detach: " ++ "physical device %s being detached from virtual device %s\n", ++ prv->dev ? prv->dev->name : "NULL", ++ dev->name); ++ ++ prv->dev = NULL; ++ prv->hard_start_xmit = NULL; ++ prv->get_stats = NULL; ++ ++ prv->hard_header = NULL; ++#ifdef DETACH_AND_DOWN ++ dev->hard_header = NULL; ++#endif /* DETACH_AND_DOWN */ ++ ++ prv->rebuild_header = NULL; ++#ifdef DETACH_AND_DOWN ++ dev->rebuild_header = NULL; ++#endif /* DETACH_AND_DOWN */ ++ ++ prv->set_mac_address = NULL; ++#ifdef DETACH_AND_DOWN ++ dev->set_mac_address = NULL; ++#endif /* DETACH_AND_DOWN */ ++ ++ prv->header_cache_update = NULL; ++#ifdef DETACH_AND_DOWN ++ dev->header_cache_update = NULL; ++#endif /* DETACH_AND_DOWN */ ++ ++#ifdef DETACH_AND_DOWN ++ dev->neigh_setup = NULL; ++#endif /* DETACH_AND_DOWN */ ++ ++ dev->hard_header_len = 0; ++#ifdef DETACH_AND_DOWN ++ dev->mtu = 0; ++#endif /* DETACH_AND_DOWN */ ++ prv->mtu = 0; ++ for (i=0; idev_addr[i] = 0; ++ } ++ dev->addr_len = 0; ++#ifdef PHYSDEV_TYPE ++ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */ ++#endif /* PHYSDEV_TYPE */ ++ ++ return 0; ++} ++ ++/* ++ * We call the clear routine to detach all ipsec masts from other devices. ++ */ ++DEBUG_NO_STATIC int ++ipsec_mast_clear(void) ++{ ++ int i; ++ struct device *ipsecdev = NULL, *prvdev; ++ struct ipsecpriv *prv; ++ char name[9]; ++ int ret; ++ ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_clear: .\n"); ++ ++ for(i = 0; i < IPSEC_NUM_IF; i++) { ++ sprintf(name, IPSEC_DEV_FORMAT, i); ++ if((ipsecdev = ipsec_dev_get(name)) != NULL) { ++ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) { ++ prvdev = (struct device *)(prv->dev); ++ if(prvdev) { ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_clear: " ++ "physical device for device %s is %s\n", ++ name, prvdev->name); ++ if((ret = ipsec_mast_detach(ipsecdev))) { ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_clear: " ++ "error %d detatching device %s from device %s.\n", ++ ret, name, prvdev->name); ++ return ret; ++ } ++ } ++ } ++ } ++ } ++ return 0; ++} ++ ++DEBUG_NO_STATIC int ++ipsec_mast_ioctl(struct device *dev, struct ifreq *ifr, int cmd) ++{ ++ struct ipsecmastconf *cf = (struct ipsecmastconf *)&ifr->ifr_data; ++ struct ipsecpriv *prv = dev->priv; ++ struct device *them; /* physical device */ ++#ifdef CONFIG_IP_ALIAS ++ char *colon; ++ char realphysname[IFNAMSIZ]; ++#endif /* CONFIG_IP_ALIAS */ ++ ++ if(dev == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_ioctl: " ++ "device not supplied.\n"); ++ return -ENODEV; ++ } ++ ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_ioctl: " ++ "tncfg service call #%d for dev=%s\n", ++ cmd, ++ dev->name ? dev->name : "NULL"); ++ switch (cmd) { ++ /* attach a virtual ipsec? device to a physical device */ ++ case IPSEC_SET_DEV: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_ioctl: " ++ "calling ipsec_mast_attatch...\n"); ++#ifdef CONFIG_IP_ALIAS ++ /* If this is an IP alias interface, get its real physical name */ ++ strncpy(realphysname, cf->cf_name, IFNAMSIZ); ++ realphysname[IFNAMSIZ-1] = 0; ++ colon = strchr(realphysname, ':'); ++ if (colon) *colon = 0; ++ them = ipsec_dev_get(realphysname); ++#else /* CONFIG_IP_ALIAS */ ++ them = ipsec_dev_get(cf->cf_name); ++#endif /* CONFIG_IP_ALIAS */ ++ ++ if (them == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_ioctl: " ++ "physical device %s requested is null\n", ++ cf->cf_name); ++ return -ENXIO; ++ } ++ ++#if 0 ++ if (them->flags & IFF_UP) { ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_ioctl: " ++ "physical device %s requested is not up.\n", ++ cf->cf_name); ++ return -ENXIO; ++ } ++#endif ++ ++ if (prv && prv->dev) { ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_ioctl: " ++ "virtual device is already connected to %s.\n", ++ prv->dev->name ? prv->dev->name : "NULL"); ++ return -EBUSY; ++ } ++ return ipsec_mast_attach(dev, them); ++ ++ case IPSEC_DEL_DEV: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_ioctl: " ++ "calling ipsec_mast_detatch.\n"); ++ if (! prv->dev) { ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_ioctl: " ++ "physical device not connected.\n"); ++ return -ENODEV; ++ } ++ return ipsec_mast_detach(dev); ++ ++ case IPSEC_CLR_DEV: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_ioctl: " ++ "calling ipsec_mast_clear.\n"); ++ return ipsec_mast_clear(); ++ ++ default: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_ioctl: " ++ "unknown command %d.\n", ++ cmd); ++ return -EOPNOTSUPP; ++ } ++} ++ ++int ++ipsec_mast_device_event(struct notifier_block *unused, unsigned long event, void *ptr) ++{ ++ struct device *dev = ptr; ++ struct device *ipsec_dev; ++ struct ipsecpriv *priv; ++ char name[9]; ++ int i; ++ ++ if (dev == NULL) { ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "dev=NULL for event type %ld.\n", ++ event); ++ return(NOTIFY_DONE); ++ } ++ ++ /* check for loopback devices */ ++ if (dev && (dev->flags & IFF_LOOPBACK)) { ++ return(NOTIFY_DONE); ++ } ++ ++ switch (event) { ++ case NETDEV_DOWN: ++ /* look very carefully at the scope of these compiler ++ directives before changing anything... -- RGB */ ++ ++ case NETDEV_UNREGISTER: ++ switch (event) { ++ case NETDEV_DOWN: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "NETDEV_DOWN dev=%s flags=%x\n", ++ dev->name, ++ dev->flags); ++ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) { ++ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n", ++ dev->name); ++ } ++ break; ++ case NETDEV_UNREGISTER: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "NETDEV_UNREGISTER dev=%s flags=%x\n", ++ dev->name, ++ dev->flags); ++ break; ++ } ++ ++ /* find the attached physical device and detach it. */ ++ for(i = 0; i < IPSEC_NUM_IF; i++) { ++ sprintf(name, IPSEC_DEV_FORMAT, i); ++ ipsec_dev = ipsec_dev_get(name); ++ if(ipsec_dev) { ++ priv = (struct ipsecpriv *)(ipsec_dev->priv); ++ if(priv) { ++ ; ++ if(((struct device *)(priv->dev)) == dev) { ++ /* dev_close(ipsec_dev); */ ++ /* return */ ipsec_mast_detach(ipsec_dev); ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "device '%s' has been detached.\n", ++ ipsec_dev->name); ++ break; ++ } ++ } else { ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "device '%s' has no private data space!\n", ++ ipsec_dev->name); ++ } ++ } ++ } ++ break; ++ case NETDEV_UP: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "NETDEV_UP dev=%s\n", ++ dev->name); ++ break; ++ case NETDEV_REBOOT: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "NETDEV_REBOOT dev=%s\n", ++ dev->name); ++ break; ++ case NETDEV_CHANGE: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "NETDEV_CHANGE dev=%s flags=%x\n", ++ dev->name, ++ dev->flags); ++ break; ++ case NETDEV_REGISTER: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "NETDEV_REGISTER dev=%s\n", ++ dev->name); ++ break; ++ case NETDEV_CHANGEMTU: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n", ++ dev->name, ++ dev->mtu); ++ break; ++ case NETDEV_CHANGEADDR: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "NETDEV_CHANGEADDR dev=%s\n", ++ dev->name); ++ break; ++ case NETDEV_GOING_DOWN: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "NETDEV_GOING_DOWN dev=%s\n", ++ dev->name); ++ break; ++ case NETDEV_CHANGENAME: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "NETDEV_CHANGENAME dev=%s\n", ++ dev->name); ++ break; ++ default: ++ KLIPS_PRINT(debug_mast & DB_MAST_INIT, ++ "klips_debug:ipsec_mast_device_event: " ++ "event type %ld unrecognised for dev=%s\n", ++ event, ++ dev->name); ++ break; ++ } ++ return NOTIFY_DONE; ++} ++ ++/* ++ * Called when an ipsec mast device is initialized. ++ * The ipsec mast device structure is passed to us. ++ */ ++ ++int ++ipsec_mast_init(struct device *dev) ++{ ++ int i; ++ ++ KLIPS_PRINT(debug_mast, ++ "klips_debug:ipsec_mast_init: " ++ "allocating %lu bytes initialising device: %s\n", ++ (unsigned long) sizeof(struct ipsecpriv), ++ dev->name ? dev->name : "NULL"); ++ ++ /* Add our mast functions to the device */ ++ dev->open = ipsec_mast_open; ++ dev->stop = ipsec_mast_close; ++ dev->hard_start_xmit = ipsec_mast_start_xmit; ++ dev->get_stats = ipsec_mast_get_stats; ++ ++ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL); ++ if (dev->priv == NULL) ++ return -ENOMEM; ++ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv)); ++ ++ for(i = 0; i < sizeof(zeroes); i++) { ++ ((__u8*)(zeroes))[i] = 0; ++ } ++ ++ dev->set_multicast_list = NULL; ++ dev->do_ioctl = ipsec_mast_ioctl; ++ dev->hard_header = NULL; ++ dev->rebuild_header = NULL; ++ dev->set_mac_address = NULL; ++ dev->header_cache_update= NULL; ++ dev->neigh_setup = ipsec_mast_neigh_setup_dev; ++ dev->hard_header_len = 0; ++ dev->mtu = 0; ++ dev->addr_len = 0; ++ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */ /* ARPHRD_ETHER; */ ++ dev->tx_queue_len = 10; /* Small queue */ ++ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */ ++ ++ /* New-style flags. */ ++ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */; ++ dev_init_buffers(dev); ++ ++ /* We're done. Have I forgotten anything? */ ++ return 0; ++} ++ ++/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ++/* Module specific interface (but it links with the rest of IPSEC) */ ++/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ++ ++int ++ipsec_mast_probe(struct device *dev) ++{ ++ ipsec_mast_init(dev); ++ return 0; ++} ++ ++int ++ipsec_mast_init_devices(void) ++{ ++ return 0; ++} ++ ++/* void */ ++int ++ipsec_mast_cleanup_devices(void) ++{ ++ int error = 0; ++ int i; ++ char name[10]; ++ struct device *dev_mast; ++ ++ for(i = 0; i < ipsec_mastdevice_count; i++) { ++ sprintf(name, MAST_DEV_FORMAT, i); ++ if((dev_mast = ipsec_dev_get(name)) == NULL) { ++ break; ++ } ++ unregister_netdev(dev_mast); ++ kfree(dev_mast->priv); ++ dev_mast->priv=NULL; ++ } ++ return error; ++} ++ ++/* ++ * $Log: ipsec_mast.c,v $ ++ * Revision 1.3 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.2.4.1 2003/10/29 01:30:41 mcr ++ * elimited "struct sa_id". ++ * ++ * Revision 1.2 2003/06/22 20:06:17 mcr ++ * refactored mast code still had lots of ipsecX junk in it. ++ * ++ * Revision 1.1 2003/02/12 19:31:12 rgb ++ * Refactored from ipsec_tunnel.c ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_md5c.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,448 @@ ++/* ++ * RCSID $Id: ipsec_md5c.c,v 1.8 2004/04/06 02:49:26 mcr Exp $ ++ */ ++ ++/* ++ * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic ++ * changes to accomodate it in the kernel by ji. ++ */ ++ ++#include ++#include ++ ++#include "openswan/ipsec_md5h.h" ++ ++/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm ++ */ ++ ++/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All ++rights reserved. ++ ++License to copy and use this software is granted provided that it ++is identified as the "RSA Data Security, Inc. MD5 Message-Digest ++Algorithm" in all material mentioning or referencing this software ++or this function. ++ ++License is also granted to make and use derivative works provided ++that such works are identified as "derived from the RSA Data ++Security, Inc. MD5 Message-Digest Algorithm" in all material ++mentioning or referencing the derived work. ++ ++RSA Data Security, Inc. makes no representations concerning either ++the merchantability of this software or the suitability of this ++software for any particular purpose. It is provided "as is" ++without express or implied warranty of any kind. ++ ++These notices must be retained in any copies of any part of this ++documentation and/or software. ++ */ ++ ++/* ++ * Additions by JI ++ * ++ * HAVEMEMCOPY is defined if mem* routines are available ++ * ++ * HAVEHTON is defined if htons() and htonl() can be used ++ * for big/little endian conversions ++ * ++ */ ++ ++#define HAVEMEMCOPY ++#ifdef __LITTLE_ENDIAN ++#define LITTLENDIAN ++#endif ++#ifdef __BIG_ENDIAN ++#define BIGENDIAN ++#endif ++ ++/* Constants for MD5Transform routine. ++ */ ++ ++#define S11 7 ++#define S12 12 ++#define S13 17 ++#define S14 22 ++#define S21 5 ++#define S22 9 ++#define S23 14 ++#define S24 20 ++#define S31 4 ++#define S32 11 ++#define S33 16 ++#define S34 23 ++#define S41 6 ++#define S42 10 ++#define S43 15 ++#define S44 21 ++ ++static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); ++ ++#ifdef LITTLEENDIAN ++#define Encode MD5_memcpy ++#define Decode MD5_memcpy ++#else ++static void Encode PROTO_LIST ++ ((unsigned char *, UINT4 *, unsigned int)); ++static void Decode PROTO_LIST ++ ((UINT4 *, unsigned char *, unsigned int)); ++#endif ++ ++#ifdef HAVEMEMCOPY ++/* no need to include here; defines these */ ++#define MD5_memcpy memcpy ++#define MD5_memset memset ++#else ++#ifdef HAVEBCOPY ++#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c)) ++#define MD5_memset(_a,_b,_c) bzero((_a),(_c)) ++#else ++static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); ++static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); ++#endif ++#endif ++static unsigned char PADDING[64] = { ++ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ++}; ++ ++/* F, G, H and I are basic MD5 functions. ++ */ ++#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) ++#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) ++#define H(x, y, z) ((x) ^ (y) ^ (z)) ++#define I(x, y, z) ((y) ^ ((x) | (~z))) ++ ++/* ROTATE_LEFT rotates x left n bits. ++ */ ++#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) ++ ++/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. ++Rotation is separate from addition to prevent recomputation. ++ */ ++#define FF(a, b, c, d, x, s, ac) { \ ++ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ ++ (a) = ROTATE_LEFT ((a), (s)); \ ++ (a) += (b); \ ++ } ++#define GG(a, b, c, d, x, s, ac) { \ ++ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ ++ (a) = ROTATE_LEFT ((a), (s)); \ ++ (a) += (b); \ ++ } ++#define HH(a, b, c, d, x, s, ac) { \ ++ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ ++ (a) = ROTATE_LEFT ((a), (s)); \ ++ (a) += (b); \ ++ } ++#define II(a, b, c, d, x, s, ac) { \ ++ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ ++ (a) = ROTATE_LEFT ((a), (s)); \ ++ (a) += (b); \ ++ } ++ ++/* ++ * MD5 initialization. Begins an MD5 operation, writing a new context. ++ */ ++void MD5Init(void *vcontext) ++{ ++ MD5_CTX *context = vcontext; ++ ++ context->count[0] = context->count[1] = 0; ++ /* Load magic initialization constants. ++*/ ++ context->state[0] = 0x67452301; ++ context->state[1] = 0xefcdab89; ++ context->state[2] = 0x98badcfe; ++ context->state[3] = 0x10325476; ++} ++ ++/* MD5 block update operation. Continues an MD5 message-digest ++ operation, processing another message block, and updating the ++ context. ++ */ ++void MD5Update (vcontext, input, inputLen) ++ void *vcontext; ++ unsigned char *input; /* input block */ ++ __u32 inputLen; /* length of input block */ ++{ ++ MD5_CTX *context = vcontext; ++ __u32 i; ++ unsigned int index, partLen; ++ ++ /* Compute number of bytes mod 64 */ ++ index = (unsigned int)((context->count[0] >> 3) & 0x3F); ++ ++ /* Update number of bits */ ++ if ((context->count[0] += ((UINT4)inputLen << 3)) ++ < ((UINT4)inputLen << 3)) ++ context->count[1]++; ++ context->count[1] += ((UINT4)inputLen >> 29); ++ ++ partLen = 64 - index; ++ ++ /* Transform as many times as possible. ++*/ ++ if (inputLen >= partLen) { ++ MD5_memcpy ++ ((POINTER)&context->buffer[index], (POINTER)input, partLen); ++ MD5Transform (context->state, context->buffer); ++ ++ for (i = partLen; i + 63 < inputLen; i += 64) ++ MD5Transform (context->state, &input[i]); ++ ++ index = 0; ++ } ++ else ++ i = 0; ++ ++ /* Buffer remaining input */ ++ MD5_memcpy ++ ((POINTER)&context->buffer[index], (POINTER)&input[i], ++ inputLen-i); ++} ++ ++/* MD5 finalization. Ends an MD5 message-digest operation, writing the ++ the message digest and zeroizing the context. ++ */ ++void MD5Final (digest, vcontext) ++unsigned char digest[16]; /* message digest */ ++void *vcontext; /* context */ ++{ ++ MD5_CTX *context = vcontext; ++ unsigned char bits[8]; ++ unsigned int index, padLen; ++ ++ /* Save number of bits */ ++ Encode (bits, context->count, 8); ++ ++ /* Pad out to 56 mod 64. ++*/ ++ index = (unsigned int)((context->count[0] >> 3) & 0x3f); ++ padLen = (index < 56) ? (56 - index) : (120 - index); ++ MD5Update (context, PADDING, padLen); ++ ++ /* Append length (before padding) */ ++ MD5Update (context, bits, 8); ++ ++ if (digest != NULL) /* Bill Simpson's padding */ ++ { ++ /* store state in digest */ ++ Encode (digest, context->state, 16); ++ ++ /* Zeroize sensitive information. ++ */ ++ MD5_memset ((POINTER)context, 0, sizeof (*context)); ++ } ++} ++ ++/* MD5 basic transformation. Transforms state based on block. ++ */ ++static void MD5Transform (state, block) ++UINT4 state[4]; ++unsigned char block[64]; ++{ ++ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; ++ ++ Decode (x, block, 64); ++ ++ /* Round 1 */ ++ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ ++ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ ++ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ ++ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ ++ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ ++ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ ++ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ ++ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ ++ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ ++ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ ++ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ ++ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ ++ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ ++ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ ++ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ ++ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ ++ ++ /* Round 2 */ ++ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ ++ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ ++ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ ++ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ ++ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ ++ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ ++ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ ++ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ ++ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ ++ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ ++ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ ++ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ ++ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ ++ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ ++ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ ++ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ ++ ++ /* Round 3 */ ++ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ ++ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ ++ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ ++ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ ++ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ ++ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ ++ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ ++ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ ++ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ ++ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ ++ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ ++ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ ++ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ ++ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ ++ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ ++ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ ++ ++ /* Round 4 */ ++ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ ++ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ ++ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ ++ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ ++ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ ++ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ ++ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ ++ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ ++ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ ++ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ ++ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ ++ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ ++ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ ++ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ ++ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ ++ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ ++ ++ state[0] += a; ++ state[1] += b; ++ state[2] += c; ++ state[3] += d; ++ ++ /* Zeroize sensitive information. ++*/ ++ MD5_memset ((POINTER)x, 0, sizeof (x)); ++} ++ ++#ifndef LITTLEENDIAN ++ ++/* Encodes input (UINT4) into output (unsigned char). Assumes len is ++ a multiple of 4. ++ */ ++static void Encode (output, input, len) ++unsigned char *output; ++UINT4 *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) { ++ output[j] = (unsigned char)(input[i] & 0xff); ++ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); ++ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); ++ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); ++ } ++} ++ ++/* Decodes input (unsigned char) into output (UINT4). Assumes len is ++ a multiple of 4. ++ */ ++static void Decode (output, input, len) ++UINT4 *output; ++unsigned char *input; ++unsigned int len; ++{ ++ unsigned int i, j; ++ ++ for (i = 0, j = 0; j < len; i++, j += 4) ++ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | ++ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); ++} ++ ++#endif ++ ++#ifndef HAVEMEMCOPY ++#ifndef HAVEBCOPY ++/* Note: Replace "for loop" with standard memcpy if possible. ++ */ ++ ++static void MD5_memcpy (output, input, len) ++POINTER output; ++POINTER input; ++unsigned int len; ++{ ++ unsigned int i; ++ ++ for (i = 0; i < len; i++) ++ ++ output[i] = input[i]; ++} ++ ++/* Note: Replace "for loop" with standard memset if possible. ++ */ ++ ++static void MD5_memset (output, value, len) ++POINTER output; ++int value; ++unsigned int len; ++{ ++ unsigned int i; ++ ++ for (i = 0; i < len; i++) ++ ((char *)output)[i] = (char)value; ++} ++#endif ++#endif ++ ++/* ++ * $Log: ipsec_md5c.c,v $ ++ * Revision 1.8 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.7 2002/09/10 01:45:14 mcr ++ * changed type of MD5_CTX and SHA1_CTX to void * so that ++ * the function prototypes would match, and could be placed ++ * into a pointer to a function. ++ * ++ * Revision 1.6 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.5 2002/04/24 07:36:28 mcr ++ * Moved from ./klips/net/ipsec/ipsec_md5c.c,v ++ * ++ * Revision 1.4 1999/12/13 13:59:12 rgb ++ * Quick fix to argument size to Update bugs. ++ * ++ * Revision 1.3 1999/05/21 18:09:28 henry ++ * unnecessary include causes trouble in 2.2 ++ * ++ * Revision 1.2 1999/04/06 04:54:26 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.1 1998/06/18 21:27:48 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid ++ * kernel-build scripts happier in the presence of symlinks ++ * ++ * Revision 1.2 1998/04/23 20:54:02 rgb ++ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when ++ * verified. ++ * ++ * Revision 1.1 1998/04/09 03:06:08 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:04 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.3 1996/11/20 14:48:53 ji ++ * Release update only. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_proc.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,1127 @@ ++/* ++ * @(#) /proc file system interface code. ++ * ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs ++ * 2001 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * Split out from ipsec_init.c version 1.70. ++ */ ++ ++char ipsec_proc_c_version[] = "RCSID $Id: ipsec_proc.c,v 1.30 2004/04/25 21:23:11 ken Exp $"; ++ ++ ++#include ++#include ++#define __NO_VERSION__ ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include /* struct sockaddr_in */ ++#include ++#include ++#ifdef SPINLOCK ++#ifdef SPINLOCK_23 ++#include /* *lock* */ ++#else /* SPINLOCK_23 */ ++#include /* *lock* */ ++#endif /* SPINLOCK_23 */ ++#endif /* SPINLOCK */ ++#ifdef NET_21 ++#include ++#include ++#endif /* NET_21 */ ++#include ++#include ++#ifdef CONFIG_PROC_FS ++#include ++#endif /* CONFIG_PROC_FS */ ++#ifdef NETLINK_SOCK ++#include ++#else ++#include ++#endif ++ ++#include "openswan/radij.h" ++ ++#include "openswan/ipsec_life.h" ++#include "openswan/ipsec_stats.h" ++#include "openswan/ipsec_sa.h" ++ ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_tunnel.h" ++#include "openswan/ipsec_xmit.h" ++ ++#include "openswan/ipsec_rcv.h" ++#include "openswan/ipsec_ah.h" ++#include "openswan/ipsec_esp.h" ++ ++#ifdef CONFIG_IPSEC_IPCOMP ++#include "openswan/ipcomp.h" ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ ++#include "openswan/ipsec_proto.h" ++ ++#include ++#include ++ ++#ifdef CONFIG_PROC_FS ++ ++#ifdef IPSEC_PROC_SUBDIRS ++static struct proc_dir_entry *proc_net_ipsec_dir = NULL; ++static struct proc_dir_entry *proc_eroute_dir = NULL; ++static struct proc_dir_entry *proc_spi_dir = NULL; ++static struct proc_dir_entry *proc_spigrp_dir = NULL; ++static struct proc_dir_entry *proc_birth_dir = NULL; ++static struct proc_dir_entry *proc_stats_dir = NULL; ++#endif ++ ++struct ipsec_birth_reply ipsec_ipv4_birth_packet; ++struct ipsec_birth_reply ipsec_ipv6_birth_packet; ++ ++#define DECREMENT_UNSIGNED(X, amount) ((amount < (X)) ? (X)-amount : 0) ++ ++extern int ipsec_xform_get_info(char *buffer, char **start, ++ off_t offset, int length IPSEC_PROC_LAST_ARG); ++ ++ ++/* ipsec_snprintf: like snprintf except ++ * - size is signed and a negative value is treated as if it were 0 ++ * - the returned result is never negative -- ++ * an error generates a "?" or null output (depending on space). ++ * (Our callers are too lazy to check for an error return.) ++ * ++ * @param buf String buffer ++ * @param size Size of the string ++ * @param fmt printf string ++ * @param ... Variables to be displayed in fmt ++ * @return int Return code ++ */ ++int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...) ++{ ++ va_list args; ++ int i; ++ size_t possize = size < 0? 0 : size; ++ va_start(args, fmt); ++ i = vsnprintf(buf,possize,fmt,args); ++ va_end(args); ++ if (i < 0) { ++ /* create empty output in place of error */ ++ i = 0; ++ if (size > 0) { ++ *buf = '\0'; ++ } ++ } ++ return i; ++} ++ ++ ++IPSEC_PROCFS_DEBUG_NO_STATIC ++int ++ipsec_eroute_get_info(char *buffer, ++ char **start, ++ off_t offset, ++ int length IPSEC_PROC_LAST_ARG) ++{ ++ struct wsbuf w = {buffer, length, offset, 0, 0}; ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if (debug_radij & DB_RJ_DUMPTREES) ++ rj_dumptrees(); /* XXXXXXXXX */ ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, ++ "klips_debug:ipsec_eroute_get_info: " ++ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", ++ buffer, ++ *start, ++ (int)offset, ++ length); ++ ++ spin_lock_bh(&eroute_lock); ++ ++ rj_walktree(rnh, ipsec_rj_walker_procprint, &w); ++/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */ ++ ++ spin_unlock_bh(&eroute_lock); ++ ++ *start = buffer + (offset - w.begin); /* Start of wanted data */ ++ return w.len - (offset - w.begin); ++} ++ ++IPSEC_PROCFS_DEBUG_NO_STATIC ++int ++ipsec_spi_get_info(char *buffer, ++ char **start, ++ off_t offset, ++ int length IPSEC_PROC_LAST_ARG) ++{ ++ const int max_content = length > 0? length-1 : 0; ++ int len = 0; ++ off_t begin = 0; ++ int i; ++ struct ipsec_sa *sa_p; ++ char sa[SATOT_BUF]; ++ char buf_s[SUBNETTOA_BUF]; ++ char buf_d[SUBNETTOA_BUF]; ++ size_t sa_len; ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, ++ "klips_debug:ipsec_spi_get_info: " ++ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", ++ buffer, ++ *start, ++ (int)offset, ++ length); ++ ++ spin_lock_bh(&tdb_lock); ++ ++ for (i = 0; i < SADB_HASHMOD; i++) { ++ for (sa_p = ipsec_sadb_hash[i]; ++ sa_p; ++ sa_p = sa_p->ips_hnext) { ++ atomic_inc(&sa_p->ips_refcount); ++ sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa)); ++ len += ipsec_snprintf(buffer+len, length-len, "%s ", ++ sa_len ? sa : " (error)"); ++ ++ len += ipsec_snprintf(buffer+len, length-len, "%s%s%s", ++ IPS_XFORM_NAME(sa_p)); ++ ++ len += ipsec_snprintf(buffer+len, length-len, ": dir=%s", ++ (sa_p->ips_flags & EMT_INBOUND) ? ++ "in " : "out"); ++ ++ if(sa_p->ips_addr_s) { ++ addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr, ++ 0, buf_s, sizeof(buf_s)); ++ len += ipsec_snprintf(buffer+len, length-len, " src=%s", ++ buf_s); ++ } ++ ++ if((sa_p->ips_said.proto == IPPROTO_IPIP) ++ && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) { ++ subnettoa(sa_p->ips_flow_s.u.v4.sin_addr, ++ sa_p->ips_mask_s.u.v4.sin_addr, ++ 0, ++ buf_s, ++ sizeof(buf_s)); ++ ++ subnettoa(sa_p->ips_flow_d.u.v4.sin_addr, ++ sa_p->ips_mask_d.u.v4.sin_addr, ++ 0, ++ buf_d, ++ sizeof(buf_d)); ++ ++ len += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s", ++ buf_s, buf_d); ++ } ++ ++ if(sa_p->ips_iv_bits) { ++ int j; ++ len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x", ++ sa_p->ips_iv_bits); ++ ++ for(j = 0; j < sa_p->ips_iv_bits / 8; j++) { ++ len += ipsec_snprintf(buffer+len, length-len, "%02x", ++ (__u32)((__u8*)(sa_p->ips_iv))[j]); ++ } ++ } ++ ++ if(sa_p->ips_encalg || sa_p->ips_authalg) { ++ if(sa_p->ips_replaywin) { ++ len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d", ++ sa_p->ips_replaywin); ++ } ++ if(sa_p->ips_errs.ips_replaywin_errs) { ++ len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d", ++ sa_p->ips_errs.ips_replaywin_errs); ++ } ++ if(sa_p->ips_replaywin_lastseq) { ++ len += ipsec_snprintf(buffer+len, length-len, " seq=%d", ++ sa_p->ips_replaywin_lastseq); ++ } ++ if(sa_p->ips_replaywin_bitmap) { ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) ++ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx", ++ sa_p->ips_replaywin_bitmap); ++#else ++ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%x%08x", ++ (__u32)(sa_p->ips_replaywin_bitmap >> 32), ++ (__u32)sa_p->ips_replaywin_bitmap); ++#endif ++ } ++ if(sa_p->ips_replaywin_maxdiff) { ++ len += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d", ++ sa_p->ips_replaywin_maxdiff); ++ } ++ } ++ if(sa_p->ips_flags & ~EMT_INBOUND) { ++ len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x", ++ sa_p->ips_flags & ~EMT_INBOUND); ++ len += ipsec_snprintf(buffer+len, length-len, "<"); ++ /* flag printing goes here */ ++ len += ipsec_snprintf(buffer+len, length-len, ">"); ++ } ++ if(sa_p->ips_auth_bits) { ++ len += ipsec_snprintf(buffer+len, length-len, " alen=%d", ++ sa_p->ips_auth_bits); ++ } ++ if(sa_p->ips_key_bits_a) { ++ len += ipsec_snprintf(buffer+len, length-len, " aklen=%d", ++ sa_p->ips_key_bits_a); ++ } ++ if(sa_p->ips_errs.ips_auth_errs) { ++ len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d", ++ sa_p->ips_errs.ips_auth_errs); ++ } ++ if(sa_p->ips_key_bits_e) { ++ len += ipsec_snprintf(buffer+len, length-len, " eklen=%d", ++ sa_p->ips_key_bits_e); ++ } ++ if(sa_p->ips_errs.ips_encsize_errs) { ++ len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d", ++ sa_p->ips_errs.ips_encsize_errs); ++ } ++ if(sa_p->ips_errs.ips_encpad_errs) { ++ len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d", ++ sa_p->ips_errs.ips_encpad_errs); ++ } ++ ++ len += ipsec_snprintf(buffer+len, length-len, " life(c,s,h)="); ++ ++ len += ipsec_lifetime_format(buffer + len, ++ length - len, ++ "alloc", ++ ipsec_life_countbased, ++ &sa_p->ips_life.ipl_allocations); ++ ++ len += ipsec_lifetime_format(buffer + len, ++ length - len, ++ "bytes", ++ ipsec_life_countbased, ++ &sa_p->ips_life.ipl_bytes); ++ ++ len += ipsec_lifetime_format(buffer + len, ++ length - len, ++ "addtime", ++ ipsec_life_timebased, ++ &sa_p->ips_life.ipl_addtime); ++ ++ len += ipsec_lifetime_format(buffer + len, ++ length - len, ++ "usetime", ++ ipsec_life_timebased, ++ &sa_p->ips_life.ipl_usetime); ++ ++ len += ipsec_lifetime_format(buffer + len, ++ length - len, ++ "packets", ++ ipsec_life_countbased, ++ &sa_p->ips_life.ipl_packets); ++ ++ if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) ++ len += ipsec_snprintf(buffer+len, length-len, " idle=%Ld", ++ jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last); ++#else ++ len += ipsec_snprintf(buffer+len, length-len, " idle=%lu", ++ jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last); ++#endif ++ } ++ ++#ifdef CONFIG_IPSEC_IPCOMP ++ if(sa_p->ips_said.proto == IPPROTO_COMP && ++ (sa_p->ips_comp_ratio_dbytes || ++ sa_p->ips_comp_ratio_cbytes)) { ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) ++ len += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld", ++ sa_p->ips_comp_ratio_dbytes, ++ sa_p->ips_comp_ratio_cbytes); ++#else ++ len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu", ++ (unsigned long)sa_p->ips_comp_ratio_dbytes, ++ (unsigned long)sa_p->ips_comp_ratio_cbytes); ++#endif ++ } ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ if(sa_p->ips_natt_type != 0) { ++ char *natttype_name; ++ ++ switch(sa_p->ips_natt_type) ++ { ++ case ESPINUDP_WITH_NON_IKE: ++ natttype_name="nonike"; ++ break; ++ case ESPINUDP_WITH_NON_ESP: ++ natttype_name="nonesp"; ++ break; ++ default: ++ natttype_name = "unknown"; ++ break; ++ } ++ ++ len += ipsec_snprintf(buffer + len, length-len, " natencap=%s", ++ natttype_name); ++ ++ len += ipsec_snprintf(buffer + len, length-len, " natsport=%d", ++ sa_p->ips_natt_sport); ++ ++ len += ipsec_snprintf(buffer + len,length-len, " natdport=%d", ++ sa_p->ips_natt_dport); ++ } ++#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */ ++ ++ len += ipsec_snprintf(buffer + len,length-len, " refcount=%d", ++ atomic_read(&sa_p->ips_refcount)); ++ ++ len += ipsec_snprintf(buffer+len, length-len, " ref=%d", ++ sa_p->ips_ref); ++#ifdef CONFIG_IPSEC_DEBUG ++ if(debug_xform) { ++ len += ipsec_snprintf(buffer+len, length-len, " reftable=%lu refentry=%lu", ++ (unsigned long)IPsecSAref2table(sa_p->ips_ref), ++ (unsigned long)IPsecSAref2entry(sa_p->ips_ref)); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ len += ipsec_snprintf(buffer+len, length-len, "\n"); ++ ++ atomic_dec(&sa_p->ips_refcount); ++ ++ if (len >= max_content) { ++ /* we've done all that can fit -- stop loops */ ++ len = max_content; /* truncate crap */ ++ goto done_spi_i; ++ } else { ++ const off_t pos = begin + len; /* file position of end of what we've generated */ ++ ++ if (pos <= offset) { ++ /* all is before first interesting character: ++ * discard, but note where we are. ++ */ ++ len = 0; ++ begin = pos; ++ } ++ } ++ } ++ } ++ ++done_spi_i: ++ spin_unlock_bh(&tdb_lock); ++ ++ *start = buffer + (offset - begin); /* Start of wanted data */ ++ return len - (offset - begin); ++} ++ ++IPSEC_PROCFS_DEBUG_NO_STATIC ++int ++ipsec_spigrp_get_info(char *buffer, ++ char **start, ++ off_t offset, ++ int length IPSEC_PROC_LAST_ARG) ++{ ++ /* Limit of useful snprintf output */ ++ const int max_content = length > 0? length-1 : 0; ++ ++ int len = 0; ++ off_t begin = 0; ++ int i; ++ struct ipsec_sa *sa_p, *sa_p2; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, ++ "klips_debug:ipsec_spigrp_get_info: " ++ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", ++ buffer, ++ *start, ++ (int)offset, ++ length); ++ ++ spin_lock_bh(&tdb_lock); ++ ++ for (i = 0; i < SADB_HASHMOD; i++) { ++ for (sa_p = ipsec_sadb_hash[i]; ++ sa_p != NULL; ++ sa_p = sa_p->ips_hnext) ++ { ++ atomic_inc(&sa_p->ips_refcount); ++ if(sa_p->ips_inext == NULL) { ++ sa_p2 = sa_p; ++ while(sa_p2 != NULL) { ++ atomic_inc(&sa_p2->ips_refcount); ++ sa_len = satot(&sa_p2->ips_said, ++ 'x', sa, sizeof(sa)); ++ ++ len += ipsec_snprintf(buffer+len, length-len, "%s ", ++ sa_len ? sa : " (error)"); ++ atomic_dec(&sa_p2->ips_refcount); ++ sa_p2 = sa_p2->ips_onext; ++ } ++ len += ipsec_snprintf(buffer+len, length-len, "\n"); ++ } ++ ++ atomic_dec(&sa_p->ips_refcount); ++ ++ if (len >= max_content) { ++ /* we've done all that can fit -- stop loops */ ++ len = max_content; /* truncate crap */ ++ goto done_spigrp_i; ++ } else { ++ const off_t pos = begin + len; ++ ++ if (pos <= offset) { ++ /* all is before first interesting character: ++ * discard, but note where we are. ++ */ ++ len = 0; ++ begin = pos; ++ } ++ } ++ } ++ } ++ ++done_spigrp_i: ++ spin_unlock_bh(&tdb_lock); ++ ++ *start = buffer + (offset - begin); /* Start of wanted data */ ++ return len - (offset - begin); ++} ++ ++ ++IPSEC_PROCFS_DEBUG_NO_STATIC ++int ++ipsec_tncfg_get_info(char *buffer, ++ char **start, ++ off_t offset, ++ int length IPSEC_PROC_LAST_ARG) ++{ ++ /* limit of useful snprintf output */ ++ const int max_content = length > 0? length-1 : 0; ++ int len = 0; ++ off_t begin = 0; ++ int i; ++ char name[9]; ++ struct device *dev, *privdev; ++ struct ipsecpriv *priv; ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, ++ "klips_debug:ipsec_tncfg_get_info: " ++ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", ++ buffer, ++ *start, ++ (int)offset, ++ length); ++ ++ for(i = 0; i < IPSEC_NUM_IF; i++) { ++ ipsec_snprintf(name, (ssize_t) sizeof(name), IPSEC_DEV_FORMAT, i); ++ dev = __ipsec_dev_get(name); ++ if(dev) { ++ priv = (struct ipsecpriv *)(dev->priv); ++ len += ipsec_snprintf(buffer+len, length-len, "%s", ++ dev->name); ++ if(priv) { ++ privdev = (struct device *)(priv->dev); ++ len += ipsec_snprintf(buffer+len, length-len, " -> %s", ++ privdev ? privdev->name : "NULL"); ++ len += ipsec_snprintf(buffer+len, length-len, " mtu=%d(%d) -> %d", ++ dev->mtu, ++ priv->mtu, ++ privdev ? privdev->mtu : 0); ++ } else { ++ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, ++ "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n", ++ dev->name); ++ } ++ len += ipsec_snprintf(buffer+len, length-len, "\n"); ++ ++ if (len >= max_content) { ++ /* we've done all that can fit -- stop loop */ ++ len = max_content; /* truncate crap */ ++ break; ++ } else { ++ const off_t pos = begin + len; ++ if (pos <= offset) { ++ len = 0; ++ begin = pos; ++ } ++ } ++ } ++ } ++ *start = buffer + (offset - begin); /* Start of wanted data */ ++ len -= (offset - begin); /* Start slop */ ++ if (len > length) ++ len = length; ++ return len; ++} ++ ++IPSEC_PROCFS_DEBUG_NO_STATIC ++int ++ipsec_version_get_info(char *buffer, ++ char **start, ++ off_t offset, ++ int length IPSEC_PROC_LAST_ARG) ++{ ++ int len = 0; ++ off_t begin = 0; ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, ++ "klips_debug:ipsec_version_get_info: " ++ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", ++ buffer, ++ *start, ++ (int)offset, ++ length); ++ ++ len += ipsec_snprintf(buffer + len,length-len, "Openswan version: %s\n", ++ ipsec_version_code()); ++#if 0 ++ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, ++ "klips_debug:ipsec_version_get_info: " ++ "ipsec_init version: %s\n", ++ ipsec_init_c_version); ++ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, ++ "klips_debug:ipsec_version_get_info: " ++ "ipsec_tunnel version: %s\n", ++ ipsec_tunnel_c_version); ++ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, ++ "klips_debug:ipsec_version_get_info: " ++ "ipsec_netlink version: %s\n", ++ ipsec_netlink_c_version); ++ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, ++ "klips_debug:ipsec_version_get_info: " ++ "radij_c_version: %s\n", ++ radij_c_version); ++#endif ++ ++ ++ *start = buffer + (offset - begin); /* Start of wanted data */ ++ len -= (offset - begin); /* Start slop */ ++ if (len > length) ++ len = length; ++ return len; ++} ++ ++IPSEC_PROCFS_DEBUG_NO_STATIC ++int ++ipsec_birth_info(char *page, ++ char **start, ++ off_t offset, ++ int count, ++ int *eof, ++ void *data) ++{ ++ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data; ++ int len; ++ ++ if(offset >= ibr->packet_template_len) { ++ if(eof) { ++ *eof=1; ++ } ++ return 0; ++ } ++ ++ len = ibr->packet_template_len; ++ len -= offset; ++ if (len > count) ++ len = count; ++ ++ memcpy(page + offset, ibr->packet_template+offset, len); ++ ++ return len; ++} ++ ++IPSEC_PROCFS_DEBUG_NO_STATIC ++int ++ipsec_birth_set(struct file *file, const char *buffer, ++ unsigned long count, void *data) ++{ ++ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data; ++ int len; ++ ++ MOD_INC_USE_COUNT; ++ if(count > IPSEC_BIRTH_TEMPLATE_MAXLEN) { ++ len = IPSEC_BIRTH_TEMPLATE_MAXLEN; ++ } else { ++ len = count; ++ } ++ ++ if(copy_from_user(ibr->packet_template, buffer, len)) { ++ MOD_DEC_USE_COUNT; ++ return -EFAULT; ++ } ++ ibr->packet_template_len = len; ++ ++ MOD_DEC_USE_COUNT; ++ ++ return len; ++} ++ ++ ++#ifdef CONFIG_IPSEC_DEBUG ++IPSEC_PROCFS_DEBUG_NO_STATIC ++int ++ipsec_klipsdebug_get_info(char *buffer, ++ char **start, ++ off_t offset, ++ int length IPSEC_PROC_LAST_ARG) ++{ ++ int len = 0; ++ off_t begin = 0; ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, ++ "klips_debug:ipsec_klipsdebug_get_info: " ++ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", ++ buffer, ++ *start, ++ (int)offset, ++ length); ++ ++ len += ipsec_snprintf(buffer+len, length-len, "debug_tunnel=%08x.\n", debug_tunnel); ++ len += ipsec_snprintf(buffer+len, length-len, "debug_xform=%08x.\n", debug_xform); ++ len += ipsec_snprintf(buffer+len, length-len, "debug_eroute=%08x.\n", debug_eroute); ++ len += ipsec_snprintf(buffer+len, length-len, "debug_spi=%08x.\n", debug_spi); ++ len += ipsec_snprintf(buffer+len, length-len, "debug_radij=%08x.\n", debug_radij); ++ len += ipsec_snprintf(buffer+len, length-len, "debug_esp=%08x.\n", debug_esp); ++ len += ipsec_snprintf(buffer+len, length-len, "debug_ah=%08x.\n", debug_ah); ++ len += ipsec_snprintf(buffer+len, length-len, "debug_rcv=%08x.\n", debug_rcv); ++ len += ipsec_snprintf(buffer+len, length-len, "debug_pfkey=%08x.\n", debug_pfkey); ++ ++ *start = buffer + (offset - begin); /* Start of wanted data */ ++ len -= (offset - begin); /* Start slop */ ++ if (len > length) ++ len = length; ++ return len; ++} ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++IPSEC_PROCFS_DEBUG_NO_STATIC ++int ++ipsec_stats_get_int_info(char *buffer, ++ char **start, ++ off_t offset, ++ int length, ++ int *eof, ++ void *data) ++{ ++ ++ const int max_content = length > 0? length-1 : 0; ++ int len = 0; ++ int *thing; ++ ++ thing = (int *)data; ++ ++ len = ipsec_snprintf(buffer+len, length-len, "%08x\n", *thing); ++ ++ if (len >= max_content) ++ len = max_content; /* truncate crap */ ++ ++ *start = buffer + offset; /* Start of wanted data */ ++ return len > offset? len - offset : 0; ++ ++} ++ ++#ifndef PROC_FS_2325 ++struct proc_dir_entry ipsec_eroute = ++{ ++ 0, ++ 12, "ipsec_eroute", ++ S_IFREG | S_IRUGO, 1, 0, 0, 0, ++ &proc_net_inode_operations, ++ ipsec_eroute_get_info, ++ NULL, NULL, NULL, NULL, NULL ++}; ++ ++struct proc_dir_entry ipsec_spi = ++{ ++ 0, ++ 9, "ipsec_spi", ++ S_IFREG | S_IRUGO, 1, 0, 0, 0, ++ &proc_net_inode_operations, ++ ipsec_spi_get_info, ++ NULL, NULL, NULL, NULL, NULL ++}; ++ ++struct proc_dir_entry ipsec_spigrp = ++{ ++ 0, ++ 12, "ipsec_spigrp", ++ S_IFREG | S_IRUGO, 1, 0, 0, 0, ++ &proc_net_inode_operations, ++ ipsec_spigrp_get_info, ++ NULL, NULL, NULL, NULL, NULL ++}; ++ ++struct proc_dir_entry ipsec_tncfg = ++{ ++ 0, ++ 11, "ipsec_tncfg", ++ S_IFREG | S_IRUGO, 1, 0, 0, 0, ++ &proc_net_inode_operations, ++ ipsec_tncfg_get_info, ++ NULL, NULL, NULL, NULL, NULL ++}; ++ ++struct proc_dir_entry ipsec_version = ++{ ++ 0, ++ 13, "ipsec_version", ++ S_IFREG | S_IRUGO, 1, 0, 0, 0, ++ &proc_net_inode_operations, ++ ipsec_version_get_info, ++ NULL, NULL, NULL, NULL, NULL ++}; ++ ++#ifdef CONFIG_IPSEC_DEBUG ++struct proc_dir_entry ipsec_klipsdebug = ++{ ++ 0, ++ 16, "ipsec_klipsdebug", ++ S_IFREG | S_IRUGO, 1, 0, 0, 0, ++ &proc_net_inode_operations, ++ ipsec_klipsdebug_get_info, ++ NULL, NULL, NULL, NULL, NULL ++}; ++#endif /* CONFIG_IPSEC_DEBUG */ ++#endif /* !PROC_FS_2325 */ ++#endif /* CONFIG_PROC_FS */ ++ ++#if defined(PROC_FS_2325) ++struct ipsec_proc_list { ++ char *name; ++ struct proc_dir_entry **parent; ++ struct proc_dir_entry **dir; ++ read_proc_t *readthing; ++ write_proc_t *writething; ++ void *data; ++}; ++static struct ipsec_proc_list proc_items[]={ ++#ifdef CONFIG_IPSEC_DEBUG ++ {"klipsdebug", &proc_net_ipsec_dir, NULL, ipsec_klipsdebug_get_info, NULL, NULL}, ++#endif ++ {"eroute", &proc_net_ipsec_dir, &proc_eroute_dir, NULL, NULL, NULL}, ++ {"all", &proc_eroute_dir, NULL, ipsec_eroute_get_info, NULL, NULL}, ++ {"spi", &proc_net_ipsec_dir, &proc_spi_dir, NULL, NULL, NULL}, ++ {"all", &proc_spi_dir, NULL, ipsec_spi_get_info, NULL, NULL}, ++ {"spigrp", &proc_net_ipsec_dir, &proc_spigrp_dir, NULL, NULL, NULL}, ++ {"all", &proc_spigrp_dir, NULL, ipsec_spigrp_get_info, NULL, NULL}, ++ {"birth", &proc_net_ipsec_dir, &proc_birth_dir, NULL, NULL, NULL}, ++ {"ipv4", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv4_birth_packet}, ++ {"ipv6", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv6_birth_packet}, ++ {"tncfg", &proc_net_ipsec_dir, NULL, ipsec_tncfg_get_info, NULL, NULL}, ++ {"xforms", &proc_net_ipsec_dir, NULL, ipsec_xform_get_info, NULL, NULL}, ++ {"stats", &proc_net_ipsec_dir, &proc_stats_dir, NULL, NULL, NULL}, ++ {"trap_count", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_count}, ++ {"trap_sendcount", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_sendcount}, ++ {"version", &proc_net_ipsec_dir, NULL, ipsec_version_get_info, NULL, NULL}, ++ {NULL, NULL, NULL, NULL, NULL, NULL} ++}; ++#endif ++ ++int ++ipsec_proc_init() ++{ ++ int error = 0; ++#ifdef IPSEC_PROC_SUBDIRS ++ struct proc_dir_entry *item; ++#endif ++ ++ /* ++ * just complain because pluto won't run without /proc! ++ */ ++#ifndef CONFIG_PROC_FS ++#error You must have PROC_FS built in to use KLIPS ++#endif ++ ++ /* for 2.0 kernels */ ++#if !defined(PROC_FS_2325) && !defined(PROC_FS_21) ++ error |= proc_register_dynamic(&proc_net, &ipsec_eroute); ++ error |= proc_register_dynamic(&proc_net, &ipsec_spi); ++ error |= proc_register_dynamic(&proc_net, &ipsec_spigrp); ++ error |= proc_register_dynamic(&proc_net, &ipsec_tncfg); ++ error |= proc_register_dynamic(&proc_net, &ipsec_version); ++#ifdef CONFIG_IPSEC_DEBUG ++ error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug); ++#endif /* CONFIG_IPSEC_DEBUG */ ++#endif ++ ++ /* for 2.2 kernels */ ++#if !defined(PROC_FS_2325) && defined(PROC_FS_21) ++ error |= proc_register(proc_net, &ipsec_eroute); ++ error |= proc_register(proc_net, &ipsec_spi); ++ error |= proc_register(proc_net, &ipsec_spigrp); ++ error |= proc_register(proc_net, &ipsec_tncfg); ++ error |= proc_register(proc_net, &ipsec_version); ++#ifdef CONFIG_IPSEC_DEBUG ++ error |= proc_register(proc_net, &ipsec_klipsdebug); ++#endif /* CONFIG_IPSEC_DEBUG */ ++#endif ++ ++ /* for 2.4 kernels */ ++#if defined(PROC_FS_2325) ++ /* create /proc/net/ipsec */ ++ ++ /* zero these out before we initialize /proc/net/ipsec/birth/stuff */ ++ memset(&ipsec_ipv4_birth_packet, 0, sizeof(struct ipsec_birth_reply)); ++ memset(&ipsec_ipv6_birth_packet, 0, sizeof(struct ipsec_birth_reply)); ++ ++ proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net); ++ if(proc_net_ipsec_dir == NULL) { ++ /* no point in continuing */ ++ return 1; ++ } ++ ++ { ++ struct ipsec_proc_list *it; ++ ++ it=proc_items; ++ while(it->name!=NULL) { ++ if(it->dir) { ++ /* make a dir instead */ ++ item = proc_mkdir(it->name, *it->parent); ++ *it->dir = item; ++ } else { ++ item = create_proc_entry(it->name, 0400, *it->parent); ++ } ++ if(item) { ++ item->read_proc = it->readthing; ++ item->write_proc = it->writething; ++ item->data = it->data; ++#ifdef MODULE ++ item->owner = THIS_MODULE; ++#endif ++ } else { ++ error |= 1; ++ } ++ it++; ++ } ++ } ++ ++ /* now create some symlinks to provide compatibility */ ++ proc_symlink("ipsec_eroute", proc_net, "ipsec/eroute/all"); ++ proc_symlink("ipsec_spi", proc_net, "ipsec/spi/all"); ++ proc_symlink("ipsec_spigrp", proc_net, "ipsec/spigrp/all"); ++ proc_symlink("ipsec_tncfg", proc_net, "ipsec/tncfg"); ++ proc_symlink("ipsec_version",proc_net, "ipsec/version"); ++ proc_symlink("ipsec_klipsdebug",proc_net,"ipsec/klipsdebug"); ++ ++#endif /* !PROC_FS_2325 */ ++ ++ return error; ++} ++ ++void ++ipsec_proc_cleanup() ++{ ++ ++ /* for 2.0 and 2.2 kernels */ ++#if !defined(PROC_FS_2325) ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0) ++ printk("klips_debug:ipsec_cleanup: " ++ "cannot unregister /proc/net/ipsec_klipsdebug\n"); ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ if (proc_net_unregister(ipsec_version.low_ino) != 0) ++ printk("klips_debug:ipsec_cleanup: " ++ "cannot unregister /proc/net/ipsec_version\n"); ++ if (proc_net_unregister(ipsec_eroute.low_ino) != 0) ++ printk("klips_debug:ipsec_cleanup: " ++ "cannot unregister /proc/net/ipsec_eroute\n"); ++ if (proc_net_unregister(ipsec_spi.low_ino) != 0) ++ printk("klips_debug:ipsec_cleanup: " ++ "cannot unregister /proc/net/ipsec_spi\n"); ++ if (proc_net_unregister(ipsec_spigrp.low_ino) != 0) ++ printk("klips_debug:ipsec_cleanup: " ++ "cannot unregister /proc/net/ipsec_spigrp\n"); ++ if (proc_net_unregister(ipsec_tncfg.low_ino) != 0) ++ printk("klips_debug:ipsec_cleanup: " ++ "cannot unregister /proc/net/ipsec_tncfg\n"); ++#endif ++ ++ /* for 2.4 kernels */ ++#if defined(PROC_FS_2325) ++ { ++ struct ipsec_proc_list *it; ++ ++ /* find end of list */ ++ it=proc_items; ++ while(it->name!=NULL) { ++ it++; ++ } ++ it--; ++ ++ do { ++ remove_proc_entry(it->name, *it->parent); ++ it--; ++ } while(it > proc_items); ++ } ++ ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ remove_proc_entry("ipsec_klipsdebug", proc_net); ++#endif /* CONFIG_IPSEC_DEBUG */ ++ remove_proc_entry("ipsec_eroute", proc_net); ++ remove_proc_entry("ipsec_spi", proc_net); ++ remove_proc_entry("ipsec_spigrp", proc_net); ++ remove_proc_entry("ipsec_tncfg", proc_net); ++ remove_proc_entry("ipsec_version", proc_net); ++ remove_proc_entry("ipsec", proc_net); ++#endif /* 2.4 kernel */ ++} ++ ++/* ++ * $Log: ipsec_proc.c,v $ ++ * Revision 1.30 2004/04/25 21:23:11 ken ++ * Pull in dhr's changes from FreeS/WAN 2.06 ++ * ++ * Revision 1.29 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.28 2004/03/28 20:29:58 paul ++ * ssize_t, not ssized_t ++ * ++ * Revision 1.27 2004/03/28 20:27:20 paul ++ * Included tested and confirmed fixes mcr made and dhr verified for ++ * snprint statements. Changed one other snprintf to use ipsec_snprintf ++ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with ++ * dhr. (thanks dhr!) ++ * ++ * Revision 1.26 2004/02/09 22:07:06 mcr ++ * added information about nat-traversal setting to spi-output. ++ * ++ * Revision 1.25.4.1 2004/04/05 04:30:46 mcr ++ * patches for alg-branch to compile/work with 2.x openswan ++ * ++ * Revision 1.25 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.24.4.1 2003/10/29 01:30:41 mcr ++ * elimited "struct sa_id". ++ * ++ * Revision 1.24 2003/06/20 01:42:21 mcr ++ * added counters to measure how many ACQUIREs we send to pluto, ++ * and how many are successfully sent. ++ * ++ * Revision 1.23 2003/04/03 17:38:09 rgb ++ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. ++ * ++ * Revision 1.22 2002/09/20 15:40:57 rgb ++ * Renamed saref macros for consistency and brevity. ++ * ++ * Revision 1.21 2002/09/20 05:01:35 rgb ++ * Print ref and reftable, refentry seperately. ++ * ++ * Revision 1.20 2002/09/19 02:35:39 mcr ++ * do not define structures needed by /proc/net/ipsec/ if we ++ * aren't going create that directory. ++ * ++ * Revision 1.19 2002/09/10 01:43:25 mcr ++ * fixed problem in /-* comment. ++ * ++ * Revision 1.18 2002/09/03 16:22:11 mcr ++ * fixed initialization of birth/stuff values - some simple ++ * screw ups in the code. ++ * removed debugging that was left in by mistake. ++ * ++ * Revision 1.17 2002/09/02 17:54:53 mcr ++ * changed how the table driven /proc entries are created so that ++ * making subdirs is now explicit rather than implicit. ++ * ++ * Revision 1.16 2002/08/30 01:23:37 mcr ++ * reorganized /proc creating code to clear up ifdefs, ++ * make the 2.4 code table driven, and put things into ++ * /proc/net/ipsec subdir. Symlinks are left for compatibility. ++ * ++ * Revision 1.15 2002/08/13 19:01:25 mcr ++ * patches from kenb to permit compilation of FreeSWAN on ia64. ++ * des library patched to use proper DES_LONG type for ia64. ++ * ++ * Revision 1.14 2002/07/26 08:48:31 rgb ++ * Added SA ref table code. ++ * ++ * Revision 1.13 2002/07/24 18:44:54 rgb ++ * Type fiddling to tame ia64 compiler. ++ * ++ * Revision 1.12 2002/05/27 18:56:07 rgb ++ * Convert to dynamic ipsec device allocation. ++ * ++ * Revision 1.11 2002/05/23 07:14:50 rgb ++ * Added refcount code. ++ * Cleaned up %p variants to 0p%p for test suite cleanup. ++ * Convert "usecount" to "refcount" to remove ambiguity. ++ * ++ * Revision 1.10 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.9 2002/04/24 07:36:28 mcr ++ * Moved from ./klips/net/ipsec/ipsec_proc.c,v ++ * ++ * Revision 1.8 2002/01/29 17:17:55 mcr ++ * moved include of ipsec_param.h to after include of linux/kernel.h ++ * otherwise, it seems that some option that is set in ipsec_param.h ++ * screws up something subtle in the include path to kernel.h, and ++ * it complains on the snprintf() prototype. ++ * ++ * Revision 1.7 2002/01/29 04:00:52 mcr ++ * more excise of kversions.h header. ++ * ++ * Revision 1.6 2002/01/29 02:13:17 mcr ++ * introduction of ipsec_kversion.h means that include of ++ * ipsec_param.h must preceed any decisions about what files to ++ * include to deal with differences in kernel source. ++ * ++ * Revision 1.5 2002/01/12 02:54:30 mcr ++ * beginnings of /proc/net/ipsec dir. ++ * ++ * Revision 1.4 2001/12/11 02:21:05 rgb ++ * Don't include module version here, fixing 2.2 compile bug. ++ * ++ * Revision 1.3 2001/12/05 07:19:44 rgb ++ * Fixed extraneous #include "version.c" bug causing modular KLIPS failure. ++ * ++ * Revision 1.2 2001/11/26 09:16:14 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.74 2001/11/22 05:44:11 henry ++ * new version stuff ++ * ++ * Revision 1.1.2.1 2001/09/25 02:19:40 mcr ++ * /proc manipulation code moved to new ipsec_proc.c ++ * ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_radij.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,869 @@ ++/* ++ * Interface between the IPSEC code and the radix (radij) tree code ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_radij.c,v 1.70 2004/04/25 21:10:52 ken Exp $ ++ */ ++ ++#include ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, struct net_device_stats and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include ++#include ++#ifdef SPINLOCK ++# ifdef SPINLOCK_23 ++# include /* *lock* */ ++# else /* 23_SPINLOCK */ ++# include /* *lock* */ ++# endif /* 23_SPINLOCK */ ++#endif /* SPINLOCK */ ++#ifdef NET_21 ++# include ++# include ++#endif ++#include ++#include ++ ++#include "openswan/ipsec_eroute.h" ++#include "openswan/ipsec_sa.h" ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/radij.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_tunnel.h" /* struct ipsecpriv */ ++#include "openswan/ipsec_xform.h" ++ ++#include ++#include ++ ++#include "openswan/ipsec_proto.h" ++ ++#ifdef CONFIG_IPSEC_DEBUG ++int debug_radij = 0; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++struct radij_node_head *rnh = NULL; ++#ifdef SPINLOCK ++spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED; ++#else /* SPINLOCK */ ++spinlock_t eroute_lock; ++#endif /* SPINLOCK */ ++ ++int ++ipsec_radijinit(void) ++{ ++ maj_keylen = sizeof (struct sockaddr_encap); ++ ++ rj_init(); ++ ++ if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */ ++ return -1; ++ return 0; ++} ++ ++int ++ipsec_radijcleanup(void) ++{ ++ int error; ++ ++ spin_lock_bh(&eroute_lock); ++ ++ error = radijcleanup(); ++ ++ spin_unlock_bh(&eroute_lock); ++ ++ return error; ++} ++ ++int ++ipsec_cleareroutes(void) ++{ ++ int error; ++ ++ spin_lock_bh(&eroute_lock); ++ ++ error = radijcleartree(); ++ ++ spin_unlock_bh(&eroute_lock); ++ ++ return error; ++} ++ ++int ++ipsec_breakroute(struct sockaddr_encap *eaddr, ++ struct sockaddr_encap *emask, ++ struct sk_buff **first, ++ struct sk_buff **last) ++{ ++ struct eroute *ro; ++ struct radij_node *rn; ++ int error; ++#ifdef CONFIG_IPSEC_DEBUG ++ ++ if (debug_eroute) { ++ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; ++ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); ++ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); ++ KLIPS_PRINT(debug_eroute, ++ "klips_debug:ipsec_breakroute: " ++ "attempting to delete eroute for %s:%d->%s:%d %d\n", ++ buf1, ntohs(eaddr->sen_sport), ++ buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ spin_lock_bh(&eroute_lock); ++ ++ if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) { ++ spin_unlock_bh(&eroute_lock); ++ KLIPS_PRINT(debug_eroute, ++ "klips_debug:ipsec_breakroute: " ++ "node not found, eroute delete failed.\n"); ++ return error; ++ } ++ ++ spin_unlock_bh(&eroute_lock); ++ ++ ro = (struct eroute *)rn; ++ ++ KLIPS_PRINT(debug_eroute, ++ "klips_debug:ipsec_breakroute: " ++ "deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n", ++ ro, ++ ro->er_ident_s.data, ++ ro->er_ident_d.data, ++ ro->er_first, ++ ro->er_last); ++ ++ if (ro->er_ident_s.data != NULL) { ++ kfree(ro->er_ident_s.data); ++ } ++ if (ro->er_ident_d.data != NULL) { ++ kfree(ro->er_ident_d.data); ++ } ++ if (ro->er_first != NULL) { ++#if 0 ++ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats); ++ stats->tx_dropped--; ++#endif ++ *first = ro->er_first; ++ } ++ if (ro->er_last != NULL) { ++#if 0 ++ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats); ++ stats->tx_dropped--; ++#endif ++ *last = ro->er_last; ++ } ++ ++ if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT)) ++ panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n"); ++ memset((caddr_t)rn, 0, sizeof (struct eroute)); ++ kfree(rn); ++ ++ return 0; ++} ++ ++int ++ipsec_makeroute(struct sockaddr_encap *eaddr, ++ struct sockaddr_encap *emask, ++ ip_said said, ++ uint32_t pid, ++ struct sk_buff *skb, ++ struct ident *ident_s, ++ struct ident *ident_d) ++{ ++ struct eroute *retrt; ++ int error; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ ++ if (debug_eroute) { ++ ++ { ++ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; ++ ++ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); ++ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); ++ sa_len = satot(&said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_eroute, ++ "klips_debug:ipsec_makeroute: " ++ "attempting to allocate %lu bytes to insert eroute for %s->%s, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n", ++ (unsigned long) sizeof(struct eroute), ++ buf1, ++ buf2, ++ sa_len ? sa : " (error)", ++ pid, ++ skb, ++ (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"), ++ (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL")); ++ } ++ { ++ char buf1[sizeof(struct sockaddr_encap)*2 + 1], ++ buf2[sizeof(struct sockaddr_encap)*2 + 1]; ++ int i; ++ unsigned char *b1 = buf1, ++ *b2 = buf2, ++ *ea = (unsigned char *)eaddr, ++ *em = (unsigned char *)emask; ++ ++ ++ for (i=0; ier_eaddr = *eaddr; ++ retrt->er_emask = *emask; ++ retrt->er_said = said; ++ retrt->er_pid = pid; ++ retrt->er_count = 0; ++ retrt->er_lasttime = jiffies/HZ; ++ rd_key((&(retrt->er_rjt))) = &(retrt->er_eaddr); ++ ++ if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) { ++ int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); ++ ++ retrt->er_ident_s.type = ident_s->type; ++ retrt->er_ident_s.id = ident_s->id; ++ retrt->er_ident_s.len = ident_s->len; ++ if(data_len) { ++ KLIPS_PRINT(debug_eroute, ++ "klips_debug:ipsec_makeroute: " ++ "attempting to allocate %u bytes for ident_s.\n", ++ data_len); ++ if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) { ++ kfree(retrt); ++ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len); ++ return ENOMEM; ++ } ++ memcpy(retrt->er_ident_s.data, ident_s->data, data_len); ++ } else { ++ retrt->er_ident_s.data = NULL; ++ } ++ } ++ ++ if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) { ++ int data_len = ident_d->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); ++ ++ retrt->er_ident_d.type = ident_d->type; ++ retrt->er_ident_d.id = ident_d->id; ++ retrt->er_ident_d.len = ident_d->len; ++ if(data_len) { ++ KLIPS_PRINT(debug_eroute, ++ "klips_debug:ipsec_makeroute: " ++ "attempting to allocate %u bytes for ident_d.\n", ++ data_len); ++ if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) { ++ if (retrt->er_ident_s.data) ++ kfree(retrt->er_ident_s.data); ++ kfree(retrt); ++ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len); ++ return ENOMEM; ++ } ++ memcpy(retrt->er_ident_d.data, ident_d->data, data_len); ++ } else { ++ retrt->er_ident_d.data = NULL; ++ } ++ } ++ retrt->er_first = skb; ++ retrt->er_last = NULL; ++ ++ KLIPS_PRINT(debug_eroute, ++ "klips_debug:ipsec_makeroute: " ++ "calling rj_addroute now\n"); ++ ++ spin_lock_bh(&eroute_lock); ++ ++ error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask), ++ rnh, retrt->er_rjt.rd_nodes); ++ ++ spin_unlock_bh(&eroute_lock); ++ ++ if(error) { ++ sa_len = satot(&said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_eroute, ++ "klips_debug:ipsec_makeroute: " ++ "rj_addroute not able to insert eroute for SA:%s (error:%d)\n", ++ sa_len ? sa : " (error)", error); ++ if (retrt->er_ident_s.data) ++ kfree(retrt->er_ident_s.data); ++ if (retrt->er_ident_d.data) ++ kfree(retrt->er_ident_d.data); ++ ++ kfree(retrt); ++ ++ return error; ++ } ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if (debug_eroute) { ++ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; ++/* ++ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); ++ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); ++*/ ++ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1)); ++ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2)); ++ sa_len = satot(&retrt->er_said, 0, sa, sizeof(sa)); ++ ++ KLIPS_PRINT(debug_eroute, ++ "klips_debug:ipsec_makeroute: " ++ "pid=%05d " ++ "count=%10d " ++ "lasttime=%6d " ++ "%-18s -> %-18s => %s\n", ++ retrt->er_pid, ++ retrt->er_count, ++ (int)(jiffies/HZ - retrt->er_lasttime), ++ buf1, ++ buf2, ++ sa_len ? sa : " (error)"); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ KLIPS_PRINT(debug_eroute, ++ "klips_debug:ipsec_makeroute: " ++ "succeeded.\n"); ++ return 0; ++} ++ ++struct eroute * ++ipsec_findroute(struct sockaddr_encap *eaddr) ++{ ++ struct radij_node *rn; ++#ifdef CONFIG_IPSEC_DEBUG ++ char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF]; ++ ++ if (debug_radij & DB_RJ_FINDROUTE) { ++ addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1)); ++ addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2)); ++ KLIPS_PRINT(debug_eroute, ++ "klips_debug:ipsec_findroute: " ++ "%s:%d->%s:%d %d\n", ++ buf1, ntohs(eaddr->sen_sport), ++ buf2, ntohs(eaddr->sen_dport), ++ eaddr->sen_proto); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ rn = rj_match((caddr_t)eaddr, rnh); ++ if(rn) { ++ KLIPS_PRINT(debug_eroute && sysctl_ipsec_debug_verbose, ++ "klips_debug:ipsec_findroute: " ++ "found, points to proto=%d, spi=%x, dst=%x.\n", ++ ((struct eroute*)rn)->er_said.proto, ++ ntohl(((struct eroute*)rn)->er_said.spi), ++ ntohl(((struct eroute*)rn)->er_said.dst.u.v4.sin_addr.s_addr)); ++ } ++ return (struct eroute *)rn; ++} ++ ++#ifdef CONFIG_PROC_FS ++/** ipsec_rj_walker_procprint: print one line of eroute table output. ++ * ++ * Theoretical BUG: if w->length is less than the length ++ * of some line we should produce, that line will never ++ * be finished. In effect, the "file" will stop part way ++ * through that line. ++ */ ++int ++ipsec_rj_walker_procprint(struct radij_node *rn, void *w0) ++{ ++ struct eroute *ro = (struct eroute *)rn; ++ struct rjtentry *rd = (struct rjtentry *)rn; ++ struct wsbuf *w = (struct wsbuf *)w0; ++ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; ++ char buf3[16]; ++ char sa[SATOT_BUF]; ++ size_t sa_len, buf_len; ++ struct sockaddr_encap *key, *mask; ++ ++ KLIPS_PRINT(debug_radij, ++ "klips_debug:ipsec_rj_walker_procprint: " ++ "rn=0p%p, w0=0p%p\n", ++ rn, ++ w0); ++ if (rn->rj_b >= 0) { ++ return 0; ++ } ++ ++ key = rd_key(rd); ++ mask = rd_mask(rd); ++ ++ if (key == NULL || mask == NULL) { ++ return 0; ++ } ++ ++ buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1)); ++ if(key->sen_sport != 0) { ++ sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport)); ++ } ++ ++ buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2)); ++ if(key->sen_dport != 0) { ++ sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport)); ++ } ++ ++ buf3[0]='\0'; ++ if(key->sen_proto != 0) { ++ sprintf(buf3, ":%d", key->sen_proto); ++ } ++ ++ sa_len = satot(&ro->er_said, 'x', sa, sizeof(sa)); ++ w->len += ipsec_snprintf(w->buffer + w->len, ++ w->length - w->len, ++ "%-10d " ++ "%-18s -> %-18s => %s%s\n", ++ ro->er_count, ++ buf1, ++ buf2, ++ sa_len ? sa : " (error)", ++ buf3); ++ ++ { ++ /* snprintf can only fill the last character with NUL ++ * so the maximum useful character is w->length-1. ++ * However, if w->length == 0, we cannot go back. ++ * (w->length surely cannot be negative.) ++ */ ++ int max_content = w->length > 0? w->length-1 : 0; ++ ++ if (w->len >= max_content) { ++ /* we've done all that can fit -- stop treewalking */ ++ w->len = max_content; /* truncate crap */ ++ return -ENOBUFS; ++ } else { ++ const off_t pos = w->begin + w->len; /* file position of end of what we've generated */ ++ ++ if (pos <= w->offset) { ++ /* all is before first interesting character: ++ * discard, but note where we are. ++ */ ++ w->len = 0; ++ w->begin = pos; ++ } ++ return 0; ++ } ++ } ++} ++#endif /* CONFIG_PROC_FS */ ++ ++int ++ipsec_rj_walker_delete(struct radij_node *rn, void *w0) ++{ ++ struct eroute *ro; ++ struct rjtentry *rd = (struct rjtentry *)rn; ++ struct radij_node *rn2; ++ int error; ++ struct sockaddr_encap *key, *mask; ++ ++ key = rd_key(rd); ++ mask = rd_mask(rd); ++ ++ if(!key || !mask) { ++ return -ENODATA; ++ } ++#ifdef CONFIG_IPSEC_DEBUG ++ if(debug_radij) { ++ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; ++ subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1)); ++ subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2)); ++ KLIPS_PRINT(debug_radij, ++ "klips_debug:ipsec_rj_walker_delete: " ++ "deleting: %s -> %s\n", ++ buf1, ++ buf2); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ if((error = rj_delete(key, mask, rnh, &rn2))) { ++ KLIPS_PRINT(debug_radij, ++ "klips_debug:ipsec_rj_walker_delete: " ++ "rj_delete failed with error=%d.\n", error); ++ return error; ++ } ++ ++ if(rn2 != rn) { ++ printk("klips_debug:ipsec_rj_walker_delete: " ++ "tried to delete a different node?!? This should never happen!\n"); ++ } ++ ++ ro = (struct eroute *)rn; ++ ++ if (ro->er_ident_s.data) ++ kfree(ro->er_ident_s.data); ++ if (ro->er_ident_d.data) ++ kfree(ro->er_ident_d.data); ++ ++ memset((caddr_t)rn, 0, sizeof (struct eroute)); ++ kfree(rn); ++ ++ return 0; ++} ++ ++/* ++ * $Log: ipsec_radij.c,v $ ++ * Revision 1.70 2004/04/25 21:10:52 ken ++ * Pull in dhr's changes from FreeS/WAN 2.06 ++ * ++ * Revision 1.69 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.68 2004/03/28 20:27:20 paul ++ * Included tested and confirmed fixes mcr made and dhr verified for ++ * snprint statements. Changed one other snprintf to use ipsec_snprintf ++ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with ++ * dhr. (thanks dhr!) ++ * ++ * Revision 1.67.4.1 2004/04/05 04:30:46 mcr ++ * patches for alg-branch to compile/work with 2.x openswan ++ * ++ * Revision 1.67 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.66.24.2 2003/10/29 01:30:41 mcr ++ * elimited "struct sa_id". ++ * ++ * Revision 1.66.24.1 2003/09/21 13:59:56 mcr ++ * pre-liminary X.509 patch - does not yet pass tests. ++ * ++ * Revision 1.66 2002/10/12 23:11:53 dhr ++ * ++ * [KenB + DHR] more 64-bit cleanup ++ * ++ * Revision 1.65 2002/09/20 05:01:40 rgb ++ * Added memory allocation debugging. ++ * ++ * Revision 1.64 2002/05/31 01:46:05 mcr ++ * added && sysctl_ipsec_debug_verbose verbose to ipsec_findroute ++ * as requested in PR#14. ++ * ++ * Revision 1.63 2002/05/23 07:14:11 rgb ++ * Cleaned up %p variants to 0p%p for test suite cleanup. ++ * ++ * Revision 1.62 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.61 2002/04/24 07:36:29 mcr ++ * Moved from ./klips/net/ipsec/ipsec_radij.c,v ++ * ++ * Revision 1.60 2002/02/19 23:59:45 rgb ++ * Removed redundant compiler directives. ++ * ++ * Revision 1.59 2002/02/06 04:13:47 mcr ++ * missing #ifdef CONFIG_IPSEC_DEBUG. ++ * ++ * Revision 1.58 2002/01/29 17:17:56 mcr ++ * moved include of ipsec_param.h to after include of linux/kernel.h ++ * otherwise, it seems that some option that is set in ipsec_param.h ++ * screws up something subtle in the include path to kernel.h, and ++ * it complains on the snprintf() prototype. ++ * ++ * Revision 1.57 2002/01/29 04:00:52 mcr ++ * more excise of kversions.h header. ++ * ++ * Revision 1.56 2002/01/29 02:13:17 mcr ++ * introduction of ipsec_kversion.h means that include of ++ * ipsec_param.h must preceed any decisions about what files to ++ * include to deal with differences in kernel source. ++ * ++ * Revision 1.55 2001/11/26 09:23:48 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.53.2.1 2001/09/25 02:26:32 mcr ++ * headers adjusted for new usage. ++ * ++ * Revision 1.54 2001/10/18 04:45:20 rgb ++ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, ++ * lib/freeswan.h version macros moved to lib/kversions.h. ++ * Other compiler directive cleanups. ++ * ++ * Revision 1.53 2001/09/19 17:19:40 rgb ++ * Debug output bugfix for NetCelo's PF_KEY ident patch. ++ * ++ * Revision 1.52 2001/09/19 16:33:37 rgb ++ * Temporarily disable ident fields to /proc/net/ipsec_eroute. ++ * ++ * Revision 1.51 2001/09/15 16:24:04 rgb ++ * Re-inject first and last HOLD packet when an eroute REPLACE is done. ++ * ++ * Revision 1.50 2001/09/14 16:58:36 rgb ++ * Added support for storing the first and last packets through a HOLD. ++ * ++ * Revision 1.49 2001/09/08 21:13:32 rgb ++ * Added pfkey ident extension support for ISAKMPd. (NetCelo) ++ * ++ * Revision 1.48 2001/06/15 04:12:56 rgb ++ * Fixed kernel memory allocation error return code polarity bug. ++ * ++ * Revision 1.47 2001/06/14 19:35:09 rgb ++ * Update copyright date. ++ * ++ * Revision 1.46 2001/06/08 08:47:18 rgb ++ * Fixed for debug disabled. ++ * ++ * Revision 1.45 2001/05/27 06:12:11 rgb ++ * Added structures for pid, packet count and last access time to eroute. ++ * Added packet count to beginning of /proc/net/ipsec_eroute. ++ * ++ * Revision 1.44 2001/05/03 19:41:01 rgb ++ * Initialise error return variable. ++ * Use more appropriate return value for ipsec_rj_walker_delete(). ++ * ++ * Revision 1.43 2001/02/27 22:24:54 rgb ++ * Re-formatting debug output (line-splitting, joining, 1arg/line). ++ * Check for satoa() return codes. ++ * ++ * Revision 1.42 2001/02/27 06:21:57 rgb ++ * Added findroute success instrumentation. ++ * ++ * Revision 1.41 2000/11/06 04:32:08 rgb ++ * Ditched spin_lock_irqsave in favour of spin_lock_bh. ++ * ++ * Revision 1.40 2000/09/08 19:12:56 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * ++ * Revision 1.39 2000/08/30 05:25:20 rgb ++ * Correct debug text in ipsec_breakroute() from incorrect ++ * "ipsec_callback". ++ * ++ * Revision 1.38 2000/07/28 14:58:31 rgb ++ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. ++ * ++ * Revision 1.37 2000/03/16 14:02:50 rgb ++ * Fixed debug scope to enable compilation with debug off. ++ * ++ * Revision 1.36 2000/01/21 06:14:46 rgb ++ * Added debugging text to ipsec_rj_walker_delete(). ++ * Set return code to negative for consistency. ++ * ++ * Revision 1.35 1999/11/23 23:05:24 rgb ++ * Use provided macro ADDRTOA_BUF instead of hardcoded value. ++ * ++ * Revision 1.34 1999/11/18 04:13:56 rgb ++ * Replaced all kernel version macros to shorter, readable form. ++ * Added CONFIG_PROC_FS compiler directives in case it is shut off. ++ * ++ * Revision 1.33 1999/11/17 15:53:39 rgb ++ * Changed all occurrences of #include "../../../lib/freeswan.h" ++ * to #include which works due to -Ilibfreeswan in the ++ * klips/net/ipsec/Makefile. ++ * ++ * Revision 1.32 1999/10/26 13:58:33 rgb ++ * Put spinlock flags variable declaration outside the debug compiler ++ * directive to enable compilation with debug shut off. ++ * ++ * Revision 1.31 1999/10/15 22:13:29 rgb ++ * Clean out cruft. ++ * Align /proc/net/ipsec_eroute output for easier readability. ++ * Fix double linefeed in radij debug output. ++ * Fix double locking bug that locks up 2.0.36 but not 2.0.38. ++ * ++ * Revision 1.30 1999/10/08 18:37:33 rgb ++ * Fix end-of-line spacing to sate whining PHMs. ++ * ++ * Revision 1.29 1999/10/03 18:52:45 rgb ++ * Spinlock support for 2.0.xx. ++ * Dumb return code spin_unlock fix. ++ * ++ * Revision 1.28 1999/10/01 16:22:24 rgb ++ * Switch from assignment init. to functional init. of spinlocks. ++ * ++ * Revision 1.27 1999/10/01 15:44:53 rgb ++ * Move spinlock header include to 2.1> scope. ++ * ++ * Revision 1.26 1999/10/01 00:01:23 rgb ++ * Added eroute structure locking. ++ * ++ * Revision 1.25 1999/06/10 16:07:30 rgb ++ * Silence delete eroute on no debug. ++ * ++ * Revision 1.24 1999/05/09 03:25:36 rgb ++ * Fix bug introduced by 2.2 quick-and-dirty patch. ++ * ++ * Revision 1.23 1999/05/05 22:02:31 rgb ++ * Add a quick and dirty port to 2.2 kernels by Marc Boucher . ++ * ++ * Revision 1.22 1999/04/29 15:17:23 rgb ++ * Add return values to init and cleanup functions. ++ * Add sanity checking for null pointer arguments. ++ * ++ * Revision 1.21 1999/04/11 00:28:58 henry ++ * GPL boilerplate ++ * ++ * Revision 1.20 1999/04/06 04:54:26 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.19 1999/02/17 16:50:35 rgb ++ * Clean out unused cruft. ++ * Consolidate for space and speed efficiency. ++ * Convert DEBUG_IPSEC to KLIPS_PRINT ++ * ++ * Revision 1.18 1999/01/22 06:22:06 rgb ++ * Cruft clean-out. ++ * 64-bit clean-up. ++ * ++ * Revision 1.17 1998/12/02 03:09:39 rgb ++ * Clean up debug printing conditionals to compile with debugging off. ++ * ++ * Revision 1.16 1998/12/01 13:49:39 rgb ++ * Wrap version info printing in debug switches. ++ * ++ * Revision 1.15 1998/11/30 13:22:54 rgb ++ * Rationalised all the klips kernel file headers. They are much shorter ++ * now and won't conflict under RH5.2. ++ * ++ * Revision 1.14 1998/10/31 06:48:17 rgb ++ * Fixed up comments in #endif directives. ++ * ++ * Revision 1.13 1998/10/27 13:48:09 rgb ++ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts. ++ * Fixed less(1) truncated output bug. ++ * Code clean-up. ++ * ++ * Revision 1.12 1998/10/25 02:41:36 rgb ++ * Change return type on ipsec_breakroute and ipsec_makeroute and add an ++ * argument to be able to transmit more infomation about errors. ++ * Fix cut-and-paste debug statement identifier. ++ * ++ * Revision 1.11 1998/10/22 06:45:39 rgb ++ * Cleaned up cruft. ++ * Convert to use satoa for printk. ++ * ++ * Revision 1.10 1998/10/19 14:44:28 rgb ++ * Added inclusion of freeswan.h. ++ * sa_id structure implemented and used: now includes protocol. ++ * ++ * Revision 1.9 1998/10/09 04:30:52 rgb ++ * Added 'klips_debug' prefix to all klips printk debug statements. ++ * Deleted old commented out cruft. ++ * ++ * Revision 1.8 1998/08/06 17:24:23 rgb ++ * Fix addrtoa return code bug from stale manpage advice preventing packets ++ * from being erouted. ++ * ++ * Revision 1.7 1998/08/06 07:44:59 rgb ++ * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that ++ * ended up in nothing being printed. ++ * ++ * Revision 1.6 1998/08/05 22:16:41 rgb ++ * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal. ++ * ++ * Revision 1.5 1998/07/29 20:38:44 rgb ++ * Debug and fix subnettoa and addrtoa output. ++ * ++ * Revision 1.4 1998/07/28 00:02:39 rgb ++ * Converting to exclusive use of addrtoa. ++ * Fix eroute delete. ++ * ++ * Revision 1.3 1998/07/14 18:21:26 rgb ++ * Add function to clear the eroute table. ++ * ++ * Revision 1.2 1998/06/23 02:59:14 rgb ++ * Added debugging output to eroute add/delete routines. ++ * ++ * Revision 1.9 1998/06/18 21:29:06 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel ++ * build scripts happier in presence of symbolic links ++ * ++ * Revision 1.8 1998/06/05 02:32:26 rgb ++ * Fix spi ntoh kernel debug output. ++ * ++ * Revision 1.7 1998/05/25 20:30:37 rgb ++ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions. ++ * ++ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and ++ * add ipsec_rj_walker_delete. ++ * ++ * Revision 1.6 1998/05/21 13:08:57 rgb ++ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of ++ * information is available for printout. ++ * ++ * Revision 1.5 1998/05/18 21:35:55 rgb ++ * Clean up output for numerical consistency and readability. Zero freed ++ * eroute memory. ++ * ++ * Revision 1.4 1998/04/21 21:28:58 rgb ++ * Rearrange debug switches to change on the fly debug output from user ++ * space. Only kernel changes checked in at this time. radij.c was also ++ * changed to temporarily remove buggy debugging code in rj_delete causing ++ * an OOPS and hence, netlink device open errors. ++ * ++ * Revision 1.3 1998/04/14 17:30:39 rgb ++ * Fix up compiling errors for radij tree memory reclamation. ++ * ++ * Revision 1.2 1998/04/12 22:03:23 rgb ++ * Updated ESP-3DES-HMAC-MD5-96, ++ * ESP-DES-HMAC-MD5-96, ++ * AH-HMAC-MD5-96, ++ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository ++ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. ++ * ++ * Fixed eroute references in /proc/net/ipsec*. ++ * ++ * Started to patch module unloading memory leaks in ipsec_netlink and ++ * radij tree unloading. ++ * ++ * Revision 1.1 1998/04/09 03:06:10 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:03 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * No changes. ++ * ++ * Revision 0.3 1996/11/20 14:39:04 ji ++ * Minor cleanups. ++ * Rationalized debugging code. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_rcv.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,1922 @@ ++/* ++ * receive code ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998-2003 Richard Guy Briggs. ++ * Copyright (C) 2004 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ */ ++ ++char ipsec_rcv_c_version[] = "RCSID $Id: ipsec_rcv.c,v 1.143.4.2 2004/08/22 03:29:06 mcr Exp $"; ++ ++#include ++#include ++ ++#define __NO_VERSION__ ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include ++#include ++#ifdef SPINLOCK ++# ifdef SPINLOCK_23 ++# include /* *lock* */ ++# else /* SPINLOCK_23 */ ++# include /* *lock* */ ++# endif /* SPINLOCK_23 */ ++#endif /* SPINLOCK */ ++#ifdef NET_21 ++# include ++# include ++# define proto_priv cb ++#endif /* NET21 */ ++#include ++#include ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_sa.h" ++ ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_tunnel.h" ++#include "openswan/ipsec_rcv.h" ++ ++#include "openswan/ipsec_auth.h" ++ ++#include "openswan/ipsec_esp.h" ++ ++#ifdef CONFIG_IPSEC_AH ++#include "openswan/ipsec_ah.h" ++#endif /* CONFIG_IPSEC_AH */ ++ ++#ifdef CONFIG_IPSEC_IPCOMP ++#include "openswan/ipsec_ipcomp.h" ++#endif /* CONFIG_IPSEC_COMP */ ++ ++#include ++#include ++ ++#include "openswan/ipsec_proto.h" ++#include "openswan/ipsec_alg.h" ++ ++#ifdef CONFIG_IPSEC_DEBUG ++int debug_rcv = 0; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++int sysctl_ipsec_inbound_policy_check = 1; ++ ++/* This is a private use protocol, and AT&T should be ashamed. They should have ++ * used protocol # 59, which is "no next header" instead of 0xFE. ++ */ ++#ifndef IPPROTO_ATT_HEARTBEAT ++#define IPPROTO_ATT_HEARTBEAT 0xFE ++#endif ++ ++#ifdef CONFIG_IPSEC_DEBUG ++void ++ipsec_dmp(char *s, caddr_t bb, int len) ++{ ++ int i; ++ unsigned char *b = bb; ++ ++ ++ printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: " ++ "at %s, len=%d:", ++ s, ++ len); ++ for (i=0; i < len; i++) { ++ if(!(i%16)){ ++ printk("\nklips_debug: "); ++ } ++ printk(" %02x", *b++); ++ } ++ printk("\n"); ++} ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++/* ++ * Check-replay-window routine, adapted from the original ++ * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt ++ * ++ * This is a routine that implements a 64 packet window. This is intend- ++ * ed on being an implementation sample. ++ */ ++ ++DEBUG_NO_STATIC int ++ipsec_checkreplaywindow(struct ipsec_sa*ipsp, __u32 seq) ++{ ++ __u32 diff; ++ ++ if (ipsp->ips_replaywin == 0) /* replay shut off */ ++ return 1; ++ if (seq == 0) ++ return 0; /* first == 0 or wrapped */ ++ ++ /* new larger sequence number */ ++ if (seq > ipsp->ips_replaywin_lastseq) { ++ return 1; /* larger is good */ ++ } ++ diff = ipsp->ips_replaywin_lastseq - seq; ++ ++ /* too old or wrapped */ /* if wrapped, kill off SA? */ ++ if (diff >= ipsp->ips_replaywin) { ++ return 0; ++ } ++ /* this packet already seen */ ++ if (ipsp->ips_replaywin_bitmap & (1 << diff)) ++ return 0; ++ return 1; /* out of order but good */ ++} ++ ++DEBUG_NO_STATIC int ++ipsec_updatereplaywindow(struct ipsec_sa*ipsp, __u32 seq) ++{ ++ __u32 diff; ++ ++ if (ipsp->ips_replaywin == 0) /* replay shut off */ ++ return 1; ++ if (seq == 0) ++ return 0; /* first == 0 or wrapped */ ++ ++ /* new larger sequence number */ ++ if (seq > ipsp->ips_replaywin_lastseq) { ++ diff = seq - ipsp->ips_replaywin_lastseq; ++ ++ /* In win, set bit for this pkt */ ++ if (diff < ipsp->ips_replaywin) ++ ipsp->ips_replaywin_bitmap = ++ (ipsp->ips_replaywin_bitmap << diff) | 1; ++ else ++ /* This packet has way larger seq num */ ++ ipsp->ips_replaywin_bitmap = 1; ++ ++ if(seq - ipsp->ips_replaywin_lastseq - 1 > ipsp->ips_replaywin_maxdiff) { ++ ipsp->ips_replaywin_maxdiff = seq - ipsp->ips_replaywin_lastseq - 1; ++ } ++ ipsp->ips_replaywin_lastseq = seq; ++ return 1; /* larger is good */ ++ } ++ diff = ipsp->ips_replaywin_lastseq - seq; ++ ++ /* too old or wrapped */ /* if wrapped, kill off SA? */ ++ if (diff >= ipsp->ips_replaywin) { ++/* ++ if(seq < 0.25*max && ipsp->ips_replaywin_lastseq > 0.75*max) { ++ ipsec_sa_delchain(ipsp); ++ } ++*/ ++ return 0; ++ } ++ /* this packet already seen */ ++ if (ipsp->ips_replaywin_bitmap & (1 << diff)) ++ return 0; ++ ipsp->ips_replaywin_bitmap |= (1 << diff); /* mark as seen */ ++ return 1; /* out of order but good */ ++} ++ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++struct auth_alg ipsec_rcv_md5[]={ ++ {MD5Init, MD5Update, MD5Final, AHMD596_ALEN} ++}; ++ ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++struct auth_alg ipsec_rcv_sha1[]={ ++ {SHA1Init, SHA1Update, SHA1Final, AHSHA196_ALEN} ++}; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++ ++enum ipsec_rcv_value ++ipsec_rcv_decap_once(struct ipsec_rcv_state *irs, struct xform_functions *proto_funcs) ++{ ++ int iphlen; ++ unsigned char *dat; ++ __u8 proto; ++ struct in_addr ipsaddr; ++ struct in_addr ipdaddr; ++ int replay = 0; /* replay value in AH or ESP packet */ ++ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */ ++ struct ipsec_sa *newipsp; ++ struct iphdr *ipp; ++ struct sk_buff *skb; ++#ifdef CONFIG_IPSEC_ALG ++ struct ipsec_alg_auth *ixt_a=NULL; ++#endif /* CONFIG_IPSEC_ALG */ ++ ++ skb = irs->skb; ++ irs->len = skb->len; ++ dat = skb->data; ++ ipp = irs->ipp; ++ proto = ipp->protocol; ++ ipsaddr.s_addr = ipp->saddr; ++ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt)); ++ ipdaddr.s_addr = ipp->daddr; ++ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt)); ++ ++ iphlen = ipp->ihl << 2; ++ irs->iphlen=iphlen; ++ ipp->check = 0; /* we know the sum is good */ ++ ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv_decap_once: " ++ "decap (%d) from %s -> %s\n", ++ proto, irs->ipsaddr_txt, irs->ipdaddr_txt); ++ ++ /* ++ * Find tunnel control block and (indirectly) call the ++ * appropriate tranform routine. The resulting sk_buf ++ * is a valid IP packet ready to go through input processing. ++ */ ++ ++ irs->said.dst.u.v4.sin_addr.s_addr = ipp->daddr; ++ irs->said.dst.u.v4.sin_family = AF_INET; ++ ++ if(proto_funcs->rcv_checks) { ++ enum ipsec_rcv_value retval = ++ (*proto_funcs->rcv_checks)(irs, skb); ++ ++ if(retval < 0) { ++ return retval; ++ } ++ } ++ ++ irs->said.proto = proto; ++ irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa)); ++ if(irs->sa_len == 0) { ++ strcpy(irs->sa, "(error)"); ++ } ++ ++ newipsp = ipsec_sa_getbyid(&irs->said); ++ if (newipsp == NULL) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n", ++ irs->sa_len ? irs->sa : " (error)"); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ return IPSEC_RCV_SAIDNOTFOUND; ++ } ++ ++ /* MCR - XXX this is bizarre. ipsec_sa_getbyid returned it, having incremented the refcount, ++ * why in the world would we decrement it here? ++ ++ ipsec_sa_put(irs->ipsp);*/ /* incomplete */ ++ ++ /* If it is in larval state, drop the packet, we cannot process yet. */ ++ if(newipsp->ips_state == SADB_SASTATE_LARVAL) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "ipsec_sa in larval state, cannot be used yet, dropping packet.\n"); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ ipsec_sa_put(newipsp); ++ return IPSEC_RCV_SAIDNOTLIVE; ++ } ++ ++ if(newipsp->ips_state == SADB_SASTATE_DEAD) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "ipsec_sa in dead state, cannot be used any more, dropping packet.\n"); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ ipsec_sa_put(newipsp); ++ return IPSEC_RCV_SAIDNOTLIVE; ++ } ++ ++ if(sysctl_ipsec_inbound_policy_check) { ++ if(irs->ipp->saddr != ((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n", ++ irs->sa_len ? irs->sa : " (error)", ++ irs->ipsaddr_txt); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ ipsec_sa_put(newipsp); ++ return IPSEC_RCV_FAILEDINBOUND; ++ } ++ ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n", ++ irs->sa_len ? irs->sa : " (error)", ++ irs->ipsaddr_txt); ++ ++ /* ++ * at this point, we have looked up a new SA, and we want to make sure that if this ++ * isn't the first SA in the list, that the previous SA actually points at this one. ++ */ ++ if(irs->ipsp) { ++ if(irs->ipsp->ips_inext != newipsp) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "unexpected SA:%s: does not agree with ips->inext policy, dropped\n", ++ irs->sa_len ? irs->sa : " (error)"); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ ipsec_sa_put(newipsp); ++ return IPSEC_RCV_FAILEDINBOUND; ++ } ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "SA:%s grouping from previous SA is OK.\n", ++ irs->sa_len ? irs->sa : " (error)"); ++ } else { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "SA:%s First SA in group.\n", ++ irs->sa_len ? irs->sa : " (error)"); ++ } ++ ++ /* ++ * previously, at this point, we checked if the back pointer from the new SA that ++ * we just found matched the back pointer. But, we won't do this check anymore, ++ * because we want to be able to nest SAs ++ */ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "natt_type=%u tdbp->ips_natt_type=%u : %s\n", ++ irs->natt_type, newipsp->ips_natt_type, ++ (irs->natt_type==newipsp->ips_natt_type)?"ok":"bad"); ++ if (irs->natt_type != newipsp->ips_natt_type) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "SA:%s does not agree with expected NAT-T policy.\n", ++ irs->sa_len ? irs->sa : " (error)"); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ ipsec_sa_put(newipsp); ++ return IPSEC_RCV_FAILEDINBOUND; ++ } ++#endif ++ } ++ ++ /* okay, SA checks out, so free any previous SA, and record a new one */ ++ ++ if(irs->ipsp) { ++ ipsec_sa_put(irs->ipsp); ++ } ++ irs->ipsp=newipsp; ++ ++ /* note that the outer code will free the irs->ipsp if there is an error */ ++ ++ ++ /* now check the lifetimes */ ++ if(ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_bytes, "bytes", ++ irs->sa, ipsec_life_countbased, ipsec_incoming, ++ irs->ipsp) == ipsec_life_harddied || ++ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "addtime", ++ irs->sa, ipsec_life_timebased, ipsec_incoming, ++ irs->ipsp) == ipsec_life_harddied || ++ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "usetime", ++ irs->sa, ipsec_life_timebased, ipsec_incoming, ++ irs->ipsp) == ipsec_life_harddied || ++ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_packets, "packets", ++ irs->sa, ipsec_life_countbased, ipsec_incoming, ++ irs->ipsp) == ipsec_life_harddied) { ++ ipsec_sa_delchain(irs->ipsp); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv_decap_once: " ++ "decap (%d) failed lifetime check\n", ++ proto); ++ ++ return IPSEC_RCV_LIFETIMEFAILED; ++ } ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ if ((irs->natt_type) && ++ ( (irs->ipp->saddr != (((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr)) || ++ (irs->natt_sport != newipsp->ips_natt_sport) ++ )) { ++ struct sockaddr sipaddr; ++ /** Advertise NAT-T addr change to pluto **/ ++ sipaddr.sa_family = AF_INET; ++ ((struct sockaddr_in*)&sipaddr)->sin_addr.s_addr = irs->ipp->saddr; ++ ((struct sockaddr_in*)&sipaddr)->sin_port = htons(irs->natt_sport); ++ pfkey_nat_t_new_mapping(newipsp, &sipaddr, irs->natt_sport); ++ /** ++ * Then allow or block packet depending on ++ * sysctl_ipsec_inbound_policy_check. ++ * ++ * In all cases, pluto will update SA if new mapping is ++ * accepted. ++ */ ++ if (sysctl_ipsec_inbound_policy_check) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "SA:%s, src=%s:%u of pkt does not agree with expected " ++ "SA source address policy (pluto has been informed).\n", ++ irs->sa_len ? irs->sa : " (error)", ++ irs->ipsaddr_txt, irs->natt_sport); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ ipsec_sa_put(newipsp); ++ return IPSEC_RCV_FAILEDINBOUND; ++ } ++ } ++#endif ++ ++ irs->authfuncs=NULL; ++ /* authenticate, if required */ ++#ifdef CONFIG_IPSEC_ALG ++ if ((ixt_a=irs->ipsp->ips_alg_auth)) { ++ irs->authlen = AHHMAC_HASHLEN; ++ irs->authfuncs = NULL; ++ irs->ictx = NULL; ++ irs->octx = NULL; ++ irs->ictx_len = 0; ++ irs->octx_len = 0; ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "authalg=%d authlen=%d\n", ++ irs->ipsp->ips_authalg, ++ irs->authlen); ++ } else ++#endif /* CONFIG_IPSEC_ALG */ ++ switch(irs->ipsp->ips_authalg) { ++#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ case AH_MD5: ++ irs->authlen = AHHMAC_HASHLEN; ++ irs->authfuncs = ipsec_rcv_md5; ++ irs->ictx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx; ++ irs->octx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx; ++ irs->ictx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx); ++ irs->octx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx); ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ case AH_SHA: ++ irs->authlen = AHHMAC_HASHLEN; ++ irs->authfuncs = ipsec_rcv_sha1; ++ irs->ictx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx; ++ irs->octx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx; ++ irs->ictx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx); ++ irs->octx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx); ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++ case AH_NONE: ++ irs->authlen = 0; ++ irs->authfuncs = NULL; ++ irs->ictx = NULL; ++ irs->octx = NULL; ++ irs->ictx_len = 0; ++ irs->octx_len = 0; ++ break; ++ default: ++ irs->ipsp->ips_errs.ips_alg_errs += 1; ++ if(irs->stats) { ++ irs->stats->rx_errors++; ++ } ++ return IPSEC_RCV_BADAUTH; ++ } ++ ++ irs->ilen = irs->len - iphlen - irs->authlen; ++ if(irs->ilen <= 0) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "runt %s packet with no data, dropping.\n", ++ (proto == IPPROTO_ESP ? "esp" : "ah")); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ return IPSEC_RCV_BADLEN; ++ } ++ ++#ifdef CONFIG_IPSEC_ALG ++ if(irs->authfuncs || ixt_a) { ++#else ++ if(irs->authfuncs) { ++#endif ++ unsigned char *authenticator = NULL; ++ ++ if(proto_funcs->rcv_setup_auth) { ++ enum ipsec_rcv_value retval ++ = (*proto_funcs->rcv_setup_auth)(irs, skb, ++ &replay, ++ &authenticator); ++ if(retval < 0) { ++ return retval; ++ } ++ } ++ ++ if(!authenticator) { ++ irs->ipsp->ips_errs.ips_auth_errs += 1; ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ return IPSEC_RCV_BADAUTH; ++ } ++ ++ if(!ipsec_checkreplaywindow(irs->ipsp, replay)) { ++ irs->ipsp->ips_errs.ips_replaywin_errs += 1; ++ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY, ++ "klips_debug:ipsec_rcv: " ++ "duplicate frame from %s, packet dropped\n", ++ irs->ipsaddr_txt); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ return IPSEC_RCV_REPLAYFAILED; ++ } ++ ++ /* ++ * verify authenticator ++ */ ++ ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "encalg = %d, authalg = %d.\n", ++ irs->ipsp->ips_encalg, ++ irs->ipsp->ips_authalg); ++ ++ /* calculate authenticator */ ++ if(proto_funcs->rcv_calc_auth == NULL) { ++ return IPSEC_RCV_BADAUTH; ++ } ++ (*proto_funcs->rcv_calc_auth)(irs, skb); ++ ++ if (memcmp(irs->hash, authenticator, irs->authlen)) { ++ irs->ipsp->ips_errs.ips_auth_errs += 1; ++ KLIPS_PRINT(debug_rcv & DB_RX_INAU, ++ "klips_debug:ipsec_rcv: " ++ "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n", ++ irs->ipsaddr_txt, ++ ntohl(*(__u32*)&irs->hash[0]), ++ ntohl(*(__u32*)&irs->hash[4]), ++ ntohl(*(__u32*)&irs->hash[8]), ++ ntohl(*(__u32*)authenticator), ++ ntohl(*((__u32*)authenticator + 1)), ++ ntohl(*((__u32*)authenticator + 2))); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ return IPSEC_RCV_AUTHFAILED; ++ } else { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "authentication successful.\n"); ++ } ++ ++ /* Crypto hygiene: clear memory used to calculate autheticator. ++ * The length varies with the algorithm. ++ */ ++ memset(irs->hash, 0, irs->authlen); ++ ++ /* If the sequence number == 0, expire SA, it had rolled */ ++ if(irs->ipsp->ips_replaywin && !replay /* !irs->ipsp->ips_replaywin_lastseq */) { ++ ipsec_sa_delchain(irs->ipsp); ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "replay window counter rolled, expiring SA.\n"); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ return IPSEC_RCV_REPLAYROLLED; ++ } ++ ++ /* now update the replay counter */ ++ if (!ipsec_updatereplaywindow(irs->ipsp, replay)) { ++ irs->ipsp->ips_errs.ips_replaywin_errs += 1; ++ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY, ++ "klips_debug:ipsec_rcv: " ++ "duplicate frame from %s, packet dropped\n", ++ irs->ipsaddr_txt); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ return IPSEC_RCV_REPLAYROLLED; ++ } ++ } ++ ++ if(proto_funcs->rcv_decrypt) { ++ enum ipsec_rcv_value retval = ++ (*proto_funcs->rcv_decrypt)(irs); ++ ++ if(retval != IPSEC_RCV_OK) { ++ return retval; ++ } ++ } ++ ++ /* ++ * Adjust pointers ++ */ ++ skb = irs->skb; ++ irs->len = skb->len; ++ dat = skb->data; ++ ++#ifdef NET_21 ++/* skb->h.ipiph=(struct iphdr *)skb->data; */ ++ skb->nh.raw = skb->data; ++ skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2); ++ ++ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); ++#else /* NET_21 */ ++ skb->h.iph=(struct iphdr *)skb->data; ++ skb->ip_hdr=(struct iphdr *)skb->data; ++ memset(skb->proto_priv, 0, sizeof(struct options)); ++#endif /* NET_21 */ ++ ++ ipp = (struct iphdr *)dat; ++ ipsaddr.s_addr = ipp->saddr; ++ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt)); ++ ipdaddr.s_addr = ipp->daddr; ++ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt)); ++ /* ++ * Discard the original ESP/AH header ++ */ ++ ipp->protocol = irs->next_header; ++ ++ ipp->check = 0; /* NOTE: this will be included in checksum */ ++ ipp->check = ip_fast_csum((unsigned char *)dat, iphlen >> 2); ++ ++ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, ++ "klips_debug:ipsec_rcv: " ++ "after <%s%s%s>, SA:%s:\n", ++ IPS_XFORM_NAME(irs->ipsp), ++ irs->sa_len ? irs->sa : " (error)"); ++ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp); ++ ++ skb->protocol = htons(ETH_P_IP); ++ skb->ip_summed = 0; ++ ++ ipsnext = irs->ipsp->ips_inext; ++ if(sysctl_ipsec_inbound_policy_check) { ++ if(ipsnext) { ++ if( ++ ipp->protocol != IPPROTO_AH ++ && ipp->protocol != IPPROTO_ESP ++#ifdef CONFIG_IPSEC_IPCOMP ++ && ipp->protocol != IPPROTO_COMP ++ && (ipsnext->ips_said.proto != IPPROTO_COMP ++ || ipsnext->ips_inext) ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ && ipp->protocol != IPPROTO_IPIP ++ && ipp->protocol != 0xFE /* added to support heartbeats to AT&T SIG/GIG */ ++ ) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "packet with incomplete policy dropped, last successful SA:%s.\n", ++ irs->sa_len ? irs->sa : " (error)"); ++ if(irs->stats) { ++ irs->stats->rx_dropped++; ++ } ++ return IPSEC_RCV_FAILEDINBOUND; ++ } ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "SA:%s, Another IPSEC header to process.\n", ++ irs->sa_len ? irs->sa : " (error)"); ++ } else { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "No ips_inext from this SA:%s.\n", ++ irs->sa_len ? irs->sa : " (error)"); ++ } ++ } ++ ++#ifdef CONFIG_IPSEC_IPCOMP ++ /* update ipcomp ratio counters, even if no ipcomp packet is present */ ++ if (ipsnext ++ && ipsnext->ips_said.proto == IPPROTO_COMP ++ && ipp->protocol != IPPROTO_COMP) { ++ ipsnext->ips_comp_ratio_cbytes += ntohs(ipp->tot_len); ++ ipsnext->ips_comp_ratio_dbytes += ntohs(ipp->tot_len); ++ } ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ ++ irs->ipsp->ips_life.ipl_bytes.ipl_count += irs->len; ++ irs->ipsp->ips_life.ipl_bytes.ipl_last = irs->len; ++ ++ if(!irs->ipsp->ips_life.ipl_usetime.ipl_count) { ++ irs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ; ++ } ++ irs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ; ++ irs->ipsp->ips_life.ipl_packets.ipl_count += 1; ++ ++#ifdef CONFIG_NETFILTER ++ if(proto == IPPROTO_ESP || proto == IPPROTO_AH) { ++ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_MASK)))) ++ | IPsecSAref2NFmark(IPsecSA2SAref(irs->ipsp)); ++ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, ++ "klips_debug:ipsec_rcv: " ++ "%s SA sets skb->nfmark=0x%x.\n", ++ proto == IPPROTO_ESP ? "ESP" : "AH", ++ (unsigned)skb->nfmark); ++ } ++#endif /* CONFIG_NETFILTER */ ++ ++ return IPSEC_RCV_OK; ++} ++ ++ ++int ++#ifdef PROTO_HANDLER_SINGLE_PARM ++ipsec_rcv(struct sk_buff *skb) ++#else /* PROTO_HANDLER_SINGLE_PARM */ ++#ifdef NET_21 ++ipsec_rcv(struct sk_buff *skb, unsigned short xlen) ++#else /* NET_21 */ ++ipsec_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ++ __u32 daddr_unused, unsigned short xlen, __u32 saddr, ++ int redo, struct inet_protocol *protocol) ++#endif /* NET_21 */ ++#endif /* PROTO_HANDLER_SINGLE_PARM */ ++{ ++#ifdef NET_21 ++#ifdef CONFIG_IPSEC_DEBUG ++ struct device *dev = skb->dev; ++#endif /* CONFIG_IPSEC_DEBUG */ ++#endif /* NET_21 */ ++ unsigned char protoc; ++ struct iphdr *ipp; ++ struct ipsec_sa *ipsp = NULL; ++ struct net_device_stats *stats = NULL; /* This device's statistics */ ++ struct device *ipsecdev = NULL, *prvdev; ++ struct ipsecpriv *prv; ++ char name[9]; ++ int i; ++ struct in_addr ipsaddr; ++ struct in_addr ipdaddr; ++ ++ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */ ++ struct ipsec_rcv_state irs; ++ ++ /* Don't unlink in the middle of a turnaround */ ++ MOD_INC_USE_COUNT; ++ ++ memset(&irs, 0, sizeof(struct ipsec_rcv_state)); ++ ++ if (skb == NULL) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "NULL skb passed in.\n"); ++ goto rcvleave; ++ } ++ ++ if (skb->data == NULL) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "NULL skb->data passed in, packet is bogus, dropping.\n"); ++ goto rcvleave; ++ } ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ if (skb->sk && skb->nh.iph && skb->nh.iph->protocol==IPPROTO_UDP) { ++ /** ++ * Packet comes from udp_queue_rcv_skb so it is already defrag, ++ * checksum verified, ... (ie safe to use) ++ * ++ * If the packet is not for us, return -1 and udp_queue_rcv_skb ++ * will continue to handle it (do not kfree skb !!). ++ */ ++#ifndef UDP_OPT_IN_SOCK ++ struct udp_opt { ++ __u32 esp_in_udp; ++ }; ++ struct udp_opt *tp = (struct udp_opt *)&(skb->sk->tp_pinfo.af_tcp); ++#else ++ struct udp_opt *tp = &(skb->sk->tp_pinfo.af_udp); ++#endif ++ struct iphdr *ip = (struct iphdr *)skb->nh.iph; ++ struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl); ++ __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr); ++ __u32 *udpdata32 = (__u32 *)udpdata; ++ ++ irs.natt_sport = ntohs(udp->source); ++ irs.natt_dport = ntohs(udp->dest); ++ ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "suspected ESPinUDP packet (NAT-Traversal) [%d].\n", ++ tp->esp_in_udp); ++ KLIPS_IP_PRINT(debug_rcv, ip); ++ ++ if (udpdata < skb->tail) { ++ unsigned int len = skb->tail - udpdata; ++ if ((len==1) && (udpdata[0]==0xff)) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ /* not IPv6 compliant message */ ++ "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr)); ++ goto rcvleave; ++ } ++ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) && ++ (len > (2*sizeof(__u32) + sizeof(struct esphdr))) && ++ (udpdata32[0]==0) && (udpdata32[1]==0) ) { ++ /* ESP Packet with Non-IKE header */ ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "ESPinUDP pkt with Non-IKE - spi=0x%x\n", ++ ntohl(udpdata32[2])); ++ irs.natt_type = ESPINUDP_WITH_NON_IKE; ++ irs.natt_len = sizeof(struct udphdr)+(2*sizeof(__u32)); ++ } ++ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) && ++ (len > sizeof(struct esphdr)) && ++ (udpdata32[0]!=0) ) { ++ /* ESP Packet without Non-ESP header */ ++ irs.natt_type = ESPINUDP_WITH_NON_ESP; ++ irs.natt_len = sizeof(struct udphdr); ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "ESPinUDP pkt without Non-ESP - spi=0x%x\n", ++ ntohl(udpdata32[0])); ++ } ++ else { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "IKE packet - not handled here\n"); ++ MOD_DEC_USE_COUNT; ++ return -1; ++ } ++ } ++ else { ++ MOD_DEC_USE_COUNT; ++ return -1; ++ } ++ } ++#endif ++ ++#ifdef IPH_is_SKB_PULLED ++ /* In Linux 2.4.4, the IP header has been skb_pull()ed before the ++ packet is passed to us. So we'll skb_push() to get back to it. */ ++ if (skb->data == skb->h.raw) { ++ skb_push(skb, skb->h.raw - skb->nh.raw); ++ } ++#endif /* IPH_is_SKB_PULLED */ ++ ++ /* dev->hard_header_len is unreliable and should not be used */ ++ irs.hard_header_len = skb->mac.raw ? (skb->data - skb->mac.raw) : 0; ++ if((irs.hard_header_len < 0) || (irs.hard_header_len > skb_headroom(skb))) ++ irs.hard_header_len = 0; ++ ++#ifdef NET_21 ++ /* if skb was cloned (most likely due to a packet sniffer such as ++ tcpdump being momentarily attached to the interface), make ++ a copy of our own to modify */ ++ if(skb_cloned(skb)) { ++ /* include any mac header while copying.. */ ++ if(skb_headroom(skb) < irs.hard_header_len) { ++ printk(KERN_WARNING "klips_error:ipsec_rcv: " ++ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n", ++ irs.hard_header_len, ++ skb_headroom(skb)); ++ goto rcvleave; ++ } ++ skb_push(skb, irs.hard_header_len); ++ if ++#ifdef SKB_COW_NEW ++ (skb_cow(skb, skb_headroom(skb)) != 0) ++#else /* SKB_COW_NEW */ ++ ((skb = skb_cow(skb, skb_headroom(skb))) == NULL) ++#endif /* SKB_COW_NEW */ ++ { ++ goto rcvleave; ++ } ++ if(skb->len < irs.hard_header_len) { ++ printk(KERN_WARNING "klips_error:ipsec_rcv: " ++ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n", ++ irs.hard_header_len, ++ skb->len); ++ goto rcvleave; ++ } ++ skb_pull(skb, irs.hard_header_len); ++ } ++ ++#endif /* NET_21 */ ++ ++#if IP_FRAGMENT_LINEARIZE ++ /* In Linux 2.4.4, we may have to reassemble fragments. They are ++ not assembled automatically to save TCP from having to copy ++ twice. ++ */ ++ if (skb_is_nonlinear(skb)) { ++ if (skb_linearize(skb, GFP_ATOMIC) != 0) { ++ goto rcvleave; ++ } ++ } ++#endif /* IP_FRAGMENT_LINEARIZE */ ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ if (irs.natt_len) { ++ /** ++ * Now, we are sure packet is ESPinUDP. Remove natt_len bytes from ++ * packet and modify protocol to ESP. ++ */ ++ if (((unsigned char *)skb->data > (unsigned char *)skb->nh.iph) && ++ ((unsigned char *)skb->nh.iph > (unsigned char *)skb->head)) { ++ unsigned int _len = (unsigned char *)skb->data - ++ (unsigned char *)skb->nh.iph; ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n", ++ _len); ++ skb_push(skb, _len); ++ } ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "removing %d bytes from ESPinUDP packet\n", irs.natt_len); ++ ipp = (struct iphdr *)skb->data; ++ irs.iphlen = ipp->ihl << 2; ++ ipp->tot_len = htons(ntohs(ipp->tot_len) - irs.natt_len); ++ if (skb->len < irs.iphlen + irs.natt_len) { ++ printk(KERN_WARNING ++ "klips_error:ipsec_rcv: " ++ "ESPinUDP packet is too small (%d < %d+%d). " ++ "This should never happen, please report.\n", ++ (int)(skb->len), irs.iphlen, irs.natt_len); ++ goto rcvleave; ++ } ++ memmove(skb->data + irs.natt_len, skb->data, irs.iphlen); ++ skb_pull(skb, irs.natt_len); ++ ++ /* update nh.iph */ ++ ipp = skb->nh.iph = (struct iphdr *)skb->data; ++ ++ /* modify protocol */ ++ ipp->protocol = IPPROTO_ESP; ++ ++ skb->sk = NULL; ++ ++ KLIPS_IP_PRINT(debug_rcv, skb->nh.iph); ++ } ++#endif ++ ++ ipp = skb->nh.iph; ++ ipsaddr.s_addr = ipp->saddr; ++ addrtoa(ipsaddr, 0, irs.ipsaddr_txt, sizeof(irs.ipsaddr_txt)); ++ ipdaddr.s_addr = ipp->daddr; ++ addrtoa(ipdaddr, 0, irs.ipdaddr_txt, sizeof(irs.ipdaddr_txt)); ++ irs.iphlen = ipp->ihl << 2; ++ ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "<<< Info -- "); ++ KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ", ++ skb->dev->name ? skb->dev->name : "NULL"); ++ KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ", ++ dev->name ? dev->name : "NULL"); ++ KLIPS_PRINTMORE(debug_rcv, "\n"); ++ ++ KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)), ++ "klips_debug:ipsec_rcv: " ++ "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n", ++ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL", ++ dev ? (dev->name ? dev->name : "NULL") : "NULL"); ++ ++ protoc = ipp->protocol; ++#ifndef NET_21 ++ if((!protocol) || (protocol->protocol != protoc)) { ++ KLIPS_PRINT(debug_rcv & DB_RX_IPSA, ++ "klips_debug:ipsec_rcv: " ++ "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n"); ++ } ++#endif /* !NET_21 */ ++ ++ if( (protoc != IPPROTO_AH) && ++#ifdef CONFIG_IPSEC_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER ++ (protoc != IPPROTO_COMP) && ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ (protoc != IPPROTO_ESP) ) { ++ KLIPS_PRINT(debug_rcv & DB_RX_IPSA, ++ "klips_debug:ipsec_rcv: Why the hell is someone " ++ "passing me a non-ipsec protocol = %d packet? -- dropped.\n", ++ protoc); ++ goto rcvleave; ++ } ++ ++ if(skb->dev) { ++ for(i = 0; i < IPSEC_NUM_IF; i++) { ++ sprintf(name, IPSEC_DEV_FORMAT, i); ++ if(!strcmp(name, skb->dev->name)) { ++ prv = (struct ipsecpriv *)(skb->dev->priv); ++ if(prv) { ++ stats = (struct net_device_stats *) &(prv->mystats); ++ } ++ ipsecdev = skb->dev; ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n"); ++ break; ++ } ++ if((ipsecdev = __ipsec_dev_get(name)) == NULL) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_error:ipsec_rcv: " ++ "device %s does not exist\n", ++ name); ++ } ++ prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL; ++ prvdev = prv ? (struct device *)(prv->dev) : NULL; ++ ++#if 0 ++ KLIPS_PRINT(debug_rcv && prvdev, ++ "klips_debug:ipsec_rcv: " ++ "physical device for device %s is %s\n", ++ name, ++ prvdev->name); ++#endif ++ if(prvdev && skb->dev && ++ !strcmp(prvdev->name, skb->dev->name)) { ++ stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL; ++ skb->dev = ipsecdev; ++ KLIPS_PRINT(debug_rcv && prvdev, ++ "klips_debug:ipsec_rcv: " ++ "assigning packet ownership to virtual device %s from physical device %s.\n", ++ name, prvdev->name); ++ if(stats) { ++ stats->rx_packets++; ++ } ++ break; ++ } ++ } ++ } else { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "device supplied with skb is NULL\n"); ++ } ++ ++ if(stats == NULL) { ++ KLIPS_PRINT((debug_rcv), ++ "klips_error:ipsec_rcv: " ++ "packet received from physical I/F (%s) not connected to ipsec I/F. Cannot record stats. May not have SA for decoding. Is IPSEC traffic expected on this I/F? Check routing.\n", ++ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL"); ++ } ++ ++ KLIPS_IP_PRINT(debug_rcv, ipp); ++ ++ /* begin decapsulating loop here */ ++ ++ /* ++ The spinlock is to prevent any other process from ++ accessing or deleting the ipsec_sa hash table or any of the ++ ipsec_sa s while we are using and updating them. ++ ++ This is not optimal, but was relatively straightforward ++ at the time. A better way to do it has been planned for ++ more than a year, to lock the hash table and put reference ++ counts on each ipsec_sa instead. This is not likely to happen ++ in KLIPS1 unless a volunteer contributes it, but will be ++ designed into KLIPS2. ++ */ ++ spin_lock(&tdb_lock); ++ ++ /* set up for decap loop */ ++ irs.stats= stats; ++ irs.ipp = ipp; ++ irs.ipsp = NULL; ++ irs.ilen = 0; ++ irs.authlen=0; ++ irs.authfuncs=NULL; ++ irs.skb = skb; ++ ++ do { ++ int decap_stat; ++ struct xform_functions *proto_funcs; ++ ++ switch(irs.ipp->protocol) { ++ case IPPROTO_ESP: ++ proto_funcs = esp_xform_funcs; ++ break; ++ ++#ifdef CONFIG_IPSEC_AH ++ case IPPROTO_AH: ++ proto_funcs = ah_xform_funcs; ++ break; ++#endif /* !CONFIG_IPSEC_AH */ ++ ++#ifdef CONFIG_IPSEC_IPCOMP ++ case IPPROTO_COMP: ++ proto_funcs = ipcomp_xform_funcs; ++ break; ++#endif /* !CONFIG_IPSEC_IPCOMP */ ++ default: ++ if(irs.stats) { ++ irs.stats->rx_errors++; ++ } ++ decap_stat = IPSEC_RCV_BADPROTO; ++ goto rcvleave; ++ } ++ ++ decap_stat = ipsec_rcv_decap_once(&irs, proto_funcs); ++ ++ if(decap_stat != IPSEC_RCV_OK) { ++ spin_unlock(&tdb_lock); ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: decap_once failed: %d\n", ++ decap_stat); ++ ++ goto rcvleave; ++ } ++ /* end decapsulation loop here */ ++ } while( (irs.ipp->protocol == IPPROTO_ESP ) ++ || (irs.ipp->protocol == IPPROTO_AH ) ++#ifdef CONFIG_IPSEC_IPCOMP ++ || (irs.ipp->protocol == IPPROTO_COMP) ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ ); ++ ++ /* set up for decap loop */ ++ ipp =irs.ipp; ++ ipsp =irs.ipsp; ++ ipsnext = ipsp->ips_inext; ++ skb = irs.skb; ++ ++ /* if there is an IPCOMP, but we don't have an IPPROTO_COMP, ++ * then we can just skip it ++ */ ++#ifdef CONFIG_IPSEC_IPCOMP ++ if(ipsnext && ipsnext->ips_said.proto == IPPROTO_COMP) { ++ ipsp = ipsnext; ++ ipsnext = ipsp->ips_inext; ++ } ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ if ((irs.natt_type) && (ipp->protocol != IPPROTO_IPIP)) { ++ /** ++ * NAT-Traversal and Transport Mode: ++ * we need to correct TCP/UDP checksum ++ * ++ * If we've got NAT-OA, we can fix checksum without recalculation. ++ */ ++ __u32 natt_oa = ipsp->ips_natt_oa ? ++ ((struct sockaddr_in*)(ipsp->ips_natt_oa))->sin_addr.s_addr : 0; ++ __u16 pkt_len = skb->tail - (unsigned char *)ipp; ++ __u16 data_len = pkt_len - (ipp->ihl << 2); ++ ++ switch (ipp->protocol) { ++ case IPPROTO_TCP: ++ if (data_len >= sizeof(struct tcphdr)) { ++ struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ipp+ipp->ihl); ++ if (natt_oa) { ++ __u32 buff[2] = { ~natt_oa, ipp->saddr }; ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "NAT-T & TRANSPORT: " ++ "fix TCP checksum using NAT-OA\n"); ++ tcp->check = csum_fold( ++ csum_partial((unsigned char *)buff, sizeof(buff), ++ tcp->check^0xffff)); ++ } ++ else { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "NAT-T & TRANSPORT: recalc TCP checksum\n"); ++ if (pkt_len > (ntohs(ipp->tot_len))) ++ data_len -= (pkt_len - ntohs(ipp->tot_len)); ++ tcp->check = 0; ++ tcp->check = csum_tcpudp_magic(ipp->saddr, ipp->daddr, ++ data_len, IPPROTO_TCP, ++ csum_partial((unsigned char *)tcp, data_len, 0)); ++ } ++ } ++ else { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "NAT-T & TRANSPORT: can't fix TCP checksum\n"); ++ } ++ break; ++ case IPPROTO_UDP: ++ if (data_len >= sizeof(struct udphdr)) { ++ struct udphdr *udp = (struct udphdr *)((__u32 *)ipp+ipp->ihl); ++ if (udp->check == 0) { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "NAT-T & TRANSPORT: UDP checksum already 0\n"); ++ } ++ else if (natt_oa) { ++ __u32 buff[2] = { ~natt_oa, ipp->saddr }; ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "NAT-T & TRANSPORT: " ++ "fix UDP checksum using NAT-OA\n"); ++ udp->check = csum_fold( ++ csum_partial((unsigned char *)buff, sizeof(buff), ++ udp->check^0xffff)); ++ } ++ else { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "NAT-T & TRANSPORT: zero UDP checksum\n"); ++ udp->check = 0; ++ } ++ } ++ else { ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "NAT-T & TRANSPORT: can't fix UDP checksum\n"); ++ } ++ break; ++ default: ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n"); ++ break; ++ } ++ } ++#endif ++ ++ /* ++ * XXX this needs to be locked from when it was first looked ++ * up in the decapsulation loop. Perhaps it is better to put ++ * the IPIP decap inside the loop. ++ */ ++ if(ipsnext) { ++ ipsp = ipsnext; ++ irs.sa_len = satot(&irs.said, 0, irs.sa, sizeof(irs.sa)); ++ if((ipp->protocol != IPPROTO_IPIP) && ++ ( 0xFE != ipp->protocol)) { /* added to support AT&T heartbeats to SIG/GIG */ ++ spin_unlock(&tdb_lock); ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "SA:%s, Hey! How did this get through? Dropped.\n", ++ irs.sa_len ? irs.sa : " (error)"); ++ if(stats) { ++ stats->rx_dropped++; ++ } ++ goto rcvleave; ++ } ++ if(sysctl_ipsec_inbound_policy_check) { ++ if((ipsnext = ipsp->ips_inext)) { ++ char sa2[SATOT_BUF]; ++ size_t sa_len2; ++ sa_len2 = satot(&ipsnext->ips_said, 0, sa2, sizeof(sa2)); ++ spin_unlock(&tdb_lock); ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "unexpected SA:%s after IPIP SA:%s\n", ++ sa_len2 ? sa2 : " (error)", ++ irs.sa_len ? irs.sa : " (error)"); ++ if(stats) { ++ stats->rx_dropped++; ++ } ++ goto rcvleave; ++ } ++ if(ipp->saddr != ((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr.s_addr) { ++ spin_unlock(&tdb_lock); ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n", ++ irs.sa_len ? irs.sa : " (error)", ++ irs.ipsaddr_txt); ++ if(stats) { ++ stats->rx_dropped++; ++ } ++ goto rcvleave; ++ } ++ } ++ ++ if(ipp->protocol == IPPROTO_IPIP) /* added to support AT&T heartbeats to SIG/GIG */ ++ { ++ /* ++ * XXX this needs to be locked from when it was first looked ++ * up in the decapsulation loop. Perhaps it is better to put ++ * the IPIP decap inside the loop. ++ */ ++ ipsp->ips_life.ipl_bytes.ipl_count += skb->len; ++ ipsp->ips_life.ipl_bytes.ipl_last = skb->len; ++ ++ if(!ipsp->ips_life.ipl_usetime.ipl_count) { ++ ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ; ++ } ++ ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ; ++ ipsp->ips_life.ipl_packets.ipl_count += 1; ++ ++ if(skb->len < irs.iphlen) { ++ spin_unlock(&tdb_lock); ++ printk(KERN_WARNING "klips_debug:ipsec_rcv: " ++ "tried to skb_pull iphlen=%d, %d available. This should never happen, please report.\n", ++ irs.iphlen, ++ (int)(skb->len)); ++ ++ goto rcvleave; ++ } ++ skb_pull(skb, irs.iphlen); ++ ++#ifdef NET_21 ++ ipp = (struct iphdr *)skb->nh.raw = skb->data; ++ skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2); ++ ++ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); ++#else /* NET_21 */ ++ ipp = skb->ip_hdr = skb->h.iph = (struct iphdr *)skb->data; ++ ++ memset(skb->proto_priv, 0, sizeof(struct options)); ++#endif /* NET_21 */ ++ ipsaddr.s_addr = ipp->saddr; ++ addrtoa(ipsaddr, 0, irs.ipsaddr_txt, sizeof(irs.ipsaddr_txt)); ++ ipdaddr.s_addr = ipp->daddr; ++ addrtoa(ipdaddr, 0, irs.ipdaddr_txt, sizeof(irs.ipdaddr_txt)); ++ ++ skb->protocol = htons(ETH_P_IP); ++ skb->ip_summed = 0; ++ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, ++ "klips_debug:ipsec_rcv: " ++ "IPIP tunnel stripped.\n"); ++ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp); ++ } ++ ++ if(sysctl_ipsec_inbound_policy_check ++ /* ++ Note: "xor" (^) logically replaces "not equal" ++ (!=) and "bitwise or" (|) logically replaces ++ "boolean or" (||). This is done to speed up ++ execution by doing only bitwise operations and ++ no branch operations ++ */ ++ && (((ipp->saddr & ipsp->ips_mask_s.u.v4.sin_addr.s_addr) ++ ^ ipsp->ips_flow_s.u.v4.sin_addr.s_addr) ++ | ((ipp->daddr & ipsp->ips_mask_d.u.v4.sin_addr.s_addr) ++ ^ ipsp->ips_flow_d.u.v4.sin_addr.s_addr)) ) ++ { ++ char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF]; ++ ++ subnettoa(ipsp->ips_flow_s.u.v4.sin_addr, ++ ipsp->ips_mask_s.u.v4.sin_addr, ++ 0, sflow_txt, sizeof(sflow_txt)); ++ subnettoa(ipsp->ips_flow_d.u.v4.sin_addr, ++ ipsp->ips_mask_d.u.v4.sin_addr, ++ 0, dflow_txt, sizeof(dflow_txt)); ++ spin_unlock(&tdb_lock); ++ KLIPS_PRINT(debug_rcv, ++ "klips_debug:ipsec_rcv: " ++ "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n", ++ irs.sa_len ? irs.sa : " (error)", ++ sflow_txt, ++ dflow_txt, ++ irs.ipsaddr_txt, ++ irs.ipdaddr_txt); ++ if(stats) { ++ stats->rx_dropped++; ++ } ++ goto rcvleave; ++ } ++#ifdef CONFIG_NETFILTER ++ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_TABLE_MASK)))) ++ | IPsecSAref2NFmark(IPsecSA2SAref(ipsp)); ++ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, ++ "klips_debug:ipsec_rcv: " ++ "IPIP SA sets skb->nfmark=0x%x.\n", ++ (unsigned)skb->nfmark); ++#endif /* CONFIG_NETFILTER */ ++ } ++ ++ spin_unlock(&tdb_lock); ++ ++#ifdef NET_21 ++ if(stats) { ++ stats->rx_bytes += skb->len; ++ } ++ if(skb->dst) { ++ dst_release(skb->dst); ++ skb->dst = NULL; ++ } ++ skb->pkt_type = PACKET_HOST; ++ if(irs.hard_header_len && ++ (skb->mac.raw != (skb->data - irs.hard_header_len)) && ++ (irs.hard_header_len <= skb_headroom(skb))) { ++ /* copy back original MAC header */ ++ memmove(skb->data - irs.hard_header_len, skb->mac.raw, irs.hard_header_len); ++ skb->mac.raw = skb->data - irs.hard_header_len; ++ } ++#endif /* NET_21 */ ++ ++#ifdef CONFIG_IPSEC_IPCOMP ++ if(ipp->protocol == IPPROTO_COMP) { ++ unsigned int flags = 0; ++ ++ if(sysctl_ipsec_inbound_policy_check) { ++ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, ++ "klips_debug:ipsec_rcv: " ++ "inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n"); ++ if (stats) { ++ stats->rx_errors++; ++ } ++ goto rcvleave; ++ } ++ /* ++ XXX need a ipsec_sa for updating ratio counters but it is not ++ following policy anyways so it is not a priority ++ */ ++ skb = skb_decompress(skb, NULL, &flags); ++ if (!skb || flags) { ++ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, ++ "klips_debug:ipsec_rcv: " ++ "skb_decompress() returned error flags: %d, dropped.\n", ++ flags); ++ if (stats) { ++ stats->rx_errors++; ++ } ++ goto rcvleave; ++ } ++ } ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ ++#ifdef SKB_RESET_NFCT ++ nf_conntrack_put(skb->nfct); ++ skb->nfct = NULL; ++#ifdef CONFIG_NETFILTER_DEBUG ++ skb->nf_debug = 0; ++#endif /* CONFIG_NETFILTER_DEBUG */ ++#endif /* SKB_RESET_NFCT */ ++ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, ++ "klips_debug:ipsec_rcv: " ++ "netif_rx() called.\n"); ++ netif_rx(skb); ++ ++ MOD_DEC_USE_COUNT; ++ return(0); ++ ++ rcvleave: ++ if(skb) { ++ ipsec_kfree_skb(skb); ++ } ++ ++ MOD_DEC_USE_COUNT; ++ return(0); ++} ++ ++/* ++ * $Log: ipsec_rcv.c,v $ ++ * Revision 1.143.4.2 2004/08/22 03:29:06 mcr ++ * include udp.h regardless of nat-t support. ++ * ++ * Revision 1.143.4.1 2004/08/21 02:14:58 ken ++ * Patch from Jochen Eisinger for AT&T MTS Heartbeat packet support ++ * ++ * Revision 1.143 2004/05/10 22:27:00 mcr ++ * fix for ESP-3DES-noauth test case. ++ * ++ * Revision 1.142 2004/05/10 22:25:57 mcr ++ * reformat of calls to ipsec_lifetime_check(). ++ * ++ * Revision 1.141 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.140 2004/02/03 03:12:53 mcr ++ * removed erroneously, double patched code. ++ * ++ * Revision 1.139 2004/01/05 23:21:29 mcr ++ * initialize sin_family in ipsec_rcv.c ++ * ++ * Revision 1.138 2003/12/24 19:46:52 mcr ++ * if sock.h patch has not been applied, then define appropriate ++ * structure so we can use it. This is serious inferior, and ++ * depends upon the concept that the structure in question is ++ * smaller than the other members of that union. ++ * getting rid of differing methods is a better solution. ++ * ++ * Revision 1.137 2003/12/22 19:40:57 mcr ++ * NAT-T patches 0.6c. ++ * ++ * Revision 1.136 2003/12/15 18:13:12 mcr ++ * when compiling with NAT traversal, don't assume that the ++ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP ++ * is set. ++ * ++ * Revision 1.135 2003/12/13 19:10:21 mcr ++ * refactored rcv and xmit code - same as FS 2.05. ++ * ++ * Revision 1.134.2.1 2003/12/22 15:25:52 jjo ++ * Merged algo-0.8.1-rc11-test1 into alg-branch ++ * ++ * Revision 1.134 2003/12/10 01:14:27 mcr ++ * NAT-traversal patches to KLIPS. ++ * ++ * Revision 1.133 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.132.2.1 2003/10/29 01:30:41 mcr ++ * elimited "struct sa_id". ++ * ++ * Revision 1.132 2003/09/02 19:51:48 mcr ++ * fixes for PR#252. ++ * ++ * Revision 1.131 2003/07/31 22:47:16 mcr ++ * preliminary (untested by FS-team) 2.5 patches. ++ * ++ * Revision 1.130 2003/04/03 17:38:25 rgb ++ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. ++ * Clarified logic for non-connected devices. ++ * ++ * Revision 1.129 2003/02/06 02:21:34 rgb ++ * ++ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h . ++ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr". ++ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code. ++ * ++ * Revision 1.128 2002/12/13 20:58:03 rgb ++ * Relegated MCR's recent "_dmp" routine to debug_verbose. ++ * Cleaned up printing of source and destination addresses in debug output. ++ * ++ * Revision 1.127 2002/12/04 16:00:16 rgb ++ * ++ * Fixed AH decapsulation pointer update bug and added some comments and ++ * debugging. ++ * This bug was caught by west-ah-0[12]. ++ * ++ * Revision 1.126 2002/11/04 05:03:43 mcr ++ * fixes for IPCOMP. There were two problems: ++ * 1) the irs->ipp pointer was not being updated properly after ++ * the ESP descryption. The meant nothing for IPIP, as the ++ * later IP header overwrote the earlier one. ++ * 2) the more serious problem was that skb_decompress will ++ * usually allocate a new SKB, so we have to make sure that ++ * it doesn't get lost. ++ * #2 meant removing the skb argument from the ->decrypt routine ++ * and moving it to the irs->skb, so it could be value/result. ++ * ++ * Revision 1.125 2002/11/01 01:53:35 dhr ++ * ++ * fix typo ++ * ++ * Revision 1.124 2002/10/31 22:49:01 dhr ++ * ++ * - eliminate unused variable "hash" ++ * - reduce scope of variable "authenticator" ++ * - add comment on a couple of tricky bits ++ * ++ * Revision 1.123 2002/10/31 22:39:56 dhr ++ * ++ * use correct type for result of function calls ++ * ++ * Revision 1.122 2002/10/31 22:36:25 dhr ++ * ++ * simplify complex test ++ * ++ * Revision 1.121 2002/10/31 22:34:04 dhr ++ * ++ * ipsprev is never used: ditch it ++ * ++ * Revision 1.120 2002/10/31 22:30:21 dhr ++ * ++ * eliminate redundant assignments ++ * ++ * Revision 1.119 2002/10/31 22:27:43 dhr ++ * ++ * make whitespace canonical ++ * ++ * Revision 1.118 2002/10/30 05:47:17 rgb ++ * Fixed cut-and-paste error mis-identifying comp runt as ah. ++ * ++ * Revision 1.117 2002/10/17 16:37:45 rgb ++ * Remove compp intermediate variable and in-line its contents ++ * where used ++ * ++ * Revision 1.116 2002/10/12 23:11:53 dhr ++ * ++ * [KenB + DHR] more 64-bit cleanup ++ * ++ * Revision 1.115 2002/10/07 19:06:58 rgb ++ * Minor fixups and activation to west-rcv-nfmark-set-01 test to check for SA reference properly set on incoming. ++ * ++ * Revision 1.114 2002/10/07 18:31:31 rgb ++ * Set saref on incoming packets. ++ * ++ * Revision 1.113 2002/09/16 21:28:12 mcr ++ * adjust hash length for HMAC calculation - must look at whether ++ * it is MD5 or SHA1. ++ * ++ * Revision 1.112 2002/09/16 21:19:15 mcr ++ * fixes for west-ah-icmp-01 - length of AH header must be ++ * calculated properly, and next_header field properly copied. ++ * ++ * Revision 1.111 2002/09/10 02:45:56 mcr ++ * re-factored the ipsec_rcv function into several functions, ++ * ipsec_rcv_decap_once, and a set of functions for AH, ESP and IPCOMP. ++ * In addition, the MD5 and SHA1 functions are replaced with pointers. ++ * ++ * Revision 1.110 2002/08/30 06:34:33 rgb ++ * Fix scope of shift in AH header length check. ++ * ++ * Revision 1.109 2002/08/27 16:49:20 rgb ++ * Fixed ESP short packet DOS (and AH and IPCOMP). ++ * ++ * Revision 1.108 2002/07/24 18:44:54 rgb ++ * Type fiddling to tame ia64 compiler. ++ * ++ * Revision 1.107 2002/05/27 18:58:18 rgb ++ * Convert to dynamic ipsec device allocation. ++ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. ++ * ++ * Revision 1.106 2002/05/23 07:15:21 rgb ++ * Pointer clean-up. ++ * Added refcount code. ++ * ++ * Revision 1.105 2002/05/14 02:35:06 rgb ++ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, ++ * ipsec_sa or ipsec_sa. ++ * Change references to _TDB to _IPSA. ++ * ++ * Revision 1.104 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.103 2002/04/24 07:36:30 mcr ++ * Moved from ./klips/net/ipsec/ipsec_rcv.c,v ++ * ++ * Revision 1.102 2002/01/29 17:17:56 mcr ++ * moved include of ipsec_param.h to after include of linux/kernel.h ++ * otherwise, it seems that some option that is set in ipsec_param.h ++ * screws up something subtle in the include path to kernel.h, and ++ * it complains on the snprintf() prototype. ++ * ++ * Revision 1.101 2002/01/29 04:00:52 mcr ++ * more excise of kversions.h header. ++ * ++ * Revision 1.100 2002/01/29 02:13:17 mcr ++ * introduction of ipsec_kversion.h means that include of ++ * ipsec_param.h must preceed any decisions about what files to ++ * include to deal with differences in kernel source. ++ * ++ * Revision 1.99 2002/01/28 21:40:59 mcr ++ * should use #if to test boolean option rather than #ifdef. ++ * ++ * Revision 1.98 2002/01/20 20:19:36 mcr ++ * renamed option to IP_FRAGMENT_LINEARIZE. ++ * ++ * Revision 1.97 2002/01/12 02:55:36 mcr ++ * fix for post-2.4.4 to linearize skb's when ESP packet ++ * was assembled from fragments. ++ * ++ * Revision 1.96 2001/11/26 09:23:49 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.93.2.2 2001/10/22 20:54:07 mcr ++ * include des.h, removed phony prototypes and fixed calling ++ * conventions to match real prototypes. ++ * ++ * Revision 1.93.2.1 2001/09/25 02:22:22 mcr ++ * struct tdb -> struct ipsec_sa. ++ * lifetime checks moved to ipsec_life.c ++ * some sa(tdb) manipulation functions renamed. ++ * ++ * Revision 1.95 2001/11/06 19:49:07 rgb ++ * Added variable descriptions. ++ * Removed unauthenticated sequence==0 check to prevent DoS. ++ * ++ * Revision 1.94 2001/10/18 04:45:20 rgb ++ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, ++ * lib/freeswan.h version macros moved to lib/kversions.h. ++ * Other compiler directive cleanups. ++ * ++ * Revision 1.93 2001/09/07 22:17:24 rgb ++ * Fix for removal of transport layer protocol handler arg in 2.4.4. ++ * Fix to accomodate peer non-conformance to IPCOMP rfc2393. ++ * ++ * Revision 1.92 2001/08/27 19:44:41 rgb ++ * Fix error in comment. ++ * ++ * Revision 1.91 2001/07/20 19:31:48 dhr ++ * [DHR] fix source and destination subnets of policy in diagnostic ++ * ++ * Revision 1.90 2001/07/06 19:51:09 rgb ++ * Added inbound policy checking code for IPIP SAs. ++ * Renamed unused function argument for ease and intuitive naming. ++ * ++ * Revision 1.89 2001/06/22 19:35:23 rgb ++ * Disable ipcomp processing if we are handed a ipcomp packet with no esp ++ * or ah header. ++ * Print protocol if we are handed a non-ipsec packet. ++ * ++ * Revision 1.88 2001/06/20 06:30:47 rgb ++ * Fixed transport mode IPCOMP policy check bug. ++ * ++ * Revision 1.87 2001/06/13 20:58:40 rgb ++ * Added parentheses around assignment used as truth value to silence ++ * compiler. ++ * ++ * Revision 1.86 2001/06/07 22:25:23 rgb ++ * Added a source address policy check for tunnel mode. It still does ++ * not check client addresses and masks. ++ * Only decapsulate IPIP if it is expected. ++ * ++ * Revision 1.85 2001/05/30 08:14:02 rgb ++ * Removed vestiges of esp-null transforms. ++ * ++ * Revision 1.84 2001/05/27 06:12:11 rgb ++ * Added structures for pid, packet count and last access time to eroute. ++ * Added packet count to beginning of /proc/net/ipsec_eroute. ++ * ++ * Revision 1.83 2001/05/04 16:45:47 rgb ++ * Remove unneeded code. ipp is not used after this point. ++ * ++ * Revision 1.82 2001/05/04 16:36:00 rgb ++ * Fix skb_cow() call for 2.4.4. (SS) ++ * ++ * Revision 1.81 2001/05/02 14:46:53 rgb ++ * Fix typo for compiler directive to pull IPH back. ++ * ++ * Revision 1.80 2001/04/30 19:46:34 rgb ++ * Update for 2.4.4. We now receive the skb with skb->data pointing to ++ * h.raw. ++ * ++ * Revision 1.79 2001/04/23 15:01:15 rgb ++ * Added spin_lock() check to prevent double-locking for multiple ++ * transforms and hence kernel lock-ups with SMP kernels. ++ * Minor spin_unlock() adjustments to unlock before non-dependant prints ++ * and IPSEC device stats updates. ++ * ++ * Revision 1.78 2001/04/21 23:04:24 rgb ++ * Check if soft expire has already been sent before sending another to ++ * prevent ACQUIRE flooding. ++ * ++ * Revision 1.77 2001/03/16 07:35:20 rgb ++ * Ditch extra #if 1 around now permanent policy checking code. ++ * ++ * Revision 1.76 2001/02/27 22:24:54 rgb ++ * Re-formatting debug output (line-splitting, joining, 1arg/line). ++ * Check for satoa() return codes. ++ * ++ * Revision 1.75 2001/02/19 22:28:30 rgb ++ * Minor change to virtual device discovery code to assert which I/F has ++ * been found. ++ * ++ * Revision 1.74 2000/11/25 03:50:36 rgb ++ * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb. ++ * ++ * Revision 1.73 2000/11/09 20:52:15 rgb ++ * More spinlock shuffling, locking earlier and unlocking later in rcv to ++ * include ipcomp and prevent races, renaming some tdb variables that got ++ * forgotten, moving some unlocks to include tdbs and adding a missing ++ * unlock. Thanks to Svenning for some of these. ++ * ++ * Revision 1.72 2000/11/09 20:11:22 rgb ++ * Minor shuffles to fix non-standard kernel config option selection. ++ * ++ * Revision 1.71 2000/11/06 04:36:18 rgb ++ * Ditched spin_lock_irqsave in favour of spin_lock. ++ * Minor initial protocol check rewrite. ++ * Clean up debug printing. ++ * Clean up tdb handling on ipcomp. ++ * Fixed transport mode null pointer de-reference without ipcomp. ++ * Add Svenning's adaptive content compression. ++ * Disabled registration of ipcomp handler. ++ * ++ * Revision 1.70 2000/10/30 23:41:43 henry ++ * Hans-Joerg Hoexer's null-pointer fix ++ * ++ * Revision 1.69 2000/10/10 18:54:16 rgb ++ * Added a fix for incoming policy check with ipcomp enabled but ++ * uncompressible. ++ * ++ * Revision 1.68 2000/09/22 17:53:12 rgb ++ * Fixed ipcomp tdb pointers update for policy checking. ++ * ++ * Revision 1.67 2000/09/21 03:40:58 rgb ++ * Added more debugging to try and track down the cpi outward copy problem. ++ * ++ * Revision 1.66 2000/09/20 04:00:10 rgb ++ * Changed static functions to DEBUG_NO_STATIC to reveal function names for ++ * debugging oopsen. ++ * ++ * Revision 1.65 2000/09/19 07:07:16 rgb ++ * Added debugging to inbound policy check for ipcomp. ++ * Added missing spin_unlocks (thanks Svenning!). ++ * Fixed misplaced tdbnext pointers causing mismatched ipip policy check. ++ * Protect ipcomp policy check following ipip decap with sysctl switch. ++ * ++ * Revision 1.64 2000/09/18 21:27:29 rgb ++ * 2.0 fixes. ++ * ++ * Revision 1.63 2000/09/18 02:35:50 rgb ++ * Added policy checking to ipcomp and re-enabled policy checking by ++ * default. ++ * Optimised satoa calls. ++ * ++ * Revision 1.62 2000/09/17 21:02:32 rgb ++ * Clean up debugging, removing slow timestamp debug code. ++ * ++ * Revision 1.61 2000/09/16 01:07:55 rgb ++ * Fixed erroneous ref from struct ipcomp to struct ipcomphdr. ++ * ++ * Revision 1.60 2000/09/15 11:37:01 rgb ++ * Merge in heavily modified Svenning Soerensen's ++ * IPCOMP zlib deflate code. ++ * ++ * Revision 1.59 2000/09/15 04:56:20 rgb ++ * Remove redundant satoa() call, reformat comment. ++ * ++ * Revision 1.58 2000/09/13 08:00:52 rgb ++ * Flick on inbound policy checking. ++ * ++ * Revision 1.57 2000/09/12 03:22:19 rgb ++ * Converted inbound_policy_check to sysctl. ++ * Re-enabled policy backcheck. ++ * Moved policy checks to top and within tdb lock. ++ * ++ * Revision 1.56 2000/09/08 19:12:56 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * ++ * Revision 1.55 2000/08/28 18:15:46 rgb ++ * Added MB's nf-debug reset patch. ++ * ++ * Revision 1.54 2000/08/27 01:41:26 rgb ++ * More minor tweaks to the bad padding debug code. ++ * ++ * Revision 1.53 2000/08/24 16:54:16 rgb ++ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level ++ * info. ++ * Tidied up device reporting at the start of ipsec_rcv. ++ * Tidied up bad padding debugging and processing. ++ * ++ * Revision 1.52 2000/08/20 21:36:03 rgb ++ * Activated pfkey_expire() calls. ++ * Added a hard/soft expiry parameter to pfkey_expire(). ++ * Added sanity checking to avoid propagating zero or smaller-length skbs ++ * from a bogus decryption. ++ * Re-arranged the order of soft and hard expiry to conform to RFC2367. ++ * Clean up references to CONFIG_IPSEC_PFKEYv2. ++ * ++ * Revision 1.51 2000/08/18 21:23:30 rgb ++ * Improve bad padding warning so that the printk buffer doesn't get ++ * trampled. ++ * ++ * Revision 1.50 2000/08/01 14:51:51 rgb ++ * Removed _all_ remaining traces of DES. ++ * ++ * Revision 1.49 2000/07/28 13:50:53 rgb ++ * Changed enet_statistics to net_device_stats and added back compatibility ++ * for pre-2.1.19. ++ * ++ * Revision 1.48 2000/05/10 19:14:40 rgb ++ * Only check usetime against soft and hard limits if the tdb has been ++ * used. ++ * Cast output of ntohl so that the broken prototype doesn't make our ++ * compile noisy. ++ * ++ * Revision 1.47 2000/05/09 17:45:43 rgb ++ * Fix replay bitmap corruption bug upon receipt of bogus packet ++ * with correct SPI. This was a DoS. ++ * ++ * Revision 1.46 2000/03/27 02:31:58 rgb ++ * Fixed authentication failure printout bug. ++ * ++ * Revision 1.45 2000/03/22 16:15:37 rgb ++ * Fixed renaming of dev_get (MB). ++ * ++ * Revision 1.44 2000/03/16 08:17:24 rgb ++ * Hardcode PF_KEYv2 support. ++ * Fixed minor bug checking AH header length. ++ * ++ * Revision 1.43 2000/03/14 12:26:59 rgb ++ * Added skb->nfct support for clearing netfilter conntrack bits (MB). ++ * ++ * Revision 1.42 2000/01/26 10:04:04 rgb ++ * Fixed inbound policy checking on transport mode bug. ++ * Fixed noisy 2.0 printk arguments. ++ * ++ * Revision 1.41 2000/01/24 20:58:02 rgb ++ * Improve debugging/reporting support for (disabled) inbound ++ * policy checking. ++ * ++ * Revision 1.40 2000/01/22 23:20:10 rgb ++ * Fixed up inboud policy checking code. ++ * Cleaned out unused crud. ++ * ++ * Revision 1.39 2000/01/21 06:15:29 rgb ++ * Added sanity checks on skb_push(), skb_pull() to prevent panics. ++ * Fixed cut-and-paste debug_tunnel to debug_rcv. ++ * Added inbound policy checking code, disabled. ++ * Simplified output code by updating ipp to post-IPIP decapsulation. ++ * ++ * elided pre-2000 comments. Use "cvs log" ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_sa.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,1383 @@ ++/* ++ * Common routines for IPsec SA maintenance routines. ++ * ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_sa.c,v 1.23 2004/04/06 02:49:26 mcr Exp $ ++ * ++ * This is the file formerly known as "ipsec_xform.h" ++ * ++ */ ++ ++#include ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* vmalloc() */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include ++#include ++#ifdef SPINLOCK ++#ifdef SPINLOCK_23 ++#include /* *lock* */ ++#else /* SPINLOCK_23 */ ++#include /* *lock* */ ++#endif /* SPINLOCK_23 */ ++#endif /* SPINLOCK */ ++#ifdef NET_21 ++#include ++#include ++#endif ++#include ++#include ++ ++#include "openswan/radij.h" ++ ++#include "openswan/ipsec_stats.h" ++#include "openswan/ipsec_life.h" ++#include "openswan/ipsec_sa.h" ++#include "openswan/ipsec_xform.h" ++ ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_ipe4.h" ++#include "openswan/ipsec_ah.h" ++#include "openswan/ipsec_esp.h" ++ ++#include ++#include ++ ++#include "openswan/ipsec_proto.h" ++#include "openswan/ipsec_alg.h" ++ ++ ++#ifdef CONFIG_IPSEC_DEBUG ++int debug_xform = 0; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) ++ ++struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD]; ++#ifdef SPINLOCK ++spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED; ++#else /* SPINLOCK */ ++spinlock_t tdb_lock; ++#endif /* SPINLOCK */ ++ ++struct ipsec_sadb ipsec_sadb; ++ ++#if IPSEC_SA_REF_CODE ++ ++/* the sub table must be narrower (or equal) in bits than the variable type ++ in the main table to count the number of unused entries in it. */ ++typedef struct { ++ int testSizeOf_refSubTable : ++ ((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1); ++} dummy; ++ ++ ++/* The field where the saref will be hosted in the skb must be wide enough to ++ accomodate the information it needs to store. */ ++typedef struct { ++ int testSizeOf_refField : ++ (IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 ); ++} dummy2; ++ ++ ++#define IPS_HASH(said) (((said)->spi + (said)->dst.u.v4.sin_addr.s_addr + (said)->proto) % SADB_HASHMOD) ++ ++ ++void ++ipsec_SAtest(void) ++{ ++ IPsecSAref_t SAref = 258; ++ struct ipsec_sa ips; ++ ips.ips_ref = 772; ++ ++ printk("klips_debug:ipsec_SAtest: " ++ "IPSEC_SA_REF_SUBTABLE_IDX_WIDTH=%u\n" ++ "IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES=%u\n" ++ "IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES=%u\n" ++ "IPSEC_SA_REF_HOST_FIELD_WIDTH=%lu\n" ++ "IPSEC_SA_REF_TABLE_MASK=%x\n" ++ "IPSEC_SA_REF_ENTRY_MASK=%x\n" ++ "IPsecSAref2table(%d)=%u\n" ++ "IPsecSAref2entry(%d)=%u\n" ++ "IPsecSAref2NFmark(%d)=%u\n" ++ "IPsecSAref2SA(%d)=%p\n" ++ "IPsecSA2SAref(%p)=%d\n" ++ , ++ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH, ++ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES, ++ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES, ++ (unsigned long) IPSEC_SA_REF_HOST_FIELD_WIDTH, ++ IPSEC_SA_REF_TABLE_MASK, ++ IPSEC_SA_REF_ENTRY_MASK, ++ SAref, IPsecSAref2table(SAref), ++ SAref, IPsecSAref2entry(SAref), ++ SAref, IPsecSAref2NFmark(SAref), ++ SAref, IPsecSAref2SA(SAref), ++ (&ips), IPsecSA2SAref((&ips)) ++ ); ++ return; ++} ++ ++int ++ipsec_SAref_recycle(void) ++{ ++ int table; ++ int entry; ++ int error = 0; ++ ++ ipsec_sadb.refFreeListHead = -1; ++ ipsec_sadb.refFreeListTail = -1; ++ ++ if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_SAref_recycle: " ++ "end of table reached, continuing at start..\n"); ++ ipsec_sadb.refFreeListCont = 0; ++ } ++ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_SAref_recycle: " ++ "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n", ++ ipsec_sadb.refFreeListCont, ++ (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL, ++ IPsecSAref2table(ipsec_sadb.refFreeListCont), ++ IPsecSAref2entry(ipsec_sadb.refFreeListCont)); ++ ++ for(table = IPsecSAref2table(ipsec_sadb.refFreeListCont); ++ table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; ++ table++) { ++ if(ipsec_sadb.refTable[table] == NULL) { ++ error = ipsec_SArefSubTable_alloc(table); ++ if(error) { ++ return error; ++ } ++ } ++ for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont); ++ entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; ++ entry++) { ++ if(ipsec_sadb.refTable[table]->entry[entry] == NULL) { ++ ipsec_sadb.refFreeList[++ipsec_sadb.refFreeListTail] = IPsecSArefBuild(table, entry); ++ if(ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) { ++ ipsec_sadb.refFreeListHead = 0; ++ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1; ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_SAref_recycle: " ++ "SArefFreeList refilled.\n"); ++ return 0; ++ } ++ } ++ } ++ } ++ ++ if(ipsec_sadb.refFreeListTail == -1) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_SAref_recycle: " ++ "out of room in the SArefTable.\n"); ++ ++ return(-ENOSPC); ++ } ++ ++ ipsec_sadb.refFreeListHead = 0; ++ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1; ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_SAref_recycle: " ++ "SArefFreeList partly refilled to %d of %d.\n", ++ ipsec_sadb.refFreeListTail, ++ IPSEC_SA_REF_FREELIST_NUM_ENTRIES); ++ return 0; ++} ++ ++int ++ipsec_SArefSubTable_alloc(unsigned table) ++{ ++ unsigned entry; ++ struct IPsecSArefSubTable* SArefsub; ++ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_SArefSubTable_alloc: " ++ "allocating %lu bytes for table %u of %u.\n", ++ (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)), ++ table, ++ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES); ++ ++ /* allocate another sub-table */ ++ SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)); ++ if(SArefsub == NULL) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_SArefSubTable_alloc: " ++ "error allocating memory for table %u of %u!\n", ++ table, ++ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES); ++ return -ENOMEM; ++ } ++ ++ /* add this sub-table to the main table */ ++ ipsec_sadb.refTable[table] = SArefsub; ++ ++ /* initialise each element to NULL */ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_SArefSubTable_alloc: " ++ "initialising %u elements (2 ^ %u) of table %u.\n", ++ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES, ++ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH, ++ table); ++ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) { ++ SArefsub->entry[entry] = NULL; ++ } ++ ++ return 0; ++} ++#endif /* IPSEC_SA_REF_CODE */ ++ ++int ++ipsec_saref_freelist_init(void) ++{ ++ int i; ++ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_saref_freelist_init: " ++ "initialising %u elements of FreeList.\n", ++ IPSEC_SA_REF_FREELIST_NUM_ENTRIES); ++ ++ for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) { ++ ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL; ++ } ++ ipsec_sadb.refFreeListHead = -1; ++ ipsec_sadb.refFreeListCont = 0; ++ ipsec_sadb.refFreeListTail = -1; ++ ++ return 0; ++} ++ ++int ++ipsec_sadb_init(void) ++{ ++ int error = 0; ++ unsigned i; ++ ++ for(i = 0; i < SADB_HASHMOD; i++) { ++ ipsec_sadb_hash[i] = NULL; ++ } ++ /* parts above are for the old style SADB hash table */ ++ ++ ++#if IPSEC_SA_REF_CODE ++ /* initialise SA reference table */ ++ ++ /* initialise the main table */ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sadb_init: " ++ "initialising main table of size %u (2 ^ %u).\n", ++ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES, ++ IPSEC_SA_REF_MAINTABLE_IDX_WIDTH); ++ { ++ unsigned table; ++ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) { ++ ipsec_sadb.refTable[table] = NULL; ++ } ++ } ++ ++ /* allocate the first sub-table */ ++ error = ipsec_SArefSubTable_alloc(0); ++ if(error) { ++ return error; ++ } ++ ++ error = ipsec_saref_freelist_init(); ++#endif /* IPSEC_SA_REF_CODE */ ++ return error; ++} ++ ++#if IPSEC_SA_REF_CODE ++IPsecSAref_t ++ipsec_SAref_alloc(int*error) /* pass in error var by pointer */ ++{ ++ IPsecSAref_t SAref; ++ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_SAref_alloc: " ++ "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n", ++ ipsec_sadb.refFreeListHead, ++ ipsec_sadb.refFreeListCont, ++ ipsec_sadb.refFreeListTail, ++ IPSEC_SA_REF_FREELIST_NUM_ENTRIES); ++ ++ if(ipsec_sadb.refFreeListHead == -1) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_SAref_alloc: " ++ "FreeList empty, recycling...\n"); ++ *error = ipsec_SAref_recycle(); ++ if(*error) { ++ return IPSEC_SAREF_NULL; ++ } ++ } ++ ++ SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead]; ++ if(SAref == IPSEC_SAREF_NULL) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_SAref_alloc: " ++ "unexpected error, refFreeListHead = %d points to invalid entry.\n", ++ ipsec_sadb.refFreeListHead); ++ *error = -ESPIPE; ++ return IPSEC_SAREF_NULL; ++ } ++ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_SAref_alloc: " ++ "allocating SAref=%d, table=%u, entry=%u of %u.\n", ++ SAref, ++ IPsecSAref2table(SAref), ++ IPsecSAref2entry(SAref), ++ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES); ++ ++ ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL; ++ ipsec_sadb.refFreeListHead++; ++ if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_SAref_alloc: " ++ "last FreeList entry allocated, resetting list head to empty.\n"); ++ ipsec_sadb.refFreeListHead = -1; ++ } ++ ++ return SAref; ++} ++#endif /* IPSEC_SA_REF_CODE */ ++ ++int ++ipsec_sa_print(struct ipsec_sa *ips) ++{ ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ ++ printk(KERN_INFO "klips_debug: SA:"); ++ if(ips == NULL) { ++ printk("NULL\n"); ++ return -ENOENT; ++ } ++ printk(" ref=%d", ips->ips_ref); ++ printk(" refcount=%d", atomic_read(&ips->ips_refcount)); ++ if(ips->ips_hnext != NULL) { ++ printk(" hnext=0p%p", ips->ips_hnext); ++ } ++ if(ips->ips_inext != NULL) { ++ printk(" inext=0p%p", ips->ips_inext); ++ } ++ if(ips->ips_onext != NULL) { ++ printk(" onext=0p%p", ips->ips_onext); ++ } ++ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); ++ printk(" said=%s", sa_len ? sa : " (error)"); ++ if(ips->ips_seq) { ++ printk(" seq=%u", ips->ips_seq); ++ } ++ if(ips->ips_pid) { ++ printk(" pid=%u", ips->ips_pid); ++ } ++ if(ips->ips_authalg) { ++ printk(" authalg=%u", ips->ips_authalg); ++ } ++ if(ips->ips_encalg) { ++ printk(" encalg=%u", ips->ips_encalg); ++ } ++ printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips)); ++ if(ips->ips_replaywin) { ++ printk(" ooowin=%u", ips->ips_replaywin); ++ } ++ if(ips->ips_flags) { ++ printk(" flags=%u", ips->ips_flags); ++ } ++ if(ips->ips_addr_s) { ++ char buf[SUBNETTOA_BUF]; ++ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr, ++ 0, buf, sizeof(buf)); ++ printk(" src=%s", buf); ++ } ++ if(ips->ips_addr_d) { ++ char buf[SUBNETTOA_BUF]; ++ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr, ++ 0, buf, sizeof(buf)); ++ printk(" dst=%s", buf); ++ } ++ if(ips->ips_addr_p) { ++ char buf[SUBNETTOA_BUF]; ++ addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr, ++ 0, buf, sizeof(buf)); ++ printk(" proxy=%s", buf); ++ } ++ if(ips->ips_key_bits_a) { ++ printk(" key_bits_a=%u", ips->ips_key_bits_a); ++ } ++ if(ips->ips_key_bits_e) { ++ printk(" key_bits_e=%u", ips->ips_key_bits_e); ++ } ++ ++ printk("\n"); ++ return 0; ++} ++ ++struct ipsec_sa* ++ipsec_sa_alloc(int*error) /* pass in error var by pointer */ ++{ ++ struct ipsec_sa* ips; ++ ++ if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_alloc: " ++ "memory allocation error\n"); ++ *error = -ENOMEM; ++ return NULL; ++ } ++ memset((caddr_t)ips, 0, sizeof(*ips)); ++#if IPSEC_SA_REF_CODE ++ ips->ips_ref = ipsec_SAref_alloc(error); /* pass in error return by pointer */ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_alloc: " ++ "allocated %lu bytes for ipsec_sa struct=0p%p ref=%d.\n", ++ (unsigned long) sizeof(*ips), ++ ips, ++ ips->ips_ref); ++ if(ips->ips_ref == IPSEC_SAREF_NULL) { ++ kfree(ips); ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_alloc: " ++ "SAref allocation error\n"); ++ return NULL; ++ } ++ ++ atomic_inc(&ips->ips_refcount); ++ IPsecSAref2SA(ips->ips_ref) = ips; ++#endif /* IPSEC_SA_REF_CODE */ ++ ++ *error = 0; ++ return(ips); ++} ++ ++int ++ipsec_sa_free(struct ipsec_sa* ips) ++{ ++ return ipsec_sa_wipe(ips); ++} ++ ++struct ipsec_sa * ++ipsec_sa_getbyid(ip_said *said) ++{ ++ int hashval; ++ struct ipsec_sa *ips; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ ++ if(said == NULL) { ++ KLIPS_PRINT(debug_xform, ++ "klips_error:ipsec_sa_getbyid: " ++ "null pointer passed in!\n"); ++ return NULL; ++ } ++ ++ sa_len = satot(said, 0, sa, sizeof(sa)); ++ ++ hashval = IPS_HASH(said); ++ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_getbyid: " ++ "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n", ++ hashval, ++ sa_len ? sa : " (error)"); ++ ++ if((ips = ipsec_sadb_hash[hashval]) == NULL) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_getbyid: " ++ "no entries in ipsec_sa table for hash=%d of SA:%s.\n", ++ hashval, ++ sa_len ? sa : " (error)"); ++ return NULL; ++ } ++ ++ for (; ips; ips = ips->ips_hnext) { ++ if ((ips->ips_said.spi == said->spi) && ++ (ips->ips_said.dst.u.v4.sin_addr.s_addr == said->dst.u.v4.sin_addr.s_addr) && ++ (ips->ips_said.proto == said->proto)) { ++ atomic_inc(&ips->ips_refcount); ++ return ips; ++ } ++ } ++ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_getbyid: " ++ "no entry in linked list for hash=%d of SA:%s.\n", ++ hashval, ++ sa_len ? sa : " (error)"); ++ return NULL; ++} ++ ++int ++ipsec_sa_put(struct ipsec_sa *ips) ++{ ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ ++ if(ips == NULL) { ++ KLIPS_PRINT(debug_xform, ++ "klips_error:ipsec_sa_put: " ++ "null pointer passed in!\n"); ++ return -1; ++ } ++ ++ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); ++ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_put: " ++ "ipsec_sa SA:%s, ref:%d reference count decremented.\n", ++ sa_len ? sa : " (error)", ++ ips->ips_ref); ++ ++ atomic_dec(&ips->ips_refcount); ++ ++ return 0; ++} ++ ++/* ++ The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen ++*/ ++int ++ipsec_sa_add(struct ipsec_sa *ips) ++{ ++ int error = 0; ++ unsigned int hashval; ++ ++ if(ips == NULL) { ++ KLIPS_PRINT(debug_xform, ++ "klips_error:ipsec_sa_add: " ++ "null pointer passed in!\n"); ++ return -ENODATA; ++ } ++ hashval = IPS_HASH(&ips->ips_said); ++ ++ atomic_inc(&ips->ips_refcount); ++ spin_lock_bh(&tdb_lock); ++ ++ ips->ips_hnext = ipsec_sadb_hash[hashval]; ++ ipsec_sadb_hash[hashval] = ips; ++ ++ spin_unlock_bh(&tdb_lock); ++ ++ return error; ++} ++ ++/* ++ The ipsec_sa table better be locked before it is handed in, or races might happen ++*/ ++int ++ipsec_sa_del(struct ipsec_sa *ips) ++{ ++ unsigned int hashval; ++ struct ipsec_sa *ipstp; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ ++ if(ips == NULL) { ++ KLIPS_PRINT(debug_xform, ++ "klips_error:ipsec_sa_del: " ++ "null pointer passed in!\n"); ++ return -ENODATA; ++ } ++ ++ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); ++ if(ips->ips_inext || ips->ips_onext) { ++ KLIPS_PRINT(debug_xform, ++ "klips_error:ipsec_sa_del: " ++ "SA:%s still linked!\n", ++ sa_len ? sa : " (error)"); ++ return -EMLINK; ++ } ++ ++ hashval = IPS_HASH(&ips->ips_said); ++ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_del: " ++ "deleting SA:%s, hashval=%d.\n", ++ sa_len ? sa : " (error)", ++ hashval); ++ if(ipsec_sadb_hash[hashval] == NULL) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_del: " ++ "no entries in ipsec_sa table for hash=%d of SA:%s.\n", ++ hashval, ++ sa_len ? sa : " (error)"); ++ return -ENOENT; ++ } ++ ++ if (ips == ipsec_sadb_hash[hashval]) { ++ ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext; ++ ips->ips_hnext = NULL; ++ atomic_dec(&ips->ips_refcount); ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_del: " ++ "successfully deleted first ipsec_sa in chain.\n"); ++ return 0; ++ } else { ++ for (ipstp = ipsec_sadb_hash[hashval]; ++ ipstp; ++ ipstp = ipstp->ips_hnext) { ++ if (ipstp->ips_hnext == ips) { ++ ipstp->ips_hnext = ips->ips_hnext; ++ ips->ips_hnext = NULL; ++ atomic_dec(&ips->ips_refcount); ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_del: " ++ "successfully deleted link in ipsec_sa chain.\n"); ++ return 0; ++ } ++ } ++ } ++ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_del: " ++ "no entries in linked list for hash=%d of SA:%s.\n", ++ hashval, ++ sa_len ? sa : " (error)"); ++ return -ENOENT; ++} ++ ++/* ++ The ipsec_sa table better be locked before it is handed in, or races ++ might happen ++*/ ++int ++ipsec_sa_delchain(struct ipsec_sa *ips) ++{ ++ struct ipsec_sa *ipsdel; ++ int error = 0; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ ++ if(ips == NULL) { ++ KLIPS_PRINT(debug_xform, ++ "klips_error:ipsec_sa_delchain: " ++ "null pointer passed in!\n"); ++ return -ENODATA; ++ } ++ ++ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_delchain: " ++ "passed SA:%s\n", ++ sa_len ? sa : " (error)"); ++ while(ips->ips_onext != NULL) { ++ ips = ips->ips_onext; ++ } ++ ++ while(ips) { ++ /* XXX send a pfkey message up to advise of deleted ipsec_sa */ ++ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_delchain: " ++ "unlinking and delting SA:%s", ++ sa_len ? sa : " (error)"); ++ ipsdel = ips; ++ ips = ips->ips_inext; ++ if(ips != NULL) { ++ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_xform, ++ ", inext=%s", ++ sa_len ? sa : " (error)"); ++ atomic_dec(&ipsdel->ips_refcount); ++ ipsdel->ips_inext = NULL; ++ atomic_dec(&ips->ips_refcount); ++ ips->ips_onext = NULL; ++ } ++ KLIPS_PRINT(debug_xform, ++ ".\n"); ++ if((error = ipsec_sa_del(ipsdel))) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_delchain: " ++ "ipsec_sa_del returned error %d.\n", -error); ++ return error; ++ } ++ if((error = ipsec_sa_wipe(ipsdel))) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_delchain: " ++ "ipsec_sa_wipe returned error %d.\n", -error); ++ return error; ++ } ++ } ++ return error; ++} ++ ++int ++ipsec_sadb_cleanup(__u8 proto) ++{ ++ unsigned i; ++ int error = 0; ++ struct ipsec_sa *ips, **ipsprev, *ipsdel; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sadb_cleanup: " ++ "cleaning up proto=%d.\n", ++ proto); ++ ++ spin_lock_bh(&tdb_lock); ++ ++ for (i = 0; i < SADB_HASHMOD; i++) { ++ ipsprev = &(ipsec_sadb_hash[i]); ++ ips = ipsec_sadb_hash[i]; ++ if(ips != NULL) { ++ atomic_inc(&ips->ips_refcount); ++ } ++ for(; ips != NULL;) { ++ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sadb_cleanup: " ++ "checking SA:%s, hash=%d, ref=%d", ++ sa_len ? sa : " (error)", ++ i, ++ ips->ips_ref); ++ ipsdel = ips; ++ ips = ipsdel->ips_hnext; ++ if(ips != NULL) { ++ atomic_inc(&ips->ips_refcount); ++ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_xform, ++ ", hnext=%s", ++ sa_len ? sa : " (error)"); ++ } ++ if(*ipsprev != NULL) { ++ sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_xform, ++ ", *ipsprev=%s", ++ sa_len ? sa : " (error)"); ++ if((*ipsprev)->ips_hnext) { ++ sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_xform, ++ ", *ipsprev->ips_hnext=%s", ++ sa_len ? sa : " (error)"); ++ } ++ } ++ KLIPS_PRINT(debug_xform, ++ ".\n"); ++ if(proto == 0 || (proto == ipsdel->ips_said.proto)) { ++ sa_len = satot(&ipsdel->ips_said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sadb_cleanup: " ++ "deleting SA chain:%s.\n", ++ sa_len ? sa : " (error)"); ++ if((error = ipsec_sa_delchain(ipsdel))) { ++ SENDERR(-error); ++ } ++ ipsprev = &(ipsec_sadb_hash[i]); ++ ips = ipsec_sadb_hash[i]; ++ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sadb_cleanup: " ++ "deleted SA chain:%s", ++ sa_len ? sa : " (error)"); ++ if(ips != NULL) { ++ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_xform, ++ ", ipsec_sadb_hash[%d]=%s", ++ i, ++ sa_len ? sa : " (error)"); ++ } ++ if(*ipsprev != NULL) { ++ sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_xform, ++ ", *ipsprev=%s", ++ sa_len ? sa : " (error)"); ++ if((*ipsprev)->ips_hnext != NULL) { ++ sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_xform, ++ ", *ipsprev->ips_hnext=%s", ++ sa_len ? sa : " (error)"); ++ } ++ } ++ KLIPS_PRINT(debug_xform, ++ ".\n"); ++ } else { ++ ipsprev = &ipsdel; ++ } ++ if(ipsdel != NULL) { ++ ipsec_sa_put(ipsdel); ++ } ++ } ++ } ++ errlab: ++ ++ spin_unlock_bh(&tdb_lock); ++ ++ ++#if IPSEC_SA_REF_CODE ++ /* clean up SA reference table */ ++ ++ /* go through the ref table and clean out all the SAs */ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sadb_cleanup: " ++ "removing SAref entries and tables."); ++ { ++ unsigned table, entry; ++ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sadb_cleanup: " ++ "cleaning SAref table=%u.\n", ++ table); ++ if(ipsec_sadb.refTable[table] == NULL) { ++ printk("\n"); ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sadb_cleanup: " ++ "cleaned %u used refTables.\n", ++ table); ++ break; ++ } ++ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) { ++ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) { ++ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]); ++ ipsec_sadb.refTable[table]->entry[entry] = NULL; ++ } ++ } ++ } ++ } ++#endif /* IPSEC_SA_REF_CODE */ ++ ++ return(error); ++} ++ ++int ++ipsec_sadb_free(void) ++{ ++ int error = 0; ++ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sadb_free: " ++ "freeing SArefTable memory.\n"); ++ ++ /* clean up SA reference table */ ++ ++ /* go through the ref table and clean out all the SAs if any are ++ left and free table memory */ ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sadb_free: " ++ "removing SAref entries and tables.\n"); ++ { ++ unsigned table, entry; ++ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sadb_free: " ++ "removing SAref table=%u.\n", ++ table); ++ if(ipsec_sadb.refTable[table] == NULL) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sadb_free: " ++ "removed %u used refTables.\n", ++ table); ++ break; ++ } ++ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) { ++ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) { ++ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]); ++ ipsec_sadb.refTable[table]->entry[entry] = NULL; ++ } ++ } ++ vfree(ipsec_sadb.refTable[table]); ++ ipsec_sadb.refTable[table] = NULL; ++ } ++ } ++ ++ return(error); ++} ++ ++int ++ipsec_sa_wipe(struct ipsec_sa *ips) ++{ ++ if(ips == NULL) { ++ return -ENODATA; ++ } ++ ++ /* if(atomic_dec_and_test(ips)) { ++ }; */ ++ ++#if IPSEC_SA_REF_CODE ++ /* remove me from the SArefTable */ ++ { ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_wipe: " ++ "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n", ++ sa_len ? sa : " (error)", ++ ips, ++ ips->ips_ref, ++ IPsecSAref2table(IPsecSA2SAref(ips)), ++ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))], ++ IPsecSAref2entry(IPsecSA2SAref(ips))); ++ } ++ if(ips->ips_ref == IPSEC_SAREF_NULL) { ++ KLIPS_PRINT(debug_xform, ++ "klips_debug:ipsec_sa_wipe: " ++ "why does this SA not have a valid SAref?.\n"); ++ } ++ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL; ++ ips->ips_ref = IPSEC_SAREF_NULL; ++ ipsec_sa_put(ips); ++#endif /* IPSEC_SA_REF_CODE */ ++ ++ /* paranoid clean up */ ++ if(ips->ips_addr_s != NULL) { ++ memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size); ++ kfree(ips->ips_addr_s); ++ } ++ ips->ips_addr_s = NULL; ++ ++ if(ips->ips_addr_d != NULL) { ++ memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size); ++ kfree(ips->ips_addr_d); ++ } ++ ips->ips_addr_d = NULL; ++ ++ if(ips->ips_addr_p != NULL) { ++ memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size); ++ kfree(ips->ips_addr_p); ++ } ++ ips->ips_addr_p = NULL; ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ if(ips->ips_natt_oa) { ++ memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size); ++ kfree(ips->ips_natt_oa); ++ } ++ ips->ips_natt_oa = NULL; ++#endif ++ ++ if(ips->ips_key_a != NULL) { ++ memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size); ++ kfree(ips->ips_key_a); ++ } ++ ips->ips_key_a = NULL; ++ ++ if(ips->ips_key_e != NULL) { ++#ifdef CONFIG_IPSEC_ALG ++ if (ips->ips_alg_enc&&ips->ips_alg_enc->ixt_e_destroy_key) { ++ ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc, ++ ips->ips_key_e); ++ } else { ++#endif /* CONFIG_IPSEC_ALG */ ++ memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size); ++ kfree(ips->ips_key_e); ++#ifdef CONFIG_IPSEC_ALG ++ } ++#endif /* CONFIG_IPSEC_ALG */ ++ } ++ ips->ips_key_e = NULL; ++ ++ if(ips->ips_iv != NULL) { ++ memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size); ++ kfree(ips->ips_iv); ++ } ++ ips->ips_iv = NULL; ++ ++ if(ips->ips_ident_s.data != NULL) { ++ memset((caddr_t)(ips->ips_ident_s.data), ++ 0, ++ ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident)); ++ kfree(ips->ips_ident_s.data); ++ } ++ ips->ips_ident_s.data = NULL; ++ ++ if(ips->ips_ident_d.data != NULL) { ++ memset((caddr_t)(ips->ips_ident_d.data), ++ 0, ++ ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident)); ++ kfree(ips->ips_ident_d.data); ++ } ++ ips->ips_ident_d.data = NULL; ++ ++#ifdef CONFIG_IPSEC_ALG ++ if (ips->ips_alg_enc||ips->ips_alg_auth) { ++ ipsec_alg_sa_wipe(ips); ++ } ++#endif /* CONFIG_IPSEC_ALG */ ++ ++ memset((caddr_t)ips, 0, sizeof(*ips)); ++ kfree(ips); ++ ips = NULL; ++ ++ return 0; ++} ++ ++/* ++ * $Log: ipsec_sa.c,v $ ++ * Revision 1.23 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.22.2.1 2003/12/22 15:25:52 jjo ++ * . Merged algo-0.8.1-rc11-test1 into alg-branch ++ * ++ * Revision 1.22 2003/12/10 01:14:27 mcr ++ * NAT-traversal patches to KLIPS. ++ * ++ * Revision 1.21 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.20.4.1 2003/10/29 01:30:41 mcr ++ * elimited "struct sa_id". ++ * ++ * Revision 1.20 2003/02/06 01:50:34 rgb ++ * Fixed initialisation bug for first sadb hash bucket that would only manifest itself on platforms where NULL != 0. ++ * ++ * Revision 1.19 2003/01/30 02:32:22 rgb ++ * ++ * Rename SAref table macro names for clarity. ++ * Transmit error code through to caller from callee for better diagnosis of problems. ++ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug. ++ * ++ * Revision 1.18 2002/10/12 23:11:53 dhr ++ * ++ * [KenB + DHR] more 64-bit cleanup ++ * ++ * Revision 1.17 2002/10/07 18:31:43 rgb ++ * Move field width sanity checks to ipsec_sa.c ++ * ++ * Revision 1.16 2002/09/20 15:41:02 rgb ++ * Re-wrote most of the SAref code to eliminate Entry pointers. ++ * Added SAref code compiler directive switch. ++ * Added a saref test function for testing macros. ++ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc(). ++ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem ++ * of freeing newly created structures when clearing the reftable upon startup ++ * to start from a known state. ++ * Place all ipsec sadb globals into one struct. ++ * Rework saref freelist. ++ * Added memory allocation debugging. ++ * ++ * Revision 1.15 2002/09/20 05:01:44 rgb ++ * Update copyright date. ++ * ++ * Revision 1.14 2002/08/13 19:01:25 mcr ++ * patches from kenb to permit compilation of FreeSWAN on ia64. ++ * des library patched to use proper DES_LONG type for ia64. ++ * ++ * Revision 1.13 2002/07/29 03:06:20 mcr ++ * get rid of variable not used warnings. ++ * ++ * Revision 1.12 2002/07/26 08:48:31 rgb ++ * Added SA ref table code. ++ * ++ * Revision 1.11 2002/06/04 16:48:49 rgb ++ * Tidied up pointer code for processor independance. ++ * ++ * Revision 1.10 2002/05/23 07:16:17 rgb ++ * Added ipsec_sa_put() for releasing an ipsec_sa refcount. ++ * Pointer clean-up. ++ * Added refcount code. ++ * Convert "usecount" to "refcount" to remove ambiguity. ++ * ++ * Revision 1.9 2002/05/14 02:34:49 rgb ++ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion ++ * with "put" usage in the kernel. ++ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, ++ * ipsec_sa or ipsec_sa. ++ * Added some preliminary refcount code. ++ * ++ * Revision 1.8 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.7 2002/04/24 07:36:30 mcr ++ * Moved from ./klips/net/ipsec/ipsec_sa.c,v ++ * ++ * Revision 1.6 2002/04/20 00:12:25 rgb ++ * Added esp IV CBC attack fix, disabled. ++ * ++ * Revision 1.5 2002/01/29 17:17:56 mcr ++ * moved include of ipsec_param.h to after include of linux/kernel.h ++ * otherwise, it seems that some option that is set in ipsec_param.h ++ * screws up something subtle in the include path to kernel.h, and ++ * it complains on the snprintf() prototype. ++ * ++ * Revision 1.4 2002/01/29 04:00:52 mcr ++ * more excise of kversions.h header. ++ * ++ * Revision 1.3 2002/01/29 02:13:18 mcr ++ * introduction of ipsec_kversion.h means that include of ++ * ipsec_param.h must preceed any decisions about what files to ++ * include to deal with differences in kernel source. ++ * ++ * Revision 1.2 2001/11/26 09:16:15 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.1.2.2 2001/10/22 21:05:41 mcr ++ * removed phony prototype for des_set_key. ++ * ++ * Revision 1.1.2.1 2001/09/25 02:24:57 mcr ++ * struct tdb -> struct ipsec_sa. ++ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c ++ * ipsec_xform.c removed. header file still contains useful things. ++ * ++ * ++ * ++ * CLONED from ipsec_xform.c: ++ * Revision 1.53 2001/09/08 21:13:34 rgb ++ * Added pfkey ident extension support for ISAKMPd. (NetCelo) ++ * ++ * Revision 1.52 2001/06/14 19:35:11 rgb ++ * Update copyright date. ++ * ++ * Revision 1.51 2001/05/30 08:14:03 rgb ++ * Removed vestiges of esp-null transforms. ++ * ++ * Revision 1.50 2001/05/03 19:43:18 rgb ++ * Initialise error return variable. ++ * Update SENDERR macro. ++ * Fix sign of error return code for ipsec_tdbcleanup(). ++ * Use more appropriate return code for ipsec_tdbwipe(). ++ * ++ * Revision 1.49 2001/04/19 18:56:17 rgb ++ * Fixed tdb table locking comments. ++ * ++ * Revision 1.48 2001/02/27 22:24:55 rgb ++ * Re-formatting debug output (line-splitting, joining, 1arg/line). ++ * Check for satoa() return codes. ++ * ++ * Revision 1.47 2000/11/06 04:32:08 rgb ++ * Ditched spin_lock_irqsave in favour of spin_lock_bh. ++ * ++ * Revision 1.46 2000/09/20 16:21:57 rgb ++ * Cleaned up ident string alloc/free. ++ * ++ * Revision 1.45 2000/09/08 19:16:51 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * Removed all references to CONFIG_IPSEC_PFKEYv2. ++ * ++ * Revision 1.44 2000/08/30 05:29:04 rgb ++ * Compiler-define out no longer used tdb_init() in ipsec_xform.c. ++ * ++ * Revision 1.43 2000/08/18 21:30:41 rgb ++ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear. ++ * ++ * Revision 1.42 2000/08/01 14:51:51 rgb ++ * Removed _all_ remaining traces of DES. ++ * ++ * Revision 1.41 2000/07/28 14:58:31 rgb ++ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. ++ * ++ * Revision 1.40 2000/06/28 05:50:11 rgb ++ * Actually set iv_bits. ++ * ++ * Revision 1.39 2000/05/10 23:11:09 rgb ++ * Added netlink debugging output. ++ * Added a cast to quiet down the ntohl bug. ++ * ++ * Revision 1.38 2000/05/10 19:18:42 rgb ++ * Cast output of ntohl so that the broken prototype doesn't make our ++ * compile noisy. ++ * ++ * Revision 1.37 2000/03/16 14:04:59 rgb ++ * Hardwired CONFIG_IPSEC_PFKEYv2 on. ++ * ++ * Revision 1.36 2000/01/26 10:11:28 rgb ++ * Fixed spacing in error text causing run-in words. ++ * ++ * Revision 1.35 2000/01/21 06:17:16 rgb ++ * Tidied up compiler directive indentation for readability. ++ * Added ictx,octx vars for simplification.(kravietz) ++ * Added macros for HMAC padding magic numbers.(kravietz) ++ * Fixed missing key length reporting bug. ++ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in. ++ * ++ * Revision 1.34 1999/12/08 00:04:19 rgb ++ * Fixed SA direction overwriting bug for netlink users. ++ * ++ * Revision 1.33 1999/12/01 22:16:44 rgb ++ * Minor formatting changes in ESP MD5 initialisation. ++ * ++ * Revision 1.32 1999/11/25 09:06:36 rgb ++ * Fixed error return messages, should be returning negative numbers. ++ * Implemented SENDERR macro for propagating error codes. ++ * Added debug message and separate error code for algorithms not compiled ++ * in. ++ * ++ * Revision 1.31 1999/11/23 23:06:26 rgb ++ * Sort out pfkey and freeswan headers, putting them in a library path. ++ * ++ * Revision 1.30 1999/11/18 04:09:20 rgb ++ * Replaced all kernel version macros to shorter, readable form. ++ * ++ * Revision 1.29 1999/11/17 15:53:40 rgb ++ * Changed all occurrences of #include "../../../lib/freeswan.h" ++ * to #include which works due to -Ilibfreeswan in the ++ * klips/net/ipsec/Makefile. ++ * ++ * Revision 1.28 1999/10/18 20:04:01 rgb ++ * Clean-out unused cruft. ++ * ++ * Revision 1.27 1999/10/03 19:01:03 rgb ++ * Spinlock support for 2.3.xx and 2.0.xx kernels. ++ * ++ * Revision 1.26 1999/10/01 16:22:24 rgb ++ * Switch from assignment init. to functional init. of spinlocks. ++ * ++ * Revision 1.25 1999/10/01 15:44:54 rgb ++ * Move spinlock header include to 2.1> scope. ++ * ++ * Revision 1.24 1999/10/01 00:03:46 rgb ++ * Added tdb structure locking. ++ * Minor formatting changes. ++ * Add function to initialize tdb hash table. ++ * ++ * Revision 1.23 1999/05/25 22:42:12 rgb ++ * Add deltdbchain() debugging. ++ * ++ * Revision 1.22 1999/05/25 21:24:31 rgb ++ * Add debugging statements to deltdbchain(). ++ * ++ * Revision 1.21 1999/05/25 03:51:48 rgb ++ * Refix error return code. ++ * ++ * Revision 1.20 1999/05/25 03:34:07 rgb ++ * Fix error return for flush. ++ * ++ * Revision 1.19 1999/05/09 03:25:37 rgb ++ * Fix bug introduced by 2.2 quick-and-dirty patch. ++ * ++ * Revision 1.18 1999/05/05 22:02:32 rgb ++ * Add a quick and dirty port to 2.2 kernels by Marc Boucher . ++ * ++ * Revision 1.17 1999/04/29 15:20:16 rgb ++ * Change gettdb parameter to a pointer to reduce stack loading and ++ * facilitate parameter sanity checking. ++ * Add sanity checking for null pointer arguments. ++ * Add debugging instrumentation. ++ * Add function deltdbchain() which will take care of unlinking, ++ * zeroing and deleting a chain of tdbs. ++ * Add a parameter to tdbcleanup to be able to delete a class of SAs. ++ * tdbwipe now actually zeroes the tdb as well as any of its pointed ++ * structures. ++ * ++ * Revision 1.16 1999/04/16 15:36:29 rgb ++ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing. ++ * ++ * Revision 1.15 1999/04/11 00:29:01 henry ++ * GPL boilerplate ++ * ++ * Revision 1.14 1999/04/06 04:54:28 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.13 1999/02/19 18:23:01 rgb ++ * Nix debug off compile warning. ++ * ++ * Revision 1.12 1999/02/17 16:52:16 rgb ++ * Consolidate satoa()s for space and speed efficiency. ++ * Convert DEBUG_IPSEC to KLIPS_PRINT ++ * Clean out unused cruft. ++ * Ditch NET_IPIP dependancy. ++ * Loop for 3des key setting. ++ * ++ * Revision 1.11 1999/01/26 02:09:05 rgb ++ * Remove ah/esp/IPIP switching on include files. ++ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. ++ * Removed dead code. ++ * Clean up debug code when switched off. ++ * Remove references to INET_GET_PROTOCOL. ++ * Added code exclusion macros to reduce code from unused algorithms. ++ * ++ * Revision 1.10 1999/01/22 06:28:55 rgb ++ * Cruft clean-out. ++ * Put random IV generation in kernel. ++ * Added algorithm switch code. ++ * Enhanced debugging. ++ * 64-bit clean-up. ++ * ++ * Revision 1.9 1998/11/30 13:22:55 rgb ++ * Rationalised all the klips kernel file headers. They are much shorter ++ * now and won't conflict under RH5.2. ++ * ++ * Revision 1.8 1998/11/25 04:59:06 rgb ++ * Add conditionals for no IPIP tunnel code. ++ * Delete commented out code. ++ * ++ * Revision 1.7 1998/10/31 06:50:41 rgb ++ * Convert xform ASCII names to no spaces. ++ * Fixed up comments in #endif directives. ++ * ++ * Revision 1.6 1998/10/19 14:44:28 rgb ++ * Added inclusion of freeswan.h. ++ * sa_id structure implemented and used: now includes protocol. ++ * ++ * Revision 1.5 1998/10/09 04:32:19 rgb ++ * Added 'klips_debug' prefix to all klips printk debug statements. ++ * ++ * Revision 1.4 1998/08/12 00:11:31 rgb ++ * Added new xform functions to the xform table. ++ * Fixed minor debug output spelling error. ++ * ++ * Revision 1.3 1998/07/09 17:45:31 rgb ++ * Clarify algorithm not available message. ++ * ++ * Revision 1.2 1998/06/23 03:00:51 rgb ++ * Check for presence of IPIP protocol if it is setup one way (we don't ++ * know what has been set up the other way and can only assume it will be ++ * symmetrical with the exception of keys). ++ * ++ * Revision 1.1 1998/06/18 21:27:51 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid ++ * kernel-build scripts happier in the presence of symlinks ++ * ++ * Revision 1.3 1998/06/11 05:54:59 rgb ++ * Added transform version string pointer to xformsw initialisations. ++ * ++ * Revision 1.2 1998/04/21 21:28:57 rgb ++ * Rearrange debug switches to change on the fly debug output from user ++ * space. Only kernel changes checked in at this time. radij.c was also ++ * changed to temporarily remove buggy debugging code in rj_delete causing ++ * an OOPS and hence, netlink device open errors. ++ * ++ * Revision 1.1 1998/04/09 03:06:13 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:02 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.5 1997/06/03 04:24:48 ji ++ * Added ESP-3DES-MD5-96 ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * Added new transforms. ++ * ++ * Revision 0.3 1996/11/20 14:39:04 ji ++ * Minor cleanups. ++ * Rationalized debugging code. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_sha1.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,219 @@ ++/* ++ * RCSID $Id: ipsec_sha1.c,v 1.9 2004/04/06 02:49:26 mcr Exp $ ++ */ ++ ++/* ++ * The rest of the code is derived from sha1.c by Steve Reid, which is ++ * public domain. ++ * Minor cosmetic changes to accomodate it in the Linux kernel by ji. ++ */ ++ ++#include ++#include ++ ++#include "openswan/ipsec_sha1.h" ++ ++#if defined(rol) ++#undef rol ++#endif ++ ++#define SHA1HANDSOFF ++ ++#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) ++ ++/* blk0() and blk() perform the initial expand. */ ++/* I got the idea of expanding during the round function from SSLeay */ ++#ifdef __LITTLE_ENDIAN ++#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ ++ |(rol(block->l[i],8)&0x00FF00FF)) ++#else ++#define blk0(i) block->l[i] ++#endif ++#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ ++ ^block->l[(i+2)&15]^block->l[i&15],1)) ++ ++/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ ++#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); ++#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); ++#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); ++#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); ++#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); ++ ++ ++/* Hash a single 512-bit block. This is the core of the algorithm. */ ++ ++void SHA1Transform(__u32 state[5], __u8 buffer[64]) ++{ ++__u32 a, b, c, d, e; ++typedef union { ++ unsigned char c[64]; ++ __u32 l[16]; ++} CHAR64LONG16; ++CHAR64LONG16* block; ++#ifdef SHA1HANDSOFF ++static unsigned char workspace[64]; ++ block = (CHAR64LONG16*)workspace; ++ memcpy(block, buffer, 64); ++#else ++ block = (CHAR64LONG16*)buffer; ++#endif ++ /* Copy context->state[] to working vars */ ++ a = state[0]; ++ b = state[1]; ++ c = state[2]; ++ d = state[3]; ++ e = state[4]; ++ /* 4 rounds of 20 operations each. Loop unrolled. */ ++ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); ++ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); ++ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); ++ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); ++ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); ++ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); ++ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); ++ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); ++ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); ++ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); ++ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); ++ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); ++ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); ++ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); ++ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); ++ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); ++ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); ++ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); ++ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); ++ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); ++ /* Add the working vars back into context.state[] */ ++ state[0] += a; ++ state[1] += b; ++ state[2] += c; ++ state[3] += d; ++ state[4] += e; ++ /* Wipe variables */ ++ a = b = c = d = e = 0; ++} ++ ++ ++/* SHA1Init - Initialize new context */ ++ ++void SHA1Init(void *vcontext) ++{ ++ SHA1_CTX* context = vcontext; ++ ++ /* SHA1 initialization constants */ ++ context->state[0] = 0x67452301; ++ context->state[1] = 0xEFCDAB89; ++ context->state[2] = 0x98BADCFE; ++ context->state[3] = 0x10325476; ++ context->state[4] = 0xC3D2E1F0; ++ context->count[0] = context->count[1] = 0; ++} ++ ++ ++/* Run your data through this. */ ++ ++void SHA1Update(void *vcontext, unsigned char* data, __u32 len) ++{ ++ SHA1_CTX* context = vcontext; ++ __u32 i, j; ++ ++ j = context->count[0]; ++ if ((context->count[0] += len << 3) < j) ++ context->count[1]++; ++ context->count[1] += (len>>29); ++ j = (j >> 3) & 63; ++ if ((j + len) > 63) { ++ memcpy(&context->buffer[j], data, (i = 64-j)); ++ SHA1Transform(context->state, context->buffer); ++ for ( ; i + 63 < len; i += 64) { ++ SHA1Transform(context->state, &data[i]); ++ } ++ j = 0; ++ } ++ else i = 0; ++ memcpy(&context->buffer[j], &data[i], len - i); ++} ++ ++ ++/* Add padding and return the message digest. */ ++ ++void SHA1Final(unsigned char digest[20], void *vcontext) ++{ ++ __u32 i, j; ++ unsigned char finalcount[8]; ++ SHA1_CTX* context = vcontext; ++ ++ for (i = 0; i < 8; i++) { ++ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] ++ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ ++ } ++ SHA1Update(context, (unsigned char *)"\200", 1); ++ while ((context->count[0] & 504) != 448) { ++ SHA1Update(context, (unsigned char *)"\0", 1); ++ } ++ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ ++ for (i = 0; i < 20; i++) { ++ digest[i] = (unsigned char) ++ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); ++ } ++ /* Wipe variables */ ++ i = j = 0; ++ memset(context->buffer, 0, 64); ++ memset(context->state, 0, 20); ++ memset(context->count, 0, 8); ++ memset(&finalcount, 0, 8); ++#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */ ++ SHA1Transform(context->state, context->buffer); ++#endif ++} ++ ++ ++/* ++ * $Log: ipsec_sha1.c,v $ ++ * Revision 1.9 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.8 2002/09/10 01:45:14 mcr ++ * changed type of MD5_CTX and SHA1_CTX to void * so that ++ * the function prototypes would match, and could be placed ++ * into a pointer to a function. ++ * ++ * Revision 1.7 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.6 2002/04/24 07:36:30 mcr ++ * Moved from ./klips/net/ipsec/ipsec_sha1.c,v ++ * ++ * Revision 1.5 1999/12/13 13:59:13 rgb ++ * Quick fix to argument size to Update bugs. ++ * ++ * Revision 1.4 1999/04/11 00:29:00 henry ++ * GPL boilerplate ++ * ++ * Revision 1.3 1999/04/06 04:54:27 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.2 1999/01/22 06:55:50 rgb ++ * 64-bit clean-up. ++ * ++ * Revision 1.1 1998/06/18 21:27:50 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid ++ * kernel-build scripts happier in the presence of symlinks ++ * ++ * Revision 1.2 1998/04/23 20:54:04 rgb ++ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when ++ * verified. ++ * ++ * Revision 1.1 1998/04/09 03:06:11 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:05 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * New transform ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_tunnel.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,2645 @@ ++/* ++ * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ */ ++ ++char ipsec_tunnel_c_version[] = "RCSID $Id: ipsec_tunnel.c,v 1.220 2004/04/06 02:49:26 mcr Exp $"; ++ ++#define __NO_VERSION__ ++#include ++#include /* for CONFIG_IP_FORWARD */ ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include /* struct tcphdr */ ++#include /* struct udphdr */ ++#include ++#include ++#ifdef NET_21 ++# include ++# include ++# define ip_chk_addr inet_addr_type ++# define IS_MYADDR RTN_LOCAL ++# include ++# undef dev_kfree_skb ++# define dev_kfree_skb(a,b) kfree_skb(a) ++# define PHYSDEV_TYPE ++#endif /* NET_21 */ ++#include ++#include /* icmp_send() */ ++#include ++#ifdef NETDEV_23 ++# include ++#endif /* NETDEV_23 */ ++ ++#include ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_life.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_eroute.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_sa.h" ++#include "openswan/ipsec_tunnel.h" ++#include "openswan/ipsec_xmit.h" ++#include "openswan/ipsec_ipe4.h" ++#include "openswan/ipsec_ah.h" ++#include "openswan/ipsec_esp.h" ++ ++#include ++#include ++ ++#include "openswan/ipsec_proto.h" ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++#include ++#endif ++ ++static __u32 zeroes[64]; ++ ++#ifdef CONFIG_IPSEC_DEBUG ++int debug_tunnel = 0; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++DEBUG_NO_STATIC int ++ipsec_tunnel_open(struct device *dev) ++{ ++ struct ipsecpriv *prv = dev->priv; ++ ++ /* ++ * Can't open until attached. ++ */ ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_open: " ++ "dev = %s, prv->dev = %s\n", ++ dev->name, prv->dev?prv->dev->name:"NONE"); ++ ++ if (prv->dev == NULL) ++ return -ENODEV; ++ ++ MOD_INC_USE_COUNT; ++ return 0; ++} ++ ++DEBUG_NO_STATIC int ++ipsec_tunnel_close(struct device *dev) ++{ ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++#ifdef NETDEV_23 ++static inline int ipsec_tunnel_xmit2(struct sk_buff *skb) ++{ ++#ifdef NETDEV_25 /* 2.6 kernels */ ++ return dst_output(skb); ++#else ++ return ip_send(skb); ++#endif ++} ++#endif /* NETDEV_23 */ ++ ++enum ipsec_xmit_value ++ipsec_tunnel_strip_hard_header(struct ipsec_xmit_state *ixs) ++{ ++ /* ixs->physdev->hard_header_len is unreliable and should not be used */ ++ ixs->hard_header_len = (unsigned char *)(ixs->iph) - ixs->skb->data; ++ ++ if(ixs->hard_header_len < 0) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_error:ipsec_xmit_strip_hard_header: " ++ "Negative hard_header_len (%d)?!\n", ixs->hard_header_len); ++ ixs->stats->tx_dropped++; ++ return IPSEC_XMIT_BADHHLEN; ++ } ++ ++ /* while ixs->physdev->hard_header_len is unreliable and ++ * should not be trusted, it accurate and required for ATM, GRE and ++ * some other interfaces to work. Thanks to Willy Tarreau ++ * . ++ */ ++ if(ixs->hard_header_len == 0) { /* no hard header present */ ++ ixs->hard_header_stripped = 1; ++ ixs->hard_header_len = ixs->physdev->hard_header_len; ++ } ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if (debug_tunnel & DB_TN_XMIT) { ++ int i; ++ char c; ++ ++ printk(KERN_INFO "klips_debug:ipsec_xmit_strip_hard_header: " ++ ">>> skb->len=%ld hard_header_len:%d", ++ (unsigned long int)ixs->skb->len, ixs->hard_header_len); ++ c = ' '; ++ for (i=0; i < ixs->hard_header_len; i++) { ++ printk("%c%02x", c, ixs->skb->data[i]); ++ c = ':'; ++ } ++ printk(" \n"); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph); ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_strip_hard_header: " ++ "Original head,tailroom: %d,%d\n", ++ skb_headroom(ixs->skb), skb_tailroom(ixs->skb)); ++ ++ return IPSEC_XMIT_OK; ++} ++ ++enum ipsec_xmit_value ++ipsec_tunnel_SAlookup(struct ipsec_xmit_state *ixs) ++{ ++ /* ++ * First things first -- look us up in the erouting tables. ++ */ ++ ixs->matcher.sen_len = sizeof (struct sockaddr_encap); ++ ixs->matcher.sen_family = AF_ENCAP; ++ ixs->matcher.sen_type = SENT_IP4; ++ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr; ++ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr; ++ ixs->matcher.sen_proto = ixs->iph->protocol; ++ ipsec_extract_ports(ixs->iph, &ixs->matcher); ++ ++ /* ++ * The spinlock is to prevent any other process from accessing or deleting ++ * the eroute while we are using and updating it. ++ */ ++ spin_lock(&eroute_lock); ++ ++ ixs->eroute = ipsec_findroute(&ixs->matcher); ++ ++ if(ixs->iph->protocol == IPPROTO_UDP) { ++ if(ixs->skb->sk) { ++ ixs->sport=ntohs(ixs->skb->sk->sport); ++ ixs->dport=ntohs(ixs->skb->sk->dport); ++ } else if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 && ++ ((ixs->skb->len - ixs->hard_header_len) >= ++ ((ixs->iph->ihl << 2) + sizeof(struct udphdr)))) { ++ ixs->sport=ntohs(((struct udphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)))->source); ++ ixs->dport=ntohs(((struct udphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl<<2)))->dest); ++ } else { ++ ixs->sport=0; ixs->dport=0; ++ } ++ } ++ ++ /* default to a %drop eroute */ ++ ixs->outgoing_said.proto = IPPROTO_INT; ++ ixs->outgoing_said.spi = htonl(SPI_DROP); ++ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY; ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_SAlookup: " ++ "checking for local udp/500 IKE packet " ++ "saddr=%x, er=0p%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n", ++ ntohl((unsigned int)ixs->iph->saddr), ++ ixs->eroute, ++ ntohl((unsigned int)ixs->iph->daddr), ++ ixs->eroute ? ntohl((unsigned int)ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr) : 0, ++ ixs->iph->protocol, ++ ixs->sport, ++ ixs->dport); ++ ++ /* ++ * Quick cheat for now...are we udp/500? If so, let it through ++ * without interference since it is most likely an IKE packet. ++ */ ++ ++ if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR ++ && (!ixs->eroute ++ || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr ++ || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr) ++ ++ && ((ixs->sport == 500) || (ixs->sport == 4500))) { ++ /* Whatever the eroute, this is an IKE message ++ * from us (i.e. not being forwarded). ++ * Furthermore, if there is a tunnel eroute, ++ * the destination is the peer for this eroute. ++ * So %pass the packet: modify the default %drop. ++ */ ++ ixs->outgoing_said.spi = htonl(SPI_PASS); ++ if(!(ixs->skb->sk) && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0)) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_SAlookup: " ++ "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n"); ++ } ++ } else if (ixs->eroute) { ++ ixs->eroute->er_count++; ++ ixs->eroute->er_lasttime = jiffies/HZ; ++ if(ixs->eroute->er_said.proto==IPPROTO_INT ++ && ixs->eroute->er_said.spi==htonl(SPI_HOLD)) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_SAlookup: " ++ "shunt SA of HOLD: skb stored in HOLD.\n"); ++ if(ixs->eroute->er_last != NULL) { ++ kfree_skb(ixs->eroute->er_last); ++ } ++ ixs->eroute->er_last = ixs->skb; ++ ixs->skb = NULL; ++ ixs->stats->tx_dropped++; ++ spin_unlock(&eroute_lock); ++ return IPSEC_XMIT_STOLEN; ++ } ++ ixs->outgoing_said = ixs->eroute->er_said; ++ ixs->eroute_pid = ixs->eroute->er_pid; ++ /* Copy of the ident for the TRAP/TRAPSUBNET eroutes */ ++ if(ixs->outgoing_said.proto==IPPROTO_INT ++ && (ixs->outgoing_said.spi==htonl(SPI_TRAP) ++ || (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) { ++ int len; ++ ++ ixs->ips.ips_ident_s.type = ixs->eroute->er_ident_s.type; ++ ixs->ips.ips_ident_s.id = ixs->eroute->er_ident_s.id; ++ ixs->ips.ips_ident_s.len = ixs->eroute->er_ident_s.len; ++ if (ixs->ips.ips_ident_s.len) { ++ len = ixs->ips.ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_SAlookup: " ++ "allocating %d bytes for ident_s shunt SA of HOLD: skb stored in HOLD.\n", ++ len); ++ if ((ixs->ips.ips_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) { ++ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: " ++ "Failed, tried to allocate %d bytes for source ident.\n", ++ len); ++ ixs->stats->tx_dropped++; ++ spin_unlock(&eroute_lock); ++ return IPSEC_XMIT_ERRMEMALLOC; ++ } ++ memcpy(ixs->ips.ips_ident_s.data, ixs->eroute->er_ident_s.data, len); ++ } ++ ixs->ips.ips_ident_d.type = ixs->eroute->er_ident_d.type; ++ ixs->ips.ips_ident_d.id = ixs->eroute->er_ident_d.id; ++ ixs->ips.ips_ident_d.len = ixs->eroute->er_ident_d.len; ++ if (ixs->ips.ips_ident_d.len) { ++ len = ixs->ips.ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_SAlookup: " ++ "allocating %d bytes for ident_d shunt SA of HOLD: skb stored in HOLD.\n", ++ len); ++ if ((ixs->ips.ips_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) { ++ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: " ++ "Failed, tried to allocate %d bytes for dest ident.\n", ++ len); ++ ixs->stats->tx_dropped++; ++ spin_unlock(&eroute_lock); ++ return IPSEC_XMIT_ERRMEMALLOC; ++ } ++ memcpy(ixs->ips.ips_ident_d.data, ixs->eroute->er_ident_d.data, len); ++ } ++ } ++ } ++ ++ spin_unlock(&eroute_lock); ++ return IPSEC_XMIT_OK; ++} ++ ++enum ipsec_xmit_value ++ipsec_tunnel_restore_hard_header(struct ipsec_xmit_state*ixs) ++{ ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_restore_hard_header: " ++ "After recursive xforms -- head,tailroom: %d,%d\n", ++ skb_headroom(ixs->skb), ++ skb_tailroom(ixs->skb)); ++ ++ if(ixs->saved_header) { ++ if(skb_headroom(ixs->skb) < ixs->hard_header_len) { ++ printk(KERN_WARNING ++ "klips_error:ipsec_xmit_restore_hard_header: " ++ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n", ++ ixs->hard_header_len, ++ skb_headroom(ixs->skb)); ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_PUSHPULLERR; ++ ++ } ++ skb_push(ixs->skb, ixs->hard_header_len); ++ { ++ int i; ++ for (i = 0; i < ixs->hard_header_len; i++) { ++ ixs->skb->data[i] = ixs->saved_header[i]; ++ } ++ } ++ } ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ if (ixs->natt_type && ixs->natt_head) { ++ struct iphdr *ipp = ixs->skb->nh.iph; ++ struct udphdr *udp; ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "encapsuling packet into UDP (NAT-Traversal) (%d %d)\n", ++ ixs->natt_type, ixs->natt_head); ++ ++ ixs->iphlen = ipp->ihl << 2; ++ ipp->tot_len = ++ htons(ntohs(ipp->tot_len) + ixs->natt_head); ++ if(skb_tailroom(ixs->skb) < ixs->natt_head) { ++ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: " ++ "tried to skb_put %d, %d available. " ++ "This should never happen, please report.\n", ++ ixs->natt_head, ++ skb_tailroom(ixs->skb)); ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_ESPUDP; ++ } ++ skb_put(ixs->skb, ixs->natt_head); ++ ++ udp = (struct udphdr *)((char *)ipp + ixs->iphlen); ++ ++ /* move ESP hdr after UDP hdr */ ++ memmove((void *)((char *)udp + ixs->natt_head), ++ (void *)(udp), ++ ntohs(ipp->tot_len) - ixs->iphlen - ixs->natt_head); ++ ++ /* clear UDP & Non-IKE Markers (if any) */ ++ memset(udp, 0, ixs->natt_head); ++ ++ /* fill UDP with usefull informations ;-) */ ++ udp->source = htons(ixs->natt_sport); ++ udp->dest = htons(ixs->natt_dport); ++ udp->len = htons(ntohs(ipp->tot_len) - ixs->iphlen); ++ ++ /* set protocol */ ++ ipp->protocol = IPPROTO_UDP; ++ ++ /* fix IP checksum */ ++ ipp->check = 0; ++ ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl); ++ } ++#endif ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_restore_hard_header: " ++ "With hard_header, final head,tailroom: %d,%d\n", ++ skb_headroom(ixs->skb), ++ skb_tailroom(ixs->skb)); ++ ++ return IPSEC_XMIT_OK; ++} ++ ++enum ipsec_xmit_value ++ipsec_tunnel_send(struct ipsec_xmit_state*ixs) ++{ ++#ifdef NETDEV_25 ++ struct flowi fl; ++#endif ++ ++#ifdef NET_21 /* 2.2 and 2.4 kernels */ ++ /* new route/dst cache code from James Morris */ ++ ixs->skb->dev = ixs->physdev; ++#ifdef NETDEV_25 ++ fl.oif = ixs->physdev->iflink; ++ fl.nl_u.ip4_u.daddr = ixs->skb->nh.iph->daddr; ++ fl.nl_u.ip4_u.saddr = ixs->pass ? 0 : ixs->skb->nh.iph->saddr; ++ fl.nl_u.ip4_u.tos = RT_TOS(ixs->skb->nh.iph->tos); ++ fl.proto = ixs->skb->nh.iph->protocol; ++ if ((ixs->error = ip_route_output_key(&ixs->route, &fl))) { ++#else ++ /*skb_orphan(ixs->skb);*/ ++ if((ixs->error = ip_route_output(&ixs->route, ++ ixs->skb->nh.iph->daddr, ++ ixs->pass ? 0 : ixs->skb->nh.iph->saddr, ++ RT_TOS(ixs->skb->nh.iph->tos), ++ /* mcr->rgb: should this be 0 instead? */ ++ ixs->physdev->iflink))) { ++#endif ++ ixs->stats->tx_errors++; ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_send: " ++ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n", ++ ixs->error, ++ ixs->route->u.dst.dev->name); ++ return IPSEC_XMIT_ROUTEERR; ++ } ++ if(ixs->dev == ixs->route->u.dst.dev) { ++ ip_rt_put(ixs->route); ++ /* This is recursion, drop it. */ ++ ixs->stats->tx_errors++; ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_send: " ++ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n", ++ ixs->dev->name); ++ return IPSEC_XMIT_RECURSDETECT; ++ } ++ dst_release(ixs->skb->dst); ++ ixs->skb->dst = &ixs->route->u.dst; ++ ixs->stats->tx_bytes += ixs->skb->len; ++ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) { ++ ixs->stats->tx_errors++; ++ printk(KERN_WARNING ++ "klips_error:ipsec_xmit_send: " ++ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n", ++ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data), ++ ixs->skb->len); ++ return IPSEC_XMIT_PUSHPULLERR; ++ } ++ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data); ++#ifdef SKB_RESET_NFCT ++ if(!ixs->pass) { ++ nf_conntrack_put(ixs->skb->nfct); ++ ixs->skb->nfct = NULL; ++ } ++#ifdef CONFIG_NETFILTER_DEBUG ++ ixs->skb->nf_debug = 0; ++#endif /* CONFIG_NETFILTER_DEBUG */ ++#endif /* SKB_RESET_NFCT */ ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_send: " ++ "...done, calling ip_send() on device:%s\n", ++ ixs->skb->dev ? ixs->skb->dev->name : "NULL"); ++ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->skb->nh.iph); ++#ifdef NETDEV_23 /* 2.4 kernels */ ++ { ++ int err; ++ ++ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev, ++ ipsec_tunnel_xmit2); ++ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) { ++ if(net_ratelimit()) ++ printk(KERN_ERR ++ "klips_error:ipsec_xmit_send: " ++ "ip_send() failed, err=%d\n", ++ -err); ++ ixs->stats->tx_errors++; ++ ixs->stats->tx_aborted_errors++; ++ ixs->skb = NULL; ++ return IPSEC_XMIT_IPSENDFAILURE; ++ } ++ } ++#else /* NETDEV_23 */ /* 2.2 kernels */ ++ ip_send(ixs->skb); ++#endif /* NETDEV_23 */ ++#else /* NET_21 */ /* 2.0 kernels */ ++ ixs->skb->arp = 1; ++ /* ISDN/ASYNC PPP from Matjaz Godec. */ ++ /* skb->protocol = htons(ETH_P_IP); */ ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_send: " ++ "...done, calling dev_queue_xmit() or ip_fragment().\n"); ++ IP_SEND(ixs->skb, ixs->physdev); ++#endif /* NET_21 */ ++ ixs->stats->tx_packets++; ++ ++ ixs->skb = NULL; ++ ++ return IPSEC_XMIT_OK; ++} ++ ++void ++ipsec_tunnel_cleanup(struct ipsec_xmit_state*ixs) ++{ ++#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) ++ netif_wake_queue(ixs->dev); ++#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ ++ ixs->dev->tbusy = 0; ++#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ ++ if(ixs->saved_header) { ++ kfree(ixs->saved_header); ++ } ++ if(ixs->skb) { ++ dev_kfree_skb(ixs->skb, FREE_WRITE); ++ } ++ if(ixs->oskb) { ++ dev_kfree_skb(ixs->oskb, FREE_WRITE); ++ } ++ if (ixs->ips.ips_ident_s.data) { ++ kfree(ixs->ips.ips_ident_s.data); ++ } ++ if (ixs->ips.ips_ident_d.data) { ++ kfree(ixs->ips.ips_ident_d.data); ++ } ++} ++ ++/* ++ * This function assumes it is being called from dev_queue_xmit() ++ * and that skb is filled properly by that function. ++ */ ++int ++ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev) ++{ ++ struct ipsec_xmit_state ixs_mem; ++ struct ipsec_xmit_state *ixs = &ixs_mem; ++ enum ipsec_xmit_value stat; ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ ixs->natt_type = 0, ixs->natt_head = 0; ++ ixs->natt_sport = 0, ixs->natt_dport = 0; ++#endif ++ ++ memset((caddr_t)ixs, 0, sizeof(*ixs)); ++ ixs->oskb = NULL; ++ ixs->saved_header = NULL; /* saved copy of the hard header */ ++ ixs->route = NULL; ++ memset((caddr_t)&(ixs->ips), 0, sizeof(ixs->ips)); ++ ixs->dev = dev; ++ ixs->skb = skb; ++ ++ stat = ipsec_xmit_sanity_check_dev(ixs); ++ if(stat != IPSEC_XMIT_OK) { ++ goto cleanup; ++ } ++ ++ stat = ipsec_xmit_sanity_check_skb(ixs); ++ if(stat != IPSEC_XMIT_OK) { ++ goto cleanup; ++ } ++ ++ stat = ipsec_tunnel_strip_hard_header(ixs); ++ if(stat != IPSEC_XMIT_OK) { ++ goto cleanup; ++ } ++ ++ stat = ipsec_tunnel_SAlookup(ixs); ++ if(stat != IPSEC_XMIT_OK) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_tunnel_start_xmit: SAlookup failed: %d\n", ++ stat); ++ goto cleanup; ++ } ++ ++ ixs->innersrc = ixs->iph->saddr; ++ /* start encapsulation loop here XXX */ ++ do { ++ stat = ipsec_xmit_encap_bundle(ixs); ++ if(stat != IPSEC_XMIT_OK) { ++ if(stat == IPSEC_XMIT_PASS) { ++ goto bypass; ++ } ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_tunnel_start_xmit: encap_bundle failed: %d\n", ++ stat); ++ goto cleanup; ++ } ++ ++ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr; ++ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr; ++ ixs->matcher.sen_proto = ixs->iph->protocol; ++ ipsec_extract_ports(ixs->iph, &ixs->matcher); ++ ++ spin_lock(&eroute_lock); ++ ixs->eroute = ipsec_findroute(&ixs->matcher); ++ if(ixs->eroute) { ++ ixs->outgoing_said = ixs->eroute->er_said; ++ ixs->eroute_pid = ixs->eroute->er_pid; ++ ixs->eroute->er_count++; ++ ixs->eroute->er_lasttime = jiffies/HZ; ++ } ++ spin_unlock(&eroute_lock); ++ ++ KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) && ++ /* ((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc)) */ ++ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) && ++ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr && ++ ixs->eroute, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "We are recursing here.\n"); ++ ++ } while(/*((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc))*/ ++ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) && ++ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr && ++ ixs->eroute); ++ ++ stat = ipsec_tunnel_restore_hard_header(ixs); ++ if(stat != IPSEC_XMIT_OK) { ++ goto cleanup; ++ } ++ ++ bypass: ++ stat = ipsec_tunnel_send(ixs); ++ ++ cleanup: ++ ipsec_tunnel_cleanup(ixs); ++ ++ return 0; ++} ++ ++DEBUG_NO_STATIC struct net_device_stats * ++ipsec_tunnel_get_stats(struct device *dev) ++{ ++ return &(((struct ipsecpriv *)(dev->priv))->mystats); ++} ++ ++/* ++ * Revectored calls. ++ * For each of these calls, a field exists in our private structure. ++ */ ++ ++DEBUG_NO_STATIC int ++ipsec_tunnel_hard_header(struct sk_buff *skb, struct device *dev, ++ unsigned short type, void *daddr, void *saddr, unsigned len) ++{ ++ struct ipsecpriv *prv = dev->priv; ++ struct device *tmp; ++ int ret; ++ struct net_device_stats *stats; /* This device's statistics */ ++ ++ if(skb == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_hard_header: " ++ "no skb...\n"); ++ return -ENODATA; ++ } ++ ++ if(dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_hard_header: " ++ "no device...\n"); ++ return -ENODEV; ++ } ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_hard_header: " ++ "skb->dev=%s dev=%s.\n", ++ skb->dev ? skb->dev->name : "NULL", ++ dev->name); ++ ++ if(prv == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_hard_header: " ++ "no private space associated with dev=%s\n", ++ dev->name ? dev->name : "NULL"); ++ return -ENODEV; ++ } ++ ++ stats = (struct net_device_stats *) &(prv->mystats); ++ ++ if(prv->dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_hard_header: " ++ "no physical device associated with dev=%s\n", ++ dev->name ? dev->name : "NULL"); ++ stats->tx_dropped++; ++ return -ENODEV; ++ } ++ ++ /* check if we have to send a IPv6 packet. It might be a Router ++ Solicitation, where the building of the packet happens in ++ reverse order: ++ 1. ll hdr, ++ 2. IPv6 hdr, ++ 3. ICMPv6 hdr ++ -> skb->nh.raw is still uninitialized when this function is ++ called!! If this is no IPv6 packet, we can print debugging ++ messages, otherwise we skip all debugging messages and just ++ build the ll header */ ++ if(type != ETH_P_IPV6) { ++ /* execute this only, if we don't have to build the ++ header for a IPv6 packet */ ++ if(!prv->hard_header) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_hard_header: " ++ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ", ++ saddr, ++ daddr, ++ len, ++ type, ++ dev->name); ++#ifdef NET_21 ++ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, ++ "ip=%08x->%08x\n", ++ (__u32)ntohl(skb->nh.iph->saddr), ++ (__u32)ntohl(skb->nh.iph->daddr) ); ++#else /* NET_21 */ ++ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, ++ "ip=%08x->%08x\n", ++ (__u32)ntohl(skb->ip_hdr->saddr), ++ (__u32)ntohl(skb->ip_hdr->daddr) ); ++#endif /* NET_21 */ ++ stats->tx_dropped++; ++ return -ENODEV; ++ } ++ ++#define da ((struct device *)(prv->dev))->dev_addr ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_hard_header: " ++ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ", ++ saddr, ++ daddr, ++ len, ++ type, ++ dev->name, ++ prv->dev->name, ++ da[0], da[1], da[2], da[3], da[4], da[5]); ++#ifdef NET_21 ++ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, ++ "ip=%08x->%08x\n", ++ (__u32)ntohl(skb->nh.iph->saddr), ++ (__u32)ntohl(skb->nh.iph->daddr) ); ++#else /* NET_21 */ ++ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, ++ "ip=%08x->%08x\n", ++ (__u32)ntohl(skb->ip_hdr->saddr), ++ (__u32)ntohl(skb->ip_hdr->daddr) ); ++#endif /* NET_21 */ ++ } else { ++ KLIPS_PRINT(debug_tunnel, ++ "klips_debug:ipsec_tunnel_hard_header: " ++ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n"); ++ } ++ tmp = skb->dev; ++ skb->dev = prv->dev; ++ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len); ++ skb->dev = tmp; ++ return ret; ++} ++ ++DEBUG_NO_STATIC int ++#ifdef NET_21 ++ipsec_tunnel_rebuild_header(struct sk_buff *skb) ++#else /* NET_21 */ ++ipsec_tunnel_rebuild_header(void *buff, struct device *dev, ++ unsigned long raddr, struct sk_buff *skb) ++#endif /* NET_21 */ ++{ ++ struct ipsecpriv *prv = skb->dev->priv; ++ struct device *tmp; ++ int ret; ++ struct net_device_stats *stats; /* This device's statistics */ ++ ++ if(skb->dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_rebuild_header: " ++ "no device..."); ++ return -ENODEV; ++ } ++ ++ if(prv == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_rebuild_header: " ++ "no private space associated with dev=%s", ++ skb->dev->name ? skb->dev->name : "NULL"); ++ return -ENODEV; ++ } ++ ++ stats = (struct net_device_stats *) &(prv->mystats); ++ ++ if(prv->dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_rebuild_header: " ++ "no physical device associated with dev=%s", ++ skb->dev->name ? skb->dev->name : "NULL"); ++ stats->tx_dropped++; ++ return -ENODEV; ++ } ++ ++ if(!prv->rebuild_header) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_rebuild_header: " ++ "physical device has been detached, packet dropped skb->dev=%s->NULL ", ++ skb->dev->name); ++#ifdef NET_21 ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "ip=%08x->%08x\n", ++ (__u32)ntohl(skb->nh.iph->saddr), ++ (__u32)ntohl(skb->nh.iph->daddr) ); ++#else /* NET_21 */ ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "ip=%08x->%08x\n", ++ (__u32)ntohl(skb->ip_hdr->saddr), ++ (__u32)ntohl(skb->ip_hdr->daddr) ); ++#endif /* NET_21 */ ++ stats->tx_dropped++; ++ return -ENODEV; ++ } ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel: " ++ "Revectored rebuild_header dev=%s->%s ", ++ skb->dev->name, prv->dev->name); ++#ifdef NET_21 ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "ip=%08x->%08x\n", ++ (__u32)ntohl(skb->nh.iph->saddr), ++ (__u32)ntohl(skb->nh.iph->daddr) ); ++#else /* NET_21 */ ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "ip=%08x->%08x\n", ++ (__u32)ntohl(skb->ip_hdr->saddr), ++ (__u32)ntohl(skb->ip_hdr->daddr) ); ++#endif /* NET_21 */ ++ tmp = skb->dev; ++ skb->dev = prv->dev; ++ ++#ifdef NET_21 ++ ret = prv->rebuild_header(skb); ++#else /* NET_21 */ ++ ret = prv->rebuild_header(buff, prv->dev, raddr, skb); ++#endif /* NET_21 */ ++ skb->dev = tmp; ++ return ret; ++} ++ ++DEBUG_NO_STATIC int ++ipsec_tunnel_set_mac_address(struct device *dev, void *addr) ++{ ++ struct ipsecpriv *prv = dev->priv; ++ ++ struct net_device_stats *stats; /* This device's statistics */ ++ ++ if(dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_set_mac_address: " ++ "no device..."); ++ return -ENODEV; ++ } ++ ++ if(prv == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_set_mac_address: " ++ "no private space associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ return -ENODEV; ++ } ++ ++ stats = (struct net_device_stats *) &(prv->mystats); ++ ++ if(prv->dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_set_mac_address: " ++ "no physical device associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ stats->tx_dropped++; ++ return -ENODEV; ++ } ++ ++ if(!prv->set_mac_address) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_set_mac_address: " ++ "physical device has been detached, cannot set - skb->dev=%s->NULL\n", ++ dev->name); ++ return -ENODEV; ++ } ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_set_mac_address: " ++ "Revectored dev=%s->%s addr=0p%p\n", ++ dev->name, prv->dev->name, addr); ++ return prv->set_mac_address(prv->dev, addr); ++ ++} ++ ++#ifndef NET_21 ++DEBUG_NO_STATIC void ++ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct device *dev, ++ unsigned short htype, __u32 daddr) ++{ ++ struct ipsecpriv *prv = dev->priv; ++ ++ struct net_device_stats *stats; /* This device's statistics */ ++ ++ if(dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_cache_bind: " ++ "no device..."); ++ return; ++ } ++ ++ if(prv == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_cache_bind: " ++ "no private space associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ return; ++ } ++ ++ stats = (struct net_device_stats *) &(prv->mystats); ++ ++ if(prv->dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_cache_bind: " ++ "no physical device associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ stats->tx_dropped++; ++ return; ++ } ++ ++ if(!prv->header_cache_bind) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_cache_bind: " ++ "physical device has been detached, cannot set - skb->dev=%s->NULL\n", ++ dev->name); ++ stats->tx_dropped++; ++ return; ++ } ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_cache_bind: " ++ "Revectored \n"); ++ prv->header_cache_bind(hhp, prv->dev, htype, daddr); ++ return; ++} ++#endif /* !NET_21 */ ++ ++ ++DEBUG_NO_STATIC void ++ipsec_tunnel_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr) ++{ ++ struct ipsecpriv *prv = dev->priv; ++ ++ struct net_device_stats *stats; /* This device's statistics */ ++ ++ if(dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_cache_update: " ++ "no device..."); ++ return; ++ } ++ ++ if(prv == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_cache_update: " ++ "no private space associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ return; ++ } ++ ++ stats = (struct net_device_stats *) &(prv->mystats); ++ ++ if(prv->dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_cache_update: " ++ "no physical device associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ stats->tx_dropped++; ++ return; ++ } ++ ++ if(!prv->header_cache_update) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_cache_update: " ++ "physical device has been detached, cannot set - skb->dev=%s->NULL\n", ++ dev->name); ++ return; ++ } ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel: " ++ "Revectored cache_update\n"); ++ prv->header_cache_update(hh, prv->dev, haddr); ++ return; ++} ++ ++#ifdef NET_21 ++DEBUG_NO_STATIC int ++ipsec_tunnel_neigh_setup(struct neighbour *n) ++{ ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_neigh_setup:\n"); ++ ++ if (n->nud_state == NUD_NONE) { ++ n->ops = &arp_broken_ops; ++ n->output = n->ops->output; ++ } ++ return 0; ++} ++ ++DEBUG_NO_STATIC int ++ipsec_tunnel_neigh_setup_dev(struct device *dev, struct neigh_parms *p) ++{ ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_neigh_setup_dev: " ++ "setting up %s\n", ++ dev ? dev->name : "NULL"); ++ ++ if (p->tbl->family == AF_INET) { ++ p->neigh_setup = ipsec_tunnel_neigh_setup; ++ p->ucast_probes = 0; ++ p->mcast_probes = 0; ++ } ++ return 0; ++} ++#endif /* NET_21 */ ++ ++/* ++ * We call the attach routine to attach another device. ++ */ ++ ++DEBUG_NO_STATIC int ++ipsec_tunnel_attach(struct device *dev, struct device *physdev) ++{ ++ int i; ++ struct ipsecpriv *prv = dev->priv; ++ ++ if(dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_attach: " ++ "no device..."); ++ return -ENODEV; ++ } ++ ++ if(prv == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_attach: " ++ "no private space associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ return -ENODATA; ++ } ++ ++ prv->dev = physdev; ++ prv->hard_start_xmit = physdev->hard_start_xmit; ++ prv->get_stats = physdev->get_stats; ++ ++ if (physdev->hard_header) { ++ prv->hard_header = physdev->hard_header; ++ dev->hard_header = ipsec_tunnel_hard_header; ++ } else ++ dev->hard_header = NULL; ++ ++ if (physdev->rebuild_header) { ++ prv->rebuild_header = physdev->rebuild_header; ++ dev->rebuild_header = ipsec_tunnel_rebuild_header; ++ } else ++ dev->rebuild_header = NULL; ++ ++ if (physdev->set_mac_address) { ++ prv->set_mac_address = physdev->set_mac_address; ++ dev->set_mac_address = ipsec_tunnel_set_mac_address; ++ } else ++ dev->set_mac_address = NULL; ++ ++#ifndef NET_21 ++ if (physdev->header_cache_bind) { ++ prv->header_cache_bind = physdev->header_cache_bind; ++ dev->header_cache_bind = ipsec_tunnel_cache_bind; ++ } else ++ dev->header_cache_bind = NULL; ++#endif /* !NET_21 */ ++ ++ if (physdev->header_cache_update) { ++ prv->header_cache_update = physdev->header_cache_update; ++ dev->header_cache_update = ipsec_tunnel_cache_update; ++ } else ++ dev->header_cache_update = NULL; ++ ++ dev->hard_header_len = physdev->hard_header_len; ++ ++#ifdef NET_21 ++/* prv->neigh_setup = physdev->neigh_setup; */ ++ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev; ++#endif /* NET_21 */ ++ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */ ++ prv->mtu = physdev->mtu; ++ ++#ifdef PHYSDEV_TYPE ++ dev->type = physdev->type; /* ARPHRD_TUNNEL; */ ++#endif /* PHYSDEV_TYPE */ ++ ++ dev->addr_len = physdev->addr_len; ++ for (i=0; iaddr_len; i++) { ++ dev->dev_addr[i] = physdev->dev_addr[i]; ++ } ++#ifdef CONFIG_IPSEC_DEBUG ++ if(debug_tunnel & DB_TN_INIT) { ++ printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: " ++ "physical device %s being attached has HW address: %2x", ++ physdev->name, physdev->dev_addr[0]); ++ for (i=1; i < physdev->addr_len; i++) { ++ printk(":%02x", physdev->dev_addr[i]); ++ } ++ printk("\n"); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ return 0; ++} ++ ++/* ++ * We call the detach routine to detach the ipsec tunnel from another device. ++ */ ++ ++DEBUG_NO_STATIC int ++ipsec_tunnel_detach(struct device *dev) ++{ ++ int i; ++ struct ipsecpriv *prv = dev->priv; ++ ++ if(dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_detach: " ++ "no device..."); ++ return -ENODEV; ++ } ++ ++ if(prv == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, ++ "klips_debug:ipsec_tunnel_detach: " ++ "no private space associated with dev=%s", ++ dev->name ? dev->name : "NULL"); ++ return -ENODATA; ++ } ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_detach: " ++ "physical device %s being detached from virtual device %s\n", ++ prv->dev ? prv->dev->name : "NULL", ++ dev->name); ++ ++ ipsec_dev_put(prv->dev); ++ prv->dev = NULL; ++ prv->hard_start_xmit = NULL; ++ prv->get_stats = NULL; ++ ++ prv->hard_header = NULL; ++#ifdef DETACH_AND_DOWN ++ dev->hard_header = NULL; ++#endif /* DETACH_AND_DOWN */ ++ ++ prv->rebuild_header = NULL; ++#ifdef DETACH_AND_DOWN ++ dev->rebuild_header = NULL; ++#endif /* DETACH_AND_DOWN */ ++ ++ prv->set_mac_address = NULL; ++#ifdef DETACH_AND_DOWN ++ dev->set_mac_address = NULL; ++#endif /* DETACH_AND_DOWN */ ++ ++#ifndef NET_21 ++ prv->header_cache_bind = NULL; ++#ifdef DETACH_AND_DOWN ++ dev->header_cache_bind = NULL; ++#endif /* DETACH_AND_DOWN */ ++#endif /* !NET_21 */ ++ ++ prv->header_cache_update = NULL; ++#ifdef DETACH_AND_DOWN ++ dev->header_cache_update = NULL; ++#endif /* DETACH_AND_DOWN */ ++ ++#ifdef NET_21 ++/* prv->neigh_setup = NULL; */ ++#ifdef DETACH_AND_DOWN ++ dev->neigh_setup = NULL; ++#endif /* DETACH_AND_DOWN */ ++#endif /* NET_21 */ ++ dev->hard_header_len = 0; ++#ifdef DETACH_AND_DOWN ++ dev->mtu = 0; ++#endif /* DETACH_AND_DOWN */ ++ prv->mtu = 0; ++ for (i=0; idev_addr[i] = 0; ++ } ++ dev->addr_len = 0; ++#ifdef PHYSDEV_TYPE ++ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ ++#endif /* PHYSDEV_TYPE */ ++ ++ return 0; ++} ++ ++/* ++ * We call the clear routine to detach all ipsec tunnels from other devices. ++ */ ++DEBUG_NO_STATIC int ++ipsec_tunnel_clear(void) ++{ ++ int i; ++ struct device *ipsecdev = NULL, *prvdev; ++ struct ipsecpriv *prv; ++ char name[9]; ++ int ret; ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_clear: .\n"); ++ ++ for(i = 0; i < IPSEC_NUM_IF; i++) { ++ ipsecdev = ipsecdevices[i]; ++ if(ipsecdev != NULL) { ++ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) { ++ prvdev = (struct device *)(prv->dev); ++ if(prvdev) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_clear: " ++ "physical device for device %s is %s\n", ++ name, prvdev->name); ++ if((ret = ipsec_tunnel_detach(ipsecdev))) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_clear: " ++ "error %d detatching device %s from device %s.\n", ++ ret, name, prvdev->name); ++ return ret; ++ } ++ } ++ } ++ } ++ } ++ return 0; ++} ++ ++DEBUG_NO_STATIC int ++ipsec_tunnel_ioctl(struct device *dev, struct ifreq *ifr, int cmd) ++{ ++ struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data; ++ struct ipsecpriv *prv = dev->priv; ++ struct device *them; /* physical device */ ++#ifdef CONFIG_IP_ALIAS ++ char *colon; ++ char realphysname[IFNAMSIZ]; ++#endif /* CONFIG_IP_ALIAS */ ++ ++ if(dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_ioctl: " ++ "device not supplied.\n"); ++ return -ENODEV; ++ } ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_ioctl: " ++ "tncfg service call #%d for dev=%s\n", ++ cmd, ++ dev->name ? dev->name : "NULL"); ++ switch (cmd) { ++ /* attach a virtual ipsec? device to a physical device */ ++ case IPSEC_SET_DEV: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_ioctl: " ++ "calling ipsec_tunnel_attatch...\n"); ++#ifdef CONFIG_IP_ALIAS ++ /* If this is an IP alias interface, get its real physical name */ ++ strncpy(realphysname, cf->cf_name, IFNAMSIZ); ++ realphysname[IFNAMSIZ-1] = 0; ++ colon = strchr(realphysname, ':'); ++ if (colon) *colon = 0; ++ them = ipsec_dev_get(realphysname); ++#else /* CONFIG_IP_ALIAS */ ++ them = ipsec_dev_get(cf->cf_name); ++#endif /* CONFIG_IP_ALIAS */ ++ ++ if (them == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_ioctl: " ++ "physical device %s requested is null\n", ++ cf->cf_name); ++ ipsec_dev_put(them); ++ return -ENXIO; ++ } ++ ++#if 0 ++ if (them->flags & IFF_UP) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_ioctl: " ++ "physical device %s requested is not up.\n", ++ cf->cf_name); ++ ipsec_dev_put(them); ++ return -ENXIO; ++ } ++#endif ++ ++ if (prv && prv->dev) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_ioctl: " ++ "virtual device is already connected to %s.\n", ++ prv->dev->name ? prv->dev->name : "NULL"); ++ ipsec_dev_put(them); ++ return -EBUSY; ++ } ++ return ipsec_tunnel_attach(dev, them); ++ ++ case IPSEC_DEL_DEV: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_ioctl: " ++ "calling ipsec_tunnel_detatch.\n"); ++ if (! prv->dev) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_ioctl: " ++ "physical device not connected.\n"); ++ return -ENODEV; ++ } ++ return ipsec_tunnel_detach(dev); ++ ++ case IPSEC_CLR_DEV: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_ioctl: " ++ "calling ipsec_tunnel_clear.\n"); ++ return ipsec_tunnel_clear(); ++ ++ default: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_ioctl: " ++ "unknown command %d.\n", ++ cmd); ++ return -EOPNOTSUPP; ++ } ++} ++ ++int ++ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr) ++{ ++ struct device *dev = ptr; ++ struct device *ipsec_dev; ++ struct ipsecpriv *priv; ++ int i; ++ ++ if (dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "dev=NULL for event type %ld.\n", ++ event); ++ return(NOTIFY_DONE); ++ } ++ ++ /* check for loopback devices */ ++ if (dev && (dev->flags & IFF_LOOPBACK)) { ++ return(NOTIFY_DONE); ++ } ++ ++ switch (event) { ++ case NETDEV_DOWN: ++ /* look very carefully at the scope of these compiler ++ directives before changing anything... -- RGB */ ++#ifdef NET_21 ++ case NETDEV_UNREGISTER: ++ switch (event) { ++ case NETDEV_DOWN: ++#endif /* NET_21 */ ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "NETDEV_DOWN dev=%s flags=%x\n", ++ dev->name, ++ dev->flags); ++ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) { ++ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n", ++ dev->name); ++ } ++#ifdef NET_21 ++ break; ++ case NETDEV_UNREGISTER: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "NETDEV_UNREGISTER dev=%s flags=%x\n", ++ dev->name, ++ dev->flags); ++ break; ++ } ++#endif /* NET_21 */ ++ ++ /* find the attached physical device and detach it. */ ++ for(i = 0; i < IPSEC_NUM_IF; i++) { ++ ipsec_dev = ipsecdevices[i]; ++ ++ if(ipsec_dev) { ++ priv = (struct ipsecpriv *)(ipsec_dev->priv); ++ if(priv) { ++ ; ++ if(((struct device *)(priv->dev)) == dev) { ++ /* dev_close(ipsec_dev); */ ++ /* return */ ipsec_tunnel_detach(ipsec_dev); ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "device '%s' has been detached.\n", ++ ipsec_dev->name); ++ break; ++ } ++ } else { ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "device '%s' has no private data space!\n", ++ ipsec_dev->name); ++ } ++ } ++ } ++ break; ++ case NETDEV_UP: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "NETDEV_UP dev=%s\n", ++ dev->name); ++ break; ++#ifdef NET_21 ++ case NETDEV_REBOOT: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "NETDEV_REBOOT dev=%s\n", ++ dev->name); ++ break; ++ case NETDEV_CHANGE: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "NETDEV_CHANGE dev=%s flags=%x\n", ++ dev->name, ++ dev->flags); ++ break; ++ case NETDEV_REGISTER: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "NETDEV_REGISTER dev=%s\n", ++ dev->name); ++ break; ++ case NETDEV_CHANGEMTU: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n", ++ dev->name, ++ dev->mtu); ++ break; ++ case NETDEV_CHANGEADDR: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "NETDEV_CHANGEADDR dev=%s\n", ++ dev->name); ++ break; ++ case NETDEV_GOING_DOWN: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "NETDEV_GOING_DOWN dev=%s\n", ++ dev->name); ++ break; ++ case NETDEV_CHANGENAME: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "NETDEV_CHANGENAME dev=%s\n", ++ dev->name); ++ break; ++#endif /* NET_21 */ ++ default: ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_device_event: " ++ "event type %ld unrecognised for dev=%s\n", ++ event, ++ dev->name); ++ break; ++ } ++ return NOTIFY_DONE; ++} ++ ++/* ++ * Called when an ipsec tunnel device is initialized. ++ * The ipsec tunnel device structure is passed to us. ++ */ ++ ++int ++ipsec_tunnel_init(struct device *dev) ++{ ++ int i; ++ ++ KLIPS_PRINT(debug_tunnel, ++ "klips_debug:ipsec_tunnel_init: " ++ "allocating %lu bytes initialising device: %s\n", ++ (unsigned long) sizeof(struct ipsecpriv), ++ dev->name ? dev->name : "NULL"); ++ ++ /* Add our tunnel functions to the device */ ++ dev->open = ipsec_tunnel_open; ++ dev->stop = ipsec_tunnel_close; ++ dev->hard_start_xmit = ipsec_tunnel_start_xmit; ++ dev->get_stats = ipsec_tunnel_get_stats; ++ ++ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL); ++ if (dev->priv == NULL) ++ return -ENOMEM; ++ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv)); ++ ++ for(i = 0; i < sizeof(zeroes); i++) { ++ ((__u8*)(zeroes))[i] = 0; ++ } ++ ++#ifndef NET_21 ++ /* Initialize the tunnel device structure */ ++ for (i = 0; i < DEV_NUMBUFFS; i++) ++ skb_queue_head_init(&dev->buffs[i]); ++#endif /* !NET_21 */ ++ ++ dev->set_multicast_list = NULL; ++ dev->do_ioctl = ipsec_tunnel_ioctl; ++ dev->hard_header = NULL; ++ dev->rebuild_header = NULL; ++ dev->set_mac_address = NULL; ++#ifndef NET_21 ++ dev->header_cache_bind = NULL; ++#endif /* !NET_21 */ ++ dev->header_cache_update= NULL; ++ ++#ifdef NET_21 ++/* prv->neigh_setup = NULL; */ ++ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev; ++#endif /* NET_21 */ ++ dev->hard_header_len = 0; ++ dev->mtu = 0; ++ dev->addr_len = 0; ++ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */ ++ dev->tx_queue_len = 10; /* Small queue */ ++ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */ ++ ++ /* New-style flags. */ ++ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */; ++#ifdef NET_21 ++ dev_init_buffers(dev); ++#else /* NET_21 */ ++ dev->family = AF_INET; ++ dev->pa_addr = 0; ++ dev->pa_brdaddr = 0; ++ dev->pa_mask = 0; ++ dev->pa_alen = 4; ++#endif /* NET_21 */ ++ ++ /* We're done. Have I forgotten anything? */ ++ return 0; ++} ++ ++/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ++/* Module specific interface (but it links with the rest of IPSEC) */ ++/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ++ ++int ++ipsec_tunnel_probe(struct device *dev) ++{ ++ ipsec_tunnel_init(dev); ++ return 0; ++} ++ ++struct device *ipsecdevices[IPSEC_NUM_IF]; ++ ++int ++ipsec_tunnel_init_devices(void) ++{ ++ int i; ++ char name[IFNAMSIZ]; ++ struct device *dev_ipsec; ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_init_devices: " ++ "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n", ++ IPSEC_NUM_IF, ++ (unsigned long) (sizeof(struct device) + IFNAMSIZ), ++ IFNAMSIZ); ++ ++ for(i = 0; i < IPSEC_NUM_IF; i++) { ++ sprintf(name, IPSEC_DEV_FORMAT, i); ++ dev_ipsec = (struct device*)kmalloc(sizeof(struct device), GFP_KERNEL); ++ if (dev_ipsec == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_init_devices: " ++ "failed to allocate memory for device %s, quitting device init.\n", ++ name); ++ return -ENOMEM; ++ } ++ memset((caddr_t)dev_ipsec, 0, sizeof(struct device)); ++#ifdef NETDEV_23 ++ strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name)); ++#else /* NETDEV_23 */ ++ dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL); ++ if (dev_ipsec->name == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_init_devices: " ++ "failed to allocate memory for device %s name, quitting device init.\n", ++ name); ++ return -ENOMEM; ++ } ++ memset((caddr_t)dev_ipsec->name, 0, IFNAMSIZ); ++ strncpy(dev_ipsec->name, name, IFNAMSIZ); ++#endif /* NETDEV_23 */ ++ dev_ipsec->next = NULL; ++ dev_ipsec->init = &ipsec_tunnel_probe; ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_init_devices: " ++ "registering device %s\n", ++ dev_ipsec->name); ++ ++ /* reference and hold the device reference */ ++ dev_hold(dev_ipsec); ++ ipsecdevices[i]=dev_ipsec; ++ ++ if (register_netdev(dev_ipsec) != 0) { ++ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_init_devices: " ++ "registering device %s failed, quitting device init.\n", ++ dev_ipsec->name); ++ return -EIO; ++ } else { ++ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, ++ "klips_debug:ipsec_tunnel_init_devices: " ++ "registering device %s succeeded, continuing...\n", ++ dev_ipsec->name); ++ } ++ } ++ return 0; ++} ++ ++/* void */ ++int ++ipsec_tunnel_cleanup_devices(void) ++{ ++ int error = 0; ++ int i; ++ char name[32]; ++ struct device *dev_ipsec; ++ ++ for(i = 0; i < IPSEC_NUM_IF; i++) { ++ dev_ipsec = ipsecdevices[i]; ++ if(dev_ipsec == NULL) { ++ continue; ++ } ++ ++ /* release reference */ ++ ipsecdevices[i]=NULL; ++ ipsec_dev_put(dev_ipsec); ++ ++ KLIPS_PRINT(debug_tunnel, "Unregistering %s (refcnt=%d)\n", ++ name, ++ atomic_read(&dev_ipsec->refcnt)); ++ unregister_netdev(dev_ipsec); ++ KLIPS_PRINT(debug_tunnel, "Unregisted %s\n", name); ++#ifndef NETDEV_23 ++ kfree(dev_ipsec->name); ++ dev_ipsec->name=NULL; ++#endif /* !NETDEV_23 */ ++ kfree(dev_ipsec->priv); ++ dev_ipsec->priv=NULL; ++ } ++ return error; ++} ++ ++/* ++ * $Log: ipsec_tunnel.c,v $ ++ * Revision 1.220 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.219 2004/02/03 03:13:17 mcr ++ * minor edits for readability, and error reporting. ++ * ++ * Revision 1.218 2004/01/27 20:29:20 mcr ++ * fix for unregister_netdev() problem for underlying eth0. ++ * ++ * Revision 1.217 2003/12/10 01:14:27 mcr ++ * NAT-traversal patches to KLIPS. ++ * ++ * Revision 1.216 2003/12/04 23:01:17 mcr ++ * removed ipsec_netlink.h ++ * ++ * Revision 1.215 2003/12/04 16:35:16 ken ++ * Fix for ATM devices where physdev->hard_header_len *is* correct ++ * ++ * Revision 1.214 2003/11/25 23:52:37 mcr ++ * fix typo in patch - ixs-> needed. ++ * ++ * Revision 1.213 2003/11/24 18:25:49 mcr ++ * patch from willy@w.ods.org to fix problems with ATM interfaces. ++ * ++ * Revision 1.212 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.211.2.2 2003/10/29 01:30:41 mcr ++ * elimited "struct sa_id". ++ * ++ * Revision 1.211.2.1 2003/09/21 13:59:56 mcr ++ * pre-liminary X.509 patch - does not yet pass tests. ++ * ++ * Revision 1.211 2003/09/10 16:46:30 mcr ++ * patches for 2.4 backport/2.6 existence. ++ * ++ * Revision 1.210 2003/07/31 22:47:16 mcr ++ * preliminary (untested by FS-team) 2.5 patches. ++ * ++ * Revision 1.209 2003/06/22 21:28:43 mcr ++ * inability to unload module was caused by calls to dev_get ++ * (ipsec_dev_get), to gather a device from a name. There is ++ * simply no reason to look the devices up - they should be kept ++ * in a nice array, ready for use. ++ * ++ * Revision 1.208 2003/06/22 21:25:07 mcr ++ * all staticly counted ipsecXXX device support removed. ++ * ++ * Revision 1.207 2003/04/02 20:15:37 mcr ++ * fix for PR#204 - do not clear connection tracking info if we ++ * the packet is being sent in the clear. ++ * ++ * Revision 1.206 2003/02/12 19:32:51 rgb ++ * Refactored file to: ++ * ipsec_xmit.c ++ * ipsec_xmit.h ++ * ipsec_mast.c ++ * ++ * Revision 1.205 2003/02/06 17:47:00 rgb ++ * ++ * Remove unused ipsec_tunnel_lock() and ipsec_tunnel_unlock() code. ++ * Refactor ipsec_tunnel_start_xmit() further into: ++ * ipsec_xmit_sanity_check_dev() ++ * ipsec_xmit_sanity_check_skb() ++ * ipsec_xmit_strip_hard_header() ++ * ipsec_xmit_restore_hard_header() ++ * ipsec_xmit_send() ++ * ipsec_xmit_cleanup() ++ * and start a skeletal ipsec_mast_start_xmit() . ++ * ++ * Revision 1.204 2003/02/06 06:43:46 rgb ++ * ++ * Refactor ipsec_tunnel_start_xmit, bringing out: ++ * ipsec_xmit_SAlookup ++ * ipsec_xmit_encap_once ++ * ipsec_xmit_encap_bundle ++ * ++ * Revision 1.203 2003/02/06 02:21:34 rgb ++ * ++ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h . ++ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr". ++ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code. ++ * ++ * Revision 1.202 2003/01/03 07:38:01 rgb ++ * ++ * Start to refactor ipsec_tunnel_start_xmit() by putting local variables ++ * into struct ipsec_xmit_state and renaming a few variables to give more ++ * unique or searchable names. ++ * ++ * Revision 1.201 2003/01/03 00:31:28 rgb ++ * ++ * Clean up memset usage, including fixing 2 places where keys were not ++ * properly wiped. ++ * ++ * Revision 1.200 2002/12/06 02:24:02 mcr ++ * patches for compiling against SUSE 8.1 kernels. Requires ++ * an additional -DSUSE_LINUX_2_4_19_IS_STUPID. ++ * ++ * Revision 1.199 2002/10/12 23:11:53 dhr ++ * ++ * [KenB + DHR] more 64-bit cleanup ++ * ++ * Revision 1.198 2002/10/05 05:02:58 dhr ++ * ++ * C labels go on statements ++ * ++ * Revision 1.197 2002/09/20 05:01:50 rgb ++ * Added compiler directive to switch on IP options and fix IP options bug. ++ * Make ip->ihl treatment consistent using shifts rather than multiplications. ++ * Check for large enough packet before accessing udp header for IKE bypass. ++ * Added memory allocation debugging. ++ * Fixed potential memory allocation failure-induced oops. ++ * ++ * Revision 1.196 2002/07/24 18:44:54 rgb ++ * Type fiddling to tame ia64 compiler. ++ * ++ * Revision 1.195 2002/07/23 03:36:07 rgb ++ * Fixed 2.2 device initialisation hang. ++ * ++ * Revision 1.194 2002/05/27 21:40:34 rgb ++ * Set unused ipsec devices to ARPHRD_VOID to avoid confusing iproute2. ++ * Cleaned up intermediate step to dynamic device allocation. ++ * ++ * Revision 1.193 2002/05/27 19:31:36 rgb ++ * Convert to dynamic ipsec device allocation. ++ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. ++ * ++ * Revision 1.192 2002/05/23 07:14:28 rgb ++ * Added refcount code. ++ * Cleaned up %p variants to 0p%p for test suite cleanup. ++ * ++ * Revision 1.191 2002/05/14 02:34:37 rgb ++ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, ++ * ipsec_sa or ipsec_sa. ++ * ++ * Revision 1.190 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.189 2002/04/24 07:36:32 mcr ++ * Moved from ./klips/net/ipsec/ipsec_tunnel.c,v ++ * ++ * Revision 1.188 2002/04/20 00:12:25 rgb ++ * Added esp IV CBC attack fix, disabled. ++ * ++ * Revision 1.187 2002/03/23 19:55:17 rgb ++ * Fix for 2.2 local IKE fragmentation blackhole. Still won't work if ++ * iptraf or another pcap app is running. ++ * ++ * Revision 1.186 2002/03/19 03:26:22 rgb ++ * Applied DHR's tunnel patch to streamline IKE/specialSA processing. ++ * ++ * Revision 1.185 2002/02/20 04:13:05 rgb ++ * Send back ICMP_PKT_FILTERED upon %reject. ++ * ++ * Revision 1.184 2002/01/29 17:17:56 mcr ++ * moved include of ipsec_param.h to after include of linux/kernel.h ++ * otherwise, it seems that some option that is set in ipsec_param.h ++ * screws up something subtle in the include path to kernel.h, and ++ * it complains on the snprintf() prototype. ++ * ++ * Revision 1.183 2002/01/29 04:00:53 mcr ++ * more excise of kversions.h header. ++ * ++ * Revision 1.182 2002/01/29 02:13:18 mcr ++ * introduction of ipsec_kversion.h means that include of ++ * ipsec_param.h must preceed any decisions about what files to ++ * include to deal with differences in kernel source. ++ * ++ * Revision 1.181 2002/01/07 20:00:33 rgb ++ * Added IKE destination port debugging. ++ * ++ * Revision 1.180 2001/12/21 21:49:54 rgb ++ * Fixed bug as a result of moving IKE bypass above %trap/%hold code. ++ * ++ * Revision 1.179 2001/12/19 21:08:14 rgb ++ * Added transport protocol ports to ipsec_print_ip(). ++ * Update eroute info for non-SA targets. ++ * Added obey DF code disabled. ++ * Fixed formatting bugs in ipsec_tunnel_hard_header(). ++ * ++ * Revision 1.178 2001/12/05 09:36:10 rgb ++ * Moved the UDP/500 IKE check just above the %hold/%trap checks to avoid ++ * IKE packets being stolen by the %hold (and returned to the sending KMd ++ * in an ACQUIRE, ironically ;-). ++ * ++ * Revision 1.177 2001/11/26 09:23:50 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.170.2.1 2001/09/25 02:28:27 mcr ++ * struct tdb -> struct ipsec_sa. ++ * lifetime checks moved to common routines. ++ * cleaned up includes. ++ * ++ * Revision 1.170.2.2 2001/10/22 21:08:01 mcr ++ * include des.h, removed phony prototypes and fixed calling ++ * conventions to match real prototypes. ++ * ++ * Revision 1.176 2001/11/09 18:32:31 rgb ++ * Added Hans Schultz' fragmented UDP/500 IKE socket port selector. ++ * ++ * Revision 1.175 2001/11/06 20:47:00 rgb ++ * Added Eric Espie's TRAPSUBNET fix, minus spin-lock-bh dabbling. ++ * ++ * Revision 1.174 2001/11/06 19:50:43 rgb ++ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for ++ * use also by pfkey_v2_parser.c ++ * ++ * Revision 1.173 2001/10/29 21:53:44 henry ++ * tone down the device-down message slightly, until we can make it smarter ++ * ++ * Revision 1.172 2001/10/26 04:59:37 rgb ++ * Added a critical level syslog message if an ipsec device goes down. ++ * ++ * Revision 1.171 2001/10/18 04:45:21 rgb ++ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, ++ * lib/freeswan.h version macros moved to lib/kversions.h. ++ * Other compiler directive cleanups. ++ * ++ * Revision 1.170 2001/09/25 00:09:50 rgb ++ * Added NetCelo's TRAPSUBNET code to convert a new type TRAPSUBNET into a ++ * HOLD. ++ * ++ * Revision 1.169 2001/09/15 16:24:05 rgb ++ * Re-inject first and last HOLD packet when an eroute REPLACE is done. ++ * ++ * Revision 1.168 2001/09/14 16:58:37 rgb ++ * Added support for storing the first and last packets through a HOLD. ++ * ++ * Revision 1.167 2001/09/08 21:13:33 rgb ++ * Added pfkey ident extension support for ISAKMPd. (NetCelo) ++ * ++ * Revision 1.166 2001/08/27 19:47:59 rgb ++ * Clear tdb before usage. ++ * Added comment: clear IF before calling routing? ++ * ++ * Revision 1.165 2001/07/03 01:23:53 rgb ++ * Send back ICMP iff DF set, !ICMP, offset==0, sysctl_icmp, iph->tot_len > ++ * emtu, and don't drop. ++ * ++ * Revision 1.164 2001/06/14 19:35:10 rgb ++ * Update copyright date. ++ * ++ * Revision 1.163 2001/06/06 20:28:51 rgb ++ * Added sanity checks for NULL skbs and devices. ++ * Added more debugging output to various functions. ++ * Removed redundant dev->priv argument to ipsec_tunnel_{at,de}tach(). ++ * Renamed ipsec_tunnel_attach() virtual and physical device arguments. ++ * Corrected neigh_setup() device function assignment. ++ * Keep valid pointers to ipsec_tunnel_*() on detach. ++ * Set dev->type to the originally-initiallised value. ++ * ++ * Revision 1.162 2001/06/01 07:28:04 rgb ++ * Added sanity checks for detached devices. Don't down virtual devices ++ * to prevent packets going out in the clear if the detached device comes ++ * back up. ++ * ++ * Revision 1.161 2001/05/30 08:14:52 rgb ++ * Removed vestiges of esp-null transforms. ++ * NetDev Notifier instrumentation to track down disappearing devices. ++ * ++ * Revision 1.160 2001/05/29 05:15:12 rgb ++ * Added SS' PMTU patch which notifies sender if packet doesn't fit ++ * physical MTU (if it wasn't ICMP) and then drops it. ++ * ++ * Revision 1.159 2001/05/27 06:12:12 rgb ++ * Added structures for pid, packet count and last access time to eroute. ++ * Added packet count to beginning of /proc/net/ipsec_eroute. ++ * ++ * Revision 1.158 2001/05/24 05:39:33 rgb ++ * Applied source zeroing to 2.2 ip_route_output() call as well to enable ++ * PASS eroutes for opportunism. ++ * ++ * Revision 1.157 2001/05/23 22:35:28 rgb ++ * 2.4 source override simplification. ++ * ++ * Revision 1.156 2001/05/23 21:41:31 rgb ++ * Added error return code printing on ip_route_output(). ++ * ++ * Revision 1.155 2001/05/23 05:09:13 rgb ++ * Fixed incorrect ip_route_output() failure message. ++ * ++ * Revision 1.154 2001/05/21 14:53:31 rgb ++ * Added debug statement for case when ip_route_output() fails, causing ++ * packet to be dropped, but log looked ok. ++ * ++ * Revision 1.153 2001/05/19 02:37:54 rgb ++ * Fixed missing comment termination. ++ * ++ * Revision 1.152 2001/05/19 02:35:50 rgb ++ * Debug code optimisation for non-debug speed. ++ * Kernel version compiler define comments. ++ * 2.2 and 2.4 kernel ip_send device and ip debug output added. ++ * ++ * Revision 1.151 2001/05/18 16:17:35 rgb ++ * Changed reference from "magic" to "shunt" SAs. ++ * ++ * Revision 1.150 2001/05/18 16:12:19 rgb ++ * Changed UDP/500 bypass test from 3 nested ifs to one anded if. ++ * ++ * Revision 1.149 2001/05/16 04:39:33 rgb ++ * Add default == eroute.dest to IKE bypass conditions for magic eroutes. ++ * ++ * Revision 1.148 2001/05/05 03:31:41 rgb ++ * IP frag debugging updates and enhancements. ++ * ++ * Revision 1.147 2001/05/03 19:41:40 rgb ++ * Added SS' skb_cow fix for 2.4.4. ++ * ++ * Revision 1.146 2001/04/30 19:28:16 rgb ++ * Update for 2.4.4. ip_select_ident() now has 3 args. ++ * ++ * Revision 1.145 2001/04/23 14:56:10 rgb ++ * Added spin_lock() check to prevent double-locking for multiple ++ * transforms and hence kernel lock-ups with SMP kernels. ++ * ++ * Revision 1.144 2001/04/21 23:04:45 rgb ++ * Define out skb->used for 2.4 kernels. ++ * Check if soft expire has already been sent before sending another to ++ * prevent ACQUIRE flooding. ++ * ++ * Revision 1.143 2001/03/16 07:37:21 rgb ++ * Added comments to all #endifs. ++ * ++ * Revision 1.142 2001/02/28 05:03:27 rgb ++ * Clean up and rationalise startup messages. ++ * ++ * Revision 1.141 2001/02/27 22:24:54 rgb ++ * Re-formatting debug output (line-splitting, joining, 1arg/line). ++ * Check for satoa() return codes. ++ * ++ * Revision 1.140 2001/02/27 06:40:12 rgb ++ * Fixed TRAP->HOLD eroute byte order. ++ * ++ * Revision 1.139 2001/02/26 20:38:59 rgb ++ * Added compiler defines for 2.4.x-specific code. ++ * ++ * Revision 1.138 2001/02/26 19:57:27 rgb ++ * Implement magic SAs %drop, %reject, %trap, %hold, %pass as part ++ * of the new SPD and to support opportunistic. ++ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs. ++ * ++ * Revision 1.137 2001/02/19 22:29:49 rgb ++ * Fixes for presence of active ipv6 segments which share ipsec physical ++ * device (gg). ++ * ++ * Revision 1.136 2001/01/29 22:30:38 rgb ++ * Fixed minor acquire debug printing bug. ++ * ++ * Revision 1.135 2001/01/29 22:19:45 rgb ++ * Zero source address for 2.4 bypass route lookup. ++ * ++ * Revision 1.134 2001/01/23 20:19:49 rgb ++ * 2.4 fix to remove removed is_clone member. ++ * ++ * Revision 1.133 2000/12/09 22:08:35 rgb ++ * Fix NET_23 bug, should be NETDEV_23. ++ * ++ * Revision 1.132 2000/12/01 06:54:50 rgb ++ * Fix for new 2.4 IP TTL default variable name. ++ * ++ * Revision 1.131 2000/11/09 20:52:15 rgb ++ * More spinlock shuffling, locking earlier and unlocking later in rcv to ++ * include ipcomp and prevent races, renaming some tdb variables that got ++ * forgotten, moving some unlocks to include tdbs and adding a missing ++ * unlock. Thanks to Svenning for some of these. ++ * ++ * Revision 1.130 2000/11/09 20:11:22 rgb ++ * Minor shuffles to fix non-standard kernel config option selection. ++ * ++ * Revision 1.129 2000/11/06 04:32:49 rgb ++ * Clean up debug printing. ++ * Copy skb->protocol for all kernel versions. ++ * Ditched spin_lock_irqsave in favour of spin_lock. ++ * Disabled TTL decrement, done in ip_forward. ++ * Added debug printing before pfkey_acquire(). ++ * Fixed printk-deltdbchain-spin_lock races (Svenning). ++ * Use defaultTTL for 2.1+ kernels. ++ * Add Svenning's adaptive content compression. ++ * Fix up debug display arguments. ++ * ++ * Revision 1.128 2000/09/28 00:58:57 rgb ++ * Moved the IKE passthrough check after the eroute lookup so we can pass ++ * IKE through intermediate tunnels. ++ * ++ * Revision 1.127 2000/09/22 17:52:11 rgb ++ * Fixed misleading ipcomp debug output. ++ * ++ * Revision 1.126 2000/09/22 04:22:56 rgb ++ * Fixed dumb spi->cpi conversion error. ++ * ++ * Revision 1.125 2000/09/21 04:34:48 rgb ++ * A few debug-specific things should be hidden under ++ * CONFIG_IPSEC_DEBUG.(MB) ++ * Improved ip_send() error handling.(MB) ++ * ++ * Revision 1.124 2000/09/21 03:40:58 rgb ++ * Added more debugging to try and track down the cpi outward copy problem. ++ * ++ * Revision 1.123 2000/09/19 07:08:49 rgb ++ * Added debugging to outgoing compression report. ++ * ++ * Revision 1.122 2000/09/18 19:21:26 henry ++ * RGB-supplied fix for RH5.2 problem ++ * ++ * Revision 1.121 2000/09/17 21:05:09 rgb ++ * Added tdb to skb_compress call to write in cpi. ++ * ++ * Revision 1.120 2000/09/17 16:57:16 rgb ++ * Added Svenning's patch to remove restriction of ipcomp to innermost ++ * transform. ++ * ++ * Revision 1.119 2000/09/15 11:37:01 rgb ++ * Merge in heavily modified Svenning Soerensen's ++ * IPCOMP zlib deflate code. ++ * ++ * Revision 1.118 2000/09/15 04:57:16 rgb ++ * Moved debug output after sanity check. ++ * Added tos copy sysctl. ++ * ++ * Revision 1.117 2000/09/12 03:22:51 rgb ++ * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to ++ * sysctl. ++ * ++ * Revision 1.116 2000/09/08 19:18:19 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * Added outgoing opportunistic hook, ifdef'ed out. ++ * ++ * Revision 1.115 2000/08/30 05:27:29 rgb ++ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst. ++ * Kill remainder of tdb_xform, tdb_xdata, xformsw. ++ * ++ * Revision 1.114 2000/08/28 18:15:46 rgb ++ * Added MB's nf-debug reset patch. ++ * ++ * Revision 1.113 2000/08/27 02:26:40 rgb ++ * Send all no-eroute-bypass, pluto-bypass and passthrough packets through ++ * fragmentation machinery for 2.0, 2.2 and 2.4 kernels. ++ * ++ * Revision 1.112 2000/08/20 21:37:33 rgb ++ * Activated pfkey_expire() calls. ++ * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil) ++ * Re-arranged the order of soft and hard expiry to conform to RFC2367. ++ * Clean up references to CONFIG_IPSEC_PFKEYv2. ++ * ++ * Revision 1.111 2000/08/01 14:51:51 rgb ++ * Removed _all_ remaining traces of DES. ++ * ++ * Revision 1.110 2000/07/28 14:58:31 rgb ++ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. ++ * ++ * Revision 1.109 2000/07/28 13:50:54 rgb ++ * Changed enet_statistics to net_device_stats and added back compatibility ++ * for pre-2.1.19. ++ * ++ * Revision 1.108 2000/05/16 03:03:11 rgb ++ * Updates for 2.3.99pre8 from MB. ++ * ++ * Revision 1.107 2000/05/10 23:08:21 rgb ++ * Print a debug warning about bogus packets received by the outgoing ++ * processing machinery only when klipsdebug is not set to none. ++ * Comment out the device initialisation informational messages. ++ * ++ * Revision 1.106 2000/05/10 19:17:14 rgb ++ * Define an IP_SEND macro, intending to have all packet passthroughs ++ * use fragmentation. This didn't quite work, but is a step in the ++ * right direction. ++ * Added buffer allocation debugging statements. ++ * Added configure option to shut off no eroute passthrough. ++ * Only check usetime against soft and hard limits if the tdb has been ++ * used. ++ * Cast output of ntohl so that the broken prototype doesn't make our ++ * compile noisy. ++ * ++ * Revision 1.105 2000/03/22 16:15:37 rgb ++ * Fixed renaming of dev_get (MB). ++ * ++ * Revision 1.104 2000/03/16 14:04:15 rgb ++ * Indented headers for readability. ++ * Fixed debug scope to enable compilation with debug off. ++ * Added macros for ip_chk_addr and IS_MYADDR for identifying self. ++ * ++ * Revision 1.103 2000/03/16 07:11:07 rgb ++ * Hardcode PF_KEYv2 support. ++ * Fixed bug which allowed UDP/500 packet from another machine ++ * through in the clear. ++ * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec. ++ * ++ * Revision 1.102 2000/03/14 12:26:59 rgb ++ * Added skb->nfct support for clearing netfilter conntrack bits (MB). ++ * ++ * Revision 1.101 2000/02/14 21:05:22 rgb ++ * Added MB's netif_queue fix for kernels 2.3.43+. ++ * ++ * Revision 1.100 2000/01/26 10:04:57 rgb ++ * Fixed noisy 2.0 printk arguments. ++ * ++ * Revision 1.99 2000/01/21 06:16:25 rgb ++ * Added sanity checks on skb_push(), skb_pull() to prevent panics. ++ * Switched to AF_ENCAP macro. ++ * Shortened debug output per packet and re-arranging debug_tunnel ++ * bitmap flags, while retaining necessary information to avoid ++ * trampling the kernel print ring buffer. ++ * Reformatted recursion switch code. ++ * Changed all references to tdb_proto to tdb_said.proto for clarity. ++ * ++ * Revision 1.98 2000/01/13 08:09:31 rgb ++ * Shuffled debug_tunnel switches to focus output. ++ * Fixed outgoing recursion bug, limiting to recursing only if the remote ++ * SG changes and if it is valid, ie. not passthrough. ++ * Clarified a number of debug messages. ++ * ++ * Revision 1.97 2000/01/10 16:37:16 rgb ++ * MB support for new ip_select_ident() upon disappearance of ++ * ip_id_count in 2.3.36+. ++ * ++ * Revision 1.96 1999/12/31 14:59:08 rgb ++ * MB fix to use new skb_copy_expand in kernel 2.3.35. ++ * ++ * Revision 1.95 1999/12/29 21:15:44 rgb ++ * Fix tncfg to aliased device bug. ++ * ++ * Revision 1.94 1999/12/22 04:26:06 rgb ++ * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable ++ * debugging by providing external labels to all functions with debugging ++ * turned on. ++ * ++ * Revision 1.93 1999/12/13 13:30:14 rgb ++ * Changed MTU reports and HW address reporting back to debug only. ++ * ++ * Revision 1.92 1999/12/07 18:57:56 rgb ++ * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled. ++ * ++ * Revision 1.91 1999/12/01 22:15:36 rgb ++ * Add checks for LARVAL and DEAD SAs. ++ * Change state of SA from MATURE to DYING when a soft lifetime is ++ * reached and print debug warning. ++ * ++ * Revision 1.90 1999/11/23 23:04:04 rgb ++ * Use provided macro ADDRTOA_BUF instead of hardcoded value. ++ * Sort out pfkey and freeswan headers, putting them in a library path. ++ * ++ * Revision 1.89 1999/11/18 18:50:59 rgb ++ * Changed all device registrations for static linking to ++ * dynamic to reduce the number and size of patches. ++ * ++ * Revision 1.88 1999/11/18 04:09:19 rgb ++ * Replaced all kernel version macros to shorter, readable form. ++ * ++ * Revision 1.87 1999/11/17 15:53:40 rgb ++ * Changed all occurrences of #include "../../../lib/freeswan.h" ++ * to #include which works due to -Ilibfreeswan in the ++ * klips/net/ipsec/Makefile. ++ * ++ * Revision 1.86 1999/10/16 18:25:37 rgb ++ * Moved SA lifetime expiry checks before packet processing. ++ * Expire SA on replay counter rollover. ++ * ++ * Revision 1.85 1999/10/16 04:24:31 rgb ++ * Add stats for time since last packet. ++ * ++ * Revision 1.84 1999/10/16 00:30:47 rgb ++ * Added SA lifetime counting. ++ * ++ * Revision 1.83 1999/10/15 22:15:57 rgb ++ * Clean out cruft. ++ * Add debugging. ++ * ++ * Revision 1.82 1999/10/08 18:26:19 rgb ++ * Fix 2.0.3x outgoing fragmented packet memory leak. ++ * ++ * Revision 1.81 1999/10/05 02:38:54 rgb ++ * Lower the default mtu of virtual devices to 16260. ++ * ++ * Revision 1.80 1999/10/03 18:56:41 rgb ++ * Spinlock support for 2.3.xx. ++ * Don't forget to undo spinlocks on error! ++ * Check for valid eroute before copying the structure. ++ * ++ * Revision 1.79 1999/10/01 15:44:53 rgb ++ * Move spinlock header include to 2.1> scope. ++ * ++ * Revision 1.78 1999/10/01 00:02:43 rgb ++ * Added tdb structure locking. ++ * Added eroute structure locking. ++ * ++ * Revision 1.77 1999/09/30 02:52:29 rgb ++ * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c). ++ * ++ * Revision 1.76 1999/09/25 19:31:27 rgb ++ * Refine MSS hack to affect SYN, but not SYN+ACK packets. ++ * ++ * Revision 1.75 1999/09/24 22:52:38 rgb ++ * Fix two things broken in 2.0.38 by trying to fix network notifiers. ++ * ++ * Revision 1.74 1999/09/24 00:30:37 rgb ++ * Add test for changed source as well as destination to check for ++ * recursion. ++ * ++ * Revision 1.73 1999/09/23 20:52:24 rgb ++ * Add James Morris' MSS hack patch, disabled. ++ * ++ * Revision 1.72 1999/09/23 20:22:40 rgb ++ * Enable, tidy and fix network notifier code. ++ * ++ * Revision 1.71 1999/09/23 18:09:05 rgb ++ * Clean up 2.2.x fragmenting traces. ++ * Disable dev->type switching, forcing ARPHRD_TUNNEL. ++ * ++ * Revision 1.70 1999/09/22 14:14:24 rgb ++ * Add sanity checks for revectored calls to prevent calling a downed I/F. ++ * ++ * Revision 1.69 1999/09/21 15:00:57 rgb ++ * Add Marc Boucher's packet size check. ++ * Flesh out network device notifier code. ++ * ++ * Revision 1.68 1999/09/18 11:39:57 rgb ++ * Start to add (disabled) netdevice notifier code. ++ * ++ * Revision 1.67 1999/09/17 23:44:40 rgb ++ * Add a comment warning potential code hackers to stay away from mac.raw. ++ * ++ * Revision 1.66 1999/09/17 18:04:02 rgb ++ * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB). ++ * Ditch TTL decrement in 2.2 (MB). ++ * ++ * Revision 1.65 1999/09/15 23:15:35 henry ++ * Marc Boucher's PPP fixes ++ * ++ * Revision 1.64 1999/09/07 13:40:53 rgb ++ * Ditch unreliable references to skb->mac.raw. ++ * ++ * Revision 1.63 1999/08/28 11:33:09 rgb ++ * Check for null skb->mac pointer. ++ * ++ * Revision 1.62 1999/08/28 02:02:30 rgb ++ * Add Marc Boucher's fix for properly dealing with skb->sk. ++ * ++ * Revision 1.61 1999/08/27 05:23:05 rgb ++ * Clean up skb->data/raw/nh/h manipulation. ++ * Add Marc Boucher's mods to aid tcpdump. ++ * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand. ++ * Re-order hard_header stripping -- might be able to remove it... ++ * ++ * Revision 1.60 1999/08/26 20:01:02 rgb ++ * Tidy up compiler directives and macros. ++ * Re-enable ICMP for tunnels where inner_dst != outer_dst. ++ * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x. ++ * ++ * Revision 1.59 1999/08/25 15:44:41 rgb ++ * Clean up from 2.2.x instrumenting for compilation under 2.0.36. ++ * ++ * Revision 1.58 1999/08/25 15:00:54 rgb ++ * Add dst cache code for 2.2.xx. ++ * Add sanity check for skb packet header pointers. ++ * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and ++ * *_rebuild_header. ++ * Add neigh_* cache code. ++ * Change dev->type back to ARPHRD_TUNNEL. ++ * ++ * Revision 1.57 1999/08/17 21:50:23 rgb ++ * Fixed minor debug output bugs. ++ * Regrouped error recovery exit code. ++ * Added compiler directives to remove unwanted code and symbols. ++ * Shut off ICMP messages: to be refined to only send ICMP to remote systems. ++ * Add debugging code for output function addresses. ++ * Fix minor bug in (possibly unused) header_cache_bind function. ++ * Add device neighbour caching code. ++ * Change dev->type from ARPHRD_TUNNEL to physdev->type. ++ * ++ * Revision 1.56 1999/08/03 17:22:56 rgb ++ * Debug output clarification using KERN_* macros. Other inactive changes ++ * added. ++ * ++ * Revision 1.55 1999/08/03 16:58:46 rgb ++ * Fix skb_copy_expand size bug. Was getting incorrect size. ++ * ++ * Revision 1.54 1999/07/14 19:32:38 rgb ++ * Fix oversize packet crash and ssh stalling in 2.2.x kernels. ++ * ++ * Revision 1.53 1999/06/10 15:44:02 rgb ++ * Minor reformatting and clean-up. ++ * ++ * Revision 1.52 1999/05/09 03:25:36 rgb ++ * Fix bug introduced by 2.2 quick-and-dirty patch. ++ * ++ * Revision 1.51 1999/05/08 21:24:59 rgb ++ * Add casting to silence the 2.2.x compile. ++ * ++ * Revision 1.50 1999/05/05 22:02:32 rgb ++ * Add a quick and dirty port to 2.2 kernels by Marc Boucher . ++ * ++ * Revision 1.49 1999/04/29 15:18:52 rgb ++ * Change gettdb parameter to a pointer to reduce stack loading and ++ * facilitate parameter sanity checking. ++ * Fix undetected bug that might have tried to access a null pointer. ++ * Eliminate unnessessary usage of tdb_xform member to further switch ++ * away from the transform switch to the algorithm switch. ++ * Add return values to init and cleanup functions. ++ * ++ * Revision 1.48 1999/04/16 15:38:00 rgb ++ * Minor rearrangement of freeing code to avoid memory leaks with impossible or ++ * rare situations. ++ * ++ * Revision 1.47 1999/04/15 15:37:25 rgb ++ * Forward check changes from POST1_00 branch. ++ * ++ * Revision 1.32.2.4 1999/04/13 21:00:18 rgb ++ * Ditch 'things I wish I had known before...'. ++ * ++ * Revision 1.32.2.3 1999/04/13 20:34:38 rgb ++ * Free skb after fragmentation. ++ * Use stats more effectively. ++ * Add I/F to mtu notch-down reporting. ++ * ++ * Revision 1.32.2.2 1999/04/02 04:26:14 rgb ++ * Backcheck from HEAD, pre1.0. ++ * ++ * Revision 1.46 1999/04/11 00:29:00 henry ++ * GPL boilerplate ++ * ++ * Revision 1.45 1999/04/07 15:42:01 rgb ++ * Fix mtu/ping bug AGAIN! ++ * ++ * Revision 1.44 1999/04/06 04:54:27 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.43 1999/04/04 03:57:07 rgb ++ * ip_fragment() doesn't free the supplied skb. Freed. ++ * ++ * Revision 1.42 1999/04/01 23:27:15 rgb ++ * Preload size of virtual mtu. ++ * ++ * Revision 1.41 1999/04/01 09:31:23 rgb ++ * Invert meaning of ICMP PMTUD config option and clarify. ++ * Code clean-up. ++ * ++ * Revision 1.40 1999/04/01 04:37:17 rgb ++ * SSH stalling bug fix. ++ * ++ * Revision 1.39 1999/03/31 23:44:28 rgb ++ * Don't send ICMP on DF and frag_off. ++ * ++ * Revision 1.38 1999/03/31 15:20:10 rgb ++ * Quiet down debugging. ++ * ++ * Revision 1.37 1999/03/31 08:30:31 rgb ++ * Add switch to shut off ICMP PMTUD packets. ++ * ++ * Revision 1.36 1999/03/31 05:44:47 rgb ++ * Keep PMTU reduction private. ++ * ++ * Revision 1.35 1999/03/27 15:13:02 rgb ++ * PMTU/fragmentation bug fix. ++ * ++ * Revision 1.34 1999/03/17 21:19:26 rgb ++ * Fix kmalloc nonatomic bug. ++ * ++ * Revision 1.33 1999/03/17 15:38:42 rgb ++ * Code clean-up. ++ * ESP_NULL IV bug fix. ++ * ++ * Revision 1.32 1999/03/01 20:44:25 rgb ++ * Code clean-up. ++ * Memory leak bug fix. ++ * ++ * Revision 1.31 1999/02/27 00:02:09 rgb ++ * Tune to report the MTU reduction once, rather than after every recursion ++ * through the encapsulating code, preventing tcp stream stalling. ++ * ++ * Revision 1.30 1999/02/24 20:21:01 rgb ++ * Reformat debug printk's. ++ * Fix recursive encapsulation, dynamic MTU bugs and add debugging code. ++ * Clean-up. ++ * ++ * Revision 1.29 1999/02/22 17:08:14 rgb ++ * Fix recursive encapsulation code. ++ * ++ * Revision 1.28 1999/02/19 18:27:02 rgb ++ * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery. ++ * ++ * Revision 1.27 1999/02/17 16:51:37 rgb ++ * Clean out unused cruft. ++ * Temporarily tone down volume of debug output. ++ * Temporarily shut off fragment rejection. ++ * Disabled temporary failed recursive encapsulation loop. ++ * ++ * Revision 1.26 1999/02/12 21:21:26 rgb ++ * Move KLIPS_PRINT to ipsec_netlink.h for accessibility. ++ * ++ * Revision 1.25 1999/02/11 19:38:27 rgb ++ * More clean-up. ++ * Add sanity checking for skb_copy_expand() to prevent kernel panics on ++ * skb_put() values out of range. ++ * Fix head/tailroom calculation causing skb_put() out-of-range values. ++ * Fix return values to prevent 'nonatomic alloc_skb' warnings. ++ * Allocate new skb iff needed. ++ * Added more debug statements. ++ * Make headroom depend on structure, not hard-coded values. ++ * ++ * Revision 1.24 1999/02/10 23:20:33 rgb ++ * Shut up annoying 'statement has no effect' compiler warnings with ++ * debugging compiled out. ++ * ++ * Revision 1.23 1999/02/10 22:36:30 rgb ++ * Clean-up obsolete, unused and messy code. ++ * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros. ++ * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated ++ * original ipsec_tunnel_start_xmit. ++ * Send all packet with different inner and outer destinations directly to ++ * the attached physical device, rather than back through ip_forward, ++ * preventing disappearing routes problems. ++ * Do sanity checking before investing too much CPU in allocating new ++ * structures. ++ * Fail on IP header options: We cannot process them yet. ++ * Add some helpful comments. ++ * Use virtual device for parameters instead of physical device. ++ * ++ * Revision 1.22 1999/02/10 03:03:02 rgb ++ * Duh. Fixed the TTL bug: forgot to update the checksum. ++ * ++ * Revision 1.21 1999/02/09 23:17:53 rgb ++ * Add structure members to ipsec_print_ip debug function. ++ * Temporarily fix TTL bug preventing tunnel mode from functioning. ++ * ++ * Revision 1.20 1999/02/09 00:14:25 rgb ++ * Add KLIPSPRINT macro. (Not used yet, though.) ++ * Delete old ip_tunnel code (BADCODE). ++ * Decrement TTL in outgoing packet. ++ * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL. ++ * Delete ethernet only feature and fix hard-coded hard_header_len. ++ * ++ * Revision 1.19 1999/01/29 17:56:22 rgb ++ * 64-bit re-fix submitted by Peter Onion. ++ * ++ * Revision 1.18 1999/01/28 22:43:24 rgb ++ * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion. ++ * ++ * Revision 1.17 1999/01/26 02:08:16 rgb ++ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. ++ * Removed dead code. ++ * ++ * Revision 1.16 1999/01/22 06:25:26 rgb ++ * Cruft clean-out. ++ * Added algorithm switch code. ++ * 64-bit clean-up. ++ * Passthrough on IPIP protocol, spi 0x0 fix. ++ * Enhanced debugging. ++ * ++ * Revision 1.15 1998/12/01 13:22:04 rgb ++ * Added support for debug printing of version info. ++ * ++ * Revision 1.14 1998/11/30 13:22:55 rgb ++ * Rationalised all the klips kernel file headers. They are much shorter ++ * now and won't conflict under RH5.2. ++ * ++ * Revision 1.13 1998/11/17 21:13:52 rgb ++ * Put IKE port bypass debug output in user-switched debug statements. ++ * ++ * Revision 1.12 1998/11/13 13:20:25 rgb ++ * Fixed ntohs bug in udp/500 hole for IKE. ++ * ++ * Revision 1.11 1998/11/10 08:01:19 rgb ++ * Kill tcp/500 hole, keep udp/500 hole. ++ * ++ * Revision 1.10 1998/11/09 21:29:26 rgb ++ * If no eroute is found, discard packet and incr. tx_error. ++ * ++ * Revision 1.9 1998/10/31 06:50:00 rgb ++ * Add tcp/udp/500 bypass. ++ * Fixed up comments in #endif directives. ++ * ++ * Revision 1.8 1998/10/27 00:34:31 rgb ++ * Reformat debug output of IP headers. ++ * Newlines added before calls to ipsec_print_ip. ++ * ++ * Revision 1.7 1998/10/19 14:44:28 rgb ++ * Added inclusion of freeswan.h. ++ * sa_id structure implemented and used: now includes protocol. ++ * ++ * Revision 1.6 1998/10/09 04:31:35 rgb ++ * Added 'klips_debug' prefix to all klips printk debug statements. ++ * ++ * Revision 1.5 1998/08/28 03:09:51 rgb ++ * Prevent kernel log spam with default route through ipsec. ++ * ++ * Revision 1.4 1998/08/05 22:23:09 rgb ++ * Change setdev return code to ENXIO for a non-existant physical device. ++ * ++ * Revision 1.3 1998/07/29 20:41:11 rgb ++ * Add ipsec_tunnel_clear to clear all tunnel attachments. ++ * ++ * Revision 1.2 1998/06/25 20:00:33 rgb ++ * Clean up #endif comments. ++ * Rename dev_ipsec to dev_ipsec0 for consistency. ++ * Document ipsec device fields. ++ * Make ipsec_tunnel_probe visible from rest of kernel for static linking. ++ * Get debugging report for *every* ipsec device initialisation. ++ * Comment out redundant code. ++ * ++ * Revision 1.1 1998/06/18 21:27:50 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid ++ * kernel-build scripts happier in the presence of symlinks ++ * ++ * Revision 1.8 1998/06/14 23:49:40 rgb ++ * Clarify version reporting on module loading. ++ * ++ * Revision 1.7 1998/05/27 23:19:20 rgb ++ * Added version reporting. ++ * ++ * Revision 1.6 1998/05/18 21:56:23 rgb ++ * Clean up for numerical consistency of output and cleaning up debug code. ++ * ++ * Revision 1.5 1998/05/12 02:44:23 rgb ++ * Clarifying 'no e-route to host' message. ++ * ++ * Revision 1.4 1998/04/30 15:34:35 rgb ++ * Enclosed most remaining debugging statements in #ifdef's to make it quieter. ++ * ++ * Revision 1.3 1998/04/21 21:28:54 rgb ++ * Rearrange debug switches to change on the fly debug output from user ++ * space. Only kernel changes checked in at this time. radij.c was also ++ * changed to temporarily remove buggy debugging code in rj_delete causing ++ * an OOPS and hence, netlink device open errors. ++ * ++ * Revision 1.2 1998/04/12 22:03:24 rgb ++ * Updated ESP-3DES-HMAC-MD5-96, ++ * ESP-DES-HMAC-MD5-96, ++ * AH-HMAC-MD5-96, ++ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository ++ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. ++ * ++ * Fixed eroute references in /proc/net/ipsec*. ++ * ++ * Started to patch module unloading memory leaks in ipsec_netlink and ++ * radij tree unloading. ++ * ++ * Revision 1.1 1998/04/09 03:06:12 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:04 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.5 1997/06/03 04:24:48 ji ++ * Added transport mode. ++ * Changed the way routing is done. ++ * Lots of bug fixes. ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * No changes. ++ * ++ * Revision 0.3 1996/11/20 14:39:04 ji ++ * Minor cleanups. ++ * Rationalized debugging code. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * Local Variables: ++ * c-style: linux ++ * End: ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_xform.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,351 @@ ++/* ++ * Common routines for IPSEC transformations. ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: ipsec_xform.c,v 1.63 2003/10/31 02:27:55 mcr Exp $ ++ */ ++ ++#include ++#include ++#include /* printk() */ ++ ++#include "freeswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include ++#include /* get_random_bytes() */ ++#include ++#ifdef SPINLOCK ++# ifdef SPINLOCK_23 ++# include /* *lock* */ ++# else /* SPINLOCK_23 */ ++# include /* *lock* */ ++# endif /* SPINLOCK_23 */ ++#endif /* SPINLOCK */ ++#ifdef NET_21 ++# include ++# include ++#endif ++#include ++#include ++ ++#include "freeswan/radij.h" ++#include "freeswan/ipsec_encap.h" ++#include "freeswan/ipsec_radij.h" ++#include "freeswan/ipsec_xform.h" ++#include "freeswan/ipsec_ipe4.h" ++#include "freeswan/ipsec_ah.h" ++#include "freeswan/ipsec_esp.h" ++ ++#include ++#include ++ ++#ifdef CONFIG_IPSEC_DEBUG ++int debug_xform = 0; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++#ifdef SPINLOCK ++spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED; ++#else /* SPINLOCK */ ++spinlock_t tdb_lock; ++#endif /* SPINLOCK */ ++ ++/* ++ * $Log: ipsec_xform.c,v $ ++ * Revision 1.63 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.62.30.1 2003/10/29 01:30:41 mcr ++ * elimited "struct sa_id". ++ * ++ * Revision 1.62 2002/05/14 02:34:21 rgb ++ * Delete stale code. ++ * ++ * Revision 1.61 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.60 2002/04/24 07:36:33 mcr ++ * Moved from ./klips/net/ipsec/ipsec_xform.c,v ++ * ++ * Revision 1.59 2002/03/29 15:01:36 rgb ++ * Delete decommissioned code. ++ * ++ * Revision 1.58 2002/01/29 17:17:57 mcr ++ * moved include of ipsec_param.h to after include of linux/kernel.h ++ * otherwise, it seems that some option that is set in ipsec_param.h ++ * screws up something subtle in the include path to kernel.h, and ++ * it complains on the snprintf() prototype. ++ * ++ * Revision 1.57 2002/01/29 04:00:53 mcr ++ * more excise of kversions.h header. ++ * ++ * Revision 1.56 2001/11/27 05:17:22 mcr ++ * turn off the worst of the per-packet debugging. ++ * ++ * Revision 1.55 2001/11/26 09:23:50 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.54 2001/10/18 04:45:21 rgb ++ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, ++ * lib/freeswan.h version macros moved to lib/kversions.h. ++ * Other compiler directive cleanups. ++ * ++ * Revision 1.53 2001/09/08 21:13:34 rgb ++ * Added pfkey ident extension support for ISAKMPd. (NetCelo) ++ * ++ * Revision 1.52 2001/06/14 19:35:11 rgb ++ * Update copyright date. ++ * ++ * Revision 1.51 2001/05/30 08:14:03 rgb ++ * Removed vestiges of esp-null transforms. ++ * ++ * Revision 1.50 2001/05/03 19:43:18 rgb ++ * Initialise error return variable. ++ * Update SENDERR macro. ++ * Fix sign of error return code for ipsec_tdbcleanup(). ++ * Use more appropriate return code for ipsec_tdbwipe(). ++ * ++ * Revision 1.49 2001/04/19 18:56:17 rgb ++ * Fixed tdb table locking comments. ++ * ++ * Revision 1.48 2001/02/27 22:24:55 rgb ++ * Re-formatting debug output (line-splitting, joining, 1arg/line). ++ * Check for satoa() return codes. ++ * ++ * Revision 1.47 2000/11/06 04:32:08 rgb ++ * Ditched spin_lock_irqsave in favour of spin_lock_bh. ++ * ++ * Revision 1.46 2000/09/20 16:21:57 rgb ++ * Cleaned up ident string alloc/free. ++ * ++ * Revision 1.45 2000/09/08 19:16:51 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * Removed all references to CONFIG_IPSEC_PFKEYv2. ++ * ++ * Revision 1.44 2000/08/30 05:29:04 rgb ++ * Compiler-define out no longer used tdb_init() in ipsec_xform.c. ++ * ++ * Revision 1.43 2000/08/18 21:30:41 rgb ++ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear. ++ * ++ * Revision 1.42 2000/08/01 14:51:51 rgb ++ * Removed _all_ remaining traces of DES. ++ * ++ * Revision 1.41 2000/07/28 14:58:31 rgb ++ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. ++ * ++ * Revision 1.40 2000/06/28 05:50:11 rgb ++ * Actually set iv_bits. ++ * ++ * Revision 1.39 2000/05/10 23:11:09 rgb ++ * Added netlink debugging output. ++ * Added a cast to quiet down the ntohl bug. ++ * ++ * Revision 1.38 2000/05/10 19:18:42 rgb ++ * Cast output of ntohl so that the broken prototype doesn't make our ++ * compile noisy. ++ * ++ * Revision 1.37 2000/03/16 14:04:59 rgb ++ * Hardwired CONFIG_IPSEC_PFKEYv2 on. ++ * ++ * Revision 1.36 2000/01/26 10:11:28 rgb ++ * Fixed spacing in error text causing run-in words. ++ * ++ * Revision 1.35 2000/01/21 06:17:16 rgb ++ * Tidied up compiler directive indentation for readability. ++ * Added ictx,octx vars for simplification.(kravietz) ++ * Added macros for HMAC padding magic numbers.(kravietz) ++ * Fixed missing key length reporting bug. ++ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in. ++ * ++ * Revision 1.34 1999/12/08 00:04:19 rgb ++ * Fixed SA direction overwriting bug for netlink users. ++ * ++ * Revision 1.33 1999/12/01 22:16:44 rgb ++ * Minor formatting changes in ESP MD5 initialisation. ++ * ++ * Revision 1.32 1999/11/25 09:06:36 rgb ++ * Fixed error return messages, should be returning negative numbers. ++ * Implemented SENDERR macro for propagating error codes. ++ * Added debug message and separate error code for algorithms not compiled ++ * in. ++ * ++ * Revision 1.31 1999/11/23 23:06:26 rgb ++ * Sort out pfkey and freeswan headers, putting them in a library path. ++ * ++ * Revision 1.30 1999/11/18 04:09:20 rgb ++ * Replaced all kernel version macros to shorter, readable form. ++ * ++ * Revision 1.29 1999/11/17 15:53:40 rgb ++ * Changed all occurrences of #include "../../../lib/freeswan.h" ++ * to #include which works due to -Ilibfreeswan in the ++ * klips/net/ipsec/Makefile. ++ * ++ * Revision 1.28 1999/10/18 20:04:01 rgb ++ * Clean-out unused cruft. ++ * ++ * Revision 1.27 1999/10/03 19:01:03 rgb ++ * Spinlock support for 2.3.xx and 2.0.xx kernels. ++ * ++ * Revision 1.26 1999/10/01 16:22:24 rgb ++ * Switch from assignment init. to functional init. of spinlocks. ++ * ++ * Revision 1.25 1999/10/01 15:44:54 rgb ++ * Move spinlock header include to 2.1> scope. ++ * ++ * Revision 1.24 1999/10/01 00:03:46 rgb ++ * Added tdb structure locking. ++ * Minor formatting changes. ++ * Add function to initialize tdb hash table. ++ * ++ * Revision 1.23 1999/05/25 22:42:12 rgb ++ * Add deltdbchain() debugging. ++ * ++ * Revision 1.22 1999/05/25 21:24:31 rgb ++ * Add debugging statements to deltdbchain(). ++ * ++ * Revision 1.21 1999/05/25 03:51:48 rgb ++ * Refix error return code. ++ * ++ * Revision 1.20 1999/05/25 03:34:07 rgb ++ * Fix error return for flush. ++ * ++ * Revision 1.19 1999/05/09 03:25:37 rgb ++ * Fix bug introduced by 2.2 quick-and-dirty patch. ++ * ++ * Revision 1.18 1999/05/05 22:02:32 rgb ++ * Add a quick and dirty port to 2.2 kernels by Marc Boucher . ++ * ++ * Revision 1.17 1999/04/29 15:20:16 rgb ++ * Change gettdb parameter to a pointer to reduce stack loading and ++ * facilitate parameter sanity checking. ++ * Add sanity checking for null pointer arguments. ++ * Add debugging instrumentation. ++ * Add function deltdbchain() which will take care of unlinking, ++ * zeroing and deleting a chain of tdbs. ++ * Add a parameter to tdbcleanup to be able to delete a class of SAs. ++ * tdbwipe now actually zeroes the tdb as well as any of its pointed ++ * structures. ++ * ++ * Revision 1.16 1999/04/16 15:36:29 rgb ++ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing. ++ * ++ * Revision 1.15 1999/04/11 00:29:01 henry ++ * GPL boilerplate ++ * ++ * Revision 1.14 1999/04/06 04:54:28 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.13 1999/02/19 18:23:01 rgb ++ * Nix debug off compile warning. ++ * ++ * Revision 1.12 1999/02/17 16:52:16 rgb ++ * Consolidate satoa()s for space and speed efficiency. ++ * Convert DEBUG_IPSEC to KLIPS_PRINT ++ * Clean out unused cruft. ++ * Ditch NET_IPIP dependancy. ++ * Loop for 3des key setting. ++ * ++ * Revision 1.11 1999/01/26 02:09:05 rgb ++ * Remove ah/esp/IPIP switching on include files. ++ * Removed CONFIG_IPSEC_ALGO_SWITCH macro. ++ * Removed dead code. ++ * Clean up debug code when switched off. ++ * Remove references to INET_GET_PROTOCOL. ++ * Added code exclusion macros to reduce code from unused algorithms. ++ * ++ * Revision 1.10 1999/01/22 06:28:55 rgb ++ * Cruft clean-out. ++ * Put random IV generation in kernel. ++ * Added algorithm switch code. ++ * Enhanced debugging. ++ * 64-bit clean-up. ++ * ++ * Revision 1.9 1998/11/30 13:22:55 rgb ++ * Rationalised all the klips kernel file headers. They are much shorter ++ * now and won't conflict under RH5.2. ++ * ++ * Revision 1.8 1998/11/25 04:59:06 rgb ++ * Add conditionals for no IPIP tunnel code. ++ * Delete commented out code. ++ * ++ * Revision 1.7 1998/10/31 06:50:41 rgb ++ * Convert xform ASCII names to no spaces. ++ * Fixed up comments in #endif directives. ++ * ++ * Revision 1.6 1998/10/19 14:44:28 rgb ++ * Added inclusion of freeswan.h. ++ * sa_id structure implemented and used: now includes protocol. ++ * ++ * Revision 1.5 1998/10/09 04:32:19 rgb ++ * Added 'klips_debug' prefix to all klips printk debug statements. ++ * ++ * Revision 1.4 1998/08/12 00:11:31 rgb ++ * Added new xform functions to the xform table. ++ * Fixed minor debug output spelling error. ++ * ++ * Revision 1.3 1998/07/09 17:45:31 rgb ++ * Clarify algorithm not available message. ++ * ++ * Revision 1.2 1998/06/23 03:00:51 rgb ++ * Check for presence of IPIP protocol if it is setup one way (we don't ++ * know what has been set up the other way and can only assume it will be ++ * symmetrical with the exception of keys). ++ * ++ * Revision 1.1 1998/06/18 21:27:51 henry ++ * move sources from klips/src to klips/net/ipsec, to keep stupid ++ * kernel-build scripts happier in the presence of symlinks ++ * ++ * Revision 1.3 1998/06/11 05:54:59 rgb ++ * Added transform version string pointer to xformsw initialisations. ++ * ++ * Revision 1.2 1998/04/21 21:28:57 rgb ++ * Rearrange debug switches to change on the fly debug output from user ++ * space. Only kernel changes checked in at this time. radij.c was also ++ * changed to temporarily remove buggy debugging code in rj_delete causing ++ * an OOPS and hence, netlink device open errors. ++ * ++ * Revision 1.1 1998/04/09 03:06:13 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:02 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.5 1997/06/03 04:24:48 ji ++ * Added ESP-3DES-MD5-96 ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * Added new transforms. ++ * ++ * Revision 0.3 1996/11/20 14:39:04 ji ++ * Minor cleanups. ++ * Rationalized debugging code. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/ipsec_xmit.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,1869 @@ ++/* ++ * IPSEC Transmit code. ++ * Copyright (C) 1996, 1997 John Ioannidis. ++ * Copyright (C) 1998-2003 Richard Guy Briggs. ++ * Copyright (C) 2004 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ */ ++ ++char ipsec_xmit_c_version[] = "RCSID $Id: ipsec_xmit.c,v 1.8 2004/04/06 02:49:26 mcr Exp $"; ++ ++#define __NO_VERSION__ ++#include ++#include /* for CONFIG_IP_FORWARD */ ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include /* struct tcphdr */ ++#include /* struct udphdr */ ++#include ++#include ++#ifdef NET_21 ++# define MSS_HACK_ /* experimental */ ++# include ++# include ++# include ++# define proto_priv cb ++#endif /* NET_21 */ ++#include ++#include /* icmp_send() */ ++#include ++#ifdef NETDEV_23 ++# include ++#endif /* NETDEV_23 */ ++ ++#include ++#ifdef MSS_HACK ++# include /* TCP options */ ++#endif /* MSS_HACK */ ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_life.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_eroute.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_xmit.h" ++#include "openswan/ipsec_sa.h" ++#include "openswan/ipsec_tunnel.h" ++#include "openswan/ipsec_ipe4.h" ++#include "openswan/ipsec_ah.h" ++#include "openswan/ipsec_esp.h" ++ ++#ifdef CONFIG_IPSEC_IPCOMP ++#include "openswan/ipcomp.h" ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ ++#include ++#include ++ ++#include "openswan/ipsec_proto.h" ++#include "openswan/ipsec_alg.h" ++ ++ ++/* ++ * Stupid kernel API differences in APIs. Not only do some ++ * kernels not have ip_select_ident, but some have differing APIs, ++ * and SuSE has one with one parameter, but no way of checking to ++ * see what is really what. ++ */ ++ ++#ifdef SUSE_LINUX_2_4_19_IS_STUPID ++#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph) ++#else ++ ++/* simplest case, nothing */ ++#if !defined(IP_SELECT_IDENT) ++#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0) ++#endif ++ ++/* kernels > 2.3.37-ish */ ++#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW) ++#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst) ++#endif ++ ++/* kernels > 2.4.2 */ ++#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW) ++#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL) ++#endif ++ ++#endif /* SUSE_LINUX_2_4_19_IS_STUPID */ ++ ++ ++static __u32 zeroes[64]; ++ ++#ifdef CONFIG_IPSEC_DEBUG ++int sysctl_ipsec_debug_verbose = 0; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++int ipsec_xmit_trap_count = 0; ++int ipsec_xmit_trap_sendcount = 0; ++ ++int sysctl_ipsec_icmp = 0; ++int sysctl_ipsec_tos = 0; ++ ++#ifdef CONFIG_IPSEC_DEBUG_ ++DEBUG_NO_STATIC void ++dmp(char *s, caddr_t bb, int len) ++{ ++ int i; ++ unsigned char *b = bb; ++ ++ if (debug_tunnel) { ++ printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: " ++ "at %s, len=%d:", ++ s, ++ len); ++ for (i=0; i < len; i++) { ++ if(!(i%16)){ ++ printk("\nklips_debug: "); ++ } ++ printk(" %02x", *b++); ++ } ++ printk("\n"); ++ } ++} ++#else /* CONFIG_IPSEC_DEBUG */ ++#define dmp(_x, _y, _z) ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++#ifndef SKB_COPY_EXPAND ++/* ++ * This is mostly skbuff.c:skb_copy(). ++ */ ++struct sk_buff * ++skb_copy_expand(struct sk_buff *skb, int headroom, int tailroom, int priority) ++{ ++ struct sk_buff *n; ++ unsigned long offset; ++ ++ /* ++ * Do sanity checking ++ */ ++ if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) { ++ printk(KERN_WARNING ++ "klips_error:skb_copy_expand: " ++ "Illegal negative head,tailroom %d,%d\n", ++ headroom, ++ tailroom); ++ return NULL; ++ } ++ /* ++ * Allocate the copy buffer ++ */ ++ ++#ifndef NET_21 ++ IS_SKB(skb); ++#endif /* !NET_21 */ ++ ++ ++ n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority); ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:skb_copy_expand: " ++ "allocating %d bytes, head=0p%p data=0p%p tail=0p%p end=0p%p end-head=%d tail-data=%d\n", ++ skb->end - skb->head + headroom + tailroom, ++ skb->head, ++ skb->data, ++ skb->tail, ++ skb->end, ++ skb->end - skb->head, ++ skb->tail - skb->data); ++ ++ if(n==NULL) ++ return NULL; ++ ++ /* ++ * Shift between the two data areas in bytes ++ */ ++ ++ /* Set the data pointer */ ++ skb_reserve(n,skb->data-skb->head+headroom); ++ /* Set the tail pointer and length */ ++ if(skb_tailroom(n) < skb->len) { ++ printk(KERN_WARNING "klips_error:skb_copy_expand: " ++ "tried to skb_put %ld, %d available. This should never happen, please report.\n", ++ (unsigned long int)skb->len, ++ skb_tailroom(n)); ++ ipsec_kfree_skb(n); ++ return NULL; ++ } ++ skb_put(n,skb->len); ++ ++ offset=n->head + headroom - skb->head; ++ ++ /* Copy the bytes */ ++ memcpy(n->head + headroom, skb->head,skb->end-skb->head); ++#ifdef NET_21 ++ n->csum=skb->csum; ++ n->priority=skb->priority; ++ n->dst=dst_clone(skb->dst); ++ if(skb->nh.raw) ++ n->nh.raw=skb->nh.raw+offset; ++#ifndef NETDEV_23 ++ n->is_clone=0; ++#endif /* NETDEV_23 */ ++ atomic_set(&n->users, 1); ++ n->destructor = NULL; ++ n->security=skb->security; ++#else /* NET_21 */ ++ n->link3=NULL; ++ n->when=skb->when; ++ if(skb->ip_hdr) ++ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset); ++ n->saddr=skb->saddr; ++ n->daddr=skb->daddr; ++ n->raddr=skb->raddr; ++ n->seq=skb->seq; ++ n->end_seq=skb->end_seq; ++ n->ack_seq=skb->ack_seq; ++ n->acked=skb->acked; ++ n->free=1; ++ n->arp=skb->arp; ++ n->tries=0; ++ n->lock=0; ++ n->users=0; ++#endif /* NET_21 */ ++ n->protocol=skb->protocol; ++ n->list=NULL; ++ n->sk=NULL; ++ n->dev=skb->dev; ++ if(skb->h.raw) ++ n->h.raw=skb->h.raw+offset; ++ if(skb->mac.raw) ++ n->mac.raw=skb->mac.raw+offset; ++ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv)); ++#ifndef NETDEV_23 ++ n->used=skb->used; ++#endif /* !NETDEV_23 */ ++ n->pkt_type=skb->pkt_type; ++ n->stamp=skb->stamp; ++ ++#ifndef NET_21 ++ IS_SKB(n); ++#endif /* !NET_21 */ ++ return n; ++} ++#endif /* !SKB_COPY_EXPAND */ ++ ++#ifdef CONFIG_IPSEC_DEBUG ++void ++ipsec_print_ip(struct iphdr *ip) ++{ ++ char buf[ADDRTOA_BUF]; ++ ++ printk(KERN_INFO "klips_debug: IP:"); ++ printk(" ihl:%d", ip->ihl << 2); ++ printk(" ver:%d", ip->version); ++ printk(" tos:%d", ip->tos); ++ printk(" tlen:%d", ntohs(ip->tot_len)); ++ printk(" id:%d", ntohs(ip->id)); ++ printk(" %s%s%sfrag_off:%d", ++ ip->frag_off & __constant_htons(IP_CE) ? "CE " : "", ++ ip->frag_off & __constant_htons(IP_DF) ? "DF " : "", ++ ip->frag_off & __constant_htons(IP_MF) ? "MF " : "", ++ (ntohs(ip->frag_off) & IP_OFFSET) << 3); ++ printk(" ttl:%d", ip->ttl); ++ printk(" proto:%d", ip->protocol); ++ if(ip->protocol == IPPROTO_UDP) ++ printk(" (UDP)"); ++ if(ip->protocol == IPPROTO_TCP) ++ printk(" (TCP)"); ++ if(ip->protocol == IPPROTO_ICMP) ++ printk(" (ICMP)"); ++ printk(" chk:%d", ntohs(ip->check)); ++ addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf)); ++ printk(" saddr:%s", buf); ++ if(ip->protocol == IPPROTO_UDP) ++ printk(":%d", ++ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source)); ++ if(ip->protocol == IPPROTO_TCP) ++ printk(":%d", ++ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source)); ++ addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf)); ++ printk(" daddr:%s", buf); ++ if(ip->protocol == IPPROTO_UDP) ++ printk(":%d", ++ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest)); ++ if(ip->protocol == IPPROTO_TCP) ++ printk(":%d", ++ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest)); ++ if(ip->protocol == IPPROTO_ICMP) ++ printk(" type:code=%d:%d", ++ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type, ++ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code); ++ printk("\n"); ++ ++ if(sysctl_ipsec_debug_verbose) { ++ __u8 *c; ++ int i; ++ ++ c = ((__u8*)ip) + ip->ihl*4; ++ for(i = 0; i < ntohs(ip->tot_len) - ip->ihl*4; i++ /*, c++*/) { ++ if(!(i % 16)) { ++ printk(KERN_INFO ++ "klips_debug: @%03x:", ++ i); ++ } ++ printk(" %02x", /***/c[i]); ++ if(!((i + 1) % 16)) { ++ printk("\n"); ++ } ++ } ++ if(i % 16) { ++ printk("\n"); ++ } ++ } ++} ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++#ifdef MSS_HACK ++/* ++ * Issues: ++ * 1) Fragments arriving in the tunnel should probably be rejected. ++ * 2) How does this affect syncookies, mss_cache, dst cache ? ++ * 3) Path MTU discovery handling needs to be reviewed. For example, ++ * if we receive an ICMP 'packet too big' message from an intermediate ++ * router specifying it's next hop MTU, our stack may process this and ++ * adjust the MSS without taking our AH/ESP overheads into account. ++ */ ++ ++ ++/* ++ * Recaclulate checksum using differences between changed datum, ++ * borrowed from netfilter. ++ */ ++DEBUG_NO_STATIC u_int16_t ++ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck) ++{ ++ u_int32_t diffs[] = { oldvalinv, newval }; ++ return csum_fold(csum_partial((char *)diffs, sizeof(diffs), ++ oldcheck^0xFFFF)); ++} ++ ++/* ++ * Determine effective MSS. ++ * ++ * Note that we assume that there is always an MSS option for our own ++ * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x. ++ * This could change, and we should probably parse TCP options instead. ++ * ++ */ ++DEBUG_NO_STATIC u_int8_t ++ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu) ++{ ++ u_int16_t oldmss, newmss; ++ u_int32_t *mssp; ++ struct sock *sk = skb->sk; ++ ++ newmss = tcp_sync_mss(sk, mtu); ++ printk(KERN_INFO "klips: setting mss to %u\n", newmss); ++ mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t); ++ oldmss = ntohl(*mssp) & 0x0000FFFF; ++ *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss); ++ tcph->check = ipsec_fast_csum(htons(~oldmss), ++ htons(newmss), tcph->check); ++ return 1; ++} ++#endif /* MSS_HACK */ ++ ++/* ++ * Sanity checks ++ */ ++enum ipsec_xmit_value ++ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs) ++{ ++ ++ if (ixs->dev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_error:ipsec_xmit_sanity_check_dev: " ++ "No device associated with skb!\n" ); ++ return IPSEC_XMIT_NODEV; ++ } ++ ++ ixs->prv = ixs->dev->priv; ++ if (ixs->prv == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_error:ipsec_xmit_sanity_check_dev: " ++ "Device has no private structure!\n" ); ++ return IPSEC_XMIT_NOPRIVDEV; ++ } ++ ++ ixs->physdev = ixs->prv->dev; ++ if (ixs->physdev == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_error:ipsec_xmit_sanity_check_dev: " ++ "Device is not attached to physical device!\n" ); ++ return IPSEC_XMIT_NOPHYSDEV; ++ } ++ ++ ixs->physmtu = ixs->physdev->mtu; ++ ++ ixs->stats = (struct net_device_stats *) &(ixs->prv->mystats); ++ ++ return IPSEC_XMIT_OK; ++} ++ ++enum ipsec_xmit_value ++ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs) ++{ ++ /* ++ * Return if there is nothing to do. (Does this ever happen?) XXX ++ */ ++ if (ixs->skb == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_error:ipsec_xmit_sanity_check_skb: " ++ "Nothing to do!\n" ); ++ return IPSEC_XMIT_NOSKB; ++ } ++#ifdef NET_21 ++ /* if skb was cloned (most likely due to a packet sniffer such as ++ tcpdump being momentarily attached to the interface), make ++ a copy of our own to modify */ ++ if(skb_cloned(ixs->skb)) { ++ if ++#ifdef SKB_COW_NEW ++ (skb_cow(ixs->skb, skb_headroom(ixs->skb)) != 0) ++#else /* SKB_COW_NEW */ ++ ((ixs->skb = skb_cow(ixs->skb, skb_headroom(ixs->skb))) == NULL) ++#endif /* SKB_COW_NEW */ ++ { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_error:ipsec_xmit_sanity_check_skb: " ++ "skb_cow failed to allocate buffer, dropping.\n" ); ++ ixs->stats->tx_dropped++; ++ return IPSEC_XMIT_ERRSKBALLOC; ++ } ++ } ++#endif /* NET_21 */ ++ ++#ifdef NET_21 ++ ixs->iph = ixs->skb->nh.iph; ++#else /* NET_21 */ ++ ixs->iph = ixs->skb->ip_hdr; ++#endif /* NET_21 */ ++ ++ /* sanity check for IP version as we can't handle IPv6 right now */ ++ if (ixs->iph->version != 4) { ++ KLIPS_PRINT(debug_tunnel, ++ "klips_debug:ipsec_xmit_sanity_check_skb: " ++ "found IP Version %d but cannot process other IP versions than v4.\n", ++ ixs->iph->version); /* XXX */ ++ ixs->stats->tx_dropped++; ++ return IPSEC_XMIT_NOIPV6; ++ } ++ ++#if IPSEC_DISALLOW_IPOPTIONS ++ if ((ixs->iph->ihl << 2) != sizeof (struct iphdr)) { ++ KLIPS_PRINT(debug_tunnel, ++ "klips_debug:ipsec_xmit_sanity_check_skb: " ++ "cannot process IP header options yet. May be mal-formed packet.\n"); /* XXX */ ++ ixs->stats->tx_dropped++; ++ return IPSEC_XMIT_NOIPOPTIONS; ++ } ++#endif /* IPSEC_DISALLOW_IPOPTIONS */ ++ ++#ifndef NET_21 ++ if (ixs->iph->ttl <= 0) { ++ /* Tell the sender its packet died... */ ++ ICMP_SEND(ixs->skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, ixs->physdev); ++ ++ KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_xmit_sanity_check_skb: " ++ "TTL=0, too many hops!\n"); ++ ixs->stats->tx_dropped++; ++ return IPSEC_XMIT_TTLEXPIRED; ++ } ++#endif /* !NET_21 */ ++ ++ return IPSEC_XMIT_OK; ++} ++ ++enum ipsec_xmit_value ++ipsec_xmit_encap_once(struct ipsec_xmit_state *ixs) ++{ ++#ifdef CONFIG_IPSEC_ESP ++ struct esphdr *espp; ++#ifdef CONFIG_IPSEC_ENC_3DES ++ __u32 iv[ESP_IV_MAXSZ_INT]; ++#endif /* !CONFIG_IPSEC_ENC_3DES */ ++ unsigned char *idat, *pad; ++ int authlen = 0, padlen = 0, i; ++#endif /* !CONFIG_IPSEC_ESP */ ++#ifdef CONFIG_IPSEC_AH ++ struct iphdr ipo; ++ struct ahhdr *ahp; ++#endif /* CONFIG_IPSEC_AH */ ++#if defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) ++ union { ++#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ MD5_CTX md5; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ SHA1_CTX sha1; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++ } tctx; ++ __u8 hash[AH_AMAX]; ++#endif /* defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) */ ++ int headroom = 0, tailroom = 0, ilen = 0, len = 0; ++ unsigned char *dat; ++ int blocksize = 8; /* XXX: should be inside ixs --jjo */ ++#ifdef CONFIG_IPSEC_ALG ++ struct ipsec_alg_enc *ixt_e = NULL; ++ struct ipsec_alg_auth *ixt_a = NULL; ++#endif /* CONFIG_IPSEC_ALG */ ++ ++ ixs->iphlen = ixs->iph->ihl << 2; ++ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen; ++ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, SATOT_BUF); ++ KLIPS_PRINT(debug_tunnel & DB_TN_OXFS, ++ "klips_debug:ipsec_xmit_encap_once: " ++ "calling output for <%s%s%s>, SA:%s\n", ++ IPS_XFORM_NAME(ixs->ipsp), ++ ixs->sa_len ? ixs->sa_txt : " (error)"); ++ ++ switch(ixs->ipsp->ips_said.proto) { ++#ifdef CONFIG_IPSEC_AH ++ case IPPROTO_AH: ++ headroom += sizeof(struct ahhdr); ++ break; ++#endif /* CONFIG_IPSEC_AH */ ++#ifdef CONFIG_IPSEC_ESP ++ case IPPROTO_ESP: ++#ifdef CONFIG_IPSEC_ALG ++ if ((ixt_e=ixs->ipsp->ips_alg_enc)) { ++ blocksize = ixt_e->ixt_blocksize; ++ headroom += ESP_HEADER_LEN + ixt_e->ixt_ivlen/8; ++ } else ++#endif /* CONFIG_IPSEC_ALG */ ++ switch(ixs->ipsp->ips_encalg) { ++#ifdef CONFIG_IPSEC_ENC_3DES ++ case ESP_3DES: ++ headroom += sizeof(struct esphdr); ++ break; ++#endif /* CONFIG_IPSEC_ENC_3DES */ ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_ESP_BADALG; ++ } ++#ifdef CONFIG_IPSEC_ALG ++ if ((ixt_a=ixs->ipsp->ips_alg_auth)) { ++ tailroom += AHHMAC_HASHLEN; ++ } else ++#endif /* CONFIG_IPSEC_ALG */ ++ switch(ixs->ipsp->ips_authalg) { ++#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ case AH_MD5: ++ authlen = AHHMAC_HASHLEN; ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ case AH_SHA: ++ authlen = AHHMAC_HASHLEN; ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++ case AH_NONE: ++ break; ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_ESP_BADALG; ++ } ++#ifdef CONFIG_IPSEC_ALG ++ tailroom += blocksize != 1 ? ++ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 : ++ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2; ++#else ++ tailroom += ((8 - ((ixs->pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2; ++#endif /* CONFIG_IPSEC_ALG */ ++ tailroom += authlen; ++ break; ++#endif /* !CONFIG_IPSEC_ESP */ ++#ifdef CONFIG_IPSEC_IPIP ++ case IPPROTO_IPIP: ++ headroom += sizeof(struct iphdr); ++ ixs->iphlen = sizeof(struct iphdr); ++ break; ++#endif /* !CONFIG_IPSEC_IPIP */ ++#ifdef CONFIG_IPSEC_IPCOMP ++ case IPPROTO_COMP: ++ break; ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_BADPROTO; ++ } ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_once: " ++ "pushing %d bytes, putting %d, proto %d.\n", ++ headroom, tailroom, ixs->ipsp->ips_said.proto); ++ if(skb_headroom(ixs->skb) < headroom) { ++ printk(KERN_WARNING ++ "klips_error:ipsec_xmit_encap_once: " ++ "tried to skb_push headroom=%d, %d available. This should never happen, please report.\n", ++ headroom, skb_headroom(ixs->skb)); ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_ESP_PUSHPULLERR; ++ } ++ dat = skb_push(ixs->skb, headroom); ++ ilen = ixs->skb->len - tailroom; ++ if(skb_tailroom(ixs->skb) < tailroom) { ++ printk(KERN_WARNING ++ "klips_error:ipsec_xmit_encap_once: " ++ "tried to skb_put %d, %d available. This should never happen, please report.\n", ++ tailroom, skb_tailroom(ixs->skb)); ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_ESP_PUSHPULLERR; ++ } ++ skb_put(ixs->skb, tailroom); ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_once: " ++ "head,tailroom: %d,%d before xform.\n", ++ skb_headroom(ixs->skb), skb_tailroom(ixs->skb)); ++ len = ixs->skb->len; ++ if(len > 0xfff0) { ++ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_once: " ++ "tot_len (%d) > 65520. This should never happen, please report.\n", ++ len); ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_BADLEN; ++ } ++ memmove((void *)dat, (void *)(dat + headroom), ixs->iphlen); ++ ixs->iph = (struct iphdr *)dat; ++ ixs->iph->tot_len = htons(ixs->skb->len); ++ ++ switch(ixs->ipsp->ips_said.proto) { ++#ifdef CONFIG_IPSEC_ESP ++ case IPPROTO_ESP: ++ espp = (struct esphdr *)(dat + ixs->iphlen); ++ espp->esp_spi = ixs->ipsp->ips_said.spi; ++ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq)); ++ ++#ifdef CONFIG_IPSEC_ALG ++ if (!ixt_e) ++#endif /* CONFIG_IPSEC_ALG */ ++ switch(ixs->ipsp->ips_encalg) { ++#if defined(CONFIG_IPSEC_ENC_3DES) ++#ifdef CONFIG_IPSEC_ENC_3DES ++ case ESP_3DES: ++#endif /* CONFIG_IPSEC_ENC_3DES */ ++ iv[0] = *((__u32*)&(espp->esp_iv) ) = ++ ((__u32*)(ixs->ipsp->ips_iv))[0]; ++ iv[1] = *((__u32*)&(espp->esp_iv) + 1) = ++ ((__u32*)(ixs->ipsp->ips_iv))[1]; ++ break; ++#endif /* defined(CONFIG_IPSEC_ENC_3DES) */ ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_ESP_BADALG; ++ } ++ ++ idat = dat + ixs->iphlen + headroom; ++ ilen = len - (ixs->iphlen + headroom + authlen); ++ ++ /* Self-describing padding */ ++ pad = &dat[len - tailroom]; ++ padlen = tailroom - 2 - authlen; ++ for (i = 0; i < padlen; i++) { ++ pad[i] = i + 1; ++ } ++ dat[len - authlen - 2] = padlen; ++ ++ dat[len - authlen - 1] = ixs->iph->protocol; ++ ixs->iph->protocol = IPPROTO_ESP; ++ ++#ifdef CONFIG_IPSEC_ALG ++ /* Do all operations here: ++ * copy IV->ESP, encrypt, update ips IV ++ */ ++ if (ixt_e) { ++ int ret; ++ memcpy(espp->esp_iv, ++ ixs->ipsp->ips_iv, ++ ixt_e->ixt_ivlen/8); ++ ret=ipsec_alg_esp_encrypt(ixs->ipsp, ++ idat, ilen, espp->esp_iv, ++ IPSEC_ALG_ENCRYPT); ++ memcpy(ixs->ipsp->ips_iv, ++ idat + ilen - ixt_e->ixt_ivlen/8, ++ ixt_e->ixt_ivlen/8); ++ } else ++#endif /* CONFIG_IPSEC_ALG */ ++ switch(ixs->ipsp->ips_encalg) { ++#ifdef CONFIG_IPSEC_ENC_3DES ++ case ESP_3DES: ++ des_ede3_cbc_encrypt((des_cblock *)idat, ++ (des_cblock *)idat, ++ ilen, ++ ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks, ++ ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks, ++ ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks, ++ (des_cblock *)iv, 1); ++ break; ++#endif /* CONFIG_IPSEC_ENC_3DES */ ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_ESP_BADALG; ++ } ++ ++#ifdef CONFIG_IPSEC_ALG ++ if (!ixt_e) ++#endif /* CONFIG_IPSEC_ALG */ ++ switch(ixs->ipsp->ips_encalg) { ++#if defined(CONFIG_IPSEC_ENC_3DES) ++#ifdef CONFIG_IPSEC_ENC_3DES ++ case ESP_3DES: ++#endif /* CONFIG_IPSEC_ENC_3DES */ ++ /* XXX update IV with the last 8 octets of the encryption */ ++#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK ++ ((__u32*)(ixs->ipsp->ips_iv))[0] = ++ ((__u32 *)(idat))[(ilen >> 2) - 2]; ++ ((__u32*)(ixs->ipsp->ips_iv))[1] = ++ ((__u32 *)(idat))[(ilen >> 2) - 1]; ++#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */ ++ prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ); ++#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */ ++ break; ++#endif /* defined(CONFIG_IPSEC_ENC_3DES) */ ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_ESP_BADALG; ++ } ++ ++#ifdef CONFIG_IPSEC_ALG ++ if (ixt_a) { ++ ipsec_alg_sa_esp_hash(ixs->ipsp, ++ (caddr_t)espp, len - ixs->iphlen - authlen, ++ &(dat[len - authlen]), authlen); ++ ++ } else ++#endif /* CONFIG_IPSEC_ALG */ ++ switch(ixs->ipsp->ips_authalg) { ++#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ case AH_MD5: ++ dmp("espp", (char*)espp, len - ixs->iphlen - authlen); ++ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx; ++ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, (caddr_t)espp, len - ixs->iphlen - authlen); ++ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Final(hash, &tctx.md5); ++ dmp("ictx hash", (char*)&hash, sizeof(hash)); ++ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx; ++ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, hash, AHMD596_ALEN); ++ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Final(hash, &tctx.md5); ++ dmp("octx hash", (char*)&hash, sizeof(hash)); ++ memcpy(&(dat[len - authlen]), hash, authlen); ++ ++ /* paranoid */ ++ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5)); ++ memset((caddr_t)hash, 0, sizeof(*hash)); ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ case AH_SHA: ++ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx; ++ SHA1Update(&tctx.sha1, (caddr_t)espp, len - ixs->iphlen - authlen); ++ SHA1Final(hash, &tctx.sha1); ++ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx; ++ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); ++ SHA1Final(hash, &tctx.sha1); ++ memcpy(&(dat[len - authlen]), hash, authlen); ++ ++ /* paranoid */ ++ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1)); ++ memset((caddr_t)hash, 0, sizeof(*hash)); ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++ case AH_NONE: ++ break; ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_AH_BADALG; ++ } ++#ifdef NET_21 ++ ixs->skb->h.raw = (unsigned char*)espp; ++#endif /* NET_21 */ ++ break; ++#endif /* !CONFIG_IPSEC_ESP */ ++#ifdef CONFIG_IPSEC_AH ++ case IPPROTO_AH: ++ ahp = (struct ahhdr *)(dat + ixs->iphlen); ++ ahp->ah_spi = ixs->ipsp->ips_said.spi; ++ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq)); ++ ahp->ah_rv = 0; ++ ahp->ah_nh = ixs->iph->protocol; ++ ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32); ++ ixs->iph->protocol = IPPROTO_AH; ++ dmp("ahp", (char*)ahp, sizeof(*ahp)); ++ ++ ipo = *ixs->iph; ++ ipo.tos = 0; ++ ipo.frag_off = 0; ++ ipo.ttl = 0; ++ ipo.check = 0; ++ dmp("ipo", (char*)&ipo, sizeof(ipo)); ++ ++ switch(ixs->ipsp->ips_authalg) { ++#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ case AH_MD5: ++ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx; ++ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr)); ++ dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data)); ++ dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN); ++ dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom); ++ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Final(hash, &tctx.md5); ++ dmp("ictx hash", (char*)&hash, sizeof(hash)); ++ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx; ++ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Update(&tctx.md5, hash, AHMD596_ALEN); ++ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5)); ++ MD5Final(hash, &tctx.md5); ++ dmp("octx hash", (char*)&hash, sizeof(hash)); ++ ++ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN); ++ ++ /* paranoid */ ++ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5)); ++ memset((caddr_t)hash, 0, sizeof(*hash)); ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ case AH_SHA: ++ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx; ++ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr)); ++ SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data)); ++ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN); ++ SHA1Update(&tctx.sha1, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom); ++ SHA1Final(hash, &tctx.sha1); ++ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx; ++ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); ++ SHA1Final(hash, &tctx.sha1); ++ ++ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN); ++ ++ /* paranoid */ ++ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1)); ++ memset((caddr_t)hash, 0, sizeof(*hash)); ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_AH_BADALG; ++ } ++#ifdef NET_21 ++ ixs->skb->h.raw = (unsigned char*)ahp; ++#endif /* NET_21 */ ++ break; ++#endif /* CONFIG_IPSEC_AH */ ++#ifdef CONFIG_IPSEC_IPIP ++ case IPPROTO_IPIP: ++ ixs->iph->version = 4; ++ switch(sysctl_ipsec_tos) { ++ case 0: ++#ifdef NET_21 ++ ixs->iph->tos = ixs->skb->nh.iph->tos; ++#else /* NET_21 */ ++ ixs->iph->tos = ixs->skb->ip_hdr->tos; ++#endif /* NET_21 */ ++ break; ++ case 1: ++ ixs->iph->tos = 0; ++ break; ++ default: ++ break; ++ } ++#ifdef NET_21 ++#ifdef NETDEV_23 ++ ixs->iph->ttl = sysctl_ip_default_ttl; ++#else /* NETDEV_23 */ ++ ixs->iph->ttl = ip_statistics.IpDefaultTTL; ++#endif /* NETDEV_23 */ ++#else /* NET_21 */ ++ ixs->iph->ttl = 64; /* ip_statistics.IpDefaultTTL; */ ++#endif /* NET_21 */ ++ ixs->iph->frag_off = 0; ++ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr; ++ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr; ++ ixs->iph->protocol = IPPROTO_IPIP; ++ ixs->iph->ihl = sizeof(struct iphdr) >> 2; ++ ++ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb); ++ ++ ixs->newdst = (__u32)ixs->iph->daddr; ++ ixs->newsrc = (__u32)ixs->iph->saddr; ++ ++#ifdef NET_21 ++ ixs->skb->h.ipiph = ixs->skb->nh.iph; ++#endif /* NET_21 */ ++ break; ++#endif /* !CONFIG_IPSEC_IPIP */ ++#ifdef CONFIG_IPSEC_IPCOMP ++ case IPPROTO_COMP: ++ { ++ unsigned int flags = 0; ++#ifdef CONFIG_IPSEC_DEBUG ++ unsigned int old_tot_len = ntohs(ixs->iph->tot_len); ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len); ++ ++ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags); ++ ++#ifdef NET_21 ++ ixs->iph = ixs->skb->nh.iph; ++#else /* NET_21 */ ++ ixs->iph = ixs->skb->ip_hdr; ++#endif /* NET_21 */ ++ ++ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len); ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if (debug_tunnel & DB_TN_CROUT) ++ { ++ if (old_tot_len > ntohs(ixs->iph->tot_len)) ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_once: " ++ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n", ++ old_tot_len, ntohs(ixs->iph->tot_len), ++ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi), ++ ntohl(ixs->ipsp->ips_said.spi), ++ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff)); ++ else ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_once: " ++ "packet did not compress (flags = %d).\n", ++ flags); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ } ++ break; ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ default: ++ ixs->stats->tx_errors++; ++ return IPSEC_XMIT_BADPROTO; ++ } ++ ++#ifdef NET_21 ++ ixs->skb->nh.raw = ixs->skb->data; ++#else /* NET_21 */ ++ ixs->skb->ip_hdr = ixs->skb->h.iph = (struct iphdr *) ixs->skb->data; ++#endif /* NET_21 */ ++ ixs->iph->check = 0; ++ ixs->iph->check = ip_fast_csum((unsigned char *)ixs->iph, ixs->iph->ihl); ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_encap_once: " ++ "after <%s%s%s>, SA:%s:\n", ++ IPS_XFORM_NAME(ixs->ipsp), ++ ixs->sa_len ? ixs->sa_txt : " (error)"); ++ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph); ++ ++ ixs->ipsp->ips_life.ipl_bytes.ipl_count += len; ++ ixs->ipsp->ips_life.ipl_bytes.ipl_last = len; ++ ++ if(!ixs->ipsp->ips_life.ipl_usetime.ipl_count) { ++ ixs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ; ++ } ++ ixs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ; ++ ixs->ipsp->ips_life.ipl_packets.ipl_count++; ++ ++ ixs->ipsp = ixs->ipsp->ips_onext; ++ ++ return IPSEC_XMIT_OK; ++} ++ ++/* ++ * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps ++ * source and destination ports to those from the TCP/UDP header. ++ */ ++void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er) ++{ ++ struct udphdr *udp; ++ ++ switch (iph->protocol) { ++ case IPPROTO_UDP: ++ case IPPROTO_TCP: ++ /* ++ * The ports are at the same offsets in a TCP and UDP ++ * header so hack it ... ++ */ ++ udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2)); ++ er->sen_sport = udp->source; ++ er->sen_dport = udp->dest; ++ break; ++ default: ++ er->sen_sport = 0; ++ er->sen_dport = 0; ++ break; ++ } ++} ++ ++/* ++ * A TRAP eroute is installed and we want to replace it with a HOLD ++ * eroute. ++ */ ++static int create_hold_eroute(struct eroute *origtrap, ++ struct sk_buff * skb, struct iphdr * iph, ++ uint32_t eroute_pid) ++{ ++ struct eroute hold_eroute; ++ ip_said hold_said; ++ struct sk_buff *first, *last; ++ int error; ++ ++ first = last = NULL; ++ memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute)); ++ memset((caddr_t)&hold_said, 0, sizeof(hold_said)); ++ ++ hold_said.proto = IPPROTO_INT; ++ hold_said.spi = htonl(SPI_HOLD); ++ hold_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY; ++ ++ hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap); ++ hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap); ++ hold_eroute.er_eaddr.sen_family = AF_ENCAP; ++ hold_eroute.er_emask.sen_family = AF_ENCAP; ++ hold_eroute.er_eaddr.sen_type = SENT_IP4; ++ hold_eroute.er_emask.sen_type = 255; ++ ++ hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr; ++ hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr; ++ hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST; ++ hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST; ++ hold_eroute.er_emask.sen_sport = 0; ++ hold_eroute.er_emask.sen_dport = 0; ++ hold_eroute.er_pid = eroute_pid; ++ hold_eroute.er_count = 0; ++ hold_eroute.er_lasttime = jiffies/HZ; ++ ++ /* ++ * if it wasn't captured by a wildcard, then don't record it as ++ * a wildcard. ++ */ ++ if(origtrap->er_eaddr.sen_proto != 0) { ++ hold_eroute.er_eaddr.sen_proto = iph->protocol; ++ ++ if((iph->protocol == IPPROTO_TCP || ++ iph->protocol == IPPROTO_UDP) && ++ (origtrap->er_eaddr.sen_sport != 0 || ++ origtrap->er_eaddr.sen_dport != 0)) { ++ ++ if(origtrap->er_eaddr.sen_sport != 0) ++ hold_eroute.er_emask.sen_sport = ~0; ++ ++ if(origtrap->er_eaddr.sen_dport != 0) ++ hold_eroute.er_emask.sen_dport = ~0; ++ ++ ipsec_extract_ports(iph, &hold_eroute.er_eaddr); ++ } ++ } ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if (debug_pfkey) { ++ char buf1[64], buf2[64]; ++ subnettoa(hold_eroute.er_eaddr.sen_ip_src, ++ hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); ++ subnettoa(hold_eroute.er_eaddr.sen_ip_dst, ++ hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n", ++ buf1, ntohs(hold_eroute.er_eaddr.sen_sport), ++ buf2, ntohs(hold_eroute.er_eaddr.sen_dport), ++ hold_eroute.er_eaddr.sen_proto); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask), ++ &first, &last)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "HOLD breakeroute found nothing.\n"); ++ } else { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n", ++ NIPQUAD(hold_eroute.er_eaddr.sen_ip_src), ++ ntohs(hold_eroute.er_eaddr.sen_sport), ++ NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst), ++ ntohs(hold_eroute.er_eaddr.sen_dport), ++ hold_eroute.er_eaddr.sen_proto); ++ } ++ if (first != NULL) ++ kfree_skb(first); ++ if (last != NULL) ++ kfree_skb(last); ++ ++ error = ipsec_makeroute(&(hold_eroute.er_eaddr), ++ &(hold_eroute.er_emask), ++ hold_said, eroute_pid, skb, NULL, NULL); ++ if (error) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "HOLD makeroute returned %d, failed.\n", error); ++ } else { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "HOLD makeroute call successful.\n"); ++ } ++ return (error == 0); ++} ++ ++enum ipsec_xmit_value ++ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs) ++{ ++#ifdef CONFIG_IPSEC_ALG ++ struct ipsec_alg_enc *ixt_e = NULL; ++ struct ipsec_alg_auth *ixt_a = NULL; ++ int blocksize = 8; ++#endif /* CONFIG_IPSEC_ALG */ ++ enum ipsec_xmit_value bundle_stat = IPSEC_XMIT_OK; ++ ++ ixs->newdst = ixs->orgdst = ixs->iph->daddr; ++ ixs->newsrc = ixs->orgsrc = ixs->iph->saddr; ++ ixs->orgedst = ixs->outgoing_said.dst.u.v4.sin_addr.s_addr; ++ ixs->iphlen = ixs->iph->ihl << 2; ++ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen; ++ ixs->max_headroom = ixs->max_tailroom = 0; ++ ++ if (ixs->outgoing_said.proto == IPPROTO_INT) { ++ switch (ntohl(ixs->outgoing_said.spi)) { ++ case SPI_DROP: ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "shunt SA of DROP or no eroute: dropping.\n"); ++ ixs->stats->tx_dropped++; ++ break; ++ ++ case SPI_REJECT: ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "shunt SA of REJECT: notifying and dropping.\n"); ++ ICMP_SEND(ixs->skb, ++ ICMP_DEST_UNREACH, ++ ICMP_PKT_FILTERED, ++ 0, ++ ixs->physdev); ++ ixs->stats->tx_dropped++; ++ break; ++ ++ case SPI_PASS: ++#ifdef NET_21 ++ ixs->pass = 1; ++#endif /* NET_21 */ ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "PASS: calling dev_queue_xmit\n"); ++ return IPSEC_XMIT_PASS; ++ goto cleanup; ++ ++ case SPI_HOLD: ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "shunt SA of HOLD: this does not make sense here, dropping.\n"); ++ ixs->stats->tx_dropped++; ++ break; ++ ++ case SPI_TRAP: ++ case SPI_TRAPSUBNET: ++ { ++ struct sockaddr_in src, dst; ++#ifdef CONFIG_IPSEC_DEBUG ++ char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF]; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ /* Signal all listening KMds with a PF_KEY ACQUIRE */ ++ ++ src.sin_family = AF_INET; ++ dst.sin_family = AF_INET; ++ src.sin_addr.s_addr = ixs->iph->saddr; ++ dst.sin_addr.s_addr = ixs->iph->daddr; ++ ++ ixs->ips.ips_transport_protocol = 0; ++ src.sin_port = 0; ++ dst.sin_port = 0; ++ { ++ int i; ++ for(i = 0; ++ i < sizeof(struct sockaddr_in) ++ - offsetof(struct sockaddr_in, sin_zero); ++ i++) { ++ src.sin_zero[i] = 0; ++ dst.sin_zero[i] = 0; ++ } ++ } ++ ++ if(ixs->eroute->er_eaddr.sen_proto != 0) { ++ ixs->ips.ips_transport_protocol = ixs->iph->protocol; ++ ++ if(ixs->eroute->er_eaddr.sen_sport != 0) { ++ src.sin_port = ++ (ixs->iph->protocol == IPPROTO_UDP ++ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->source ++ : (ixs->iph->protocol == IPPROTO_TCP ++ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->source ++ : 0)); ++ } ++ if(ixs->eroute->er_eaddr.sen_dport != 0) { ++ dst.sin_port = ++ (ixs->iph->protocol == IPPROTO_UDP ++ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->dest ++ : (ixs->iph->protocol == IPPROTO_TCP ++ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->dest ++ : 0)); ++ } ++ } ++ ++ ixs->ips.ips_addr_s = (struct sockaddr*)(&src); ++ ixs->ips.ips_addr_d = (struct sockaddr*)(&dst); ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n", ++ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR", ++ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_port), ++ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR", ++ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_port), ++ ixs->ips.ips_said.proto); ++ ++ /* increment count of total traps needed */ ++ ipsec_xmit_trap_count++; ++ ++ if (pfkey_acquire(&ixs->ips) == 0) { ++ ++ /* note that we succeeded */ ++ ipsec_xmit_trap_sendcount++; ++ ++ if (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)) { ++ /* ++ * The spinlock is to prevent any other ++ * process from accessing or deleting ++ * the eroute while we are using and ++ * updating it. ++ */ ++ spin_lock(&eroute_lock); ++ ixs->eroute = ipsec_findroute(&ixs->matcher); ++ if(ixs->eroute) { ++ ixs->eroute->er_said.spi = htonl(SPI_HOLD); ++ ixs->eroute->er_first = ixs->skb; ++ ixs->skb = NULL; ++ } ++ spin_unlock(&eroute_lock); ++ } else if (create_hold_eroute(ixs->eroute, ++ ixs->skb, ++ ixs->iph, ++ ixs->eroute_pid)) { ++ ixs->skb = NULL; ++ } ++ /* whether or not the above succeeded, we continue */ ++ ++ } ++ ixs->stats->tx_dropped++; ++ } ++ default: ++ /* XXX what do we do with an unknown shunt spi? */ ++ break; ++ } /* switch (ntohl(ixs->outgoing_said.spi)) */ ++ return IPSEC_XMIT_STOLEN; ++ } /* if (ixs->outgoing_said.proto == IPPROTO_INT) */ ++ ++ /* ++ The spinlock is to prevent any other process from ++ accessing or deleting the ipsec_sa hash table or any of the ++ ipsec_sa s while we are using and updating them. ++ ++ This is not optimal, but was relatively straightforward ++ at the time. A better way to do it has been planned for ++ more than a year, to lock the hash table and put reference ++ counts on each ipsec_sa instead. This is not likely to happen ++ in KLIPS1 unless a volunteer contributes it, but will be ++ designed into KLIPS2. ++ */ ++ spin_lock(&tdb_lock); ++ ++ ixs->ipsp = ipsec_sa_getbyid(&ixs->outgoing_said); ++ ixs->sa_len = satot(&ixs->outgoing_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt)); ++ ++ if (ixs->ipsp == NULL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "no ipsec_sa for SA%s: outgoing packet with no SA, dropped.\n", ++ ixs->sa_len ? ixs->sa_txt : " (error)"); ++ ixs->stats->tx_dropped++; ++ bundle_stat = IPSEC_XMIT_SAIDNOTFOUND; ++ goto cleanup; ++ } ++ ++ ipsec_sa_put(ixs->ipsp); /* incomplete */ ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "found ipsec_sa -- SA:<%s%s%s> %s\n", ++ IPS_XFORM_NAME(ixs->ipsp), ++ ixs->sa_len ? ixs->sa_txt : " (error)"); ++ ++ /* ++ * How much headroom do we need to be able to apply ++ * all the grouped transforms? ++ */ ++ ixs->ipsq = ixs->ipsp; /* save the head of the ipsec_sa chain */ ++ while (ixs->ipsp) { ++ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt)); ++ if(ixs->sa_len == 0) { ++ strcpy(ixs->sa_txt, "(error)"); ++ } ++ ++ /* If it is in larval state, drop the packet, we cannot process yet. */ ++ if(ixs->ipsp->ips_state == SADB_SASTATE_LARVAL) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "ipsec_sa in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n", ++ IPS_XFORM_NAME(ixs->ipsp), ++ ixs->sa_len ? ixs->sa_txt : " (error)"); ++ ixs->stats->tx_errors++; ++ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE; ++ goto cleanup; ++ } ++ ++ if(ixs->ipsp->ips_state == SADB_SASTATE_DEAD) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "ipsec_sa in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n", ++ IPS_XFORM_NAME(ixs->ipsp), ++ ixs->sa_len ? ixs->sa_txt : " (error)"); ++ ixs->stats->tx_errors++; ++ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE; ++ goto cleanup; ++ } ++ ++ /* If the replay window counter == -1, expire SA, it will roll */ ++ if(ixs->ipsp->ips_replaywin && ixs->ipsp->ips_replaywin_lastseq == -1) { ++ pfkey_expire(ixs->ipsp, 1); ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n", ++ IPS_XFORM_NAME(ixs->ipsp), ++ ixs->sa_len ? ixs->sa_txt : " (error)"); ++ ipsec_sa_delchain(ixs->ipsp); ++ ixs->stats->tx_errors++; ++ bundle_stat = IPSEC_XMIT_REPLAYROLLED; ++ goto cleanup; ++ } ++ ++ /* ++ * if this is the first time we are using this SA, mark start time, ++ * and offset hard/soft counters by "now" for later checking. ++ */ ++#if 0 ++ if(ixs->ipsp->ips_life.ipl_usetime.count == 0) { ++ ixs->ipsp->ips_life.ipl_usetime.count = jiffies; ++ ixs->ipsp->ips_life.ipl_usetime.hard += jiffies; ++ ixs->ipsp->ips_life.ipl_usetime.soft += jiffies; ++ } ++#endif ++ ++ ++ if(ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_bytes, "bytes", ixs->sa_txt, ++ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied || ++ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_addtime, "addtime",ixs->sa_txt, ++ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied || ++ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_usetime, "usetime",ixs->sa_txt, ++ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied || ++ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_packets, "packets",ixs->sa_txt, ++ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied) { ++ ++ ipsec_sa_delchain(ixs->ipsp); ++ ixs->stats->tx_errors++; ++ bundle_stat = IPSEC_XMIT_LIFETIMEFAILED; ++ goto cleanup; ++ } ++ ++ ++ ixs->headroom = ixs->tailroom = 0; ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "calling room for <%s%s%s>, SA:%s\n", ++ IPS_XFORM_NAME(ixs->ipsp), ++ ixs->sa_len ? ixs->sa_txt : " (error)"); ++ switch(ixs->ipsp->ips_said.proto) { ++#ifdef CONFIG_IPSEC_AH ++ case IPPROTO_AH: ++ ixs->headroom += sizeof(struct ahhdr); ++ break; ++#endif /* CONFIG_IPSEC_AH */ ++#ifdef CONFIG_IPSEC_ESP ++ case IPPROTO_ESP: ++#ifdef CONFIG_IPSEC_ALG ++ if ((ixt_e=ixs->ipsp->ips_alg_enc)) { ++ blocksize = ixt_e->ixt_blocksize; ++ ixs->headroom += ESP_HEADER_LEN + ixt_e->ixt_ivlen/8; ++ } else ++#endif /* CONFIG_IPSEC_ALG */ ++ switch(ixs->ipsp->ips_encalg) { ++#ifdef CONFIG_IPSEC_ENC_3DES ++ case ESP_3DES: ++ ixs->headroom += sizeof(struct esphdr); ++ break; ++#endif /* CONFIG_IPSEC_ENC_3DES */ ++ default: ++ ixs->stats->tx_errors++; ++ bundle_stat = IPSEC_XMIT_ESP_BADALG; ++ goto cleanup; ++ } ++#ifdef CONFIG_IPSEC_ALG ++ if ((ixt_a=ixs->ipsp->ips_alg_auth)) { ++ ixs->tailroom += AHHMAC_HASHLEN; ++ } else ++#endif /* CONFIG_IPSEC_ALG */ ++ switch(ixs->ipsp->ips_authalg) { ++#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ case AH_MD5: ++ ixs->tailroom += AHHMAC_HASHLEN; ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ case AH_SHA: ++ ixs->tailroom += AHHMAC_HASHLEN; ++ break; ++#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++ case AH_NONE: ++ break; ++ default: ++ ixs->stats->tx_errors++; ++ bundle_stat = IPSEC_XMIT_AH_BADALG; ++ goto cleanup; ++ } ++#ifdef CONFIG_IPSEC_ALG ++ ixs->tailroom += blocksize != 1 ? ++ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 : ++ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2; ++#else ++ ixs->tailroom += ((8 - ((ixs->pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2; ++#endif /* CONFIG_IPSEC_ALG */ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ if ((ixs->ipsp->ips_natt_type) && (!ixs->natt_type)) { ++ ixs->natt_type = ixs->ipsp->ips_natt_type; ++ ixs->natt_sport = ixs->ipsp->ips_natt_sport; ++ ixs->natt_dport = ixs->ipsp->ips_natt_dport; ++ switch (ixs->natt_type) { ++ case ESPINUDP_WITH_NON_IKE: ++ ixs->natt_head = sizeof(struct udphdr)+(2*sizeof(__u32)); ++ break; ++ ++ case ESPINUDP_WITH_NON_ESP: ++ ixs->natt_head = sizeof(struct udphdr); ++ break; ++ ++ default: ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT ++ , "klips_xmit: invalid nat-t type %d" ++ , ixs->natt_type); ++ bundle_stat = IPSEC_XMIT_ESPUDP_BADTYPE; ++ goto cleanup; ++ ++ break; ++ } ++ ixs->tailroom += ixs->natt_head; ++ } ++#endif ++ break; ++#endif /* !CONFIG_IPSEC_ESP */ ++#ifdef CONFIG_IPSEC_IPIP ++ case IPPROTO_IPIP: ++ ixs->headroom += sizeof(struct iphdr); ++ break; ++#endif /* !CONFIG_IPSEC_IPIP */ ++ case IPPROTO_COMP: ++#ifdef CONFIG_IPSEC_IPCOMP ++ /* ++ We can't predict how much the packet will ++ shrink without doing the actual compression. ++ We could do it here, if we were the first ++ encapsulation in the chain. That might save ++ us a skb_copy_expand, since we might fit ++ into the existing skb then. However, this ++ would be a bit unclean (and this hack has ++ bit us once), so we better not do it. After ++ all, the skb_copy_expand is cheap in ++ comparison to the actual compression. ++ At least we know the packet will not grow. ++ */ ++ break; ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ default: ++ ixs->stats->tx_errors++; ++ bundle_stat = IPSEC_XMIT_BADPROTO; ++ goto cleanup; ++ } ++ ixs->ipsp = ixs->ipsp->ips_onext; ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "Required head,tailroom: %d,%d\n", ++ ixs->headroom, ixs->tailroom); ++ ixs->max_headroom += ixs->headroom; ++ ixs->max_tailroom += ixs->tailroom; ++ ixs->pyldsz += (ixs->headroom + ixs->tailroom); ++ } ++ ixs->ipsp = ixs->ipsq; /* restore the head of the ipsec_sa chain */ ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n", ++ skb_headroom(ixs->skb), skb_tailroom(ixs->skb), ++ ixs->max_headroom, ixs->max_tailroom); ++ ++ ixs->tot_headroom += ixs->max_headroom; ++ ixs->tot_tailroom += ixs->max_tailroom; ++ ++ ixs->mtudiff = ixs->prv->mtu + ixs->tot_headroom + ixs->tot_tailroom - ixs->physmtu; ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n", ++ ixs->prv->mtu, ixs->physmtu, ++ ixs->tot_headroom, ixs->tot_tailroom, ixs->mtudiff, ntohs(ixs->iph->tot_len)); ++ if(ixs->mtudiff > 0) { ++ int newmtu = ixs->physmtu - (ixs->tot_headroom + ((ixs->tot_tailroom + 2) & ~7) + 5); ++ ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_info:ipsec_xmit_encap_bundle: " ++ "dev %s mtu of %d decreased by %d to %d\n", ++ ixs->dev->name, ++ ixs->prv->mtu, ++ ixs->prv->mtu - newmtu, ++ newmtu); ++ ixs->prv->mtu = newmtu; ++#ifdef NET_21 ++#if 0 ++ ixs->skb->dst->pmtu = ixs->prv->mtu; /* RGB */ ++#endif /* 0 */ ++#else /* NET_21 */ ++#if 0 ++ ixs->dev->mtu = ixs->prv->mtu; /* RGB */ ++#endif /* 0 */ ++#endif /* NET_21 */ ++ } ++ ++ /* ++ If the sender is doing PMTU discovery, and the ++ packet doesn't fit within ixs->prv->mtu, notify him ++ (unless it was an ICMP packet, or it was not the ++ zero-offset packet) and send it anyways. ++ ++ Note: buggy firewall configuration may prevent the ++ ICMP packet from getting back. ++ */ ++ if(sysctl_ipsec_icmp ++ && ixs->prv->mtu < ntohs(ixs->iph->tot_len) ++ && (ixs->iph->frag_off & __constant_htons(IP_DF)) ) { ++ int notify = ixs->iph->protocol != IPPROTO_ICMP ++ && (ixs->iph->frag_off & __constant_htons(IP_OFFSET)) == 0; ++ ++#ifdef IPSEC_obey_DF ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "fragmentation needed and DF set; %sdropping packet\n", ++ notify ? "sending ICMP and " : ""); ++ if (notify) ++ ICMP_SEND(ixs->skb, ++ ICMP_DEST_UNREACH, ++ ICMP_FRAG_NEEDED, ++ ixs->prv->mtu, ++ ixs->physdev); ++ ixs->stats->tx_errors++; ++ bundle_stat = IPSEC_XMIT_CANNOTFRAG; ++ goto cleanup; ++#else /* IPSEC_obey_DF */ ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "fragmentation needed and DF set; %spassing packet\n", ++ notify ? "sending ICMP and " : ""); ++ if (notify) ++ ICMP_SEND(ixs->skb, ++ ICMP_DEST_UNREACH, ++ ICMP_FRAG_NEEDED, ++ ixs->prv->mtu, ++ ixs->physdev); ++#endif /* IPSEC_obey_DF */ ++ } ++ ++#ifdef MSS_HACK ++ /* ++ * If this is a transport mode TCP packet with ++ * SYN set, determine an effective MSS based on ++ * AH/ESP overheads determined above. ++ */ ++ if (ixs->iph->protocol == IPPROTO_TCP ++ && ixs->outgoing_said.proto != IPPROTO_IPIP) { ++ struct tcphdr *tcph = ixs->skb->h.th; ++ if (tcph->syn && !tcph->ack) { ++ if(!ipsec_adjust_mss(ixs->skb, tcph, ixs->prv->mtu)) { ++ printk(KERN_WARNING ++ "klips_warning:ipsec_xmit_encap_bundle: " ++ "ipsec_adjust_mss() failed\n"); ++ ixs->stats->tx_errors++; ++ bundle_stat = IPSEC_XMIT_MSSERR; ++ goto cleanup; ++ } ++ } ++ } ++#endif /* MSS_HACK */ ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ if ((ixs->natt_type) && (ixs->outgoing_said.proto != IPPROTO_IPIP)) { ++ /** ++ * NAT-Traversal and Transport Mode: ++ * we need to correct TCP/UDP checksum ++ * ++ * If we've got NAT-OA, we can fix checksum without recalculation. ++ * If we don't we can zero udp checksum. ++ */ ++ __u32 natt_oa = ixs->ipsp->ips_natt_oa ? ++ ((struct sockaddr_in*)(ixs->ipsp->ips_natt_oa))->sin_addr.s_addr : 0; ++ __u16 pkt_len = ixs->skb->tail - (unsigned char *)ixs->iph; ++ __u16 data_len = pkt_len - (ixs->iph->ihl << 2); ++ switch (ixs->iph->protocol) { ++ case IPPROTO_TCP: ++ if (data_len >= sizeof(struct tcphdr)) { ++ struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ixs->iph+ixs->iph->ihl); ++ if (natt_oa) { ++ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa }; ++ KLIPS_PRINT(debug_tunnel, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "NAT-T & TRANSPORT: " ++ "fix TCP checksum using NAT-OA\n"); ++ tcp->check = csum_fold( ++ csum_partial((unsigned char *)buff, sizeof(buff), ++ tcp->check^0xffff)); ++ } ++ else { ++ KLIPS_PRINT(debug_tunnel, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "NAT-T & TRANSPORT: do not recalc TCP checksum\n"); ++ } ++ } ++ else { ++ KLIPS_PRINT(debug_tunnel, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "NAT-T & TRANSPORT: can't fix TCP checksum\n"); ++ } ++ break; ++ case IPPROTO_UDP: ++ if (data_len >= sizeof(struct udphdr)) { ++ struct udphdr *udp = (struct udphdr *)((__u32 *)ixs->iph+ixs->iph->ihl); ++ if (udp->check == 0) { ++ KLIPS_PRINT(debug_tunnel, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "NAT-T & TRANSPORT: UDP checksum already 0\n"); ++ } ++ else if (natt_oa) { ++ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa }; ++ KLIPS_PRINT(debug_tunnel, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "NAT-T & TRANSPORT: " ++ "fix UDP checksum using NAT-OA\n"); ++ udp->check = csum_fold( ++ csum_partial((unsigned char *)buff, sizeof(buff), ++ udp->check^0xffff)); ++ } ++ else { ++ KLIPS_PRINT(debug_tunnel, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "NAT-T & TRANSPORT: zero UDP checksum\n"); ++ udp->check = 0; ++ } ++ } ++ else { ++ KLIPS_PRINT(debug_tunnel, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "NAT-T & TRANSPORT: can't fix UDP checksum\n"); ++ } ++ break; ++ default: ++ KLIPS_PRINT(debug_tunnel, ++ "klips_debug:ipsec_tunnel_start_xmit: " ++ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n"); ++ break; ++ } ++ } ++#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */ ++ ++ if(!ixs->hard_header_stripped) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "allocating %d bytes for hardheader.\n", ++ ixs->hard_header_len); ++ if((ixs->saved_header = kmalloc(ixs->hard_header_len, GFP_ATOMIC)) == NULL) { ++ printk(KERN_WARNING "klips_debug:ipsec_xmit_encap_bundle: " ++ "Failed, tried to allocate %d bytes for temp hard_header.\n", ++ ixs->hard_header_len); ++ ixs->stats->tx_errors++; ++ bundle_stat = IPSEC_XMIT_ERRMEMALLOC; ++ goto cleanup; ++ } ++ { ++ int i; ++ for (i = 0; i < ixs->hard_header_len; i++) { ++ ixs->saved_header[i] = ixs->skb->data[i]; ++ } ++ } ++ if(ixs->skb->len < ixs->hard_header_len) { ++ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_bundle: " ++ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n", ++ ixs->hard_header_len, (int)(ixs->skb->len)); ++ ixs->stats->tx_errors++; ++ bundle_stat = IPSEC_XMIT_ESP_PUSHPULLERR; ++ goto cleanup; ++ } ++ skb_pull(ixs->skb, ixs->hard_header_len); ++ ixs->hard_header_stripped = 1; ++ ++/* ixs->iph = (struct iphdr *) (ixs->skb->data); */ ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "head,tailroom: %d,%d after hard_header stripped.\n", ++ skb_headroom(ixs->skb), skb_tailroom(ixs->skb)); ++ KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, ixs->iph); ++ } else { ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "hard header already stripped.\n"); ++ } ++ ++ ixs->ll_headroom = (ixs->hard_header_len + 15) & ~15; ++ ++ if ((skb_headroom(ixs->skb) >= ixs->max_headroom + 2 * ixs->ll_headroom) && ++ (skb_tailroom(ixs->skb) >= ixs->max_tailroom) ++#ifndef NET_21 ++ && ixs->skb->free ++#endif /* !NET_21 */ ++ ) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "data fits in existing skb\n"); ++ } else { ++ struct sk_buff* tskb; ++ ++ if(!ixs->oskb) { ++ ixs->oskb = ixs->skb; ++ } ++ ++ tskb = skb_copy_expand(ixs->skb, ++ /* The need for 2 * link layer length here remains unexplained...RGB */ ++ ixs->max_headroom + 2 * ixs->ll_headroom, ++ ixs->max_tailroom, ++ GFP_ATOMIC); ++#ifdef NET_21 ++ if(tskb && ixs->skb->sk) { ++ skb_set_owner_w(tskb, ixs->skb->sk); ++ } ++#endif /* NET_21 */ ++ if(ixs->skb != ixs->oskb) { ++ ipsec_kfree_skb(ixs->skb); ++ } ++ ixs->skb = tskb; ++ if (!ixs->skb) { ++ printk(KERN_WARNING ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "Failed, tried to allocate %d head and %d tailroom\n", ++ ixs->max_headroom, ixs->max_tailroom); ++ ixs->stats->tx_errors++; ++ bundle_stat = IPSEC_XMIT_ERRSKBALLOC; ++ goto cleanup; ++ } ++ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, ++ "klips_debug:ipsec_xmit_encap_bundle: " ++ "head,tailroom: %d,%d after allocation\n", ++ skb_headroom(ixs->skb), skb_tailroom(ixs->skb)); ++ } ++ ++ /* ++ * Apply grouped transforms to packet ++ */ ++ while (ixs->ipsp) { ++ enum ipsec_xmit_value encap_stat = IPSEC_XMIT_OK; ++ ++ encap_stat = ipsec_xmit_encap_once(ixs); ++ if(encap_stat != IPSEC_XMIT_OK) { ++ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, ++ "klips_debug:ipsec_xmit_encap_bundle: encap_once failed: %d\n", ++ encap_stat); ++ ++ bundle_stat = IPSEC_XMIT_ENCAPFAIL; ++ goto cleanup; ++ } ++ } ++ /* end encapsulation loop here XXX */ ++ cleanup: ++ spin_unlock(&tdb_lock); ++ return bundle_stat; ++} ++ ++/* ++ * $Log: ipsec_xmit.c,v $ ++ * Revision 1.8 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.7 2004/02/03 03:13:41 mcr ++ * mark invalid encapsulation states. ++ * ++ * Revision 1.6.2.1 2003/12/22 15:25:52 jjo ++ * Merged algo-0.8.1-rc11-test1 into alg-branch ++ * ++ * Revision 1.6 2003/12/10 01:14:27 mcr ++ * NAT-traversal patches to KLIPS. ++ * ++ * Revision 1.5 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.4.4.2 2003/10/29 01:37:39 mcr ++ * when creating %hold from %trap, only make the %hold as ++ * specific as the %trap was - so if the protocol and ports ++ * were wildcards, then the %hold will be too. ++ * ++ * Revision 1.4.4.1 2003/09/21 13:59:56 mcr ++ * pre-liminary X.509 patch - does not yet pass tests. ++ * ++ * Revision 1.4 2003/06/20 02:28:10 mcr ++ * misstype of variable name, not detected by module build. ++ * ++ * Revision 1.3 2003/06/20 01:42:21 mcr ++ * added counters to measure how many ACQUIREs we send to pluto, ++ * and how many are successfully sent. ++ * ++ * Revision 1.2 2003/04/03 17:38:35 rgb ++ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. ++ * Normalised coding style. ++ * Simplified logic and reduced duplication of code. ++ * ++ * Revision 1.1 2003/02/12 19:31:23 rgb ++ * Refactored from ipsec_tunnel.c ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/pfkey_v2.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,2126 @@ ++/* ++ * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F ++ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: pfkey_v2.c,v 1.81 2004/04/25 21:23:11 ken Exp $ ++ */ ++ ++/* ++ * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c. ++ * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c. ++ */ ++ ++#define __NO_VERSION__ ++#include ++#include ++#include ++#include ++ ++#include "openswan/ipsec_param.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* struct socket */ ++#include ++#include ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include ++#include ++#include ++#include /* struct sock */ ++/* #include */ ++#include ++#ifdef CONFIG_PROC_FS ++# include ++#endif /* CONFIG_PROC_FS */ ++ ++#include ++ ++#include ++#ifdef NET_21 ++# include ++# include ++#endif /* NET_21 */ ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_sa.h" ++ ++#include ++#include ++ ++#include "openswan/ipsec_proto.h" ++ ++#ifdef CONFIG_IPSEC_DEBUG ++int debug_pfkey = 0; ++extern int sysctl_ipsec_debug_verbose; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) ++ ++#ifndef SOCKOPS_WRAPPED ++#define SOCKOPS_WRAPPED(name) name ++#endif /* SOCKOPS_WRAPPED */ ++ ++extern struct proto_ops pfkey_ops; ++struct sock *pfkey_sock_list = NULL; ++struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1]; ++ ++struct socket_list *pfkey_open_sockets = NULL; ++struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1]; ++ ++int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **); ++ ++int ++pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets) ++{ ++ struct socket_list *socket_listp,*prev; ++ ++ if(!socketp) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_remove_socket: " ++ "NULL socketp handed in, failed.\n"); ++ return -EINVAL; ++ } ++ ++ if(!sockets) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_remove_socket: " ++ "NULL sockets list handed in, failed.\n"); ++ return -EINVAL; ++ } ++ ++ socket_listp = *sockets; ++ prev = NULL; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_remove_socket: " ++ "removing sock=0p%p\n", ++ socketp); ++ ++ while(socket_listp != NULL) { ++ if(socket_listp->socketp == socketp) { ++ if(prev != NULL) { ++ prev->next = socket_listp->next; ++ } else { ++ *sockets = socket_listp->next; ++ } ++ ++ kfree((void*)socket_listp); ++ ++ break; ++ } ++ prev = socket_listp; ++ socket_listp = socket_listp->next; ++ } ++ ++ return 0; ++} ++ ++int ++pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets) ++{ ++ struct socket_list *socket_listp; ++ ++ if(!socketp) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_insert_socket: " ++ "NULL socketp handed in, failed.\n"); ++ return -EINVAL; ++ } ++ ++ if(!sockets) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_insert_socket: " ++ "NULL sockets list handed in, failed.\n"); ++ return -EINVAL; ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_insert_socket: " ++ "allocating %lu bytes for socketp=0p%p\n", ++ (unsigned long) sizeof(struct socket_list), ++ socketp); ++ ++ if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_insert_socket: " ++ "memory allocation error.\n"); ++ return -ENOMEM; ++ } ++ ++ socket_listp->socketp = socketp; ++ socket_listp->next = *sockets; ++ *sockets = socket_listp; ++ ++ return 0; ++} ++ ++int ++pfkey_list_remove_supported(struct supported *supported, struct supported_list **supported_list) ++{ ++ struct supported_list *supported_listp = *supported_list, *prev = NULL; ++ ++ if(!supported) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_remove_supported: " ++ "NULL supported handed in, failed.\n"); ++ return -EINVAL; ++ } ++ ++ if(!supported_list) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_remove_supported: " ++ "NULL supported_list handed in, failed.\n"); ++ return -EINVAL; ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_remove_supported: " ++ "removing supported=0p%p\n", ++ supported); ++ ++ while(supported_listp != NULL) { ++ if(supported_listp->supportedp == supported) { ++ if(prev != NULL) { ++ prev->next = supported_listp->next; ++ } else { ++ *supported_list = supported_listp->next; ++ } ++ ++ kfree((void*)supported_listp); ++ ++ break; ++ } ++ prev = supported_listp; ++ supported_listp = supported_listp->next; ++ } ++ ++ return 0; ++} ++ ++int ++pfkey_list_insert_supported(struct supported *supported, struct supported_list **supported_list) ++{ ++ struct supported_list *supported_listp; ++ ++ if(!supported) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_insert_supported: " ++ "NULL supported handed in, failed.\n"); ++ return -EINVAL; ++ } ++ ++ if(!supported_list) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_insert_supported: " ++ "NULL supported_list handed in, failed.\n"); ++ return -EINVAL; ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_insert_supported: " ++ "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n", ++ (unsigned long) sizeof(struct supported_list), ++ supported, ++ supported_list); ++ ++ supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL); ++ if(supported_listp == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_insert_supported: " ++ "memory allocation error.\n"); ++ return -ENOMEM; ++ } ++ ++ supported_listp->supportedp = supported; ++ supported_listp->next = *supported_list; ++ *supported_list = supported_listp; ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_list_insert_supported: " ++ "outgoing, supported=0p%p, supported_list=0p%p\n", ++ supported, ++ supported_list); ++ ++ return 0; ++} ++ ++#ifndef NET_21 ++DEBUG_NO_STATIC void ++pfkey_state_change(struct sock *sk) ++{ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_state_change: .\n"); ++ if(!sk->dead) { ++ wake_up_interruptible(sk->sleep); ++ } ++} ++#endif /* !NET_21 */ ++ ++#ifndef NET_21 ++DEBUG_NO_STATIC void ++pfkey_data_ready(struct sock *sk, int len) ++{ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_data_ready: " ++ "sk=0p%p len=%d\n", ++ sk, ++ len); ++ if(!sk->dead) { ++ wake_up_interruptible(sk->sleep); ++ sock_wake_async(sk->socket, 1); ++ } ++} ++ ++DEBUG_NO_STATIC void ++pfkey_write_space(struct sock *sk) ++{ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_write_space: .\n"); ++ if(!sk->dead) { ++ wake_up_interruptible(sk->sleep); ++ sock_wake_async(sk->socket, 2); ++ } ++} ++#endif /* !NET_21 */ ++ ++DEBUG_NO_STATIC void ++pfkey_insert_socket(struct sock *sk) ++{ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_insert_socket: " ++ "sk=0p%p\n", ++ sk); ++ cli(); ++ sk->next=pfkey_sock_list; ++ pfkey_sock_list=sk; ++ sti(); ++} ++ ++DEBUG_NO_STATIC void ++pfkey_remove_socket(struct sock *sk) ++{ ++ struct sock **s; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_remove_socket: .\n"); ++ cli(); ++ s=&pfkey_sock_list; ++ ++ while(*s!=NULL) { ++ if(*s==sk) { ++ *s=sk->next; ++ sk->next=NULL; ++ sti(); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_remove_socket: " ++ "succeeded.\n"); ++ return; ++ } ++ s=&((*s)->next); ++ } ++ sti(); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_remove_socket: " ++ "not found.\n"); ++ return; ++} ++ ++DEBUG_NO_STATIC void ++pfkey_destroy_socket(struct sock *sk) ++{ ++ struct sk_buff *skb; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_destroy_socket: .\n"); ++ pfkey_remove_socket(sk); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_destroy_socket: " ++ "pfkey_remove_socket called.\n"); ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_destroy_socket: " ++ "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n", ++ sk, ++ &(sk->receive_queue), ++ sk->receive_queue.next, ++ sk->receive_queue.prev); ++ while(sk && ((skb=skb_dequeue(&(sk->receive_queue)))!=NULL)) { ++#ifdef NET_21 ++#ifdef CONFIG_IPSEC_DEBUG ++ if(debug_pfkey && sysctl_ipsec_debug_verbose) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_destroy_socket: " ++ "skb=0p%p dequeued.\n", skb); ++ printk(KERN_INFO "klips_debug:pfkey_destroy_socket: " ++ "pfkey_skb contents:"); ++ printk(" next:0p%p", skb->next); ++ printk(" prev:0p%p", skb->prev); ++ printk(" list:0p%p", skb->list); ++ printk(" sk:0p%p", skb->sk); ++ printk(" stamp:%ld.%ld", skb->stamp.tv_sec, skb->stamp.tv_usec); ++ printk(" dev:0p%p", skb->dev); ++ if(skb->dev) { ++ if(skb->dev->name) { ++ printk(" dev->name:%s", skb->dev->name); ++ } else { ++ printk(" dev->name:NULL?"); ++ } ++ } else { ++ printk(" dev:NULL"); ++ } ++ printk(" h:0p%p", skb->h.raw); ++ printk(" nh:0p%p", skb->nh.raw); ++ printk(" mac:0p%p", skb->mac.raw); ++ printk(" dst:0p%p", skb->dst); ++ if(sysctl_ipsec_debug_verbose) { ++ int i; ++ ++ printk(" cb"); ++ for(i=0; i<48; i++) { ++ printk(":%2x", skb->cb[i]); ++ } ++ } ++ printk(" len:%d", skb->len); ++ printk(" csum:%d", skb->csum); ++#ifndef NETDEV_23 ++ printk(" used:%d", skb->used); ++ printk(" is_clone:%d", skb->is_clone); ++#endif /* NETDEV_23 */ ++ printk(" cloned:%d", skb->cloned); ++ printk(" pkt_type:%d", skb->pkt_type); ++ printk(" ip_summed:%d", skb->ip_summed); ++ printk(" priority:%d", skb->priority); ++ printk(" protocol:%d", skb->protocol); ++ printk(" security:%d", skb->security); ++ printk(" truesize:%d", skb->truesize); ++ printk(" head:0p%p", skb->head); ++ printk(" data:0p%p", skb->data); ++ printk(" tail:0p%p", skb->tail); ++ printk(" end:0p%p", skb->end); ++ if(sysctl_ipsec_debug_verbose) { ++ unsigned char* i; ++ printk(" data"); ++ for(i = skb->head; i < skb->end; i++) { ++ printk(":%2x", (unsigned char)(*(i))); ++ } ++ } ++ printk(" destructor:0p%p", skb->destructor); ++ printk("\n"); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++#endif /* NET_21 */ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_destroy_socket: " ++ "skb=0p%p freed.\n", ++ skb); ++ ipsec_kfree_skb(skb); ++ } ++ ++ sk->dead = 1; ++ sk_free(sk); ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_destroy_socket: destroyed.\n"); ++} ++ ++int ++pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg) ++{ ++ int error = 0; ++ struct sk_buff * skb = NULL; ++ struct sock *sk; ++ ++ if(sock == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_upmsg: " ++ "NULL socket passed in.\n"); ++ return -EINVAL; ++ } ++ ++ if(pfkey_msg == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_upmsg: " ++ "NULL pfkey_msg passed in.\n"); ++ return -EINVAL; ++ } ++ ++#ifdef NET_21 ++ sk = sock->sk; ++#else /* NET_21 */ ++ sk = sock->data; ++#endif /* NET_21 */ ++ ++ if(sk == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_upmsg: " ++ "NULL sock passed in.\n"); ++ return -EINVAL; ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_upmsg: " ++ "allocating %d bytes...\n", ++ (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)); ++ if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_upmsg: " ++ "no buffers left to send up a message.\n"); ++ return -ENOBUFS; ++ } ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_upmsg: " ++ "...allocated at 0p%p.\n", ++ skb); ++ ++ skb->dev = NULL; ++ ++ if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) { ++ printk(KERN_WARNING "klips_error:pfkey_upmsg: " ++ "tried to skb_put %ld, %d available. This should never happen, please report.\n", ++ (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, ++ skb_tailroom(skb)); ++ ipsec_kfree_skb(skb); ++ return -ENOBUFS; ++ } ++ skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); ++ memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); ++ ++#ifndef NET_21 ++ skb->free = 1; ++#endif /* !NET_21 */ ++ ++ if((error = sock_queue_rcv_skb(sk, skb)) < 0) { ++ skb->sk=NULL; ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_upmsg: " ++ "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n", ++ error, ++ skb); ++ ipsec_kfree_skb(skb); ++ return error; ++ } ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_create(struct socket *sock, int protocol) ++{ ++ struct sock *sk; ++ ++ if(sock == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_create: " ++ "socket NULL.\n"); ++ return -EINVAL; ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_create: " ++ "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n", ++ sock, ++ sock->type, ++ (unsigned int)(sock->state), ++ sock->flags, protocol); ++ ++ if(sock->type != SOCK_RAW) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_create: " ++ "only SOCK_RAW supported.\n"); ++ return -ESOCKTNOSUPPORT; ++ } ++ ++ if(protocol != PF_KEY_V2) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_create: " ++ "protocol not PF_KEY_V2.\n"); ++ return -EPROTONOSUPPORT; ++ } ++ ++ if((current->uid != 0)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_create: " ++ "must be root to open pfkey sockets.\n"); ++ return -EACCES; ++ } ++ ++#ifdef NET_21 ++ sock->state = SS_UNCONNECTED; ++#endif /* NET_21 */ ++ MOD_INC_USE_COUNT; ++#ifdef NET_21 ++ if((sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1)) == NULL) ++#else /* NET_21 */ ++ if((sk=(struct sock *)sk_alloc(GFP_KERNEL)) == NULL) ++#endif /* NET_21 */ ++ { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_create: " ++ "Out of memory trying to allocate.\n"); ++ MOD_DEC_USE_COUNT; ++ return -ENOMEM; ++ } ++ ++#ifndef NET_21 ++ memset(sk, 0, sizeof(*sk)); ++#endif /* !NET_21 */ ++ ++#ifdef NET_21 ++ sock_init_data(sock, sk); ++ ++ sk->destruct = NULL; ++ sk->reuse = 1; ++ sock->ops = &pfkey_ops; ++ ++ sk->zapped=0; ++ sk->family = PF_KEY; ++/* sk->num = protocol; */ ++ sk->protocol = protocol; ++ key_pid(sk) = current->pid; ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_create: " ++ "sock->fasync_list=0p%p sk->sleep=0p%p.\n", ++ sock->fasync_list, ++ sk->sleep); ++#else /* NET_21 */ ++ sk->type=sock->type; ++ init_timer(&sk->timer); ++ skb_queue_head_init(&sk->write_queue); ++ skb_queue_head_init(&sk->receive_queue); ++ skb_queue_head_init(&sk->back_log); ++ sk->rcvbuf=SK_RMEM_MAX; ++ sk->sndbuf=SK_WMEM_MAX; ++ sk->allocation=GFP_KERNEL; ++ sk->state=TCP_CLOSE; ++ sk->priority=SOPRI_NORMAL; ++ sk->state_change=pfkey_state_change; ++ sk->data_ready=pfkey_data_ready; ++ sk->write_space=pfkey_write_space; ++ sk->error_report=pfkey_state_change; ++ sk->mtu=4096; ++ sk->socket=sock; ++ sock->data=(void *)sk; ++ sk->sleep=sock->wait; ++#endif /* NET_21 */ ++ ++ pfkey_insert_socket(sk); ++ pfkey_list_insert_socket(sock, &pfkey_open_sockets); ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_create: " ++ "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk); ++ return 0; ++} ++ ++#ifndef NET_21 ++DEBUG_NO_STATIC int ++pfkey_dup(struct socket *newsock, struct socket *oldsock) ++{ ++ struct sock *sk; ++ ++ if(newsock==NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_dup: " ++ "No new socket attached.\n"); ++ return -EINVAL; ++ } ++ ++ if(oldsock==NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_dup: " ++ "No old socket attached.\n"); ++ return -EINVAL; ++ } ++ ++#ifdef NET_21 ++ sk=oldsock->sk; ++#else /* NET_21 */ ++ sk=oldsock->data; ++#endif /* NET_21 */ ++ ++ /* May not have data attached */ ++ if(sk==NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_dup: " ++ "No sock attached to old socket.\n"); ++ return -EINVAL; ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_dup: .\n"); ++ ++ return pfkey_create(newsock, sk->protocol); ++} ++#endif /* !NET_21 */ ++ ++DEBUG_NO_STATIC int ++#ifdef NETDEV_23 ++pfkey_release(struct socket *sock) ++#else /* NETDEV_23 */ ++pfkey_release(struct socket *sock, struct socket *peersock) ++#endif /* NETDEV_23 */ ++{ ++ struct sock *sk; ++ int i; ++ ++ if(sock==NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_release: " ++ "No socket attached.\n"); ++ return 0; /* -EINVAL; */ ++ } ++ ++#ifdef NET_21 ++ sk=sock->sk; ++#else /* NET_21 */ ++ sk=sock->data; ++#endif /* NET_21 */ ++ ++ /* May not have data attached */ ++ if(sk==NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_release: " ++ "No sk attached to sock=0p%p.\n", sock); ++ return 0; /* -EINVAL; */ ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_release: " ++ "sock=0p%p sk=0p%p\n", sock, sk); ++ ++#ifdef NET_21 ++ if(!sk->dead) ++#endif /* NET_21 */ ++ if(sk->state_change) { ++ sk->state_change(sk); ++ } ++ ++#ifdef NET_21 ++ sock->sk = NULL; ++#else /* NET_21 */ ++ sock->data = NULL; ++#endif /* NET_21 */ ++ ++ /* Try to flush out this socket. Throw out buffers at least */ ++ pfkey_destroy_socket(sk); ++ pfkey_list_remove_socket(sock, &pfkey_open_sockets); ++ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) { ++ pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i])); ++ } ++ ++ MOD_DEC_USE_COUNT; ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_release: " ++ "succeeded.\n"); ++ ++ return 0; ++} ++ ++#ifndef NET_21 ++DEBUG_NO_STATIC int ++pfkey_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) ++{ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_bind: " ++ "operation not supported.\n"); ++ return -EINVAL; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) ++{ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_connect: " ++ "operation not supported.\n"); ++ return -EINVAL; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_socketpair(struct socket *a, struct socket *b) ++{ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_socketpair: " ++ "operation not supported.\n"); ++ return -EINVAL; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_accept(struct socket *sock, struct socket *newsock, int flags) ++{ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_aaccept: " ++ "operation not supported.\n"); ++ return -EINVAL; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, ++ int peer) ++{ ++ struct sockaddr *ska = (struct sockaddr*)uaddr; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_getname: .\n"); ++ ska->sa_family = PF_KEY; ++ *uaddr_len = sizeof(*ska); ++ return 0; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_select(struct socket *sock, int sel_type, select_table *wait) ++{ ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_select: " ++ ".sock=0p%p sk=0p%p sel_type=%d\n", ++ sock, ++ sock->data, ++ sel_type); ++ if(sock == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_select: " ++ "Null socket passed in.\n"); ++ return -EINVAL; ++ } ++ return datagram_select(sock->data, sel_type, wait); ++} ++ ++DEBUG_NO_STATIC int ++pfkey_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ++{ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ioctl: " ++ "not supported.\n"); ++ return -EINVAL; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_listen(struct socket *sock, int backlog) ++{ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_listen: " ++ "not supported.\n"); ++ return -EINVAL; ++} ++#endif /* !NET_21 */ ++ ++DEBUG_NO_STATIC int ++pfkey_shutdown(struct socket *sock, int mode) ++{ ++ struct sock *sk; ++ ++ if(sock == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_shutdown: " ++ "NULL socket passed in.\n"); ++ return -EINVAL; ++ } ++ ++#ifdef NET_21 ++ sk=sock->sk; ++#else /* NET_21 */ ++ sk=sock->data; ++#endif /* NET_21 */ ++ ++ if(sk == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_shutdown: " ++ "No sock attached to socket.\n"); ++ return -EINVAL; ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_shutdown: " ++ "mode=%x.\n", mode); ++ mode++; ++ ++ if(mode&SEND_SHUTDOWN) { ++ sk->shutdown|=SEND_SHUTDOWN; ++ sk->state_change(sk); ++ } ++ ++ if(mode&RCV_SHUTDOWN) { ++ sk->shutdown|=RCV_SHUTDOWN; ++ sk->state_change(sk); ++ } ++ return 0; ++} ++ ++#ifndef NET_21 ++DEBUG_NO_STATIC int ++pfkey_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen) ++{ ++#ifndef NET_21 ++ struct sock *sk; ++ ++ if(sock == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_setsockopt: " ++ "Null socket passed in.\n"); ++ return -EINVAL; ++ } ++ ++ sk=sock->data; ++ ++ if(sk == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_setsockopt: " ++ "Null sock passed in.\n"); ++ return -EINVAL; ++ } ++#endif /* !NET_21 */ ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_setsockopt: .\n"); ++ if(level!=SOL_SOCKET) { ++ return -EOPNOTSUPP; ++ } ++#ifdef NET_21 ++ return sock_setsockopt(sock, level, optname, optval, optlen); ++#else /* NET_21 */ ++ return sock_setsockopt(sk, level, optname, optval, optlen); ++#endif /* NET_21 */ ++} ++ ++DEBUG_NO_STATIC int ++pfkey_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen) ++{ ++#ifndef NET_21 ++ struct sock *sk; ++ ++ if(sock == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_setsockopt: " ++ "Null socket passed in.\n"); ++ return -EINVAL; ++ } ++ ++ sk=sock->data; ++ ++ if(sk == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_setsockopt: " ++ "Null sock passed in.\n"); ++ return -EINVAL; ++ } ++#endif /* !NET_21 */ ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_getsockopt: .\n"); ++ if(level!=SOL_SOCKET) { ++ return -EOPNOTSUPP; ++ } ++#ifdef NET_21 ++ return sock_getsockopt(sock, level, optname, optval, optlen); ++#else /* NET_21 */ ++ return sock_getsockopt(sk, level, optname, optval, optlen); ++#endif /* NET_21 */ ++} ++ ++DEBUG_NO_STATIC int ++pfkey_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg) ++{ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_fcntl: " ++ "not supported.\n"); ++ return -EINVAL; ++} ++#endif /* !NET_21 */ ++ ++/* ++ * Send PF_KEY data down. ++ */ ++ ++DEBUG_NO_STATIC int ++#ifdef NET_21 ++pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm) ++#else /* NET_21 */ ++pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags) ++#endif /* NET_21 */ ++{ ++ struct sock *sk; ++ int error = 0; ++ struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL; ++ ++ if(sock == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "Null socket passed in.\n"); ++ SENDERR(EINVAL); ++ } ++ ++#ifdef NET_21 ++ sk = sock->sk; ++#else /* NET_21 */ ++ sk = sock->data; ++#endif /* NET_21 */ ++ ++ if(sk == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "Null sock passed in.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(msg == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "Null msghdr passed in.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: .\n"); ++ if(sk->err) { ++ error = sock_error(sk); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "sk->err is non-zero, returns %d.\n", ++ error); ++ SENDERR(-error); ++ } ++ ++ if((current->uid != 0)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "must be root to send messages to pfkey sockets.\n"); ++ SENDERR(EACCES); ++ } ++ ++#ifdef NET_21 ++ if(msg->msg_control) ++#else /* NET_21 */ ++ if(flags || msg->msg_control) ++#endif /* NET_21 */ ++ { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "can't set flags or set msg_control.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(sk->shutdown & SEND_SHUTDOWN) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "shutdown.\n"); ++ send_sig(SIGPIPE, current, 0); ++ SENDERR(EPIPE); ++ } ++ ++ if(len < sizeof(struct sadb_msg)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "bogus msg len of %d, too small.\n", len); ++ SENDERR(EMSGSIZE); ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "allocating %d bytes for downward message.\n", ++ len); ++ if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "memory allocation error.\n"); ++ SENDERR(ENOBUFS); ++ } ++ ++ memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len); ++ ++ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) { ++ KLIPS_PRINT(1 || debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "not PF_KEY_V2 msg, found %d, should be %d.\n", ++ pfkey_msg->sadb_msg_version, ++ PF_KEY_V2); ++ kfree((void*)pfkey_msg); ++ return -EINVAL; ++ } ++ ++ if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "bogus msg len of %d, not %d byte aligned.\n", ++ len, (int)IPSEC_PFKEYv2_ALIGN); ++ SENDERR(EMSGSIZE); ++ } ++ ++#if 0 ++ /* This check is questionable, since a downward message could be ++ the result of an ACQUIRE either from kernel (PID==0) or ++ userspace (some other PID). */ ++ /* check PID */ ++ if(pfkey_msg->sadb_msg_pid != current->pid) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "pid (%d) does not equal sending process pid (%d).\n", ++ pfkey_msg->sadb_msg_pid, current->pid); ++ SENDERR(EINVAL); ++ } ++#endif ++ ++ if(pfkey_msg->sadb_msg_reserved) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "reserved field must be zero, set to %d.\n", ++ pfkey_msg->sadb_msg_reserved); ++ SENDERR(EINVAL); ++ } ++ ++ if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "msg type too large or small:%d.\n", ++ pfkey_msg->sadb_msg_type); ++ SENDERR(EINVAL); ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "msg sent for parsing.\n"); ++ ++ if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) { ++ struct socket_list *pfkey_socketsp; ++ ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " ++ "pfkey_msg_parse returns %d.\n", ++ error); ++ ++ if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "memory allocation error.\n"); ++ SENDERR(ENOBUFS); ++ } ++ memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg)); ++ pfkey_reply->sadb_msg_errno = -error; ++ pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; ++ ++ for(pfkey_socketsp = pfkey_open_sockets; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ int error_upmsg = 0; ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " ++ "sending up error=%d message=0p%p to socket=0p%p.\n", ++ error, ++ pfkey_reply, ++ pfkey_socketsp->socketp); ++ if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " ++ "sending up error message to socket=0p%p failed with error=%d.\n", ++ pfkey_socketsp->socketp, ++ error_upmsg); ++ /* pfkey_msg_free(&pfkey_reply); */ ++ /* SENDERR(-error); */ ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " ++ "sending up error message to socket=0p%p succeeded.\n", ++ pfkey_socketsp->socketp); ++ } ++ ++ pfkey_msg_free(&pfkey_reply); ++ ++ SENDERR(-error); ++ } ++ ++ errlab: ++ if (pfkey_msg) { ++ kfree((void*)pfkey_msg); ++ } ++ ++ if(error) { ++ return error; ++ } else { ++ return len; ++ } ++} ++ ++/* ++ * Receive PF_KEY data up. ++ */ ++ ++DEBUG_NO_STATIC int ++#ifdef NET_21 ++pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm) ++#else /* NET_21 */ ++pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len) ++#endif /* NET_21 */ ++{ ++ struct sock *sk; ++#ifdef NET_21 ++ int noblock = flags & MSG_DONTWAIT; ++#endif /* NET_21 */ ++ struct sk_buff *skb; ++ int error; ++ ++ if(sock == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_recvmsg: " ++ "Null socket passed in.\n"); ++ return -EINVAL; ++ } ++ ++#ifdef NET_21 ++ sk = sock->sk; ++#else /* NET_21 */ ++ sk = sock->data; ++#endif /* NET_21 */ ++ ++ if(sk == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_recvmsg: " ++ "Null sock passed in for sock=0p%p.\n", sock); ++ return -EINVAL; ++ } ++ ++ if(msg == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_recvmsg: " ++ "Null msghdr passed in for sock=0p%p, sk=0p%p.\n", ++ sock, sk); ++ return -EINVAL; ++ } ++ ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n", ++ sock, sk, msg, size); ++ if(flags & ~MSG_PEEK) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "flags (%d) other than MSG_PEEK not supported.\n", ++ flags); ++ return -EOPNOTSUPP; ++ } ++ ++#ifdef NET_21 ++ msg->msg_namelen = 0; /* sizeof(*ska); */ ++#else /* NET_21 */ ++ if(addr_len) { ++ *addr_len = 0; /* sizeof(*ska); */ ++ } ++#endif /* NET_21 */ ++ ++ if(sk->err) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sendmsg: " ++ "sk->err=%d.\n", sk->err); ++ return sock_error(sk); ++ } ++ ++ if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) { ++ return error; ++ } ++ ++ if(size > skb->len) { ++ size = skb->len; ++ } ++#ifdef NET_21 ++ else if(size len) { ++ msg->msg_flags |= MSG_TRUNC; ++ } ++#endif /* NET_21 */ ++ ++ skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size); ++ sk->stamp=skb->stamp; ++ ++ skb_free_datagram(sk, skb); ++ return size; ++} ++ ++#ifdef NET_21 ++struct net_proto_family pfkey_family_ops = { ++ PF_KEY, ++ pfkey_create ++}; ++ ++struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = { ++#ifdef NETDEV_23 ++ family: PF_KEY, ++ release: pfkey_release, ++ bind: sock_no_bind, ++ connect: sock_no_connect, ++ socketpair: sock_no_socketpair, ++ accept: sock_no_accept, ++ getname: sock_no_getname, ++ poll: datagram_poll, ++ ioctl: sock_no_ioctl, ++ listen: sock_no_listen, ++ shutdown: pfkey_shutdown, ++ setsockopt: sock_no_setsockopt, ++ getsockopt: sock_no_getsockopt, ++ sendmsg: pfkey_sendmsg, ++ recvmsg: pfkey_recvmsg, ++ mmap: sock_no_mmap, ++#else /* NETDEV_23 */ ++ PF_KEY, ++ sock_no_dup, ++ pfkey_release, ++ sock_no_bind, ++ sock_no_connect, ++ sock_no_socketpair, ++ sock_no_accept, ++ sock_no_getname, ++ datagram_poll, ++ sock_no_ioctl, ++ sock_no_listen, ++ pfkey_shutdown, ++ sock_no_setsockopt, ++ sock_no_getsockopt, ++ sock_no_fcntl, ++ pfkey_sendmsg, ++ pfkey_recvmsg ++#endif /* NETDEV_23 */ ++}; ++ ++#ifdef NETDEV_23 ++#include ++SOCKOPS_WRAP(pfkey, PF_KEY); ++#endif /* NETDEV_23 */ ++ ++#else /* NET_21 */ ++struct proto_ops pfkey_proto_ops = { ++ PF_KEY, ++ pfkey_create, ++ pfkey_dup, ++ pfkey_release, ++ pfkey_bind, ++ pfkey_connect, ++ pfkey_socketpair, ++ pfkey_accept, ++ pfkey_getname, ++ pfkey_select, ++ pfkey_ioctl, ++ pfkey_listen, ++ pfkey_shutdown, ++ pfkey_setsockopt, ++ pfkey_getsockopt, ++ pfkey_fcntl, ++ pfkey_sendmsg, ++ pfkey_recvmsg ++}; ++#endif /* NET_21 */ ++ ++#ifdef CONFIG_PROC_FS ++#ifndef PROC_FS_2325 ++DEBUG_NO_STATIC ++#endif /* PROC_FS_2325 */ ++int ++pfkey_get_info(char *buffer, char **start, off_t offset, int length ++#ifndef PROC_NO_DUMMY ++, int dummy ++#endif /* !PROC_NO_DUMMY */ ++) ++{ ++ const int max_content = length > 0? length-1 : 0; ++ off_t begin=0; ++ int len=0; ++ struct sock *sk=pfkey_sock_list; ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if(!sysctl_ipsec_debug_verbose) { ++#endif /* CONFIG_IPSEC_DEBUG */ ++ len+= snprintf(buffer,length, ++ " sock pid socket next prev e n p sndbf Flags Type St\n"); ++#ifdef CONFIG_IPSEC_DEBUG ++ } else { ++ len+= snprintf(buffer,length, ++ " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n"); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ while(sk!=NULL) { ++#ifdef CONFIG_IPSEC_DEBUG ++ if(!sysctl_ipsec_debug_verbose) { ++#endif /* CONFIG_IPSEC_DEBUG */ ++ len += ipsec_snprintf(buffer+len, length-len, ++ "%8p %5d %8p %8p %8p %d %d %d %5d %08lX %8X %2X\n", ++ sk, ++ key_pid(sk), ++ sk->socket, ++ sk->next, ++ sk->prev, ++ sk->err, ++ sk->num, ++ sk->protocol, ++ sk->sndbuf, ++ sk->socket->flags, ++ sk->socket->type, ++ sk->socket->state); ++#ifdef CONFIG_IPSEC_DEBUG ++ } else { ++ len += ipsec_snprintf(buffer+len, length-len, ++ "%8p %5d %d %8p %8p %8p %8p %d %d %d %d %d %5d %d.%06d %08lX %8X %2X\n", ++ sk, ++ key_pid(sk), ++ sk->dead, ++ sk->sleep, ++ sk->socket, ++ sk->next, ++ sk->prev, ++ sk->err, ++ sk->reuse, ++ sk->zapped, ++ sk->num, ++ sk->protocol, ++ sk->sndbuf, ++ (unsigned int)sk->stamp.tv_sec, ++ (unsigned int)sk->stamp.tv_usec, ++ sk->socket->flags, ++ sk->socket->type, ++ sk->socket->state); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ if (len >= max_content) { ++ /* we've done all that can fit -- stop loop */ ++ len = max_content; /* truncate crap */ ++ break; ++ } else { ++ ++ const off_t pos = begin + len; /* file position of end of what we've generated */ ++ ++ if (pos <= offset) { ++ /* all is before first interesting character: ++ * discard, but note where we are. ++ */ ++ len = 0; ++ begin = pos; ++ } ++ } ++ sk=sk->next; ++ ++ } ++ ++ *start = buffer + (offset - begin); /* Start of wanted data */ ++ return len - (offset - begin); ++ ++} ++ ++#ifndef PROC_FS_2325 ++DEBUG_NO_STATIC ++#endif /* PROC_FS_2325 */ ++int ++pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length ++#ifndef PROC_NO_DUMMY ++, int dummy ++#endif /* !PROC_NO_DUMMY */ ++) ++{ ++ const int max_content = length > 0? length-1 : 0; ++ off_t begin=0; ++ int len=0; ++ int satype; ++ struct supported_list *pfkey_supported_p; ++ ++ len += ipsec_snprintf(buffer, length, ++ "satype exttype alg_id ivlen minbits maxbits\n"); ++ ++ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) { ++ pfkey_supported_p = pfkey_supported_list[satype]; ++ while(pfkey_supported_p) { ++ len += ipsec_snprintf(buffer+len, length-len, ++ " %2d %2d %2d %3d %3d %3d\n", ++ satype, ++ pfkey_supported_p->supportedp->supported_alg_exttype, ++ pfkey_supported_p->supportedp->supported_alg_id, ++ pfkey_supported_p->supportedp->supported_alg_ivlen, ++ pfkey_supported_p->supportedp->supported_alg_minbits, ++ pfkey_supported_p->supportedp->supported_alg_maxbits); ++ ++ if (len >= max_content) { ++ /* we've done all that can fit -- stop loop */ ++ len = max_content; /* truncate crap */ ++ break; ++ } else { ++ const off_t pos = begin + len; /* file position of end of what we've generated */ ++ ++ if (pos <= offset) { ++ /* all is before first interesting character: ++ * discard, but note where we are. ++ */ ++ len = 0; ++ begin = pos; ++ } ++ } ++ ++ pfkey_supported_p = pfkey_supported_p->next; ++ } ++ } ++ ++ *start = buffer + (offset - begin); /* Start of wanted data */ ++ return len - (offset - begin); ++ ++} ++ ++#ifndef PROC_FS_2325 ++DEBUG_NO_STATIC ++#endif /* PROC_FS_2325 */ ++int ++pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length ++#ifndef PROC_NO_DUMMY ++, int dummy ++#endif /* !PROC_NO_DUMMY */ ++) ++{ ++ const int max_content = length > 0? length-1 : 0; ++ off_t begin=0; ++ int len=0; ++ int satype; ++ struct socket_list *pfkey_sockets; ++ ++ len += ipsec_snprintf(buffer, length, ++ "satype socket pid sk\n"); ++ ++ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) { ++ pfkey_sockets = pfkey_registered_sockets[satype]; ++ while(pfkey_sockets) { ++#ifdef NET_21 ++ len += ipsec_snprintf(buffer+len, length-len, ++ " %2d %8p %5d %8p\n", ++ satype, ++ pfkey_sockets->socketp, ++ key_pid(pfkey_sockets->socketp->sk), ++ pfkey_sockets->socketp->sk); ++#else /* NET_21 */ ++ len += ipsec_snprintf(buffer+len, length-len, ++ " %2d %8p N/A %8p\n", ++ satype, ++ pfkey_sockets->socketp, ++#if 0 ++ key_pid((pfkey_sockets->socketp)->data), ++#endif ++ (pfkey_sockets->socketp)->data); ++#endif /* NET_21 */ ++ ++ if (len >= max_content) { ++ /* we've done all that can fit -- stop loop (could stop two) */ ++ len = max_content; /* truncate crap */ ++ break; ++ } else { ++ const off_t pos = begin + len; /* file position of end of what we've generated */ ++ ++ if (pos <= offset) { ++ /* all is before first interesting character: ++ * discard, but note where we are. ++ */ ++ len = 0; ++ begin = pos; ++ } ++ } ++ ++ ++ pfkey_sockets = pfkey_sockets->next; ++ } ++ } ++ *start = buffer + (offset - begin); /* Start of wanted data */ ++ return len - (offset - begin); ++} ++ ++#ifndef PROC_FS_2325 ++struct proc_dir_entry proc_net_pfkey = ++{ ++ 0, ++ 6, "pf_key", ++ S_IFREG | S_IRUGO, 1, 0, 0, ++ 0, &proc_net_inode_operations, ++ pfkey_get_info ++}; ++struct proc_dir_entry proc_net_pfkey_supported = ++{ ++ 0, ++ 16, "pf_key_supported", ++ S_IFREG | S_IRUGO, 1, 0, 0, ++ 0, &proc_net_inode_operations, ++ pfkey_supported_get_info ++}; ++struct proc_dir_entry proc_net_pfkey_registered = ++{ ++ 0, ++ 17, "pf_key_registered", ++ S_IFREG | S_IRUGO, 1, 0, 0, ++ 0, &proc_net_inode_operations, ++ pfkey_registered_get_info ++}; ++#endif /* !PROC_FS_2325 */ ++#endif /* CONFIG_PROC_FS */ ++ ++DEBUG_NO_STATIC int ++supported_add_all(int satype, struct supported supported[], int size) ++{ ++ int i; ++ int error = 0; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:init_pfkey: " ++ "sizeof(supported_init_)[%d]/sizeof(struct supported)[%d]=%d.\n", ++ satype, ++ size, ++ (int)sizeof(struct supported), ++ (int)(size/sizeof(struct supported))); ++ ++ for(i = 0; i < size / sizeof(struct supported); i++) { ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:init_pfkey: " ++ "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n", ++ i, ++ satype, ++ supported[i].supported_alg_exttype, ++ supported[i].supported_alg_id, ++ supported[i].supported_alg_ivlen, ++ supported[i].supported_alg_minbits, ++ supported[i].supported_alg_maxbits); ++ ++ error |= pfkey_list_insert_supported(&(supported[i]), ++ &(pfkey_supported_list[satype])); ++ } ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++supported_remove_all(int satype) ++{ ++ int error = 0; ++ struct supported*supportedp; ++ ++ while(pfkey_supported_list[satype]) { ++ supportedp = pfkey_supported_list[satype]->supportedp; ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:init_pfkey: " ++ "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n", ++ satype, ++ supportedp->supported_alg_exttype, ++ supportedp->supported_alg_id, ++ supportedp->supported_alg_ivlen, ++ supportedp->supported_alg_minbits, ++ supportedp->supported_alg_maxbits); ++ ++ error |= pfkey_list_remove_supported(supportedp, ++ &(pfkey_supported_list[satype])); ++ } ++ return error; ++} ++ ++int ++pfkey_init(void) ++{ ++ int error = 0; ++ int i; ++ ++ static struct supported supported_init_ah[] = { ++#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128}, ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160} ++#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++ }; ++ static struct supported supported_init_esp[] = { ++#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128}, ++#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}, ++#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++#ifdef CONFIG_IPSEC_ENC_3DES ++ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 64, 168, 168}, ++#endif /* CONFIG_IPSEC_ENC_3DES */ ++ }; ++ static struct supported supported_init_ipip[] = { ++ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32} ++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32} ++ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128} ++ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128} ++#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ ++ }; ++#ifdef CONFIG_IPSEC_IPCOMP ++ static struct supported supported_init_ipcomp[] = { ++ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1} ++ }; ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ ++#if 0 ++ printk(KERN_INFO ++ "klips_info:pfkey_init: " ++ "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n"); ++#endif ++ ++ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) { ++ pfkey_registered_sockets[i] = NULL; ++ pfkey_supported_list[i] = NULL; ++ } ++ ++ error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah)); ++ error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp)); ++#ifdef CONFIG_IPSEC_IPCOMP ++ error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp)); ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip)); ++ ++#ifdef NET_21 ++ error |= sock_register(&pfkey_family_ops); ++#else /* NET_21 */ ++ error |= sock_register(pfkey_proto_ops.family, &pfkey_proto_ops); ++#endif /* NET_21 */ ++ ++#ifdef CONFIG_PROC_FS ++# ifndef PROC_FS_2325 ++# ifdef PROC_FS_21 ++ error |= proc_register(proc_net, &proc_net_pfkey); ++ error |= proc_register(proc_net, &proc_net_pfkey_supported); ++ error |= proc_register(proc_net, &proc_net_pfkey_registered); ++# else /* PROC_FS_21 */ ++ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey); ++ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported); ++ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered); ++# endif /* PROC_FS_21 */ ++# else /* !PROC_FS_2325 */ ++ proc_net_create ("pf_key", 0, pfkey_get_info); ++ proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info); ++ proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info); ++# endif /* !PROC_FS_2325 */ ++#endif /* CONFIG_PROC_FS */ ++ ++ return error; ++} ++ ++int ++pfkey_cleanup(void) ++{ ++ int error = 0; ++ ++ printk(KERN_INFO "klips_info:pfkey_cleanup: " ++ "shutting down PF_KEY domain sockets.\n"); ++#ifdef NET_21 ++ error |= sock_unregister(PF_KEY); ++#else /* NET_21 */ ++ error |= sock_unregister(pfkey_proto_ops.family); ++#endif /* NET_21 */ ++ ++ error |= supported_remove_all(SADB_SATYPE_AH); ++ error |= supported_remove_all(SADB_SATYPE_ESP); ++#ifdef CONFIG_IPSEC_IPCOMP ++ error |= supported_remove_all(SADB_X_SATYPE_COMP); ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ error |= supported_remove_all(SADB_X_SATYPE_IPIP); ++ ++#ifdef CONFIG_PROC_FS ++# ifndef PROC_FS_2325 ++ if (proc_net_unregister(proc_net_pfkey.low_ino) != 0) ++ printk("klips_debug:pfkey_cleanup: " ++ "cannot unregister /proc/net/pf_key\n"); ++ if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0) ++ printk("klips_debug:pfkey_cleanup: " ++ "cannot unregister /proc/net/pf_key_supported\n"); ++ if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0) ++ printk("klips_debug:pfkey_cleanup: " ++ "cannot unregister /proc/net/pf_key_registered\n"); ++# else /* !PROC_FS_2325 */ ++ proc_net_remove ("pf_key"); ++ proc_net_remove ("pf_key_supported"); ++ proc_net_remove ("pf_key_registered"); ++# endif /* !PROC_FS_2325 */ ++#endif /* CONFIG_PROC_FS */ ++ ++ /* other module unloading cleanup happens here */ ++ return error; ++} ++ ++#ifdef MODULE ++#if 0 ++int ++init_module(void) ++{ ++ pfkey_init(); ++ return 0; ++} ++ ++void ++cleanup_module(void) ++{ ++ pfkey_cleanup(); ++} ++#endif /* 0 */ ++#else /* MODULE */ ++void ++pfkey_proto_init(struct net_proto *pro) ++{ ++ pfkey_init(); ++} ++#endif /* MODULE */ ++ ++/* ++ * $Log: pfkey_v2.c,v $ ++ * Revision 1.81 2004/04/25 21:23:11 ken ++ * Pull in dhr's changes from FreeS/WAN 2.06 ++ * ++ * Revision 1.80 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.79.4.1 2003/12/22 15:25:52 jjo ++ * . Merged algo-0.8.1-rc11-test1 into alg-branch ++ * ++ * Revision 1.79 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.78.4.1 2003/10/29 01:30:41 mcr ++ * elimited "struct sa_id". ++ * ++ * Revision 1.78 2003/04/03 17:38:09 rgb ++ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. ++ * ++ * Revision 1.77 2002/10/17 16:49:36 mcr ++ * sock->ops should reference the unwrapped options so that ++ * we get hacked in locking on SMP systems. ++ * ++ * Revision 1.76 2002/10/12 23:11:53 dhr ++ * ++ * [KenB + DHR] more 64-bit cleanup ++ * ++ * Revision 1.75 2002/09/20 05:01:57 rgb ++ * Added memory allocation debugging. ++ * ++ * Revision 1.74 2002/09/19 02:42:50 mcr ++ * do not define the pfkey_ops function for now. ++ * ++ * Revision 1.73 2002/09/17 17:29:23 mcr ++ * #if 0 out some dead code - pfkey_ops is never used as written. ++ * ++ * Revision 1.72 2002/07/24 18:44:54 rgb ++ * Type fiddling to tame ia64 compiler. ++ * ++ * Revision 1.71 2002/05/23 07:14:11 rgb ++ * Cleaned up %p variants to 0p%p for test suite cleanup. ++ * ++ * Revision 1.70 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.69 2002/04/24 07:36:33 mcr ++ * Moved from ./klips/net/ipsec/pfkey_v2.c,v ++ * ++ * Revision 1.68 2002/03/08 01:15:17 mcr ++ * put some internal structure only debug messages behind ++ * && sysctl_ipsec_debug_verbose. ++ * ++ * Revision 1.67 2002/01/29 17:17:57 mcr ++ * moved include of ipsec_param.h to after include of linux/kernel.h ++ * otherwise, it seems that some option that is set in ipsec_param.h ++ * screws up something subtle in the include path to kernel.h, and ++ * it complains on the snprintf() prototype. ++ * ++ * Revision 1.66 2002/01/29 04:00:54 mcr ++ * more excise of kversions.h header. ++ * ++ * Revision 1.65 2002/01/29 02:13:18 mcr ++ * introduction of ipsec_kversion.h means that include of ++ * ipsec_param.h must preceed any decisions about what files to ++ * include to deal with differences in kernel source. ++ * ++ * Revision 1.64 2001/11/26 09:23:51 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.61.2.1 2001/09/25 02:28:44 mcr ++ * cleaned up includes. ++ * ++ * Revision 1.63 2001/11/12 19:38:00 rgb ++ * Continue trying other sockets even if one fails and return only original ++ * error. ++ * ++ * Revision 1.62 2001/10/18 04:45:22 rgb ++ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, ++ * lib/freeswan.h version macros moved to lib/kversions.h. ++ * Other compiler directive cleanups. ++ * ++ * Revision 1.61 2001/09/20 15:32:59 rgb ++ * Min/max cleanup. ++ * ++ * Revision 1.60 2001/06/14 19:35:12 rgb ++ * Update copyright date. ++ * ++ * Revision 1.59 2001/06/13 15:35:48 rgb ++ * Fixed #endif comments. ++ * ++ * Revision 1.58 2001/05/04 16:37:24 rgb ++ * Remove erroneous checking of return codes for proc_net_* in 2.4. ++ * ++ * Revision 1.57 2001/05/03 19:43:36 rgb ++ * Initialise error return variable. ++ * Check error return codes in startup and shutdown. ++ * Standardise on SENDERR() macro. ++ * ++ * Revision 1.56 2001/04/21 23:05:07 rgb ++ * Define out skb->used for 2.4 kernels. ++ * ++ * Revision 1.55 2001/02/28 05:03:28 rgb ++ * Clean up and rationalise startup messages. ++ * ++ * Revision 1.54 2001/02/27 22:24:55 rgb ++ * Re-formatting debug output (line-splitting, joining, 1arg/line). ++ * Check for satoa() return codes. ++ * ++ * Revision 1.53 2001/02/27 06:48:18 rgb ++ * Fixed pfkey socket unregister log message to reflect type and function. ++ * ++ * Revision 1.52 2001/02/26 22:34:38 rgb ++ * Fix error return code that was getting overwritten by the error return ++ * code of an upmsg. ++ * ++ * Revision 1.51 2001/01/30 23:42:47 rgb ++ * Allow pfkey msgs from pid other than user context required for ACQUIRE ++ * and subsequent ADD or UDATE. ++ * ++ * Revision 1.50 2001/01/23 20:22:59 rgb ++ * 2.4 fix to remove removed is_clone member. ++ * ++ * Revision 1.49 2000/11/06 04:33:47 rgb ++ * Changed non-exported functions to DEBUG_NO_STATIC. ++ * ++ * Revision 1.48 2000/09/29 19:47:41 rgb ++ * Update copyright. ++ * ++ * Revision 1.47 2000/09/22 04:23:04 rgb ++ * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error. ++ * ++ * Revision 1.46 2000/09/21 04:20:44 rgb ++ * Fixed array size off-by-one error. (Thanks Svenning!) ++ * ++ * Revision 1.45 2000/09/20 04:01:26 rgb ++ * Changed static functions to DEBUG_NO_STATIC for revealing function names ++ * in oopsen. ++ * ++ * Revision 1.44 2000/09/19 00:33:17 rgb ++ * 2.0 fixes. ++ * ++ * Revision 1.43 2000/09/16 01:28:13 rgb ++ * Fixed use of 0 in p format warning. ++ * ++ * Revision 1.42 2000/09/16 01:09:41 rgb ++ * Fixed debug format warning for pointers that was expecting ints. ++ * ++ * Revision 1.41 2000/09/13 15:54:00 rgb ++ * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info(). ++ * Moved supported algos add and remove to functions. ++ * ++ * Revision 1.40 2000/09/12 18:49:28 rgb ++ * Added IPIP tunnel and IPCOMP register support. ++ * ++ * Revision 1.39 2000/09/12 03:23:49 rgb ++ * Converted #if0 debugs to sysctl. ++ * Removed debug_pfkey initialisations that prevented no_debug loading or ++ * linking. ++ * ++ * Revision 1.38 2000/09/09 06:38:02 rgb ++ * Return positive errno in pfkey_reply error message. ++ * ++ * Revision 1.37 2000/09/08 19:19:09 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * Clean-up of long-unused crud... ++ * Create pfkey error message on on failure. ++ * Give pfkey_list_{insert,remove}_{socket,supported}() some error ++ * checking. ++ * ++ * Revision 1.36 2000/09/01 18:49:38 rgb ++ * Reap experimental NET_21_ bits. ++ * Turned registered sockets list into an array of one list per satype. ++ * Remove references to deprecated sklist_{insert,remove}_socket. ++ * Removed leaking socket debugging code. ++ * Removed duplicate pfkey_insert_socket in pfkey_create. ++ * Removed all references to pfkey msg->msg_name, since it is not used for ++ * pfkey. ++ * Added a supported algorithms array lists, one per satype and registered ++ * existing algorithms. ++ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to ++ * list. ++ * Only send pfkey_expire() messages to sockets registered for that satype. ++ * ++ * Revision 1.35 2000/08/24 17:03:00 rgb ++ * Corrected message size error return code for PF_KEYv2. ++ * Removed downward error prohibition. ++ * ++ * Revision 1.34 2000/08/21 16:32:26 rgb ++ * Re-formatted for cosmetic consistency and readability. ++ * ++ * Revision 1.33 2000/08/20 21:38:24 rgb ++ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil) ++ * Extended the upward message initiation of pfkey_sendmsg(). (Momchil) ++ * ++ * Revision 1.32 2000/07/28 14:58:31 rgb ++ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. ++ * ++ * Revision 1.31 2000/05/16 03:04:00 rgb ++ * Updates for 2.3.99pre8 from MB. ++ * ++ * Revision 1.30 2000/05/10 19:22:21 rgb ++ * Use sklist private functions for 2.3.xx compatibility. ++ * ++ * Revision 1.29 2000/03/22 16:17:03 rgb ++ * Fixed SOCKOPS_WRAPPED macro for SMP (MB). ++ * ++ * Revision 1.28 2000/02/21 19:30:45 rgb ++ * Removed references to pkt_bridged for 2.3.47 compatibility. ++ * ++ * Revision 1.27 2000/02/14 21:07:00 rgb ++ * Fixed /proc/net/pf-key legend spacing. ++ * ++ * Revision 1.26 2000/01/22 03:46:59 rgb ++ * Fixed pfkey error return mechanism so that we are able to free the ++ * local copy of the pfkey_msg, plugging a memory leak and silencing ++ * the bad object free complaints. ++ * ++ * Revision 1.25 2000/01/21 06:19:44 rgb ++ * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT. ++ * Added debugging to pfkey_upmsg. ++ * ++ * Revision 1.24 2000/01/10 16:38:23 rgb ++ * MB fixups for 2.3.x. ++ * ++ * Revision 1.23 1999/12/09 23:22:16 rgb ++ * Added more instrumentation for debugging 2.0 socket ++ * selection/reading. ++ * Removed erroneous 2.0 wait==NULL check bug in select. ++ * ++ * Revision 1.22 1999/12/08 20:32:16 rgb ++ * Tidied up 2.0.xx support, after major pfkey work, eliminating ++ * msg->msg_name twiddling in the process, since it is not defined ++ * for PF_KEYv2. ++ * ++ * Revision 1.21 1999/12/01 22:17:19 rgb ++ * Set skb->dev to zero on new skb in case it is a reused skb. ++ * Added check for skb_put overflow and freeing to avoid upmsg on error. ++ * Added check for wrong pfkey version and freeing to avoid upmsg on ++ * error. ++ * Shut off content dumping in pfkey_destroy. ++ * Added debugging message for size of buffer allocated for upmsg. ++ * ++ * Revision 1.20 1999/11/27 12:11:00 rgb ++ * Minor clean-up, enabling quiet operation of pfkey if desired. ++ * ++ * Revision 1.19 1999/11/25 19:04:21 rgb ++ * Update proc_fs code for pfkey to use dynamic registration. ++ * ++ * Revision 1.18 1999/11/25 09:07:17 rgb ++ * Implemented SENDERR macro for propagating error codes. ++ * Fixed error return code bug. ++ * ++ * Revision 1.17 1999/11/23 23:07:20 rgb ++ * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer ++ * parses. (PJO) ++ * Sort out pfkey and freeswan headers, putting them in a library path. ++ * ++ * Revision 1.16 1999/11/20 22:00:22 rgb ++ * Moved socketlist type declarations and prototypes for shared use. ++ * Renamed reformatted and generically extended for use by other socket ++ * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket. ++ * ++ * Revision 1.15 1999/11/18 04:15:09 rgb ++ * Make pfkey_data_ready temporarily available for 2.2.x testing. ++ * Clean up pfkey_destroy_socket() debugging statements. ++ * Add Peter Onion's code to send messages up to all listening sockets. ++ * Changed all occurrences of #include "../../../lib/freeswan.h" ++ * to #include which works due to -Ilibfreeswan in the ++ * klips/net/ipsec/Makefile. ++ * Replaced all kernel version macros to shorter, readable form. ++ * Added CONFIG_PROC_FS compiler directives in case it is shut off. ++ * ++ * Revision 1.14 1999/11/17 16:01:00 rgb ++ * Make pfkey_data_ready temporarily available for 2.2.x testing. ++ * Clean up pfkey_destroy_socket() debugging statements. ++ * Add Peter Onion's code to send messages up to all listening sockets. ++ * Changed #include "../../../lib/freeswan.h" to #include ++ * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile. ++ * ++ * Revision 1.13 1999/10/27 19:59:51 rgb ++ * Removed af_unix comments that are no longer relevant. ++ * Added debug prink statements. ++ * Added to the /proc output in pfkey_get_info. ++ * Made most functions non-static to enable oops tracing. ++ * Re-enable skb dequeueing and freeing. ++ * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg(). ++ * ++ * Revision 1.12 1999/10/26 17:05:42 rgb ++ * Complete re-ordering based on proto_ops structure order. ++ * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity. ++ * Simplification to use built-in socket ops where possible for 2.2.x. ++ * Add shorter macros for compiler directives to visually clean-up. ++ * Add lots of sk skb dequeueing debugging statements. ++ * Added to the /proc output in pfkey_get_info. ++ * ++ * Revision 1.11 1999/09/30 02:55:10 rgb ++ * Bogus skb detection. ++ * Fix incorrect /proc/net/ipsec-eroute printk message. ++ * ++ * Revision 1.10 1999/09/21 15:22:13 rgb ++ * Temporary fix while I figure out the right way to destroy sockets. ++ * ++ * Revision 1.9 1999/07/08 19:19:44 rgb ++ * Fix pointer format warning. ++ * Fix missing member error under 2.0.xx kernels. ++ * ++ * Revision 1.8 1999/06/13 07:24:04 rgb ++ * Add more debugging. ++ * ++ * Revision 1.7 1999/06/10 05:24:17 rgb ++ * Clarified compiler directives. ++ * Renamed variables to reduce confusion. ++ * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support. ++ * Added lots of sanity checking. ++ * ++ * Revision 1.6 1999/06/03 18:59:50 rgb ++ * More updates to 2.2.x socket support. Almost works, oops at end of call. ++ * ++ * Revision 1.5 1999/05/25 22:44:05 rgb ++ * Start fixing 2.2 sockets. ++ * ++ * Revision 1.4 1999/04/29 15:21:34 rgb ++ * Move log to the end of the file. ++ * Eliminate min/max redefinition in #include . ++ * Correct path for pfkey #includes ++ * Standardise an error return method. ++ * Add debugging instrumentation. ++ * Move message type checking to pfkey_msg_parse(). ++ * Add check for errno incorrectly set. ++ * Add check for valid PID. ++ * Add check for reserved illegally set. ++ * Add check for message out of bounds. ++ * ++ * Revision 1.3 1999/04/15 17:58:07 rgb ++ * Add RCSID labels. ++ * ++ * Revision 1.2 1999/04/15 15:37:26 rgb ++ * Forward check changes from POST1_00 branch. ++ * ++ * Revision 1.1.2.2 1999/04/13 20:37:12 rgb ++ * Header Title correction. ++ * ++ * Revision 1.1.2.1 1999/03/26 20:58:55 rgb ++ * Add pfkeyv2 support to KLIPS. ++ * ++ * ++ * RFC 2367 ++ * PF_KEY_v2 Key Management API ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/pfkey_v2_ext_process.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,922 @@ ++/* ++ * @(#) RFC2367 PF_KEYv2 Key management API message parser ++ * Copyright (C) 1998-2003 Richard Guy Briggs. ++ * Copyright (C) 2004 Michael Richardson ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: pfkey_v2_ext_process.c,v 1.15 2004/04/06 02:49:26 mcr Exp $ ++ */ ++ ++/* ++ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c. ++ */ ++ ++char pfkey_v2_ext_process_c_version[] = "$Id: pfkey_v2_ext_process.c,v 1.15 2004/04/06 02:49:26 mcr Exp $"; ++ ++#include ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include ++ ++#include ++ ++#include ++ ++#ifdef SPINLOCK ++# ifdef SPINLOCK_23 ++# include /* *lock* */ ++# else /* SPINLOCK_23 */ ++# include /* *lock* */ ++# endif /* SPINLOCK_23 */ ++#endif /* SPINLOCK */ ++#ifdef NET_21 ++# include ++# include ++# define ip_chk_addr inet_addr_type ++# define IS_MYADDR RTN_LOCAL ++#endif ++#include ++#include ++#ifdef NETLINK_SOCK ++# include ++#else ++# include ++#endif ++ ++#include /* get_random_bytes() */ ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_sa.h" ++ ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_ah.h" ++#include "openswan/ipsec_esp.h" ++#include "openswan/ipsec_tunnel.h" ++#include "openswan/ipsec_rcv.h" ++#include "openswan/ipcomp.h" ++ ++#include ++#include ++ ++#include "openswan/ipsec_proto.h" ++#include "openswan/ipsec_alg.h" ++ ++#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) ++ ++int ++pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext; ++ int error = 0; ++ struct ipsec_sa* ipsp; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sa_process: .\n"); ++ ++ if(!extr || !extr->ips) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sa_process: " ++ "extr or extr->ips is NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ ++ switch(pfkey_ext->sadb_ext_type) { ++ case SADB_EXT_SA: ++ ipsp = extr->ips; ++ break; ++ case SADB_X_EXT_SA2: ++ if(extr->ips2 == NULL) { ++ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */ ++ } ++ if(extr->ips2 == NULL) { ++ SENDERR(-error); ++ } ++ ipsp = extr->ips2; ++ break; ++ default: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sa_process: " ++ "invalid exttype=%d.\n", ++ pfkey_ext->sadb_ext_type); ++ SENDERR(EINVAL); ++ } ++ ++ ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi; ++ ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay; ++ ipsp->ips_state = pfkey_sa->sadb_sa_state; ++ ipsp->ips_flags = pfkey_sa->sadb_sa_flags; ++ ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0; ++ ipsp->ips_ref_rel = pfkey_sa->sadb_x_sa_ref; ++ ++ switch(ipsp->ips_said.proto) { ++ case IPPROTO_AH: ++ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth; ++ ipsp->ips_encalg = SADB_EALG_NONE; ++ break; ++ case IPPROTO_ESP: ++ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth; ++ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt; ++#ifdef CONFIG_IPSEC_ALG ++ ipsec_alg_sa_init(ipsp); ++#endif /* CONFIG_IPSEC_ALG */ ++ break; ++ case IPPROTO_IPIP: ++ ipsp->ips_authalg = AH_NONE; ++ ipsp->ips_encalg = ESP_NONE; ++ break; ++#ifdef CONFIG_IPSEC_IPCOMP ++ case IPPROTO_COMP: ++ ipsp->ips_authalg = AH_NONE; ++ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt; ++ break; ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ case IPPROTO_INT: ++ ipsp->ips_authalg = AH_NONE; ++ ipsp->ips_encalg = ESP_NONE; ++ break; ++ case 0: ++ break; ++ default: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sa_process: " ++ "unknown proto=%d.\n", ++ ipsp->ips_said.proto); ++ SENDERR(EINVAL); ++ } ++ ++errlab: ++ return error; ++} ++ ++int ++pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_lifetime_process: .\n"); ++ ++ if(!extr || !extr->ips) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_lifetime_process: " ++ "extr or extr->ips is NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ ++ switch(pfkey_lifetime->sadb_lifetime_exttype) { ++ case SADB_EXT_LIFETIME_CURRENT: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_lifetime_process: " ++ "lifetime_current not supported yet.\n"); ++ SENDERR(EINVAL); ++ break; ++ case SADB_EXT_LIFETIME_HARD: ++ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations, ++ pfkey_lifetime->sadb_lifetime_allocations); ++ ++ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes, ++ pfkey_lifetime->sadb_lifetime_bytes); ++ ++ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime, ++ pfkey_lifetime->sadb_lifetime_addtime); ++ ++ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime, ++ pfkey_lifetime->sadb_lifetime_usetime); ++ ++ break; ++ ++ case SADB_EXT_LIFETIME_SOFT: ++ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations, ++ pfkey_lifetime->sadb_lifetime_allocations); ++ ++ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes, ++ pfkey_lifetime->sadb_lifetime_bytes); ++ ++ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime, ++ pfkey_lifetime->sadb_lifetime_addtime); ++ ++ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime, ++ pfkey_lifetime->sadb_lifetime_usetime); ++ ++ break; ++ default: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_lifetime_process: " ++ "invalid exttype=%d.\n", ++ pfkey_ext->sadb_ext_type); ++ SENDERR(EINVAL); ++ } ++ ++errlab: ++ return error; ++} ++ ++int ++pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ int saddr_len = 0; ++ char ipaddr_txt[ADDRTOA_BUF]; ++ unsigned char **sap; ++ unsigned short * portp = 0; ++ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext; ++ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address)); ++ struct ipsec_sa* ipsp; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process:\n"); ++ ++ if(!extr || !extr->ips) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "extr or extr->ips is NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ ++ switch(s->sa_family) { ++ case AF_INET: ++ saddr_len = sizeof(struct sockaddr_in); ++ addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt)); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "found address family=%d, AF_INET, %s.\n", ++ s->sa_family, ++ ipaddr_txt); ++ break; ++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++ case AF_INET6: ++ saddr_len = sizeof(struct sockaddr_in6); ++ break; ++#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ ++ default: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "s->sa_family=%d not supported.\n", ++ s->sa_family); ++ SENDERR(EPFNOSUPPORT); ++ } ++ ++ switch(pfkey_address->sadb_address_exttype) { ++ case SADB_EXT_ADDRESS_SRC: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "found src address.\n"); ++ sap = (unsigned char **)&(extr->ips->ips_addr_s); ++ extr->ips->ips_addr_s_size = saddr_len; ++ break; ++ case SADB_EXT_ADDRESS_DST: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "found dst address.\n"); ++ sap = (unsigned char **)&(extr->ips->ips_addr_d); ++ extr->ips->ips_addr_d_size = saddr_len; ++ break; ++ case SADB_EXT_ADDRESS_PROXY: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "found proxy address.\n"); ++ sap = (unsigned char **)&(extr->ips->ips_addr_p); ++ extr->ips->ips_addr_p_size = saddr_len; ++ break; ++ case SADB_X_EXT_ADDRESS_DST2: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "found 2nd dst address.\n"); ++ if(extr->ips2 == NULL) { ++ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */ ++ } ++ if(extr->ips2 == NULL) { ++ SENDERR(-error); ++ } ++ sap = (unsigned char **)&(extr->ips2->ips_addr_d); ++ extr->ips2->ips_addr_d_size = saddr_len; ++ break; ++ case SADB_X_EXT_ADDRESS_SRC_FLOW: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "found src flow address.\n"); ++ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { ++ SENDERR(ENOMEM); ++ } ++ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src); ++ portp = &(extr->eroute->er_eaddr.sen_sport); ++ break; ++ case SADB_X_EXT_ADDRESS_DST_FLOW: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "found dst flow address.\n"); ++ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { ++ SENDERR(ENOMEM); ++ } ++ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst); ++ portp = &(extr->eroute->er_eaddr.sen_dport); ++ break; ++ case SADB_X_EXT_ADDRESS_SRC_MASK: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "found src mask address.\n"); ++ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { ++ SENDERR(ENOMEM); ++ } ++ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src); ++ portp = &(extr->eroute->er_emask.sen_sport); ++ break; ++ case SADB_X_EXT_ADDRESS_DST_MASK: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "found dst mask address.\n"); ++ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { ++ SENDERR(ENOMEM); ++ } ++ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst); ++ portp = &(extr->eroute->er_emask.sen_dport); ++ break; ++#ifdef NAT_TRAVERSAL ++ case SADB_X_EXT_NAT_T_OA: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "found NAT-OA address.\n"); ++ sap = (unsigned char **)&(extr->ips->ips_natt_oa); ++ extr->ips->ips_natt_oa_size = saddr_len; ++ break; ++#endif ++ default: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "unrecognised ext_type=%d.\n", ++ pfkey_address->sadb_address_exttype); ++ SENDERR(EINVAL); ++ } ++ ++ switch(pfkey_address->sadb_address_exttype) { ++ case SADB_EXT_ADDRESS_SRC: ++ case SADB_EXT_ADDRESS_DST: ++ case SADB_EXT_ADDRESS_PROXY: ++ case SADB_X_EXT_ADDRESS_DST2: ++#ifdef NAT_TRAVERSAL ++ case SADB_X_EXT_NAT_T_OA: ++#endif ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "allocating %d bytes for saddr.\n", ++ saddr_len); ++ if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) { ++ SENDERR(ENOMEM); ++ } ++ memcpy(*sap, s, saddr_len); ++ break; ++ default: ++ if(s->sa_family != AF_INET) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "s->sa_family=%d not supported.\n", ++ s->sa_family); ++ SENDERR(EPFNOSUPPORT); ++ } ++ (unsigned long)(*sap) = ((struct sockaddr_in*)s)->sin_addr.s_addr; ++ if (portp != 0) ++ *portp = ((struct sockaddr_in*)s)->sin_port; ++#ifdef CONFIG_IPSEC_DEBUG ++ if(extr->eroute) { ++ char buf1[64], buf2[64]; ++ if (debug_pfkey) { ++ subnettoa(extr->eroute->er_eaddr.sen_ip_src, ++ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); ++ subnettoa(extr->eroute->er_eaddr.sen_ip_dst, ++ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_parse: " ++ "extr->eroute set to %s:%d->%s:%d\n", ++ buf1, ++ ntohs(extr->eroute->er_eaddr.sen_sport), ++ buf2, ++ ntohs(extr->eroute->er_eaddr.sen_dport)); ++ } ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ } ++ ++ ipsp = extr->ips; ++ switch(pfkey_address->sadb_address_exttype) { ++ case SADB_X_EXT_ADDRESS_DST2: ++ ipsp = extr->ips2; ++ case SADB_EXT_ADDRESS_DST: ++ if(s->sa_family == AF_INET) { ++ ipsp->ips_said.dst.u.v4.sin_addr.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr; ++ ipsp->ips_said.dst.u.v4.sin_family = AF_INET; ++ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr, ++ 0, ++ ipaddr_txt, ++ sizeof(ipaddr_txt)); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "ips_said.dst set to %s.\n", ++ ipaddr_txt); ++ } else { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: " ++ "uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n", ++ s->sa_family); ++ } ++ default: ++ break; ++ } ++ ++ /* XXX check if port!=0 */ ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_address_process: successful.\n"); ++ errlab: ++ return error; ++} ++ ++int ++pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_key_process: .\n"); ++ ++ if(!extr || !extr->ips) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_key_process: " ++ "extr or extr->ips is NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ ++ switch(pfkey_key->sadb_key_exttype) { ++ case SADB_EXT_KEY_AUTH: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_key_process: " ++ "allocating %d bytes for authkey.\n", ++ DIVUP(pfkey_key->sadb_key_bits, 8)); ++ if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_key_process: " ++ "memory allocation error.\n"); ++ SENDERR(ENOMEM); ++ } ++ extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits; ++ extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8); ++ memcpy(extr->ips->ips_key_a, ++ (char*)pfkey_key + sizeof(struct sadb_key), ++ extr->ips->ips_key_a_size); ++ break; ++ case SADB_EXT_KEY_ENCRYPT: /* Key(s) */ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_key_process: " ++ "allocating %d bytes for enckey.\n", ++ DIVUP(pfkey_key->sadb_key_bits, 8)); ++ if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_key_process: " ++ "memory allocation error.\n"); ++ SENDERR(ENOMEM); ++ } ++ extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits; ++ extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8); ++ memcpy(extr->ips->ips_key_e, ++ (char*)pfkey_key + sizeof(struct sadb_key), ++ extr->ips->ips_key_e_size); ++ break; ++ default: ++ SENDERR(EINVAL); ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_key_process: " ++ "success.\n"); ++errlab: ++ return error; ++} ++ ++int ++pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext; ++ int data_len; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ident_process: .\n"); ++ ++ if(!extr || !extr->ips) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ident_process: " ++ "extr or extr->ips is NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ ++ switch(pfkey_ident->sadb_ident_exttype) { ++ case SADB_EXT_IDENTITY_SRC: ++ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); ++ ++ extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type; ++ extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id; ++ extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len; ++ if(data_len) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ident_process: " ++ "allocating %d bytes for ident_s.\n", ++ data_len); ++ if(!(extr->ips->ips_ident_s.data ++ = kmalloc(data_len, GFP_KERNEL))) { ++ SENDERR(ENOMEM); ++ } ++ memcpy(extr->ips->ips_ident_s.data, ++ (char*)pfkey_ident + sizeof(struct sadb_ident), ++ data_len); ++ } else { ++ extr->ips->ips_ident_s.data = NULL; ++ } ++ break; ++ case SADB_EXT_IDENTITY_DST: /* Identity(ies) */ ++ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); ++ ++ extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type; ++ extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id; ++ extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len; ++ if(data_len) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ident_process: " ++ "allocating %d bytes for ident_d.\n", ++ data_len); ++ if(!(extr->ips->ips_ident_d.data ++ = kmalloc(data_len, GFP_KERNEL))) { ++ SENDERR(ENOMEM); ++ } ++ memcpy(extr->ips->ips_ident_d.data, ++ (char*)pfkey_ident + sizeof(struct sadb_ident), ++ data_len); ++ } else { ++ extr->ips->ips_ident_d.data = NULL; ++ } ++ break; ++ default: ++ SENDERR(EINVAL); ++ } ++errlab: ++ return error; ++} ++ ++int ++pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_sens_process: " ++ "Sorry, I can't process exttype=%d yet.\n", ++ pfkey_ext->sadb_ext_type); ++ SENDERR(EINVAL); /* don't process these yet */ ++ errlab: ++ return error; ++} ++ ++int ++pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_prop_process: " ++ "Sorry, I can't process exttype=%d yet.\n", ++ pfkey_ext->sadb_ext_type); ++ SENDERR(EINVAL); /* don't process these yet */ ++ ++ errlab: ++ return error; ++} ++ ++int ++pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_supported_process: " ++ "Sorry, I can't process exttype=%d yet.\n", ++ pfkey_ext->sadb_ext_type); ++ SENDERR(EINVAL); /* don't process these yet */ ++ ++errlab: ++ return error; ++} ++ ++int ++pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_spirange_process: .\n"); ++/* errlab: */ ++ return error; ++} ++ ++int ++pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_kmprivate_process: " ++ "Sorry, I can't process exttype=%d yet.\n", ++ pfkey_ext->sadb_ext_type); ++ SENDERR(EINVAL); /* don't process these yet */ ++ ++errlab: ++ return error; ++} ++ ++int ++pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_satype_process: .\n"); ++ ++ if(!extr || !extr->ips) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_satype_process: " ++ "extr or extr->ips is NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(extr->ips2 == NULL) { ++ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */ ++ } ++ if(extr->ips2 == NULL) { ++ SENDERR(-error); ++ } ++ if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_satype_process: " ++ "proto lookup from satype=%d failed.\n", ++ pfkey_x_satype->sadb_x_satype_satype); ++ SENDERR(EINVAL); ++ } ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_satype_process: " ++ "protocol==%d decoded from satype==%d(%s).\n", ++ extr->ips2->ips_said.proto, ++ pfkey_x_satype->sadb_x_satype_satype, ++ satype2name(pfkey_x_satype->sadb_x_satype_satype)); ++ ++errlab: ++ return error; ++} ++ ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++int ++pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext; ++ ++ if(!pfkey_x_nat_t_type) { ++ printk("klips_debug:pfkey_x_nat_t_type_process: " ++ "null pointer passed in\n"); ++ SENDERR(EINVAL); ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_nat_t_type_process: %d.\n", ++ pfkey_x_nat_t_type->sadb_x_nat_t_type_type); ++ ++ if(!extr || !extr->ips) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_nat_t_type_process: " ++ "extr or extr->ips is NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ ++ switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) { ++ case ESPINUDP_WITH_NON_IKE: /* with Non-IKE (older version) */ ++ case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */ ++ ++ extr->ips->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type; ++ break; ++ default: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_nat_t_type_process: " ++ "unknown type %d.\n", ++ pfkey_x_nat_t_type->sadb_x_nat_t_type_type); ++ SENDERR(EINVAL); ++ break; ++ } ++ ++errlab: ++ return error; ++} ++ ++int ++pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext; ++ ++ if(!pfkey_x_nat_t_port) { ++ printk("klips_debug:pfkey_x_nat_t_port_process: " ++ "null pointer passed in\n"); ++ SENDERR(EINVAL); ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n", ++ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype, ++ pfkey_x_nat_t_port->sadb_x_nat_t_port_port); ++ ++ if(!extr || !extr->ips) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_nat_t_type_process: " ++ "extr or extr->ips is NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ ++ switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) { ++ case SADB_X_EXT_NAT_T_SPORT: ++ extr->ips->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port; ++ break; ++ case SADB_X_EXT_NAT_T_DPORT: ++ extr->ips->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port; ++ break; ++ default: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_nat_t_port_process: " ++ "unknown exttype %d.\n", ++ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype); ++ SENDERR(EINVAL); ++ break; ++ } ++ ++errlab: ++ return error; ++} ++#endif ++ ++int ++pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext; ++ ++ if(!pfkey_x_debug) { ++ printk("klips_debug:pfkey_x_debug_process: " ++ "null pointer passed in\n"); ++ SENDERR(EINVAL); ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_debug_process: .\n"); ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if(pfkey_x_debug->sadb_x_debug_netlink >> ++ (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) { ++ pfkey_x_debug->sadb_x_debug_netlink &= ++ ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1)); ++ debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel; ++ debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink; ++ debug_xform |= pfkey_x_debug->sadb_x_debug_xform; ++ debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute; ++ debug_spi |= pfkey_x_debug->sadb_x_debug_spi; ++ debug_radij |= pfkey_x_debug->sadb_x_debug_radij; ++ debug_esp |= pfkey_x_debug->sadb_x_debug_esp; ++ debug_ah |= pfkey_x_debug->sadb_x_debug_ah; ++ debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv; ++ debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey; ++#ifdef CONFIG_IPSEC_IPCOMP ++ sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp; ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose; ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_debug_process: " ++ "set\n"); ++ } else { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_debug_process: " ++ "unset\n"); ++ debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel; ++ debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink; ++ debug_xform &= pfkey_x_debug->sadb_x_debug_xform; ++ debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute; ++ debug_spi &= pfkey_x_debug->sadb_x_debug_spi; ++ debug_radij &= pfkey_x_debug->sadb_x_debug_radij; ++ debug_esp &= pfkey_x_debug->sadb_x_debug_esp; ++ debug_ah &= pfkey_x_debug->sadb_x_debug_ah; ++ debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv; ++ debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey; ++#ifdef CONFIG_IPSEC_IPCOMP ++ sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp; ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose; ++ } ++#else /* CONFIG_IPSEC_DEBUG */ ++ printk("klips_debug:pfkey_x_debug_process: " ++ "debugging not enabled\n"); ++ SENDERR(EINVAL); ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++errlab: ++ return error; ++} ++ ++/* ++ * $Log: pfkey_v2_ext_process.c,v $ ++ * Revision 1.15 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.14 2004/02/03 03:13:59 mcr ++ * no longer #ifdef out NON_ESP mode. That was a mistake. ++ * ++ * Revision 1.13 2003/12/15 18:13:12 mcr ++ * when compiling with NAT traversal, don't assume that the ++ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP ++ * is set. ++ * ++ * Revision 1.12.2.1 2003/12/22 15:25:52 jjo ++ * Merged algo-0.8.1-rc11-test1 into alg-branch ++ * ++ * Revision 1.12 2003/12/10 01:14:27 mcr ++ * NAT-traversal patches to KLIPS. ++ * ++ * Revision 1.11 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.10.4.2 2003/10/29 01:30:41 mcr ++ * elimited "struct sa_id". ++ * ++ * Revision 1.10.4.1 2003/09/21 13:59:56 mcr ++ * pre-liminary X.509 patch - does not yet pass tests. ++ * ++ * Revision 1.10 2003/02/06 01:51:41 rgb ++ * Removed no longer relevant comment ++ * ++ * Revision 1.9 2003/01/30 02:32:44 rgb ++ * ++ * Transmit error code through to caller from callee for better diagnosis of problems. ++ * ++ * Revision 1.8 2002/12/13 22:42:22 mcr ++ * restored sa_ref code ++ * ++ * Revision 1.7 2002/12/13 22:40:48 mcr ++ * temporarily removed sadb_x_sa_ref reference for 2.xx ++ * ++ * Revision 1.6 2002/10/05 05:02:58 dhr ++ * ++ * C labels go on statements ++ * ++ * Revision 1.5 2002/09/20 15:41:08 rgb ++ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc(). ++ * Added sadb_x_sa_ref to struct sadb_sa. ++ * ++ * Revision 1.4 2002/09/20 05:02:02 rgb ++ * Added memory allocation debugging. ++ * ++ * Revision 1.3 2002/07/24 18:44:54 rgb ++ * Type fiddling to tame ia64 compiler. ++ * ++ * Revision 1.2 2002/05/27 18:55:03 rgb ++ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. ++ * ++ * Revision 1.1 2002/05/14 02:33:51 rgb ++ * Moved all the extension processing functions to pfkey_v2_ext_process.c. ++ * ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/pfkey_v2_parser.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,4018 @@ ++/* ++ * @(#) RFC2367 PF_KEYv2 Key management API message parser ++ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: pfkey_v2_parser.c,v 1.123 2004/04/06 02:49:26 mcr Exp $ ++ */ ++ ++/* ++ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c. ++ */ ++ ++char pfkey_v2_parser_c_version[] = "$Id: pfkey_v2_parser.c,v 1.123 2004/04/06 02:49:26 mcr Exp $"; ++ ++#include ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include ++ ++#include ++ ++#include ++ ++#ifdef SPINLOCK ++# ifdef SPINLOCK_23 ++# include /* *lock* */ ++# else /* SPINLOCK_23 */ ++# include /* *lock* */ ++# endif /* SPINLOCK_23 */ ++#endif /* SPINLOCK */ ++#ifdef NET_21 ++# include ++# include ++# define ip_chk_addr inet_addr_type ++# define IS_MYADDR RTN_LOCAL ++#endif ++#include ++#include ++#ifdef NETLINK_SOCK ++# include ++#else ++# include ++#endif ++ ++#include /* get_random_bytes() */ ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_sa.h" ++ ++#include "openswan/ipsec_radij.h" ++#include "openswan/ipsec_xform.h" ++#include "openswan/ipsec_ah.h" ++#include "openswan/ipsec_esp.h" ++#include "openswan/ipsec_tunnel.h" ++#include "openswan/ipsec_rcv.h" ++#include "openswan/ipcomp.h" ++ ++#include ++#include ++ ++#include "openswan/ipsec_proto.h" ++#include "openswan/ipsec_alg.h" ++ ++ ++#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) ++ ++struct sklist_t { ++ struct socket *sk; ++ struct sklist_t* next; ++} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev; ++ ++__u32 pfkey_msg_seq = 0; ++ ++ ++#if 0 ++#define DUMP_SAID dump_said(&extr->ips->ips_said, __LINE__) ++#define DUMP_SAID2 dump_said(&extr.ips->ips_said, __LINE__) ++static void dump_said(ip_said *s, int line) ++{ ++ char msa[SATOT_BUF]; ++ size_t msa_len; ++ ++ msa_len = satot(s, 0, msa, sizeof(msa)); ++ ++ printk("line: %d msa: %s\n", line, msa); ++} ++#endif ++ ++ ++int ++pfkey_alloc_eroute(struct eroute** eroute) ++{ ++ int error = 0; ++ if(*eroute) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_alloc_eroute: " ++ "eroute struct already allocated\n"); ++ SENDERR(EEXIST); ++ } ++ ++ if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_alloc_eroute: " ++ "memory allocation error\n"); ++ SENDERR(ENOMEM); ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_alloc_eroute: " ++ "allocating %lu bytes for an eroute at 0p%p\n", ++ (unsigned long) sizeof(**eroute), *eroute); ++ ++ memset((caddr_t)*eroute, 0, sizeof(**eroute)); ++ (*eroute)->er_eaddr.sen_len = ++ (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap); ++ (*eroute)->er_eaddr.sen_family = ++ (*eroute)->er_emask.sen_family = AF_ENCAP; ++ (*eroute)->er_eaddr.sen_type = SENT_IP4; ++ (*eroute)->er_emask.sen_type = 255; ++ (*eroute)->er_pid = 0; ++ (*eroute)->er_count = 0; ++ (*eroute)->er_lasttime = jiffies/HZ; ++ ++ errlab: ++ return(error); ++} ++ ++DEBUG_NO_STATIC int ++pfkey_x_protocol_process(struct sadb_ext *pfkey_ext, ++ struct pfkey_extracted_data *extr) ++{ ++ int error = 0; ++ struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext; ++ ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr); ++ ++ if (extr == 0) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_protocol_process:" ++ "extr is NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ if (extr->eroute == 0) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_protocol_process:" ++ "extr->eroute is NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ ++ extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto; ++ extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0; ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_protocol_process: protocol = %d.\n", ++ p->sadb_protocol_proto); ++ errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_ipsec_sa_init(struct ipsec_sa *ipsp, struct sadb_ext **extensions) ++{ ++ int i; ++ int error = 0; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ char ipaddr_txt[ADDRTOA_BUF]; ++ char ipaddr2_txt[ADDRTOA_BUF]; ++#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined (CONFIG_IPSEC_AUTH_HMAC_SHA1) ++ unsigned char kb[AHMD596_BLKLEN]; ++#endif ++#ifdef CONFIG_IPSEC_ALG ++ struct ipsec_alg_enc *ixt_e = NULL; ++ struct ipsec_alg_auth *ixt_a = NULL; ++#endif /* CONFIG_IPSEC_ALG */ ++ ++ if(ipsp == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "ipsp is NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ ++ sa_len = satot(&ipsp->ips_said, 0, sa, sizeof(sa)); ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "(pfkey defined) called for SA:%s\n", ++ sa_len ? sa : " (error)"); ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "calling init routine of %s%s%s\n", ++ IPS_XFORM_NAME(ipsp)); ++ ++ switch(ipsp->ips_said.proto) { ++ ++#ifdef CONFIG_IPSEC_IPIP ++ case IPPROTO_IPIP: { ++ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr, ++ 0, ++ ipaddr_txt, sizeof(ipaddr_txt)); ++ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr, ++ 0, ++ ipaddr2_txt, sizeof(ipaddr_txt)); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n", ++ ipaddr_txt, ++ ipaddr2_txt); ++ } ++ break; ++#endif /* !CONFIG_IPSEC_IPIP */ ++#ifdef CONFIG_IPSEC_AH ++ case IPPROTO_AH: ++ switch(ipsp->ips_authalg) { ++# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ case AH_MD5: { ++ unsigned char *akp; ++ unsigned int aks; ++ MD5_CTX *ictx; ++ MD5_CTX *octx; ++ ++ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, ++ ipsp->ips_key_bits_a, AHMD596_KLEN * 8); ++ SENDERR(EINVAL); ++ } ++ ++# if KLIPS_DIVULGE_HMAC_KEY ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "hmac md5-96 key is 0x%08x %08x %08x %08x\n", ++ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)), ++ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)), ++ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)), ++ ntohl(*(((__u32 *)ipsp->ips_key_a)+3))); ++# endif /* KLIPS_DIVULGE_HMAC_KEY */ ++ ++ ipsp->ips_auth_bits = AHMD596_ALEN * 8; ++ ++ /* save the pointer to the key material */ ++ akp = ipsp->ips_key_a; ++ aks = ipsp->ips_key_a_size; ++ ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "allocating %lu bytes for md5_ctx.\n", ++ (unsigned long) sizeof(struct md5_ctx)); ++ if((ipsp->ips_key_a = (caddr_t) ++ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) { ++ ipsp->ips_key_a = akp; ++ SENDERR(ENOMEM); ++ } ++ ipsp->ips_key_a_size = sizeof(struct md5_ctx); ++ ++ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { ++ kb[i] = akp[i] ^ HMAC_IPAD; ++ } ++ for (; i < AHMD596_BLKLEN; i++) { ++ kb[i] = HMAC_IPAD; ++ } ++ ++ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx); ++ MD5Init(ictx); ++ MD5Update(ictx, kb, AHMD596_BLKLEN); ++ ++ for (i = 0; i < AHMD596_BLKLEN; i++) { ++ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); ++ } ++ ++ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx); ++ MD5Init(octx); ++ MD5Update(octx, kb, AHMD596_BLKLEN); ++ ++# if KLIPS_DIVULGE_HMAC_KEY ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", ++ ((__u32*)ictx)[0], ++ ((__u32*)ictx)[1], ++ ((__u32*)ictx)[2], ++ ((__u32*)ictx)[3], ++ ((__u32*)octx)[0], ++ ((__u32*)octx)[1], ++ ((__u32*)octx)[2], ++ ((__u32*)octx)[3] ); ++# endif /* KLIPS_DIVULGE_HMAC_KEY */ ++ ++ /* zero key buffer -- paranoid */ ++ memset(akp, 0, aks); ++ kfree(akp); ++ } ++ break; ++# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ case AH_SHA: { ++ unsigned char *akp; ++ unsigned int aks; ++ SHA1_CTX *ictx; ++ SHA1_CTX *octx; ++ ++ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, ++ ipsp->ips_key_bits_a, AHSHA196_KLEN * 8); ++ SENDERR(EINVAL); ++ } ++ ++# if KLIPS_DIVULGE_HMAC_KEY ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n", ++ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)), ++ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)), ++ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)), ++ ntohl(*(((__u32 *)ipsp->ips_key_a)+3))); ++# endif /* KLIPS_DIVULGE_HMAC_KEY */ ++ ++ ipsp->ips_auth_bits = AHSHA196_ALEN * 8; ++ ++ /* save the pointer to the key material */ ++ akp = ipsp->ips_key_a; ++ aks = ipsp->ips_key_a_size; ++ ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "allocating %lu bytes for sha1_ctx.\n", ++ (unsigned long) sizeof(struct sha1_ctx)); ++ if((ipsp->ips_key_a = (caddr_t) ++ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) { ++ ipsp->ips_key_a = akp; ++ SENDERR(ENOMEM); ++ } ++ ipsp->ips_key_a_size = sizeof(struct sha1_ctx); ++ ++ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { ++ kb[i] = akp[i] ^ HMAC_IPAD; ++ } ++ for (; i < AHMD596_BLKLEN; i++) { ++ kb[i] = HMAC_IPAD; ++ } ++ ++ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx); ++ SHA1Init(ictx); ++ SHA1Update(ictx, kb, AHSHA196_BLKLEN); ++ ++ for (i = 0; i < AHSHA196_BLKLEN; i++) { ++ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); ++ } ++ ++ octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx); ++ SHA1Init(octx); ++ SHA1Update(octx, kb, AHSHA196_BLKLEN); ++ ++# if KLIPS_DIVULGE_HMAC_KEY ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", ++ ((__u32*)ictx)[0], ++ ((__u32*)ictx)[1], ++ ((__u32*)ictx)[2], ++ ((__u32*)ictx)[3], ++ ((__u32*)octx)[0], ++ ((__u32*)octx)[1], ++ ((__u32*)octx)[2], ++ ((__u32*)octx)[3] ); ++# endif /* KLIPS_DIVULGE_HMAC_KEY */ ++ /* zero key buffer -- paranoid */ ++ memset(akp, 0, aks); ++ kfree(akp); ++ } ++ break; ++# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++ default: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "authalg=%d support not available in the kernel", ++ ipsp->ips_authalg); ++ SENDERR(EINVAL); ++ } ++ break; ++#endif /* CONFIG_IPSEC_AH */ ++#ifdef CONFIG_IPSEC_ESP ++ case IPPROTO_ESP: { ++#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined (CONFIG_IPSEC_AUTH_HMAC_SHA1) ++ unsigned char *akp; ++ unsigned int aks; ++#endif ++#if defined (CONFIG_IPSEC_ENC_3DES) ++ unsigned char *ekp; ++ unsigned int eks; ++#endif ++ ++ ipsp->ips_iv_size = 0; ++#ifdef CONFIG_IPSEC_ALG ++ if ((ixt_e=ipsp->ips_alg_enc)) { ++ ipsp->ips_iv_size = ixt_e->ixt_ivlen/8; ++ } else ++#endif /* CONFIG_IPSEC_ALG */ ++ switch(ipsp->ips_encalg) { ++# ifdef CONFIG_IPSEC_ENC_3DES ++ case ESP_3DES: ++# endif /* CONFIG_IPSEC_ENC_3DES */ ++# if defined(CONFIG_IPSEC_ENC_3DES) ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "allocating %u bytes for iv.\n", ++ EMT_ESPDES_IV_SZ); ++ if((ipsp->ips_iv = (caddr_t) ++ kmalloc((ipsp->ips_iv_size = EMT_ESPDES_IV_SZ), GFP_ATOMIC)) == NULL) { ++ SENDERR(ENOMEM); ++ } ++ prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, EMT_ESPDES_IV_SZ); ++ ipsp->ips_iv_bits = ipsp->ips_iv_size * 8; ++ ipsp->ips_iv_size = EMT_ESPDES_IV_SZ; ++ break; ++# endif /* defined(CONFIG_IPSEC_ENC_3DES) */ ++ case ESP_NONE: ++ break; ++ default: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "encalg=%d support not available in the kernel", ++ ipsp->ips_encalg); ++ SENDERR(EINVAL); ++ } ++ ++ /* Create IV */ ++ if (ipsp->ips_iv_size) { ++ if((ipsp->ips_iv = (caddr_t) ++ kmalloc(ipsp->ips_iv_size, GFP_ATOMIC)) == NULL) { ++ SENDERR(ENOMEM); ++ } ++ prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, ipsp->ips_iv_size); ++ ipsp->ips_iv_bits = ipsp->ips_iv_size * 8; ++ } ++ ++#ifdef CONFIG_IPSEC_ALG ++ if (ixt_e) { ++ if ((error=ipsec_alg_enc_key_create(ipsp)) < 0) ++ SENDERR(-error); ++ } else ++#endif /* CONFIG_IPSEC_ALG */ ++ switch(ipsp->ips_encalg) { ++# ifdef CONFIG_IPSEC_ENC_3DES ++ case ESP_3DES: ++ if(ipsp->ips_key_bits_e != (EMT_ESP3DES_KEY_SZ * 8)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "incorrect encryption key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, ++ ipsp->ips_key_bits_e, EMT_ESP3DES_KEY_SZ * 8); ++ SENDERR(EINVAL); ++ } ++ ++ /* save encryption key pointer */ ++ ekp = ipsp->ips_key_e; ++ eks = ipsp->ips_key_e_size; ++ ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "allocating %lu bytes for 3des.\n", ++ (unsigned long) (3 * sizeof(struct des_eks))); ++ if((ipsp->ips_key_e = (caddr_t) ++ kmalloc(3 * sizeof(struct des_eks), GFP_ATOMIC)) == NULL) { ++ ipsp->ips_key_e = ekp; ++ SENDERR(ENOMEM); ++ } ++ ipsp->ips_key_e_size = 3 * sizeof(struct des_eks); ++ ++ for(i = 0; i < 3; i++) { ++#if KLIPS_DIVULGE_CYPHER_KEY ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "3des key %d/3 is 0x%08x%08x\n", ++ i + 1, ++ ntohl(*((__u32 *)ekp + i * 2)), ++ ntohl(*((__u32 *)ekp + i * 2 + 1))); ++# endif ++#if KLIPS_FIXES_DES_PARITY ++ /* force parity */ ++ des_set_odd_parity((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i)); ++#endif ++ error = des_set_key((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i), ++ ((struct des_eks *)(ipsp->ips_key_e))[i].ks); ++ if (error == -1) ++ printk("klips_debug:pfkey_ipsec_sa_init: " ++ "parity error in des key %d/3\n", ++ i + 1); ++ else if (error == -2) ++ printk("klips_debug:pfkey_ipsec_sa_init: " ++ "illegal weak des key %d/3\n", i + 1); ++ if (error) { ++ memset(ekp, 0, eks); ++ kfree(ekp); ++ SENDERR(EINVAL); ++ } ++ } ++ ++ /* paranoid */ ++ memset(ekp, 0, eks); ++ kfree(ekp); ++ break; ++# endif /* CONFIG_IPSEC_ENC_3DES */ ++ case ESP_NONE: ++ break; ++ default: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "encalg=%d support not available in the kernel", ++ ipsp->ips_encalg); ++ SENDERR(EINVAL); ++ } ++ ++#ifdef CONFIG_IPSEC_ALG ++ if ((ixt_a=ipsp->ips_alg_auth)) { ++ if ((error=ipsec_alg_auth_key_create(ipsp)) < 0) ++ SENDERR(-error); ++ } else ++#endif /* CONFIG_IPSEC_ALG */ ++ ++ switch(ipsp->ips_authalg) { ++# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 ++ case AH_MD5: { ++ MD5_CTX *ictx; ++ MD5_CTX *octx; ++ ++ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, ++ ipsp->ips_key_bits_a, ++ AHMD596_KLEN * 8); ++ SENDERR(EINVAL); ++ } ++ ++# if KLIPS_DIVULGE_HMAC_KEY ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "hmac md5-96 key is 0x%08x %08x %08x %08x\n", ++ ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)), ++ ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)), ++ ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)), ++ ntohl(*(((__u32 *)(ipsp->ips_key_a))+3))); ++# endif /* KLIPS_DIVULGE_HMAC_KEY */ ++ ipsp->ips_auth_bits = AHMD596_ALEN * 8; ++ ++ /* save the pointer to the key material */ ++ akp = ipsp->ips_key_a; ++ aks = ipsp->ips_key_a_size; ++ ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "allocating %lu bytes for md5_ctx.\n", ++ (unsigned long) sizeof(struct md5_ctx)); ++ if((ipsp->ips_key_a = (caddr_t) ++ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) { ++ ipsp->ips_key_a = akp; ++ SENDERR(ENOMEM); ++ } ++ ipsp->ips_key_a_size = sizeof(struct md5_ctx); ++ ++ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { ++ kb[i] = akp[i] ^ HMAC_IPAD; ++ } ++ for (; i < AHMD596_BLKLEN; i++) { ++ kb[i] = HMAC_IPAD; ++ } ++ ++ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx); ++ MD5Init(ictx); ++ MD5Update(ictx, kb, AHMD596_BLKLEN); ++ ++ for (i = 0; i < AHMD596_BLKLEN; i++) { ++ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); ++ } ++ ++ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx); ++ MD5Init(octx); ++ MD5Update(octx, kb, AHMD596_BLKLEN); ++ ++# if KLIPS_DIVULGE_HMAC_KEY ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", ++ ((__u32*)ictx)[0], ++ ((__u32*)ictx)[1], ++ ((__u32*)ictx)[2], ++ ((__u32*)ictx)[3], ++ ((__u32*)octx)[0], ++ ((__u32*)octx)[1], ++ ((__u32*)octx)[2], ++ ((__u32*)octx)[3] ); ++# endif /* KLIPS_DIVULGE_HMAC_KEY */ ++ /* paranoid */ ++ memset(akp, 0, aks); ++ kfree(akp); ++ break; ++ } ++# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ ++# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 ++ case AH_SHA: { ++ SHA1_CTX *ictx; ++ SHA1_CTX *octx; ++ ++ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, ++ ipsp->ips_key_bits_a, ++ AHSHA196_KLEN * 8); ++ SENDERR(EINVAL); ++ } ++ ++# if KLIPS_DIVULGE_HMAC_KEY ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n", ++ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)), ++ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)), ++ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)), ++ ntohl(*(((__u32 *)ipsp->ips_key_a)+3))); ++# endif /* KLIPS_DIVULGE_HMAC_KEY */ ++ ipsp->ips_auth_bits = AHSHA196_ALEN * 8; ++ ++ /* save the pointer to the key material */ ++ akp = ipsp->ips_key_a; ++ aks = ipsp->ips_key_a_size; ++ ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "allocating %lu bytes for sha1_ctx.\n", ++ (unsigned long) sizeof(struct sha1_ctx)); ++ if((ipsp->ips_key_a = (caddr_t) ++ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) { ++ ipsp->ips_key_a = akp; ++ SENDERR(ENOMEM); ++ } ++ ipsp->ips_key_a_size = sizeof(struct sha1_ctx); ++ ++ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) { ++ kb[i] = akp[i] ^ HMAC_IPAD; ++ } ++ for (; i < AHMD596_BLKLEN; i++) { ++ kb[i] = HMAC_IPAD; ++ } ++ ++ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx); ++ SHA1Init(ictx); ++ SHA1Update(ictx, kb, AHSHA196_BLKLEN); ++ ++ for (i = 0; i < AHSHA196_BLKLEN; i++) { ++ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); ++ } ++ ++ octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx; ++ SHA1Init(octx); ++ SHA1Update(octx, kb, AHSHA196_BLKLEN); ++ ++# if KLIPS_DIVULGE_HMAC_KEY ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", ++ ((__u32*)ictx)[0], ++ ((__u32*)ictx)[1], ++ ((__u32*)ictx)[2], ++ ((__u32*)ictx)[3], ++ ((__u32*)octx)[0], ++ ((__u32*)octx)[1], ++ ((__u32*)octx)[2], ++ ((__u32*)octx)[3] ); ++# endif /* KLIPS_DIVULGE_HMAC_KEY */ ++ memset(akp, 0, aks); ++ kfree(akp); ++ break; ++ } ++# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ ++ case AH_NONE: ++ break; ++ default: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "authalg=%d support not available in the kernel.\n", ++ ipsp->ips_authalg); ++ SENDERR(EINVAL); ++ } ++ } ++ break; ++#endif /* !CONFIG_IPSEC_ESP */ ++#ifdef CONFIG_IPSEC_IPCOMP ++ case IPPROTO_COMP: ++ ipsp->ips_comp_adapt_tries = 0; ++ ipsp->ips_comp_adapt_skip = 0; ++ ipsp->ips_comp_ratio_cbytes = 0; ++ ipsp->ips_comp_ratio_dbytes = 0; ++ break; ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ default: ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_ipsec_sa_init: " ++ "proto=%d unknown.\n", ++ ipsp->ips_said.proto); ++ SENDERR(EINVAL); ++ } ++ ++ errlab: ++ return(error); ++} ++ ++ ++int ++pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1]) ++{ ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: " ++ "error=%d\n", ++ error); ++ if (!error) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:" ++ "success.\n"); ++ return 1; ++ } else { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:" ++ "caught error %d\n", ++ error); ++ pfkey_extensions_free(extensions); ++ return 0; ++ } ++} ++ ++ ++DEBUG_NO_STATIC int ++pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L); ++ int found_avail = 0; ++ struct ipsec_sa *ipsq; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; ++ struct sadb_msg *pfkey_reply = NULL; ++ struct socket_list *pfkey_socketsp; ++ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_getspi_parse: .\n"); ++ ++ pfkey_extensions_init(extensions_reply); ++ ++ if(extr == NULL || extr->ips == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_getspi_parse: " ++ "error, extr or extr->ipsec_sa pointer NULL\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(extensions[SADB_EXT_SPIRANGE]) { ++ minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min; ++ maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max; ++ } ++ ++ if(maxspi == minspi) { ++ extr->ips->ips_said.spi = maxspi; ++ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); ++ if(ipsq != NULL) { ++ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); ++ ipsec_sa_put(ipsq); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_getspi_parse: " ++ "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n", ++ sa_len ? sa : " (error)"); ++ SENDERR(EEXIST); ++ } else { ++ found_avail = 1; ++ } ++ } else { ++ int i = 0; ++ __u32 rand_val; ++ __u32 spi_diff; ++ while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) { ++ prng_bytes(&ipsec_prng, (char *) &(rand_val), ++ ( (spi_diff < (2^8)) ? 1 : ++ ( (spi_diff < (2^16)) ? 2 : ++ ( (spi_diff < (2^24)) ? 3 : ++ 4 ) ) ) ); ++ extr->ips->ips_said.spi = htonl(ntohl(minspi) + ++ (rand_val % ++ (spi_diff + 1))); ++ i++; ++ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); ++ if(ipsq == NULL) { ++ found_avail = 1; ++ } else { ++ ipsec_sa_put(ipsq); ++ } ++ } ++ } ++ ++ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); ++ ++ if (!found_avail) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_getspi_parse: " ++ "found an old ipsec_sa for SA: %s, delete it first.\n", ++ sa_len ? sa : " (error)"); ++ SENDERR(EEXIST); ++ } ++ ++ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) { ++ extr->ips->ips_flags |= EMT_INBOUND; ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_getspi_parse: " ++ "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n", ++ sa_len ? sa : " (error)", ++ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out"); ++ ++ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/ ++ extr->ips->ips_rcvif = NULL; ++ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ; ++ ++ extr->ips->ips_state = SADB_SASTATE_LARVAL; ++ ++ if(!extr->ips->ips_life.ipl_allocations.ipl_count) { ++ extr->ips->ips_life.ipl_allocations.ipl_count += 1; ++ } ++ ++ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], ++ SADB_GETSPI, ++ satype, ++ 0, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], ++ SADB_EXT_SA, ++ extr->ips->ips_said.spi, ++ 0, ++ SADB_SASTATE_LARVAL, ++ 0, ++ 0, ++ 0, ++ extr->ips->ips_ref), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], ++ SADB_EXT_ADDRESS_SRC, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_s), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], ++ SADB_EXT_ADDRESS_DST, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_d), ++ extensions_reply) )) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " ++ "failed to build the getspi reply message extensions\n"); ++ goto errlab; ++ } ++ ++ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " ++ "failed to build the getspi reply message\n"); ++ SENDERR(-error); ++ } ++ for(pfkey_socketsp = pfkey_open_sockets; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " ++ "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " ++ "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp); ++ } ++ ++ if((error = ipsec_sa_add(extr->ips))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " ++ "failed to add the larval SA=%s with error=%d.\n", ++ sa_len ? sa : " (error)", ++ error); ++ SENDERR(-error); ++ } ++ extr->ips = NULL; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_getspi_parse: " ++ "successful for SA: %s\n", ++ sa_len ? sa : " (error)"); ++ ++ errlab: ++ if (pfkey_reply) { ++ pfkey_msg_free(&pfkey_reply); ++ } ++ pfkey_extensions_free(extensions_reply); ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ struct ipsec_sa* ipsq; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; ++ struct sadb_msg *pfkey_reply = NULL; ++ struct socket_list *pfkey_socketsp; ++ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ struct ipsec_sa *nat_t_ips_saved = NULL; ++#endif ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_update_parse: .\n"); ++ ++ pfkey_extensions_init(extensions_reply); ++ ++ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_update_parse: " ++ "error, sa_state=%d must be MATURE=%d\n", ++ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, ++ SADB_SASTATE_MATURE); ++ SENDERR(EINVAL); ++ } ++ ++ if(extr == NULL || extr->ips == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_update_parse: " ++ "error, extr or extr->ips pointer NULL\n"); ++ SENDERR(EINVAL); ++ } ++ ++ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); ++ ++ spin_lock_bh(&tdb_lock); ++ ++ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); ++ if (ipsq == NULL) { ++ spin_unlock_bh(&tdb_lock); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_update_parse: " ++ "reserved ipsec_sa for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n", ++ sa_len ? sa : " (error)"); ++ SENDERR(ENOENT); ++ } ++ ++ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) { ++ extr->ips->ips_flags |= EMT_INBOUND; ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_update_parse: " ++ "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n", ++ sa_len ? sa : " (error)", ++ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out"); ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ if (extr->ips->ips_natt_sport || extr->ips->ips_natt_dport) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_update_parse: only updating NAT-T ports " ++ "(%u:%u -> %u:%u)\n", ++ ipsq->ips_natt_sport, ipsq->ips_natt_dport, ++ extr->ips->ips_natt_sport, extr->ips->ips_natt_dport); ++ ++ if (extr->ips->ips_natt_sport) { ++ ipsq->ips_natt_sport = extr->ips->ips_natt_sport; ++ if (ipsq->ips_addr_s->sa_family == AF_INET) { ++ ((struct sockaddr_in *)(ipsq->ips_addr_s))->sin_port = htons(extr->ips->ips_natt_sport); ++ } ++ } ++ ++ if (extr->ips->ips_natt_dport) { ++ ipsq->ips_natt_dport = extr->ips->ips_natt_dport; ++ if (ipsq->ips_addr_d->sa_family == AF_INET) { ++ ((struct sockaddr_in *)(ipsq->ips_addr_d))->sin_port = htons(extr->ips->ips_natt_dport); ++ } ++ } ++ ++ nat_t_ips_saved = extr->ips; ++ extr->ips = ipsq; ++ } ++ else { ++#endif ++ ++ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/ ++ extr->ips->ips_rcvif = NULL; ++ if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) { ++ ipsec_sa_put(ipsq); ++ spin_unlock_bh(&tdb_lock); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_update_parse: " ++ "not successful for SA: %s, deleting.\n", ++ sa_len ? sa : " (error)"); ++ SENDERR(-error); ++ } ++ ++ extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count; ++ ipsec_sa_put(ipsq); ++ if((error = ipsec_sa_delchain(ipsq))) { ++ spin_unlock_bh(&tdb_lock); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_update_parse: " ++ "error=%d, trouble deleting intermediate ipsec_sa for SA=%s.\n", ++ error, ++ sa_len ? sa : " (error)"); ++ SENDERR(-error); ++ } ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ } ++#endif ++ ++ spin_unlock_bh(&tdb_lock); ++ ++ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], ++ SADB_UPDATE, ++ satype, ++ 0, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], ++ SADB_EXT_SA, ++ extr->ips->ips_said.spi, ++ extr->ips->ips_replaywin, ++ extr->ips->ips_state, ++ extr->ips->ips_authalg, ++ extr->ips->ips_encalg, ++ extr->ips->ips_flags, ++ extr->ips->ips_ref), ++ extensions_reply) ++ /* The 3 lifetime extentions should only be sent if non-zero. */ ++ && (extensions[SADB_EXT_LIFETIME_HARD] ++ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], ++ SADB_EXT_LIFETIME_HARD, ++ extr->ips->ips_life.ipl_allocations.ipl_hard, ++ extr->ips->ips_life.ipl_bytes.ipl_hard, ++ extr->ips->ips_life.ipl_addtime.ipl_hard, ++ extr->ips->ips_life.ipl_usetime.ipl_hard, ++ extr->ips->ips_life.ipl_packets.ipl_hard), ++ extensions_reply) : 1) ++ && (extensions[SADB_EXT_LIFETIME_SOFT] ++ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], ++ SADB_EXT_LIFETIME_SOFT, ++ extr->ips->ips_life.ipl_allocations.ipl_count, ++ extr->ips->ips_life.ipl_bytes.ipl_count, ++ extr->ips->ips_life.ipl_addtime.ipl_count, ++ extr->ips->ips_life.ipl_usetime.ipl_count, ++ extr->ips->ips_life.ipl_packets.ipl_count), ++ extensions_reply) : 1) ++ && (extr->ips->ips_life.ipl_allocations.ipl_count ++ || extr->ips->ips_life.ipl_bytes.ipl_count ++ || extr->ips->ips_life.ipl_addtime.ipl_count ++ || extr->ips->ips_life.ipl_usetime.ipl_count ++ || extr->ips->ips_life.ipl_packets.ipl_count ++ ++ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT], ++ SADB_EXT_LIFETIME_CURRENT, ++ extr->ips->ips_life.ipl_allocations.ipl_count, ++ extr->ips->ips_life.ipl_bytes.ipl_count, ++ extr->ips->ips_life.ipl_addtime.ipl_count, ++ extr->ips->ips_life.ipl_usetime.ipl_count, ++ extr->ips->ips_life.ipl_packets.ipl_count), ++ extensions_reply) : 1) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], ++ SADB_EXT_ADDRESS_SRC, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_s), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], ++ SADB_EXT_ADDRESS_DST, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_d), ++ extensions_reply) ++ && (extr->ips->ips_ident_s.data ++ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], ++ SADB_EXT_IDENTITY_SRC, ++ extr->ips->ips_ident_s.type, ++ extr->ips->ips_ident_s.id, ++ extr->ips->ips_ident_s.len, ++ extr->ips->ips_ident_s.data), ++ extensions_reply) : 1) ++ && (extr->ips->ips_ident_d.data ++ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], ++ SADB_EXT_IDENTITY_DST, ++ extr->ips->ips_ident_d.type, ++ extr->ips->ips_ident_d.id, ++ extr->ips->ips_ident_d.len, ++ extr->ips->ips_ident_d.data), ++ extensions_reply) : 1) ++#if 0 ++ /* FIXME: This won't work yet because I have not finished ++ it. */ ++ && (extr->ips->ips_sens_ ++ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], ++ extr->ips->ips_sens_dpd, ++ extr->ips->ips_sens_sens_level, ++ extr->ips->ips_sens_sens_len, ++ extr->ips->ips_sens_sens_bitmap, ++ extr->ips->ips_sens_integ_level, ++ extr->ips->ips_sens_integ_len, ++ extr->ips->ips_sens_integ_bitmap), ++ extensions_reply) : 1) ++#endif ++ )) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " ++ "failed to build the update reply message extensions\n"); ++ SENDERR(-error); ++ } ++ ++ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " ++ "failed to build the update reply message\n"); ++ SENDERR(-error); ++ } ++ for(pfkey_socketsp = pfkey_open_sockets; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " ++ "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " ++ "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp); ++ } ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ if (nat_t_ips_saved) { ++ /** ++ * As we _really_ update existing SA, we keep tdbq and need to delete ++ * parsed ips (nat_t_ips_saved, was extr->ips). ++ * ++ * goto errlab with extr->ips = nat_t_ips_saved will free it. ++ */ ++ ++ extr->ips = nat_t_ips_saved; ++ ++ error = 0; ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_update_parse (NAT-T ports): " ++ "successful for SA: %s\n", ++ sa_len ? sa : " (error)"); ++ ++ goto errlab; ++ } ++#endif ++ ++ if((error = ipsec_sa_add(extr->ips))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " ++ "failed to update the mature SA=%s with error=%d.\n", ++ sa_len ? sa : " (error)", ++ error); ++ SENDERR(-error); ++ } ++ extr->ips = NULL; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_update_parse: " ++ "successful for SA: %s\n", ++ sa_len ? sa : " (error)"); ++ ++ errlab: ++ if (pfkey_reply) { ++ pfkey_msg_free(&pfkey_reply); ++ } ++ pfkey_extensions_free(extensions_reply); ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ struct ipsec_sa* ipsq; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; ++ struct sadb_msg *pfkey_reply = NULL; ++ struct socket_list *pfkey_socketsp; ++ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_add_parse: .\n"); ++ ++ pfkey_extensions_init(extensions_reply); ++ ++ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_add_parse: " ++ "error, sa_state=%d must be MATURE=%d\n", ++ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, ++ SADB_SASTATE_MATURE); ++ SENDERR(EINVAL); ++ } ++ ++ if(!extr || !extr->ips) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_add_parse: " ++ "extr or extr->ips pointer NULL\n"); ++ SENDERR(EINVAL); ++ } ++ ++ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); ++ ++ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); ++ if(ipsq != NULL) { ++ ipsec_sa_put(ipsq); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_add_parse: " ++ "found an old ipsec_sa for SA%s, delete it first.\n", ++ sa_len ? sa : " (error)"); ++ SENDERR(EEXIST); ++ } ++ ++ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) { ++ extr->ips->ips_flags |= EMT_INBOUND; ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_add_parse: " ++ "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n", ++ sa_len ? sa : " (error)", ++ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out"); ++ ++ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/ ++ extr->ips->ips_rcvif = NULL; ++ ++ if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_add_parse: " ++ "not successful for SA: %s, deleting.\n", ++ sa_len ? sa : " (error)"); ++ SENDERR(-error); ++ } ++ ++ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ; ++ if(!extr->ips->ips_life.ipl_allocations.ipl_count) { ++ extr->ips->ips_life.ipl_allocations.ipl_count += 1; ++ } ++ ++ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], ++ SADB_ADD, ++ satype, ++ 0, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], ++ SADB_EXT_SA, ++ extr->ips->ips_said.spi, ++ extr->ips->ips_replaywin, ++ extr->ips->ips_state, ++ extr->ips->ips_authalg, ++ extr->ips->ips_encalg, ++ extr->ips->ips_flags, ++ extr->ips->ips_ref), ++ extensions_reply) ++ /* The 3 lifetime extentions should only be sent if non-zero. */ ++ && (extensions[SADB_EXT_LIFETIME_HARD] ++ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], ++ SADB_EXT_LIFETIME_HARD, ++ extr->ips->ips_life.ipl_allocations.ipl_hard, ++ extr->ips->ips_life.ipl_bytes.ipl_hard, ++ extr->ips->ips_life.ipl_addtime.ipl_hard, ++ extr->ips->ips_life.ipl_usetime.ipl_hard, ++ extr->ips->ips_life.ipl_packets.ipl_hard), ++ extensions_reply) : 1) ++ && (extensions[SADB_EXT_LIFETIME_SOFT] ++ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], ++ SADB_EXT_LIFETIME_SOFT, ++ extr->ips->ips_life.ipl_allocations.ipl_soft, ++ extr->ips->ips_life.ipl_bytes.ipl_soft, ++ extr->ips->ips_life.ipl_addtime.ipl_soft, ++ extr->ips->ips_life.ipl_usetime.ipl_soft, ++ extr->ips->ips_life.ipl_packets.ipl_soft), ++ extensions_reply) : 1) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], ++ SADB_EXT_ADDRESS_SRC, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_s), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], ++ SADB_EXT_ADDRESS_DST, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_d), ++ extensions_reply) ++ && (extr->ips->ips_ident_s.data ++ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], ++ SADB_EXT_IDENTITY_SRC, ++ extr->ips->ips_ident_s.type, ++ extr->ips->ips_ident_s.id, ++ extr->ips->ips_ident_s.len, ++ extr->ips->ips_ident_s.data), ++ extensions_reply) : 1) ++ && (extr->ips->ips_ident_d.data ++ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], ++ SADB_EXT_IDENTITY_DST, ++ extr->ips->ips_ident_d.type, ++ extr->ips->ips_ident_d.id, ++ extr->ips->ips_ident_d.len, ++ extr->ips->ips_ident_d.data), ++ extensions_reply) : 1) ++#if 0 ++ /* FIXME: This won't work yet because I have not finished ++ it. */ ++ && (extr->ips->ips_sens_ ++ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], ++ extr->ips->ips_sens_dpd, ++ extr->ips->ips_sens_sens_level, ++ extr->ips->ips_sens_sens_len, ++ extr->ips->ips_sens_sens_bitmap, ++ extr->ips->ips_sens_integ_level, ++ extr->ips->ips_sens_integ_len, ++ extr->ips->ips_sens_integ_bitmap), ++ extensions_reply) : 1) ++#endif ++ )) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " ++ "failed to build the add reply message extensions\n"); ++ SENDERR(-error); ++ } ++ ++ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " ++ "failed to build the add reply message\n"); ++ SENDERR(-error); ++ } ++ for(pfkey_socketsp = pfkey_open_sockets; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " ++ "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " ++ "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp); ++ } ++ ++ if((error = ipsec_sa_add(extr->ips))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " ++ "failed to add the mature SA=%s with error=%d.\n", ++ sa_len ? sa : " (error)", ++ error); ++ SENDERR(-error); ++ } ++ extr->ips = NULL; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_add_parse: " ++ "successful for SA: %s\n", ++ sa_len ? sa : " (error)"); ++ ++ errlab: ++ if (pfkey_reply) { ++ pfkey_msg_free(&pfkey_reply); ++ } ++ pfkey_extensions_free(extensions_reply); ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ struct ipsec_sa *ipsp; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ int error = 0; ++ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; ++ struct sadb_msg *pfkey_reply = NULL; ++ struct socket_list *pfkey_socketsp; ++ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_delete_parse: .\n"); ++ ++ pfkey_extensions_init(extensions_reply); ++ ++ if(!extr || !extr->ips) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_delete_parse: " ++ "extr or extr->ips pointer NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ ++ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); ++ ++ spin_lock_bh(&tdb_lock); ++ ++ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said)); ++ if (ipsp == NULL) { ++ spin_unlock_bh(&tdb_lock); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_delete_parse: " ++ "ipsec_sa not found for SA:%s, could not delete.\n", ++ sa_len ? sa : " (error)"); ++ SENDERR(ESRCH); ++ } ++ ++ ipsec_sa_put(ipsp); ++ if((error = ipsec_sa_delchain(ipsp))) { ++ spin_unlock_bh(&tdb_lock); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_delete_parse: " ++ "error=%d returned trying to delete ipsec_sa for SA:%s.\n", ++ error, ++ sa_len ? sa : " (error)"); ++ SENDERR(-error); ++ } ++ spin_unlock_bh(&tdb_lock); ++ ++ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], ++ SADB_DELETE, ++ satype, ++ 0, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], ++ SADB_EXT_SA, ++ extr->ips->ips_said.spi, ++ 0, ++ 0, ++ 0, ++ 0, ++ 0, ++ extr->ips->ips_ref), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], ++ SADB_EXT_ADDRESS_SRC, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_s), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], ++ SADB_EXT_ADDRESS_DST, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_d), ++ extensions_reply) ++ )) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " ++ "failed to build the delete reply message extensions\n"); ++ SENDERR(-error); ++ } ++ ++ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " ++ "failed to build the delete reply message\n"); ++ SENDERR(-error); ++ } ++ for(pfkey_socketsp = pfkey_open_sockets; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " ++ "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " ++ "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp); ++ } ++ ++ errlab: ++ if (pfkey_reply) { ++ pfkey_msg_free(&pfkey_reply); ++ } ++ pfkey_extensions_free(extensions_reply); ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ struct ipsec_sa *ipsp; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; ++ struct sadb_msg *pfkey_reply = NULL; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_get_parse: .\n"); ++ ++ pfkey_extensions_init(extensions_reply); ++ ++ if(!extr || !extr->ips) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_get_parse: " ++ "extr or extr->ips pointer NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ ++ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); ++ ++ spin_lock_bh(&tdb_lock); ++ ++ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said)); ++ if (ipsp == NULL) { ++ spin_unlock_bh(&tdb_lock); ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " ++ "ipsec_sa not found for SA=%s, could not get.\n", ++ sa_len ? sa : " (error)"); ++ SENDERR(ESRCH); ++ } ++ ++ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], ++ SADB_GET, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype, ++ 0, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], ++ SADB_EXT_SA, ++ extr->ips->ips_said.spi, ++ extr->ips->ips_replaywin, ++ extr->ips->ips_state, ++ extr->ips->ips_authalg, ++ extr->ips->ips_encalg, ++ extr->ips->ips_flags, ++ extr->ips->ips_ref), ++ extensions_reply) ++ /* The 3 lifetime extentions should only be sent if non-zero. */ ++ && (ipsp->ips_life.ipl_allocations.ipl_count ++ || ipsp->ips_life.ipl_bytes.ipl_count ++ || ipsp->ips_life.ipl_addtime.ipl_count ++ || ipsp->ips_life.ipl_usetime.ipl_count ++ || ipsp->ips_life.ipl_packets.ipl_count ++ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT], ++ SADB_EXT_LIFETIME_CURRENT, ++ ipsp->ips_life.ipl_allocations.ipl_count, ++ ipsp->ips_life.ipl_bytes.ipl_count, ++ ipsp->ips_life.ipl_addtime.ipl_count, ++ ipsp->ips_life.ipl_usetime.ipl_count, ++ ipsp->ips_life.ipl_packets.ipl_count), ++ extensions_reply) : 1) ++ && (ipsp->ips_life.ipl_allocations.ipl_hard ++ || ipsp->ips_life.ipl_bytes.ipl_hard ++ || ipsp->ips_life.ipl_addtime.ipl_hard ++ || ipsp->ips_life.ipl_usetime.ipl_hard ++ || ipsp->ips_life.ipl_packets.ipl_hard ++ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], ++ SADB_EXT_LIFETIME_HARD, ++ ipsp->ips_life.ipl_allocations.ipl_hard, ++ ipsp->ips_life.ipl_bytes.ipl_hard, ++ ipsp->ips_life.ipl_addtime.ipl_hard, ++ ipsp->ips_life.ipl_usetime.ipl_hard, ++ ipsp->ips_life.ipl_packets.ipl_hard), ++ extensions_reply) : 1) ++ && (ipsp->ips_life.ipl_allocations.ipl_soft ++ || ipsp->ips_life.ipl_bytes.ipl_soft ++ || ipsp->ips_life.ipl_addtime.ipl_soft ++ || ipsp->ips_life.ipl_usetime.ipl_soft ++ || ipsp->ips_life.ipl_packets.ipl_soft ++ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], ++ SADB_EXT_LIFETIME_SOFT, ++ ipsp->ips_life.ipl_allocations.ipl_soft, ++ ipsp->ips_life.ipl_bytes.ipl_soft, ++ ipsp->ips_life.ipl_addtime.ipl_soft, ++ ipsp->ips_life.ipl_usetime.ipl_soft, ++ ipsp->ips_life.ipl_packets.ipl_soft), ++ extensions_reply) : 1) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], ++ SADB_EXT_ADDRESS_SRC, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_s), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], ++ SADB_EXT_ADDRESS_DST, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_d), ++ extensions_reply) ++ && (extr->ips->ips_addr_p ++ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY], ++ SADB_EXT_ADDRESS_PROXY, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_p), ++ extensions_reply) : 1) ++#if 0 ++ /* FIXME: This won't work yet because the keys are not ++ stored directly in the ipsec_sa. They are stored as ++ contexts. */ ++ && (extr->ips->ips_key_a_size ++ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH], ++ SADB_EXT_KEY_AUTH, ++ extr->ips->ips_key_a_size * 8, ++ extr->ips->ips_key_a), ++ extensions_reply) : 1) ++ /* FIXME: This won't work yet because the keys are not ++ stored directly in the ipsec_sa. They are stored as ++ key schedules. */ ++ && (extr->ips->ips_key_e_size ++ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT], ++ SADB_EXT_KEY_ENCRYPT, ++ extr->ips->ips_key_e_size * 8, ++ extr->ips->ips_key_e), ++ extensions_reply) : 1) ++#endif ++ && (extr->ips->ips_ident_s.data ++ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], ++ SADB_EXT_IDENTITY_SRC, ++ extr->ips->ips_ident_s.type, ++ extr->ips->ips_ident_s.id, ++ extr->ips->ips_ident_s.len, ++ extr->ips->ips_ident_s.data), ++ extensions_reply) : 1) ++ && (extr->ips->ips_ident_d.data ++ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], ++ SADB_EXT_IDENTITY_DST, ++ extr->ips->ips_ident_d.type, ++ extr->ips->ips_ident_d.id, ++ extr->ips->ips_ident_d.len, ++ extr->ips->ips_ident_d.data), ++ extensions_reply) : 1) ++#if 0 ++ /* FIXME: This won't work yet because I have not finished ++ it. */ ++ && (extr->ips->ips_sens_ ++ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], ++ extr->ips->ips_sens_dpd, ++ extr->ips->ips_sens_sens_level, ++ extr->ips->ips_sens_sens_len, ++ extr->ips->ips_sens_sens_bitmap, ++ extr->ips->ips_sens_integ_level, ++ extr->ips->ips_sens_integ_len, ++ extr->ips->ips_sens_integ_bitmap), ++ extensions_reply) : 1) ++#endif ++ )) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " ++ "failed to build the get reply message extensions\n"); ++ ipsec_sa_put(ipsp); ++ spin_unlock_bh(&tdb_lock); ++ SENDERR(-error); ++ } ++ ++ ipsec_sa_put(ipsp); ++ spin_unlock_bh(&tdb_lock); ++ ++ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " ++ "failed to build the get reply message\n"); ++ SENDERR(-error); ++ } ++ ++ if((error = pfkey_upmsg(sk->socket, pfkey_reply))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " ++ "failed to send the get reply message\n"); ++ SENDERR(-error); ++ } ++ ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " ++ "succeeded in sending get reply message.\n"); ++ ++ errlab: ++ if (pfkey_reply) { ++ pfkey_msg_free(&pfkey_reply); ++ } ++ pfkey_extensions_free(extensions_reply); ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ struct socket_list *pfkey_socketsp; ++ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_acquire_parse: .\n"); ++ ++ /* XXX I don't know if we want an upper bound, since userspace may ++ want to register itself for an satype > SADB_SATYPE_MAX. */ ++ if((satype == 0) || (satype > SADB_SATYPE_MAX)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_acquire_parse: " ++ "SATYPE=%d invalid.\n", ++ satype); ++ SENDERR(EINVAL); ++ } ++ ++ if(!(pfkey_registered_sockets[satype])) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " ++ "no sockets registered for SAtype=%d(%s).\n", ++ satype, ++ satype2name(satype)); ++ SENDERR(EPROTONOSUPPORT); ++ } ++ ++ for(pfkey_socketsp = pfkey_registered_sockets[satype]; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " ++ "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " ++ "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp); ++ } ++ ++ errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_register_parse: .\n"); ++ ++ /* XXX I don't know if we want an upper bound, since userspace may ++ want to register itself for an satype > SADB_SATYPE_MAX. */ ++ if((satype == 0) || (satype > SADB_SATYPE_MAX)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_register_parse: " ++ "SATYPE=%d invalid.\n", ++ satype); ++ SENDERR(EINVAL); ++ } ++ ++ if(!pfkey_list_insert_socket(sk->socket, ++ &(pfkey_registered_sockets[satype]))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_register_parse: " ++ "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n", ++ satype, ++ satype2name(satype), ++ key_pid(sk)); ++ }; ++ ++ /* send up register msg with supported SATYPE algos */ ++ ++ error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[SADB_EXT_RESERVED]); ++ errlab: ++ return error; ++} ++ ++int ++pfkey_register_reply(int satype, struct sadb_msg *sadb_msg) ++{ ++ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; ++ struct sadb_msg *pfkey_reply = NULL; ++ struct socket_list *pfkey_socketsp; ++ struct supported_list *pfkey_supported_listp; ++ unsigned int alg_num_a = 0, alg_num_e = 0; ++ struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL; ++ int error = 0; ++ ++ pfkey_extensions_init(extensions_reply); ++ ++ if((satype == 0) || (satype > SADB_SATYPE_MAX)) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " ++ "SAtype=%d unspecified or unknown.\n", ++ satype); ++ SENDERR(EINVAL); ++ } ++ if(!(pfkey_registered_sockets[satype])) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " ++ "no sockets registered for SAtype=%d(%s).\n", ++ satype, ++ satype2name(satype)); ++ SENDERR(EPROTONOSUPPORT); ++ } ++ /* send up register msg with supported SATYPE algos */ ++ pfkey_supported_listp = pfkey_supported_list[satype]; ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_register_reply: " ++ "pfkey_supported_list[%d]=0p%p\n", ++ satype, ++ pfkey_supported_list[satype]); ++ while(pfkey_supported_listp) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_register_reply: " ++ "checking supported=0p%p\n", ++ pfkey_supported_listp); ++ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_register_reply: " ++ "adding auth alg.\n"); ++ alg_num_a++; ++ } ++ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_register_reply: " ++ "adding encrypt alg.\n"); ++ alg_num_e++; ++ } ++ pfkey_supported_listp = pfkey_supported_listp->next; ++ } ++ ++ if(alg_num_a) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_register_reply: " ++ "allocating %lu bytes for auth algs.\n", ++ (unsigned long) (alg_num_a * sizeof(struct sadb_alg))); ++ if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_register_reply: " ++ "auth alg memory allocation error\n"); ++ SENDERR(ENOMEM); ++ } ++ alg_ap = alg_a; ++ } ++ ++ if(alg_num_e) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_register_reply: " ++ "allocating %lu bytes for enc algs.\n", ++ (unsigned long) (alg_num_e * sizeof(struct sadb_alg))); ++ if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_register_reply: " ++ "enc alg memory allocation error\n"); ++ SENDERR(ENOMEM); ++ } ++ alg_ep = alg_e; ++ } ++ ++ pfkey_supported_listp = pfkey_supported_list[satype]; ++ while(pfkey_supported_listp) { ++ if(alg_num_a) { ++ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) { ++ alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id; ++ alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen; ++ alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits; ++ alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits; ++ alg_ap->sadb_alg_reserved = 0; ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_register_reply: " ++ "adding auth=0p%p\n", ++ alg_ap); ++ alg_ap++; ++ } ++ } ++ if(alg_num_e) { ++ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) { ++ alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id; ++ alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen; ++ alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits; ++ alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits; ++ alg_ep->sadb_alg_reserved = 0; ++ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, ++ "klips_debug:pfkey_register_reply: " ++ "adding encrypt=0p%p\n", ++ alg_ep); ++ alg_ep++; ++ } ++ } ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_register_reply: " ++ "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_supported_listp->supportedp->supported_alg_exttype, ++ pfkey_supported_listp->supportedp->supported_alg_id, ++ pfkey_supported_listp->supportedp->supported_alg_ivlen, ++ pfkey_supported_listp->supportedp->supported_alg_minbits, ++ pfkey_supported_listp->supportedp->supported_alg_maxbits); ++ pfkey_supported_listp = pfkey_supported_listp->next; ++ } ++ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], ++ SADB_REGISTER, ++ satype, ++ 0, ++ sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq, ++ sadb_msg? sadb_msg->sadb_msg_pid: current->pid), ++ extensions_reply) && ++ (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH], ++ SADB_EXT_SUPPORTED_AUTH, ++ alg_num_a, ++ alg_a), ++ extensions_reply) : 1) && ++ (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT], ++ SADB_EXT_SUPPORTED_ENCRYPT, ++ alg_num_e, ++ alg_e), ++ extensions_reply) : 1))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " ++ "failed to build the register message extensions_reply\n"); ++ SENDERR(-error); ++ } ++ ++ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " ++ "failed to build the register message\n"); ++ SENDERR(-error); ++ } ++ /* this should go to all registered sockets for that satype only */ ++ for(pfkey_socketsp = pfkey_registered_sockets[satype]; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " ++ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " ++ "sending up register message for satype=%d(%s) to socket=0p%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp); ++ } ++ ++ errlab: ++ if(alg_a) { ++ kfree(alg_a); ++ } ++ if(alg_e) { ++ kfree(alg_e); ++ } ++ if (pfkey_reply) { ++ pfkey_msg_free(&pfkey_reply); ++ } ++ pfkey_extensions_free(extensions_reply); ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ struct socket_list *pfkey_socketsp; ++#ifdef CONFIG_IPSEC_DEBUG ++ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_expire_parse: .\n"); ++ ++ if(pfkey_open_sockets) { ++ for(pfkey_socketsp = pfkey_open_sockets; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: " ++ "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: " ++ "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp); ++ } ++ } ++ ++ errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ struct socket_list *pfkey_socketsp; ++ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; ++ uint8_t proto = 0; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_flush_parse: " ++ "flushing type %d SAs\n", ++ satype); ++ ++ if(satype && !(proto = satype2proto(satype))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_flush_parse: " ++ "satype %d lookup failed.\n", ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); ++ SENDERR(EINVAL); ++ } ++ ++ if ((error = ipsec_sadb_cleanup(proto))) { ++ SENDERR(-error); ++ } ++ ++ if(pfkey_open_sockets) { ++ for(pfkey_socketsp = pfkey_open_sockets; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: " ++ "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ proto, ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: " ++ "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp); ++ } ++ } ++ ++ errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_dump_parse: .\n"); ++ ++ SENDERR(ENOSYS); ++ errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_promisc_parse: .\n"); ++ ++ SENDERR(ENOSYS); ++ errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_pchange_parse: .\n"); ++ ++ SENDERR(ENOSYS); ++ errlab: ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ struct ipsec_sa *ips1p, *ips2p, *ipsp; ++ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; ++ struct sadb_msg *pfkey_reply = NULL; ++ struct socket_list *pfkey_socketsp; ++ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; ++ char sa1[SATOT_BUF], sa2[SATOT_BUF]; ++ size_t sa_len1, sa_len2 = 0; ++ int error = 0; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_grpsa_parse: .\n"); ++ ++ pfkey_extensions_init(extensions_reply); ++ ++ if(extr == NULL || extr->ips == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_grpsa_parse: " ++ "extr or extr->ips is NULL, fatal.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ sa_len1 = satot(&extr->ips->ips_said, 0, sa1, sizeof(sa1)); ++ if(extr->ips2 != NULL) { ++ sa_len2 = satot(&extr->ips2->ips_said, 0, sa2, sizeof(sa2)); ++ } ++ ++ spin_lock_bh(&tdb_lock); ++ ++ ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said)); ++ if(ips1p == NULL) { ++ spin_unlock_bh(&tdb_lock); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_grpsa_parse: " ++ "reserved ipsec_sa for SA1: %s not found. Call SADB_ADD/UPDATE first.\n", ++ sa_len1 ? sa1 : " (error)"); ++ SENDERR(ENOENT); ++ } ++ if(extr->ips2) { /* GRPSA */ ++ ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said)); ++ if(ips2p == NULL) { ++ ipsec_sa_put(ips1p); ++ spin_unlock_bh(&tdb_lock); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_grpsa_parse: " ++ "reserved ipsec_sa for SA2: %s not found. Call SADB_ADD/UPDATE first.\n", ++ sa_len2 ? sa2 : " (error)"); ++ SENDERR(ENOENT); ++ } ++ ++ /* Is either one already linked? */ ++ if(ips1p->ips_onext) { ++ ipsec_sa_put(ips1p); ++ ipsec_sa_put(ips2p); ++ spin_unlock_bh(&tdb_lock); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_grpsa_parse: " ++ "ipsec_sa for SA: %s is already linked.\n", ++ sa_len1 ? sa1 : " (error)"); ++ SENDERR(EEXIST); ++ } ++ if(ips2p->ips_inext) { ++ ipsec_sa_put(ips1p); ++ ipsec_sa_put(ips2p); ++ spin_unlock_bh(&tdb_lock); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_grpsa_parse: " ++ "ipsec_sa for SA: %s is already linked.\n", ++ sa_len2 ? sa2 : " (error)"); ++ SENDERR(EEXIST); ++ } ++ ++ /* Is extr->ips already linked to extr->ips2? */ ++ ipsp = ips2p; ++ while(ipsp) { ++ if(ipsp == ips1p) { ++ ipsec_sa_put(ips1p); ++ ipsec_sa_put(ips2p); ++ spin_unlock_bh(&tdb_lock); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_grpsa_parse: " ++ "ipsec_sa for SA: %s is already linked to %s.\n", ++ sa_len1 ? sa1 : " (error)", ++ sa_len2 ? sa2 : " (error)"); ++ SENDERR(EEXIST); ++ } ++ ipsp = ipsp->ips_onext; ++ } ++ ++ /* link 'em */ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_grpsa_parse: " ++ "linking ipsec_sa SA: %s with %s.\n", ++ sa_len1 ? sa1 : " (error)", ++ sa_len2 ? sa2 : " (error)"); ++ ips1p->ips_onext = ips2p; ++ ips2p->ips_inext = ips1p; ++ } else { /* UNGRPSA */ ++ ipsec_sa_put(ips1p); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_grpsa_parse: " ++ "unlinking ipsec_sa SA: %s.\n", ++ sa_len1 ? sa1 : " (error)"); ++ while(ips1p->ips_onext) { ++ ips1p = ips1p->ips_onext; ++ } ++ while(ips1p->ips_inext) { ++ ipsp = ips1p; ++ ips1p = ips1p->ips_inext; ++ ipsec_sa_put(ips1p); ++ ipsp->ips_inext = NULL; ++ ipsec_sa_put(ipsp); ++ ips1p->ips_onext = NULL; ++ } ++ } ++ ++ spin_unlock_bh(&tdb_lock); ++ ++ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], ++ SADB_X_GRPSA, ++ satype, ++ 0, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], ++ SADB_EXT_SA, ++ extr->ips->ips_said.spi, ++ extr->ips->ips_replaywin, ++ extr->ips->ips_state, ++ extr->ips->ips_authalg, ++ extr->ips->ips_encalg, ++ extr->ips->ips_flags, ++ extr->ips->ips_ref), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], ++ SADB_EXT_ADDRESS_DST, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_d), ++ extensions_reply) ++ && (extr->ips2 ++ ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2], ++ ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype ++ /* proto2satype(extr->ips2->ips_said.proto) */), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2], ++ SADB_X_EXT_SA2, ++ extr->ips2->ips_said.spi, ++ extr->ips2->ips_replaywin, ++ extr->ips2->ips_state, ++ extr->ips2->ips_authalg, ++ extr->ips2->ips_encalg, ++ extr->ips2->ips_flags, ++ extr->ips2->ips_ref), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2], ++ SADB_X_EXT_ADDRESS_DST2, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips2->ips_addr_d), ++ extensions_reply) ) : 1 ) ++ )) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " ++ "failed to build the x_grpsa reply message extensions\n"); ++ SENDERR(-error); ++ } ++ ++ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " ++ "failed to build the x_grpsa reply message\n"); ++ SENDERR(-error); ++ } ++ ++ for(pfkey_socketsp = pfkey_open_sockets; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " ++ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " ++ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp); ++ } ++ ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " ++ "succeeded in sending x_grpsa reply message.\n"); ++ ++ errlab: ++ if (pfkey_reply) { ++ pfkey_msg_free(&pfkey_reply); ++ } ++ pfkey_extensions_free(extensions_reply); ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++#ifdef CONFIG_IPSEC_DEBUG ++ char buf1[64], buf2[64]; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; ++ struct sadb_msg *pfkey_reply = NULL; ++ struct socket_list *pfkey_socketsp; ++ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; ++ ip_address srcflow, dstflow, srcmask, dstmask; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_addflow_parse: .\n"); ++ ++ pfkey_extensions_init(extensions_reply); ++ ++ memset((caddr_t)&srcflow, 0, sizeof(srcflow)); ++ memset((caddr_t)&dstflow, 0, sizeof(dstflow)); ++ memset((caddr_t)&srcmask, 0, sizeof(srcmask)); ++ memset((caddr_t)&dstmask, 0, sizeof(dstmask)); ++ ++ if(!extr || !(extr->ips) || !(extr->eroute)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_addflow_parse: " ++ "missing extr, ipsec_sa or eroute data.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ srcflow.u.v4.sin_family = AF_INET; ++ dstflow.u.v4.sin_family = AF_INET; ++ srcmask.u.v4.sin_family = AF_INET; ++ dstmask.u.v4.sin_family = AF_INET; ++ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src; ++ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst; ++ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src; ++ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst; ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if (debug_pfkey) { ++ subnettoa(extr->eroute->er_eaddr.sen_ip_src, ++ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); ++ subnettoa(extr->eroute->er_eaddr.sen_ip_dst, ++ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_addflow_parse: " ++ "calling breakeroute and/or makeroute for %s->%s\n", ++ buf1, buf2); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) { ++/* if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) */ ++ struct ipsec_sa *ipsp, *ipsq; ++ char sa[SATOT_BUF]; ++ size_t sa_len; ++ ++ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said)); ++ if(ipsq == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_addflow_parse: " ++ "ipsec_sa not found, cannot set incoming policy.\n"); ++ SENDERR(ENOENT); ++ } ++ ++ ipsp = ipsq; ++ while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) { ++ ipsp = ipsp->ips_inext; ++ } ++ ++ if(ipsp == NULL) { ++ ipsec_sa_put(ipsq); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_addflow_parse: " ++ "SA chain does not have an IPIP SA, cannot set incoming policy.\n"); ++ SENDERR(ENOENT); ++ } ++ ++ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa)); ++ ++ ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW; ++ ipsp->ips_flow_s = srcflow; ++ ipsp->ips_flow_d = dstflow; ++ ipsp->ips_mask_s = srcmask; ++ ipsp->ips_mask_d = dstmask; ++ ++ ipsec_sa_put(ipsq); ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_addflow_parse: " ++ "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n", ++ sa_len ? sa : " (error)"); ++ } else { ++ struct sk_buff *first = NULL, *last = NULL; ++ ++ if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_addflow_parse: " ++ "REPLACEFLOW flag set, calling breakeroute.\n"); ++ if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr), ++ &(extr->eroute->er_emask), ++ &first, &last))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_addflow_parse: " ++ "breakeroute returned %d. first=0p%p, last=0p%p\n", ++ error, ++ first, ++ last); ++ if(first != NULL) { ++ ipsec_kfree_skb(first); ++ } ++ if(last != NULL) { ++ ipsec_kfree_skb(last); ++ } ++ SENDERR(-error); ++ } ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_addflow_parse: " ++ "calling makeroute.\n"); ++ ++ if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr), ++ &(extr->eroute->er_emask), ++ extr->ips->ips_said, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid, ++ NULL, ++ &(extr->ips->ips_ident_s), ++ &(extr->ips->ips_ident_d)))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_addflow_parse: " ++ "makeroute returned %d.\n", error); ++ SENDERR(-error); ++ } ++ if(first != NULL) { ++ KLIPS_PRINT(debug_eroute, ++ "klips_debug:pfkey_x_addflow_parse: " ++ "first=0p%p HOLD packet re-injected.\n", ++ first); ++ DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL); ++ } ++ if(last != NULL) { ++ KLIPS_PRINT(debug_eroute, ++ "klips_debug:pfkey_x_addflow_parse: " ++ "last=0p%p HOLD packet re-injected.\n", ++ last); ++ DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL); ++ } ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_addflow_parse: " ++ "makeroute call successful.\n"); ++ ++ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], ++ SADB_X_ADDFLOW, ++ satype, ++ 0, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], ++ SADB_EXT_SA, ++ extr->ips->ips_said.spi, ++ extr->ips->ips_replaywin, ++ extr->ips->ips_state, ++ extr->ips->ips_authalg, ++ extr->ips->ips_encalg, ++ extr->ips->ips_flags, ++ extr->ips->ips_ref), ++ extensions_reply) ++ && (extensions[SADB_EXT_ADDRESS_SRC] ++ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], ++ SADB_EXT_ADDRESS_SRC, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_s), ++ extensions_reply) : 1) ++ && (extensions[SADB_EXT_ADDRESS_DST] ++ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], ++ SADB_EXT_ADDRESS_DST, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ extr->ips->ips_addr_d), ++ extensions_reply) : 1) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW], ++ SADB_X_EXT_ADDRESS_SRC_FLOW, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ (struct sockaddr*)&srcflow), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW], ++ SADB_X_EXT_ADDRESS_DST_FLOW, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ (struct sockaddr*)&dstflow), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK], ++ SADB_X_EXT_ADDRESS_SRC_MASK, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ (struct sockaddr*)&srcmask), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK], ++ SADB_X_EXT_ADDRESS_DST_MASK, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ (struct sockaddr*)&dstmask), ++ extensions_reply) ++ )) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " ++ "failed to build the x_addflow reply message extensions\n"); ++ SENDERR(-error); ++ } ++ ++ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " ++ "failed to build the x_addflow reply message\n"); ++ SENDERR(-error); ++ } ++ ++ for(pfkey_socketsp = pfkey_open_sockets; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " ++ "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " ++ "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ extr->ips->ips_said.proto, ++ pfkey_socketsp->socketp); ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_addflow_parse: " ++ "extr->ips cleaned up and freed.\n"); ++ ++ errlab: ++ if (pfkey_reply) { ++ pfkey_msg_free(&pfkey_reply); ++ } ++ pfkey_extensions_free(extensions_reply); ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++#ifdef CONFIG_IPSEC_DEBUG ++ char buf1[64], buf2[64]; ++#endif /* CONFIG_IPSEC_DEBUG */ ++ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; ++ struct sadb_msg *pfkey_reply = NULL; ++ struct socket_list *pfkey_socketsp; ++ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; ++ ip_address srcflow, dstflow, srcmask, dstmask; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_delflow_parse: .\n"); ++ ++ pfkey_extensions_init(extensions_reply); ++ ++ memset((caddr_t)&srcflow, 0, sizeof(srcflow)); ++ memset((caddr_t)&dstflow, 0, sizeof(dstflow)); ++ memset((caddr_t)&srcmask, 0, sizeof(srcmask)); ++ memset((caddr_t)&dstmask, 0, sizeof(dstmask)); ++ ++ if(!extr || !(extr->ips)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_delflow_parse: " ++ "extr, or extr->ips is NULL, fatal\n"); ++ SENDERR(EINVAL); ++ } ++ ++ if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_delflow_parse: " ++ "CLEARFLOW flag set, calling cleareroutes.\n"); ++ if ((error = ipsec_cleareroutes())) ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_delflow_parse: " ++ "cleareroutes returned %d.\n", error); ++ SENDERR(-error); ++ } else { ++ struct sk_buff *first = NULL, *last = NULL; ++ ++ if(!(extr->eroute)) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_delflow_parse: " ++ "extr->eroute is NULL, fatal.\n"); ++ SENDERR(EINVAL); ++ } ++ ++ srcflow.u.v4.sin_family = AF_INET; ++ dstflow.u.v4.sin_family = AF_INET; ++ srcmask.u.v4.sin_family = AF_INET; ++ dstmask.u.v4.sin_family = AF_INET; ++ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src; ++ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst; ++ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src; ++ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst; ++ ++#ifdef CONFIG_IPSEC_DEBUG ++ if (debug_pfkey) { ++ subnettoa(extr->eroute->er_eaddr.sen_ip_src, ++ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); ++ subnettoa(extr->eroute->er_eaddr.sen_ip_dst, ++ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_delflow_parse: " ++ "calling breakeroute for %s->%s\n", ++ buf1, buf2); ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ error = ipsec_breakroute(&(extr->eroute->er_eaddr), ++ &(extr->eroute->er_emask), ++ &first, &last); ++ if(error) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_delflow_parse: " ++ "breakeroute returned %d. first=0p%p, last=0p%p\n", ++ error, ++ first, ++ last); ++ } ++ if(first != NULL) { ++ ipsec_kfree_skb(first); ++ } ++ if(last != NULL) { ++ ipsec_kfree_skb(last); ++ } ++ if(error) { ++ SENDERR(-error); ++ } ++ } ++ ++ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], ++ SADB_X_DELFLOW, ++ satype, ++ 0, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, ++ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA], ++ SADB_EXT_SA, ++ extr->ips->ips_said.spi, ++ extr->ips->ips_replaywin, ++ extr->ips->ips_state, ++ extr->ips->ips_authalg, ++ extr->ips->ips_encalg, ++ extr->ips->ips_flags, ++ extr->ips->ips_ref), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW], ++ SADB_X_EXT_ADDRESS_SRC_FLOW, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ (struct sockaddr*)&srcflow), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW], ++ SADB_X_EXT_ADDRESS_DST_FLOW, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ (struct sockaddr*)&dstflow), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK], ++ SADB_X_EXT_ADDRESS_SRC_MASK, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ (struct sockaddr*)&srcmask), ++ extensions_reply) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK], ++ SADB_X_EXT_ADDRESS_DST_MASK, ++ 0, /*extr->ips->ips_said.proto,*/ ++ 0, ++ (struct sockaddr*)&dstmask), ++ extensions_reply) ++ )) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " ++ "failed to build the x_delflow reply message extensions\n"); ++ SENDERR(-error); ++ } ++ ++ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " ++ "failed to build the x_delflow reply message\n"); ++ SENDERR(-error); ++ } ++ ++ for(pfkey_socketsp = pfkey_open_sockets; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " ++ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " ++ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp); ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_delflow_parse: " ++ "extr->ips cleaned up and freed.\n"); ++ ++ errlab: ++ if (pfkey_reply) { ++ pfkey_msg_free(&pfkey_reply); ++ } ++ pfkey_extensions_free(extensions_reply); ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ int error = 0; ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_x_msg_debug_parse: .\n"); ++ ++/* errlab:*/ ++ return error; ++} ++ ++/* pfkey_expire expects the ipsec_sa table to be locked before being called. */ ++int ++pfkey_expire(struct ipsec_sa *ipsp, int hard) ++{ ++ struct sadb_ext *extensions[SADB_EXT_MAX+1]; ++ struct sadb_msg *pfkey_msg = NULL; ++ struct socket_list *pfkey_socketsp; ++ int error = 0; ++ uint8_t satype; ++ ++ pfkey_extensions_init(extensions); ++ ++ if(!(satype = proto2satype(ipsp->ips_said.proto))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_expire: " ++ "satype lookup for protocol %d lookup failed.\n", ++ ipsp->ips_said.proto); ++ SENDERR(EINVAL); ++ } ++ ++ if(!pfkey_open_sockets) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " ++ "no sockets listening.\n"); ++ SENDERR(EPROTONOSUPPORT); ++ } ++ ++ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0], ++ SADB_EXPIRE, ++ satype, ++ 0, ++ ++pfkey_msg_seq, ++ 0), ++ extensions) ++ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions[SADB_EXT_SA], ++ SADB_EXT_SA, ++ ipsp->ips_said.spi, ++ ipsp->ips_replaywin, ++ ipsp->ips_state, ++ ipsp->ips_authalg, ++ ipsp->ips_encalg, ++ ipsp->ips_flags, ++ ipsp->ips_ref), ++ extensions) ++ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT], ++ SADB_EXT_LIFETIME_CURRENT, ++ ipsp->ips_life.ipl_allocations.ipl_count, ++ ipsp->ips_life.ipl_bytes.ipl_count, ++ ipsp->ips_life.ipl_addtime.ipl_count, ++ ipsp->ips_life.ipl_usetime.ipl_count, ++ ipsp->ips_life.ipl_packets.ipl_count), ++ extensions) ++ && (hard ? ++ pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD], ++ SADB_EXT_LIFETIME_HARD, ++ ipsp->ips_life.ipl_allocations.ipl_hard, ++ ipsp->ips_life.ipl_bytes.ipl_hard, ++ ipsp->ips_life.ipl_addtime.ipl_hard, ++ ipsp->ips_life.ipl_usetime.ipl_hard, ++ ipsp->ips_life.ipl_packets.ipl_hard), ++ extensions) ++ : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT], ++ SADB_EXT_LIFETIME_SOFT, ++ ipsp->ips_life.ipl_allocations.ipl_soft, ++ ipsp->ips_life.ipl_bytes.ipl_soft, ++ ipsp->ips_life.ipl_addtime.ipl_soft, ++ ipsp->ips_life.ipl_usetime.ipl_soft, ++ ipsp->ips_life.ipl_packets.ipl_soft), ++ extensions)) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], ++ SADB_EXT_ADDRESS_SRC, ++ 0, /* ipsp->ips_said.proto, */ ++ 0, ++ ipsp->ips_addr_s), ++ extensions) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], ++ SADB_EXT_ADDRESS_DST, ++ 0, /* ipsp->ips_said.proto, */ ++ 0, ++ ipsp->ips_addr_d), ++ extensions))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " ++ "failed to build the expire message extensions\n"); ++ spin_unlock(&tdb_lock); ++ goto errlab; ++ } ++ ++ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " ++ "failed to build the expire message\n"); ++ SENDERR(-error); ++ } ++ ++ for(pfkey_socketsp = pfkey_open_sockets; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " ++ "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " ++ "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ ipsp->ips_said.proto, ++ pfkey_socketsp->socketp); ++ } ++ ++ errlab: ++ if (pfkey_msg) { ++ pfkey_msg_free(&pfkey_msg); ++ } ++ pfkey_extensions_free(extensions); ++ return error; ++} ++ ++int ++pfkey_acquire(struct ipsec_sa *ipsp) ++{ ++ struct sadb_ext *extensions[SADB_EXT_MAX+1]; ++ struct sadb_msg *pfkey_msg = NULL; ++ struct socket_list *pfkey_socketsp; ++ int error = 0; ++ struct sadb_comb comb[] = { ++ /* auth; encrypt; flags; */ ++ /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */ ++ /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */ ++ /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */ ++ /* soft_packets; hard_packets; */ ++ { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS, ++ 128, 128, 168, 168, ++ 0, 0, 0, 0, 0, ++ 57600, 86400, 57600, 86400, ++ 0, 0 }, ++ { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS, ++ 160, 160, 168, 168, ++ 0, 0, 0, 0, 0, ++ 57600, 86400, 57600, 86400, ++ 0, 0 } ++ }; ++ ++ /* XXX This should not be hard-coded. It should be taken from the spdb */ ++ uint8_t satype = SADB_SATYPE_ESP; ++ ++ pfkey_extensions_init(extensions); ++ ++ if((satype == 0) || (satype > SADB_SATYPE_MAX)) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " ++ "SAtype=%d unspecified or unknown.\n", ++ satype); ++ SENDERR(EINVAL); ++ } ++ ++ if(!(pfkey_registered_sockets[satype])) { ++ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " ++ "no sockets registered for SAtype=%d(%s).\n", ++ satype, ++ satype2name(satype)); ++ SENDERR(EPROTONOSUPPORT); ++ } ++ ++ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0], ++ SADB_ACQUIRE, ++ satype, ++ 0, ++ ++pfkey_msg_seq, ++ 0), ++ extensions) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], ++ SADB_EXT_ADDRESS_SRC, ++ ipsp->ips_transport_protocol, ++ 0, ++ ipsp->ips_addr_s), ++ extensions) ++ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], ++ SADB_EXT_ADDRESS_DST, ++ ipsp->ips_transport_protocol, ++ 0, ++ ipsp->ips_addr_d), ++ extensions) ++#if 0 ++ && (ipsp->ips_addr_p ++ ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY], ++ SADB_EXT_ADDRESS_PROXY, ++ ipsp->ips_transport_protocol, ++ 0, ++ ipsp->ips_addr_p), ++ extensions) : 1) ++#endif ++ && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED ++ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC], ++ SADB_EXT_IDENTITY_SRC, ++ ipsp->ips_ident_s.type, ++ ipsp->ips_ident_s.id, ++ ipsp->ips_ident_s.len, ++ ipsp->ips_ident_s.data), ++ extensions) : 1) ++ ++ && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED ++ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST], ++ SADB_EXT_IDENTITY_DST, ++ ipsp->ips_ident_d.type, ++ ipsp->ips_ident_d.id, ++ ipsp->ips_ident_d.len, ++ ipsp->ips_ident_d.data), ++ extensions) : 1) ++#if 0 ++ /* FIXME: This won't work yet because I have not finished ++ it. */ ++ && (ipsp->ips_sens_ ++ ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY], ++ ipsp->ips_sens_dpd, ++ ipsp->ips_sens_sens_level, ++ ipsp->ips_sens_sens_len, ++ ipsp->ips_sens_sens_bitmap, ++ ipsp->ips_sens_integ_level, ++ ipsp->ips_sens_integ_len, ++ ipsp->ips_sens_integ_bitmap), ++ extensions) : 1) ++#endif ++ && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL], ++ 64, /* replay */ ++ sizeof(comb)/sizeof(struct sadb_comb), ++ &(comb[0])), ++ extensions) ++ )) { ++ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " ++ "failed to build the acquire message extensions\n"); ++ SENDERR(-error); ++ } ++ ++ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { ++ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " ++ "failed to build the acquire message\n"); ++ SENDERR(-error); ++ } ++ ++#if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0 ++ if(sysctl_ipsec_regress_pfkey_lossage) { ++ return(0); ++ } ++#endif ++ ++ /* this should go to all registered sockets for that satype only */ ++ for(pfkey_socketsp = pfkey_registered_sockets[satype]; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { ++ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: " ++ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " ++ "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp); ++ } ++ ++ errlab: ++ if (pfkey_msg) { ++ pfkey_msg_free(&pfkey_msg); ++ } ++ pfkey_extensions_free(extensions); ++ return error; ++} ++ ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++int ++pfkey_nat_t_new_mapping(struct ipsec_sa *ipsp, struct sockaddr *ipaddr, ++ __u16 sport) ++{ ++ struct sadb_ext *extensions[SADB_EXT_MAX+1]; ++ struct sadb_msg *pfkey_msg = NULL; ++ struct socket_list *pfkey_socketsp; ++ int error = 0; ++ uint8_t satype = (ipsp->ips_said.proto==IPPROTO_ESP) ? SADB_SATYPE_ESP : 0; ++ ++ /* Construct SADB_X_NAT_T_NEW_MAPPING message */ ++ ++ pfkey_extensions_init(extensions); ++ ++ if((satype == 0) || (satype > SADB_SATYPE_MAX)) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " ++ "SAtype=%d unspecified or unknown.\n", ++ satype); ++ SENDERR(EINVAL); ++ } ++ ++ if(!(pfkey_registered_sockets[satype])) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " ++ "no sockets registered for SAtype=%d(%s).\n", ++ satype, ++ satype2name(satype)); ++ SENDERR(EPROTONOSUPPORT); ++ } ++ ++ if (!(pfkey_safe_build ++ (error = pfkey_msg_hdr_build(&extensions[0], SADB_X_NAT_T_NEW_MAPPING, ++ satype, 0, ++pfkey_msg_seq, 0), extensions) ++ /* SA */ ++ && pfkey_safe_build ++ (error = pfkey_sa_build(&extensions[SADB_EXT_SA], ++ SADB_EXT_SA, ipsp->ips_said.spi, 0, 0, 0, 0, 0), extensions) ++ /* ADDRESS_SRC = old addr */ ++ && pfkey_safe_build ++ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], ++ SADB_EXT_ADDRESS_SRC, ipsp->ips_said.proto, 0, ipsp->ips_addr_s), ++ extensions) ++ /* NAT_T_SPORT = old port */ ++ && pfkey_safe_build ++ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_SPORT], ++ SADB_X_EXT_NAT_T_SPORT, ipsp->ips_natt_sport), extensions) ++ /* ADDRESS_DST = new addr */ ++ && pfkey_safe_build ++ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], ++ SADB_EXT_ADDRESS_DST, ipsp->ips_said.proto, 0, ipaddr), extensions) ++ /* NAT_T_DPORT = new port */ ++ && pfkey_safe_build ++ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_DPORT], ++ SADB_X_EXT_NAT_T_DPORT, sport), extensions) ++ )) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " ++ "failed to build the nat_t_new_mapping message extensions\n"); ++ SENDERR(-error); ++ } ++ ++ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " ++ "failed to build the nat_t_new_mapping message\n"); ++ SENDERR(-error); ++ } ++ ++ /* this should go to all registered sockets for that satype only */ ++ for(pfkey_socketsp = pfkey_registered_sockets[satype]; ++ pfkey_socketsp; ++ pfkey_socketsp = pfkey_socketsp->next) { ++ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " ++ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp, ++ error); ++ SENDERR(-error); ++ } ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " ++ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n", ++ satype, ++ satype2name(satype), ++ pfkey_socketsp->socketp); ++ } ++ ++ errlab: ++ if (pfkey_msg) { ++ pfkey_msg_free(&pfkey_msg); ++ } ++ pfkey_extensions_free(extensions); ++ return error; ++} ++ ++DEBUG_NO_STATIC int ++pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) ++{ ++ /* SADB_X_NAT_T_NEW_MAPPING not used in kernel */ ++ return -EINVAL; ++} ++#endif ++ ++DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) = ++{ ++ NULL, /* pfkey_msg_process, */ ++ pfkey_sa_process, ++ pfkey_lifetime_process, ++ pfkey_lifetime_process, ++ pfkey_lifetime_process, ++ pfkey_address_process, ++ pfkey_address_process, ++ pfkey_address_process, ++ pfkey_key_process, ++ pfkey_key_process, ++ pfkey_ident_process, ++ pfkey_ident_process, ++ pfkey_sens_process, ++ pfkey_prop_process, ++ pfkey_supported_process, ++ pfkey_supported_process, ++ pfkey_spirange_process, ++ pfkey_x_kmprivate_process, ++ pfkey_x_satype_process, ++ pfkey_sa_process, ++ pfkey_address_process, ++ pfkey_address_process, ++ pfkey_address_process, ++ pfkey_address_process, ++ pfkey_address_process, ++ pfkey_x_debug_process, ++ pfkey_x_protocol_process ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ , ++ pfkey_x_nat_t_type_process, ++ pfkey_x_nat_t_port_process, ++ pfkey_x_nat_t_port_process, ++ pfkey_address_process ++#endif ++}; ++ ++ ++DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr) ++ = ++{ ++ NULL, /* RESERVED */ ++ pfkey_getspi_parse, ++ pfkey_update_parse, ++ pfkey_add_parse, ++ pfkey_delete_parse, ++ pfkey_get_parse, ++ pfkey_acquire_parse, ++ pfkey_register_parse, ++ pfkey_expire_parse, ++ pfkey_flush_parse, ++ pfkey_dump_parse, ++ pfkey_x_promisc_parse, ++ pfkey_x_pchange_parse, ++ pfkey_x_grpsa_parse, ++ pfkey_x_addflow_parse, ++ pfkey_x_delflow_parse, ++ pfkey_x_msg_debug_parse ++#ifdef CONFIG_IPSEC_NAT_TRAVERSAL ++ , pfkey_x_nat_t_new_mapping_parse ++#endif ++}; ++ ++int ++pfkey_build_reply(struct sadb_msg *pfkey_msg, struct pfkey_extracted_data *extr, ++ struct sadb_msg **pfkey_reply) ++{ ++ struct sadb_ext *extensions[SADB_EXT_MAX+1]; ++ int error = 0; ++ int msg_type = pfkey_msg->sadb_msg_type; ++ int seq = pfkey_msg->sadb_msg_seq; ++ ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " ++ "building reply with type: %d\n", ++ msg_type); ++ pfkey_extensions_init(extensions); ++ if (!extr || !extr->ips) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " ++ "bad ipsec_sa passed\n"); ++ return EINVAL; ++ } ++ error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0], ++ msg_type, ++ proto2satype(extr->ips->ips_said.proto), ++ 0, ++ seq, ++ pfkey_msg->sadb_msg_pid), ++ extensions) && ++ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & ++ 1 << SADB_EXT_SA) ++ || pfkey_safe_build(pfkey_sa_ref_build(&extensions[SADB_EXT_SA], ++ SADB_EXT_SA, ++ extr->ips->ips_said.spi, ++ extr->ips->ips_replaywin, ++ extr->ips->ips_state, ++ extr->ips->ips_authalg, ++ extr->ips->ips_encalg, ++ extr->ips->ips_flags, ++ extr->ips->ips_ref), ++ extensions)) && ++ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & ++ 1 << SADB_EXT_LIFETIME_CURRENT) ++ || pfkey_safe_build(pfkey_lifetime_build(&extensions ++ [SADB_EXT_LIFETIME_CURRENT], ++ SADB_EXT_LIFETIME_CURRENT, ++ extr->ips->ips_life.ipl_allocations.ipl_count, ++ extr->ips->ips_life.ipl_bytes.ipl_count, ++ extr->ips->ips_life.ipl_addtime.ipl_count, ++ extr->ips->ips_life.ipl_usetime.ipl_count, ++ extr->ips->ips_life.ipl_packets.ipl_count), ++ extensions)) && ++ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & ++ 1 << SADB_EXT_ADDRESS_SRC) ++ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], ++ SADB_EXT_ADDRESS_SRC, ++ extr->ips->ips_said.proto, ++ 0, ++ extr->ips->ips_addr_s), ++ extensions)) && ++ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & ++ 1 << SADB_EXT_ADDRESS_DST) ++ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], ++ SADB_EXT_ADDRESS_DST, ++ extr->ips->ips_said.proto, ++ 0, ++ extr->ips->ips_addr_d), ++ extensions)); ++ ++ if (error == 0) { ++ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " ++ "building extensions failed\n"); ++ return EINVAL; ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_build_reply: " ++ "built extensions, proceed to build the message\n"); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_build_reply: " ++ "extensions[1]=0p%p\n", ++ extensions[1]); ++ error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT); ++ pfkey_extensions_free(extensions); ++ ++ return error; ++} ++ ++int ++pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg, ++ struct sadb_msg **pfkey_reply) ++{ ++ int error = 0; ++ int i; ++ struct sadb_ext *extensions[SADB_EXT_MAX+1]; ++ struct pfkey_extracted_data extr = {NULL, NULL, NULL}; ++ ++ pfkey_extensions_init(extensions); ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_msg_interp: " ++ "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n", ++ pfkey_msg->sadb_msg_version, ++ pfkey_msg->sadb_msg_type, ++ pfkey_msg->sadb_msg_errno, ++ pfkey_msg->sadb_msg_satype, ++ satype2name(pfkey_msg->sadb_msg_satype), ++ pfkey_msg->sadb_msg_len, ++ pfkey_msg->sadb_msg_reserved, ++ pfkey_msg->sadb_msg_seq, ++ pfkey_msg->sadb_msg_pid); ++ ++ extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */ ++ if(extr.ips == NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_msg_interp: " ++ "memory allocation error.\n"); ++ SENDERR(-error); ++ } ++ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_msg_interp: " ++ "allocated extr->ips=0p%p.\n", ++ extr.ips); ++ ++ if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_msg_interp: " ++ "satype %d > max %d\n", ++ pfkey_msg->sadb_msg_satype, ++ SADB_SATYPE_MAX); ++ SENDERR(EINVAL); ++ } ++ ++ switch(pfkey_msg->sadb_msg_type) { ++ case SADB_GETSPI: ++ case SADB_UPDATE: ++ case SADB_ADD: ++ case SADB_DELETE: ++ case SADB_X_GRPSA: ++ case SADB_X_ADDFLOW: ++ ++ if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_msg_interp: " ++ "satype %d lookup failed.\n", ++ pfkey_msg->sadb_msg_satype); ++ SENDERR(EINVAL); ++ } else { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_msg_interp: " ++ "satype %d lookups to proto=%d.\n", ++ pfkey_msg->sadb_msg_satype, ++ extr.ips->ips_said.proto); ++ } ++ break; ++ default: ++ break; ++ } ++ ++ /* The NULL below causes the default extension parsers to be used */ ++ /* Parse the extensions */ ++ if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN))) ++ { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_msg_interp: " ++ "message parsing failed with error %d.\n", ++ error); ++ SENDERR(-error); ++ } ++ ++ /* Process the extensions */ ++ for(i=1; i <= SADB_EXT_MAX;i++) { ++ if(extensions[i] != NULL) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_msg_interp: " ++ "processing ext %d 0p%p with processor 0p%p.\n", ++ i, extensions[i], ext_processors[i]); ++ if((error = ext_processors[i](extensions[i], &extr))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_msg_interp: " ++ "extension processing for type %d failed with error %d.\n", ++ i, ++ error); ++ SENDERR(-error); ++ } ++ ++ } ++ ++ } ++ ++ /* Parse the message types */ ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_msg_interp: " ++ "parsing message type %d(%s) with msg_parser 0p%p.\n", ++ pfkey_msg->sadb_msg_type, ++ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type), ++ msg_parsers[pfkey_msg->sadb_msg_type]); ++ if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) { ++ KLIPS_PRINT(debug_pfkey, ++ "klips_debug:pfkey_msg_interp: " ++ "message parsing failed with error %d.\n", ++ error); ++ SENDERR(-error); ++ } ++ ++#if 0 ++ error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply); ++ if (error) { ++ *pfkey_reply = NULL; ++ } ++#endif ++ errlab: ++ if(extr.ips != NULL) { ++ ipsec_sa_wipe(extr.ips); ++ } ++ if(extr.ips2 != NULL) { ++ ipsec_sa_wipe(extr.ips2); ++ } ++ if (extr.eroute != NULL) { ++ kfree(extr.eroute); ++ } ++ return(error); ++} ++ ++/* ++ * $Log: pfkey_v2_parser.c,v $ ++ * Revision 1.123 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.122.2.2 2004/04/05 04:30:46 mcr ++ * patches for alg-branch to compile/work with 2.x openswan ++ * ++ * Revision 1.122.2.1 2003/12/22 15:25:52 jjo ++ * . Merged algo-0.8.1-rc11-test1 into alg-branch ++ * ++ * Revision 1.122 2003/12/10 01:14:27 mcr ++ * NAT-traversal patches to KLIPS. ++ * ++ * Revision 1.121 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.120.4.2 2003/10/29 01:30:41 mcr ++ * elimited "struct sa_id". ++ * ++ * Revision 1.120.4.1 2003/09/21 13:59:56 mcr ++ * pre-liminary X.509 patch - does not yet pass tests. ++ * ++ * Revision 1.120 2003/04/03 17:38:09 rgb ++ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}. ++ * ++ * Revision 1.119 2003/02/06 01:52:37 rgb ++ * Removed no longer relevant comment ++ * ++ * Revision 1.118 2003/01/30 02:32:44 rgb ++ * ++ * Transmit error code through to caller from callee for better diagnosis of problems. ++ * ++ * Revision 1.117 2003/01/16 18:48:13 rgb ++ * ++ * Fixed sign bug in error return from an sa allocation call in ++ * pfkey_msg_interp. ++ * ++ * Revision 1.116 2002/10/17 16:38:01 rgb ++ * Change pfkey_alloc_eroute() to never static since its consumers ++ * have been moved outside the file. ++ * ++ * Revision 1.115 2002/10/12 23:11:53 dhr ++ * ++ * [KenB + DHR] more 64-bit cleanup ++ * ++ * Revision 1.114 2002/10/05 05:02:58 dhr ++ * ++ * C labels go on statements ++ * ++ * Revision 1.113 2002/09/30 19:11:22 rgb ++ * Turn on debugging for upgoing acquire messages to test for reliability. ++ * ++ * Revision 1.112 2002/09/20 15:41:16 rgb ++ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc(). ++ * Added sadb_x_sa_ref to struct sadb_sa. ++ * Added ref parameter to pfkey_sa_build(). ++ * ++ * Revision 1.111 2002/09/20 05:02:08 rgb ++ * Added memory allocation debugging. ++ * Convert to switch to divulge hmac keys for debugging. ++ * Added text labels to elucidate numeric values presented. ++ * ++ * Revision 1.110 2002/08/03 18:03:05 mcr ++ * loop that checks for SPI's to have been already linked ++ * fails to actually step to next pointer, but continuously ++ * resets to head of list. Wrong pointer used. ++ * test east-icmp-02 revealed this. ++ * ++ * Revision 1.109 2002/07/26 08:48:31 rgb ++ * Added SA ref table code. ++ * ++ * Revision 1.108 2002/05/27 18:55:03 rgb ++ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT. ++ * ++ * Revision 1.107 2002/05/23 07:16:08 rgb ++ * Added ipsec_sa_put() for releasing an ipsec_sa refcount. ++ * Pointer clean-up. ++ * Added refcount code. ++ * ++ * Revision 1.106 2002/05/14 02:34:13 rgb ++ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion ++ * with "put" usage in the kernel. ++ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips, ++ * ipsec_sa or ipsec_sa. ++ * Moved all the extension parsing functions to pfkey_v2_ext_process.c. ++ * ++ * Revision 1.105 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.104 2002/04/24 07:36:34 mcr ++ * Moved from ./klips/net/ipsec/pfkey_v2_parser.c,v ++ * ++ * Revision 1.103 2002/04/20 00:12:25 rgb ++ * Added esp IV CBC attack fix, disabled. ++ * ++ * Revision 1.102 2002/03/08 01:15:17 mcr ++ * put some internal structure only debug messages behind ++ * && sysctl_ipsec_debug_verbose. ++ * ++ * Revision 1.101 2002/01/29 17:17:57 mcr ++ * moved include of ipsec_param.h to after include of linux/kernel.h ++ * otherwise, it seems that some option that is set in ipsec_param.h ++ * screws up something subtle in the include path to kernel.h, and ++ * it complains on the snprintf() prototype. ++ * ++ * Revision 1.100 2002/01/29 04:00:54 mcr ++ * more excise of kversions.h header. ++ * ++ * Revision 1.99 2002/01/29 02:13:19 mcr ++ * introduction of ipsec_kversion.h means that include of ++ * ipsec_param.h must preceed any decisions about what files to ++ * include to deal with differences in kernel source. ++ * ++ * Revision 1.98 2002/01/12 02:57:57 mcr ++ * first regression test causes acquire messages to be lost ++ * 100% of the time. This is to help testing of pluto. ++ * ++ * Revision 1.97 2001/11/26 09:23:52 rgb ++ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. ++ * ++ * Revision 1.93.2.4 2001/10/23 04:20:27 mcr ++ * parity was forced on wrong structure! prototypes help here. ++ * ++ * Revision 1.93.2.3 2001/10/22 21:14:59 mcr ++ * include des.h, removed phony prototypes and fixed calling ++ * conventions to match real prototypes. ++ * ++ * Revision 1.93.2.2 2001/10/15 05:39:03 mcr ++ * %08lx is not the right format for u32. Use %08x. 64-bit safe? ha. ++ * ++ * Revision 1.93.2.1 2001/09/25 02:30:14 mcr ++ * struct tdb -> struct ipsec_sa. ++ * use new lifetime structure. common format routines for debug. ++ * ++ * Revision 1.96 2001/11/06 20:47:54 rgb ++ * Fixed user context call to ipsec_dev_start_xmit() bug. Call ++ * dev_queue_xmit() instead. ++ * ++ * Revision 1.95 2001/11/06 19:47:46 rgb ++ * Added packet parameter to lifetime and comb structures. ++ * ++ * Revision 1.94 2001/10/18 04:45:23 rgb ++ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, ++ * lib/freeswan.h version macros moved to lib/kversions.h. ++ * Other compiler directive cleanups. ++ * ++ * Revision 1.93 2001/09/20 15:32:59 rgb ++ * Min/max cleanup. ++ * ++ * Revision 1.92 2001/09/19 16:35:48 rgb ++ * PF_KEY ident fix for getspi from NetCelo (puttdb duplication). ++ * ++ * Revision 1.91 2001/09/15 16:24:06 rgb ++ * Re-inject first and last HOLD packet when an eroute REPLACE is done. ++ * ++ * Revision 1.90 2001/09/14 16:58:38 rgb ++ * Added support for storing the first and last packets through a HOLD. ++ * ++ * Revision 1.89 2001/09/08 21:14:07 rgb ++ * Added pfkey ident extension support for ISAKMPd. (NetCelo) ++ * Better state coherency (error management) between pf_key and IKE daemon. ++ * (NetCelo) ++ * ++ * Revision 1.88 2001/08/27 19:42:44 rgb ++ * Fix memory leak of encrypt and auth structs in pfkey register. ++ * ++ * Revision 1.87 2001/07/06 19:50:46 rgb ++ * Removed unused debugging code. ++ * Added inbound policy checking code for IPIP SAs. ++ * ++ * Revision 1.86 2001/06/20 06:26:04 rgb ++ * Changed missing SA errors from EEXIST to ENOENT and added debug output ++ * for already linked SAs. ++ * ++ * Revision 1.85 2001/06/15 04:57:02 rgb ++ * Remove single error return condition check and check for all errors in ++ * the case of a replace eroute delete operation. This means that ++ * applications must expect to be deleting something before replacing it ++ * and if nothing is found, complain. ++ * ++ * Revision 1.84 2001/06/14 19:35:12 rgb ++ * Update copyright date. ++ * ++ * Revision 1.83 2001/06/12 00:03:19 rgb ++ * Silence debug set/unset under normal conditions. ++ * ++ * Revision 1.82 2001/05/30 08:14:04 rgb ++ * Removed vestiges of esp-null transforms. ++ * ++ * Revision 1.81 2001/05/27 06:12:12 rgb ++ * Added structures for pid, packet count and last access time to eroute. ++ * Added packet count to beginning of /proc/net/ipsec_eroute. ++ * ++ * Revision 1.80 2001/05/03 19:43:59 rgb ++ * Check error return codes for all build function calls. ++ * Standardise on SENDERR() macro. ++ * ++ * Revision 1.79 2001/04/20 21:09:16 rgb ++ * Cleaned up fixed tdbwipes. ++ * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and ++ * delflow (Per Cederqvist) plugging memleaks. ++ * ++ * Revision 1.78 2001/04/19 19:02:39 rgb ++ * Fixed extr.tdb freeing, stealing it for getspi, update and add. ++ * Refined a couple of spinlocks, fixed the one in update. ++ * ++ * Revision 1.77 2001/04/18 20:26:16 rgb ++ * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp() ++ * instead of inside each message type parser. This fixes two memleaks. ++ * ++ * Revision 1.76 2001/04/17 23:51:18 rgb ++ * Quiet down pfkey_x_debug_process(). ++ * ++ * Revision 1.75 2001/03/29 01:55:05 rgb ++ * Fixed pfkey key init memleak. ++ * Fixed pfkey encryption key debug output. ++ * ++ * Revision 1.74 2001/03/27 05:29:14 rgb ++ * Debug output cleanup/silencing. ++ * ++ * Revision 1.73 2001/02/28 05:03:28 rgb ++ * Clean up and rationalise startup messages. ++ * ++ * Revision 1.72 2001/02/27 22:24:56 rgb ++ * Re-formatting debug output (line-splitting, joining, 1arg/line). ++ * Check for satoa() return codes. ++ * ++ * Revision 1.71 2001/02/27 06:59:30 rgb ++ * Added satype2name() conversions most places satype is debug printed. ++ * ++ * Revision 1.70 2001/02/26 22:37:08 rgb ++ * Fixed 'unknown proto' INT bug in new code. ++ * Added satype to protocol debugging instrumentation. ++ * ++ * Revision 1.69 2001/02/26 19:57:51 rgb ++ * Re-formatted debug output (split lines, consistent spacing). ++ * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup() ++ * with an satype instead of proto. ++ * Checked for satype consistency and fixed minor bugs. ++ * Fixed undetected ungrpspi bug that tried to upmsg a second tdb. ++ * Check for satype sanity in pfkey_expire(). ++ * Added satype sanity check to addflow. ++ * ++ * Revision 1.68 2001/02/12 23:14:40 rgb ++ * Remove double spin lock in pfkey_expire(). ++ * ++ * Revision 1.67 2001/01/31 19:23:40 rgb ++ * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete). ++ * ++ * Revision 1.66 2001/01/29 22:20:04 rgb ++ * Fix minor add upmsg lifetime bug. ++ * ++ * Revision 1.65 2001/01/24 06:12:33 rgb ++ * Fixed address extension compile bugs just introduced. ++ * ++ * Revision 1.64 2001/01/24 00:31:15 rgb ++ * Added upmsg for addflow/delflow. ++ * ++ * Revision 1.63 2001/01/23 22:02:55 rgb ++ * Added upmsg to x_grpsa. ++ * Fixed lifetimes extentions to add/update/get upmsg. ++ * ++ * Revision 1.62 2000/11/30 21:47:51 rgb ++ * Fix error return bug after returning from pfkey_tdb_init(). ++ * ++ * Revision 1.61 2000/11/17 18:10:29 rgb ++ * Fixed bugs mostly relating to spirange, to treat all spi variables as ++ * network byte order since this is the way PF_KEYv2 stored spis. ++ * ++ * Revision 1.60 2000/11/06 04:34:53 rgb ++ * Changed non-exported functions to DEBUG_NO_STATIC. ++ * Add Svenning's adaptive content compression. ++ * Ditched spin_lock_irqsave in favour of spin_lock/_bh. ++ * Fixed double unlock bug (Svenning). ++ * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}(). ++ * Fixed incorrect extension type (prop) in pfkey)acquire(). ++ * ++ * Revision 1.59 2000/10/11 15:25:12 rgb ++ * Fixed IPCOMP disabled compile bug. ++ * ++ * Revision 1.58 2000/10/11 14:54:03 rgb ++ * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey ++ * protocol violations of setting pfkey_address_build() protocol parameter ++ * to non-zero except in the case of pfkey_acquire(). ++ * ++ * Revision 1.57 2000/10/10 20:10:18 rgb ++ * Added support for debug_ipcomp and debug_verbose to klipsdebug. ++ * ++ * Revision 1.56 2000/10/06 20:24:36 rgb ++ * Fixes to pfkey_acquire to initialize extensions[] and use correct ++ * ipproto. ++ * ++ * Revision 1.55 2000/10/03 03:20:57 rgb ++ * Added brackets to get a?b:c scope right for pfkey_register reply. ++ * ++ * Revision 1.54 2000/09/29 19:49:30 rgb ++ * As-yet-unused-bits cleanup. ++ * ++ * Revision 1.53 2000/09/28 00:35:45 rgb ++ * Padded SATYPE printout in pfkey_register for vertical alignment. ++ * ++ * Revision 1.52 2000/09/20 16:21:58 rgb ++ * Cleaned up ident string alloc/free. ++ * ++ * Revision 1.51 2000/09/20 04:04:20 rgb ++ * Changed static functions to DEBUG_NO_STATIC to reveal function names in ++ * oopsen. ++ * ++ * Revision 1.50 2000/09/16 01:10:53 rgb ++ * Fixed unused var warning with debug off. ++ * ++ * Revision 1.49 2000/09/15 11:37:02 rgb ++ * Merge in heavily modified Svenning Soerensen's ++ * IPCOMP zlib deflate code. ++ * ++ * Revision 1.48 2000/09/15 04:57:57 rgb ++ * Cleaned up existing IPCOMP code before svenning addition. ++ * Initialize pfkey_reply and extensions_reply in case of early error in ++ * message parsing functions (thanks Kai!). ++ * ++ * Revision 1.47 2000/09/13 08:02:56 rgb ++ * Added KMd registration notification. ++ * ++ * Revision 1.46 2000/09/12 22:35:36 rgb ++ * Restructured to remove unused extensions from CLEARFLOW messages. ++ * ++ * Revision 1.45 2000/09/12 03:24:23 rgb ++ * Converted #if0 debugs to sysctl. ++ * ++ * Revision 1.44 2000/09/09 06:38:39 rgb ++ * Correct SADB message type for update, add and delete. ++ * ++ * Revision 1.43 2000/09/08 19:19:56 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * Removed all references to CONFIG_IPSEC_PFKEYv2. ++ * Put in sanity checks in most msg type parsers to catch invalid satypes ++ * and empty socket lists. ++ * Moved spin-locks in pfkey_get_parse() to simplify. ++ * Added pfkey_acquire(). ++ * Added upwards messages to update, add, delete, acquire_parse, ++ * expire_parse and flush. ++ * Fix pfkey_prop_build() parameter to be only single indirection. ++ * Changed all replies to use pfkey_reply. ++ * Check return code on puttdb() and deltdbchain() in getspi, update, ++ * add, delete. ++ * Fixed up all pfkey replies to open and registered sockets. ++ * ++ * Revision 1.42 2000/09/01 18:50:26 rgb ++ * Added a supported algorithms array lists, one per satype and registered ++ * existing algorithms. ++ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to ++ * list. ++ * Only send pfkey_expire() messages to sockets registered for that satype. ++ * Added reply to pfkey_getspi_parse(). ++ * Added reply to pfkey_get_parse(). ++ * Fixed debug output label bug in pfkey_lifetime_process(). ++ * Cleaned up pfkey_sa_process a little. ++ * Moved pfkey_safe_build() above message type parsers to make it available ++ * for creating replies. ++ * Added comments for future work in pfkey_acquire_parse(). ++ * Fleshed out guts of pfkey_register_parse(). ++ * ++ * Revision 1.41 2000/08/24 16:58:11 rgb ++ * Fixed key debugging variables. ++ * Fixed error return code for a failed search. ++ * Changed order of pfkey_get operations. ++ * ++ * Revision 1.40 2000/08/21 16:32:27 rgb ++ * Re-formatted for cosmetic consistency and readability. ++ * ++ * Revision 1.39 2000/08/20 21:38:57 rgb ++ * Bugfixes to as-yet-unused pfkey_update_parse() and ++ * pfkey_register_parse(). (Momchil) ++ * Added functions pfkey_safe_build(), pfkey_expire() and ++ * pfkey_build_reply(). (Momchil) ++ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil) ++ * ++ * Revision 1.38 2000/08/18 21:30:41 rgb ++ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear. ++ * ++ * Revision 1.37 2000/08/18 18:18:02 rgb ++ * Cosmetic and descriptive changes made to debug test. ++ * getspi and update fixes from Momchil. ++ * ++ * Revision 1.36 2000/08/15 15:41:55 rgb ++ * Fixed the (as yet unused and untested) pfkey_getspi() routine. ++ * ++ * Revision 1.35 2000/08/01 14:51:52 rgb ++ * Removed _all_ remaining traces of DES. ++ * ++ * Revision 1.34 2000/07/28 14:58:32 rgb ++ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. ++ * ++ * Revision 1.33 2000/06/28 05:50:11 rgb ++ * Actually set iv_bits. ++ * ++ * Revision 1.32 2000/05/30 18:36:56 rgb ++ * Fix AH auth hash setup bug. This breaks interop with previous PF_KEY ++ * FreeS/WAN, but fixes interop with other implementations. ++ * ++ * Revision 1.31 2000/03/16 14:05:48 rgb ++ * Fixed brace scope preventing non-debug compile. ++ * Added null parameter check for pfkey_x_debug(). ++ * ++ * Revision 1.30 2000/01/22 23:21:13 rgb ++ * Use new function satype2proto(). ++ * ++ * Revision 1.29 2000/01/22 08:40:21 rgb ++ * Invert condition to known value to avoid AF_INET6 in 2.0.36. ++ * ++ * Revision 1.28 2000/01/22 07:58:57 rgb ++ * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR. ++ * ++ * Revision 1.27 2000/01/22 03:48:01 rgb ++ * Added extr pointer component debugging. ++ * ++ * Revision 1.26 2000/01/21 09:41:25 rgb ++ * Changed a (void*) to (char*) cast to do proper pointer math. ++ * Don't call tdbwipe if tdb2 is NULL. ++ * ++ * Revision 1.25 2000/01/21 06:21:01 rgb ++ * Added address cases for eroute flows. ++ * Tidied up compiler directive indentation for readability. ++ * Added ictx,octx vars for simplification. ++ * Added macros for HMAC padding magic numbers. ++ * Converted from double tdb arguments to one structure (extr) ++ * containing pointers to all temporary information structures ++ * and checking for valid arguments to all ext processors and ++ * msg type parsers. ++ * Added spiungrp'ing. ++ * Added klipsdebug switching capability. ++ * Removed sa_process() check for zero protocol. ++ * Added address case for DST2 for grouping. ++ * Added/changed minor debugging instrumentation. ++ * Fixed spigrp for single said, ungrouping case. ++ * Added code to parse addflow and delflow messages. ++ * Removed redundant statements duplicating tdbwipe() functionality ++ * and causing double kfrees. ++ * Permit addflow to have a protocol of 0. ++ * ++ * Revision 1.24 1999/12/09 23:23:00 rgb ++ * Added check to pfkey_sa_process() to do eroutes. ++ * Converted to DIVUP() macro. ++ * Converted if() to switch() in pfkey_register_parse(). ++ * Use new pfkey_extensions_init() instead of memset(). ++ * ++ * Revision 1.23 1999/12/01 22:18:13 rgb ++ * Preset minspi and maxspi values in case and spirange extension is not ++ * included and check for the presence of an spirange extension before ++ * using it. Initialise tdb_sastate to LARVAL. ++ * Fixed debugging output typo. ++ * Fixed authentication context initialisation bugs (4 places). ++ * ++ * Revision 1.22 1999/11/27 11:53:08 rgb ++ * Moved pfkey_msg_parse prototype to pfkey.h ++ * Moved exts_permitted/required prototype to pfkey.h. ++ * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c. ++ * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never ++ * be called. ++ * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c ++ * Debugging error messages added. ++ * Enable lifetime_current checking. ++ * Remove illegal requirement for SA extension to be present in an ++ * originating GETSPI call. ++ * Re-instate requirement for UPDATE or ADD message to be MATURE. ++ * Add argument to pfkey_msg_parse() for direction. ++ * Fixed IPIP dst address bug and purged redundant, leaky code. ++ * ++ * Revision 1.21 1999/11/24 05:24:20 rgb ++ * hanged 'void*extensions' to 'struct sadb_ext*extensions'. ++ * Fixed indention. ++ * Ditched redundant replay check. ++ * Fixed debug message text from 'parse' to 'process'. ++ * Added more debug output. ++ * Forgot to zero extensions array causing bug, fixed. ++ * ++ * Revision 1.20 1999/11/23 23:08:13 rgb ++ * Move all common parsing code to lib/pfkey_v2_parse.c and rename ++ * remaining bits to *_process. (PJO) ++ * Add macros for dealing with alignment and rounding up more opaquely. ++ * Use provided macro ADDRTOA_BUF instead of hardcoded value. ++ * Sort out pfkey and freeswan headers, putting them in a library path. ++ * Corrected a couple of bugs in as-yet-inactive code. ++ * ++ * Revision 1.19 1999/11/20 22:01:10 rgb ++ * Add more descriptive error messages for non-zero reserved fields. ++ * Add more descriptive error message for spirange parsing. ++ * Start on supported extension parsing. ++ * Start on register and get message parsing. ++ * ++ * Revision 1.18 1999/11/18 04:09:20 rgb ++ * Replaced all kernel version macros to shorter, readable form. ++ * ++ * Revision 1.17 1999/11/17 15:53:41 rgb ++ * Changed all occurrences of #include "../../../lib/freeswan.h" ++ * to #include which works due to -Ilibfreeswan in the ++ * klips/net/ipsec/Makefile. ++ * ++ * Revision 1.16 1999/10/26 16:57:43 rgb ++ * Add shorter macros for compiler directives to visually clean-up. ++ * Give ipv6 code meaningful compiler directive. ++ * Add comments to other #if 0 debug code. ++ * Remove unused *_bh_atomic() calls. ++ * Fix mis-placed spinlock. ++ * ++ * Revision 1.15 1999/10/16 18:27:10 rgb ++ * Clean-up unused cruft. ++ * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations. ++ * ++ * Revision 1.14 1999/10/08 18:37:34 rgb ++ * Fix end-of-line spacing to sate whining PHMs. ++ * ++ * Revision 1.13 1999/10/03 18:49:12 rgb ++ * Spinlock fixes for 2.0.xx and 2.3.xx. ++ * ++ * Revision 1.12 1999/10/01 15:44:54 rgb ++ * Move spinlock header include to 2.1> scope. ++ * ++ * Revision 1.11 1999/10/01 00:05:45 rgb ++ * Added tdb structure locking. ++ * Use 'jiffies' instead of do_get_timeofday(). ++ * Fix lifetime assignments. ++ * ++ * Revision 1.10 1999/09/21 15:24:45 rgb ++ * Rework spirange code to save entropy and prevent endless loops. ++ * ++ * Revision 1.9 1999/09/16 12:10:21 rgb ++ * Minor fixes to random spi selection for correctness and entropy conservation. ++ * ++ * Revision 1.8 1999/05/25 22:54:46 rgb ++ * Fix comparison that should be an assignment in an if. ++ * ++ * Revision 1.7 1999/05/09 03:25:37 rgb ++ * Fix bug introduced by 2.2 quick-and-dirty patch. ++ * ++ * Revision 1.6 1999/05/08 21:32:30 rgb ++ * Fix error return reporting. ++ * ++ * Revision 1.5 1999/05/05 22:02:33 rgb ++ * Add a quick and dirty port to 2.2 kernels by Marc Boucher . ++ * ++ * Revision 1.4 1999/04/29 15:22:40 rgb ++ * Standardise an error return method. ++ * Add debugging instrumentation. ++ * Add check for existence of macros min/max. ++ * Add extensions permitted/required in/out filters. ++ * Add satype-to-protocol table. ++ * Add a second tdb pointer to each parser to accomodate GRPSA. ++ * Move AH & no_algo_set to GETSPI, UPDATE and ADD. ++ * Add OOO window check. ++ * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP. ++ * Add timestamp to lifetime parse. ++ * Fix address structure length checking bug. ++ * Fix address structure allocation bug (forgot to kmalloc!). ++ * Add checks for extension lengths. ++ * Add checks for extension reserved illegal values. ++ * Add check for spirange legal values. ++ * Add an extension type for parsing a second satype, SA and ++ * DST_ADDRESS. ++ * Make changes to tdb_init() template to get pfkey_tdb_init(), ++ * eliminating any mention of xformsw. ++ * Implement getspi, update and grpsa (not tested). ++ * Add stubs for as yet unimplemented message types. ++ * Add table of message parsers to substitute for msg_parse switch. ++ * ++ * Revision 1.3 1999/04/15 17:58:07 rgb ++ * Add RCSID labels. ++ * ++ * Revision 1.2 1999/04/15 15:37:26 rgb ++ * Forward check changes from POST1_00 branch. ++ * ++ * Revision 1.1.2.1 1999/03/26 20:58:56 rgb ++ * Add pfkeyv2 support to KLIPS. ++ * ++ * Local variables: ++ * c-file-style: "linux" ++ * End: ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/radij.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,1225 @@ ++char radij_c_version[] = "RCSID $Id: radij.c,v 1.46 2004/04/06 02:49:26 mcr Exp $"; ++ ++/* ++ * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite ++ * ++ * Variable and procedure names have been modified so that they don't ++ * conflict with the original BSD code, as a small number of modifications ++ * have been introduced and we may want to reuse this code in BSD. ++ * ++ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek ++ * chi or a German ch sound (as `doch', not as in `milch'), or even a ++ * spanish j as in Juan. It is not as far back in the throat like ++ * the corresponding Hebrew sound, nor is it a soft breath like the English h. ++ * It has nothing to do with the Dutch ij sound. ++ * ++ * Here is the appropriate copyright notice: ++ */ ++ ++/* ++ * Copyright (c) 1988, 1989, 1993 ++ * The Regents of the University of California. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * This product includes software developed by the University of ++ * California, Berkeley and its contributors. ++ * 4. Neither the name of the University nor the names of its contributors ++ * may be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * @(#)radix.c 8.2 (Berkeley) 1/4/94 ++ */ ++ ++/* ++ * Routines to build and maintain radix trees for routing lookups. ++ */ ++ ++#include ++#include ++#include /* printk() */ ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef MALLOC_SLAB ++# include /* kmalloc() */ ++#else /* MALLOC_SLAB */ ++# include /* kmalloc() */ ++#endif /* MALLOC_SLAB */ ++#include /* error codes */ ++#include /* size_t */ ++#include /* mark_bh */ ++ ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include ++#ifdef NET_21 ++# include ++# include ++#endif /* NET_21 */ ++#include ++#include ++ ++#include ++ ++#include "openswan/radij.h" ++#include "openswan/ipsec_encap.h" ++#include "openswan/ipsec_radij.h" ++ ++int maj_keylen; ++struct radij_mask *rj_mkfreelist; ++struct radij_node_head *mask_rjhead; ++static int gotOddMasks; ++static char *maskedKey; ++static char *rj_zeroes, *rj_ones; ++ ++#define rj_masktop (mask_rjhead->rnh_treetop) ++#ifdef Bcmp ++# undef Bcmp ++#endif /* Bcmp */ ++#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l)) ++/* ++ * The data structure for the keys is a radix tree with one way ++ * branching removed. The index rj_b at an internal node n represents a bit ++ * position to be tested. The tree is arranged so that all descendants ++ * of a node n have keys whose bits all agree up to position rj_b - 1. ++ * (We say the index of n is rj_b.) ++ * ++ * There is at least one descendant which has a one bit at position rj_b, ++ * and at least one with a zero there. ++ * ++ * A route is determined by a pair of key and mask. We require that the ++ * bit-wise logical and of the key and mask to be the key. ++ * We define the index of a route to associated with the mask to be ++ * the first bit number in the mask where 0 occurs (with bit number 0 ++ * representing the highest order bit). ++ * ++ * We say a mask is normal if every bit is 0, past the index of the mask. ++ * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b, ++ * and m is a normal mask, then the route applies to every descendant of n. ++ * If the index(m) < rj_b, this implies the trailing last few bits of k ++ * before bit b are all 0, (and hence consequently true of every descendant ++ * of n), so the route applies to all descendants of the node as well. ++ * ++ * The present version of the code makes no use of normal routes, ++ * but similar logic shows that a non-normal mask m such that ++ * index(m) <= index(n) could potentially apply to many children of n. ++ * Thus, for each non-host route, we attach its mask to a list at an internal ++ * node as high in the tree as we can go. ++ */ ++ ++struct radij_node * ++rj_search(v_arg, head) ++ void *v_arg; ++ struct radij_node *head; ++{ ++ register struct radij_node *x; ++ register caddr_t v; ++ ++ for (x = head, v = v_arg; x->rj_b >= 0;) { ++ if (x->rj_bmask & v[x->rj_off]) ++ x = x->rj_r; ++ else ++ x = x->rj_l; ++ } ++ return (x); ++}; ++ ++struct radij_node * ++rj_search_m(v_arg, head, m_arg) ++ struct radij_node *head; ++ void *v_arg, *m_arg; ++{ ++ register struct radij_node *x; ++ register caddr_t v = v_arg, m = m_arg; ++ ++ for (x = head; x->rj_b >= 0;) { ++ if ((x->rj_bmask & m[x->rj_off]) && ++ (x->rj_bmask & v[x->rj_off])) ++ x = x->rj_r; ++ else ++ x = x->rj_l; ++ } ++ return x; ++}; ++ ++int ++rj_refines(m_arg, n_arg) ++ void *m_arg, *n_arg; ++{ ++ register caddr_t m = m_arg, n = n_arg; ++ register caddr_t lim, lim2 = lim = n + *(u_char *)n; ++ int longer = (*(u_char *)n++) - (int)(*(u_char *)m++); ++ int masks_are_equal = 1; ++ ++ if (longer > 0) ++ lim -= longer; ++ while (n < lim) { ++ if (*n & ~(*m)) ++ return 0; ++ if (*n++ != *m++) ++ masks_are_equal = 0; ++ ++ } ++ while (n < lim2) ++ if (*n++) ++ return 0; ++ if (masks_are_equal && (longer < 0)) ++ for (lim2 = m - longer; m < lim2; ) ++ if (*m++) ++ return 1; ++ return (!masks_are_equal); ++} ++ ++ ++struct radij_node * ++rj_match(v_arg, head) ++ void *v_arg; ++ struct radij_node_head *head; ++{ ++ caddr_t v = v_arg; ++ register struct radij_node *t = head->rnh_treetop, *x; ++ register caddr_t cp = v, cp2, cp3; ++ caddr_t cplim, mstart; ++ struct radij_node *saved_t, *top = t; ++ int off = t->rj_off, vlen = *(u_char *)cp, matched_off; ++ ++ /* ++ * Open code rj_search(v, top) to avoid overhead of extra ++ * subroutine call. ++ */ ++ for (; t->rj_b >= 0; ) { ++ if (t->rj_bmask & cp[t->rj_off]) ++ t = t->rj_r; ++ else ++ t = t->rj_l; ++ } ++ /* ++ * See if we match exactly as a host destination ++ */ ++ KLIPS_PRINT(debug_radij, ++ "klips_debug:rj_match: " ++ "* See if we match exactly as a host destination\n"); ++ ++ cp += off; cp2 = t->rj_key + off; cplim = v + vlen; ++ for (; cp < cplim; cp++, cp2++) ++ if (*cp != *cp2) ++ goto on1; ++ /* ++ * This extra grot is in case we are explicitly asked ++ * to look up the default. Ugh! ++ */ ++ if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey) ++ t = t->rj_dupedkey; ++ return t; ++on1: ++ matched_off = cp - v; ++ saved_t = t; ++ KLIPS_PRINT(debug_radij, ++ "klips_debug:rj_match: " ++ "** try to match a leaf, t=0p%p\n", t); ++ do { ++ if (t->rj_mask) { ++ /* ++ * Even if we don't match exactly as a hosts; ++ * we may match if the leaf we wound up at is ++ * a route to a net. ++ */ ++ cp3 = matched_off + t->rj_mask; ++ cp2 = matched_off + t->rj_key; ++ for (; cp < cplim; cp++) ++ if ((*cp2++ ^ *cp) & *cp3++) ++ break; ++ if (cp == cplim) ++ return t; ++ cp = matched_off + v; ++ } ++ } while ((t = t->rj_dupedkey)); ++ t = saved_t; ++ /* start searching up the tree */ ++ KLIPS_PRINT(debug_radij, ++ "klips_debug:rj_match: " ++ "*** start searching up the tree, t=0p%p\n", ++ t); ++ do { ++ register struct radij_mask *m; ++ ++ t = t->rj_p; ++ KLIPS_PRINT(debug_radij, ++ "klips_debug:rj_match: " ++ "**** t=0p%p\n", ++ t); ++ if ((m = t->rj_mklist)) { ++ /* ++ * After doing measurements here, it may ++ * turn out to be faster to open code ++ * rj_search_m here instead of always ++ * copying and masking. ++ */ ++ /* off = min(t->rj_off, matched_off); */ ++ off = t->rj_off; ++ if (matched_off < off) ++ off = matched_off; ++ mstart = maskedKey + off; ++ do { ++ cp2 = mstart; ++ cp3 = m->rm_mask + off; ++ KLIPS_PRINT(debug_radij, ++ "klips_debug:rj_match: " ++ "***** cp2=0p%p cp3=0p%p\n", ++ cp2, cp3); ++ for (cp = v + off; cp < cplim;) ++ *cp2++ = *cp++ & *cp3++; ++ x = rj_search(maskedKey, t); ++ while (x && x->rj_mask != m->rm_mask) ++ x = x->rj_dupedkey; ++ if (x && ++ (Bcmp(mstart, x->rj_key + off, ++ vlen - off) == 0)) ++ return x; ++ } while ((m = m->rm_mklist)); ++ } ++ } while (t != top); ++ KLIPS_PRINT(debug_radij, ++ "klips_debug:rj_match: " ++ "***** not found.\n"); ++ return 0; ++}; ++ ++#ifdef RJ_DEBUG ++int rj_nodenum; ++struct radij_node *rj_clist; ++int rj_saveinfo; ++DEBUG_NO_STATIC void traverse(struct radij_node *); ++#ifdef RJ_DEBUG2 ++int rj_debug = 1; ++#else ++int rj_debug = 0; ++#endif /* RJ_DEBUG2 */ ++#endif /* RJ_DEBUG */ ++ ++struct radij_node * ++rj_newpair(v, b, nodes) ++ void *v; ++ int b; ++ struct radij_node nodes[2]; ++{ ++ register struct radij_node *tt = nodes, *t = tt + 1; ++ t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7); ++ t->rj_l = tt; t->rj_off = b >> 3; ++ tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t; ++ tt->rj_flags = t->rj_flags = RJF_ACTIVE; ++#ifdef RJ_DEBUG ++ tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++; ++ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt; ++#endif /* RJ_DEBUG */ ++ return t; ++} ++ ++struct radij_node * ++rj_insert(v_arg, head, dupentry, nodes) ++ void *v_arg; ++ struct radij_node_head *head; ++ int *dupentry; ++ struct radij_node nodes[2]; ++{ ++ caddr_t v = v_arg; ++ struct radij_node *top = head->rnh_treetop; ++ int head_off = top->rj_off, vlen = (int)*((u_char *)v); ++ register struct radij_node *t = rj_search(v_arg, top); ++ register caddr_t cp = v + head_off; ++ register int b; ++ struct radij_node *tt; ++ /* ++ *find first bit at which v and t->rj_key differ ++ */ ++ { ++ register caddr_t cp2 = t->rj_key + head_off; ++ register int cmp_res; ++ caddr_t cplim = v + vlen; ++ ++ while (cp < cplim) ++ if (*cp2++ != *cp++) ++ goto on1; ++ *dupentry = 1; ++ return t; ++on1: ++ *dupentry = 0; ++ cmp_res = (cp[-1] ^ cp2[-1]) & 0xff; ++ for (b = (cp - v) << 3; cmp_res; b--) ++ cmp_res >>= 1; ++ } ++ { ++ register struct radij_node *p, *x = top; ++ cp = v; ++ do { ++ p = x; ++ if (cp[x->rj_off] & x->rj_bmask) ++ x = x->rj_r; ++ else x = x->rj_l; ++ } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */ ++#ifdef RJ_DEBUG ++ if (rj_debug) ++ printk("klips_debug:rj_insert: Going In:\n"), traverse(p); ++#endif /* RJ_DEBUG */ ++ t = rj_newpair(v_arg, b, nodes); tt = t->rj_l; ++ if ((cp[p->rj_off] & p->rj_bmask) == 0) ++ p->rj_l = t; ++ else ++ p->rj_r = t; ++ x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */ ++ if ((cp[t->rj_off] & t->rj_bmask) == 0) { ++ t->rj_r = x; ++ } else { ++ t->rj_r = tt; t->rj_l = x; ++ } ++#ifdef RJ_DEBUG ++ if (rj_debug) ++ printk("klips_debug:rj_insert: Coming out:\n"), traverse(p); ++#endif /* RJ_DEBUG */ ++ } ++ return (tt); ++} ++ ++struct radij_node * ++rj_addmask(n_arg, search, skip) ++ int search, skip; ++ void *n_arg; ++{ ++ caddr_t netmask = (caddr_t)n_arg; ++ register struct radij_node *x; ++ register caddr_t cp, cplim; ++ register int b, mlen, j; ++ int maskduplicated; ++ ++ mlen = *(u_char *)netmask; ++ if (search) { ++ x = rj_search(netmask, rj_masktop); ++ mlen = *(u_char *)netmask; ++ if (Bcmp(netmask, x->rj_key, mlen) == 0) ++ return (x); ++ } ++ R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x)); ++ if (x == 0) ++ return (0); ++ Bzero(x, maj_keylen + 2 * sizeof (*x)); ++ cp = (caddr_t)(x + 2); ++ Bcopy(netmask, cp, mlen); ++ netmask = cp; ++ x = rj_insert(netmask, mask_rjhead, &maskduplicated, x); ++ /* ++ * Calculate index of mask. ++ */ ++ cplim = netmask + mlen; ++ for (cp = netmask + skip; cp < cplim; cp++) ++ if (*(u_char *)cp != 0xff) ++ break; ++ b = (cp - netmask) << 3; ++ if (cp != cplim) { ++ if (*cp != 0) { ++ gotOddMasks = 1; ++ for (j = 0x80; j; b++, j >>= 1) ++ if ((j & *cp) == 0) ++ break; ++ } ++ } ++ x->rj_b = -1 - b; ++ return (x); ++} ++ ++#if 0 ++struct radij_node * ++#endif ++int ++rj_addroute(v_arg, n_arg, head, treenodes) ++ void *v_arg, *n_arg; ++ struct radij_node_head *head; ++ struct radij_node treenodes[2]; ++{ ++ caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg; ++ register struct radij_node *t, *x=NULL, *tt; ++ struct radij_node *saved_tt, *top = head->rnh_treetop; ++ short b = 0, b_leaf; ++ int mlen, keyduplicated; ++ caddr_t cplim; ++ struct radij_mask *m, **mp; ++ ++ /* ++ * In dealing with non-contiguous masks, there may be ++ * many different routes which have the same mask. ++ * We will find it useful to have a unique pointer to ++ * the mask to speed avoiding duplicate references at ++ * nodes and possibly save time in calculating indices. ++ */ ++ if (netmask) { ++ x = rj_search(netmask, rj_masktop); ++ mlen = *(u_char *)netmask; ++ if (Bcmp(netmask, x->rj_key, mlen) != 0) { ++ x = rj_addmask(netmask, 0, top->rj_off); ++ if (x == 0) ++ return -ENOMEM; /* (0) rgb */ ++ } ++ netmask = x->rj_key; ++ b = -1 - x->rj_b; ++ } ++ /* ++ * Deal with duplicated keys: attach node to previous instance ++ */ ++ saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes); ++#ifdef RJ_DEBUG ++ printk("addkey: duplicated: %d\n", keyduplicated); ++#endif ++ if (keyduplicated) { ++ do { ++ if (tt->rj_mask == netmask) ++ return -EEXIST; /* -ENXIO; (0) rgb */ ++ t = tt; ++ if (netmask == 0 || ++ (tt->rj_mask && rj_refines(netmask, tt->rj_mask))) ++ break; ++ } while ((tt = tt->rj_dupedkey)); ++ /* ++ * If the mask is not duplicated, we wouldn't ++ * find it among possible duplicate key entries ++ * anyway, so the above test doesn't hurt. ++ * ++ * We sort the masks for a duplicated key the same way as ++ * in a masklist -- most specific to least specific. ++ * This may require the unfortunate nuisance of relocating ++ * the head of the list. ++ */ ++ if (tt && t == saved_tt) { ++ struct radij_node *xx = x; ++ /* link in at head of list */ ++ (tt = treenodes)->rj_dupedkey = t; ++ tt->rj_flags = t->rj_flags; ++ tt->rj_p = x = t->rj_p; ++ if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt; ++ saved_tt = tt; x = xx; ++ } else { ++ (tt = treenodes)->rj_dupedkey = t->rj_dupedkey; ++ t->rj_dupedkey = tt; ++ } ++#ifdef RJ_DEBUG ++ t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++; ++ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt; ++#endif /* RJ_DEBUG */ ++ t = saved_tt; ++ tt->rj_key = (caddr_t) v; ++ tt->rj_b = -1; ++ tt->rj_flags = t->rj_flags & ~RJF_ROOT; ++ } ++ /* ++ * Put mask in tree. ++ */ ++ if (netmask) { ++ tt->rj_mask = netmask; ++ tt->rj_b = x->rj_b; ++ } ++ t = saved_tt->rj_p; ++ b_leaf = -1 - t->rj_b; ++ if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r; ++ /* Promote general routes from below */ ++ if (x->rj_b < 0) { ++ if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) { ++ MKGet(m); ++ if (m) { ++ Bzero(m, sizeof *m); ++ m->rm_b = x->rj_b; ++ m->rm_mask = x->rj_mask; ++ x->rj_mklist = t->rj_mklist = m; ++ } ++ } ++ } else if (x->rj_mklist) { ++ /* ++ * Skip over masks whose index is > that of new node ++ */ ++ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) ++ if (m->rm_b >= b_leaf) ++ break; ++ t->rj_mklist = m; *mp = 0; ++ } ++ /* Add new route to highest possible ancestor's list */ ++ if ((netmask == 0) || (b > t->rj_b )) { ++#ifdef RJ_DEBUG ++ printk("klips:radij.c: netmask = %p or b(%d)>t->rjb(%d)\n", netmask, b, t->rj_b); ++#endif ++ return 0; /* tt rgb */ /* can't lift at all */ ++ } ++ b_leaf = tt->rj_b; ++ do { ++ x = t; ++ t = t->rj_p; ++ } while (b <= t->rj_b && x != top); ++ /* ++ * Search through routes associated with node to ++ * insert new route according to index. ++ * For nodes of equal index, place more specific ++ * masks first. ++ */ ++ cplim = netmask + mlen; ++ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) { ++ if (m->rm_b < b_leaf) ++ continue; ++ if (m->rm_b > b_leaf) ++ break; ++ if (m->rm_mask == netmask) { ++ m->rm_refs++; ++ tt->rj_mklist = m; ++#ifdef RJ_DEBUG ++ printk("klips:radij.c: m->rm_mask %p == netmask\n", netmask); ++#endif ++ return 0; /* tt rgb */ ++ } ++ if (rj_refines(netmask, m->rm_mask)) ++ break; ++ } ++ MKGet(m); ++ if (m == 0) { ++ printk("klips_debug:rj_addroute: " ++ "Mask for route not entered\n"); ++ return 0; /* (tt) rgb */ ++ } ++ Bzero(m, sizeof *m); ++ m->rm_b = b_leaf; ++ m->rm_mask = netmask; ++ m->rm_mklist = *mp; ++ *mp = m; ++ tt->rj_mklist = m; ++#ifdef RJ_DEBUG ++ printk("klips:radij.c: addroute done\n"); ++#endif ++ return 0; /* tt rgb */ ++} ++ ++int ++rj_delete(v_arg, netmask_arg, head, node) ++ void *v_arg, *netmask_arg; ++ struct radij_node_head *head; ++ struct radij_node **node; ++{ ++ register struct radij_node *t, *p, *x, *tt; ++ struct radij_mask *m, *saved_m, **mp; ++ struct radij_node *dupedkey, *saved_tt, *top; ++ caddr_t v, netmask; ++ int b, head_off, vlen; ++ ++ v = v_arg; ++ netmask = netmask_arg; ++ x = head->rnh_treetop; ++ tt = rj_search(v, x); ++ head_off = x->rj_off; ++ vlen = *(u_char *)v; ++ saved_tt = tt; ++ top = x; ++ if (tt == 0 || ++ Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off)) ++ return -EFAULT; /* (0) rgb */ ++ /* ++ * Delete our route from mask lists. ++ */ ++ if ((dupedkey = tt->rj_dupedkey)) { ++ if (netmask) ++ netmask = rj_search(netmask, rj_masktop)->rj_key; ++ while (tt->rj_mask != netmask) ++ if ((tt = tt->rj_dupedkey) == 0) ++ return -ENOENT; /* -ENXIO; (0) rgb */ ++ } ++ if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0) ++ goto on1; ++ if (m->rm_mask != tt->rj_mask) { ++ printk("klips_debug:rj_delete: " ++ "inconsistent annotation\n"); ++ goto on1; ++ } ++ if (--m->rm_refs >= 0) ++ goto on1; ++ b = -1 - tt->rj_b; ++ t = saved_tt->rj_p; ++ if (b > t->rj_b) ++ goto on1; /* Wasn't lifted at all */ ++ do { ++ x = t; ++ t = t->rj_p; ++ } while (b <= t->rj_b && x != top); ++ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) ++ if (m == saved_m) { ++ *mp = m->rm_mklist; ++ MKFree(m); ++ break; ++ } ++ if (m == 0) ++ printk("klips_debug:rj_delete: " ++ "couldn't find our annotation\n"); ++on1: ++ /* ++ * Eliminate us from tree ++ */ ++ if (tt->rj_flags & RJF_ROOT) ++ return -EFAULT; /* (0) rgb */ ++#ifdef RJ_DEBUG ++ /* Get us out of the creation list */ ++ for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {} ++ if (t) t->rj_ybro = tt->rj_ybro; ++#endif /* RJ_DEBUG */ ++ t = tt->rj_p; ++ if (dupedkey) { ++ if (tt == saved_tt) { ++ x = dupedkey; x->rj_p = t; ++ if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x; ++ } else { ++ for (x = p = saved_tt; p && p->rj_dupedkey != tt;) ++ p = p->rj_dupedkey; ++ if (p) p->rj_dupedkey = tt->rj_dupedkey; ++ else printk("klips_debug:rj_delete: " ++ "couldn't find node that we started with\n"); ++ } ++ t = tt + 1; ++ if (t->rj_flags & RJF_ACTIVE) { ++#ifndef RJ_DEBUG ++ *++x = *t; p = t->rj_p; ++#else ++ b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p; ++#endif /* RJ_DEBUG */ ++ if (p->rj_l == t) p->rj_l = x; else p->rj_r = x; ++ x->rj_l->rj_p = x; x->rj_r->rj_p = x; ++ } ++ goto out; ++ } ++ if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l; ++ p = t->rj_p; ++ if (p->rj_r == t) p->rj_r = x; else p->rj_l = x; ++ x->rj_p = p; ++ /* ++ * Demote routes attached to us. ++ */ ++ if (t->rj_mklist) { ++ if (x->rj_b >= 0) { ++ for (mp = &x->rj_mklist; (m = *mp);) ++ mp = &m->rm_mklist; ++ *mp = t->rj_mklist; ++ } else { ++ for (m = t->rj_mklist; m;) { ++ struct radij_mask *mm = m->rm_mklist; ++ if (m == x->rj_mklist && (--(m->rm_refs) < 0)) { ++ x->rj_mklist = 0; ++ MKFree(m); ++ } else ++ printk("klips_debug:rj_delete: " ++ "Orphaned Mask 0p%p at 0p%p\n", m, x); ++ m = mm; ++ } ++ } ++ } ++ /* ++ * We may be holding an active internal node in the tree. ++ */ ++ x = tt + 1; ++ if (t != x) { ++#ifndef RJ_DEBUG ++ *t = *x; ++#else ++ b = t->rj_info; *t = *x; t->rj_info = b; ++#endif /* RJ_DEBUG */ ++ t->rj_l->rj_p = t; t->rj_r->rj_p = t; ++ p = x->rj_p; ++ if (p->rj_l == x) p->rj_l = t; else p->rj_r = t; ++ } ++out: ++ tt->rj_flags &= ~RJF_ACTIVE; ++ tt[1].rj_flags &= ~RJF_ACTIVE; ++ *node = tt; ++ return 0; /* (tt) rgb */ ++} ++ ++int ++rj_walktree(h, f, w) ++ struct radij_node_head *h; ++ register int (*f)(struct radij_node *,void *); ++ void *w; ++{ ++ int error; ++ struct radij_node *base, *next; ++ register struct radij_node *rn; ++ ++ if(!h || !f /* || !w */) { ++ return -ENODATA; ++ } ++ ++ rn = h->rnh_treetop; ++ /* ++ * This gets complicated because we may delete the node ++ * while applying the function f to it, so we need to calculate ++ * the successor node in advance. ++ */ ++ /* First time through node, go left */ ++ while (rn->rj_b >= 0) ++ rn = rn->rj_l; ++ for (;;) { ++#ifdef CONFIG_IPSEC_DEBUG ++ if(debug_radij) { ++ printk("klips_debug:rj_walktree: " ++ "for: rn=0p%p rj_b=%d rj_flags=%x", ++ rn, ++ rn->rj_b, ++ rn->rj_flags); ++ rn->rj_b >= 0 ? ++ printk(" node off=%x\n", ++ rn->rj_off) : ++ printk(" leaf key = %08x->%08x\n", ++ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), ++ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)) ++ ; ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ base = rn; ++ /* If at right child go back up, otherwise, go right */ ++ while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0) ++ rn = rn->rj_p; ++ /* Find the next *leaf* since next node might vanish, too */ ++ for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;) ++ rn = rn->rj_l; ++ next = rn; ++#ifdef CONFIG_IPSEC_DEBUG ++ if(debug_radij) { ++ printk("klips_debug:rj_walktree: " ++ "processing leaves, rn=0p%p rj_b=%d rj_flags=%x", ++ rn, ++ rn->rj_b, ++ rn->rj_flags); ++ rn->rj_b >= 0 ? ++ printk(" node off=%x\n", ++ rn->rj_off) : ++ printk(" leaf key = %08x->%08x\n", ++ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), ++ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)) ++ ; ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ /* Process leaves */ ++ while ((rn = base)) { ++ base = rn->rj_dupedkey; ++#ifdef CONFIG_IPSEC_DEBUG ++ if(debug_radij) { ++ printk("klips_debug:rj_walktree: " ++ "while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x", ++ base, ++ rn, ++ rn->rj_b, ++ rn->rj_flags); ++ rn->rj_b >= 0 ? ++ printk(" node off=%x\n", ++ rn->rj_off) : ++ printk(" leaf key = %08x->%08x\n", ++ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), ++ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)) ++ ; ++ } ++#endif /* CONFIG_IPSEC_DEBUG */ ++ if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w))) ++ return (-error); ++ } ++ rn = next; ++ if (rn->rj_flags & RJF_ROOT) ++ return (0); ++ } ++ /* NOTREACHED */ ++} ++ ++int ++rj_inithead(head, off) ++ void **head; ++ int off; ++{ ++ register struct radij_node_head *rnh; ++ register struct radij_node *t, *tt, *ttt; ++ if (*head) ++ return (1); ++ R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh)); ++ if (rnh == NULL) ++ return (0); ++ Bzero(rnh, sizeof (*rnh)); ++ *head = rnh; ++ t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes); ++ ttt = rnh->rnh_nodes + 2; ++ t->rj_r = ttt; ++ t->rj_p = t; ++ tt = t->rj_l; ++ tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE; ++ tt->rj_b = -1 - off; ++ *ttt = *tt; ++ ttt->rj_key = rj_ones; ++ rnh->rnh_addaddr = rj_addroute; ++ rnh->rnh_deladdr = rj_delete; ++ rnh->rnh_matchaddr = rj_match; ++ rnh->rnh_walktree = rj_walktree; ++ rnh->rnh_treetop = t; ++ return (1); ++} ++ ++void ++rj_init() ++{ ++ char *cp, *cplim; ++ ++ if (maj_keylen == 0) { ++ printk("klips_debug:rj_init: " ++ "radij functions require maj_keylen be set\n"); ++ return; ++ } ++ R_Malloc(rj_zeroes, char *, 3 * maj_keylen); ++ if (rj_zeroes == NULL) ++ panic("rj_init"); ++ Bzero(rj_zeroes, 3 * maj_keylen); ++ rj_ones = cp = rj_zeroes + maj_keylen; ++ maskedKey = cplim = rj_ones + maj_keylen; ++ while (cp < cplim) ++ *cp++ = -1; ++ if (rj_inithead((void **)&mask_rjhead, 0) == 0) ++ panic("rj_init 2"); ++} ++ ++void ++rj_preorder(struct radij_node *rn, int l) ++{ ++ int i; ++ ++ if (rn == NULL){ ++ printk("klips_debug:rj_preorder: " ++ "NULL pointer\n"); ++ return; ++ } ++ ++ if (rn->rj_b >= 0){ ++ rj_preorder(rn->rj_l, l+1); ++ rj_preorder(rn->rj_r, l+1); ++ printk("klips_debug:"); ++ for (i=0; irj_off); ++ } else { ++ printk("klips_debug:"); ++ for (i=0; irj_flags); ++ if (rn->rj_flags & RJF_ACTIVE) { ++ printk(" @key=0p%p", ++ rn->rj_key); ++ printk(" key = %08x->%08x", ++ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), ++ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)); ++ printk(" @mask=0p%p", ++ rn->rj_mask); ++ if (rn->rj_mask) ++ printk(" mask = %08x->%08x", ++ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr), ++ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr)); ++ if (rn->rj_dupedkey) ++ printk(" dupedkey = 0p%p", ++ rn->rj_dupedkey); ++ } ++ printk("\n"); ++ } ++} ++ ++#ifdef RJ_DEBUG ++DEBUG_NO_STATIC void traverse(struct radij_node *p) ++{ ++ rj_preorder(p, 0); ++} ++#endif /* RJ_DEBUG */ ++ ++void ++rj_dumptrees(void) ++{ ++ rj_preorder(rnh->rnh_treetop, 0); ++} ++ ++void ++rj_free_mkfreelist(void) ++{ ++ struct radij_mask *mknp, *mknp2; ++ ++ mknp = rj_mkfreelist; ++ while(mknp) ++ { ++ mknp2 = mknp; ++ mknp = mknp->rm_mklist; ++ kfree(mknp2); ++ } ++} ++ ++int ++radijcleartree(void) ++{ ++ return rj_walktree(rnh, ipsec_rj_walker_delete, NULL); ++} ++ ++int ++radijcleanup(void) ++{ ++ int error = 0; ++ ++ error = radijcleartree(); ++ ++ rj_free_mkfreelist(); ++ ++/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */ ++ if(mask_rjhead) { ++ kfree(mask_rjhead); ++ } ++ ++ if(rj_zeroes) { ++ kfree(rj_zeroes); ++ } ++ ++ if(rnh) { ++ kfree(rnh); ++ } ++ ++ return error; ++} ++ ++/* ++ * $Log: radij.c,v $ ++ * Revision 1.46 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.45 2003/10/31 02:27:55 mcr ++ * pulled up port-selector patches and sa_id elimination. ++ * ++ * Revision 1.44.30.1 2003/10/29 01:30:41 mcr ++ * elimited "struct sa_id". ++ * ++ * Revision 1.44 2002/07/24 18:44:54 rgb ++ * Type fiddling to tame ia64 compiler. ++ * ++ * Revision 1.43 2002/05/23 07:14:11 rgb ++ * Cleaned up %p variants to 0p%p for test suite cleanup. ++ * ++ * Revision 1.42 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.41 2002/04/24 07:36:35 mcr ++ * Moved from ./klips/net/ipsec/radij.c,v ++ * ++ * Revision 1.40 2002/01/29 17:17:58 mcr ++ * moved include of ipsec_param.h to after include of linux/kernel.h ++ * otherwise, it seems that some option that is set in ipsec_param.h ++ * screws up something subtle in the include path to kernel.h, and ++ * it complains on the snprintf() prototype. ++ * ++ * Revision 1.39 2002/01/29 04:00:55 mcr ++ * more excise of kversions.h header. ++ * ++ * Revision 1.38 2002/01/29 02:13:19 mcr ++ * introduction of ipsec_kversion.h means that include of ++ * ipsec_param.h must preceed any decisions about what files to ++ * include to deal with differences in kernel source. ++ * ++ * Revision 1.37 2001/10/18 04:45:23 rgb ++ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, ++ * lib/freeswan.h version macros moved to lib/kversions.h. ++ * Other compiler directive cleanups. ++ * ++ * Revision 1.36 2001/08/22 13:43:51 henry ++ * eliminate the single use of min() to avoid problems with Linus changing it ++ * ++ * Revision 1.35 2001/06/15 04:57:29 rgb ++ * Clarified error return codes. ++ * Changed mask add already exists to EEXIST. ++ * Changed mask delete did not exist to ENOENT. ++ * ++ * Revision 1.34 2001/05/03 19:44:26 rgb ++ * Fix sign of error return codes for rj_addroute(). ++ * ++ * Revision 1.33 2001/02/27 22:24:56 rgb ++ * Re-formatting debug output (line-splitting, joining, 1arg/line). ++ * Check for satoa() return codes. ++ * ++ * Revision 1.32 2001/02/27 06:23:15 rgb ++ * Debug line splitting. ++ * ++ * Revision 1.31 2000/11/06 04:35:21 rgb ++ * Clear table *before* releasing other items in radijcleanup. ++ * ++ * Revision 1.30 2000/09/20 04:07:40 rgb ++ * Changed static functions to DEBUG_NO_STATIC to reveal function names in ++ * oopsen. ++ * ++ * Revision 1.29 2000/09/12 03:25:02 rgb ++ * Moved radij_c_version printing to ipsec_version_get_info(). ++ * ++ * Revision 1.28 2000/09/08 19:12:56 rgb ++ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. ++ * ++ * Revision 1.27 2000/07/28 14:58:32 rgb ++ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. ++ * ++ * Revision 1.26 2000/05/10 23:11:37 rgb ++ * Comment out most of the startup version information. ++ * ++ * Revision 1.25 2000/01/21 06:21:47 rgb ++ * Change return codes to negative on error. ++ * ++ * Revision 1.24 1999/11/18 04:09:20 rgb ++ * Replaced all kernel version macros to shorter, readable form. ++ * ++ * Revision 1.23 1999/11/17 15:53:41 rgb ++ * Changed all occurrences of #include "../../../lib/freeswan.h" ++ * to #include which works due to -Ilibfreeswan in the ++ * klips/net/ipsec/Makefile. ++ * ++ * Revision 1.22 1999/10/15 22:17:28 rgb ++ * Modify radijcleanup() to call radijcleartree(). ++ * ++ * Revision 1.21 1999/10/08 18:37:34 rgb ++ * Fix end-of-line spacing to sate whining PHMs. ++ * ++ * Revision 1.20 1999/10/01 15:44:54 rgb ++ * Move spinlock header include to 2.1> scope. ++ * ++ * Revision 1.19 1999/10/01 08:35:52 rgb ++ * Add spinlock include to shut up compiler for 2.0.38. ++ * ++ * Revision 1.18 1999/09/23 18:02:52 rgb ++ * De-alarm the search failure message so it doesn't sound so grave. ++ * ++ * Revision 1.17 1999/05/25 21:26:01 rgb ++ * Fix rj_walktree() sanity checking bug. ++ * ++ * Revision 1.16 1999/05/09 03:25:38 rgb ++ * Fix bug introduced by 2.2 quick-and-dirty patch. ++ * ++ * Revision 1.15 1999/05/05 22:02:33 rgb ++ * Add a quick and dirty port to 2.2 kernels by Marc Boucher . ++ * ++ * Revision 1.14 1999/04/29 15:24:15 rgb ++ * Add sanity checking for null pointer arguments. ++ * Standardise an error return method. ++ * ++ * Revision 1.13 1999/04/11 00:29:02 henry ++ * GPL boilerplate ++ * ++ * Revision 1.12 1999/04/06 04:54:28 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ * Revision 1.11 1999/02/17 16:52:53 rgb ++ * Convert DEBUG_IPSEC to KLIPS_PRINT ++ * Clean out unused cruft. ++ * ++ * Revision 1.10 1999/01/22 06:30:05 rgb ++ * Cruft clean-out. ++ * 64-bit clean-up. ++ * ++ * Revision 1.9 1998/12/01 13:22:04 rgb ++ * Added support for debug printing of version info. ++ * ++ * Revision 1.8 1998/11/30 13:22:55 rgb ++ * Rationalised all the klips kernel file headers. They are much shorter ++ * now and won't conflict under RH5.2. ++ * ++ * Revision 1.7 1998/10/25 02:43:26 rgb ++ * Change return type on rj_addroute and rj_delete and add and argument ++ * to the latter to be able to transmit more infomation about errors. ++ * ++ * Revision 1.6 1998/10/19 14:30:06 rgb ++ * Added inclusion of freeswan.h. ++ * ++ * Revision 1.5 1998/10/09 04:33:27 rgb ++ * Added 'klips_debug' prefix to all klips printk debug statements. ++ * Fixed output formatting slightly. ++ * ++ * Revision 1.4 1998/07/28 00:06:59 rgb ++ * Add debug detail to tree traversing. ++ * ++ * Revision 1.3 1998/07/14 18:07:58 rgb ++ * Add a routine to clear the eroute tree. ++ * ++ * Revision 1.2 1998/06/25 20:03:22 rgb ++ * Cleanup #endif comments. Debug output for rj_init. ++ * ++ * Revision 1.1 1998/06/18 21:30:22 henry ++ * move sources from klips/src to klips/net/ipsec to keep stupid kernel ++ * build scripts happier about symlinks ++ * ++ * Revision 1.8 1998/05/25 20:34:15 rgb ++ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions. ++ * ++ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and ++ * add ipsec_rj_walker_delete. ++ * ++ * Recover memory for eroute table on unload of module. ++ * ++ * Revision 1.7 1998/05/21 12:58:58 rgb ++ * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix. ++ * ++ * Revision 1.6 1998/04/23 20:57:29 rgb ++ * Cleaned up compiler warnings for unused debugging functions. ++ * ++ * Revision 1.5 1998/04/22 16:51:38 rgb ++ * Tidy up radij debug code from recent rash of modifications to debug code. ++ * ++ * Revision 1.4 1998/04/21 21:28:56 rgb ++ * Rearrange debug switches to change on the fly debug output from user ++ * space. Only kernel changes checked in at this time. radij.c was also ++ * changed to temporarily remove buggy debugging code in rj_delete causing ++ * an OOPS and hence, netlink device open errors. ++ * ++ * Revision 1.3 1998/04/14 17:30:37 rgb ++ * Fix up compiling errors for radij tree memory reclamation. ++ * ++ * Revision 1.2 1998/04/12 22:03:25 rgb ++ * Updated ESP-3DES-HMAC-MD5-96, ++ * ESP-DES-HMAC-MD5-96, ++ * AH-HMAC-MD5-96, ++ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository ++ * from old standards (RFC182[5-9] to new (as of March 1998) drafts. ++ * ++ * Fixed eroute references in /proc/net/ipsec*. ++ * ++ * Started to patch module unloading memory leaks in ipsec_netlink and ++ * radij tree unloading. ++ * ++ * Revision 1.1 1998/04/09 03:06:15 henry ++ * sources moved up from linux/net/ipsec ++ * ++ * Revision 1.1.1.1 1998/04/08 05:35:03 henry ++ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 ++ * ++ * Revision 0.4 1997/01/15 01:28:15 ji ++ * No changes. ++ * ++ * Revision 0.3 1996/11/20 14:39:04 ji ++ * Minor cleanups. ++ * Rationalized debugging code. ++ * ++ * Revision 0.2 1996/11/02 00:18:33 ji ++ * First limited release. ++ * ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/sysctl_net_ipsec.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,196 @@ ++/* ++ * sysctl interface to net IPSEC subsystem. ++ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * RCSID $Id: sysctl_net_ipsec.c,v 1.16 2004/04/06 02:49:26 mcr Exp $ ++ */ ++ ++/* -*- linux-c -*- ++ * ++ * Initiated April 3, 1998, Richard Guy Briggs ++ */ ++ ++#include ++#include ++ ++#include "openswan/ipsec_param.h" ++ ++#ifdef CONFIG_SYSCTL ++ ++#define NET_IPSEC 2112 /* Random number */ ++#ifdef CONFIG_IPSEC_DEBUG ++extern int debug_ah; ++extern int debug_esp; ++extern int debug_tunnel; ++extern int debug_eroute; ++extern int debug_spi; ++extern int debug_radij; ++extern int debug_netlink; ++extern int debug_xform; ++extern int debug_rcv; ++extern int debug_pfkey; ++extern int sysctl_ipsec_debug_verbose; ++#ifdef CONFIG_IPSEC_IPCOMP ++extern int sysctl_ipsec_debug_ipcomp; ++#endif /* CONFIG_IPSEC_IPCOMP */ ++#endif /* CONFIG_IPSEC_DEBUG */ ++ ++extern int sysctl_ipsec_icmp; ++extern int sysctl_ipsec_inbound_policy_check; ++extern int sysctl_ipsec_tos; ++int sysctl_ipsec_regress_pfkey_lossage; ++ ++enum { ++#ifdef CONFIG_IPSEC_DEBUG ++ NET_IPSEC_DEBUG_AH=1, ++ NET_IPSEC_DEBUG_ESP=2, ++ NET_IPSEC_DEBUG_TUNNEL=3, ++ NET_IPSEC_DEBUG_EROUTE=4, ++ NET_IPSEC_DEBUG_SPI=5, ++ NET_IPSEC_DEBUG_RADIJ=6, ++ NET_IPSEC_DEBUG_NETLINK=7, ++ NET_IPSEC_DEBUG_XFORM=8, ++ NET_IPSEC_DEBUG_RCV=9, ++ NET_IPSEC_DEBUG_PFKEY=10, ++ NET_IPSEC_DEBUG_VERBOSE=11, ++ NET_IPSEC_DEBUG_IPCOMP=12, ++#endif /* CONFIG_IPSEC_DEBUG */ ++ NET_IPSEC_ICMP=13, ++ NET_IPSEC_INBOUND_POLICY_CHECK=14, ++ NET_IPSEC_TOS=15, ++ NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16, ++}; ++ ++static ctl_table ipsec_table[] = { ++#ifdef CONFIG_IPSEC_DEBUG ++ { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++ { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++ { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++ { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++ { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++ { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++ { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++ { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++ { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++ { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++ { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++#ifdef CONFIG_IPSEC_IPCOMP ++ { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++#endif /* CONFIG_IPSEC_IPCOMP */ ++ ++#ifdef CONFIG_IPSEC_REGRESS ++ { NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage", ++ &sysctl_ipsec_regress_pfkey_lossage, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++#endif /* CONFIG_IPSEC_REGRESS */ ++ ++#endif /* CONFIG_IPSEC_DEBUG */ ++ { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++ { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++ { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos, ++ sizeof(int), 0644, NULL, &proc_dointvec}, ++ {0} ++}; ++ ++static ctl_table ipsec_net_table[] = { ++ { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table }, ++ { 0 } ++}; ++ ++static ctl_table ipsec_root_table[] = { ++ { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table }, ++ { 0 } ++}; ++ ++static struct ctl_table_header *ipsec_table_header; ++ ++int ipsec_sysctl_register(void) ++{ ++ ipsec_table_header = register_sysctl_table(ipsec_root_table, 0); ++ if (!ipsec_table_header) { ++ return -ENOMEM; ++ } ++ return 0; ++} ++ ++void ipsec_sysctl_unregister(void) ++{ ++ unregister_sysctl_table(ipsec_table_header); ++} ++ ++#endif /* CONFIG_SYSCTL */ ++ ++/* ++ * $Log: sysctl_net_ipsec.c,v $ ++ * Revision 1.16 2004/04/06 02:49:26 mcr ++ * pullup of algo code from alg-branch. ++ * ++ * Revision 1.15 2002/04/24 07:55:32 mcr ++ * #include patches and Makefiles for post-reorg compilation. ++ * ++ * Revision 1.14 2002/04/24 07:36:35 mcr ++ * Moved from ./klips/net/ipsec/sysctl_net_ipsec.c,v ++ * ++ * Revision 1.13 2002/01/12 02:58:32 mcr ++ * first regression test causes acquire messages to be lost ++ * 100% of the time. This is to help testing of pluto. ++ * ++ * Revision 1.12 2001/06/14 19:35:13 rgb ++ * Update copyright date. ++ * ++ * Revision 1.11 2001/02/26 19:58:13 rgb ++ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs. ++ * ++ * Revision 1.10 2000/09/16 01:50:15 rgb ++ * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the ++ * linker won't blame rj_delete() for missing symbols. ;-> Damn statics... ++ * ++ * Revision 1.9 2000/09/15 23:17:51 rgb ++ * Moved stuff around to compile with debug off. ++ * ++ * Revision 1.8 2000/09/15 11:37:02 rgb ++ * Merge in heavily modified Svenning Soerensen's ++ * IPCOMP zlib deflate code. ++ * ++ * Revision 1.7 2000/09/15 07:37:15 rgb ++ * Munged silly log comment that was causing a warning. ++ * ++ * Revision 1.6 2000/09/15 04:58:23 rgb ++ * Added tos runtime switch. ++ * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames. ++ * ++ * Revision 1.5 2000/09/12 03:25:28 rgb ++ * Filled in and implemented sysctl. ++ * ++ * Revision 1.4 1999/04/11 00:29:03 henry ++ * GPL boilerplate ++ * ++ * Revision 1.3 1999/04/06 04:54:29 rgb ++ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes ++ * patch shell fixes. ++ * ++ */ +--- /dev/null Tue Mar 11 13:02:56 2003 ++++ linux/net/ipsec/version.c Mon Feb 9 13:51:03 2004 +@@ -0,0 +1,44 @@ ++/* ++ * return IPsec version information ++ * Copyright (C) 2001 Henry Spencer. ++ * ++ * This library is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Library General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public ++ * License for more details. ++ * ++ * RCSID $Id: version.in.c,v 1.2 2004/04/14 05:09:46 ken Exp $ ++ */ ++ ++#ifdef __KERNEL__ ++#include ++#endif ++ ++#include "openswan.h" ++ ++#define V "cvs2002Mar12_01:19:03" /* substituted in by Makefile */ ++static const char openswan_number[] = V; ++static const char openswan_string[] = "Openswan " V; ++ ++/* ++ - ipsec_version_code - return IPsec version number/code, as string ++ */ ++const char * ++ipsec_version_code() ++{ ++ return openswan_number; ++} ++ ++/* ++ - ipsec_version_string - return full version string ++ */ ++const char * ++ipsec_version_string() ++{ ++ return openswan_string; ++} +RCSID $Id: af_inet.c.fs2_4.patch,v 1.6 2002/04/24 07:36:36 mcr Exp $ +--- linux-old/net/ipv4/af_inet.c.preipsec Wed Apr 26 15:13:17 2000 ++++ linux/net/ipv4/af_inet.c Fri Jun 30 15:01:27 2000 +@@ -1019,6 +1019,17 @@ + ip_mr_init(); + #endif + ++#if defined(CONFIG_IPSEC) ++ { ++ extern /* void */ int ipsec_init(void); ++ /* ++ * Initialise AF_INET ESP and AH protocol support including ++ * e-routing and SA tables ++ */ ++ ipsec_init(); ++ } ++#endif /* CONFIG_IPSEC */ ++ + /* + * Create all the /proc entries. + */ +--- /dev/null Fri May 10 13:59:54 2002 ++++ linux/net/ipsec/Makefile.ver Sun Jul 28 22:10:40 2002 +@@ -0,0 +1 @@ ++IPSECVERSION=cvs2002Mar12_01:19:03 +make[1]: Leaving directory `/data/mtx/oe/tmp/work/openswan-2.2.0-r0/openswan-2.2.0' diff --git a/packages/linux/linux-mtx-2-2.4.27/16-i2c.patch b/packages/linux/linux-mtx-2-2.4.27/16-i2c.patch new file mode 100644 index 0000000000..cec737bdfe --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/16-i2c.patch @@ -0,0 +1,7482 @@ +--- linux-old/Documentation/Configure.help Mon Dec 13 16:57:33 2004 ++++ linux/Documentation/Configure.help Mon Dec 13 19:26:23 2004 +@@ -19347,6 +19347,16 @@ + . + The module will be called i2c-velleman.o. + ++Basic I2C on Parallel Port adapter ++CONFIG_I2C_PPORT ++ This supports directly connecting I2C devices to the parallel port. ++ See for more information. ++ ++ This driver is also available as a module. If you want to compile ++ it as a module, say M here and read ++ . ++ The module will be called i2c-pport.o. ++ + I2C PCF 8584 interfaces + CONFIG_I2C_ALGOPCF + This allows you to use a range of I2C adapters called PCF adapters. +@@ -19368,6 +19378,15 @@ + . + The module will be called i2c-elektor.o. + ++PCF on the EPP Parallel Port ++CONFIG_I2C_PCFEPP ++ This supports the PCF8584 connected to the parallel port. ++ ++ This driver is also available as a module. If you want to compile ++ it as a module, say M here and read ++ . ++ The module will be called i2c-pcf-epp.o. ++ + ITE I2C Algorithm + CONFIG_ITE_I2C_ALGO + This supports the use the ITE8172 I2C interface found on some MIPS +@@ -19405,6 +19424,51 @@ + Supports the SGI interfaces like the ones found on SGI Indy VINO + or SGI O2 MACE. + ++Motorola 8xx I2C algorithm ++CONFIG_I2C_ALGO8XX ++ This is the algorithm that allows you to use Motorola 8xx I2C adapters. ++ ++ This driver is also available as a module. If you want to compile ++ it as a module, say M here and read ++ . ++ The module will be called i2c-algo-8xx.o. ++ ++Motorola 8xx I2C interface ++CONFIG_I2C_RPXLITE ++ This supports the Motorola 8xx I2C device. ++ ++ This driver is also available as a module. If you want to compile ++ it as a module, say M here and read ++ . ++ The module will be called i2c-rpx.o. ++ ++IBM 405 I2C algorithm ++CONFIG_I2C_IBM_OCP_ALGO ++ This is the algorithm that allows you to use IBM 405 I2C adapters. ++ ++ This driver is also available as a module. If you want to compile ++ it as a module, say M here and read ++ . ++ The module will be called i2c-algo-ibm_ocp.o. ++ ++IBM 405 I2C interface ++CONFIG_I2C_IBM_OCP_ADAP ++ This supports the IBM 405 I2C device. ++ ++ This driver is also available as a module. If you want to compile ++ it as a module, say M here and read ++ . ++ The module will be called i2c-adap-ibm_ocp.o. ++ ++StrongARM SA-1110 interface ++CONFIG_I2C_FRODO ++ This supports the StrongARM SA-1110 Development Board. ++ ++ This driver is also available as a module. If you want to compile ++ it as a module, say M here and read ++ . ++ The module will be called i2c-frodo.o. ++ + I2C device interface + CONFIG_I2C_CHARDEV + Say Y here to use i2c-* device files, usually found in the /dev +--- linux-old/Documentation/i2c/dev-interface Mon Dec 22 22:44:34 2003 ++++ linux/Documentation/i2c/dev-interface Mon Dec 13 19:26:23 2004 +@@ -89,6 +89,11 @@ + Selects ten bit addresses if select not equals 0, selects normal 7 bit + addresses if select equals 0. Default 0. + ++ioctl(file,I2C_PEC,long select) ++ Selects SMBus PEC (packet error checking) generation and verification ++ if select not equals 0, disables if select equals 0. Default 0. ++ Used only for SMBus transactions. ++ + ioctl(file,I2C_FUNCS,unsigned long *funcs) + Gets the adapter functionality and puts it in *funcs. + +--- linux-old/Documentation/i2c/i2c-pport Thu Jan 1 00:00:00 1970 ++++ linux/Documentation/i2c/i2c-pport Mon Dec 13 19:26:24 2004 +@@ -0,0 +1,67 @@ ++Parallel Port Adapters ++---------------------- ++If you are installing parallel port adapters it means you are probably messing ++around with wires and IC's and the like. If you have purchased a card that ++provides an external i2c/smbus this will require combined algorithm and ++adapter code in a single module. ++If you are doing it yourself by using the parallel port there ++are basically 2 options. ++ ++1) Using the parallel port and using the i2c-pport adapter module and the ++i2c-algo-bit algorithm module together to enable you to wire up your parallel ++port to act as an i2c/smbus. This provides a bus that will enable most ++sensors to work but doesn't support the entire i2c/smbus capability. ++ ++2) Using the parallel port to interface to a Philips PCF8584 parallel to i2c ++adapter chip. You will need to build a bit of a circuit to do this. This ++configuration needs the i2c-pcf-epp adapter module and the i2c-algo-pcf ++algorithm module. This support almost all of the i2c/smbus capabilities. ++ ++ ++i2c-pport Documentation ++----------------------- ++This is a primitive parallel port driver for the i2c bus, which exploits ++features of modern bidirectional parallel ports. ++ ++Bidirectional ports have particular bits connected in following way: ++ ++ | ++ /-----| R ++ --o| |-----| ++ read \-----| /------- Out pin ++ |/ ++ - -|\ ++ write V ++ | ++ --- ++ ++ ++It means when output is set to 1 we can read the port. Therefore ++we can use 2 pins of parallel port as SDA and SCL for i2c bus. It ++is not necessary to add any external - additional parts, we can ++read and write the same port simultaneously. ++ I only use register base+2 so it is possible to use all ++8 data bits of parallel port for other applications (I have ++connected EEPROM and LCD display). I do not use bit Enable Bi-directional ++ Port. The only disadvantage is we can only support 5V chips. ++ ++Layout: ++ ++Cannon 25 pin ++ ++SDA - connect to pin 14 (Auto Linefeed) ++SCL - connect to pin 16 (Initialize Printer) ++GND - connect to pin 18-25 +++5V - use external supply (I use 5V from 3.5" floppy connector) ++ ++no pullups requied ++ ++Module parameters: ++ ++base = 0xXXX ++XXX - 278 or 378 ++ ++That's all. ++ ++Daniel Smolik ++marvin@sitour.cz +--- linux-old/Documentation/i2c/i2c-protocol Mon Dec 22 22:44:34 2003 ++++ linux/Documentation/i2c/i2c-protocol Mon Dec 13 19:26:24 2004 +@@ -65,3 +65,12 @@ + need to emit an Rd instead of a Wr, or vice versa, you set this + flag. For example: + S Addr Rd [A] Data [A] Data [A] ... [A] Data [A] P ++ ++ Flags I2C_M_IGNORE_NAK ++ Normally message is interrupted immediately if there is [NA] from the ++ client. Setting this flag treats any [NA] as [A], and all of ++ message is sent. ++ These messages may still fail to SCL lo->hi timeout. ++ ++ Flags I2C_M_NO_RD_ACK ++ In a read message, master A/NA bit is skipped. +--- linux-old/Documentation/i2c/summary Tue Jan 20 15:10:28 2004 ++++ linux/Documentation/i2c/summary Mon Dec 13 19:26:24 2004 +@@ -59,16 +59,16 @@ + i2c-algo-8xx: An algorithm for CPM's I2C device in Motorola 8xx processors (NOT BUILT BY DEFAULT) + i2c-algo-bit: A bit-banging algorithm + i2c-algo-pcf: A PCF 8584 style algorithm +-i2c-algo-ppc405: An algorithm for the I2C device in IBM 405xx processors (NOT BUILT BY DEFAULT) ++i2c-algo-ibm_ocp: An algorithm for the I2C device in IBM 4xx processors (NOT BUILT BY DEFAULT) + + Adapter drivers + --------------- + + i2c-elektor: Elektor ISA card (uses i2c-algo-pcf) + i2c-elv: ELV parallel port adapter (uses i2c-algo-bit) +-i2c-pcf-epp: PCF8584 on a EPP parallel port (uses i2c-algo-pcf) (BROKEN - missing i2c-pcf-epp.h) ++i2c-pcf-epp: PCF8584 on a EPP parallel port (uses i2c-algo-pcf) (NOT mkpatched) + i2c-philips-par: Philips style parallel port adapter (uses i2c-algo-bit) +-i2c-ppc405: IBM 405xx processor I2C device (uses i2c-algo-ppc405) (NOT BUILT BY DEFAULT) ++i2c-adap-ibm_ocp: IBM 4xx processor I2C device (uses i2c-algo-ibm_ocp) (NOT BUILT BY DEFAULT) + i2c-pport: Primitive parallel port adapter (uses i2c-algo-bit) + i2c-rpx: RPX board Motorola 8xx I2C device (uses i2c-algo-8xx) (NOT BUILT BY DEFAULT) + i2c-velleman: Velleman K8000 parallel port adapter (uses i2c-algo-bit) +--- linux-old/Documentation/i2c/writing-clients Mon Dec 22 22:44:34 2003 ++++ linux/Documentation/i2c/writing-clients Mon Dec 13 19:26:25 2004 +@@ -24,24 +24,24 @@ + routines, a client structure specific information like the actual I2C + address. + +- struct i2c_driver foo_driver +- { +- /* name */ "Foo version 2.3 and later driver", +- /* id */ I2C_DRIVERID_FOO, +- /* flags */ I2C_DF_NOTIFY, +- /* attach_adapter */ &foo_attach_adapter, +- /* detach_client */ &foo_detach_client, +- /* command */ &foo_command, /* May be NULL */ +- /* inc_use */ &foo_inc_use, /* May be NULL */ +- /* dec_use */ &foo_dec_use /* May be NULL */ +- } ++static struct i2c_driver foo_driver = { ++ .owner = THIS_MODULE, ++ .name = "Foo version 2.3 driver", ++ .id = I2C_DRIVERID_FOO, /* from i2c-id.h, optional */ ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = &foo_attach_adapter, ++ .detach_client = &foo_detach_client, ++ .command = &foo_command /* may be NULL */ ++} + + The name can be chosen freely, and may be upto 40 characters long. Please + use something descriptive here. + +-The id should be a unique ID. The range 0xf000 to 0xffff is reserved for +-local use, and you can use one of those until you start distributing the +-driver. Before you do that, contact the i2c authors to get your own ID(s). ++If used, the id should be a unique ID. The range 0xf000 to 0xffff is ++reserved for local use, and you can use one of those until you start ++distributing the driver, at which time you should contact the i2c authors ++to get your own ID(s). Note that most of the time you don't need an ID ++at all so you can just omit it. + + Don't worry about the flags field; just put I2C_DF_NOTIFY into it. This + means that your driver will be notified when new adapters are found. +@@ -50,43 +50,8 @@ + All other fields are for call-back functions which will be explained + below. + +- +-Module usage count +-================== +- +-If your driver can also be compiled as a module, there are moments at +-which the module can not be removed from memory. For example, when you +-are doing a lengthy transaction, or when you create a /proc directory, +-and some process has entered that directory (this last case is the +-main reason why these call-backs were introduced). +- +-To increase or decrease the module usage count, you can use the +-MOD_{INC,DEC}_USE_COUNT macros. They must be called from the module +-which needs to get its usage count changed; that is why each driver +-module has to implement its own callback. +- +- void foo_inc_use (struct i2c_client *client) +- { +- #ifdef MODULE +- MOD_INC_USE_COUNT; +- #endif +- } +- +- void foo_dec_use (struct i2c_client *client) +- { +- #ifdef MODULE +- MOD_DEC_USE_COUNT; +- #endif +- } +- +-Do not call these call-back functions directly; instead, use one of the +-following functions defined in i2c.h: +- void i2c_inc_use_client(struct i2c_client *); +- void i2c_dec_use_client(struct i2c_client *); +- +-You should *not* increase the module count just because a device is +-detected and a client created. This would make it impossible to remove +-an adapter driver! ++There use to be two additional fields in this structure, inc_use et dec_use, ++for module usage count, but these fields were obsoleted and removed. + + + Extra client data +--- linux-old/drivers/i2c/i2c-adap-ibm_ocp.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-adap-ibm_ocp.c Mon Dec 13 19:26:26 2004 +@@ -0,0 +1,346 @@ ++/* ++ ------------------------------------------------------------------------- ++ i2c-adap-ibm_ocp.c i2c-hw access for the IIC peripheral on the IBM PPC 405 ++ ------------------------------------------------------------------------- ++ ++ Ian DaSilva, MontaVista Software, Inc. ++ idasilva@mvista.com or source@mvista.com ++ ++ Copyright 2000 MontaVista Software Inc. ++ ++ Changes made to support the IIC peripheral on the IBM PPC 405 ++ ++ ++ ---------------------------------------------------------------------------- ++ This file was highly leveraged from i2c-elektor.c, which was created ++ by Simon G. Vogl and Hans Berglund: ++ ++ ++ Copyright (C) 1995-97 Simon G. Vogl ++ 1998-99 Hans Berglund ++ ++ With some changes from Kyösti Mälkki and even ++ Frodo Looijaard ++ ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ---------------------------------------------------------------------------- ++ ++ History: 01/20/12 - Armin ++ akuster@mvista.com ++ ported up to 2.4.16+ ++ ++ Version 02/03/25 - Armin ++ converted to ocp format ++ removed commented out or #if 0 code ++ ++ TODO: convert to ocp_register ++ add PM hooks ++ ++*/ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * This next section is configurable, and it is used to set the number ++ * of i2c controllers in the system. The default number of instances is 1, ++ * however, this should be changed to reflect your system's configuration. ++ */ ++ ++/* ++ * The STB03xxx, with a PPC405 core, has two i2c controllers. ++ */ ++//(sizeof(IIC_ADDR)/sizeof(struct iic_regs)) ++extern iic_t *IIC_ADDR[]; ++static struct iic_ibm iic_ibmocp_adaps[IIC_NUMS][5]; ++ ++static struct i2c_algo_iic_data *iic_ibmocp_data[IIC_NUMS]; ++static struct i2c_adapter *iic_ibmocp_ops[IIC_NUMS]; ++ ++static int i2c_debug=0; ++static wait_queue_head_t iic_wait[IIC_NUMS]; ++static int iic_pending; ++static spinlock_t irq_driver_lock = SPIN_LOCK_UNLOCKED; ++ ++ ++/* ----- global defines ----------------------------------------------- */ ++#define DEB(x) if (i2c_debug>=1) x ++#define DEB2(x) if (i2c_debug>=2) x ++#define DEB3(x) if (i2c_debug>=3) x ++#define DEBE(x) x /* error messages */ ++ ++/* ----- local functions ---------------------------------------------- */ ++ ++// ++// Description: Write a byte to IIC hardware ++// ++static void iic_ibmocp_setbyte(void *data, int ctl, int val) ++{ ++ // writeb resolves to a write to the specified memory location ++ // plus a call to eieio. eieio ensures that all instructions ++ // preceding it are completed before any further stores are ++ // completed. ++ // Delays at this level (to protect writes) are not needed here. ++ writeb(val, ctl); ++} ++ ++ ++// ++// Description: Read a byte from IIC hardware ++// ++static int iic_ibmocp_getbyte(void *data, int ctl) ++{ ++ int val; ++ ++ val = readb(ctl); ++ return (val); ++} ++ ++ ++// ++// Description: Return our slave address. This is the address ++// put on the I2C bus when another master on the bus wants to address us ++// as a slave ++// ++static int iic_ibmocp_getown(void *data) ++{ ++ return(((struct iic_ibm *)(data))->iic_own); ++} ++ ++ ++// ++// Description: Return the clock rate ++// ++static int iic_ibmocp_getclock(void *data) ++{ ++ return(((struct iic_ibm *)(data))->iic_clock); ++} ++ ++ ++ ++// ++// Description: Put this process to sleep. We will wake up when the ++// IIC controller interrupts. ++// ++static void iic_ibmocp_waitforpin(void *data) { ++ ++ int timeout = 2; ++ struct iic_ibm *priv_data = data; ++ ++ // ++ // If interrupts are enabled (which they are), then put the process to ++ // sleep. This process will be awakened by two events -- either the ++ // the IIC peripheral interrupts or the timeout expires. ++ // ++ if (priv_data->iic_irq > 0) { ++ spin_lock_irq(&irq_driver_lock); ++ if (iic_pending == 0) { ++ interruptible_sleep_on_timeout(&(iic_wait[priv_data->index]), timeout*HZ ); ++ } else ++ iic_pending = 0; ++ spin_unlock_irq(&irq_driver_lock); ++ } else { ++ // ++ // If interrupts are not enabled then delay for a reasonable amount ++ // of time and return. We expect that by time we return to the calling ++ // function that the IIC has finished our requested transaction and ++ // the status bit reflects this. ++ // ++ // udelay is probably not the best choice for this since it is ++ // the equivalent of a busy wait ++ // ++ udelay(100); ++ } ++ //printk("iic_ibmocp_waitforpin: exitting\n"); ++} ++ ++ ++// ++// Description: The registered interrupt handler ++// ++static void iic_ibmocp_handler(int this_irq, void *dev_id, struct pt_regs *regs) ++{ ++ int ret; ++ struct iic_regs *iic; ++ struct iic_ibm *priv_data = dev_id; ++ iic = (struct iic_regs *) priv_data->iic_base; ++ iic_pending = 1; ++ DEB2(printk("iic_ibmocp_handler: in interrupt handler\n")); ++ // Read status register ++ ret = readb((int) &(iic->sts)); ++ DEB2(printk("iic_ibmocp_handler: status = %x\n", ret)); ++ // Clear status register. See IBM PPC 405 reference manual for details ++ writeb(0x0a, (int) &(iic->sts)); ++ wake_up_interruptible(&(iic_wait[priv_data->index])); ++} ++ ++ ++// ++// Description: This function is very hardware dependent. First, we lock ++// the region of memory where out registers exist. Next, we request our ++// interrupt line and register its associated handler. Our IIC peripheral ++// uses interrupt number 2, as specified by the 405 reference manual. ++// ++static int iic_hw_resrc_init(int instance) ++{ ++ ++ DEB(printk("iic_hw_resrc_init: Physical Base address: 0x%x\n", (u32) IIC_ADDR[instance] )); ++ iic_ibmocp_adaps[instance]->iic_base = (u32)ioremap((unsigned long)IIC_ADDR[instance],PAGE_SIZE); ++ ++ DEB(printk("iic_hw_resrc_init: ioremapped base address: 0x%x\n", iic_ibmocp_adaps[instance]->iic_base)); ++ ++ if (iic_ibmocp_adaps[instance]->iic_irq > 0) { ++ ++ if (request_irq(iic_ibmocp_adaps[instance]->iic_irq, iic_ibmocp_handler, ++ 0, "IBM OCP IIC", iic_ibmocp_adaps[instance]) < 0) { ++ printk(KERN_ERR "iic_hw_resrc_init: Request irq%d failed\n", ++ iic_ibmocp_adaps[instance]->iic_irq); ++ iic_ibmocp_adaps[instance]->iic_irq = 0; ++ } else { ++ DEB3(printk("iic_hw_resrc_init: Enabled interrupt\n")); ++ } ++ } ++ return 0; ++} ++ ++ ++// ++// Description: Release irq and memory ++// ++static void iic_ibmocp_release(void) ++{ ++ int i; ++ ++ for(i=0; idata; ++ if (priv_data->iic_irq > 0) { ++ disable_irq(priv_data->iic_irq); ++ free_irq(priv_data->iic_irq, 0); ++ } ++ kfree(iic_ibmocp_data[i]); ++ kfree(iic_ibmocp_ops[i]); ++ } ++} ++ ++ ++// ++// Description: Called when the module is loaded. This function starts the ++// cascade of calls up through the heirarchy of i2c modules (i.e. up to the ++// algorithm layer and into to the core layer) ++// ++static int __init iic_ibmocp_init(void) ++{ ++ int i; ++ ++ printk(KERN_INFO "iic_ibmocp_init: IBM on-chip iic adapter module\n"); ++ ++ for(i=0; iiic_irq = IIC_IRQ(0); ++ break; ++ case 1: ++ iic_ibmocp_adaps[i]->iic_irq = IIC_IRQ(1); ++ break; ++ } ++ iic_ibmocp_adaps[i]->iic_clock = IIC_CLOCK; ++ iic_ibmocp_adaps[i]->iic_own = IIC_OWN; ++ iic_ibmocp_adaps[i]->index = i; ++ ++ DEB(printk("irq %x\n", iic_ibmocp_adaps[i]->iic_irq)); ++ DEB(printk("clock %x\n", iic_ibmocp_adaps[i]->iic_clock)); ++ DEB(printk("own %x\n", iic_ibmocp_adaps[i]->iic_own)); ++ DEB(printk("index %x\n", iic_ibmocp_adaps[i]->index)); ++ ++ ++ iic_ibmocp_data[i]->data = (struct iic_regs *)iic_ibmocp_adaps[i]; ++ iic_ibmocp_data[i]->setiic = iic_ibmocp_setbyte; ++ iic_ibmocp_data[i]->getiic = iic_ibmocp_getbyte; ++ iic_ibmocp_data[i]->getown = iic_ibmocp_getown; ++ iic_ibmocp_data[i]->getclock = iic_ibmocp_getclock; ++ iic_ibmocp_data[i]->waitforpin = iic_ibmocp_waitforpin; ++ iic_ibmocp_data[i]->udelay = 80; ++ iic_ibmocp_data[i]->mdelay = 80; ++ iic_ibmocp_data[i]->timeout = HZ; ++ ++ iic_ibmocp_ops[i] = kmalloc(sizeof(struct i2c_adapter), GFP_KERNEL); ++ if(iic_ibmocp_ops[i] == NULL) { ++ return -ENOMEM; ++ } ++ memset(iic_ibmocp_ops[i], 0, sizeof(struct i2c_adapter)); ++ strcpy(iic_ibmocp_ops[i]->name, "IBM OCP IIC adapter"); ++ iic_ibmocp_ops[i]->owner = THIS_MODULE; ++ iic_ibmocp_ops[i]->id = I2C_HW_OCP; ++ iic_ibmocp_ops[i]->algo = NULL; ++ iic_ibmocp_ops[i]->algo_data = iic_ibmocp_data[i]; ++ ++ ++ init_waitqueue_head(&(iic_wait[i])); ++ if (iic_hw_resrc_init(i) == 0) { ++ if (i2c_ocp_add_bus(iic_ibmocp_ops[i]) < 0) ++ return -ENODEV; ++ } else { ++ return -ENODEV; ++ } ++ DEB(printk(KERN_INFO "iic_ibmocp_init: found device at %#x.\n\n", iic_ibmocp_adaps[i]->iic_base)); ++ } ++ return 0; ++} ++ ++ ++static void __exit iic_ibmocp_exit(void) ++{ ++ int i; ++ ++ for(i=0; i"); ++MODULE_DESCRIPTION("I2C-Bus adapter routines for PPC 405 IIC bus adapter"); ++MODULE_LICENSE("GPL"); ++ ++MODULE_PARM(base, "i"); ++MODULE_PARM(irq, "i"); ++MODULE_PARM(clock, "i"); ++MODULE_PARM(own, "i"); ++MODULE_PARM(i2c_debug,"i"); ++ ++ ++module_init(iic_ibmocp_init); ++module_exit(iic_ibmocp_exit); +--- linux-old/drivers/i2c/i2c-algo-8xx.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-algo-8xx.c Mon Dec 13 19:26:27 2004 +@@ -0,0 +1,616 @@ ++/* ++ * i2c-algo-8xx.c i2x driver algorithms for MPC8XX CPM ++ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net). ++ * ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ * moved into proper i2c interface; separated out platform specific ++ * parts into i2c-rpx.c ++ * Brad Parker (brad@heeltoe.com) ++ */ ++ ++// XXX todo ++// timeout sleep? ++ ++/* $Id: i2c-algo-8xx.c,v 1.14 2003/07/25 07:56:42 khali Exp $ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define CPM_MAX_READ 513 ++/* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an older CPU(earlier than rev D4) */ ++static wait_queue_head_t iic_wait; ++static ushort r_tbase, r_rbase; ++ ++int cpm_debug = 0; ++ ++static void ++cpm_iic_interrupt(void *dev_id, struct pt_regs *regs) ++{ ++ volatile i2c8xx_t *i2c = (i2c8xx_t *)dev_id; ++ if (cpm_debug > 1) ++ printk("cpm_iic_interrupt(dev_id=%p)\n", dev_id); ++#if 0 ++ /* Chip errata, clear enable. This is not needed on rev D4 CPUs */ ++ /* This should probably be removed and replaced by I2C_CHIP_ERRATA stuff */ ++ /* Someone with a buggy CPU needs to confirm that */ ++ i2c->i2c_i2mod &= ~1; ++#endif ++ /* Clear interrupt. ++ */ ++ i2c->i2c_i2cer = 0xff; ++ ++ /* Get 'me going again. ++ */ ++ wake_up_interruptible(&iic_wait); ++} ++ ++static void ++cpm_iic_init(struct i2c_algo_8xx_data *cpm) ++{ ++ volatile iic_t *iip = cpm->iip; ++ volatile i2c8xx_t *i2c = cpm->i2c; ++ unsigned char brg; ++ bd_t *bd = (bd_t *)__res; ++ ++ if (cpm_debug) printk(KERN_DEBUG "cpm_iic_init()\n"); ++ ++ /* Initialize the parameter ram. ++ * We need to make sure many things are initialized to zero, ++ * especially in the case of a microcode patch. ++ */ ++ iip->iic_rstate = 0; ++ iip->iic_rdp = 0; ++ iip->iic_rbptr = 0; ++ iip->iic_rbc = 0; ++ iip->iic_rxtmp = 0; ++ iip->iic_tstate = 0; ++ iip->iic_tdp = 0; ++ iip->iic_tbptr = 0; ++ iip->iic_tbc = 0; ++ iip->iic_txtmp = 0; ++ ++ /* Set up the IIC parameters in the parameter ram. ++ */ ++ iip->iic_tbase = r_tbase = cpm->dp_addr; ++ iip->iic_rbase = r_rbase = cpm->dp_addr + sizeof(cbd_t)*2; ++ ++ iip->iic_tfcr = SMC_EB; ++ iip->iic_rfcr = SMC_EB; ++ ++ /* Set maximum receive size. ++ */ ++ iip->iic_mrblr = CPM_MAX_READ; ++ ++ /* Initialize Tx/Rx parameters. ++ */ ++ if (cpm->reloc == 0) { ++ volatile cpm8xx_t *cp = cpm->cp; ++ ++ cp->cp_cpcr = ++ mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG; ++ while (cp->cp_cpcr & CPM_CR_FLG); ++ } else { ++ iip->iic_rbptr = iip->iic_rbase; ++ iip->iic_tbptr = iip->iic_tbase; ++ iip->iic_rstate = 0; ++ iip->iic_tstate = 0; ++ } ++ ++ /* Select an arbitrary address. Just make sure it is unique. ++ */ ++ i2c->i2c_i2add = 0xfe; ++ ++ /* Make clock run at 60 KHz. ++ */ ++ brg = (unsigned char) (bd->bi_intfreq/(32*2*60000) -3); ++ i2c->i2c_i2brg = brg; ++ ++ i2c->i2c_i2mod = 0x00; ++ i2c->i2c_i2com = 0x01; /* Master mode */ ++ ++ /* Disable interrupts. ++ */ ++ i2c->i2c_i2cmr = 0; ++ i2c->i2c_i2cer = 0xff; ++ ++ init_waitqueue_head(&iic_wait); ++ ++ /* Install interrupt handler. ++ */ ++ if (cpm_debug) { ++ printk ("%s[%d] Install ISR for IRQ %d\n", ++ __func__,__LINE__, CPMVEC_I2C); ++ } ++ (*cpm->setisr)(CPMVEC_I2C, cpm_iic_interrupt, (void *)i2c); ++} ++ ++ ++static int ++cpm_iic_shutdown(struct i2c_algo_8xx_data *cpm) ++{ ++ volatile i2c8xx_t *i2c = cpm->i2c; ++ ++ /* Shut down IIC. ++ */ ++ i2c->i2c_i2mod &= ~1; ++ i2c->i2c_i2cmr = 0; ++ i2c->i2c_i2cer = 0xff; ++ ++ return(0); ++} ++ ++static void ++cpm_reset_iic_params(volatile iic_t *iip) ++{ ++ iip->iic_tbase = r_tbase; ++ iip->iic_rbase = r_rbase; ++ ++ iip->iic_tfcr = SMC_EB; ++ iip->iic_rfcr = SMC_EB; ++ ++ iip->iic_mrblr = CPM_MAX_READ; ++ ++ iip->iic_rstate = 0; ++ iip->iic_rdp = 0; ++ iip->iic_rbptr = iip->iic_rbase; ++ iip->iic_rbc = 0; ++ iip->iic_rxtmp = 0; ++ iip->iic_tstate = 0; ++ iip->iic_tdp = 0; ++ iip->iic_tbptr = iip->iic_tbase; ++ iip->iic_tbc = 0; ++ iip->iic_txtmp = 0; ++} ++ ++#define BD_SC_NAK ((ushort)0x0004) /* NAK - did not respond */ ++#define BD_SC_OV ((ushort)0x0002) /* OV - receive overrun */ ++#define CPM_CR_CLOSE_RXBD ((ushort)0x0007) ++ ++static void force_close(struct i2c_algo_8xx_data *cpm) ++{ ++ volatile i2c8xx_t *i2c = cpm->i2c; ++ if (cpm->reloc == 0) { /* micro code disabled */ ++ volatile cpm8xx_t *cp = cpm->cp; ++ ++ if (cpm_debug) printk("force_close()\n"); ++ cp->cp_cpcr = ++ mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_CLOSE_RXBD) | ++ CPM_CR_FLG; ++ ++ while (cp->cp_cpcr & CPM_CR_FLG); ++ } ++ i2c->i2c_i2cmr = 0x00; /* Disable all interrupts */ ++ i2c->i2c_i2cer = 0xff; ++} ++ ++ ++/* Read from IIC... ++ * abyte = address byte, with r/w flag already set ++ */ ++static int ++cpm_iic_read(struct i2c_algo_8xx_data *cpm, u_char abyte, char *buf, int count) ++{ ++ volatile iic_t *iip = cpm->iip; ++ volatile i2c8xx_t *i2c = cpm->i2c; ++ volatile cpm8xx_t *cp = cpm->cp; ++ volatile cbd_t *tbdf, *rbdf; ++ u_char *tb; ++ unsigned long flags, tmo; ++ ++ if (count >= CPM_MAX_READ) ++ return -EINVAL; ++ ++ /* check for and use a microcode relocation patch */ ++ if (cpm->reloc) { ++ cpm_reset_iic_params(iip); ++ } ++ ++ tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase]; ++ rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase]; ++ ++ /* To read, we need an empty buffer of the proper length. ++ * All that is used is the first byte for address, the remainder ++ * is just used for timing (and doesn't really have to exist). ++ */ ++ tb = cpm->temp; ++ tb = (u_char *)(((uint)tb + 15) & ~15); ++ tb[0] = abyte; /* Device address byte w/rw flag */ ++ ++ flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1)); ++ ++ if (cpm_debug) printk("cpm_iic_read(abyte=0x%x)\n", abyte); ++ ++ tbdf->cbd_bufaddr = __pa(tb); ++ tbdf->cbd_datlen = count + 1; ++ tbdf->cbd_sc = ++ BD_SC_READY | BD_SC_LAST | ++ BD_SC_WRAP | BD_IIC_START; ++ ++ iip->iic_mrblr = count +1; /* prevent excessive read, +1 ++ is needed otherwise will the ++ RXB interrupt come too early */ ++ ++ /* flush will invalidate too. */ ++ flush_dcache_range((unsigned long) buf, (unsigned long) (buf+count)); ++ ++ rbdf->cbd_datlen = 0; ++ rbdf->cbd_bufaddr = __pa(buf); ++ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP| BD_SC_INTRPT; ++ if(count > 16){ ++ /* Chip bug, set enable here */ ++ local_irq_save(flags); ++ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */ ++ i2c->i2c_i2cer = 0xff; ++ i2c->i2c_i2mod |= 1; /* Enable */ ++ i2c->i2c_i2com |= 0x80; /* Begin transmission */ ++ ++ /* Wait for IIC transfer */ ++ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ); ++ local_irq_restore(flags); ++ } else { /* busy wait for small transfers, its faster */ ++ i2c->i2c_i2cmr = 0x00; /* Disable I2C interupts */ ++ i2c->i2c_i2cer = 0xff; ++ i2c->i2c_i2mod |= 1; /* Enable */ ++ i2c->i2c_i2com |= 0x80; /* Begin transmission */ ++ tmo = jiffies + 1*HZ; ++ while(!(i2c->i2c_i2cer & 0x11 || time_after(jiffies, tmo))); /* Busy wait, with a timeout */ ++ } ++ ++ if (signal_pending(current) || !tmo){ ++ force_close(cpm); ++ if(cpm_debug) ++ printk("IIC read: timeout!\n"); ++ return -EIO; ++ } ++#ifdef I2C_CHIP_ERRATA ++ /* Chip errata, clear enable. This is not needed on rev D4 CPUs. ++ Disabling I2C too early may cause too short stop condition */ ++ udelay(4); ++ i2c->i2c_i2mod &= ~1; ++#endif ++ if (cpm_debug) { ++ printk("tx sc %04x, rx sc %04x\n", ++ tbdf->cbd_sc, rbdf->cbd_sc); ++ } ++ ++ if (tbdf->cbd_sc & BD_SC_READY) { ++ printk("IIC read; complete but tbuf ready\n"); ++ force_close(cpm); ++ printk("tx sc %04x, rx sc %04x\n", ++ tbdf->cbd_sc, rbdf->cbd_sc); ++ } ++ ++ if (tbdf->cbd_sc & BD_SC_NAK) { ++ if (cpm_debug) ++ printk("IIC read; no ack\n"); ++ return -EREMOTEIO; ++ } ++ ++ if (rbdf->cbd_sc & BD_SC_EMPTY) { ++ /* force_close(cpm); */ ++ if (cpm_debug){ ++ printk("IIC read; complete but rbuf empty\n"); ++ printk("tx sc %04x, rx sc %04x\n", ++ tbdf->cbd_sc, rbdf->cbd_sc); ++ } ++ return -EREMOTEIO; ++ } ++ ++ if (rbdf->cbd_sc & BD_SC_OV) { ++ if (cpm_debug) ++ printk("IIC read; Overrun\n"); ++ return -EREMOTEIO;; ++ } ++ ++ if (cpm_debug) printk("read %d bytes\n", rbdf->cbd_datlen); ++ ++ if (rbdf->cbd_datlen < count) { ++ if (cpm_debug) ++ printk("IIC read; short, wanted %d got %d\n", ++ count, rbdf->cbd_datlen); ++ return 0; ++ } ++ ++ return count; ++} ++ ++/* Write to IIC... ++ * addr = address byte, with r/w flag already set ++ */ ++static int ++cpm_iic_write(struct i2c_algo_8xx_data *cpm, u_char abyte, char *buf,int count) ++{ ++ volatile iic_t *iip = cpm->iip; ++ volatile i2c8xx_t *i2c = cpm->i2c; ++ volatile cpm8xx_t *cp = cpm->cp; ++ volatile cbd_t *tbdf; ++ u_char *tb; ++ unsigned long flags, tmo; ++ ++ /* check for and use a microcode relocation patch */ ++ if (cpm->reloc) { ++ cpm_reset_iic_params(iip); ++ } ++ tb = cpm->temp; ++ tb = (u_char *)(((uint)tb + 15) & ~15); ++ *tb = abyte; /* Device address byte w/rw flag */ ++ ++ flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1)); ++ flush_dcache_range((unsigned long) buf, (unsigned long) (buf+count)); ++ ++ if (cpm_debug) printk("cpm_iic_write(abyte=0x%x)\n", abyte); ++ ++ /* set up 2 descriptors */ ++ tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase]; ++ ++ tbdf[0].cbd_bufaddr = __pa(tb); ++ tbdf[0].cbd_datlen = 1; ++ tbdf[0].cbd_sc = BD_SC_READY | BD_IIC_START; ++ ++ tbdf[1].cbd_bufaddr = __pa(buf); ++ tbdf[1].cbd_datlen = count; ++ tbdf[1].cbd_sc = BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | BD_SC_WRAP; ++ ++ if(count > 16){ ++ /* Chip bug, set enable here */ ++ local_irq_save(flags); ++ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */ ++ i2c->i2c_i2cer = 0xff; ++ i2c->i2c_i2mod |= 1; /* Enable */ ++ i2c->i2c_i2com |= 0x80; /* Begin transmission */ ++ ++ /* Wait for IIC transfer */ ++ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ); ++ local_irq_restore(flags); ++ } else { /* busy wait for small transfers, its faster */ ++ i2c->i2c_i2cmr = 0x00; /* Disable I2C interupts */ ++ i2c->i2c_i2cer = 0xff; ++ i2c->i2c_i2mod |= 1; /* Enable */ ++ i2c->i2c_i2com |= 0x80; /* Begin transmission */ ++ tmo = jiffies + 1*HZ; ++ while(!(i2c->i2c_i2cer & 0x12 || time_after(jiffies, tmo))); /* Busy wait, with a timeout */ ++ } ++ ++ if (signal_pending(current) || !tmo){ ++ force_close(cpm); ++ if(cpm_debug && !tmo) ++ printk("IIC write: timeout!\n"); ++ return -EIO; ++ } ++ ++#if I2C_CHIP_ERRATA ++ /* Chip errata, clear enable. This is not needed on rev D4 CPUs. ++ Disabling I2C too early may cause too short stop condition */ ++ udelay(4); ++ i2c->i2c_i2mod &= ~1; ++#endif ++ if (cpm_debug) { ++ printk("tx0 sc %04x, tx1 sc %04x\n", ++ tbdf[0].cbd_sc, tbdf[1].cbd_sc); ++ } ++ ++ if (tbdf->cbd_sc & BD_SC_NAK) { ++ if (cpm_debug) ++ printk("IIC write; no ack\n"); ++ return 0; ++ } ++ ++ if (tbdf->cbd_sc & BD_SC_READY) { ++ if (cpm_debug) ++ printk("IIC write; complete but tbuf ready\n"); ++ return 0; ++ } ++ ++ return count; ++} ++ ++/* See if an IIC address exists.. ++ * addr = 7 bit address, unshifted ++ */ ++static int ++cpm_iic_tryaddress(struct i2c_algo_8xx_data *cpm, int addr) ++{ ++ volatile iic_t *iip = cpm->iip; ++ volatile i2c8xx_t *i2c = cpm->i2c; ++ volatile cpm8xx_t *cp = cpm->cp; ++ volatile cbd_t *tbdf, *rbdf; ++ u_char *tb; ++ unsigned long flags, len, tmo; ++ ++ if (cpm_debug > 1) ++ printk("cpm_iic_tryaddress(cpm=%p,addr=%d)\n", cpm, addr); ++ ++ /* check for and use a microcode relocation patch */ ++ if (cpm->reloc) { ++ cpm_reset_iic_params(iip); ++ } ++ ++ if (cpm_debug && addr == 0) { ++ printk("iip %p, dp_addr 0x%x\n", cpm->iip, cpm->dp_addr); ++ printk("iic_tbase %d, r_tbase %d\n", iip->iic_tbase, r_tbase); ++ } ++ ++ tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase]; ++ rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase]; ++ ++ tb = cpm->temp; ++ tb = (u_char *)(((uint)tb + 15) & ~15); ++ ++ /* do a simple read */ ++ tb[0] = (addr << 1) | 1; /* device address (+ read) */ ++ len = 2; ++ ++ flush_dcache_range((unsigned long) tb, (unsigned long) (tb+2)); ++ ++ tbdf->cbd_bufaddr = __pa(tb); ++ tbdf->cbd_datlen = len; ++ tbdf->cbd_sc = ++ BD_SC_READY | BD_SC_LAST | ++ BD_SC_WRAP | BD_IIC_START; ++ ++ rbdf->cbd_datlen = 0; ++ rbdf->cbd_bufaddr = __pa(tb+2); ++ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP | BD_SC_INTRPT; ++ ++ local_irq_save(flags); ++ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */ ++ i2c->i2c_i2cer = 0xff; ++ i2c->i2c_i2mod |= 1; /* Enable */ ++ i2c->i2c_i2com |= 0x80; /* Begin transmission */ ++ ++ if (cpm_debug > 1) printk("about to sleep\n"); ++ ++ /* wait for IIC transfer */ ++ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ); ++ local_irq_restore(flags); ++ ++#ifdef I2C_CHIP_ERRATA ++ /* Chip errata, clear enable. This is not needed on rev D4 CPUs. ++ Disabling I2C too early may cause too short stop condition */ ++ udelay(4); ++ i2c->i2c_i2mod &= ~1; ++#endif ++ ++ if (signal_pending(current) || !tmo){ ++ force_close(cpm); ++ if(cpm_debug && !tmo) ++ printk("IIC tryaddress: timeout!\n"); ++ return -EIO; ++ } ++ ++ if (cpm_debug > 1) printk("back from sleep\n"); ++ ++ if (tbdf->cbd_sc & BD_SC_NAK) { ++ if (cpm_debug > 1) printk("IIC try; no ack\n"); ++ return 0; ++ } ++ ++ if (tbdf->cbd_sc & BD_SC_READY) { ++ printk("IIC try; complete but tbuf ready\n"); ++ } ++ ++ return 1; ++} ++ ++static int cpm_xfer(struct i2c_adapter *adap, ++ struct i2c_msg msgs[], ++ int num) ++{ ++ struct i2c_algo_8xx_data *cpm = adap->algo_data; ++ struct i2c_msg *pmsg; ++ int i, ret; ++ u_char addr; ++ ++ for (i = 0; i < num; i++) { ++ pmsg = &msgs[i]; ++ ++ if (cpm_debug) ++ printk("i2c-algo-8xx.o: " ++ "#%d addr=0x%x flags=0x%x len=%d\n buf=%lx\n", ++ i, pmsg->addr, pmsg->flags, pmsg->len, (unsigned long)pmsg->buf); ++ ++ addr = pmsg->addr << 1; ++ if (pmsg->flags & I2C_M_RD ) ++ addr |= 1; ++ if (pmsg->flags & I2C_M_REV_DIR_ADDR ) ++ addr ^= 1; ++ ++ if (!(pmsg->flags & I2C_M_NOSTART)) { ++ } ++ if (pmsg->flags & I2C_M_RD ) { ++ /* read bytes into buffer*/ ++ ret = cpm_iic_read(cpm, addr, pmsg->buf, pmsg->len); ++ if (cpm_debug) ++ printk("i2c-algo-8xx.o: read %d bytes\n", ret); ++ if (ret < pmsg->len ) { ++ return (ret<0)? ret : -EREMOTEIO; ++ } ++ } else { ++ /* write bytes from buffer */ ++ ret = cpm_iic_write(cpm, addr, pmsg->buf, pmsg->len); ++ if (cpm_debug) ++ printk("i2c-algo-8xx.o: wrote %d\n", ret); ++ if (ret < pmsg->len ) { ++ return (ret<0) ? ret : -EREMOTEIO; ++ } ++ } ++ } ++ return (num); ++} ++ ++static u32 cpm_func(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | ++ I2C_FUNC_PROTOCOL_MANGLING; ++} ++ ++/* -----exported algorithm data: ------------------------------------- */ ++ ++static struct i2c_algorithm cpm_algo = { ++ .owner = THIS_MODULE, ++ .name = "MPC8xx CPM algorithm", ++ .id = I2C_ALGO_MPC8XX, ++ .master_xfer = cpm_xfer, ++ .functionality = cpm_func, ++}; ++ ++/* ++ * registering functions to load algorithms at runtime ++ */ ++int i2c_8xx_add_bus(struct i2c_adapter *adap) ++{ ++ int i; ++ struct i2c_algo_8xx_data *cpm = adap->algo_data; ++ ++ if (cpm_debug) ++ printk("i2c-algo-8xx.o: hw routines for %s registered.\n", ++ adap->name); ++ ++ /* register new adapter to i2c module... */ ++ ++ adap->id |= cpm_algo.id; ++ adap->algo = &cpm_algo; ++ ++ i2c_add_adapter(adap); ++ cpm_iic_init(cpm); ++} ++ ++ ++int i2c_8xx_del_bus(struct i2c_adapter *adap) ++{ ++ struct i2c_algo_8xx_data *cpm = adap->algo_data; ++ ++ cpm_iic_shutdown(cpm); ++ ++ return i2c_del_adapter(adap); ++} ++ ++EXPORT_SYMBOL(i2c_8xx_add_bus); ++EXPORT_SYMBOL(i2c_8xx_del_bus); ++ ++MODULE_AUTHOR("Brad Parker "); ++MODULE_DESCRIPTION("I2C-Bus MPC8XX algorithm"); ++MODULE_LICENSE("GPL"); +--- linux-old/include/linux/i2c-algo-8xx.h Thu Jan 1 00:00:00 1970 ++++ linux/include/linux/i2c-algo-8xx.h Mon Dec 13 19:26:27 2004 +@@ -0,0 +1,43 @@ ++/* ------------------------------------------------------------------------- */ ++/* i2c-algo-8xx.h i2c driver algorithms for MPX8XX CPM */ ++/* ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ ++/* ------------------------------------------------------------------------- */ ++ ++/* $Id: i2c-algo-8xx.h,v 1.7 2003/08/01 20:56:38 khali Exp $ */ ++ ++#ifndef _LINUX_I2C_ALGO_8XX_H ++#define _LINUX_I2C_ALGO_8XX_H ++ ++#include "asm/commproc.h" ++ ++struct i2c_algo_8xx_data { ++ uint dp_addr; ++ int reloc; ++ volatile i2c8xx_t *i2c; ++ volatile iic_t *iip; ++ volatile cpm8xx_t *cp; ++ ++ int (*setisr) (int irq, ++ void (*func)(void *, void *), ++ void *data); ++ ++ u_char temp[513]; ++}; ++ ++int i2c_8xx_add_bus(struct i2c_adapter *); ++int i2c_8xx_del_bus(struct i2c_adapter *); ++ ++#endif /* _LINUX_I2C_ALGO_8XX_H */ +--- linux-old/drivers/i2c/i2c-algo-bit.c Tue Jan 20 15:10:31 2004 ++++ linux/drivers/i2c/i2c-algo-bit.c Mon Dec 13 19:26:27 2004 +@@ -18,24 +18,22 @@ + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + /* ------------------------------------------------------------------------- */ + +-/* With some changes from Kyösti Mälkki and even +- Frodo Looijaard */ ++/* With some changes from Frodo Looijaard , Kyösti Mälkki ++ and Jean Delvare */ + +-/* $Id: i2c-algo-bit.c,v 1.30 2001/07/29 02:44:25 mds Exp $ */ ++/* $Id: i2c-algo-bit.c,v 1.50 2003/12/22 20:03:39 khali Exp $ */ + + #include + #include + #include + #include + #include +-#include +-#include + #include + #include +- + #include + #include + ++ + /* ----- global defines ----------------------------------------------- */ + #define DEB(x) if (i2c_debug>=1) x; + #define DEB2(x) if (i2c_debug>=2) x; +@@ -43,27 +41,13 @@ + #define DEBPROTO(x) if (i2c_debug>=9) { x; } + /* debug the protocol by showing transferred bits */ + +-/* debugging - slow down transfer to have a look at the data .. */ +-/* I use this with two leds&resistors, each one connected to sda,scl */ +-/* respectively. This makes sure that the algorithm works. Some chips */ +-/* might not like this, as they have an internal timeout of some mils */ +-/* +-#define SLO_IO jif=jiffies;while(time_before_eq(jiffies, jif+i2c_table[minor].veryslow))\ +- if (need_resched) schedule(); +-*/ +- + + /* ----- global variables --------------------------------------------- */ + +-#ifdef SLO_IO +- int jif; +-#endif +- + /* module parameters: + */ + static int i2c_debug; + static int bit_test; /* see if the line-setting functions work */ +-static int bit_scan; /* have a look at what's hanging 'round */ + + /* --- setting states on the bus with the right timing: --------------- */ + +@@ -88,9 +72,6 @@ + { + setscl(adap,0); + udelay(adap->udelay); +-#ifdef SLO_IO +- SLO_IO +-#endif + } + + /* +@@ -99,33 +80,35 @@ + */ + static inline int sclhi(struct i2c_algo_bit_data *adap) + { +- int start=jiffies; ++ int start; + + setscl(adap,1); + +- udelay(adap->udelay); +- + /* Not all adapters have scl sense line... */ +- if (adap->getscl == NULL ) ++ if (adap->getscl == NULL ) { ++ udelay(adap->udelay); + return 0; ++ } + +- while (! getscl(adap) ) { ++ start=jiffies; ++ while (! getscl(adap) ) { + /* the hw knows how to read the clock line, + * so we wait until it actually gets high. + * This is safer as some chips may hold it low + * while they are processing data internally. + */ +- setscl(adap,1); + if (time_after_eq(jiffies, start+adap->timeout)) { + return -ETIMEDOUT; + } ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + if (current->need_resched) + schedule(); ++#else ++ cond_resched(); ++#endif + } + DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start)); +-#ifdef SLO_IO +- SLO_IO +-#endif ++ udelay(adap->udelay); + return 0; + } + +@@ -144,7 +127,7 @@ + /* scl, sda may not be high */ + DEBPROTO(printk(" Sr ")); + setsda(adap,1); +- setscl(adap,1); ++ sclhi(adap); + udelay(adap->udelay); + + sdalo(adap); +@@ -178,7 +161,6 @@ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + /* assert: scl is low */ +- DEB2(printk(KERN_DEBUG " i2c_outb:%2.2X\n",c&0xff)); + for ( i=7 ; i>=0 ; i-- ) { + sb = c & ( 1 << i ); + setsda(adap,sb); +@@ -186,6 +168,7 @@ + DEBPROTO(printk(KERN_DEBUG "%d",sb!=0)); + if (sclhi(adap)<0) { /* timed out */ + sdahi(adap); /* we don't want to block the net */ ++ DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at bit #%d\n", c&0xff, i)); + return -ETIMEDOUT; + }; + /* do arbitration here: +@@ -196,11 +179,12 @@ + } + sdahi(adap); + if (sclhi(adap)<0){ /* timeout */ ++ DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at ack\n", c&0xff)); + return -ETIMEDOUT; + }; + /* read ack: SDA should be pulled down by slave */ + ack=getsda(adap); /* ack: sda is pulled low ->success. */ +- DEB2(printk(KERN_DEBUG " i2c_outb: getsda() = 0x%2.2x\n", ~ack )); ++ DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x , getsda() = %d\n", c & 0xff, ack)); + + DEBPROTO( printk(KERN_DEBUG "[%2.2x]",c&0xff) ); + DEBPROTO(if (0==ack){ printk(KERN_DEBUG " A ");} else printk(KERN_DEBUG " NA ") ); +@@ -219,11 +203,10 @@ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + /* assert: scl is low */ +- DEB2(printk(KERN_DEBUG "i2c_inb.\n")); +- + sdahi(adap); + for (i=0;i<8;i++) { + if (sclhi(adap)<0) { /* timeout */ ++ DEB2(printk(KERN_DEBUG " i2c_inb: timeout at bit #%d\n", 7-i)); + return -ETIMEDOUT; + }; + indata *= 2; +@@ -232,6 +215,8 @@ + scllo(adap); + } + /* assert: scl is low */ ++ DEB2(printk(KERN_DEBUG "i2c_inb: 0x%02x\n", indata & 0xff)); ++ + DEBPROTO(printk(KERN_DEBUG " 0x%02x", indata & 0xff)); + return (int) (indata & 0xff); + } +@@ -242,71 +227,75 @@ + */ + static int test_bus(struct i2c_algo_bit_data *adap, char* name) { + int scl,sda; ++ ++ if (adap->getscl==NULL) ++ printk(KERN_INFO "i2c-algo-bit.o: Testing SDA only, " ++ "SCL is not readable.\n"); ++ + sda=getsda(adap); +- if (adap->getscl==NULL) { +- printk("i2c-algo-bit.o: Warning: Adapter can't read from clock line - skipping test.\n"); +- return 0; +- } +- scl=getscl(adap); +- printk("i2c-algo-bit.o: Adapter: %s scl: %d sda: %d -- testing...\n", +- name,getscl(adap),getsda(adap)); ++ scl=(adap->getscl==NULL?1:getscl(adap)); ++ printk(KERN_DEBUG "i2c-algo-bit.o: (0) scl=%d, sda=%d\n",scl,sda); + if (!scl || !sda ) { +- printk("i2c-algo-bit.o: %s seems to be busy.\n",name); ++ printk(KERN_WARNING "i2c-algo-bit.o: %s seems to be busy.\n", name); + goto bailout; + } ++ + sdalo(adap); +- printk("i2c-algo-bit.o:1 scl: %d sda: %d \n",getscl(adap), +- getsda(adap)); +- if ( 0 != getsda(adap) ) { +- printk("i2c-algo-bit.o: %s SDA stuck high!\n",name); +- sdahi(adap); ++ sda=getsda(adap); ++ scl=(adap->getscl==NULL?1:getscl(adap)); ++ printk(KERN_DEBUG "i2c-algo-bit.o: (1) scl=%d, sda=%d\n",scl,sda); ++ if ( 0 != sda ) { ++ printk(KERN_WARNING "i2c-algo-bit.o: SDA stuck high!\n"); + goto bailout; + } +- if ( 0 == getscl(adap) ) { +- printk("i2c-algo-bit.o: %s SCL unexpected low while pulling SDA low!\n", +- name); ++ if ( 0 == scl ) { ++ printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low " ++ "while pulling SDA low!\n"); + goto bailout; + } ++ + sdahi(adap); +- printk("i2c-algo-bit.o:2 scl: %d sda: %d \n",getscl(adap), +- getsda(adap)); +- if ( 0 == getsda(adap) ) { +- printk("i2c-algo-bit.o: %s SDA stuck low!\n",name); +- sdahi(adap); ++ sda=getsda(adap); ++ scl=(adap->getscl==NULL?1:getscl(adap)); ++ printk(KERN_DEBUG "i2c-algo-bit.o: (2) scl=%d, sda=%d\n",scl,sda); ++ if ( 0 == sda ) { ++ printk(KERN_WARNING "i2c-algo-bit.o: SDA stuck low!\n"); + goto bailout; + } +- if ( 0 == getscl(adap) ) { +- printk("i2c-algo-bit.o: %s SCL unexpected low while SDA high!\n", +- name); +- goto bailout; ++ if ( 0 == scl ) { ++ printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low " ++ "while pulling SDA high!\n"); ++ goto bailout; + } ++ + scllo(adap); +- printk("i2c-algo-bit.o:3 scl: %d sda: %d \n",getscl(adap), +- getsda(adap)); +- if ( 0 != getscl(adap) ) { +- printk("i2c-algo-bit.o: %s SCL stuck high!\n",name); +- sclhi(adap); ++ sda=getsda(adap); ++ scl=(adap->getscl==NULL?0:getscl(adap)); ++ printk(KERN_DEBUG "i2c-algo-bit.o: (3) scl=%d, sda=%d\n",scl,sda); ++ if ( 0 != scl ) { ++ printk(KERN_WARNING "i2c-algo-bit.o: SCL stuck high!\n"); + goto bailout; + } +- if ( 0 == getsda(adap) ) { +- printk("i2c-algo-bit.o: %s SDA unexpected low while pulling SCL low!\n", +- name); ++ if ( 0 == sda ) { ++ printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low " ++ "while pulling SCL low!\n"); + goto bailout; + } ++ + sclhi(adap); +- printk("i2c-algo-bit.o:4 scl: %d sda: %d \n",getscl(adap), +- getsda(adap)); +- if ( 0 == getscl(adap) ) { +- printk("i2c-algo-bit.o: %s SCL stuck low!\n",name); +- sclhi(adap); ++ sda=getsda(adap); ++ scl=(adap->getscl==NULL?1:getscl(adap)); ++ printk(KERN_DEBUG "i2c-algo-bit.o: (4) scl=%d, sda=%d\n",scl,sda); ++ if ( 0 == scl ) { ++ printk(KERN_WARNING "i2c-algo-bit.o: SCL stuck low!\n"); + goto bailout; + } +- if ( 0 == getsda(adap) ) { +- printk("i2c-algo-bit.o: %s SDA unexpected low while SCL high!\n", +- name); ++ if ( 0 == sda ) { ++ printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low " ++ "while pulling SCL high!\n"); + goto bailout; + } +- printk("i2c-algo-bit.o: %s passed test.\n",name); ++ printk(KERN_INFO "i2c-algo-bit.o: %s passed test.\n",name); + return 0; + bailout: + sdahi(adap); +@@ -340,16 +329,21 @@ + i2c_start(adap); + udelay(adap->udelay); + } +- DEB2(if (i) printk(KERN_DEBUG "i2c-algo-bit.o: needed %d retries for %d\n", +- i,addr)); ++ DEB2(if (i) ++ printk(KERN_DEBUG "i2c-algo-bit.o: Used %d tries to %s client at 0x%02x : %s\n", ++ i+1, addr & 1 ? "read" : "write", addr>>1, ++ ret==1 ? "success" : ret==0 ? "no ack" : "failed, timeout?" ) ++ ); + return ret; + } + +-static int sendbytes(struct i2c_adapter *i2c_adap,const char *buf, int count) ++static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) + { + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + char c; +- const char *temp = buf; ++ const char *temp = msg->buf; ++ int count = msg->len; ++ unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; + int retval; + int wrcount=0; + +@@ -358,7 +352,7 @@ + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: %s sendbytes: writing %2.2X\n", + i2c_adap->name, c&0xff)); + retval = i2c_outb(i2c_adap,c); +- if (retval>0) { ++ if ((retval>0) || (nak_ok && (retval==0))) { /* ok or ignored NAK */ + count--; + temp++; + wrcount++; +@@ -377,12 +371,18 @@ + return wrcount; + } + +-static inline int readbytes(struct i2c_adapter *i2c_adap,char *buf,int count) ++static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) + { +- char *temp = buf; + int inval; + int rdcount=0; /* counts bytes read */ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; ++ char *temp = msg->buf; ++ int count = msg->len; ++ int recv_len = 0; ++ ++ /* Receive [Count] for I2C_SMBUS_BLOCK_DATA or I2C_SMBUS_BLOCK_PROC_CALL protocol */ ++ if (msg->flags & I2C_M_RECV_LEN) ++ recv_len = 1; + + while (count > 0) { + inval = i2c_inb(i2c_adap); +@@ -395,6 +395,20 @@ + break; + } + ++ if (recv_len) { ++ recv_len = 0; ++ /* [Count] should be between 1 and 31 (I2C_SMBUS_BLOCK_MAX - 1). */ ++ if (inval > 0 && inval < I2C_SMBUS_BLOCK_MAX) { ++ count = inval + 1; /* plus one for [Count] itself */ ++ msg->len = count; ++ if (msg->flags & I2C_M_RECV_PEC) ++ count++; /* plus one for PEC */ ++ } else { ++ printk(KERN_ERR "i2c-algo-bit.o: readbytes: bad block count (%d).\n", inval); ++ break; ++ } ++ } ++ + if ( count > 1 ) { /* send ack */ + sdalo(adap); + DEBPROTO(printk(" Am ")); +@@ -419,31 +433,34 @@ + * try_address) and transmits the address in the necessary format to handle + * reads, writes as well as 10bit-addresses. + * returns: +- * 0 everything went okay, the chip ack'ed ++ * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set + * -x an error occurred (like: -EREMOTEIO if the device did not answer, or + * -ETIMEDOUT, for example if the lines are stuck...) + */ +-static inline int bit_doAddress(struct i2c_adapter *i2c_adap, +- struct i2c_msg *msg, int retries) ++static inline int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) + { + unsigned short flags = msg->flags; ++ unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + unsigned char addr; +- int ret; ++ int ret, retries; ++ ++ retries = nak_ok ? 0 : i2c_adap->retries; ++ + if ( (flags & I2C_M_TEN) ) { + /* a ten bit address */ + addr = 0xf0 | (( msg->addr >> 7) & 0x03); + DEB2(printk(KERN_DEBUG "addr0: %d\n",addr)); + /* try extended address code...*/ + ret = try_address(i2c_adap, addr, retries); +- if (ret!=1) { ++ if ((ret != 1) && !nak_ok) { + printk(KERN_ERR "died at extended address code.\n"); + return -EREMOTEIO; + } + /* the remaining 8 bit address */ + ret = i2c_outb(i2c_adap,msg->addr & 0x7f); +- if (ret != 1) { ++ if ((ret != 1) && !nak_ok) { + /* the chip did not ack / xmission error occurred */ + printk(KERN_ERR "died at 2nd address code.\n"); + return -EREMOTEIO; +@@ -453,7 +470,7 @@ + /* okay, now switch into reading mode */ + addr |= 0x01; + ret = try_address(i2c_adap, addr, retries); +- if (ret!=1) { ++ if ((ret!=1) && !nak_ok) { + printk(KERN_ERR "died at extended address code.\n"); + return -EREMOTEIO; + } +@@ -465,10 +482,10 @@ + if (flags & I2C_M_REV_DIR_ADDR ) + addr ^= 1; + ret = try_address(i2c_adap, addr, retries); +- if (ret!=1) { ++ if ((ret!=1) && !nak_ok) + return -EREMOTEIO; +- } + } ++ + return 0; + } + +@@ -479,16 +496,18 @@ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + int i,ret; ++ unsigned short nak_ok; + + i2c_start(adap); + for (i=0;iflags & I2C_M_IGNORE_NAK; + if (!(pmsg->flags & I2C_M_NOSTART)) { + if (i) { + i2c_repstart(adap); + } +- ret = bit_doAddress(i2c_adap,pmsg,i2c_adap->retries); +- if (ret != 0) { ++ ret = bit_doAddress(i2c_adap, pmsg); ++ if ((ret != 0) && !nak_ok) { + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device addr %2.2x msg #%d\n", + msgs[i].addr,i)); + return (ret<0) ? ret : -EREMOTEIO; +@@ -496,14 +515,14 @@ + } + if (pmsg->flags & I2C_M_RD ) { + /* read bytes into buffer*/ +- ret = readbytes(i2c_adap,pmsg->buf,pmsg->len); ++ ret = readbytes(i2c_adap, pmsg); + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d bytes.\n",ret)); + if (ret < pmsg->len ) { + return (ret<0)? ret : -EREMOTEIO; + } + } else { + /* write bytes from buffer */ +- ret = sendbytes(i2c_adap,pmsg->buf,pmsg->len); ++ ret = sendbytes(i2c_adap, pmsg); + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d bytes.\n",ret)); + if (ret < pmsg->len ) { + return (ret<0) ? ret : -EREMOTEIO; +@@ -514,30 +533,25 @@ + return num; + } + +-static int algo_control(struct i2c_adapter *adapter, +- unsigned int cmd, unsigned long arg) +-{ +- return 0; +-} +- +-static u32 bit_func(struct i2c_adapter *adap) ++static u32 bit_func(struct i2c_adapter *i2c_adap) + { + return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | +- I2C_FUNC_PROTOCOL_MANGLING; ++ I2C_FUNC_PROTOCOL_MANGLING | ++ I2C_FUNC_SMBUS_BLOCK_PROC_CALL | ++ I2C_FUNC_SMBUS_READ_BLOCK_DATA | ++ I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC | ++ I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC; + } + + + /* -----exported algorithm data: ------------------------------------- */ + + static struct i2c_algorithm i2c_bit_algo = { +- "Bit-shift algorithm", +- I2C_ALGO_BIT, +- bit_xfer, +- NULL, +- NULL, /* slave_xmit */ +- NULL, /* slave_recv */ +- algo_control, /* ioctl */ +- bit_func, /* functionality */ ++ .owner = THIS_MODULE, ++ .name = "Bit-shift algorithm", ++ .id = I2C_ALGO_BIT, ++ .master_xfer = bit_xfer, ++ .functionality = bit_func, + }; + + /* +@@ -545,7 +559,6 @@ + */ + int i2c_bit_add_bus(struct i2c_adapter *adap) + { +- int i; + struct i2c_algo_bit_data *bit_adap = adap->algo_data; + + if (bit_test) { +@@ -565,78 +578,26 @@ + adap->timeout = 100; /* default values, should */ + adap->retries = 3; /* be replaced by defines */ + +- /* scan bus */ +- if (bit_scan) { +- int ack; +- printk(KERN_INFO " i2c-algo-bit.o: scanning bus %s.\n", +- adap->name); +- for (i = 0x00; i < 0xff; i+=2) { +- i2c_start(bit_adap); +- ack = i2c_outb(adap,i); +- i2c_stop(bit_adap); +- if (ack>0) { +- printk("(%02x)",i>>1); +- } else +- printk("."); +- } +- printk("\n"); +- } +- +-#ifdef MODULE +- MOD_INC_USE_COUNT; +-#endif + i2c_add_adapter(adap); +- + return 0; + } + + + int i2c_bit_del_bus(struct i2c_adapter *adap) + { +- int res; +- +- if ((res = i2c_del_adapter(adap)) < 0) +- return res; +- +- DEB2(printk("i2c-algo-bit.o: adapter unregistered: %s\n",adap->name)); +- +-#ifdef MODULE +- MOD_DEC_USE_COUNT; +-#endif +- return 0; +-} +- +-int __init i2c_algo_bit_init (void) +-{ +- printk(KERN_INFO "i2c-algo-bit.o: i2c bit algorithm module\n"); +- return 0; ++ return i2c_del_adapter(adap); + } + +- +- + EXPORT_SYMBOL(i2c_bit_add_bus); + EXPORT_SYMBOL(i2c_bit_del_bus); + +-#ifdef MODULE + MODULE_AUTHOR("Simon G. Vogl "); + MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm"); + MODULE_LICENSE("GPL"); + + MODULE_PARM(bit_test, "i"); +-MODULE_PARM(bit_scan, "i"); + MODULE_PARM(i2c_debug,"i"); + + MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is stuck"); +-MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus"); + MODULE_PARM_DESC(i2c_debug, + "debug level - 0 off; 1 normal; 2,3 more verbose; 9 bit-protocol"); +- +-int init_module(void) +-{ +- return i2c_algo_bit_init(); +-} +- +-void cleanup_module(void) +-{ +-} +-#endif +--- linux-old/include/linux/i2c-algo-bit.h Sat Feb 5 06:47:38 2000 ++++ linux/include/linux/i2c-algo-bit.h Mon Dec 13 19:26:28 2004 +@@ -21,12 +21,10 @@ + /* With some changes from Kyösti Mälkki and even + Frodo Looijaard */ + +-/* $Id: i2c-algo-bit.h,v 1.7 1999/12/21 23:45:58 frodo Exp $ */ ++/* $Id: i2c-algo-bit.h,v 1.11 2003/07/25 07:56:42 khali Exp $ */ + +-#ifndef I2C_ALGO_BIT_H +-#define I2C_ALGO_BIT_H 1 +- +-#include ++#ifndef _LINUX_I2C_ALGO_BIT_H ++#define _LINUX_I2C_ALGO_BIT_H + + /* --- Defines for bit-adapters --------------------------------------- */ + /* +@@ -42,9 +40,10 @@ + int (*getscl) (void *data); + + /* local settings */ +- int udelay; +- int mdelay; +- int timeout; ++ int udelay; /* half-clock-cycle time in microsecs */ ++ /* i.e. clock is (500 / udelay) KHz */ ++ int mdelay; /* in millisecs, unused */ ++ int timeout; /* in jiffies */ + }; + + #define I2C_BIT_ADAP_MAX 16 +@@ -52,4 +51,4 @@ + int i2c_bit_add_bus(struct i2c_adapter *); + int i2c_bit_del_bus(struct i2c_adapter *); + +-#endif /* I2C_ALGO_BIT_H */ ++#endif /* _LINUX_I2C_ALGO_BIT_H */ +--- linux-old/drivers/i2c/i2c-algo-ibm_ocp.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-algo-ibm_ocp.c Mon Dec 13 19:26:29 2004 +@@ -0,0 +1,901 @@ ++/* ++ ------------------------------------------------------------------------- ++ i2c-algo-ibm_ocp.c i2c driver algorithms for IBM PPC 405 adapters ++ ------------------------------------------------------------------------- ++ ++ Ian DaSilva, MontaVista Software, Inc. ++ idasilva@mvista.com or source@mvista.com ++ ++ Copyright 2000 MontaVista Software Inc. ++ ++ Changes made to support the IIC peripheral on the IBM PPC 405 ++ ++ ++ --------------------------------------------------------------------------- ++ This file was highly leveraged from i2c-algo-pcf.c, which was created ++ by Simon G. Vogl and Hans Berglund: ++ ++ ++ Copyright (C) 1995-1997 Simon G. Vogl ++ 1998-2000 Hans Berglund ++ ++ With some changes from Kyösti Mälkki and ++ Frodo Looijaard ,and also from Martin Bailey ++ ++ ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ --------------------------------------------------------------------------- ++ ++ History: 01/20/12 - Armin ++ akuster@mvista.com ++ ported up to 2.4.16+ ++ ++ Version 02/03/25 - Armin ++ converted to ocp format ++ removed commented out or #if 0 code ++ added Gérard Basler's fix to iic_combined_transaction() such that it ++ returns the number of successfully completed transfers . ++*/ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* ----- global defines ----------------------------------------------- */ ++#define DEB(x) if (i2c_debug>=1) x ++#define DEB2(x) if (i2c_debug>=2) x ++#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/ ++#define DEBPROTO(x) if (i2c_debug>=9) x; ++ /* debug the protocol by showing transferred bits */ ++#define DEF_TIMEOUT 5 ++ ++ ++/* ----- global variables --------------------------------------------- */ ++ ++ ++/* module parameters: ++ */ ++static int i2c_debug=0; ++ ++/* --- setting states on the bus with the right timing: --------------- */ ++ ++#define iic_outb(adap, reg, val) adap->setiic(adap->data, (int) &(reg), val) ++#define iic_inb(adap, reg) adap->getiic(adap->data, (int) &(reg)) ++ ++#define IICO_I2C_SDAHIGH 0x0780 ++#define IICO_I2C_SDALOW 0x0781 ++#define IICO_I2C_SCLHIGH 0x0782 ++#define IICO_I2C_SCLLOW 0x0783 ++#define IICO_I2C_LINEREAD 0x0784 ++ ++#define IIC_SINGLE_XFER 0 ++#define IIC_COMBINED_XFER 1 ++ ++#define IIC_ERR_LOST_ARB -2 ++#define IIC_ERR_INCOMPLETE_XFR -3 ++#define IIC_ERR_NACK -1 ++ ++/* --- other auxiliary functions -------------------------------------- */ ++ ++ ++// ++// Description: Puts this process to sleep for a period equal to timeout ++// ++static inline void iic_sleep(unsigned long timeout) ++{ ++ schedule_timeout( timeout * HZ); ++} ++ ++ ++// ++// Description: This performs the IBM PPC 405 IIC initialization sequence ++// as described in the PPC405GP data book. ++// ++static int iic_init (struct i2c_algo_iic_data *adap) ++{ ++ struct iic_regs *iic; ++ struct iic_ibm *adap_priv_data = adap->data; ++ unsigned short retval; ++ iic = (struct iic_regs *) adap_priv_data->iic_base; ++ ++ /* Clear master low master address */ ++ iic_outb(adap,iic->lmadr, 0); ++ ++ /* Clear high master address */ ++ iic_outb(adap,iic->hmadr, 0); ++ ++ /* Clear low slave address */ ++ iic_outb(adap,iic->lsadr, 0); ++ ++ /* Clear high slave address */ ++ iic_outb(adap,iic->hsadr, 0); ++ ++ /* Clear status */ ++ iic_outb(adap,iic->sts, 0x0a); ++ ++ /* Clear extended status */ ++ iic_outb(adap,iic->extsts, 0x8f); ++ ++ /* Set clock division */ ++ iic_outb(adap,iic->clkdiv, 0x04); ++ ++ retval = iic_inb(adap, iic->clkdiv); ++ DEB(printk("iic_init: CLKDIV register = %x\n", retval)); ++ ++ /* Enable interrupts on Requested Master Transfer Complete */ ++ iic_outb(adap,iic->intmsk, 0x01); ++ ++ /* Clear transfer count */ ++ iic_outb(adap,iic->xfrcnt, 0x0); ++ ++ /* Clear extended control and status */ ++ iic_outb(adap,iic->xtcntlss, 0xf0); ++ ++ /* Set mode control (flush master data buf, enable hold SCL, exit */ ++ /* unknown state. */ ++ iic_outb(adap,iic->mdcntl, 0x47); ++ ++ /* Clear control register */ ++ iic_outb(adap,iic->cntl, 0x0); ++ ++ DEB2(printk(KERN_DEBUG "iic_init: Initialized IIC on PPC 405\n")); ++ return 0; ++} ++ ++ ++// ++// Description: After we issue a transaction on the IIC bus, this function ++// is called. It puts this process to sleep until we get an interrupt from ++// from the controller telling us that the transaction we requested in complete. ++// ++static int wait_for_pin(struct i2c_algo_iic_data *adap, int *status) ++{ ++ ++ int timeout = DEF_TIMEOUT; ++ int retval; ++ struct iic_regs *iic; ++ struct iic_ibm *adap_priv_data = adap->data; ++ iic = (struct iic_regs *) adap_priv_data->iic_base; ++ ++ ++ *status = iic_inb(adap, iic->sts); ++#ifndef STUB_I2C ++ ++ while (timeout-- && (*status & 0x01)) { ++ adap->waitforpin(adap->data); ++ *status = iic_inb(adap, iic->sts); ++ } ++#endif ++ if (timeout <= 0) { ++ /* Issue stop signal on the bus, and force an interrupt */ ++ retval = iic_inb(adap, iic->cntl); ++ iic_outb(adap, iic->cntl, retval | 0x80); ++ /* Clear status register */ ++ iic_outb(adap, iic->sts, 0x0a); ++ /* Exit unknown bus state */ ++ retval = iic_inb(adap, iic->mdcntl); ++ iic_outb(adap, iic->mdcntl, (retval | 0x02)); ++ ++ // Check the status of the controller. Does it still see a ++ // pending transfer, even though we've tried to stop any ++ // ongoing transaction? ++ retval = iic_inb(adap, iic->sts); ++ retval = retval & 0x01; ++ if(retval) { ++ // The iic controller is hosed. It is not responding to any ++ // of our commands. We have already tried to force it into ++ // a known state, but it has not worked. Our only choice now ++ // is a soft reset, which will clear all registers, and force ++ // us to re-initialize the controller. ++ /* Soft reset */ ++ iic_outb(adap, iic->xtcntlss, 0x01); ++ udelay(500); ++ iic_init(adap); ++ /* Is the pending transfer bit in the sts reg finally cleared? */ ++ retval = iic_inb(adap, iic->sts); ++ retval = retval & 0x01; ++ if(retval) { ++ printk(KERN_CRIT "The IIC Controller is hosed. A processor reset is required\n"); ++ } ++ // For some reason, even though the interrupt bit in this ++ // register was set during iic_init, it didn't take. We ++ // need to set it again. Don't ask me why....this is just what ++ // I saw when testing timeouts. ++ iic_outb(adap, iic->intmsk, 0x01); ++ } ++ return(-1); ++ } ++ else ++ return(0); ++} ++ ++ ++//------------------------------------ ++// Utility functions ++// ++ ++ ++// ++// Description: Look at the status register to see if there was an error ++// in the requested transaction. If there is, look at the extended status ++// register and determine the exact cause. ++// ++int analyze_status(struct i2c_algo_iic_data *adap, int *error_code) ++{ ++ int ret; ++ struct iic_regs *iic; ++ struct iic_ibm *adap_priv_data = adap->data; ++ iic = (struct iic_regs *) adap_priv_data->iic_base; ++ ++ ++ ret = iic_inb(adap, iic->sts); ++ if(ret & 0x04) { ++ // Error occurred ++ ret = iic_inb(adap, iic->extsts); ++ if(ret & 0x04) { ++ // Lost arbitration ++ *error_code = IIC_ERR_LOST_ARB; ++ } ++ if(ret & 0x02) { ++ // Incomplete transfer ++ *error_code = IIC_ERR_INCOMPLETE_XFR; ++ } ++ if(ret & 0x01) { ++ // Master transfer aborted by a NACK during the transfer of the ++ // address byte ++ *error_code = IIC_ERR_NACK; ++ } ++ return -1; ++ } ++ return 0; ++} ++ ++ ++// ++// Description: This function is called by the upper layers to do the ++// grunt work for a master send transaction ++// ++static int iic_sendbytes(struct i2c_adapter *i2c_adap,const char *buf, ++ int count, int xfer_flag) ++{ ++ struct iic_regs *iic; ++ struct i2c_algo_iic_data *adap = i2c_adap->algo_data; ++ struct iic_ibm *adap_priv_data = adap->data; ++ int wrcount, status, timeout; ++ int loops, remainder, i, j; ++ int ret, error_code; ++ iic = (struct iic_regs *) adap_priv_data->iic_base; ++ ++ ++ if( count == 0 ) return 0; ++ wrcount = 0; ++ loops = count / 4; ++ remainder = count % 4; ++ ++ if((loops > 1) && (remainder == 0)) { ++ for(i=0; i<(loops-1); i++) { ++ // ++ // Write four bytes to master data buffer ++ // ++ for(j=0; j<4; j++) { ++ iic_outb(adap, iic->mdbuf, ++ buf[wrcount++]); ++ } ++ // ++ // Issue command to IICO device to begin transmission ++ // ++ iic_outb(adap, iic->cntl, 0x35); ++ // ++ // Wait for transmission to complete. When it does, ++ //loop to the top of the for statement and write the ++ // next four bytes. ++ // ++ timeout = wait_for_pin(adap, &status); ++ if(timeout < 0) { ++ // ++ // Error handling ++ // ++ //printk(KERN_ERR "Error: write timeout\n"); ++ return wrcount; ++ } ++ ret = analyze_status(adap, &error_code); ++ if(ret < 0) { ++ if(error_code == IIC_ERR_INCOMPLETE_XFR) { ++ // Return the number of bytes transferred ++ ret = iic_inb(adap, iic->xfrcnt); ++ ret = ret & 0x07; ++ return (wrcount-4+ret); ++ } ++ else return error_code; ++ } ++ } ++ } ++ else if((loops >= 1) && (remainder > 0)){ ++ //printk(KERN_DEBUG "iic_sendbytes: (loops >= 1)\n"); ++ for(i=0; imdbuf, ++ buf[wrcount++]); ++ } ++ // ++ // Issue command to IICO device to begin transmission ++ // ++ iic_outb(adap, iic->cntl, 0x35); ++ // ++ // Wait for transmission to complete. When it does, ++ //loop to the top of the for statement and write the ++ // next four bytes. ++ // ++ timeout = wait_for_pin(adap, &status); ++ if(timeout < 0) { ++ // ++ // Error handling ++ // ++ //printk(KERN_ERR "Error: write timeout\n"); ++ return wrcount; ++ } ++ ret = analyze_status(adap, &error_code); ++ if(ret < 0) { ++ if(error_code == IIC_ERR_INCOMPLETE_XFR) { ++ // Return the number of bytes transferred ++ ret = iic_inb(adap, iic->xfrcnt); ++ ret = ret & 0x07; ++ return (wrcount-4+ret); ++ } ++ else return error_code; ++ } ++ } ++ } ++ ++ //printk(KERN_DEBUG "iic_sendbytes: expedite write\n"); ++ if(remainder == 0) remainder = 4; ++ // remainder = remainder - 1; ++ // ++ // Write the remaining bytes (less than or equal to 4) ++ // ++ for(i=0; imdbuf, buf[wrcount++]); ++ //printk(KERN_DEBUG "iic_sendbytes: data transferred = %x, wrcount = %d\n", buf[wrcount-1], (wrcount-1)); ++ } ++ //printk(KERN_DEBUG "iic_sendbytes: Issuing write\n"); ++ ++ if(xfer_flag == IIC_COMBINED_XFER) { ++ iic_outb(adap, iic->cntl, (0x09 | ((remainder-1) << 4))); ++ } ++ else { ++ iic_outb(adap, iic->cntl, (0x01 | ((remainder-1) << 4))); ++ } ++ DEB2(printk(KERN_DEBUG "iic_sendbytes: Waiting for interrupt\n")); ++ timeout = wait_for_pin(adap, &status); ++ if(timeout < 0) { ++ // ++ // Error handling ++ // ++ //printk(KERN_ERR "Error: write timeout\n"); ++ return wrcount; ++ } ++ ret = analyze_status(adap, &error_code); ++ if(ret < 0) { ++ if(error_code == IIC_ERR_INCOMPLETE_XFR) { ++ // Return the number of bytes transferred ++ ret = iic_inb(adap, iic->xfrcnt); ++ ret = ret & 0x07; ++ return (wrcount-4+ret); ++ } ++ else return error_code; ++ } ++ DEB2(printk(KERN_DEBUG "iic_sendbytes: Got interrupt\n")); ++ return wrcount; ++} ++ ++ ++// ++// Description: Called by the upper layers to do the grunt work for ++// a master read transaction. ++// ++static int iic_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count, int xfer_type) ++{ ++ struct iic_regs *iic; ++ int rdcount=0, i, status, timeout; ++ struct i2c_algo_iic_data *adap = i2c_adap->algo_data; ++ struct iic_ibm *adap_priv_data = adap->data; ++ int loops, remainder, j; ++ int ret, error_code; ++ iic = (struct iic_regs *) adap_priv_data->iic_base; ++ ++ if(count == 0) return 0; ++ loops = count / 4; ++ remainder = count % 4; ++ ++ //printk(KERN_DEBUG "iic_readbytes: loops = %d, remainder = %d\n", loops, remainder); ++ ++ if((loops > 1) && (remainder == 0)) { ++ //printk(KERN_DEBUG "iic_readbytes: (loops > 1) && (remainder == 0)\n"); ++ for(i=0; i<(loops-1); i++) { ++ // ++ // Issue command to begin master read (4 bytes maximum) ++ // ++ //printk(KERN_DEBUG "--->Issued read command\n"); ++ iic_outb(adap, iic->cntl, 0x37); ++ // ++ // Wait for transmission to complete. When it does, ++ // loop to the top of the for statement and write the ++ // next four bytes. ++ // ++ //printk(KERN_DEBUG "--->Waiting for interrupt\n"); ++ timeout = wait_for_pin(adap, &status); ++ if(timeout < 0) { ++ // Error Handler ++ //printk(KERN_ERR "Error: read timed out\n"); ++ return rdcount; ++ } ++ //printk(KERN_DEBUG "--->Got interrupt\n"); ++ ++ ret = analyze_status(adap, &error_code); ++ if(ret < 0) { ++ if(error_code == IIC_ERR_INCOMPLETE_XFR) ++ return rdcount; ++ else ++ return error_code; ++ } ++ ++ for(j=0; j<4; j++) { ++ // Wait for data to shuffle to top of data buffer ++ // This value needs to optimized. ++ udelay(1); ++ buf[rdcount] = iic_inb(adap, iic->mdbuf); ++ rdcount++; ++ //printk(KERN_DEBUG "--->Read one byte\n"); ++ } ++ } ++ } ++ ++ else if((loops >= 1) && (remainder > 0)){ ++ //printk(KERN_DEBUG "iic_readbytes: (loops >=1) && (remainder > 0)\n"); ++ for(i=0; iIssued read command\n"); ++ iic_outb(adap, iic->cntl, 0x37); ++ // ++ // Wait for transmission to complete. When it does, ++ // loop to the top of the for statement and write the ++ // next four bytes. ++ // ++ //printk(KERN_DEBUG "--->Waiting for interrupt\n"); ++ timeout = wait_for_pin(adap, &status); ++ if(timeout < 0) { ++ // Error Handler ++ //printk(KERN_ERR "Error: read timed out\n"); ++ return rdcount; ++ } ++ //printk(KERN_DEBUG "--->Got interrupt\n"); ++ ++ ret = analyze_status(adap, &error_code); ++ if(ret < 0) { ++ if(error_code == IIC_ERR_INCOMPLETE_XFR) ++ return rdcount; ++ else ++ return error_code; ++ } ++ ++ for(j=0; j<4; j++) { ++ // Wait for data to shuffle to top of data buffer ++ // This value needs to optimized. ++ udelay(1); ++ buf[rdcount] = iic_inb(adap, iic->mdbuf); ++ rdcount++; ++ //printk(KERN_DEBUG "--->Read one byte\n"); ++ } ++ } ++ } ++ ++ //printk(KERN_DEBUG "iic_readbytes: expedite read\n"); ++ if(remainder == 0) remainder = 4; ++ DEB2(printk(KERN_DEBUG "iic_readbytes: writing %x to IICO_CNTL\n", (0x03 | ((remainder-1) << 4)))); ++ ++ if(xfer_type == IIC_COMBINED_XFER) { ++ iic_outb(adap, iic->cntl, (0x0b | ((remainder-1) << 4))); ++ } ++ else { ++ iic_outb(adap, iic->cntl, (0x03 | ((remainder-1) << 4))); ++ } ++ DEB2(printk(KERN_DEBUG "iic_readbytes: Wait for pin\n")); ++ timeout = wait_for_pin(adap, &status); ++ DEB2(printk(KERN_DEBUG "iic_readbytes: Got the interrupt\n")); ++ if(timeout < 0) { ++ // Error Handler ++ //printk(KERN_ERR "Error: read timed out\n"); ++ return rdcount; ++ } ++ ++ ret = analyze_status(adap, &error_code); ++ if(ret < 0) { ++ if(error_code == IIC_ERR_INCOMPLETE_XFR) ++ return rdcount; ++ else ++ return error_code; ++ } ++ ++ //printk(KERN_DEBUG "iic_readbyte: Begin reading data buffer\n"); ++ for(i=0; imdbuf); ++ // printk(KERN_DEBUG "iic_readbytes: Character read = %x\n", buf[rdcount]); ++ rdcount++; ++ } ++ ++ return rdcount; ++} ++ ++ ++// ++// Description: This function implements combined transactions. Combined ++// transactions consist of combinations of reading and writing blocks of data. ++// Each transfer (i.e. a read or a write) is separated by a repeated start ++// condition. ++// ++static int iic_combined_transaction(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) ++{ ++ int i; ++ struct i2c_msg *pmsg; ++ int ret; ++ ++ DEB2(printk(KERN_DEBUG "Beginning combined transaction\n")); ++ for(i=0; i < num; i++) { ++ pmsg = &msgs[i]; ++ if(pmsg->flags & I2C_M_RD) { ++ ++ // Last read or write segment needs to be terminated with a stop ++ if(i < num-1) { ++ DEB2(printk(KERN_DEBUG "This one is a read\n")); ++ } ++ else { ++ DEB2(printk(KERN_DEBUG "Doing the last read\n")); ++ } ++ ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, (i < num-1) ? IIC_COMBINED_XFER : IIC_SINGLE_XFER); ++ ++ if (ret != pmsg->len) { ++ DEB2(printk("i2c-algo-ppc405.o: fail: " ++ "only read %d bytes.\n",ret)); ++ return i; ++ } ++ else { ++ DEB2(printk("i2c-algo-ppc405.o: read %d bytes.\n",ret)); ++ } ++ } ++ else if(!(pmsg->flags & I2C_M_RD)) { ++ ++ // Last read or write segment needs to be terminated with a stop ++ if(i < num-1) { ++ DEB2(printk(KERN_DEBUG "This one is a write\n")); ++ } ++ else { ++ DEB2(printk(KERN_DEBUG "Doing the last write\n")); ++ } ++ ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, (i < num-1) ? IIC_COMBINED_XFER : IIC_SINGLE_XFER); ++ ++ if (ret != pmsg->len) { ++ DEB2(printk("i2c-algo-ppc405.o: fail: " ++ "only wrote %d bytes.\n",ret)); ++ return i; ++ } ++ else { ++ DEB2(printk("i2c-algo-ppc405.o: wrote %d bytes.\n",ret)); ++ } ++ } ++ } ++ ++ return num; ++} ++ ++ ++// ++// Description: Whenever we initiate a transaction, the first byte clocked ++// onto the bus after the start condition is the address (7 bit) of the ++// device we want to talk to. This function manipulates the address specified ++// so that it makes sense to the hardware when written to the IIC peripheral. ++// ++// Note: 10 bit addresses are not supported in this driver, although they are ++// supported by the hardware. This functionality needs to be implemented. ++// ++static inline int iic_doAddress(struct i2c_algo_iic_data *adap, ++ struct i2c_msg *msg, int retries) ++{ ++ struct iic_regs *iic; ++ unsigned short flags = msg->flags; ++ unsigned char addr; ++ struct iic_ibm *adap_priv_data = adap->data; ++ iic = (struct iic_regs *) adap_priv_data->iic_base; ++ ++// ++// The following segment for 10 bit addresses needs to be ported ++// ++/* Ten bit addresses not supported right now ++ if ( (flags & I2C_M_TEN) ) { ++ // a ten bit address ++ addr = 0xf0 | (( msg->addr >> 7) & 0x03); ++ DEB2(printk(KERN_DEBUG "addr0: %d\n",addr)); ++ // try extended address code... ++ ret = try_address(adap, addr, retries); ++ if (ret!=1) { ++ printk(KERN_ERR "iic_doAddress: died at extended address code.\n"); ++ return -EREMOTEIO; ++ } ++ // the remaining 8 bit address ++ iic_outb(adap,msg->addr & 0x7f); ++ // Status check comes here ++ if (ret != 1) { ++ printk(KERN_ERR "iic_doAddress: died at 2nd address code.\n"); ++ return -EREMOTEIO; ++ } ++ if ( flags & I2C_M_RD ) { ++ i2c_repstart(adap); ++ // okay, now switch into reading mode ++ addr |= 0x01; ++ ret = try_address(adap, addr, retries); ++ if (ret!=1) { ++ printk(KERN_ERR "iic_doAddress: died at extended address code.\n"); ++ return -EREMOTEIO; ++ } ++ } ++ } else ----------> // normal 7 bit address ++ ++Ten bit addresses not supported yet */ ++ ++ addr = ( msg->addr << 1 ); ++ if (flags & I2C_M_RD ) ++ addr |= 1; ++ if (flags & I2C_M_REV_DIR_ADDR ) ++ addr ^= 1; ++ // ++ // Write to the low slave address ++ // ++ iic_outb(adap, iic->lmadr, addr); ++ // ++ // Write zero to the high slave register since we are ++ // only using 7 bit addresses ++ // ++ iic_outb(adap, iic->hmadr, 0); ++ ++ return 0; ++} ++ ++ ++// ++// Description: Prepares the controller for a transaction (clearing status ++// registers, data buffers, etc), and then calls either iic_readbytes or ++// iic_sendbytes to do the actual transaction. ++// ++static int iic_xfer(struct i2c_adapter *i2c_adap, ++ struct i2c_msg msgs[], ++ int num) ++{ ++ struct iic_regs *iic; ++ struct i2c_algo_iic_data *adap = i2c_adap->algo_data; ++ struct iic_ibm *adap_priv_data = adap->data; ++ struct i2c_msg *pmsg; ++ int i = 0; ++ int ret; ++ iic = (struct iic_regs *) adap_priv_data->iic_base; ++ ++ pmsg = &msgs[i]; ++ ++ // ++ // Clear status register ++ // ++ DEB2(printk(KERN_DEBUG "iic_xfer: iic_xfer: Clearing status register\n")); ++ iic_outb(adap, iic->sts, 0x0a); ++ ++ // ++ // Wait for any pending transfers to complete ++ // ++ DEB2(printk(KERN_DEBUG "iic_xfer: Waiting for any pending transfers to complete\n")); ++ while((ret = iic_inb(adap, iic->sts)) == 0x01) { ++ ; ++ } ++ ++ // ++ // Flush master data buf ++ // ++ DEB2(printk(KERN_DEBUG "iic_xfer: Clearing master data buffer\n")); ++ ret = iic_inb(adap, iic->mdcntl); ++ iic_outb(adap, iic->mdcntl, ret | 0x40); ++ ++ // ++ // Load slave address ++ // ++ DEB2(printk(KERN_DEBUG "iic_xfer: Loading slave address\n")); ++ ret = iic_doAddress(adap, pmsg, i2c_adap->retries); ++ ++ // ++ // Check to see if the bus is busy ++ // ++ ret = iic_inb(adap, iic->extsts); ++ // Mask off the irrelevent bits ++ ret = ret & 0x70; ++ // When the bus is free, the BCS bits in the EXTSTS register are 0b100 ++ if(ret != 0x40) return IIC_ERR_LOST_ARB; ++ ++ // ++ // Combined transaction (read and write) ++ // ++ if(num > 1) { ++ DEB2(printk(KERN_DEBUG "iic_xfer: Call combined transaction\n")); ++ ret = iic_combined_transaction(i2c_adap, msgs, num); ++ } ++ // ++ // Read only ++ // ++ else if((num == 1) && (pmsg->flags & I2C_M_RD)) { ++ // ++ // Tell device to begin reading data from the master data ++ // ++ DEB2(printk(KERN_DEBUG "iic_xfer: Call adapter's read\n")); ++ ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER); ++ } ++ // ++ // Write only ++ // ++ else if((num == 1 ) && (!(pmsg->flags & I2C_M_RD))) { ++ // ++ // Write data to master data buffers and tell our device ++ // to begin transmitting ++ // ++ DEB2(printk(KERN_DEBUG "iic_xfer: Call adapter's write\n")); ++ ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER); ++ } ++ ++ return ret; ++} ++ ++ ++// ++// Description: Implements device specific ioctls. Higher level ioctls can ++// be found in i2c-core.c and are typical of any i2c controller (specifying ++// slave address, timeouts, etc). These ioctls take advantage of any hardware ++// features built into the controller for which this algorithm-adapter set ++// was written. These ioctls allow you to take control of the data and clock ++// lines on the IBM PPC 405 IIC controller and set the either high or low, ++// similar to a GPIO pin. ++// ++static int algo_control(struct i2c_adapter *adapter, ++ unsigned int cmd, unsigned long arg) ++{ ++ struct iic_regs *iic; ++ struct i2c_algo_iic_data *adap = adapter->algo_data; ++ struct iic_ibm *adap_priv_data = adap->data; ++ int ret=0; ++ int lines; ++ iic = (struct iic_regs *) adap_priv_data->iic_base; ++ ++ lines = iic_inb(adap, iic->directcntl); ++ ++ if (cmd == IICO_I2C_SDAHIGH) { ++ lines = lines & 0x01; ++ if( lines ) lines = 0x04; ++ else lines = 0; ++ iic_outb(adap, iic->directcntl,(0x08|lines)); ++ } ++ else if (cmd == IICO_I2C_SDALOW) { ++ lines = lines & 0x01; ++ if( lines ) lines = 0x04; ++ else lines = 0; ++ iic_outb(adap, iic->directcntl,(0x00|lines)); ++ } ++ else if (cmd == IICO_I2C_SCLHIGH) { ++ lines = lines & 0x02; ++ if( lines ) lines = 0x08; ++ else lines = 0; ++ iic_outb(adap, iic->directcntl,(0x04|lines)); ++ } ++ else if (cmd == IICO_I2C_SCLLOW) { ++ lines = lines & 0x02; ++ if( lines ) lines = 0x08; ++ else lines = 0; ++ iic_outb(adap, iic->directcntl,(0x00|lines)); ++ } ++ else if (cmd == IICO_I2C_LINEREAD) { ++ ret = lines; ++ } ++ return ret; ++} ++ ++ ++static u32 iic_func(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | ++ I2C_FUNC_PROTOCOL_MANGLING; ++} ++ ++ ++/* -----exported algorithm data: ------------------------------------- */ ++ ++static struct i2c_algorithm iic_algo = { ++ .owner = THIS_MODULE, ++ .name = "IBM on-chip IIC algorithm", ++ .id = I2C_ALGO_OCP, ++ .master_xfer = iic_xfer, ++ .algo_control = algo_control, ++ .functionality = iic_func, ++}; ++ ++/* ++ * registering functions to load algorithms at runtime ++ */ ++ ++ ++// ++// Description: Register bus structure ++// ++int i2c_ocp_add_bus(struct i2c_adapter *adap) ++{ ++ struct i2c_algo_iic_data *iic_adap = adap->algo_data; ++ ++ DEB2(printk(KERN_DEBUG "i2c-algo-iic.o: hw routines for %s registered.\n", ++ adap->name)); ++ ++ /* register new adapter to i2c module... */ ++ ++ adap->id |= iic_algo.id; ++ adap->algo = &iic_algo; ++ ++ adap->timeout = 100; /* default values, should */ ++ adap->retries = 3; /* be replaced by defines */ ++ ++ iic_init(iic_adap); ++ i2c_add_adapter(adap); ++ return 0; ++} ++ ++ ++// ++// Done ++// ++int i2c_ocp_del_bus(struct i2c_adapter *adap) ++{ ++ return i2c_del_adapter(adap); ++} ++ ++ ++EXPORT_SYMBOL(i2c_ocp_add_bus); ++EXPORT_SYMBOL(i2c_ocp_del_bus); ++ ++// ++// The MODULE_* macros resolve to nothing if MODULES is not defined ++// when this file is compiled. ++// ++MODULE_AUTHOR("MontaVista Software "); ++MODULE_DESCRIPTION("PPC 405 iic algorithm"); ++MODULE_LICENSE("GPL"); ++ ++MODULE_PARM(i2c_debug,"i"); ++ ++MODULE_PARM_DESC(i2c_debug, ++ "debug level - 0 off; 1 normal; 2,3 more verbose; 9 iic-protocol"); ++ +--- linux-old/include/linux/i2c-algo-ibm_ocp.h Thu Jan 1 00:00:00 1970 ++++ linux/include/linux/i2c-algo-ibm_ocp.h Mon Dec 13 19:26:29 2004 +@@ -0,0 +1,52 @@ ++/* ------------------------------------------------------------------------- */ ++/* i2c-algo-ibm_ocp.h i2c driver algorithms for IBM PPC 405 IIC adapters */ ++/* ------------------------------------------------------------------------- */ ++/* Copyright (C) 1995-97 Simon G. Vogl ++ 1998-99 Hans Berglund ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ ++/* ------------------------------------------------------------------------- */ ++ ++/* With some changes from Kyösti Mälkki and even ++ Frodo Looijaard */ ++ ++/* Modifications by MontaVista Software, August 2000 ++ Changes made to support the IIC peripheral on the IBM PPC 405 */ ++ ++#ifndef _LINUX_I2C_ALGO_IBM_OCP_H ++#define _LINUX_I2C_ALGO_IBM_OCP_H ++ ++struct i2c_algo_iic_data { ++ struct iic_regs *data; /* private data for lolevel routines */ ++ void (*setiic) (void *data, int ctl, int val); ++ int (*getiic) (void *data, int ctl); ++ int (*getown) (void *data); ++ int (*getclock) (void *data); ++ void (*waitforpin) (void *data); ++ ++ /* local settings */ ++ int udelay; ++ int mdelay; ++ int timeout; ++}; ++ ++ ++#define I2C_IIC_ADAP_MAX 16 ++ ++ ++int i2c_ocp_add_bus(struct i2c_adapter *); ++int i2c_ocp_del_bus(struct i2c_adapter *); ++ ++#endif /* _LINUX_I2C_ALGO_IBM_OCP_H */ +--- linux-old/drivers/i2c/i2c-algo-pcf.c Tue Jan 20 15:10:31 2004 ++++ linux/drivers/i2c/i2c-algo-pcf.c Mon Dec 13 19:26:29 2004 +@@ -32,14 +32,11 @@ + #include + #include + #include +-#include +-#include + #include + #include +- + #include + #include +-#include "i2c-pcf8584.h" ++ + + /* ----- global defines ----------------------------------------------- */ + #define DEB(x) if (i2c_debug>=1) x +@@ -52,7 +49,6 @@ + /* module parameters: + */ + static int i2c_debug=0; +-static int pcf_scan=0; /* have a look at what's hanging 'round */ + + /* --- setting states on the bus with the right timing: --------------- */ + +@@ -149,8 +145,7 @@ + set_pcf(adap, 1, I2C_PCF_PIN); + /* check to see S1 now used as R/W ctrl - + PCF8584 does that when ESO is zero */ +- /* PCF also resets PIN bit */ +- if ((temp = get_pcf(adap, 1)) != (0)) { ++ if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) { + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); + return -ENXIO; /* definetly not PCF8584 */ + } +@@ -166,7 +161,7 @@ + /* S1=0xA0, next byte in S2 */ + set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1); + /* check to see S2 now selected */ +- if ((temp = get_pcf(adap, 1)) != I2C_PCF_ES1) { ++ if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) { + DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp)); + return -ENXIO; + } +@@ -427,12 +422,6 @@ + return (i); + } + +-static int algo_control(struct i2c_adapter *adapter, +- unsigned int cmd, unsigned long arg) +-{ +- return 0; +-} +- + static u32 pcf_func(struct i2c_adapter *adap) + { + return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | +@@ -442,14 +431,11 @@ + /* -----exported algorithm data: ------------------------------------- */ + + static struct i2c_algorithm pcf_algo = { +- "PCF8584 algorithm", +- I2C_ALGO_PCF, +- pcf_xfer, +- NULL, +- NULL, /* slave_xmit */ +- NULL, /* slave_recv */ +- algo_control, /* ioctl */ +- pcf_func, /* functionality */ ++ .owner = THIS_MODULE, ++ .name = "PCF8584 algorithm", ++ .id = I2C_ALGO_PCF, ++ .master_xfer = pcf_xfer, ++ .functionality = pcf_func, + }; + + /* +@@ -457,7 +443,7 @@ + */ + int i2c_pcf_add_bus(struct i2c_adapter *adap) + { +- int i, status; ++ int i; + struct i2c_algo_pcf_data *pcf_adap = adap->algo_data; + + DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: hw routines for %s registered.\n", +@@ -475,81 +461,23 @@ + return i; + } + +-#ifdef MODULE +- MOD_INC_USE_COUNT; +-#endif +- + i2c_add_adapter(adap); +- +- /* scan bus */ +- if (pcf_scan) { +- printk(KERN_INFO " i2c-algo-pcf.o: scanning bus %s.\n", +- adap->name); +- for (i = 0x00; i < 0xff; i+=2) { +- if (wait_for_bb(pcf_adap)) { +- printk(KERN_INFO " i2c-algo-pcf.o: scanning bus %s - TIMEOUTed.\n", +- adap->name); +- break; +- } +- i2c_outb(pcf_adap, i); +- i2c_start(pcf_adap); +- if ((wait_for_pin(pcf_adap, &status) >= 0) && +- ((status & I2C_PCF_LRB) == 0)) { +- printk("(%02x)",i>>1); +- } else { +- printk("."); +- } +- i2c_stop(pcf_adap); +- udelay(pcf_adap->udelay); +- } +- printk("\n"); +- } + return 0; + } + + + int i2c_pcf_del_bus(struct i2c_adapter *adap) + { +- int res; +- if ((res = i2c_del_adapter(adap)) < 0) +- return res; +- DEB2(printk("i2c-algo-pcf.o: adapter unregistered: %s\n",adap->name)); +- +-#ifdef MODULE +- MOD_DEC_USE_COUNT; +-#endif +- return 0; +-} +- +-int __init i2c_algo_pcf_init (void) +-{ +- printk("i2c-algo-pcf.o: i2c pcf8584 algorithm module\n"); +- return 0; ++ return i2c_del_adapter(adap); + } + +- + EXPORT_SYMBOL(i2c_pcf_add_bus); + EXPORT_SYMBOL(i2c_pcf_del_bus); + +-#ifdef MODULE + MODULE_AUTHOR("Hans Berglund "); + MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm"); + MODULE_LICENSE("GPL"); + +-MODULE_PARM(pcf_scan, "i"); + MODULE_PARM(i2c_debug,"i"); +- +-MODULE_PARM_DESC(pcf_scan, "Scan for active chips on the bus"); + MODULE_PARM_DESC(i2c_debug, + "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol"); +- +- +-int init_module(void) +-{ +- return i2c_algo_pcf_init(); +-} +- +-void cleanup_module(void) +-{ +-} +-#endif +--- linux-old/include/linux/i2c-algo-pcf.h Thu Mar 23 02:26:01 2000 ++++ linux/include/linux/i2c-algo-pcf.h Mon Dec 13 19:26:30 2004 +@@ -22,13 +22,12 @@ + /* With some changes from Kyösti Mälkki and even + Frodo Looijaard */ + +-/* $Id: i2c-algo-pcf.h,v 1.7 2000/02/27 23:02:45 frodo Exp $ */ ++/* $Id: i2c-algo-pcf.h,v 1.9 2003/07/25 07:56:42 khali Exp $ */ + +-#ifndef I2C_ALGO_PCF_H +-#define I2C_ALGO_PCF_H 1 ++#ifndef _LINUX_I2C_ALGO_PCF_H ++#define _LINUX_I2C_ALGO_PCF_H + +-/* --- Defines for pcf-adapters --------------------------------------- */ +-#include ++#include + + struct i2c_algo_pcf_data { + void *data; /* private data for lolevel routines */ +@@ -49,4 +48,4 @@ + int i2c_pcf_add_bus(struct i2c_adapter *); + int i2c_pcf_del_bus(struct i2c_adapter *); + +-#endif /* I2C_ALGO_PCF_H */ ++#endif /* _LINUX_I2C_ALGO_PCF_H */ +--- linux-old/drivers/i2c/i2c-core.c Wed Jul 7 00:38:02 2004 ++++ linux/drivers/i2c/i2c-core.c Mon Dec 13 19:26:31 2004 +@@ -18,56 +18,33 @@ + /* ------------------------------------------------------------------------- */ + + /* With some changes from Kyösti Mälkki . +- All SMBus-related things are written by Frodo Looijaard */ ++ All SMBus-related things are written by Frodo Looijaard ++ SMBus 2.0 support by Mark Studebaker */ + +-/* $Id: i2c-core.c,v 1.64 2001/08/13 01:35:56 mds Exp $ */ ++/* i2c-core.c,v 1.91.2.2 2003/01/21 10:00:19 kmalkki Exp */ + + #include + #include + #include + #include + #include +-#include +- +-#include +- +-/* ----- compatibility stuff ----------------------------------------------- */ +- + #include +- ++#include + #include + + /* ----- global defines ---------------------------------------------------- */ + +-/* exclusive access to the bus */ +-#define I2C_LOCK(adap) down(&adap->lock) +-#define I2C_UNLOCK(adap) up(&adap->lock) +- +-#define ADAP_LOCK() down(&adap_lock) +-#define ADAP_UNLOCK() up(&adap_lock) +- +-#define DRV_LOCK() down(&driver_lock) +-#define DRV_UNLOCK() up(&driver_lock) +- + #define DEB(x) if (i2c_debug>=1) x; + #define DEB2(x) if (i2c_debug>=2) x; + + /* ----- global variables -------------------------------------------------- */ + +-/**** lock for writing to global variables: the adapter & driver list */ +-struct semaphore adap_lock; +-struct semaphore driver_lock; +- +-/**** adapter list */ ++DECLARE_MUTEX(core_lists); + static struct i2c_adapter *adapters[I2C_ADAP_MAX]; +-static int adap_count; +- +-/**** drivers list */ + static struct i2c_driver *drivers[I2C_DRIVER_MAX]; +-static int driver_count; + + /**** debug level */ +-static int i2c_debug=1; ++static int i2c_debug; + + /* --------------------------------------------------- + * /proc entry declarations +@@ -75,10 +52,6 @@ + */ + + #ifdef CONFIG_PROC_FS +- +-static int i2cproc_init(void); +-static int i2cproc_cleanup(void); +- + static ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count, + loff_t *ppos); + static int read_bus_i2c(char *buf, char **start, off_t offset, int len, +@@ -87,15 +60,11 @@ + /* To implement the dynamic /proc/bus/i2c-? files, we need our own + implementation of the read hook */ + static struct file_operations i2cproc_operations = { +- read: i2cproc_bus_read, ++ .read = i2cproc_bus_read, + }; + +-static int i2cproc_initialized = 0; +- +-#else /* undef CONFIG_PROC_FS */ +- +-#define i2cproc_init() 0 +-#define i2cproc_cleanup() 0 ++static int i2cproc_register(struct i2c_adapter *adap, int bus); ++static void i2cproc_remove(int bus); + + #endif /* CONFIG_PROC_FS */ + +@@ -112,9 +81,9 @@ + */ + int i2c_add_adapter(struct i2c_adapter *adap) + { +- int i,j,res; ++ int i,j,res = 0; + +- ADAP_LOCK(); ++ down(&core_lists); + for (i = 0; i < I2C_ADAP_MAX; i++) + if (NULL == adapters[i]) + break; +@@ -125,68 +94,39 @@ + res = -ENOMEM; + goto ERROR0; + } ++ ++#ifdef CONFIG_PROC_FS ++ res = i2cproc_register(adap, i); ++ if (res<0) ++ goto ERROR0; ++#endif /* def CONFIG_PROC_FS */ + + adapters[i] = adap; +- adap_count++; +- ADAP_UNLOCK(); + + /* init data types */ +- init_MUTEX(&adap->lock); +- +-#ifdef CONFIG_PROC_FS +- +- if (i2cproc_initialized) { +- char name[8]; +- struct proc_dir_entry *proc_entry; +- +- sprintf(name,"i2c-%d", i); +- +- proc_entry = create_proc_entry(name,0,proc_bus); +- if (! proc_entry) { +- printk("i2c-core.o: Could not create /proc/bus/%s\n", +- name); +- res = -ENOENT; +- goto ERROR1; +- } +- +- proc_entry->proc_fops = &i2cproc_operations; +- proc_entry->owner = THIS_MODULE; +- adap->inode = proc_entry->low_ino; +- } +- +-#endif /* def CONFIG_PROC_FS */ ++ init_MUTEX(&adap->bus); ++ init_MUTEX(&adap->list); + + /* inform drivers of new adapters */ +- DRV_LOCK(); + for (j=0;jflags&(I2C_DF_NOTIFY|I2C_DF_DUMMY))) + /* We ignore the return code; if it fails, too bad */ + drivers[j]->attach_adapter(adap); +- DRV_UNLOCK(); + + DEB(printk(KERN_DEBUG "i2c-core.o: adapter %s registered as adapter %d.\n", + adap->name,i)); +- +- return 0; +- +- +-ERROR1: +- ADAP_LOCK(); +- adapters[i] = NULL; +- adap_count--; + ERROR0: +- ADAP_UNLOCK(); ++ up(&core_lists); + return res; + } + + + int i2c_del_adapter(struct i2c_adapter *adap) + { +- int i,j,res; +- +- ADAP_LOCK(); ++ int i,j,res = 0; + ++ down(&core_lists); + for (i = 0; i < I2C_ADAP_MAX; i++) + if (adap == adapters[i]) + break; +@@ -202,20 +142,17 @@ + * *detach* it! Of course, each dummy driver should know about + * this or hell will break loose... + */ +- DRV_LOCK(); + for (j = 0; j < I2C_DRIVER_MAX; j++) + if (drivers[j] && (drivers[j]->flags & I2C_DF_DUMMY)) + if ((res = drivers[j]->attach_adapter(adap))) { + printk(KERN_WARNING "i2c-core.o: can't detach adapter %s " + "while detaching driver %s: driver not " + "detached!",adap->name,drivers[j]->name); +- goto ERROR1; ++ goto ERROR0; + } +- DRV_UNLOCK(); +- + + /* detach any active clients. This must be done first, because +- * it can fail; in which case we give upp. */ ++ * it can fail; in which case we give up. */ + for (j=0;jclients[j]; + if (client!=NULL) +@@ -231,26 +168,15 @@ + goto ERROR0; + } + } ++ + #ifdef CONFIG_PROC_FS +- if (i2cproc_initialized) { +- char name[8]; +- sprintf(name,"i2c-%d", i); +- remove_proc_entry(name,proc_bus); +- } ++ i2cproc_remove(i); + #endif /* def CONFIG_PROC_FS */ + + adapters[i] = NULL; +- adap_count--; +- +- ADAP_UNLOCK(); + DEB(printk(KERN_DEBUG "i2c-core.o: adapter unregistered: %s\n",adap->name)); +- return 0; +- + ERROR0: +- ADAP_UNLOCK(); +- return res; +-ERROR1: +- DRV_UNLOCK(); ++ up(&core_lists); + return res; + } + +@@ -264,7 +190,8 @@ + int i2c_add_driver(struct i2c_driver *driver) + { + int i; +- DRV_LOCK(); ++ ++ down(&core_lists); + for (i = 0; i < I2C_DRIVER_MAX; i++) + if (NULL == drivers[i]) + break; +@@ -273,19 +200,12 @@ + " i2c-core.o: register_driver(%s) " + "- enlarge I2C_DRIVER_MAX.\n", + driver->name); +- DRV_UNLOCK(); ++ up(&core_lists); + return -ENOMEM; + } +- + drivers[i] = driver; +- driver_count++; +- +- DRV_UNLOCK(); /* driver was successfully added */ +- + DEB(printk(KERN_DEBUG "i2c-core.o: driver %s registered.\n",driver->name)); + +- ADAP_LOCK(); +- + /* now look for instances of driver on our adapters + */ + if (driver->flags& (I2C_DF_NOTIFY|I2C_DF_DUMMY)) { +@@ -294,15 +214,15 @@ + /* Ignore errors */ + driver->attach_adapter(adapters[i]); + } +- ADAP_UNLOCK(); ++ up(&core_lists); + return 0; + } + + int i2c_del_driver(struct i2c_driver *driver) + { +- int i,j,k,res; ++ int i,j,k,res = 0; + +- DRV_LOCK(); ++ down(&core_lists); + for (i = 0; i < I2C_DRIVER_MAX; i++) + if (driver == drivers[i]) + break; +@@ -310,7 +230,7 @@ + printk(KERN_WARNING " i2c-core.o: unregister_driver: " + "[%s] not found\n", + driver->name); +- DRV_UNLOCK(); ++ up(&core_lists); + return -ENODEV; + } + /* Have a look at each adapter, if clients of this driver are still +@@ -322,7 +242,6 @@ + * invalid operation might (will!) result, when using stale client + * pointers. + */ +- ADAP_LOCK(); /* should be moved inside the if statement... */ + for (k=0;kname, + adap->name); +- ADAP_UNLOCK(); +- return res; ++ goto ERROR0; + } + } else { + for (j=0;jname, + client->addr, + adap->name); +- ADAP_UNLOCK(); +- return res; ++ goto ERROR0; + } + } + } + } + } +- ADAP_UNLOCK(); + drivers[i] = NULL; +- driver_count--; +- DRV_UNLOCK(); +- + DEB(printk(KERN_DEBUG "i2c-core.o: driver unregistered: %s\n",driver->name)); +- return 0; ++ ++ERROR0: ++ up(&core_lists); ++ return res; + } + +-int i2c_check_addr (struct i2c_adapter *adapter, int addr) ++static int __i2c_check_addr (struct i2c_adapter *adapter, int addr) + { + int i; + for (i = 0; i < I2C_CLIENT_MAX ; i++) + if (adapter->clients[i] && (adapter->clients[i]->addr == addr)) + return -EBUSY; ++ + return 0; + } + ++int i2c_check_addr (struct i2c_adapter *adapter, int addr) ++{ ++ int rval; ++ ++ down(&adapter->list); ++ rval = __i2c_check_addr(adapter, addr); ++ up(&adapter->list); ++ ++ return rval; ++} ++ + int i2c_attach_client(struct i2c_client *client) + { + struct i2c_adapter *adapter = client->adapter; +@@ -398,6 +326,7 @@ + if (i2c_check_addr(client->adapter,client->addr)) + return -EBUSY; + ++ down(&adapter->list); + for (i = 0; i < I2C_CLIENT_MAX; i++) + if (NULL == adapter->clients[i]) + break; +@@ -405,11 +334,11 @@ + printk(KERN_WARNING + " i2c-core.o: attach_client(%s) - enlarge I2C_CLIENT_MAX.\n", + client->name); ++ up(&adapter->list); + return -ENOMEM; + } +- + adapter->clients[i] = client; +- adapter->client_count++; ++ up(&adapter->list); + + if (adapter->client_register) + if (adapter->client_register(client)) +@@ -431,16 +360,6 @@ + struct i2c_adapter *adapter = client->adapter; + int i,res; + +- for (i = 0; i < I2C_CLIENT_MAX; i++) +- if (client == adapter->clients[i]) +- break; +- if (I2C_CLIENT_MAX == i) { +- printk(KERN_WARNING " i2c-core.o: unregister_client " +- "[%s] not found\n", +- client->name); +- return -ENODEV; +- } +- + if( (client->flags & I2C_CLIENT_ALLOW_USE) && + (client->usage_count>0)) + return -EBUSY; +@@ -452,33 +371,41 @@ + return res; + } + ++ down(&adapter->list); ++ for (i = 0; i < I2C_CLIENT_MAX; i++) ++ if (client == adapter->clients[i]) ++ break; ++ if (I2C_CLIENT_MAX == i) { ++ printk(KERN_WARNING " i2c-core.o: unregister_client " ++ "[%s] not found\n", ++ client->name); ++ up(&adapter->list); ++ return -ENODEV; ++ } + adapter->clients[i] = NULL; +- adapter->client_count--; ++ up(&adapter->list); + + DEB(printk(KERN_DEBUG "i2c-core.o: client [%s] unregistered.\n",client->name)); + return 0; + } + +-void i2c_inc_use_client(struct i2c_client *client) ++static void i2c_inc_use_client(struct i2c_client *client) + { +- +- if (client->driver->inc_use != NULL) +- client->driver->inc_use(client); +- +- if (client->adapter->inc_use != NULL) +- client->adapter->inc_use(client->adapter); ++ if(client->driver->owner) ++ __MOD_INC_USE_COUNT(client->driver->owner); ++ if(client->adapter->owner) ++ __MOD_INC_USE_COUNT(client->adapter->owner); + } + +-void i2c_dec_use_client(struct i2c_client *client) ++static void i2c_dec_use_client(struct i2c_client *client) + { +- +- if (client->driver->dec_use != NULL) +- client->driver->dec_use(client); +- +- if (client->adapter->dec_use != NULL) +- client->adapter->dec_use(client->adapter); ++ if(client->driver->owner) ++ __MOD_DEC_USE_COUNT(client->driver->owner); ++ if(client->adapter->owner) ++ __MOD_DEC_USE_COUNT(client->adapter->owner); + } + ++#if 0 /* just forget about this for now --km */ + struct i2c_client *i2c_get_client(int driver_id, int adapter_id, + struct i2c_client *prev) + { +@@ -545,18 +472,17 @@ + + return 0; + } ++#endif + + int i2c_use_client(struct i2c_client *client) + { +- if(client->flags & I2C_CLIENT_ALLOW_USE) { +- if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE) ++ if (client->flags & I2C_CLIENT_ALLOW_USE) { ++ if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE) ++ client->usage_count++; ++ else if (client->usage_count > 0) ++ return -EBUSY; ++ else + client->usage_count++; +- else { +- if(client->usage_count > 0) +- return -EBUSY; +- else +- client->usage_count++; +- } + } + + i2c_inc_use_client(client); +@@ -589,12 +515,13 @@ + #ifdef CONFIG_PROC_FS + + /* This function generates the output for /proc/bus/i2c */ +-int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof, ++static int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof, + void *private) + { + int i; + int nr = 0; + /* Note that it is safe to write a `little' beyond len. Yes, really. */ ++ down(&core_lists); + for (i = 0; (i < I2C_ADAP_MAX) && (nr < len); i++) + if (adapters[i]) { + nr += sprintf(buf+nr, "i2c-%d\t", i); +@@ -611,6 +538,7 @@ + adapters[i]->name, + adapters[i]->algo->name); + } ++ up(&core_lists); + return nr; + } + +@@ -621,98 +549,125 @@ + struct inode * inode = file->f_dentry->d_inode; + char *kbuf; + struct i2c_client *client; ++ struct i2c_adapter *adap; + int i,j,k,order_nr,len=0; + size_t len_total; + int order[I2C_CLIENT_MAX]; ++#define OUTPUT_LENGTH_PER_LINE 70 + +- if (count > 4000) +- return -EINVAL; + len_total = file->f_pos + count; +- /* Too bad if this gets longer (unlikely) */ +- if (len_total > 4000) +- len_total = 4000; +- for (i = 0; i < I2C_ADAP_MAX; i++) +- if (adapters[i]->inode == inode->i_ino) { +- /* We need a bit of slack in the kernel buffer; this makes the +- sprintf safe. */ +- if (! (kbuf = kmalloc(count + 80,GFP_KERNEL))) +- return -ENOMEM; +- /* Order will hold the indexes of the clients +- sorted by address */ +- order_nr=0; +- for (j = 0; j < I2C_CLIENT_MAX; j++) { +- if ((client = adapters[i]->clients[j]) && +- (client->driver->id != I2C_DRIVERID_I2CDEV)) { +- for(k = order_nr; +- (k > 0) && +- adapters[i]->clients[order[k-1]]-> +- addr > client->addr; +- k--) +- order[k] = order[k-1]; +- order[k] = j; +- order_nr++; +- } +- } +- +- +- for (j = 0; (j < order_nr) && (len < len_total); j++) { +- client = adapters[i]->clients[order[j]]; +- len += sprintf(kbuf+len,"%02x\t%-32s\t%-32s\n", +- client->addr, +- client->name, +- client->driver->name); +- } +- len = len - file->f_pos; +- if (len > count) +- len = count; +- if (len < 0) +- len = 0; +- if (copy_to_user (buf,kbuf+file->f_pos, len)) { +- kfree(kbuf); +- return -EFAULT; +- } +- file->f_pos += len; +- kfree(kbuf); +- return len; +- } +- return -ENOENT; ++ if (len_total > (I2C_CLIENT_MAX * OUTPUT_LENGTH_PER_LINE) ) ++ /* adjust to maximum file size */ ++ len_total = (I2C_CLIENT_MAX * OUTPUT_LENGTH_PER_LINE); ++ ++ down(&core_lists); ++ /* adap = file->private_data; ?? --km */ ++ for (i = 0; i < I2C_ADAP_MAX; i++) { ++ adap = adapters[i]; ++ if (adap && (adap->inode == inode->i_ino)) ++ break; ++ } ++ if ( I2C_ADAP_MAX == i ) { ++ up(&core_lists); ++ return -ENOENT; ++ } ++ ++ /* We need a bit of slack in the kernel buffer; this makes the ++ sprintf safe. */ ++ if (! (kbuf = kmalloc(len_total + ++ OUTPUT_LENGTH_PER_LINE, ++ GFP_KERNEL))) ++ return -ENOMEM; ++ ++ /* Order will hold the indexes of the clients ++ sorted by address */ ++ order_nr=0; ++ down(&adap->list); ++ for (j = 0; j < I2C_CLIENT_MAX; j++) { ++ if ((client = adap->clients[j]) && ++ (client->driver->id != I2C_DRIVERID_I2CDEV)) { ++ for(k = order_nr; ++ (k > 0) && ++ adap->clients[order[k-1]]-> ++ addr > client->addr; ++ k--) ++ order[k] = order[k-1]; ++ order[k] = j; ++ order_nr++; ++ } ++ } ++ ++ ++ for (j = 0; (j < order_nr) && (len < len_total); j++) { ++ client = adap->clients[order[j]]; ++ len += sprintf(kbuf+len,"%02x\t%-32s\t%-32s\n", ++ client->addr, ++ client->name, ++ client->driver->name); ++ } ++ up(&adap->list); ++ up(&core_lists); ++ ++ len = len - file->f_pos; ++ if (len > count) ++ len = count; ++ if (len < 0) ++ len = 0; ++ if (copy_to_user (buf,kbuf+file->f_pos, len)) { ++ kfree(kbuf); ++ return -EFAULT; ++ } ++ file->f_pos += len; ++ kfree(kbuf); ++ return len; ++} ++ ++static int i2cproc_register(struct i2c_adapter *adap, int bus) ++{ ++ char name[8]; ++ struct proc_dir_entry *proc_entry; ++ ++ sprintf(name,"i2c-%d", bus); ++ proc_entry = create_proc_entry(name,0,proc_bus); ++ if (! proc_entry) { ++ printk(KERN_ERR "i2c-core.o: Could not create /proc/bus/%s\n", ++ name); ++ return -ENOENT; ++ } ++ ++ proc_entry->proc_fops = &i2cproc_operations; ++ proc_entry->owner = adap->owner; ++ adap->inode = proc_entry->low_ino; ++ return 0; + } + +-int i2cproc_init(void) ++static void i2cproc_remove(int bus) + { ++ char name[8]; ++ sprintf(name,"i2c-%d", bus); ++ remove_proc_entry(name, proc_bus); ++} + ++static int __init i2cproc_init(void) ++{ + struct proc_dir_entry *proc_bus_i2c; + +- i2cproc_initialized = 0; +- +- if (! proc_bus) { +- printk("i2c-core.o: /proc/bus/ does not exist"); +- i2cproc_cleanup(); +- return -ENOENT; +- } + proc_bus_i2c = create_proc_entry("i2c",0,proc_bus); + if (!proc_bus_i2c) { + printk(KERN_ERR "i2c-core.o: Could not create /proc/bus/i2c"); +- i2cproc_cleanup(); + return -ENOENT; + } ++ + proc_bus_i2c->read_proc = &read_bus_i2c; + proc_bus_i2c->owner = THIS_MODULE; +- i2cproc_initialized += 2; + return 0; + } + +-int i2cproc_cleanup(void) ++static void __exit i2cproc_cleanup(void) + { +- +- if (i2cproc_initialized >= 1) { +- remove_proc_entry("i2c",proc_bus); +- i2cproc_initialized -= 2; +- } +- return 0; ++ remove_proc_entry("i2c",proc_bus); + } + +- + #endif /* def CONFIG_PROC_FS */ + + /* ---------------------------------------------------- +@@ -728,9 +683,9 @@ + DEB2(printk(KERN_DEBUG "i2c-core.o: master_xfer: %s with %d msgs.\n", + adap->name,num)); + +- I2C_LOCK(adap); ++ down(&adap->bus); + ret = adap->algo->master_xfer(adap,msgs,num); +- I2C_UNLOCK(adap); ++ up(&adap->bus); + + return ret; + } else { +@@ -755,9 +710,9 @@ + DEB2(printk(KERN_DEBUG "i2c-core.o: master_send: writing %d bytes on %s.\n", + count,client->adapter->name)); + +- I2C_LOCK(adap); ++ down(&adap->bus); + ret = adap->algo->master_xfer(adap,&msg,1); +- I2C_UNLOCK(adap); ++ up(&adap->bus); + + /* if everything went ok (i.e. 1 msg transmitted), return #bytes + * transmitted, else error code. +@@ -785,9 +740,9 @@ + DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: reading %d bytes on %s.\n", + count,client->adapter->name)); + +- I2C_LOCK(adap); ++ down(&adap->bus); + ret = adap->algo->master_xfer(adap,&msg,1); +- I2C_UNLOCK(adap); ++ up(&adap->bus); + + DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: return:%d (count:%d, addr:0x%02x)\n", + ret, count, client->addr)); +@@ -965,6 +920,123 @@ + + /* The SMBus parts */ + ++#define POLY (0x1070U << 3) ++static u8 ++crc8(u16 data) ++{ ++ int i; ++ ++ for(i = 0; i < 8; i++) { ++ if (data & 0x8000) ++ data = data ^ POLY; ++ data = data << 1; ++ } ++ return (u8)(data >> 8); ++} ++ ++/* CRC over count bytes in the first array plus the bytes in the rest ++ array if it is non-null. rest[0] is the (length of rest) - 1 ++ and is included. */ ++u8 i2c_smbus_partial_pec(u8 crc, int count, u8 *first, u8 *rest) ++{ ++ int i; ++ ++ for(i = 0; i < count; i++) ++ crc = crc8((crc ^ first[i]) << 8); ++ if(rest != NULL) ++ for(i = 0; i <= rest[0]; i++) ++ crc = crc8((crc ^ rest[i]) << 8); ++ return crc; ++} ++ ++u8 i2c_smbus_pec(int count, u8 *first, u8 *rest) ++{ ++ return i2c_smbus_partial_pec(0, count, first, rest); ++} ++ ++/* Returns new "size" (transaction type) ++ Note that we convert byte to byte_data and byte_data to word_data ++ rather than invent new xxx_PEC transactions. */ ++int i2c_smbus_add_pec(u16 addr, u8 command, int size, ++ union i2c_smbus_data *data) ++{ ++ u8 buf[3]; ++ ++ buf[0] = addr << 1; ++ buf[1] = command; ++ switch(size) { ++ case I2C_SMBUS_BYTE: ++ data->byte = i2c_smbus_pec(2, buf, NULL); ++ size = I2C_SMBUS_BYTE_DATA; ++ break; ++ case I2C_SMBUS_BYTE_DATA: ++ buf[2] = data->byte; ++ data->word = buf[2] || ++ (i2c_smbus_pec(3, buf, NULL) << 8); ++ size = I2C_SMBUS_WORD_DATA; ++ break; ++ case I2C_SMBUS_WORD_DATA: ++ /* unsupported */ ++ break; ++ case I2C_SMBUS_BLOCK_DATA: ++ data->block[data->block[0] + 1] = ++ i2c_smbus_pec(2, buf, data->block); ++ size = I2C_SMBUS_BLOCK_DATA_PEC; ++ break; ++ } ++ return size; ++} ++ ++int i2c_smbus_check_pec(u16 addr, u8 command, int size, u8 partial, ++ union i2c_smbus_data *data) ++{ ++ u8 buf[3], rpec, cpec; ++ ++ buf[1] = command; ++ switch(size) { ++ case I2C_SMBUS_BYTE_DATA: ++ buf[0] = (addr << 1) | 1; ++ cpec = i2c_smbus_pec(2, buf, NULL); ++ rpec = data->byte; ++ break; ++ case I2C_SMBUS_WORD_DATA: ++ buf[0] = (addr << 1) | 1; ++ buf[2] = data->word & 0xff; ++ cpec = i2c_smbus_pec(3, buf, NULL); ++ rpec = data->word >> 8; ++ break; ++ case I2C_SMBUS_WORD_DATA_PEC: ++ /* unsupported */ ++ cpec = rpec = 0; ++ break; ++ case I2C_SMBUS_PROC_CALL_PEC: ++ /* unsupported */ ++ cpec = rpec = 0; ++ break; ++ case I2C_SMBUS_BLOCK_DATA_PEC: ++ buf[0] = (addr << 1); ++ buf[2] = (addr << 1) | 1; ++ cpec = i2c_smbus_pec(3, buf, data->block); ++ rpec = data->block[data->block[0] + 1]; ++ break; ++ case I2C_SMBUS_BLOCK_PROC_CALL_PEC: ++ buf[0] = (addr << 1) | 1; ++ rpec = i2c_smbus_partial_pec(partial, 1, ++ buf, data->block); ++ cpec = data->block[data->block[0] + 1]; ++ break; ++ default: ++ cpec = rpec = 0; ++ break; ++ } ++ if(rpec != cpec) { ++ DEB(printk(KERN_DEBUG "i2c-core.o: Bad PEC 0x%02x vs. 0x%02x\n", ++ rpec, cpec)); ++ return -1; ++ } ++ return 0; ++} ++ + extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value) + { + return i2c_smbus_xfer(client->adapter,client->addr,client->flags, +@@ -983,8 +1055,9 @@ + + extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value) + { ++ union i2c_smbus_data data; /* only for PEC */ + return i2c_smbus_xfer(client->adapter,client->addr,client->flags, +- I2C_SMBUS_WRITE,value, I2C_SMBUS_BYTE,NULL); ++ I2C_SMBUS_WRITE,value, I2C_SMBUS_BYTE,&data); + } + + extern s32 i2c_smbus_read_byte_data(struct i2c_client * client, u8 command) +@@ -1072,6 +1145,43 @@ + I2C_SMBUS_BLOCK_DATA,&data); + } + ++/* Returns the number of read bytes */ ++extern s32 i2c_smbus_block_process_call(struct i2c_client * client, ++ u8 command, u8 length, u8 *values) ++{ ++ union i2c_smbus_data data; ++ int i; ++ if (length > I2C_SMBUS_BLOCK_MAX - 1) ++ return -1; ++ data.block[0] = length; ++ for (i = 1; i <= length; i++) ++ data.block[i] = values[i-1]; ++ if(i2c_smbus_xfer(client->adapter,client->addr,client->flags, ++ I2C_SMBUS_WRITE, command, ++ I2C_SMBUS_BLOCK_PROC_CALL, &data)) ++ return -1; ++ for (i = 1; i <= data.block[0]; i++) ++ values[i-1] = data.block[i]; ++ return data.block[0]; ++} ++ ++/* Returns the number of read bytes */ ++extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, ++ u8 command, u8 *values) ++{ ++ union i2c_smbus_data data; ++ int i; ++ if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, ++ I2C_SMBUS_READ,command, ++ I2C_SMBUS_I2C_BLOCK_DATA,&data)) ++ return -1; ++ else { ++ for (i = 1; i <= data.block[0]; i++) ++ values[i-1] = data.block[i]; ++ return data.block[0]; ++ } ++} ++ + extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client, + u8 command, u8 length, u8 *values) + { +@@ -1098,13 +1208,13 @@ + need to use only one message; when reading, we need two. We initialize + most things with sane defaults, to keep the code below somewhat + simpler. */ +- unsigned char msgbuf0[34]; +- unsigned char msgbuf1[34]; ++ unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+2]; ++ unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; + int num = read_write == I2C_SMBUS_READ?2:1; + struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, + { addr, flags | I2C_M_RD, 0, msgbuf1 } + }; +- int i; ++ int i, len; + + msgbuf0[0] = command; + switch(size) { +@@ -1140,16 +1250,30 @@ + break; + case I2C_SMBUS_PROC_CALL: + num = 2; /* Special case */ ++ read_write = I2C_SMBUS_READ; + msg[0].len = 3; + msg[1].len = 2; + msgbuf0[1] = data->word & 0xff; + msgbuf0[2] = (data->word >> 8) & 0xff; + break; + case I2C_SMBUS_BLOCK_DATA: ++ case I2C_SMBUS_BLOCK_DATA_PEC: + if (read_write == I2C_SMBUS_READ) { +- printk(KERN_ERR "i2c-core.o: Block read not supported " +- "under I2C emulation!\n"); +- return -1; ++ /* I2C_FUNC_SMBUS_EMUL doesn't include I2C_FUNC_SMBUS_READ_BLOCK_DATA */ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BLOCK_DATA)) { ++ printk(KERN_ERR "i2c-core.o: Block read not supported " ++ "under I2C emulation!\n"); ++ return -1; ++ } ++ /* set send message */ ++ msg[0].len = 1; ++ /* set recv message */ ++ msg[1].flags |= I2C_M_RECV_LEN; ++ msg[1].len = I2C_SMBUS_BLOCK_MAX + 1; ++ if (size == I2C_SMBUS_BLOCK_DATA_PEC) { ++ msg[1].len++; ++ msg[1].flags |= I2C_M_RECV_PEC; ++ } + } else { + msg[0].len = data->block[0] + 2; + if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { +@@ -1158,10 +1282,57 @@ + data->block[0]); + return -1; + } ++ if(size == I2C_SMBUS_BLOCK_DATA_PEC) ++ (msg[0].len)++; + for (i = 1; i <= msg[0].len; i++) + msgbuf0[i] = data->block[i-1]; + } + break; ++ case I2C_SMBUS_BLOCK_PROC_CALL: ++ case I2C_SMBUS_BLOCK_PROC_CALL_PEC: ++ /* I2C_FUNC_SMBUS_EMUL doesn't include I2C_FUNC_SMBUS_BLOCK_PROC_CALL */ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BLOCK_PROC_CALL)) { ++ printk(KERN_ERR "i2c-core.o: adapter doesn't support block process call!\n"); ++ return -1; ++ } ++ ++ /* Another special case */ ++ num = 2; ++ read_write = I2C_SMBUS_READ; ++ ++ /* set send message */ ++ msg[0].len = data->block[0] + 2; ++ if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { ++ printk(KERN_ERR "i2c-core.o: smbus_access called with " ++ "invalid block write size (%d)\n", data->block[0]); ++ return -1; ++ } ++ for (i = 1; i <= msg[0].len; i++) ++ msgbuf0[i] = data->block[i-1]; ++ ++ /* set recv message */ ++ msg[1].flags |= I2C_M_RECV_LEN; ++ msg[1].len = I2C_SMBUS_BLOCK_MAX + 1; ++ if (size == I2C_SMBUS_BLOCK_PROC_CALL_PEC) { ++ msg[1].len++; ++ msg[1].flags |= I2C_M_RECV_PEC; ++ } ++ break; ++ case I2C_SMBUS_I2C_BLOCK_DATA: ++ if (read_write == I2C_SMBUS_READ) { ++ msg[1].len = I2C_SMBUS_I2C_BLOCK_MAX; ++ } else { ++ msg[0].len = data->block[0] + 1; ++ if (msg[0].len > I2C_SMBUS_I2C_BLOCK_MAX + 1) { ++ printk("i2c-core.o: i2c_smbus_xfer_emulated called with " ++ "invalid block write size (%d)\n", ++ data->block[0]); ++ return -1; ++ } ++ for (i = 1; i <= data->block[0]; i++) ++ msgbuf0[i] = data->block[i]; ++ } ++ break; + default: + printk(KERN_ERR "i2c-core.o: smbus_access called with invalid size (%d)\n", + size); +@@ -1183,25 +1354,72 @@ + case I2C_SMBUS_PROC_CALL: + data->word = msgbuf1[0] | (msgbuf1[1] << 8); + break; ++ case I2C_SMBUS_I2C_BLOCK_DATA: ++ /* fixed at 32 for now */ ++ data->block[0] = I2C_SMBUS_I2C_BLOCK_MAX; ++ for (i = 0; i < I2C_SMBUS_I2C_BLOCK_MAX; i++) ++ data->block[i+1] = msgbuf1[i]; ++ break; ++ case I2C_SMBUS_BLOCK_DATA: ++ case I2C_SMBUS_BLOCK_PROC_CALL: ++ case I2C_SMBUS_BLOCK_DATA_PEC: ++ case I2C_SMBUS_BLOCK_PROC_CALL_PEC: ++ len = msgbuf1[0] + 1; ++ if(size == I2C_SMBUS_BLOCK_DATA_PEC || ++ size == I2C_SMBUS_BLOCK_PROC_CALL_PEC) ++ len++; ++ for (i = 0; i < len; i++) ++ data->block[i] = msgbuf1[i]; ++ break; + } + return 0; + } + + +-s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, ++s32 i2c_smbus_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, + char read_write, u8 command, int size, + union i2c_smbus_data * data) + { + s32 res; +- flags = flags & I2C_M_TEN; +- if (adapter->algo->smbus_xfer) { +- I2C_LOCK(adapter); +- res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write, ++ int swpec = 0; ++ u8 partial = 0; ++ ++ flags &= I2C_M_TEN | I2C_CLIENT_PEC; ++ if((flags & I2C_CLIENT_PEC) && ++ !(i2c_check_functionality(adap, I2C_FUNC_SMBUS_HWPEC_CALC))) { ++ swpec = 1; ++ if(read_write == I2C_SMBUS_READ && ++ size == I2C_SMBUS_BLOCK_DATA) ++ size = I2C_SMBUS_BLOCK_DATA_PEC; ++ else if(size == I2C_SMBUS_PROC_CALL) ++ size = I2C_SMBUS_PROC_CALL_PEC; ++ else if(size == I2C_SMBUS_BLOCK_PROC_CALL) { ++ i2c_smbus_add_pec(addr, command, ++ I2C_SMBUS_BLOCK_DATA, data); ++ partial = data->block[data->block[0] + 1]; ++ size = I2C_SMBUS_BLOCK_PROC_CALL_PEC; ++ } else if(read_write == I2C_SMBUS_WRITE && ++ size != I2C_SMBUS_QUICK && ++ size != I2C_SMBUS_I2C_BLOCK_DATA) ++ size = i2c_smbus_add_pec(addr, command, size, data); ++ } ++ ++ if (adap->algo->smbus_xfer) { ++ down(&adap->bus); ++ res = adap->algo->smbus_xfer(adap,addr,flags,read_write, + command,size,data); +- I2C_UNLOCK(adapter); ++ up(&adap->bus); + } else +- res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, ++ res = i2c_smbus_xfer_emulated(adap,addr,flags,read_write, + command,size,data); ++ ++ if(res >= 0 && swpec && ++ size != I2C_SMBUS_QUICK && size != I2C_SMBUS_I2C_BLOCK_DATA && ++ (read_write == I2C_SMBUS_READ || size == I2C_SMBUS_PROC_CALL_PEC || ++ size == I2C_SMBUS_BLOCK_PROC_CALL_PEC)) { ++ if(i2c_smbus_check_pec(addr, command, size, partial, data)) ++ return -1; ++ } + return res; + } + +@@ -1228,143 +1446,37 @@ + printk(KERN_INFO "i2c-core.o: i2c core module version %s (%s)\n", I2C_VERSION, I2C_DATE); + memset(adapters,0,sizeof(adapters)); + memset(drivers,0,sizeof(drivers)); +- adap_count=0; +- driver_count=0; + +- init_MUTEX(&adap_lock); +- init_MUTEX(&driver_lock); +- +- i2cproc_init(); +- ++#ifdef CONFIG_PROC_FS ++ return i2cproc_init(); ++#else + return 0; +-} +- +-#ifndef MODULE +-#ifdef CONFIG_I2C_CHARDEV +- extern int i2c_dev_init(void); +-#endif +-#ifdef CONFIG_I2C_ALGOBIT +- extern int i2c_algo_bit_init(void); +-#endif +-#ifdef CONFIG_I2C_PHILIPSPAR +- extern int i2c_bitlp_init(void); +-#endif +-#ifdef CONFIG_I2C_ELV +- extern int i2c_bitelv_init(void); +-#endif +-#ifdef CONFIG_I2C_VELLEMAN +- extern int i2c_bitvelle_init(void); +-#endif +-#ifdef CONFIG_I2C_BITVIA +- extern int i2c_bitvia_init(void); +-#endif +- +-#ifdef CONFIG_I2C_ALGOPCF +- extern int i2c_algo_pcf_init(void); +-#endif +-#ifdef CONFIG_I2C_ELEKTOR +- extern int i2c_pcfisa_init(void); +-#endif +- +-#ifdef CONFIG_I2C_ALGO8XX +- extern int i2c_algo_8xx_init(void); +-#endif +-#ifdef CONFIG_I2C_RPXLITE +- extern int i2c_rpx_init(void); +-#endif +- +-#ifdef CONFIG_I2C_ALGO_SIBYTE +- extern int i2c_algo_sibyte_init(void); +- extern int i2c_sibyte_init(void); +-#endif +-#ifdef CONFIG_I2C_MAX1617 +- extern int i2c_max1617_init(void); +-#endif +-#ifdef CONFIG_I2C_ALGO_AU1550 +- extern int i2c_pb1550_init(void); + #endif ++} + +-#ifdef CONFIG_I2C_PROC +- extern int sensors_init(void); ++static void __exit i2c_exit(void) ++{ ++#ifdef CONFIG_PROC_FS ++ i2cproc_cleanup(); + #endif ++} + +-/* This is needed for automatic patch generation: sensors code starts here */ +-/* This is needed for automatic patch generation: sensors code ends here */ +- ++/* leave this in for now simply to make patching easier so we don't have ++ to remove the call in drivers/char/mem.c */ + int __init i2c_init_all(void) + { +- /* --------------------- global ----- */ +- i2c_init(); +- +-#ifdef CONFIG_I2C_CHARDEV +- i2c_dev_init(); +-#endif +- /* --------------------- bit -------- */ +-#ifdef CONFIG_I2C_ALGOBIT +- i2c_algo_bit_init(); +-#endif +-#ifdef CONFIG_I2C_PHILIPSPAR +- i2c_bitlp_init(); +-#endif +-#ifdef CONFIG_I2C_ELV +- i2c_bitelv_init(); +-#endif +-#ifdef CONFIG_I2C_VELLEMAN +- i2c_bitvelle_init(); +-#endif +- +- /* --------------------- pcf -------- */ +-#ifdef CONFIG_I2C_ALGOPCF +- i2c_algo_pcf_init(); +-#endif +-#ifdef CONFIG_I2C_ELEKTOR +- i2c_pcfisa_init(); +-#endif +- +- /* --------------------- 8xx -------- */ +-#ifdef CONFIG_I2C_ALGO8XX +- i2c_algo_8xx_init(); +-#endif +-#ifdef CONFIG_I2C_RPXLITE +- i2c_rpx_init(); +-#endif +- +- /* --------------------- SiByte -------- */ +-#ifdef CONFIG_I2C_ALGO_SIBYTE +- i2c_algo_sibyte_init(); +- i2c_sibyte_init(); +-#endif +-#ifdef CONFIG_I2C_MAX1617 +- i2c_max1617_init(); +-#endif +- +-#ifdef CONFIG_I2C_ALGO_AU1550 +- i2c_pb1550_init(); +-#endif +- +- /* -------------- proc interface ---- */ +-#ifdef CONFIG_I2C_PROC +- sensors_init(); +-#endif +-/* This is needed for automatic patch generation: sensors code starts here */ +-/* This is needed for automatic patch generation: sensors code ends here */ +- + return 0; + } + +-#endif +- +- +- + EXPORT_SYMBOL(i2c_add_adapter); + EXPORT_SYMBOL(i2c_del_adapter); + EXPORT_SYMBOL(i2c_add_driver); + EXPORT_SYMBOL(i2c_del_driver); + EXPORT_SYMBOL(i2c_attach_client); + EXPORT_SYMBOL(i2c_detach_client); +-EXPORT_SYMBOL(i2c_inc_use_client); +-EXPORT_SYMBOL(i2c_dec_use_client); ++#if 0 + EXPORT_SYMBOL(i2c_get_client); ++#endif + EXPORT_SYMBOL(i2c_use_client); + EXPORT_SYMBOL(i2c_release_client); + EXPORT_SYMBOL(i2c_check_addr); +@@ -1388,11 +1500,12 @@ + EXPORT_SYMBOL(i2c_smbus_process_call); + EXPORT_SYMBOL(i2c_smbus_read_block_data); + EXPORT_SYMBOL(i2c_smbus_write_block_data); ++EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); ++EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data); + + EXPORT_SYMBOL(i2c_get_functionality); + EXPORT_SYMBOL(i2c_check_functionality); + +-#ifdef MODULE + MODULE_AUTHOR("Simon G. Vogl "); + MODULE_DESCRIPTION("I2C-Bus main module"); + MODULE_LICENSE("GPL"); +@@ -1400,13 +1513,5 @@ + MODULE_PARM(i2c_debug, "i"); + MODULE_PARM_DESC(i2c_debug,"debug level"); + +-int init_module(void) +-{ +- return i2c_init(); +-} +- +-void cleanup_module(void) +-{ +- i2cproc_cleanup(); +-} +-#endif ++module_init(i2c_init); ++module_exit(i2c_exit); +--- linux-old/drivers/i2c/i2c-dev.c Tue Jan 20 15:10:31 2004 ++++ linux/drivers/i2c/i2c-dev.c Mon Dec 13 19:26:32 2004 +@@ -28,9 +28,8 @@ + /* The devfs code is contributed by Philipp Matthias Hahn + */ + +-/* $Id: i2c-dev.c,v 1.40 2001/08/25 01:28:01 mds Exp $ */ ++/* $Id: i2c-dev.c,v 1.57 2003/12/22 20:03:39 khali Exp $ */ + +-#include + #include + #include + #include +@@ -39,21 +38,14 @@ + #ifdef CONFIG_DEVFS_FS + #include + #endif +- +- +-/* If you want debugging uncomment: */ +-/* #define DEBUG */ +- + #include +-#include +- + #include + #include ++#include ++ ++/* If you want debugging uncomment: */ ++/* #define DEBUG */ + +-#ifdef MODULE +-extern int init_module(void); +-extern int cleanup_module(void); +-#endif /* def MODULE */ + + /* struct file_operations changed too often in the 2.1 series for nice code */ + +@@ -73,22 +65,14 @@ + static int i2cdev_command(struct i2c_client *client, unsigned int cmd, + void *arg); + +-#ifdef MODULE +-static +-#else +-extern +-#endif +- int __init i2c_dev_init(void); +-static int i2cdev_cleanup(void); +- + static struct file_operations i2cdev_fops = { +- owner: THIS_MODULE, +- llseek: no_llseek, +- read: i2cdev_read, +- write: i2cdev_write, +- ioctl: i2cdev_ioctl, +- open: i2cdev_open, +- release: i2cdev_release, ++ .owner = THIS_MODULE, ++ .llseek = no_llseek, ++ .read = i2cdev_read, ++ .write = i2cdev_write, ++ .ioctl = i2cdev_ioctl, ++ .open = i2cdev_open, ++ .release = i2cdev_release, + }; + + #define I2CDEV_ADAPS_MAX I2C_ADAP_MAX +@@ -99,28 +83,22 @@ + #endif + + static struct i2c_driver i2cdev_driver = { +- name: "i2c-dev dummy driver", +- id: I2C_DRIVERID_I2CDEV, +- flags: I2C_DF_DUMMY, +- attach_adapter: i2cdev_attach_adapter, +- detach_client: i2cdev_detach_client, +- command: i2cdev_command, +-/* inc_use: NULL, +- dec_use: NULL, */ ++ .owner = THIS_MODULE, /* not really used */ ++ .name = "i2c-dev dummy driver", ++ .id = I2C_DRIVERID_I2CDEV, ++ .flags = I2C_DF_DUMMY, ++ .attach_adapter = i2cdev_attach_adapter, ++ .detach_client = i2cdev_detach_client, ++ .command = i2cdev_command, + }; + + static struct i2c_client i2cdev_client_template = { +- name: "I2C /dev entry", +- id: 1, +- flags: 0, +- addr: -1, +-/* adapter: NULL, */ +- driver: &i2cdev_driver, +-/* data: NULL */ ++ .name = "I2C /dev entry", ++ .id = 1, ++ .addr = -1, ++ .driver = &i2cdev_driver, + }; + +-static int i2cdev_initialized; +- + static ssize_t i2cdev_read (struct file *file, char *buf, size_t count, + loff_t *offset) + { +@@ -142,7 +120,7 @@ + return -ENOMEM; + + #ifdef DEBUG +- printk(KERN_DEBUG "i2c-dev.o: i2c-%d reading %d bytes.\n",MINOR(inode->i_rdev), ++ printk(KERN_DEBUG "i2c-dev.o: i2c-%d reading %d bytes.\n",minor(inode->i_rdev), + count); + #endif + +@@ -177,7 +155,7 @@ + } + + #ifdef DEBUG +- printk(KERN_DEBUG "i2c-dev.o: i2c-%d writing %d bytes.\n",MINOR(inode->i_rdev), ++ printk(KERN_DEBUG "i2c-dev.o: i2c-%d writing %d bytes.\n",minor(inode->i_rdev), + count); + #endif + ret = i2c_master_send(client,tmp,count); +@@ -199,7 +177,7 @@ + + #ifdef DEBUG + printk(KERN_DEBUG "i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n", +- MINOR(inode->i_rdev),cmd, arg); ++ minor(inode->i_rdev),cmd, arg); + #endif /* DEBUG */ + + switch ( cmd ) { +@@ -218,6 +196,12 @@ + else + client->flags &= ~I2C_M_TEN; + return 0; ++ case I2C_PEC: ++ if (arg) ++ client->flags |= I2C_CLIENT_PEC; ++ else ++ client->flags &= ~I2C_CLIENT_PEC; ++ return 0; + case I2C_FUNCS: + funcs = i2c_get_functionality(client->adapter); + return (copy_to_user((unsigned long *)arg,&funcs, +@@ -318,7 +302,8 @@ + (data_arg.size != I2C_SMBUS_WORD_DATA) && + (data_arg.size != I2C_SMBUS_PROC_CALL) && + (data_arg.size != I2C_SMBUS_BLOCK_DATA) && +- (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA)) { ++ (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) && ++ (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) { + #ifdef DEBUG + printk(KERN_DEBUG "i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n", + data_arg.size); +@@ -361,10 +346,11 @@ + else if ((data_arg.size == I2C_SMBUS_WORD_DATA) || + (data_arg.size == I2C_SMBUS_PROC_CALL)) + datasize = sizeof(data_arg.data->word); +- else /* size == I2C_SMBUS_BLOCK_DATA */ ++ else /* size == smbus block, i2c block, or block proc. call */ + datasize = sizeof(data_arg.data->block); + + if ((data_arg.size == I2C_SMBUS_PROC_CALL) || ++ (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || + (data_arg.read_write == I2C_SMBUS_WRITE)) { + if (copy_from_user(&temp, data_arg.data, datasize)) + return -EFAULT; +@@ -373,6 +359,7 @@ + data_arg.read_write, + data_arg.command,data_arg.size,&temp); + if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) || ++ (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) || + (data_arg.read_write == I2C_SMBUS_READ))) { + if (copy_to_user(data_arg.data, &temp, datasize)) + return -EFAULT; +@@ -387,7 +374,7 @@ + + int i2cdev_open (struct inode *inode, struct file *file) + { +- unsigned int minor = MINOR(inode->i_rdev); ++ unsigned int minor = minor(inode->i_rdev); + struct i2c_client *client; + + if ((minor >= I2CDEV_ADAPS_MAX) || ! (i2cdev_adaps[minor])) { +@@ -403,11 +390,13 @@ + if(! (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) + return -ENOMEM; + memcpy(client,&i2cdev_client_template,sizeof(struct i2c_client)); ++ ++ /* registered with adapter, passed as client to user */ + client->adapter = i2cdev_adaps[minor]; + file->private_data = client; + +- if (i2cdev_adaps[minor]->inc_use) +- i2cdev_adaps[minor]->inc_use(i2cdev_adaps[minor]); ++ if(client->adapter->owner) ++ __MOD_INC_USE_COUNT(client->adapter->owner); + + #ifdef DEBUG + printk(KERN_DEBUG "i2c-dev.o: opened i2c-%d\n",minor); +@@ -417,16 +406,19 @@ + + static int i2cdev_release (struct inode *inode, struct file *file) + { +- unsigned int minor = MINOR(inode->i_rdev); +- kfree(file->private_data); +- file->private_data=NULL; ++ struct i2c_client *client; ++#ifdef DEBUG ++ unsigned int minor = minor(inode->i_rdev); ++#endif ++ ++ client = file->private_data; ++ file->private_data = NULL; ++ if(client->adapter->owner) ++ __MOD_DEC_USE_COUNT(client->adapter->owner); ++ kfree(client); + #ifdef DEBUG + printk(KERN_DEBUG "i2c-dev.o: Closed: i2c-%d\n", minor); + #endif +- lock_kernel(); +- if (i2cdev_adaps[minor]->dec_use) +- i2cdev_adaps[minor]->dec_use(i2cdev_adaps[minor]); +- unlock_kernel(); + return 0; + } + +@@ -451,7 +443,7 @@ + devfs_i2c[i] = devfs_register (devfs_handle, name, + DEVFS_FL_DEFAULT, I2C_MAJOR, i, + S_IFCHR | S_IRUSR | S_IWUSR, +- &i2cdev_fops, NULL); ++ &i2cdev_fops, adap); + #endif + printk(KERN_DEBUG "i2c-dev.o: Registered '%s' as minor %d\n",adap->name,i); + } else { +@@ -479,13 +471,12 @@ + return -1; + } + +-int __init i2c_dev_init(void) ++static int __init i2c_dev_init(void) + { + int res; + + printk(KERN_INFO "i2c-dev.o: i2c /dev entries driver module version %s (%s)\n", I2C_VERSION, I2C_DATE); + +- i2cdev_initialized = 0; + #ifdef CONFIG_DEVFS_FS + if (devfs_register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops)) { + #else +@@ -498,63 +489,31 @@ + #ifdef CONFIG_DEVFS_FS + devfs_handle = devfs_mk_dir(NULL, "i2c", NULL); + #endif +- i2cdev_initialized ++; +- + if ((res = i2c_add_driver(&i2cdev_driver))) { + printk(KERN_ERR "i2c-dev.o: Driver registration failed, module not inserted.\n"); +- i2cdev_cleanup(); ++#ifdef CONFIG_DEVFS_FS ++ devfs_unregister(devfs_handle); ++#endif ++ unregister_chrdev(I2C_MAJOR,"i2c"); + return res; + } +- i2cdev_initialized ++; + return 0; + } + +-int i2cdev_cleanup(void) ++static void __exit i2c_dev_exit(void) + { +- int res; +- +- if (i2cdev_initialized >= 2) { +- if ((res = i2c_del_driver(&i2cdev_driver))) { +- printk("i2c-dev.o: Driver deregistration failed, " +- "module not removed.\n"); +- return res; +- } +- i2cdev_initialized --; +- } +- +- if (i2cdev_initialized >= 1) { ++ i2c_del_driver(&i2cdev_driver); + #ifdef CONFIG_DEVFS_FS +- devfs_unregister(devfs_handle); +- if ((res = devfs_unregister_chrdev(I2C_MAJOR, "i2c"))) { +-#else +- if ((res = unregister_chrdev(I2C_MAJOR,"i2c"))) { ++ devfs_unregister(devfs_handle); + #endif +- printk("i2c-dev.o: unable to release major %d for i2c bus\n", +- I2C_MAJOR); +- return res; +- } +- i2cdev_initialized --; +- } +- return 0; ++ unregister_chrdev(I2C_MAJOR,"i2c"); + } + + EXPORT_NO_SYMBOLS; + +-#ifdef MODULE +- + MODULE_AUTHOR("Frodo Looijaard and Simon G. Vogl "); + MODULE_DESCRIPTION("I2C /dev entries driver"); + MODULE_LICENSE("GPL"); + +-int init_module(void) +-{ +- return i2c_dev_init(); +-} +- +-int cleanup_module(void) +-{ +- return i2cdev_cleanup(); +-} +- +-#endif /* def MODULE */ +- ++module_init(i2c_dev_init); ++module_exit(i2c_dev_exit); +--- linux-old/include/linux/i2c-dev.h Sat Jul 5 03:23:47 2003 ++++ linux/include/linux/i2c-dev.h Mon Dec 13 19:26:32 2004 +@@ -19,14 +19,16 @@ + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +-/* $Id: i2c-dev.h,v 1.9 2001/08/15 03:04:58 mds Exp $ */ +- +-#ifndef I2C_DEV_H +-#define I2C_DEV_H ++/* $Id: i2c-dev.h,v 1.14 2003/07/25 07:56:42 khali Exp $ */ + ++#ifndef _LINUX_I2C_DEV_H ++#define _LINUX_I2C_DEV_H + + #include +-#include ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) ++#define minor(d) MINOR(d) ++#endif + + /* Some IOCTL commands are defined in */ + /* Note: 10-bit addresses are NOT supported! */ +@@ -45,137 +47,4 @@ + __u32 nmsgs; /* number of i2c_msgs */ + }; + +-#ifndef __KERNEL__ +- +-#include +- +-static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command, +- int size, union i2c_smbus_data *data) +-{ +- struct i2c_smbus_ioctl_data args; +- +- args.read_write = read_write; +- args.command = command; +- args.size = size; +- args.data = data; +- return ioctl(file,I2C_SMBUS,&args); +-} +- +- +-static inline __s32 i2c_smbus_write_quick(int file, __u8 value) +-{ +- return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL); +-} +- +-static inline __s32 i2c_smbus_read_byte(int file) +-{ +- union i2c_smbus_data data; +- if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data)) +- return -1; +- else +- return 0x0FF & data.byte; +-} +- +-static inline __s32 i2c_smbus_write_byte(int file, __u8 value) +-{ +- return i2c_smbus_access(file,I2C_SMBUS_WRITE,value, +- I2C_SMBUS_BYTE,NULL); +-} +- +-static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command) +-{ +- union i2c_smbus_data data; +- if (i2c_smbus_access(file,I2C_SMBUS_READ,command, +- I2C_SMBUS_BYTE_DATA,&data)) +- return -1; +- else +- return 0x0FF & data.byte; +-} +- +-static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command, +- __u8 value) +-{ +- union i2c_smbus_data data; +- data.byte = value; +- return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, +- I2C_SMBUS_BYTE_DATA, &data); +-} +- +-static inline __s32 i2c_smbus_read_word_data(int file, __u8 command) +-{ +- union i2c_smbus_data data; +- if (i2c_smbus_access(file,I2C_SMBUS_READ,command, +- I2C_SMBUS_WORD_DATA,&data)) +- return -1; +- else +- return 0x0FFFF & data.word; +-} +- +-static inline __s32 i2c_smbus_write_word_data(int file, __u8 command, +- __u16 value) +-{ +- union i2c_smbus_data data; +- data.word = value; +- return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, +- I2C_SMBUS_WORD_DATA, &data); +-} +- +-static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value) +-{ +- union i2c_smbus_data data; +- data.word = value; +- if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command, +- I2C_SMBUS_PROC_CALL,&data)) +- return -1; +- else +- return 0x0FFFF & data.word; +-} +- +- +-/* Returns the number of read bytes */ +-static inline __s32 i2c_smbus_read_block_data(int file, __u8 command, +- __u8 *values) +-{ +- union i2c_smbus_data data; +- int i; +- if (i2c_smbus_access(file,I2C_SMBUS_READ,command, +- I2C_SMBUS_BLOCK_DATA,&data)) +- return -1; +- else { +- for (i = 1; i <= data.block[0]; i++) +- values[i-1] = data.block[i]; +- return data.block[0]; +- } +-} +- +-static inline __s32 i2c_smbus_write_block_data(int file, __u8 command, +- __u8 length, __u8 *values) +-{ +- union i2c_smbus_data data; +- int i; +- if (length > 32) +- length = 32; +- for (i = 1; i <= length; i++) +- data.block[i] = values[i-1]; +- data.block[0] = length; +- return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, +- I2C_SMBUS_BLOCK_DATA, &data); +-} +- +-static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, +- __u8 length, __u8 *values) +-{ +- union i2c_smbus_data data; +- int i; +- if (length > 32) +- length = 32; +- for (i = 1; i <= length; i++) +- data.block[i] = values[i-1]; +- data.block[0] = length; +- return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, +- I2C_SMBUS_I2C_BLOCK_DATA, &data); +-} +- +-#endif /* ndef __KERNEL__ */ +- +-#endif ++#endif /* _LINUX_I2C_DEV_H */ +--- linux-old/drivers/i2c/i2c-elektor.c Tue Jan 20 15:10:31 2004 ++++ linux/drivers/i2c/i2c-elektor.c Mon Dec 13 19:26:33 2004 +@@ -31,23 +31,22 @@ + #include + #include + #include ++#include + #include +-#include +-#include +- ++#include + #include + #include +-#include +-#include "i2c-pcf8584.h" ++#include ++#include + + #define DEFAULT_BASE 0x330 + +-static int base = 0; +-static int irq = 0; ++static int base; ++static int irq; + static int clock = 0x1c; + static int own = 0x55; +-static int mmapped = 0; +-static int i2c_debug = 0; ++static int mmapped; ++static int i2c_debug; + + /* vdovikin: removed static struct i2c_pcf_isa gpi; code - + this module in real supports only one device, due to missing arguments +@@ -56,6 +55,7 @@ + + static wait_queue_head_t pcf_wait; + static int pcf_pending; ++static spinlock_t irq_driver_lock = SPIN_LOCK_UNLOCKED; + + /* ----- global defines ----------------------------------------------- */ + #define DEB(x) if (i2c_debug>=1) x +@@ -63,13 +63,24 @@ + #define DEB3(x) if (i2c_debug>=3) x + #define DEBE(x) x /* error messages */ + ++ ++/* compatibility */ ++#ifndef isa_readb ++#define isa_readb readb ++#endif ++ ++#ifndef isa_writeb ++#define isa_writeb writeb ++#endif ++ + /* ----- local functions ---------------------------------------------- */ + + static void pcf_isa_setbyte(void *data, int ctl, int val) + { + int address = ctl ? (base + 1) : base; + +- if (ctl && irq) { ++ /* enable irq if any specified for serial operation */ ++ if (ctl && irq && (val & I2C_PCF_ESO)) { + val |= I2C_PCF_ENI; + } + +@@ -81,10 +92,10 @@ + break; + case 2: /* double mapped I/O needed for UP2000 board, + I don't know why this... */ +- writeb(val, address); ++ isa_writeb(val, address); + /* fall */ + case 1: /* memory mapped I/O */ +- writeb(val, address); ++ isa_writeb(val, address); + break; + } + } +@@ -92,7 +103,7 @@ + static int pcf_isa_getbyte(void *data, int ctl) + { + int address = ctl ? (base + 1) : base; +- int val = mmapped ? readb(address) : inb(address); ++ int val = mmapped ? isa_readb(address) : inb(address); + + DEB3(printk(KERN_DEBUG "i2c-elektor.o: Read 0x%X 0x%02X\n", address, val)); + +@@ -115,12 +126,12 @@ + int timeout = 2; + + if (irq > 0) { +- cli(); ++ spin_lock_irq(&irq_driver_lock); + if (pcf_pending == 0) { + interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ ); + } else + pcf_pending = 0; +- sti(); ++ spin_unlock_irq(&irq_driver_lock); + } else { + udelay(100); + } +@@ -136,13 +147,11 @@ + static int pcf_isa_init(void) + { + if (!mmapped) { +- if (check_region(base, 2) < 0 ) { ++ if (!request_region(base, 2, "i2c (isa bus adapter)")) { + printk(KERN_ERR + "i2c-elektor.o: requested I/O region (0x%X:2) " + "is in use.\n", base); + return -ENODEV; +- } else { +- request_region(base, 2, "i2c (isa bus adapter)"); + } + } + if (irq > 0) { +@@ -156,70 +165,29 @@ + } + + +-static void __exit pcf_isa_exit(void) +-{ +- if (irq > 0) { +- disable_irq(irq); +- free_irq(irq, 0); +- } +- if (!mmapped) { +- release_region(base , 2); +- } +-} +- +- +-static int pcf_isa_reg(struct i2c_client *client) +-{ +- return 0; +-} +- +- +-static int pcf_isa_unreg(struct i2c_client *client) +-{ +- return 0; +-} +- +-static void pcf_isa_inc_use(struct i2c_adapter *adap) +-{ +-#ifdef MODULE +- MOD_INC_USE_COUNT; +-#endif +-} +- +-static void pcf_isa_dec_use(struct i2c_adapter *adap) +-{ +-#ifdef MODULE +- MOD_DEC_USE_COUNT; +-#endif +-} +- +- + /* ------------------------------------------------------------------------ + * Encapsulate the above functions in the correct operations structure. + * This is only done when more than one hardware adapter is supported. + */ + static struct i2c_algo_pcf_data pcf_isa_data = { +- NULL, +- pcf_isa_setbyte, +- pcf_isa_getbyte, +- pcf_isa_getown, +- pcf_isa_getclock, +- pcf_isa_waitforpin, +- 10, 10, 100, /* waits, timeout */ ++ .setpcf = pcf_isa_setbyte, ++ .getpcf = pcf_isa_getbyte, ++ .getown = pcf_isa_getown, ++ .getclock = pcf_isa_getclock, ++ .waitforpin = pcf_isa_waitforpin, ++ .udelay = 10, ++ .mdelay = 10, ++ .timeout = HZ, + }; + + static struct i2c_adapter pcf_isa_ops = { +- "PCF8584 ISA adapter", +- I2C_HW_P_ELEK, +- NULL, +- &pcf_isa_data, +- pcf_isa_inc_use, +- pcf_isa_dec_use, +- pcf_isa_reg, +- pcf_isa_unreg, ++ .owner = THIS_MODULE, ++ .name = "PCF8584 ISA adapter", ++ .id = I2C_HW_P_ELEK, ++ .algo_data = &pcf_isa_data, + }; + +-int __init i2c_pcfisa_init(void) ++static int __init i2c_pcfisa_init(void) + { + #ifdef __alpha__ + /* check to see we have memory mapped PCF8584 connected to the +@@ -277,22 +245,41 @@ + } + + init_waitqueue_head(&pcf_wait); +- if (pcf_isa_init() == 0) { +- if (i2c_pcf_add_bus(&pcf_isa_ops) < 0) +- return -ENODEV; +- } else { ++ if (pcf_isa_init()) + return -ENODEV; +- } ++ if (i2c_pcf_add_bus(&pcf_isa_ops) < 0) ++ goto fail; + + printk(KERN_DEBUG "i2c-elektor.o: found device at %#x.\n", base); + + return 0; ++ ++ fail: ++ if (irq > 0) { ++ disable_irq(irq); ++ free_irq(irq, 0); ++ } ++ ++ if (!mmapped) ++ release_region(base , 2); ++ return -ENODEV; + } + ++static void __exit i2c_pcfisa_exit(void) ++{ ++ i2c_pcf_del_bus(&pcf_isa_ops); ++ ++ if (irq > 0) { ++ disable_irq(irq); ++ free_irq(irq, 0); ++ } ++ ++ if (!mmapped) ++ release_region(base , 2); ++} + + EXPORT_NO_SYMBOLS; + +-#ifdef MODULE + MODULE_AUTHOR("Hans Berglund "); + MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 ISA bus adapter"); + MODULE_LICENSE("GPL"); +@@ -304,15 +291,5 @@ + MODULE_PARM(mmapped, "i"); + MODULE_PARM(i2c_debug, "i"); + +-int init_module(void) +-{ +- return i2c_pcfisa_init(); +-} +- +-void cleanup_module(void) +-{ +- i2c_pcf_del_bus(&pcf_isa_ops); +- pcf_isa_exit(); +-} +- +-#endif ++module_init(i2c_pcfisa_init); ++module_exit(i2c_pcfisa_exit); +--- linux-old/include/linux/i2c-elektor.h Tue Nov 6 00:55:29 2001 ++++ linux/include/linux/i2c-elektor.h Mon Dec 13 19:26:33 2004 +@@ -1,47 +0,0 @@ +-/* ------------------------------------------------------------------------- */ +-/* i2c-elektor.c i2c-hw access for PCF8584 style isa bus adaptes */ +-/* ------------------------------------------------------------------------- */ +-/* Copyright (C) 1995-97 Simon G. Vogl +- 1998-99 Hans Berglund +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 2 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; if not, write to the Free Software +- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +-/* ------------------------------------------------------------------------- */ +- +-/* With some changes from Kyösti Mälkki and even +- Frodo Looijaard */ +- +-/* $Id: i2c-elektor.h,v 1.5 2001/06/05 01:46:33 mds Exp $ */ +- +-#ifndef I2C_PCF_ELEKTOR_H +-#define I2C_PCF_ELEKTOR_H 1 +- +-/* +- * This struct contains the hw-dependent functions of PCF8584 adapters to +- * manipulate the registers, and to init any hw-specific features. +- * vdovikin: removed: this module in real supports only one device, +- * due to missing arguments in some functions, called from the algo-pcf module. +- * Sometimes it's need to be rewriten - +- * but for now just remove this for simpler reading */ +- +-/* +-struct i2c_pcf_isa { +- int pi_base; +- int pi_irq; +- int pi_clock; +- int pi_own; +-}; +-*/ +- +-#endif /* PCF_ELEKTOR_H */ +--- linux-old/drivers/i2c/i2c-elv.c Tue Jan 20 15:10:31 2004 ++++ linux/drivers/i2c/i2c-elv.c Mon Dec 13 19:26:33 2004 +@@ -21,21 +21,18 @@ + /* With some changes from Kyösti Mälkki and even + Frodo Looijaard */ + +-/* $Id: i2c-elv.c,v 1.17 2001/07/29 02:44:25 mds Exp $ */ ++/* $Id: i2c-elv.c,v 1.29 2003/12/22 20:03:11 khali Exp $ */ + + #include + #include + #include + #include + #include +- +-#include +- + #include +-#include + #include + #include + #include ++#include + + #define DEFAULT_BASE 0x378 + static int base=0; +@@ -89,58 +86,31 @@ + + static int bit_elv_init(void) + { +- if (check_region(base,(base == 0x3bc)? 3 : 8) < 0 ) { +- return -ENODEV; +- } else { +- /* test for ELV adap. */ +- if (inb(base+1) & 0x80) { /* BUSY should be high */ +- DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Busy was low.\n")); +- return -ENODEV; +- } else { +- outb(0x0c,base+2); /* SLCT auf low */ +- udelay(400); +- if ( !(inb(base+1) && 0x10) ) { +- outb(0x04,base+2); +- DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Select was high.\n")); +- return -ENODEV; +- } +- } +- request_region(base,(base == 0x3bc)? 3 : 8, +- "i2c (ELV adapter)"); +- PortData = 0; +- bit_elv_setsda((void*)base,1); +- bit_elv_setscl((void*)base,1); ++ if (!request_region(base, (base == 0x3bc) ? 3 : 8, ++ "i2c (ELV adapter)")) ++ return -ENODEV; ++ ++ if (inb(base+1) & 0x80) { /* BUSY should be high */ ++ DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Busy was low.\n")); ++ goto fail; ++ } ++ ++ outb(0x0c,base+2); /* SLCT auf low */ ++ udelay(400); ++ if (!(inb(base+1) && 0x10)) { ++ outb(0x04,base+2); ++ DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Select was high.\n")); ++ goto fail; + } +- return 0; +-} +- +-static void __exit bit_elv_exit(void) +-{ +- release_region( base , (base == 0x3bc)? 3 : 8 ); +-} +- +-static int bit_elv_reg(struct i2c_client *client) +-{ +- return 0; +-} + +-static int bit_elv_unreg(struct i2c_client *client) +-{ ++ PortData = 0; ++ bit_elv_setsda((void*)base,1); ++ bit_elv_setscl((void*)base,1); + return 0; +-} + +-static void bit_elv_inc_use(struct i2c_adapter *adap) +-{ +-#ifdef MODULE +- MOD_INC_USE_COUNT; +-#endif +-} +- +-static void bit_elv_dec_use(struct i2c_adapter *adap) +-{ +-#ifdef MODULE +- MOD_DEC_USE_COUNT; +-#endif ++fail: ++ release_region(base , (base == 0x3bc) ? 3 : 8); ++ return -ENODEV; + } + + /* ------------------------------------------------------------------------ +@@ -148,26 +118,23 @@ + * This is only done when more than one hardware adapter is supported. + */ + static struct i2c_algo_bit_data bit_elv_data = { +- NULL, +- bit_elv_setsda, +- bit_elv_setscl, +- bit_elv_getsda, +- bit_elv_getscl, +- 80, 80, 100, /* waits, timeout */ ++ .setsda = bit_elv_setsda, ++ .setscl = bit_elv_setscl, ++ .getsda = bit_elv_getsda, ++ .getscl = bit_elv_getscl, ++ .udelay = 80, ++ .mdelay = 80, ++ .timeout = HZ + }; + + static struct i2c_adapter bit_elv_ops = { +- "ELV Parallel port adaptor", +- I2C_HW_B_ELV, +- NULL, +- &bit_elv_data, +- bit_elv_inc_use, +- bit_elv_dec_use, +- bit_elv_reg, +- bit_elv_unreg, ++ .owner = THIS_MODULE, ++ .name = "ELV Parallel port adaptor", ++ .id = I2C_HW_B_ELV, ++ .algo_data = &bit_elv_data, + }; + +-int __init i2c_bitelv_init(void) ++static int __init i2c_bitelv_init(void) + { + printk(KERN_INFO "i2c-elv.o: i2c ELV parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); + if (base==0) { +@@ -193,25 +160,19 @@ + return 0; + } + ++static void __exit i2c_bitelv_exit(void) ++{ ++ i2c_bit_del_bus(&bit_elv_ops); ++ release_region(base, (base == 0x3bc) ? 3 : 8); ++} + + EXPORT_NO_SYMBOLS; + +-#ifdef MODULE + MODULE_AUTHOR("Simon G. Vogl "); + MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter"); + MODULE_LICENSE("GPL"); + + MODULE_PARM(base, "i"); + +-int init_module(void) +-{ +- return i2c_bitelv_init(); +-} +- +-void cleanup_module(void) +-{ +- i2c_bit_del_bus(&bit_elv_ops); +- bit_elv_exit(); +-} +- +-#endif ++module_init(i2c_bitelv_init); ++module_exit(i2c_bitelv_exit); +--- linux-old/drivers/i2c/i2c-frodo.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-frodo.c Mon Dec 13 19:26:33 2004 +@@ -0,0 +1,83 @@ ++ ++/* ++ * linux/drivers/i2c/i2c-frodo.c ++ * ++ * Author: Abraham van der Merwe ++ * ++ * An I2C adapter driver for the 2d3D, Inc. StrongARM SA-1110 ++ * Development board (Frodo). ++ * ++ * This source code 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. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++static void frodo_setsda (void *data,int state) ++{ ++ if (state) ++ FRODO_CPLD_I2C |= FRODO_I2C_SDA_OUT; ++ else ++ FRODO_CPLD_I2C &= ~FRODO_I2C_SDA_OUT; ++} ++ ++static void frodo_setscl (void *data,int state) ++{ ++ if (state) ++ FRODO_CPLD_I2C |= FRODO_I2C_SCL_OUT; ++ else ++ FRODO_CPLD_I2C &= ~FRODO_I2C_SCL_OUT; ++} ++ ++static int frodo_getsda (void *data) ++{ ++ return ((FRODO_CPLD_I2C & FRODO_I2C_SDA_IN) != 0); ++} ++ ++static int frodo_getscl (void *data) ++{ ++ return ((FRODO_CPLD_I2C & FRODO_I2C_SCL_IN) != 0); ++} ++ ++static struct i2c_algo_bit_data bit_frodo_data = { ++ .setsda = frodo_setsda, ++ .setscl = frodo_setscl, ++ .getsda = frodo_getsda, ++ .getscl = frodo_getscl, ++ .udelay = 80, ++ .mdelay = 80, ++ .timeout = HZ ++}; ++ ++static struct i2c_adapter frodo_ops = { ++ .owner = THIS_MODULE, ++ .name = "Frodo adapter driver", ++ .id = I2C_HW_B_FRODO, ++ .algo_data = &bit_frodo_data, ++}; ++ ++static int __init i2c_frodo_init (void) ++{ ++ return i2c_bit_add_bus(&frodo_ops); ++} ++ ++static void __exit i2c_frodo_exit (void) ++{ ++ i2c_bit_del_bus(&frodo_ops); ++} ++ ++MODULE_AUTHOR ("Abraham van der Merwe "); ++MODULE_DESCRIPTION ("I2C-Bus adapter routines for Frodo"); ++MODULE_LICENSE ("GPL"); ++ ++module_init (i2c_frodo_init); ++module_exit (i2c_frodo_exit); ++ +--- linux-old/include/linux/i2c-id.h Wed Jul 7 00:38:02 2004 ++++ linux/include/linux/i2c-id.h Mon Dec 13 19:26:33 2004 +@@ -20,10 +20,11 @@ + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + /* ------------------------------------------------------------------------- */ + +-/* $Id: i2c-id.h,v 1.35 2001/08/12 17:22:20 mds Exp $ */ ++/* $Id: i2c-id.h,v 1.92 2004/07/27 18:15:06 mmh Exp $ */ ++ ++#ifndef LINUX_I2C_ID_H ++#define LINUX_I2C_ID_H + +-#ifndef I2C_ID_H +-#define I2C_ID_H + /* + * This file is part of the i2c-bus package and contains the identifier + * values for drivers, adapters and other folk populating these serial +@@ -90,10 +91,25 @@ + #define I2C_DRIVERID_DRP3510 43 /* ADR decoder (Astra Radio) */ + #define I2C_DRIVERID_SP5055 44 /* Satellite tuner */ + #define I2C_DRIVERID_STV0030 45 /* Multipurpose switch */ ++#define I2C_DRIVERID_SAA7108 46 /* video decoder, image scaler */ ++#define I2C_DRIVERID_DS1307 47 /* DS1307 real time clock */ + #define I2C_DRIVERID_ADV7175 48 /* ADV 7175/7176 video encoder */ +-#define I2C_DRIVERID_MAX1617 56 /* temp sensor */ +-#define I2C_DRIVERID_SAA7191 57 /* video decoder */ +-#define I2C_DRIVERID_INDYCAM 58 /* SGI IndyCam */ ++#define I2C_DRIVERID_ZR36067 49 /* Zoran 36067 video encoder */ ++#define I2C_DRIVERID_ZR36120 50 /* Zoran 36120 video encoder */ ++#define I2C_DRIVERID_24LC32A 51 /* Microchip 24LC32A 32k EEPROM */ ++#define I2C_DRIVERID_STM41T00 52 /* real time clock */ ++#define I2C_DRIVERID_UDA1342 53 /* UDA1342 audio codec */ ++#define I2C_DRIVERID_ADV7170 54 /* video encoder */ ++#define I2C_DRIVERID_RADEON 55 /* I2C bus on Radeon boards */ ++#define I2C_DRIVERID_MAX1617 56 /* temp sensor */ ++#define I2C_DRIVERID_SAA7191 57 /* video encoder */ ++#define I2C_DRIVERID_INDYCAM 58 /* SGI IndyCam */ ++#define I2C_DRIVERID_BT832 59 /* CMOS camera video processor */ ++#define I2C_DRIVERID_TDA9887 60 /* TDA988x IF-PLL demodulator */ ++#define I2C_DRIVERID_OVCAMCHIP 61 /* OmniVision CMOS image sens. */ ++#define I2C_DRIVERID_TDA7313 62 /* TDA7313 audio processor */ ++#define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */ ++ + + #define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */ + #define I2C_DRIVERID_EXP1 0xF1 +@@ -102,6 +118,8 @@ + + #define I2C_DRIVERID_I2CDEV 900 + #define I2C_DRIVERID_I2CPROC 901 ++#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ ++#define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */ + + /* IDs -- Use DRIVERIDs 1000-1999 for sensors. + These were originally in sensors.h in the lm_sensors package */ +@@ -131,6 +149,28 @@ + #define I2C_DRIVERID_ADM1024 1025 + #define I2C_DRIVERID_IT87 1026 + #define I2C_DRIVERID_CH700X 1027 /* single driver for CH7003-7009 digital pc to tv encoders */ ++#define I2C_DRIVERID_FSCPOS 1028 ++#define I2C_DRIVERID_FSCSCY 1029 ++#define I2C_DRIVERID_PCF8591 1030 ++#define I2C_DRIVERID_SMSC47M1 1031 ++#define I2C_DRIVERID_VT1211 1032 ++#define I2C_DRIVERID_LM92 1033 ++#define I2C_DRIVERID_VT8231 1034 ++#define I2C_DRIVERID_SMARTBATT 1035 ++#define I2C_DRIVERID_BMCSENSORS 1036 ++#define I2C_DRIVERID_FS451 1037 ++#define I2C_DRIVERID_W83627HF 1038 ++#define I2C_DRIVERID_LM85 1039 ++#define I2C_DRIVERID_LM83 1040 ++#define I2C_DRIVERID_SAA1064 1041 ++#define I2C_DRIVERID_LM90 1042 ++#define I2C_DRIVERID_ASB100 1043 ++#define I2C_DRIVERID_MAX6650 1044 ++#define I2C_DRIVERID_XEONTEMP 1045 ++#define I2C_DRIVERID_FSCHER 1046 ++#define I2C_DRIVERID_W83L785TS 1047 ++#define I2C_DRIVERID_ADM1026 1048 ++#define I2C_DRIVERID_LM93 1049 + + /* + * ---- Adapter types ---------------------------------------------------- +@@ -147,16 +187,21 @@ + #define I2C_ALGO_ISA 0x050000 /* lm_sensors ISA pseudo-adapter */ + #define I2C_ALGO_SAA7146 0x060000 /* SAA 7146 video decoder bus */ + #define I2C_ALGO_ACB 0x070000 /* ACCESS.bus algorithm */ +- ++#define I2C_ALGO_IIC 0x080000 /* ITE IIC bus */ ++#define I2C_ALGO_SAA7134 0x090000 ++#define I2C_ALGO_MPC824X 0x0a0000 /* Motorola 8240 / 8245 */ ++#define I2C_ALGO_IPMI 0x0b0000 /* IPMI dummy adapter */ ++#define I2C_ALGO_IPMB 0x0c0000 /* IPMB adapter */ ++#define I2C_ALGO_MPC107 0x0d0000 + #define I2C_ALGO_EC 0x100000 /* ACPI embedded controller */ + + #define I2C_ALGO_MPC8XX 0x110000 /* MPC8xx PowerPC I2C algorithm */ +- +-#define I2C_ALGO_SIBYTE 0x120000 /* Broadcom SiByte SOCs */ +- +-#define I2C_ALGO_SGI 0x130000 /* SGI algorithm */ +- +-#define I2C_ALGO_AU1550 0x140000 /* Alchemy Au1550 PSC */ ++#define I2C_ALGO_OCP 0x120000 /* IBM or otherwise On-chip I2C algorithm */ ++#define I2C_ALGO_BITHS 0x130000 /* enhanced bit style adapters */ ++#define I2C_ALGO_OCP_IOP3XX 0x140000 /* XSCALE IOP3XX On-chip I2C alg */ ++#define I2C_ALGO_SIBYTE 0x150000 /* Broadcom SiByte SOCs */ ++#define I2C_ALGO_SGI 0x160000 /* SGI algorithm */ ++#define I2C_ALGO_USB 0x170000 /* USB algorithm */ + + #define I2C_ALGO_EXP 0x800000 /* experimental */ + +@@ -184,21 +229,46 @@ + #define I2C_HW_B_I810 0x0a /* Intel I810 */ + #define I2C_HW_B_VOO 0x0b /* 3dfx Voodoo 3 / Banshee */ + #define I2C_HW_B_PPORT 0x0c /* Primitive parallel port adapter */ ++#define I2C_HW_B_SAVG 0x0d /* Savage 4 */ ++#define I2C_HW_B_SCX200 0x0e /* Nat'l Semi SCx200 I2C */ + #define I2C_HW_B_RIVA 0x10 /* Riva based graphics cards */ + #define I2C_HW_B_IOC 0x11 /* IOC bit-wiggling */ + #define I2C_HW_B_TSUNA 0x12 /* DEC Tsunami chipset */ ++#define I2C_HW_B_FRODO 0x13 /* 2d3D, Inc. SA-1110 Development Board */ ++#define I2C_HW_B_OMAHA 0x14 /* Omaha I2C interface (ARM) */ ++#define I2C_HW_B_GUIDE 0x15 /* Guide bit-basher */ ++#define I2C_HW_B_IXP2000 0x16 /* GPIO on IXP2000 systems */ ++#define I2C_HW_B_IXP425 0x17 /* GPIO on IXP425 systems */ ++#define I2C_HW_B_S3VIA 0x18 /* S3Via ProSavage adapter */ ++#define I2C_HW_B_ZR36067 0x19 /* Zoran-36057/36067 based boards */ ++#define I2C_HW_B_PCILYNX 0x1a /* TI PCILynx I2C adapter */ + + /* --- PCF 8584 based algorithms */ + #define I2C_HW_P_LP 0x00 /* Parallel port interface */ + #define I2C_HW_P_ISA 0x01 /* generic ISA Bus inteface card */ + #define I2C_HW_P_ELEK 0x02 /* Elektor ISA Bus inteface card */ + ++/* --- USB based adapters */ ++#define I2C_HW_USB_USBVISION 0x00 ++ + /* --- ACPI Embedded controller algorithms */ + #define I2C_HW_ACPI_EC 0x00 + ++/* --- MPC824x PowerPC adapters */ ++#define I2C_HW_MPC824X 0x00 /* Motorola 8240 / 8245 */ ++ + /* --- MPC8xx PowerPC adapters */ + #define I2C_HW_MPC8XX_EPON 0x00 /* Eponymous MPC8xx I2C adapter */ + ++/* --- ITE based algorithms */ ++#define I2C_HW_I_IIC 0x00 /* controller on the ITE */ ++ ++/* --- PowerPC on-chip adapters */ ++#define I2C_HW_OCP 0x00 /* IBM on-chip I2C adapter */ ++ ++/* --- XSCALE on-chip adapters */ ++#define I2C_HW_IOP321 0x00 ++ + /* --- Broadcom SiByte adapters */ + #define I2C_HW_SIBYTE 0x00 + +@@ -206,9 +276,6 @@ + #define I2C_HW_SGI_VINO 0x00 + #define I2C_HW_SGI_MACE 0x01 + +-/* --- Au1550 PSC adapters */ +-#define I2C_HW_AU1550_PSC 0x00 +- + /* --- SMBus only adapters */ + #define I2C_HW_SMBUS_PIIX4 0x00 + #define I2C_HW_SMBUS_ALI15X3 0x01 +@@ -218,9 +285,27 @@ + #define I2C_HW_SMBUS_AMD756 0x05 + #define I2C_HW_SMBUS_SIS5595 0x06 + #define I2C_HW_SMBUS_ALI1535 0x07 ++#define I2C_HW_SMBUS_SIS630 0x08 ++#define I2C_HW_SMBUS_SIS645 0x09 ++#define I2C_HW_SMBUS_AMD8111 0x0a ++#define I2C_HW_SMBUS_SCX200 0x0b ++#define I2C_HW_SMBUS_NFORCE2 0x0c + #define I2C_HW_SMBUS_W9968CF 0x0d ++#define I2C_HW_SMBUS_OV511 0x0e /* OV511(+) USB 1.1 webcam ICs */ ++#define I2C_HW_SMBUS_OV518 0x0f /* OV518(+) USB 1.1 webcam ICs */ ++#define I2C_HW_SMBUS_OV519 0x10 /* OV519 USB 1.1 webcam IC */ ++#define I2C_HW_SMBUS_OVFX2 0x11 /* Cypress/OmniVision FX2 webcam */ + + /* --- ISA pseudo-adapter */ + #define I2C_HW_ISA 0x00 + +-#endif /* I2C_ID_H */ ++/* --- IPMI pseudo-adapter */ ++#define I2C_HW_IPMI 0x00 ++ ++/* --- IPMB adapter */ ++#define I2C_HW_IPMB 0x00 ++ ++/* --- MCP107 adapter */ ++#define I2C_HW_MPC107 0x00 ++ ++#endif /* LINUX_I2C_ID_H */ +--- linux-old/drivers/i2c/i2c-pcf-epp.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-pcf-epp.c Mon Dec 13 19:26:34 2004 +@@ -0,0 +1,281 @@ ++/* ------------------------------------------------------------------------- */ ++/* i2c-pcf-epp.c i2c-hw access for PCF8584 style EPP parallel port adapters */ ++/* ------------------------------------------------------------------------- */ ++/* Copyright (C) 1998-99 Hans Berglund ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ ++/* ------------------------------------------------------------------------- */ ++ ++/* With some changes from Ryosuke Tajima */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++struct i2c_pcf_epp { ++ int pe_base; ++ int pe_irq; ++ int pe_clock; ++ int pe_own; ++} ; ++ ++#define DEFAULT_BASE 0x378 ++#define DEFAULT_IRQ 7 ++#define DEFAULT_CLOCK 0x1c ++#define DEFAULT_OWN 0x55 ++ ++static int base = 0; ++static int irq = 0; ++static int clock = 0; ++static int own = 0; ++static int i2c_debug=0; ++static struct i2c_pcf_epp gpe; ++static wait_queue_head_t pcf_wait; ++static int pcf_pending; ++static spinlock_t irq_driver_lock = SPIN_LOCK_UNLOCKED; ++ ++/* ----- global defines ----------------------------------------------- */ ++#define DEB(x) if (i2c_debug>=1) x ++#define DEB2(x) if (i2c_debug>=2) x ++#define DEB3(x) if (i2c_debug>=3) x ++#define DEBE(x) x /* error messages */ ++ ++/* --- Convenience defines for the EPP/SPP port: */ ++#define BASE ((struct i2c_pcf_epp *)(data))->pe_base ++// #define DATA BASE /* SPP data port */ ++#define STAT (BASE+1) /* SPP status port */ ++#define CTRL (BASE+2) /* SPP control port */ ++#define EADD (BASE+3) /* EPP address port */ ++#define EDAT (BASE+4) /* EPP data port */ ++ ++/* ----- local functions ---------------------------------------------- */ ++ ++static void pcf_epp_setbyte(void *data, int ctl, int val) ++{ ++ if (ctl) { ++ if (gpe.pe_irq > 0) { ++ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Write control 0x%x\n", ++ val|I2C_PCF_ENI)); ++ // set A0 pin HIGH ++ outb(inb(CTRL) | PARPORT_CONTROL_INIT, CTRL); ++ // DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: CTRL port = 0x%x\n", inb(CTRL))); ++ // DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: STAT port = 0x%x\n", inb(STAT))); ++ ++ // EPP write data cycle ++ outb(val | I2C_PCF_ENI, EDAT); ++ } else { ++ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Write control 0x%x\n", val)); ++ // set A0 pin HIGH ++ outb(inb(CTRL) | PARPORT_CONTROL_INIT, CTRL); ++ outb(val, CTRL); ++ } ++ } else { ++ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Write data 0x%x\n", val)); ++ // set A0 pin LO ++ outb(inb(CTRL) & ~PARPORT_CONTROL_INIT, CTRL); ++ // DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: CTRL port = 0x%x\n", inb(CTRL))); ++ // DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: STAT port = 0x%x\n", inb(STAT))); ++ outb(val, EDAT); ++ } ++} ++ ++static int pcf_epp_getbyte(void *data, int ctl) ++{ ++ int val; ++ ++ if (ctl) { ++ // set A0 pin HIGH ++ outb(inb(CTRL) | PARPORT_CONTROL_INIT, CTRL); ++ val = inb(EDAT); ++ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Read control 0x%x\n", val)); ++ } else { ++ // set A0 pin LOW ++ outb(inb(CTRL) & ~PARPORT_CONTROL_INIT, CTRL); ++ val = inb(EDAT); ++ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Read data 0x%x\n", val)); ++ } ++ return (val); ++} ++ ++static int pcf_epp_getown(void *data) ++{ ++ return (gpe.pe_own); ++} ++ ++ ++static int pcf_epp_getclock(void *data) ++{ ++ return (gpe.pe_clock); ++} ++ ++#if 0 ++static void pcf_epp_sleep(unsigned long timeout) ++{ ++ schedule_timeout( timeout * HZ); ++} ++#endif ++ ++static void pcf_epp_waitforpin(void) { ++ int timeout = 10; ++ ++ if (gpe.pe_irq > 0) { ++ spin_lock_irq(&irq_driver_lock); ++ if (pcf_pending == 0) { ++ interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ); ++ //udelay(100); ++ } else { ++ pcf_pending = 0; ++ } ++ spin_unlock_irq(&irq_driver_lock); ++ } else { ++ udelay(100); ++ } ++} ++ ++static void pcf_epp_handler(int this_irq, void *dev_id, struct pt_regs *regs) { ++ pcf_pending = 1; ++ wake_up_interruptible(&pcf_wait); ++ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: in interrupt handler.\n")); ++} ++ ++ ++static int pcf_epp_init(void *data) ++{ ++ if (check_region(gpe.pe_base, 5) < 0 ) { ++ ++ printk(KERN_WARNING "Could not request port region with base 0x%x\n", gpe.pe_base); ++ return -ENODEV; ++ } else { ++ request_region(gpe.pe_base, 5, "i2c (EPP parallel port adapter)"); ++ } ++ ++ DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: init status port = 0x%x\n", inb(0x379))); ++ ++ if (gpe.pe_irq > 0) { ++ if (request_irq(gpe.pe_irq, pcf_epp_handler, 0, "PCF8584", 0) < 0) { ++ printk(KERN_NOTICE "i2c-pcf-epp.o: Request irq%d failed\n", gpe.pe_irq); ++ gpe.pe_irq = 0; ++ } else ++ disable_irq(gpe.pe_irq); ++ enable_irq(gpe.pe_irq); ++ } ++ // EPP mode initialize ++ // enable interrupt from nINTR pin ++ outb(inb(CTRL)|0x14, CTRL); ++ // clear ERROR bit of STAT ++ outb(inb(STAT)|0x01, STAT); ++ outb(inb(STAT)&~0x01,STAT); ++ ++ return 0; ++} ++ ++/* ------------------------------------------------------------------------ ++ * Encapsulate the above functions in the correct operations structure. ++ * This is only done when more than one hardware adapter is supported. ++ */ ++static struct i2c_algo_pcf_data pcf_epp_data = { ++ .setpcf = pcf_epp_setbyte, ++ .getpcf = pcf_epp_getbyte, ++ .getown = pcf_epp_getown, ++ .getclock = pcf_epp_getclock, ++ .waitforpin = pcf_epp_waitforpin, ++ .udelay = 80, ++ .mdelay = 80, ++ .timeout = HZ, ++}; ++ ++static struct i2c_adapter pcf_epp_ops = { ++ .owner = THIS_MODULE, ++ .name = "PCF8584 EPP adapter", ++ .id = I2C_HW_P_LP, ++ .algo_data = &pcf_epp_data, ++}; ++ ++static int __init i2c_pcfepp_init(void) ++{ ++ struct i2c_pcf_epp *pepp = &gpe; ++ ++ printk(KERN_DEBUG "i2c-pcf-epp.o: i2c pcf8584-epp adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); ++ if (base == 0) ++ pepp->pe_base = DEFAULT_BASE; ++ else ++ pepp->pe_base = base; ++ ++ if (irq == 0) ++ pepp->pe_irq = DEFAULT_IRQ; ++ else if (irq<0) { ++ // switch off irq ++ pepp->pe_irq=0; ++ } else { ++ pepp->pe_irq = irq; ++ } ++ if (clock == 0) ++ pepp->pe_clock = DEFAULT_CLOCK; ++ else ++ pepp->pe_clock = clock; ++ ++ if (own == 0) ++ pepp->pe_own = DEFAULT_OWN; ++ else ++ pepp->pe_own = own; ++ ++ pcf_epp_data.data = (void *)pepp; ++ init_waitqueue_head(&pcf_wait); ++ if (pcf_epp_init(pepp) == 0) { ++ int ret; ++ if ( (ret = i2c_pcf_add_bus(&pcf_epp_ops)) < 0) { ++ printk(KERN_WARNING "i2c_pcf_add_bus caused an error: %d\n",ret); ++ release_region(pepp->pe_base , 5); ++ return ret; ++ } ++ } else { ++ ++ return -ENODEV; ++ } ++ printk(KERN_DEBUG "i2c-pcf-epp.o: found device at %#x.\n", pepp->pe_base); ++ return 0; ++} ++ ++static void __exit pcf_epp_exit(void) ++{ ++ i2c_pcf_del_bus(&pcf_epp_ops); ++ if (gpe.pe_irq > 0) { ++ disable_irq(gpe.pe_irq); ++ free_irq(gpe.pe_irq, 0); ++ } ++ release_region(gpe.pe_base , 5); ++} ++ ++MODULE_AUTHOR("Hans Berglund \n modified by Ryosuke Tajima "); ++MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 EPP parallel port adapter"); ++MODULE_LICENSE("GPL"); ++ ++MODULE_PARM(base, "i"); ++MODULE_PARM(irq, "i"); ++MODULE_PARM(clock, "i"); ++MODULE_PARM(own, "i"); ++MODULE_PARM(i2c_debug, "i"); ++ ++module_init(i2c_pcfepp_init); ++module_exit(pcf_epp_exit); +--- linux-old/include/linux/i2c-pcf8584.h Thu Jan 1 00:00:00 1970 ++++ linux/include/linux/i2c-pcf8584.h Mon Dec 13 19:26:34 2004 +@@ -0,0 +1,78 @@ ++/* -------------------------------------------------------------------- */ ++/* i2c-pcf8584.h: PCF 8584 global defines */ ++/* -------------------------------------------------------------------- */ ++/* Copyright (C) 1996 Simon G. Vogl ++ 1999 Hans Berglund ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ ++/* -------------------------------------------------------------------- */ ++ ++/* With some changes from Frodo Looijaard */ ++ ++/* $Id: i2c-pcf8584.h,v 1.6 2003/07/25 07:56:42 khali Exp $ */ ++ ++#ifndef _LINUX_I2C_PCF8584_H ++#define _LINUX_I2C_PCF8584_H ++ ++/* ----- Control register bits ---------------------------------------- */ ++#define I2C_PCF_PIN 0x80 ++#define I2C_PCF_ESO 0x40 ++#define I2C_PCF_ES1 0x20 ++#define I2C_PCF_ES2 0x10 ++#define I2C_PCF_ENI 0x08 ++#define I2C_PCF_STA 0x04 ++#define I2C_PCF_STO 0x02 ++#define I2C_PCF_ACK 0x01 ++ ++#define I2C_PCF_START (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_STA | I2C_PCF_ACK) ++#define I2C_PCF_STOP (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_STO | I2C_PCF_ACK) ++#define I2C_PCF_REPSTART ( I2C_PCF_ESO | I2C_PCF_STA | I2C_PCF_ACK) ++#define I2C_PCF_IDLE (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_ACK) ++ ++/* ----- Status register bits ----------------------------------------- */ ++/*#define I2C_PCF_PIN 0x80 as above*/ ++ ++#define I2C_PCF_INI 0x40 /* 1 if not initialized */ ++#define I2C_PCF_STS 0x20 ++#define I2C_PCF_BER 0x10 ++#define I2C_PCF_AD0 0x08 ++#define I2C_PCF_LRB 0x08 ++#define I2C_PCF_AAS 0x04 ++#define I2C_PCF_LAB 0x02 ++#define I2C_PCF_BB 0x01 ++ ++/* ----- Chip clock frequencies --------------------------------------- */ ++#define I2C_PCF_CLK3 0x00 ++#define I2C_PCF_CLK443 0x10 ++#define I2C_PCF_CLK6 0x14 ++#define I2C_PCF_CLK 0x18 ++#define I2C_PCF_CLK12 0x1c ++ ++/* ----- transmission frequencies ------------------------------------- */ ++#define I2C_PCF_TRNS90 0x00 /* 90 kHz */ ++#define I2C_PCF_TRNS45 0x01 /* 45 kHz */ ++#define I2C_PCF_TRNS11 0x02 /* 11 kHz */ ++#define I2C_PCF_TRNS15 0x03 /* 1.5 kHz */ ++ ++ ++/* ----- Access to internal registers according to ES1,ES2 ------------ */ ++/* they are mapped to the data port ( a0 = 0 ) */ ++/* available when ESO == 0 : */ ++ ++#define I2C_PCF_OWNADR 0 ++#define I2C_PCF_INTREG I2C_PCF_ES2 ++#define I2C_PCF_CLKREG I2C_PCF_ES1 ++ ++#endif /* _LINUX_I2C_PCF8584_H */ +--- linux-old/drivers/i2c/i2c-philips-par.c Fri Feb 20 01:22:16 2004 ++++ linux/drivers/i2c/i2c-philips-par.c Mon Dec 13 19:26:34 2004 +@@ -21,7 +21,7 @@ + /* With some changes from Kyösti Mälkki and even + Frodo Looijaard */ + +-/* $Id: i2c-philips-par.c,v 1.18 2000/07/06 19:21:49 frodo Exp $ */ ++/* $Id: i2c-philips-par.c,v 1.33 2004/01/23 20:22:53 khali Exp $ */ + + #include + #include +@@ -29,14 +29,10 @@ + #include + #include + #include +- ++#include + #include + #include + +-#ifndef __exit +-#define __exit __init +-#endif +- + static int type; + + struct i2c_par +@@ -130,59 +126,34 @@ + PARPORT_STATUS_BUSY) ? 0 : 1; + } + +-static int bit_lp_reg(struct i2c_client *client) +-{ +- return 0; +-} +- +-static int bit_lp_unreg(struct i2c_client *client) +-{ +- return 0; +-} +- +-static void bit_lp_inc_use(struct i2c_adapter *adap) +-{ +- MOD_INC_USE_COUNT; +-} +- +-static void bit_lp_dec_use(struct i2c_adapter *adap) +-{ +- MOD_DEC_USE_COUNT; +-} +- + /* ------------------------------------------------------------------------ + * Encapsulate the above functions in the correct operations structure. + * This is only done when more than one hardware adapter is supported. + */ + + static struct i2c_algo_bit_data bit_lp_data = { +- NULL, +- bit_lp_setsda, +- bit_lp_setscl, +- bit_lp_getsda, +- bit_lp_getscl, +- 80, 80, 100, /* waits, timeout */ ++ .setsda = bit_lp_setsda, ++ .setscl = bit_lp_setscl, ++ .getsda = bit_lp_getsda, ++ .getscl = bit_lp_getscl, ++ .udelay = 80, ++ .mdelay = 80, ++ .timeout = HZ + }; + + static struct i2c_algo_bit_data bit_lp_data2 = { +- NULL, +- bit_lp_setsda2, +- bit_lp_setscl2, +- bit_lp_getsda2, +- NULL, +- 80, 80, 100, /* waits, timeout */ ++ .setsda = bit_lp_setsda2, ++ .setscl = bit_lp_setscl2, ++ .getsda = bit_lp_getsda2, ++ .udelay = 80, ++ .mdelay = 80, ++ .timeout = HZ + }; + + static struct i2c_adapter bit_lp_ops = { +- "Philips Parallel port adapter", +- I2C_HW_B_LP, +- NULL, +- NULL, +- bit_lp_inc_use, +- bit_lp_dec_use, +- bit_lp_reg, +- +- bit_lp_unreg, ++ .owner = THIS_MODULE, ++ .name = "Philips Parallel port adapter", ++ .id = I2C_HW_B_LP, + }; + + static void i2c_parport_attach (struct parport *port) +@@ -202,6 +173,7 @@ + NULL); + if (!adapter->pdev) { + printk(KERN_ERR "i2c-philips-par: Unable to register with parport.\n"); ++ kfree(adapter); + return; + } + +@@ -210,8 +182,12 @@ + adapter->bit_lp_data = type ? bit_lp_data2 : bit_lp_data; + adapter->bit_lp_data.data = port; + ++ if (parport_claim_or_block(adapter->pdev) < 0 ) { ++ printk(KERN_ERR "i2c-philips-par: Could not claim parallel port.\n"); ++ kfree(adapter); ++ return; ++ } + /* reset hardware to sane state */ +- parport_claim_or_block(adapter->pdev); + adapter->bit_lp_data.setsda(port, 1); + adapter->bit_lp_data.setscl(port, 1); + parport_release(adapter->pdev); +@@ -257,7 +233,7 @@ + NULL + }; + +-int __init i2c_bitlp_init(void) ++static int __init i2c_bitlp_init(void) + { + printk(KERN_INFO "i2c-philips-par.o: i2c Philips parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); + +@@ -266,7 +242,7 @@ + return 0; + } + +-void __exit i2c_bitlp_exit(void) ++static void __exit i2c_bitlp_exit(void) + { + parport_unregister_driver(&i2c_driver); + } +@@ -279,14 +255,5 @@ + + MODULE_PARM(type, "i"); + +-#ifdef MODULE +-int init_module(void) +-{ +- return i2c_bitlp_init(); +-} +- +-void cleanup_module(void) +-{ +- i2c_bitlp_exit(); +-} +-#endif ++module_init(i2c_bitlp_init); ++module_exit(i2c_bitlp_exit); +--- linux-old/drivers/i2c/i2c-pport.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-pport.c Mon Dec 13 19:26:34 2004 +@@ -0,0 +1,169 @@ ++/* ------------------------------------------------------------------------- */ ++/* i2c-pport.c i2c-hw access for primitive i2c par. port adapter */ ++/* ------------------------------------------------------------------------- */ ++/* Copyright (C) 2001 Daniel Smolik ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ ++/* ------------------------------------------------------------------------- */ ++ ++/* ++ See doc/i2c-pport for instructions on wiring to the ++ parallel port connector. ++ ++ Cut & paste :-) based on Velleman K8000 driver by Simon G. Vogl ++ ++ Note that SDA is hardware inverted. ++*/ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define DEFAULT_BASE 0x378 ++static int base = DEFAULT_BASE; ++static unsigned char PortData = 0; ++ ++/* ----- global defines ----------------------------------------------- */ ++#define DEB(x) /* should be reasonable open, close &c. */ ++#define DEB2(x) /* low level debugging - very slow */ ++#define DEBE(x) x /* error messages */ ++#define DEBINIT(x) x /* detection status messages */ ++ ++/* --- Convenience defines for the parallel port: */ ++#define BASE (unsigned int)(data) ++#define DATA BASE /* Centronics data port */ ++#define STAT (BASE+1) /* Centronics status port */ ++#define CTRL (BASE+2) /* Centronics control port */ ++ ++/* we will use SDA - Auto Linefeed(14) POUT (ctrl bit 1) */ ++/* we will use SCL - Initialize printer(16) BUSY (ctrl bit 2) */ ++ ++#define SET_SCL | 0x04 ++#define CLR_SCL & 0xFB ++ ++#define SET_SDA & 0xFD ++#define CLR_SDA | 0x02 ++ ++ ++/* ----- local functions ---------------------------------------------- */ ++ ++ ++static void bit_pport_setscl(void *data, int state) ++{ ++ if (state) { ++ PortData = PortData SET_SCL; ++ } else { ++ PortData = PortData CLR_SCL; ++ } ++ outb(PortData, CTRL); ++} ++ ++static void bit_pport_setsda(void *data, int state) ++{ ++ if (state) { ++ PortData = PortData SET_SDA; ++ } else { ++ PortData = PortData CLR_SDA; ++ } ++ outb(PortData, CTRL); ++} ++ ++static int bit_pport_getscl(void *data) ++{ ++ return ( 4 == ( (inb_p(CTRL)) & 0x04 ) ); ++} ++ ++static int bit_pport_getsda(void *data) ++{ ++ return ( 0 == ( (inb_p(CTRL)) & 0x02 ) ); ++} ++ ++static int bit_pport_init(void) ++{ ++ if (!request_region((base+2),1, "i2c (PPORT adapter)")) { ++ return -ENODEV; ++ } ++ ++ PortData = inb(base+2); ++ bit_pport_setsda((void*)base, 1); ++ bit_pport_setscl((void*)base, 1); ++ ++ return 0; ++} ++ ++ ++/* ------------------------------------------------------------------------ ++ * Encapsulate the above functions in the correct operations structure. ++ * This is only done when more than one hardware adapter is supported. ++ */ ++static struct i2c_algo_bit_data bit_pport_data = { ++ .setsda = bit_pport_setsda, ++ .setscl = bit_pport_setscl, ++ .getsda = bit_pport_getsda, ++ .getscl = bit_pport_getscl, ++ .udelay = 40, ++ .mdelay = 80, ++ .timeout = HZ ++}; ++ ++static struct i2c_adapter bit_pport_ops = { ++ .owner = THIS_MODULE, ++ .name = "Primitive Parallel port adaptor", ++ .id = I2C_HW_B_PPORT, ++ .algo_data = &bit_pport_data, ++}; ++ ++static int __init i2c_bitpport_init(void) ++{ ++ printk("i2c-pport.o: i2c Primitive parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); ++ ++ bit_pport_data.data = (void*)base; ++ if (bit_pport_init() < 0) ++ return -ENODEV; ++ ++ if (i2c_bit_add_bus(&bit_pport_ops) < 0) { ++ release_region(base+2, 1); ++ return -ENODEV; ++ } ++ ++ printk("i2c-pport.o: found device at %#x.\n",base); ++ return 0; ++} ++ ++static void __exit i2c_bitpport_exit(void) ++{ ++ i2c_bit_del_bus(&bit_pport_ops); ++ release_region((base+2),1); ++} ++ ++EXPORT_NO_SYMBOLS; ++ ++MODULE_AUTHOR("Daniel Smolik "); ++MODULE_DESCRIPTION("I2C-Bus adapter routines for Primitive parallel port adapter"); ++MODULE_LICENSE("GPL"); ++ ++MODULE_PARM(base, "i"); ++ ++module_init(i2c_bitpport_init); ++module_exit(i2c_bitpport_exit); +--- linux-old/drivers/i2c/i2c-proc.c Tue Jan 20 15:10:31 2004 ++++ linux/drivers/i2c/i2c-proc.c Mon Dec 13 19:26:35 2004 +@@ -23,29 +23,26 @@ + This driver puts entries in /proc/sys/dev/sensors for each I2C device + */ + ++#include + #include + #include + #include + #include + #include + #include ++#include + #include +-#include +- + #include + #include ++#include + +-#include +- +-#ifndef THIS_MODULE +-#define THIS_MODULE NULL ++#ifndef CONFIG_SYSCTL ++#error Your kernel lacks sysctl support (CONFIG_SYSCTL)! + #endif + +-static int i2c_create_name(char **name, const char *prefix, +- struct i2c_adapter *adapter, int addr); + static int i2c_parse_reals(int *nrels, void *buffer, int bufsize, + long *results, int magnitude); +-static int i2c_write_reals(int nrels, void *buffer, int *bufsize, ++static int i2c_write_reals(int nrels, void *buffer, size_t *bufsize, + long *results, int magnitude); + static int i2c_proc_chips(ctl_table * ctl, int write, + struct file *filp, void *buffer, +@@ -55,22 +52,10 @@ + void *newval, size_t newlen, + void **context); + +-int __init sensors_init(void); +- + #define SENSORS_ENTRY_MAX 20 + static struct ctl_table_header *i2c_entries[SENSORS_ENTRY_MAX]; + + static struct i2c_client *i2c_clients[SENSORS_ENTRY_MAX]; +-static unsigned short i2c_inodes[SENSORS_ENTRY_MAX]; +- +-static ctl_table sysctl_table[] = { +- {CTL_DEV, "dev", NULL, 0, 0555}, +- {0}, +- {DEV_SENSORS, "sensors", NULL, 0, 0555}, +- {0}, +- {0, NULL, NULL, 0, 0555}, +- {0} +-}; + + static ctl_table i2c_proc_dev_sensors[] = { + {SENSORS_CHIPS, "chips", NULL, 0, 0644, NULL, &i2c_proc_chips, +@@ -91,31 +76,45 @@ + + + static struct ctl_table_header *i2c_proc_header; +-static int i2c_initialized; + + /* This returns a nice name for a new directory; for example lm78-isa-0310 + (for a LM78 chip on the ISA bus at port 0x310), or lm75-i2c-3-4e (for + a LM75 chip on the third i2c bus at address 0x4e). + name is allocated first. */ +-int i2c_create_name(char **name, const char *prefix, +- struct i2c_adapter *adapter, int addr) ++static char *generate_name(struct i2c_client *client, const char *prefix) + { +- char name_buffer[50]; +- int id; +- if (i2c_is_isa_adapter(adapter)) ++ struct i2c_adapter *adapter = client->adapter; ++ int addr = client->addr; ++ char name_buffer[50], *name; ++ ++ if (i2c_is_isa_adapter(adapter)) { + sprintf(name_buffer, "%s-isa-%04x", prefix, addr); +- else { +- if ((id = i2c_adapter_id(adapter)) < 0) +- return -ENOENT; ++ } else if (adapter->algo->smbus_xfer || adapter->algo->master_xfer) { ++ int id = i2c_adapter_id(adapter); ++ if (id < 0) ++ return ERR_PTR(-ENOENT); + sprintf(name_buffer, "%s-i2c-%d-%02x", prefix, id, addr); ++ } else { /* dummy adapter, generate prefix */ ++ int end, i; ++ ++ sprintf(name_buffer, "%s-", prefix); ++ end = strlen(name_buffer); ++ ++ for (i = 0; i < 32; i++) { ++ if (adapter->algo->name[i] == ' ') ++ break; ++ name_buffer[end++] = tolower(adapter->algo->name[i]); ++ } ++ ++ name_buffer[end] = 0; ++ sprintf(name_buffer + end, "-%04x", addr); + } +- *name = kmalloc(strlen(name_buffer) + 1, GFP_KERNEL); +- if (!*name) { +- printk (KERN_WARNING "i2c_create_name: not enough memory\n"); +- return -ENOMEM; +- } +- strcpy(*name, name_buffer); +- return 0; ++ ++ name = kmalloc(strlen(name_buffer) + 1, GFP_KERNEL); ++ if (!name) ++ return ERR_PTR(-ENOMEM); ++ strcpy(name, name_buffer); ++ return name; + } + + /* This rather complex function must be called when you want to add an entry +@@ -124,139 +123,91 @@ + ctl_template should be a template of the newly created directory. It is + copied in memory. The extra2 field of each file is set to point to client. + If any driver wants subdirectories within the newly created directory, +- this function must be updated! +- controlling_mod is the controlling module. It should usually be +- THIS_MODULE when calling. Note that this symbol is not defined in +- kernels before 2.3.13; define it to NULL in that case. We will not use it +- for anything older than 2.3.27 anyway. */ ++ this function must be updated! */ + int i2c_register_entry(struct i2c_client *client, const char *prefix, +- ctl_table * ctl_template, +- struct module *controlling_mod) ++ struct ctl_table *ctl_template) + { +- int i, res, len, id; +- ctl_table *new_table; +- char *name; +- struct ctl_table_header *new_header; +- +- if ((res = i2c_create_name(&name, prefix, client->adapter, +- client->addr))) return res; ++ struct { struct ctl_table root[2], dev[2], sensors[2]; } *tbl; ++ struct ctl_table_header *hdr; ++ struct ctl_table *tmp, *leaf; ++ const char *name; ++ int id, len = 0; + +- for (id = 0; id < SENSORS_ENTRY_MAX; id++) +- if (!i2c_entries[id]) { +- break; +- } +- if (id == SENSORS_ENTRY_MAX) { +- kfree(name); +- return -ENOMEM; +- } +- id += 256; ++ name = generate_name(client, prefix); ++ if (IS_ERR(name)) ++ return PTR_ERR(name); + +- len = 0; +- while (ctl_template[len].procname) +- len++; +- len += 7; +- if (!(new_table = kmalloc(sizeof(ctl_table) * len, GFP_KERNEL))) { +- kfree(name); +- return -ENOMEM; +- } +- +- memcpy(new_table, sysctl_table, 6 * sizeof(ctl_table)); +- new_table[0].child = &new_table[2]; +- new_table[2].child = &new_table[4]; +- new_table[4].child = &new_table[6]; +- new_table[4].procname = name; +- new_table[4].ctl_name = id; +- memcpy(new_table + 6, ctl_template, (len - 6) * sizeof(ctl_table)); +- for (i = 6; i < len; i++) +- new_table[i].extra2 = client; +- +- if (!(new_header = register_sysctl_table(new_table, 0))) { +- kfree(new_table); +- kfree(name); +- return -ENOMEM; ++ for (id = 0; id < SENSORS_ENTRY_MAX; id++) { ++ if (!i2c_entries[id]) ++ goto free_slot; + } + +- i2c_entries[id - 256] = new_header; ++ goto out_free_name; + +- i2c_clients[id - 256] = client; +-#ifdef DEBUG +- if (!new_header || !new_header->ctl_table || +- !new_header->ctl_table->child || +- !new_header->ctl_table->child->child || +- !new_header->ctl_table->child->child->de) { +- printk +- ("i2c-proc.o: NULL pointer when trying to install fill_inode fix!\n"); +- return id; +- } +-#endif /* DEBUG */ +- i2c_inodes[id - 256] = +- new_header->ctl_table->child->child->de->low_ino; +- new_header->ctl_table->child->child->de->owner = controlling_mod; +- +- return id; ++ free_slot: ++ while (ctl_template[len].ctl_name) ++ len++; ++ tbl = kmalloc(sizeof(*tbl) + sizeof(ctl_table) * (len + 1), ++ GFP_KERNEL); ++ if (!tbl) ++ goto out_free_name; ++ memset(tbl, 0, sizeof(*tbl)); ++ ++ /* The client sysctls */ ++ leaf = (struct ctl_table *) (tbl + 1); ++ memcpy(leaf, ctl_template, sizeof(ctl_table) * (len+1)); ++ for (tmp = leaf; tmp->ctl_name; tmp++) ++ tmp->extra2 = client; ++ ++ tbl->sensors->ctl_name = id+256; ++ tbl->sensors->procname = name; ++ tbl->sensors->mode = 0555; ++ tbl->sensors->child = leaf; ++ ++ tbl->dev->ctl_name = DEV_SENSORS; ++ tbl->dev->procname = "sensors"; ++ tbl->dev->mode = 0555; ++ tbl->dev->child = tbl->sensors; ++ ++ tbl->root->ctl_name = CTL_DEV; ++ tbl->root->procname = "dev"; ++ tbl->root->mode = 0555; ++ tbl->root->child = tbl->dev; ++ ++ hdr = register_sysctl_table(tbl->root, 0); ++ if (!hdr) ++ goto out_free_tbl; ++ ++ i2c_entries[id] = hdr; ++ i2c_clients[id] = client; ++ ++ return (id + 256); /* XXX(hch) why?? */ ++ ++ out_free_tbl: ++ kfree(tbl); ++ out_free_name: ++ kfree(name); ++ return -ENOMEM; + } + + void i2c_deregister_entry(int id) + { +- ctl_table *table; +- char *temp; + id -= 256; +- if (i2c_entries[id]) { +- table = i2c_entries[id]->ctl_table; +- unregister_sysctl_table(i2c_entries[id]); +- /* 2-step kfree needed to keep gcc happy about const points */ +- (const char *) temp = table[4].procname; +- kfree(temp); +- kfree(table); +- i2c_entries[id] = NULL; +- i2c_clients[id] = NULL; +- } +-} + +-/* Monitor access for /proc/sys/dev/sensors; make unloading i2c-proc.o +- impossible if some process still uses it or some file in it */ +-void i2c_fill_inode(struct inode *inode, int fill) +-{ +- if (fill) +- MOD_INC_USE_COUNT; +- else +- MOD_DEC_USE_COUNT; +-} +- +-/* Monitor access for /proc/sys/dev/sensors/ directories; make unloading +- the corresponding module impossible if some process still uses it or +- some file in it */ +-void i2c_dir_fill_inode(struct inode *inode, int fill) +-{ +- int i; +- struct i2c_client *client; ++ if (i2c_entries[id]) { ++ struct ctl_table_header *hdr = i2c_entries[id]; ++ struct ctl_table *tbl = hdr->ctl_table; + +-#ifdef DEBUG +- if (!inode) { +- printk("i2c-proc.o: Warning: inode NULL in fill_inode()\n"); +- return; ++ unregister_sysctl_table(hdr); ++ kfree(tbl->child->child->procname); ++ kfree(tbl); /* actually the whole anonymous struct */ + } +-#endif /* def DEBUG */ + +- for (i = 0; i < SENSORS_ENTRY_MAX; i++) +- if (i2c_clients[i] +- && (i2c_inodes[i] == inode->i_ino)) break; +-#ifdef DEBUG +- if (i == SENSORS_ENTRY_MAX) { +- printk +- ("i2c-proc.o: Warning: inode (%ld) not found in fill_inode()\n", +- inode->i_ino); +- return; +- } +-#endif /* def DEBUG */ +- client = i2c_clients[i]; +- if (fill) +- client->driver->inc_use(client); +- else +- client->driver->dec_use(client); ++ i2c_entries[id] = NULL; ++ i2c_clients[id] = NULL; + } + +-int i2c_proc_chips(ctl_table * ctl, int write, struct file *filp, ++static int i2c_proc_chips(ctl_table * ctl, int write, struct file *filp, + void *buffer, size_t * lenp) + { + char BUF[SENSORS_PREFIX_MAX + 30]; +@@ -294,7 +245,7 @@ + return 0; + } + +-int i2c_sysctl_chips(ctl_table * table, int *name, int nlen, ++static int i2c_sysctl_chips(ctl_table * table, int *name, int nlen, + void *oldval, size_t * oldlenp, void *newval, + size_t newlen, void **context) + { +@@ -456,7 +407,7 @@ + WARNING! This is tricky code. I have tested it, but there may still be + hidden bugs in it, even leading to crashes and things! + */ +-int i2c_parse_reals(int *nrels, void *buffer, int bufsize, ++static int i2c_parse_reals(int *nrels, void *buffer, int bufsize, + long *results, int magnitude) + { + int maxels, min, mag; +@@ -557,7 +508,7 @@ + return 0; + } + +-int i2c_write_reals(int nrels, void *buffer, int *bufsize, ++static int i2c_write_reals(int nrels, void *buffer, size_t *bufsize, + long *results, int magnitude) + { + #define BUFLEN 20 +@@ -646,6 +597,7 @@ + I2C_FUNC_SMBUS_QUICK)) return -1; + + for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) { ++ /* XXX: WTF is going on here??? */ + if ((is_isa && check_region(addr, 1)) || + (!is_isa && i2c_check_addr(adapter, addr))) + continue; +@@ -846,46 +798,33 @@ + return 0; + } + +-int __init sensors_init(void) ++static int __init i2c_proc_init(void) + { + printk(KERN_INFO "i2c-proc.o version %s (%s)\n", I2C_VERSION, I2C_DATE); +- i2c_initialized = 0; + if (! + (i2c_proc_header = +- register_sysctl_table(i2c_proc, 0))) return -ENOMEM; ++ register_sysctl_table(i2c_proc, 0))) { ++ printk(KERN_ERR "i2c-proc.o: error: sysctl interface not supported by kernel!\n"); ++ return -EPERM; ++ } + i2c_proc_header->ctl_table->child->de->owner = THIS_MODULE; +- i2c_initialized++; + return 0; + } + ++static void __exit i2c_proc_exit(void) ++{ ++ unregister_sysctl_table(i2c_proc_header); ++} ++ ++EXPORT_SYMBOL(i2c_register_entry); + EXPORT_SYMBOL(i2c_deregister_entry); +-EXPORT_SYMBOL(i2c_detect); + EXPORT_SYMBOL(i2c_proc_real); +-EXPORT_SYMBOL(i2c_register_entry); + EXPORT_SYMBOL(i2c_sysctl_real); +- +-#ifdef MODULE ++EXPORT_SYMBOL(i2c_detect); + + MODULE_AUTHOR("Frodo Looijaard "); + MODULE_DESCRIPTION("i2c-proc driver"); + MODULE_LICENSE("GPL"); + +-int i2c_cleanup(void) +-{ +- if (i2c_initialized >= 1) { +- unregister_sysctl_table(i2c_proc_header); +- i2c_initialized--; +- } +- return 0; +-} +- +-int init_module(void) +-{ +- return sensors_init(); +-} +- +-int cleanup_module(void) +-{ +- return i2c_cleanup(); +-} +-#endif /* MODULE */ ++module_init(i2c_proc_init); ++module_exit(i2c_proc_exit); +--- linux-old/include/linux/i2c-proc.h Tue Nov 6 00:55:29 2001 ++++ linux/include/linux/i2c-proc.h Mon Dec 13 19:26:36 2004 +@@ -1,6 +1,7 @@ + /* +- sensors.h - Part of lm_sensors, Linux kernel modules for hardware +- monitoring ++ i2c-proc.h - Part of the i2c package ++ was originally sensors.h - Part of lm_sensors, Linux kernel modules ++ for hardware monitoring + Copyright (c) 1998, 1999 Frodo Looijaard + + This program is free software; you can redistribute it and/or modify +@@ -18,14 +19,9 @@ + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +-#ifndef SENSORS_SENSORS_H +-#define SENSORS_SENSORS_H ++#ifndef _LINUX_I2C_PROC_H ++#define _LINUX_I2C_PROC_H + +-#ifdef __KERNEL__ +- +-/* Next two must be included before sysctl.h can be included, in 2.0 kernels */ +-#include +-#include + #include + + /* The type of callback functions used in sensors_{proc,sysctl}_real */ +@@ -73,8 +69,7 @@ + these functions must be updated! */ + extern int i2c_register_entry(struct i2c_client *client, + const char *prefix, +- ctl_table * ctl_template, +- struct module *controlling_mod); ++ ctl_table * ctl_template); + + extern void i2c_deregister_entry(int id); + +@@ -347,6 +342,31 @@ + {NULL}}; \ + SENSORS_INSMOD + ++#define SENSORS_INSMOD_8(chip1,chip2,chip3,chip4,chip5,chip6,chip7,chip8) \ ++ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8 }; \ ++ SENSORS_MODULE_PARM(force, \ ++ "List of adapter,address pairs to boldly assume " \ ++ "to be present"); \ ++ SENSORS_MODULE_PARM_FORCE(chip1); \ ++ SENSORS_MODULE_PARM_FORCE(chip2); \ ++ SENSORS_MODULE_PARM_FORCE(chip3); \ ++ SENSORS_MODULE_PARM_FORCE(chip4); \ ++ SENSORS_MODULE_PARM_FORCE(chip5); \ ++ SENSORS_MODULE_PARM_FORCE(chip6); \ ++ SENSORS_MODULE_PARM_FORCE(chip7); \ ++ SENSORS_MODULE_PARM_FORCE(chip8); \ ++ static struct i2c_force_data forces[] = {{force,any_chip}, \ ++ {force_ ## chip1,chip1}, \ ++ {force_ ## chip2,chip2}, \ ++ {force_ ## chip3,chip3}, \ ++ {force_ ## chip4,chip4}, \ ++ {force_ ## chip5,chip5}, \ ++ {force_ ## chip6,chip6}, \ ++ {force_ ## chip7,chip7}, \ ++ {force_ ## chip8,chip8}, \ ++ {NULL}}; \ ++ SENSORS_INSMOD ++ + typedef int i2c_found_addr_proc(struct i2c_adapter *adapter, + int addr, unsigned short flags, + int kind); +@@ -362,7 +382,7 @@ + + /* This macro is used to scale user-input to sensible values in almost all + chip drivers. */ +-extern inline int SENSORS_LIMIT(long value, long low, long high) ++static inline int SENSORS_LIMIT(long value, long low, long high) + { + if (value < low) + return low; +@@ -372,8 +392,6 @@ + return value; + } + +-#endif /* def __KERNEL__ */ +- + + /* The maximum length of the prefix */ + #define SENSORS_PREFIX_MAX 20 +@@ -392,5 +410,5 @@ + char name[SENSORS_PREFIX_MAX + 13]; + }; + +-#endif /* def SENSORS_SENSORS_H */ ++#endif /* def _LINUX_I2C_PROC_H */ + +--- linux-old/drivers/i2c/i2c-rpx.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-rpx.c Mon Dec 13 19:26:36 2004 +@@ -0,0 +1,101 @@ ++/* ++ * Embedded Planet RPX Lite MPC8xx CPM I2C interface. ++ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net). ++ * ++ * moved into proper i2c interface; ++ * Brad Parker (brad@heeltoe.com) ++ * ++ * RPX lite specific parts of the i2c interface ++ * Update: There actually isn't anything RPXLite-specific about this module. ++ * This should work for most any 8xx board. The console messages have been ++ * changed to eliminate RPXLite references. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++static void ++rpx_iic_init(struct i2c_algo_8xx_data *data) ++{ ++ volatile cpm8xx_t *cp; ++ volatile immap_t *immap; ++ ++ cp = cpmp; /* Get pointer to Communication Processor */ ++ immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ ++ ++ data->iip = (iic_t *)&cp->cp_dparam[PROFF_IIC]; ++ ++ /* Check for and use a microcode relocation patch. ++ */ ++ if ((data->reloc = data->iip->iic_rpbase)) ++ data->iip = (iic_t *)&cp->cp_dpmem[data->iip->iic_rpbase]; ++ ++ data->i2c = (i2c8xx_t *)&(immap->im_i2c); ++ data->cp = cp; ++ ++ /* Initialize Port B IIC pins. ++ */ ++ cp->cp_pbpar |= 0x00000030; ++ cp->cp_pbdir |= 0x00000030; ++ cp->cp_pbodr |= 0x00000030; ++ ++ /* Allocate space for two transmit and two receive buffer ++ * descriptors in the DP ram. ++ */ ++ data->dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 4); ++ ++ /* ptr to i2c area */ ++ data->i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c); ++} ++ ++static int rpx_install_isr(int irq, void (*func)(void *, void *), void *data) ++{ ++ /* install interrupt handler */ ++ cpm_install_handler(irq, (void (*)(void *, struct pt_regs *)) func, data); ++ ++ return 0; ++} ++ ++static struct i2c_algo_8xx_data rpx_data = { ++ .setisr = rpx_install_isr ++}; ++ ++static struct i2c_adapter rpx_ops = { ++ .owner = THIS_MODULE, ++ .name = "m8xx", ++ .id = I2C_HW_MPC8XX_EPON, ++ .algo_data = &rpx_data, ++}; ++ ++static int __init i2c_rpx_init(void) ++{ ++ printk("i2c-rpx.o: i2c MPC8xx module version %s (%s)\n", I2C_VERSION, I2C_DATE); ++ ++ /* reset hardware to sane state */ ++ rpx_iic_init(&rpx_data); ++ ++ if (i2c_8xx_add_bus(&rpx_ops) < 0) { ++ printk("i2c-rpx: Unable to register with I2C\n"); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++static void __exit i2c_rpx_exit(void) ++{ ++ i2c_8xx_del_bus(&rpx_ops); ++} ++ ++MODULE_AUTHOR("Dan Malek "); ++MODULE_DESCRIPTION("I2C-Bus adapter routines for MPC8xx boards"); ++ ++module_init(i2c_rpx_init); ++module_exit(i2c_rpx_exit); +--- linux-old/drivers/i2c/i2c-velleman.c Tue Jan 20 15:10:31 2004 ++++ linux/drivers/i2c/i2c-velleman.c Mon Dec 13 19:26:36 2004 +@@ -18,18 +18,18 @@ + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + /* ------------------------------------------------------------------------- */ + +-/* $Id: i2c-velleman.c,v 1.19 2000/01/24 02:06:33 mds Exp $ */ ++/* $Id: i2c-velleman.c,v 1.33 2003/12/24 17:49:44 khali Exp $ */ + + #include + #include + #include + #include +-#include /* for 2.0 kernels to get NULL */ +-#include /* for 2.0 kernels to get ENODEV */ +-#include +- ++#include ++#include + #include + #include ++#include ++#include /* for HZ */ + + /* ----- global defines ----------------------------------------------- */ + #define DEB(x) /* should be reasonable open, close &c. */ +@@ -90,75 +90,38 @@ + + static int bit_velle_init(void) + { +- if (check_region(base,(base == 0x3bc)? 3 : 8) < 0 ) { +- DEBE(printk("i2c-velleman.o: Port %#x already in use.\n", +- base)); ++ if (!request_region(base, (base == 0x3bc) ? 3 : 8, ++ "i2c (Vellemann adapter)")) + return -ENODEV; +- } else { +- request_region(base, (base == 0x3bc)? 3 : 8, +- "i2c (Vellemann adapter)"); +- bit_velle_setsda((void*)base,1); +- bit_velle_setscl((void*)base,1); +- } +- return 0; +-} + +-static void __exit bit_velle_exit(void) +-{ +- release_region( base , (base == 0x3bc)? 3 : 8 ); +-} +- +- +-static int bit_velle_reg(struct i2c_client *client) +-{ +- return 0; +-} +- +-static int bit_velle_unreg(struct i2c_client *client) +-{ ++ bit_velle_setsda((void*)base,1); ++ bit_velle_setscl((void*)base,1); + return 0; + } + +-static void bit_velle_inc_use(struct i2c_adapter *adap) +-{ +-#ifdef MODULE +- MOD_INC_USE_COUNT; +-#endif +-} +- +-static void bit_velle_dec_use(struct i2c_adapter *adap) +-{ +-#ifdef MODULE +- MOD_DEC_USE_COUNT; +-#endif +-} +- + /* ------------------------------------------------------------------------ + * Encapsulate the above functions in the correct operations structure. + * This is only done when more than one hardware adapter is supported. + */ + + static struct i2c_algo_bit_data bit_velle_data = { +- NULL, +- bit_velle_setsda, +- bit_velle_setscl, +- bit_velle_getsda, +- bit_velle_getscl, +- 10, 10, 100, /* waits, timeout */ ++ .setsda = bit_velle_setsda, ++ .setscl = bit_velle_setscl, ++ .getsda = bit_velle_getsda, ++ .getscl = bit_velle_getscl, ++ .udelay = 10, ++ .mdelay = 10, ++ .timeout = HZ + }; + + static struct i2c_adapter bit_velle_ops = { +- "Velleman K8000", +- I2C_HW_B_VELLE, +- NULL, +- &bit_velle_data, +- bit_velle_inc_use, +- bit_velle_dec_use, +- bit_velle_reg, +- bit_velle_unreg, ++ .owner = THIS_MODULE, ++ .name = "Velleman K8000", ++ .id = I2C_HW_B_VELLE, ++ .algo_data = &bit_velle_data, + }; + +-int __init i2c_bitvelle_init(void) ++static int __init i2c_bitvelle_init(void) + { + printk(KERN_INFO "i2c-velleman.o: i2c Velleman K8000 adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); + if (base==0) { +@@ -184,24 +147,19 @@ + return 0; + } + ++static void __exit i2c_bitvelle_exit(void) ++{ ++ i2c_bit_del_bus(&bit_velle_ops); ++ release_region(base, (base == 0x3bc) ? 3 : 8); ++} ++ + EXPORT_NO_SYMBOLS; + +-#ifdef MODULE + MODULE_AUTHOR("Simon G. Vogl "); + MODULE_DESCRIPTION("I2C-Bus adapter routines for Velleman K8000 adapter"); + MODULE_LICENSE("GPL"); + + MODULE_PARM(base, "i"); + +-int init_module(void) +-{ +- return i2c_bitvelle_init(); +-} +- +-void cleanup_module(void) +-{ +- i2c_bit_del_bus(&bit_velle_ops); +- bit_velle_exit(); +-} +- +-#endif ++module_init(i2c_bitvelle_init); ++module_exit(i2c_bitvelle_exit); +--- linux-old/include/linux/i2c.h Tue Jan 20 15:10:34 2004 ++++ linux/include/linux/i2c.h Mon Dec 13 19:26:37 2004 +@@ -23,36 +23,33 @@ + /* With some changes from Kyösti Mälkki and + Frodo Looijaard */ + +-/* $Id: i2c.h,v 1.46 2001/08/31 00:04:07 phil Exp $ */ ++/* $Id: i2c.h,v 1.80 2004/10/07 23:47:17 phil Exp $ */ + +-#ifndef I2C_H +-#define I2C_H ++#ifndef _LINUX_I2C_H ++#define _LINUX_I2C_H + +-#define I2C_DATE "20010830" +-#define I2C_VERSION "2.6.1" ++#define I2C_DATE "20041007" ++#define I2C_VERSION "2.8.8" + +-#include /* id values of adapters et. al. */ ++#include + #include +- +- +-struct i2c_msg; +- +- +-#ifdef __KERNEL__ +- +-/* --- Includes and compatibility declarations ------------------------ */ +- ++#include ++#include + #include +-#include ++#include ++ ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) ++#define MODULE_LICENSE(x) ++#endif + + /* --- General options ------------------------------------------------ */ + +-#define I2C_ALGO_MAX 4 /* control memory consumption */ +-#define I2C_ADAP_MAX 16 ++#define I2C_ADAP_MAX 16 /* control memory consumption */ + #define I2C_DRIVER_MAX 16 + #define I2C_CLIENT_MAX 32 +-#define I2C_DUMMY_MAX 4 + ++struct i2c_msg; + struct i2c_algorithm; + struct i2c_adapter; + struct i2c_client; +@@ -60,7 +57,6 @@ + struct i2c_client_address_data; + union i2c_smbus_data; + +- + /* + * The master routines are the ones normally used to transmit data to devices + * on a bus (or read from them). Apart from two basic transfer functions to +@@ -113,6 +109,8 @@ + extern s32 i2c_smbus_write_block_data(struct i2c_client * client, + u8 command, u8 length, + u8 *values); ++extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, ++ u8 command, u8 *values); + extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client, + u8 command, u8 length, + u8 *values); +@@ -125,6 +123,7 @@ + */ + + struct i2c_driver { ++ struct module *owner; + char name[32]; + int id; + unsigned int flags; /* div., see below */ +@@ -148,18 +147,6 @@ + * with the device. + */ + int (*command)(struct i2c_client *client,unsigned int cmd, void *arg); +- +- /* These two are mainly used for bookkeeping & dynamic unloading of +- * kernel modules. inc_use tells the driver that a client is being +- * used by another module & that it should increase its ref. counter. +- * dec_use is the inverse operation. +- * NB: Make sure you have no circular dependencies, or else you get a +- * deadlock when trying to unload the modules. +- * You should use the i2c_{inc,dec}_use_client functions instead of +- * calling this function directly. +- */ +- void (*inc_use)(struct i2c_client *client); +- void (*dec_use)(struct i2c_client *client); + }; + + /* +@@ -192,6 +179,7 @@ + * to name two of the most common. + */ + struct i2c_algorithm { ++ struct module *owner; /* future use --km */ + char name[32]; /* textual description */ + unsigned int id; + +@@ -221,16 +209,13 @@ + * with the access algorithms necessary to access it. + */ + struct i2c_adapter { ++ struct module *owner; + char name[32]; /* some useful name to identify the adapter */ + unsigned int id;/* == is algo->id | hwdep.struct->id, */ + /* for registered values see below */ + struct i2c_algorithm *algo;/* the algorithm to access the bus */ + void *algo_data; + +- /* --- These may be NULL, but should increase the module use count */ +- void (*inc_use)(struct i2c_adapter *); +- void (*dec_use)(struct i2c_adapter *); +- + /* --- administration stuff. */ + int (*client_register)(struct i2c_client *); + int (*client_unregister)(struct i2c_client *); +@@ -241,11 +226,11 @@ + /* and can be set via the i2c_ioctl call */ + + /* data fields that are valid for all devices */ +- struct semaphore lock; ++ struct semaphore bus; ++ struct semaphore list; + unsigned int flags;/* flags specifying div. data */ + + struct i2c_client *clients[I2C_CLIENT_MAX]; +- int client_count; + + int timeout; + int retries; +@@ -264,6 +249,9 @@ + #define I2C_CLIENT_ALLOW_USE 0x01 /* Client allows access */ + #define I2C_CLIENT_ALLOW_MULTIPLE_USE 0x02 /* Allow multiple access-locks */ + /* on an i2c_client */ ++#define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */ ++#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */ ++ /* Must equal I2C_M_TEN below */ + + /* i2c_client_address_data is the struct for holding default client + * addresses for a driver and for the parameters supplied on the +@@ -302,12 +290,6 @@ + extern int i2c_attach_client(struct i2c_client *); + extern int i2c_detach_client(struct i2c_client *); + +-/* Only call these if you grab a resource that makes unloading the +- client and the adapter it is on completely impossible. Like when a +- /proc directory is entered. */ +-extern void i2c_inc_use_client(struct i2c_client *); +-extern void i2c_dec_use_client(struct i2c_client *); +- + /* New function: This is to get an i2c_client-struct for controlling the + client either by using i2c_control-function or having the + client-module export functions that can be used with the i2c_client +@@ -341,6 +323,15 @@ + struct i2c_client_address_data *address_data, + i2c_client_found_addr_proc *found_proc); + ++static inline int i2c_client_command(struct i2c_client *client, ++ unsigned int cmd, void *arg) ++{ ++ if (client->driver && client->driver->command) ++ return client->driver->command(client, cmd, arg); ++ else ++ return -EINVAL; ++} ++ + /* An ioctl like call to set div. parameters of the adapter. + */ + extern int i2c_control(struct i2c_client *,unsigned int, unsigned long); +@@ -358,8 +349,6 @@ + /* Return 1 if adapter supports everything we need, 0 if not. */ + extern int i2c_check_functionality (struct i2c_adapter *adap, u32 func); + +-#endif /* __KERNEL__ */ +- + /* + * I2C Message - used for pure i2c transaction, also from /dev interface + */ +@@ -370,15 +359,28 @@ + #define I2C_M_RD 0x01 + #define I2C_M_NOSTART 0x4000 + #define I2C_M_REV_DIR_ADDR 0x2000 ++#define I2C_M_IGNORE_NAK 0x1000 ++#define I2C_M_NO_RD_ACK 0x0800 ++#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ ++#define I2C_M_RECV_PEC 0x0200 /* receive one more than the returned ++ length byte for the PEC */ + __u16 len; /* msg length */ + __u8 *buf; /* pointer to msg data */ ++ int err; ++ short done; + }; + + /* To determine what functionality is present */ + + #define I2C_FUNC_I2C 0x00000001 + #define I2C_FUNC_10BIT_ADDR 0x00000002 +-#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART} */ ++#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */ ++#define I2C_FUNC_SMBUS_HWPEC_CALC 0x00000008 /* SMBus 2.0 */ ++#define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC 0x00000800 /* SMBus 2.0 */ ++#define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000 /* SMBus 2.0 */ ++#define I2C_FUNC_SMBUS_PROC_CALL_PEC 0x00002000 /* SMBus 2.0 */ ++#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000 /* SMBus 2.0 */ ++#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */ + #define I2C_FUNC_SMBUS_QUICK 0x00010000 + #define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 + #define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 +@@ -389,8 +391,12 @@ + #define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 + #define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 + #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 +-#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* New I2C-like block */ +-#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* transfer */ ++#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */ ++#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */ ++#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */ ++#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */ ++#define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000 /* SMBus 2.0 */ ++#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */ + + #define I2C_FUNC_SMBUS_BYTE I2C_FUNC_SMBUS_READ_BYTE | \ + I2C_FUNC_SMBUS_WRITE_BYTE +@@ -402,13 +408,28 @@ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA + #define I2C_FUNC_SMBUS_I2C_BLOCK I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK ++#define I2C_FUNC_SMBUS_I2C_BLOCK_2 I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \ ++ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 ++#define I2C_FUNC_SMBUS_BLOCK_DATA_PEC I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC | \ ++ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC ++#define I2C_FUNC_SMBUS_WORD_DATA_PEC I2C_FUNC_SMBUS_READ_WORD_DATA_PEC | \ ++ I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC ++ ++#define I2C_FUNC_SMBUS_READ_BYTE_PEC I2C_FUNC_SMBUS_READ_BYTE_DATA ++#define I2C_FUNC_SMBUS_WRITE_BYTE_PEC I2C_FUNC_SMBUS_WRITE_BYTE_DATA ++#define I2C_FUNC_SMBUS_READ_BYTE_DATA_PEC I2C_FUNC_SMBUS_READ_WORD_DATA ++#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA_PEC I2C_FUNC_SMBUS_WRITE_WORD_DATA ++#define I2C_FUNC_SMBUS_BYTE_PEC I2C_FUNC_SMBUS_BYTE_DATA ++#define I2C_FUNC_SMBUS_BYTE_DATA_PEC I2C_FUNC_SMBUS_WORD_DATA + + #define I2C_FUNC_SMBUS_EMUL I2C_FUNC_SMBUS_QUICK | \ + I2C_FUNC_SMBUS_BYTE | \ + I2C_FUNC_SMBUS_BYTE_DATA | \ + I2C_FUNC_SMBUS_WORD_DATA | \ + I2C_FUNC_SMBUS_PROC_CALL | \ +- I2C_FUNC_SMBUS_WRITE_BLOCK_DATA ++ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ ++ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \ ++ I2C_FUNC_SMBUS_I2C_BLOCK + + /* + * Data for SMBus Messages +@@ -418,8 +439,9 @@ + union i2c_smbus_data { + __u8 byte; + __u16 word; +- __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */ ++ __u8 block[I2C_SMBUS_BLOCK_MAX + 3]; /* block[0] is used for length */ + /* one more for read length in block process call */ ++ /* and one more for PEC */ + }; + + /* smbus_access read or write markers */ +@@ -435,6 +457,11 @@ + #define I2C_SMBUS_PROC_CALL 4 + #define I2C_SMBUS_BLOCK_DATA 5 + #define I2C_SMBUS_I2C_BLOCK_DATA 6 ++#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ ++#define I2C_SMBUS_BLOCK_DATA_PEC 8 /* SMBus 2.0 */ ++#define I2C_SMBUS_PROC_CALL_PEC 9 /* SMBus 2.0 */ ++#define I2C_SMBUS_BLOCK_PROC_CALL_PEC 10 /* SMBus 2.0 */ ++#define I2C_SMBUS_WORD_DATA_PEC 11 /* SMBus 2.0 */ + + + /* ----- commands for the ioctl like i2c_command call: +@@ -460,6 +487,7 @@ + + #define I2C_FUNCS 0x0705 /* Get the adapter functionality */ + #define I2C_RDWR 0x0707 /* Combined R/W transfer (one stop only)*/ ++#define I2C_PEC 0x0708 /* != 0 for SMBus PEC */ + #if 0 + #define I2C_ACK_TEST 0x0710 /* See if a slave is at a specific address */ + #endif +@@ -475,16 +503,6 @@ + + #define I2C_MAJOR 89 /* Device major number */ + +-#ifdef __KERNEL__ +- +-# ifndef NULL +-# define NULL ( (void *) 0 ) +-# endif +- +-# ifndef ENODEV +-# include +-# endif +- + /* These defines are used for probing i2c client addresses */ + /* Default fill of many variables */ + #define I2C_CLIENT_DEFAULTS {I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ +@@ -546,5 +564,11 @@ + #define i2c_is_isa_adapter(adapptr) \ + ((adapptr)->algo->id == I2C_ALGO_ISA) + +-#endif /* def __KERNEL__ */ +-#endif /* I2C_H */ ++/* Tiny delay function used by the i2c bus drivers */ ++static inline void i2c_delay(signed long timeout) ++{ ++ set_current_state(TASK_INTERRUPTIBLE); ++ schedule_timeout(timeout); ++} ++ ++#endif /* _LINUX_I2C_H */ diff --git a/packages/linux/linux-mtx-2-2.4.27/17-lmsensors.2.8.8.patch b/packages/linux/linux-mtx-2-2.4.27/17-lmsensors.2.8.8.patch new file mode 100644 index 0000000000..3b288e6351 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/17-lmsensors.2.8.8.patch @@ -0,0 +1,40940 @@ +--- linux-old/drivers/i2c/i2c-ali1535.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-ali1535.c Mon Dec 13 20:18:40 2004 +@@ -0,0 +1,601 @@ ++/* ++ i2c-ali1535.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 2000 Frodo Looijaard , ++ Philip Edelbrock , ++ Mark D. Studebaker , ++ Dan Eaton and ++ Stephen Rousset ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ This is the driver for the SMB Host controller on ++ Acer Labs Inc. (ALI) M1535 South Bridge. ++ ++ The M1535 is a South bridge for portable systems. ++ It is very similar to the M15x3 South bridges also produced ++ by Acer Labs Inc. Some of the registers within the part ++ have moved and some have been redefined slightly. Additionally, ++ the sequencing of the SMBus transactions has been modified ++ to be more consistent with the sequencing recommended by ++ the manufacturer and observed through testing. These ++ changes are reflected in this driver and can be identified ++ by comparing this driver to the i2c-ali15x3 driver. ++ For an overview of these chips see http://www.acerlabs.com ++ ++ The SMB controller is part of the 7101 device, which is an ++ ACPI-compliant Power Management Unit (PMU). ++ ++ The whole 7101 device has to be enabled for the SMB to work. ++ You can't just enable the SMB alone. ++ The SMB and the ACPI have separate I/O spaces. ++ We make sure that the SMB is enabled. We leave the ACPI alone. ++ ++ This driver controls the SMB Host only. ++ ++ This driver does not use interrupts. ++*/ ++ ++ ++/* Note: we assume there can only be one ALI1535, with one SMBus interface */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++ ++/* ALI1535 SMBus address offsets */ ++#define SMBHSTSTS (0 + ali1535_smba) ++#define SMBHSTTYP (1 + ali1535_smba) ++#define SMBHSTPORT (2 + ali1535_smba) ++#define SMBHSTCMD (7 + ali1535_smba) ++#define SMBHSTADD (3 + ali1535_smba) ++#define SMBHSTDAT0 (4 + ali1535_smba) ++#define SMBHSTDAT1 (5 + ali1535_smba) ++#define SMBBLKDAT (6 + ali1535_smba) ++ ++/* PCI Address Constants */ ++#define SMBCOM 0x004 ++#define SMBREV 0x008 ++#define SMBCFG 0x0D1 ++#define SMBBA 0x0E2 ++#define SMBHSTCFG 0x0F0 ++#define SMBCLK 0x0F2 ++ ++/* Other settings */ ++#define MAX_TIMEOUT 500 /* times 1/100 sec */ ++#define ALI1535_SMB_IOSIZE 32 ++ ++/* ++*/ ++#define ALI1535_SMB_DEFAULTBASE 0x8040 ++ ++/* ALI1535 address lock bits */ ++#define ALI1535_LOCK 0x06 < dwe > ++ ++/* ALI1535 command constants */ ++#define ALI1535_QUICK 0x00 ++#define ALI1535_BYTE 0x10 ++#define ALI1535_BYTE_DATA 0x20 ++#define ALI1535_WORD_DATA 0x30 ++#define ALI1535_BLOCK_DATA 0x40 ++#define ALI1535_I2C_READ 0x60 ++ ++#define ALI1535_DEV10B_EN 0x80 /* Enable 10-bit addressing in */ ++ /* I2C read */ ++#define ALI1535_T_OUT 0x08 /* Time-out Command (write) */ ++#define ALI1535_A_HIGH_BIT9 0x08 /* Bit 9 of 10-bit address in */ ++ /* Alert-Response-Address */ ++ /* (read) */ ++#define ALI1535_KILL 0x04 /* Kill Command (write) */ ++#define ALI1535_A_HIGH_BIT8 0x04 /* Bit 8 of 10-bit address in */ ++ /* Alert-Response-Address */ ++ /* (read) */ ++ ++#define ALI1535_D_HI_MASK 0x03 /* Mask for isolating bits 9-8 */ ++ /* of 10-bit address in I2C */ ++ /* Read Command */ ++ ++/* ALI1535 status register bits */ ++#define ALI1535_STS_IDLE 0x04 ++#define ALI1535_STS_BUSY 0x08 /* host busy */ ++#define ALI1535_STS_DONE 0x10 /* transaction complete */ ++#define ALI1535_STS_DEV 0x20 /* device error */ ++#define ALI1535_STS_BUSERR 0x40 /* bus error */ ++#define ALI1535_STS_FAIL 0x80 /* failed bus transaction */ ++#define ALI1535_STS_ERR 0xE0 /* all the bad error bits */ ++ ++#define ALI1535_BLOCK_CLR 0x04 /* reset block data index */ ++ ++/* ALI1535 device address register bits */ ++#define ALI1535_RD_ADDR 0x01 /* Read/Write Bit in Device */ ++ /* Address field */ ++ /* -> Write = 0 */ ++ /* -> Read = 1 */ ++#define ALI1535_SMBIO_EN 0x04 /* SMB I/O Space enable */ ++ ++static int ali1535_transaction(void); ++ ++static unsigned short ali1535_smba = 0; ++DECLARE_MUTEX(i2c_ali1535_sem); ++ ++ ++/* Detect whether a ALI1535 can be found, and initialize it, where necessary. ++ Note the differences between kernels with the old PCI BIOS interface and ++ newer kernels with the real PCI interface. In compat.h some things are ++ defined to make the transition easier. */ ++int ali1535_setup(struct pci_dev *ALI1535_dev) ++{ ++ int error_return = 0; ++ unsigned char temp; ++ ++/* Check the following things: ++ - SMB I/O address is initialized ++ - Device is enabled ++ - We can use the addresses ++*/ ++ ++/* Determine the address of the SMBus area */ ++ pci_read_config_word(ALI1535_dev, SMBBA, &ali1535_smba); ++ ali1535_smba &= (0xffff & ~(ALI1535_SMB_IOSIZE - 1)); ++ if (ali1535_smba == 0) { ++ printk ++ ("i2c-ali1535.o: ALI1535_smb region uninitialized - upgrade BIOS?\n"); ++ error_return = -ENODEV; ++ } ++ ++ if (error_return == -ENODEV) ++ goto END; ++ ++ if (check_region(ali1535_smba, ALI1535_SMB_IOSIZE)) { ++ printk ++ ("i2c-ali1535.o: ALI1535_smb region 0x%x already in use!\n", ++ ali1535_smba); ++ error_return = -ENODEV; ++ } ++ ++ if (error_return == -ENODEV) ++ goto END; ++ ++ /* check if whole device is enabled */ ++ pci_read_config_byte(ALI1535_dev, SMBCFG, &temp); ++ if ((temp & ALI1535_SMBIO_EN) == 0) { ++ printk ++ ("i2c-ali1535.o: SMB device not enabled - upgrade BIOS?\n"); ++ error_return = -ENODEV; ++ goto END; ++ } ++ ++/* Is SMB Host controller enabled? */ ++ pci_read_config_byte(ALI1535_dev, SMBHSTCFG, &temp); ++ if ((temp & 1) == 0) { ++ printk ++ ("i2c-ali1535.o: SMBus controller not enabled - upgrade BIOS?\n"); ++ error_return = -ENODEV; ++ goto END; ++ } ++ ++/* set SMB clock to 74KHz as recommended in data sheet */ ++ pci_write_config_byte(ALI1535_dev, SMBCLK, 0x20); ++ ++ /* Everything is happy, let's grab the memory and set things up. */ ++ request_region(ali1535_smba, ALI1535_SMB_IOSIZE, "ali1535-smb"); ++ ++#ifdef DEBUG ++/* ++ The interrupt routing for SMB is set up in register 0x77 in the ++ 1533 ISA Bridge device, NOT in the 7101 device. ++ Don't bother with finding the 1533 device and reading the register. ++ if ((....... & 0x0F) == 1) ++ printk("i2c-ali1535.o: ALI1535 using Interrupt 9 for SMBus.\n"); ++*/ ++ pci_read_config_byte(ALI1535_dev, SMBREV, &temp); ++ printk("i2c-ali1535.o: SMBREV = 0x%X\n", temp); ++ printk("i2c-ali1535.o: ALI1535_smba = 0x%X\n", ali1535_smba); ++#endif /* DEBUG */ ++ ++ END: ++ return error_return; ++} ++ ++ ++/* Another internally used function */ ++int ali1535_transaction(void) ++{ ++ int temp; ++ int result = 0; ++ int timeout = 0; ++ ++#ifdef DEBUG ++ printk ++ ("i2c-ali1535.o: Transaction (pre): STS=%02x, TYP=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, " ++ "DAT1=%02x\n", inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), ++ inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), ++ inb_p(SMBHSTDAT1)); ++#endif ++ ++ /* get status */ ++ temp = inb_p(SMBHSTSTS); ++ ++ /* Make sure the SMBus host is ready to start transmitting */ ++ /* Check the busy bit first */ ++ if (temp & ALI1535_STS_BUSY) { ++/* ++ If the host controller is still busy, it may have timed out in the previous transaction, ++ resulting in a "SMBus Timeout" printk. ++ I've tried the following to reset a stuck busy bit. ++ 1. Reset the controller with an KILL command. ++ (this doesn't seem to clear the controller if an external device is hung) ++ 2. Reset the controller and the other SMBus devices with a T_OUT command. ++ (this clears the host busy bit if an external device is hung, ++ but it comes back upon a new access to a device) ++ 3. Disable and reenable the controller in SMBHSTCFG ++ Worst case, nothing seems to work except power reset. ++*/ ++/* Abort - reset the host controller */ ++/* ++#ifdef DEBUG ++ printk("i2c-ali1535.o: Resetting host controller to clear busy condition\n",temp); ++#endif ++ outb_p(ALI1535_KILL, SMBHSTTYP); ++ temp = inb_p(SMBHSTSTS); ++ if (temp & ALI1535_STS_BUSY) { ++*/ ++ ++/* ++ Try resetting entire SMB bus, including other devices - ++ This may not work either - it clears the BUSY bit but ++ then the BUSY bit may come back on when you try and use the chip again. ++ If that's the case you are stuck. ++*/ ++ printk ++ ("i2c-ali1535.o: Resetting entire SMB Bus to clear busy condition (%02x)\n", ++ temp); ++ outb_p(ALI1535_T_OUT, SMBHSTTYP); ++ temp = inb_p(SMBHSTSTS); ++ } ++/* ++ } ++*/ ++ ++ /* now check the error bits and the busy bit */ ++ if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) { ++ /* do a clear-on-write */ ++ outb_p(0xFF, SMBHSTSTS); ++ if ((temp = inb_p(SMBHSTSTS)) & ++ (ALI1535_STS_ERR | ALI1535_STS_BUSY)) { ++ /* this is probably going to be correctable only by a power reset ++ as one of the bits now appears to be stuck */ ++ /* This may be a bus or device with electrical problems. */ ++ printk ++ ("i2c-ali1535.o: SMBus reset failed! (0x%02x) - controller or device on bus is probably hung\n", ++ temp); ++ return -1; ++ } ++ } else { ++ /* check and clear done bit */ ++ if (temp & ALI1535_STS_DONE) { ++ outb_p(temp, SMBHSTSTS); ++ } ++ } ++ ++ /* start the transaction by writing anything to the start register */ ++ outb_p(0xFF, SMBHSTPORT); ++ ++ /* We will always wait for a fraction of a second! */ ++ timeout = 0; ++ do { ++ i2c_delay(1); ++ temp = inb_p(SMBHSTSTS); ++ } while (((temp & ALI1535_STS_BUSY) && !(temp & ALI1535_STS_IDLE)) ++ && (timeout++ < MAX_TIMEOUT)); ++ ++ /* If the SMBus is still busy, we give up */ ++ if (timeout >= MAX_TIMEOUT) { ++ result = -1; ++ printk("i2c-ali1535.o: SMBus Timeout!\n"); ++ } ++ ++ if (temp & ALI1535_STS_FAIL) { ++ result = -1; ++#ifdef DEBUG ++ printk("i2c-ali1535.o: Error: Failed bus transaction\n"); ++#endif ++ } ++ ++/* ++ Unfortunately the ALI SMB controller maps "no response" and "bus collision" ++ into a single bit. No reponse is the usual case so don't do a printk. ++ This means that bus collisions go unreported. ++*/ ++ if (temp & ALI1535_STS_BUSERR) { ++ result = -1; ++#ifdef DEBUG ++ printk ++ ("i2c-ali1535.o: Error: no response or bus collision ADD=%02x\n", ++ inb_p(SMBHSTADD)); ++#endif ++ } ++ ++/* haven't ever seen this */ ++ if (temp & ALI1535_STS_DEV) { ++ result = -1; ++ printk("i2c-ali1535.o: Error: device error\n"); ++ } ++ ++/* ++ check to see if the "command complete" indication is set ++ */ ++ if (!(temp & ALI1535_STS_DONE)) { ++ result = -1; ++ printk("i2c-ali1535.o: Error: command never completed\n"); ++ } ++#ifdef DEBUG ++ printk ++ ("i2c-ali1535.o: Transaction (post): STS=%02x, TYP=%02x, CMD=%02x, ADD=%02x, " ++ "DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), ++ inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), ++ inb_p(SMBHSTDAT1)); ++#endif ++ ++/* ++ take consequent actions for error conditions ++ */ ++ if (!(temp & ALI1535_STS_DONE)) { ++ /* issue "kill" to reset host controller */ ++ outb_p(ALI1535_KILL,SMBHSTTYP); ++ outb_p(0xFF,SMBHSTSTS); ++ } ++ else if (temp & ALI1535_STS_ERR) { ++ /* issue "timeout" to reset all devices on bus */ ++ outb_p(ALI1535_T_OUT,SMBHSTTYP); ++ outb_p(0xFF,SMBHSTSTS); ++ } ++ ++ return result; ++} ++ ++/* Return -1 on error. */ ++s32 ali1535_access(struct i2c_adapter * adap, u16 addr, ++ unsigned short flags, char read_write, u8 command, ++ int size, union i2c_smbus_data * data) ++{ ++ int i, len; ++ int temp; ++ int timeout; ++ s32 result = 0; ++ ++ down(&i2c_ali1535_sem); ++/* make sure SMBus is idle */ ++ temp = inb_p(SMBHSTSTS); ++ for (timeout = 0; ++ (timeout < MAX_TIMEOUT) && !(temp & ALI1535_STS_IDLE); ++ timeout++) { ++ i2c_delay(1); ++ temp = inb_p(SMBHSTSTS); ++ } ++ if (timeout >= MAX_TIMEOUT) { ++ printk("i2c-ali1535.o: Idle wait Timeout! STS=0x%02x\n", ++ temp); ++ } ++ ++/* clear status register (clear-on-write) */ ++ outb_p(0xFF, SMBHSTSTS); ++ ++ switch (size) { ++ case I2C_SMBUS_QUICK: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ size = ALI1535_QUICK; ++ outb_p(size, SMBHSTTYP); /* output command */ ++ break; ++ case I2C_SMBUS_BYTE: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ size = ALI1535_BYTE; ++ outb_p(size, SMBHSTTYP); /* output command */ ++ if (read_write == I2C_SMBUS_WRITE) ++ outb_p(command, SMBHSTCMD); ++ break; ++ case I2C_SMBUS_BYTE_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ size = ALI1535_BYTE_DATA; ++ outb_p(size, SMBHSTTYP); /* output command */ ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) ++ outb_p(data->byte, SMBHSTDAT0); ++ break; ++ case I2C_SMBUS_WORD_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ size = ALI1535_WORD_DATA; ++ outb_p(size, SMBHSTTYP); /* output command */ ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) { ++ outb_p(data->word & 0xff, SMBHSTDAT0); ++ outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); ++ } ++ break; ++ case I2C_SMBUS_BLOCK_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ size = ALI1535_BLOCK_DATA; ++ outb_p(size, SMBHSTTYP); /* output command */ ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) { ++ len = data->block[0]; ++ if (len < 0) { ++ len = 0; ++ data->block[0] = len; ++ } ++ if (len > 32) { ++ len = 32; ++ data->block[0] = len; ++ } ++ outb_p(len, SMBHSTDAT0); ++ outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP); /* Reset SMBBLKDAT */ ++ for (i = 1; i <= len; i++) ++ outb_p(data->block[i], SMBBLKDAT); ++ } ++ break; ++ default: ++ printk ++ (KERN_WARNING "i2c-ali1535.o: Unsupported transaction %d\n", size); ++ result = -1; ++ goto EXIT; ++ } ++ ++ if (ali1535_transaction()) /* Error in transaction */ ++ { ++ result = -1; ++ goto EXIT; ++ } ++ ++ if ((read_write == I2C_SMBUS_WRITE) || (size == ALI1535_QUICK)) ++ { ++ result = 0; ++ goto EXIT; ++ } ++ ++ switch (size) { ++ case ALI1535_BYTE: /* Result put in SMBHSTDAT0 */ ++ data->byte = inb_p(SMBHSTDAT0); ++ break; ++ case ALI1535_BYTE_DATA: ++ data->byte = inb_p(SMBHSTDAT0); ++ break; ++ case ALI1535_WORD_DATA: ++ data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); ++ break; ++ case ALI1535_BLOCK_DATA: ++ len = inb_p(SMBHSTDAT0); ++ if (len > 32) ++ len = 32; ++ data->block[0] = len; ++ outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP); /* Reset SMBBLKDAT */ ++ for (i = 1; i <= data->block[0]; i++) { ++ data->block[i] = inb_p(SMBBLKDAT); ++#ifdef DEBUG ++ printk ++ ("i2c-ali1535.o: Blk: len=%d, i=%d, data=%02x\n", ++ len, i, data->block[i]); ++#endif /* DEBUG */ ++ } ++ break; ++ } ++EXIT: ++ up(&i2c_ali1535_sem); ++ return result; ++} ++ ++ ++u32 ali1535_func(struct i2c_adapter *adapter) ++{ ++ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | ++ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | ++ I2C_FUNC_SMBUS_BLOCK_DATA; ++} ++ ++static struct i2c_algorithm smbus_algorithm = { ++ .name = "Non-i2c SMBus adapter", ++ .id = I2C_ALGO_SMBUS, ++ .smbus_xfer = ali1535_access, ++ .functionality = ali1535_func, ++}; ++ ++static struct i2c_adapter ali1535_adapter = { ++ .owner = THIS_MODULE, ++ .name = "unset", ++ .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_ALI1535, ++ .algo = &smbus_algorithm, ++}; ++ ++ ++static struct pci_device_id ali1535_ids[] __devinitdata = { ++ { ++ .vendor = PCI_VENDOR_ID_AL, ++ .device = PCI_DEVICE_ID_AL_M7101, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { 0, } ++}; ++ ++static int __devinit ali1535_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ if (ali1535_setup(dev)) { ++ printk ++ ("i2c-ali1535.o: ALI1535 not detected, module not inserted.\n"); ++ return -ENODEV; ++ } ++ ++ sprintf(ali1535_adapter.name, "SMBus ALI1535 adapter at %04x", ++ ali1535_smba); ++ return i2c_add_adapter(&ali1535_adapter); ++} ++ ++static void __devexit ali1535_remove(struct pci_dev *dev) ++{ ++ i2c_del_adapter(&ali1535_adapter); ++ release_region(ali1535_smba, ALI1535_SMB_IOSIZE); ++} ++ ++ ++static struct pci_driver ali1535_driver = { ++ .name = "ali1535 smbus", ++ .id_table = ali1535_ids, ++ .probe = ali1535_probe, ++ .remove = __devexit_p(ali1535_remove), ++}; ++ ++static int __init i2c_ali1535_init(void) ++{ ++ printk("i2c-ali1535.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return pci_module_init(&ali1535_driver); ++} ++ ++ ++static void __exit i2c_ali1535_exit(void) ++{ ++ pci_unregister_driver(&ali1535_driver); ++} ++ ++#ifdef RLX ++EXPORT_SYMBOL(ali1535_smba); ++EXPORT_SYMBOL(ali1535_access); ++EXPORT_SYMBOL(i2c_ali1535_sem); ++#endif ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard , Philip Edelbrock , " ++ "Mark D. Studebaker and Dan Eaton "); ++MODULE_DESCRIPTION("ALI1535 SMBus driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(i2c_ali1535_init); ++module_exit(i2c_ali1535_exit); ++ +--- linux-old/drivers/i2c/i2c-ali15x3.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-ali15x3.c Mon Dec 13 20:18:40 2004 +@@ -0,0 +1,533 @@ ++/* ++ ali15x3.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1999 Frodo Looijaard and ++ Philip Edelbrock and ++ Mark D. Studebaker ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ This is the driver for the SMB Host controller on ++ Acer Labs Inc. (ALI) M1541 and M1543C South Bridges. ++ ++ The M1543C is a South bridge for desktop systems. ++ The M1533 is a South bridge for portable systems. ++ They are part of the following ALI chipsets: ++ "Aladdin Pro 2": Includes the M1621 Slot 1 North bridge ++ with AGP and 100MHz CPU Front Side bus ++ "Aladdin V": Includes the M1541 Socket 7 North bridge ++ with AGP and 100MHz CPU Front Side bus ++ "Aladdin IV": Includes the M1541 Socket 7 North bridge ++ with host bus up to 83.3 MHz. ++ For an overview of these chips see http://www.acerlabs.com ++ ++ The M1533/M1543C devices appear as FOUR separate devices ++ on the PCI bus. An output of lspci will show something similar ++ to the following: ++ ++ 00:02.0 USB Controller: Acer Laboratories Inc. M5237 ++ 00:03.0 Bridge: Acer Laboratories Inc. M7101 ++ 00:07.0 ISA bridge: Acer Laboratories Inc. M1533 ++ 00:0f.0 IDE interface: Acer Laboratories Inc. M5229 ++ ++ The SMB controller is part of the 7101 device, which is an ++ ACPI-compliant Power Management Unit (PMU). ++ ++ The whole 7101 device has to be enabled for the SMB to work. ++ You can't just enable the SMB alone. ++ The SMB and the ACPI have separate I/O spaces. ++ We make sure that the SMB is enabled. We leave the ACPI alone. ++ ++ This driver controls the SMB Host only. ++ The SMB Slave controller on the M15X3 is not enabled. ++ ++ This driver does not use interrupts. ++*/ ++ ++/* Note: we assume there can only be one ALI15X3, with one SMBus interface */ ++ ++/* #define DEBUG 1 */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++ ++/* ALI15X3 SMBus address offsets */ ++#define SMBHSTSTS (0 + ali15x3_smba) ++#define SMBHSTCNT (1 + ali15x3_smba) ++#define SMBHSTSTART (2 + ali15x3_smba) ++#define SMBHSTCMD (7 + ali15x3_smba) ++#define SMBHSTADD (3 + ali15x3_smba) ++#define SMBHSTDAT0 (4 + ali15x3_smba) ++#define SMBHSTDAT1 (5 + ali15x3_smba) ++#define SMBBLKDAT (6 + ali15x3_smba) ++ ++/* PCI Address Constants */ ++#define SMBCOM 0x004 ++#define SMBBA 0x014 ++#define SMBATPC 0x05B /* used to unlock xxxBA registers */ ++#define SMBHSTCFG 0x0E0 ++#define SMBSLVC 0x0E1 ++#define SMBCLK 0x0E2 ++#define SMBREV 0x008 ++ ++/* Other settings */ ++#define MAX_TIMEOUT 200 /* times 1/100 sec */ ++#define ALI15X3_SMB_IOSIZE 32 ++ ++/* this is what the Award 1004 BIOS sets them to on a ASUS P5A MB. ++ We don't use these here. If the bases aren't set to some value we ++ tell user to upgrade BIOS and we fail. ++*/ ++#define ALI15X3_SMB_DEFAULTBASE 0xE800 ++ ++/* ALI15X3 address lock bits */ ++#define ALI15X3_LOCK 0x06 ++ ++/* ALI15X3 command constants */ ++#define ALI15X3_ABORT 0x02 ++#define ALI15X3_T_OUT 0x04 ++#define ALI15X3_QUICK 0x00 ++#define ALI15X3_BYTE 0x10 ++#define ALI15X3_BYTE_DATA 0x20 ++#define ALI15X3_WORD_DATA 0x30 ++#define ALI15X3_BLOCK_DATA 0x40 ++#define ALI15X3_BLOCK_CLR 0x80 ++ ++/* ALI15X3 status register bits */ ++#define ALI15X3_STS_IDLE 0x04 ++#define ALI15X3_STS_BUSY 0x08 ++#define ALI15X3_STS_DONE 0x10 ++#define ALI15X3_STS_DEV 0x20 /* device error */ ++#define ALI15X3_STS_COLL 0x40 /* collision or no response */ ++#define ALI15X3_STS_TERM 0x80 /* terminated by abort */ ++#define ALI15X3_STS_ERR 0xE0 /* all the bad error bits */ ++ ++ ++/* If force_addr is set to anything different from 0, we forcibly enable ++ the device at the given address. */ ++static int force_addr = 0; ++MODULE_PARM(force_addr, "i"); ++MODULE_PARM_DESC(force_addr, ++ "Initialize the base address of the i2c controller"); ++ ++static unsigned short ali15x3_smba = 0; ++ ++static int ali15x3_setup(struct pci_dev *ALI15X3_dev) ++{ ++ u16 a; ++ unsigned char temp; ++ ++ /* Check the following things: ++ - SMB I/O address is initialized ++ - Device is enabled ++ - We can use the addresses ++ */ ++ ++ /* Unlock the register. ++ The data sheet says that the address registers are read-only ++ if the lock bits are 1, but in fact the address registers ++ are zero unless you clear the lock bits. ++ */ ++ pci_read_config_byte(ALI15X3_dev, SMBATPC, &temp); ++ if (temp & ALI15X3_LOCK) { ++ temp &= ~ALI15X3_LOCK; ++ pci_write_config_byte(ALI15X3_dev, SMBATPC, temp); ++ } ++ ++ /* Determine the address of the SMBus area */ ++ pci_read_config_word(ALI15X3_dev, SMBBA, &ali15x3_smba); ++ ali15x3_smba &= (0xffff & ~(ALI15X3_SMB_IOSIZE - 1)); ++ if (ali15x3_smba == 0 && force_addr == 0) { ++ dev_err(ALI15X3_dev, "ALI15X3_smb region uninitialized " ++ "- upgrade BIOS or use force_addr=0xaddr\n"); ++ return -ENODEV; ++ } ++ ++ if(force_addr) ++ ali15x3_smba = force_addr & ~(ALI15X3_SMB_IOSIZE - 1); ++ ++ if (!request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE, "ali15x3-smb")) { ++ dev_err(ALI15X3_dev, ++ "ALI15X3_smb region 0x%x already in use!\n", ++ ali15x3_smba); ++ return -ENODEV; ++ } ++ ++ if(force_addr) { ++ dev_info(ALI15X3_dev, "forcing ISA address 0x%04X\n", ++ ali15x3_smba); ++ if (PCIBIOS_SUCCESSFUL != ++ pci_write_config_word(ALI15X3_dev, SMBBA, ali15x3_smba)) ++ return -ENODEV; ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_word(ALI15X3_dev, SMBBA, &a)) ++ return -ENODEV; ++ if ((a & ~(ALI15X3_SMB_IOSIZE - 1)) != ali15x3_smba) { ++ /* make sure it works */ ++ dev_err(ALI15X3_dev, ++ "force address failed - not supported?\n"); ++ return -ENODEV; ++ } ++ } ++ /* check if whole device is enabled */ ++ pci_read_config_byte(ALI15X3_dev, SMBCOM, &temp); ++ if ((temp & 1) == 0) { ++ dev_info(ALI15X3_dev, "enabling SMBus device\n"); ++ pci_write_config_byte(ALI15X3_dev, SMBCOM, temp | 0x01); ++ } ++ ++ /* Is SMB Host controller enabled? */ ++ pci_read_config_byte(ALI15X3_dev, SMBHSTCFG, &temp); ++ if ((temp & 1) == 0) { ++ dev_info(ALI15X3_dev, "enabling SMBus controller\n"); ++ pci_write_config_byte(ALI15X3_dev, SMBHSTCFG, temp | 0x01); ++ } ++ ++ /* set SMB clock to 74KHz as recommended in data sheet */ ++ pci_write_config_byte(ALI15X3_dev, SMBCLK, 0x20); ++ ++ /* ++ The interrupt routing for SMB is set up in register 0x77 in the ++ 1533 ISA Bridge device, NOT in the 7101 device. ++ Don't bother with finding the 1533 device and reading the register. ++ if ((....... & 0x0F) == 1) ++ dev_dbg(ALI15X3_dev, "ALI15X3 using Interrupt 9 for SMBus.\n"); ++ */ ++ pci_read_config_byte(ALI15X3_dev, SMBREV, &temp); ++ dev_dbg(ALI15X3_dev, "SMBREV = 0x%X\n", temp); ++ dev_dbg(ALI15X3_dev, "iALI15X3_smba = 0x%X\n", ali15x3_smba); ++ ++ return 0; ++} ++ ++/* Another internally used function */ ++static int ali15x3_transaction(struct i2c_adapter *adap) ++{ ++ int temp; ++ int result = 0; ++ int timeout = 0; ++ ++ dev_dbg(adap, "Transaction (pre): STS=%02x, CNT=%02x, CMD=%02x, " ++ "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTSTS), ++ inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), ++ inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); ++ ++ /* get status */ ++ temp = inb_p(SMBHSTSTS); ++ ++ /* Make sure the SMBus host is ready to start transmitting */ ++ /* Check the busy bit first */ ++ if (temp & ALI15X3_STS_BUSY) { ++ /* ++ If the host controller is still busy, it may have timed out in the ++ previous transaction, resulting in a "SMBus Timeout" Dev. ++ I've tried the following to reset a stuck busy bit. ++ 1. Reset the controller with an ABORT command. ++ (this doesn't seem to clear the controller if an external ++ device is hung) ++ 2. Reset the controller and the other SMBus devices with a ++ T_OUT command. (this clears the host busy bit if an ++ external device is hung, but it comes back upon a new access ++ to a device) ++ 3. Disable and reenable the controller in SMBHSTCFG ++ Worst case, nothing seems to work except power reset. ++ */ ++ /* Abort - reset the host controller */ ++ /* ++ Try resetting entire SMB bus, including other devices - ++ This may not work either - it clears the BUSY bit but ++ then the BUSY bit may come back on when you try and use the chip again. ++ If that's the case you are stuck. ++ */ ++ dev_info(adap, "Resetting entire SMB Bus to " ++ "clear busy condition (%02x)\n", temp); ++ outb_p(ALI15X3_T_OUT, SMBHSTCNT); ++ temp = inb_p(SMBHSTSTS); ++ } ++ ++ /* now check the error bits and the busy bit */ ++ if (temp & (ALI15X3_STS_ERR | ALI15X3_STS_BUSY)) { ++ /* do a clear-on-write */ ++ outb_p(0xFF, SMBHSTSTS); ++ if ((temp = inb_p(SMBHSTSTS)) & ++ (ALI15X3_STS_ERR | ALI15X3_STS_BUSY)) { ++ /* this is probably going to be correctable only by a power reset ++ as one of the bits now appears to be stuck */ ++ /* This may be a bus or device with electrical problems. */ ++ dev_err(adap, "SMBus reset failed! (0x%02x) - " ++ "controller or device on bus is probably hung\n", ++ temp); ++ return -1; ++ } ++ } else { ++ /* check and clear done bit */ ++ if (temp & ALI15X3_STS_DONE) { ++ outb_p(temp, SMBHSTSTS); ++ } ++ } ++ ++ /* start the transaction by writing anything to the start register */ ++ outb_p(0xFF, SMBHSTSTART); ++ ++ /* We will always wait for a fraction of a second! */ ++ timeout = 0; ++ do { ++ i2c_delay(1); ++ temp = inb_p(SMBHSTSTS); ++ } while ((!(temp & (ALI15X3_STS_ERR | ALI15X3_STS_DONE))) ++ && (timeout++ < MAX_TIMEOUT)); ++ ++ /* If the SMBus is still busy, we give up */ ++ if (timeout >= MAX_TIMEOUT) { ++ result = -1; ++ dev_err(adap, "SMBus Timeout!\n"); ++ } ++ ++ if (temp & ALI15X3_STS_TERM) { ++ result = -1; ++ dev_dbg(adap, "Error: Failed bus transaction\n"); ++ } ++ ++ /* ++ Unfortunately the ALI SMB controller maps "no response" and "bus ++ collision" into a single bit. No reponse is the usual case so don't ++ do a printk. ++ This means that bus collisions go unreported. ++ */ ++ if (temp & ALI15X3_STS_COLL) { ++ result = -1; ++ dev_dbg(adap, ++ "Error: no response or bus collision ADD=%02x\n", ++ inb_p(SMBHSTADD)); ++ } ++ ++ /* haven't ever seen this */ ++ if (temp & ALI15X3_STS_DEV) { ++ result = -1; ++ dev_err(adap, "Error: device error\n"); ++ } ++ dev_dbg(adap, "Transaction (post): STS=%02x, CNT=%02x, CMD=%02x, " ++ "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTSTS), ++ inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), ++ inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); ++ return result; ++} ++ ++/* Return -1 on error. */ ++static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr, ++ unsigned short flags, char read_write, u8 command, ++ int size, union i2c_smbus_data * data) ++{ ++ int i, len; ++ int temp; ++ int timeout; ++ ++ /* clear all the bits (clear-on-write) */ ++ outb_p(0xFF, SMBHSTSTS); ++ /* make sure SMBus is idle */ ++ temp = inb_p(SMBHSTSTS); ++ for (timeout = 0; ++ (timeout < MAX_TIMEOUT) && !(temp & ALI15X3_STS_IDLE); ++ timeout++) { ++ i2c_delay(1); ++ temp = inb_p(SMBHSTSTS); ++ } ++ if (timeout >= MAX_TIMEOUT) { ++ dev_err(adap, "Idle wait Timeout! STS=0x%02x\n", temp); ++ } ++ ++ switch (size) { ++ case I2C_SMBUS_QUICK: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ size = ALI15X3_QUICK; ++ break; ++ case I2C_SMBUS_BYTE: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ if (read_write == I2C_SMBUS_WRITE) ++ outb_p(command, SMBHSTCMD); ++ size = ALI15X3_BYTE; ++ break; ++ case I2C_SMBUS_BYTE_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) ++ outb_p(data->byte, SMBHSTDAT0); ++ size = ALI15X3_BYTE_DATA; ++ break; ++ case I2C_SMBUS_WORD_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) { ++ outb_p(data->word & 0xff, SMBHSTDAT0); ++ outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); ++ } ++ size = ALI15X3_WORD_DATA; ++ break; ++ case I2C_SMBUS_BLOCK_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) { ++ len = data->block[0]; ++ if (len < 0) { ++ len = 0; ++ data->block[0] = len; ++ } ++ if (len > 32) { ++ len = 32; ++ data->block[0] = len; ++ } ++ outb_p(len, SMBHSTDAT0); ++ /* Reset SMBBLKDAT */ ++ outb_p(inb_p(SMBHSTCNT) | ALI15X3_BLOCK_CLR, SMBHSTCNT); ++ for (i = 1; i <= len; i++) ++ outb_p(data->block[i], SMBBLKDAT); ++ } ++ size = ALI15X3_BLOCK_DATA; ++ break; ++ default: ++ printk ++ (KERN_WARNING "i2c-ali15x3.o: Unsupported transaction %d\n", size); ++ return -1; ++ } ++ ++ outb_p(size, SMBHSTCNT); /* output command */ ++ ++ if (ali15x3_transaction(adap)) /* Error in transaction */ ++ return -1; ++ ++ if ((read_write == I2C_SMBUS_WRITE) || (size == ALI15X3_QUICK)) ++ return 0; ++ ++ ++ switch (size) { ++ case ALI15X3_BYTE: /* Result put in SMBHSTDAT0 */ ++ data->byte = inb_p(SMBHSTDAT0); ++ break; ++ case ALI15X3_BYTE_DATA: ++ data->byte = inb_p(SMBHSTDAT0); ++ break; ++ case ALI15X3_WORD_DATA: ++ data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); ++ break; ++ case ALI15X3_BLOCK_DATA: ++ len = inb_p(SMBHSTDAT0); ++ if (len > 32) ++ len = 32; ++ data->block[0] = len; ++ /* Reset SMBBLKDAT */ ++ outb_p(inb_p(SMBHSTCNT) | ALI15X3_BLOCK_CLR, SMBHSTCNT); ++ for (i = 1; i <= data->block[0]; i++) { ++ data->block[i] = inb_p(SMBBLKDAT); ++ dev_dbg(adap, "Blk: len=%d, i=%d, data=%02x\n", ++ len, i, data->block[i]); ++ } ++ break; ++ } ++ return 0; ++} ++ ++static u32 ali15x3_func(struct i2c_adapter *adapter) ++{ ++ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | ++ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | ++ I2C_FUNC_SMBUS_BLOCK_DATA; ++} ++ ++static struct i2c_algorithm smbus_algorithm = { ++ .name = "Non-I2C SMBus adapter", ++ .id = I2C_ALGO_SMBUS, ++ .smbus_xfer = ali15x3_access, ++ .functionality = ali15x3_func, ++}; ++ ++static struct i2c_adapter ali15x3_adapter = { ++ .owner = THIS_MODULE, ++ .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_ALI15X3, ++ .algo = &smbus_algorithm, ++ .name = "unset", ++}; ++ ++static struct pci_device_id ali15x3_ids[] __devinitdata = { ++ { ++ .vendor = PCI_VENDOR_ID_AL, ++ .device = PCI_DEVICE_ID_AL_M7101, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { 0, } ++}; ++ ++static int __devinit ali15x3_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ if (ali15x3_setup(dev)) { ++ dev_err(dev, ++ "ALI15X3 not detected, module not inserted.\n"); ++ return -ENODEV; ++ } ++ ++ snprintf(ali15x3_adapter.name, 32, ++ "SMBus ALI15X3 adapter at %04x", ali15x3_smba); ++ return i2c_add_adapter(&ali15x3_adapter); ++} ++ ++static void __devexit ali15x3_remove(struct pci_dev *dev) ++{ ++ i2c_del_adapter(&ali15x3_adapter); ++ release_region(ali15x3_smba, ALI15X3_SMB_IOSIZE); ++} ++ ++static struct pci_driver ali15x3_driver = { ++ .name = "ali15x3 smbus", ++ .id_table = ali15x3_ids, ++ .probe = ali15x3_probe, ++ .remove = __devexit_p(ali15x3_remove), ++}; ++ ++static int __init i2c_ali15x3_init(void) ++{ ++ printk("i2c-ali15x3.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return pci_module_init(&ali15x3_driver); ++} ++ ++static void __exit i2c_ali15x3_exit(void) ++{ ++ pci_unregister_driver(&ali15x3_driver); ++} ++ ++MODULE_AUTHOR ("Frodo Looijaard , " ++ "Philip Edelbrock , " ++ "and Mark D. Studebaker "); ++MODULE_DESCRIPTION("ALI15X3 SMBus driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(i2c_ali15x3_init); ++module_exit(i2c_ali15x3_exit); +--- linux-old/drivers/i2c/i2c-amd756.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-amd756.c Mon Dec 13 20:18:41 2004 +@@ -0,0 +1,425 @@ ++/* ++ amd756.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ ++ Copyright (c) 1999-2002 Merlin Hughes ++ ++ Shamelessly ripped from i2c-piix4.c: ++ ++ Copyright (c) 1998, 1999 Frodo Looijaard and ++ Philip Edelbrock ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ 2002-04-08: Added nForce support. (Csaba Halasz) ++ 2002-10-03: Fixed nForce PnP I/O port. (Michael Steil) ++ 2002-12-28: Rewritten into something that resembles a Linux driver (hch) ++ 2003-11-29: Added back AMD8111 removed by the previous rewrite. ++ (Philip Pokorny) ++ 2004-02-15: Don't register driver to avoid driver conflicts. ++ (Daniel Rune Jensen) ++*/ ++ ++/* ++ Supports AMD756, AMD766, AMD768, AMD8111 and nVidia nForce ++ Note: we assume there can only be one device, with one SMBus interface. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++#define DRV_NAME "i2c-amd756" ++ ++/* AMD756 SMBus address offsets */ ++#define SMB_ADDR_OFFSET 0xE0 ++#define SMB_IOSIZE 16 ++#define SMB_GLOBAL_STATUS (0x0 + amd756_ioport) ++#define SMB_GLOBAL_ENABLE (0x2 + amd756_ioport) ++#define SMB_HOST_ADDRESS (0x4 + amd756_ioport) ++#define SMB_HOST_DATA (0x6 + amd756_ioport) ++#define SMB_HOST_COMMAND (0x8 + amd756_ioport) ++#define SMB_HOST_BLOCK_DATA (0x9 + amd756_ioport) ++#define SMB_HAS_DATA (0xA + amd756_ioport) ++#define SMB_HAS_DEVICE_ADDRESS (0xC + amd756_ioport) ++#define SMB_HAS_HOST_ADDRESS (0xE + amd756_ioport) ++#define SMB_SNOOP_ADDRESS (0xF + amd756_ioport) ++ ++/* PCI Address Constants */ ++ ++/* address of I/O space */ ++#define SMBBA 0x058 /* mh */ ++#define SMBBANFORCE 0x014 ++ ++/* general configuration */ ++#define SMBGCFG 0x041 /* mh */ ++ ++/* silicon revision code */ ++#define SMBREV 0x008 ++ ++/* Other settings */ ++#define MAX_TIMEOUT 500 ++ ++/* AMD756 constants */ ++#define AMD756_QUICK 0x00 ++#define AMD756_BYTE 0x01 ++#define AMD756_BYTE_DATA 0x02 ++#define AMD756_WORD_DATA 0x03 ++#define AMD756_PROCESS_CALL 0x04 ++#define AMD756_BLOCK_DATA 0x05 ++ ++ ++static unsigned short amd756_ioport = 0; ++ ++/* ++ SMBUS event = I/O 28-29 bit 11 ++ see E0 for the status bits and enabled in E2 ++ ++*/ ++ ++#define GS_ABRT_STS (1 << 0) ++#define GS_COL_STS (1 << 1) ++#define GS_PRERR_STS (1 << 2) ++#define GS_HST_STS (1 << 3) ++#define GS_HCYC_STS (1 << 4) ++#define GS_TO_STS (1 << 5) ++#define GS_SMB_STS (1 << 11) ++ ++#define GS_CLEAR_STS (GS_ABRT_STS | GS_COL_STS | GS_PRERR_STS | \ ++ GS_HCYC_STS | GS_TO_STS ) ++ ++#define GE_CYC_TYPE_MASK (7) ++#define GE_HOST_STC (1 << 3) ++#define GE_ABORT (1 << 5) ++ ++ ++static int amd756_transaction(void) ++{ ++ int temp; ++ int result = 0; ++ int timeout = 0; ++ ++ pr_debug(DRV_NAME ++ ": Transaction (pre): GS=%04x, GE=%04x, ADD=%04x, DAT=%04x\n", ++ inw_p(SMB_GLOBAL_STATUS), inw_p(SMB_GLOBAL_ENABLE), ++ inw_p(SMB_HOST_ADDRESS), inb_p(SMB_HOST_DATA)); ++ ++ /* Make sure the SMBus host is ready to start transmitting */ ++ if ((temp = inw_p(SMB_GLOBAL_STATUS)) & (GS_HST_STS | GS_SMB_STS)) { ++ pr_debug(DRV_NAME ": SMBus busy (%04x). Waiting... \n", temp); ++ do { ++ i2c_delay(1); ++ temp = inw_p(SMB_GLOBAL_STATUS); ++ } while ((temp & (GS_HST_STS | GS_SMB_STS)) && ++ (timeout++ < MAX_TIMEOUT)); ++ /* If the SMBus is still busy, we give up */ ++ if (timeout >= MAX_TIMEOUT) { ++ pr_debug(DRV_NAME ": Busy wait timeout (%04x)\n", temp); ++ goto abort; ++ } ++ timeout = 0; ++ } ++ ++ /* start the transaction by setting the start bit */ ++ outw_p(inw(SMB_GLOBAL_ENABLE) | GE_HOST_STC, SMB_GLOBAL_ENABLE); ++ ++ /* We will always wait for a fraction of a second! */ ++ do { ++ i2c_delay(1); ++ temp = inw_p(SMB_GLOBAL_STATUS); ++ } while ((temp & GS_HST_STS) && (timeout++ < MAX_TIMEOUT)); ++ ++ /* If the SMBus is still busy, we give up */ ++ if (timeout >= MAX_TIMEOUT) { ++ pr_debug(DRV_NAME ": Completion timeout!\n"); ++ goto abort; ++ } ++ ++ if (temp & GS_PRERR_STS) { ++ result = -1; ++ pr_debug(DRV_NAME ": SMBus Protocol error (no response)!\n"); ++ } ++ ++ if (temp & GS_COL_STS) { ++ result = -1; ++ printk(KERN_WARNING DRV_NAME ": SMBus collision!\n"); ++ } ++ ++ if (temp & GS_TO_STS) { ++ result = -1; ++ pr_debug(DRV_NAME ": SMBus protocol timeout!\n"); ++ } ++ ++ if (temp & GS_HCYC_STS) ++ pr_debug(DRV_NAME ": SMBus protocol success!\n"); ++ ++ outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS); ++ ++#ifdef DEBUG ++ if (((temp = inw_p(SMB_GLOBAL_STATUS)) & GS_CLEAR_STS) != 0x00) { ++ pr_debug(DRV_NAME ++ ": Failed reset at end of transaction (%04x)\n", temp); ++ } ++ ++ pr_debug(DRV_NAME ++ ": Transaction (post): GS=%04x, GE=%04x, ADD=%04x, DAT=%04x\n", ++ inw_p(SMB_GLOBAL_STATUS), inw_p(SMB_GLOBAL_ENABLE), ++ inw_p(SMB_HOST_ADDRESS), inb_p(SMB_HOST_DATA)); ++#endif ++ ++ return result; ++ ++ abort: ++ printk(KERN_WARNING DRV_NAME ": Sending abort.\n"); ++ outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE); ++ i2c_delay(100); ++ outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS); ++ return -1; ++} ++ ++/* Return -1 on error. */ ++ ++static s32 amd756_access(struct i2c_adapter * adap, u16 addr, ++ unsigned short flags, char read_write, ++ u8 command, int size, union i2c_smbus_data * data) ++{ ++ int i, len; ++ ++ /** TODO: Should I supporte the 10-bit transfers? */ ++ switch (size) { ++ /* TODO: proc call is supported, I'm just not sure what to do here... */ ++ case I2C_SMBUS_QUICK: ++ outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMB_HOST_ADDRESS); ++ size = AMD756_QUICK; ++ break; ++ case I2C_SMBUS_BYTE: ++ outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMB_HOST_ADDRESS); ++ if (read_write == I2C_SMBUS_WRITE) ++ outb_p(command, SMB_HOST_DATA); ++ size = AMD756_BYTE; ++ break; ++ case I2C_SMBUS_BYTE_DATA: ++ outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMB_HOST_ADDRESS); ++ outb_p(command, SMB_HOST_COMMAND); ++ if (read_write == I2C_SMBUS_WRITE) ++ outw_p(data->byte, SMB_HOST_DATA); ++ size = AMD756_BYTE_DATA; ++ break; ++ case I2C_SMBUS_WORD_DATA: ++ outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMB_HOST_ADDRESS); ++ outb_p(command, SMB_HOST_COMMAND); ++ if (read_write == I2C_SMBUS_WRITE) ++ outw_p(data->word, SMB_HOST_DATA); /* TODO: endian???? */ ++ size = AMD756_WORD_DATA; ++ break; ++ case I2C_SMBUS_BLOCK_DATA: ++ outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMB_HOST_ADDRESS); ++ outb_p(command, SMB_HOST_COMMAND); ++ if (read_write == I2C_SMBUS_WRITE) { ++ len = data->block[0]; ++ if (len < 0) ++ len = 0; ++ if (len > 32) ++ len = 32; ++ outw_p(len, SMB_HOST_DATA); ++ /* i = inw_p(SMBHSTCNT); Reset SMBBLKDAT */ ++ for (i = 1; i <= len; i++) ++ outb_p(data->block[i], ++ SMB_HOST_BLOCK_DATA); ++ } ++ size = AMD756_BLOCK_DATA; ++ break; ++ default: ++ printk ++ (KERN_WARNING "i2c-amd756.o: Unsupported transaction %d\n", size); ++ return -1; ++ } ++ ++ /* How about enabling interrupts... */ ++ outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE); ++ ++ if (amd756_transaction()) /* Error in transaction */ ++ return -1; ++ ++ if ((read_write == I2C_SMBUS_WRITE) || (size == AMD756_QUICK)) ++ return 0; ++ ++ ++ switch (size) { ++ case AMD756_BYTE: ++ data->byte = inw_p(SMB_HOST_DATA); ++ break; ++ case AMD756_BYTE_DATA: ++ data->byte = inw_p(SMB_HOST_DATA); ++ break; ++ case AMD756_WORD_DATA: ++ data->word = inw_p(SMB_HOST_DATA); /* TODO: endian???? */ ++ break; ++ case AMD756_BLOCK_DATA: ++ data->block[0] = inw_p(SMB_HOST_DATA) & 0x3f; ++ if(data->block[0] > 32) ++ data->block[0] = 32; ++ /* i = inw_p(SMBHSTCNT); Reset SMBBLKDAT */ ++ for (i = 1; i <= data->block[0]; i++) ++ data->block[i] = inb_p(SMB_HOST_BLOCK_DATA); ++ break; ++ } ++ ++ return 0; ++} ++ ++static u32 amd756_func(struct i2c_adapter *adapter) ++{ ++ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | ++ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | ++ I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL; ++} ++ ++static struct i2c_algorithm smbus_algorithm = { ++ .name = "Non-I2C SMBus adapter", ++ .id = I2C_ALGO_SMBUS, ++ .smbus_xfer = amd756_access, ++ .functionality = amd756_func, ++}; ++ ++static struct i2c_adapter amd756_adapter = { ++ .owner = THIS_MODULE, ++ .name = "unset", ++ .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD756, ++ .algo = &smbus_algorithm, ++}; ++ ++enum chiptype { AMD756, AMD766, AMD768, NFORCE, AMD8111 }; ++ ++static struct pci_device_id amd756_ids[] __devinitdata = { ++ {PCI_VENDOR_ID_AMD, 0x740B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD756 }, ++ {PCI_VENDOR_ID_AMD, 0x7413, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD766 }, ++ {PCI_VENDOR_ID_AMD, 0x7443, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD768 }, ++ {PCI_VENDOR_ID_AMD, 0x746B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD8111 }, ++ {PCI_VENDOR_ID_NVIDIA, 0x01B4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE }, ++ { 0, } ++}; ++ ++static int __devinit amd756_probe(struct pci_dev *pdev, ++ const struct pci_device_id *id) ++{ ++ int nforce = (id->driver_data == NFORCE); ++ int error; ++ u8 temp; ++ ++ if (amd756_ioport) { ++ printk(KERN_ERR DRV_NAME ": Only one device supported. " ++ "(you have a strange motherboard, btw..)\n"); ++ return -ENODEV; ++ } ++ ++ if (nforce) { ++ if (PCI_FUNC(pdev->devfn) != 1) ++ return -ENODEV; ++ ++ pci_read_config_word(pdev, SMBBANFORCE, &amd756_ioport); ++ amd756_ioport &= 0xfffc; ++ } else { /* amd */ ++ if (PCI_FUNC(pdev->devfn) != 3) ++ return -ENODEV; ++ ++ pci_read_config_byte(pdev, SMBGCFG, &temp); ++ if ((temp & 128) == 0) { ++ printk(KERN_ERR DRV_NAME ++ ": Error: SMBus controller I/O not enabled!\n"); ++ return -ENODEV; ++ } ++ ++ /* Determine the address of the SMBus areas */ ++ /* Technically it is a dword but... */ ++ pci_read_config_word(pdev, SMBBA, &amd756_ioport); ++ amd756_ioport &= 0xff00; ++ amd756_ioport += SMB_ADDR_OFFSET; ++ } ++ ++ if (!request_region(amd756_ioport, SMB_IOSIZE, "amd756-smbus")) { ++ printk(KERN_ERR DRV_NAME ++ ": SMB region 0x%x already in use!\n", amd756_ioport); ++ return -ENODEV; ++ } ++ ++#ifdef DEBUG ++ pci_read_config_byte(pdev, SMBREV, &temp); ++ printk(KERN_DEBUG DRV_NAME ": SMBREV = 0x%X\n", temp); ++ printk(KERN_DEBUG DRV_NAME ": AMD756_smba = 0x%X\n", amd756_ioport); ++#endif ++ ++ sprintf(amd756_adapter.name, ++ "SMBus AMD756 adapter at %04x", amd756_ioport); ++ ++ error = i2c_add_adapter(&amd756_adapter); ++ if (error) { ++ printk(KERN_ERR DRV_NAME ++ ": Adapter registration failed, module not inserted.\n"); ++ goto out_err; ++ } ++ ++ return 0; ++ ++ out_err: ++ release_region(amd756_ioport, SMB_IOSIZE); ++ return error; ++} ++ ++ ++static int __init i2c_amd756_init(void) ++{ ++ struct pci_dev *dev; ++ const struct pci_device_id *id; ++ ++ printk(KERN_INFO "i2c-amd756.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ ++ pci_for_each_dev(dev) { ++ id = pci_match_device(amd756_ids, dev); ++ if (id && amd756_probe(dev, id) >= 0) ++ return 0; ++ } ++ ++ return -ENODEV; ++} ++ ++ ++static void __exit i2c_amd756_exit(void) ++{ ++ i2c_del_adapter(&amd756_adapter); ++ release_region(amd756_ioport, SMB_IOSIZE); ++} ++ ++MODULE_AUTHOR("Merlin Hughes "); ++MODULE_DESCRIPTION("AMD756/766/768/8111 and nVidia nForce SMBus driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(i2c_amd756_init) ++module_exit(i2c_amd756_exit) +--- linux-old/drivers/i2c/i2c-amd8111.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-amd8111.c Mon Dec 13 20:18:41 2004 +@@ -0,0 +1,421 @@ ++/* ++ * SMBus 2.0 driver for AMD-8111 IO-Hub. ++ * ++ * Copyright (c) 2002 Vojtech Pavlik ++ * ++ * 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 version 2. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++#ifndef I2C_HW_SMBUS_AMD8111 ++#error Your i2c is too old - i2c-2.7.0 or greater required! ++#endif ++ ++/* kernel 2.4.9 needs this */ ++#ifndef min_t ++#define min_t(type,x,y) min(type,x,y) ++#endif ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR ("Vojtech Pavlik "); ++MODULE_DESCRIPTION("AMD8111 SMBus 2.0 driver"); ++ ++struct amd_smbus { ++ struct pci_dev *dev; ++ struct i2c_adapter adapter; ++ int base; ++ int size; ++}; ++ ++/* ++ * AMD PCI control registers definitions. ++ */ ++ ++#define AMD_PCI_MISC 0x48 ++ ++#define AMD_PCI_MISC_SCI 0x04 /* deliver SCI */ ++#define AMD_PCI_MISC_INT 0x02 /* deliver PCI IRQ */ ++#define AMD_PCI_MISC_SPEEDUP 0x01 /* 16x clock speedup */ ++ ++/* ++ * ACPI 2.0 chapter 13 PCI interface definitions. ++ */ ++ ++#define AMD_EC_DATA 0x00 /* data register */ ++#define AMD_EC_SC 0x04 /* status of controller */ ++#define AMD_EC_CMD 0x04 /* command register */ ++#define AMD_EC_ICR 0x08 /* interrupt control register */ ++ ++#define AMD_EC_SC_SMI 0x04 /* smi event pending */ ++#define AMD_EC_SC_SCI 0x02 /* sci event pending */ ++#define AMD_EC_SC_BURST 0x01 /* burst mode enabled */ ++#define AMD_EC_SC_CMD 0x08 /* byte in data reg is command */ ++#define AMD_EC_SC_IBF 0x02 /* data ready for embedded controller */ ++#define AMD_EC_SC_OBF 0x01 /* data ready for host */ ++ ++#define AMD_EC_CMD_RD 0x80 /* read EC */ ++#define AMD_EC_CMD_WR 0x81 /* write EC */ ++#define AMD_EC_CMD_BE 0x82 /* enable burst mode */ ++#define AMD_EC_CMD_BD 0x83 /* disable burst mode */ ++#define AMD_EC_CMD_QR 0x84 /* query EC */ ++ ++/* ++ * ACPI 2.0 chapter 13 access of registers of the EC ++ */ ++ ++unsigned int amd_ec_wait_write(struct amd_smbus *smbus) ++{ ++ int timeout = 500; ++ ++ while (timeout-- && (inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF)) ++ udelay(1); ++ ++ if (!timeout) { ++ printk(KERN_WARNING "i2c-amd8111.c: Timeout while waiting for IBF to clear\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++unsigned int amd_ec_wait_read(struct amd_smbus *smbus) ++{ ++ int timeout = 500; ++ ++ while (timeout-- && (~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF)) ++ udelay(1); ++ ++ if (!timeout) { ++ printk(KERN_WARNING "i2c-amd8111.c: Timeout while waiting for OBF to set\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address, unsigned char *data) ++{ ++ if (amd_ec_wait_write(smbus)) ++ return -1; ++ outb(AMD_EC_CMD_RD, smbus->base + AMD_EC_CMD); ++ ++ if (amd_ec_wait_write(smbus)) ++ return -1; ++ outb(address, smbus->base + AMD_EC_DATA); ++ ++ if (amd_ec_wait_read(smbus)) ++ return -1; ++ *data = inb(smbus->base + AMD_EC_DATA); ++ ++ return 0; ++} ++ ++unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address, unsigned char data) ++{ ++ if (amd_ec_wait_write(smbus)) ++ return -1; ++ outb(AMD_EC_CMD_WR, smbus->base + AMD_EC_CMD); ++ ++ if (amd_ec_wait_write(smbus)) ++ return -1; ++ outb(address, smbus->base + AMD_EC_DATA); ++ ++ if (amd_ec_wait_write(smbus)) ++ return -1; ++ outb(data, smbus->base + AMD_EC_DATA); ++ ++ return 0; ++} ++ ++/* ++ * ACPI 2.0 chapter 13 SMBus 2.0 EC register model ++ */ ++ ++#define AMD_SMB_PRTCL 0x00 /* protocol, PEC */ ++#define AMD_SMB_STS 0x01 /* status */ ++#define AMD_SMB_ADDR 0x02 /* address */ ++#define AMD_SMB_CMD 0x03 /* command */ ++#define AMD_SMB_DATA 0x04 /* 32 data registers */ ++#define AMD_SMB_BCNT 0x24 /* number of data bytes */ ++#define AMD_SMB_ALRM_A 0x25 /* alarm address */ ++#define AMD_SMB_ALRM_D 0x26 /* 2 bytes alarm data */ ++ ++#define AMD_SMB_STS_DONE 0x80 ++#define AMD_SMB_STS_ALRM 0x40 ++#define AMD_SMB_STS_RES 0x20 ++#define AMD_SMB_STS_STATUS 0x1f ++ ++#define AMD_SMB_STATUS_OK 0x00 ++#define AMD_SMB_STATUS_FAIL 0x07 ++#define AMD_SMB_STATUS_DNAK 0x10 ++#define AMD_SMB_STATUS_DERR 0x11 ++#define AMD_SMB_STATUS_CMD_DENY 0x12 ++#define AMD_SMB_STATUS_UNKNOWN 0x13 ++#define AMD_SMB_STATUS_ACC_DENY 0x17 ++#define AMD_SMB_STATUS_TIMEOUT 0x18 ++#define AMD_SMB_STATUS_NOTSUP 0x19 ++#define AMD_SMB_STATUS_BUSY 0x1A ++#define AMD_SMB_STATUS_PEC 0x1F ++ ++#define AMD_SMB_PRTCL_WRITE 0x00 ++#define AMD_SMB_PRTCL_READ 0x01 ++#define AMD_SMB_PRTCL_QUICK 0x02 ++#define AMD_SMB_PRTCL_BYTE 0x04 ++#define AMD_SMB_PRTCL_BYTE_DATA 0x06 ++#define AMD_SMB_PRTCL_WORD_DATA 0x08 ++#define AMD_SMB_PRTCL_BLOCK_DATA 0x0a ++#define AMD_SMB_PRTCL_PROC_CALL 0x0c ++#define AMD_SMB_PRTCL_BLOCK_PROC_CALL 0x0d ++#define AMD_SMB_PRTCL_I2C_BLOCK_DATA 0x4a ++#define AMD_SMB_PRTCL_PEC 0x80 ++ ++ ++s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short flags, ++ char read_write, u8 command, int size, union i2c_smbus_data * data) ++{ ++ struct amd_smbus *smbus = adap->algo_data; ++ unsigned char protocol, len, pec, temp[2]; ++ int i; ++ ++ protocol = (read_write == I2C_SMBUS_READ) ? AMD_SMB_PRTCL_READ : AMD_SMB_PRTCL_WRITE; ++ pec = (flags & I2C_CLIENT_PEC) ? AMD_SMB_PRTCL_PEC : 0; ++ ++ switch (size) { ++ ++ case I2C_SMBUS_QUICK: ++ protocol |= AMD_SMB_PRTCL_QUICK; ++ read_write = I2C_SMBUS_WRITE; ++ break; ++ ++ case I2C_SMBUS_BYTE: ++ if (read_write == I2C_SMBUS_WRITE) ++ amd_ec_write(smbus, AMD_SMB_CMD, command); ++ protocol |= AMD_SMB_PRTCL_BYTE; ++ break; ++ ++ case I2C_SMBUS_BYTE_DATA: ++ amd_ec_write(smbus, AMD_SMB_CMD, command); ++ if (read_write == I2C_SMBUS_WRITE) ++ amd_ec_write(smbus, AMD_SMB_DATA, data->byte); ++ protocol |= AMD_SMB_PRTCL_BYTE_DATA; ++ break; ++ ++ case I2C_SMBUS_WORD_DATA: ++ amd_ec_write(smbus, AMD_SMB_CMD, command); ++ if (read_write == I2C_SMBUS_WRITE) { ++ amd_ec_write(smbus, AMD_SMB_DATA, data->word); ++ amd_ec_write(smbus, AMD_SMB_DATA + 1, data->word >> 8); ++ } ++ protocol |= AMD_SMB_PRTCL_WORD_DATA | pec; ++ break; ++ ++ case I2C_SMBUS_BLOCK_DATA: ++ amd_ec_write(smbus, AMD_SMB_CMD, command); ++ if (read_write == I2C_SMBUS_WRITE) { ++ len = min_t(u8, data->block[0], 32); ++ amd_ec_write(smbus, AMD_SMB_BCNT, len); ++ for (i = 0; i < len; i++) ++ amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]); ++ } ++ protocol |= AMD_SMB_PRTCL_BLOCK_DATA | pec; ++ break; ++ ++ case I2C_SMBUS_I2C_BLOCK_DATA: ++ len = min_t(u8, data->block[0], 32); ++ amd_ec_write(smbus, AMD_SMB_CMD, command); ++ amd_ec_write(smbus, AMD_SMB_BCNT, len); ++ if (read_write == I2C_SMBUS_WRITE) ++ for (i = 0; i < len; i++) ++ amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]); ++ protocol |= AMD_SMB_PRTCL_I2C_BLOCK_DATA; ++ break; ++ ++ case I2C_SMBUS_PROC_CALL: ++ amd_ec_write(smbus, AMD_SMB_CMD, command); ++ amd_ec_write(smbus, AMD_SMB_DATA, data->word); ++ amd_ec_write(smbus, AMD_SMB_DATA + 1, data->word >> 8); ++ protocol = AMD_SMB_PRTCL_PROC_CALL | pec; ++ read_write = I2C_SMBUS_READ; ++ break; ++ ++ case I2C_SMBUS_BLOCK_PROC_CALL: ++ protocol |= pec; ++ len = min_t(u8, data->block[0], 31); ++ amd_ec_write(smbus, AMD_SMB_CMD, command); ++ amd_ec_write(smbus, AMD_SMB_BCNT, len); ++ for (i = 0; i < len; i++) ++ amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]); ++ protocol = AMD_SMB_PRTCL_BLOCK_PROC_CALL | pec; ++ read_write = I2C_SMBUS_READ; ++ break; ++ ++ case I2C_SMBUS_WORD_DATA_PEC: ++ case I2C_SMBUS_BLOCK_DATA_PEC: ++ case I2C_SMBUS_PROC_CALL_PEC: ++ case I2C_SMBUS_BLOCK_PROC_CALL_PEC: ++ printk(KERN_WARNING "i2c-amd8111.c: Unexpected software PEC transaction %d\n.", size); ++ return -1; ++ ++ default: ++ printk(KERN_WARNING "i2c-amd8111.c: Unsupported transaction %d\n", size); ++ return -1; ++ } ++ ++ amd_ec_write(smbus, AMD_SMB_ADDR, addr << 1); ++ amd_ec_write(smbus, AMD_SMB_PRTCL, protocol); ++ ++ amd_ec_read(smbus, AMD_SMB_STS, temp + 0); ++ ++ if (~temp[0] & AMD_SMB_STS_DONE) { ++ udelay(500); ++ amd_ec_read(smbus, AMD_SMB_STS, temp + 0); ++ } ++ ++ if (~temp[0] & AMD_SMB_STS_DONE) { ++ i2c_delay(HZ/100); ++ amd_ec_read(smbus, AMD_SMB_STS, temp + 0); ++ } ++ ++ if ((~temp[0] & AMD_SMB_STS_DONE) || (temp[0] & AMD_SMB_STS_STATUS)) ++ return -1; ++ ++ if (read_write == I2C_SMBUS_WRITE) ++ return 0; ++ ++ switch (size) { ++ ++ case I2C_SMBUS_BYTE: ++ case I2C_SMBUS_BYTE_DATA: ++ amd_ec_read(smbus, AMD_SMB_DATA, &data->byte); ++ break; ++ ++ case I2C_SMBUS_WORD_DATA: ++ case I2C_SMBUS_PROC_CALL: ++ amd_ec_read(smbus, AMD_SMB_DATA, temp + 0); ++ amd_ec_read(smbus, AMD_SMB_DATA + 1, temp + 1); ++ data->word = (temp[1] << 8) | temp[0]; ++ break; ++ ++ case I2C_SMBUS_BLOCK_DATA: ++ case I2C_SMBUS_BLOCK_PROC_CALL: ++ amd_ec_read(smbus, AMD_SMB_BCNT, &len); ++ len = min_t(u8, len, 32); ++ case I2C_SMBUS_I2C_BLOCK_DATA: ++ for (i = 0; i < len; i++) ++ amd_ec_read(smbus, AMD_SMB_DATA + i, data->block + i + 1); ++ data->block[0] = len; ++ break; ++ } ++ ++ return 0; ++} ++ ++ ++u32 amd8111_func(struct i2c_adapter *adapter) ++{ ++ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | ++ I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA | ++ I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | ++ I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_HWPEC_CALC; ++} ++ ++static struct i2c_algorithm smbus_algorithm = { ++ .name = "Non-I2C SMBus 2.0 adapter", ++ .id = I2C_ALGO_SMBUS, ++ .smbus_xfer = amd8111_access, ++ .functionality = amd8111_func, ++}; ++ ++ ++static struct pci_device_id amd8111_ids[] __devinitdata = { ++ { 0x1022, 0x746a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, ++ { 0, } ++}; ++ ++static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ struct amd_smbus *smbus; ++ int error; ++ ++ if (~pci_resource_flags(dev, 0) & IORESOURCE_IO) ++ return -1; ++ ++ if (!(smbus = (void*)kmalloc(sizeof(struct amd_smbus), GFP_KERNEL))) ++ return -1; ++ memset(smbus, 0, sizeof(struct amd_smbus)); ++ ++ pci_set_drvdata(dev, smbus); ++ smbus->dev = dev; ++ smbus->base = pci_resource_start(dev, 0); ++ smbus->size = pci_resource_len(dev, 0); ++ ++ if (!request_region(smbus->base, smbus->size, "amd8111 SMBus 2.0")) { ++ kfree(smbus); ++ return -1; ++ } ++ ++ smbus->adapter.owner = THIS_MODULE; ++ sprintf(smbus->adapter.name, "SMBus2 AMD8111 adapter at %04x", smbus->base); ++ smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD8111; ++ smbus->adapter.algo = &smbus_algorithm; ++ smbus->adapter.algo_data = smbus; ++ ++ error = i2c_add_adapter(&smbus->adapter); ++ if (error) { ++ printk(KERN_WARNING "i2c-amd8111.c: Failed to register adapter.\n"); ++ release_region(smbus->base, smbus->size); ++ kfree(smbus); ++ return -1; ++ } ++ ++ pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0); ++ ++ printk(KERN_INFO "i2c-amd8111.c: AMD8111 SMBus 2.0 adapter at %#x\n", smbus->base); ++ return 0; ++} ++ ++ ++static void __devexit amd8111_remove(struct pci_dev *dev) ++{ ++ struct amd_smbus *smbus = (void*) pci_get_drvdata(dev); ++ i2c_del_adapter(&smbus->adapter); ++ release_region(smbus->base, smbus->size); ++ kfree(smbus); ++} ++ ++static struct pci_driver amd8111_driver = { ++ .name = "amd8111 smbus 2.0", ++ .id_table = amd8111_ids, ++ .probe = amd8111_probe, ++ .remove = __devexit_p(amd8111_remove), ++}; ++ ++static int __init i2c_amd8111_init(void) ++{ ++ printk(KERN_INFO "i2c-amd8111.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return pci_module_init(&amd8111_driver); ++} ++ ++ ++static void __exit i2c_amd8111_exit(void) ++{ ++ pci_unregister_driver(&amd8111_driver); ++} ++ ++module_init(i2c_amd8111_init); ++module_exit(i2c_amd8111_exit); +--- linux-old/drivers/i2c/i2c-hydra.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-hydra.c Mon Dec 13 20:18:41 2004 +@@ -0,0 +1,175 @@ ++/* ++ i2c-hydra.c - Part of lm_sensors, Linux kernel modules ++ for hardware monitoring ++ ++ i2c Support for the Apple `Hydra' Mac I/O ++ ++ Copyright (c) 1999 Geert Uytterhoeven ++ ++ Based on i2c Support for Via Technologies 82C586B South Bridge ++ Copyright (c) 1998, 1999 Kyösti Mälkki ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* for HZ */ ++ ++MODULE_LICENSE("GPL"); ++ ++ ++#define HYDRA_CACHE_PD 0x00000030 ++ ++#define HYDRA_CPD_PD0 0x00000001 /* CachePD lines */ ++#define HYDRA_CPD_PD1 0x00000002 ++#define HYDRA_CPD_PD2 0x00000004 ++#define HYDRA_CPD_PD3 0x00000008 ++ ++#define HYDRA_SCLK HYDRA_CPD_PD0 ++#define HYDRA_SDAT HYDRA_CPD_PD1 ++#define HYDRA_SCLK_OE 0x00000010 ++#define HYDRA_SDAT_OE 0x00000020 ++ ++static unsigned long hydra_base; ++ ++static inline void pdregw(u32 val) ++{ ++ writel(val, hydra_base + HYDRA_CACHE_PD); ++} ++ ++static inline u32 pdregr(void) ++{ ++ u32 val = readl(hydra_base + HYDRA_CACHE_PD); ++ return val; ++} ++ ++static void bit_hydra_setscl(void *data, int state) ++{ ++ u32 val = pdregr(); ++ if (state) ++ val &= ~HYDRA_SCLK_OE; ++ else { ++ val &= ~HYDRA_SCLK; ++ val |= HYDRA_SCLK_OE; ++ } ++ pdregw(val); ++ pdregr(); /* flush posted write */ ++} ++ ++static void bit_hydra_setsda(void *data, int state) ++{ ++ u32 val = pdregr(); ++ if (state) ++ val &= ~HYDRA_SDAT_OE; ++ else { ++ val &= ~HYDRA_SDAT; ++ val |= HYDRA_SDAT_OE; ++ } ++ pdregw(val); ++ pdregr(); /* flush posted write */ ++} ++ ++static int bit_hydra_getscl(void *data) ++{ ++ return (pdregr() & HYDRA_SCLK) != 0; ++} ++ ++static int bit_hydra_getsda(void *data) ++{ ++ return (pdregr() & HYDRA_SDAT) != 0; ++} ++ ++/* ------------------------------------------------------------------------ */ ++ ++static struct i2c_algo_bit_data bit_hydra_data = { ++ .setsda = bit_hydra_setsda, ++ .setscl = bit_hydra_setscl, ++ .getsda = bit_hydra_getsda, ++ .getscl = bit_hydra_getscl, ++ .udelay = 5, ++ .mdelay = 5, ++ .timeout = HZ ++}; ++ ++static struct i2c_adapter bit_hydra_ops = { ++ .owner = THIS_MODULE, ++ .name = "Hydra i2c", ++ .id = I2C_HW_B_HYDRA, ++ .algo_data = &bit_hydra_data, ++}; ++ ++static struct pci_device_id hydra_ids[] __devinitdata = { ++ { ++ .vendor = PCI_VENDOR_ID_APPLE, ++ .device = PCI_DEVICE_ID_APPLE_HYDRA, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { 0, } ++}; ++ ++static int __devinit hydra_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ unsigned int base_addr; ++ ++ base_addr = dev->resource[0].start; ++ hydra_base = (unsigned long) ioremap(base_addr, 0x100); ++ ++ pdregw(0); /* clear SCLK_OE and SDAT_OE */ ++ return i2c_bit_add_bus(&bit_hydra_ops); ++} ++ ++static void __devexit hydra_remove(struct pci_dev *dev) ++{ ++ pdregw(0); /* clear SCLK_OE and SDAT_OE */ ++ i2c_bit_del_bus(&bit_hydra_ops); ++ iounmap((void *) hydra_base); ++} ++ ++ ++static struct pci_driver hydra_driver = { ++ .name = "hydra smbus", ++ .id_table = hydra_ids, ++ .probe = hydra_probe, ++ .remove = __devexit_p(hydra_remove), ++}; ++ ++static int __init i2c_hydra_init(void) ++{ ++ return pci_module_init(&hydra_driver); ++} ++ ++ ++static void __exit i2c_hydra_exit(void) ++{ ++ pci_unregister_driver(&hydra_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Geert Uytterhoeven "); ++MODULE_DESCRIPTION("i2c for Apple Hydra Mac I/O"); ++ ++module_init(i2c_hydra_init); ++module_exit(i2c_hydra_exit); ++ +--- linux-old/drivers/i2c/i2c-i801.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-i801.c Mon Dec 13 20:18:41 2004 +@@ -0,0 +1,656 @@ ++/* ++ i801.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998 - 2002 Frodo Looijaard , ++ Philip Edelbrock , and Mark D. Studebaker ++ ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ SUPPORTED DEVICES PCI ID ++ 82801AA 2413 ++ 82801AB 2423 ++ 82801BA 2443 ++ 82801CA/CAM 2483 ++ 82801DB 24C3 (HW PEC supported, 32 byte buffer not supported) ++ 82801EB 24D3 (HW PEC supported, 32 byte buffer not supported) ++ 6300ESB 25A4 ("") ++ ICH6 266A ++ This driver supports several versions of Intel's I/O Controller Hubs (ICH). ++ For SMBus support, they are similar to the PIIX4 and are part ++ of Intel's '810' and other chipsets. ++ See the doc/busses/i2c-i801 file for details. ++ I2C Block Read and Process Call are not supported. ++*/ ++ ++/* Note: we assume there can only be one I801, with one SMBus interface */ ++ ++/* #define DEBUG 1 */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++ ++/* 82801DB is undefined before kernel 2.4.19 */ ++#ifndef PCI_DEVICE_ID_INTEL_82801DB_3 ++#define PCI_DEVICE_ID_INTEL_82801DB_3 0x24c3 ++#endif ++ ++#ifdef I2C_FUNC_SMBUS_BLOCK_DATA_PEC ++#define HAVE_PEC ++#endif ++ ++/* I801 SMBus address offsets */ ++#define SMBHSTSTS (0 + i801_smba) ++#define SMBHSTCNT (2 + i801_smba) ++#define SMBHSTCMD (3 + i801_smba) ++#define SMBHSTADD (4 + i801_smba) ++#define SMBHSTDAT0 (5 + i801_smba) ++#define SMBHSTDAT1 (6 + i801_smba) ++#define SMBBLKDAT (7 + i801_smba) ++#define SMBPEC (8 + i801_smba) /* ICH4 only */ ++#define SMBAUXSTS (12 + i801_smba) /* ICH4 only */ ++#define SMBAUXCTL (13 + i801_smba) /* ICH4 only */ ++ ++/* PCI Address Constants */ ++#define SMBBA 0x020 ++#define SMBHSTCFG 0x040 ++#define SMBREV 0x008 ++ ++/* Host configuration bits for SMBHSTCFG */ ++#define SMBHSTCFG_HST_EN 1 ++#define SMBHSTCFG_SMB_SMI_EN 2 ++#define SMBHSTCFG_I2C_EN 4 ++ ++/* Other settings */ ++#define MAX_TIMEOUT 100 ++#define ENABLE_INT9 0 /* set to 0x01 to enable - untested */ ++ ++/* I801 command constants */ ++#define I801_QUICK 0x00 ++#define I801_BYTE 0x04 ++#define I801_BYTE_DATA 0x08 ++#define I801_WORD_DATA 0x0C ++#define I801_PROC_CALL 0x10 /* later chips only, unimplemented */ ++#define I801_BLOCK_DATA 0x14 ++#define I801_I2C_BLOCK_DATA 0x18 /* unimplemented */ ++#define I801_BLOCK_LAST 0x34 ++#define I801_I2C_BLOCK_LAST 0x38 /* unimplemented */ ++#define I801_START 0x40 ++#define I801_PEC_EN 0x80 /* ICH4 only */ ++ ++/* insmod parameters */ ++ ++/* If force_addr is set to anything different from 0, we forcibly enable ++ the I801 at the given address. VERY DANGEROUS! */ ++static int force_addr = 0; ++MODULE_PARM(force_addr, "i"); ++MODULE_PARM_DESC(force_addr, ++ "Forcibly enable the I801 at the given address. " ++ "EXTREMELY DANGEROUS!"); ++ ++static int i801_transaction(void); ++static int i801_block_transaction(union i2c_smbus_data *data, ++ char read_write, int command); ++ ++static unsigned short i801_smba; ++static struct pci_dev *I801_dev; ++static int isich4; ++ ++static int i801_setup(struct pci_dev *dev) ++{ ++ int error_return = 0; ++ unsigned char temp; ++ ++ /* Note: we keep on searching until we have found 'function 3' */ ++ if(PCI_FUNC(dev->devfn) != 3) ++ return -ENODEV; ++ ++ I801_dev = dev; ++ if (dev->device == PCI_DEVICE_ID_INTEL_82801DB_3 || ++ dev->device == 0x24d3 || ++ dev->device == 0x25a4) ++ isich4 = 1; ++ else ++ isich4 = 0; ++ ++ /* Determine the address of the SMBus areas */ ++ if (force_addr) { ++ i801_smba = force_addr & 0xfff0; ++ } else { ++ pci_read_config_word(I801_dev, SMBBA, &i801_smba); ++ i801_smba &= 0xfff0; ++ if(i801_smba == 0) { ++ dev_err(dev, "SMB base address uninitialized" ++ "- upgrade BIOS or use force_addr=0xaddr\n"); ++ return -ENODEV; ++ } ++ } ++ ++ if (!request_region(i801_smba, (isich4 ? 16 : 8), "i801-smbus")) { ++ dev_err(dev, "I801_smb region 0x%x already in use!\n", ++ i801_smba); ++ error_return = -EBUSY; ++ goto END; ++ } ++ ++ pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); ++ temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ ++ pci_write_config_byte(I801_dev, SMBHSTCFG, temp); ++ ++ /* If force_addr is set, we program the new address here. Just to make ++ sure, we disable the device first. */ ++ if (force_addr) { ++ pci_write_config_byte(I801_dev, SMBHSTCFG, temp & 0xfe); ++ pci_write_config_word(I801_dev, SMBBA, i801_smba); ++ pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 0x01); ++ dev_warn(dev, "WARNING: I801 SMBus interface set to " ++ "new address %04x!\n", i801_smba); ++ } else if ((temp & 1) == 0) { ++ pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 1); ++ dev_warn(dev, "enabling SMBus device\n"); ++ } ++ ++ if (temp & 0x02) ++ dev_dbg(dev, "I801 using Interrupt SMI# for SMBus.\n"); ++ else ++ dev_dbg(dev, "I801 using PCI Interrupt for SMBus.\n"); ++ ++ pci_read_config_byte(I801_dev, SMBREV, &temp); ++ dev_dbg(dev, "SMBREV = 0x%X\n", temp); ++ dev_dbg(dev, "I801_smba = 0x%X\n", i801_smba); ++ ++END: ++ return error_return; ++} ++ ++ ++static int i801_transaction(void) ++{ ++ int temp; ++ int result = 0; ++ int timeout = 0; ++ ++ dev_dbg(I801_dev, "Transaction (pre): CNT=%02x, CMD=%02x," ++ "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), ++ inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), ++ inb_p(SMBHSTDAT1)); ++ ++ /* Make sure the SMBus host is ready to start transmitting */ ++ /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ ++ if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { ++ dev_dbg(I801_dev, "SMBus busy (%02x). Resetting... \n", ++ temp); ++ outb_p(temp, SMBHSTSTS); ++ if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { ++ dev_dbg(I801_dev, "Failed! (%02x)\n", temp); ++ return -1; ++ } else { ++ dev_dbg(I801_dev, "Successfull!\n"); ++ } ++ } ++ ++ outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); ++ ++ /* We will always wait for a fraction of a second! */ ++ do { ++ i2c_delay(1); ++ temp = inb_p(SMBHSTSTS); ++ } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT)); ++ ++ /* If the SMBus is still busy, we give up */ ++ if (timeout >= MAX_TIMEOUT) { ++ dev_dbg(I801_dev, "SMBus Timeout!\n"); ++ result = -1; ++ } ++ ++ if (temp & 0x10) { ++ result = -1; ++ dev_dbg(I801_dev, "Error: Failed bus transaction\n"); ++ } ++ ++ if (temp & 0x08) { ++ result = -1; ++ dev_err(I801_dev, "Bus collision! SMBus may be locked " ++ "until next hard reset. (sorry!)\n"); ++ /* Clock stops and slave is stuck in mid-transmission */ ++ } ++ ++ if (temp & 0x04) { ++ result = -1; ++ dev_dbg(I801_dev, "Error: no response!\n"); ++ } ++ ++ if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00) ++ outb_p(inb(SMBHSTSTS), SMBHSTSTS); ++ ++ if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { ++ dev_dbg(I801_dev, "Failed reset at end of transaction" ++ "(%02x)\n", temp); ++ } ++ dev_dbg(I801_dev, "Transaction (post): CNT=%02x, CMD=%02x, " ++ "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), ++ inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), ++ inb_p(SMBHSTDAT1)); ++ return result; ++} ++ ++/* All-inclusive block transaction function */ ++static int i801_block_transaction(union i2c_smbus_data *data, char read_write, ++ int command) ++{ ++ int i, len; ++ int smbcmd; ++ int temp; ++ int result = 0; ++ int timeout; ++ unsigned char hostc, errmask; ++ ++ if (command == I2C_SMBUS_I2C_BLOCK_DATA) { ++ if (read_write == I2C_SMBUS_WRITE) { ++ /* set I2C_EN bit in configuration register */ ++ pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc); ++ pci_write_config_byte(I801_dev, SMBHSTCFG, ++ hostc | SMBHSTCFG_I2C_EN); ++ } else { ++ dev_err(I801_dev, ++ "I2C_SMBUS_I2C_BLOCK_READ not DB!\n"); ++ return -1; ++ } ++ } ++ ++ if (read_write == I2C_SMBUS_WRITE) { ++ len = data->block[0]; ++ if (len < 1) ++ len = 1; ++ if (len > 32) ++ len = 32; ++ outb_p(len, SMBHSTDAT0); ++ outb_p(data->block[1], SMBBLKDAT); ++ } else { ++ len = 32; /* max for reads */ ++ } ++ ++ if(isich4 && command != I2C_SMBUS_I2C_BLOCK_DATA) { ++ /* set 32 byte buffer */ ++ } ++ ++ for (i = 1; i <= len; i++) { ++ if (i == len && read_write == I2C_SMBUS_READ) ++ smbcmd = I801_BLOCK_LAST; ++ else ++ smbcmd = I801_BLOCK_DATA; ++ outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); ++ ++ dev_dbg(I801_dev, "Block (pre %d): CNT=%02x, CMD=%02x, " ++ "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i, ++ inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), ++ inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); ++ ++ /* Make sure the SMBus host is ready to start transmitting */ ++ temp = inb_p(SMBHSTSTS); ++ if (i == 1) { ++ /* Erronenous conditions before transaction: ++ * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ ++ errmask=0x9f; ++ } else { ++ /* Erronenous conditions during transaction: ++ * Failed, Bus_Err, Dev_Err, Intr */ ++ errmask=0x1e; ++ } ++ if (temp & errmask) { ++ dev_dbg(I801_dev, "SMBus busy (%02x). " ++ "Resetting... \n", temp); ++ outb_p(temp, SMBHSTSTS); ++ if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) { ++ dev_err(I801_dev, ++ "Reset failed! (%02x)\n", temp); ++ result = -1; ++ goto END; ++ } ++ if (i != 1) { ++ /* if die in middle of block transaction, fail */ ++ result = -1; ++ goto END; ++ } ++ } ++ ++ if (i == 1) ++ outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); ++ ++ /* We will always wait for a fraction of a second! */ ++ timeout = 0; ++ do { ++ temp = inb_p(SMBHSTSTS); ++ i2c_delay(1); ++ } ++ while ((!(temp & 0x80)) ++ && (timeout++ < MAX_TIMEOUT)); ++ ++ /* If the SMBus is still busy, we give up */ ++ if (timeout >= MAX_TIMEOUT) { ++ result = -1; ++ dev_dbg(I801_dev, "SMBus Timeout!\n"); ++ } ++ ++ if (temp & 0x10) { ++ result = -1; ++ dev_dbg(I801_dev, ++ "Error: Failed bus transaction\n"); ++ } else if (temp & 0x08) { ++ result = -1; ++ dev_err(I801_dev, "Bus collision!\n"); ++ } else if (temp & 0x04) { ++ result = -1; ++ dev_dbg(I801_dev, "Error: no response!\n"); ++ } ++ ++ if (i == 1 && read_write == I2C_SMBUS_READ) { ++ len = inb_p(SMBHSTDAT0); ++ if (len < 1) ++ len = 1; ++ if (len > 32) ++ len = 32; ++ data->block[0] = len; ++ } ++ ++ /* Retrieve/store value in SMBBLKDAT */ ++ if (read_write == I2C_SMBUS_READ) ++ data->block[i] = inb_p(SMBBLKDAT); ++ if (read_write == I2C_SMBUS_WRITE && i+1 <= len) ++ outb_p(data->block[i+1], SMBBLKDAT); ++ if ((temp & 0x9e) != 0x00) ++ outb_p(temp, SMBHSTSTS); /* signals SMBBLKDAT ready */ ++ ++ if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) { ++ dev_dbg(I801_dev, ++ "Bad status (%02x) at end of transaction\n", ++ temp); ++ } ++ dev_dbg(I801_dev, "Block (post %d): CNT=%02x, CMD=%02x, " ++ "ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i, ++ inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD), ++ inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT)); ++ ++ if (result < 0) ++ goto END; ++ } ++ ++#ifdef HAVE_PEC ++ if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) { ++ /* wait for INTR bit as advised by Intel */ ++ timeout = 0; ++ do { ++ temp = inb_p(SMBHSTSTS); ++ i2c_delay(1); ++ } while ((!(temp & 0x02)) ++ && (timeout++ < MAX_TIMEOUT)); ++ ++ if (timeout >= MAX_TIMEOUT) { ++ dev_dbg(I801_dev, "PEC Timeout!\n"); ++ } ++ outb_p(temp, SMBHSTSTS); ++ } ++#endif ++ result = 0; ++END: ++ if (command == I2C_SMBUS_I2C_BLOCK_DATA) { ++ /* restore saved configuration register value */ ++ pci_write_config_byte(I801_dev, SMBHSTCFG, hostc); ++ } ++ return result; ++} ++ ++/* Return -1 on error. */ ++static s32 i801_access(struct i2c_adapter * adap, u16 addr, ++ unsigned short flags, char read_write, u8 command, ++ int size, union i2c_smbus_data * data) ++{ ++ int hwpec = 0; ++ int block = 0; ++ int ret, xact = 0; ++ ++#ifdef HAVE_PEC ++ if(isich4) ++ hwpec = (flags & I2C_CLIENT_PEC) != 0; ++#endif ++ ++ switch (size) { ++ case I2C_SMBUS_QUICK: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ xact = I801_QUICK; ++ break; ++ case I2C_SMBUS_BYTE: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ if (read_write == I2C_SMBUS_WRITE) ++ outb_p(command, SMBHSTCMD); ++ xact = I801_BYTE; ++ break; ++ case I2C_SMBUS_BYTE_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) ++ outb_p(data->byte, SMBHSTDAT0); ++ xact = I801_BYTE_DATA; ++ break; ++ case I2C_SMBUS_WORD_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) { ++ outb_p(data->word & 0xff, SMBHSTDAT0); ++ outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); ++ } ++ xact = I801_WORD_DATA; ++ break; ++ case I2C_SMBUS_BLOCK_DATA: ++ case I2C_SMBUS_I2C_BLOCK_DATA: ++#ifdef HAVE_PEC ++ case I2C_SMBUS_BLOCK_DATA_PEC: ++ if(hwpec && size == I2C_SMBUS_BLOCK_DATA) ++ size = I2C_SMBUS_BLOCK_DATA_PEC; ++#endif ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ outb_p(command, SMBHSTCMD); ++ block = 1; ++ break; ++ case I2C_SMBUS_PROC_CALL: ++ default: ++ dev_err(I801_dev, "Unsupported transaction %d\n", size); ++ return -1; ++ } ++ ++#ifdef HAVE_PEC ++ if(isich4 && hwpec) { ++ if(size != I2C_SMBUS_QUICK && ++ size != I2C_SMBUS_I2C_BLOCK_DATA) ++ outb_p(1, SMBAUXCTL); /* enable HW PEC */ ++ } ++#endif ++ if(block) ++ ret = i801_block_transaction(data, read_write, size); ++ else { ++ outb_p(xact | ENABLE_INT9, SMBHSTCNT); ++ ret = i801_transaction(); ++ } ++ ++#ifdef HAVE_PEC ++ if(isich4 && hwpec) { ++ if(size != I2C_SMBUS_QUICK && ++ size != I2C_SMBUS_I2C_BLOCK_DATA) ++ outb_p(0, SMBAUXCTL); ++ } ++#endif ++ ++ if(block) ++ return ret; ++ if(ret) ++ return -1; ++ if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK)) ++ return 0; ++ ++ switch (xact & 0x7f) { ++ case I801_BYTE: /* Result put in SMBHSTDAT0 */ ++ case I801_BYTE_DATA: ++ data->byte = inb_p(SMBHSTDAT0); ++ break; ++ case I801_WORD_DATA: ++ data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); ++ break; ++ } ++ return 0; ++} ++ ++ ++static u32 i801_func(struct i2c_adapter *adapter) ++{ ++ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | ++ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | ++ I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK ++#ifdef HAVE_PEC ++ | (isich4 ? I2C_FUNC_SMBUS_BLOCK_DATA_PEC | ++ I2C_FUNC_SMBUS_HWPEC_CALC ++ : 0) ++#endif ++ ; ++} ++ ++static struct i2c_algorithm smbus_algorithm = { ++ .name = "Non-I2C SMBus adapter", ++ .id = I2C_ALGO_SMBUS, ++ .smbus_xfer = i801_access, ++ .functionality = i801_func, ++}; ++ ++static struct i2c_adapter i801_adapter = { ++ .owner = THIS_MODULE, ++ .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_I801, ++ .algo = &smbus_algorithm, ++ .name = "unset", ++}; ++ ++static struct pci_device_id i801_ids[] __devinitdata = { ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_82801AA_3, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_82801AB_3, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_82801BA_2, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_82801CA_3, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_82801DB_3, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = 0x24d3, /* 82801EB ICH5 */ ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = 0x25a4, /* PCI_DEVICE_ID_INTEL_ESB_4 */ ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = 0x266a, /* PCI_DEVICE_ID_INTEL_ICH6_16 */ ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { 0, } ++}; ++ ++static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ ++ if (i801_setup(dev)) { ++ dev_warn(dev, ++ "I801 not detected, module not inserted.\n"); ++ return -ENODEV; ++ } ++ ++ snprintf(i801_adapter.name, 32, ++ "SMBus I801 adapter at %04x", i801_smba); ++ return i2c_add_adapter(&i801_adapter); ++} ++ ++static void __devexit i801_remove(struct pci_dev *dev) ++{ ++ i2c_del_adapter(&i801_adapter); ++ release_region(i801_smba, (isich4 ? 16 : 8)); ++} ++ ++static struct pci_driver i801_driver = { ++ .name = "i801 smbus", ++ .id_table = i801_ids, ++ .probe = i801_probe, ++ .remove = __devexit_p(i801_remove), ++}; ++ ++static int __init i2c_i801_init(void) ++{ ++ printk(KERN_INFO "i2c-i801 version %s (%s)\n", LM_VERSION, LM_DATE); ++ return pci_module_init(&i801_driver); ++} ++ ++static void __exit i2c_i801_exit(void) ++{ ++ pci_unregister_driver(&i801_driver); ++} ++ ++MODULE_AUTHOR ("Frodo Looijaard , " ++ "Philip Edelbrock , " ++ "and Mark D. Studebaker "); ++MODULE_DESCRIPTION("I801 SMBus driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(i2c_i801_init); ++module_exit(i2c_i801_exit); +--- linux-old/drivers/i2c/i2c-i810.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-i810.c Mon Dec 13 20:18:41 2004 +@@ -0,0 +1,310 @@ ++/* ++ i2c-i810.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999, 2000 Frodo Looijaard , ++ Philip Edelbrock , ++ Ralph Metzler , and ++ Mark D. Studebaker ++ ++ Based on code written by Ralph Metzler and ++ Simon Vogl ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++/* ++ This interfaces to the I810/I815 to provide access to ++ the DDC Bus and the I2C Bus. ++ ++ SUPPORTED DEVICES PCI ID ++ i810AA 7121 ++ i810AB 7123 ++ i810E 7125 ++ i815 1132 ++*/ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* for HZ */ ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++#ifndef PCI_DEVICE_ID_INTEL_82815_2 ++#define PCI_DEVICE_ID_INTEL_82815_2 0x1132 ++#endif ++ ++/* GPIO register locations */ ++#define I810_IOCONTROL_OFFSET 0x5000 ++#define I810_HVSYNC 0x00 /* not used */ ++#define I810_GPIOA 0x10 ++#define I810_GPIOB 0x14 ++ ++/* bit locations in the registers */ ++#define SCL_DIR_MASK 0x0001 ++#define SCL_DIR 0x0002 ++#define SCL_VAL_MASK 0x0004 ++#define SCL_VAL_OUT 0x0008 ++#define SCL_VAL_IN 0x0010 ++#define SDA_DIR_MASK 0x0100 ++#define SDA_DIR 0x0200 ++#define SDA_VAL_MASK 0x0400 ++#define SDA_VAL_OUT 0x0800 ++#define SDA_VAL_IN 0x1000 ++ ++/* initialization states */ ++#define INIT1 0x1 ++#define INIT2 0x2 ++#define INIT3 0x4 ++ ++/* delays */ ++#define CYCLE_DELAY 10 ++#define TIMEOUT (HZ / 2) ++ ++ ++static void config_i810(struct pci_dev *dev); ++ ++ ++static unsigned long ioaddr; ++ ++/* The i810 GPIO registers have individual masks for each bit ++ so we never have to read before writing. Nice. */ ++ ++static void bit_i810i2c_setscl(void *data, int val) ++{ ++ writel((val ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK, ++ ioaddr + I810_GPIOB); ++ readl(ioaddr + I810_GPIOB); /* flush posted write */ ++} ++ ++static void bit_i810i2c_setsda(void *data, int val) ++{ ++ writel((val ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK, ++ ioaddr + I810_GPIOB); ++ readl(ioaddr + I810_GPIOB); /* flush posted write */ ++} ++ ++/* The GPIO pins are open drain, so the pins could always remain outputs. ++ However, some chip versions don't latch the inputs unless they ++ are set as inputs. ++ We rely on the i2c-algo-bit routines to set the pins high before ++ reading the input from other chips. Following guidance in the 815 ++ prog. ref. guide, we do a "dummy write" of 0 to the register before ++ reading which forces the input value to be latched. We presume this ++ applies to the 810 as well; shouldn't hurt anyway. This is necessary to get ++ i2c_algo_bit bit_test=1 to pass. */ ++ ++static int bit_i810i2c_getscl(void *data) ++{ ++ writel(SCL_DIR_MASK, ioaddr + I810_GPIOB); ++ writel(0, ioaddr + I810_GPIOB); ++ return (0 != (readl(ioaddr + I810_GPIOB) & SCL_VAL_IN)); ++} ++ ++static int bit_i810i2c_getsda(void *data) ++{ ++ writel(SDA_DIR_MASK, ioaddr + I810_GPIOB); ++ writel(0, ioaddr + I810_GPIOB); ++ return (0 != (readl(ioaddr + I810_GPIOB) & SDA_VAL_IN)); ++} ++ ++static void bit_i810ddc_setscl(void *data, int val) ++{ ++ writel((val ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK, ++ ioaddr + I810_GPIOA); ++ readl(ioaddr + I810_GPIOA); /* flush posted write */ ++} ++ ++static void bit_i810ddc_setsda(void *data, int val) ++{ ++ writel((val ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK, ++ ioaddr + I810_GPIOA); ++ readl(ioaddr + I810_GPIOA); /* flush posted write */ ++} ++ ++static int bit_i810ddc_getscl(void *data) ++{ ++ writel(SCL_DIR_MASK, ioaddr + I810_GPIOA); ++ writel(0, ioaddr + I810_GPIOA); ++ return (0 != (readl(ioaddr + I810_GPIOA) & SCL_VAL_IN)); ++} ++ ++static int bit_i810ddc_getsda(void *data) ++{ ++ writel(SDA_DIR_MASK, ioaddr + I810_GPIOA); ++ writel(0, ioaddr + I810_GPIOA); ++ return (0 != (readl(ioaddr + I810_GPIOA) & SDA_VAL_IN)); ++} ++ ++ ++/* Configures the chip */ ++void config_i810(struct pci_dev *dev) ++{ ++ unsigned long cadr; ++ ++ /* map I810 memory */ ++ cadr = dev->resource[1].start; ++ cadr += I810_IOCONTROL_OFFSET; ++ cadr &= PCI_BASE_ADDRESS_MEM_MASK; ++ ioaddr = (unsigned long)ioremap_nocache(cadr, 0x1000); ++ if(ioaddr) { ++ bit_i810i2c_setscl(NULL, 1); ++ bit_i810i2c_setsda(NULL, 1); ++ bit_i810ddc_setscl(NULL, 1); ++ bit_i810ddc_setsda(NULL, 1); ++ } ++} ++ ++ ++static struct i2c_algo_bit_data i810_i2c_bit_data = { ++ .setsda = bit_i810i2c_setsda, ++ .setscl = bit_i810i2c_setscl, ++ .getsda = bit_i810i2c_getsda, ++ .getscl = bit_i810i2c_getscl, ++ .udelay = CYCLE_DELAY, ++ .mdelay = CYCLE_DELAY, ++ .timeout = TIMEOUT, ++}; ++ ++static struct i2c_adapter i810_i2c_adapter = { ++ .owner = THIS_MODULE, ++ .name = "I810/I815 I2C Adapter", ++ .id = I2C_HW_B_I810, ++ .algo_data = &i810_i2c_bit_data, ++}; ++ ++static struct i2c_algo_bit_data i810_ddc_bit_data = { ++ .setsda = bit_i810ddc_setsda, ++ .setscl = bit_i810ddc_setscl, ++ .getsda = bit_i810ddc_getsda, ++ .getscl = bit_i810ddc_getscl, ++ .udelay = CYCLE_DELAY, ++ .mdelay = CYCLE_DELAY, ++ .timeout = TIMEOUT, ++}; ++ ++static struct i2c_adapter i810_ddc_adapter = { ++ .owner = THIS_MODULE, ++ .name = "I810/I815 DDC Adapter", ++ .id = I2C_HW_B_I810, ++ .algo_data = &i810_ddc_bit_data, ++}; ++ ++ ++static struct pci_device_id i810_ids[] __devinitdata = { ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_82810_IG1, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_82810_IG3, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = 0x7125, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_82815_2, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = 0x2562, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { 0, } ++}; ++ ++static int __devinit i810_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ int retval; ++ ++ config_i810(dev); ++ printk("i2c-i810.o: i810/i815 found.\n"); ++ ++ retval = i2c_bit_add_bus(&i810_i2c_adapter); ++ if(retval) ++ return retval; ++ retval = i2c_bit_add_bus(&i810_ddc_adapter); ++ if(retval) ++ i2c_bit_del_bus(&i810_i2c_adapter); ++ return retval; ++} ++ ++static void __devexit i810_remove(struct pci_dev *dev) ++{ ++ i2c_bit_del_bus(&i810_ddc_adapter); ++ i2c_bit_del_bus(&i810_i2c_adapter); ++} ++ ++ ++/* Don't register driver to avoid driver conflicts */ ++/* ++static struct pci_driver i810_driver = { ++ .name = "i810 smbus", ++ .id_table = i810_ids, ++ .probe = i810_probe, ++ .remove = __devexit_p(i810_remove), ++}; ++*/ ++ ++static int __init i2c_i810_init(void) ++{ ++ struct pci_dev *dev; ++ const struct pci_device_id *id; ++ ++ printk("i2c-i810.o version %s (%s)\n", LM_VERSION, LM_DATE); ++/* ++ return pci_module_init(&i810_driver); ++*/ ++ pci_for_each_dev(dev) { ++ id = pci_match_device(i810_ids, dev); ++ if(id) ++ if(i810_probe(dev, id) >= 0) ++ return 0; ++ } ++ return -ENODEV; ++} ++ ++static void __exit i2c_i810_exit(void) ++{ ++/* ++ pci_unregister_driver(&i810_driver); ++*/ ++ i810_remove(NULL); ++ iounmap((void *)ioaddr); ++} ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard , Philip Edelbrock , Ralph Metzler , and Mark D. Studebaker "); ++MODULE_DESCRIPTION("I810/I815 I2C/DDC driver"); ++ ++module_init(i2c_i810_init); ++module_exit(i2c_i810_exit); +--- linux-old/drivers/i2c/i2c-isa.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-isa.c Mon Dec 13 20:18:41 2004 +@@ -0,0 +1,74 @@ ++/* ++ i2c-isa.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* This implements an i2c algorithm/adapter for ISA bus. Not that this is ++ on first sight very useful; almost no functionality is preserved. ++ Except that it makes writing drivers for chips which can be on both ++ the SMBus and the ISA bus very much easier. See lm78.c for an example ++ of this. */ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++static u32 isa_func(struct i2c_adapter *adapter); ++ ++/* This is the actual algorithm we define */ ++static struct i2c_algorithm isa_algorithm = { ++ .name = "ISA bus algorithm", ++ .id = I2C_ALGO_ISA, ++ .functionality = isa_func, ++}; ++ ++/* There can only be one... */ ++static struct i2c_adapter isa_adapter = { ++ .owner = THIS_MODULE, ++ .name = "ISA main adapter", ++ .id = I2C_ALGO_ISA | I2C_HW_ISA, ++ .algo = &isa_algorithm, ++}; ++ ++/* We can't do a thing... */ ++static u32 isa_func(struct i2c_adapter *adapter) ++{ ++ return 0; ++} ++ ++static int __init i2c_isa_init(void) ++{ ++ printk("i2c-isa.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_adapter(&isa_adapter); ++} ++ ++static void __exit i2c_isa_exit(void) ++{ ++ i2c_del_adapter(&isa_adapter); ++} ++ ++MODULE_AUTHOR("Frodo Looijaard "); ++MODULE_DESCRIPTION("ISA bus access through i2c"); ++MODULE_LICENSE("GPL"); ++ ++module_init(i2c_isa_init); ++module_exit(i2c_isa_exit); +--- linux-old/drivers/i2c/i2c-nforce2.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-nforce2.c Mon Dec 13 20:18:41 2004 +@@ -0,0 +1,409 @@ ++/* ++ SMBus driver for nVidia nForce2 MCP ++ ++ Copyright (c) 2003 Hans-Frieder Vogt , ++ Based on ++ SMBus 2.0 driver for AMD-8111 IO-Hub ++ Copyright (c) 2002 Vojtech Pavlik ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ SUPPORTED DEVICES PCI ID ++ nForce2 MCP 0064 ++ ++ This driver supports the 2 SMBuses that are included in the MCP2 of the ++ nForce2 chipset. ++*/ ++ ++/* Note: we assume there can only be one nForce2, with two SMBus interfaces */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++/* kernel 2.4.9 needs this */ ++#ifndef min_t ++#define min_t(type,x,y) min(type,x,y) ++#endif ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR ("Hans-Frieder Vogt "); ++MODULE_DESCRIPTION("nForce2 SMBus driver"); ++ ++#ifndef PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS ++#define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS 0x0064 ++#endif ++ ++ ++struct nforce2_smbus { ++ struct pci_dev *dev; ++ struct i2c_adapter adapter; ++ int base; ++ int size; ++}; ++ ++ ++/* ++ * nVidia nForce2 SMBus control register definitions ++ */ ++#define NFORCE_PCI_SMB1 0x50 ++#define NFORCE_PCI_SMB2 0x54 ++ ++ ++/* ++ * ACPI 2.0 chapter 13 SMBus 2.0 EC register model ++ */ ++#define NVIDIA_SMB_PRTCL (smbus->base + 0x00) /* protocol, PEC */ ++#define NVIDIA_SMB_STS (smbus->base + 0x01) /* status */ ++#define NVIDIA_SMB_ADDR (smbus->base + 0x02) /* address */ ++#define NVIDIA_SMB_CMD (smbus->base + 0x03) /* command */ ++#define NVIDIA_SMB_DATA (smbus->base + 0x04) /* 32 data registers */ ++#define NVIDIA_SMB_BCNT (smbus->base + 0x24) /* number of data bytes */ ++#define NVIDIA_SMB_ALRM_A (smbus->base + 0x25) /* alarm address */ ++#define NVIDIA_SMB_ALRM_D (smbus->base + 0x26) /* 2 bytes alarm data */ ++ ++#define NVIDIA_SMB_STS_DONE 0x80 ++#define NVIDIA_SMB_STS_ALRM 0x40 ++#define NVIDIA_SMB_STS_RES 0x20 ++#define NVIDIA_SMB_STS_STATUS 0x1f ++ ++#define NVIDIA_SMB_PRTCL_WRITE 0x00 ++#define NVIDIA_SMB_PRTCL_READ 0x01 ++#define NVIDIA_SMB_PRTCL_QUICK 0x02 ++#define NVIDIA_SMB_PRTCL_BYTE 0x04 ++#define NVIDIA_SMB_PRTCL_BYTE_DATA 0x06 ++#define NVIDIA_SMB_PRTCL_WORD_DATA 0x08 ++#define NVIDIA_SMB_PRTCL_BLOCK_DATA 0x0a ++#define NVIDIA_SMB_PRTCL_PROC_CALL 0x0c ++#define NVIDIA_SMB_PRTCL_BLOCK_PROC_CALL 0x0d ++#define NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA 0x4a ++#define NVIDIA_SMB_PRTCL_PEC 0x80 ++ ++ ++/* Other settings */ ++#define MAX_TIMEOUT 256 ++ ++ ++ ++static s32 nforce2_access(struct i2c_adapter *adap, u16 addr, ++ unsigned short flags, char read_write, ++ u8 command, int size, union i2c_smbus_data *data); ++/* ++static int nforce2_block_transaction(union i2c_smbus_data *data, ++ char read_write, int i2c_enable); ++ */ ++static u32 nforce2_func(struct i2c_adapter *adapter); ++ ++ ++static struct i2c_algorithm smbus_algorithm = { ++ .name = "Non-I2C SMBus adapter", ++ .id = I2C_ALGO_SMBUS, ++ .smbus_xfer = nforce2_access, ++ .functionality = nforce2_func, ++}; ++ ++/* Return -1 on error. See smbus.h for more information */ ++s32 nforce2_access(struct i2c_adapter * adap, u16 addr, unsigned short flags, ++ char read_write, u8 command, int size, ++ union i2c_smbus_data * data) ++{ ++ struct nforce2_smbus *smbus = adap->algo_data; ++ unsigned char protocol, pec, temp; ++ unsigned char len = 0; /* to keep the compiler quiet */ ++ int timeout = 0; ++ int i; ++ ++ protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ : NVIDIA_SMB_PRTCL_WRITE; ++ pec = (flags & I2C_CLIENT_PEC) ? NVIDIA_SMB_PRTCL_PEC : 0; ++ ++ switch (size) { ++ ++ case I2C_SMBUS_QUICK: ++ protocol |= NVIDIA_SMB_PRTCL_QUICK; ++ read_write = I2C_SMBUS_WRITE; ++ break; ++ ++ case I2C_SMBUS_BYTE: ++ if (read_write == I2C_SMBUS_WRITE) ++ outb_p(command, NVIDIA_SMB_CMD); ++ protocol |= NVIDIA_SMB_PRTCL_BYTE; ++ break; ++ ++ case I2C_SMBUS_BYTE_DATA: ++ outb_p(command, NVIDIA_SMB_CMD); ++ if (read_write == I2C_SMBUS_WRITE) ++ outb_p(data->byte, NVIDIA_SMB_DATA); ++ protocol |= NVIDIA_SMB_PRTCL_BYTE_DATA; ++ break; ++ ++ case I2C_SMBUS_WORD_DATA: ++ outb_p(command, NVIDIA_SMB_CMD); ++ if (read_write == I2C_SMBUS_WRITE) { ++ outb_p(data->word, NVIDIA_SMB_DATA); ++ outb_p(data->word >> 8, NVIDIA_SMB_DATA+1); ++ } ++ protocol |= NVIDIA_SMB_PRTCL_WORD_DATA | pec; ++ break; ++ ++ case I2C_SMBUS_BLOCK_DATA: ++ outb_p(command, NVIDIA_SMB_CMD); ++ if (read_write == I2C_SMBUS_WRITE) { ++ len = min_t(u8, data->block[0], 32); ++ outb_p(len, NVIDIA_SMB_BCNT); ++ for (i = 0; i < len; i++) ++ outb_p(data->block[i + 1], NVIDIA_SMB_DATA+i); ++ } ++ protocol |= NVIDIA_SMB_PRTCL_BLOCK_DATA | pec; ++ break; ++ ++ case I2C_SMBUS_I2C_BLOCK_DATA: ++ len = min_t(u8, data->block[0], 32); ++ outb_p(command, NVIDIA_SMB_CMD); ++ outb_p(len, NVIDIA_SMB_BCNT); ++ if (read_write == I2C_SMBUS_WRITE) ++ for (i = 0; i < len; i++) ++ outb_p(data->block[i + 1], NVIDIA_SMB_DATA+i); ++ protocol |= NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA; ++ break; ++ ++ case I2C_SMBUS_PROC_CALL: ++ printk(KERN_WARNING "i2c-nforce2.o: I2C_SMBUS_PROC_CALL not supported!\n"); ++ return -1; ++ /* ++ outb_p(command, NVIDIA_SMB_CMD); ++ outb_p(data->word, NVIDIA_SMB_DATA); ++ outb_p(data->word >> 8, NVIDIA_SMB_DATA + 1); ++ protocol = NVIDIA_SMB_PRTCL_PROC_CALL | pec; ++ read_write = I2C_SMBUS_READ; ++ break; ++ */ ++ ++ case I2C_SMBUS_BLOCK_PROC_CALL: ++ printk(KERN_WARNING "i2c-nforce2.o: I2C_SMBUS_BLOCK_PROC_CALL not supported!\n"); ++ return -1; ++ /* ++ protocol |= pec; ++ len = min_t(u8, data->block[0], 31); ++ outb_p(command, NVIDIA_SMB_CMD); ++ outb_p(len, NVIDIA_SMB_BCNT); ++ for (i = 0; i < len; i++) ++ outb_p(data->block[i + 1], NVIDIA_SMB_DATA + i); ++ protocol = NVIDIA_SMB_PRTCL_BLOCK_PROC_CALL | pec; ++ read_write = I2C_SMBUS_READ; ++ break; ++ */ ++ ++ case I2C_SMBUS_WORD_DATA_PEC: ++ case I2C_SMBUS_BLOCK_DATA_PEC: ++ case I2C_SMBUS_PROC_CALL_PEC: ++ case I2C_SMBUS_BLOCK_PROC_CALL_PEC: ++ printk(KERN_WARNING "i2c-nforce2.c: Unexpected software PEC transaction %d\n.", size); ++ return -1; ++ ++ default: ++ printk(KERN_WARNING "i2c-nforce2.c: Unsupported transaction %d\n", size); ++ return -1; ++ } ++ ++ outb_p((addr & 0x7f) << 1, NVIDIA_SMB_ADDR); ++ outb_p(protocol, NVIDIA_SMB_PRTCL); ++ ++ temp = inb_p(NVIDIA_SMB_STS); ++ ++#if 0 ++ do { ++ i2c_delay(1); ++ temp = inb_p(NVIDIA_SMB_STS); ++ } while (((temp & NVIDIA_SMB_STS_DONE) == 0) && (timeout++ < MAX_TIMEOUT)); ++#endif ++ if (~temp & NVIDIA_SMB_STS_DONE) { ++ udelay(500); ++ temp = inb_p(NVIDIA_SMB_STS); ++ } ++ if (~temp & NVIDIA_SMB_STS_DONE) { ++ i2c_delay(HZ/100); ++ temp = inb_p(NVIDIA_SMB_STS); ++ } ++ ++ if ((timeout >= MAX_TIMEOUT) || (~temp & NVIDIA_SMB_STS_DONE) || (temp & NVIDIA_SMB_STS_STATUS)) ++ return -1; ++ ++ if (read_write == I2C_SMBUS_WRITE) ++ return 0; ++ ++ switch (size) { ++ ++ case I2C_SMBUS_BYTE: ++ case I2C_SMBUS_BYTE_DATA: ++ data->byte = inb_p(NVIDIA_SMB_DATA); ++ break; ++ ++ case I2C_SMBUS_WORD_DATA: ++ /* case I2C_SMBUS_PROC_CALL: not supported */ ++ data->word = inb_p(NVIDIA_SMB_DATA) | (inb_p(NVIDIA_SMB_DATA+1) << 8); ++ break; ++ ++ case I2C_SMBUS_BLOCK_DATA: ++ /* case I2C_SMBUS_BLOCK_PROC_CALL: not supported */ ++ len = inb_p(NVIDIA_SMB_BCNT); ++ len = min_t(u8, len, 32); ++ case I2C_SMBUS_I2C_BLOCK_DATA: ++ for (i = 0; i < len; i++) ++ data->block[i+1] = inb_p(NVIDIA_SMB_DATA + i); ++ data->block[0] = len; ++ break; ++ } ++ ++ return 0; ++} ++ ++ ++u32 nforce2_func(struct i2c_adapter *adapter) ++{ ++ /* other functionality might be possible, but is not tested */ ++ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | ++ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA /* | ++ I2C_FUNC_SMBUS_BLOCK_DATA */; ++} ++ ++ ++static struct pci_device_id nforce2_ids[] = { ++ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, ++ { 0 } ++}; ++ ++ ++static int __devinit nforce2_probe_smb (struct pci_dev *dev, int reg, struct nforce2_smbus *smbus, char *name) ++{ ++ u16 iobase; ++ int error; ++ ++ if (pci_read_config_word(dev, reg, &iobase) != PCIBIOS_SUCCESSFUL) { ++ printk (KERN_ERR "i2c-nforce2.o: Error reading PCI config for %s\n", name); ++ return -1; ++ } ++ smbus->dev = dev; ++ smbus->base = iobase & 0xfffc; ++ smbus->size = 8; ++ ++ if (!request_region(smbus->base, smbus->size, "nForce2 SMBus")) { ++ printk (KERN_ERR "i2c-nforce2.o: Error requesting region %02x .. %02X for %s\n", smbus->base, smbus->base+smbus->size-1, name); ++ return -1; ++ } ++ ++ /* TODO: find a better way to find out whether this file is compiled ++ * with i2c 2.7.0 of earlier ++ */ ++#ifdef I2C_HW_SMBUS_AMD8111 ++ smbus->adapter.owner = THIS_MODULE; ++#endif ++ sprintf(smbus->adapter.name, "SMBus nForce2 adapter at %04x", smbus->base); ++ smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_NFORCE2; ++ smbus->adapter.algo = &smbus_algorithm; ++ smbus->adapter.algo_data = smbus; ++ ++ error = i2c_add_adapter(&smbus->adapter); ++ if (error) { ++ printk(KERN_WARNING "i2c-nforce2.o: Failed to register adapter.\n"); ++ release_region(smbus->base, smbus->size); ++ return -1; ++ } ++ printk(KERN_INFO "i2c-nforce2.o: nForce2 SMBus adapter at %#x\n", smbus->base); ++ return 0; ++} ++ ++ ++static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ struct nforce2_smbus *smbuses; ++ int res1, res2; ++ ++ /* we support 2 SMBus adapters */ ++ if (!(smbuses = (void *)kmalloc(2*sizeof(struct nforce2_smbus), ++ GFP_KERNEL))) ++ return -ENOMEM; ++ memset (smbuses, 0, 2*sizeof(struct nforce2_smbus)); ++ pci_set_drvdata(dev, smbuses); ++ ++ /* SMBus adapter 1 */ ++ res1 = nforce2_probe_smb (dev, NFORCE_PCI_SMB1, &smbuses[0], "SMB1"); ++ if (res1 < 0) { ++ printk (KERN_ERR "i2c-nforce2.o: Error probing SMB1.\n"); ++ smbuses[0].base = 0; /* to have a check value */ ++ } ++ res2 = nforce2_probe_smb (dev, NFORCE_PCI_SMB2, &smbuses[1], "SMB2"); ++ if (res2 < 0) { ++ printk (KERN_ERR "i2c-nforce2.o: Error probing SMB2.\n"); ++ smbuses[1].base = 0; /* to have a check value */ ++ } ++ if ((res1 < 0) && (res2 < 0)) { ++ /* we did not find even one of the SMBuses, so we give up */ ++ kfree(smbuses); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++ ++static void __devexit nforce2_remove(struct pci_dev *dev) ++{ ++ struct nforce2_smbus *smbuses = (void*) pci_get_drvdata(dev); ++ ++ if (smbuses[0].base) { ++ i2c_del_adapter(&smbuses[0].adapter); ++ release_region(smbuses[0].base, smbuses[0].size); ++ } ++ if (smbuses[1].base) { ++ i2c_del_adapter(&smbuses[1].adapter); ++ release_region(smbuses[1].base, smbuses[1].size); ++ } ++ kfree(smbuses); ++} ++ ++static struct pci_driver nforce2_driver = { ++ .name = "nForce2 SMBus", ++ .id_table = nforce2_ids, ++ .probe = nforce2_probe, ++ .remove = __devexit_p(nforce2_remove), ++}; ++ ++int __init nforce2_init(void) ++{ ++ printk(KERN_INFO "i2c-nforce2.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return pci_module_init(&nforce2_driver); ++} ++ ++void __exit nforce2_exit(void) ++{ ++ pci_unregister_driver(&nforce2_driver); ++} ++ ++module_init(nforce2_init); ++module_exit(nforce2_exit); ++ +--- linux-old/drivers/i2c/i2c-piix4.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-piix4.c Mon Dec 13 20:18:42 2004 +@@ -0,0 +1,549 @@ ++/* ++ piix4.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998 - 2002 Frodo Looijaard and ++ Philip Edelbrock ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ Supports: ++ Intel PIIX4, 440MX ++ Serverworks OSB4, CSB5, CSB6 ++ SMSC Victory66 ++ ++ Note: we assume there can only be one device, with one SMBus interface. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++ ++struct sd { ++ const unsigned short mfr; ++ const unsigned short dev; ++ const unsigned char fn; ++ const char *name; ++}; ++ ++/* PIIX4 SMBus address offsets */ ++#define SMBHSTSTS (0 + piix4_smba) ++#define SMBHSLVSTS (1 + piix4_smba) ++#define SMBHSTCNT (2 + piix4_smba) ++#define SMBHSTCMD (3 + piix4_smba) ++#define SMBHSTADD (4 + piix4_smba) ++#define SMBHSTDAT0 (5 + piix4_smba) ++#define SMBHSTDAT1 (6 + piix4_smba) ++#define SMBBLKDAT (7 + piix4_smba) ++#define SMBSLVCNT (8 + piix4_smba) ++#define SMBSHDWCMD (9 + piix4_smba) ++#define SMBSLVEVT (0xA + piix4_smba) ++#define SMBSLVDAT (0xC + piix4_smba) ++ ++/* count for request_region */ ++#define SMBIOSIZE 8 ++ ++/* PCI Address Constants */ ++#define SMBBA 0x090 ++#define SMBHSTCFG 0x0D2 ++#define SMBSLVC 0x0D3 ++#define SMBSHDW1 0x0D4 ++#define SMBSHDW2 0x0D5 ++#define SMBREV 0x0D6 ++ ++/* Other settings */ ++#define MAX_TIMEOUT 500 ++#define ENABLE_INT9 0 ++ ++/* PIIX4 constants */ ++#define PIIX4_QUICK 0x00 ++#define PIIX4_BYTE 0x04 ++#define PIIX4_BYTE_DATA 0x08 ++#define PIIX4_WORD_DATA 0x0C ++#define PIIX4_BLOCK_DATA 0x14 ++ ++/* insmod parameters */ ++ ++/* If force is set to anything different from 0, we forcibly enable the ++ PIIX4. DANGEROUS! */ ++static int force = 0; ++MODULE_PARM(force, "i"); ++MODULE_PARM_DESC(force, "Forcibly enable the PIIX4. DANGEROUS!"); ++ ++/* If force_addr is set to anything different from 0, we forcibly enable ++ the PIIX4 at the given address. VERY DANGEROUS! */ ++static int force_addr = 0; ++MODULE_PARM(force_addr, "i"); ++MODULE_PARM_DESC(force_addr, ++ "Forcibly enable the PIIX4 at the given address. " ++ "EXTREMELY DANGEROUS!"); ++ ++static int fix_hstcfg = 0; ++MODULE_PARM(fix_hstcfg, "i"); ++MODULE_PARM_DESC(fix_hstcfg, ++ "Fix config register. Needed on some boards (Force CPCI735)."); ++ ++static int piix4_transaction(void); ++ ++static unsigned short piix4_smba = 0; ++ ++#ifdef CONFIG_X86 ++/* ++ * Get DMI information. ++ */ ++ ++static int __devinit ibm_dmi_probe(void) ++{ ++ extern int is_unsafe_smbus; ++ return is_unsafe_smbus; ++} ++#endif ++ ++/* Detect whether a PIIX4 can be found, and initialize it, where necessary. ++ Note the differences between kernels with the old PCI BIOS interface and ++ newer kernels with the real PCI interface. In compat.h some things are ++ defined to make the transition easier. */ ++static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, ++ const struct pci_device_id *id) ++{ ++ unsigned char temp; ++ ++ /* match up the function */ ++ if (PCI_FUNC(PIIX4_dev->devfn) != id->driver_data) ++ return -ENODEV; ++ ++ printk(KERN_INFO "Found %s device\n", PIIX4_dev->name); ++ ++#ifdef CONFIG_X86 ++ if(ibm_dmi_probe() && PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) { ++ printk(KERN_ERR "i2c-piix4.o: IBM Laptop detected; this module " ++ "may corrupt your serial eeprom! Refusing to load " ++ "module!\n"); ++ return -EPERM; ++ } ++#endif ++ ++ /* Determine the address of the SMBus areas */ ++ if (force_addr) { ++ piix4_smba = force_addr & 0xfff0; ++ force = 0; ++ } else { ++ pci_read_config_word(PIIX4_dev, SMBBA, &piix4_smba); ++ piix4_smba &= 0xfff0; ++ if(piix4_smba == 0) { ++ printk(KERN_ERR "i2c-piix4.o: SMB base address " ++ "uninitialized - upgrade BIOS or use " ++ "force_addr=0xaddr\n"); ++ return -ENODEV; ++ } ++ } ++ ++ if (!request_region(piix4_smba, SMBIOSIZE, "piix4-smbus")) { ++ printk(KERN_ERR "i2c-piix4.o: SMB region 0x%x already in " ++ "use!\n", piix4_smba); ++ return -ENODEV; ++ } ++ ++ pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp); ++ ++ /* Some BIOS will set up the chipset incorrectly and leave a register ++ in an undefined state (causing I2C to act very strangely). */ ++ if (temp & 0x02) { ++ if (fix_hstcfg) { ++ printk(KERN_INFO "i2c-piix4.o: Working around buggy " ++ "BIOS (I2C)\n"); ++ temp &= 0xfd; ++ pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp); ++ } else { ++ printk(KERN_INFO "i2c-piix4.o: Unusual config register " ++ "value\n"); ++ printk(KERN_INFO "i2c-piix4.o: Try using fix_hstcfg=1 " ++ "if you experience problems\n"); ++ } ++ } ++ ++ /* If force_addr is set, we program the new address here. Just to make ++ sure, we disable the PIIX4 first. */ ++ if (force_addr) { ++ pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp & 0xfe); ++ pci_write_config_word(PIIX4_dev, SMBBA, piix4_smba); ++ pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp | 0x01); ++ printk(KERN_INFO "i2c-piix4.o: WARNING: SMBus interface set to " ++ "new address %04x!\n", piix4_smba); ++ } else if ((temp & 1) == 0) { ++ if (force) { ++ /* This should never need to be done, but has been ++ * noted that many Dell machines have the SMBus ++ * interface on the PIIX4 disabled!? NOTE: This assumes ++ * I/O space and other allocations WERE done by the ++ * Bios! Don't complain if your hardware does weird ++ * things after enabling this. :') Check for Bios ++ * updates before resorting to this. ++ */ ++ pci_write_config_byte(PIIX4_dev, SMBHSTCFG, ++ temp | 1); ++ printk(KERN_NOTICE "i2c-piix4.o: WARNING: SMBus " ++ "interface has been FORCEFULLY ENABLED!\n"); ++ } else { ++ printk(KERN_ERR "i2c-piix4.o: Host SMBus controller " ++ "not enabled!\n"); ++ release_region(piix4_smba, SMBIOSIZE); ++ piix4_smba = 0; ++ return -ENODEV; ++ } ++ } ++ ++#ifdef DEBUG ++ if ((temp & 0x0E) == 8) ++ printk(KERN_DEBUG "i2c-piix4.o: Using Interrupt 9 for " ++ "SMBus.\n"); ++ else if ((temp & 0x0E) == 0) ++ printk(KERN_DEBUG "i2c-piix4.o: Using Interrupt SMI# " ++ "for SMBus.\n"); ++ else ++ printk(KERN_ERR "i2c-piix4.o: Illegal Interrupt configuration " ++ "(or code out of date)!\n"); ++ ++ pci_read_config_byte(PIIX4_dev, SMBREV, &temp); ++ printk(KERN_DEBUG "i2c-piix4.o: SMBREV = 0x%X\n", temp); ++ printk(KERN_DEBUG "i2c-piix4.o: SMBA = 0x%X\n", piix4_smba); ++#endif /* DEBUG */ ++ ++ return 0; ++} ++ ++ ++/* Another internally used function */ ++int piix4_transaction(void) ++{ ++ int temp; ++ int result = 0; ++ int timeout = 0; ++ ++#ifdef DEBUG ++ printk ++ (KERN_DEBUG "i2c-piix4.o: Transaction (pre): CNT=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, " ++ "DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), ++ inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); ++#endif ++ ++ /* Make sure the SMBus host is ready to start transmitting */ ++ if ((temp = inb_p(SMBHSTSTS)) != 0x00) { ++#ifdef DEBUG ++ printk(KERN_DEBUG "i2c-piix4.o: SMBus busy (%02x). Resetting... \n", ++ temp); ++#endif ++ outb_p(temp, SMBHSTSTS); ++ if ((temp = inb_p(SMBHSTSTS)) != 0x00) { ++#ifdef DEBUG ++ printk(KERN_ERR "i2c-piix4.o: Failed! (%02x)\n", temp); ++#endif ++ return -1; ++ } else { ++#ifdef DEBUG ++ printk(KERN_DEBUG "i2c-piix4.o: Successfull!\n"); ++#endif ++ } ++ } ++ ++ /* start the transaction by setting bit 6 */ ++ outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); ++ ++ /* We will always wait for a fraction of a second! (See PIIX4 docs errata) */ ++ do { ++ i2c_delay(1); ++ temp = inb_p(SMBHSTSTS); ++ } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT)); ++ ++#ifdef DEBUG ++ /* If the SMBus is still busy, we give up */ ++ if (timeout >= MAX_TIMEOUT) { ++ printk(KERN_ERR "i2c-piix4.o: SMBus Timeout!\n"); ++ result = -1; ++ } ++#endif ++ ++ if (temp & 0x10) { ++ result = -1; ++#ifdef DEBUG ++ printk(KERN_ERR "i2c-piix4.o: Error: Failed bus transaction\n"); ++#endif ++ } ++ ++ if (temp & 0x08) { ++ result = -1; ++ printk ++ (KERN_ERR "i2c-piix4.o: Bus collision! SMBus may be locked until next hard\n" ++ "reset. (sorry!)\n"); ++ /* Clock stops and slave is stuck in mid-transmission */ ++ } ++ ++ if (temp & 0x04) { ++ result = -1; ++#ifdef DEBUG ++ printk(KERN_ERR "i2c-piix4.o: Error: no response!\n"); ++#endif ++ } ++ ++ if (inb_p(SMBHSTSTS) != 0x00) ++ outb_p(inb(SMBHSTSTS), SMBHSTSTS); ++ ++#ifdef DEBUG ++ if ((temp = inb_p(SMBHSTSTS)) != 0x00) { ++ printk ++ (KERN_ERR "i2c-piix4.o: Failed reset at end of transaction (%02x)\n", ++ temp); ++ } ++ printk ++ (KERN_DEBUG "i2c-piix4.o: Transaction (post): CNT=%02x, CMD=%02x, ADD=%02x, " ++ "DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), ++ inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); ++#endif ++ return result; ++} ++ ++/* Return -1 on error. */ ++s32 piix4_access(struct i2c_adapter * adap, u16 addr, ++ unsigned short flags, char read_write, ++ u8 command, int size, union i2c_smbus_data * data) ++{ ++ int i, len; ++ ++ switch (size) { ++ case I2C_SMBUS_QUICK: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ size = PIIX4_QUICK; ++ break; ++ case I2C_SMBUS_BYTE: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ if (read_write == I2C_SMBUS_WRITE) ++ outb_p(command, SMBHSTCMD); ++ size = PIIX4_BYTE; ++ break; ++ case I2C_SMBUS_BYTE_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) ++ outb_p(data->byte, SMBHSTDAT0); ++ size = PIIX4_BYTE_DATA; ++ break; ++ case I2C_SMBUS_WORD_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) { ++ outb_p(data->word & 0xff, SMBHSTDAT0); ++ outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); ++ } ++ size = PIIX4_WORD_DATA; ++ break; ++ case I2C_SMBUS_BLOCK_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) { ++ len = data->block[0]; ++ if (len < 0) ++ len = 0; ++ if (len > 32) ++ len = 32; ++ outb_p(len, SMBHSTDAT0); ++ i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ ++ for (i = 1; i <= len; i++) ++ outb_p(data->block[i], SMBBLKDAT); ++ } ++ size = PIIX4_BLOCK_DATA; ++ break; ++ default: ++ printk ++ (KERN_WARNING "i2c-piix4.o: Unsupported transaction %d\n", size); ++ return -1; ++ } ++ ++ outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT); ++ ++ if (piix4_transaction()) /* Error in transaction */ ++ return -1; ++ ++ if ((read_write == I2C_SMBUS_WRITE) || (size == PIIX4_QUICK)) ++ return 0; ++ ++ ++ switch (size) { ++ case PIIX4_BYTE: /* Where is the result put? I assume here it is in ++ SMBHSTDAT0 but it might just as well be in the ++ SMBHSTCMD. No clue in the docs */ ++ ++ data->byte = inb_p(SMBHSTDAT0); ++ break; ++ case PIIX4_BYTE_DATA: ++ data->byte = inb_p(SMBHSTDAT0); ++ break; ++ case PIIX4_WORD_DATA: ++ data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); ++ break; ++ case PIIX4_BLOCK_DATA: ++ data->block[0] = inb_p(SMBHSTDAT0); ++ i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ ++ for (i = 1; i <= data->block[0]; i++) ++ data->block[i] = inb_p(SMBBLKDAT); ++ break; ++ } ++ return 0; ++} ++ ++ ++u32 piix4_func(struct i2c_adapter *adapter) ++{ ++ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | ++ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | ++ I2C_FUNC_SMBUS_BLOCK_DATA; ++} ++ ++static struct i2c_algorithm smbus_algorithm = { ++ .name = "Non-I2C SMBus adapter", ++ .id = I2C_ALGO_SMBUS, ++ .smbus_xfer = piix4_access, ++ .functionality = piix4_func, ++}; ++ ++static struct i2c_adapter piix4_adapter = { ++ .owner = THIS_MODULE, ++ .name = "unset", ++ .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_PIIX4, ++ .algo = &smbus_algorithm, ++}; ++ ++#ifndef PCI_DEVICE_ID_SERVERWORKS_CSB6 ++#define PCI_DEVICE_ID_SERVERWORKS_CSB6 0x0203 ++#endif ++ ++static struct pci_device_id piix4_ids[] __devinitdata = { ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_82371AB_3, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = 3 ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_SERVERWORKS, ++ .device = PCI_DEVICE_ID_SERVERWORKS_OSB4, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = 0, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_SERVERWORKS, ++ .device = PCI_DEVICE_ID_SERVERWORKS_CSB5, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = 0, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_SERVERWORKS, ++ .device = PCI_DEVICE_ID_SERVERWORKS_CSB6, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = 0, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_INTEL, ++ .device = PCI_DEVICE_ID_INTEL_82443MX_3, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = 3, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_EFAR, ++ .device = PCI_DEVICE_ID_EFAR_SLC90E66_3, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = 0, ++ }, ++ { 0, } ++}; ++ ++static int __devinit piix4_probe(struct pci_dev *dev, ++ const struct pci_device_id *id) ++{ ++ int retval; ++ ++ retval = piix4_setup(dev, id); ++ if (retval) ++ return retval; ++ ++ sprintf(piix4_adapter.name, "SMBus PIIX4 adapter at %04x", ++ piix4_smba); ++ ++ if ((retval = i2c_add_adapter(&piix4_adapter))) { ++ printk(KERN_ERR "i2c-piix4.o: Couldn't register adapter!\n"); ++ release_region(piix4_smba, SMBIOSIZE); ++ piix4_smba = 0; ++ } ++ ++ return retval; ++} ++ ++static void __devexit piix4_remove(struct pci_dev *dev) ++{ ++ if (piix4_smba) { ++ i2c_del_adapter(&piix4_adapter); ++ release_region(piix4_smba, SMBIOSIZE); ++ piix4_smba = 0; ++ } ++} ++ ++static struct pci_driver piix4_driver = { ++ .name = "piix4 smbus", ++ .id_table = piix4_ids, ++ .probe = piix4_probe, ++ .remove = __devexit_p(piix4_remove), ++}; ++ ++static int __init i2c_piix4_init(void) ++{ ++ printk("i2c-piix4.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return pci_module_init(&piix4_driver); ++} ++ ++static void __exit i2c_piix4_exit(void) ++{ ++ pci_unregister_driver(&piix4_driver); ++} ++ ++MODULE_AUTHOR("Frodo Looijaard and " ++ "Philip Edelbrock "); ++MODULE_DESCRIPTION("PIIX4 SMBus driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(i2c_piix4_init); ++module_exit(i2c_piix4_exit); +--- linux-old/drivers/i2c/i2c-savage4.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-savage4.c Mon Dec 13 20:18:42 2004 +@@ -0,0 +1,229 @@ ++/* ++ i2c-savage4.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (C) 1998-2003 The LM Sensors Team ++ Alexander Wold ++ Mark D. Studebaker ++ ++ Based on i2c-voodoo3.c. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* This interfaces to the I2C bus of the Savage4 to gain access to ++ the BT869 and possibly other I2C devices. The DDC bus is not ++ yet supported because its register is not memory-mapped. ++ However we leave the DDC code here, commented out, to make ++ it easier to add later. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* for HZ */ ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++/* 3DFX defines */ ++/* #define PCI_VENDOR_ID_S3 0x5333 */ ++#define PCI_CHIP_SAVAGE3D 0x8A20 ++#define PCI_CHIP_SAVAGE3D_MV 0x8A21 ++#define PCI_CHIP_SAVAGE4 0x8A22 ++#define PCI_CHIP_SAVAGE2000 0x9102 ++#define PCI_CHIP_PROSAVAGE_PM 0x8A25 ++#define PCI_CHIP_PROSAVAGE_KM 0x8A26 ++#define PCI_CHIP_SAVAGE_MX_MV 0x8c10 ++#define PCI_CHIP_SAVAGE_MX 0x8c11 ++#define PCI_CHIP_SAVAGE_IX_MV 0x8c12 ++#define PCI_CHIP_SAVAGE_IX 0x8c13 ++ ++#define REG 0xff20 /* Serial Port 1 Register */ ++ ++/* bit locations in the register */ ++//#define DDC_ENAB 0x00040000 ++//#define DDC_SCL_OUT 0x00080000 ++//#define DDC_SDA_OUT 0x00100000 ++//#define DDC_SCL_IN 0x00200000 ++//#define DDC_SDA_IN 0x00400000 ++#define I2C_ENAB 0x00000020 ++#define I2C_SCL_OUT 0x00000001 ++#define I2C_SDA_OUT 0x00000002 ++#define I2C_SCL_IN 0x00000008 ++#define I2C_SDA_IN 0x00000010 ++ ++/* initialization states */ ++#define INIT2 0x20 ++/* #define INIT3 0x4 */ ++ ++/* delays */ ++#define CYCLE_DELAY 10 ++#define TIMEOUT (HZ / 2) ++ ++ ++static void config_s4(struct pci_dev *dev); ++ ++static unsigned long ioaddr; ++ ++/* The sav GPIO registers don't have individual masks for each bit ++ so we always have to read before writing. */ ++ ++static void bit_savi2c_setscl(void *data, int val) ++{ ++ unsigned int r; ++ r = readl(ioaddr + REG); ++ if(val) ++ r |= I2C_SCL_OUT; ++ else ++ r &= ~I2C_SCL_OUT; ++ writel(r, ioaddr + REG); ++ readl(ioaddr + REG); /* flush posted write */ ++} ++ ++static void bit_savi2c_setsda(void *data, int val) ++{ ++ unsigned int r; ++ r = readl(ioaddr + REG); ++ if(val) ++ r |= I2C_SDA_OUT; ++ else ++ r &= ~I2C_SDA_OUT; ++ writel(r, ioaddr + REG); ++ readl(ioaddr + REG); /* flush posted write */ ++} ++ ++/* The GPIO pins are open drain, so the pins always remain outputs. ++ We rely on the i2c-algo-bit routines to set the pins high before ++ reading the input from other chips. */ ++ ++static int bit_savi2c_getscl(void *data) ++{ ++ return (0 != (readl(ioaddr + REG) & I2C_SCL_IN)); ++} ++ ++static int bit_savi2c_getsda(void *data) ++{ ++ return (0 != (readl(ioaddr + REG) & I2C_SDA_IN)); ++} ++ ++/* Configures the chip */ ++ ++void config_s4(struct pci_dev *dev) ++{ ++ unsigned int cadr; ++ ++ /* map memory */ ++ cadr = dev->resource[0].start; ++ cadr &= PCI_BASE_ADDRESS_MEM_MASK; ++ ioaddr = (unsigned long)ioremap_nocache(cadr, 0x0080000); ++ if(ioaddr) { ++// writel(0x8160, ioaddr + REG2); ++ writel(0x00000020, ioaddr + REG); ++ printk("i2c-savage4: Using Savage4 at 0x%lx\n", ioaddr); ++ } ++} ++ ++ ++static struct i2c_algo_bit_data sav_i2c_bit_data = { ++ .setsda = bit_savi2c_setsda, ++ .setscl = bit_savi2c_setscl, ++ .getsda = bit_savi2c_getsda, ++ .getscl = bit_savi2c_getscl, ++ .udelay = CYCLE_DELAY, ++ .mdelay = CYCLE_DELAY, ++ .timeout = TIMEOUT ++}; ++ ++static struct i2c_adapter savage4_i2c_adapter = { ++ .owner = THIS_MODULE, ++ .name = "I2C Savage4 adapter", ++ .id = I2C_HW_B_SAVG, ++ .algo_data = &sav_i2c_bit_data, ++}; ++ ++static struct pci_device_id savage4_ids[] __devinitdata = { ++ { ++ .vendor = PCI_VENDOR_ID_S3, ++ .device = PCI_CHIP_SAVAGE4, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_S3, ++ .device = PCI_CHIP_SAVAGE2000, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { 0, } ++}; ++ ++static int __devinit savage4_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ config_s4(dev); ++ return i2c_bit_add_bus(&savage4_i2c_adapter); ++} ++ ++static void __devexit savage4_remove(struct pci_dev *dev) ++{ ++ i2c_bit_del_bus(&savage4_i2c_adapter); ++} ++ ++ ++/* Don't register driver to avoid driver conflicts */ ++/* ++static struct pci_driver savage4_driver = { ++ .name = "savage4 smbus", ++ .id_table = savage4_ids, ++ .probe = savage4_probe, ++ .remove = __devexit_p(savage4_remove), ++}; ++*/ ++ ++static int __init i2c_savage4_init(void) ++{ ++ struct pci_dev *dev; ++ const struct pci_device_id *id; ++ ++ printk("i2c-savage4.o version %s (%s)\n", LM_VERSION, LM_DATE); ++/* ++ return pci_module_init(&savage4_driver); ++*/ ++ pci_for_each_dev(dev) { ++ id = pci_match_device(savage4_ids, dev); ++ if(id) ++ if(savage4_probe(dev, id) >= 0) ++ return 0; ++ } ++ return -ENODEV; ++} ++ ++static void __exit i2c_savage4_exit(void) ++{ ++/* ++ pci_unregister_driver(&savage4_driver); ++*/ ++ savage4_remove(NULL); ++ iounmap((void *)ioaddr); ++} ++ ++MODULE_AUTHOR("Alexander Wold " ++ "and Mark D. Studebaker "); ++MODULE_DESCRIPTION("Savage4 I2C/SMBus driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(i2c_savage4_init); ++module_exit(i2c_savage4_exit); +--- linux-old/drivers/i2c/i2c-sis5595.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-sis5595.c Mon Dec 13 20:18:42 2004 +@@ -0,0 +1,481 @@ ++/* ++ sis5595.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard and ++ Philip Edelbrock ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* Note: we assume there can only be one SIS5595 with one SMBus interface */ ++ ++/* ++ Note: all have mfr. ID 0x1039. ++ SUPPORTED PCI ID ++ 5595 0008 ++ ++ Note: these chips contain a 0008 device which is incompatible with the ++ 5595. We recognize these by the presence of the listed ++ "blacklist" PCI ID and refuse to load. ++ ++ NOT SUPPORTED PCI ID BLACKLIST PCI ID ++ 540 0008 0540 ++ 550 0008 0550 ++ 5513 0008 5511 ++ 5581 0008 5597 ++ 5582 0008 5597 ++ 5597 0008 5597 ++ 5598 0008 5597/5598 ++ 630 0008 0630 ++ 645 0008 0645 ++ 646 0008 0646 ++ 648 0008 0648 ++ 650 0008 0650 ++ 651 0008 0651 ++ 730 0008 0730 ++ 735 0008 0735 ++ 745 0008 0745 ++ 746 0008 0746 ++*/ ++ ++/* TO DO: ++ * Add Block Transfers (ugly, but supported by the adapter) ++ * Add adapter resets ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++static int blacklist[] = { ++ PCI_DEVICE_ID_SI_540, ++ PCI_DEVICE_ID_SI_550, ++ PCI_DEVICE_ID_SI_630, ++ PCI_DEVICE_ID_SI_730, ++ PCI_DEVICE_ID_SI_5511, /* 5513 chip has the 0008 device but ++ that ID shows up in other chips so we ++ use the 5511 ID for recognition */ ++ PCI_DEVICE_ID_SI_5597, ++ PCI_DEVICE_ID_SI_5598, ++ 0x645, ++ 0x646, ++ 0x648, ++ 0x650, ++ 0x651, ++ 0x735, ++ 0x745, ++ 0x746, ++ 0 }; ++ ++/* Length of ISA address segment */ ++#define SIS5595_EXTENT 8 ++/* SIS5595 SMBus registers */ ++#define SMB_STS_LO 0x00 ++#define SMB_STS_HI 0x01 ++#define SMB_CTL_LO 0x02 ++#define SMB_CTL_HI 0x03 ++#define SMB_ADDR 0x04 ++#define SMB_CMD 0x05 ++#define SMB_PCNT 0x06 ++#define SMB_CNT 0x07 ++#define SMB_BYTE 0x08 ++#define SMB_DEV 0x10 ++#define SMB_DB0 0x11 ++#define SMB_DB1 0x12 ++#define SMB_HAA 0x13 ++ ++/* PCI Address Constants */ ++#define SMB_INDEX 0x38 ++#define SMB_DAT 0x39 ++#define SIS5595_ENABLE_REG 0x40 ++#define ACPI_BASE 0x90 ++ ++/* Other settings */ ++#define MAX_TIMEOUT 500 ++ ++/* SIS5595 constants */ ++#define SIS5595_QUICK 0x00 ++#define SIS5595_BYTE 0x02 ++#define SIS5595_BYTE_DATA 0x04 ++#define SIS5595_WORD_DATA 0x06 ++#define SIS5595_PROC_CALL 0x08 ++#define SIS5595_BLOCK_DATA 0x0A ++ ++/* insmod parameters */ ++ ++/* If force_addr is set to anything different from 0, we forcibly enable ++ the device at the given address. */ ++static int force_addr = 0; ++MODULE_PARM(force_addr, "i"); ++MODULE_PARM_DESC(force_addr, ++ "Initialize the base address of the i2c controller"); ++ ++static int sis5595_transaction(void); ++ ++static unsigned short sis5595_base = 0; ++ ++static u8 sis5595_read(u8 reg) ++{ ++ outb(reg, sis5595_base + SMB_INDEX); ++ return inb(sis5595_base + SMB_DAT); ++} ++ ++static void sis5595_write(u8 reg, u8 data) ++{ ++ outb(reg, sis5595_base + SMB_INDEX); ++ outb(data, sis5595_base + SMB_DAT); ++} ++ ++ ++/* Detect whether a SIS5595 can be found, and initialize it, where necessary. ++ Note the differences between kernels with the old PCI BIOS interface and ++ newer kernels with the real PCI interface. In compat.h some things are ++ defined to make the transition easier. */ ++int sis5595_setup(struct pci_dev *SIS5595_dev) ++{ ++ u16 a; ++ u8 val; ++ int *i; ++ ++ /* Look for imposters */ ++ for(i = blacklist; *i != 0; i++) { ++ if (pci_find_device(PCI_VENDOR_ID_SI, *i, NULL)) { ++ printk("i2c-sis5595.o: Error: Looked for SIS5595 but found unsupported device %.4X\n", *i); ++ return -ENODEV; ++ } ++ } ++ ++/* Determine the address of the SMBus areas */ ++ pci_read_config_word(SIS5595_dev, ACPI_BASE, &sis5595_base); ++ if(sis5595_base == 0 && force_addr == 0) { ++ printk("i2c-sis5595.o: ACPI base address uninitialized - upgrade BIOS or use force_addr=0xaddr\n"); ++ return -ENODEV; ++ } ++ ++ if(force_addr) ++ sis5595_base = force_addr & ~(SIS5595_EXTENT - 1); ++#ifdef DEBUG ++ printk("ACPI Base address: %04x\n", sis5595_base); ++#endif ++ /* NB: We grab just the two SMBus registers here, but this may still ++ * interfere with ACPI :-( */ ++ if (check_region(sis5595_base + SMB_INDEX, 2)) { ++ printk ++ ("i2c-sis5595.o: SMBus registers 0x%04x-0x%04x already in use!\n", ++ sis5595_base + SMB_INDEX, ++ sis5595_base + SMB_INDEX + 1); ++ return -ENODEV; ++ } ++ ++ if(force_addr) { ++ printk("i2c-sis5595.o: forcing ISA address 0x%04X\n", sis5595_base); ++ if (PCIBIOS_SUCCESSFUL != ++ pci_write_config_word(SIS5595_dev, ACPI_BASE, sis5595_base)) ++ return -ENODEV; ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_word(SIS5595_dev, ACPI_BASE, &a)) ++ return -ENODEV; ++ if ((a & ~(SIS5595_EXTENT - 1)) != sis5595_base) { ++ /* doesn't work for some chips! */ ++ printk("i2c-sis5595.o: force address failed - not supported?\n"); ++ return -ENODEV; ++ } ++ } ++ ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)) ++ return -ENODEV; ++ if((val & 0x80) == 0) { ++ printk("sis5595.o: enabling ACPI\n"); ++ if (PCIBIOS_SUCCESSFUL != ++ pci_write_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, ++ val | 0x80)) ++ return -ENODEV; ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)) ++ return -ENODEV; ++ if((val & 0x80) == 0) { /* doesn't work for some chips? */ ++ printk("sis5595.o: ACPI enable failed - not supported?\n"); ++ return -ENODEV; ++ } ++ } ++ ++ /* Everything is happy, let's grab the memory and set things up. */ ++ request_region(sis5595_base + SMB_INDEX, 2, "sis5595-smbus"); ++ return(0); ++} ++ ++ ++/* Another internally used function */ ++int sis5595_transaction(void) ++{ ++ int temp; ++ int result = 0; ++ int timeout = 0; ++ ++ /* Make sure the SMBus host is ready to start transmitting */ ++ if ( ++ (temp = ++ sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != ++ 0x00) { ++#ifdef DEBUG ++ printk("i2c-sis5595.o: SMBus busy (%04x). Resetting... \n", ++ temp); ++#endif ++ sis5595_write(SMB_STS_LO, temp & 0xff); ++ sis5595_write(SMB_STS_HI, temp >> 8); ++ if ( ++ (temp = ++ sis5595_read(SMB_STS_LO) + ++ (sis5595_read(SMB_STS_HI) << 8)) != 0x00) { ++#ifdef DEBUG ++ printk("i2c-sis5595.o: Failed! (%02x)\n", temp); ++#endif ++ return -1; ++ } else { ++#ifdef DEBUG ++ printk("i2c-sis5595.o: Successfull!\n"); ++#endif ++ } ++ } ++ ++ /* start the transaction by setting bit 4 */ ++ sis5595_write(SMB_CTL_LO, sis5595_read(SMB_CTL_LO) | 0x10); ++ ++ /* We will always wait for a fraction of a second! */ ++ do { ++ i2c_delay(1); ++ temp = sis5595_read(SMB_STS_LO); ++ } while (!(temp & 0x40) && (timeout++ < MAX_TIMEOUT)); ++ ++ /* If the SMBus is still busy, we give up */ ++ if (timeout >= MAX_TIMEOUT) { ++#ifdef DEBUG ++ printk("i2c-sis5595.o: SMBus Timeout!\n"); ++#endif ++ result = -1; ++ } ++ ++ if (temp & 0x10) { ++ result = -1; ++#ifdef DEBUG ++ printk("i2c-sis5595.o: Error: Failed bus transaction\n"); ++#endif ++ } ++ ++ if (temp & 0x20) { ++ result = -1; ++ printk ++ ("i2c-sis5595.o: Bus collision! SMBus may be locked until next hard\n" ++ "reset (or not...)\n"); ++ /* Clock stops and slave is stuck in mid-transmission */ ++ } ++ ++ if ( ++ (temp = ++ sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != ++ 0x00) { ++ sis5595_write(SMB_STS_LO, temp & 0xff); ++ sis5595_write(SMB_STS_HI, temp >> 8); ++ } ++ ++ if ( ++ (temp = ++ sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != ++ 0x00) { ++ ++#ifdef DEBUG ++ printk ++ ("i2c-sis5595.o: Failed reset at end of transaction (%02x)\n", ++ temp); ++#endif ++ } ++ return result; ++} ++ ++/* Return -1 on error. */ ++s32 sis5595_access(struct i2c_adapter * adap, u16 addr, ++ unsigned short flags, char read_write, ++ u8 command, int size, union i2c_smbus_data * data) ++{ ++ switch (size) { ++ case I2C_SMBUS_QUICK: ++ sis5595_write(SMB_ADDR, ++ ((addr & 0x7f) << 1) | (read_write & 0x01)); ++ size = SIS5595_QUICK; ++ break; ++ case I2C_SMBUS_BYTE: ++ sis5595_write(SMB_ADDR, ++ ((addr & 0x7f) << 1) | (read_write & 0x01)); ++ if (read_write == I2C_SMBUS_WRITE) ++ sis5595_write(SMB_CMD, command); ++ size = SIS5595_BYTE; ++ break; ++ case I2C_SMBUS_BYTE_DATA: ++ sis5595_write(SMB_ADDR, ++ ((addr & 0x7f) << 1) | (read_write & 0x01)); ++ sis5595_write(SMB_CMD, command); ++ if (read_write == I2C_SMBUS_WRITE) ++ sis5595_write(SMB_BYTE, data->byte); ++ size = SIS5595_BYTE_DATA; ++ break; ++ case I2C_SMBUS_PROC_CALL: ++ case I2C_SMBUS_WORD_DATA: ++ sis5595_write(SMB_ADDR, ++ ((addr & 0x7f) << 1) | (read_write & 0x01)); ++ sis5595_write(SMB_CMD, command); ++ if (read_write == I2C_SMBUS_WRITE) { ++ sis5595_write(SMB_BYTE, data->word & 0xff); ++ sis5595_write(SMB_BYTE + 1, ++ (data->word & 0xff00) >> 8); ++ } ++ size = ++ (size == ++ I2C_SMBUS_PROC_CALL) ? SIS5595_PROC_CALL : ++ SIS5595_WORD_DATA; ++ break; ++/* ++ case I2C_SMBUS_BLOCK_DATA: ++ printk("sis5595.o: Block data not yet implemented!\n"); ++ return -1; ++ break; ++*/ ++ default: ++ printk ++ (KERN_WARNING "sis5595.o: Unsupported transaction %d\n", size); ++ return -1; ++ } ++ ++ sis5595_write(SMB_CTL_LO, ((size & 0x0E))); ++ ++ if (sis5595_transaction()) /* Error in transaction */ ++ return -1; ++ ++ if ((size != SIS5595_PROC_CALL) && ++ ((read_write == I2C_SMBUS_WRITE) || (size == SIS5595_QUICK))) ++ return 0; ++ ++ ++ switch (size) { ++ case SIS5595_BYTE: /* Where is the result put? I assume here it is in ++ SMB_DATA but it might just as well be in the ++ SMB_CMD. No clue in the docs */ ++ case SIS5595_BYTE_DATA: ++ data->byte = sis5595_read(SMB_BYTE); ++ break; ++ case SIS5595_WORD_DATA: ++ case SIS5595_PROC_CALL: ++ data->word = ++ sis5595_read(SMB_BYTE) + ++ (sis5595_read(SMB_BYTE + 1) << 8); ++ break; ++ } ++ return 0; ++} ++ ++ ++u32 sis5595_func(struct i2c_adapter *adapter) ++{ ++ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | ++ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | ++ I2C_FUNC_SMBUS_PROC_CALL; ++} ++ ++ ++static struct i2c_algorithm smbus_algorithm = { ++ .name = "Non-I2C SMBus adapter", ++ .id = I2C_ALGO_SMBUS, ++ .smbus_xfer = sis5595_access, ++ .functionality = sis5595_func, ++}; ++ ++static struct i2c_adapter sis5595_adapter = { ++ .owner = THIS_MODULE, ++ .name = "unset", ++ .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_SIS5595, ++ .algo = &smbus_algorithm, ++}; ++ ++ ++static struct pci_device_id sis5595_ids[] __devinitdata = { ++ { ++ .vendor = PCI_VENDOR_ID_SI, ++ .device = PCI_DEVICE_ID_SI_503, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { 0, } ++}; ++ ++static int __devinit sis5595_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ ++ if (sis5595_setup(dev)) { ++ printk ++ ("i2c-sis5595.o: SIS5595 not detected, module not inserted.\n"); ++ ++ return -ENODEV; ++ } ++ ++ sprintf(sis5595_adapter.name, "SMBus SIS5595 adapter at %04x", ++ sis5595_base + SMB_INDEX); ++ i2c_add_adapter(&sis5595_adapter); ++ ++ return 0; ++} ++ ++static void __devexit sis5595_remove(struct pci_dev *dev) ++{ ++ i2c_del_adapter(&sis5595_adapter); ++ release_region(sis5595_base + SMB_INDEX, 2); ++} ++ ++ ++static struct pci_driver sis5595_driver = { ++ .name = "sis5595 smbus", ++ .id_table = sis5595_ids, ++ .probe = sis5595_probe, ++ .remove = __devexit_p(sis5595_remove), ++}; ++ ++static int __init i2c_sis5595_init(void) ++{ ++ printk("i2c-sis5595.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return pci_module_init(&sis5595_driver); ++} ++ ++ ++static void __exit i2c_sis5595_exit(void) ++{ ++ pci_unregister_driver(&sis5595_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Frodo Looijaard "); ++MODULE_DESCRIPTION("SIS5595 SMBus driver"); ++ ++module_init(i2c_sis5595_init); ++module_exit(i2c_sis5595_exit); +--- linux-old/drivers/i2c/i2c-sis630.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-sis630.c Mon Dec 13 20:18:42 2004 +@@ -0,0 +1,527 @@ ++/* ++ i2c-sis630.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ ++ Copyright (c) 2002,2003 Alexander Malysh ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ Changes: ++ 24.08.2002 ++ Fixed the typo in sis630_access (Thanks to Mark M. Hoffman) ++ Changed sis630_transaction.(Thanks to Mark M. Hoffman) ++ 18.09.2002 ++ Added SIS730 as supported. ++ 21.09.2002 ++ Added high_clock module option.If this option is set ++ used Host Master Clock 56KHz (default 14KHz).For now we save old Host ++ Master Clock and after transaction completed restore (otherwise ++ it's confuse BIOS and hung Machine). ++ 24.09.2002 ++ Fixed typo in sis630_access ++ Fixed logical error by restoring of Host Master Clock ++ 31.07.2003 ++ Added block data read/write support. ++*/ ++ ++/* ++ Status: beta ++ ++ Supports: ++ SIS 630 ++ SIS 730 ++ ++ Note: we assume there can only be one device, with one SMBus interface. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++ ++#ifdef DEBUG ++#define DBG(x...) printk(KERN_DEBUG "i2c-sis630.o: " x) ++#else ++#define DBG(x...) ++#endif ++ ++/* SIS630 SMBus registers */ ++#define SMB_STS 0x80 /* status */ ++#define SMB_EN 0x81 /* status enable */ ++#define SMB_CNT 0x82 ++#define SMBHOST_CNT 0x83 ++#define SMB_ADDR 0x84 ++#define SMB_CMD 0x85 ++#define SMB_PCOUNT 0x86 /* processed count */ ++#define SMB_COUNT 0x87 ++#define SMB_BYTE 0x88 /* ~0x8F data byte field */ ++#define SMBDEV_ADDR 0x90 ++#define SMB_DB0 0x91 ++#define SMB_DB1 0x92 ++#define SMB_SAA 0x93 ++ ++/* register count for request_region */ ++#define SIS630_SMB_IOREGION 20 ++ ++/* PCI address constants */ ++/* acpi base address register */ ++#define SIS630_ACPI_BASE_REG 0x74 ++/* bios control register */ ++#define SIS630_BIOS_CTL_REG 0x40 ++ ++/* Other settings */ ++#define MAX_TIMEOUT 500 ++ ++/* SIS630 constants */ ++#define SIS630_QUICK 0x00 ++#define SIS630_BYTE 0x01 ++#define SIS630_BYTE_DATA 0x02 ++#define SIS630_WORD_DATA 0x03 ++#define SIS630_PCALL 0x04 ++#define SIS630_BLOCK_DATA 0x05 ++ ++/* insmod parameters */ ++static int high_clock = 0; ++static int force = 0; ++MODULE_PARM(high_clock, "i"); ++MODULE_PARM_DESC(high_clock, "Set Host Master Clock to 56KHz (default 14KHz)."); ++MODULE_PARM(force, "i"); ++MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!"); ++ ++/* acpi base address */ ++static unsigned short acpi_base = 0; ++ ++/* supported chips */ ++static int supported[] = { ++ PCI_DEVICE_ID_SI_630, ++ PCI_DEVICE_ID_SI_730, ++ 0 /* terminates the list */ ++}; ++ ++static inline u8 sis630_read(u8 reg) { ++ return inb(acpi_base + reg); ++} ++ ++static inline void sis630_write(u8 reg, u8 data) { ++ outb(data, acpi_base + reg); ++} ++ ++static int sis630_transaction_start(int size, u8 *oldclock) { ++ int temp; ++ ++ /* ++ Make sure the SMBus host is ready to start transmitting. ++ */ ++ if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) { ++ DBG("SMBus busy (%02x).Resetting...\n",temp); ++ /* kill smbus transaction */ ++ sis630_write(SMBHOST_CNT, 0x20); ++ ++ if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) { ++ DBG("Failed! (%02x)\n", temp); ++ return -1; ++ } else { ++ DBG("Successfull!\n"); ++ } ++ } ++ ++ /* save old clock, so we can prevent machine for hung */ ++ *oldclock = sis630_read(SMB_CNT); ++ ++ DBG("saved clock 0x%02x\n", *oldclock); ++ ++ /* disable timeout interrupt , set Host Master Clock to 56KHz if requested */ ++ if (high_clock > 0) ++ sis630_write(SMB_CNT, 0x20); ++ else ++ sis630_write(SMB_CNT, (*oldclock & ~0x40)); ++ ++ /* clear all sticky bits */ ++ temp = sis630_read(SMB_STS); ++ sis630_write(SMB_STS, temp & 0x1e); ++ ++ /* start the transaction by setting bit 4 and size */ ++ sis630_write(SMBHOST_CNT,0x10 | (size & 0x07)); ++ ++ return 0; ++} ++ ++static int sis630_transaction_wait(int size) { ++ int temp, result = 0, timeout = 0; ++ ++ /* We will always wait for a fraction of a second! */ ++ do { ++ i2c_delay(1); ++ temp = sis630_read(SMB_STS); ++ /* check if block transmitted */ ++ if (size == SIS630_BLOCK_DATA && (temp & 0x10)) ++ break; ++ } while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT)); ++ ++ /* If the SMBus is still busy, we give up */ ++ if (timeout >= MAX_TIMEOUT) { ++ DBG("SMBus Timeout!\n"); ++ result = -1; ++ } ++ ++ if (temp & 0x02) { ++ result = -1; ++ DBG("Error: Failed bus transaction\n"); ++ } ++ ++ if (temp & 0x04) { ++ result = -1; ++ printk(KERN_ERR "i2c-sis630.o: Bus collision!\n"); ++ /* ++ TBD: Datasheet say: ++ the software should clear this bit and restart SMBUS operation. ++ Should we do it or user start request again? ++ */ ++ } ++ ++ return result; ++} ++ ++static void sis630_transaction_end(u8 oldclock) { ++ int temp = 0; ++ ++ /* clear all status "sticky" bits */ ++ sis630_write(SMB_STS, temp); ++ ++ DBG("SMB_CNT before clock restore 0x%02x\n", sis630_read(SMB_CNT)); ++ ++ /* ++ * restore old Host Master Clock if high_clock is set ++ * and oldclock was not 56KHz ++ */ ++ if (high_clock > 0 && !(oldclock & 0x20)) ++ sis630_write(SMB_CNT,(sis630_read(SMB_CNT) & ~0x20)); ++ ++ DBG("SMB_CNT after clock restore 0x%02x\n", sis630_read(SMB_CNT)); ++} ++ ++static int sis630_transaction(int size) { ++ int result = 0; ++ u8 oldclock = 0; ++ ++ if (!(result = sis630_transaction_start(size, &oldclock))) { ++ result = sis630_transaction_wait(size); ++ sis630_transaction_end(oldclock); ++ } ++ ++ return result; ++} ++ ++static int sis630_block_data(union i2c_smbus_data * data, int read_write) { ++ int i, len = 0, rc = 0; ++ u8 oldclock = 0; ++ ++ if (read_write == I2C_SMBUS_WRITE) { ++ len = data->block[0]; ++ if (len < 0) ++ len = 0; ++ else if (len > 32) ++ len = 32; ++ sis630_write(SMB_COUNT, len); ++ for (i=1; i <= len; i++) { ++ DBG("set data 0x%02x\n", data->block[i]); ++ /* set data */ ++ sis630_write(SMB_BYTE+(i-1)%8, data->block[i]); ++ if (i==8 || (len<8 && i==len)) { ++ DBG("start trans len=%d i=%d\n",len ,i); ++ /* first transaction */ ++ if (sis630_transaction_start(SIS630_BLOCK_DATA, &oldclock)) ++ return -1; ++ } ++ else if ((i-1)%8 == 7 || i==len) { ++ DBG("trans_wait len=%d i=%d\n",len,i); ++ if (i>8) { ++ DBG("clear smbary_sts len=%d i=%d\n",len,i); ++ /* ++ If this is not first transaction, ++ we must clear sticky bit. ++ clear SMBARY_STS ++ */ ++ sis630_write(SMB_STS,0x10); ++ } ++ if (sis630_transaction_wait(SIS630_BLOCK_DATA)) { ++ DBG("trans_wait failed\n"); ++ rc = -1; ++ break; ++ } ++ ++ } ++ } ++ } ++ else { /* read request */ ++ data->block[0] = len = 0; ++ if (sis630_transaction_start(SIS630_BLOCK_DATA, &oldclock)) { ++ return -1; ++ } ++ do { ++ if (sis630_transaction_wait(SIS630_BLOCK_DATA)) { ++ DBG("trans_wait failed\n"); ++ rc = -1; ++ break; ++ } ++ /* if this first transaction then read byte count */ ++ if (len == 0) ++ data->block[0] = sis630_read(SMB_COUNT); ++ ++ /* just to be sure */ ++ if (data->block[0] > 32) ++ data->block[0] = 32; ++ ++ DBG("block data read len=0x%x\n", data->block[0]); ++ ++ for (i=0; i < 8 && len < data->block[0]; i++,len++) { ++ DBG("read i=%d len=%d\n", i, len); ++ data->block[len+1] = sis630_read(SMB_BYTE+i); ++ } ++ ++ DBG("clear smbary_sts len=%d i=%d\n",len,i); ++ ++ /* clear SMBARY_STS */ ++ sis630_write(SMB_STS,0x10); ++ } while(len < data->block[0]); ++ } ++ ++ sis630_transaction_end(oldclock); ++ ++ return rc; ++} ++ ++/* Return -1 on error. */ ++static s32 sis630_access(struct i2c_adapter * adap, u16 addr, ++ unsigned short flags, char read_write, ++ u8 command, int size, union i2c_smbus_data * data) ++{ ++ ++ switch (size) { ++ case I2C_SMBUS_QUICK: ++ sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); ++ size = SIS630_QUICK; ++ break; ++ case I2C_SMBUS_BYTE: ++ sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); ++ if (read_write == I2C_SMBUS_WRITE) ++ sis630_write(SMB_CMD, command); ++ size = SIS630_BYTE; ++ break; ++ case I2C_SMBUS_BYTE_DATA: ++ sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); ++ sis630_write(SMB_CMD, command); ++ if (read_write == I2C_SMBUS_WRITE) ++ sis630_write(SMB_BYTE, data->byte); ++ size = SIS630_BYTE_DATA; ++ break; ++ case I2C_SMBUS_PROC_CALL: ++ case I2C_SMBUS_WORD_DATA: ++ sis630_write(SMB_ADDR,((addr & 0x7f) << 1) | (read_write & 0x01)); ++ sis630_write(SMB_CMD, command); ++ if (read_write == I2C_SMBUS_WRITE) { ++ sis630_write(SMB_BYTE, data->word & 0xff); ++ sis630_write(SMB_BYTE + 1,(data->word & 0xff00) >> 8); ++ } ++ size = (size == I2C_SMBUS_PROC_CALL ? SIS630_PCALL : SIS630_WORD_DATA); ++ break; ++ case I2C_SMBUS_BLOCK_DATA: ++ sis630_write(SMB_ADDR,((addr & 0x7f) << 1) | (read_write & 0x01)); ++ sis630_write(SMB_CMD, command); ++ size = SIS630_BLOCK_DATA; ++ return sis630_block_data(data, read_write); ++ default: ++ printk("Unsupported I2C size\n"); ++ return -1; ++ break; ++ } ++ ++ ++ if (sis630_transaction(size)) ++ return -1; ++ ++ if ((size != SIS630_PCALL) && ++ ((read_write == I2C_SMBUS_WRITE) || (size == SIS630_QUICK))) { ++ return 0; ++ } ++ ++ switch(size) { ++ case SIS630_BYTE: ++ case SIS630_BYTE_DATA: ++ data->byte = sis630_read(SMB_BYTE); ++ break; ++ case SIS630_PCALL: ++ case SIS630_WORD_DATA: ++ data->word = sis630_read(SMB_BYTE) + (sis630_read(SMB_BYTE + 1) << 8); ++ break; ++ default: ++ return -1; ++ break; ++ } ++ ++ return 0; ++} ++ ++ ++static u32 sis630_func(struct i2c_adapter *adapter) { ++ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | ++ I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL | ++ I2C_FUNC_SMBUS_BLOCK_DATA; ++} ++ ++static int __devinit sis630_setup(struct pci_dev *sis630_dev) { ++ unsigned char b; ++ struct pci_dev *dummy = NULL; ++ int i; ++ ++ /* check for supported SiS devices */ ++ for (i=0; supported[i] > 0; i++) { ++ if ((dummy = pci_find_device(PCI_VENDOR_ID_SI, supported[i], dummy))) ++ break; /* found */ ++ } ++ ++ if (!dummy && force > 0) { ++ printk(KERN_ERR "i2c-sis630.o: WARNING: Can't detect SIS630 compatible device, but " ++ "loading because of force option enabled\n"); ++ } ++ else if (!dummy) { ++ return -ENODEV; ++ } ++ ++ /* ++ Enable ACPI first , so we can accsess reg 74-75 ++ in acpi io space and read acpi base addr ++ */ ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) { ++ printk(KERN_ERR "i2c-sis630.o: Error: Can't read bios ctl reg\n"); ++ return -ENODEV; ++ } ++ ++ /* if ACPI already enabled , do nothing */ ++ if (!(b & 0x80) && ++ PCIBIOS_SUCCESSFUL != ++ pci_write_config_byte(sis630_dev,SIS630_BIOS_CTL_REG,b|0x80)) { ++ printk(KERN_ERR "i2c-sis630.o: Error: Can't enable ACPI\n"); ++ return -ENODEV; ++ } ++ /* Determine the ACPI base address */ ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) { ++ printk(KERN_ERR "i2c-sis630.o: Error: Can't determine ACPI base address\n"); ++ return -ENODEV; ++ } ++ ++ DBG("ACPI base at 0x%04x\n", acpi_base); ++ ++ /* Everything is happy, let's grab the memory and set things up. */ ++ if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION, "sis630-smbus")){ ++ printk(KERN_ERR "i2c-sis630.o: SMBus registers 0x%04x-0x%04x " ++ "already in use!\n",acpi_base + SMB_STS, acpi_base + SMB_SAA); ++ acpi_base = 0; /* reset acpi_base */ ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++ ++static struct i2c_algorithm smbus_algorithm = { ++ .name = "Non-I2C SMBus adapter", ++ .id = I2C_ALGO_SMBUS, ++ .smbus_xfer = sis630_access, ++ .functionality = sis630_func, ++}; ++ ++static struct i2c_adapter sis630_adapter = { ++ .owner = THIS_MODULE, ++ .name = "unset", ++ .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_SIS630, ++ .algo = &smbus_algorithm, ++}; ++ ++ ++static struct pci_device_id sis630_ids[] __devinitdata = { ++ { ++ .vendor = PCI_VENDOR_ID_SI, ++ .device = PCI_DEVICE_ID_SI_503, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { 0, } ++}; ++ ++static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ if (sis630_setup(dev)) { ++ printk(KERN_ERR "i2c-sis630.o: SIS630 comp. bus not detected, module not inserted.\n"); ++ return -ENODEV; ++ } ++ ++ sprintf(sis630_adapter.name, "SMBus SIS630 adapter at %04x", ++ acpi_base + SMB_STS); ++ ++ return i2c_add_adapter(&sis630_adapter); ++} ++ ++static void __devexit sis630_remove(struct pci_dev *dev) ++{ ++ if (acpi_base) { ++ i2c_del_adapter(&sis630_adapter); ++ release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION); ++ acpi_base = 0; ++ } ++} ++ ++ ++static struct pci_driver sis630_driver = { ++ .name = "sis630 smbus", ++ .id_table = sis630_ids, ++ .probe = sis630_probe, ++ .remove = __devexit_p(sis630_remove), ++}; ++ ++static int __init i2c_sis630_init(void) ++{ ++ printk("i2c-sis630.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return pci_module_init(&sis630_driver); ++} ++ ++ ++static void __exit i2c_sis630_exit(void) ++{ ++ pci_unregister_driver(&sis630_driver); ++} ++ ++ ++ ++ ++MODULE_LICENSE("GPL"); ++ ++MODULE_AUTHOR("Alexander Malysh "); ++MODULE_DESCRIPTION("SIS630 SMBus driver"); ++ ++module_init(i2c_sis630_init); ++module_exit(i2c_sis630_exit); +--- linux-old/drivers/i2c/i2c-sis645.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-sis645.c Mon Dec 13 20:18:42 2004 +@@ -0,0 +1,590 @@ ++/* ++ sis645.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ ++ Copyright (c) 2003 Mark M. Hoffman ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ This module must be considered BETA unless and until ++ the chipset manufacturer releases a datasheet. ++ ++ The register definitions are based on the SiS630. ++ The method for *finding* the registers is based on trial and error. ++ ++ A history of changes to this file is available by anonymous CVS: ++ http://www2.lm-sensors.nu/~lm78/download.html ++*/ ++ ++/* 25th March 2004 ++ Support for Sis655 chipsets added by Ken Healy ++*/ ++ ++/* ++ Note: we assume there can only be one SiS645 with one SMBus interface ++*/ ++ ++/* #define DEBUG 1 */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++ ++#define DRV_NAME "i2c-sis645" ++ ++/* SiS645DX north bridge (defined in 2.4.21) */ ++#ifndef PCI_DEVICE_ID_SI_646 ++#define PCI_DEVICE_ID_SI_646 0x0646 ++#endif ++ ++/* SiS648 north bridge (defined in 2.4.21) */ ++#ifndef PCI_DEVICE_ID_SI_648 ++#define PCI_DEVICE_ID_SI_648 0x0648 ++#endif ++ ++/* SiS650 north bridge (defined in 2.4.19) */ ++#ifndef PCI_DEVICE_ID_SI_650 ++#define PCI_DEVICE_ID_SI_650 0x0650 ++#endif ++ ++/* SiS651 north bridge (defined in 2.4.21)*/ ++#ifndef PCI_DEVICE_ID_SI_651 ++#define PCI_DEVICE_ID_SI_651 0x0651 ++#endif ++ ++/* SiS655 north bridge (defined in 2.4.22)*/ ++#ifndef PCI_DEVICE_ID_SI_655 ++#define PCI_DEVICE_ID_SI_655 0x0655 ++#endif ++ ++/* SiS746 north bridge (defined in 2.4.21) */ ++#ifndef PCI_DEVICE_ID_SI_746 ++#define PCI_DEVICE_ID_SI_746 0x0746 ++#endif ++ ++/* SiS85C503/5513 (LPC Bridge) */ ++#ifndef PCI_DEVICE_ID_SI_LPC ++#define PCI_DEVICE_ID_SI_LPC 0x0018 ++#endif ++ ++/* SiS961 south bridge */ ++#ifndef PCI_DEVICE_ID_SI_961 ++#define PCI_DEVICE_ID_SI_961 0x0961 ++#endif ++ ++/* SiS962 south bridge */ ++#ifndef PCI_DEVICE_ID_SI_962 ++#define PCI_DEVICE_ID_SI_962 0x0962 ++#endif ++ ++/* SiS963 south bridge */ ++#ifndef PCI_DEVICE_ID_SI_963 ++#define PCI_DEVICE_ID_SI_963 0x0963 ++#endif ++ ++/* SMBus ID */ ++#ifndef PCI_DEVICE_ID_SI_SMBUS ++#define PCI_DEVICE_ID_SI_SMBUS 0x16 ++#endif ++ ++/* base address register in PCI config space */ ++#define SIS645_BAR 0x04 ++ ++/* SiS645 SMBus registers */ ++#define SMB_STS 0x00 ++#define SMB_EN 0x01 ++#define SMB_CNT 0x02 ++#define SMB_HOST_CNT 0x03 ++#define SMB_ADDR 0x04 ++#define SMB_CMD 0x05 ++#define SMB_PCOUNT 0x06 ++#define SMB_COUNT 0x07 ++#define SMB_BYTE 0x08 ++#define SMB_DEV_ADDR 0x10 ++#define SMB_DB0 0x11 ++#define SMB_DB1 0x12 ++#define SMB_SAA 0x13 ++ ++/* register count for request_region */ ++#define SMB_IOSIZE 0x20 ++ ++/* Other settings */ ++#define MAX_TIMEOUT 500 ++ ++/* SiS645 SMBus constants */ ++#define SIS645_QUICK 0x00 ++#define SIS645_BYTE 0x01 ++#define SIS645_BYTE_DATA 0x02 ++#define SIS645_WORD_DATA 0x03 ++#define SIS645_PROC_CALL 0x04 ++#define SIS645_BLOCK_DATA 0x05 ++ ++static struct i2c_adapter sis645_adapter; ++static u16 sis645_smbus_base = 0; ++ ++static inline u8 sis645_read(u8 reg) ++{ ++ return inb(sis645_smbus_base + reg) ; ++} ++ ++static inline void sis645_write(u8 reg, u8 data) ++{ ++ outb(data, sis645_smbus_base + reg) ; ++} ++ ++#ifdef CONFIG_HOTPLUG ++ ++/* Turns on SMBus device if it is not; return 0 iff successful ++ */ ++static int __devinit sis645_enable_smbus(struct pci_dev *dev) ++{ ++ u8 val = 0; ++ ++ pci_read_config_byte(dev, 0x77, &val); ++ ++#ifdef DEBUG ++ printk(KERN_DEBUG DRV_NAME ": Config byte was 0x%02x.\n", val); ++#endif ++ ++ pci_write_config_byte(dev, 0x77, val & ~0x10); ++ ++ pci_read_config_byte(dev, 0x77, &val); ++ ++ if (val & 0x10) { ++#ifdef DEBUG ++ printk(KERN_DEBUG DRV_NAME ": Config byte stuck!\n"); ++#endif ++ return -1; ++ } ++ ++ return 0; ++} ++ ++/* Builds the basic pci_dev for SiS645 SMBus ++ */ ++static int __devinit sis645_build_dev(struct pci_dev **smbus_dev, ++ struct pci_dev *bridge_dev) ++{ ++ struct pci_dev temp_dev; ++ u16 vid = 0, did = 0; ++ int ret; ++ ++ /* fill in the device structure for search */ ++ memset(&temp_dev, 0, sizeof(temp_dev)); ++ temp_dev.bus = bridge_dev->bus; ++ temp_dev.sysdata = bridge_dev->bus->sysdata; ++ temp_dev.hdr_type = PCI_HEADER_TYPE_NORMAL; ++ ++ /* the SMBus device is function 1 on the same unit as the ISA bridge */ ++ temp_dev.devfn = bridge_dev->devfn + 1; ++ ++ /* query to make sure */ ++ ret = pci_read_config_word(&temp_dev, PCI_VENDOR_ID, &vid); ++ if (ret || PCI_VENDOR_ID_SI != vid) { ++ printk(KERN_ERR DRV_NAME ": Couldn't find SMBus device!\n"); ++ return ret; ++ } ++ temp_dev.vendor = vid; ++ ++ ret = pci_read_config_word(&temp_dev, PCI_DEVICE_ID, &did); ++ if (ret || PCI_DEVICE_ID_SI_SMBUS != did) { ++ printk(KERN_ERR DRV_NAME ": Couldn't find SMBus device!\n"); ++ return ret; ++ } ++ temp_dev.device = did; ++ ++ /* ok, we've got it... request some memory and finish it off */ ++ *smbus_dev = kmalloc(sizeof(**smbus_dev), GFP_ATOMIC); ++ if (NULL == *smbus_dev) { ++ printk(KERN_ERR DRV_NAME ": Out of memory!\n"); ++ return -ENOMEM; ++ } ++ ++ **smbus_dev = temp_dev; ++ ++ ret = pci_setup_device(*smbus_dev); ++ if (ret) { ++ printk(KERN_ERR DRV_NAME ": pci_setup_device failed (0x%08x)\n",ret); ++ } ++ return ret; ++} ++ ++/* See if a SMBus can be found, and enable it if possible. ++ */ ++static int __devinit sis645_hotplug_smbus(void) ++{ ++ int ret; ++ struct pci_dev *smbus_dev, *bridge_dev ; ++ ++ if ((bridge_dev = pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_961, NULL))) ++ printk(KERN_INFO DRV_NAME ": Found SiS961 south bridge.\n"); ++ ++ else if ((bridge_dev = pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_962, NULL))) ++ printk(KERN_INFO DRV_NAME ": Found SiS962 [MuTIOL Media IO].\n"); ++ ++ else if ((bridge_dev = pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_963, NULL))) ++ printk(KERN_INFO DRV_NAME ": Found SiS963 [MuTIOL Media IO].\n"); ++ ++ else if ((bridge_dev = pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_503, NULL)) || ++ (bridge_dev = pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_LPC, NULL))) { ++ ++ printk(KERN_INFO DRV_NAME ": Found SiS south bridge in compatability mode(?)\n"); ++ ++ /* look for known compatible north bridges */ ++ if ((NULL == pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_645, NULL)) ++ && (NULL == pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_646, NULL)) ++ && (NULL == pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_648, NULL)) ++ && (NULL == pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_650, NULL)) ++ && (NULL == pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_651, NULL)) ++ && (NULL == pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_655, NULL)) ++ && (NULL == pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_735, NULL)) ++ && (NULL == pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_745, NULL)) ++ && (NULL == pci_find_device(PCI_VENDOR_ID_SI, ++ PCI_DEVICE_ID_SI_746, NULL))) { ++ printk(KERN_ERR DRV_NAME ": Can't find suitable host bridge!\n"); ++ return -ENODEV; ++ } ++ } else { ++ printk(KERN_ERR DRV_NAME ": Can't find suitable south bridge!\n"); ++ return -ENODEV; ++ } ++ ++ /* if we get this far, we think the smbus device is present */ ++ ++ if ((ret = sis645_enable_smbus(bridge_dev))) ++ return ret; ++ ++ if ((ret = sis645_build_dev(&smbus_dev, bridge_dev))) ++ return ret; ++ ++ if ((ret = pci_enable_device(smbus_dev))) { ++ printk(KERN_ERR DRV_NAME ": Can't pci_enable SMBus device!" ++ " (0x%08x)\n", ret); ++ return ret; ++ } ++ ++ pci_insert_device(smbus_dev, smbus_dev->bus); ++ ++ return 0; ++} ++#endif /* CONFIG_HOTPLUG */ ++ ++/* Execute a SMBus transaction. ++ int size is from SIS645_QUICK to SIS645_BLOCK_DATA ++ */ ++static int sis645_transaction(int size) ++{ ++ int temp; ++ int result = 0; ++ int timeout = 0; ++ ++ /* Make sure the SMBus host is ready to start transmitting */ ++ if (((temp = sis645_read(SMB_CNT)) & 0x03) != 0x00) { ++#ifdef DEBUG ++ printk(KERN_DEBUG DRV_NAME ": SMBus busy (0x%02x). Resetting...\n", ++ temp); ++#endif ++ ++ /* kill the transaction */ ++ sis645_write(SMB_HOST_CNT, 0x20); ++ ++ /* check it again */ ++ if (((temp = sis645_read(SMB_CNT)) & 0x03) != 0x00) { ++#ifdef DEBUG ++ printk(KERN_DEBUG DRV_NAME ": Failed! (0x%02x)\n", temp); ++#endif ++ return -1; ++ } else { ++#ifdef DEBUG ++ printk(KERN_DEBUG DRV_NAME ": Successful!\n"); ++#endif ++ } ++ } ++ ++ /* Turn off timeout interrupts, set fast host clock */ ++ sis645_write(SMB_CNT, 0x20); ++ ++ /* clear all (sticky) status flags */ ++ temp = sis645_read(SMB_STS); ++ sis645_write(SMB_STS, temp & 0x1e); ++ ++ /* start the transaction by setting bit 4 and size bits */ ++ sis645_write(SMB_HOST_CNT, 0x10 | (size & 0x07)); ++ ++ /* We will always wait for a fraction of a second! */ ++ do { ++ i2c_delay(1); ++ temp = sis645_read(SMB_STS); ++ } while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT)); ++ ++ /* If the SMBus is still busy, we give up */ ++ if (timeout >= MAX_TIMEOUT) { ++ printk(KERN_DEBUG DRV_NAME ": SMBus Timeout! (0x%02x)\n",temp); ++ result = -1; ++ } ++ ++ /* device error - probably missing ACK */ ++ if (temp & 0x02) { ++#ifdef DEBUG ++ printk(KERN_DEBUG DRV_NAME ": Failed bus transaction!\n"); ++#endif ++ result = -1; ++ } ++ ++ /* bus collision */ ++ if (temp & 0x04) { ++#ifdef DEBUG ++ printk(KERN_DEBUG DRV_NAME ": Bus collision!\n"); ++#endif ++ result = -1; ++ } ++ ++ /* Finish up by resetting the bus */ ++ sis645_write(SMB_STS, temp); ++ if ((temp = sis645_read(SMB_STS))) { ++#ifdef DEBUG ++ printk(KERN_DEBUG DRV_NAME ": Failed reset at end of transaction!" ++ " (0x%02x)\n", temp); ++#endif ++ } ++ ++ return result; ++} ++ ++/* Return -1 on error. */ ++static s32 sis645_access(struct i2c_adapter * adap, u16 addr, ++ unsigned short flags, char read_write, ++ u8 command, int size, union i2c_smbus_data * data) ++{ ++ ++ switch (size) { ++ case I2C_SMBUS_QUICK: ++ sis645_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); ++ size = SIS645_QUICK; ++ break; ++ ++ case I2C_SMBUS_BYTE: ++ sis645_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); ++ if (read_write == I2C_SMBUS_WRITE) ++ sis645_write(SMB_CMD, command); ++ size = SIS645_BYTE; ++ break; ++ ++ case I2C_SMBUS_BYTE_DATA: ++ sis645_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); ++ sis645_write(SMB_CMD, command); ++ if (read_write == I2C_SMBUS_WRITE) ++ sis645_write(SMB_BYTE, data->byte); ++ size = SIS645_BYTE_DATA; ++ break; ++ ++ case I2C_SMBUS_PROC_CALL: ++ case I2C_SMBUS_WORD_DATA: ++ sis645_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); ++ sis645_write(SMB_CMD, command); ++ if (read_write == I2C_SMBUS_WRITE) { ++ sis645_write(SMB_BYTE, data->word & 0xff); ++ sis645_write(SMB_BYTE + 1, (data->word & 0xff00) >> 8); ++ } ++ size = (size == I2C_SMBUS_PROC_CALL ? SIS645_PROC_CALL : SIS645_WORD_DATA); ++ break; ++ ++ case I2C_SMBUS_BLOCK_DATA: ++ /* TO DO: */ ++ printk(KERN_INFO DRV_NAME ": SMBus block not implemented!\n"); ++ return -1; ++ break; ++ ++ default: ++ printk(KERN_INFO DRV_NAME ": Unsupported I2C size\n"); ++ return -1; ++ break; ++ } ++ ++ if (sis645_transaction(size)) ++ return -1; ++ ++ if ((size != SIS645_PROC_CALL) && ++ ((read_write == I2C_SMBUS_WRITE) || (size == SIS645_QUICK))) ++ return 0; ++ ++ switch (size) { ++ case SIS645_BYTE: ++ case SIS645_BYTE_DATA: ++ data->byte = sis645_read(SMB_BYTE); ++ break; ++ ++ case SIS645_WORD_DATA: ++ case SIS645_PROC_CALL: ++ data->word = sis645_read(SMB_BYTE) + ++ (sis645_read(SMB_BYTE + 1) << 8); ++ break; ++ } ++ return 0; ++} ++ ++static u32 sis645_func(struct i2c_adapter *adapter) ++{ ++ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | ++ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | ++ I2C_FUNC_SMBUS_PROC_CALL; ++} ++ ++static struct i2c_algorithm smbus_algorithm = { ++ .name = "Non-I2C SMBus adapter", ++ .id = I2C_ALGO_SMBUS, ++ .smbus_xfer = sis645_access, ++ .functionality = sis645_func, ++}; ++ ++static struct i2c_adapter sis645_adapter = { ++ .owner = THIS_MODULE, ++ .name = "unset", ++ .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_SIS645, ++ .algo = &smbus_algorithm, ++}; ++ ++static struct pci_device_id sis645_ids[] __devinitdata = { ++ { ++ .vendor = PCI_VENDOR_ID_SI, ++ .device = PCI_DEVICE_ID_SI_SMBUS, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { 0, } ++}; ++ ++static int __devinit sis645_probe(struct pci_dev *dev, ++ const struct pci_device_id *id) ++{ ++ u16 ww = 0; ++ int retval; ++ ++ if (sis645_smbus_base) { ++ dev_err(dev, "Only one device supported.\n"); ++ return -EBUSY; ++ } ++ ++ pci_read_config_word(dev, PCI_CLASS_DEVICE, &ww); ++ if (PCI_CLASS_SERIAL_SMBUS != ww) { ++ dev_err(dev, "Unsupported device class 0x%04x!\n", ww); ++ return -ENODEV; ++ } ++ ++ sis645_smbus_base = pci_resource_start(dev, SIS645_BAR); ++ if (!sis645_smbus_base) { ++ dev_err(dev, "SiS645 SMBus base address " ++ "not initialized!\n"); ++ return -EINVAL; ++ } ++ dev_info(dev, "SiS645 SMBus base address: 0x%04x\n", ++ sis645_smbus_base); ++ ++ /* Everything is happy, let's grab the memory and set things up. */ ++ if (!request_region(sis645_smbus_base, SMB_IOSIZE, "sis645-smbus")) { ++ dev_err(dev, "SMBus registers 0x%04x-0x%04x " ++ "already in use!\n", sis645_smbus_base, ++ sis645_smbus_base + SMB_IOSIZE - 1); ++ ++ sis645_smbus_base = 0; ++ return -EINVAL; ++ } ++ ++ sprintf(sis645_adapter.name, "SiS645 SMBus adapter at 0x%04x", ++ sis645_smbus_base); ++ ++ if ((retval = i2c_add_adapter(&sis645_adapter))) { ++ dev_err(dev, "Couldn't register adapter!\n"); ++ release_region(sis645_smbus_base, SMB_IOSIZE); ++ sis645_smbus_base = 0; ++ } ++ ++ return retval; ++} ++ ++static void __devexit sis645_remove(struct pci_dev *dev) ++{ ++ if (sis645_smbus_base) { ++ i2c_del_adapter(&sis645_adapter); ++ release_region(sis645_smbus_base, SMB_IOSIZE); ++ sis645_smbus_base = 0; ++ } ++} ++ ++static struct pci_driver sis645_driver = { ++ .name = "sis645 smbus", ++ .id_table = sis645_ids, ++ .probe = sis645_probe, ++ .remove = __devexit_p(sis645_remove), ++}; ++ ++static int __init i2c_sis645_init(void) ++{ ++ printk(KERN_INFO DRV_NAME ".o version %s (%s)\n", LM_VERSION, LM_DATE); ++ ++ /* if the required device id is not present, try to HOTPLUG it first */ ++ if (!pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS, NULL)) { ++ ++ printk(KERN_INFO DRV_NAME ": " ++ "Attempting to enable SiS645 SMBus device\n"); ++ ++#ifdef CONFIG_HOTPLUG ++ sis645_hotplug_smbus(); ++#else ++ printk(KERN_INFO DRV_NAME ": " ++ "Requires kernel with CONFIG_HOTPLUG, sorry!\n"); ++#endif ++ } ++ ++ return pci_module_init(&sis645_driver); ++} ++ ++static void __exit i2c_sis645_exit(void) ++{ ++ pci_unregister_driver(&sis645_driver); ++} ++ ++MODULE_AUTHOR("Mark M. Hoffman "); ++MODULE_DESCRIPTION("SiS645 SMBus driver"); ++MODULE_LICENSE("GPL"); ++ ++/* Register initialization functions using helper macros */ ++module_init(i2c_sis645_init); ++module_exit(i2c_sis645_exit); +--- linux-old/drivers/i2c/i2c-tsunami.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-tsunami.c Mon Dec 13 20:18:42 2004 +@@ -0,0 +1,155 @@ ++/* ++ i2c-tsunami.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 2001 Oleg Vdovikin ++ ++ Based on code written by Ralph Metzler and ++ Simon Vogl ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* This interfaces to the I2C bus of the Tsunami/Typhoon 21272 chipsets ++ to gain access to the on-board I2C devices. ++ ++ For more information refer to Compaq's ++ "Tsunami/Typhoon 21272 Chipset Hardware Reference Manual" ++ Order Number: DS-0025-TE ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Memory Presence Detect Register (MPD-RW) bits ++ with except of reserved RAZ bits */ ++ ++#define MPD_DR 0x8 /* Data receive - RO */ ++#define MPD_CKR 0x4 /* Clock receive - RO */ ++#define MPD_DS 0x2 /* Data send - Must be a 1 to receive - WO */ ++#define MPD_CKS 0x1 /* Clock send - WO */ ++ ++static inline void writempd(unsigned long value) ++{ ++ TSUNAMI_cchip->mpd.csr = value; ++ mb(); ++} ++ ++static inline unsigned long readmpd(void) ++{ ++ return TSUNAMI_cchip->mpd.csr; ++} ++ ++static void bit_tsunami_setscl(void *data, int val) ++{ ++ /* read currently setted bits to modify them */ ++ unsigned long bits = readmpd() >> 2; /* assume output == input */ ++ ++ if (val) ++ bits |= MPD_CKS; ++ else ++ bits &= ~MPD_CKS; ++ ++ writempd(bits); ++} ++ ++static void bit_tsunami_setsda(void *data, int val) ++{ ++ /* read currently setted bits to modify them */ ++ unsigned long bits = readmpd() >> 2; /* assume output == input */ ++ ++ if (val) ++ bits |= MPD_DS; ++ else ++ bits &= ~MPD_DS; ++ ++ writempd(bits); ++} ++ ++/* The MPD pins are open drain, so the pins always remain outputs. ++ We rely on the i2c-algo-bit routines to set the pins high before ++ reading the input from other chips. */ ++ ++static int bit_tsunami_getscl(void *data) ++{ ++ return (0 != (readmpd() & MPD_CKR)); ++} ++ ++static int bit_tsunami_getsda(void *data) ++{ ++ return (0 != (readmpd() & MPD_DR)); ++} ++ ++static struct i2c_algo_bit_data tsunami_i2c_bit_data = { ++ .setsda = bit_tsunami_setsda, ++ .setscl = bit_tsunami_setscl, ++ .getsda = bit_tsunami_getsda, ++ .getscl = bit_tsunami_getscl, ++ .udelay = 10, ++ .mdelay = 10, ++ .timeout = HZ/2 ++}; ++ ++static struct i2c_adapter tsunami_i2c_adapter = { ++ .owner = THIS_MODULE, ++ .name = "I2C Tsunami/Typhoon adapter", ++ .id = I2C_HW_B_TSUNA, ++ .algo_data = &tsunami_i2c_bit_data, ++}; ++ ++ ++#if 0 ++static struct pci_driver tsunami_driver = { ++ .name = "tsunami smbus", ++ .id_table = tsunami_ids, ++ .probe = tsunami_probe, ++ .remove = __devexit_p(tsunami_remove), ++}; ++#endif ++ ++static int __init i2c_tsunami_init(void) ++{ ++ printk("i2c-tsunami.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ ++ if (hwrpb->sys_type != ST_DEC_TSUNAMI) { ++ printk("i2c-tsunami.o: not Tsunami based system (%ld), module not inserted.\n", hwrpb->sys_type); ++ return -ENXIO; ++ } else { ++ printk("i2c-tsunami.o: using Cchip MPD at 0x%lx.\n", (long) &TSUNAMI_cchip->mpd); ++ } ++ return i2c_bit_add_bus(&tsunami_i2c_adapter); ++} ++ ++ ++static void __exit i2c_tsunami_exit(void) ++{ ++ i2c_bit_del_bus(&tsunami_i2c_adapter); ++} ++ ++ ++ ++MODULE_AUTHOR("Oleg I. Vdovikin "); ++MODULE_DESCRIPTION("Tsunami I2C/SMBus driver"); ++ ++module_init(i2c_tsunami_init); ++module_exit(i2c_tsunami_exit); +--- linux-old/drivers/i2c/i2c-via.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-via.c Mon Dec 13 20:18:42 2004 +@@ -0,0 +1,207 @@ ++/* ++ i2c-via.c - Part of lm_sensors, Linux kernel modules ++ for hardware monitoring ++ ++ i2c Support for Via Technologies 82C586B South Bridge ++ ++ Copyright (c) 1998, 1999 Kyösti Mälkki ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* for HZ */ ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++/* Power management registers */ ++ ++#define PM_CFG_REVID 0x08 /* silicon revision code */ ++#define PM_CFG_IOBASE0 0x20 ++#define PM_CFG_IOBASE1 0x48 ++ ++#define I2C_DIR (pm_io_base+0x40) ++#define I2C_OUT (pm_io_base+0x42) ++#define I2C_IN (pm_io_base+0x44) ++#define I2C_SCL 0x02 /* clock bit in DIR/OUT/IN register */ ++#define I2C_SDA 0x04 ++ ++/* io-region reservation */ ++#define IOSPACE 0x06 ++#define IOTEXT "via-i2c" ++ ++static u16 pm_io_base = 0; ++ ++/* ++ It does not appear from the datasheet that the GPIO pins are ++ open drain. So a we set a low value by setting the direction to ++ output and a high value by setting the direction to input and ++ relying on the required I2C pullup. The data value is initialized ++ to 0 in via_init() and never changed. ++*/ ++ ++static void bit_via_setscl(void *data, int state) ++{ ++ outb(state ? inb(I2C_DIR) & ~I2C_SCL : inb(I2C_DIR) | I2C_SCL, ++ I2C_DIR); ++} ++ ++static void bit_via_setsda(void *data, int state) ++{ ++ outb(state ? inb(I2C_DIR) & ~I2C_SDA : inb(I2C_DIR) | I2C_SDA, ++ I2C_DIR); ++} ++ ++static int bit_via_getscl(void *data) ++{ ++ return (0 != (inb(I2C_IN) & I2C_SCL)); ++} ++ ++static int bit_via_getsda(void *data) ++{ ++ return (0 != (inb(I2C_IN) & I2C_SDA)); ++} ++ ++ ++static struct i2c_algo_bit_data bit_data = { ++ .setsda = bit_via_setsda, ++ .setscl = bit_via_setscl, ++ .getsda = bit_via_getsda, ++ .getscl = bit_via_getscl, ++ .udelay = 5, ++ .mdelay = 5, ++ .timeout = HZ ++}; ++ ++static struct i2c_adapter vt586b_adapter = { ++ .owner = THIS_MODULE, ++ .name = "VIA i2c", ++ .id = I2C_HW_B_VIA, ++ .algo_data = &bit_data, ++}; ++ ++ ++static struct pci_device_id vt586b_ids[] __devinitdata = { ++ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, ++ { 0, } ++}; ++ ++static int __devinit vt586b_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ u16 base; ++ u8 rev; ++ int res; ++ ++ if (pm_io_base) { ++ printk(KERN_ERR "i2c-via.o: Will only support one host\n"); ++ return -EBUSY; ++ } ++ ++ pci_read_config_byte(dev, PM_CFG_REVID, &rev); ++ ++ switch (rev) { ++ case 0x00: ++ base = PM_CFG_IOBASE0; ++ break; ++ case 0x01: ++ case 0x10: ++ base = PM_CFG_IOBASE1; ++ break; ++ ++ default: ++ base = PM_CFG_IOBASE1; ++ /* later revision */ ++ } ++ ++ pci_read_config_word(dev, base, &pm_io_base); ++ pm_io_base &= (0xff << 8); ++ ++ if (! request_region(I2C_DIR, IOSPACE, IOTEXT)) { ++ printk("i2c-via.o: IO 0x%x-0x%x already in use\n", ++ I2C_DIR, I2C_DIR + IOSPACE); ++ return -EBUSY; ++ } ++ outb(inb(I2C_DIR) & ~(I2C_SDA | I2C_SCL), I2C_DIR); ++ outb(inb(I2C_OUT) & ~(I2C_SDA | I2C_SCL), I2C_OUT); ++ ++ res = i2c_bit_add_bus(&vt586b_adapter); ++ if ( res < 0 ) { ++ release_region(I2C_DIR, IOSPACE); ++ pm_io_base = 0; ++ return res; ++ } ++ return 0; ++} ++ ++static void __devexit vt586b_remove(struct pci_dev *dev) ++{ ++ i2c_bit_del_bus(&vt586b_adapter); ++ release_region(I2C_DIR, IOSPACE); ++ pm_io_base = 0; ++} ++ ++ ++/* Don't register driver to avoid driver conflicts */ ++/* ++static struct pci_driver vt586b_driver = { ++ .name = "vt586b smbus", ++ .id_table = vt586b_ids, ++ .probe = vt586b_probe, ++ .remove = __devexit_p(vt586b_remove), ++}; ++*/ ++ ++static int __init i2c_vt586b_init(void) ++{ ++ struct pci_dev *dev; ++ const struct pci_device_id *id; ++ ++ printk("i2c-via.o version %s (%s)\n", LM_VERSION, LM_DATE); ++/* ++ return pci_module_init(&vt586b_driver); ++*/ ++ pci_for_each_dev(dev) { ++ id = pci_match_device(vt586b_ids, dev); ++ if(id) ++ if(vt586b_probe(dev, id) >= 0) ++ return 0; ++ } ++ return -ENODEV; ++} ++ ++ ++static void __exit i2c_vt586b_exit(void) ++{ ++/* ++ pci_unregister_driver(&vt586b_driver); ++*/ ++ vt586b_remove(NULL); ++} ++ ++ ++MODULE_AUTHOR("Kyösti Mälkki "); ++MODULE_DESCRIPTION("i2c for Via vt82c586b southbridge"); ++MODULE_LICENSE("GPL"); ++ ++module_init(i2c_vt586b_init); ++module_exit(i2c_vt586b_exit); +--- linux-old/drivers/i2c/i2c-viapro.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-viapro.c Mon Dec 13 20:18:43 2004 +@@ -0,0 +1,514 @@ ++/* ++ i2c-viapro.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998 - 2002 Frodo Looijaard , ++ Philip Edelbrock , Kyösti Mälkki , ++ Mark D. Studebaker ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ Supports Via devices: ++ 82C596A/B (0x3050) ++ 82C596B (0x3051) ++ 82C686A/B ++ 8231 ++ 8233 ++ 8233A (0x3147 and 0x3177) ++ 8235 ++ 8237 ++ Note: we assume there can only be one device, with one SMBus interface. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++ ++#define SMBBA1 0x90 ++#define SMBBA2 0x80 ++#define SMBBA3 0xD0 ++ ++/* SMBus address offsets */ ++static unsigned short vt596_smba; ++#define SMBHSTSTS (vt596_smba + 0) ++#define SMBHSLVSTS (vt596_smba + 1) ++#define SMBHSTCNT (vt596_smba + 2) ++#define SMBHSTCMD (vt596_smba + 3) ++#define SMBHSTADD (vt596_smba + 4) ++#define SMBHSTDAT0 (vt596_smba + 5) ++#define SMBHSTDAT1 (vt596_smba + 6) ++#define SMBBLKDAT (vt596_smba + 7) ++#define SMBSLVCNT (vt596_smba + 8) ++#define SMBSHDWCMD (vt596_smba + 9) ++#define SMBSLVEVT (vt596_smba + 0xA) ++#define SMBSLVDAT (vt596_smba + 0xC) ++ ++/* PCI Address Constants */ ++ ++/* SMBus data in configuration space can be found in two places, ++ We try to select the better one*/ ++ ++static unsigned short smb_cf_hstcfg = 0xD2; ++ ++#define SMBHSTCFG (smb_cf_hstcfg) ++#define SMBSLVC (smb_cf_hstcfg + 1) ++#define SMBSHDW1 (smb_cf_hstcfg + 2) ++#define SMBSHDW2 (smb_cf_hstcfg + 3) ++#define SMBREV (smb_cf_hstcfg + 4) ++ ++/* Other settings */ ++#define MAX_TIMEOUT 500 ++#define ENABLE_INT9 0 ++ ++/* VT82C596 constants */ ++#define VT596_QUICK 0x00 ++#define VT596_BYTE 0x04 ++#define VT596_BYTE_DATA 0x08 ++#define VT596_WORD_DATA 0x0C ++#define VT596_BLOCK_DATA 0x14 ++ ++ ++/* If force is set to anything different from 0, we forcibly enable the ++ VT596. DANGEROUS! */ ++static int force; ++MODULE_PARM(force, "i"); ++MODULE_PARM_DESC(force, "Forcibly enable the SMBus. DANGEROUS!"); ++ ++/* If force_addr is set to anything different from 0, we forcibly enable ++ the VT596 at the given address. VERY DANGEROUS! */ ++static int force_addr; ++MODULE_PARM(force_addr, "i"); ++MODULE_PARM_DESC(force_addr, ++ "Forcibly enable the SMBus at the given address. " ++ "EXTREMELY DANGEROUS!"); ++ ++ ++static struct i2c_adapter vt596_adapter; ++ ++/* Another internally used function */ ++static int vt596_transaction(void) ++{ ++ int temp; ++ int result = 0; ++ int timeout = 0; ++ ++ dev_dbg(&vt596_adapter, "Transaction (pre): CNT=%02x, CMD=%02x, " ++ "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), ++ inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), ++ inb_p(SMBHSTDAT1)); ++ ++ /* Make sure the SMBus host is ready to start transmitting */ ++ if ((temp = inb_p(SMBHSTSTS)) != 0x00) { ++ dev_dbg(&vt596_adapter, "SMBus busy (0x%02x). " ++ "Resetting...\n", temp); ++ ++ outb_p(temp, SMBHSTSTS); ++ if ((temp = inb_p(SMBHSTSTS)) != 0x00) { ++ dev_dbg(&vt596_adapter, "Failed! (0x%02x)\n", temp); ++ ++ return -1; ++ } else { ++ dev_dbg(&vt596_adapter, "Successfull!\n"); ++ } ++ } ++ ++ /* start the transaction by setting bit 6 */ ++ outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); ++ ++ /* We will always wait for a fraction of a second! ++ I don't know if VIA needs this, Intel did */ ++ do { ++ i2c_delay(1); ++ temp = inb_p(SMBHSTSTS); ++ } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT)); ++ ++ /* If the SMBus is still busy, we give up */ ++ if (timeout >= MAX_TIMEOUT) { ++ result = -1; ++ dev_dbg(&vt596_adapter, "SMBus Timeout!\n"); ++ } ++ ++ if (temp & 0x10) { ++ result = -1; ++ dev_dbg(&vt596_adapter, "Error: Failed bus transaction\n"); ++ } ++ ++ if (temp & 0x08) { ++ result = -1; ++ dev_info(&vt596_adapter, "Bus collision! SMBus may be " ++ "locked until next hard\nreset. (sorry!)\n"); ++ /* Clock stops and slave is stuck in mid-transmission */ ++ } ++ ++ if (temp & 0x04) { ++ result = -1; ++ dev_dbg(&vt596_adapter, "Error: no response!\n"); ++ } ++ ++ if (inb_p(SMBHSTSTS) != 0x00) ++ outb_p(inb(SMBHSTSTS), SMBHSTSTS); ++ ++ if ((temp = inb_p(SMBHSTSTS)) != 0x00) { ++ dev_dbg(&vt596_adapter, "Failed reset at end of " ++ "transaction (%02x)\n", temp); ++ } ++ dev_dbg(&vt596_adapter, "Transaction (post): CNT=%02x, CMD=%02x, " ++ "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), ++ inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), ++ inb_p(SMBHSTDAT1)); ++ ++ return result; ++} ++ ++/* Return -1 on error. */ ++static s32 vt596_access(struct i2c_adapter *adap, u16 addr, ++ unsigned short flags, char read_write, u8 command, ++ int size, union i2c_smbus_data *data) ++{ ++ int i, len; ++ ++ switch (size) { ++ case I2C_SMBUS_QUICK: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ size = VT596_QUICK; ++ break; ++ case I2C_SMBUS_BYTE: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ if (read_write == I2C_SMBUS_WRITE) ++ outb_p(command, SMBHSTCMD); ++ size = VT596_BYTE; ++ break; ++ case I2C_SMBUS_BYTE_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) ++ outb_p(data->byte, SMBHSTDAT0); ++ size = VT596_BYTE_DATA; ++ break; ++ case I2C_SMBUS_WORD_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) { ++ outb_p(data->word & 0xff, SMBHSTDAT0); ++ outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); ++ } ++ size = VT596_WORD_DATA; ++ break; ++ case I2C_SMBUS_BLOCK_DATA: ++ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), ++ SMBHSTADD); ++ outb_p(command, SMBHSTCMD); ++ if (read_write == I2C_SMBUS_WRITE) { ++ len = data->block[0]; ++ if (len < 0) ++ len = 0; ++ if (len > 32) ++ len = 32; ++ outb_p(len, SMBHSTDAT0); ++ i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ ++ for (i = 1; i <= len; i++) ++ outb_p(data->block[i], SMBBLKDAT); ++ } ++ size = VT596_BLOCK_DATA; ++ break; ++ default: ++ dev_warn(&vt596_adapter, "Unsupported transaction %d\n", size); ++ return -1; ++ } ++ ++ outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT); ++ ++ if (vt596_transaction()) /* Error in transaction */ ++ return -1; ++ ++ if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK)) ++ return 0; ++ ++ switch (size) { ++ case VT596_BYTE: ++ /* Where is the result put? I assume here it is in ++ * SMBHSTDAT0 but it might just as well be in the ++ * SMBHSTCMD. No clue in the docs ++ */ ++ data->byte = inb_p(SMBHSTDAT0); ++ break; ++ case VT596_BYTE_DATA: ++ data->byte = inb_p(SMBHSTDAT0); ++ break; ++ case VT596_WORD_DATA: ++ data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); ++ break; ++ case VT596_BLOCK_DATA: ++ data->block[0] = inb_p(SMBHSTDAT0); ++ if (data->block[0] > 32) ++ data->block[0] = 32; ++ i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ ++ for (i = 1; i <= data->block[0]; i++) ++ data->block[i] = inb_p(SMBBLKDAT); ++ break; ++ } ++ return 0; ++} ++ ++static u32 vt596_func(struct i2c_adapter *adapter) ++{ ++ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | ++ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | ++ I2C_FUNC_SMBUS_BLOCK_DATA; ++} ++ ++static struct i2c_algorithm smbus_algorithm = { ++ .name = "Non-I2C SMBus adapter", ++ .id = I2C_ALGO_SMBUS, ++ .smbus_xfer = vt596_access, ++ .functionality = vt596_func, ++}; ++ ++static struct i2c_adapter vt596_adapter = { ++ .owner = THIS_MODULE, ++ .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_VIA2, ++ .algo = &smbus_algorithm, ++ .name = "unset", ++}; ++ ++static int __devinit vt596_probe(struct pci_dev *pdev, ++ const struct pci_device_id *id) ++{ ++ unsigned char temp; ++ int error = -ENODEV; ++ ++ /* Determine the address of the SMBus areas */ ++ if (force_addr) { ++ vt596_smba = force_addr & 0xfff0; ++ force = 0; ++ goto found; ++ } ++ ++ if ((pci_read_config_word(pdev, id->driver_data, &vt596_smba)) || ++ !(vt596_smba & 0x1)) { ++ /* try 2nd address and config reg. for 596 */ ++ if (id->device == PCI_DEVICE_ID_VIA_82C596_3 && ++ !pci_read_config_word(pdev, SMBBA2, &vt596_smba) && ++ (vt596_smba & 0x1)) { ++ smb_cf_hstcfg = 0x84; ++ } else { ++ /* no matches at all */ ++ dev_err(pdev, "Cannot configure " ++ "SMBus I/O Base address\n"); ++ return -ENODEV; ++ } ++ } ++ ++ vt596_smba &= 0xfff0; ++ if (vt596_smba == 0) { ++ dev_err(pdev, "SMBus base address " ++ "uninitialized - upgrade BIOS or use " ++ "force_addr=0xaddr\n"); ++ return -ENODEV; ++ } ++ ++ found: ++ if (!request_region(vt596_smba, 8, "viapro-smbus")) { ++ dev_err(pdev, "SMBus region 0x%x already in use!\n", ++ vt596_smba); ++ return -ENODEV; ++ } ++ ++ pci_read_config_byte(pdev, SMBHSTCFG, &temp); ++ /* If force_addr is set, we program the new address here. Just to make ++ sure, we disable the VT596 first. */ ++ if (force_addr) { ++ pci_write_config_byte(pdev, SMBHSTCFG, temp & 0xfe); ++ pci_write_config_word(pdev, id->driver_data, vt596_smba); ++ pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01); ++ dev_warn(pdev, "WARNING: SMBus interface set to new " ++ "address 0x%04x!\n", vt596_smba); ++ } else if ((temp & 1) == 0) { ++ if (force) { ++ /* NOTE: This assumes I/O space and other allocations ++ * WERE done by the Bios! Don't complain if your ++ * hardware does weird things after enabling this. ++ * :') Check for Bios updates before resorting to ++ * this. ++ */ ++ pci_write_config_byte(pdev, SMBHSTCFG, temp | 1); ++ dev_info(pdev, "Enabling SMBus device\n"); ++ } else { ++ dev_err(pdev, "SMBUS: Error: Host SMBus " ++ "controller not enabled! - upgrade BIOS or " ++ "use force=1\n"); ++ goto release_region; ++ } ++ } ++ ++ if ((temp & 0x0E) == 8) ++ dev_dbg(pdev, "using Interrupt 9 for SMBus.\n"); ++ else if ((temp & 0x0E) == 0) ++ dev_dbg(pdev, "using Interrupt SMI# for SMBus.\n"); ++ else ++ dev_dbg(pdev, "Illegal Interrupt configuration " ++ "(or code out of date)!\n"); ++ ++ pci_read_config_byte(pdev, SMBREV, &temp); ++ dev_dbg(pdev, "SMBREV = 0x%X\n", temp); ++ dev_dbg(pdev, "VT596_smba = 0x%X\n", vt596_smba); ++ ++ snprintf(vt596_adapter.name, 32, ++ "SMBus Via Pro adapter at %04x", vt596_smba); ++ ++ return i2c_add_adapter(&vt596_adapter); ++ ++ release_region: ++ release_region(vt596_smba, 8); ++ return error; ++} ++ ++static void __devexit vt596_remove(struct pci_dev *pdev) ++{ ++ i2c_del_adapter(&vt596_adapter); ++ release_region(vt596_smba, 8); ++} ++ ++/* 8233A is undefined before kernel 2.4.19 */ ++#ifndef PCI_DEVICE_ID_VIA_8233A ++#define PCI_DEVICE_ID_VIA_8233A 0x3147 ++#endif ++/* 8235 is undefined before kernel 2.4.20 */ ++#ifndef PCI_DEVICE_ID_VIA_8235 ++#define PCI_DEVICE_ID_VIA_8235 0x3177 ++#endif ++/* 8237 is undefined before kernel 2.4.21 */ ++#ifndef PCI_DEVICE_ID_VIA_8237 ++#define PCI_DEVICE_ID_VIA_8237 0x3227 ++#endif ++static struct pci_device_id vt596_ids[] __devinitdata = { ++ { ++ .vendor = PCI_VENDOR_ID_VIA, ++ .device = PCI_DEVICE_ID_VIA_82C596_3, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = SMBBA1, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_VIA, ++ .device = PCI_DEVICE_ID_VIA_82C596B_3, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = SMBBA1, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_VIA, ++ .device = PCI_DEVICE_ID_VIA_82C686_4, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = SMBBA1, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_VIA, ++ .device = PCI_DEVICE_ID_VIA_8233_0, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = SMBBA3 ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_VIA, ++ .device = PCI_DEVICE_ID_VIA_8233A, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = SMBBA3, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_VIA, ++ .device = PCI_DEVICE_ID_VIA_8235, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = SMBBA3 ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_VIA, ++ .device = PCI_DEVICE_ID_VIA_8237, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = SMBBA3 ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_VIA, ++ .device = PCI_DEVICE_ID_VIA_8231_4, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = SMBBA1, ++ }, ++ { 0, } ++}; ++ ++/* Don't register driver to avoid driver conflicts */ ++/* ++static struct pci_driver vt596_driver = { ++ .name = "vt596 smbus", ++ .id_table = vt596_ids, ++ .probe = vt596_probe, ++ .remove = __devexit_p(vt596_remove), ++}; ++*/ ++ ++static int __init i2c_vt596_init(void) ++{ ++ struct pci_dev *dev; ++ const struct pci_device_id *id; ++ ++ printk("i2c-viapro.o version %s (%s)\n", LM_VERSION, LM_DATE); ++/* ++ return pci_module_init(&vt596_driver); ++*/ ++ pci_for_each_dev(dev) { ++ id = pci_match_device(vt596_ids, dev); ++ if(id) ++ if(vt596_probe(dev, id) >= 0) ++ return 0; ++ } ++ return -ENODEV; ++} ++ ++ ++static void __exit i2c_vt596_exit(void) ++{ ++/* ++ pci_unregister_driver(&vt596_driver); ++*/ ++ vt596_remove(NULL); ++} ++ ++MODULE_AUTHOR( ++ "Frodo Looijaard and " ++ "Philip Edelbrock "); ++MODULE_DESCRIPTION("vt82c596 SMBus driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(i2c_vt596_init); ++module_exit(i2c_vt596_exit); +--- linux-old/drivers/i2c/i2c-voodoo3.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/i2c/i2c-voodoo3.c Mon Dec 13 20:18:43 2004 +@@ -0,0 +1,281 @@ ++/* ++ voodoo3.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard , ++ Philip Edelbrock , ++ Ralph Metzler , and ++ Mark D. Studebaker ++ ++ Based on code written by Ralph Metzler and ++ Simon Vogl ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* This interfaces to the I2C bus of the Voodoo3 to gain access to ++ the BT869 and possibly other I2C devices. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* for HZ */ ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* the only registers we use */ ++#define REG 0x78 ++#define REG2 0x70 ++ ++/* bit locations in the register */ ++#define DDC_ENAB 0x00040000 ++#define DDC_SCL_OUT 0x00080000 ++#define DDC_SDA_OUT 0x00100000 ++#define DDC_SCL_IN 0x00200000 ++#define DDC_SDA_IN 0x00400000 ++#define I2C_ENAB 0x00800000 ++#define I2C_SCL_OUT 0x01000000 ++#define I2C_SDA_OUT 0x02000000 ++#define I2C_SCL_IN 0x04000000 ++#define I2C_SDA_IN 0x08000000 ++ ++/* initialization states */ ++#define INIT2 0x2 ++#define INIT3 0x4 ++ ++/* delays */ ++#define CYCLE_DELAY 10 ++#define TIMEOUT (HZ / 2) ++ ++ ++static void config_v3(struct pci_dev *dev); ++ ++static unsigned long ioaddr; ++ ++/* The voo GPIO registers don't have individual masks for each bit ++ so we always have to read before writing. */ ++ ++static void bit_vooi2c_setscl(void *data, int val) ++{ ++ unsigned int r; ++ r = readl(ioaddr + REG); ++ if(val) ++ r |= I2C_SCL_OUT; ++ else ++ r &= ~I2C_SCL_OUT; ++ writel(r, ioaddr + REG); ++ readl(ioaddr + REG); /* flush posted write */ ++} ++ ++static void bit_vooi2c_setsda(void *data, int val) ++{ ++ unsigned int r; ++ r = readl(ioaddr + REG); ++ if(val) ++ r |= I2C_SDA_OUT; ++ else ++ r &= ~I2C_SDA_OUT; ++ writel(r, ioaddr + REG); ++ readl(ioaddr + REG); /* flush posted write */ ++} ++ ++/* The GPIO pins are open drain, so the pins always remain outputs. ++ We rely on the i2c-algo-bit routines to set the pins high before ++ reading the input from other chips. */ ++ ++static int bit_vooi2c_getscl(void *data) ++{ ++ return (0 != (readl(ioaddr + REG) & I2C_SCL_IN)); ++} ++ ++static int bit_vooi2c_getsda(void *data) ++{ ++ return (0 != (readl(ioaddr + REG) & I2C_SDA_IN)); ++} ++ ++static void bit_vooddc_setscl(void *data, int val) ++{ ++ unsigned int r; ++ r = readl(ioaddr + REG); ++ if(val) ++ r |= DDC_SCL_OUT; ++ else ++ r &= ~DDC_SCL_OUT; ++ writel(r, ioaddr + REG); ++ readl(ioaddr + REG); /* flush posted write */ ++} ++ ++static void bit_vooddc_setsda(void *data, int val) ++{ ++ unsigned int r; ++ r = readl(ioaddr + REG); ++ if(val) ++ r |= DDC_SDA_OUT; ++ else ++ r &= ~DDC_SDA_OUT; ++ writel(r, ioaddr + REG); ++ readl(ioaddr + REG); /* flush posted write */ ++} ++ ++static int bit_vooddc_getscl(void *data) ++{ ++ return (0 != (readl(ioaddr + REG) & DDC_SCL_IN)); ++} ++ ++static int bit_vooddc_getsda(void *data) ++{ ++ return (0 != (readl(ioaddr + REG) & DDC_SDA_IN)); ++} ++ ++ ++/* Configures the chip */ ++ ++void config_v3(struct pci_dev *dev) ++{ ++ unsigned int cadr; ++ ++ /* map Voodoo3 memory */ ++ cadr = dev->resource[0].start; ++ cadr &= PCI_BASE_ADDRESS_MEM_MASK; ++ ioaddr = (unsigned long)ioremap_nocache(cadr, 0x1000); ++ if(ioaddr) { ++ writel(0x8160, ioaddr + REG2); ++ writel(0xcffc0020, ioaddr + REG); ++ printk("i2c-voodoo3: Using Banshee/Voodoo3 at 0x%lx\n", ioaddr); ++ } ++} ++ ++static struct i2c_algo_bit_data voo_i2c_bit_data = { ++ .setsda = bit_vooi2c_setsda, ++ .setscl = bit_vooi2c_setscl, ++ .getsda = bit_vooi2c_getsda, ++ .getscl = bit_vooi2c_getscl, ++ .udelay = CYCLE_DELAY, ++ .mdelay = CYCLE_DELAY, ++ .timeout = TIMEOUT ++}; ++ ++static struct i2c_adapter voodoo3_i2c_adapter = { ++ .owner = THIS_MODULE, ++ .name = "I2C Voodoo3/Banshee adapter", ++ .id = I2C_HW_B_VOO, ++ .algo_data = &voo_i2c_bit_data, ++}; ++ ++static struct i2c_algo_bit_data voo_ddc_bit_data = { ++ .setsda = bit_vooddc_setsda, ++ .setscl = bit_vooddc_setscl, ++ .getsda = bit_vooddc_getsda, ++ .getscl = bit_vooddc_getscl, ++ .udelay = CYCLE_DELAY, ++ .mdelay = CYCLE_DELAY, ++ .timeout = TIMEOUT ++}; ++ ++static struct i2c_adapter voodoo3_ddc_adapter = { ++ .owner = THIS_MODULE, ++ .name = "DDC Voodoo3/Banshee adapter", ++ .id = I2C_HW_B_VOO, ++ .algo_data = &voo_ddc_bit_data, ++}; ++ ++ ++static struct pci_device_id voodoo3_ids[] __devinitdata = { ++ { ++ .vendor = PCI_VENDOR_ID_3DFX, ++ .device = PCI_DEVICE_ID_3DFX_VOODOO3, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = PCI_VENDOR_ID_3DFX, ++ .device = PCI_DEVICE_ID_3DFX_BANSHEE, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { 0, } ++}; ++ ++static int __devinit voodoo3_probe(struct pci_dev *dev, const struct pci_device_id *id) ++{ ++ int retval; ++ ++ printk("voodoo3: in probe\n"); ++ config_v3(dev); ++ retval = i2c_bit_add_bus(&voodoo3_i2c_adapter); ++ if(retval) ++ return retval; ++ retval = i2c_bit_add_bus(&voodoo3_ddc_adapter); ++ if(retval) ++ i2c_bit_del_bus(&voodoo3_i2c_adapter); ++ return retval; ++} ++ ++static void __devexit voodoo3_remove(struct pci_dev *dev) ++{ ++ i2c_bit_del_bus(&voodoo3_i2c_adapter); ++ i2c_bit_del_bus(&voodoo3_ddc_adapter); ++} ++ ++ ++/* Don't register driver to avoid driver conflicts */ ++/* ++static struct pci_driver voodoo3_driver = { ++ .name = "voodoo3 smbus", ++ .id_table = voodoo3_ids, ++ .probe = voodoo3_probe, ++ .remove = __devexit_p(voodoo3_remove), ++}; ++*/ ++ ++static int __init i2c_voodoo3_init(void) ++{ ++ struct pci_dev *dev; ++ const struct pci_device_id *id; ++ ++ printk("i2c-voodoo3.o version %s (%s)\n", LM_VERSION, LM_DATE); ++/* ++ return pci_module_init(&voodoo3_driver); ++*/ ++ pci_for_each_dev(dev) { ++ id = pci_match_device(voodoo3_ids, dev); ++ if(id) ++ if(voodoo3_probe(dev, id) >= 0) ++ return 0; ++ } ++ return -ENODEV; ++} ++ ++ ++static void __exit i2c_voodoo3_exit(void) ++{ ++/* ++ pci_unregister_driver(&voodoo3_driver); ++*/ ++ voodoo3_remove(NULL); ++ iounmap((void *)ioaddr); ++} ++ ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard , Philip Edelbrock , Ralph Metzler , and Mark D. Studebaker "); ++MODULE_DESCRIPTION("Voodoo3 I2C/SMBus driver"); ++ ++module_init(i2c_voodoo3_init); ++module_exit(i2c_voodoo3_exit); +--- linux-old/drivers/sensors/adm1021.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/adm1021.c Mon Dec 13 20:18:43 2004 +@@ -0,0 +1,594 @@ ++/* ++ adm1021.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard and ++ Philip Edelbrock ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x18, 0x1a, 0x29, 0x2b, ++ 0x4c, 0x4e, SENSORS_I2C_END ++}; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, mc1066); ++ ++/* adm1021 constants specified below */ ++ ++/* The adm1021 registers */ ++/* Read-only */ ++#define ADM1021_REG_TEMP 0x00 ++#define ADM1021_REG_REMOTE_TEMP 0x01 ++#define ADM1021_REG_STATUS 0x02 ++#define ADM1021_REG_MAN_ID 0x0FE /* 0x41 = Analog Devices, 0x49 = TI, ++ 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi*/ ++#define ADM1021_REG_DEV_ID 0x0FF /* ADM1021 = 0x0X, ADM1021A/ADM1023 = 0x3X */ ++#define ADM1021_REG_DIE_CODE 0x0FF /* MAX1617A */ ++/* These use different addresses for reading/writing */ ++#define ADM1021_REG_CONFIG_R 0x03 ++#define ADM1021_REG_CONFIG_W 0x09 ++#define ADM1021_REG_CONV_RATE_R 0x04 ++#define ADM1021_REG_CONV_RATE_W 0x0A ++/* These are for the ADM1023's additional precision on the remote temp sensor */ ++#define ADM1021_REG_REM_TEMP_PREC 0x010 ++#define ADM1021_REG_REM_OFFSET 0x011 ++#define ADM1021_REG_REM_OFFSET_PREC 0x012 ++#define ADM1021_REG_REM_TOS_PREC 0x013 ++#define ADM1021_REG_REM_THYST_PREC 0x014 ++/* limits */ ++#define ADM1021_REG_TOS_R 0x05 ++#define ADM1021_REG_TOS_W 0x0B ++#define ADM1021_REG_REMOTE_TOS_R 0x07 ++#define ADM1021_REG_REMOTE_TOS_W 0x0D ++#define ADM1021_REG_THYST_R 0x06 ++#define ADM1021_REG_THYST_W 0x0C ++#define ADM1021_REG_REMOTE_THYST_R 0x08 ++#define ADM1021_REG_REMOTE_THYST_W 0x0E ++/* write-only */ ++#define ADM1021_REG_ONESHOT 0x0F ++ ++#define ADM1021_ALARM_TEMP (ADM1021_ALARM_TEMP_HIGH | ADM1021_ALARM_TEMP_LOW) ++#define ADM1021_ALARM_RTEMP (ADM1021_ALARM_RTEMP_HIGH | ADM1021_ALARM_RTEMP_LOW\ ++ | ADM1021_ALARM_RTEMP_NA) ++#define ADM1021_ALARM_ALL (ADM1021_ALARM_TEMP | ADM1021_ALARM_RTEMP) ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++/* Conversions note: 1021 uses normal integer signed-byte format*/ ++#define TEMP_FROM_REG(val) (val > 127 ? val-256 : val) ++#define TEMP_TO_REG(val) (SENSORS_LIMIT((val < 0 ? val+256 : val),0,255)) ++ ++/* Each client has this additional data */ ++struct adm1021_data { ++ struct i2c_client client; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 temp, temp_os, temp_hyst; /* Register values */ ++ u8 remote_temp, remote_temp_os, remote_temp_hyst, alarms, die_code; ++ u8 fail; ++ /* Special values for ADM1023 only */ ++ u8 remote_temp_prec, remote_temp_os_prec, remote_temp_hyst_prec, ++ remote_temp_offset, remote_temp_offset_prec; ++}; ++ ++static int adm1021_attach_adapter(struct i2c_adapter *adapter); ++static int adm1021_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static void adm1021_init_client(struct i2c_client *client); ++static int adm1021_detach_client(struct i2c_client *client); ++static int adm1021_read_value(struct i2c_client *client, u8 reg); ++static int adm1021_rd_good(u8 *val, struct i2c_client *client, u8 reg, u8 mask); ++static int adm1021_write_value(struct i2c_client *client, u8 reg, ++ u16 value); ++static void adm1021_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1021_remote_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, ++ long *results); ++static void adm1021_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1021_die_code(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1021_update_client(struct i2c_client *client); ++ ++/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */ ++static int read_only = 0; ++ ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver adm1021_driver = { ++ .owner = THIS_MODULE, ++ .name = "ADM1021, MAX1617 sensor driver", ++ .id = I2C_DRIVERID_ADM1021, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = adm1021_attach_adapter, ++ .detach_client = adm1021_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define ADM1021_SYSCTL_TEMP 1200 ++#define ADM1021_SYSCTL_REMOTE_TEMP 1201 ++#define ADM1021_SYSCTL_DIE_CODE 1202 ++#define ADM1021_SYSCTL_ALARMS 1203 ++ ++#define ADM1021_ALARM_TEMP_HIGH 0x40 ++#define ADM1021_ALARM_TEMP_LOW 0x20 ++#define ADM1021_ALARM_RTEMP_HIGH 0x10 ++#define ADM1021_ALARM_RTEMP_LOW 0x08 ++#define ADM1021_ALARM_RTEMP_NA 0x04 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected adm1021. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table adm1021_dir_table_template[] = { ++ {ADM1021_SYSCTL_TEMP, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1021_temp}, ++ {ADM1021_SYSCTL_REMOTE_TEMP, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1021_remote_temp}, ++ {ADM1021_SYSCTL_DIE_CODE, "die_code", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1021_die_code}, ++ {ADM1021_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1021_alarms}, ++ {0} ++}; ++ ++static ctl_table adm1021_max_dir_table_template[] = { ++ {ADM1021_SYSCTL_TEMP, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1021_temp}, ++ {ADM1021_SYSCTL_REMOTE_TEMP, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1021_remote_temp}, ++ {ADM1021_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1021_alarms}, ++ {0} ++}; ++ ++static int adm1021_id = 0; ++ ++static int adm1021_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, adm1021_detect); ++} ++ ++static int adm1021_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct adm1021_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("adm1021.o: adm1021_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto error0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access adm1021_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct adm1021_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto error0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &adm1021_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ ++ if (kind < 0) { ++ if ((adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0x03) != 0x00 ++ || (adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x3F) != 0x00 ++ || (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) & 0xF8) != 0x00) { ++ err = -ENODEV; ++ goto error1; ++ } ++ } ++ ++ /* Determine the chip type. */ ++ ++ if (kind <= 0) { ++ i = adm1021_read_value(new_client, ADM1021_REG_MAN_ID); ++ if (i == 0x41) ++ if ((adm1021_read_value (new_client, ADM1021_REG_DEV_ID) & 0xF0) == 0x30) ++ kind = adm1023; ++ else ++ kind = adm1021; ++ else if (i == 0x49) ++ kind = thmc10; ++ else if (i == 0x23) ++ kind = gl523sm; ++ else if ((i == 0x4d) && ++ (adm1021_read_value ++ (new_client, ADM1021_REG_DEV_ID) == 0x01)) ++ kind = max1617a; ++ else if (i == 0x54) ++ kind = mc1066; ++ /* LM84 Mfr ID in a different place, and it has more unused bits */ ++ else if (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) == 0x00 ++ && (kind == 0 /* skip extra detection */ ++ || ((adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x7F) == 0x00 ++ && (adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0xAB) == 0x00))) ++ kind = lm84; ++ else ++ kind = max1617; ++ } ++ ++ if (kind == max1617) { ++ type_name = "max1617"; ++ client_name = "MAX1617 chip"; ++ } else if (kind == max1617a) { ++ type_name = "max1617a"; ++ client_name = "MAX1617A chip"; ++ } else if (kind == adm1021) { ++ type_name = "adm1021"; ++ client_name = "ADM1021 chip"; ++ } else if (kind == adm1023) { ++ type_name = "adm1023"; ++ client_name = "ADM1023 chip"; ++ } else if (kind == thmc10) { ++ type_name = "thmc10"; ++ client_name = "THMC10 chip"; ++ } else if (kind == lm84) { ++ type_name = "lm84"; ++ client_name = "LM84 chip"; ++ } else if (kind == gl523sm) { ++ type_name = "gl523sm"; ++ client_name = "GL523SM chip"; ++ } else if (kind == mc1066) { ++ type_name = "mc1066"; ++ client_name = "MC1066 chip"; ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ data->type = kind; ++ ++ new_client->id = adm1021_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto error3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, type_name, ++ data->type == adm1021 ? adm1021_dir_table_template : ++ adm1021_max_dir_table_template)) < 0) { ++ err = i; ++ goto error4; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the ADM1021 chip */ ++ if (kind != lm84) ++ adm1021_init_client(new_client); ++ return 0; ++ ++ error4: ++ i2c_detach_client(new_client); ++ error3: ++ error1: ++ kfree(data); ++ error0: ++ return err; ++} ++ ++static void adm1021_init_client(struct i2c_client *client) ++{ ++ /* Enable ADC and disable suspend mode */ ++ adm1021_write_value(client, ADM1021_REG_CONFIG_W, ++ adm1021_read_value(client, ADM1021_REG_CONFIG_R) & 0xBF); ++ /* Set Conversion rate to 1/sec (this can be tinkered with) */ ++ adm1021_write_value(client, ADM1021_REG_CONV_RATE_W, 0x04); ++} ++ ++static int adm1021_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct adm1021_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("adm1021.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++ ++/* All registers are byte-sized */ ++static int adm1021_read_value(struct i2c_client *client, u8 reg) ++{ ++ return i2c_smbus_read_byte_data(client, reg); ++} ++ ++/* only update value if read succeeded; set fail bit if failed */ ++static int adm1021_rd_good(u8 *val, struct i2c_client *client, u8 reg, u8 mask) ++{ ++ int i; ++ struct adm1021_data *data = client->data; ++ ++ i = i2c_smbus_read_byte_data(client, reg); ++ if (i < 0) { ++ data->fail |= mask; ++ return i; ++ } ++ *val = i; ++ return 0; ++} ++ ++static int adm1021_write_value(struct i2c_client *client, u8 reg, u16 value) ++{ ++ if (read_only > 0) ++ return 0; ++ ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++static void adm1021_update_client(struct i2c_client *client) ++{ ++ struct adm1021_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("Starting adm1021 update\n"); ++#endif ++ ++ data->fail = 0; ++ adm1021_rd_good(&(data->temp), client, ADM1021_REG_TEMP, ++ ADM1021_ALARM_TEMP); ++ adm1021_rd_good(&(data->temp_os), client, ADM1021_REG_TOS_R, ++ ADM1021_ALARM_TEMP); ++ adm1021_rd_good(&(data->temp_hyst), client, ++ ADM1021_REG_THYST_R, ADM1021_ALARM_TEMP); ++ adm1021_rd_good(&(data->remote_temp), client, ++ ADM1021_REG_REMOTE_TEMP, ADM1021_ALARM_RTEMP); ++ adm1021_rd_good(&(data->remote_temp_os), client, ++ ADM1021_REG_REMOTE_TOS_R, ADM1021_ALARM_RTEMP); ++ adm1021_rd_good(&(data->remote_temp_hyst), client, ++ ADM1021_REG_REMOTE_THYST_R, ++ ADM1021_ALARM_RTEMP); ++ data->alarms = ADM1021_ALARM_ALL; ++ if (!adm1021_rd_good(&(data->alarms), client, ++ ADM1021_REG_STATUS, 0)) ++ data->alarms &= ADM1021_ALARM_ALL; ++ if (data->type == adm1021) ++ adm1021_rd_good(&(data->die_code), client, ++ ADM1021_REG_DIE_CODE, 0); ++ if (data->type == adm1023) { ++ adm1021_rd_good(&(data->remote_temp_prec), client, ++ ADM1021_REG_REM_TEMP_PREC, ++ ADM1021_ALARM_TEMP); ++ adm1021_rd_good(&(data->remote_temp_os_prec), client, ++ ADM1021_REG_REM_TOS_PREC, ++ ADM1021_ALARM_RTEMP); ++ adm1021_rd_good(&(data->remote_temp_hyst_prec), client, ++ ADM1021_REG_REM_THYST_PREC, ++ ADM1021_ALARM_RTEMP); ++ adm1021_rd_good(&(data->remote_temp_offset), client, ++ ADM1021_REG_REM_OFFSET, ++ ADM1021_ALARM_RTEMP); ++ adm1021_rd_good(&(data->remote_temp_offset_prec), ++ client, ADM1021_REG_REM_OFFSET_PREC, ++ ADM1021_ALARM_RTEMP); ++ } ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++void adm1021_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1021_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1021_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_os); ++ results[1] = TEMP_FROM_REG(data->temp_hyst); ++ results[2] = TEMP_FROM_REG(data->temp); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_os = TEMP_TO_REG(results[0]); ++ adm1021_write_value(client, ADM1021_REG_TOS_W, ++ data->temp_os); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst = TEMP_TO_REG(results[1]); ++ adm1021_write_value(client, ADM1021_REG_THYST_W, ++ data->temp_hyst); ++ } ++ } ++} ++ ++void adm1021_remote_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct adm1021_data *data = client->data; ++ int prec = 0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ if (data->type == adm1023) { *nrels_mag = 3; } ++ else { *nrels_mag = 0; } ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1021_update_client(client); ++ results[0] = TEMP_FROM_REG(data->remote_temp_os); ++ results[1] = TEMP_FROM_REG(data->remote_temp_hyst); ++ results[2] = TEMP_FROM_REG(data->remote_temp); ++ if (data->type == adm1023) { ++ results[0]=results[0]*1000 + ++ ((data->remote_temp_os_prec >> 5) * 125); ++ results[1]=results[1]*1000 + ++ ((data->remote_temp_hyst_prec >> 5) * 125); ++ results[2]=(TEMP_FROM_REG(data->remote_temp_offset)*1000) + ++ ((data->remote_temp_offset_prec >> 5) * 125); ++ results[3]=TEMP_FROM_REG(data->remote_temp)*1000 + ++ ((data->remote_temp_prec >> 5) * 125); ++ *nrels_mag = 4; ++ } else { ++ *nrels_mag = 3; ++ } ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ if (data->type == adm1023) { ++ prec=((results[0]-((results[0]/1000)*1000))/125)<<5; ++ adm1021_write_value(client, ++ ADM1021_REG_REM_TOS_PREC, ++ prec); ++ results[0]=results[0]/1000; ++ data->remote_temp_os_prec=prec; ++ } ++ data->remote_temp_os = TEMP_TO_REG(results[0]); ++ adm1021_write_value(client, ++ ADM1021_REG_REMOTE_TOS_W, ++ data->remote_temp_os); ++ } ++ if (*nrels_mag >= 2) { ++ if (data->type == adm1023) { ++ prec=((results[1]-((results[1]/1000)*1000))/125)<<5; ++ adm1021_write_value(client, ++ ADM1021_REG_REM_THYST_PREC, ++ prec); ++ results[1]=results[1]/1000; ++ data->remote_temp_hyst_prec=prec; ++ } ++ data->remote_temp_hyst = TEMP_TO_REG(results[1]); ++ adm1021_write_value(client, ++ ADM1021_REG_REMOTE_THYST_W, ++ data->remote_temp_hyst); ++ } ++ if (*nrels_mag >= 3) { ++ if (data->type == adm1023) { ++ prec=((results[2]-((results[2]/1000)*1000))/125)<<5; ++ adm1021_write_value(client, ++ ADM1021_REG_REM_OFFSET_PREC, ++ prec); ++ results[2]=results[2]/1000; ++ data->remote_temp_offset_prec=prec; ++ data->remote_temp_offset=results[2]; ++ adm1021_write_value(client, ++ ADM1021_REG_REM_OFFSET, ++ data->remote_temp_offset); ++ } ++ } ++ } ++} ++ ++void adm1021_die_code(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct adm1021_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1021_update_client(client); ++ results[0] = data->die_code; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ /* Can't write to it */ ++ } ++} ++ ++void adm1021_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1021_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1021_update_client(client); ++ results[0] = data->alarms | data->fail; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ /* Can't write to it */ ++ } ++} ++ ++static int __init sm_adm1021_init(void) ++{ ++ printk(KERN_INFO "adm1021.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&adm1021_driver); ++} ++ ++static void __exit sm_adm1021_exit(void) ++{ ++ i2c_del_driver(&adm1021_driver); ++} ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard and Philip Edelbrock "); ++MODULE_DESCRIPTION("adm1021 driver"); ++MODULE_LICENSE("GPL"); ++ ++MODULE_PARM(read_only, "i"); ++MODULE_PARM_DESC(read_only, "Don't set any values, read only mode"); ++ ++module_init(sm_adm1021_init) ++module_exit(sm_adm1021_exit) +--- linux-old/drivers/sensors/adm1024.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/adm1024.c Mon Dec 13 20:18:43 2004 +@@ -0,0 +1,782 @@ ++/* ++ adm1024.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Add by Ken Bowley from the adm1025.c written by ++ Gordon Wu and from adm9240.c written by ++ Copyright (c) 1999 Frodo Looijaard ++ and Philip Edelbrock ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* Supports the Analog Devices ADM1024. See doc/chips/adm1024 for details */ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x2c, 0x2e, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(adm1024); ++ ++/* Many ADM1024 constants specified below */ ++ ++#define ADM1024_REG_IN_MAX(nr) (0x2b + (nr) * 2) ++#define ADM1024_REG_IN_MIN(nr) (0x2c + (nr) * 2) ++#define ADM1024_REG_IN(nr) (0x20 + (nr)) ++ ++/* The ADM1024 registers */ ++#define ADM1024_REG_INT_TEMP_TRIP_SET 0x13 ++#define ADM1024_REG_EXT_TEMP_TRIP_SET 0x14 ++#define ADM1024_REG_TEST 0x15 ++#define ADM1024_REG_CHANNEL_MODE 0x16 ++#define ADM1024_REG_INT_TEMP_TRIP 0x17 /* read only */ ++#define ADM1024_REG_EXT_TEMP_TRIP 0x18 /* read only */ ++#define ADM1024_REG_ANALOG_OUT 0x19 ++#define ADM1024_REG_AIN1_LOW_LIMIT 0x1A ++#define ADM1024_REG_AIN2_LOW_LIMIT 0x1B ++/* These are all read-only */ ++#define ADM1024_REG_2_5V 0x20 /* 2.5V Measured Value/EXT Temp 2 */ ++#define ADM1024_REG_VCCP1 0x21 ++#define ADM1024_REG_3_3V 0x22 /* VCC Measured Value */ ++#define ADM1024_REG_5V 0x23 ++#define ADM1024_REG_12V 0x24 ++#define ADM1024_REG_VCCP2 0x25 ++#define ADM1024_REG_EXT_TEMP1 0x26 ++#define ADM1024_REG_TEMP 0x27 ++#define ADM1024_REG_FAN1 0x28 /* FAN1/AIN1 Value */ ++#define ADM1024_REG_FAN2 0x29 /* FAN2/AIN2 Value */ ++#define ADM1024_REG_COMPANY_ID 0x3E /* 0x41 for ADM1024 */ ++#define ADM1024_REG_DIE_REV 0x3F ++/* These are read/write */ ++#define ADM1024_REG_2_5V_HIGH 0x2B /* 2.5V/Ext Temp2 High Limit */ ++#define ADM1024_REG_2_5V_LOW 0x2C /* 2.5V/Ext Temp2 Low Limit */ ++#define ADM1024_REG_VCCP1_HIGH 0x2D ++#define ADM1024_REG_VCCP1_LOW 0x2E ++#define ADM1024_REG_3_3V_HIGH 0x2F /* VCC High Limit */ ++#define ADM1024_REG_3_3V_LOW 0x30 /* VCC Low Limit */ ++#define ADM1024_REG_5V_HIGH 0x31 ++#define ADM1024_REG_5V_LOW 0x32 ++#define ADM1024_REG_12V_HIGH 0x33 ++#define ADM1024_REG_12V_LOW 0x34 ++#define ADM1024_REG_VCCP2_HIGH 0x35 ++#define ADM1024_REG_VCCP2_LOW 0x36 ++#define ADM1024_REG_EXT_TEMP1_HIGH 0x37 ++#define ADM1024_REG_EXT_TEMP1_LOW 0x38 ++#define ADM1024_REG_TOS 0x39 ++#define ADM1024_REG_THYST 0x3A ++#define ADM1024_REG_FAN1_MIN 0x3B ++#define ADM1024_REG_FAN2_MIN 0x3C ++ ++#define ADM1024_REG_CONFIG 0x40 ++#define ADM1024_REG_INT1_STAT 0x41 ++#define ADM1024_REG_INT2_STAT 0x42 ++#define ADM1024_REG_INT1_MASK 0x43 ++#define ADM1024_REG_INT2_MASK 0x44 ++ ++#define ADM1024_REG_CHASSIS_CLEAR 0x46 ++#define ADM1024_REG_VID_FAN_DIV 0x47 ++#define ADM1024_REG_I2C_ADDR 0x48 ++#define ADM1024_REG_VID4 0x49 ++#define ADM1024_REG_CONFIG2 0x4A ++#define ADM1024_REG_TEMP_CONFIG 0x4B ++#define ADM1024_REG_EXTMODE1 0x4C /* Interupt Status Register Mirror No. 1 */ ++#define ADM1024_REG_EXTMODE2 0x4D /* Interupt Status Register Mirror No. 2 */ ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++#define IN_TO_REG(val,nr) (SENSORS_LIMIT(((val) & 0xff),0,255)) ++#define IN_FROM_REG(val,nr) (val) ++ ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 255; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, ++ 254); ++} ++ ++#define FAN_FROM_REG(val,div) ((val)==0?-1:\ ++ (val)==255?0:1350000/((div)*(val))) ++ ++#define TEMP_FROM_REG(temp) \ ++ ((temp)<256?((((temp)&0x1fe) >> 1) * 10) + ((temp) & 1) * 5: \ ++ ((((temp)&0x1fe) >> 1) -255) * 10 - ((temp) & 1) * 5) \ ++ ++#define EXT_TEMP_FROM_REG(temp) (((temp)>0x80?(temp)-0x100:(temp))*10) ++ ++ ++#define TEMP_LIMIT_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10) ++ ++#define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT(((val)<0?(((val)-5)/10):\ ++ ((val)+5)/10), \ ++ 0,255) ++ ++#define ALARMS_FROM_REG(val) (val) ++ ++#define DIV_FROM_REG(val) (1 << (val)) ++#define DIV_TO_REG(val) ((val)==1?0:((val)==8?3:((val)==4?2:1))) ++ ++#define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\ ++ 205-(val)*5) ++ ++/* For each registered ADM1024, we need to keep some data in memory. That ++ data is pointed to by adm1024_list[NR]->data. The structure itself is ++ dynamically allocated, at the same time when a new adm1024 client is ++ allocated. */ ++struct adm1024_data { ++ struct i2c_client client; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 in[6]; /* Register value */ ++ u8 in_max[6]; /* Register value */ ++ u8 in_min[6]; /* Register value */ ++ u8 fan[2]; /* Register value */ ++ u8 fan_min[2]; /* Register value */ ++ u8 fan_div[2]; /* Register encoding, shifted right */ ++ int temp; /* Temp, shifted right */ ++ u8 temp_os_max; /* Register value */ ++ u8 temp_os_hyst; /* Register value */ ++ int temp1; /* Ext Temp 1 */ ++ u8 temp1_os_max; ++ u8 temp1_os_hyst; ++ int temp2; /* Ext Temp 2 */ ++ u8 temp2_os_max; ++ u8 temp2_os_hyst; ++ u16 alarms; /* Register encoding, combined */ ++ u8 analog_out; /* Register value */ ++ u8 vid; /* Register value combined */ ++}; ++ ++ ++ ++static int adm1024_attach_adapter(struct i2c_adapter *adapter); ++static int adm1024_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int adm1024_detach_client(struct i2c_client *client); ++ ++static int adm1024_read_value(struct i2c_client *client, u8 register); ++static int adm1024_write_value(struct i2c_client *client, u8 register, ++ u8 value); ++static void adm1024_update_client(struct i2c_client *client); ++static void adm1024_init_client(struct i2c_client *client); ++ ++ ++static void adm1024_in(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1024_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1024_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1024_temp1(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1024_temp2(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1024_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1024_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1024_analog_out(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, ++ long *results); ++static void adm1024_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static int adm1024_id = 0; ++ ++static struct i2c_driver adm1024_driver = { ++ .owner = THIS_MODULE, ++ .name = "ADM1024 sensor driver", ++ .id = I2C_DRIVERID_ADM1024, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = adm1024_attach_adapter, ++ .detach_client = adm1024_detach_client, ++}; ++ ++/* The /proc/sys entries */ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define ADM1024_SYSCTL_IN0 1000 /* Volts * 100 */ ++#define ADM1024_SYSCTL_IN1 1001 ++#define ADM1024_SYSCTL_IN2 1002 ++#define ADM1024_SYSCTL_IN3 1003 ++#define ADM1024_SYSCTL_IN4 1004 ++#define ADM1024_SYSCTL_IN5 1005 ++#define ADM1024_SYSCTL_FAN1 1101 /* Rotations/min */ ++#define ADM1024_SYSCTL_FAN2 1102 ++#define ADM1024_SYSCTL_TEMP 1250 /* Degrees Celcius * 100 */ ++#define ADM1024_SYSCTL_TEMP1 1290 /* Degrees Celcius */ ++#define ADM1024_SYSCTL_TEMP2 1295 /* Degrees Celcius */ ++#define ADM1024_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define ADM1024_SYSCTL_ALARMS 2001 /* bitvector */ ++#define ADM1024_SYSCTL_ANALOG_OUT 2002 ++#define ADM1024_SYSCTL_VID 2003 ++ ++#define ADM1024_ALARM_IN0 0x0001 ++#define ADM1024_ALARM_IN1 0x0002 ++#define ADM1024_ALARM_IN2 0x0004 ++#define ADM1024_ALARM_IN3 0x0008 ++#define ADM1024_ALARM_IN4 0x0100 ++#define ADM1024_ALARM_IN5 0x0200 ++#define ADM1024_ALARM_FAN1 0x0040 ++#define ADM1024_ALARM_FAN2 0x0080 ++#define ADM1024_ALARM_TEMP 0x0010 ++#define ADM1024_ALARM_TEMP1 0x0020 ++#define ADM1024_ALARM_TEMP2 0x0001 ++#define ADM1024_ALARM_CHAS 0x1000 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected ADM1024. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table adm1024_dir_table_template[] = { ++ {ADM1024_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_in}, ++ {ADM1024_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_in}, ++ {ADM1024_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_in}, ++ {ADM1024_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_in}, ++ {ADM1024_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_in}, ++ {ADM1024_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_in}, ++ {ADM1024_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_fan}, ++ {ADM1024_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_fan}, ++ {ADM1024_SYSCTL_TEMP, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_temp}, ++ {ADM1024_SYSCTL_TEMP1, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_temp1}, ++ {ADM1024_SYSCTL_TEMP2, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_temp2}, ++ {ADM1024_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_fan_div}, ++ {ADM1024_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_alarms}, ++ {ADM1024_SYSCTL_ANALOG_OUT, "analog_out", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_analog_out}, ++ {ADM1024_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1024_vid}, ++ {0} ++}; ++ ++static int adm1024_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, adm1024_detect); ++} ++ ++static int adm1024_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct adm1024_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("adm1024.o: adm1024_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access adm1024_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct adm1024_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &adm1024_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ ++ if (kind < 0) { ++ if((adm1024_read_value(new_client, ADM1024_REG_CONFIG) & 0x80) != 0x00) ++ goto ERROR1; ++ } ++ ++ /* Determine the chip type. */ ++ if (kind <= 0) { ++ i = adm1024_read_value(new_client, ADM1024_REG_COMPANY_ID); ++ if (i == 0x41) ++ kind = adm1024; ++ else { ++ if (kind == 0) ++ printk ++ ("adm1024.o: Ignoring 'force' parameter for unknown chip at " ++ "adapter %d, address 0x%02x\n", ++ i2c_adapter_id(adapter), address); ++ goto ERROR1; ++ } ++ } ++ ++ if (kind == adm1024) { ++ type_name = "adm1024"; ++ client_name = "ADM1024 chip"; ++ } else { ++#ifdef DEBUG ++ printk("adm1024.o: Internal error: unknown kind (%d)?!?", ++ kind); ++#endif ++ goto ERROR1; ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ data->type = kind; ++ ++ new_client->id = adm1024_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, ++ type_name, ++ adm1024_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the ADM1024 chip */ ++ adm1024_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int adm1024_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct adm1024_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("adm1024.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++static int adm1024_read_value(struct i2c_client *client, u8 reg) ++{ ++ return 0xFF & i2c_smbus_read_byte_data(client, reg); ++} ++ ++static int adm1024_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++static void adm1024_init_client(struct i2c_client *client) ++{ ++ /* Enable temperature channel 2 */ ++ adm1024_write_value(client, ADM1024_REG_CHANNEL_MODE, adm1024_read_value(client, ADM1024_REG_CHANNEL_MODE) | 0x04); ++ ++ /* Start monitoring */ ++ adm1024_write_value(client, ADM1024_REG_CONFIG, 0x07); ++} ++ ++static void adm1024_update_client(struct i2c_client *client) ++{ ++ struct adm1024_data *data = client->data; ++ u8 i; ++ ++ down(&data->update_lock); ++ ++ if ( ++ (jiffies - data->last_updated > ++ (data->type == adm1024 ? HZ / 2 : HZ * 2)) ++ || (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("Starting adm1024 update\n"); ++#endif ++ for (i = 0; i <= 5; i++) { ++ data->in[i] = ++ adm1024_read_value(client, ADM1024_REG_IN(i)); ++ data->in_min[i] = ++ adm1024_read_value(client, ++ ADM1024_REG_IN_MIN(i)); ++ data->in_max[i] = ++ adm1024_read_value(client, ++ ADM1024_REG_IN_MAX(i)); ++ } ++ data->fan[0] = ++ adm1024_read_value(client, ADM1024_REG_FAN1); ++ data->fan_min[0] = ++ adm1024_read_value(client, ADM1024_REG_FAN1_MIN); ++ data->fan[1] = ++ adm1024_read_value(client, ADM1024_REG_FAN2); ++ data->fan_min[1] = ++ adm1024_read_value(client, ADM1024_REG_FAN2_MIN); ++ data->temp = ++ (adm1024_read_value(client, ADM1024_REG_TEMP) << 1) + ++ ((adm1024_read_value ++ (client, ADM1024_REG_TEMP_CONFIG) & 0x80) >> 7); ++ data->temp_os_max = ++ adm1024_read_value(client, ADM1024_REG_TOS); ++ data->temp_os_hyst = ++ adm1024_read_value(client, ADM1024_REG_THYST); ++ data->temp1 = ++ adm1024_read_value(client, ADM1024_REG_EXT_TEMP1); ++ data->temp1_os_max = ++ adm1024_read_value(client, ADM1024_REG_EXT_TEMP1_HIGH); ++ data->temp1_os_hyst = ++ adm1024_read_value(client, ADM1024_REG_EXT_TEMP1_LOW); ++ data->temp2 = ++ adm1024_read_value(client, ADM1024_REG_2_5V); ++ data->temp2_os_max = ++ adm1024_read_value(client, ADM1024_REG_2_5V_HIGH); ++ data->temp2_os_hyst = ++ adm1024_read_value(client, ADM1024_REG_2_5V_LOW); ++ ++ i = adm1024_read_value(client, ADM1024_REG_VID_FAN_DIV); ++ data->fan_div[0] = (i >> 4) & 0x03; ++ data->fan_div[1] = (i >> 6) & 0x03; ++ data->vid = i & 0x0f; ++ data->vid |= ++ (adm1024_read_value(client, ADM1024_REG_VID4) & 0x01) ++ << 4; ++ ++ data->alarms = ++ adm1024_read_value(client, ++ ADM1024_REG_INT1_STAT) + ++ (adm1024_read_value(client, ADM1024_REG_INT2_STAT) << ++ 8); ++ data->analog_out = ++ adm1024_read_value(client, ADM1024_REG_ANALOG_OUT); ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the date ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++void adm1024_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ ++ int scales[6] = { 250, 225, 330, 500, 1200, 270 }; ++ ++ struct adm1024_data *data = client->data; ++ int nr = ctl_name - ADM1024_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1024_update_client(client); ++ results[0] = ++ IN_FROM_REG(data->in_min[nr], nr) * scales[nr] / 192; ++ results[1] = ++ IN_FROM_REG(data->in_max[nr], nr) * scales[nr] / 192; ++ results[2] = ++ IN_FROM_REG(data->in[nr], nr) * scales[nr] / 192; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = ++ IN_TO_REG((results[0] * 192) / scales[nr], nr); ++ adm1024_write_value(client, ADM1024_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = ++ IN_TO_REG((results[1] * 192) / scales[nr], nr); ++ adm1024_write_value(client, ADM1024_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++} ++ ++void adm1024_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1024_data *data = client->data; ++ int nr = ctl_name - ADM1024_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1024_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr - 1], ++ DIV_FROM_REG(data-> ++ fan_div[nr - 1])); ++ results[1] = ++ FAN_FROM_REG(data->fan[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = FAN_TO_REG(results[0], ++ DIV_FROM_REG ++ (data-> ++ fan_div[nr - ++ 1])); ++ adm1024_write_value(client, ++ nr == ++ 1 ? ADM1024_REG_FAN1_MIN : ++ ADM1024_REG_FAN2_MIN, ++ data->fan_min[nr - 1]); ++ } ++ } ++} ++ ++ ++void adm1024_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1024_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1024_update_client(client); ++ results[0] = TEMP_LIMIT_FROM_REG(data->temp_os_max); ++ results[1] = TEMP_LIMIT_FROM_REG(data->temp_os_hyst); ++ results[2] = TEMP_FROM_REG(data->temp); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_os_max = TEMP_LIMIT_TO_REG(results[0]); ++ adm1024_write_value(client, ADM1024_REG_TOS, ++ data->temp_os_max); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_os_hyst = TEMP_LIMIT_TO_REG(results[1]); ++ adm1024_write_value(client, ADM1024_REG_THYST, ++ data->temp_os_hyst); ++ } ++ } ++} ++ ++void adm1024_temp1(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1024_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1024_update_client(client); ++ results[0] = TEMP_LIMIT_FROM_REG(data->temp1_os_max); ++ results[1] = TEMP_LIMIT_FROM_REG(data->temp1_os_hyst); ++ results[2] = EXT_TEMP_FROM_REG(data->temp1); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp1_os_max = TEMP_LIMIT_TO_REG(results[0]); ++ adm1024_write_value(client, ADM1024_REG_EXT_TEMP1_HIGH, ++ data->temp1_os_max); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp1_os_hyst = TEMP_LIMIT_TO_REG(results[1]); ++ adm1024_write_value(client, ADM1024_REG_EXT_TEMP1_LOW, ++ data->temp1_os_hyst); ++ } ++ } ++} ++ ++void adm1024_temp2(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1024_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1024_update_client(client); ++ results[0] = TEMP_LIMIT_FROM_REG(data->temp2_os_max); ++ results[1] = TEMP_LIMIT_FROM_REG(data->temp2_os_hyst); ++ results[2] = EXT_TEMP_FROM_REG(data->temp2); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp2_os_max = TEMP_LIMIT_TO_REG(results[0]); ++ adm1024_write_value(client, ADM1024_REG_2_5V_HIGH, ++ data->temp2_os_max); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp2_os_hyst = TEMP_LIMIT_TO_REG(results[1]); ++ adm1024_write_value(client, ADM1024_REG_2_5V_LOW, ++ data->temp2_os_hyst); ++ } ++ } ++} ++ ++void adm1024_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1024_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1024_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++void adm1024_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct adm1024_data *data = client->data; ++ int old; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1024_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = adm1024_read_value(client, ADM1024_REG_VID_FAN_DIV); ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ old = (old & 0x3f) | (data->fan_div[1] << 6); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ old = (old & 0xcf) | (data->fan_div[0] << 4); ++ adm1024_write_value(client, ++ ADM1024_REG_VID_FAN_DIV, old); ++ } ++ } ++} ++ ++void adm1024_analog_out(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct adm1024_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1024_update_client(client); ++ results[0] = data->analog_out; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->analog_out = results[0]; ++ adm1024_write_value(client, ADM1024_REG_ANALOG_OUT, ++ data->analog_out); ++ } ++ } ++} ++ ++void adm1024_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1024_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1024_update_client(client); ++ results[0] = VID_FROM_REG(data->vid); ++ *nrels_mag = 1; ++ } ++} ++ ++static int __init sm_adm1024_init(void) ++{ ++ printk("adm1024.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&adm1024_driver); ++} ++ ++static void __exit sm_adm1024_exit(void) ++{ ++ i2c_del_driver(&adm1024_driver); ++} ++ ++ ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard and Philip Edelbrock "); ++MODULE_DESCRIPTION("ADM1024 driver"); ++ ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_adm1024_init); ++module_exit(sm_adm1024_exit); +--- linux-old/drivers/sensors/adm1025.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/adm1025.c Mon Dec 13 20:18:43 2004 +@@ -0,0 +1,594 @@ ++/* ++ adm1025.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 2000 Chen-Yuan Wu ++ Copyright (c) 2003-2004 Jean Delvare ++ ++ Based on the adm9240 driver. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* Supports the Analog Devices ADM1025 and the Philips NE1619. ++ See doc/chips/adm1025 for details */ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x2c, 0x2e, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_2(adm1025, ne1619); ++ ++/* Many ADM1025 constants specified below */ ++ ++ ++/* The ADM1025 registers */ ++ ++/* These are all read-only */ ++#define ADM1025_REG_2_5V 0x20 /* not used directly, see */ ++#define ADM1025_REG_VCCP1 0x21 /* ADM1025_REG_IN(nr) below */ ++#define ADM1025_REG_3_3V 0x22 ++#define ADM1025_REG_5V 0x23 ++#define ADM1025_REG_12V 0x24 ++#define ADM1025_REG_VCC 0x25 ++ ++#define ADM1025_REG_RTEMP 0x26 /* not used directly, see */ ++#define ADM1025_REG_LTEMP 0x27 /* ADM1025_REG_TEMP(nr) below */ ++ ++#define ADM1025_REG_COMPANY_ID 0x3E /* 0x41 for Analog Devices, ++ 0xA1 for Philips */ ++#define ADM1025_REG_DIE_REV 0x3F /* 0x20-0x2F for ADM1025 and compatible */ ++ ++#define ADM1025_REG_STATUS1 0x41 ++#define ADM1025_REG_STATUS2 0x42 ++ ++#define ADM1025_REG_VID 0x47 ++#define ADM1025_REG_VID4 0x49 /* actually R/W ++ but we don't write to it */ ++ ++/* These are read/write */ ++#define ADM1025_REG_2_5V_HIGH 0x2B /* not used directly, see */ ++#define ADM1025_REG_2_5V_LOW 0x2C /* ADM1025_REG_IN_MAX(nr) and */ ++#define ADM1025_REG_VCCP1_HIGH 0x2D /* ADM1025_REG_IN_MIN(nr) below */ ++#define ADM1025_REG_VCCP1_LOW 0x2E ++#define ADM1025_REG_3_3V_HIGH 0x2F ++#define ADM1025_REG_3_3V_LOW 0x30 ++#define ADM1025_REG_5V_HIGH 0x31 ++#define ADM1025_REG_5V_LOW 0x32 ++#define ADM1025_REG_12V_HIGH 0x33 ++#define ADM1025_REG_12V_LOW 0x34 ++#define ADM1025_REG_VCC_HIGH 0x35 ++#define ADM1025_REG_VCC_LOW 0x36 ++ ++#define ADM1025_REG_RTEMP_HIGH 0x37 /* not used directly, see */ ++#define ADM1025_REG_RTEMP_LOW 0x38 /* ADM1025_REG_TEMP_MAX(nr) and */ ++#define ADM1025_REG_LTEMP_HIGH 0x39 /* ADM1025_REG_TEMP_MIN(nr) below */ ++#define ADM1025_REG_LTEMP_LOW 0x3A ++ ++#define ADM1025_REG_CONFIG 0x40 ++ ++/* Useful macros */ ++#define ADM1025_REG_IN(nr) (ADM1025_REG_2_5V + (nr)) ++#define ADM1025_REG_IN_MAX(nr) (ADM1025_REG_2_5V_HIGH + (nr) * 2) ++#define ADM1025_REG_IN_MIN(nr) (ADM1025_REG_2_5V_LOW + (nr) * 2) ++#define ADM1025_REG_TEMP(nr) (ADM1025_REG_RTEMP + (nr)) ++#define ADM1025_REG_TEMP_HIGH(nr) (ADM1025_REG_RTEMP_HIGH + (nr) * 2) ++#define ADM1025_REG_TEMP_LOW(nr) (ADM1025_REG_RTEMP_LOW + (nr) * 2) ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++#define IN_TO_REG(val) SENSORS_LIMIT(val, 0, 255) ++#define IN_FROM_REG(val) (val) ++ ++#define TEMP_FROM_REG(val) (((val)>=0x80?(val)-0x100:(val))*10) ++#define TEMP_TO_REG(val) SENSORS_LIMIT(((val)<0?(((val)-5)/10):\ ++ ((val)+5)/10),-128,127) ++ ++#define ALARMS_FROM_REG(val) (val) ++ ++/* For each registered ADM1025, we need to keep some data in memory. That ++ data is pointed to by adm1025_list[NR]->data. The structure itself is ++ dynamically allocated, at the same time when a new adm1025 client is ++ allocated. */ ++struct adm1025_data { ++ struct i2c_client client; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 in[6]; /* Register value */ ++ u8 in_max[6]; /* Register value */ ++ u8 in_min[6]; /* Register value */ ++ u8 temp[2]; /* Register value */ ++ u8 temp_high[2]; /* Register value */ ++ u8 temp_low[2]; /* Register value */ ++ u16 alarms; /* Register encoding, combined */ ++ u8 vid; /* Register value combined */ ++ u8 vrm; ++}; ++ ++ ++static int adm1025_attach_adapter(struct i2c_adapter *adapter); ++static int adm1025_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int adm1025_detach_client(struct i2c_client *client); ++static void adm1025_update_client(struct i2c_client *client); ++static void adm1025_init_client(struct i2c_client *client); ++ ++ ++static void adm1025_in(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1025_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1025_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1025_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1025_vrm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static int adm1025_id = 0; ++ ++static struct i2c_driver adm1025_driver = { ++ .owner = THIS_MODULE, ++ .name = "ADM1025 sensor driver", ++ .id = I2C_DRIVERID_ADM1025, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = adm1025_attach_adapter, ++ .detach_client = adm1025_detach_client, ++}; ++ ++/* The /proc/sys entries */ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define ADM1025_SYSCTL_IN0 1000 /* Volts * 100 */ ++#define ADM1025_SYSCTL_IN1 1001 ++#define ADM1025_SYSCTL_IN2 1002 ++#define ADM1025_SYSCTL_IN3 1003 ++#define ADM1025_SYSCTL_IN4 1004 ++#define ADM1025_SYSCTL_IN5 1005 ++ ++#define ADM1025_SYSCTL_RTEMP 1250 /* Degrees Celcius * 10 */ ++#define ADM1025_SYSCTL_TEMP 1251 ++ ++#define ADM1025_SYSCTL_ALARMS 2001 /* bitvector */ ++#define ADM1025_SYSCTL_VID 2003 /* Volts * 1000 */ ++#define ADM1025_SYSCTL_VRM 2004 ++ ++#define ADM1025_ALARM_IN0 0x0001 ++#define ADM1025_ALARM_IN1 0x0002 ++#define ADM1025_ALARM_IN2 0x0004 ++#define ADM1025_ALARM_IN3 0x0008 ++#define ADM1025_ALARM_IN4 0x0100 ++#define ADM1025_ALARM_IN5 0x0200 ++#define ADM1025_ALARM_RTEMP 0x0020 ++#define ADM1025_ALARM_TEMP 0x0010 ++#define ADM1025_ALARM_RFAULT 0x4000 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected ADM1025. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table adm1025_dir_table_template[] = { ++ {ADM1025_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1025_in}, ++ {ADM1025_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1025_in}, ++ {ADM1025_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1025_in}, ++ {ADM1025_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1025_in}, ++ {ADM1025_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1025_in}, ++ {ADM1025_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1025_in}, ++ {ADM1025_SYSCTL_RTEMP, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1025_temp}, ++ {ADM1025_SYSCTL_TEMP, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1025_temp}, ++ {ADM1025_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1025_alarms}, ++ {ADM1025_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1025_vid}, ++ {ADM1025_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1025_vrm}, ++ {0} ++}; ++ ++static int adm1025_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, adm1025_detect); ++} ++ ++static int adm1025_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct adm1025_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("adm1025.o: adm1025_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access adm1025_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct adm1025_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &adm1025_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ ++ if (kind < 0) { ++ if ((i2c_smbus_read_byte_data(new_client, ++ ADM1025_REG_CONFIG) & 0x80) != 0x00 ++ || (i2c_smbus_read_byte_data(new_client, ++ ADM1025_REG_STATUS1) & 0xC0) != 0x00 ++ || (i2c_smbus_read_byte_data(new_client, ++ ADM1025_REG_STATUS2) & 0xBC) != 0x00) ++ goto ERROR1; ++ } ++ ++ /* Determine the chip type. */ ++ if (kind <= 0) { ++ u8 man_id, chip_id; ++ ++ man_id = i2c_smbus_read_byte_data(new_client, ++ ADM1025_REG_COMPANY_ID); ++ chip_id = i2c_smbus_read_byte_data(new_client, ++ ADM1025_REG_DIE_REV); ++ ++ if (man_id == 0x41) { /* Analog Devices */ ++ if ((chip_id & 0xF0) == 0x20) /* ADM1025 */ ++ kind = adm1025; ++ } else if (man_id == 0xA1) { /* Philips */ ++ if (address != 0x2E ++ && (chip_id & 0xF0) == 0x20) /* NE1619 */ ++ kind = ne1619; ++ } ++ } ++ ++ if (kind <= 0) { /* Identification failed */ ++ printk("adm1025.o: Unsupported chip.\n"); ++ goto ERROR1; ++ } ++ ++ if (kind == adm1025) { ++ type_name = "adm1025"; ++ client_name = "ADM1025 chip"; ++ } else if (kind == ne1619) { ++ type_name = "ne1619"; ++ client_name = "NE1619 chip"; ++ } else { ++#ifdef DEBUG ++ printk("adm1025.o: Internal error: unknown kind (%d)?!?", ++ kind); ++#endif ++ goto ERROR1; ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ data->type = kind; ++ ++ new_client->id = adm1025_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, ++ type_name, ++ adm1025_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the ADM1025 chip */ ++ adm1025_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int adm1025_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct adm1025_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("adm1025.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++/* Called when we have found a new ADM1025. */ ++static void adm1025_init_client(struct i2c_client *client) ++{ ++ struct adm1025_data *data = client->data; ++ u8 reg; ++ int i; ++ ++ data->vrm = 82; ++ ++ /* Set high limits ++ Usually we avoid setting limits on driver init, but it happens ++ that the ADM1025 comes with stupid default limits (all registers ++ set to 0). In case the chip has not gone through any limit ++ setting yet, we better set the high limits to the max so that ++ no alarm triggers. */ ++ for (i=0; i<6; i++) { ++ reg = i2c_smbus_read_byte_data(client, ++ ADM1025_REG_IN_MAX(i)); ++ if (reg == 0) ++ i2c_smbus_write_byte_data(client, ++ ADM1025_REG_IN_MAX(i), ++ 0xFF); ++ } ++ for (i=0; i<2; i++) { ++ reg = i2c_smbus_read_byte_data(client, ++ ADM1025_REG_TEMP_HIGH(i)); ++ if (reg == 0) ++ i2c_smbus_write_byte_data(client, ++ ADM1025_REG_TEMP_HIGH(i), ++ 0x7F); ++ } ++ ++ /* Start monitoring */ ++ reg = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG); ++ i2c_smbus_write_byte_data(client, ADM1025_REG_CONFIG, (reg|0x01)&0x7F); ++} ++ ++static void adm1025_update_client(struct i2c_client *client) ++{ ++ struct adm1025_data *data = client->data; ++ u8 nr; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > 2 * HZ) ++ || (jiffies < data->last_updated) || !data->valid) { ++#ifdef DEBUG ++ printk("Starting adm1025 update\n"); ++#endif ++ ++ /* Voltages */ ++ for (nr = 0; nr < 6; nr++) { ++ data->in[nr] = i2c_smbus_read_byte_data(client, ADM1025_REG_IN(nr)); ++ data->in_min[nr] = i2c_smbus_read_byte_data(client, ADM1025_REG_IN_MIN(nr)); ++ data->in_max[nr] = i2c_smbus_read_byte_data(client, ADM1025_REG_IN_MAX(nr)); ++ } ++ ++ /* Temperatures */ ++ for (nr = 0; nr < 2; nr++) { ++ data->temp[nr] = i2c_smbus_read_byte_data(client, ADM1025_REG_TEMP(nr)); ++ data->temp_high[nr] = i2c_smbus_read_byte_data(client, ADM1025_REG_TEMP_HIGH(nr)); ++ data->temp_low[nr] = i2c_smbus_read_byte_data(client, ADM1025_REG_TEMP_LOW(nr)); ++ } ++ ++ /* VID */ ++ data->vid = (i2c_smbus_read_byte_data(client, ADM1025_REG_VID) & 0x0f) ++ + ((i2c_smbus_read_byte_data(client, ADM1025_REG_VID4) & 0x01) << 4); ++ ++ /* Alarms */ ++ data->alarms = (i2c_smbus_read_byte_data(client, ADM1025_REG_STATUS1) & 0x3f) ++ + ((i2c_smbus_read_byte_data(client, ADM1025_REG_STATUS2) & 0x43) << 8); ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the data ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++void adm1025_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ int scales[6] = { 250, 225, 330, 500, 1200, 330 }; ++ ++ struct adm1025_data *data = client->data; ++ int nr = ctl_name - ADM1025_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1025_update_client(client); ++ results[0] = (IN_FROM_REG(data->in_min[nr]) * scales[nr] + 96) / 192; ++ results[1] = (IN_FROM_REG(data->in_max[nr]) * scales[nr] + 96) / 192; ++ results[2] = (IN_FROM_REG(data->in[nr]) * scales[nr] + 96) / 192; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = IN_TO_REG((results[0] * 192 + scales[nr] / 2) ++ / scales[nr]); ++ i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = IN_TO_REG((results[1] * 192 + scales[nr] / 2) ++ / scales[nr]); ++ i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++} ++ ++void adm1025_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1025_data *data = client->data; ++ int nr = ctl_name - ADM1025_SYSCTL_RTEMP; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1025_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_high[nr]); ++ results[1] = TEMP_FROM_REG(data->temp_low[nr]); ++ results[2] = TEMP_FROM_REG(data->temp[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_high[nr] = TEMP_TO_REG(results[0]); ++ i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_HIGH(nr), ++ data->temp_high[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_low[nr] = TEMP_TO_REG(results[1]); ++ i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_LOW(nr), ++ data->temp_low[nr]); ++ } ++ } ++} ++ ++void adm1025_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1025_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1025_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++void adm1025_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1025_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1025_update_client(client); ++ results[0] = vid_from_reg(data->vid, data->vrm); ++ *nrels_mag = 1; ++ } ++} ++ ++void adm1025_vrm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1025_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->vrm; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) ++ data->vrm = results[0]; ++ } ++} ++ ++static int __init sm_adm1025_init(void) ++{ ++ printk("adm1025.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&adm1025_driver); ++} ++ ++static void __exit sm_adm1025_exit(void) ++{ ++ i2c_del_driver(&adm1025_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Chen-Yuan Wu " ++ " and Jean Delvare "); ++MODULE_DESCRIPTION("ADM1025 driver"); ++ ++module_init(sm_adm1025_init); ++module_exit(sm_adm1025_exit); +--- linux-old/drivers/sensors/adm1026.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/adm1026.c Mon Dec 13 20:18:44 2004 +@@ -0,0 +1,1745 @@ ++/* ++ adm1026.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 2002, 2003 Philip Pokorny ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ CHANGELOG ++ ++ 2003-03-13 Initial development ++ 2003-05-07 First Release. Includes GPIO fixup and full ++ functionality. ++ 2003-05-18 Minor fixups and tweaks. ++ Print GPIO config after fixup. ++ Adjust fan MIN if DIV changes. ++ 2003-05-21 Fix printing of FAN/GPIO config ++ Fix silly bug in fan_div logic ++ Fix fan_min handling so that 0xff is 0 is 0xff ++ 2003-05-25 Fix more silly typos... ++ 2003-06-11 Change FAN_xx_REG macros to use different scaling ++ Most (all?) drivers assume two pulses per rev fans ++ and the old scaling was producing double the RPM's ++ Thanks to Jerome Hsiao @ Arima for pointing this out. ++ 2004-01-27 Remove use of temporary ID. ++ Define addresses as a range. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++ ++#ifndef I2C_DRIVERID_ADM1026 ++#define I2C_DRIVERID_ADM1026 1048 ++#endif ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x2c, 0x2e, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(adm1026); ++ ++static int gpio_input[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1 }; ++static int gpio_output[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1 }; ++static int gpio_inverted[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1 }; ++static int gpio_normal[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, ++ -1, -1, -1, -1, -1, -1, -1, -1 }; ++static int gpio_fan[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; ++MODULE_PARM(gpio_input,"1-17i"); ++MODULE_PARM_DESC(gpio_input,"List of GPIO pins (0-16) to program as inputs"); ++MODULE_PARM(gpio_output,"1-17i"); ++MODULE_PARM_DESC(gpio_output,"List of GPIO pins (0-16) to program as outputs"); ++MODULE_PARM(gpio_inverted,"1-17i"); ++MODULE_PARM_DESC(gpio_inverted,"List of GPIO pins (0-16) to program as inverted"); ++MODULE_PARM(gpio_normal,"1-17i"); ++MODULE_PARM_DESC(gpio_normal,"List of GPIO pins (0-16) to program as normal/non-inverted"); ++MODULE_PARM(gpio_fan,"1-8i"); ++MODULE_PARM_DESC(gpio_fan,"List of GPIO pins (0-7) to program as fan tachs"); ++ ++/* Many ADM1026 constants specified below */ ++ ++/* The ADM1026 registers */ ++#define ADM1026_REG_CONFIG1 (0x00) ++#define CFG1_MONITOR (0x01) ++#define CFG1_INT_ENABLE (0x02) ++#define CFG1_INT_CLEAR (0x04) ++#define CFG1_AIN8_9 (0x08) ++#define CFG1_THERM_HOT (0x10) ++#define CFG1_DAC_AFC (0x20) ++#define CFG1_PWM_AFC (0x40) ++#define CFG1_RESET (0x80) ++#define ADM1026_REG_CONFIG2 (0x01) ++/* CONFIG2 controls FAN0/GPIO0 through FAN7/GPIO7 */ ++#define ADM1026_REG_CONFIG3 (0x07) ++#define CFG3_GPIO16_ENABLE (0x01) ++#define CFG3_CI_CLEAR (0x02) ++#define CFG3_VREF_250 (0x04) ++#define CFG3_GPIO16_DIR (0x40) ++#define CFG3_GPIO16_POL (0x80) ++#define ADM1026_REG_E2CONFIG (0x13) ++#define E2CFG_READ (0x01) ++#define E2CFG_WRITE (0x02) ++#define E2CFG_ERASE (0x04) ++#define E2CFG_ROM (0x08) ++#define E2CFG_CLK_EXT (0x80) ++ ++/* There are 10 general analog inputs and 7 dedicated inputs ++ * They are: ++ * 0 - 9 = AIN0 - AIN9 ++ * 10 = Vbat ++ * 11 = 3.3V Standby ++ * 12 = 3.3V Main ++ * 13 = +5V ++ * 14 = Vccp (CPU core voltage) ++ * 15 = +12V ++ * 16 = -12V ++ */ ++static u16 REG_IN[] = { ++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, ++ 0x36, 0x37, 0x27, 0x29, 0x26, 0x2a, ++ 0x2b, 0x2c, 0x2d, 0x2e, 0x2f ++ }; ++static u16 REG_IN_MIN[] = { ++ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, ++ 0x5e, 0x5f, 0x6d, 0x49, 0x6b, 0x4a, ++ 0x4b, 0x4c, 0x4d, 0x4e, 0x4f ++ }; ++static u16 REG_IN_MAX[] = { ++ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, ++ 0x56, 0x57, 0x6c, 0x41, 0x6a, 0x42, ++ 0x43, 0x44, 0x45, 0x46, 0x47 ++ }; ++#define ADM1026_REG_IN(nr) (REG_IN[(nr)]) ++#define ADM1026_REG_IN_MIN(nr) (REG_IN_MIN[(nr)]) ++#define ADM1026_REG_IN_MAX(nr) (REG_IN_MAX[(nr)]) ++ ++/* Temperatures are: ++ * 0 - Internal ++ * 1 - External 1 ++ * 2 - External 2 ++ */ ++static u16 REG_TEMP[] = { 0x1f, 0x28, 0x29 }; ++static u16 REG_TEMP_MIN[] = { 0x69, 0x48, 0x49 }; ++static u16 REG_TEMP_MAX[] = { 0x68, 0x40, 0x41 }; ++static u16 REG_TEMP_TMIN[] = { 0x10, 0x11, 0x12 }; ++static u16 REG_TEMP_THERM[] = { 0x0d, 0x0e, 0x0f }; ++static u16 REG_TEMP_OFFSET[] = { 0x1e, 0x6e, 0x6f }; ++#define ADM1026_REG_TEMP(nr) (REG_TEMP[(nr)]) ++#define ADM1026_REG_TEMP_MIN(nr) (REG_TEMP_MIN[(nr)]) ++#define ADM1026_REG_TEMP_MAX(nr) (REG_TEMP_MAX[(nr)]) ++#define ADM1026_REG_TEMP_TMIN(nr) (REG_TEMP_TMIN[(nr)]) ++#define ADM1026_REG_TEMP_THERM(nr) (REG_TEMP_THERM[(nr)]) ++#define ADM1026_REG_TEMP_OFFSET(nr) (REG_TEMP_OFFSET[(nr)]) ++ ++#define ADM1026_REG_FAN(nr) (0x38 + (nr)) ++#define ADM1026_REG_FAN_MIN(nr) (0x60 + (nr)) ++#define ADM1026_REG_FAN_DIV_0_3 (0x02) ++#define ADM1026_REG_FAN_DIV_4_7 (0x03) ++ ++#define ADM1026_REG_DAC (0x04) ++#define ADM1026_REG_PWM (0x05) ++ ++#define ADM1026_REG_GPIO_CFG_0_3 (0x08) ++#define ADM1026_REG_GPIO_CFG_4_7 (0x09) ++#define ADM1026_REG_GPIO_CFG_8_11 (0x0a) ++#define ADM1026_REG_GPIO_CFG_12_15 (0x0b) ++/* CFG_16 in REG_CFG3 */ ++#define ADM1026_REG_GPIO_STATUS_0_7 (0x24) ++#define ADM1026_REG_GPIO_STATUS_8_15 (0x25) ++/* STATUS_16 in REG_STATUS4 */ ++#define ADM1026_REG_GPIO_MASK_0_7 (0x1c) ++#define ADM1026_REG_GPIO_MASK_8_15 (0x1d) ++/* MASK_16 in REG_MASK4 */ ++ ++#define ADM1026_REG_COMPANY 0x16 ++#define ADM1026_REG_VERSTEP 0x17 ++/* These are the recognized values for the above regs */ ++#define ADM1026_COMPANY_ANALOG_DEV 0x41 ++#define ADM1026_VERSTEP_GENERIC 0x40 ++#define ADM1026_VERSTEP_ADM1026 0x44 ++ ++#define ADM1026_REG_MASK1 0x18 ++#define ADM1026_REG_MASK2 0x19 ++#define ADM1026_REG_MASK3 0x1a ++#define ADM1026_REG_MASK4 0x1b ++ ++#define ADM1026_REG_STATUS1 0x20 ++#define ADM1026_REG_STATUS2 0x21 ++#define ADM1026_REG_STATUS3 0x22 ++#define ADM1026_REG_STATUS4 0x23 ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ */ ++ ++/* IN are scaled acording to built-in resistors. These are the ++ * voltages corresponding to 3/4 of full scale (192 or 0xc0) ++ * NOTE: The -12V input needs an additional factor to account ++ * for the Vref pullup resistor. ++ * NEG12_OFFSET = SCALE * Vref / V-192 - Vref ++ * = 13875 * 2.50 / 1.875 - 2500 ++ * = 16000 ++ */ ++#if 1 ++/* The values in this table are based on Table II, page 15 of the ++ * datasheet. ++ */ ++static int adm1026_scaling[] = { /* .001 Volts */ ++ 2250, 2250, 2250, 2250, 2250, 2250, ++ 1875, 1875, 1875, 1875, 3000, 3330, ++ 3330, 4995, 2250, 12000, 13875 ++ }; ++#define NEG12_OFFSET 16000 ++#else ++/* The values in this table are based on the resistors in ++ * Figure 5 on page 16. But the 3.3V inputs are not in ++ * the figure and the values for the 5V input are wrong. ++ * For 5V, I'm guessing that R2 at 55.2k is right, but ++ * the total resistance should be 1400 or 1449 like the ++ * other inputs. Using 1449, gives 4.922V at 192. ++ */ ++static int adm1026_scaling[] = { /* .001 Volts */ ++ 2249, 2249, 2249, 2249, 2249, 2249, ++ 1875, 1875, 1875, 1875, 3329, 3329, ++ 3329, 4922, 2249, 11969, 13889 ++ }; ++#define NEG12_OFFSET 16019 ++#endif ++ ++#define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from)) ++#define INS_TO_REG(n,val) (SENSORS_LIMIT(SCALE(val,adm1026_scaling[n],192),0,255)) ++#if 0 /* If we have extended A/D bits */ ++#define INSEXT_FROM_REG(n,val,ext) (SCALE((val)*4 + (ext),192*4,adm1026_scaling[n])) ++#define INS_FROM_REG(n,val) (INSEXT_FROM_REG(n,val,0)) ++#else ++#define INS_FROM_REG(n,val) (SCALE(val,192,adm1026_scaling[n])) ++#endif ++ ++/* FAN speed is measured using 22.5kHz clock and counts for 2 pulses ++ * and we assume a 2 pulse-per-rev fan tach signal ++ * 22500 kHz * 60 (sec/min) * 2 (pulse) / 2 (pulse/rev) == 1350000 ++ */ ++#define FAN_TO_REG(val,div) ((val)<=0 ? 0xff : SENSORS_LIMIT(1350000/((val)*(div)),1,254)) ++#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==0xff ? 0 : 1350000/((val)*(div))) ++#define DIV_FROM_REG(val) (1<<(val)) ++#define DIV_TO_REG(val) ((val)>=8 ? 3 : (val)>=4 ? 2 : (val)>=2 ? 1 : 0) ++ ++/* Temperature is reported in 1 degC increments */ ++#define TEMP_TO_REG(val) (SENSORS_LIMIT(val,-127,127)) ++#define TEMP_FROM_REG(val) (val) ++#define OFFSET_TO_REG(val) (SENSORS_LIMIT(val,-127,127)) ++#define OFFSET_FROM_REG(val) (val) ++ ++#define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255)) ++#define PWM_FROM_REG(val) (val) ++ ++/* Analog output is a voltage, but it's used like a PWM ++ * Seems like this should be scaled, but to be consistent ++ * with other drivers, we do it this way. ++ */ ++#define DAC_TO_REG(val) (SENSORS_LIMIT(val,0,255)) ++#define DAC_FROM_REG(val) (val) ++ ++/* sensors_vid.h defines vid_from_reg() */ ++#define VID_FROM_REG(val,vrm) (vid_from_reg(val,vrm)) ++ ++#define ALARMS_FROM_REG(val) (val) ++ ++/* Unlike some other drivers we DO NOT set initial limits. Use ++ * the config file to set limits. ++ */ ++ ++/* Typically used with systems using a v9.1 VRM spec ? */ ++#define ADM1026_INIT_VRM 91 ++#define ADM1026_INIT_VID -1 ++ ++/* Chip sampling rates ++ * ++ * Some sensors are not updated more frequently than once per second ++ * so it doesn't make sense to read them more often than that. ++ * We cache the results and return the saved data if the driver ++ * is called again before a second has elapsed. ++ * ++ * Also, there is significant configuration data for this chip ++ * So, we keep the config data up to date in the cache ++ * when it is written and only sample it once every 5 *minutes* ++ */ ++#define ADM1026_DATA_INTERVAL (1 * HZ) ++#define ADM1026_CONFIG_INTERVAL (5 * 60 * HZ) ++ ++/* We allow for multiple chips in a single system. ++ * ++ * For each registered ADM1026, we need to keep state information ++ * at client->data. The adm1026_data structure is dynamically ++ * allocated, when a new client structure is allocated. */ ++ ++struct adm1026_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ int valid; /* !=0 if following fields are valid */ ++ unsigned long last_reading; /* In jiffies */ ++ unsigned long last_config; /* In jiffies */ ++ ++ u8 in[17]; /* Register value */ ++ u8 in_max[17]; /* Register value */ ++ u8 in_min[17]; /* Register value */ ++ s8 temp[3]; /* Register value */ ++ s8 temp_min[3]; /* Register value */ ++ s8 temp_max[3]; /* Register value */ ++ s8 temp_tmin[3]; /* Register value */ ++ s8 temp_therm[3]; /* Register value */ ++ s8 temp_offset[3]; /* Register value */ ++ u8 fan[8]; /* Register value */ ++ u8 fan_min[8]; /* Register value */ ++ u8 fan_div[8]; /* Decoded value */ ++ u8 pwm; /* Register value */ ++ u8 analog_out; /* Register value */ ++ int vid; /* Decoded value */ ++ u8 vrm; /* VRM version */ ++ long alarms; /* Register encoding, combined */ ++ long alarm_mask; /* Register encoding, combined */ ++ long gpio; /* Register encoding, combined */ ++ long gpio_mask; /* Register encoding, combined */ ++ u8 gpio_config[17]; /* Decoded value */ ++ u8 config1; /* Register value */ ++ u8 config2; /* Register value */ ++ u8 config3; /* Register value */ ++}; ++ ++static int adm1026_attach_adapter(struct i2c_adapter *adapter); ++static int adm1026_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int adm1026_detach_client(struct i2c_client *client); ++ ++static int adm1026_read_value(struct i2c_client *client, u8 register); ++static int adm1026_write_value(struct i2c_client *client, u8 register, int value); ++static void adm1026_print_gpio(struct i2c_client *client); ++static void adm1026_fixup_gpio(struct i2c_client *client); ++static void adm1026_update_client(struct i2c_client *client); ++static void adm1026_init_client(struct i2c_client *client); ++ ++ ++static void adm1026_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++static void adm1026_in16(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++static void adm1026_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_fixup_fan_min(struct i2c_client *client, ++ int fan, int old_div); ++static void adm1026_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_temp_offset(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_temp_tmin(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_temp_therm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_vrm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_alarm_mask(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_gpio(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_gpio_mask(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_pwm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_analog_out(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1026_afc(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static struct i2c_driver adm1026_driver = { ++ .owner = THIS_MODULE, ++ .name = "ADM1026 compatible sensor driver", ++ .id = I2C_DRIVERID_ADM1026, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = &adm1026_attach_adapter, ++ .detach_client = &adm1026_detach_client, ++}; ++ ++/* Unique ID assigned to each ADM1026 detected */ ++static int adm1026_id = 0; ++ ++/* -- SENSORS SYSCTL START -- */ ++#define ADM1026_SYSCTL_FAN0 1000 ++#define ADM1026_SYSCTL_FAN1 1001 ++#define ADM1026_SYSCTL_FAN2 1002 ++#define ADM1026_SYSCTL_FAN3 1003 ++#define ADM1026_SYSCTL_FAN4 1004 ++#define ADM1026_SYSCTL_FAN5 1005 ++#define ADM1026_SYSCTL_FAN6 1006 ++#define ADM1026_SYSCTL_FAN7 1007 ++#define ADM1026_SYSCTL_FAN_DIV 1008 ++#define ADM1026_SYSCTL_GPIO 1009 ++#define ADM1026_SYSCTL_GPIO_MASK 1010 ++#define ADM1026_SYSCTL_ALARMS 1011 ++#define ADM1026_SYSCTL_ALARM_MASK 1012 ++#define ADM1026_SYSCTL_IN0 1013 ++#define ADM1026_SYSCTL_IN1 1014 ++#define ADM1026_SYSCTL_IN2 1015 ++#define ADM1026_SYSCTL_IN3 1016 ++#define ADM1026_SYSCTL_IN4 1017 ++#define ADM1026_SYSCTL_IN5 1018 ++#define ADM1026_SYSCTL_IN6 1019 ++#define ADM1026_SYSCTL_IN7 1020 ++#define ADM1026_SYSCTL_IN8 1021 ++#define ADM1026_SYSCTL_IN9 1022 ++#define ADM1026_SYSCTL_IN10 1023 ++#define ADM1026_SYSCTL_IN11 1024 ++#define ADM1026_SYSCTL_IN12 1025 ++#define ADM1026_SYSCTL_IN13 1026 ++#define ADM1026_SYSCTL_IN14 1027 ++#define ADM1026_SYSCTL_IN15 1028 ++#define ADM1026_SYSCTL_IN16 1029 ++#define ADM1026_SYSCTL_PWM 1030 ++#define ADM1026_SYSCTL_ANALOG_OUT 1031 ++#define ADM1026_SYSCTL_AFC 1032 ++#define ADM1026_SYSCTL_TEMP1 1033 ++#define ADM1026_SYSCTL_TEMP2 1034 ++#define ADM1026_SYSCTL_TEMP3 1035 ++#define ADM1026_SYSCTL_TEMP_OFFSET1 1036 ++#define ADM1026_SYSCTL_TEMP_OFFSET2 1037 ++#define ADM1026_SYSCTL_TEMP_OFFSET3 1038 ++#define ADM1026_SYSCTL_TEMP_THERM1 1039 ++#define ADM1026_SYSCTL_TEMP_THERM2 1040 ++#define ADM1026_SYSCTL_TEMP_THERM3 1041 ++#define ADM1026_SYSCTL_TEMP_TMIN1 1042 ++#define ADM1026_SYSCTL_TEMP_TMIN2 1043 ++#define ADM1026_SYSCTL_TEMP_TMIN3 1044 ++#define ADM1026_SYSCTL_VID 1045 ++#define ADM1026_SYSCTL_VRM 1046 ++ ++#define ADM1026_ALARM_TEMP2 (1L << 0) ++#define ADM1026_ALARM_TEMP3 (1L << 1) ++#define ADM1026_ALARM_IN9 (1L << 1) ++#define ADM1026_ALARM_IN11 (1L << 2) ++#define ADM1026_ALARM_IN12 (1L << 3) ++#define ADM1026_ALARM_IN13 (1L << 4) ++#define ADM1026_ALARM_IN14 (1L << 5) ++#define ADM1026_ALARM_IN15 (1L << 6) ++#define ADM1026_ALARM_IN16 (1L << 7) ++#define ADM1026_ALARM_IN0 (1L << 8) ++#define ADM1026_ALARM_IN1 (1L << 9) ++#define ADM1026_ALARM_IN2 (1L << 10) ++#define ADM1026_ALARM_IN3 (1L << 11) ++#define ADM1026_ALARM_IN4 (1L << 12) ++#define ADM1026_ALARM_IN5 (1L << 13) ++#define ADM1026_ALARM_IN6 (1L << 14) ++#define ADM1026_ALARM_IN7 (1L << 15) ++#define ADM1026_ALARM_FAN0 (1L << 16) ++#define ADM1026_ALARM_FAN1 (1L << 17) ++#define ADM1026_ALARM_FAN2 (1L << 18) ++#define ADM1026_ALARM_FAN3 (1L << 19) ++#define ADM1026_ALARM_FAN4 (1L << 20) ++#define ADM1026_ALARM_FAN5 (1L << 21) ++#define ADM1026_ALARM_FAN6 (1L << 22) ++#define ADM1026_ALARM_FAN7 (1L << 23) ++#define ADM1026_ALARM_TEMP1 (1L << 24) ++#define ADM1026_ALARM_IN10 (1L << 25) ++#define ADM1026_ALARM_IN8 (1L << 26) ++#define ADM1026_ALARM_THERM (1L << 27) ++#define ADM1026_ALARM_AFC_FAN (1L << 28) ++#define ADM1026_ALARM_UNUSED (1L << 29) ++#define ADM1026_ALARM_CI (1L << 30) ++/* -- SENSORS SYSCTL END -- */ ++ ++/* The /proc/sys entries */ ++/* These files are created for each detected ADM1026. This is just a template; ++ * The actual list is built from this and additional per-chip ++ * custom lists below. Note the XXX_LEN macros. These must be ++ * compile time constants because they will be used to allocate ++ * space for the final template passed to i2c_register_entry. ++ * We depend on the ability of GCC to evaluate expressions at ++ * compile time to turn these expressions into compile time ++ * constants, but this can generate a warning. ++ */ ++static ctl_table adm1026_common[] = { ++ {ADM1026_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN9, "in9", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN10, "in10", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN11, "in11", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN12, "in12", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN13, "in13", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN14, "in14", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN15, "in15", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in}, ++ {ADM1026_SYSCTL_IN16, "in16", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_in16}, ++ ++ {ADM1026_SYSCTL_FAN0, "fan0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_fan}, ++ {ADM1026_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_fan}, ++ {ADM1026_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_fan}, ++ {ADM1026_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_fan}, ++ {ADM1026_SYSCTL_FAN4, "fan4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_fan}, ++ {ADM1026_SYSCTL_FAN5, "fan5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_fan}, ++ {ADM1026_SYSCTL_FAN6, "fan6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_fan}, ++ {ADM1026_SYSCTL_FAN7, "fan7", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_fan}, ++ {ADM1026_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1026_fan_div}, ++ ++ {ADM1026_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_temp}, ++ {ADM1026_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_temp}, ++ {ADM1026_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_temp}, ++ {ADM1026_SYSCTL_TEMP_OFFSET1, "temp1_offset", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1026_temp_offset}, ++ {ADM1026_SYSCTL_TEMP_OFFSET2, "temp2_offset", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1026_temp_offset}, ++ {ADM1026_SYSCTL_TEMP_OFFSET3, "temp3_offset", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1026_temp_offset}, ++ {ADM1026_SYSCTL_TEMP_TMIN1, "temp1_tmin", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1026_temp_tmin}, ++ {ADM1026_SYSCTL_TEMP_TMIN2, "temp2_tmin", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1026_temp_tmin}, ++ {ADM1026_SYSCTL_TEMP_TMIN3, "temp3_tmin", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1026_temp_tmin}, ++ {ADM1026_SYSCTL_TEMP_THERM1, "temp1_therm", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1026_temp_therm}, ++ {ADM1026_SYSCTL_TEMP_THERM2, "temp2_therm", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1026_temp_therm}, ++ {ADM1026_SYSCTL_TEMP_THERM3, "temp3_therm", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1026_temp_therm}, ++ ++ {ADM1026_SYSCTL_VID, "vid", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_vid}, ++ {ADM1026_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_vrm}, ++ ++ {ADM1026_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_alarms}, ++ {ADM1026_SYSCTL_ALARM_MASK, "alarm_mask", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1026_alarm_mask}, ++ ++ {ADM1026_SYSCTL_GPIO, "gpio", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_gpio}, ++ {ADM1026_SYSCTL_GPIO_MASK, "gpio_mask", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1026_gpio_mask}, ++ ++ {ADM1026_SYSCTL_PWM, "pwm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_pwm}, ++ {ADM1026_SYSCTL_ANALOG_OUT, "analog_out", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1026_analog_out}, ++ {ADM1026_SYSCTL_AFC, "afc", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm1026_afc}, ++ ++ {0} ++}; ++#define CTLTBL_COMMON (sizeof(adm1026_common)/sizeof(adm1026_common[0])) ++ ++#define MAX2(a,b) ((a)>(b)?(a):(b)) ++#define MAX3(a,b,c) ((a)>(b)?MAX2((a),(c)):MAX2((b),(c))) ++#define MAX4(a,b,c,d) ((a)>(b)?MAX3((a),(c),(d)):MAX3((b),(c),(d))) ++ ++#define CTLTBL_MAX (CTLTBL_COMMON) ++ ++/* This function is called when: ++ * the module is loaded ++ * a new adapter is loaded ++ */ ++int adm1026_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, adm1026_detect); ++} ++ ++/* This function is called by i2c_detect */ ++int adm1026_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ int company, verstep ; ++ struct i2c_client *new_client; ++ struct adm1026_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ struct ctl_table template[CTLTBL_MAX] ; ++ struct ctl_table * template_next = template ; ++ ++ if (i2c_is_isa_adapter(adapter)) { ++ /* This chip has no ISA interface */ ++ goto ERROR0 ; ++ } ++ ++ if (!i2c_check_functionality(adapter, ++ I2C_FUNC_SMBUS_BYTE_DATA)) { ++ /* We need to be able to do byte I/O */ ++ goto ERROR0 ; ++ } ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access adm1026_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct adm1026_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &adm1026_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ ++ company = adm1026_read_value(new_client, ADM1026_REG_COMPANY); ++ verstep = adm1026_read_value(new_client, ADM1026_REG_VERSTEP); ++ ++#ifdef DEBUG ++ printk("adm1026: Detecting device at %d,0x%02x with" ++ " COMPANY: 0x%02x and VERSTEP: 0x%02x\n", ++ i2c_adapter_id(new_client->adapter), new_client->addr, ++ company, verstep ++ ); ++#endif ++ ++ /* If auto-detecting, Determine the chip type. */ ++ if (kind <= 0) { ++#ifdef DEBUG ++ printk("adm1026: Autodetecting device at %d,0x%02x ...\n", ++ i2c_adapter_id(adapter), address ); ++#endif ++ if( company == ADM1026_COMPANY_ANALOG_DEV ++ && verstep == ADM1026_VERSTEP_ADM1026 ) { ++ kind = adm1026 ; ++ } else if( company == ADM1026_COMPANY_ANALOG_DEV ++ && (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC ) { ++ printk("adm1026: Unrecgonized stepping 0x%02x" ++ " Defaulting to ADM1026.\n", verstep ); ++ kind = adm1026 ; ++ } else if( (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC ) { ++ printk("adm1026: Found version/stepping 0x%02x" ++ " Assuming generic ADM1026.\n", verstep ); ++ kind = any_chip ; ++ } else { ++#ifdef DEBUG ++ printk("adm1026: Autodetection failed\n"); ++#endif ++ /* Not an ADM1026 ... */ ++ if( kind == 0 ) { /* User used force=x,y */ ++ printk("adm1026: Generic ADM1026 Version 6 not" ++ " found at %d,0x%02x. Try force_adm1026.\n", ++ i2c_adapter_id(adapter), address ); ++ } ++ err = 0 ; ++ goto ERROR1; ++ } ++ } ++ ++ /* Fill in the chip specific driver values */ ++ switch (kind) { ++ case any_chip : ++ type_name = "adm1026"; ++ strcpy(new_client->name, "Generic ADM1026"); ++ template_next = template ; /* None used */ ++ break ; ++ case adm1026 : ++ type_name = "adm1026"; ++ strcpy(new_client->name, "Analog Devices ADM1026"); ++ template_next = template ; ++ break ; ++#if 0 ++ /* Example of another adm1026 "compatible" device */ ++ case adx1000 : ++ type_name = "adx1000"; ++ strcpy(new_client->name, "Compatible ADX1000"); ++ memcpy( template, adx_specific, sizeof(adx_specific) ); ++ template_next = template + CTLTBL_ADX1000 ; ++ break ; ++#endif ++ default : ++ printk("adm1026: Internal error, invalid kind (%d)!", kind); ++ err = -EFAULT ; ++ goto ERROR1; ++ } ++ ++ /* Fill in the remaining client fields */ ++ new_client->id = adm1026_id++; ++ printk("adm1026(%d): Assigning ID %d to %s at %d,0x%02x\n", ++ new_client->id, new_client->id, new_client->name, ++ i2c_adapter_id(new_client->adapter), ++ new_client->addr ++ ); ++ ++ /* Housekeeping values */ ++ data->type = kind; ++ data->valid = 0; ++ ++ /* Set the VRM version */ ++ data->vrm = ADM1026_INIT_VRM ; ++ data->vid = ADM1026_INIT_VID ; ++ ++ init_MUTEX(&data->update_lock); ++ ++ /* Initialize the ADM1026 chip */ ++ adm1026_init_client(new_client); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR1; ++ ++ /* Finish out the template */ ++ memcpy(template_next, adm1026_common, sizeof(adm1026_common)); ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, ++ type_name, ++ template)) < 0) { ++ err = i; ++ goto ERROR2; ++ } ++ data->sysctl_id = i; ++ ++ return 0; ++ ++ /* Error out and cleanup code */ ++ ERROR2: ++ i2c_detach_client(new_client); ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++int adm1026_detach_client(struct i2c_client *client) ++{ ++ int err; ++ int id ; ++ ++ id = client->id; ++ i2c_deregister_entry(((struct adm1026_data *)(client->data))->sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk("adm1026(%d): Client deregistration failed," ++ " client not detached.\n", id ); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++int adm1026_read_value(struct i2c_client *client, u8 reg) ++{ ++ int res; ++ ++ if( reg < 0x80 ) { ++ /* "RAM" locations */ ++ res = i2c_smbus_read_byte_data(client, reg) & 0xff ; ++ } else { ++ /* EEPROM, do nothing */ ++ res = 0 ; ++ } ++ ++ return res ; ++} ++ ++int adm1026_write_value(struct i2c_client *client, u8 reg, int value) ++{ ++ int res ; ++ ++ if( reg < 0x80 ) { ++ /* "RAM" locations */ ++ res = i2c_smbus_write_byte_data(client, reg, value); ++ } else { ++ /* EEPROM, do nothing */ ++ res = 0 ; ++ } ++ ++ return res ; ++} ++ ++/* Called when we have found a new ADM1026. */ ++void adm1026_init_client(struct i2c_client *client) ++{ ++ int value ; ++ int i; ++ struct adm1026_data *data = client->data; ++ ++#ifdef DEBUG ++ printk("adm1026(%d): Initializing device\n", client->id); ++#endif ++ ++ /* Read chip config */ ++ data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1); ++ data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2); ++ data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3); ++ ++ /* Inform user of chip config */ ++#ifdef DEBUG ++ printk("adm1026(%d): ADM1026_REG_CONFIG1 is: 0x%02x\n", ++ client->id, data->config1 ); ++#endif ++ if( (data->config1 & CFG1_MONITOR) == 0 ) { ++ printk("adm1026(%d): Monitoring not currently enabled.\n", ++ client->id ); ++ } ++ if( data->config1 & CFG1_INT_ENABLE ) { ++ printk("adm1026(%d): SMBALERT interrupts are enabled.\n", ++ client->id ); ++ } ++ if( data->config1 & CFG1_AIN8_9 ) { ++ printk("adm1026(%d): in8 and in9 enabled. temp3 disabled.\n", ++ client->id ); ++ } else { ++ printk("adm1026(%d): temp3 enabled. in8 and in9 disabled.\n", ++ client->id ); ++ } ++ if( data->config1 & CFG1_THERM_HOT ) { ++ printk("adm1026(%d): Automatic THERM, PWM, and temp limits enabled.\n", ++ client->id ); ++ } ++ ++ value = data->config3 ; ++ if( data->config3 & CFG3_GPIO16_ENABLE ) { ++ printk("adm1026(%d): GPIO16 enabled. THERM pin disabled.\n", ++ client->id ); ++ } else { ++ printk("adm1026(%d): THERM pin enabled. GPIO16 disabled.\n", ++ client->id ); ++ } ++ if( data->config3 & CFG3_VREF_250 ) { ++ printk("adm1026(%d): Vref is 2.50 Volts.\n", client->id ); ++ } else { ++ printk("adm1026(%d): Vref is 1.82 Volts.\n", client->id ); ++ } ++ ++ /* Read and pick apart the existing GPIO configuration */ ++ value = 0 ; ++ for( i = 0 ; i <= 15 ; ++i ) { ++ if( (i & 0x03) == 0 ) { ++ value = adm1026_read_value(client, ++ ADM1026_REG_GPIO_CFG_0_3 + i/4 ); ++ } ++ data->gpio_config[i] = value & 0x03 ; ++ value >>= 2 ; ++ } ++ data->gpio_config[16] = (data->config3 >> 6) & 0x03 ; ++ ++ /* ... and then print it */ ++ adm1026_print_gpio(client); ++ ++ /* If the user asks us to reprogram the GPIO config, then ++ * do it now. But only if this is the first ADM1026. ++ */ ++ if( client->id == 0 ++ && (gpio_input[0] != -1 || gpio_output[0] != -1 ++ || gpio_inverted[0] != -1 || gpio_normal[0] != -1 ++ || gpio_fan[0] != -1 ) ) { ++ adm1026_fixup_gpio(client); ++ } ++ ++ /* WE INTENTIONALLY make no changes to the limits, ++ * offsets, pwms and fans. If they were ++ * configured, we don't want to mess with them. ++ * If they weren't, the default is generally safe ++ * and will suffice until 'sensors -s' can be run. ++ */ ++ ++ /* Start monitoring */ ++ value = adm1026_read_value(client, ADM1026_REG_CONFIG1); ++ ++ /* Set MONITOR, clear interrupt acknowledge and s/w reset */ ++ value = (value | CFG1_MONITOR) & (~CFG1_INT_CLEAR & ~CFG1_RESET) ; ++#ifdef DEBUG ++ printk("adm1026(%d): Setting CONFIG to: 0x%02x\n", client->id, value ); ++#endif ++ data->config1 = value ; ++ adm1026_write_value(client, ADM1026_REG_CONFIG1, value); ++ ++} ++ ++void adm1026_print_gpio(struct i2c_client *client) ++{ ++ struct adm1026_data *data = client->data; ++ int i ; ++ ++ printk("adm1026(%d): GPIO config is:\nadm1026(%d):", ++ client->id, client->id ); ++ for( i = 0 ; i <= 7 ; ++i ) { ++ if( data->config2 & (1 << i) ) { ++ printk( " %sGP%s%d", ++ data->gpio_config[i] & 0x02 ? "" : "!", ++ data->gpio_config[i] & 0x01 ? "OUT" : "IN", ++ i ); ++ } else { ++ printk( " FAN%d", i ); ++ } ++ } ++ printk( "\nadm1026(%d):", client->id ); ++ for( i = 8 ; i <= 15 ; ++i ) { ++ printk( " %sGP%s%d", ++ data->gpio_config[i] & 0x02 ? "" : "!", ++ data->gpio_config[i] & 0x01 ? "OUT" : "IN", ++ i ); ++ } ++ if( data->config3 & CFG3_GPIO16_ENABLE ) { ++ printk( " %sGP%s16\n", ++ data->gpio_config[16] & 0x02 ? "" : "!", ++ data->gpio_config[16] & 0x01 ? "OUT" : "IN" ); ++ } else { ++ /* GPIO16 is THERM */ ++ printk( " THERM\n" ); ++ } ++} ++ ++void adm1026_fixup_gpio(struct i2c_client *client) ++{ ++ struct adm1026_data *data = client->data; ++ int i ; ++ int value ; ++ ++ /* Make the changes requested. */ ++ /* We may need to unlock/stop monitoring or soft-reset the ++ * chip before we can make changes. This hasn't been ++ * tested much. FIXME ++ */ ++ ++ /* Make outputs */ ++ for( i = 0 ; i <= 16 ; ++i ) { ++ if( gpio_output[i] >= 0 && gpio_output[i] <= 16 ) { ++ data->gpio_config[gpio_output[i]] |= 0x01 ; ++ } ++ /* if GPIO0-7 is output, it isn't a FAN tach */ ++ if( gpio_output[i] >= 0 && gpio_output[i] <= 7 ) { ++ data->config2 |= 1 << gpio_output[i] ; ++ } ++ } ++ ++ /* Input overrides output */ ++ for( i = 0 ; i <= 16 ; ++i ) { ++ if( gpio_input[i] >= 0 && gpio_input[i] <= 16 ) { ++ data->gpio_config[gpio_input[i]] &= ~ 0x01 ; ++ } ++ /* if GPIO0-7 is input, it isn't a FAN tach */ ++ if( gpio_input[i] >= 0 && gpio_input[i] <= 7 ) { ++ data->config2 |= 1 << gpio_input[i] ; ++ } ++ } ++ ++ /* Inverted */ ++ for( i = 0 ; i <= 16 ; ++i ) { ++ if( gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16 ) { ++ data->gpio_config[gpio_inverted[i]] &= ~ 0x02 ; ++ } ++ } ++ ++ /* Normal overrides inverted */ ++ for( i = 0 ; i <= 16 ; ++i ) { ++ if( gpio_normal[i] >= 0 && gpio_normal[i] <= 16 ) { ++ data->gpio_config[gpio_normal[i]] |= 0x02 ; ++ } ++ } ++ ++ /* Fan overrides input and output */ ++ for( i = 0 ; i <= 7 ; ++i ) { ++ if( gpio_fan[i] >= 0 && gpio_fan[i] <= 7 ) { ++ data->config2 &= ~( 1 << gpio_fan[i] ); ++ } ++ } ++ ++ /* Write new configs to registers */ ++ adm1026_write_value(client, ADM1026_REG_CONFIG2, data->config2); ++ data->config3 = (data->config3 & 0x3f) ++ | ((data->gpio_config[16] & 0x03) << 6) ; ++ adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3); ++ for( i = 15, value = 0 ; i >= 0 ; --i ) { ++ value <<= 2 ; ++ value |= data->gpio_config[i] & 0x03 ; ++ if( (i & 0x03) == 0 ) { ++ adm1026_write_value(client, ++ ADM1026_REG_GPIO_CFG_0_3 + i/4, ++ value ); ++ value = 0 ; ++ } ++ } ++ ++ /* Print the new config */ ++ adm1026_print_gpio(client); ++} ++ ++void adm1026_update_client(struct i2c_client *client) ++{ ++ struct adm1026_data *data = client->data; ++ int i; ++ long value, alarms, gpio ; ++ ++ down(&data->update_lock); ++ ++ if (!data->valid ++ || (jiffies - data->last_reading > ADM1026_DATA_INTERVAL )) { ++ /* Things that change quickly */ ++ ++#ifdef DEBUG ++ printk("adm1026(%d): Reading sensor values\n", client->id); ++#endif ++ for (i = 0 ; i <= 16 ; ++i) { ++ data->in[i] = ++ adm1026_read_value(client, ADM1026_REG_IN(i)); ++ } ++ ++ for (i = 0 ; i <= 7 ; ++i) { ++ data->fan[i] = ++ adm1026_read_value(client, ADM1026_REG_FAN(i)); ++ } ++ ++ for (i = 0 ; i <= 2 ; ++i) { ++ /* NOTE: temp[] is s8 and we assume 2's complement ++ * "conversion" in the assignment */ ++ data->temp[i] = ++ adm1026_read_value(client, ADM1026_REG_TEMP(i)); ++ } ++ ++ data->pwm = adm1026_read_value(client, ADM1026_REG_PWM); ++ data->analog_out = adm1026_read_value(client, ADM1026_REG_DAC); ++ ++ /* GPIO16 is MSbit of alarms, move it to gpio */ ++ alarms = adm1026_read_value(client, ADM1026_REG_STATUS4); ++ gpio = alarms & 0x80 ? 0x0100 : 0 ; /* GPIO16 */ ++ alarms &= 0x7f ; ++ alarms <<= 8 ; ++ alarms |= adm1026_read_value(client, ADM1026_REG_STATUS3); ++ alarms <<= 8 ; ++ alarms |= adm1026_read_value(client, ADM1026_REG_STATUS2); ++ alarms <<= 8 ; ++ alarms |= adm1026_read_value(client, ADM1026_REG_STATUS1); ++ data->alarms = alarms ; ++ ++ /* Read the GPIO values */ ++ gpio |= adm1026_read_value(client, ADM1026_REG_GPIO_STATUS_8_15); ++ gpio <<= 8 ; ++ gpio |= adm1026_read_value(client, ADM1026_REG_GPIO_STATUS_0_7); ++ data->gpio = gpio ; ++ ++ data->last_reading = jiffies ; ++ }; /* last_reading */ ++ ++ if (!data->valid ++ || (jiffies - data->last_config > ADM1026_CONFIG_INTERVAL) ) { ++ /* Things that don't change often */ ++ ++#ifdef DEBUG ++ printk("adm1026(%d): Reading config values\n", client->id); ++#endif ++ for (i = 0 ; i <= 16 ; ++i) { ++ data->in_min[i] = ++ adm1026_read_value(client, ADM1026_REG_IN_MIN(i)); ++ data->in_max[i] = ++ adm1026_read_value(client, ADM1026_REG_IN_MAX(i)); ++ } ++ ++ value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) ++ | (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8); ++ for (i = 0 ; i <= 7 ; ++i) { ++ data->fan_min[i] = ++ adm1026_read_value(client, ADM1026_REG_FAN_MIN(i)); ++ data->fan_div[i] = DIV_FROM_REG(value & 0x03); ++ value >>= 2 ; ++ } ++ ++ for (i = 0; i <= 2; ++i) { ++ /* NOTE: temp_xxx[] are s8 and we assume 2's complement ++ * "conversion" in the assignment */ ++ data->temp_min[i] = ++ adm1026_read_value(client, ADM1026_REG_TEMP_MIN(i)); ++ data->temp_max[i] = ++ adm1026_read_value(client, ADM1026_REG_TEMP_MAX(i)); ++ data->temp_tmin[i] = ++ adm1026_read_value(client, ADM1026_REG_TEMP_TMIN(i)); ++ data->temp_therm[i] = ++ adm1026_read_value(client, ADM1026_REG_TEMP_THERM(i)); ++ data->temp_offset[i] = ++ adm1026_read_value(client, ADM1026_REG_TEMP_OFFSET(i)); ++ } ++ ++ /* Read the STATUS/alarm masks */ ++ alarms = adm1026_read_value(client, ADM1026_REG_MASK4); ++ gpio = alarms & 0x80 ? 0x0100 : 0 ; /* GPIO16 */ ++ alarms = (alarms & 0x7f) << 8 ; ++ alarms |= adm1026_read_value(client, ADM1026_REG_MASK3); ++ alarms <<= 8 ; ++ alarms |= adm1026_read_value(client, ADM1026_REG_MASK2); ++ alarms <<= 8 ; ++ alarms |= adm1026_read_value(client, ADM1026_REG_MASK1); ++ data->alarm_mask = alarms ; ++ ++ /* Read the GPIO values */ ++ gpio |= adm1026_read_value(client, ADM1026_REG_GPIO_MASK_8_15); ++ gpio <<= 8 ; ++ gpio |= adm1026_read_value(client, ADM1026_REG_GPIO_MASK_0_7); ++ data->gpio_mask = gpio ; ++ ++ /* Read the GPIO config */ ++ data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2); ++ data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3); ++ data->gpio_config[16] = (data->config3 >> 6) & 0x03 ; ++ ++ value = 0 ; ++ for( i = 0 ; i <= 15 ; ++i ) { ++ if( (i & 0x03) == 0 ) { ++ value = adm1026_read_value(client, ++ ADM1026_REG_GPIO_CFG_0_3 + i/4 ); ++ } ++ data->gpio_config[i] = value & 0x03 ; ++ value >>= 2 ; ++ } ++ ++ data->last_config = jiffies; ++ }; /* last_config */ ++ ++ /* We don't know where or even _if_ the VID might be on the GPIO ++ * pins. But the datasheet gives an example config showing ++ * GPIO11-15 being used to monitor VID0-4, so we go with that ++ * but make the vid WRITEABLE so if it's wrong, the user can ++ * set it in /etc/sensors.conf perhaps using an expression or ++ * 0 to trigger a re-read from the GPIO pins. ++ */ ++ if( data->vid == ADM1026_INIT_VID ) { ++ /* Hasn't been set yet, make a bold assumption */ ++ printk("adm1026(%d): Setting VID from GPIO11-15.\n", ++ client->id ); ++ data->vid = (data->gpio >> 11) & 0x1f ; ++ } ++ ++ data->valid = 1; ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The following functions are the call-back functions of the /proc/sys and ++ sysctl files. The appropriate function is referenced in the ctl_table ++ extra1 field. ++ ++ Each function must return the magnitude (power of 10 to divide the ++ data with) if it is called with operation set to SENSORS_PROC_REAL_INFO. ++ It must put a maximum of *nrels elements in results reflecting the ++ data of this file, and set *nrels to the number it actually put in ++ it, if operation is SENSORS_PROC_REAL_READ. Finally, it must get ++ up to *nrels elements from results and write them to the chip, if ++ operations is SENSORS_PROC_REAL_WRITE. ++ */ ++void adm1026_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ int nr = ctl_name - ADM1026_SYSCTL_IN0; ++ ++ /* We handle in0 - in15 here. in16 (-12V) is handled below */ ++ if (nr < 0 || nr > 15) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; /* 1.000 */ ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = INS_FROM_REG(nr,data->in_min[nr]); ++ results[1] = INS_FROM_REG(nr,data->in_max[nr]); ++ results[2] = INS_FROM_REG(nr,data->in[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 1) { ++ data->in_max[nr] = INS_TO_REG(nr,results[1]); ++ adm1026_write_value(client, ADM1026_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ if (*nrels_mag > 0) { ++ data->in_min[nr] = INS_TO_REG(nr,results[0]); ++ adm1026_write_value(client, ADM1026_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1026_in16(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ int nr = ctl_name - ADM1026_SYSCTL_IN0; ++ ++ /* We handle in16 (-12V) here */ ++ if (nr != 16) ++ return ; /* ERROR */ ++ ++ /* Apply offset and swap min/max so that min is 90% of ++ * target and max is 110% of target. ++ */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; /* 1.000 */ ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = INS_FROM_REG(nr,data->in_max[nr])-NEG12_OFFSET ; ++ results[1] = INS_FROM_REG(nr,data->in_min[nr])-NEG12_OFFSET ; ++ results[2] = INS_FROM_REG(nr,data->in[nr])-NEG12_OFFSET ; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 1) { ++ data->in_min[nr] = INS_TO_REG(nr,results[1]+NEG12_OFFSET); ++ adm1026_write_value(client, ADM1026_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag > 0) { ++ data->in_max[nr] = INS_TO_REG(nr,results[0]+NEG12_OFFSET); ++ adm1026_write_value(client, ADM1026_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1026_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ int nr = ctl_name - ADM1026_SYSCTL_FAN0 ; ++ ++ if (nr < 0 || nr > 7) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr], data->fan_div[nr]); ++ results[1] = FAN_FROM_REG(data->fan[nr], data->fan_div[nr]); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 0) { ++ data->fan_min[nr] = FAN_TO_REG(results[0], ++ data->fan_div[nr]); ++ adm1026_write_value(client, ADM1026_REG_FAN_MIN(nr), ++ data->fan_min[nr]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++/* Adjust fan_min to account for new fan divisor */ ++void adm1026_fixup_fan_min(struct i2c_client *client, int fan, int old_div) ++{ ++ struct adm1026_data *data = client->data; ++ int new_div = data->fan_div[fan] ; ++ int new_min; ++ ++ /* 0 and 0xff are special. Don't adjust them */ ++ if( data->fan_min[fan] == 0 || data->fan_min[fan] == 0xff ) { ++ return ; ++ } ++ ++ new_min = data->fan_min[fan] * old_div / new_div ; ++ new_min = SENSORS_LIMIT(new_min, 1, 254); ++ data->fan_min[fan] = new_min ; ++ adm1026_write_value(client, ADM1026_REG_FAN_MIN(fan), new_min); ++} ++ ++void adm1026_fan_div(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ int i ; ++ int value, div, old ; ++ ++ if (ctl_name != ADM1026_SYSCTL_FAN_DIV) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ for( i = 0 ; i <= 7 ; ++i ) { ++ results[i] = data->fan_div[i] ; ++ } ++ *nrels_mag = 8; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ value = 0 ; ++ for( i = 7 ; i >= 0 ; --i ) { ++ value <<= 2 ; ++ if (*nrels_mag > i) { ++ old = data->fan_div[i] ; ++ div = DIV_TO_REG(results[i]) ; ++ data->fan_div[i] = DIV_FROM_REG(div) ; ++ if( data->fan_div[i] != old ) { ++ adm1026_fixup_fan_min(client,i,old); ++ } ++ } else { ++ div = DIV_TO_REG(data->fan_div[i]) ; ++ } ++ value |= div ; ++ } ++ adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3, ++ value & 0xff); ++ adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7, ++ (value >> 8) & 0xff); ++ up(&data->update_lock); ++ } ++} ++ ++void adm1026_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ int nr = ctl_name - ADM1026_SYSCTL_TEMP1 ; ++ ++ if (nr < 0 || nr > 2) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_min[nr]); ++ results[1] = TEMP_FROM_REG(data->temp_max[nr]); ++ results[2] = TEMP_FROM_REG(data->temp[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 1) { ++ data->temp_max[nr] = TEMP_TO_REG(results[1]); ++ adm1026_write_value(client, ADM1026_REG_TEMP_MAX(nr), ++ data->temp_max[nr]); ++ } ++ if (*nrels_mag > 0) { ++ data->temp_min[nr] = TEMP_TO_REG(results[0]); ++ adm1026_write_value(client, ADM1026_REG_TEMP_MIN(nr), ++ data->temp_min[nr]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1026_temp_offset(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ int nr = ctl_name - ADM1026_SYSCTL_TEMP_OFFSET1 ; ++ ++ if (nr < 0 || nr > 2) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_offset[nr]); ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 0) { ++ data->temp_offset[nr] = TEMP_TO_REG(results[0]); ++ adm1026_write_value(client, ADM1026_REG_TEMP_OFFSET(nr), ++ data->temp_offset[nr]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1026_temp_tmin(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ int nr = ctl_name - ADM1026_SYSCTL_TEMP_TMIN1 ; ++ ++ if (nr < 0 || nr > 2) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_tmin[nr]); ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 0) { ++ data->temp_tmin[nr] = TEMP_TO_REG(results[0]); ++ adm1026_write_value(client, ADM1026_REG_TEMP_TMIN(nr), ++ data->temp_tmin[nr]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1026_temp_therm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ int nr = ctl_name - ADM1026_SYSCTL_TEMP_THERM1 ; ++ ++ if (nr < 0 || nr > 2) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_therm[nr]); ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 0) { ++ data->temp_therm[nr] = TEMP_TO_REG(results[0]); ++ adm1026_write_value(client, ADM1026_REG_TEMP_THERM(nr), ++ data->temp_therm[nr]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1026_pwm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ ++ if (ctl_name != ADM1026_SYSCTL_PWM) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = PWM_FROM_REG(data->pwm); ++ results[1] = 1 ; /* Always enabled */ ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ /* PWM enable is read-only */ ++ if (*nrels_mag > 0) { ++ data->pwm = PWM_TO_REG(results[0]); ++ adm1026_write_value(client, ADM1026_REG_PWM, ++ data->pwm); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1026_analog_out(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ ++ if (ctl_name != ADM1026_SYSCTL_ANALOG_OUT) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; /* 0 - 255 */ ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = DAC_FROM_REG(data->analog_out); ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 0) { ++ data->analog_out = DAC_TO_REG(results[0]); ++ adm1026_write_value(client, ADM1026_REG_DAC, ++ data->analog_out); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1026_afc(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ ++ if (ctl_name != ADM1026_SYSCTL_AFC) ++ return ; /* ERROR */ ++ ++ /* PWM auto fan control, DAC auto fan control */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = (data->config1 & CFG1_PWM_AFC) != 0 ; ++ results[1] = (data->config1 & CFG1_DAC_AFC) != 0 ; ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 1) { ++ data->config1 = (data->config1 & ~CFG1_DAC_AFC) ++ | (results[1] ? CFG1_DAC_AFC : 0) ; ++ } ++ if (*nrels_mag > 0) { ++ data->config1 = (data->config1 & ~CFG1_PWM_AFC) ++ | (results[0] ? CFG1_PWM_AFC : 0) ; ++ adm1026_write_value(client, ADM1026_REG_CONFIG1, ++ data->config1); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1026_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ ++ if( ctl_name != ADM1026_SYSCTL_VID ) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = VID_FROM_REG((data->vid)&0x3f,data->vrm); ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ /* Hmmm... There isn't a VID_TO_REG mapping */ ++ if (*nrels_mag > 0) { ++ if( results[0] >= 0 ) { ++ data->vid = results[0] & 0x3f ; ++ } else { ++ data->vid = ADM1026_INIT_VID ; ++ } ++ } ++ up(&data->update_lock); ++ } ++ ++} ++ ++void adm1026_vrm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ ++ if( ctl_name != ADM1026_SYSCTL_VRM ) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->vrm ; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag > 0) { ++ data->vrm = results[0] ; ++ } ++ } ++} ++ ++void adm1026_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ ++ if( ctl_name != ADM1026_SYSCTL_ALARMS ) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = data->alarms ; ++ *nrels_mag = 1; ++ } ++ /* FIXME: Perhaps we should implement a write function ++ * to clear an alarm? ++ */ ++} ++ ++void adm1026_alarm_mask(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ unsigned long mask ; ++ ++ if( ctl_name != ADM1026_SYSCTL_ALARM_MASK ) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = data->alarm_mask ; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 0) { ++ data->alarm_mask = results[0] & 0x7fffffff ; ++ mask = data->alarm_mask ++ | (data->gpio_mask & 0x10000 ? 0x80000000 : 0) ; ++ adm1026_write_value(client, ADM1026_REG_MASK1, ++ mask & 0xff); ++ mask >>= 8 ; ++ adm1026_write_value(client, ADM1026_REG_MASK2, ++ mask & 0xff); ++ mask >>= 8 ; ++ adm1026_write_value(client, ADM1026_REG_MASK3, ++ mask & 0xff); ++ mask >>= 8 ; ++ adm1026_write_value(client, ADM1026_REG_MASK4, ++ mask & 0xff); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1026_gpio(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ long gpio ; ++ ++ if( ctl_name != ADM1026_SYSCTL_GPIO ) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = data->gpio ; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 0) { ++ data->gpio = results[0] & 0x1ffff ; ++ gpio = data->gpio ; ++ adm1026_write_value(client, ++ ADM1026_REG_GPIO_STATUS_0_7, ++ gpio & 0xff ); ++ gpio >>= 8 ; ++ adm1026_write_value(client, ++ ADM1026_REG_GPIO_STATUS_8_15, ++ gpio & 0xff ); ++ gpio = ((gpio >> 1) & 0x80) ++ | (data->alarms >> 24 & 0x7f); ++ adm1026_write_value(client, ++ ADM1026_REG_STATUS4, ++ gpio & 0xff ); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1026_gpio_mask(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct adm1026_data *data = client->data; ++ long mask ; ++ ++ if( ctl_name != ADM1026_SYSCTL_GPIO_MASK ) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm1026_update_client(client); ++ results[0] = data->gpio_mask ; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 0) { ++ data->gpio_mask = results[0] & 0x1ffff ; ++ mask = data->gpio_mask ; ++ adm1026_write_value(client, ADM1026_REG_GPIO_MASK_0_7, ++ mask & 0xff); ++ mask >>= 8 ; ++ adm1026_write_value(client, ADM1026_REG_GPIO_MASK_8_15, ++ mask & 0xff); ++ mask = ((mask >> 1) & 0x80) ++ | (data->alarm_mask >> 24 & 0x7f); ++ adm1026_write_value(client, ADM1026_REG_MASK1, ++ mask & 0xff); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++static int __init sm_adm1026_init(void) ++{ ++ printk("adm1026: Version %s (%s)\n", LM_VERSION, LM_DATE); ++ printk("adm1026: See http://www.penguincomputing.com/lm_sensors for more info.\n" ); ++ return i2c_add_driver(&adm1026_driver); ++} ++ ++static void __exit sm_adm1026_exit(void) ++{ ++ i2c_del_driver(&adm1026_driver); ++} ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Philip Pokorny ++ and Philip Edelbrock ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* Supports ADM9240, DS1780, and LM81. See doc/chips/adm9240 for details */ ++ ++/* ++ A couple notes about the ADM9240: ++ ++* It claims to be 'LM7x' register compatible. This must be in reference ++ to only the LM78, because it is missing stuff to emulate LM75's as well. ++ (like the Winbond W83781 does) ++ ++* This driver was written from rev. 0 of the PDF, but it seems well ++ written and complete (unlike the W83781 which is horrible and has ++ supposidly gone through a few revisions.. rev 0 of that one must ++ have been in crayon on construction paper...) ++ ++* All analog inputs can range from 0 to 2.5, eventhough some inputs are ++ marked as being 5V, 12V, etc. I don't have any real voltages going ++ into my prototype, so I'm not sure that things are computed right, ++ but at least the limits seem to be working OK. ++ ++* Another curiousity is that the fan_div seems to be read-only. I.e., ++ any written value to it doesn't seem to make any difference. The ++ fan_div seems to be 'stuck' at 2 (which isn't a bad value in most cases). ++ ++ ++ --Phil ++ ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x2c, 0x2f, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_3(adm9240, ds1780, lm81); ++ ++/* Many ADM9240 constants specified below */ ++ ++#define ADM9240_REG_IN_MAX(nr) (0x2b + (nr) * 2) ++#define ADM9240_REG_IN_MIN(nr) (0x2c + (nr) * 2) ++#define ADM9240_REG_IN(nr) (0x20 + (nr)) ++ ++/* The ADM9240 registers */ ++#define ADM9240_REG_TEST 0x15 ++#define ADM9240_REG_ANALOG_OUT 0x19 ++/* These are all read-only */ ++#define ADM9240_REG_2_5V 0x20 ++#define ADM9240_REG_VCCP1 0x21 ++#define ADM9240_REG_3_3V 0x22 ++#define ADM9240_REG_5V 0x23 ++#define ADM9240_REG_12V 0x24 ++#define ADM9240_REG_VCCP2 0x25 ++#define ADM9240_REG_TEMP 0x27 ++#define ADM9240_REG_FAN1 0x28 ++#define ADM9240_REG_FAN2 0x29 ++#define ADM9240_REG_COMPANY_ID 0x3E /* 0x23 for ADM9240; 0xDA for DS1780 */ ++ /* 0x01 for LM81 */ ++#define ADM9240_REG_DIE_REV 0x3F ++/* These are read/write */ ++#define ADM9240_REG_2_5V_HIGH 0x2B ++#define ADM9240_REG_2_5V_LOW 0x2C ++#define ADM9240_REG_VCCP1_HIGH 0x2D ++#define ADM9240_REG_VCCP1_LOW 0x2E ++#define ADM9240_REG_3_3V_HIGH 0x2F ++#define ADM9240_REG_3_3V_LOW 0x30 ++#define ADM9240_REG_5V_HIGH 0x31 ++#define ADM9240_REG_5V_LOW 0x32 ++#define ADM9240_REG_12V_HIGH 0x33 ++#define ADM9240_REG_12V_LOW 0x34 ++#define ADM9240_REG_VCCP2_HIGH 0x35 ++#define ADM9240_REG_VCCP2_LOW 0x36 ++#define ADM9240_REG_TCRIT_LIMIT 0x37 /* LM81 only - not supported */ ++#define ADM9240_REG_LOW_LIMIT 0x38 /* LM81 only - not supported */ ++#define ADM9240_REG_TOS 0x39 ++#define ADM9240_REG_THYST 0x3A ++#define ADM9240_REG_FAN1_MIN 0x3B ++#define ADM9240_REG_FAN2_MIN 0x3C ++ ++#define ADM9240_REG_CONFIG 0x40 ++#define ADM9240_REG_INT1_STAT 0x41 ++#define ADM9240_REG_INT2_STAT 0x42 ++#define ADM9240_REG_INT1_MASK 0x43 ++#define ADM9240_REG_INT2_MASK 0x44 ++ ++#define ADM9240_REG_COMPAT 0x45 /* dummy compat. register for other drivers? */ ++#define ADM9240_REG_CHASSIS_CLEAR 0x46 ++#define ADM9240_REG_VID_FAN_DIV 0x47 ++#define ADM9240_REG_I2C_ADDR 0x48 ++#define ADM9240_REG_VID4 0x49 ++#define ADM9240_REG_TEMP_CONFIG 0x4B ++#define ADM9240_REG_EXTMODE1 0x4C /* LM81 only - not supported */ ++#define ADM9240_REG_EXTMODE2 0x4D /* LM81 only - not supported */ ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++#define IN_TO_REG(val,nr) (SENSORS_LIMIT((val), 0, 255)) ++#define IN_FROM_REG(val,nr) (val) ++ ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 255; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, ++ 254); ++} ++ ++#define FAN_FROM_REG(val,div) ((val)==0?-1:\ ++ (val)==255?0:1350000/((div)*(val))) ++ ++#define TEMP_FROM_REG(temp) ((temp)<256 ? (temp) * 5 : \ ++ ((temp) - 512) * 5) ++ ++#define TEMP_LIMIT_FROM_REG(val) (((val)>=0x80?(val)-0x100:(val))*10) ++ ++#define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT(((val)<0?(((val)-5)/10)+256:\ ++ ((val)+5)/10), \ ++ 0,255) ++ ++#define ALARMS_FROM_REG(val) (val) ++ ++#define DIV_FROM_REG(val) (1 << (val)) ++#define DIV_TO_REG(val) ((val)==1?0:((val)==8?3:((val)==4?2:1))) ++ ++#define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\ ++ 205-(val)*5) ++ ++/* For each registered ADM9240, we need to keep some data in memory. */ ++struct adm9240_data { ++ struct i2c_client client; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 in[6]; /* Register value */ ++ u8 in_max[6]; /* Register value */ ++ u8 in_min[6]; /* Register value */ ++ u8 fan[2]; /* Register value */ ++ u8 fan_min[2]; /* Register value */ ++ u8 fan_div[2]; /* Register encoding, shifted right */ ++ int temp; /* Temp, shifted right */ ++ u8 temp_os_max; /* Register value */ ++ u8 temp_os_hyst; /* Register value */ ++ u16 alarms; /* Register encoding, combined */ ++ u8 analog_out; /* Register value */ ++ u8 vid; /* Register value combined */ ++}; ++ ++ ++static int adm9240_attach_adapter(struct i2c_adapter *adapter); ++static int adm9240_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int adm9240_detach_client(struct i2c_client *client); ++ ++static int adm9240_read_value(struct i2c_client *client, u8 reg); ++static int adm9240_write_value(struct i2c_client *client, u8 reg, u8 value); ++static void adm9240_update_client(struct i2c_client *client); ++static void adm9240_init_client(struct i2c_client *client); ++ ++ ++static void adm9240_in(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm9240_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm9240_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm9240_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm9240_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm9240_analog_out(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, ++ long *results); ++static void adm9240_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static int adm9240_id = 0; ++ ++static struct i2c_driver adm9240_driver = { ++ .owner = THIS_MODULE, ++ .name = "ADM9240 sensor driver", ++ .id = I2C_DRIVERID_ADM9240, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = adm9240_attach_adapter, ++ .detach_client = adm9240_detach_client, ++}; ++ ++/* The /proc/sys entries */ ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define ADM9240_SYSCTL_IN0 1000 /* Volts * 100 */ ++#define ADM9240_SYSCTL_IN1 1001 ++#define ADM9240_SYSCTL_IN2 1002 ++#define ADM9240_SYSCTL_IN3 1003 ++#define ADM9240_SYSCTL_IN4 1004 ++#define ADM9240_SYSCTL_IN5 1005 ++#define ADM9240_SYSCTL_FAN1 1101 /* Rotations/min */ ++#define ADM9240_SYSCTL_FAN2 1102 ++#define ADM9240_SYSCTL_TEMP 1250 /* Degrees Celcius * 100 */ ++#define ADM9240_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define ADM9240_SYSCTL_ALARMS 2001 /* bitvector */ ++#define ADM9240_SYSCTL_ANALOG_OUT 2002 ++#define ADM9240_SYSCTL_VID 2003 ++ ++#define ADM9240_ALARM_IN0 0x0001 ++#define ADM9240_ALARM_IN1 0x0002 ++#define ADM9240_ALARM_IN2 0x0004 ++#define ADM9240_ALARM_IN3 0x0008 ++#define ADM9240_ALARM_IN4 0x0100 ++#define ADM9240_ALARM_IN5 0x0200 ++#define ADM9240_ALARM_FAN1 0x0040 ++#define ADM9240_ALARM_FAN2 0x0080 ++#define ADM9240_ALARM_TEMP 0x0010 ++#define ADM9240_ALARM_CHAS 0x1000 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected ADM9240. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table adm9240_dir_table_template[] = { ++ {ADM9240_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm9240_in}, ++ {ADM9240_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm9240_in}, ++ {ADM9240_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm9240_in}, ++ {ADM9240_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm9240_in}, ++ {ADM9240_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm9240_in}, ++ {ADM9240_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm9240_in}, ++ {ADM9240_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm9240_fan}, ++ {ADM9240_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm9240_fan}, ++ {ADM9240_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm9240_temp}, ++ {ADM9240_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm9240_fan_div}, ++ {ADM9240_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm9240_alarms}, ++ {ADM9240_SYSCTL_ANALOG_OUT, "analog_out", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm9240_analog_out}, ++ {ADM9240_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &adm9240_vid}, ++ {0} ++}; ++ ++static int adm9240_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, adm9240_detect); ++} ++ ++static int adm9240_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct adm9240_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access adm9240_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct adm9240_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &adm9240_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ ++ if (kind < 0) { ++ if ( ++ ((adm9240_read_value ++ (new_client, ADM9240_REG_CONFIG) & 0x80) != 0x00) ++ || ++ (adm9240_read_value(new_client, ADM9240_REG_I2C_ADDR) ++ != address)) ++ goto ERROR1; ++ } ++ ++ /* Determine the chip type. */ ++ if (kind <= 0) { ++ i = adm9240_read_value(new_client, ADM9240_REG_COMPANY_ID); ++ if (i == 0x23) ++ kind = adm9240; ++ else if (i == 0xda) ++ kind = ds1780; ++ else if (i == 0x01) ++ kind = lm81; ++ else { ++ if (kind == 0) ++ printk ++ ("adm9240.o: Ignoring 'force' parameter for unknown chip at " ++ "adapter %d, address 0x%02x\n", ++ i2c_adapter_id(adapter), address); ++ goto ERROR1; ++ } ++ } ++ ++ if (kind == adm9240) { ++ type_name = "adm9240"; ++ client_name = "ADM9240 chip"; ++ } else if (kind == ds1780) { ++ type_name = "ds1780"; ++ client_name = "DS1780 chip"; ++ } else if (kind == lm81) { ++ type_name = "lm81"; ++ client_name = "LM81 chip"; ++ } else { ++#ifdef DEBUG ++ printk("adm9240.o: Internal error: unknown kind (%d)?!?", ++ kind); ++#endif ++ goto ERROR1; ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ data->type = kind; ++ ++ new_client->id = adm9240_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, ++ type_name, ++ adm9240_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the ADM9240 chip */ ++ adm9240_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int adm9240_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct adm9240_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("adm9240.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++ ++static int adm9240_read_value(struct i2c_client *client, u8 reg) ++{ ++ return i2c_smbus_read_byte_data(client, reg); ++} ++ ++static int adm9240_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++/* Called when we have found a new ADM9240. */ ++static void adm9240_init_client(struct i2c_client *client) ++{ ++ /* Start monitoring */ ++ adm9240_write_value(client, ADM9240_REG_CONFIG, 0x01); ++} ++ ++static void adm9240_update_client(struct i2c_client *client) ++{ ++ struct adm9240_data *data = client->data; ++ u8 i; ++ ++ down(&data->update_lock); ++ ++ if ( ++ (jiffies - data->last_updated > ++ (data->type == adm9240 ? HZ / 2 : HZ * 2)) ++ || (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("Starting adm9240 update\n"); ++#endif ++ for (i = 0; i <= 5; i++) { ++ data->in[i] = ++ adm9240_read_value(client, ADM9240_REG_IN(i)); ++ data->in_min[i] = ++ adm9240_read_value(client, ++ ADM9240_REG_IN_MIN(i)); ++ data->in_max[i] = ++ adm9240_read_value(client, ++ ADM9240_REG_IN_MAX(i)); ++ } ++ data->fan[0] = ++ adm9240_read_value(client, ADM9240_REG_FAN1); ++ data->fan_min[0] = ++ adm9240_read_value(client, ADM9240_REG_FAN1_MIN); ++ data->fan[1] = ++ adm9240_read_value(client, ADM9240_REG_FAN2); ++ data->fan_min[1] = ++ adm9240_read_value(client, ADM9240_REG_FAN2_MIN); ++ data->temp = ++ (adm9240_read_value(client, ADM9240_REG_TEMP) << 1) + ++ ((adm9240_read_value ++ (client, ADM9240_REG_TEMP_CONFIG) & 0x80) >> 7); ++ data->temp_os_max = ++ adm9240_read_value(client, ADM9240_REG_TOS); ++ data->temp_os_hyst = ++ adm9240_read_value(client, ADM9240_REG_THYST); ++ ++ i = adm9240_read_value(client, ADM9240_REG_VID_FAN_DIV); ++ data->fan_div[0] = (i >> 4) & 0x03; ++ data->fan_div[1] = (i >> 6) & 0x03; ++ data->vid = i & 0x0f; ++ data->vid |= ++ (adm9240_read_value(client, ADM9240_REG_VID4) & 0x01) ++ << 4; ++ ++ data->alarms = ++ adm9240_read_value(client, ++ ADM9240_REG_INT1_STAT) + ++ (adm9240_read_value(client, ADM9240_REG_INT2_STAT) << ++ 8); ++ data->analog_out = ++ adm9240_read_value(client, ADM9240_REG_ANALOG_OUT); ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the date ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++void adm9240_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ ++ int scales[6] = { 250, 270, 330, 500, 1200, 270 }; ++ ++ struct adm9240_data *data = client->data; ++ int nr = ctl_name - ADM9240_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm9240_update_client(client); ++ results[0] = ++ IN_FROM_REG(data->in_min[nr], nr) * scales[nr] / 192; ++ results[1] = ++ IN_FROM_REG(data->in_max[nr], nr) * scales[nr] / 192; ++ results[2] = ++ IN_FROM_REG(data->in[nr], nr) * scales[nr] / 192; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = ++ IN_TO_REG((results[0] * 192) / scales[nr], nr); ++ adm9240_write_value(client, ADM9240_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = ++ IN_TO_REG((results[1] * 192) / scales[nr], nr); ++ adm9240_write_value(client, ADM9240_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++} ++ ++void adm9240_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm9240_data *data = client->data; ++ int nr = ctl_name - ADM9240_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm9240_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr - 1], ++ DIV_FROM_REG(data-> ++ fan_div[nr - 1])); ++ results[1] = ++ FAN_FROM_REG(data->fan[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = FAN_TO_REG(results[0], ++ DIV_FROM_REG ++ (data-> ++ fan_div[nr - ++ 1])); ++ adm9240_write_value(client, ++ nr == ++ 1 ? ADM9240_REG_FAN1_MIN : ++ ADM9240_REG_FAN2_MIN, ++ data->fan_min[nr - 1]); ++ } ++ } ++} ++ ++ ++void adm9240_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm9240_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm9240_update_client(client); ++ results[0] = TEMP_LIMIT_FROM_REG(data->temp_os_max); ++ results[1] = TEMP_LIMIT_FROM_REG(data->temp_os_hyst); ++ results[2] = TEMP_FROM_REG(data->temp); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_os_max = TEMP_LIMIT_TO_REG(results[0]); ++ adm9240_write_value(client, ADM9240_REG_TOS, ++ data->temp_os_max); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_os_hyst = TEMP_LIMIT_TO_REG(results[1]); ++ adm9240_write_value(client, ADM9240_REG_THYST, ++ data->temp_os_hyst); ++ } ++ } ++} ++ ++void adm9240_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm9240_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm9240_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++void adm9240_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct adm9240_data *data = client->data; ++ int old; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm9240_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = adm9240_read_value(client, ADM9240_REG_VID_FAN_DIV); ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ old = (old & 0x3f) | (data->fan_div[1] << 6); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ old = (old & 0xcf) | (data->fan_div[0] << 4); ++ adm9240_write_value(client, ++ ADM9240_REG_VID_FAN_DIV, old); ++ } ++ } ++} ++ ++void adm9240_analog_out(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct adm9240_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm9240_update_client(client); ++ results[0] = data->analog_out; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->analog_out = results[0]; ++ adm9240_write_value(client, ADM9240_REG_ANALOG_OUT, ++ data->analog_out); ++ } ++ } ++} ++ ++void adm9240_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct adm9240_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ adm9240_update_client(client); ++ results[0] = VID_FROM_REG(data->vid); ++ *nrels_mag = 1; ++ } ++} ++ ++static int __init sm_adm9240_init(void) ++{ ++ printk("adm9240.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&adm9240_driver); ++} ++ ++static void __exit sm_adm9240_exit(void) ++{ ++ i2c_del_driver(&adm9240_driver); ++} ++ ++ ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard and Philip Edelbrock "); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("ADM9240 driver"); ++ ++module_init(sm_adm9240_init); ++module_exit(sm_adm9240_exit); +--- linux-old/drivers/sensors/asb100.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/asb100.c Mon Dec 13 20:18:45 2004 +@@ -0,0 +1,1025 @@ ++/* ++ asb100.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ ++ Copyright (c) 2003 Mark M. Hoffman ++ ++ (derived from w83781d.c) ++ ++ Copyright (c) 1998 - 2003 Frodo Looijaard , ++ Philip Edelbrock , and ++ Mark Studebaker ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ This driver supports the hardware sensor chips: Asus ASB100 and ++ ASB100-A "BACH". ++ ++ ASB100-A supports pwm1, while plain ASB100 does not. There is no known ++ way for the driver to tell which one is there. ++ ++ Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA ++ asb100 7 3 1 4 0x31 0x0694 yes no ++*/ ++ ++//#define DEBUG 1 ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++#include "lm75.h" ++ ++#ifndef I2C_DRIVERID_ASB100 ++#define I2C_DRIVERID_ASB100 1043 ++#endif ++ ++/* I2C addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x28, 0x2f, SENSORS_I2C_END }; ++ ++/* ISA addresses to scan (none) */ ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* default VRM to 9.0 instead of 8.2 */ ++#define ASB100_DEFAULT_VRM 90 ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(asb100); ++SENSORS_MODULE_PARM(force_subclients, "List of subclient addresses: " \ ++ "{bus, clientaddr, subclientaddr1, subclientaddr2}"); ++ ++/* Voltage IN registers 0-6 */ ++#define ASB100_REG_IN(nr) (0x20 + (nr)) ++#define ASB100_REG_IN_MAX(nr) (0x2b + (nr * 2)) ++#define ASB100_REG_IN_MIN(nr) (0x2c + (nr * 2)) ++ ++/* FAN IN registers 1-3 */ ++#define ASB100_REG_FAN(nr) (0x27 + (nr)) ++#define ASB100_REG_FAN_MIN(nr) (0x3a + (nr)) ++ ++/* TEMPERATURE registers 1-4 */ ++static const u16 asb100_reg_temp[] = {0, 0x27, 0x150, 0x250, 0x17}; ++static const u16 asb100_reg_temp_max[] = {0, 0x39, 0x155, 0x255, 0x18}; ++static const u16 asb100_reg_temp_hyst[] = {0, 0x3a, 0x153, 0x253, 0x19}; ++ ++#define ASB100_REG_TEMP(nr) (asb100_reg_temp[nr]) ++#define ASB100_REG_TEMP_MAX(nr) (asb100_reg_temp_max[nr]) ++#define ASB100_REG_TEMP_HYST(nr) (asb100_reg_temp_hyst[nr]) ++ ++#define ASB100_REG_TEMP2_CONFIG 0x0152 ++#define ASB100_REG_TEMP3_CONFIG 0x0252 ++ ++ ++#define ASB100_REG_CONFIG 0x40 ++#define ASB100_REG_ALARM1 0x41 ++#define ASB100_REG_ALARM2 0x42 ++#define ASB100_REG_SMIM1 0x43 ++#define ASB100_REG_SMIM2 0x44 ++#define ASB100_REG_VID_FANDIV 0x47 ++#define ASB100_REG_I2C_ADDR 0x48 ++#define ASB100_REG_CHIPID 0x49 ++#define ASB100_REG_I2C_SUBADDR 0x4a ++#define ASB100_REG_PIN 0x4b ++#define ASB100_REG_IRQ 0x4c ++#define ASB100_REG_BANK 0x4e ++#define ASB100_REG_CHIPMAN 0x4f ++ ++#define ASB100_REG_WCHIPID 0x58 ++ ++/* bit 7 -> enable, bits 0-3 -> duty cycle */ ++#define ASB100_REG_PWM1 0x59 ++ ++/* CONVERSIONS ++ Rounding and limit checking is only done on the TO_REG variants. */ ++ ++/* These constants are a guess, consistent w/ w83781d */ ++#define ASB100_IN_MIN ( 0) ++#define ASB100_IN_MAX (408) ++ ++/* IN: 1/100 V (0V to 4.08V) ++ REG: 16mV/bit */ ++static u8 IN_TO_REG(unsigned val) ++{ ++ unsigned nval = SENSORS_LIMIT(val, ASB100_IN_MIN, ASB100_IN_MAX); ++ return (nval * 10 + 8) / 16; ++} ++ ++static unsigned IN_FROM_REG(u8 reg) ++{ ++ return (reg * 16 + 5) / 10; ++} ++ ++static u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 255; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); ++} ++ ++static int FAN_FROM_REG(u8 val, int div) ++{ ++ return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div); ++} ++ ++/* These constants are a guess, consistent w/ w83781d */ ++#define ASB100_TEMP_MIN (-1280) ++#define ASB100_TEMP_MAX ( 1270) ++ ++/* TEMP: 1/10 degrees C (-128C to +127C) ++ REG: 1C/bit, two's complement */ ++static u8 TEMP_TO_REG(int temp) ++{ ++ int ntemp = SENSORS_LIMIT(temp, ASB100_TEMP_MIN, ASB100_TEMP_MAX); ++ ntemp += (ntemp<0 ? -5 : 5); ++ return (u8)(ntemp / 10); ++} ++ ++static int TEMP_FROM_REG(u8 reg) ++{ ++ return (s8)reg * 10; ++} ++ ++/* PWM: 0 - 255 per sensors documentation ++ REG: (6.25% duty cycle per bit) */ ++static u8 ASB100_PWM_TO_REG(int pwm) ++{ ++ pwm = SENSORS_LIMIT(pwm, 0, 255); ++ return (u8)(pwm / 16); ++} ++ ++static int ASB100_PWM_FROM_REG(u8 reg) ++{ ++ return reg * 16; ++} ++ ++#define ALARMS_FROM_REG(val) (val) ++ ++#define DIV_FROM_REG(val) (1 << (val)) ++ ++/* FAN DIV: 1, 2, 4, or 8 (defaults to 2) ++ REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */ ++static u8 DIV_TO_REG(long val) ++{ ++ return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1; ++} ++ ++/* For each registered client, we need to keep some data in memory. That ++ data is pointed to by client->data. The structure itself is ++ dynamically allocated, at the same time the client itself is allocated. */ ++struct asb100_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ unsigned long last_updated; /* In jiffies */ ++ ++ /* array of 2 pointers to subclients */ ++ struct i2c_client *lm75[2]; ++ ++ char valid; /* !=0 if following fields are valid */ ++ u8 in[7]; /* Register value */ ++ u8 in_max[7]; /* Register value */ ++ u8 in_min[7]; /* Register value */ ++ u8 fan[3]; /* Register value */ ++ u8 fan_min[3]; /* Register value */ ++ u16 temp[4]; /* Register value (0 and 3 are u8 only) */ ++ u16 temp_max[4]; /* Register value (0 and 3 are u8 only) */ ++ u16 temp_hyst[4]; /* Register value (0 and 3 are u8 only) */ ++ u8 fan_div[3]; /* Register encoding, right justified */ ++ u8 pwm; /* Register encoding */ ++ u8 vid; /* Register encoding, combined */ ++ u32 alarms; /* Register encoding, combined */ ++ u8 vrm; ++}; ++ ++static int asb100_attach_adapter(struct i2c_adapter *adapter); ++static int asb100_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int asb100_detach_client(struct i2c_client *client); ++ ++static int asb100_read_value(struct i2c_client *client, u16 reg); ++static void asb100_write_value(struct i2c_client *client, u16 reg, u16 val); ++static void asb100_update_client(struct i2c_client *client); ++static void asb100_init_client(struct i2c_client *client); ++ ++static void asb100_in(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void asb100_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void asb100_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void asb100_temp_add(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void asb100_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void asb100_vrm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void asb100_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void asb100_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void asb100_pwm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static struct i2c_driver asb100_driver = { ++ .owner = THIS_MODULE, ++ .name = "asb100", ++ .id = I2C_DRIVERID_ASB100, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = asb100_attach_adapter, ++ .detach_client = asb100_detach_client, ++}; ++ ++/* The /proc/sys entries */ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define ASB100_SYSCTL_IN0 1000 /* Volts * 100 */ ++#define ASB100_SYSCTL_IN1 1001 ++#define ASB100_SYSCTL_IN2 1002 ++#define ASB100_SYSCTL_IN3 1003 ++#define ASB100_SYSCTL_IN4 1004 ++#define ASB100_SYSCTL_IN5 1005 ++#define ASB100_SYSCTL_IN6 1006 ++ ++#define ASB100_SYSCTL_FAN1 1101 /* Rotations/min */ ++#define ASB100_SYSCTL_FAN2 1102 ++#define ASB100_SYSCTL_FAN3 1103 ++ ++#define ASB100_SYSCTL_TEMP1 1200 /* Degrees Celcius * 10 */ ++#define ASB100_SYSCTL_TEMP2 1201 ++#define ASB100_SYSCTL_TEMP3 1202 ++#define ASB100_SYSCTL_TEMP4 1203 ++ ++#define ASB100_SYSCTL_VID 1300 /* Volts * 1000 */ ++#define ASB100_SYSCTL_VRM 1301 ++ ++#define ASB100_SYSCTL_PWM1 1401 /* 0-255 => 0-100% duty cycle */ ++ ++#define ASB100_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define ASB100_SYSCTL_ALARMS 2001 /* bitvector */ ++ ++#define ASB100_ALARM_IN0 0x0001 /* ? */ ++#define ASB100_ALARM_IN1 0x0002 /* ? */ ++#define ASB100_ALARM_IN2 0x0004 ++#define ASB100_ALARM_IN3 0x0008 ++#define ASB100_ALARM_TEMP1 0x0010 ++#define ASB100_ALARM_TEMP2 0x0020 ++#define ASB100_ALARM_FAN1 0x0040 ++#define ASB100_ALARM_FAN2 0x0080 ++#define ASB100_ALARM_IN4 0x0100 ++#define ASB100_ALARM_IN5 0x0200 /* ? */ ++#define ASB100_ALARM_IN6 0x0400 /* ? */ ++#define ASB100_ALARM_FAN3 0x0800 ++#define ASB100_ALARM_CHAS 0x1000 ++#define ASB100_ALARM_TEMP3 0x2000 ++ ++#define ASB100_ALARM_IN7 0x10000 /* ? */ ++#define ASB100_ALARM_IN8 0x20000 /* ? */ ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected chip. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++ ++/* no datasheet - but we did get some hints from someone who ++ claimed to have the datasheet */ ++#define ASB100_SYSCTL_IN(nr) {ASB100_SYSCTL_IN##nr, "in" #nr, NULL, 0, \ ++ 0644, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, &asb100_in} ++#define ASB100_SYSCTL_FAN(nr) {ASB100_SYSCTL_FAN##nr, "fan" #nr, NULL, 0, \ ++ 0644, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, &asb100_fan} ++#define ASB100_SYSCTL_TEMP(nr, func) {ASB100_SYSCTL_TEMP##nr, "temp" #nr, \ ++ NULL, 0, 0644, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, func} ++static ctl_table asb100_dir_table_template[] = { ++ ASB100_SYSCTL_IN(0), ++ ASB100_SYSCTL_IN(1), ++ ASB100_SYSCTL_IN(2), ++ ASB100_SYSCTL_IN(3), ++ ASB100_SYSCTL_IN(4), ++ ASB100_SYSCTL_IN(5), ++ ASB100_SYSCTL_IN(6), ++ ++ ASB100_SYSCTL_FAN(1), ++ ASB100_SYSCTL_FAN(2), ++ ASB100_SYSCTL_FAN(3), ++ ++ ASB100_SYSCTL_TEMP(1, &asb100_temp), ++ ASB100_SYSCTL_TEMP(2, &asb100_temp_add), ++ ASB100_SYSCTL_TEMP(3, &asb100_temp_add), ++ ASB100_SYSCTL_TEMP(4, &asb100_temp), ++ ++ {ASB100_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &asb100_vid}, ++ {ASB100_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &asb100_vrm}, ++ {ASB100_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &asb100_fan_div}, ++ {ASB100_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &asb100_alarms}, ++ {ASB100_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &asb100_pwm}, ++ {0} ++}; ++ ++/* This function is called when: ++ asb100_driver is inserted (when this module is loaded), for each ++ available adapter ++ when a new adapter is inserted (and asb100_driver is still present) ++ */ ++static int asb100_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, asb100_detect); ++} ++ ++static int asb100_detect_subclients(struct i2c_adapter *adapter, int address, ++ int kind, struct i2c_client *new_client) ++{ ++ int i, id, err; ++ struct asb100_data *data = new_client->data; ++ ++ data->lm75[0] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); ++ if (!(data->lm75[0])) { ++ err = -ENOMEM; ++ goto ERROR_SC_0; ++ } ++ memset(data->lm75[0], 0x00, sizeof(struct i2c_client)); ++ ++ data->lm75[1] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); ++ if (!(data->lm75[1])) { ++ err = -ENOMEM; ++ goto ERROR_SC_1; ++ } ++ memset(data->lm75[1], 0x00, sizeof(struct i2c_client)); ++ ++ id = i2c_adapter_id(adapter); ++ ++ if (force_subclients[0] == id && force_subclients[1] == address) { ++ for (i = 2; i <= 3; i++) { ++ if (force_subclients[i] < 0x48 || ++ force_subclients[i] > 0x4f) { ++ printk(KERN_ERR "asb100.o: invalid subclient " ++ "address %d; must be 0x48-0x4f\n", ++ force_subclients[i]); ++ err = -ENODEV; ++ goto ERROR_SC_2; ++ } ++ } ++ asb100_write_value(new_client, ASB100_REG_I2C_SUBADDR, ++ (force_subclients[2] & 0x07) | ++ ((force_subclients[3] & 0x07) <<4)); ++ data->lm75[0]->addr = force_subclients[2]; ++ data->lm75[1]->addr = force_subclients[3]; ++ } else { ++ int val = asb100_read_value(new_client, ASB100_REG_I2C_SUBADDR); ++ data->lm75[0]->addr = 0x48 + (val & 0x07); ++ data->lm75[1]->addr = 0x48 + ((val >> 4) & 0x07); ++ } ++ ++ if(data->lm75[0]->addr == data->lm75[1]->addr) { ++ printk(KERN_ERR "asb100.o: duplicate addresses 0x%x " ++ "for subclients\n", data->lm75[0]->addr); ++ err = -ENODEV; ++ goto ERROR_SC_2; ++ } ++ ++ for (i = 0; i <= 1; i++) { ++ data->lm75[i]->data = NULL; ++ data->lm75[i]->adapter = adapter; ++ data->lm75[i]->driver = &asb100_driver; ++ data->lm75[i]->flags = 0; ++ strcpy(data->lm75[i]->name, "asb100 subclient"); ++ } ++ ++ if ((err = i2c_attach_client(data->lm75[0]))) { ++ printk(KERN_ERR "asb100.o: Subclient %d registration " ++ "at address 0x%x failed.\n", i, data->lm75[0]->addr); ++ goto ERROR_SC_2; ++ } ++ ++ if ((err = i2c_attach_client(data->lm75[1]))) { ++ printk(KERN_ERR "asb100.o: Subclient %d registration " ++ "at address 0x%x failed.\n", i, data->lm75[1]->addr); ++ goto ERROR_SC_3; ++ } ++ ++ return 0; ++ ++/* Undo inits in case of errors */ ++ERROR_SC_3: ++ i2c_detach_client(data->lm75[0]); ++ERROR_SC_2: ++ kfree(data->lm75[1]); ++ERROR_SC_1: ++ kfree(data->lm75[0]); ++ERROR_SC_0: ++ return err; ++} ++ ++static int asb100_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int err; ++ struct i2c_client *new_client; ++ struct asb100_data *data; ++ ++ /* asb100 is SMBus only */ ++ if (i2c_is_isa_adapter(adapter)) { ++ pr_debug("asb100.o: detect failed, " ++ "cannot attach to legacy adapter!\n"); ++ err = -ENODEV; ++ goto ERROR0; ++ } ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { ++ pr_debug("asb100.o: detect failed, " ++ "smbus byte data not supported!\n"); ++ err = -ENODEV; ++ goto ERROR0; ++ } ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access asb100_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct asb100_data), GFP_KERNEL))) { ++ pr_debug("asb100.o: detect failed, kmalloc failed!\n"); ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ init_MUTEX(&data->lock); ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &asb100_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ ++ /* The chip may be stuck in some other bank than bank 0. This may ++ make reading other information impossible. Specify a force=... or ++ force_*=... parameter, and the chip will be reset to the right ++ bank. */ ++ if (kind < 0) { ++ ++ int val1 = asb100_read_value(new_client, ASB100_REG_BANK); ++ int val2 = asb100_read_value(new_client, ASB100_REG_CHIPMAN); ++ ++ /* If we're in bank 0 */ ++ if ( (!(val1 & 0x07)) && ++ /* Check for ASB100 ID (low byte) */ ++ ( ((!(val1 & 0x80)) && (val2 != 0x94)) || ++ /* Check for ASB100 ID (high byte ) */ ++ ((val1 & 0x80) && (val2 != 0x06)) ) ) { ++ pr_debug("asb100.o: detect failed, " ++ "bad chip id 0x%02x!\n", val2); ++ err = -ENODEV; ++ goto ERROR1; ++ } ++ ++ } /* kind < 0 */ ++ ++ /* We have either had a force parameter, or we have already detected ++ Winbond. Put it now into bank 0 and Vendor ID High Byte */ ++ asb100_write_value(new_client, ASB100_REG_BANK, ++ (asb100_read_value(new_client, ASB100_REG_BANK) & 0x78) | 0x80); ++ ++ /* Determine the chip type. */ ++ if (kind <= 0) { ++ int val1 = asb100_read_value(new_client, ASB100_REG_WCHIPID); ++ int val2 = asb100_read_value(new_client, ASB100_REG_CHIPMAN); ++ ++ if ((val1 == 0x31) && (val2 == 0x06)) ++ kind = asb100; ++ else { ++ if (kind == 0) ++ printk (KERN_WARNING "asb100.o: Ignoring " ++ "'force' parameter for unknown chip " ++ "at adapter %d, address 0x%02x.\n", ++ i2c_adapter_id(adapter), address); ++ err = -ENODEV; ++ goto ERROR1; ++ } ++ } ++ ++ /* Fill in remaining client fields and put it into the global list */ ++ strcpy(new_client->name, "ASB100 chip"); ++ data->type = kind; ++ ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR1; ++ ++ /* Attach secondary lm75 clients */ ++ if ((err = asb100_detect_subclients(adapter, address, kind, ++ new_client))) ++ goto ERROR2; ++ ++ /* Initialize the chip */ ++ asb100_init_client(new_client); ++ ++ /* Register a new directory entry with module sensors */ ++ if ((data->sysctl_id = i2c_register_entry(new_client, "asb100", ++ asb100_dir_table_template)) < 0) { ++ err = data->sysctl_id; ++ goto ERROR3; ++ } ++ ++ return 0; ++ ++ERROR3: ++ i2c_detach_client(data->lm75[0]); ++ kfree(data->lm75[1]); ++ kfree(data->lm75[0]); ++ERROR2: ++ i2c_detach_client(new_client); ++ERROR1: ++ kfree(data); ++ERROR0: ++ return err; ++} ++ ++static int asb100_detach_client(struct i2c_client *client) ++{ ++ int err; ++ struct asb100_data *data = client->data; ++ ++ /* remove sysctl table (primary client only) */ ++ if ((data)) ++ i2c_deregister_entry(data->sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk (KERN_ERR "asb100.o: Client deregistration failed; " ++ "client not detached.\n"); ++ return err; ++ } ++ ++ if (data) { ++ /* primary client */ ++ kfree(data); ++ } else { ++ /* subclients */ ++ kfree(client); ++ } ++ ++ return 0; ++} ++ ++/* The SMBus locks itself, usually, but nothing may access the Winbond between ++ bank switches. ISA access must always be locked explicitly! ++ We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, ++ would slow down the W83781D access and should not be necessary. ++ There are some ugly typecasts here, but the good news is - they should ++ nowhere else be necessary! */ ++static int asb100_read_value(struct i2c_client *client, u16 reg) ++{ ++ struct asb100_data *data = client->data; ++ struct i2c_client *cl; ++ int res, bank; ++ ++ down(&data->lock); ++ ++ bank = (reg >> 8) & 0x0f; ++ if (bank > 2) ++ /* switch banks */ ++ i2c_smbus_write_byte_data(client, ASB100_REG_BANK, bank); ++ ++ if (bank == 0 || bank > 2) { ++ res = i2c_smbus_read_byte_data(client, reg & 0xff); ++ } else { ++ /* switch to subclient */ ++ cl = data->lm75[bank - 1]; ++ ++ /* convert from ISA to LM75 I2C addresses */ ++ switch (reg & 0xff) { ++ case 0x50: /* TEMP */ ++ res = swab16(i2c_smbus_read_word_data (cl, 0)); ++ break; ++ case 0x52: /* CONFIG */ ++ res = i2c_smbus_read_byte_data(cl, 1); ++ break; ++ case 0x53: /* HYST */ ++ res = swab16(i2c_smbus_read_word_data (cl, 2)); ++ break; ++ case 0x55: /* MAX */ ++ default: ++ res = swab16(i2c_smbus_read_word_data (cl, 3)); ++ break; ++ } ++ } ++ ++ if (bank > 2) ++ i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0); ++ ++ up(&data->lock); ++ ++ return res; ++} ++ ++static void asb100_write_value(struct i2c_client *client, u16 reg, u16 value) ++{ ++ struct asb100_data *data = client->data; ++ struct i2c_client *cl; ++ int bank; ++ ++ down(&data->lock); ++ ++ bank = (reg >> 8) & 0x0f; ++ if (bank > 2) ++ /* switch banks */ ++ i2c_smbus_write_byte_data(client, ASB100_REG_BANK, bank); ++ ++ if (bank == 0 || bank > 2) { ++ i2c_smbus_write_byte_data(client, reg & 0xff, value & 0xff); ++ } else { ++ /* switch to subclient */ ++ cl = data->lm75[bank - 1]; ++ ++ /* convert from ISA to LM75 I2C addresses */ ++ switch (reg & 0xff) { ++ case 0x52: /* CONFIG */ ++ i2c_smbus_write_byte_data(cl, 1, value & 0xff); ++ break; ++ case 0x53: /* HYST */ ++ i2c_smbus_write_word_data(cl, 2, swab16(value)); ++ break; ++ case 0x55: /* MAX */ ++ i2c_smbus_write_word_data(cl, 3, swab16(value)); ++ break; ++ } ++ } ++ ++ if (bank > 2) ++ i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0); ++ ++ up(&data->lock); ++} ++ ++static void asb100_init_client(struct i2c_client *client) ++{ ++ struct asb100_data *data = client->data; ++ int vid = 0; ++ ++ vid = asb100_read_value(client, ASB100_REG_VID_FANDIV) & 0x0f; ++ vid |= (asb100_read_value(client, ASB100_REG_CHIPID) & 0x01) << 4; ++ data->vrm = ASB100_DEFAULT_VRM; ++ vid = vid_from_reg(vid, data->vrm); ++ ++ /* Start monitoring */ ++ asb100_write_value(client, ASB100_REG_CONFIG, ++ (asb100_read_value(client, ASB100_REG_CONFIG) & 0xf7) | 0x01); ++} ++ ++static void asb100_update_client(struct i2c_client *client) ++{ ++ struct asb100_data *data = client->data; ++ int i; ++ ++ down(&data->update_lock); ++ ++ if (time_after(jiffies - data->last_updated, HZ + HZ / 2) || ++ time_before(jiffies, data->last_updated) || !data->valid) { ++ ++ pr_debug("asb100.o: starting device update...\n"); ++ ++ /* 7 voltage inputs */ ++ for (i = 0; i < 7; i++) { ++ data->in[i] = asb100_read_value(client, ++ ASB100_REG_IN(i)); ++ data->in_min[i] = asb100_read_value(client, ++ ASB100_REG_IN_MIN(i)); ++ data->in_max[i] = asb100_read_value(client, ++ ASB100_REG_IN_MAX(i)); ++ } ++ ++ /* 3 fan inputs */ ++ for (i = 1; i <= 3; i++) { ++ data->fan[i-1] = asb100_read_value(client, ++ ASB100_REG_FAN(i)); ++ data->fan_min[i-1] = asb100_read_value(client, ++ ASB100_REG_FAN_MIN(i)); ++ } ++ ++ /* 4 temperature inputs */ ++ for (i = 1; i <= 4; i++) { ++ data->temp[i-1] = asb100_read_value(client, ++ ASB100_REG_TEMP(i)); ++ data->temp_max[i-1] = asb100_read_value(client, ++ ASB100_REG_TEMP_MAX(i)); ++ data->temp_hyst[i-1] = asb100_read_value(client, ++ ASB100_REG_TEMP_HYST(i)); ++ } ++ ++ /* VID and fan divisors */ ++ i = asb100_read_value(client, ASB100_REG_VID_FANDIV); ++ data->vid = i & 0x0f; ++ data->vid |= (asb100_read_value(client, ++ ASB100_REG_CHIPID) & 0x01) << 4; ++ data->fan_div[0] = (i >> 4) & 0x03; ++ data->fan_div[1] = (i >> 6) & 0x03; ++ data->fan_div[2] = (asb100_read_value(client, ++ ASB100_REG_PIN) >> 6) & 0x03; ++ ++ /* PWM */ ++ data->pwm = asb100_read_value(client, ASB100_REG_PWM1); ++ ++ /* alarms */ ++ data->alarms = asb100_read_value(client, ASB100_REG_ALARM1) + ++ (asb100_read_value(client, ASB100_REG_ALARM2) << 8); ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ ++ pr_debug("asb100.o: ... update complete.\n"); ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the date ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++static void asb100_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct asb100_data *data = client->data; ++ int nr = ctl_name - ASB100_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ asb100_update_client(client); ++ results[0] = IN_FROM_REG(data->in_min[nr]); ++ results[1] = IN_FROM_REG(data->in_max[nr]); ++ results[2] = IN_FROM_REG(data->in[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = IN_TO_REG(results[0]); ++ asb100_write_value(client, ASB100_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = IN_TO_REG(results[1]); ++ asb100_write_value(client, ASB100_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++} ++ ++void asb100_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct asb100_data *data = client->data; ++ int nr = ctl_name - ASB100_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ asb100_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ results[1] = FAN_FROM_REG(data->fan[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = ++ FAN_TO_REG(results[0], ++ DIV_FROM_REG(data->fan_div[nr-1])); ++ asb100_write_value(client, ++ ASB100_REG_FAN_MIN(nr), ++ data->fan_min[nr - 1]); ++ } ++ } ++} ++ ++void asb100_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct asb100_data *data = client->data; ++ int nr = ctl_name - ASB100_SYSCTL_TEMP1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ asb100_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_max[nr]); ++ results[1] = TEMP_FROM_REG(data->temp_hyst[nr]); ++ results[2] = TEMP_FROM_REG(data->temp[nr]); ++ *nrels_mag = 3; ++ ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_max[nr] = TEMP_TO_REG(results[0]); ++ asb100_write_value(client, ASB100_REG_TEMP_MAX(nr+1), ++ data->temp_max[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst[nr] = TEMP_TO_REG(results[1]); ++ asb100_write_value(client, ASB100_REG_TEMP_HYST(nr+1), ++ data->temp_hyst[nr]); ++ } ++ } ++} ++ ++void asb100_temp_add(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct asb100_data *data = client->data; ++ int nr = ctl_name - ASB100_SYSCTL_TEMP1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ asb100_update_client(client); ++ ++ results[0] = LM75_TEMP_FROM_REG(data->temp_max[nr]); ++ results[1] = LM75_TEMP_FROM_REG(data->temp_hyst[nr]); ++ results[2] = LM75_TEMP_FROM_REG(data->temp[nr]); ++ *nrels_mag = 3; ++ ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_max[nr] = ++ LM75_TEMP_TO_REG(results[0]); ++ asb100_write_value(client, ASB100_REG_TEMP_MAX(nr+1), ++ data->temp_max[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst[nr] = ++ LM75_TEMP_TO_REG(results[1]); ++ asb100_write_value(client, ASB100_REG_TEMP_HYST(nr+1), ++ data->temp_hyst[nr]); ++ } ++ } ++} ++ ++void asb100_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct asb100_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ asb100_update_client(client); ++ results[0] = vid_from_reg(data->vid, data->vrm); ++ *nrels_mag = 1; ++ } ++} ++ ++void asb100_vrm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct asb100_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->vrm; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) ++ data->vrm = results[0]; ++ } ++} ++ ++void asb100_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct asb100_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ asb100_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++void asb100_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct asb100_data *data = client->data; ++ int old, old2; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ asb100_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ results[2] = DIV_FROM_REG(data->fan_div[2]); ++ *nrels_mag = 3; ++ ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = asb100_read_value(client, ASB100_REG_VID_FANDIV); ++ if (*nrels_mag >= 3) { ++ data->fan_div[2] = DIV_TO_REG(results[2]); ++ old2 = asb100_read_value(client, ASB100_REG_PIN); ++ old2 = (old2 & 0x3f) | ((data->fan_div[2] & 0x03) << 6); ++ asb100_write_value(client, ASB100_REG_PIN, old2); ++ } ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ old = (old & 0x3f) | ((data->fan_div[1] & 0x03) << 6); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ old = (old & 0xcf) | ((data->fan_div[0] & 0x03) << 4); ++ asb100_write_value(client, ASB100_REG_VID_FANDIV, old); ++ } ++ } ++} ++ ++void asb100_pwm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct asb100_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ asb100_update_client(client); ++ results[0] = ASB100_PWM_FROM_REG(data->pwm & 0x0f); ++ results[1] = (data->pwm & 0x80) ? 1 : 0; ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ u8 val = data->pwm; ++ if (*nrels_mag >= 1) { ++ val = 0x0f & ASB100_PWM_TO_REG(results[0]); ++ if (*nrels_mag >= 2) { ++ if (results[1]) ++ val |= 0x80; ++ else ++ val &= ~0x80; ++ } ++ asb100_write_value(client, ASB100_REG_PWM1, val); ++ } ++ } ++} ++ ++static int __init asb100_init(void) ++{ ++ printk(KERN_INFO "asb100.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&asb100_driver); ++} ++ ++static void __exit asb100_exit(void) ++{ ++ i2c_del_driver(&asb100_driver); ++} ++ ++MODULE_AUTHOR( "Mark M. Hoffman , " ++ "Frodo Looijaard , " ++ "Philip Edelbrock , and" ++ "Mark Studebaker "); ++ ++MODULE_DESCRIPTION("ASB100 'Bach' driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(asb100_init); ++module_exit(asb100_exit); ++ +--- linux-old/drivers/sensors/bt869.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/bt869.c Mon Dec 13 20:18:45 2004 +@@ -0,0 +1,891 @@ ++/* ++ bt869.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ ++ Copyright (c) 1998, 1999 Frodo Looijaard ++ Copyright (c) 2001, 2002 Stephen Davies ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++ ++#define DEBUG 1 ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++ ++/* found only at 0x44 or 0x45 */ ++static unsigned short normal_i2c_range[] = { 0x44, 0x45, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(bt869); ++ ++/* Many bt869 constants specified below */ ++ ++/* The bt869 registers */ ++/* Coming soon: Many, many registers */ ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++ ++ /*none */ ++ ++/* Initial values */ ++/*none*/ ++ ++/* Each client has this additional data */ ++struct bt869_data { ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 status[3]; /* Register values */ ++ u16 res[2]; /* Resolution XxY */ ++ u8 ntsc; /* 1=NTSC, 0=PAL */ ++ u8 half; /* go half res */ ++ u8 depth; /* screen depth */ ++ u8 colorbars; /* turn on/off colorbar calibration screen */ ++ u8 svideo; /* output format: (2=RGB) 1=SVIDEO, 0=Composite */ ++}; ++ ++static int bt869_attach_adapter(struct i2c_adapter *adapter); ++static int bt869_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static void bt869_init_client(struct i2c_client *client); ++static int bt869_detach_client(struct i2c_client *client); ++static int bt869_read_value(struct i2c_client *client, u8 reg); ++static int bt869_write_value(struct i2c_client *client, u8 reg, u16 value); ++static void bt869_write_values(struct i2c_client *client, u16 *values); ++static void bt869_status(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void bt869_ntsc(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void bt869_res(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void bt869_half(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void bt869_colorbars(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void bt869_svideo(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void bt869_depth(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void bt869_update_client(struct i2c_client *client); ++ ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver bt869_driver = { ++ .owner = THIS_MODULE, ++ .name = "BT869 video-output chip driver", ++ .id = I2C_DRIVERID_BT869, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = bt869_attach_adapter, ++ .detach_client = bt869_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++#define BT869_SYSCTL_STATUS 1000 ++#define BT869_SYSCTL_NTSC 1001 ++#define BT869_SYSCTL_HALF 1002 ++#define BT869_SYSCTL_RES 1003 ++#define BT869_SYSCTL_COLORBARS 1004 ++#define BT869_SYSCTL_DEPTH 1005 ++#define BT869_SYSCTL_SVIDEO 1006 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected bt869. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table bt869_dir_table_template[] = { ++ {BT869_SYSCTL_STATUS, "status", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &bt869_status}, ++ {BT869_SYSCTL_NTSC, "ntsc", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &bt869_ntsc}, ++ {BT869_SYSCTL_RES, "res", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &bt869_res}, ++ {BT869_SYSCTL_HALF, "half", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &bt869_half}, ++ {BT869_SYSCTL_COLORBARS, "colorbars", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &bt869_colorbars}, ++ {BT869_SYSCTL_DEPTH, "depth", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &bt869_depth}, ++ {BT869_SYSCTL_SVIDEO, "svideo", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &bt869_svideo}, ++ {0} ++}; ++ ++/* ****************** ++ ++720x576, 27.5MHz, PAL, no overscan compensation. ++ ++This mode should be use for digital video, DVD playback etc. ++ ++NOTE: This mode for PAL, see 720x480 for an equivalent NTSC mode ++NOTE: -- Steve Davies ++ ++ ++Compatible X modeline: ++ ++ Mode "720x576-BT869" ++ DotClock 27.5 ++ HTimings 720 744 800 880 ++ VTimings 576 581 583 625 ++ EndMode ++ ++ ++625LINE=1 625 line output format ++BST_AMP[7:0]=x57 87 Burst ampl. multiplication factor (PAL std??) ++BY_PLL=0 Use the PLL ++CATTENUATE[2:0]=0 No chroma attenuation ++CCF1B1[7:0]=0 close caption stuff ++CCF1B2[7:0]=0 close caption stuff ++CCF2B1[7:0]=0 close caption stuff ++CCF2B2[7:0]=0 close caption stuff ++CCORING[2:0]=0 Bypass chroma coring ++CCR_START[8:0]=0 [CCR_START[8]=0; CCR_START[7:0]=0] Close-caption clock runin start from hsync ++CC_ADD[11:0]=xD2 210 [CC_ADD[11:8]=0; CC_ADD[7:0]=xD2] Close-caption DTO increment ++CHECK_STAT=0 Don't check monitor status ++CLPF[1:0]=0 Hoz chroma lowpass filter=Bypass ++DACDISA=1 Disable DACA ++DACDISB=0 Don't disable DACB ++DACDISC=0 Don't disable DACC ++DACOFF=0 Don't disable the DACs ++DATDLY = 0 normal ++DATSWP=0 normal ++DCHROMA=0 Don't blank chroma ++DIS_FFILT=1 Disable flickerfilter ++DIS_GMSHC=1 Disable chroma psuedo-gamma removal ++DIS_GMSHY=1 Disable luma pseudo gamma removal ++DIS_GMUSHC=1 Disable chroma anti-pseudo gamma removal ++DIS_GMUSHY=1 Disable luma anti-pseudo gamma removal ++DIS_SCRESET=0 Normal subcarrier phase resets ++DIS_YFLPF=0 Disable Luma initial hoz low pass filter ++DIV2=0 Input pixel rate not divided by 2 ++ECBAR=0 No colour bars ++ECCF1=0 Disable closed caption ++ECCF2=0 Disable closed caption ++ECCGATE=0 Normal close caption encoding ++ECLIP=0 0=disable clipping ++EN_ASYNC=0 set to 0 for normal operation ++EN_BLANKO=0 BLANK is an input ++EN_DOT=0 Disables dot clock sync on BLANK pin ++EN_OUT=1 Allows outputs to be enabled ++EN_XCLK=1 Use CLKI pin as clock source ++ESTATUS[1:0]=0 Used to select readback register ++FIELDI=0 Logical 1 on FIELD indicates even field ++F_SELC[2:0]=0 5 line chroma flickerfilter ++F_SELY[2:0]=0 5 line luma flickerfilter ++HBURST_BEGIN[7:0]=x98 152 Chroma burst start point in clocks ++HBURST_END[7:0]=x58 88 Chroma burst end point in clocks - 128 ++HSYNCI=0 Active low HSYNC ++HSYNC_WIDTH[7:0]=x80 128 Analogue sync width in clocks ++HSYNOFFSET[9:0]=0 [HSYNOFFSET[9:8]=0; HSYNOFFSET[7:0]=0] hsync in "standard position" ++HSYNWIDTH[5:0]=2 2 pixel hsync width ++H_ACTIVE[9:0]=x2D0 720 [H_ACTIVE[9:8]=2; H_ACTIVE[7:0]=xD0] Active pixels per line ++H_BLANKI[8:0]=x84 132 [H_BLANKI[8]=0; H_BLANKI[7:0]=x84] End of blanking of input video ++H_BLANKO[9:0]=x120 288 [H_BLANKO[9:8]=1; H_BLANKO[7:0]=x20] End of blanking from hoz sync leading edge ++H_CLKI[10:0]=x378 888 [H_CLKI[10:8]=3; H_CLKI[7:0]=x78] Input line length total in clocks ++H_CLKO[11:0]=x6e0 1760 [H_CLKO[11:8]=6; H_CLKO[7:0]=xe0] Output clocks per line ++H_FRACT[7:0]=0 0 fractional input clocks per line ++IN_MODE[2:0]=0 24Bit RGB muxed ++LUMADLY[1:0]=0 0 pixel delay on Y_DLY luma ++MCB[7:0]=x49 73 Mult factor for CB prior to subcarrier mod. ++MCR[7:0]=x82 130 Mult factor for CR prior to subcarrier mod. ++MODE2X=0 Don't divide clock input by 2 ++MSC[31:0]=x2945E0B4 692445365 [MSC[31:24]=x29; MSC[23:16]=x45; MSC[15:8]=xE0; MSC[7:0]=xB4] Subcarrier incr. ++MY[7:0]=x8C 140 Mult factor for Y ++NI_OUT=0 Normal interlaced output ++OUT_MODE[1:0]=0 video0-3 is CVBS, Y, C, Y_DLY ++OUT_MUXA[1:0]=0 Don't care as DACA is disabled ++OUT_MUXB[1:0]=1 Output video[1] (Y) on DACB ++OUT_MUXC[1:0]=2 Output video[2] (C) on DACC ++PAL_MD=1 Video output in PAL mode ++PHASE_OFF[7:0]=0 Subcarrier phase offset ++PLL_FRACT[15:0]=x30 48 [PLL_FRACT[15:8]=0x0; PLL_FRACT[7:0]=x30] frac portion of pll multiplier ++PLL_INT[5:0]=0x0C 12 Int portion of pll multiplier ++SETUP=0 7.5-IRE setup disabled ++SLAVER=1 ++SRESET=0 Don't do a software reset ++SYNC_AMP[7:0]=xF0 240 Sync amp mult. factor (PAL std???) ++VBLANKDLY=0 Extra line of blanking in 2nd field? ++VSYNCI=0 Active low VSYNC ++VSYNC_DUR=0 2.5line VSYNC duration on output ++VSYNCOFFSET[10:0]=0 [VSYNOFFSET[10:8]=0; VSYNOFFSET[7:0]=0] VSYNC in standard position ++VSYNWIDTH[2:0]=1 1 line of vsync width ++V_ACTIVEI[9:0]=x240 576 [V_ACTIVEI[9:0]=2; V_ACTIVEI[7:0]=x40] Active input lines ++V_ACTIVEO[8:0]=x122 290 [V_ACTIVE0[8]=1; V_ACTIVEO[7:0]=x22] ++V_BLANKI[7:0]=x2A 42 Input lines from vsync to first active line ++V_BLANKO[7:0]=x16 22 ++V_LINESI[9:0]=x271 625 [V_LINESI[9:8]=2; V_LINESI[7:0]=x71] Number of input lines ++V_SCALE[13:0]=x1000 4096 [V_SCALE[13:8]=x10; V_SCALE[7:0]=0] Vert scale coefficient="none"? ++YATTENUATE[2:0]=0 no luma attenuation ++YCORING[2:0]=0 Luma-coring bypass ++YLPF[1:0]=0 Luma hoz low pass filter=bypass ++ ++***************** */ ++ ++static u16 registers_720_576[] = ++ { ++ 0x6e, 0x00, /* HSYNOFFSET[7:0]=0 */ ++ 0x70, 0x02, /* HSYNOFFSET[9:8]=0; HSYNWIDTH[5:0]=2 */ ++ 0x72, 0x00, /* VSYNOFFSET[7:0]=0 */ ++ 0x74, 0x01, /* DATDLY = 0; DATSWP=0; VSYNOFFSET[10:8]=0; VSYNWIDTH[2:0]=1 */ ++ 0x76, 0xe0, /* H_CLKO[7:0]=xe0 */ ++ 0x78, 0xd0, /* H_ACTIVE[7:0]=xD0 */ ++ 0x7a, 0x80, /* HSYNC_WIDTH[7:0]=x80 */ ++ 0x7c, 0x98, /* HBURST_BEGIN[7:0]=x98 */ ++ 0x7e, 0x58, /* HBURST_END[7:0]=x58 */ ++ 0x80, 0x20, /* H_BLANKO[7:0]=x20 */ ++ 0x82, 0x16, /* V_BLANKO[7:0]=x16 */ ++ 0x84, 0x22, /* V_ACTIVEO[7:0]=x22 */ ++ 0x86, 0xa6, /* V_ACTIVE0[8]=1; H_ACTIVE[9:8]=2; H_CLKO[11:8]=6 */ ++ 0x88, 0x00, /* H_FRACT[7:0]=0 */ ++ 0x8a, 0x78, /* H_CLKI[7:0]=x78 */ ++ 0x8c, 0x80, /* H_BLANKI[7:0]=x84 */ ++ 0x8e, 0x03, /* VBLANKDLY=0; H_BLANKI[8]=0; H_CLKI[10:8]=3 */ ++ 0x90, 0x71, /* V_LINESI[7:0]=x71 */ ++ 0x92, 0x2a, /* V_BLANKI[7:0]=x2A */ ++ 0x94, 0x40, /* V_ACTIVEI[7:0]=x40 */ ++ 0x96, 0x0a, /* CLPF[1:0]=0; YLPF[1:0]=0; V_ACTIVEI[9:0]=2; V_LINESI[9:8]=2 */ ++ 0x98, 0x00, /* V_SCALE[7:0]=0 */ ++ 0x9a, 0x50, /* H_BLANKO[9:8]=1; V_SCALE[13:8]=x10 */ ++ 0x9c, 0x30, /* PLL_FRACT[7:0]=x30 */ ++ 0x9e, 0x0, /* PLL_FRACT[15:8]=0x0 */ ++ 0xa0, 0x8c, /* EN_XCLK=1; BY_PLL=0; PLL_INT[5:0]=0x0C */ ++ 0xa2, 0x24, /* ECLIP=0; PAL_MD=1; DIS_SCRESET=0; VSYNC_DUR=0; 625LINE=1; SETUP=0; NI_OUT=0 */ ++ 0xa4, 0xf0, /* SYNC_AMP[7:0]=xF0 */ ++ 0xa6, 0x57, /* BST_AMP[7:0]=x57 */ ++ 0xa8, 0x82, /* MCR[7:0]=x82 */ ++ 0xaa, 0x49, /* MCB[7:0]=x49 */ ++ 0xac, 0x8c, /* MY[7:0]=x8C */ ++ 0xae, 0xb4, /* MSC[7:0]=xb4 */ ++ 0xb0, 0xe0, /* MSC[15:8]=xe0 */ ++ 0xb2, 0x45, /* MSC[23:16]=x45 */ ++ 0xb4, 0x29, /* MSC[31:24]=x29 */ ++ 0xb6, 0x00, /* PHASE_OFF[7:0]=0 */ ++ //0xba, 0x21, /* SRESET=0; CHECK_STAT=0; SLAVER=1; DACOFF=0; DACDISC=0; DACDISB=0; DACDISA=1 */ ++ 0xc4, 0x01, /* ESTATUS[1:0]=0; ECCF2=0; ECCF1=0; ECCGATE=0; ECBAR=0; DCHROMA=0; EN_OUT=1 */ ++ 0xc6, 0x00, /* EN_BLANKO=0; EN_DOT=0; FIELDI=0; VSYNCI=0; HSYNCI=0; IN_MODE[2:0]=0(24bRGB) */ ++ 0xc8, 0x40, /* DIS_YFLPF=0; DIS_FFILT=1; F_SELC[2:0]=0; F_SELY[2:0]=0 */ ++ 0xca, 0xc0, /* DIS_GMUSHY=1; DIS_GMSHY=1; YCORING[2:0]=0; YATTENUATE[2:0]=0 */ ++ 0xcc, 0xc0, /* DIS_GMUSHC=1; DIS_GMSHC=1; CCORING[2:0]=0; CATTENUATE[2:0]=0 */ ++ //0xce, 0x24, /* OUT_MUXC=2 [C]; OUT_MUXB=1 [Y]; OUT_MUXA=0 [CVBS, but disabled]*/ ++ //0xce, 0x04, /* OUT_MUXC=0 [CVBS]; OUT_MUXB=1 [Y]; OUT_MUXA=0 [CVBS, but disabled]*/ ++ 0xd6, 0x00, /* OUT_MODE[1:0]=0; LUMADLY[1:0]=0 */ ++ 0, 0 ++ }; ++ ++ ++/* ****************** ++ ++720x480, 27.5MHz, NTSC no overscan compensation. ++ ++This mode should be use for digital video, DVD playback etc. ++ ++NOTE: This mode for NTSC, see 720x576 for an equivalent PAL mode ++NOTE: -- Steve Davies ++ ++Compatible X modeline: ++ ++ Mode "720x480-BT869" ++ DotClock 27.5 ++ HTimings 720 744 800 872 ++ VTimings 480 483 485 525 ++ EndMode ++ ++ ++625LINE=0 not 625 line output format ++BST_AMP[7:0]=x74 116 Burst ampl. multiplication factor (NTSC std??) ++BY_PLL=0 Use the PLL ++CATTENUATE[2:0]=0 No chroma attenuation ++CCF1B1[7:0]=0 close caption stuff ++CCF1B2[7:0]=0 close caption stuff ++CCF2B1[7:0]=0 close caption stuff ++CCF2B2[7:0]=0 close caption stuff ++CCORING[2:0]=0 Bypass chroma coring ++CCR_START[8:0]=0 [CCR_START[8]=0; CCR_START[7:0]=0] Close-caption clock runin start from hsync ++CC_ADD[11:0]=xD2 210 [CC_ADD[11:8]=0; CC_ADD[7:0]=xD2] Close-caption DTO increment ++CHECK_STAT=0 Don't check monitor status ++CLPF[1:0]=0 Hoz chroma lowpass filter=Bypass ++DACDISA=1 Disable DACA ++DACDISB=0 Don't disable DACB ++DACDISC=0 Don't disable DACC ++DACOFF=0 Don't disable the DACs ++DATDLY = 0 normal ++DATSWP=0 normal ++DCHROMA=0 Don't blank chroma ++DIS_FFILT=1 Disable flickerfilter ++DIS_GMSHC=1 Disable chroma psuedo-gamma removal ++DIS_GMSHY=1 Disable luma pseudo gamma removal ++DIS_GMUSHC=1 Disable chroma anti-pseudo gamma removal ++DIS_GMUSHY=1 Disable luma anti-pseudo gamma removal ++DIS_SCRESET=0 Normal subcarrier phase resets ++DIS_YFLPF=0 Disable Luma initial hoz low pass filter ++DIV2=0 Input pixel rate not divided by 2 ++ECBAR=0 No colour bars ++ECCF1=0 Disable closed caption ++ECCF2=0 Disable closed caption ++ECCGATE=0 Normal close caption encoding ++ECLIP=0 0=disable clipping ++EN_ASYNC=0 set to 0 for normal operation ++EN_BLANKO=0 BLANK is an input ++EN_DOT=0 Disables dot clock sync on BLANK pin ++EN_OUT=1 Allows outputs to be enabled ++EN_XCLK=1 Use CLKI pin as clock source ++ESTATUS[1:0]=0 Used to select readback register ++FIELDI=0 Logical 1 on FIELD indicates even field ++F_SELC[2:0]=0 5 line chroma flickerfilter ++F_SELY[2:0]=0 5 line luma flickerfilter ++HBURST_BEGIN[7:0]=x92 146 Chroma burst start point in clocks ++HBURST_END[7:0]=x57 87 Chroma burst end point in clocks - 128 ++HSYNCI=0 Active low HSYNC ++HSYNC_WIDTH[7:0]=x80 128 Analogue sync width in clocks ++HSYNOFFSET[9:0]=0 [HSYNOFFSET[9:8]=0; HSYNOFFSET[7:0]=0] hsync in "standard position" ++HSYNWIDTH[5:0]=2 2 pixel hsync width ++H_ACTIVE[9:0]=x2D0 720 [H_ACTIVE[9:8]=2; H_ACTIVE[7:0]=xD0] Active pixels per line ++H_BLANKI[8:0]=x80 128 [H_BLANKI[8]=0; H_BLANKI[7:0]=x80] End of blanking of input video ++H_BLANKO[9:0]=x102 258 [H_BLANKO[9:8]=1; H_BLANKO[7:0]=x2] End of blanking from hoz sync leading edge ++H_CLKI[10:0]=x368 872 [H_CLKI[10:8]=3; H_CLKI[7:0]=x68] Input line length total in clocks ++H_CLKO[11:0]=x6d0 1744 [H_CLKO[11:8]=6; H_CLKO[7:0]=xD0] Output clocks per line ++H_FRACT[7:0]=0 0 fractional input clocks per line ++IN_MODE[2:0]=0 24Bit RGB muxed ++LUMADLY[1:0]=0 0 pixel delay on Y_DLY luma ++MCB[7:0]=x43 67 Mult factor for CB prior to subcarrier mod. ++MCR[7:0]=x77 119 Mult factor for CR prior to subcarrier mod. ++MODE2X=0 Don't divide clock input by 2 ++MSC[31:0]=x215282E5 559055589 [MSC[31:24]=x21; MSC[23:16]=x52; MSC[15:8]=x82; MSC[7:0]=xE5] Subcarrier incr. ++MY[7:0]=x85 133 Mult factor for Y ++NI_OUT=0 Normal interlaced output ++OUT_MODE[1:0]=0 video0-3 is CVBS, Y, C, Y_DLY ++OUT_MUXA[1:0]=0 Don't care as DACA is disabled ++OUT_MUXB[1:0]=1 Output video[1] (Y) on DACB ++OUT_MUXC[1:0]=2 Output video[2] (C) on DACC ++PAL_MD=0 Video output in PAL mode? No. ++PHASE_OFF[7:0]=0 Subcarrier phase offset ++PLL_FRACT[15:0]=x30 48 [PLL_FRACT[15:8]=0x0; PLL_FRACT[7:0]=x30] frac portion of pll multiplier ++PLL_INT[5:0]=0x0C 12 Int portion of pll multiplier ++SETUP=1 7.5-IRE enabled for NTSC ++SLAVER=1 ++SRESET=0 Don't do a software reset ++SYNC_AMP[7:0]=xE5 229 Sync amp mult. factor (PAL std???) ++VBLANKDLY=0 Extra line of blanking in 2nd field? ++VSYNCI=0 Active low VSYNC ++VSYNC_DUR=1 2.5line VSYNC duration on output (Yes for NTSC) ++VSYNCOFFSET[10:0]=0 [VSYNOFFSET[10:8]=0; VSYNOFFSET[7:0]=0] VSYNC in standard position ++VSYNWIDTH[2:0]=1 1 line of vsync width ++V_ACTIVEI[9:0]=x1E0 480 [V_ACTIVEI[9:0]=1; V_ACTIVEI[7:0]=xE0] Active input lines ++V_ACTIVEO[8:0]=xF0 240 [V_ACTIVE0[8]=0; V_ACTIVEO[7:0]=xF0] ++V_BLANKI[7:0]=x2A 42 Input lines from vsync to first active line ++V_BLANKO[7:0]=x16 22 ++V_LINESI[9:0]=x20D 525 [V_LINESI[9:8]=2; V_LINESI[7:0]=x0D] Number of input lines ++V_SCALE[13:0]=x1000 4096 [V_SCALE[13:8]=x10; V_SCALE[7:0]=0] Vert scale coefficient="none"? ++YATTENUATE[2:0]=0 no luma attenuation ++YCORING[2:0]=0 Luma-coring bypass ++YLPF[1:0]=0 Luma hoz low pass filter=bypass ++ ++***************** */ ++ ++static u16 registers_720_480[] = ++ { ++ 0x6e, 0x00, /* HSYNOFFSET[7:0]=0 */ ++ 0x70, 0x02, /* HSYNOFFSET[9:8]=0; HSYNWIDTH[5:0]=2 */ ++ 0x72, 0x00, /* VSYNOFFSET[7:0]=0 */ ++ 0x74, 0x01, /* DATDLY = 0; DATSWP=0; VSYNOFFSET[10:8]=0; VSYNWIDTH[2:0]=1 */ ++ 0x76, 0xD0, /* H_CLKO[7:0]=xD0 */ ++ 0x78, 0xD0, /* H_ACTIVE[7:0]=xD0 */ ++ 0x7a, 0x80, /* HSYNC_WIDTH[7:0]=x80 */ ++ 0x7c, 0x92, /* HBURST_BEGIN[7:0]=x92 */ ++ 0x7e, 0x57, /* HBURST_END[7:0]=x57 */ ++ 0x80, 0x02, /* H_BLANKO[7:0]=x2 */ ++ 0x82, 0x16, /* V_BLANKO[7:0]=x16 */ ++ 0x84, 0xF0, /* V_ACTIVEO[7:0]=xF0 */ ++ 0x86, 0x26, /* V_ACTIVE0[8]=0; H_ACTIVE[9:8]=2; H_CLKO[11:8]=6 */ ++ 0x88, 0x00, /* H_FRACT[7:0]=0 */ ++ 0x8a, 0xD0, /* H_CLKI[7:0]=xD0 */ ++ 0x8c, 0x80, /* H_BLANKI[7:0]=x80 */ ++ 0x8e, 0x03, /* VBLANKDLY=0; H_BLANKI[8]=0; H_CLKI[10:8]=3 */ ++ 0x90, 0x0D, /* V_LINESI[7:0]=x0D */ ++ 0x92, 0x2A, /* V_BLANKI[7:0]=x2A */ ++ 0x94, 0xE0, /* V_ACTIVEI[7:0]=xE0 */ ++ 0x96, 0x06, /* CLPF[1:0]=0; YLPF[1:0]=0; V_ACTIVEI[9:8]=1; V_LINESI[9:8]=2 */ ++ 0x98, 0x00, /* V_SCALE[7:0]=0 */ ++ 0x9a, 0x50, /* H_BLANKO[9:8]=1; V_SCALE[13:8]=x10 */ ++ 0x9c, 0x30, /* PLL_FRACT[7:0]=x30 */ ++ 0x9e, 0x0, /* PLL_FRACT[15:8]=0x0 */ ++ 0xa0, 0x8c, /* EN_XCLK=1; BY_PLL=0; PLL_INT[5:0]=0x0C */ ++ 0xa2, 0x0A, /* ECLIP=0; PAL_MD=0; DIS_SCRESET=0; VSYNC_DUR=1; 625LINE=0; SETUP=1; NI_OUT=0 */ ++ 0xa4, 0xE5, /* SYNC_AMP[7:0]=xE5 */ ++ 0xa6, 0x74, /* BST_AMP[7:0]=x74 */ ++ 0xa8, 0x77, /* MCR[7:0]=x77 */ ++ 0xaa, 0x43, /* MCB[7:0]=x43 */ ++ 0xac, 0x85, /* MY[7:0]=x85 */ ++ 0xae, 0xE5, /* MSC[7:0]=xE5 */ ++ 0xb0, 0x82, /* MSC[15:8]=x82 */ ++ 0xb2, 0x52, /* MSC[23:16]=x52 */ ++ 0xb4, 0x21, /* MSC[31:24]=x21 */ ++ 0xb6, 0x00, /* PHASE_OFF[7:0]=0 */ ++ //0xba, 0x21, /* SRESET=0; CHECK_STAT=0; SLAVER=1; DACOFF=0; DACDISC=0; DACDISB=0; DACDISA=1 */ ++ 0xc4, 0x01, /* ESTATUS[1:0]=0; ECCF2=0; ECCF1=0; ECCGATE=0; ECBAR=0; DCHROMA=0; EN_OUT=1 */ ++ 0xc6, 0x00, /* EN_BLANKO=0; EN_DOT=0; FIELDI=0; VSYNCI=0; HSYNCI=0; IN_MODE[2:0]=0(24bRGB) */ ++ 0xc8, 0x40, /* DIS_YFLPF=0; DIS_FFILT=1; F_SELC[2:0]=0; F_SELY[2:0]=0 */ ++ 0xca, 0xc0, /* DIS_GMUSHY=1; DIS_GMSHY=1; YCORING[2:0]=0; YATTENUATE[2:0]=0 */ ++ 0xcc, 0xc0, /* DIS_GMUSHC=1; DIS_GMSHC=1; CCORING[2:0]=0; CATTENUATE[2:0]=0 */ ++ //0xce, 0x24, /* OUT_MUXC=2 [C]; OUT_MUXB=1 [Y]; OUT_MUXA=0 [CVBS, but disabled]*/ ++ //0xce, 0x04, /* OUT_MUXC=0 [CVBS]; OUT_MUXB=1 [Y]; OUT_MUXA=0 [CVBS, but disabled]*/ ++ 0xd6, 0x00, /* OUT_MODE[1:0]=0; LUMADLY[1:0]=0 */ ++ 0, 0 ++ }; ++ ++ ++int bt869_id = 0; ++ ++static int bt869_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, bt869_detect); ++} ++ ++/* This function is called by i2c_detect */ ++int bt869_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i, cur; ++ struct i2c_client *new_client; ++ struct bt869_data *data; ++ int err = 0; ++ const char *type_name, *client_name; ++ ++ ++ printk("bt869.o: probing address %d .\n", address); ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("bt869.o: bt869_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE | ++ I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access bt869_{read,write}_value. */ ++ if (!(data = kmalloc(sizeof(struct bt869_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &bt869_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. It is lousy. */ ++ i2c_smbus_write_byte_data(new_client, 0xC4, 0); /* set status bank 0 */ ++ cur = i2c_smbus_read_byte(new_client); ++ printk("bt869.o: address 0x%X testing-->0x%X\n", address, cur); ++ if ((cur & 0xE0) != 0x20) ++ goto ERROR1; ++ ++ /* Determine the chip type */ ++ kind = ((cur & 0x20) >> 5); ++ ++ if (kind) { ++ type_name = "bt869"; ++ client_name = "bt869 chip"; ++ printk("bt869.o: BT869 detected\n"); ++ } else { ++ type_name = "bt868"; ++ client_name = "bt868 chip"; ++ printk("bt869.o: BT868 detected\n"); ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = bt869_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, type_name, ++ bt869_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ bt869_init_client((struct i2c_client *) new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int bt869_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct bt869_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("bt869.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++ ++/* All registers are byte-sized. ++ bt869 uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int bt869_read_value(struct i2c_client *client, u8 reg) ++{ ++ return i2c_smbus_read_byte(client); ++} ++ ++/* All registers are byte-sized. ++ bt869 uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int bt869_write_value(struct i2c_client *client, u8 reg, u16 value) ++{ ++#ifdef DEBUG ++ printk("bt869.o: write_value(0x%X, 0x%X)\n", reg, value); ++#endif ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++static void bt869_write_values(struct i2c_client *client, u16 *values) ++{ ++ /* writes set of registers from array. 0,0 marks end of table */ ++ while (*values) { ++ bt869_write_value(client, values[0], values[1]); ++ values += 2; ++ } ++} ++ ++static void bt869_init_client(struct i2c_client *client) ++{ ++ struct bt869_data *data = client->data; ++ ++ /* Initialize the bt869 chip */ ++ bt869_write_value(client, 0x0ba, 0x80); ++ // bt869_write_value(client,0x0D6, 0x00); ++ /* Be a slave to the clock on the Voodoo3 */ ++ bt869_write_value(client, 0xa0, 0x80); ++ bt869_write_value(client, 0xba, 0x20); ++ /* depth =16bpp */ ++ bt869_write_value(client, 0x0C6, 0x001); ++ bt869_write_value(client, 0xC4, 1); ++ /* Flicker free enable and config */ ++ bt869_write_value(client, 0xC8, 0); ++ data->res[0] = 640; ++ data->res[1] = 480; ++ data->ntsc = 1; ++ data->half = 0; ++ data->colorbars = 0; ++ data->svideo = 0; ++ data->depth = 16; ++ ++} ++ ++static void bt869_update_client(struct i2c_client *client) ++{ ++ struct bt869_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++#ifdef DEBUG ++ printk("Starting bt869 update\n"); ++#endif ++ if ((data->res[0] == 800) && (data->res[1] == 600)) { ++ /* 800x600 built-in mode */ ++ bt869_write_value(client, 0xB8, ++ (2 + (!data->ntsc))); ++ bt869_write_value(client, 0xa0, 0x80 + 0x11); ++ printk("bt869.o: writing into config -->0x%X\n", ++ (2 + (!data->ntsc))); ++ } ++ else if ((data->res[0] == 720) && (data->res[1] == 576)) { ++ /* 720x576 no-overscan-compensation mode suitable for PAL DVD playback */ ++ data->ntsc = 0; /* This mode always PAL */ ++ bt869_write_values(client, registers_720_576); ++ } ++ else if ((data->res[0] == 720) && (data->res[1] == 480)) { ++ /* 720x480 no-overscan-compensation mode suitable for NTSC DVD playback */ ++ data->ntsc = 1; /* This mode always NTSC */ ++ bt869_write_values(client, registers_720_480); ++ } ++ else { ++ /* 640x480 built-in mode */ ++ bt869_write_value(client, 0xB8, (!data->ntsc)); ++ bt869_write_value(client, 0xa0, 0x80 + 0x0C); ++ printk("bt869.o: writing into config -->0x%X\n", ++ (0 + (!data->ntsc))); ++ if ((data->res[0] != 640) || (data->res[1] != 480)) { ++ printk ++ ("bt869.o: Warning: arbitrary resolutions not supported yet. Using 640x480.\n"); ++ data->res[0] = 640; ++ data->res[1] = 480; ++ } ++ } ++ /* Set colour depth */ ++ if ((data->depth != 24) && (data->depth != 16)) ++ data->depth = 16; ++ if (data->depth == 16) ++ bt869_write_value(client, 0x0C6, 0x001); ++ if (data->depth == 24) ++ bt869_write_value(client, 0x0C6, 0x000); ++ /* set "half" resolution mode */ ++ bt869_write_value(client, 0xd4, data->half << 6); ++ /* Set composite/svideo mode, also enable the right dacs */ ++ switch (data->svideo) { ++ case 2: /* RGB */ ++ /* requires hardware mod on Voodoo3 to get all outputs, ++ untested in practice... Feedback to steve@daviesfam.org please */ ++ bt869_write_value(client, 0xd6, 0x0c); ++ bt869_write_value(client, 0xce, 0x24); ++ bt869_write_value(client, 0xba, 0x20); ++ break; ++ case 1: /* Svideo*/ ++ bt869_write_value(client, 0xce, 0x24); ++ bt869_write_value(client, 0xba, 0x21); ++ break; ++ default: /* Composite */ ++ bt869_write_value(client, 0xce, 0x0); ++ bt869_write_value(client, 0xba, 0x21); ++ break; ++ } ++ /* Enable outputs */ ++ bt869_write_value(client, 0xC4, 1); ++ /* Issue timing reset */ ++ bt869_write_value(client, 0x6c, 0x80); ++ ++/* Read back status registers */ ++ bt869_write_value(client, 0xC4, ++ 1 | (data->colorbars << 2)); ++ data->status[0] = bt869_read_value(client, 1); ++ bt869_write_value(client, 0xC4, ++ 0x41 | (data->colorbars << 2)); ++ data->status[1] = bt869_read_value(client, 1); ++ bt869_write_value(client, 0xC4, ++ 0x81 | (data->colorbars << 2)); ++ data->status[2] = bt869_read_value(client, 1); ++ bt869_write_value(client, 0xC4, ++ 0x0C1 | (data->colorbars << 2)); ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ up(&data->update_lock); ++} ++ ++ ++void bt869_status(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct bt869_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ bt869_update_client(client); ++ results[0] = data->status[0]; ++ results[1] = data->status[1]; ++ results[2] = data->status[2]; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ printk ++ ("bt869.o: Warning: write was requested on read-only proc file: status\n"); ++ } ++} ++ ++ ++void bt869_ntsc(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct bt869_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ bt869_update_client(client); ++ results[0] = data->ntsc; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->ntsc = (results[0] > 0); ++ } ++ bt869_update_client(client); ++ } ++} ++ ++ ++void bt869_svideo(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct bt869_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ bt869_update_client(client); ++ results[0] = data->svideo; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->svideo = results[0]; ++ } ++ bt869_update_client(client); ++ } ++} ++ ++ ++void bt869_res(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct bt869_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ bt869_update_client(client); ++ results[0] = data->res[0]; ++ results[1] = data->res[1]; ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->res[0] = results[0]; ++ } ++ if (*nrels_mag >= 2) { ++ data->res[1] = results[1]; ++ } ++ bt869_update_client(client); ++ } ++} ++ ++ ++void bt869_half(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct bt869_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ bt869_update_client(client); ++ results[0] = data->half; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->half = (results[0] > 0); ++ bt869_update_client(client); ++ } ++ } ++} ++ ++void bt869_colorbars(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct bt869_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ bt869_update_client(client); ++ results[0] = data->colorbars; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->colorbars = (results[0] > 0); ++ bt869_update_client(client); ++ } ++ } ++} ++ ++void bt869_depth(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct bt869_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ bt869_update_client(client); ++ results[0] = data->depth; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->depth = results[0]; ++ bt869_update_client(client); ++ } ++ } ++} ++ ++static int __init sm_bt869_init(void) ++{ ++ printk("bt869.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&bt869_driver); ++} ++ ++static void __exit sm_bt869_exit(void) ++{ ++ i2c_del_driver(&bt869_driver); ++} ++ ++ ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard , Philip Edelbrock , Stephen Davies "); ++MODULE_DESCRIPTION("bt869 driver"); ++ ++module_init(sm_bt869_init); ++module_exit(sm_bt869_exit); +--- linux-old/drivers/sensors/ddcmon.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/ddcmon.c Mon Dec 13 20:18:45 2004 +@@ -0,0 +1,591 @@ ++/* ++ ddcmon.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999, 2000 Frodo Looijaard , ++ Philip Edelbrock , ++ and Mark Studebaker ++ Copyright (c) 2003 Jean Delvare ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { 0x50, SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(ddcmon); ++ ++static int checksum = 0; ++MODULE_PARM(checksum, "i"); ++MODULE_PARM_DESC(checksum, "Only accept eeproms whose checksum is correct"); ++ ++/* Many constants specified below */ ++ ++/* DDCMON registers */ ++/* vendor section */ ++#define DDCMON_REG_MAN_ID 0x08 ++#define DDCMON_REG_PROD_ID 0x0A ++#define DDCMON_REG_SERIAL 0x0C ++#define DDCMON_REG_WEEK 0x10 ++#define DDCMON_REG_YEAR 0x11 ++/* EDID version */ ++#define DDCMON_REG_EDID_VER 0x12 ++#define DDCMON_REG_EDID_REV 0x13 ++/* display information */ ++#define DDCMON_REG_HORSIZE 0x15 ++#define DDCMON_REG_VERSIZE 0x16 ++#define DDCMON_REG_GAMMA 0x17 ++#define DDCMON_REG_DPMS_FLAGS 0x18 ++/* supported timings */ ++#define DDCMON_REG_ESTABLISHED_TIMINGS 0x23 ++#define DDCMON_REG_STANDARD_TIMINGS 0x26 ++#define DDCMON_REG_TIMBASE 0x36 ++#define DDCMON_REG_TIMINCR 18 ++#define DDCMON_REG_TIMNUM 4 ++ ++#define DDCMON_REG_CHECKSUM 0x7f ++ ++/* Size of DDCMON in bytes */ ++#define DDCMON_SIZE 128 ++ ++/* Each client has this additional data */ ++struct ddcmon_data { ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 data[DDCMON_SIZE]; /* Register values */ ++}; ++ ++ ++static int ddcmon_attach_adapter(struct i2c_adapter *adapter); ++static int ddcmon_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int ddcmon_detach_client(struct i2c_client *client); ++ ++static void ddcmon_idcall(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ddcmon_size(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ddcmon_sync(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ddcmon_maxclock(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ddcmon_timings(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ddcmon_serial(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ddcmon_time(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ddcmon_edid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ddcmon_gamma(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ddcmon_dpms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ddcmon_standard_timing(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ddcmon_update_client(struct i2c_client *client); ++ ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver ddcmon_driver = { ++ .owner = THIS_MODULE, ++ .name = "DDCMON READER", ++ .id = I2C_DRIVERID_DDCMON, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = ddcmon_attach_adapter, ++ .detach_client = ddcmon_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define DDCMON_SYSCTL_ID 1010 ++#define DDCMON_SYSCTL_SIZE 1011 ++#define DDCMON_SYSCTL_SYNC 1012 ++#define DDCMON_SYSCTL_TIMINGS 1013 ++#define DDCMON_SYSCTL_SERIAL 1014 ++#define DDCMON_SYSCTL_TIME 1015 ++#define DDCMON_SYSCTL_EDID 1016 ++#define DDCMON_SYSCTL_GAMMA 1017 ++#define DDCMON_SYSCTL_DPMS 1018 ++#define DDCMON_SYSCTL_TIMING1 1021 ++#define DDCMON_SYSCTL_TIMING2 1022 ++#define DDCMON_SYSCTL_TIMING3 1023 ++#define DDCMON_SYSCTL_TIMING4 1024 ++#define DDCMON_SYSCTL_TIMING5 1025 ++#define DDCMON_SYSCTL_TIMING6 1026 ++#define DDCMON_SYSCTL_TIMING7 1027 ++#define DDCMON_SYSCTL_TIMING8 1028 ++#define DDCMON_SYSCTL_MAXCLOCK 1029 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected DDCMON. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table ddcmon_dir_table_template[] = { ++ {DDCMON_SYSCTL_ID, "id", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &ddcmon_idcall}, ++ {DDCMON_SYSCTL_SIZE, "size", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &ddcmon_size}, ++ {DDCMON_SYSCTL_SYNC, "sync", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_sync}, ++ {DDCMON_SYSCTL_TIMINGS, "timings", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_timings}, ++ {DDCMON_SYSCTL_SERIAL, "serial", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_serial}, ++ {DDCMON_SYSCTL_TIME, "time", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_time}, ++ {DDCMON_SYSCTL_EDID, "edid", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_edid}, ++ {DDCMON_SYSCTL_GAMMA, "gamma", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_gamma}, ++ {DDCMON_SYSCTL_DPMS, "dpms", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_dpms}, ++ {DDCMON_SYSCTL_TIMING1, "timing1", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_standard_timing}, ++ {DDCMON_SYSCTL_TIMING2, "timing2", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_standard_timing}, ++ {DDCMON_SYSCTL_TIMING3, "timing3", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_standard_timing}, ++ {DDCMON_SYSCTL_TIMING4, "timing4", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_standard_timing}, ++ {DDCMON_SYSCTL_TIMING5, "timing5", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_standard_timing}, ++ {DDCMON_SYSCTL_TIMING6, "timing6", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_standard_timing}, ++ {DDCMON_SYSCTL_TIMING7, "timing7", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_standard_timing}, ++ {DDCMON_SYSCTL_TIMING8, "timing8", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_standard_timing}, ++ {DDCMON_SYSCTL_MAXCLOCK, "maxclock", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ddcmon_maxclock}, ++ {0} ++}; ++ ++static int ddcmon_id = 0; ++ ++static int ddcmon_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, ddcmon_detect); ++} ++ ++/* This function is called by i2c_detect */ ++int ddcmon_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i, cs; ++ struct i2c_client *new_client; ++ struct ddcmon_data *data; ++ int err = 0; ++ const char *type_name, *client_name; ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access ddcmon_{read,write}_value. */ ++ if (!(data = kmalloc(sizeof(struct ddcmon_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ memset(data->data, 0xff, DDCMON_SIZE); ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &ddcmon_driver; ++ new_client->flags = 0; ++ ++ /* prevent 24RF08 corruption (just in case) */ ++ i2c_smbus_write_quick(new_client, 0); ++ ++ /* Now, we do the remaining detection. */ ++ if (checksum) { ++ int cs = 0; ++ for (i = 0; i < 0x80; i++) ++ cs += i2c_smbus_read_byte_data(new_client, i); ++ if ((cs & 0xff) != 0) ++ goto ERROR1; ++ } ++ ++ /* Verify the first 8 locations 0x00FFFFFFFFFFFF00 */ ++ /* Allow force and force_ddcmon arguments */ ++ if(kind < 0) ++ { ++ for(i = 0; i < 8; i++) { ++ cs = i2c_smbus_read_byte_data(new_client, i); ++ if(i == 0 || i == 7) { ++ if(cs != 0) ++ goto ERROR1; ++ } else if(cs != 0xff) ++ goto ERROR1; ++ } ++ } ++ ++ type_name = "ddcmon"; ++ client_name = "DDC Monitor"; ++ ++ /* Fill in the remaining client fields and put it in the global list */ ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = ddcmon_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, type_name, ++ ddcmon_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ return 0; ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int ddcmon_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct ddcmon_data *) (client->data))-> ++ sysctl_id); ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("ddcmon.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ kfree(client->data); ++ return 0; ++} ++ ++static void ddcmon_update_client(struct i2c_client *client) ++{ ++ struct ddcmon_data *data = client->data; ++ int i, j; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > 300 * HZ) || ++ (jiffies < data->last_updated) || !data->valid) { ++ if (i2c_check_functionality(client->adapter, ++ I2C_FUNC_SMBUS_READ_I2C_BLOCK)) ++ { ++ for (i=0; idata + i) ++ != I2C_SMBUS_I2C_BLOCK_MAX) { ++ printk(KERN_WARNING "ddcmon.o: block read fail at 0x%.2x!\n", i); ++ goto DONE; ++ } ++ } else { ++ if (i2c_smbus_write_byte(client, 0)) { ++ printk(KERN_WARNING "ddcmon.o: read start fail at 0!\n"); ++ goto DONE; ++ } ++ for (i = 0; i < DDCMON_SIZE; i++) { ++ j = i2c_smbus_read_byte(client); ++ if (j < 0) { ++ printk(KERN_WARNING "eeprom.o: read fail at 0x%.2x!\n", i); ++ goto DONE; ++ } ++ data->data[i] = (u8) j; ++ } ++ } ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++DONE: ++ up(&data->update_lock); ++} ++ ++ ++void ddcmon_idcall(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct ddcmon_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ddcmon_update_client(client); ++ results[0] = data->data[DDCMON_REG_MAN_ID + 1] | ++ (data->data[DDCMON_REG_MAN_ID] << 8); ++ results[1] = data->data[DDCMON_REG_PROD_ID + 1] | ++ (data->data[DDCMON_REG_PROD_ID] << 8); ++ *nrels_mag = 2; ++ } ++} ++ ++void ddcmon_size(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct ddcmon_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ddcmon_update_client(client); ++ results[0] = data->data[DDCMON_REG_VERSIZE]; ++ results[1] = data->data[DDCMON_REG_HORSIZE]; ++ *nrels_mag = 2; ++ } ++} ++ ++void ddcmon_sync(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ int i, j; ++ struct ddcmon_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ddcmon_update_client(client); ++ *nrels_mag = 4; ++ /* look for monitor limits entry */ ++ for(i = DDCMON_REG_TIMBASE; ++ i < DDCMON_REG_TIMBASE + ++ (DDCMON_REG_TIMNUM * DDCMON_REG_TIMINCR); ++ i += DDCMON_REG_TIMINCR) { ++ if (data->data[i] == 0x00 ++ && data->data[i + 1] == 0x00 ++ && data->data[i + 2] == 0x00 ++ && data->data[i + 3] == 0xfd) { ++ for(j = 0; j < 4; j++) ++ results[j] = data->data[i + j + 5]; ++ return; ++ } ++ } ++ for(j = 0; j < 4; j++) ++ results[j] = 0; ++ } ++} ++ ++void ddcmon_maxclock(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ int i; ++ struct ddcmon_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ddcmon_update_client(client); ++ *nrels_mag = 1; ++ /* look for monitor limits entry */ ++ for(i = DDCMON_REG_TIMBASE; ++ i < DDCMON_REG_TIMBASE + ++ (DDCMON_REG_TIMNUM * DDCMON_REG_TIMINCR); ++ i += DDCMON_REG_TIMINCR) { ++ if (data->data[i] == 0x00 ++ && data->data[i + 1] == 0x00 ++ && data->data[i + 2] == 0x00 ++ && data->data[i + 3] == 0xfd) { ++ results[0] = (data->data[i + 9] == 0xff ? ++ 0 : data->data[i + 9] * 10); ++ return; ++ } ++ } ++ results[0] = 0; ++ } ++} ++ ++void ddcmon_timings(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct ddcmon_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ddcmon_update_client(client); ++ results[0] = data->data[DDCMON_REG_ESTABLISHED_TIMINGS] | ++ (data->data[DDCMON_REG_ESTABLISHED_TIMINGS + 1] << 8) | ++ (data->data[DDCMON_REG_ESTABLISHED_TIMINGS + 2] << 16); ++ *nrels_mag = 1; ++ } ++} ++ ++void ddcmon_serial(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct ddcmon_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ddcmon_update_client(client); ++ results[0] = data->data[DDCMON_REG_SERIAL] | ++ (data->data[DDCMON_REG_SERIAL + 1] << 8) | ++ (data->data[DDCMON_REG_SERIAL + 2] << 16) | ++ (data->data[DDCMON_REG_SERIAL + 3] << 24); ++ *nrels_mag = 1; ++ } ++} ++ ++void ddcmon_time(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct ddcmon_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ddcmon_update_client(client); ++ results[0] = data->data[DDCMON_REG_YEAR] + 1990; ++ results[1] = data->data[DDCMON_REG_WEEK]; ++ *nrels_mag = 2; ++ } ++} ++ ++void ddcmon_edid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct ddcmon_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ddcmon_update_client(client); ++ results[0] = data->data[DDCMON_REG_EDID_VER]; ++ results[1] = data->data[DDCMON_REG_EDID_REV]; ++ *nrels_mag = 2; ++ } ++} ++ ++void ddcmon_gamma(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct ddcmon_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ddcmon_update_client(client); ++ results[0] = 100 + data->data[DDCMON_REG_GAMMA]; ++ *nrels_mag = 1; ++ } ++} ++ ++void ddcmon_dpms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct ddcmon_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ddcmon_update_client(client); ++ results[0] = data->data[DDCMON_REG_DPMS_FLAGS]; ++ *nrels_mag = 1; ++ } ++} ++ ++void ddcmon_standard_timing(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct ddcmon_data *data = client->data; ++ int nr = ctl_name - DDCMON_SYSCTL_TIMING1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ddcmon_update_client(client); ++ /* If both bytes of the timing are 0x00 or 0x01, then the timing ++ slot is unused. */ ++ if ((data->data[DDCMON_REG_STANDARD_TIMINGS + nr * 2] ++ | data->data[DDCMON_REG_STANDARD_TIMINGS + nr * 2 + 1]) & 0xfe) { ++ results[0] = (data->data[DDCMON_REG_STANDARD_TIMINGS + nr * 2] + 31) * 8; ++ switch (data->data[DDCMON_REG_STANDARD_TIMINGS + nr * 2 + 1] >> 6) { ++ /* We don't care about rounding issues there, it really ++ should be OK without it. */ ++ case 0x00: ++ results[1] = results[0]; /* unconfirmed */ ++ break; ++ case 0x01: ++ results[1] = results[0] * 3 / 4; ++ break; ++ case 0x02: ++ results[1] = results[0] * 4 / 5; ++ break; ++ case 0x03: ++ results[1] = results[0] * 9 / 16; ++ break; ++ } ++ results[2] = (data->data[DDCMON_REG_STANDARD_TIMINGS + nr * 2 + 1] & 0x3f) + 60; ++ } else { ++ results[0] = 0; ++ results[1] = 0; ++ results[2] = 0; ++ } ++ *nrels_mag = 3; ++ } ++} ++ ++static int __init sm_ddcmon_init(void) ++{ ++ printk("ddcmon.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&ddcmon_driver); ++} ++ ++static void __exit sm_ddcmon_exit(void) ++{ ++ i2c_del_driver(&ddcmon_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Frodo Looijaard , " ++ "Philip Edelbrock , " ++ "Mark Studebaker " ++ "and Jean Delvare "); ++MODULE_DESCRIPTION("DDCMON driver"); ++ ++module_init(sm_ddcmon_init); ++module_exit(sm_ddcmon_exit); +--- linux-old/drivers/sensors/ds1621.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/ds1621.c Mon Dec 13 20:18:45 2004 +@@ -0,0 +1,528 @@ ++/* ++ ds1621.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Christian W. Zuckschwerdt 2000-11-23 ++ based on lm75.c by Frodo Looijaard ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* Supports DS1621. See doc/chips/ds1621 for details */ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x48, 0x4f, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(ds1621); ++ ++/* Many DS1621 constants specified below */ ++ ++/* Config register used for detection */ ++/* 7 6 5 4 3 2 1 0 */ ++/* |Done|THF |TLF |NVB | 1 | 0 |POL |1SHOT| */ ++#define DS1621_REG_CONFIG_MASK 0x0C ++#define DS1621_REG_CONFIG_VAL 0x08 ++#define DS1621_REG_CONFIG_POLARITY 0x02 ++#define DS1621_REG_CONFIG_1SHOT 0x01 ++#define DS1621_REG_CONFIG_DONE 0x80 ++ ++/* Note: the done bit is always unset if continuous conversion is in progress. ++ We need to stop the continuous conversion or switch to single shot ++ before this bit becomes available! ++ */ ++ ++/* The DS1621 registers */ ++#define DS1621_REG_TEMP 0xAA /* word, RO */ ++#define DS1621_REG_TEMP_OVER 0xA1 /* word, RW */ ++#define DS1621_REG_TEMP_HYST 0xA2 /* word, RW -- it's a low temp trigger */ ++#define DS1621_REG_CONF 0xAC /* byte, RW */ ++#define DS1621_REG_TEMP_COUNTER 0xA8 /* byte, RO */ ++#define DS1621_REG_TEMP_SLOPE 0xA9 /* byte, RO */ ++#define DS1621_COM_START 0xEE /* no data */ ++#define DS1621_COM_STOP 0x22 /* no data */ ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++#define TEMP_FROM_REG(val) ((((val & 0x7fff) >> 7) * 5) | \ ++ ((val & 0x8000)?-256:0)) ++#define TEMP_TO_REG(val) (SENSORS_LIMIT((val<0 ? (0x200+((val)/5))<<7 : \ ++ (((val) + 2) / 5) << 7),0,0xffff)) ++#define ALARMS_FROM_REG(val) ((val) & \ ++ (DS1621_ALARM_TEMP_HIGH | DS1621_ALARM_TEMP_LOW)) ++#define ITEMP_FROM_REG(val) ((((val & 0x7fff) >> 8)) | \ ++ ((val & 0x8000)?-256:0)) ++ ++/* Each client has this additional data */ ++struct ds1621_data { ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u16 temp, temp_over, temp_hyst; /* Register values, word */ ++ u8 conf; /* Register encoding, combined */ ++ ++ char enable; /* !=0 if we're expected to restart the conversion */ ++ u8 temp_int, temp_counter, temp_slope; /* Register values, byte */ ++}; ++ ++static int ds1621_attach_adapter(struct i2c_adapter *adapter); ++static int ds1621_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static void ds1621_init_client(struct i2c_client *client); ++static int ds1621_detach_client(struct i2c_client *client); ++ ++static int ds1621_read_value(struct i2c_client *client, u8 reg); ++static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value); ++static void ds1621_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ds1621_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ds1621_enable(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ds1621_continuous(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ds1621_polarity(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void ds1621_update_client(struct i2c_client *client); ++ ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver ds1621_driver = { ++ .owner = THIS_MODULE, ++ .name = "DS1621 sensor driver", ++ .id = I2C_DRIVERID_DS1621, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = ds1621_attach_adapter, ++ .detach_client = ds1621_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++#define DS1621_SYSCTL_TEMP 1200 /* Degrees Celcius * 10 */ ++#define DS1621_SYSCTL_ALARMS 2001 /* bitvector */ ++#define DS1621_ALARM_TEMP_HIGH 0x40 ++#define DS1621_ALARM_TEMP_LOW 0x20 ++#define DS1621_SYSCTL_ENABLE 2002 ++#define DS1621_SYSCTL_CONTINUOUS 2003 ++#define DS1621_SYSCTL_POLARITY 2004 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected DS1621. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table ds1621_dir_table_template[] = { ++ {DS1621_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ds1621_temp}, ++ {DS1621_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ds1621_alarms}, ++ {DS1621_SYSCTL_ENABLE, "enable", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ds1621_enable}, ++ {DS1621_SYSCTL_CONTINUOUS, "continuous", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ds1621_continuous}, ++ {DS1621_SYSCTL_POLARITY, "polarity", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &ds1621_polarity}, ++ {0} ++}; ++ ++static int ds1621_id = 0; ++ ++static int ds1621_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, ds1621_detect); ++} ++ ++/* This function is called by i2c_detect */ ++int ds1621_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i, conf; ++ struct i2c_client *new_client; ++ struct ds1621_data *data; ++ int err = 0; ++ const char *type_name, *client_name; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("ds1621.o: ds1621_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | ++ I2C_FUNC_SMBUS_WORD_DATA | ++ I2C_FUNC_SMBUS_WRITE_BYTE)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access ds1621_{read,write}_value. */ ++ if (!(data = kmalloc(sizeof(struct ds1621_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &ds1621_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. It is lousy. */ ++ if (kind < 0) { ++ conf = i2c_smbus_read_byte_data(new_client, ++ DS1621_REG_CONF); ++ if ((conf & DS1621_REG_CONFIG_MASK) ++ != DS1621_REG_CONFIG_VAL) ++ goto ERROR1; ++ } ++ ++ /* Determine the chip type - only one kind supported! */ ++ if (kind <= 0) ++ kind = ds1621; ++ ++ if (kind == ds1621) { ++ type_name = "ds1621"; ++ client_name = "DS1621 chip"; ++ } else { ++#ifdef DEBUG ++ printk("ds1621.o: Internal error: unknown kind (%d)?!?", ++ kind); ++#endif ++ goto ERROR1; ++ } ++ ++ /* Fill in remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = ds1621_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, type_name, ++ ds1621_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ ds1621_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int ds1621_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct ds1621_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("ds1621.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++ ++/* All registers are word-sized, except for the configuration register. ++ DS1621 uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int ds1621_read_value(struct i2c_client *client, u8 reg) ++{ ++ if ((reg == DS1621_REG_CONF) || (reg == DS1621_REG_TEMP_COUNTER) ++ || (reg == DS1621_REG_TEMP_SLOPE)) ++ return i2c_smbus_read_byte_data(client, reg); ++ else ++ return swab16(i2c_smbus_read_word_data(client, reg)); ++} ++ ++/* All registers are word-sized, except for the configuration register. ++ DS1621 uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value) ++{ ++ if ( (reg == DS1621_COM_START) || (reg == DS1621_COM_STOP) ) ++ return i2c_smbus_write_byte(client, reg); ++ else ++ if ((reg == DS1621_REG_CONF) || (reg == DS1621_REG_TEMP_COUNTER) ++ || (reg == DS1621_REG_TEMP_SLOPE)) ++ return i2c_smbus_write_byte_data(client, reg, value); ++ else ++ return i2c_smbus_write_word_data(client, reg, swab16(value)); ++} ++ ++static void ds1621_init_client(struct i2c_client *client) ++{ ++ int reg; ++ ++ reg = ds1621_read_value(client, DS1621_REG_CONF); ++ /* start the continous conversion */ ++ if(reg & 0x01) ++ ds1621_write_value(client, DS1621_REG_CONF, reg & 0xfe); ++} ++ ++static void ds1621_update_client(struct i2c_client *client) ++{ ++ struct ds1621_data *data = client->data; ++ u8 new_conf; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("Starting ds1621 update\n"); ++#endif ++ ++ data->conf = ds1621_read_value(client, DS1621_REG_CONF); ++ ++ data->temp = ds1621_read_value(client, ++ DS1621_REG_TEMP); ++ data->temp_over = ds1621_read_value(client, ++ DS1621_REG_TEMP_OVER); ++ data->temp_hyst = ds1621_read_value(client, ++ DS1621_REG_TEMP_HYST); ++ ++ /* wait for the DONE bit before reading extended values */ ++ ++ if (data->conf & DS1621_REG_CONFIG_DONE) { ++ data->temp_counter = ds1621_read_value(client, ++ DS1621_REG_TEMP_COUNTER); ++ data->temp_slope = ds1621_read_value(client, ++ DS1621_REG_TEMP_SLOPE); ++ data->temp_int = ITEMP_FROM_REG(data->temp); ++ /* restart the conversion */ ++ if (data->enable) ++ ds1621_write_value(client, DS1621_COM_START, 0); ++ } ++ ++ /* reset alarms if neccessary */ ++ new_conf = data->conf; ++ if (data->temp < data->temp_over) ++ new_conf &= ~DS1621_ALARM_TEMP_HIGH; ++ if (data->temp > data->temp_hyst) ++ new_conf &= ~DS1621_ALARM_TEMP_LOW; ++ if (data->conf != new_conf) ++ ds1621_write_value(client, DS1621_REG_CONF, ++ new_conf); ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++void ds1621_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct ds1621_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ if (!(data->conf & DS1621_REG_CONFIG_DONE) || ++ (data->temp_counter > data->temp_slope) || ++ (data->temp_slope == 0)) { ++ *nrels_mag = 1; ++ } else { ++ *nrels_mag = 2; ++ } ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ds1621_update_client(client); ++ /* decide wether to calculate more precise temp */ ++ if (!(data->conf & DS1621_REG_CONFIG_DONE) || ++ (data->temp_counter > data->temp_slope) || ++ (data->temp_slope == 0)) { ++ results[0] = TEMP_FROM_REG(data->temp_over); ++ results[1] = TEMP_FROM_REG(data->temp_hyst); ++ results[2] = TEMP_FROM_REG(data->temp); ++ } else { ++ results[0] = TEMP_FROM_REG(data->temp_over)*10; ++ results[1] = TEMP_FROM_REG(data->temp_hyst)*10; ++ results[2] = data->temp_int * 100 - 25 + ++ ((data->temp_slope - data->temp_counter) * ++ 100 / data->temp_slope); ++ } ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_over = TEMP_TO_REG(results[0]); ++ ds1621_write_value(client, DS1621_REG_TEMP_OVER, ++ data->temp_over); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst = TEMP_TO_REG(results[1]); ++ ds1621_write_value(client, DS1621_REG_TEMP_HYST, ++ data->temp_hyst); ++ } ++ } ++} ++ ++void ds1621_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct ds1621_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ds1621_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->conf); ++ *nrels_mag = 1; ++ } ++} ++ ++void ds1621_enable(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ /* If you really screw up your chip (like I did) this is */ ++ /* sometimes needed to (re)start the continous conversion */ ++ /* there is no data to read so this might hang your SMBus! */ ++ ++ struct ds1621_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ds1621_update_client(client); ++ results[0] = !(data->conf & DS1621_REG_CONFIG_DONE); ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ if (results[0]) { ++ ds1621_write_value(client, DS1621_COM_START, 0); ++ data->enable=1; ++ } else { ++ ds1621_write_value(client, DS1621_COM_STOP, 0); ++ data->enable=0; ++ } ++ } else { ++ ds1621_write_value(client, DS1621_COM_START, 0); ++ data->enable=1; ++ } ++ } ++} ++ ++void ds1621_continuous(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct ds1621_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ds1621_update_client(client); ++ results[0] = !(data->conf & DS1621_REG_CONFIG_1SHOT); ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ ds1621_update_client(client); ++ if (*nrels_mag >= 1) { ++ if (results[0]) { ++ ds1621_write_value(client, DS1621_REG_CONF, ++ data->conf & ~DS1621_REG_CONFIG_1SHOT); ++ } else { ++ ds1621_write_value(client, DS1621_REG_CONF, ++ data->conf | DS1621_REG_CONFIG_1SHOT); ++ } ++ } else { ++ ds1621_write_value(client, DS1621_REG_CONF, ++ data->conf & ~DS1621_REG_CONFIG_1SHOT); ++ } ++ } ++} ++ ++void ds1621_polarity(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct ds1621_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ ds1621_update_client(client); ++ results[0] = !(!(data->conf & DS1621_REG_CONFIG_POLARITY)); ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ ds1621_update_client(client); ++ if (*nrels_mag >= 1) { ++ if (results[0]) { ++ ds1621_write_value(client, DS1621_REG_CONF, ++ data->conf | DS1621_REG_CONFIG_POLARITY); ++ } else { ++ ds1621_write_value(client, DS1621_REG_CONF, ++ data->conf & ~DS1621_REG_CONFIG_POLARITY); ++ } ++ } ++ } ++} ++ ++static int __init sm_ds1621_init(void) ++{ ++ printk("ds1621.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&ds1621_driver); ++} ++ ++static void __exit sm_ds1621_exit(void) ++{ ++ i2c_del_driver(&ds1621_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Christian W. Zuckschwerdt "); ++MODULE_DESCRIPTION("DS1621 driver"); ++ ++module_init(sm_ds1621_init); ++module_exit(sm_ds1621_exit); +--- linux-old/drivers/sensors/eeprom.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/eeprom.c Mon Dec 13 20:18:45 2004 +@@ -0,0 +1,418 @@ ++/* ++ eeprom.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard and ++ Philip Edelbrock ++ ++ 2003-08-18 Jean Delvare ++ Divide the eeprom in 2-row (arbitrary) slices. This significantly ++ speeds sensors up, as well as various scripts using the eeprom ++ module. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include /* for capable() */ ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x50, 0x57, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(eeprom); ++ ++static int checksum = 0; ++MODULE_PARM(checksum, "i"); ++MODULE_PARM_DESC(checksum, ++ "Only accept eeproms whose checksum is correct"); ++ ++ ++/* Many constants specified below */ ++ ++/* EEPROM registers */ ++#define EEPROM_REG_CHECKSUM 0x3f ++ ++/* possible natures */ ++#define NATURE_UNKNOWN 0 ++#define NATURE_VAIO 1 ++ ++/* Size of EEPROM in bytes */ ++#define EEPROM_SIZE 256 ++ ++/* Each client has this additional data */ ++struct eeprom_data { ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ u8 valid; /* bitfield, bit!=0 if slice is valid */ ++ unsigned long last_updated[8]; /* In jiffies, 8 slices */ ++ ++ u8 data[EEPROM_SIZE]; /* Register values */ ++ u8 nature; ++}; ++ ++ ++static int eeprom_attach_adapter(struct i2c_adapter *adapter); ++static int eeprom_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int eeprom_detach_client(struct i2c_client *client); ++ ++#if 0 ++static int eeprom_write_value(struct i2c_client *client, u8 reg, ++ u8 value); ++#endif ++ ++static void eeprom_contents(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void eeprom_update_client(struct i2c_client *client, u8 slice); ++ ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver eeprom_driver = { ++ .owner = THIS_MODULE, ++ .name = "EEPROM READER", ++ .id = I2C_DRIVERID_EEPROM, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = eeprom_attach_adapter, ++ .detach_client = eeprom_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define EEPROM_SYSCTL1 1000 ++#define EEPROM_SYSCTL2 1001 ++#define EEPROM_SYSCTL3 1002 ++#define EEPROM_SYSCTL4 1003 ++#define EEPROM_SYSCTL5 1004 ++#define EEPROM_SYSCTL6 1005 ++#define EEPROM_SYSCTL7 1006 ++#define EEPROM_SYSCTL8 1007 ++#define EEPROM_SYSCTL9 1008 ++#define EEPROM_SYSCTL10 1009 ++#define EEPROM_SYSCTL11 1010 ++#define EEPROM_SYSCTL12 1011 ++#define EEPROM_SYSCTL13 1012 ++#define EEPROM_SYSCTL14 1013 ++#define EEPROM_SYSCTL15 1014 ++#define EEPROM_SYSCTL16 1015 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected EEPROM. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table eeprom_dir_table_template[] = { ++ {EEPROM_SYSCTL1, "00", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL2, "10", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL3, "20", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL4, "30", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL5, "40", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL6, "50", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL7, "60", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL8, "70", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL9, "80", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL10, "90", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL11, "a0", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL12, "b0", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL13, "c0", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL14, "d0", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL15, "e0", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {EEPROM_SYSCTL16, "f0", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &eeprom_contents}, ++ {0} ++}; ++ ++static int eeprom_id = 0; ++ ++static int eeprom_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, eeprom_detect); ++} ++ ++/* This function is called by i2c_detect */ ++int eeprom_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct eeprom_data *data; ++ int err = 0; ++ const char *type_name, *client_name; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("eeprom.o: eeprom_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access eeprom_{read,write}_value. */ ++ if (!(data = kmalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ memset(data->data, 0xff, EEPROM_SIZE); ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &eeprom_driver; ++ new_client->flags = 0; ++ ++ /* prevent 24RF08 corruption */ ++ i2c_smbus_write_quick(new_client, 0); ++ ++ /* Now, we do the remaining detection. It is not there, unless you force ++ the checksum to work out. */ ++ if (checksum) { ++ int cs = 0; ++ for (i = 0; i <= 0x3e; i++) ++ cs += i2c_smbus_read_byte_data(new_client, i); ++ cs &= 0xff; ++ if (i2c_smbus_read_byte_data ++ (new_client, EEPROM_REG_CHECKSUM) != cs) ++ goto ERROR1; ++ } ++ ++ data->nature = NATURE_UNKNOWN; ++ /* Detect the Vaio nature of EEPROMs. ++ We use the "PCG-" prefix as the signature. */ ++ if (address == 0x57) ++ { ++ if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P' ++ && i2c_smbus_read_byte_data(new_client, 0x81) == 'C' ++ && i2c_smbus_read_byte_data(new_client, 0x82) == 'G' ++ && i2c_smbus_read_byte_data(new_client, 0x83) == '-') ++ data->nature = NATURE_VAIO; ++ } ++ ++ /* Determine the chip type - only one kind supported! */ ++ if (kind <= 0) ++ kind = eeprom; ++ ++ if (kind == eeprom) { ++ type_name = "eeprom"; ++ client_name = "EEPROM chip"; ++ } else { ++#ifdef DEBUG ++ printk("eeprom.o: Internal error: unknown kind (%d)?!?", ++ kind); ++#endif ++ goto ERROR1; ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = eeprom_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, type_name, ++ eeprom_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int eeprom_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct eeprom_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("eeprom.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++ ++#if 0 ++/* No writes yet (PAE) */ ++static int eeprom_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++#endif ++ ++static void eeprom_update_client(struct i2c_client *client, u8 slice) ++{ ++ struct eeprom_data *data = client->data; ++ int i, j; ++ ++ down(&data->update_lock); ++ ++ if (!(data->valid & (1 << slice)) ++ || (jiffies - data->last_updated[slice] > 300 * HZ) ++ || (jiffies < data->last_updated[slice])) { ++ ++#ifdef DEBUG ++ printk("Starting eeprom update, slice %u\n", slice); ++#endif ++ ++ if (i2c_check_functionality(client->adapter, ++ I2C_FUNC_SMBUS_READ_I2C_BLOCK)) ++ { ++ for (i = slice << 5; i < (slice + 1) << 5; ++ i += I2C_SMBUS_I2C_BLOCK_MAX) ++ if (i2c_smbus_read_i2c_block_data(client, ++ i, data->data + i) ++ != I2C_SMBUS_I2C_BLOCK_MAX) { ++ printk(KERN_WARNING "eeprom.o: block read fail at 0x%.2x!\n", i); ++ goto DONE; ++ } ++ } else { ++ if (i2c_smbus_write_byte(client, slice << 5)) { ++ printk(KERN_WARNING "eeprom.o: read start fail at 0x%.2x!\n", slice << 5); ++ goto DONE; ++ } ++ for (i = slice << 5; i < (slice + 1) << 5; i++) { ++ j = i2c_smbus_read_byte(client); ++ if (j < 0) { ++ printk(KERN_WARNING "eeprom.o: read fail at 0x%.2x!\n", i); ++ goto DONE; ++ } ++ data->data[i] = (u8) j; ++ } ++ } ++ data->last_updated[slice] = jiffies; ++ data->valid |= (1 << slice); ++ } ++DONE: ++ up(&data->update_lock); ++} ++ ++ ++void eeprom_contents(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ int i; ++ int nr = ctl_name - EEPROM_SYSCTL1; ++ struct eeprom_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ eeprom_update_client(client, nr >> 1); ++ /* Hide Vaio security settings to regular users */ ++ if (nr == 0 && data->nature == NATURE_VAIO ++ && !capable(CAP_SYS_ADMIN)) ++ for (i = 0; i < 16; i++) ++ results[i] = 0; ++ else ++ for (i = 0; i < 16; i++) ++ results[i] = data->data[i + nr * 16]; ++#ifdef DEBUG ++ printk("eeprom.o: 0x%X EEPROM contents (row %d):", ++ client->addr, nr + 1); ++ if (nr == 0 && data->nature == NATURE_VAIO) ++ printk(" \n"); ++ else { ++ for (i = 0; i < 16; i++) ++ printk(" 0x%02X", data->data[i + nr * 16]); ++ printk("\n"); ++ } ++#endif ++ *nrels_mag = 16; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ ++/* No writes to the EEPROM (yet, anyway) (PAE) */ ++ printk("eeprom.o: No writes to EEPROMs supported!\n"); ++ } ++} ++ ++static int __init sm_eeprom_init(void) ++{ ++ printk("eeprom.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&eeprom_driver); ++} ++ ++static void __exit sm_eeprom_exit(void) ++{ ++ i2c_del_driver(&eeprom_driver); ++} ++ ++ ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard and Philip Edelbrock "); ++MODULE_DESCRIPTION("EEPROM driver"); ++ ++module_init(sm_eeprom_init); ++module_exit(sm_eeprom_exit); +--- linux-old/drivers/sensors/fscpos.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/fscpos.c Mon Dec 13 20:18:46 2004 +@@ -0,0 +1,690 @@ ++/* ++ fscpos.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 2001 Hermann Jung ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ fujitsu siemens poseidon chip, ++ module based on lm80.c ++ Copyright (c) 1998, 1999 Frodo Looijaard ++ and Philip Edelbrock ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { 0x73, SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(fscpos); ++ ++/* The FSCPOS registers */ ++ ++/* chip identification */ ++#define FSCPOS_REG_IDENT_0 0x00 ++#define FSCPOS_REG_IDENT_1 0x01 ++#define FSCPOS_REG_IDENT_2 0x02 ++#define FSCPOS_REG_REVISION 0x03 ++ ++/* global control and status */ ++#define FSCPOS_REG_EVENT_STATE 0x04 ++#define FSCPOS_REG_CONTROL 0x05 ++ ++/* watchdog */ ++#define FSCPOS_REG_WDOG_PRESET 0x28 ++#define FSCPOS_REG_WDOG_STATE 0x23 ++#define FSCPOS_REG_WDOG_CONTROL 0x21 ++ ++/* fan 0 */ ++#define FSCPOS_REG_FAN0_MIN 0x55 ++#define FSCPOS_REG_FAN0_ACT 0x0e ++#define FSCPOS_REG_FAN0_STATE 0x0d ++#define FSCPOS_REG_FAN0_RIPPLE 0x0f ++ ++/* fan 1 */ ++#define FSCPOS_REG_FAN1_MIN 0x65 ++#define FSCPOS_REG_FAN1_ACT 0x6b ++#define FSCPOS_REG_FAN1_STATE 0x62 ++#define FSCPOS_REG_FAN1_RIPPLE 0x6f ++ ++/* fan 2 */ ++/* min speed fan2 not supported */ ++#define FSCPOS_REG_FAN2_ACT 0xab ++#define FSCPOS_REG_FAN2_STATE 0xa2 ++#define FSCPOS_REG_FAN2_RIPPLE 0x0af ++ ++/* voltage supervision */ ++#define FSCPOS_REG_VOLT_12 0x45 ++#define FSCPOS_REG_VOLT_5 0x42 ++#define FSCPOS_REG_VOLT_BATT 0x48 ++ ++/* temperatures */ ++/* sensor 0 */ ++#define FSCPOS_REG_TEMP0_ACT 0x64 ++#define FSCPOS_REG_TEMP0_STATE 0x71 ++ ++/* sensor 1 */ ++#define FSCPOS_REG_TEMP1_ACT 0x32 ++#define FSCPOS_REG_TEMP1_STATE 0x81 ++ ++/* sensor 2 */ ++#define FSCPOS_REG_TEMP2_ACT 0x35 ++#define FSCPOS_REG_TEMP2_STATE 0x91 ++ ++ ++ ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++ ++#define IN_TO_REG(val,nr) (SENSORS_LIMIT((val),0,255)) ++#define IN_FROM_REG(val,nr) (val) ++ ++/* Initial limits */ ++ ++/* For each registered FSCPOS, we need to keep some data in memory. That ++ data is pointed to by fscpos_list[NR]->data. The structure itself is ++ dynamically allocated, at the same time when a new fscpos client is ++ allocated. */ ++struct fscpos_data { ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 revision; /* revision of chip */ ++ u8 global_event; /* global event status */ ++ u8 global_control; /* global control register */ ++ u8 watchdog[3]; /* watchdog */ ++ u8 volt[3]; /* 12, 5, battery current */ ++ u8 temp_act[3]; /* temperature */ ++ u8 temp_status[3]; /* status of sensor */ ++ u8 fan_act[3]; /* fans revolutions per second */ ++ u8 fan_status[3]; /* fan status */ ++ u8 fan_min[3]; /* fan min value for rps */ ++ u8 fan_ripple[3]; /* divider for rps */ ++}; ++ ++ ++static int fscpos_attach_adapter(struct i2c_adapter *adapter); ++static int fscpos_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int fscpos_detach_client(struct i2c_client *client); ++ ++static int fscpos_read_value(struct i2c_client *client, u8 register); ++static int fscpos_write_value(struct i2c_client *client, u8 register, ++ u8 value); ++static void fscpos_update_client(struct i2c_client *client); ++static void fscpos_init_client(struct i2c_client *client); ++ ++ ++static void fscpos_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++static void fscpos_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void fscpos_fan_internal(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results, ++ int nr, int reg_state, int reg_min, int res_ripple); ++static void fscpos_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void fscpos_volt(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void fscpos_wdog(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static int fscpos_id = 0; ++ ++static struct i2c_driver fscpos_driver = { ++ .owner = THIS_MODULE, ++ .name = "FSCPOS sensor driver", ++ .id = I2C_DRIVERID_FSCPOS, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = fscpos_attach_adapter, ++ .detach_client = fscpos_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++#define FSCPOS_SYSCTL_VOLT0 1000 /* 12 volt supply */ ++#define FSCPOS_SYSCTL_VOLT1 1001 /* 5 volt supply */ ++#define FSCPOS_SYSCTL_VOLT2 1002 /* batterie voltage*/ ++#define FSCPOS_SYSCTL_FAN0 1101 /* state, min, ripple, actual value fan 0 */ ++#define FSCPOS_SYSCTL_FAN1 1102 /* state, min, ripple, actual value fan 1 */ ++#define FSCPOS_SYSCTL_FAN2 1103 /* state, min, ripple, actual value fan 2 */ ++#define FSCPOS_SYSCTL_TEMP0 1201 /* state and value of sensor 0, cpu die */ ++#define FSCPOS_SYSCTL_TEMP1 1202 /* state and value of sensor 1, motherboard */ ++#define FSCPOS_SYSCTL_TEMP2 1203 /* state and value of sensor 2, chassis */ ++#define FSCPOS_SYSCTL_REV 2000 /* Revision */ ++#define FSCPOS_SYSCTL_EVENT 2001 /* global event status */ ++#define FSCPOS_SYSCTL_CONTROL 2002 /* global control byte */ ++#define FSCPOS_SYSCTL_WDOG 2003 /* state, min, ripple, actual value fan 2 */ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected FSCPOS. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table fscpos_dir_table_template[] = { ++ {FSCPOS_SYSCTL_REV, "rev", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscpos_in}, ++ {FSCPOS_SYSCTL_EVENT, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscpos_in}, ++ {FSCPOS_SYSCTL_CONTROL, "control", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscpos_in}, ++ {FSCPOS_SYSCTL_TEMP0, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscpos_temp}, ++ {FSCPOS_SYSCTL_TEMP1, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscpos_temp}, ++ {FSCPOS_SYSCTL_TEMP2, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscpos_temp}, ++ {FSCPOS_SYSCTL_VOLT0, "in0", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscpos_volt}, ++ {FSCPOS_SYSCTL_VOLT1, "in1", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscpos_volt}, ++ {FSCPOS_SYSCTL_VOLT2, "in2", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscpos_volt}, ++ {FSCPOS_SYSCTL_FAN0, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscpos_fan}, ++ {FSCPOS_SYSCTL_FAN1, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscpos_fan}, ++ {FSCPOS_SYSCTL_FAN2, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscpos_fan}, ++ {FSCPOS_SYSCTL_WDOG, "wdog", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscpos_wdog}, ++ {0} ++}; ++ ++static int fscpos_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, fscpos_detect); ++} ++ ++int fscpos_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct fscpos_data *data; ++ int err = 0; ++ const char *type_name, *client_name; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("fscpos.o: fscpos_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access fscpos_{read,write}_value. */ ++ if (!(data = kmalloc(sizeof(struct fscpos_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &fscpos_driver; ++ new_client->flags = 0; ++ ++ /* Do the remaining detection unless force or force_fscpos parameter */ ++ if (kind < 0) { ++ if (fscpos_read_value(new_client, FSCPOS_REG_IDENT_0) != 0x50) ++ goto ERROR1; ++ if (fscpos_read_value(new_client, FSCPOS_REG_IDENT_1) != 0x45) ++ goto ERROR1; ++ if (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2) != 0x47) ++ goto ERROR1; ++ } ++ ++ kind = fscpos; ++ ++ type_name = "fscpos"; ++ client_name = "fsc poseidon chip"; ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = fscpos_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, type_name, ++ fscpos_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ fscpos_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int fscpos_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct fscpos_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("fscpos.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++static int fscpos_read_value(struct i2c_client *client, u8 reg) ++{ ++#ifdef DEBUG ++ printk("fscpos: read reg 0x%02x\n",reg); ++#endif ++ return i2c_smbus_read_byte_data(client, reg); ++} ++ ++static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++#ifdef DEBUG ++ printk("fscpos: write reg 0x%02x, val 0x%02x\n",reg, value); ++#endif ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++/* Called when we have found a new FSCPOS. It should set limits, etc. */ ++static void fscpos_init_client(struct i2c_client *client) ++{ ++ struct fscpos_data *data = client->data; ++ ++ /* read revision from chip */ ++ data->revision = fscpos_read_value(client,FSCPOS_REG_REVISION); ++ /* setup missing fan2_min value */ ++ data->fan_min[2] = 0xff; ++} ++ ++static void fscpos_update_client(struct i2c_client *client) ++{ ++ struct fscpos_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > 2 * HZ) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("Starting fscpos update\n"); ++#endif ++ data->temp_act[0] = fscpos_read_value(client, FSCPOS_REG_TEMP0_ACT); ++ data->temp_act[1] = fscpos_read_value(client, FSCPOS_REG_TEMP1_ACT); ++ data->temp_act[2] = fscpos_read_value(client, FSCPOS_REG_TEMP2_ACT); ++ data->temp_status[0] = fscpos_read_value(client, FSCPOS_REG_TEMP0_STATE); ++ data->temp_status[1] = fscpos_read_value(client, FSCPOS_REG_TEMP1_STATE); ++ data->temp_status[2] = fscpos_read_value(client, FSCPOS_REG_TEMP2_STATE); ++ ++ data->volt[0] = fscpos_read_value(client, FSCPOS_REG_VOLT_12); ++ data->volt[1] = fscpos_read_value(client, FSCPOS_REG_VOLT_5); ++ data->volt[2] = fscpos_read_value(client, FSCPOS_REG_VOLT_BATT); ++ ++ data->fan_act[0] = fscpos_read_value(client, FSCPOS_REG_FAN0_ACT); ++ data->fan_act[1] = fscpos_read_value(client, FSCPOS_REG_FAN1_ACT); ++ data->fan_act[2] = fscpos_read_value(client, FSCPOS_REG_FAN2_ACT); ++ data->fan_status[0] = fscpos_read_value(client, FSCPOS_REG_FAN0_STATE); ++ data->fan_status[1] = fscpos_read_value(client, FSCPOS_REG_FAN1_STATE); ++ data->fan_status[2] = fscpos_read_value(client, FSCPOS_REG_FAN2_STATE); ++ data->fan_min[0] = fscpos_read_value(client, FSCPOS_REG_FAN0_MIN); ++ data->fan_min[1] = fscpos_read_value(client, FSCPOS_REG_FAN1_MIN); ++ /* fan2_min is not supported */ ++ data->fan_ripple[0] = fscpos_read_value(client, FSCPOS_REG_FAN0_RIPPLE); ++ data->fan_ripple[1] = fscpos_read_value(client, FSCPOS_REG_FAN1_RIPPLE); ++ data->fan_ripple[2] = fscpos_read_value(client, FSCPOS_REG_FAN2_RIPPLE); ++ ++ data->watchdog[0] = fscpos_read_value(client, FSCPOS_REG_WDOG_PRESET); ++ data->watchdog[1] = fscpos_read_value(client, FSCPOS_REG_WDOG_STATE); ++ data->watchdog[2] = fscpos_read_value(client, FSCPOS_REG_WDOG_CONTROL); ++ ++ data->global_event = fscpos_read_value(client, FSCPOS_REG_EVENT_STATE); ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the date ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++void fscpos_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct fscpos_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ fscpos_update_client(client); ++ switch(ctl_name) { ++ case FSCPOS_SYSCTL_REV: ++ results[0] = data->revision ; ++ break; ++ case FSCPOS_SYSCTL_EVENT: ++ results[0] = data->global_event & 0x1f; ++ break; ++ case FSCPOS_SYSCTL_CONTROL: ++ results[0] = data->global_control & 0x01; ++ break; ++ default: ++ printk("fscpos: ctl_name %d not supported\n", ++ ctl_name); ++ *nrels_mag = 0; ++ return; ++ } ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if((ctl_name == FSCPOS_SYSCTL_CONTROL) && (*nrels_mag >= 1)) { ++ data->global_control = (results[0] & 0x01); ++ printk("fscpos: writing 0x%02x to global_control\n", ++ data->global_control); ++ fscpos_write_value(client,FSCPOS_REG_CONTROL, ++ data->global_control); ++ } ++ else ++ printk("fscpos: writing to chip not supported\n"); ++ } ++} ++ ++#define TEMP_FROM_REG(val) (val-128) ++ ++ ++void fscpos_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct fscpos_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ fscpos_update_client(client); ++ switch(ctl_name) { ++ case FSCPOS_SYSCTL_TEMP0: ++ results[0] = data->temp_status[0] & 0x03; ++ results[1] = TEMP_FROM_REG(data->temp_act[0]); ++ break; ++ case FSCPOS_SYSCTL_TEMP1: ++ results[0] = data->temp_status[1] & 0x03; ++ results[1] = TEMP_FROM_REG(data->temp_act[1]); ++ break; ++ case FSCPOS_SYSCTL_TEMP2: ++ results[0] = data->temp_status[2] & 0x03; ++ results[1] = TEMP_FROM_REG(data->temp_act[2]); ++ break; ++ default: ++ printk("fscpos: ctl_name %d not supported\n", ++ ctl_name); ++ *nrels_mag = 0; ++ return; ++ } ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if(*nrels_mag >= 1) { ++ switch(ctl_name) { ++ case FSCPOS_SYSCTL_TEMP0: ++ data->temp_status[0] = ++ (data->temp_status[0] & ~0x02) ++ | (results[0] & 0x02); ++ printk("fscpos: writing value 0x%02x " ++ "to temp0_status\n", ++ data->temp_status[0]); ++ fscpos_write_value(client, ++ FSCPOS_REG_TEMP0_STATE, ++ data->temp_status[0] & 0x02); ++ break; ++ case FSCPOS_SYSCTL_TEMP1: ++ data->temp_status[1] = (data->temp_status[1] & ~0x02) | (results[0] & 0x02); ++ printk("fscpos: writing value 0x%02x to temp1_status\n", data->temp_status[1]); ++ fscpos_write_value(client,FSCPOS_REG_TEMP1_STATE, ++ data->temp_status[1] & 0x02); ++ break; ++ case FSCPOS_SYSCTL_TEMP2: ++ data->temp_status[2] = (data->temp_status[2] & ~0x02) | (results[0] & 0x02); ++ printk("fscpos: writing value 0x%02x to temp2_status\n", data->temp_status[2]); ++ fscpos_write_value(client,FSCPOS_REG_TEMP2_STATE, ++ data->temp_status[2] & 0x02); ++ break; ++ default: ++ printk("fscpos: ctl_name %d not supported\n",ctl_name); ++ } ++ } ++ else ++ printk("fscpos: writing to chip not supported\n"); ++ } ++} ++ ++#define VOLT_FROM_REG(val,mult) (val*mult/255) ++ ++void fscpos_volt(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct fscpos_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ fscpos_update_client(client); ++ switch(ctl_name) { ++ case FSCPOS_SYSCTL_VOLT0: ++ results[0] = VOLT_FROM_REG(data->volt[0],1420); ++ break; ++ case FSCPOS_SYSCTL_VOLT1: ++ results[0] = VOLT_FROM_REG(data->volt[1],660); ++ break; ++ case FSCPOS_SYSCTL_VOLT2: ++ results[0] = VOLT_FROM_REG(data->volt[2],330); ++ break; ++ default: ++ printk("fscpos: ctl_name %d not supported\n", ++ ctl_name); ++ *nrels_mag = 0; ++ return; ++ } ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ printk("fscpos: writing to chip not supported\n"); ++ } ++} ++ ++void fscpos_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ ++ switch(ctl_name) { ++ case FSCPOS_SYSCTL_FAN0: ++ fscpos_fan_internal(client,operation,ctl_name,nrels_mag,results, ++ 0,FSCPOS_REG_FAN0_STATE,FSCPOS_REG_FAN0_MIN, ++ FSCPOS_REG_FAN0_RIPPLE); ++ break; ++ case FSCPOS_SYSCTL_FAN1: ++ fscpos_fan_internal(client,operation,ctl_name,nrels_mag,results, ++ 1,FSCPOS_REG_FAN1_STATE,FSCPOS_REG_FAN1_MIN, ++ FSCPOS_REG_FAN1_RIPPLE); ++ break; ++ case FSCPOS_SYSCTL_FAN2: ++ fscpos_fan_internal(client,operation,ctl_name,nrels_mag,results, ++ 2,FSCPOS_REG_FAN2_STATE,0xff, ++ FSCPOS_REG_FAN2_RIPPLE); ++ break; ++ default: ++ printk("fscpos: illegal fan nr %d\n",ctl_name); ++ } ++} ++ ++#define RPM_FROM_REG(val) (val*60) ++ ++void fscpos_fan_internal(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results, int nr, ++ int reg_state, int reg_min, int reg_ripple ) ++{ ++ struct fscpos_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ fscpos_update_client(client); ++ results[0] = data->fan_status[nr] & 0x04; ++ results[1] = data->fan_min[nr]; ++ results[2] = data->fan_ripple[nr] & 0x03; ++ results[3] = RPM_FROM_REG(data->fan_act[nr]); ++ *nrels_mag = 4; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if(*nrels_mag >= 1) { ++ data->fan_status[nr] = results[0] & 0x04; ++ printk("fscpos: writing value 0x%02x to fan%d_status\n", ++ data->fan_status[nr],nr); ++ fscpos_write_value(client,reg_state, ++ data->fan_status[nr]); ++ } ++ if((*nrels_mag >= 2) && (nr < 2)) { ++ /* minimal speed for fan2 not supported */ ++ data->fan_min[nr] = results[1]; ++ printk("fscpos: writing value 0x%02x to fan%d_min\n", ++ data->fan_min[nr],nr); ++ fscpos_write_value(client,reg_min, ++ data->fan_min[nr]); ++ } ++ if(*nrels_mag >= 3) { ++ if((results[2] & 0x03) == 0) { ++ printk("fscpos: fan%d ripple 0 not allowed\n",nr); ++ return; ++ } ++ data->fan_ripple[nr] = results[2] & 0x03; ++ printk("fscpos: writing value 0x%02x to fan%d_ripple\n", ++ data->fan_ripple[nr],nr); ++ fscpos_write_value(client,reg_ripple, ++ data->fan_ripple[nr]); ++ } ++ } ++} ++ ++void fscpos_wdog(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct fscpos_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ fscpos_update_client(client); ++ results[0] = data->watchdog[0] ; ++ results[1] = data->watchdog[1] & 0x02; ++ results[2] = data->watchdog[2] & 0xb0; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->watchdog[0] = results[0] & 0xff; ++ printk("fscpos: writing value 0x%02x to wdog_preset\n", ++ data->watchdog[0]); ++ fscpos_write_value(client,FSCPOS_REG_WDOG_PRESET, ++ data->watchdog[0]); ++ } ++ if (*nrels_mag >= 2) { ++ data->watchdog[1] = results[1] & 0x02; ++ printk("fscpos: writing value 0x%02x to wdog_state\n", ++ data->watchdog[1]); ++ fscpos_write_value(client,FSCPOS_REG_WDOG_STATE, ++ data->watchdog[1]); ++ } ++ if (*nrels_mag >= 3) { ++ data->watchdog[2] = results[2] & 0xb0; ++ printk("fscpos: writing value 0x%02x to wdog_control\n", ++ data->watchdog[2]); ++ fscpos_write_value(client,FSCPOS_REG_WDOG_CONTROL, ++ data->watchdog[2]); ++ } ++ } ++} ++ ++static int __init sm_fscpos_init(void) ++{ ++ printk("fscpos.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&fscpos_driver); ++} ++ ++static void __exit sm_fscpos_exit(void) ++{ ++ i2c_del_driver(&fscpos_driver); ++} ++ ++ ++ ++MODULE_AUTHOR ++ ("Hermann Jung based on work from Frodo Looijaard and Philip Edelbrock "); ++MODULE_DESCRIPTION("fujitsu siemens poseidon chip driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_fscpos_init); ++module_exit(sm_fscpos_exit); +--- linux-old/drivers/sensors/fscscy.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/fscscy.c Mon Dec 13 20:18:46 2004 +@@ -0,0 +1,915 @@ ++/* ++ fscscy.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 2001 Martin Knoblauch ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ fujitsu siemens scylla chip, ++ module based on lm80.c, fscpos.c ++ Copyright (c) 1998, 1999 Frodo Looijaard ++ and Philip Edelbrock ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { 0x73, SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(fscscy); ++ ++/* The FSCSCY registers */ ++ ++/* chip identification */ ++#define FSCSCY_REG_IDENT_0 0x00 ++#define FSCSCY_REG_IDENT_1 0x01 ++#define FSCSCY_REG_IDENT_2 0x02 ++#define FSCSCY_REG_REVISION 0x03 ++ ++/* global control and status */ ++#define FSCSCY_REG_EVENT_STATE 0x04 ++#define FSCSCY_REG_CONTROL 0x05 ++ ++/* watchdog */ ++#define FSCSCY_REG_WDOG_PRESET 0x28 ++#define FSCSCY_REG_WDOG_STATE 0x23 ++#define FSCSCY_REG_WDOG_CONTROL 0x21 ++ ++/* ++** Fan definitions ++** ++** _RPMMIN: Minimum speed. Can be set via interface, but only for three of the fans ++** FAN1_RPMMIN is wired to Fan 0 (CPU Fans) ++** FAN4_RPMMIN is wired to Fan 2 (PS Fans ??) ++** FAN5_RPMMIN is wired to Fan 3 (AUX Fans ??) ++** _ACT: Actual Fan Speed ++** _STATE: Fan status register ++** _RIPPLE: Fan speed multiplier ++*/ ++ ++/* fan 0 */ ++#define FSCSCY_REG_FAN0_RPMMIN 0x65 ++#define FSCSCY_REG_FAN0_ACT 0x6b ++#define FSCSCY_REG_FAN0_STATE 0x62 ++#define FSCSCY_REG_FAN0_RIPPLE 0x6f ++ ++/* fan 1 */ ++#define FSCSCY_REG_FAN1_RPMMIN FSCSCY_REG_FAN0_RPMMIN ++#define FSCSCY_REG_FAN1_ACT 0x6c ++#define FSCSCY_REG_FAN1_STATE 0x61 ++#define FSCSCY_REG_FAN1_RIPPLE 0x6f ++ ++/* fan 2 */ ++#define FSCSCY_REG_FAN2_RPMMIN 0x55 ++#define FSCSCY_REG_FAN2_ACT 0x0e ++#define FSCSCY_REG_FAN2_STATE 0x0d ++#define FSCSCY_REG_FAN2_RIPPLE 0x0f ++ ++/* fan 3 */ ++#define FSCSCY_REG_FAN3_RPMMIN 0xa5 ++#define FSCSCY_REG_FAN3_ACT 0xab ++#define FSCSCY_REG_FAN3_STATE 0xa2 ++#define FSCSCY_REG_FAN3_RIPPLE 0xaf ++ ++/* fan 4 */ ++#define FSCSCY_REG_FAN4_RPMMIN FSCSCY_REG_FAN2_RPMMIN ++#define FSCSCY_REG_FAN4_ACT 0x5c ++#define FSCSCY_REG_FAN4_STATE 0x52 ++#define FSCSCY_REG_FAN4_RIPPLE 0x0f ++ ++/* fan 5 */ ++#define FSCSCY_REG_FAN5_RPMMIN FSCSCY_REG_FAN3_RPMMIN ++#define FSCSCY_REG_FAN5_ACT 0xbb ++#define FSCSCY_REG_FAN5_STATE 0xb2 ++#define FSCSCY_REG_FAN5_RIPPLE 0xbf ++ ++/* voltage supervision */ ++#define FSCSCY_REG_VOLT_12 0x45 ++#define FSCSCY_REG_VOLT_5 0x42 ++#define FSCSCY_REG_VOLT_BATT 0x48 ++ ++/* temperatures */ ++/* sensor 0 */ ++#define FSCSCY_REG_TEMP0_ACT 0x64 ++#define FSCSCY_REG_TEMP0_STATE 0x71 ++#define FSCSCY_REG_TEMP0_LIM 0x76 ++ ++/* sensor 1 */ ++#define FSCSCY_REG_TEMP1_ACT 0xD0 ++#define FSCSCY_REG_TEMP1_STATE 0xD1 ++#define FSCSCY_REG_TEMP1_LIM 0xD6 ++ ++/* sensor 2 */ ++#define FSCSCY_REG_TEMP2_ACT 0x32 ++#define FSCSCY_REG_TEMP2_STATE 0x81 ++#define FSCSCY_REG_TEMP2_LIM 0x86 ++ ++/* sensor3 */ ++#define FSCSCY_REG_TEMP3_ACT 0x35 ++#define FSCSCY_REG_TEMP3_STATE 0x91 ++#define FSCSCY_REG_TEMP3_LIM 0x96 ++ ++/* PCI Load */ ++#define FSCSCY_REG_PCILOAD 0x1a ++ ++/* Intrusion Sensor */ ++#define FSCSCY_REG_INTR_STATE 0x13 ++#define FSCSCY_REG_INTR_CTRL 0x12 ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++ ++#define IN_TO_REG(val,nr) (SENSORS_LIMIT((val),0,255)) ++#define IN_FROM_REG(val,nr) (val) ++ ++/* Initial limits */ ++ ++/* For each registered FSCSCY, we need to keep some data in memory. That ++ data is pointed to by fscscy_list[NR]->data. The structure itself is ++ dynamically allocated, at the same time when a new fscscy client is ++ allocated. */ ++struct fscscy_data { ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 revision; /* revision of chip */ ++ u8 global_event; /* global event status */ ++ u8 global_control; /* global control register */ ++ u8 watchdog[3]; /* watchdog */ ++ u8 volt[3]; /* 12, 5, battery current */ ++ u8 volt_min[3]; /* minimum voltages over module "lifetime" */ ++ u8 volt_max[3]; /* maximum voltages over module "lifetime" */ ++ u8 temp_act[4]; /* temperature */ ++ u8 temp_status[4]; /* status of temp. sensor */ ++ u8 temp_lim[4]; /* limit temperature of temp. sensor */ ++ u8 temp_min[4]; /* minimum of temp. sensor, this is just calculated by the module */ ++ u8 temp_max[4]; /* maximum of temp. sensor, this is just calculsted by the module */ ++ u8 fan_act[6]; /* fans revolutions per second */ ++ u8 fan_status[6]; /* fan status */ ++ u8 fan_rpmmin[6]; /* fan min value for rps */ ++ u8 fan_ripple[6]; /* divider for rps */ ++ u8 fan_min[6]; /* minimum RPM over module "lifetime" */ ++ u8 fan_max[6]; /* maximum RPM over module "lifetime" */ ++ u8 pciload; /* PCILoad value */ ++ u8 intr_status; /* Intrusion Status */ ++ u8 intr_control; /* Intrusion Control */ ++}; ++ ++ ++static int fscscy_attach_adapter(struct i2c_adapter *adapter); ++static int fscscy_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int fscscy_detach_client(struct i2c_client *client); ++ ++static int fscscy_read_value(struct i2c_client *client, u8 register); ++static int fscscy_write_value(struct i2c_client *client, u8 register, ++ u8 value); ++static void fscscy_update_client(struct i2c_client *client); ++static void fscscy_init_client(struct i2c_client *client); ++ ++ ++static void fscscy_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++static void fscscy_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void fscscy_fan_internal(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results, ++ int nr, int reg_state, int reg_min, int res_ripple); ++static void fscscy_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void fscscy_volt(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void fscscy_wdog(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void fscscy_pciload(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void fscscy_intrusion(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static int fscscy_id = 0; ++ ++static struct i2c_driver fscscy_driver = { ++ .owner = THIS_MODULE, ++ .name = "FSCSCY sensor driver", ++ .id = I2C_DRIVERID_FSCSCY, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = fscscy_attach_adapter, ++ .detach_client = fscscy_detach_client, ++}; ++ ++/* The /proc/sys entries */ ++ ++/* -- SENSORS SYSCTL START -- */ ++#define FSCSCY_SYSCTL_VOLT0 1000 /* 12 volt supply */ ++#define FSCSCY_SYSCTL_VOLT1 1001 /* 5 volt supply */ ++#define FSCSCY_SYSCTL_VOLT2 1002 /* batterie voltage*/ ++#define FSCSCY_SYSCTL_FAN0 1101 /* state, min, ripple, actual value fan 0 */ ++#define FSCSCY_SYSCTL_FAN1 1102 /* state, min, ripple, actual value fan 1 */ ++#define FSCSCY_SYSCTL_FAN2 1103 /* state, min, ripple, actual value fan 2 */ ++#define FSCSCY_SYSCTL_FAN3 1104 /* state, min, ripple, actual value fan 3 */ ++#define FSCSCY_SYSCTL_FAN4 1105 /* state, min, ripple, actual value fan 4 */ ++#define FSCSCY_SYSCTL_FAN5 1106 /* state, min, ripple, actual value fan 5 */ ++#define FSCSCY_SYSCTL_TEMP0 1201 /* state and value of sensor 0, cpu die */ ++#define FSCSCY_SYSCTL_TEMP1 1202 /* state and value of sensor 1, motherboard */ ++#define FSCSCY_SYSCTL_TEMP2 1203 /* state and value of sensor 2, chassis */ ++#define FSCSCY_SYSCTL_TEMP3 1204 /* state and value of sensor 3, chassis */ ++#define FSCSCY_SYSCTL_REV 2000 /* Revision */ ++#define FSCSCY_SYSCTL_EVENT 2001 /* global event status */ ++#define FSCSCY_SYSCTL_CONTROL 2002 /* global control byte */ ++#define FSCSCY_SYSCTL_WDOG 2003 /* state, min, ripple, actual value fan 2 */ ++#define FSCSCY_SYSCTL_PCILOAD 2004 /* PCILoad value */ ++#define FSCSCY_SYSCTL_INTRUSION 2005 /* state, control for intrusion sensor */ ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected FSCSCY. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table fscscy_dir_table_template[] = { ++ {FSCSCY_SYSCTL_REV, "rev", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_in}, ++ {FSCSCY_SYSCTL_EVENT, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_in}, ++ {FSCSCY_SYSCTL_CONTROL, "control", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_in}, ++ {FSCSCY_SYSCTL_TEMP0, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_temp}, ++ {FSCSCY_SYSCTL_TEMP1, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_temp}, ++ {FSCSCY_SYSCTL_TEMP2, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_temp}, ++ {FSCSCY_SYSCTL_TEMP3, "temp4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_temp}, ++ {FSCSCY_SYSCTL_VOLT0, "in0", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_volt}, ++ {FSCSCY_SYSCTL_VOLT1, "in1", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_volt}, ++ {FSCSCY_SYSCTL_VOLT2, "in2", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_volt}, ++ {FSCSCY_SYSCTL_FAN0, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_fan}, ++ {FSCSCY_SYSCTL_FAN1, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_fan}, ++ {FSCSCY_SYSCTL_FAN2, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_fan}, ++ {FSCSCY_SYSCTL_FAN3, "fan4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_fan}, ++ {FSCSCY_SYSCTL_FAN4, "fan5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_fan}, ++ {FSCSCY_SYSCTL_FAN5, "fan6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_fan}, ++ {FSCSCY_SYSCTL_WDOG, "wdog", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_wdog}, ++ {FSCSCY_SYSCTL_PCILOAD, "pciload", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_pciload}, ++ {FSCSCY_SYSCTL_INTRUSION, "intrusion", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &fscscy_intrusion}, ++ {0} ++}; ++ ++static int fscscy_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, fscscy_detect); ++} ++ ++int fscscy_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct fscscy_data *data; ++ int err = 0; ++ const char *type_name, *client_name; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("fscscy.o: fscscy_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access fscscy_{read,write}_value. */ ++ if (!(data = kmalloc(sizeof(struct fscscy_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &fscscy_driver; ++ new_client->flags = 0; ++ ++ /* Do the remaining detection unless force or force_fscscy parameter */ ++ if (kind < 0) { ++ if (fscscy_read_value(new_client, FSCSCY_REG_IDENT_0) != 0x53) ++ goto ERROR1; ++ if (fscscy_read_value(new_client, FSCSCY_REG_IDENT_1) != 0x43) ++ goto ERROR1; ++ if (fscscy_read_value(new_client, FSCSCY_REG_IDENT_2) != 0x59) ++ goto ERROR1; ++ } ++ ++ kind = fscscy; ++ ++ type_name = "fscscy"; ++ client_name = "fsc scylla chip"; ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = fscscy_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, type_name, ++ fscscy_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ fscscy_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int fscscy_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct fscscy_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("fscscy.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++static int fscscy_read_value(struct i2c_client *client, u8 reg) ++{ ++#ifdef DEBUG ++ printk("fscscy: read reg 0x%02x\n",reg); ++#endif ++ return i2c_smbus_read_byte_data(client, reg); ++} ++ ++static int fscscy_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++#ifdef DEBUG ++ printk("fscscy: write reg 0x%02x, val 0x%02x\n",reg, value); ++#endif ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++/* Called when we have found a new FSCSCY. It should set limits, etc. */ ++static void fscscy_init_client(struct i2c_client *client) ++{ ++ struct fscscy_data *data = client->data; ++ ++ /* read revision from chip */ ++ data->revision = fscscy_read_value(client,FSCSCY_REG_REVISION); ++ ++ /* Initialize min/max values from chip */ ++ data->fan_min[0] = data->fan_max[0] = fscscy_read_value(client, FSCSCY_REG_FAN0_ACT); ++ data->fan_min[1] = data->fan_max[1] = fscscy_read_value(client, FSCSCY_REG_FAN1_ACT); ++ data->fan_min[2] = data->fan_max[2] = fscscy_read_value(client, FSCSCY_REG_FAN2_ACT); ++ data->fan_min[3] = data->fan_max[3] = fscscy_read_value(client, FSCSCY_REG_FAN3_ACT); ++ data->fan_min[4] = data->fan_max[4] = fscscy_read_value(client, FSCSCY_REG_FAN4_ACT); ++ data->fan_min[4] = data->fan_max[5] = fscscy_read_value(client, FSCSCY_REG_FAN5_ACT); ++ data->temp_min[0] = data->temp_max[0] = fscscy_read_value(client, FSCSCY_REG_TEMP0_ACT); ++ data->temp_min[1] = data->temp_max[1] = fscscy_read_value(client, FSCSCY_REG_TEMP1_ACT); ++ data->temp_min[2] = data->temp_max[2] = fscscy_read_value(client, FSCSCY_REG_TEMP2_ACT); ++ data->temp_min[3] = data->temp_max[3] = fscscy_read_value(client, FSCSCY_REG_TEMP3_ACT); ++ data->volt_min[0] = data->volt_max[0] = fscscy_read_value(client, FSCSCY_REG_VOLT_12); ++ data->volt_min[1] = data->volt_max[1] = fscscy_read_value(client, FSCSCY_REG_VOLT_5); ++ data->volt_min[2] = data->volt_max[2] = fscscy_read_value(client, FSCSCY_REG_VOLT_BATT); ++} ++ ++static void fscscy_update_client(struct i2c_client *client) ++{ ++ struct fscscy_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > 2 * HZ) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("Starting fscscy update\n"); ++#endif ++ data->temp_act[0] = fscscy_read_value(client, FSCSCY_REG_TEMP0_ACT); ++ if (data->temp_min[0] > data->temp_act[0]) data->temp_min[0] = data->temp_act[0]; ++ if (data->temp_max[0] < data->temp_act[0]) data->temp_max[0] = data->temp_act[0]; ++ data->temp_act[1] = fscscy_read_value(client, FSCSCY_REG_TEMP1_ACT); ++ if (data->temp_min[1] > data->temp_act[1]) data->temp_min[1] = data->temp_act[1]; ++ if (data->temp_max[1] < data->temp_act[1]) data->temp_max[1] = data->temp_act[1]; ++ data->temp_act[2] = fscscy_read_value(client, FSCSCY_REG_TEMP2_ACT); ++ if (data->temp_min[2] > data->temp_act[2]) data->temp_min[2] = data->temp_act[2]; ++ if (data->temp_max[2] < data->temp_act[2]) data->temp_max[2] = data->temp_act[2]; ++ data->temp_act[3] = fscscy_read_value(client, FSCSCY_REG_TEMP3_ACT); ++ if (data->temp_min[3] > data->temp_act[3]) data->temp_min[3] = data->temp_act[3]; ++ if (data->temp_max[3] < data->temp_act[3]) data->temp_max[3] = data->temp_act[3]; ++ data->temp_status[0] = fscscy_read_value(client, FSCSCY_REG_TEMP0_STATE); ++ data->temp_status[1] = fscscy_read_value(client, FSCSCY_REG_TEMP1_STATE); ++ data->temp_status[2] = fscscy_read_value(client, FSCSCY_REG_TEMP2_STATE); ++ data->temp_status[3] = fscscy_read_value(client, FSCSCY_REG_TEMP3_STATE); ++ data->temp_lim[0] = fscscy_read_value(client, FSCSCY_REG_TEMP0_LIM); ++ data->temp_lim[1] = fscscy_read_value(client, FSCSCY_REG_TEMP1_LIM); ++ data->temp_lim[2] = fscscy_read_value(client, FSCSCY_REG_TEMP2_LIM); ++ data->temp_lim[3] = fscscy_read_value(client, FSCSCY_REG_TEMP3_LIM); ++ ++ data->volt[0] = fscscy_read_value(client, FSCSCY_REG_VOLT_12); ++ if (data->volt_min[0] > data->volt[0]) data->volt_min[0] = data->volt[0]; ++ if (data->volt_max[0] < data->volt[0]) data->volt_max[0] = data->volt[0]; ++ data->volt[1] = fscscy_read_value(client, FSCSCY_REG_VOLT_5); ++ if (data->volt_min[1] > data->volt[1]) data->volt_min[1] = data->volt[1]; ++ if (data->volt_max[1] < data->volt[1]) data->volt_max[1] = data->volt[1]; ++ data->volt[2] = fscscy_read_value(client, FSCSCY_REG_VOLT_BATT); ++ if (data->volt_min[2] > data->volt[2]) data->volt_min[2] = data->volt[2]; ++ if (data->volt_max[2] < data->volt[2]) data->volt_max[2] = data->volt[2]; ++ ++ data->fan_act[0] = fscscy_read_value(client, FSCSCY_REG_FAN0_ACT); ++ if (data->fan_min[0] > data->fan_act[0]) data->fan_min[0] = data->fan_act[0]; ++ if (data->fan_max[0] < data->fan_act[0]) data->fan_max[0] = data->fan_act[0]; ++ data->fan_act[1] = fscscy_read_value(client, FSCSCY_REG_FAN1_ACT); ++ if (data->fan_min[1] > data->fan_act[1]) data->fan_min[1] = data->fan_act[1]; ++ if (data->fan_max[1] < data->fan_act[1]) data->fan_max[1] = data->fan_act[1]; ++ data->fan_act[2] = fscscy_read_value(client, FSCSCY_REG_FAN2_ACT); ++ if (data->fan_min[2] > data->fan_act[2]) data->fan_min[2] = data->fan_act[2]; ++ if (data->fan_max[2] < data->fan_act[2]) data->fan_max[2] = data->fan_act[2]; ++ data->fan_act[3] = fscscy_read_value(client, FSCSCY_REG_FAN3_ACT); ++ if (data->fan_min[3] > data->fan_act[3]) data->fan_min[3] = data->fan_act[3]; ++ if (data->fan_max[3] < data->fan_act[3]) data->fan_max[3] = data->fan_act[3]; ++ data->fan_act[4] = fscscy_read_value(client, FSCSCY_REG_FAN4_ACT); ++ if (data->fan_min[4] > data->fan_act[4]) data->fan_min[4] = data->fan_act[4]; ++ if (data->fan_max[4] < data->fan_act[4]) data->fan_max[4] = data->fan_act[4]; ++ data->fan_act[5] = fscscy_read_value(client, FSCSCY_REG_FAN5_ACT); ++ if (data->fan_min[5] > data->fan_act[5]) data->fan_min[5] = data->fan_act[5]; ++ if (data->fan_max[5] < data->fan_act[5]) data->fan_max[5] = data->fan_act[5]; ++ data->fan_status[0] = fscscy_read_value(client, FSCSCY_REG_FAN0_STATE); ++ data->fan_status[1] = fscscy_read_value(client, FSCSCY_REG_FAN1_STATE); ++ data->fan_status[2] = fscscy_read_value(client, FSCSCY_REG_FAN2_STATE); ++ data->fan_status[3] = fscscy_read_value(client, FSCSCY_REG_FAN3_STATE); ++ data->fan_status[4] = fscscy_read_value(client, FSCSCY_REG_FAN4_STATE); ++ data->fan_status[5] = fscscy_read_value(client, FSCSCY_REG_FAN5_STATE); ++ data->fan_rpmmin[0] = fscscy_read_value(client, FSCSCY_REG_FAN0_RPMMIN); ++ data->fan_rpmmin[1] = fscscy_read_value(client, FSCSCY_REG_FAN1_RPMMIN); ++ data->fan_rpmmin[2] = fscscy_read_value(client, FSCSCY_REG_FAN2_RPMMIN); ++ data->fan_rpmmin[3] = fscscy_read_value(client, FSCSCY_REG_FAN3_RPMMIN); ++ data->fan_rpmmin[4] = fscscy_read_value(client, FSCSCY_REG_FAN4_RPMMIN); ++ data->fan_rpmmin[5] = fscscy_read_value(client, FSCSCY_REG_FAN5_RPMMIN); ++ data->fan_ripple[0] = fscscy_read_value(client, FSCSCY_REG_FAN0_RIPPLE); ++ data->fan_ripple[1] = fscscy_read_value(client, FSCSCY_REG_FAN1_RIPPLE); ++ data->fan_ripple[2] = fscscy_read_value(client, FSCSCY_REG_FAN2_RIPPLE); ++ data->fan_ripple[3] = fscscy_read_value(client, FSCSCY_REG_FAN3_RIPPLE); ++ data->fan_ripple[4] = fscscy_read_value(client, FSCSCY_REG_FAN4_RIPPLE); ++ data->fan_ripple[5] = fscscy_read_value(client, FSCSCY_REG_FAN5_RIPPLE); ++ ++ data->watchdog[0] = fscscy_read_value(client, FSCSCY_REG_WDOG_PRESET); ++ data->watchdog[1] = fscscy_read_value(client, FSCSCY_REG_WDOG_STATE); ++ data->watchdog[2] = fscscy_read_value(client, FSCSCY_REG_WDOG_CONTROL); ++ ++ data->global_event = fscscy_read_value(client, FSCSCY_REG_EVENT_STATE); ++ data->global_control = fscscy_read_value(client, FSCSCY_REG_CONTROL); ++ data->pciload = fscscy_read_value(client, FSCSCY_REG_PCILOAD); ++ data->intr_status = fscscy_read_value(client, FSCSCY_REG_INTR_STATE); ++ data->intr_control = fscscy_read_value(client, FSCSCY_REG_INTR_CTRL); ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the date ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++void fscscy_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct fscscy_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ fscscy_update_client(client); ++ switch(ctl_name) { ++ case FSCSCY_SYSCTL_REV: ++ results[0] = data->revision ; ++ break; ++ case FSCSCY_SYSCTL_EVENT: ++ results[0] = data->global_event & 0x9f; /* MKN */ ++ break; ++ case FSCSCY_SYSCTL_CONTROL: ++ results[0] = data->global_control & 0x19; /* MKN */ ++ break; ++ default: ++ printk("fscscy: ctl_name %d not supported\n", ++ ctl_name); ++ *nrels_mag = 0; ++ return; ++ } ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if((ctl_name == FSCSCY_SYSCTL_CONTROL) && (*nrels_mag >= 1)) { ++ data->global_control = (data->global_control & 0x18) | (results[0] & 0x01); /* MKN */ ++ printk("fscscy: writing 0x%02x to global_control\n", ++ data->global_control); ++ fscscy_write_value(client,FSCSCY_REG_CONTROL, ++ data->global_control); ++ } ++ else ++ printk("fscscy: writing to chip not supported\n"); ++ } ++} ++ ++#define TEMP_FROM_REG(val) (val-128) ++ ++ ++void fscscy_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct fscscy_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ fscscy_update_client(client); ++ switch(ctl_name) { ++ case FSCSCY_SYSCTL_TEMP0: ++ results[0] = data->temp_status[0] & 0x03; ++ results[1] = TEMP_FROM_REG(data->temp_act[0]); ++ results[2] = TEMP_FROM_REG(data->temp_lim[0]); ++ results[3] = TEMP_FROM_REG(data->temp_min[0]); ++ results[4] = TEMP_FROM_REG(data->temp_max[0]); ++ break; ++ case FSCSCY_SYSCTL_TEMP1: ++ results[0] = data->temp_status[1] & 0x03; ++ results[1] = TEMP_FROM_REG(data->temp_act[1]); ++ results[2] = TEMP_FROM_REG(data->temp_lim[1]); ++ results[3] = TEMP_FROM_REG(data->temp_min[1]); ++ results[4] = TEMP_FROM_REG(data->temp_max[1]); ++ break; ++ case FSCSCY_SYSCTL_TEMP2: ++ results[0] = data->temp_status[2] & 0x03; ++ results[1] = TEMP_FROM_REG(data->temp_act[2]); ++ results[2] = TEMP_FROM_REG(data->temp_lim[2]); ++ results[3] = TEMP_FROM_REG(data->temp_min[2]); ++ results[4] = TEMP_FROM_REG(data->temp_max[2]); ++ break; ++ case FSCSCY_SYSCTL_TEMP3: ++ results[0] = data->temp_status[3] & 0x03; ++ results[1] = TEMP_FROM_REG(data->temp_act[3]); ++ results[2] = TEMP_FROM_REG(data->temp_lim[3]); ++ results[3] = TEMP_FROM_REG(data->temp_min[3]); ++ results[4] = TEMP_FROM_REG(data->temp_max[3]); ++ break; ++ default: ++ printk("fscscy: ctl_name %d not supported\n", ++ ctl_name); ++ *nrels_mag = 0; ++ return; ++ } ++ *nrels_mag = 5; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if(*nrels_mag >= 1) { ++ switch(ctl_name) { ++ case FSCSCY_SYSCTL_TEMP0: ++ data->temp_status[0] = ++ (data->temp_status[0] & ~0x02) ++ | (results[0] & 0x02); ++ printk("fscscy: writing value 0x%02x " ++ "to temp0_status\n", ++ data->temp_status[0]); ++ fscscy_write_value(client, ++ FSCSCY_REG_TEMP0_STATE, ++ data->temp_status[0] & 0x02); ++ break; ++ case FSCSCY_SYSCTL_TEMP1: ++ data->temp_status[1] = (data->temp_status[1] & ~0x02) | (results[0] & 0x02); ++ printk("fscscy: writing value 0x%02x to temp1_status\n", data->temp_status[1]); ++ fscscy_write_value(client,FSCSCY_REG_TEMP1_STATE, ++ data->temp_status[1] & 0x02); ++ break; ++ case FSCSCY_SYSCTL_TEMP2: ++ data->temp_status[2] = (data->temp_status[2] & ~0x02) | (results[0] & 0x02); ++ printk("fscscy: writing value 0x%02x to temp2_status\n", data->temp_status[2]); ++ fscscy_write_value(client,FSCSCY_REG_TEMP2_STATE, ++ data->temp_status[2] & 0x02); ++ break; ++ case FSCSCY_SYSCTL_TEMP3: ++ data->temp_status[3] = (data->temp_status[3] & ~0x02) | (results[0] & 0x02); ++ printk("fscscy: writing value 0x%02x to temp3_status\n", data->temp_status[3]); ++ fscscy_write_value(client,FSCSCY_REG_TEMP3_STATE, ++ data->temp_status[3] & 0x02); ++ break; ++ default: ++ printk("fscscy: ctl_name %d not supported\n",ctl_name); ++ } ++ } ++ else ++ printk("fscscy: writing to chip not supported\n"); ++ } ++} ++ ++#define VOLT_FROM_REG(val,mult) (val*mult/255) ++ ++void fscscy_volt(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct fscscy_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ fscscy_update_client(client); ++ switch(ctl_name) { ++ case FSCSCY_SYSCTL_VOLT0: ++ results[0] = VOLT_FROM_REG(data->volt[0],1420); ++ results[1] = VOLT_FROM_REG(data->volt_min[0],1420); ++ results[2] = VOLT_FROM_REG(data->volt_max[0],1420); ++ break; ++ case FSCSCY_SYSCTL_VOLT1: ++ results[0] = VOLT_FROM_REG(data->volt[1],660); ++ results[1] = VOLT_FROM_REG(data->volt_min[1],660); ++ results[2] = VOLT_FROM_REG(data->volt_max[1],660); ++ break; ++ case FSCSCY_SYSCTL_VOLT2: ++ results[0] = VOLT_FROM_REG(data->volt[2],330); ++ results[1] = VOLT_FROM_REG(data->volt_min[2],330); ++ results[2] = VOLT_FROM_REG(data->volt_max[2],330); ++ break; ++ default: ++ printk("fscscy: ctl_name %d not supported\n", ++ ctl_name); ++ *nrels_mag = 0; ++ return; ++ } ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ printk("fscscy: writing to chip not supported\n"); ++ } ++} ++ ++void fscscy_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ ++ switch(ctl_name) { ++ case FSCSCY_SYSCTL_FAN0: ++ fscscy_fan_internal(client,operation,ctl_name,nrels_mag,results, ++ 0,FSCSCY_REG_FAN0_STATE,FSCSCY_REG_FAN0_RPMMIN, ++ FSCSCY_REG_FAN0_RIPPLE); ++ break; ++ case FSCSCY_SYSCTL_FAN1: ++ fscscy_fan_internal(client,operation,ctl_name,nrels_mag,results, ++ 1,FSCSCY_REG_FAN1_STATE,FSCSCY_REG_FAN1_RPMMIN, ++ FSCSCY_REG_FAN1_RIPPLE); ++ break; ++ case FSCSCY_SYSCTL_FAN2: ++ fscscy_fan_internal(client,operation,ctl_name,nrels_mag,results, ++ 2,FSCSCY_REG_FAN2_STATE,FSCSCY_REG_FAN2_RPMMIN, ++ FSCSCY_REG_FAN2_RIPPLE); ++ break; ++ case FSCSCY_SYSCTL_FAN3: ++ fscscy_fan_internal(client,operation,ctl_name,nrels_mag,results, ++ 3,FSCSCY_REG_FAN3_STATE,FSCSCY_REG_FAN3_RPMMIN, ++ FSCSCY_REG_FAN3_RIPPLE); ++ break; ++ case FSCSCY_SYSCTL_FAN4: ++ fscscy_fan_internal(client,operation,ctl_name,nrels_mag,results, ++ 4,FSCSCY_REG_FAN4_STATE,FSCSCY_REG_FAN4_RPMMIN, ++ FSCSCY_REG_FAN4_RIPPLE); ++ break; ++ case FSCSCY_SYSCTL_FAN5: ++ fscscy_fan_internal(client,operation,ctl_name,nrels_mag,results, ++ 5,FSCSCY_REG_FAN5_STATE,FSCSCY_REG_FAN5_RPMMIN, ++ FSCSCY_REG_FAN5_RIPPLE); ++ break; ++ default: ++ printk("fscscy: illegal fan nr %d\n",ctl_name); ++ } ++} ++ ++#define RPM_FROM_REG(val) (val*60) ++ ++void fscscy_fan_internal(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results, int nr, ++ int reg_state, int reg_min, int reg_ripple ) ++{ ++ struct fscscy_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ fscscy_update_client(client); ++ results[0] = data->fan_status[nr] & 0x0f; /* MKN */ ++ results[1] = data->fan_rpmmin[nr]; ++ results[2] = data->fan_ripple[nr] & 0x03; ++ results[3] = RPM_FROM_REG(data->fan_act[nr]); ++ results[4] = RPM_FROM_REG(data->fan_min[nr]); ++ results[5] = RPM_FROM_REG(data->fan_max[nr]); ++ *nrels_mag = 6; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if(*nrels_mag >= 1) { ++ data->fan_status[nr] = (data->fan_status[nr] & 0x0b) | (results[0] & 0x04); /* MKN */ ++ printk("fscscy: writing value 0x%02x to fan%d_status\n", ++ data->fan_status[nr],nr); ++ fscscy_write_value(client,reg_state, ++ data->fan_status[nr]); ++ } ++ if(*nrels_mag >= 2) { ++ if((results[1] & 0xff) == 0) { ++ printk("fscscy: fan%d rpmmin 0 not allowed for safety reasons\n",nr); ++ return; ++ } ++ data->fan_rpmmin[nr] = results[1]; ++ printk("fscscy: writing value 0x%02x to fan%d_min\n", ++ data->fan_rpmmin[nr],nr); ++ fscscy_write_value(client,reg_min, ++ data->fan_rpmmin[nr]); ++ } ++ if(*nrels_mag >= 3) { ++ if((results[2] & 0x03) == 0) { ++ printk("fscscy: fan%d ripple 0 is nonsense/not allowed\n",nr); ++ return; ++ } ++ data->fan_ripple[nr] = results[2] & 0x03; ++ printk("fscscy: writing value 0x%02x to fan%d_ripple\n", ++ data->fan_ripple[nr],nr); ++ fscscy_write_value(client,reg_ripple, ++ data->fan_ripple[nr]); ++ } ++ } ++} ++ ++void fscscy_wdog(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct fscscy_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ fscscy_update_client(client); ++ results[0] = data->watchdog[0] ; ++ results[1] = data->watchdog[1] & 0x02; ++ results[2] = data->watchdog[2] & 0xb0; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->watchdog[0] = results[0] & 0xff; ++ printk("fscscy: writing value 0x%02x to wdog_preset\n", ++ data->watchdog[0]); ++ fscscy_write_value(client,FSCSCY_REG_WDOG_PRESET, ++ data->watchdog[0]); ++ } ++ if (*nrels_mag >= 2) { ++ data->watchdog[1] = results[1] & 0x02; ++ printk("fscscy: writing value 0x%02x to wdog_state\n", ++ data->watchdog[1]); ++ fscscy_write_value(client,FSCSCY_REG_WDOG_STATE, ++ data->watchdog[1]); ++ } ++ if (*nrels_mag >= 3) { ++ data->watchdog[2] = results[2] & 0xb0; ++ printk("fscscy: writing value 0x%02x to wdog_control\n", ++ data->watchdog[2]); ++ fscscy_write_value(client,FSCSCY_REG_WDOG_CONTROL, ++ data->watchdog[2]); ++ } ++ } ++} ++ ++void fscscy_pciload(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct fscscy_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ fscscy_update_client(client); ++ results[0] = data->pciload; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ printk("fscscy: writing PCILOAD to chip not supported\n"); ++ } ++} ++ ++void fscscy_intrusion(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct fscscy_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ fscscy_update_client(client); ++ results[0] = data->intr_control & 0x80; ++ results[1] = data->intr_status & 0xc0; ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->intr_control = results[0] & 0x80; ++ printk("fscscy: writing value 0x%02x to intr_control\n", ++ data->intr_control); ++ fscscy_write_value(client,FSCSCY_REG_INTR_CTRL, ++ data->intr_control); ++ } ++ } ++} ++ ++static int __init sm_fscscy_init(void) ++{ ++ printk("fscscy.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&fscscy_driver); ++} ++ ++static void __exit sm_fscscy_exit(void) ++{ ++ i2c_del_driver(&fscscy_driver); ++} ++ ++ ++ ++MODULE_AUTHOR ++ ("Martin Knoblauch based on work (fscpos) from Hermann Jung "); ++MODULE_DESCRIPTION("fujitsu siemens scylla chip driver"); ++ ++module_init(sm_fscscy_init); ++module_exit(sm_fscscy_exit); +--- linux-old/drivers/sensors/gl518sm.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/gl518sm.c Mon Dec 13 20:18:46 2004 +@@ -0,0 +1,989 @@ ++/* ++ gl518sm.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard , ++ Kyösti Mälkki ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#ifdef __SMP__ ++#include ++#endif ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { 0x2c, 0x2d, SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_2(gl518sm_r00, gl518sm_r80); ++ ++/* Defining this will enable debug messages for the voltage iteration ++ code used with rev 0 ICs */ ++#undef DEBUG_VIN ++ ++/* Many GL518 constants specified below */ ++ ++/* The GL518 registers */ ++#define GL518_REG_CHIP_ID 0x00 ++#define GL518_REG_REVISION 0x01 ++#define GL518_REG_VENDOR_ID 0x02 ++#define GL518_REG_CONF 0x03 ++#define GL518_REG_TEMP 0x04 ++#define GL518_REG_TEMP_OVER 0x05 ++#define GL518_REG_TEMP_HYST 0x06 ++#define GL518_REG_FAN_COUNT 0x07 ++#define GL518_REG_FAN_LIMIT 0x08 ++#define GL518_REG_VIN1_LIMIT 0x09 ++#define GL518_REG_VIN2_LIMIT 0x0a ++#define GL518_REG_VIN3_LIMIT 0x0b ++#define GL518_REG_VDD_LIMIT 0x0c ++#define GL518_REG_VIN3 0x0d ++#define GL518_REG_MISC 0x0f ++#define GL518_REG_ALARM 0x10 ++#define GL518_REG_MASK 0x11 ++#define GL518_REG_INT 0x12 ++#define GL518_REG_VIN2 0x13 ++#define GL518_REG_VIN1 0x14 ++#define GL518_REG_VDD 0x15 ++ ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++ ++#define TEMP_TO_REG(val) (SENSORS_LIMIT(((((val)<0?(val)-5:(val)+5) / 10)+119),\ ++ 0,255)) ++#define TEMP_FROM_REG(val) (((val) - 119) * 10) ++ ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 255; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((960000 + rpm * div / 2) / (rpm * div), 1, ++ 254); ++} ++ ++#define FAN_FROM_REG(val,div) \ ++ ( (val)==0 ? 0 : (val)==255 ? 0 : (960000/((val)*(div))) ) ++ ++#define IN_TO_REG(val) (SENSORS_LIMIT((((val)*10+8)/19),0,255)) ++#define IN_FROM_REG(val) (((val)*19)/10) ++ ++#define VDD_TO_REG(val) (SENSORS_LIMIT((((val)*10+11)/23),0,255)) ++#define VDD_FROM_REG(val) (((val)*23)/10) ++ ++#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) ++#define DIV_FROM_REG(val) (1 << (val)) ++ ++#define ALARMS_FROM_REG(val) val ++ ++#define BEEP_ENABLE_TO_REG(val) ((val)?0:1) ++#define BEEP_ENABLE_FROM_REG(val) ((val)?0:1) ++ ++#define BEEPS_TO_REG(val) ((val) & 0x7f) ++#define BEEPS_FROM_REG(val) ((val) & 0x7f) ++ ++/* Each client has this additional data */ ++struct gl518_data { ++ struct i2c_client client; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ ++ int iterate_lock; ++ int quit_thread; ++ struct task_struct *thread; ++ wait_queue_head_t wq; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ unsigned long last_updated_v00; ++ /* In jiffies (used only by rev00 chips) */ ++ ++ u8 voltage[4]; /* Register values; [0] = VDD */ ++ u8 voltage_min[4]; /* Register values; [0] = VDD */ ++ u8 voltage_max[4]; /* Register values; [0] = VDD */ ++ u8 iter_voltage[4]; /* Register values; [0] = VDD */ ++ u8 fan[2]; ++ u8 fan_min[2]; ++ u8 temp; /* Register values */ ++ u8 temp_over; /* Register values */ ++ u8 temp_hyst; /* Register values */ ++ u8 alarms, beeps; /* Register value */ ++ u8 alarm_mask; /* Register value */ ++ u8 fan_div[2]; /* Register encoding, shifted right */ ++ u8 beep_enable; /* Boolean */ ++ u8 iterate; /* Voltage iteration mode */ ++}; ++ ++static int gl518_attach_adapter(struct i2c_adapter *adapter); ++static int gl518_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static void gl518_init_client(struct i2c_client *client); ++static int gl518_detach_client(struct i2c_client *client); ++ ++static int gl518_read_value(struct i2c_client *client, u8 reg); ++static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value); ++static void gl518_update_client(struct i2c_client *client); ++ ++static void gl518_update_client_rev00(struct i2c_client *client); ++static void gl518_update_iterate(struct i2c_client *client); ++ ++static void gl518_vin(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl518_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl518_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl518_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl518_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl518_beep(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl518_fan1off(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl518_iterate(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver gl518_driver = { ++ .owner = THIS_MODULE, ++ .name = "GL518SM sensor chip driver", ++ .id = I2C_DRIVERID_GL518, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = gl518_attach_adapter, ++ .detach_client = gl518_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define GL518_SYSCTL_VDD 1000 /* Volts * 100 */ ++#define GL518_SYSCTL_VIN1 1001 ++#define GL518_SYSCTL_VIN2 1002 ++#define GL518_SYSCTL_VIN3 1003 ++#define GL518_SYSCTL_FAN1 1101 /* RPM */ ++#define GL518_SYSCTL_FAN2 1102 ++#define GL518_SYSCTL_TEMP 1200 /* Degrees Celcius * 10 */ ++#define GL518_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define GL518_SYSCTL_ALARMS 2001 /* bitvector */ ++#define GL518_SYSCTL_BEEP 2002 /* bitvector */ ++#define GL518_SYSCTL_FAN1OFF 2003 ++#define GL518_SYSCTL_ITERATE 2004 ++ ++#define GL518_ALARM_VDD 0x01 ++#define GL518_ALARM_VIN1 0x02 ++#define GL518_ALARM_VIN2 0x04 ++#define GL518_ALARM_VIN3 0x08 ++#define GL518_ALARM_TEMP 0x10 ++#define GL518_ALARM_FAN1 0x20 ++#define GL518_ALARM_FAN2 0x40 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected GL518. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table gl518_dir_table_template[] = { ++ {GL518_SYSCTL_VIN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl518_vin}, ++ {GL518_SYSCTL_VIN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl518_vin}, ++ {GL518_SYSCTL_VIN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl518_vin}, ++ {GL518_SYSCTL_VDD, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl518_vin}, ++ {GL518_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl518_fan}, ++ {GL518_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl518_fan}, ++ {GL518_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl518_temp}, ++ {GL518_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl518_fan_div}, ++ {GL518_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl518_alarms}, ++ {GL518_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl518_beep}, ++ {GL518_SYSCTL_FAN1OFF, "fan1off", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl518_fan1off}, ++ {GL518_SYSCTL_ITERATE, "iterate", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl518_iterate}, ++ {0} ++}; ++ ++/* I choose here for semi-static GL518SM allocation. Complete dynamic ++ allocation could also be used; the code needed for this would probably ++ take more memory than the datastructure takes now. */ ++#define MAX_GL518_NR 4 ++static struct i2c_client *gl518_list[MAX_GL518_NR]; ++ ++static int gl518_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, gl518_detect); ++} ++ ++static int gl518_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct gl518_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("gl518sm.o: gl518_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | ++ I2C_FUNC_SMBUS_WORD_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access gl518_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct gl518_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &gl518_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ ++ if (kind < 0) { ++ if ( ++ (gl518_read_value(new_client, GL518_REG_CHIP_ID) != ++ 0x80) ++ || (gl518_read_value(new_client, GL518_REG_CONF) & ++ 0x80)) goto ERROR1; ++ } ++ ++ /* Determine the chip type. */ ++ if (kind <= 0) { ++ i = gl518_read_value(new_client, GL518_REG_REVISION); ++ if (i == 0x00) ++ kind = gl518sm_r00; ++ else if (i == 0x80) ++ kind = gl518sm_r80; ++ else { ++ if (kind == 0) ++ printk ++ ("gl518sm.o: Ignoring 'force' parameter for unknown chip at " ++ "adapter %d, address 0x%02x\n", ++ i2c_adapter_id(adapter), address); ++ goto ERROR1; ++ } ++ } ++ ++ type_name = "gl518sm"; ++ if (kind == gl518sm_r00) { ++ client_name = "GL518SM Revision 0x00 chip"; ++ } else if (kind == gl518sm_r80) { ++ client_name = "GL518SM Revision 0x80 chip"; ++ } else { ++#ifdef DEBUG ++ printk("gl518sm.o: Internal error: unknown kind (%d)?!?", ++ kind); ++#endif ++ goto ERROR1; ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ data->type = kind; ++ ++ for (i = 0; i < MAX_GL518_NR; i++) ++ if (!gl518_list[i]) ++ break; ++ if (i == MAX_GL518_NR) { ++ printk ++ ("gl518sm.o: No empty slots left, recompile and heighten " ++ "MAX_GL518_NR!\n"); ++ err = -ENOMEM; ++ goto ERROR2; ++ } ++ gl518_list[i] = new_client; ++ new_client->id = i; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry((struct i2c_client *) new_client, ++ type_name, ++ gl518_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the GL518SM chip */ ++ if (kind == gl518sm_r00) ++ data->iterate = 0; ++ else ++ data->iterate = 3; ++ data->iterate_lock = 0; ++ data->quit_thread = 0; ++ data->thread = NULL; ++ data->alarm_mask = 0xff; ++ data->voltage[0]=data->voltage[1]=data->voltage[2]=0; ++ gl518_init_client((struct i2c_client *) new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ for (i = 0; i < MAX_GL518_NR; i++) ++ if (new_client == gl518_list[i]) ++ gl518_list[i] = NULL; ++ ERROR2: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++ ++/* Called when we have found a new GL518SM. It should set limits, etc. */ ++static void gl518_init_client(struct i2c_client *client) ++{ ++ /* Power-on defaults (bit 7=1) */ ++ gl518_write_value(client, GL518_REG_CONF, 0x80); ++ ++ /* No noisy output (bit 2=1), Comparator mode (bit 3=0), two fans (bit4=0), ++ standby mode (bit6=0) */ ++ gl518_write_value(client, GL518_REG_CONF, 0x04); ++ ++ /* Never interrupts */ ++ gl518_write_value(client, GL518_REG_MASK, 0x00); ++ ++ /* Clear status register (bit 5=1), start (bit6=1) */ ++ gl518_write_value(client, GL518_REG_CONF, 0x24); ++ gl518_write_value(client, GL518_REG_CONF, 0x44); ++} ++ ++static int gl518_detach_client(struct i2c_client *client) ++{ ++ int err, i; ++ struct gl518_data *data = client->data; ++ ++ i2c_deregister_entry(((struct gl518_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("gl518sm.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ for (i = 0; i < MAX_GL518_NR; i++) ++ if (client == gl518_list[i]) ++ break; ++ if ((i == MAX_GL518_NR)) { ++ printk("gl518sm.o: Client to detach not found.\n"); ++ return -ENOENT; ++ } ++ gl518_list[i] = NULL; ++ ++ if (data->thread) { ++ data->quit_thread = 1; ++ wake_up_interruptible(&data->wq); ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++ ++/* Registers 0x07 to 0x0c are word-sized, others are byte-sized ++ GL518 uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int gl518_read_value(struct i2c_client *client, u8 reg) ++{ ++ if ((reg >= 0x07) && (reg <= 0x0c)) ++ return swab16(i2c_smbus_read_word_data(client, reg)); ++ else ++ return i2c_smbus_read_byte_data(client, reg); ++} ++ ++/* Registers 0x07 to 0x0c are word-sized, others are byte-sized ++ GL518 uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value) ++{ ++ if ((reg >= 0x07) && (reg <= 0x0c)) ++ return i2c_smbus_write_word_data(client, reg, swab16(value)); ++ else ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++static void gl518_update_client(struct i2c_client *client) ++{ ++ struct gl518_data *data = client->data; ++ int val; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("Starting gl518 update\n"); ++#endif ++ ++ data->alarms = gl518_read_value(client, GL518_REG_INT); ++ data->beeps = gl518_read_value(client, GL518_REG_ALARM); ++ ++ val = gl518_read_value(client, GL518_REG_VDD_LIMIT); ++ data->voltage_min[0] = val & 0xff; ++ data->voltage_max[0] = (val >> 8) & 0xff; ++ val = gl518_read_value(client, GL518_REG_VIN1_LIMIT); ++ data->voltage_min[1] = val & 0xff; ++ data->voltage_max[1] = (val >> 8) & 0xff; ++ val = gl518_read_value(client, GL518_REG_VIN2_LIMIT); ++ data->voltage_min[2] = val & 0xff; ++ data->voltage_max[2] = (val >> 8) & 0xff; ++ val = gl518_read_value(client, GL518_REG_VIN3_LIMIT); ++ data->voltage_min[3] = val & 0xff; ++ data->voltage_max[3] = (val >> 8) & 0xff; ++ ++ val = gl518_read_value(client, GL518_REG_FAN_COUNT); ++ data->fan[0] = (val >> 8) & 0xff; ++ data->fan[1] = val & 0xff; ++ ++ val = gl518_read_value(client, GL518_REG_FAN_LIMIT); ++ data->fan_min[0] = (val >> 8) & 0xff; ++ data->fan_min[1] = val & 0xff; ++ ++ data->temp = gl518_read_value(client, GL518_REG_TEMP); ++ data->temp_over = ++ gl518_read_value(client, GL518_REG_TEMP_OVER); ++ data->temp_hyst = ++ gl518_read_value(client, GL518_REG_TEMP_HYST); ++ ++ val = gl518_read_value(client, GL518_REG_MISC); ++ data->fan_div[0] = (val >> 6) & 0x03; ++ data->fan_div[1] = (val >> 4) & 0x03; ++ ++ data->alarms &= data->alarm_mask; ++ ++ val = gl518_read_value(client, GL518_REG_CONF); ++ data->beep_enable = (val >> 2) & 1; ++ ++#ifndef DEBUG_VIN ++ if (data->type != gl518sm_r00) { ++ data->voltage[0] = ++ gl518_read_value(client, GL518_REG_VDD); ++ data->voltage[1] = ++ gl518_read_value(client, GL518_REG_VIN1); ++ data->voltage[2] = ++ gl518_read_value(client, GL518_REG_VIN2); ++ data->voltage[3] = ++ gl518_read_value(client, GL518_REG_VIN3); ++ } else ++ gl518_update_client_rev00(client); ++#else ++ gl518_update_client_rev00(client); ++#endif ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++/* Here we decide how to run the iteration code. ++ When called, we trigger the iteration and report the last ++ measured voltage. No delay for user apps */ ++static void gl518_update_client_rev00(struct i2c_client *client) ++{ ++ struct gl518_data *data = client->data; ++ int i; ++ ++ if (data->iterate == 1) { /* 10 sec delay */ ++ /* as that update is slow, we consider the data valid for 30 seconds */ ++ if ( ++ ((jiffies - data->last_updated_v00 > 30 * HZ) ++ || (data->alarms & 7) ++ || (!data->valid)) && (!data->iterate_lock)) { ++ data->iterate_lock = 1; ++ gl518_update_iterate(client); ++ data->iterate_lock = 0; ++ } ++ for (i = 0; i < 4; i++) ++ data->voltage[i] = data->iter_voltage[i]; ++ } else if (data->iterate == 2) { /* show results of last iteration */ ++ for (i = 0; i < 4; i++) ++ data->voltage[i] = data->iter_voltage[i]; ++ wake_up_interruptible(&data->wq); ++ } else { /* no iteration */ ++ data->voltage[3] = ++ gl518_read_value(client, GL518_REG_VIN3); ++ } ++} ++ ++static int gl518_update_thread(void *c) ++{ ++ struct i2c_client *client = c; ++ struct gl518_data *data = client->data; ++ ++#ifdef __SMP__ ++ lock_kernel(); ++#endif ++ exit_mm(current); ++ current->session = 1; ++ current->pgrp = 1; ++ sigfillset(¤t->blocked); ++ current->fs->umask = 0; ++ strcpy(current->comm, "gl518sm"); ++ ++ init_waitqueue_head(&(data->wq)); ++ data->thread = current; ++ ++#ifdef __SMP__ ++ unlock_kernel(); ++#endif ++ ++ for (;;) { ++ if (!data->iterate_lock) { ++ data->iterate_lock = 1; ++ gl518_update_iterate(client); ++ data->iterate_lock = 0; ++ } ++ ++ if ((data->quit_thread) || signal_pending(current)) ++ break; ++ interruptible_sleep_on(&data->wq); ++ } ++ ++ data->thread = NULL; ++ data->quit_thread = 0; ++ return 0; ++} ++ ++/* This updates vdd, vin1, vin2 values by doing slow and multiple ++ comparisons for the GL518SM rev 00 that lacks support for direct ++ reading of these values. Values are kept in iter_voltage */ ++ ++static void gl518_update_iterate(struct i2c_client *client) ++{ ++ struct gl518_data *data = client->data; ++ int i, j, loop_more = 1, min[3], max[3], delta[3]; ++ int alarm, beeps, irqs; ++ ++#define VIN_REG(c) c==0?GL518_REG_VDD_LIMIT:\ ++ c==1?GL518_REG_VIN1_LIMIT:\ ++ GL518_REG_VIN2_LIMIT ++ ++ /* disable beeps & irqs for vin0-2 */ ++ beeps = gl518_read_value(client, GL518_REG_ALARM); ++ irqs = gl518_read_value(client, GL518_REG_MASK); ++ gl518_write_value(client, GL518_REG_ALARM, beeps & ~0x7); ++ gl518_write_value(client, GL518_REG_MASK, irqs & ~0x7); ++ ++ alarm = data->alarms; ++ ++ for (i = 0; i < 3; i++) { ++ if (alarm & (1 << i)) { ++ min[i] = 0; ++ max[i] = 127; ++ } else { ++ min[i] = data->voltage_min[i]; ++ max[i] = ++ (data->voltage_max[i] + ++ data->voltage_min[i]) / 2; ++ } ++ delta[i] = (max[i] - min[i]) / 2; ++ } ++ ++ for (j = 0; (j < 10 && loop_more); j++) { ++ ++ for (i = 0; i < 3; i++) ++ gl518_write_value(client, VIN_REG(i), ++ max[i] << 8 | min[i]); ++ ++ if ((data->thread) && ++ ((data->quit_thread) || signal_pending(current))) ++ goto finish; ++ ++ /* we wait now 1.5 seconds before comparing */ ++ current->state = TASK_INTERRUPTIBLE; ++ schedule_timeout(HZ + HZ / 2); ++ ++ alarm = gl518_read_value(client, GL518_REG_INT); ++ ++#ifdef DEBUG_VIN ++ printk("gl518sm: iteration %2d: %4d%c %4d%c %4d%c\n", j, ++ max[0], (alarm & 1) ? '!' : ' ', ++ max[1], (alarm & 2) ? '!' : ' ', ++ max[2], (alarm & 4) ? '!' : ' '); ++#endif ++ ++ for (loop_more = 0, i = 0; i < 3; i++) { ++ if (alarm & (1 << i)) ++ max[i] += delta[i]; ++ else ++ max[i] -= delta[i]; ++ ++ if (delta[i]) ++ loop_more++; ++ delta[i] >>= 1; ++ } ++ ++ } ++ ++ for (i = 0; i < 3; i++) ++ if (alarm & (1 << i)) ++ max[i]++; ++ ++#ifdef DEBUG_VIN ++ printk("gl518sm: final :%5d %5d %5d\n", max[0], max[1], ++ max[2]); ++ printk("gl518sm: meter :%5d %5d %5d\n", data->voltage[0], ++ data->voltage[1], data->voltage[2]); ++#endif ++ ++ /* update values, including vin3 */ ++ for (i = 0; i < 3; i++) { ++ data->iter_voltage[i] = max[i]; ++ } ++ data->iter_voltage[3] = gl518_read_value(client, GL518_REG_VIN3); ++ data->last_updated_v00 = jiffies; ++ ++ finish: ++ ++ /* reset values */ ++ for (i = 0; i < 3; i++) { ++ gl518_write_value(client, VIN_REG(i), ++ data->voltage_max[i] << 8 | data-> ++ voltage_min[i]); ++ } ++ ++ gl518_write_value(client, GL518_REG_ALARM, beeps); ++ gl518_write_value(client, GL518_REG_MASK, irqs); ++ ++#undef VIN_REG ++} ++ ++void gl518_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl518_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ gl518_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_over); ++ results[1] = TEMP_FROM_REG(data->temp_hyst); ++ results[2] = TEMP_FROM_REG(data->temp); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_over = TEMP_TO_REG(results[0]); ++ gl518_write_value(client, GL518_REG_TEMP_OVER, ++ data->temp_over); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst = TEMP_TO_REG(results[1]); ++ gl518_write_value(client, GL518_REG_TEMP_HYST, ++ data->temp_hyst); ++ } ++ } ++} ++ ++void gl518_vin(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl518_data *data = client->data; ++ int nr = ctl_name - GL518_SYSCTL_VDD; ++ int regnr, old = 0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ gl518_update_client(client); ++ results[0] = nr ? IN_FROM_REG(data->voltage_min[nr]) : ++ VDD_FROM_REG(data->voltage_min[nr]); ++ results[1] = nr ? IN_FROM_REG(data->voltage_max[nr]) : ++ VDD_FROM_REG(data->voltage_max[nr]); ++ results[2] = nr ? IN_FROM_REG(data->voltage[nr]) : ++ VDD_FROM_REG(data->voltage[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ regnr = ++ nr == 0 ? GL518_REG_VDD_LIMIT : nr == ++ 1 ? GL518_REG_VIN1_LIMIT : nr == ++ 2 ? GL518_REG_VIN2_LIMIT : GL518_REG_VIN3_LIMIT; ++ if (*nrels_mag == 1) ++ old = gl518_read_value(client, regnr) & 0xff00; ++ if (*nrels_mag >= 2) { ++ data->voltage_max[nr] = ++ nr ? IN_TO_REG(results[1]) : ++ VDD_TO_REG(results[1]); ++ old = data->voltage_max[nr] << 8; ++ } ++ if (*nrels_mag >= 1) { ++ data->voltage_min[nr] = ++ nr ? IN_TO_REG(results[0]) : ++ VDD_TO_REG(results[0]); ++ old |= data->voltage_min[nr]; ++ gl518_write_value(client, regnr, old); ++ } ++ } ++} ++ ++ ++void gl518_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl518_data *data = client->data; ++ int nr = ctl_name - GL518_SYSCTL_FAN1; ++ int old; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ gl518_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr], ++ DIV_FROM_REG(data->fan_div[nr])); ++ results[1] = ++ FAN_FROM_REG(data->fan[nr], ++ DIV_FROM_REG(data->fan_div[nr])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr] = FAN_TO_REG(results[0], ++ DIV_FROM_REG(data-> ++ fan_div ++ [nr])); ++ old = ++ gl518_read_value(client, GL518_REG_FAN_LIMIT); ++ ++ if (nr == 0) { ++ old = ++ (old & 0x00ff) | (data-> ++ fan_min[0] << 8); ++ if (results[0] == 0) ++ data->alarm_mask &= ~0x20; ++ else ++ data->alarm_mask |= 0x20; ++ } else { ++ old = (old & 0xff00) | data->fan_min[1]; ++ if (results[0] == 0) ++ data->alarm_mask &= ~0x40; ++ else ++ data->alarm_mask |= 0x40; ++ } ++ gl518_write_value(client, GL518_REG_FAN_LIMIT, ++ old); ++ } ++ } ++} ++ ++ ++void gl518_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl518_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ gl518_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++void gl518_beep(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl518_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ gl518_update_client(client); ++ results[0] = BEEP_ENABLE_FROM_REG(data->beep_enable); ++ results[1] = BEEPS_FROM_REG(data->beeps); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->beep_enable = BEEP_ENABLE_TO_REG(results[0]); ++ gl518_write_value(client, GL518_REG_CONF, ++ (gl518_read_value(client, ++ GL518_REG_CONF) ++ & 0xfb) | (data-> ++ beep_enable << 2)); ++ } ++ if (*nrels_mag >= 2) { ++ data->beeps = ++ BEEPS_TO_REG(results[1]) & data->alarm_mask; ++ gl518_write_value(client, GL518_REG_ALARM, ++ data->beeps); ++ } ++ } ++} ++ ++ ++void gl518_fan_div(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl518_data *data = client->data; ++ int old; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ gl518_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = gl518_read_value(client, GL518_REG_MISC); ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ old = (old & 0xcf) | (data->fan_div[1] << 4); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ old = (old & 0x3f) | (data->fan_div[0] << 6); ++ } ++ gl518_write_value(client, GL518_REG_MISC, old); ++ } ++} ++ ++void gl518_fan1off(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ int old; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = ++ ((gl518_read_value(client, GL518_REG_MISC) & 0x08) != ++ 0); ++ results[1] = ++ ((gl518_read_value(client, GL518_REG_CONF) & 0x10) != ++ 0); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ old = ++ gl518_read_value(client, ++ GL518_REG_MISC) & 0xf7; ++ if (results[0]) ++ old |= 0x08; ++ gl518_write_value(client, GL518_REG_MISC, old); ++ } ++ if (*nrels_mag >= 2) { ++ old = ++ gl518_read_value(client, ++ GL518_REG_CONF) & 0xef; ++ if (results[1]) ++ old |= 0x10; ++ gl518_write_value(client, GL518_REG_CONF, old); ++ } ++ } ++} ++ ++void gl518_iterate(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl518_data *data = client->data; ++ int i; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->iterate; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE && ++ data->type == gl518sm_r00 ) { ++ if ((*nrels_mag >= 1) && (data->iterate != results[0])) { ++ data->iterate = results[0]; ++ for (i = 0; i < 4; i++) { ++ data->voltage[i] = 0; ++ data->iter_voltage[i] = 0; ++ } ++ data->valid = 0; ++ ++ if ((data->iterate != 2) && (data->thread)) { ++ data->quit_thread = 1; ++ wake_up_interruptible(&data->wq); ++ } else if ((data->iterate == 2) && (!data->thread)) { ++ init_waitqueue_head(&(data->wq)); ++ kernel_thread(gl518_update_thread, ++ (void *) client, 0); ++ } ++ } ++ } ++} ++ ++static int __init sm_gl518sm_init(void) ++{ ++ printk("gl518sm.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&gl518_driver); ++} ++ ++static void __exit sm_gl518sm_exit(void) ++{ ++ i2c_del_driver(&gl518_driver); ++} ++ ++ ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard and Kyösti Mälkki "); ++MODULE_DESCRIPTION("GL518SM driver"); ++ ++module_init(sm_gl518sm_init); ++module_exit(sm_gl518sm_exit); +--- linux-old/drivers/sensors/gl520sm.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/gl520sm.c Mon Dec 13 20:18:47 2004 +@@ -0,0 +1,809 @@ ++/* ++ gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard , ++ Kyösti Mälkki ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { 0x2c, 0x2d, SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(gl520sm); ++ ++/* Many GL520 constants specified below ++One of the inputs can be configured as either temp or voltage. ++That's why _TEMP2 and _VIN4 access the same register ++*/ ++ ++/* The GL520 registers */ ++#define GL520_REG_CHIP_ID 0x00 ++#define GL520_REG_REVISION 0x01 ++#define GL520_REG_VID 0x02 ++#define GL520_REG_CONF 0x03 ++#define GL520_REG_TEMP1 0x04 ++#define GL520_REG_TEMP1_OVER 0x05 ++#define GL520_REG_TEMP1_HYST 0x06 ++#define GL520_REG_FAN_COUNT 0x07 ++#define GL520_REG_FAN_LIMIT 0x08 ++#define GL520_REG_VIN1_LIMIT 0x09 ++#define GL520_REG_VIN2_LIMIT 0x0a ++#define GL520_REG_VIN3_LIMIT 0x0b ++#define GL520_REG_VDD_LIMIT 0x0c ++#define GL520_REG_VIN3 0x0d ++#define GL520_REG_VIN4 0x0e ++#define GL520_REG_TEMP2 0x0e ++#define GL520_REG_MISC 0x0f ++#define GL520_REG_ALARM 0x10 ++#define GL520_REG_MASK 0x11 ++#define GL520_REG_INT 0x12 ++#define GL520_REG_VIN2 0x13 ++#define GL520_REG_VIN1 0x14 ++#define GL520_REG_VDD 0x15 ++#define GL520_REG_TEMP2_OVER 0x17 ++#define GL520_REG_VIN4_MAX 0x17 ++#define GL520_REG_TEMP2_HYST 0x18 ++#define GL520_REG_VIN4_MIN 0x18 ++ ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++ ++#define TEMP_TO_REG(val) (SENSORS_LIMIT(((((val)<0?(val)-5:(val)+5) / 10)+130),\ ++ 0,255)) ++#define TEMP_FROM_REG(val) (((val) - 130) * 10) ++ ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 255; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((960000 + rpm * div / 2) / (rpm * div), 1, ++ 254); ++} ++ ++#define FAN_FROM_REG(val,div) \ ++ ( (val)==0 ? 0 : (val)==255 ? 0 : (960000/((val)*(div))) ) ++ ++#define IN_TO_REG(val) (SENSORS_LIMIT((((val)*10+8)/19),0,255)) ++#define IN_FROM_REG(val) (((val)*19)/10) ++ ++#define VDD_TO_REG(val) (SENSORS_LIMIT((((val)*10+11)/23),0,255)) ++#define VDD_FROM_REG(val) (((val)*23)/10) ++ ++#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) ++#define DIV_FROM_REG(val) (1 << (val)) ++ ++#define ALARMS_FROM_REG(val) val ++ ++#define BEEP_ENABLE_TO_REG(val) ((val)?0:1) ++#define BEEP_ENABLE_FROM_REG(val) ((val)?0:1) ++ ++#define BEEPS_TO_REG(val) (val) ++#define BEEPS_FROM_REG(val) (val) ++ ++#define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\ ++ 205-(val)*5) ++ ++/* Each client has this additional data */ ++struct gl520_data { ++ struct i2c_client client; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 voltage[5]; /* Register values; [0] = VDD */ ++ u8 voltage_min[5]; /* Register values; [0] = VDD */ ++ u8 voltage_max[5]; /* Register values; [0] = VDD */ ++ u8 fan[2]; ++ u8 fan_min[2]; ++ u8 temp[2]; /* Register values */ ++ u8 temp_over[2]; /* Register values */ ++ u8 temp_hyst[2]; /* Register values */ ++ u8 alarms, beeps, vid; /* Register value */ ++ u8 alarm_mask; /* Register value */ ++ u8 fan_div[2]; /* Register encoding, shifted right */ ++ u8 beep_enable; /* Boolean */ ++ u8 two_temps; /* Boolean */ ++}; ++ ++static int gl520_attach_adapter(struct i2c_adapter *adapter); ++static int gl520_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static void gl520_init_client(struct i2c_client *client); ++static int gl520_detach_client(struct i2c_client *client); ++ ++static int gl520_read_value(struct i2c_client *client, u8 reg); ++static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value); ++static void gl520_update_client(struct i2c_client *client); ++ ++static void gl520_vin(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl520_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl520_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl520_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl520_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl520_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl520_beep(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl520_fan1off(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void gl520_config(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver gl520_driver = { ++ .owner = THIS_MODULE, ++ .name = "GL520SM sensor chip driver", ++ .id = I2C_DRIVERID_GL520, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = gl520_attach_adapter, ++ .detach_client = gl520_detach_client, ++}; ++/* -- SENSORS SYSCTL START -- */ ++ ++#define GL520_SYSCTL_VDD 1000 /* Volts * 100 */ ++#define GL520_SYSCTL_VIN1 1001 ++#define GL520_SYSCTL_VIN2 1002 ++#define GL520_SYSCTL_VIN3 1003 ++#define GL520_SYSCTL_VIN4 1004 ++#define GL520_SYSCTL_FAN1 1101 /* RPM */ ++#define GL520_SYSCTL_FAN2 1102 ++#define GL520_SYSCTL_TEMP1 1200 /* Degrees Celcius * 10 */ ++#define GL520_SYSCTL_TEMP2 1201 /* Degrees Celcius * 10 */ ++#define GL520_SYSCTL_VID 1300 ++#define GL520_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define GL520_SYSCTL_ALARMS 2001 /* bitvector */ ++#define GL520_SYSCTL_BEEP 2002 /* bitvector */ ++#define GL520_SYSCTL_FAN1OFF 2003 ++#define GL520_SYSCTL_CONFIG 2004 ++ ++#define GL520_ALARM_VDD 0x01 ++#define GL520_ALARM_VIN1 0x02 ++#define GL520_ALARM_VIN2 0x04 ++#define GL520_ALARM_VIN3 0x08 ++#define GL520_ALARM_TEMP1 0x10 ++#define GL520_ALARM_FAN1 0x20 ++#define GL520_ALARM_FAN2 0x40 ++#define GL520_ALARM_TEMP2 0x80 ++#define GL520_ALARM_VIN4 0x80 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected GL520. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table gl520_dir_table_template[] = { ++ {GL520_SYSCTL_VIN1, "vin1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_vin}, ++ {GL520_SYSCTL_VIN2, "vin2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_vin}, ++ {GL520_SYSCTL_VIN3, "vin3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_vin}, ++ {GL520_SYSCTL_VIN4, "vin4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_vin}, ++ {GL520_SYSCTL_VDD, "vdd", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_vin}, ++ {GL520_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_vid}, ++ {GL520_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_fan}, ++ {GL520_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_fan}, ++ {GL520_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_temp}, ++ {GL520_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_temp}, ++ {GL520_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_fan_div}, ++ {GL520_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_alarms}, ++ {GL520_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_beep}, ++ {GL520_SYSCTL_FAN1OFF, "fan1off", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_fan1off}, ++ {GL520_SYSCTL_CONFIG, "config", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &gl520_config}, ++ {0} ++}; ++ ++static int gl520_id = 0; ++ ++static int gl520_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, gl520_detect); ++} ++ ++static int gl520_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct gl520_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ char client_name[32]; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("gl520sm.o: gl520_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | ++ I2C_FUNC_SMBUS_WORD_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access gl520_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct gl520_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &gl520_driver; ++ new_client->flags = 0; ++ ++ /* Determine the chip type. */ ++ ++ if (gl520_read_value(new_client, GL520_REG_CHIP_ID) != 0x20) { ++ printk ++ ("gl520sm.o: Ignoring 'force' parameter for unknown chip at " ++ "adapter %d, address 0x%02x\n", ++ i2c_adapter_id(adapter), address); ++ goto ERROR1; ++ } else { ++ kind = gl520sm; ++ } ++ ++ i = gl520_read_value(new_client, GL520_REG_REVISION); ++ if (kind == gl520sm) { ++ type_name = "gl520sm"; ++ sprintf(client_name, "GL520SM Revision %02x chip", i); ++ } else { ++#ifdef DEBUG ++ printk("gl520sm.o: Internal error: unknown kind (%d)?!?", ++ kind); ++#endif ++ goto ERROR1; ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ data->type = kind; ++ ++ new_client->id = gl520_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, ++ type_name, ++ gl520_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the GL520SM chip */ ++ data->alarm_mask = 0xff; ++ gl520_init_client(new_client); ++ if (data->two_temps) ++ data->voltage_max[4] = data->voltage_min[4] = ++ data->voltage[4] = 0; ++ else ++ data->temp_hyst[1] = data->temp_over[1] = ++ data->temp[1] = 0; ++ ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++ ++/* Called when we have found a new GL520SM. */ ++static void gl520_init_client(struct i2c_client *client) ++{ ++ struct gl520_data *data = (struct gl520_data *)(client->data); ++ u8 oldconf, conf; ++ ++ conf = oldconf = gl520_read_value(client, GL520_REG_CONF); ++ data->two_temps = !(conf & 0x10); ++ ++ /* If IRQ# is disabled, we can safely force comparator mode */ ++ if (!(conf & 0x20)) ++ conf &= 0xf7; ++ ++ /* Enable monitoring if needed */ ++ conf |= 0x40; ++ ++ if (conf != oldconf) ++ gl520_write_value(client, GL520_REG_CONF, conf); ++} ++ ++static int gl520_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct gl520_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("gl520sm.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++ ++/* Registers 0x07 to 0x0c are word-sized, others are byte-sized ++ GL520 uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int gl520_read_value(struct i2c_client *client, u8 reg) ++{ ++ if ((reg >= 0x07) && (reg <= 0x0c)) ++ return swab16(i2c_smbus_read_word_data(client, reg)); ++ else ++ return i2c_smbus_read_byte_data(client, reg); ++} ++ ++/* Registers 0x07 to 0x0c are word-sized, others are byte-sized ++ GL520 uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value) ++{ ++ if ((reg >= 0x07) && (reg <= 0x0c)) ++ return i2c_smbus_write_word_data(client, reg, swab16(value)); ++ else ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++static void gl520_update_client(struct i2c_client *client) ++{ ++ struct gl520_data *data = client->data; ++ int val; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("Starting gl520 update\n"); ++#endif ++ ++ data->alarms = gl520_read_value(client, GL520_REG_INT); ++ data->beeps = gl520_read_value(client, GL520_REG_ALARM); ++ data->vid = gl520_read_value(client, GL520_REG_VID) & 0x1f; ++ ++ val = gl520_read_value(client, GL520_REG_VDD_LIMIT); ++ data->voltage_min[0] = val & 0xff; ++ data->voltage_max[0] = (val >> 8) & 0xff; ++ val = gl520_read_value(client, GL520_REG_VIN1_LIMIT); ++ data->voltage_min[1] = val & 0xff; ++ data->voltage_max[1] = (val >> 8) & 0xff; ++ val = gl520_read_value(client, GL520_REG_VIN2_LIMIT); ++ data->voltage_min[2] = val & 0xff; ++ data->voltage_max[2] = (val >> 8) & 0xff; ++ val = gl520_read_value(client, GL520_REG_VIN3_LIMIT); ++ data->voltage_min[3] = val & 0xff; ++ data->voltage_max[3] = (val >> 8) & 0xff; ++ ++ val = gl520_read_value(client, GL520_REG_FAN_COUNT); ++ data->fan[0] = (val >> 8) & 0xff; ++ data->fan[1] = val & 0xff; ++ ++ val = gl520_read_value(client, GL520_REG_FAN_LIMIT); ++ data->fan_min[0] = (val >> 8) & 0xff; ++ data->fan_min[1] = val & 0xff; ++ ++ data->temp[0] = gl520_read_value(client, GL520_REG_TEMP1); ++ data->temp_over[0] = ++ gl520_read_value(client, GL520_REG_TEMP1_OVER); ++ data->temp_hyst[0] = ++ gl520_read_value(client, GL520_REG_TEMP1_HYST); ++ ++ val = gl520_read_value(client, GL520_REG_MISC); ++ data->fan_div[0] = (val >> 6) & 0x03; ++ data->fan_div[1] = (val >> 4) & 0x03; ++ ++ data->alarms &= data->alarm_mask; ++ ++ val = gl520_read_value(client, GL520_REG_CONF); ++ data->beep_enable = (val >> 2) & 1; ++ ++ data->voltage[0] = gl520_read_value(client, GL520_REG_VDD); ++ data->voltage[1] = ++ gl520_read_value(client, GL520_REG_VIN1); ++ data->voltage[2] = ++ gl520_read_value(client, GL520_REG_VIN2); ++ data->voltage[3] = ++ gl520_read_value(client, GL520_REG_VIN3); ++ ++ /* Temp1 and Vin4 are the same input */ ++ if (data->two_temps) { ++ data->temp[1] = ++ gl520_read_value(client, GL520_REG_TEMP2); ++ data->temp_over[1] = ++ gl520_read_value(client, GL520_REG_TEMP2_OVER); ++ data->temp_hyst[1] = ++ gl520_read_value(client, GL520_REG_TEMP2_HYST); ++ } else { ++ data->voltage[4] = ++ gl520_read_value(client, GL520_REG_VIN4); ++ data->voltage_min[4] = ++ gl520_read_value(client, GL520_REG_VIN4_MIN); ++ data->voltage_max[4] = ++ gl520_read_value(client, GL520_REG_VIN4_MAX); ++ } ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++void gl520_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl520_data *data = client->data; ++ int nr = ctl_name - GL520_SYSCTL_TEMP1; ++ int regnr; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ gl520_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_over[nr]); ++ results[1] = TEMP_FROM_REG(data->temp_hyst[nr]); ++ results[2] = TEMP_FROM_REG(data->temp[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if ((nr == 1) && (!data->two_temps)) ++ return; ++ regnr = ++ nr == 0 ? GL520_REG_TEMP1_OVER : GL520_REG_TEMP2_OVER; ++ if (*nrels_mag >= 1) { ++ data->temp_over[nr] = TEMP_TO_REG(results[0]); ++ gl520_write_value(client, regnr, ++ data->temp_over[nr]); ++ } ++ regnr = ++ nr == 0 ? GL520_REG_TEMP1_HYST : GL520_REG_TEMP2_HYST; ++ if (*nrels_mag >= 2) { ++ data->temp_hyst[nr] = TEMP_TO_REG(results[1]); ++ gl520_write_value(client, regnr, ++ data->temp_hyst[nr]); ++ } ++ } ++} ++ ++void gl520_vin(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl520_data *data = client->data; ++ int nr = ctl_name - GL520_SYSCTL_VDD; ++ int regnr, old = 0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ gl520_update_client(client); ++ results[0] = nr ? IN_FROM_REG(data->voltage_min[nr]) : ++ VDD_FROM_REG(data->voltage_min[nr]); ++ results[1] = nr ? IN_FROM_REG(data->voltage_max[nr]) : ++ VDD_FROM_REG(data->voltage_max[nr]); ++ results[2] = nr ? IN_FROM_REG(data->voltage[nr]) : ++ VDD_FROM_REG(data->voltage[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (nr != 4) { ++ regnr = ++ nr == 0 ? GL520_REG_VDD_LIMIT : nr == ++ 1 ? GL520_REG_VIN1_LIMIT : nr == ++ 2 ? GL520_REG_VIN2_LIMIT : ++ GL520_REG_VIN3_LIMIT; ++ if (*nrels_mag == 1) ++ old = ++ gl520_read_value(client, ++ regnr) & 0xff00; ++ if (*nrels_mag >= 2) { ++ data->voltage_max[nr] = ++ nr ? IN_TO_REG(results[1]) : ++ VDD_TO_REG(results[1]); ++ old = data->voltage_max[nr] << 8; ++ } ++ if (*nrels_mag >= 1) { ++ data->voltage_min[nr] = ++ nr ? IN_TO_REG(results[0]) : ++ VDD_TO_REG(results[0]); ++ old |= data->voltage_min[nr]; ++ gl520_write_value(client, regnr, old); ++ } ++ } else if (!data->two_temps) { ++ if (*nrels_mag == 1) ++ gl520_write_value(client, ++ GL520_REG_VIN4_MIN, ++ IN_TO_REG(results[0])); ++ if (*nrels_mag >= 2) ++ gl520_write_value(client, ++ GL520_REG_VIN4_MAX, ++ IN_TO_REG(results[1])); ++ } ++ } ++} ++ ++ ++void gl520_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl520_data *data = client->data; ++ int nr = ctl_name - GL520_SYSCTL_FAN1; ++ int old; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ gl520_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr], ++ DIV_FROM_REG(data->fan_div[nr])); ++ results[1] = ++ FAN_FROM_REG(data->fan[nr], ++ DIV_FROM_REG(data->fan_div[nr])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr] = FAN_TO_REG(results[0], ++ DIV_FROM_REG(data-> ++ fan_div ++ [nr])); ++ old = ++ gl520_read_value(client, GL520_REG_FAN_LIMIT); ++ ++ if (nr == 0) { ++ old = ++ (old & 0x00ff) | (data-> ++ fan_min[nr] << 8); ++ if (results[0] == 0) ++ data->alarm_mask &= ~0x20; ++ else ++ data->alarm_mask |= 0x20; ++ } else { ++ old = (old & 0xff00) | data->fan_min[nr]; ++ if (results[0] == 0) ++ data->alarm_mask &= ~0x40; ++ else ++ data->alarm_mask |= 0x40; ++ } ++ gl520_write_value(client, GL520_REG_FAN_LIMIT, ++ old); ++ } ++ } ++} ++ ++ ++void gl520_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl520_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ gl520_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++void gl520_beep(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl520_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ gl520_update_client(client); ++ results[0] = BEEP_ENABLE_FROM_REG(data->beep_enable); ++ results[1] = BEEPS_FROM_REG(data->beeps); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->beep_enable = BEEP_ENABLE_TO_REG(results[0]); ++ gl520_write_value(client, GL520_REG_CONF, ++ (gl520_read_value(client, ++ GL520_REG_CONF) ++ & 0xfb) | (data-> ++ beep_enable << 2)); ++ } ++ if (*nrels_mag >= 2) { ++ data->beeps = ++ BEEPS_TO_REG(results[1]) & data->alarm_mask; ++ gl520_write_value(client, GL520_REG_ALARM, ++ data->beeps); ++ } ++ } ++} ++ ++ ++void gl520_fan_div(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl520_data *data = client->data; ++ int old; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ gl520_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = gl520_read_value(client, GL520_REG_MISC); ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ old = (old & 0xcf) | (data->fan_div[1] << 4); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ old = (old & 0x3f) | (data->fan_div[0] << 6); ++ } ++ gl520_write_value(client, GL520_REG_MISC, old); ++ } ++} ++ ++void gl520_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl520_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ gl520_update_client(client); ++ results[0] = VID_FROM_REG(data->vid); ++ *nrels_mag = 1; ++ } ++} ++ ++void gl520_fan1off(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ int old; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = ++ ((gl520_read_value(client, GL520_REG_MISC) & 0x04) != ++ 0); ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ old = ++ gl520_read_value(client, ++ GL520_REG_MISC) & 0xfb; ++ if (results[0]) ++ old |= 0x04; ++ gl520_write_value(client, GL520_REG_MISC, old); ++ } ++ } ++} ++ ++void gl520_config(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct gl520_data *data = client->data; ++ int old; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = ++ ((gl520_read_value(client, GL520_REG_CONF) & 0x10) == ++ 0); ++ data->two_temps = results[0]; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ old = ++ gl520_read_value(client, ++ GL520_REG_CONF) & 0xef; ++ if (!results[1]) { ++ old |= 0x10; ++ data->two_temps = 0; ++ data->temp_hyst[1] = data->temp_over[1] = ++ data->temp[1] = 0; ++ } else { ++ data->two_temps = 1; ++ data->voltage_max[4] = data->voltage_min[4] = ++ data->voltage[4] = 0; ++ } ++ gl520_write_value(client, GL520_REG_CONF, old); ++ } ++ } ++} ++ ++static int __init sm_gl520sm_init(void) ++{ ++ printk("gl520sm.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&gl520_driver); ++} ++ ++static void __exit sm_gl520sm_exit(void) ++{ ++ i2c_del_driver(&gl520_driver); ++} ++ ++ ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard and Kyösti Mälkki "); ++MODULE_DESCRIPTION("GL520SM driver"); ++ ++module_init(sm_gl520sm_init); ++module_exit(sm_gl520sm_exit); +--- linux-old/drivers/sensors/it87.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/it87.c Mon Dec 13 20:18:47 2004 +@@ -0,0 +1,1128 @@ ++/* ++ it87.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring. ++ ++ Supports: IT8705F Super I/O chip w/LPC interface ++ IT8712F Super I/O chup w/LPC interface & SMbus ++ Sis950 A clone of the IT8705F ++ ++ Copyright (c) 2001 Chris Gauthron ++ Largely inspired by lm78.c of the same package ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ djg@pdp8.net David Gesswein 7/18/01 ++ Modified to fix bug with not all alarms enabled. ++ Added ability to read battery voltage and select temperature sensor ++ type at module load time. ++*/ ++ ++/* ++ michael.hufer@gmx.de Michael Hufer 09/07/03 ++ Modified configure (enable/disable) chip reset at module load time. ++ Added ability to read and set fan pwm registers and the smart ++ guardian (sg) features of the chip. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x20, 0x2f, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { 0x0290, SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_4(it87, it8705, it8712, sis950); ++ ++ ++#define REG 0x2e /* The register to read/write */ ++#define DEV 0x07 /* Register: Logical device select */ ++#define VAL 0x2f /* The value to read/write */ ++#define PME 0x04 /* The device with the fan registers in it */ ++#define DEVID 0x20 /* Register: Device ID */ ++ ++static inline void ++superio_outb(int reg, int val) ++{ ++ outb(reg, REG); ++ outb(val, VAL); ++} ++ ++static inline int ++superio_inb(int reg) ++{ ++ outb(reg, REG); ++ return inb(VAL); ++} ++ ++static inline void ++superio_select(void) ++{ ++ outb(DEV, REG); ++ outb(PME, VAL); ++} ++ ++static inline void ++superio_enter(void) ++{ ++ outb(0x87, REG); ++ outb(0x01, REG); ++ outb(0x55, REG); ++ outb(0x55, REG); ++} ++ ++static inline void ++superio_exit(void) ++{ ++ outb(0x02, REG); ++ outb(0x02, VAL); ++} ++ ++/* just IT8712F for now - this should be extended to support the other ++ chips as well */ ++#define IT87_DEVID_MATCH(id) ((id) == 0x8712) ++ ++#define IT87_ACT_REG 0x30 ++#define IT87_BASE_REG 0x60 ++ ++/* Update battery voltage after every reading if true */ ++static int update_vbat = 0; ++ ++/* Reset the registers on init */ ++static int reset = 0; ++ ++/* Many IT87 constants specified below */ ++ ++/* Length of ISA address segment */ ++#define IT87_EXTENT 8 ++ ++/* Where are the ISA address/data registers relative to the base address */ ++#define IT87_ADDR_REG_OFFSET 5 ++#define IT87_DATA_REG_OFFSET 6 ++ ++/*----- The IT87 registers -----*/ ++ ++#define IT87_REG_CONFIG 0x00 ++ ++#define IT87_REG_ALARM1 0x01 ++#define IT87_REG_ALARM2 0x02 ++#define IT87_REG_ALARM3 0x03 ++ ++#define IT87_REG_VID 0x0a ++#define IT87_REG_FAN_DIV 0x0b ++ ++#define IT87_REG_FAN(nr) (0x0c + (nr)) ++#define IT87_REG_FAN_MIN(nr) (0x0f + (nr)) ++#define IT87_REG_FAN_CTRL 0x13 ++ ++/* pwm and smart guardian registers */ ++ ++#define IT87_REG_FAN_ONOFF 0x14 ++#define IT87_REG_PWM(nr) (0x14 + (nr)) ++#define IT87_REG_SG_TL_OFF(nr) (0x58 + (nr)*8) ++#define IT87_REG_SG_TL_LOW(nr) (0x59 + (nr)*8) ++#define IT87_REG_SG_TL_MED(nr) (0x5a + (nr)*8) ++#define IT87_REG_SG_TL_HI(nr) (0x5b + (nr)*8) ++#define IT87_REG_SG_TL_OVR(nr) (0x5c + (nr)*8) ++#define IT87_REG_SG_PWM_LOW(nr) (0x5d + (nr)*8) ++#define IT87_REG_SG_PWM_MED(nr) (0x5e + (nr)*8) ++#define IT87_REG_SG_PWM_HI(nr) (0x5f + (nr)*8) ++ ++/* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */ ++ ++#define IT87_REG_VIN(nr) (0x20 + (nr)) ++#define IT87_REG_TEMP(nr) (0x28 + (nr)) ++ ++#define IT87_REG_VIN_MAX(nr) (0x30 + (nr) * 2) ++#define IT87_REG_VIN_MIN(nr) (0x31 + (nr) * 2) ++#define IT87_REG_TEMP_HIGH(nr) (0x3e + (nr) * 2) ++#define IT87_REG_TEMP_LOW(nr) (0x3f + (nr) * 2) ++ ++#define IT87_REG_I2C_ADDR 0x48 ++ ++#define IT87_REG_VIN_ENABLE 0x50 ++#define IT87_REG_TEMP_ENABLE 0x51 ++ ++#define IT87_REG_CHIPID 0x58 ++ ++/* sensor pin types */ ++#define UNUSED 0 ++#define THERMISTOR 2 ++#define PIIDIODE 3 ++ ++/* Conversions. Limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255)) ++#define IN_FROM_REG(val) (((val) * 16 + 5) / 10) ++ ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 255; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, ++ 254); ++} ++ ++#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div))) ++ ++#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-5)/10):\ ++ ((val)+5)/10),-127,127)) ++#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10) ++ ++#define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\ ++ 205-(val)*5) ++#define ALARMS_FROM_REG(val) (val) ++ ++extern inline u8 DIV_TO_REG(long val) ++{ ++ u8 i; ++ for( i = 0; i <= 7; i++ ) ++ { ++ if( val>>i == 1 ) ++ return i; ++ } ++ return 1; ++} ++#define DIV_FROM_REG(val) (1 << (val)) ++ ++/* For each registered IT87, we need to keep some data in memory. That ++ data is pointed to by it87_list[NR]->data. The structure itself is ++ dynamically allocated, at the same time when a new it87 client is ++ allocated. */ ++struct it87_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 in[9]; /* Register value */ ++ u8 in_max[9]; /* Register value */ ++ u8 in_min[9]; /* Register value */ ++ u8 fan[3]; /* Register value */ ++ u8 fan_min[3]; /* Register value */ ++ u8 temp[3]; /* Register value */ ++ u8 temp_high[3]; /* Register value */ ++ u8 temp_low[3]; /* Register value */ ++ u8 fan_div[3]; /* Register encoding, shifted right */ ++ u8 vid; /* Register encoding, combined */ ++ u32 alarms; /* Register encoding, combined */ ++ u8 pwm[3]; /* Register value */ ++ u8 fan_ctl[2]; /* Register encoding */ ++ u8 sg_tl[3][5]; /* Register value */ ++ u8 sg_pwm[3][3]; /* Register value */ ++ u8 sens[3]; /* 2 = Thermistor, ++ 3 = PII/Celeron diode */ ++}; ++ ++ ++static int it87_attach_adapter(struct i2c_adapter *adapter); ++static int it87_find(int *address); ++static int it87_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int it87_detach_client(struct i2c_client *client); ++ ++static int it87_read_value(struct i2c_client *client, u8 register); ++static int it87_write_value(struct i2c_client *client, u8 register, ++ u8 value); ++static void it87_update_client(struct i2c_client *client); ++static void it87_init_client(struct i2c_client *client); ++ ++ ++static void it87_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++static void it87_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void it87_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void it87_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void it87_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void it87_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void it87_fan_ctl(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void it87_pwm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void it87_sgpwm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void it87_sgtl(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void it87_sens(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static struct i2c_driver it87_driver = { ++ .owner = THIS_MODULE, ++ .name = "IT87xx sensor driver", ++ .id = I2C_DRIVERID_IT87, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = it87_attach_adapter, ++ .detach_client = it87_detach_client, ++}; ++ ++static int it87_id = 0; ++ ++/* The /proc/sys entries */ ++ ++/* -- SENSORS SYSCTL START -- */ ++#define IT87_SYSCTL_IN0 1000 /* Volts * 100 */ ++#define IT87_SYSCTL_IN1 1001 ++#define IT87_SYSCTL_IN2 1002 ++#define IT87_SYSCTL_IN3 1003 ++#define IT87_SYSCTL_IN4 1004 ++#define IT87_SYSCTL_IN5 1005 ++#define IT87_SYSCTL_IN6 1006 ++#define IT87_SYSCTL_IN7 1007 ++#define IT87_SYSCTL_IN8 1008 ++#define IT87_SYSCTL_FAN1 1101 /* Rotations/min */ ++#define IT87_SYSCTL_FAN2 1102 ++#define IT87_SYSCTL_FAN3 1103 ++#define IT87_SYSCTL_TEMP1 1200 /* Degrees Celcius * 10 */ ++#define IT87_SYSCTL_TEMP2 1201 /* Degrees Celcius * 10 */ ++#define IT87_SYSCTL_TEMP3 1202 /* Degrees Celcius * 10 */ ++#define IT87_SYSCTL_VID 1300 /* Volts * 100 */ ++#define IT87_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define IT87_SYSCTL_ALARMS 2004 /* bitvector */ ++ ++#define IT87_SYSCTL_PWM1 1401 ++#define IT87_SYSCTL_PWM2 1402 ++#define IT87_SYSCTL_PWM3 1403 ++#define IT87_SYSCTL_FAN_CTL 1501 ++#define IT87_SYSCTL_FAN_ON_OFF 1502 ++#define IT87_SYSCTL_SENS1 1601 /* 1, 2, or Beta (3000-5000) */ ++#define IT87_SYSCTL_SENS2 1602 ++#define IT87_SYSCTL_SENS3 1603 ++ ++#define IT87_ALARM_IN0 0x000100 ++#define IT87_ALARM_IN1 0x000200 ++#define IT87_ALARM_IN2 0x000400 ++#define IT87_ALARM_IN3 0x000800 ++#define IT87_ALARM_IN4 0x001000 ++#define IT87_ALARM_IN5 0x002000 ++#define IT87_ALARM_IN6 0x004000 ++#define IT87_ALARM_IN7 0x008000 ++#define IT87_ALARM_FAN1 0x0001 ++#define IT87_ALARM_FAN2 0x0002 ++#define IT87_ALARM_FAN3 0x0004 ++#define IT87_ALARM_TEMP1 0x00010000 ++#define IT87_ALARM_TEMP2 0x00020000 ++#define IT87_ALARM_TEMP3 0x00040000 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected IT87. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table it87_dir_table_template[] = { ++ {IT87_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_in}, ++ {IT87_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_in}, ++ {IT87_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_in}, ++ {IT87_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_in}, ++ {IT87_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_in}, ++ {IT87_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_in}, ++ {IT87_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_in}, ++ {IT87_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_in}, ++ {IT87_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_in}, ++ {IT87_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_fan}, ++ {IT87_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_fan}, ++ {IT87_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_fan}, ++ {IT87_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_temp}, ++ {IT87_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_temp}, ++ {IT87_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_temp}, ++ {IT87_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_vid}, ++ {IT87_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_fan_div}, ++ {IT87_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_alarms}, ++ {IT87_SYSCTL_FAN_CTL, "fan_ctl", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_fan_ctl}, ++ {IT87_SYSCTL_FAN_ON_OFF, "fan_on_off", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_fan_ctl}, ++ {IT87_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_pwm}, ++ {IT87_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_pwm}, ++ {IT87_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_pwm}, ++ {IT87_SYSCTL_PWM1, "sg_pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_sgpwm}, ++ {IT87_SYSCTL_PWM2, "sg_pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_sgpwm}, ++ {IT87_SYSCTL_PWM3, "sg_pwm3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_sgpwm}, ++ {IT87_SYSCTL_PWM1, "sg_tl1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_sgtl}, ++ {IT87_SYSCTL_PWM2, "sg_tl2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_sgtl}, ++ {IT87_SYSCTL_PWM3, "sg_tl3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_sgtl}, ++ {IT87_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_sens}, ++ {IT87_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_sens}, ++ {IT87_SYSCTL_SENS3, "sensor3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &it87_sens}, ++ {0} ++}; ++ ++ ++/* This function is called when: ++ * it87_driver is inserted (when this module is loaded), for each ++ available adapter ++ * when a new adapter is inserted (and it87_driver is still present) */ ++static int it87_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, it87_detect); ++} ++ ++static int it87_find(int *address) ++{ ++ u16 val; ++ ++ superio_enter(); ++ val = (superio_inb(DEVID) << 8) | ++ superio_inb(DEVID + 1); ++ if (!IT87_DEVID_MATCH(val)) { ++ superio_exit(); ++ return -ENODEV; ++ } ++ ++ superio_select(); ++ val = (superio_inb(IT87_BASE_REG) << 8) | ++ superio_inb(IT87_BASE_REG + 1); ++ superio_exit(); ++ *address = val & ~(IT87_EXTENT - 1); ++ if (*address == 0) { ++ return -ENODEV; ++ } ++ return 0; ++} ++ ++/* This function is called by i2c_detect */ ++int it87_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct it87_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ int is_isa = i2c_is_isa_adapter(adapter); ++ ++ if (!is_isa ++ && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ return 0; ++ ++ if (is_isa ++ && check_region(address, IT87_EXTENT)) ++ return 0; ++ ++ /* Probe whether there is anything available on this address. Already ++ done for SMBus clients */ ++ if (is_isa && kind < 0) { ++#define REALLY_SLOW_IO ++ /* We need the timeouts for at least some IT87-like chips. ++ But only if we read 'undefined' registers. */ ++ i = inb_p(address + 1); ++ if (inb_p(address + 2) != i ++ || inb_p(address + 3) != i ++ || inb_p(address + 7) != i) ++ return -ENODEV; ++#undef REALLY_SLOW_IO ++ ++ /* Let's just hope nothing breaks here */ ++ i = inb_p(address + 5) & 0x7f; ++ outb_p(~i & 0x7f, address + 5); ++ if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) { ++ outb_p(i, address + 5); ++ return -ENODEV; ++ } ++ } ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access it87_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct it87_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ if (is_isa) ++ init_MUTEX(&data->lock); ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &it87_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ ++ if (kind < 0) { ++ if ((it87_read_value(new_client, IT87_REG_CONFIG) & 0x80) ++ || (!is_isa ++ && it87_read_value(new_client, IT87_REG_I2C_ADDR) != address)) { ++ err = -ENODEV; ++ goto ERROR1; ++ } ++ } ++ ++ /* Determine the chip type. */ ++ if (kind <= 0) { ++ i = it87_read_value(new_client, IT87_REG_CHIPID); ++ if (i == 0x90) { ++ kind = it87; ++ } ++ else { ++ if (kind == 0) ++ printk ++ ("it87.o: Ignoring 'force' parameter for unknown chip at " ++ "adapter %d, address 0x%02x\n", ++ i2c_adapter_id(adapter), address); ++ err = -ENODEV; ++ goto ERROR1; ++ } ++ } ++ ++ if (kind == it87) { ++ type_name = "it87"; ++ client_name = "IT87 chip"; ++ } /* else if (kind == it8712) { ++ type_name = "it8712"; ++ client_name = "IT87-J chip"; ++ } */ else { ++#ifdef DEBUG ++ printk("it87.o: Internal error: unknown kind (%d)?!?", ++ kind); ++#endif ++ goto ERROR1; ++ } ++ ++ /* Reserve the ISA region */ ++ if (is_isa) ++ request_region(address, IT87_EXTENT, type_name); ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ data->type = kind; ++ ++ new_client->id = it87_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, ++ type_name, ++ it87_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the IT87 chip */ ++ it87_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ if (is_isa) ++ release_region(address, IT87_EXTENT); ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int it87_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct it87_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("it87.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ if(i2c_is_isa_client(client)) ++ release_region(client->addr, IT87_EXTENT); ++ kfree(client->data); ++ ++ return 0; ++} ++ ++/* The SMBus locks itself, but ISA access must be locked explicitely! ++ We don't want to lock the whole ISA bus, so we lock each client ++ separately. ++ We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, ++ would slow down the IT87 access and should not be necessary. ++ There are some ugly typecasts here, but the good new is - they should ++ nowhere else be necessary! */ ++static int it87_read_value(struct i2c_client *client, u8 reg) ++{ ++ int res; ++ if (i2c_is_isa_client(client)) { ++ down(&(((struct it87_data *) (client->data))->lock)); ++ outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); ++ res = inb_p(client->addr + IT87_DATA_REG_OFFSET); ++ up(&(((struct it87_data *) (client->data))->lock)); ++ return res; ++ } else ++ return i2c_smbus_read_byte_data(client, reg); ++} ++ ++/* The SMBus locks itself, but ISA access muse be locked explicitely! ++ We don't want to lock the whole ISA bus, so we lock each client ++ separately. ++ We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, ++ would slow down the IT87 access and should not be necessary. ++ There are some ugly typecasts here, but the good new is - they should ++ nowhere else be necessary! */ ++static int it87_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++ if (i2c_is_isa_client(client)) { ++ down(&(((struct it87_data *) (client->data))->lock)); ++ outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); ++ outb_p(value, client->addr + IT87_DATA_REG_OFFSET); ++ up(&(((struct it87_data *) (client->data))->lock)); ++ return 0; ++ } else ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++/* Called when we have found a new IT87. */ ++static void it87_init_client(struct i2c_client *client) ++{ ++ int tmp; ++ ++ if (reset) { ++ /* Reset all except Watchdog values and last conversion values ++ This sets fan-divs to 2, among others */ ++ it87_write_value(client, IT87_REG_CONFIG, 0x80); ++ } ++ ++ /* Check if temperature channnels are reset manually or by some reason */ ++ tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE); ++ if ((tmp & 0x3f) == 0) { ++ /* Temp1,Temp3=thermistor; Temp2=thermal diode */ ++ tmp = (tmp & 0xc0) | 0x2a; ++ it87_write_value(client, IT87_REG_TEMP_ENABLE, tmp); ++ } ++ ++ /* Check if voltage monitors are reset manually or by some reason */ ++ tmp = it87_read_value(client, IT87_REG_VIN_ENABLE); ++ if ((tmp & 0xff) == 0) { ++ /* Enable all voltage monitors */ ++ it87_write_value(client, IT87_REG_VIN_ENABLE, 0xff); ++ } ++ ++ /* Check if tachometers are reset manually or by some reason */ ++ tmp = it87_read_value(client, IT87_REG_FAN_CTRL); ++ if ((tmp & 0x70) == 0) { ++ /* Enable all fan tachometers */ ++ tmp = (tmp & 0x8f) | 0x70; ++ it87_write_value(client, IT87_REG_FAN_CTRL, tmp); ++ } ++ ++ /* Start monitoring */ ++ it87_write_value(client, IT87_REG_CONFIG, ++ (it87_read_value(client, IT87_REG_CONFIG) & 0x36) ++ | (update_vbat ? 0x41 : 0x01)); ++} ++ ++static void it87_update_client(struct i2c_client *client) ++{ ++ struct it87_data *data = client->data; ++ int i, tmp, tmp2; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++ if (update_vbat) { ++ /* Cleared after each update, so reenable. Value ++ returned by this read will be previous value */ ++ it87_write_value(client, IT87_REG_CONFIG, ++ it87_read_value(client, IT87_REG_CONFIG) | 0x40); ++ } ++ for (i = 0; i <= 7; i++) { ++ data->in[i] = ++ it87_read_value(client, IT87_REG_VIN(i)); ++ data->in_min[i] = ++ it87_read_value(client, IT87_REG_VIN_MIN(i)); ++ data->in_max[i] = ++ it87_read_value(client, IT87_REG_VIN_MAX(i)); ++ } ++ data->in[8] = ++ it87_read_value(client, IT87_REG_VIN(8)); ++ /* VBAT sensor doesn't have limit registers, set ++ to min and max value */ ++ data->in_min[8] = 0; ++ data->in_max[8] = 255; ++ ++ for (i = 1; i <= 3; i++) { ++ data->fan[i - 1] = ++ it87_read_value(client, IT87_REG_FAN(i)); ++ data->fan_min[i - 1] = ++ it87_read_value(client, IT87_REG_FAN_MIN(i)); ++ } ++ for (i = 1; i <= 3; i++) { ++ data->temp[i - 1] = ++ it87_read_value(client, IT87_REG_TEMP(i)); ++ data->temp_high[i - 1] = ++ it87_read_value(client, IT87_REG_TEMP_HIGH(i)); ++ data->temp_low[i - 1] = ++ it87_read_value(client, IT87_REG_TEMP_LOW(i)); ++ } ++ ++ /* The 8705 does not have VID capability */ ++ /*if (data->type == it8712) { ++ data->vid = it87_read_value(client, IT87_REG_VID); ++ data->vid &= 0x1f; ++ } ++ else */ { ++ data->vid = 0x1f; ++ } ++ ++ i = it87_read_value(client, IT87_REG_FAN_DIV); ++ data->fan_div[0] = i & 0x07; ++ data->fan_div[1] = (i >> 3) & 0x07; ++ data->fan_div[2] = ( (i&0x40)==0x40 ? 3 : 1 ); ++ ++ for( i = 1; i <= 3; i++ ) { ++ data->pwm[i-1] = it87_read_value(client, IT87_REG_PWM(i)); ++ data->sg_tl[i-1][0] = it87_read_value(client, IT87_REG_SG_TL_OFF(i)); ++ data->sg_tl[i-1][1] = it87_read_value(client, IT87_REG_SG_TL_LOW(i)); ++ data->sg_tl[i-1][2] = it87_read_value(client, IT87_REG_SG_TL_MED(i)); ++ data->sg_tl[i-1][3] = it87_read_value(client, IT87_REG_SG_TL_HI(i)); ++ data->sg_tl[i-1][4] = it87_read_value(client, IT87_REG_SG_TL_OVR(i)); ++ data->sg_pwm[i-1][0] = it87_read_value(client, IT87_REG_SG_PWM_LOW(i)); ++ data->sg_pwm[i-1][1] = it87_read_value(client, IT87_REG_SG_PWM_MED(i)); ++ data->sg_pwm[i-1][2] = it87_read_value(client, IT87_REG_SG_PWM_HI(i)); ++ } ++ data->alarms = ++ it87_read_value(client, IT87_REG_ALARM1) | ++ (it87_read_value(client, IT87_REG_ALARM2) << 8) | ++ (it87_read_value(client, IT87_REG_ALARM3) << 16); ++ data->fan_ctl[0] = it87_read_value(client, IT87_REG_FAN_CTRL); ++ data->fan_ctl[1] = it87_read_value(client, IT87_REG_FAN_ONOFF); ++ ++ tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE); ++ for(i = 0; i < 3; i++) { ++ tmp2 = (tmp >> i) & 0x09; ++ if(tmp2 == 0x01) ++ data->sens[i] = PIIDIODE; ++ else if(tmp2 == 0x08) ++ data->sens[i] = THERMISTOR; ++ else ++ data->sens[i] = UNUSED; ++ } ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ - Each function must return the magnitude (power of 10 to divide the ++ data with) if it is called with operation==SENSORS_PROC_REAL_INFO. ++ - It must put a maximum of *nrels elements in results reflecting the ++ data of this file, and set *nrels to the number it actually put ++ in it, if operation==SENSORS_PROC_REAL_READ. ++ - Finally, it must get upto *nrels elements from results and write them ++ to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++void it87_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct it87_data *data = client->data; ++ int nr = ctl_name - IT87_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ it87_update_client(client); ++ results[0] = IN_FROM_REG(data->in_min[nr]); ++ results[1] = IN_FROM_REG(data->in_max[nr]); ++ results[2] = IN_FROM_REG(data->in[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = IN_TO_REG(results[0]); ++ it87_write_value(client, IT87_REG_VIN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = IN_TO_REG(results[1]); ++ it87_write_value(client, IT87_REG_VIN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++} ++ ++void it87_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct it87_data *data = client->data; ++ int nr = ctl_name - IT87_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ it87_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ results[1] = FAN_FROM_REG(data->fan[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = FAN_TO_REG(results[0], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ it87_write_value(client, IT87_REG_FAN_MIN(nr), ++ data->fan_min[nr - 1]); ++ } ++ } ++} ++ ++ ++void it87_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct it87_data *data = client->data; ++ int nr = ctl_name - IT87_SYSCTL_TEMP1 + 1; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ it87_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_high[nr - 1]); ++ results[1] = TEMP_FROM_REG(data->temp_low[nr - 1]); ++ results[2] = TEMP_FROM_REG(data->temp[nr - 1]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_high[nr - 1] = TEMP_TO_REG(results[0]); ++ it87_write_value(client, IT87_REG_TEMP_HIGH(nr), ++ data->temp_high[nr - 1]); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_low[nr - 1] = TEMP_TO_REG(results[1]); ++ it87_write_value(client, IT87_REG_TEMP_LOW(nr), ++ data->temp_low[nr - 1]); ++ } ++ } ++} ++ ++void it87_pwm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct it87_data *data = client->data; ++ int nr = ctl_name - IT87_SYSCTL_PWM1 + 1; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ it87_update_client(client); ++ results[0] = data->pwm[nr - 1]; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->pwm[nr - 1] = results[0]; ++ it87_write_value(client, IT87_REG_PWM(nr), data->pwm[nr - 1]); ++ } ++ } ++} ++ ++void it87_sgpwm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct it87_data *data = client->data; ++ int nr = ctl_name - IT87_SYSCTL_PWM1 + 1; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ it87_update_client(client); ++ results[0] = data->sg_pwm[nr - 1][0]; ++ results[1] = data->sg_pwm[nr - 1][1]; ++ results[2] = data->sg_pwm[nr - 1][2]; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->sg_pwm[nr - 1][0] = results[0]; ++ it87_write_value(client, IT87_REG_SG_PWM_LOW(nr), data->sg_pwm[nr - 1][0]); ++ } ++ if (*nrels_mag >= 2) { ++ data->sg_pwm[nr - 1][1] = results[1]; ++ it87_write_value(client, IT87_REG_SG_PWM_MED(nr), data->sg_pwm[nr - 1][1]); ++ } ++ if (*nrels_mag >= 3) { ++ data->sg_pwm[nr - 1][2] = results[2]; ++ it87_write_value(client, IT87_REG_SG_PWM_HI(nr), data->sg_pwm[nr - 1][2]); ++ } ++ } ++} ++ ++void it87_sgtl(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct it87_data *data = client->data; ++ int nr = ctl_name - IT87_SYSCTL_PWM1 + 1; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ it87_update_client(client); ++ results[0] = TEMP_FROM_REG(data->sg_tl[nr - 1][0]); ++ results[1] = TEMP_FROM_REG(data->sg_tl[nr - 1][1]); ++ results[2] = TEMP_FROM_REG(data->sg_tl[nr - 1][2]); ++ results[3] = TEMP_FROM_REG(data->sg_tl[nr - 1][3]); ++ results[4] = TEMP_FROM_REG(data->sg_tl[nr - 1][4]); ++ *nrels_mag = 5; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->sg_tl[nr - 1][0] = TEMP_TO_REG(results[0]); ++ it87_write_value(client, IT87_REG_SG_TL_OFF(nr), data->sg_tl[nr - 1][0]); ++ } ++ if (*nrels_mag >= 2) { ++ data->sg_tl[nr - 1][1] = TEMP_TO_REG(results[1]); ++ it87_write_value(client, IT87_REG_SG_TL_LOW(nr), data->sg_tl[nr - 1][1]); ++ } ++ if (*nrels_mag >= 3) { ++ data->sg_tl[nr - 1][2] = TEMP_TO_REG(results[2]); ++ it87_write_value(client, IT87_REG_SG_TL_MED(nr), data->sg_tl[nr - 1][2]); ++ } ++ if (*nrels_mag >= 4) { ++ data->sg_tl[nr - 1][3] = TEMP_TO_REG(results[3]); ++ it87_write_value(client, IT87_REG_SG_TL_HI(nr), data->sg_tl[nr - 1][3]); ++ } ++ if (*nrels_mag >= 5) { ++ data->sg_tl[nr - 1][4] = TEMP_TO_REG(results[4]); ++ it87_write_value(client, IT87_REG_SG_TL_OVR(nr), data->sg_tl[nr - 1][4]); ++ } ++ } ++} ++ ++void it87_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct it87_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ it87_update_client(client); ++ results[0] = VID_FROM_REG(data->vid); ++ *nrels_mag = 1; ++ } ++} ++ ++void it87_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct it87_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ it87_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++void it87_fan_div(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct it87_data *data = client->data; ++ int old; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ it87_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ results[2] = DIV_FROM_REG(data->fan_div[2]);; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = it87_read_value(client, IT87_REG_FAN_DIV); ++ if (*nrels_mag >= 3) { ++ data->fan_div[2] = DIV_TO_REG(results[2]); ++ if( data->fan[2]!=3 ) { ++ data->fan_div[2] = 1; ++ old = (old & 0xbf); ++ } else { ++ old = (old | 0x40); ++ } ++ } ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ old = (old & 0xc3) | (data->fan_div[1] << 3); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ old = (old & 0xf8) | data->fan_div[0]; ++ it87_write_value(client, IT87_REG_FAN_DIV, old); ++ } ++ } ++} ++ ++void it87_fan_ctl(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct it87_data *data = client->data; ++ int index = ctl_name - IT87_SYSCTL_FAN_CTL; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ it87_update_client(client); ++ results[0] = data->fan_ctl[index]; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_ctl[index] = results[0]; ++ if( index == 0 ) ++ it87_write_value(client, IT87_REG_FAN_CTRL, data->fan_ctl[index] ); ++ else ++ it87_write_value(client, IT87_REG_FAN_ONOFF, data->fan_ctl[index] ); ++ } ++ } ++} ++ ++void it87_sens(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct it87_data *data = client->data; ++ int nr = 1 + ctl_name - IT87_SYSCTL_SENS1; ++ u8 tmp, val1, val2; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->sens[nr - 1]; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ val1 = 0x01 << (nr - 1); ++ val2 = 0x08 << (nr - 1); ++ tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE); ++ switch (results[0]) { ++ case PIIDIODE: ++ tmp &= ~ val2; ++ tmp |= val1; ++ break; ++ case THERMISTOR: ++ tmp &= ~ val1; ++ tmp |= val2; ++ break; ++ case UNUSED: ++ tmp &= ~ val1; ++ tmp &= ~ val2; ++ break; ++ default: ++ printk(KERN_ERR "it87.o: Invalid sensor type %ld; " ++ "must be 0 (unused), 2 (thermistor) " ++ "or 3 (diode)\n", results[0]); ++ return; ++ } ++ it87_write_value(client, ++ IT87_REG_TEMP_ENABLE, tmp); ++ data->sens[nr - 1] = results[0]; ++ } ++ } ++} ++ ++static int __init sm_it87_init(void) ++{ ++ int addr; ++ ++ printk("it87.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ if (!it87_find(&addr)) { ++ normal_isa[0] = addr; ++ } ++ return i2c_add_driver(&it87_driver); ++} ++ ++static void __exit sm_it87_exit(void) ++{ ++ i2c_del_driver(&it87_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Chris Gauthron "); ++MODULE_DESCRIPTION("IT8705F, IT8712F, Sis950 driver"); ++MODULE_PARM(update_vbat, "i"); ++MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); ++MODULE_PARM(reset, "i"); ++MODULE_PARM_DESC(reset, "Reset the chip's registers, default no"); ++ ++module_init(sm_it87_init); ++module_exit(sm_it87_exit); +--- linux-old/drivers/sensors/lm75.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/lm75.c Mon Dec 13 20:18:47 2004 +@@ -0,0 +1,331 @@ ++/* ++ lm75.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include "lm75.h" ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x48, 0x4f, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(lm75); ++ ++/* Many LM75 constants specified below */ ++ ++/* The LM75 registers */ ++#define LM75_REG_TEMP 0x00 ++#define LM75_REG_CONF 0x01 ++#define LM75_REG_TEMP_HYST 0x02 ++#define LM75_REG_TEMP_OS 0x03 ++ ++/* Each client has this additional data */ ++struct lm75_data { ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u16 temp, temp_os, temp_hyst; /* Register values */ ++}; ++ ++static int lm75_attach_adapter(struct i2c_adapter *adapter); ++static int lm75_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static void lm75_init_client(struct i2c_client *client); ++static int lm75_detach_client(struct i2c_client *client); ++ ++static int lm75_read_value(struct i2c_client *client, u8 reg); ++static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value); ++static void lm75_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm75_update_client(struct i2c_client *client); ++ ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver lm75_driver = { ++ .owner = THIS_MODULE, ++ .name = "LM75 sensor chip driver", ++ .id = I2C_DRIVERID_LM75, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = lm75_attach_adapter, ++ .detach_client = lm75_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define LM75_SYSCTL_TEMP 1200 /* Degrees Celcius * 10 */ ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected LM75. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table lm75_dir_table_template[] = { ++ {LM75_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm75_temp}, ++ {0} ++}; ++ ++static int lm75_id = 0; ++ ++static int lm75_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, lm75_detect); ++} ++ ++/* This function is called by i2c_detect */ ++int lm75_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct lm75_data *data; ++ int err = 0; ++ const char *type_name, *client_name; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("lm75.o: lm75_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | ++ I2C_FUNC_SMBUS_WORD_DATA)) ++ goto error0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access lm75_{read,write}_value. */ ++ if (!(data = kmalloc(sizeof(struct lm75_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto error0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &lm75_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. There is no identification- ++ dedicated register so we have to rely on several tricks: ++ unused bits, registers cycling over 8-address boundaries, ++ addresses 0x04-0x07 returning the last read value. ++ The cycling+unused addresses combination is not tested, ++ since it would significantly slow the detection down and would ++ hardly add any value. */ ++ if (kind < 0) { ++ int cur, conf, hyst, os; ++ ++ /* Unused addresses */ ++ cur = i2c_smbus_read_word_data(new_client, 0); ++ conf = i2c_smbus_read_byte_data(new_client, 1); ++ hyst = i2c_smbus_read_word_data(new_client, 2); ++ if (i2c_smbus_read_word_data(new_client, 4) != hyst ++ || i2c_smbus_read_word_data(new_client, 5) != hyst ++ || i2c_smbus_read_word_data(new_client, 6) != hyst ++ || i2c_smbus_read_word_data(new_client, 7) != hyst) ++ goto error1; ++ os = i2c_smbus_read_word_data(new_client, 3); ++ if (i2c_smbus_read_word_data(new_client, 4) != os ++ || i2c_smbus_read_word_data(new_client, 5) != os ++ || i2c_smbus_read_word_data(new_client, 6) != os ++ || i2c_smbus_read_word_data(new_client, 7) != os) ++ goto error1; ++ ++ /* Unused bits */ ++ if (conf & 0xe0) ++ goto error1; ++ ++ /* Addresses cycling */ ++ for (i = 8; i < 0xff; i += 8) ++ if (i2c_smbus_read_byte_data(new_client, i + 1) != conf ++ || i2c_smbus_read_word_data(new_client, i + 2) != hyst ++ || i2c_smbus_read_word_data(new_client, i + 3) != os) ++ goto error1; ++ } ++ ++ /* Determine the chip type - only one kind supported! */ ++ if (kind <= 0) ++ kind = lm75; ++ ++ if (kind == lm75) { ++ type_name = "lm75"; ++ client_name = "LM75 chip"; ++ } else { ++ pr_debug("lm75.o: Internal error: unknown kind (%d)?!?", kind); ++ goto error1; ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = lm75_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto error3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, type_name, ++ lm75_dir_table_template)) < 0) { ++ err = i; ++ goto error4; ++ } ++ data->sysctl_id = i; ++ ++ lm75_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ error4: ++ i2c_detach_client(new_client); ++ error3: ++ error1: ++ kfree(data); ++ error0: ++ return err; ++} ++ ++static int lm75_detach_client(struct i2c_client *client) ++{ ++ struct lm75_data *data = client->data; ++ ++ i2c_deregister_entry(data->sysctl_id); ++ i2c_detach_client(client); ++ kfree(client->data); ++ return 0; ++} ++ ++/* All registers are word-sized, except for the configuration register. ++ LM75 uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int lm75_read_value(struct i2c_client *client, u8 reg) ++{ ++ if (reg == LM75_REG_CONF) ++ return i2c_smbus_read_byte_data(client, reg); ++ else ++ return swab16(i2c_smbus_read_word_data(client, reg)); ++} ++ ++/* All registers are word-sized, except for the configuration register. ++ LM75 uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) ++{ ++ if (reg == LM75_REG_CONF) ++ return i2c_smbus_write_byte_data(client, reg, value); ++ else ++ return i2c_smbus_write_word_data(client, reg, swab16(value)); ++} ++ ++static void lm75_init_client(struct i2c_client *client) ++{ ++ /* Initialize the LM75 chip */ ++ lm75_write_value(client, LM75_REG_CONF, 0); ++} ++ ++static void lm75_update_client(struct i2c_client *client) ++{ ++ struct lm75_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ pr_debug("Starting lm75 update\n"); ++ ++ data->temp = lm75_read_value(client, LM75_REG_TEMP); ++ data->temp_os = lm75_read_value(client, LM75_REG_TEMP_OS); ++ data->temp_hyst = ++ lm75_read_value(client, LM75_REG_TEMP_HYST); ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++void lm75_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm75_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm75_update_client(client); ++ results[0] = LM75_TEMP_FROM_REG(data->temp_os); ++ results[1] = LM75_TEMP_FROM_REG(data->temp_hyst); ++ results[2] = LM75_TEMP_FROM_REG(data->temp); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_os = LM75_TEMP_TO_REG(results[0]); ++ lm75_write_value(client, LM75_REG_TEMP_OS, ++ data->temp_os); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst = LM75_TEMP_TO_REG(results[1]); ++ lm75_write_value(client, LM75_REG_TEMP_HYST, ++ data->temp_hyst); ++ } ++ } ++} ++ ++static int __init sm_lm75_init(void) ++{ ++ printk(KERN_INFO "lm75.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&lm75_driver); ++} ++ ++static void __exit sm_lm75_exit(void) ++{ ++ i2c_del_driver(&lm75_driver); ++} ++ ++MODULE_AUTHOR("Frodo Looijaard "); ++MODULE_DESCRIPTION("LM75 driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_lm75_init); ++module_exit(sm_lm75_exit); +--- linux-old/drivers/sensors/lm75.h Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/lm75.h Mon Dec 13 20:18:47 2004 +@@ -0,0 +1,49 @@ ++/* ++ lm75.h - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 2003 Mark M. Hoffman ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ This file contains common code for encoding/decoding LM75 type ++ temperature readings, which are emulated by many of the chips ++ we support. As the user is unlikely to load more than one driver ++ which contains this code, we don't worry about the wasted space. ++*/ ++ ++#include ++ ++/* straight from the datasheet */ ++#define LM75_TEMP_MIN (-550) ++#define LM75_TEMP_MAX 1250 ++ ++/* TEMP: 0.1C/bit (-55C to +125C) ++ REG: (0.5C/bit, two's complement) << 7 */ ++static inline u16 LM75_TEMP_TO_REG(int temp) ++{ ++ int ntemp = SENSORS_LIMIT(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); ++ ntemp += (ntemp<0 ? -2 : 2); ++ return (u16)((ntemp / 5) << 7); ++} ++ ++static inline int LM75_TEMP_FROM_REG(u16 reg) ++{ ++ /* use integer division instead of equivalent right shift to ++ guarantee arithmetic shift and preserve the sign */ ++ return ((s16)reg / 128) * 5; ++} ++ +--- linux-old/drivers/sensors/lm78.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/lm78.c Mon Dec 13 20:18:47 2004 +@@ -0,0 +1,729 @@ ++/* ++ lm78.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x20, 0x2f, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { 0x0290, SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_3(lm78, lm78j, lm79); ++ ++/* Many LM78 constants specified below */ ++ ++/* Length of ISA address segment */ ++#define LM78_EXTENT 8 ++ ++/* Where are the ISA address/data registers relative to the base address */ ++#define LM78_ADDR_REG_OFFSET 5 ++#define LM78_DATA_REG_OFFSET 6 ++ ++/* The LM78 registers */ ++#define LM78_REG_IN_MAX(nr) (0x2b + (nr) * 2) ++#define LM78_REG_IN_MIN(nr) (0x2c + (nr) * 2) ++#define LM78_REG_IN(nr) (0x20 + (nr)) ++ ++#define LM78_REG_FAN_MIN(nr) (0x3a + (nr)) ++#define LM78_REG_FAN(nr) (0x27 + (nr)) ++ ++#define LM78_REG_TEMP 0x27 ++#define LM78_REG_TEMP_OVER 0x39 ++#define LM78_REG_TEMP_HYST 0x3a ++ ++#define LM78_REG_ALARM1 0x41 ++#define LM78_REG_ALARM2 0x42 ++ ++#define LM78_REG_VID_FANDIV 0x47 ++ ++#define LM78_REG_CONFIG 0x40 ++#define LM78_REG_CHIPID 0x49 ++#define LM78_REG_I2C_ADDR 0x48 ++ ++ ++/* Conversions. Limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255)) ++#define IN_FROM_REG(val) (((val) * 16 + 5) / 10) ++ ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 255; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, ++ 254); ++} ++ ++#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div))) ++ ++#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-5)/10):\ ++ ((val)+5)/10),0,255)) ++#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10) ++ ++#define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\ ++ 205-(val)*5) ++#define ALARMS_FROM_REG(val) (val) ++ ++#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) ++#define DIV_FROM_REG(val) (1 << (val)) ++ ++/* There are some complications in a module like this. First off, LM78 chips ++ may be both present on the SMBus and the ISA bus, and we have to handle ++ those cases separately at some places. Second, there might be several ++ LM78 chips available (well, actually, that is probably never done; but ++ it is a clean illustration of how to handle a case like that). Finally, ++ a specific chip may be attached to *both* ISA and SMBus, and we would ++ not like to detect it double. Fortunately, in the case of the LM78 at ++ least, a register tells us what SMBus address we are on, so that helps ++ a bit - except if there could be more than one SMBus. Groan. No solution ++ for this yet. */ ++ ++/* This module may seem overly long and complicated. In fact, it is not so ++ bad. Quite a lot of bookkeeping is done. A real driver can often cut ++ some corners. */ ++ ++/* For each registered LM78, we need to keep some data in memory. That ++ data is pointed to by lm78_list[NR]->data. The structure itself is ++ dynamically allocated, at the same time when a new lm78 client is ++ allocated. */ ++struct lm78_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 in[7]; /* Register value */ ++ u8 in_max[7]; /* Register value */ ++ u8 in_min[7]; /* Register value */ ++ u8 fan[3]; /* Register value */ ++ u8 fan_min[3]; /* Register value */ ++ u8 temp; /* Register value */ ++ u8 temp_over; /* Register value */ ++ u8 temp_hyst; /* Register value */ ++ u8 fan_div[3]; /* Register encoding, shifted right */ ++ u8 vid; /* Register encoding, combined */ ++ u16 alarms; /* Register encoding, combined */ ++}; ++ ++ ++static int lm78_attach_adapter(struct i2c_adapter *adapter); ++static int lm78_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int lm78_detach_client(struct i2c_client *client); ++ ++static int lm78_read_value(struct i2c_client *client, u8 register); ++static int lm78_write_value(struct i2c_client *client, u8 register, ++ u8 value); ++static void lm78_update_client(struct i2c_client *client); ++static void lm78_init_client(struct i2c_client *client); ++ ++ ++static void lm78_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++static void lm78_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm78_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm78_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm78_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm78_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static struct i2c_driver lm78_driver = { ++ .owner = THIS_MODULE, ++ .name = "LM78(-J) and LM79 sensor driver", ++ .id = I2C_DRIVERID_LM78, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = lm78_attach_adapter, ++ .detach_client = lm78_detach_client, ++}; ++ ++static int lm78_id = 0; ++ ++/* The /proc/sys entries */ ++ ++/* -- SENSORS SYSCTL START -- */ ++#define LM78_SYSCTL_IN0 1000 /* Volts * 100 */ ++#define LM78_SYSCTL_IN1 1001 ++#define LM78_SYSCTL_IN2 1002 ++#define LM78_SYSCTL_IN3 1003 ++#define LM78_SYSCTL_IN4 1004 ++#define LM78_SYSCTL_IN5 1005 ++#define LM78_SYSCTL_IN6 1006 ++#define LM78_SYSCTL_FAN1 1101 /* Rotations/min */ ++#define LM78_SYSCTL_FAN2 1102 ++#define LM78_SYSCTL_FAN3 1103 ++#define LM78_SYSCTL_TEMP 1200 /* Degrees Celcius * 10 */ ++#define LM78_SYSCTL_VID 1300 /* Volts * 100 */ ++#define LM78_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define LM78_SYSCTL_ALARMS 2001 /* bitvector */ ++ ++#define LM78_ALARM_IN0 0x0001 ++#define LM78_ALARM_IN1 0x0002 ++#define LM78_ALARM_IN2 0x0004 ++#define LM78_ALARM_IN3 0x0008 ++#define LM78_ALARM_IN4 0x0100 ++#define LM78_ALARM_IN5 0x0200 ++#define LM78_ALARM_IN6 0x0400 ++#define LM78_ALARM_FAN1 0x0040 ++#define LM78_ALARM_FAN2 0x0080 ++#define LM78_ALARM_FAN3 0x0800 ++#define LM78_ALARM_TEMP 0x0010 ++#define LM78_ALARM_BTI 0x0020 ++#define LM78_ALARM_CHAS 0x1000 ++#define LM78_ALARM_FIFO 0x2000 ++#define LM78_ALARM_SMI_IN 0x4000 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected LM78. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table lm78_dir_table_template[] = { ++ {LM78_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_in}, ++ {LM78_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_in}, ++ {LM78_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_in}, ++ {LM78_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_in}, ++ {LM78_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_in}, ++ {LM78_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_in}, ++ {LM78_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_in}, ++ {LM78_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_fan}, ++ {LM78_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_fan}, ++ {LM78_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_fan}, ++ {LM78_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_temp}, ++ {LM78_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_vid}, ++ {LM78_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_fan_div}, ++ {LM78_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm78_alarms}, ++ {0} ++}; ++ ++ ++/* This function is called when: ++ * lm78_driver is inserted (when this module is loaded), for each ++ available adapter ++ * when a new adapter is inserted (and lm78_driver is still present) */ ++static int lm78_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, lm78_detect); ++} ++ ++/* This function is called by i2c_detect */ ++int lm78_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct lm78_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ int is_isa = i2c_is_isa_adapter(adapter); ++ ++ if (!is_isa ++ && !i2c_check_functionality(adapter, ++ I2C_FUNC_SMBUS_BYTE_DATA)) goto ++ ERROR0; ++ ++ if (is_isa) { ++ if (check_region(address, LM78_EXTENT)) ++ goto ERROR0; ++ } ++ ++ /* Probe whether there is anything available on this address. Already ++ done for SMBus clients */ ++ if (kind < 0) { ++ if (is_isa) { ++ ++#define REALLY_SLOW_IO ++ /* We need the timeouts for at least some LM78-like chips. But only ++ if we read 'undefined' registers. */ ++ i = inb_p(address + 1); ++ if (inb_p(address + 2) != i) ++ goto ERROR0; ++ if (inb_p(address + 3) != i) ++ goto ERROR0; ++ if (inb_p(address + 7) != i) ++ goto ERROR0; ++#undef REALLY_SLOW_IO ++ ++ /* Let's just hope nothing breaks here */ ++ i = inb_p(address + 5) & 0x7f; ++ outb_p(~i & 0x7f, address + 5); ++ if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) { ++ outb_p(i, address + 5); ++ return 0; ++ } ++ } ++ } ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access lm78_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct lm78_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ if (is_isa) ++ init_MUTEX(&data->lock); ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &lm78_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ ++ if (kind < 0) { ++ if (lm78_read_value(new_client, LM78_REG_CONFIG) & 0x80) ++ goto ERROR1; ++ if (!is_isa ++ && (lm78_read_value(new_client, LM78_REG_I2C_ADDR) != ++ address)) goto ERROR1; ++ } ++ ++ /* Determine the chip type. */ ++ if (kind <= 0) { ++ i = lm78_read_value(new_client, LM78_REG_CHIPID); ++ if (i == 0x00 || i == 0x20) ++ kind = lm78; ++ else if (i == 0x40) ++ kind = lm78j; ++ else if ((i & 0xfe) == 0xc0) ++ kind = lm79; ++ else { ++ if (kind == 0) ++ printk ++ ("lm78.o: Ignoring 'force' parameter for unknown chip at " ++ "adapter %d, address 0x%02x\n", ++ i2c_adapter_id(adapter), address); ++ goto ERROR1; ++ } ++ } ++ ++ if (kind == lm78) { ++ type_name = "lm78"; ++ client_name = "LM78 chip"; ++ } else if (kind == lm78j) { ++ type_name = "lm78-j"; ++ client_name = "LM78-J chip"; ++ } else if (kind == lm79) { ++ type_name = "lm79"; ++ client_name = "LM79 chip"; ++ } else { ++#ifdef DEBUG ++ printk("lm78.o: Internal error: unknown kind (%d)?!?", ++ kind); ++#endif ++ goto ERROR1; ++ } ++ ++ /* Reserve the ISA region */ ++ if (is_isa) ++ request_region(address, LM78_EXTENT, type_name); ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ data->type = kind; ++ ++ new_client->id = lm78_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, ++ type_name, ++ lm78_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the LM78 chip */ ++ lm78_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ if (is_isa) ++ release_region(address, LM78_EXTENT); ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int lm78_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct lm78_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("lm78.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ if(i2c_is_isa_client(client)) ++ release_region(client->addr, LM78_EXTENT); ++ kfree(client->data); ++ ++ return 0; ++} ++ ++/* The SMBus locks itself, but ISA access must be locked explicitely! ++ We don't want to lock the whole ISA bus, so we lock each client ++ separately. ++ We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks, ++ would slow down the LM78 access and should not be necessary. ++ There are some ugly typecasts here, but the good new is - they should ++ nowhere else be necessary! */ ++static int lm78_read_value(struct i2c_client *client, u8 reg) ++{ ++ int res; ++ if (i2c_is_isa_client(client)) { ++ down(&(((struct lm78_data *) (client->data))->lock)); ++ outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); ++ res = inb_p(client->addr + LM78_DATA_REG_OFFSET); ++ up(&(((struct lm78_data *) (client->data))->lock)); ++ return res; ++ } else ++ return i2c_smbus_read_byte_data(client, reg); ++} ++ ++/* The SMBus locks itself, but ISA access muse be locked explicitely! ++ We don't want to lock the whole ISA bus, so we lock each client ++ separately. ++ We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks, ++ would slow down the LM78 access and should not be necessary. ++ There are some ugly typecasts here, but the good new is - they should ++ nowhere else be necessary! */ ++static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++ if (i2c_is_isa_client(client)) { ++ down(&(((struct lm78_data *) (client->data))->lock)); ++ outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); ++ outb_p(value, client->addr + LM78_DATA_REG_OFFSET); ++ up(&(((struct lm78_data *) (client->data))->lock)); ++ return 0; ++ } else ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++/* Called when we have found a new LM78. */ ++static void lm78_init_client(struct i2c_client *client) ++{ ++ u8 config = lm78_read_value(client, LM78_REG_CONFIG); ++ ++ /* Start monitoring */ ++ if (!(config & 0x01)) ++ lm78_write_value(client, LM78_REG_CONFIG, ++ (config & 0xf7) | 0x01); ++} ++ ++static void lm78_update_client(struct i2c_client *client) ++{ ++ struct lm78_data *data = client->data; ++ int i; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("Starting lm78 update\n"); ++#endif ++ for (i = 0; i <= 6; i++) { ++ data->in[i] = ++ lm78_read_value(client, LM78_REG_IN(i)); ++ data->in_min[i] = ++ lm78_read_value(client, LM78_REG_IN_MIN(i)); ++ data->in_max[i] = ++ lm78_read_value(client, LM78_REG_IN_MAX(i)); ++ } ++ for (i = 1; i <= 3; i++) { ++ data->fan[i - 1] = ++ lm78_read_value(client, LM78_REG_FAN(i)); ++ data->fan_min[i - 1] = ++ lm78_read_value(client, LM78_REG_FAN_MIN(i)); ++ } ++ data->temp = lm78_read_value(client, LM78_REG_TEMP); ++ data->temp_over = ++ lm78_read_value(client, LM78_REG_TEMP_OVER); ++ data->temp_hyst = ++ lm78_read_value(client, LM78_REG_TEMP_HYST); ++ i = lm78_read_value(client, LM78_REG_VID_FANDIV); ++ data->vid = i & 0x0f; ++ if (data->type == lm79) ++ data->vid |= ++ (lm78_read_value(client, LM78_REG_CHIPID) & ++ 0x01) << 4; ++ else ++ data->vid |= 0x10; ++ data->fan_div[0] = (i >> 4) & 0x03; ++ data->fan_div[1] = i >> 6; ++ data->alarms = lm78_read_value(client, LM78_REG_ALARM1) + ++ (lm78_read_value(client, LM78_REG_ALARM2) << 8); ++ data->last_updated = jiffies; ++ data->valid = 1; ++ ++ data->fan_div[2] = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the date ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++void lm78_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm78_data *data = client->data; ++ int nr = ctl_name - LM78_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm78_update_client(client); ++ results[0] = IN_FROM_REG(data->in_min[nr]); ++ results[1] = IN_FROM_REG(data->in_max[nr]); ++ results[2] = IN_FROM_REG(data->in[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = IN_TO_REG(results[0]); ++ lm78_write_value(client, LM78_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = IN_TO_REG(results[1]); ++ lm78_write_value(client, LM78_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++} ++ ++void lm78_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm78_data *data = client->data; ++ int nr = ctl_name - LM78_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm78_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr - 1], ++ DIV_FROM_REG(data-> ++ fan_div[nr - 1])); ++ results[1] = ++ FAN_FROM_REG(data->fan[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = FAN_TO_REG(results[0], ++ DIV_FROM_REG ++ (data-> ++ fan_div[nr - ++ 1])); ++ lm78_write_value(client, LM78_REG_FAN_MIN(nr), ++ data->fan_min[nr - 1]); ++ } ++ } ++} ++ ++ ++void lm78_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm78_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm78_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_over); ++ results[1] = TEMP_FROM_REG(data->temp_hyst); ++ results[2] = TEMP_FROM_REG(data->temp); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_over = TEMP_TO_REG(results[0]); ++ lm78_write_value(client, LM78_REG_TEMP_OVER, ++ data->temp_over); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst = TEMP_TO_REG(results[1]); ++ lm78_write_value(client, LM78_REG_TEMP_HYST, ++ data->temp_hyst); ++ } ++ } ++} ++ ++void lm78_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm78_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm78_update_client(client); ++ results[0] = VID_FROM_REG(data->vid); ++ *nrels_mag = 1; ++ } ++} ++ ++void lm78_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm78_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm78_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++/* Note: we save and restore the fan minimum here, because its value is ++ determined in part by the fan divisor. This follows the principle of ++ least surprise: the user doesn't expect the fan minimum to change just ++ because the divisor changed. */ ++void lm78_fan_div(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm78_data *data = client->data; ++ int old, min; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm78_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ results[2] = 2; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = lm78_read_value(client, LM78_REG_VID_FANDIV); ++ if (*nrels_mag >= 2) { ++ min = FAN_FROM_REG(data->fan_min[1], ++ DIV_FROM_REG(data->fan_div[1])); ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ old = (old & 0x3f) | (data->fan_div[1] << 6); ++ data->fan_min[1] = FAN_TO_REG(min, ++ DIV_FROM_REG(data->fan_div[1])); ++ lm78_write_value(client, LM78_REG_FAN_MIN(2), ++ data->fan_min[1]); ++ } ++ if (*nrels_mag >= 1) { ++ min = FAN_FROM_REG(data->fan_min[0], ++ DIV_FROM_REG(data->fan_div[0])); ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ old = (old & 0xcf) | (data->fan_div[0] << 4); ++ data->fan_min[0] = FAN_TO_REG(min, ++ DIV_FROM_REG(data->fan_div[0])); ++ lm78_write_value(client, LM78_REG_FAN_MIN(1), ++ data->fan_min[0]); ++ lm78_write_value(client, LM78_REG_VID_FANDIV, old); ++ } ++ } ++} ++ ++static int __init sm_lm78_init(void) ++{ ++ printk("lm78.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&lm78_driver); ++} ++ ++static void __exit sm_lm78_exit(void) ++{ ++ i2c_del_driver(&lm78_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Frodo Looijaard "); ++MODULE_DESCRIPTION("LM78, LM78-J and LM79 driver"); ++ ++module_init(sm_lm78_init); ++module_exit(sm_lm78_exit); +--- linux-old/drivers/sensors/lm80.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/lm80.c Mon Dec 13 20:18:48 2004 +@@ -0,0 +1,606 @@ ++/* ++ lm80.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard ++ and Philip Edelbrock ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x20, 0x2f, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(lm80); ++ ++/* Many LM80 constants specified below */ ++ ++/* The LM80 registers */ ++#define LM80_REG_IN_MAX(nr) (0x2a + (nr) * 2) ++#define LM80_REG_IN_MIN(nr) (0x2b + (nr) * 2) ++#define LM80_REG_IN(nr) (0x20 + (nr)) ++ ++#define LM80_REG_FAN1_MIN 0x3c ++#define LM80_REG_FAN2_MIN 0x3d ++#define LM80_REG_FAN1 0x28 ++#define LM80_REG_FAN2 0x29 ++ ++#define LM80_REG_TEMP 0x27 ++#define LM80_REG_TEMP_HOT_MAX 0x38 ++#define LM80_REG_TEMP_HOT_HYST 0x39 ++#define LM80_REG_TEMP_OS_MAX 0x3a ++#define LM80_REG_TEMP_OS_HYST 0x3b ++ ++#define LM80_REG_CONFIG 0x00 ++#define LM80_REG_ALARM1 0x01 ++#define LM80_REG_ALARM2 0x02 ++#define LM80_REG_MASK1 0x03 ++#define LM80_REG_MASK2 0x04 ++#define LM80_REG_FANDIV 0x05 ++#define LM80_REG_RES 0x06 ++ ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++ ++#define IN_TO_REG(val) (SENSORS_LIMIT((val),0,255)) ++#define IN_FROM_REG(val) (val) ++ ++static inline unsigned char FAN_TO_REG(unsigned rpm, unsigned div) ++{ ++ if (rpm == 0) ++ return 255; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, ++ 254); ++} ++ ++#define FAN_FROM_REG(val,div) ((val)==0?-1:\ ++ (val)==255?0:1350000/((div)*(val))) ++ ++static inline long TEMP_FROM_REG(u16 temp) ++{ ++ long res; ++ ++ temp >>= 4; ++ if (temp < 0x0800) ++ res = 625 * (long) temp; ++ else ++ res = ((long) temp - 0x01000) * 625; ++ ++ return res / 100; ++} ++ ++#define TEMP_LIMIT_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*100) ++ ++#define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT(((val)<0?(((val)-50)/100):\ ++ ((val)+50)/100), \ ++ 0,255) ++ ++#define ALARMS_FROM_REG(val) (val) ++ ++#define DIV_FROM_REG(val) (1 << (val)) ++#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) ++ ++struct lm80_data { ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 in[7]; /* Register value */ ++ u8 in_max[7]; /* Register value */ ++ u8 in_min[7]; /* Register value */ ++ u8 fan[2]; /* Register value */ ++ u8 fan_min[2]; /* Register value */ ++ u8 fan_div[2]; /* Register encoding, shifted right */ ++ u16 temp; /* Register values, shifted right */ ++ u8 temp_hot_max; /* Register value */ ++ u8 temp_hot_hyst; /* Register value */ ++ u8 temp_os_max; /* Register value */ ++ u8 temp_os_hyst; /* Register value */ ++ u16 alarms; /* Register encoding, combined */ ++}; ++ ++ ++ ++static int lm80_attach_adapter(struct i2c_adapter *adapter); ++static int lm80_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int lm80_detach_client(struct i2c_client *client); ++ ++static int lm80_read_value(struct i2c_client *client, u8 reg); ++static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value); ++static void lm80_update_client(struct i2c_client *client); ++static void lm80_init_client(struct i2c_client *client); ++ ++ ++static void lm80_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++static void lm80_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm80_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm80_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm80_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static int lm80_id = 0; ++ ++static struct i2c_driver lm80_driver = { ++ .owner = THIS_MODULE, ++ .name = "LM80 sensor driver", ++ .id = I2C_DRIVERID_LM80, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = lm80_attach_adapter, ++ .detach_client = lm80_detach_client, ++}; ++ ++/* The /proc/sys entries */ ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define LM80_SYSCTL_IN0 1000 /* Volts * 100 */ ++#define LM80_SYSCTL_IN1 1001 ++#define LM80_SYSCTL_IN2 1002 ++#define LM80_SYSCTL_IN3 1003 ++#define LM80_SYSCTL_IN4 1004 ++#define LM80_SYSCTL_IN5 1005 ++#define LM80_SYSCTL_IN6 1006 ++#define LM80_SYSCTL_FAN1 1101 /* Rotations/min */ ++#define LM80_SYSCTL_FAN2 1102 ++#define LM80_SYSCTL_TEMP 1250 /* Degrees Celcius * 100 */ ++#define LM80_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define LM80_SYSCTL_ALARMS 2001 /* bitvector */ ++ ++#define LM80_ALARM_IN0 0x0001 ++#define LM80_ALARM_IN1 0x0002 ++#define LM80_ALARM_IN2 0x0004 ++#define LM80_ALARM_IN3 0x0008 ++#define LM80_ALARM_IN4 0x0010 ++#define LM80_ALARM_IN5 0x0020 ++#define LM80_ALARM_IN6 0x0040 ++#define LM80_ALARM_FAN1 0x0400 ++#define LM80_ALARM_FAN2 0x0800 ++#define LM80_ALARM_TEMP_HOT 0x0100 ++#define LM80_ALARM_TEMP_OS 0x2000 ++#define LM80_ALARM_CHAS 0x1000 ++#define LM80_ALARM_BTI 0x0200 ++#define LM80_ALARM_INT_IN 0x0080 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected LM80. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table lm80_dir_table_template[] = { ++ {LM80_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm80_in}, ++ {LM80_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm80_in}, ++ {LM80_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm80_in}, ++ {LM80_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm80_in}, ++ {LM80_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm80_in}, ++ {LM80_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm80_in}, ++ {LM80_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm80_in}, ++ {LM80_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm80_fan}, ++ {LM80_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm80_fan}, ++ {LM80_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm80_temp}, ++ {LM80_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm80_fan_div}, ++ {LM80_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm80_alarms}, ++ {0} ++}; ++ ++static int lm80_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, lm80_detect); ++} ++ ++int lm80_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i, cur; ++ struct i2c_client *new_client; ++ struct lm80_data *data; ++ int err = 0; ++ const char *type_name, *client_name; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("lm80.o: lm80_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access lm80_{read,write}_value. */ ++ if (!(data = kmalloc(sizeof(struct lm80_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &lm80_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. It is lousy. */ ++ if (lm80_read_value(new_client, LM80_REG_ALARM2) & 0xc0) ++ goto ERROR1; ++ for (i = 0x2a; i <= 0x3d; i++) { ++ cur = i2c_smbus_read_byte_data(new_client, i); ++ if ((i2c_smbus_read_byte_data(new_client, i + 0x40) != cur) ++ || (i2c_smbus_read_byte_data(new_client, i + 0x80) != ++ cur) ++ || (i2c_smbus_read_byte_data(new_client, i + 0xc0) != ++ cur)) goto ERROR1; ++ } ++ ++ /* Determine the chip type - only one kind supported! */ ++ if (kind <= 0) ++ kind = lm80; ++ ++ if (kind == lm80) { ++ type_name = "lm80"; ++ client_name = "LM80 chip"; ++ } else { ++#ifdef DEBUG ++ printk("lm80.o: Internal error: unknown kind (%d)?!?", ++ kind); ++#endif ++ goto ERROR1; ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = lm80_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, type_name, ++ lm80_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ lm80_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int lm80_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct lm80_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("lm80.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++static int lm80_read_value(struct i2c_client *client, u8 reg) ++{ ++ return i2c_smbus_read_byte_data(client, reg); ++} ++ ++static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++/* Called when we have found a new LM80. */ ++static void lm80_init_client(struct i2c_client *client) ++{ ++ /* Reset all except Watchdog values and last conversion values ++ This sets fan-divs to 2, among others. This makes most other ++ initializations unnecessary */ ++ lm80_write_value(client, LM80_REG_CONFIG, 0x80); ++ /* Set 11-bit temperature resolution */ ++ lm80_write_value(client, LM80_REG_RES, 0x08); ++ ++ /* Start monitoring */ ++ lm80_write_value(client, LM80_REG_CONFIG, 0x01); ++} ++ ++static void lm80_update_client(struct i2c_client *client) ++{ ++ struct lm80_data *data = client->data; ++ int i; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > 2 * HZ) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("Starting lm80 update\n"); ++#endif ++ for (i = 0; i <= 6; i++) { ++ data->in[i] = ++ lm80_read_value(client, LM80_REG_IN(i)); ++ data->in_min[i] = ++ lm80_read_value(client, LM80_REG_IN_MIN(i)); ++ data->in_max[i] = ++ lm80_read_value(client, LM80_REG_IN_MAX(i)); ++ } ++ data->fan[0] = lm80_read_value(client, LM80_REG_FAN1); ++ data->fan_min[0] = ++ lm80_read_value(client, LM80_REG_FAN1_MIN); ++ data->fan[1] = lm80_read_value(client, LM80_REG_FAN2); ++ data->fan_min[1] = ++ lm80_read_value(client, LM80_REG_FAN2_MIN); ++ ++ data->temp = ++ (lm80_read_value(client, LM80_REG_TEMP) << 8) | ++ (lm80_read_value(client, LM80_REG_RES) & 0xf0); ++ data->temp_os_max = ++ lm80_read_value(client, LM80_REG_TEMP_OS_MAX); ++ data->temp_os_hyst = ++ lm80_read_value(client, LM80_REG_TEMP_OS_HYST); ++ data->temp_hot_max = ++ lm80_read_value(client, LM80_REG_TEMP_HOT_MAX); ++ data->temp_hot_hyst = ++ lm80_read_value(client, LM80_REG_TEMP_HOT_HYST); ++ ++ i = lm80_read_value(client, LM80_REG_FANDIV); ++ data->fan_div[0] = (i >> 2) & 0x03; ++ data->fan_div[1] = (i >> 4) & 0x03; ++ data->alarms = lm80_read_value(client, LM80_REG_ALARM1) + ++ (lm80_read_value(client, LM80_REG_ALARM2) << 8); ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the date ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++void lm80_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm80_data *data = client->data; ++ int nr = ctl_name - LM80_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm80_update_client(client); ++ results[0] = IN_FROM_REG(data->in_min[nr]); ++ results[1] = IN_FROM_REG(data->in_max[nr]); ++ results[2] = IN_FROM_REG(data->in[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = IN_TO_REG(results[0]); ++ lm80_write_value(client, LM80_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = IN_TO_REG(results[1]); ++ lm80_write_value(client, LM80_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++} ++ ++void lm80_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm80_data *data = client->data; ++ int nr = ctl_name - LM80_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm80_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr - 1], ++ DIV_FROM_REG(data-> ++ fan_div[nr - 1])); ++ results[1] = ++ FAN_FROM_REG(data->fan[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = FAN_TO_REG(results[0], ++ DIV_FROM_REG ++ (data-> ++ fan_div[nr - ++ 1])); ++ lm80_write_value(client, ++ nr == ++ 1 ? LM80_REG_FAN1_MIN : ++ LM80_REG_FAN2_MIN, ++ data->fan_min[nr - 1]); ++ } ++ } ++} ++ ++ ++void lm80_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm80_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm80_update_client(client); ++ results[0] = TEMP_LIMIT_FROM_REG(data->temp_hot_max); ++ results[1] = TEMP_LIMIT_FROM_REG(data->temp_hot_hyst); ++ results[2] = TEMP_LIMIT_FROM_REG(data->temp_os_max); ++ results[3] = TEMP_LIMIT_FROM_REG(data->temp_os_hyst); ++ results[4] = TEMP_FROM_REG(data->temp); ++ *nrels_mag = 5; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_hot_max = TEMP_LIMIT_TO_REG(results[0]); ++ lm80_write_value(client, LM80_REG_TEMP_HOT_MAX, ++ data->temp_hot_max); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hot_hyst = ++ TEMP_LIMIT_TO_REG(results[1]); ++ lm80_write_value(client, LM80_REG_TEMP_HOT_HYST, ++ data->temp_hot_hyst); ++ } ++ if (*nrels_mag >= 3) { ++ data->temp_os_max = TEMP_LIMIT_TO_REG(results[2]); ++ lm80_write_value(client, LM80_REG_TEMP_OS_MAX, ++ data->temp_os_max); ++ } ++ if (*nrels_mag >= 4) { ++ data->temp_os_hyst = TEMP_LIMIT_TO_REG(results[3]); ++ lm80_write_value(client, LM80_REG_TEMP_OS_HYST, ++ data->temp_os_hyst); ++ } ++ } ++} ++ ++void lm80_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm80_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm80_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++void lm80_fan_div(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm80_data *data = client->data; ++ int old; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm80_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ results[2] = 2; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = lm80_read_value(client, LM80_REG_FANDIV); ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ old = (old & 0xcf) | (data->fan_div[1] << 4); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ old = (old & 0xf3) | (data->fan_div[0] << 2); ++ lm80_write_value(client, LM80_REG_FANDIV, old); ++ } ++ } ++} ++ ++static int __init sm_lm80_init(void) ++{ ++ printk("lm80.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&lm80_driver); ++} ++ ++static void __exit sm_lm80_exit(void) ++{ ++ i2c_del_driver(&lm80_driver); ++} ++ ++ ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard and Philip Edelbrock "); ++MODULE_DESCRIPTION("LM80 driver"); ++ ++module_init(sm_lm80_init); ++module_exit(sm_lm80_exit); +--- linux-old/drivers/sensors/lm83.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/lm83.c Mon Dec 13 20:18:48 2004 +@@ -0,0 +1,513 @@ ++/* ++ * lm83.c - Part of lm_sensors, Linux kernel modules for hardware ++ * monitoring ++ * Copyright (C) 2003 Jean Delvare ++ * ++ * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is ++ * a sensor chip made by National Semiconductor. It reports up to four ++ * temperatures (its own plus up to three external ones) with a 1 deg ++ * resolution and a 3-4 deg accuracy. Complete datasheet can be obtained ++ * from National's website at: ++ * http://www.national.com/pf/LM/LM83.html ++ * Since the datasheet omits to give the chip stepping code, I give it ++ * here: 0x03 (at register 0xff). ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++/* ++ * Addresses to scan ++ * Address is selected using 2 three-level pins, resulting in 9 possible ++ * addresses. ++ */ ++ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x18, 0x1a, 0x29, 0x2b, ++ 0x4c, 0x4e, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* ++ * Insmod parameters ++ */ ++ ++SENSORS_INSMOD_1(lm83); ++ ++/* ++ * The LM83 registers ++ * Manufacturer ID is 0x01 for National Semiconductor. ++ */ ++ ++#define LM83_REG_R_MAN_ID 0xFE ++#define LM83_REG_R_CHIP_ID 0xFF ++#define LM83_REG_R_CONFIG 0x03 ++#define LM83_REG_W_CONFIG 0x09 ++#define LM83_REG_R_STATUS1 0x02 ++#define LM83_REG_R_STATUS2 0x35 ++#define LM83_REG_R_LOCAL_TEMP 0x00 ++#define LM83_REG_R_LOCAL_HIGH 0x05 ++#define LM83_REG_W_LOCAL_HIGH 0x0B ++#define LM83_REG_R_REMOTE1_TEMP 0x30 ++#define LM83_REG_R_REMOTE1_HIGH 0x38 ++#define LM83_REG_W_REMOTE1_HIGH 0x50 ++#define LM83_REG_R_REMOTE2_TEMP 0x01 ++#define LM83_REG_R_REMOTE2_HIGH 0x07 ++#define LM83_REG_W_REMOTE2_HIGH 0x0D ++#define LM83_REG_R_REMOTE3_TEMP 0x31 ++#define LM83_REG_R_REMOTE3_HIGH 0x3A ++#define LM83_REG_W_REMOTE3_HIGH 0x52 ++#define LM83_REG_R_TCRIT 0x42 ++#define LM83_REG_W_TCRIT 0x5A ++ ++/* ++ * Conversions and various macros ++ * The LM83 uses signed 8-bit values. ++ */ ++ ++#define TEMP_FROM_REG(val) ((val) > 127 ? (val) - 0x100 : (val)) ++#define TEMP_TO_REG(val) ((val) <= -50 ? -50 + 0x100 : \ ++ (val) >= 127 ? 127 : \ ++ (val) >= 0 ? (val) : \ ++ (val) + 0x100) ++ ++static const u8 LM83_REG_R_TEMP[] = { ++ LM83_REG_R_LOCAL_TEMP, ++ LM83_REG_R_REMOTE1_TEMP, ++ LM83_REG_R_REMOTE2_TEMP, ++ LM83_REG_R_REMOTE3_TEMP ++}; ++ ++static const u8 LM83_REG_R_HIGH[] = { ++ LM83_REG_R_LOCAL_HIGH, ++ LM83_REG_R_REMOTE1_HIGH, ++ LM83_REG_R_REMOTE2_HIGH, ++ LM83_REG_R_REMOTE3_HIGH ++}; ++ ++static const u8 LM83_REG_W_HIGH[] = { ++ LM83_REG_W_LOCAL_HIGH, ++ LM83_REG_W_REMOTE1_HIGH, ++ LM83_REG_W_REMOTE2_HIGH, ++ LM83_REG_W_REMOTE3_HIGH ++}; ++ ++/* ++ * Functions declaration ++ */ ++ ++static int lm83_attach_adapter(struct i2c_adapter *adapter); ++static int lm83_detect(struct i2c_adapter *adapter, int address, unsigned ++ short flags, int kind); ++static int lm83_detach_client(struct i2c_client *client); ++static void lm83_update_client(struct i2c_client *client); ++static void lm83_temp(struct i2c_client *client, int operation, int ++ ctl_name, int *nrels_mag, long *results); ++static void lm83_tcrit(struct i2c_client *client, int operation, int ++ ctl_name, int *nrels_mag, long *results); ++static void lm83_alarms(struct i2c_client *client, int operation, int ++ ctl_name, int *nrels_mag, long *results); ++ ++/* ++ * Driver data (common to all clients) ++ */ ++ ++static struct i2c_driver lm83_driver = { ++ .owner = THIS_MODULE, ++ .name = "LM83 sensor driver", ++ .id = I2C_DRIVERID_LM83, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = lm83_attach_adapter, ++ .detach_client = lm83_detach_client, ++}; ++ ++/* ++ * Client data (each client gets its own) ++ */ ++ ++struct lm83_data ++{ ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* zero until following fields are valid */ ++ unsigned long last_updated; /* in jiffies */ ++ ++ /* registers values */ ++ u8 temp[4], temp_high[4], tcrit; ++ u16 alarms; /* bitvector, combined */ ++}; ++ ++/* ++ * Proc entries ++ * These files are created for each detected LM83. ++ */ ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define LM83_SYSCTL_LOCAL_TEMP 1200 ++#define LM83_SYSCTL_REMOTE1_TEMP 1201 ++#define LM83_SYSCTL_REMOTE2_TEMP 1202 ++#define LM83_SYSCTL_REMOTE3_TEMP 1203 ++#define LM83_SYSCTL_TCRIT 1208 ++#define LM83_SYSCTL_ALARMS 1210 ++ ++#define LM83_ALARM_LOCAL_HIGH 0x0040 ++#define LM83_ALARM_LOCAL_CRIT 0x0001 ++#define LM83_ALARM_REMOTE1_HIGH 0x8000 ++#define LM83_ALARM_REMOTE1_CRIT 0x0100 ++#define LM83_ALARM_REMOTE1_OPEN 0x2000 ++#define LM83_ALARM_REMOTE2_HIGH 0x0010 ++#define LM83_ALARM_REMOTE2_CRIT 0x0002 ++#define LM83_ALARM_REMOTE2_OPEN 0x0004 ++#define LM83_ALARM_REMOTE3_HIGH 0x1000 ++#define LM83_ALARM_REMOTE3_CRIT 0x0200 ++#define LM83_ALARM_REMOTE3_OPEN 0x0400 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++ ++static ctl_table lm83_dir_table_template[] = ++{ ++ {LM83_SYSCTL_LOCAL_TEMP, "temp1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm83_temp}, ++ {LM83_SYSCTL_REMOTE1_TEMP, "temp2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm83_temp}, ++ {LM83_SYSCTL_REMOTE2_TEMP, "temp3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm83_temp}, ++ {LM83_SYSCTL_REMOTE3_TEMP, "temp4", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm83_temp}, ++ {LM83_SYSCTL_TCRIT, "tcrit", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm83_tcrit}, ++ {LM83_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm83_alarms}, ++ {0} ++}; ++ ++/* ++ * Internal variables ++ */ ++ ++static int lm83_id = 0; ++ ++/* ++ * Real code ++ */ ++ ++static int lm83_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, lm83_detect); ++} ++ ++/* ++ * The following function does more than just detection. If detection ++ * succeeds, it also registers the new chip. ++ */ ++static int lm83_detect(struct i2c_adapter *adapter, int address, unsigned ++ short flags, int kind) ++{ ++ struct i2c_client *new_client; ++ struct lm83_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) ++ { ++ printk("lm83.o: Called for an ISA bus adapter, aborting.\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ { ++#ifdef DEBUG ++ printk("lm83.o: I2C bus doesn't support byte read mode, " ++ "skipping.\n"); ++#endif ++ return 0; ++ } ++ ++ if (!(data = kmalloc(sizeof(struct lm83_data), GFP_KERNEL))) ++ { ++ printk("lm83.o: Out of memory in lm83_detect (new_client).\n"); ++ return -ENOMEM; ++ } ++ ++ /* ++ * The common I2C client data is placed right before the ++ * LM83-specific data. The LM83-specific data is pointed to by the ++ * data field from the I2C client data. ++ */ ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &lm83_driver; ++ new_client->flags = 0; ++ ++ /* ++ * Now we do the remaining detection. A negative kind means that ++ * the driver was loaded with no force parameter (default), so we ++ * must both detect and identify the chip (actually there is only ++ * one possible kind of chip for now, LM83). A zero kind means that ++ * the driver was loaded with the force parameter, the detection ++ * step shall be skipped. A positive kind means that the driver ++ * was loaded with the force parameter and a given kind of chip is ++ * requested, so both the detection and the identification steps ++ * are skipped. ++ */ ++ ++ /* Default to an LM83 if forced */ ++ if (kind == 0) ++ kind = lm83; ++ ++ if (kind < 0) /* detection */ ++ { ++ if (((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS1) ++ & 0xA8) != 0x00) ++ || ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS2) ++ & 0x48) != 0x00) ++ || ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_CONFIG) ++ & 0x41) != 0x00)) ++ { ++#ifdef DEBUG ++ printk(KERN_DEBUG "lm83.o: Detection failed at 0x%02x.\n", ++ address); ++#endif ++ goto ERROR1; ++ } ++ } ++ ++ if (kind <= 0) /* identification */ ++ { ++ u8 man_id, chip_id; ++ ++ man_id = i2c_smbus_read_byte_data(new_client, LM83_REG_R_MAN_ID); ++ chip_id = i2c_smbus_read_byte_data(new_client, LM83_REG_R_CHIP_ID); ++ if (man_id == 0x01) /* National Semiconductor */ ++ { ++ if (chip_id == 0x03) ++ kind = lm83; ++ } ++ } ++ ++ if (kind <= 0) /* identification failed */ ++ { ++ printk("lm83.o: Unsupported chip.\n"); ++ goto ERROR1; ++ } ++ ++ if (kind == lm83) ++ { ++ type_name = "lm83"; ++ client_name = "LM83 chip"; ++ } ++ else ++ { ++ printk("lm83.o: Unknown kind %d.\n", kind); ++ goto ERROR1; ++ } ++ ++ /* ++ * OK, we got a valid chip so we can fill in the remaining client ++ * fields. ++ */ ++ ++ strcpy(new_client->name, client_name); ++ new_client->id = lm83_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* ++ * Tell the I2C layer a new client has arrived. ++ */ ++ ++ if ((err = i2c_attach_client(new_client))) ++ { ++#ifdef DEBUG ++ printk("lm83.o: Failed attaching client.\n"); ++#endif ++ goto ERROR1; ++ } ++ ++ /* ++ * Register a new directory entry. ++ */ ++ ++ if ((err = i2c_register_entry(new_client, type_name, ++ lm83_dir_table_template)) < 0) ++ { ++#ifdef DEBUG ++ printk("lm83.o: Failed registering directory entry.\n"); ++#endif ++ goto ERROR2; ++ } ++ data->sysctl_id = err; ++ ++ /* ++ * Initialize the LM83 chip ++ * (Nothing to do for this one.) ++ */ ++ ++ return 0; ++ ++ ERROR2: ++ i2c_detach_client(new_client); ++ ERROR1: ++ kfree(data); ++ return err; ++} ++ ++static int lm83_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct lm83_data *) (client->data))->sysctl_id); ++ if ((err = i2c_detach_client(client))) ++ { ++ printk("lm83.o: Client deregistration failed, client not " ++ "detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ return 0; ++} ++ ++static void lm83_update_client(struct i2c_client *client) ++{ ++ struct lm83_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ * 2) || ++ (jiffies < data->last_updated) || !data->valid) ++ { ++ int nr; ++#ifdef DEBUG ++ printk("lm83.o: Updating LM83 data.\n"); ++#endif ++ for (nr = 0; nr < 4 ; nr++) ++ { ++ data->temp[nr] = ++ i2c_smbus_read_byte_data(client, LM83_REG_R_TEMP[nr]); ++ data->temp_high[nr] = ++ i2c_smbus_read_byte_data(client, LM83_REG_R_HIGH[nr]); ++ } ++ data->tcrit = i2c_smbus_read_byte_data(client, LM83_REG_R_TCRIT); ++ data->alarms = ++ i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS1) + ++ (i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS2) << 8); ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++static void lm83_temp(struct i2c_client *client, int operation, int ++ ctl_name, int *nrels_mag, long *results) ++{ ++ struct lm83_data *data = client->data; ++ int nr = ctl_name - LM83_SYSCTL_LOCAL_TEMP; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; /* magnitude */ ++ else if (operation == SENSORS_PROC_REAL_READ) ++ { ++ lm83_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_high[nr]); ++ results[1] = TEMP_FROM_REG(data->temp[nr]); ++ *nrels_mag = 2; ++ } ++ else if (operation == SENSORS_PROC_REAL_WRITE) ++ { ++ if (*nrels_mag >= 1) ++ { ++ data->temp_high[nr] = TEMP_TO_REG(results[0]); ++ i2c_smbus_write_byte_data(client, LM83_REG_W_HIGH[nr], ++ data->temp_high[nr]); ++ } ++ } ++} ++ ++static void lm83_tcrit(struct i2c_client *client, int operation, int ++ ctl_name, int *nrels_mag, long *results) ++{ ++ struct lm83_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; /* magnitude */ ++ else if (operation == SENSORS_PROC_REAL_READ) ++ { ++ lm83_update_client(client); ++ results[0] = TEMP_FROM_REG(data->tcrit); ++ *nrels_mag = 1; ++ } ++ else if (operation == SENSORS_PROC_REAL_WRITE) ++ { ++ if (*nrels_mag >= 1) ++ { ++ data->tcrit = TEMP_TO_REG(results[0]); ++ i2c_smbus_write_byte_data(client, LM83_REG_W_TCRIT, ++ data->tcrit); ++ } ++ } ++} ++ ++static void lm83_alarms(struct i2c_client *client, int operation, int ++ ctl_name, int *nrels_mag, long *results) ++{ ++ struct lm83_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; /* magnitude */ ++ else if (operation == SENSORS_PROC_REAL_READ) ++ { ++ lm83_update_client(client); ++ results[0] = data->alarms; ++ *nrels_mag = 1; ++ } ++} ++ ++static int __init sm_lm83_init(void) ++{ ++ printk(KERN_INFO "lm83.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&lm83_driver); ++} ++ ++static void __exit sm_lm83_exit(void) ++{ ++ i2c_del_driver(&lm83_driver); ++} ++ ++MODULE_AUTHOR("Jean Delvare "); ++MODULE_DESCRIPTION("LM83 sensor driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_lm83_init); ++module_exit(sm_lm83_exit); +--- linux-old/drivers/sensors/lm85.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/lm85.c Mon Dec 13 20:18:49 2004 +@@ -0,0 +1,2043 @@ ++/* ++ lm85.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard ++ Copyright (c) 2002, 2003 Philip Pokorny ++ Copyright (c) 2003 Margit Schubert-While ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ CHANGELOG ++ ++ 2002-11-13 First patch for LM85 functionality ++ 2002-11-18 LM85 functionality mostly done ++ 2002-12-02 Adding ADM1027 functionality ++ 2002-12-06 Adding ADT7463 functionality ++ 2003-01-09 Code cleanup. ++ Save reserved bits in case they are implemented ++ in a future chip. (Solve problem with lockups ++ on ADM1027 due to chip initialization) ++ Added chip initialization bypass option ++ 2003-02-12 Add THERM asserted counts for ADT7463 ++ Added #ifdef so we can compile against 2.6.5 ++ without updating i2c-ids.h ++ 2003-02-17 Prepare for switch to 2.7.0 development ++ Implement tmin_control for ADT7463 ++ Expose THERM asserted counts to /proc ++ Code cleanup ++ 2003-02-19 Working with Margit and LM_SENSORS developers ++ 2003-02-23 Removed chip initialization entirely ++ Scale voltages in driver at Margit's request ++ Change PWM from 0-100% to 0-255 per LM sensors standard ++ 2003-02-27 Documentation and code cleanups ++ Added this CHANGELOG ++ Print additional precision for temperatures and voltages ++ Many thanks to Margit Schubert-While and Brandt xxxxxx ++ for help testing this version ++ 2003-02-28 More diagnostic messages regarding BIOS setup ++ 2003-03-01 Added Interrupt mask register support. ++ 2003-03-08 Fixed problem with pseudo 16-bit registers ++ Cleaned up some compiler warnings. ++ Fixed problem with Operating Point and THERM counting ++ 2003-03-21 Initial support for EMC6D100 and EMC6D101 chips ++ 2003-06-30 Add support for EMC6D100 extra voltage inputs. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++ ++#ifndef I2C_DRIVERID_LM85 ++#define I2C_DRIVERID_LM85 1039 ++#endif ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_5(lm85b, lm85c, adm1027, adt7463, emc6d100); ++ ++/* Many LM85 constants specified below */ ++ ++/* The LM85 registers */ ++#define LM85_REG_IN(nr) (0x20 + (nr)) ++#define LM85_REG_IN_MIN(nr) (0x44 + (nr) * 2) ++#define LM85_REG_IN_MAX(nr) (0x45 + (nr) * 2) ++ ++#define LM85_REG_TEMP(nr) (0x25 + (nr)) ++#define LM85_REG_TEMP_MIN(nr) (0x4e + (nr) * 2) ++#define LM85_REG_TEMP_MAX(nr) (0x4f + (nr) * 2) ++ ++/* Fan speeds are LSB, MSB (2 bytes) */ ++#define LM85_REG_FAN(nr) (0x28 + (nr) *2) ++#define LM85_REG_FAN_MIN(nr) (0x54 + (nr) *2) ++ ++#define LM85_REG_PWM(nr) (0x30 + (nr)) ++ ++#define ADT7463_REG_OPPOINT(nr) (0x33 + (nr)) ++ ++#define ADT7463_REG_TMIN_CTL1 0x36 ++#define ADT7463_REG_TMIN_CTL2 0x37 ++#define ADT7463_REG_TMIN_CTL 0x0136 ++ ++#define LM85_REG_DEVICE 0x3d ++#define LM85_REG_COMPANY 0x3e ++#define LM85_REG_VERSTEP 0x3f ++/* These are the recognized values for the above regs */ ++#define LM85_DEVICE_ADX 0x27 ++#define LM85_COMPANY_NATIONAL 0x01 ++#define LM85_COMPANY_ANALOG_DEV 0x41 ++#define LM85_COMPANY_SMSC 0x5c ++#define LM85_VERSTEP_VMASK 0xf0 ++#define LM85_VERSTEP_SMASK 0x0f ++#define LM85_VERSTEP_GENERIC 0x60 ++#define LM85_VERSTEP_LM85C 0x60 ++#define LM85_VERSTEP_LM85B 0x62 ++#define LM85_VERSTEP_ADM1027 0x60 ++#define LM85_VERSTEP_ADT7463 0x62 ++#define LM85_VERSTEP_EMC6D100_A0 0x60 ++#define LM85_VERSTEP_EMC6D100_A1 0x61 ++ ++#define LM85_REG_CONFIG 0x40 ++ ++#define LM85_REG_ALARM1 0x41 ++#define LM85_REG_ALARM2 0x42 ++#define LM85_REG_ALARM 0x0141 ++ ++#define LM85_REG_VID 0x43 ++ ++/* Automated FAN control */ ++#define LM85_REG_AFAN_CONFIG(nr) (0x5c + (nr)) ++#define LM85_REG_AFAN_RANGE(nr) (0x5f + (nr)) ++#define LM85_REG_AFAN_SPIKE1 0x62 ++#define LM85_REG_AFAN_SPIKE2 0x63 ++#define LM85_REG_AFAN_MINPWM(nr) (0x64 + (nr)) ++#define LM85_REG_AFAN_LIMIT(nr) (0x67 + (nr)) ++#define LM85_REG_AFAN_CRITICAL(nr) (0x6a + (nr)) ++#define LM85_REG_AFAN_HYST1 0x6d ++#define LM85_REG_AFAN_HYST2 0x6e ++ ++#define LM85_REG_TACH_MODE 0x74 ++#define LM85_REG_SPINUP_CTL 0x75 ++ ++#define ADM1027_REG_TEMP_OFFSET(nr) (0x70 + (nr)) ++#define ADM1027_REG_CONFIG2 0x73 ++#define ADM1027_REG_INTMASK1 0x74 ++#define ADM1027_REG_INTMASK2 0x75 ++#define ADM1027_REG_INTMASK 0x0174 ++#define ADM1027_REG_EXTEND_ADC1 0x76 ++#define ADM1027_REG_EXTEND_ADC2 0x77 ++#define ADM1027_REG_EXTEND_ADC 0x0176 ++#define ADM1027_REG_CONFIG3 0x78 ++#define ADM1027_REG_FAN_PPR 0x7b ++ ++#define ADT7463_REG_THERM 0x79 ++#define ADT7463_REG_THERM_LIMIT 0x7A ++#define ADT7463_REG_CONFIG4 0x7D ++ ++#define EMC6D100_REG_SFR 0x7c ++#define EMC6D100_REG_ALARM3 0x7d ++#define EMC6D100_REG_CONF 0x7f ++#define EMC6D100_REG_INT_EN 0x80 ++/* IN5, IN6 and IN7 */ ++#define EMC6D100_REG_IN(nr) (0x70 + ((nr)-5)) ++#define EMC6D100_REG_IN_MIN(nr) (0x73 + ((nr)-5) * 2) ++#define EMC6D100_REG_IN_MAX(nr) (0x74 + ((nr)-5) * 2) ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ */ ++ ++/* IN are scaled 1.000 == 0xc0, mag = 3 */ ++#define IN_TO_REG(val) (SENSORS_LIMIT((((val)*0xc0+500)/1000),0,255)) ++#define INEXT_FROM_REG(val,ext) (((val)*1000 + (ext)*250 + 96)/0xc0) ++#define IN_FROM_REG(val) (INEXT_FROM_REG(val,0)) ++ ++/* IN are scaled acording to built-in resistors */ ++static int lm85_scaling[] = { /* .001 Volts */ ++ 2500, 2250, 3300, 5000, 12000, ++ 3300, 1500, 1800, /* EMC6D100 */ ++ }; ++#define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from)) ++#define INS_TO_REG(n,val) (SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255)) ++#define INSEXT_FROM_REG(n,val,ext) (SCALE((val)*4 + (ext),192*4,lm85_scaling[n])) ++#define INS_FROM_REG(n,val) (INSEXT_FROM_REG(n,val,0)) ++ ++/* FAN speed is measured using 90kHz clock */ ++#define FAN_TO_REG(val) (SENSORS_LIMIT( (val)<=0?0: 5400000/(val),0,65534)) ++#define FAN_FROM_REG(val) ((val)==0?-1:(val)==0xffff?0:5400000/(val)) ++ ++/* Temperature is reported in .01 degC increments */ ++#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)+50)/100,-127,127)) ++#define TEMPEXT_FROM_REG(val,ext) ((val)*100 + (ext)*25) ++#define TEMP_FROM_REG(val) (TEMPEXT_FROM_REG(val,0)) ++#define EXTTEMP_TO_REG(val) (SENSORS_LIMIT((val)/25,-127,127)) ++#define OPPOINT_TO_REG(val) (SENSORS_LIMIT(val,-127,127)) ++#define OPPOINT_FROM_REG(val) (val) ++ ++#define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255)) ++#define PWM_FROM_REG(val) (val) ++ ++#define EXT_FROM_REG(val,sensor) (((val)>>(sensor * 2))&0x03) ++ ++/* ZONEs have the following parameters: ++ * Limit (low) temp, 1. degC ++ * Hysteresis (below limit), 1. degC (0-15) ++ * Range of speed control, .1 degC (2-80) ++ * Critical (high) temp, 1. degC ++ * ++ * FAN PWMs have the following parameters: ++ * Reference Zone, 1, 2, 3, etc. ++ * Spinup time, .05 sec ++ * PWM value at limit/low temp, 1 count ++ * PWM Frequency, 1. Hz ++ * PWM is Min or OFF below limit, flag ++ * Invert PWM output, flag ++ * ++ * Some chips filter the temp, others the fan. ++ * Filter constant (or disabled) .1 seconds ++ */ ++ ++/* These are the zone temperature range encodings */ ++static int lm85_range_map[] = { /* .1 degC */ ++ 20, 25, 33, 40, 50, 66, ++ 80, 100, 133, 160, 200, 266, ++ 320, 400, 533, 800 ++ }; ++static int RANGE_TO_REG( int range ) ++{ ++ int i; ++ ++ if( range >= lm85_range_map[15] ) { return 15 ; } ++ for( i = 0 ; i < 15 ; ++i ) ++ if( range <= lm85_range_map[i] ) ++ break ; ++ return( i & 0x0f ); ++} ++#define RANGE_FROM_REG(val) (lm85_range_map[(val)&0x0f]) ++ ++/* These are the Acoustic Enhancement, or Temperature smoothing encodings ++ * NOTE: The enable/disable bit is INCLUDED in these encodings as the ++ * MSB (bit 3, value 8). If the enable bit is 0, the encoded value ++ * is ignored, or set to 0. ++ */ ++static int lm85_smooth_map[] = { /* .1 sec */ ++ 350, 176, 118, 70, 44, 30, 16, 8 ++/* 35.4 * 1/1, 1/2, 1/3, 1/5, 1/8, 1/12, 1/24, 1/48 */ ++ }; ++static int SMOOTH_TO_REG( int smooth ) ++{ ++ int i; ++ ++ if( smooth <= 0 ) { return 0 ; } /* Disabled */ ++ for( i = 0 ; i < 7 ; ++i ) ++ if( smooth >= lm85_smooth_map[i] ) ++ break ; ++ return( (i & 0x07) | 0x08 ); ++} ++#define SMOOTH_FROM_REG(val) ((val)&0x08?lm85_smooth_map[(val)&0x07]:0) ++ ++/* These are the fan spinup delay time encodings */ ++static int lm85_spinup_map[] = { /* .1 sec */ ++ 0, 1, 2, 4, 7, 10, 20, 40 ++ }; ++static int SPINUP_TO_REG( int spinup ) ++{ ++ int i; ++ ++ if( spinup >= lm85_spinup_map[7] ) { return 7 ; } ++ for( i = 0 ; i < 7 ; ++i ) ++ if( spinup <= lm85_spinup_map[i] ) ++ break ; ++ return( i & 0x07 ); ++} ++#define SPINUP_FROM_REG(val) (lm85_spinup_map[(val)&0x07]) ++ ++/* These are the PWM frequency encodings */ ++static int lm85_freq_map[] = { /* .1 Hz */ ++ 100, 150, 230, 300, 380, 470, 620, 980 ++ }; ++static int FREQ_TO_REG( int freq ) ++{ ++ int i; ++ ++ if( freq >= lm85_freq_map[7] ) { return 7 ; } ++ for( i = 0 ; i < 7 ; ++i ) ++ if( freq <= lm85_freq_map[i] ) ++ break ; ++ return( i & 0x07 ); ++} ++#define FREQ_FROM_REG(val) (lm85_freq_map[(val)&0x07]) ++ ++/* Since we can't use strings, I'm abusing these numbers ++ * to stand in for the following meanings: ++ * 1 -- PWM responds to Zone 1 ++ * 2 -- PWM responds to Zone 2 ++ * 3 -- PWM responds to Zone 3 ++ * 23 -- PWM responds to the higher temp of Zone 2 or 3 ++ * 123 -- PWM responds to highest of Zone 1, 2, or 3 ++ * 0 -- PWM is always at 0% (ie, off) ++ * -1 -- PWM is always at 100% ++ * -2 -- PWM responds to manual control ++ */ ++static int lm85_zone_map[] = { 1, 2, 3, -1, 0, 23, 123, -2 }; ++static int ZONE_TO_REG( int zone ) ++{ ++ int i; ++ ++ for( i = 0 ; i <= 7 ; ++i ) ++ if( zone == lm85_zone_map[i] ) ++ break ; ++ if( i > 7 ) /* Not found. */ ++ i = 3; /* Always 100% */ ++ return( (i & 0x07)<<5 ); ++} ++#define ZONE_FROM_REG(val) (lm85_zone_map[((val)>>5)&0x07]) ++ ++#define HYST_TO_REG(val) (SENSORS_LIMIT((-(val)+5)/10,0,15)) ++#define HYST_FROM_REG(val) (-(val)*10) ++ ++#define OFFSET_TO_REG(val) (SENSORS_LIMIT((val)/25,-127,127)) ++#define OFFSET_FROM_REG(val) ((val)*25) ++ ++#define PPR_MASK(fan) (0x03<<(fan *2)) ++#define PPR_TO_REG(val,fan) (SENSORS_LIMIT((val)-1,0,3)<<(fan *2)) ++#define PPR_FROM_REG(val,fan) ((((val)>>(fan * 2))&0x03)+1) ++ ++/* sensors_vid.h defines vid_from_reg() */ ++#define VID_FROM_REG(val,vrm) (vid_from_reg((val),(vrm))) ++ ++#define ALARMS_FROM_REG(val) (val) ++ ++/* When converting to REG, we need to fixup the carry-over bit */ ++#define INTMASK_FROM_REG(val) (val) ++#define INTMASK_TO_REG(val) (SENSORS_LIMIT((val)|((val)&0xff00?0x80:0),0,65535)) ++ ++/* Unlike some other drivers we DO NOT set initial limits. Use ++ * the config file to set limits. Some users have reported ++ * motherboards shutting down when we set limits in a previous ++ * version of this driver. This may be caused by APM/ACPI ++ * detecting an out-of-limit condition when we had the wrong ++ * limits set. ++ */ ++ ++/* Typically used with Pentium 4 systems v9.1 VRM spec */ ++#define LM85_INIT_VRM 91 ++ ++/* Chip sampling rates ++ * ++ * Some sensors are not updated more frequently than once per second ++ * so it doesn't make sense to read them more often than that. ++ * We cache the results and return the saved data if the driver ++ * is called again before a second has elapsed. ++ * ++ * Also, there is significant configuration data for this chip ++ * given the automatic PWM fan control that is possible. There ++ * are about 47 bytes of config data to only 22 bytes of actual ++ * readings. So, we keep the config data up to date in the cache ++ * when it is written and only sample it once every 5 *minutes* ++ */ ++#define LM85_DATA_INTERVAL (1 * HZ) ++#define LM85_CONFIG_INTERVAL (5 * 60 * HZ) ++ ++/* For each registered LM85, we need to keep some data in memory. That ++ data is pointed to by client->data. The structure itself is ++ dynamically allocated, when a new lm85 client is allocated. */ ++ ++/* LM85 can automatically adjust fan speeds based on temperature ++ * This structure encapsulates an entire Zone config. There are ++ * three zones (one for each temperature input) on the lm85 ++ */ ++struct lm85_zone { ++ s8 limit; /* Low temp limit */ ++ u8 hyst; /* Low limit hysteresis. (0-15) */ ++ u8 range; /* Temp range, encoded */ ++ s8 critical; /* "All fans ON" temp limit */ ++}; ++ ++struct lm85_autofan { ++ u8 config; /* Register value */ ++ u8 freq; /* PWM frequency, encoded */ ++ u8 min_pwm; /* Minimum PWM value, encoded */ ++ u8 min_off; /* Min PWM or OFF below "limit", flag */ ++}; ++ ++struct lm85_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ int valid; /* !=0 if following fields are valid */ ++ unsigned long last_reading; /* In jiffies */ ++ unsigned long last_config; /* In jiffies */ ++ ++ u8 in[8]; /* Register value */ ++ u8 in_max[8]; /* Register value */ ++ u8 in_min[8]; /* Register value */ ++ s8 temp[3]; /* Register value */ ++ s8 temp_min[3]; /* Register value */ ++ s8 temp_max[3]; /* Register value */ ++ s8 temp_offset[3]; /* Register value */ ++ u16 fan[4]; /* Register value */ ++ u16 fan_min[4]; /* Register value */ ++ u8 pwm[3]; /* Register value */ ++ u8 spinup_ctl; /* Register encoding, combined */ ++ u8 tach_mode; /* Register encoding, combined */ ++ u16 extend_adc; /* Register value */ ++ u8 fan_ppr; /* Register value */ ++ u8 smooth[3]; /* Register encoding */ ++ u8 vid; /* Register value */ ++ u8 vrm; /* VRM version */ ++ u8 syncpwm3; /* Saved PWM3 for TACH 2,3,4 config */ ++ s8 oppoint[3]; /* Register value */ ++ u16 tmin_ctl; /* Register value */ ++ long therm_total; /* Cummulative therm count */ ++ long therm_ovfl; /* Count of therm overflows */ ++ u8 therm_limit; /* Register value */ ++ u32 alarms; /* Register encoding, combined */ ++ u32 alarm_mask; /* Register encoding, combined */ ++ struct lm85_autofan autofan[3]; ++ struct lm85_zone zone[3]; ++}; ++ ++static int lm85_attach_adapter(struct i2c_adapter *adapter); ++static int lm85_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int lm85_detach_client(struct i2c_client *client); ++static int lm85_read_value(struct i2c_client *client, u16 register); ++static int lm85_write_value(struct i2c_client *client, u16 register, int value); ++static void lm85_update_client(struct i2c_client *client); ++static void lm85_init_client(struct i2c_client *client); ++ ++ ++static void lm85_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++static void lm85_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm85_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm85_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm85_vrm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm85_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm85_pwm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm85_zone(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm85_pwm_config(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm85_pwm_zone(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm85_smooth(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static void lm85_spinup_ctl(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm85_tach_mode(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static void adm1027_tach_mode(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1027_temp_offset(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1027_fan_ppr(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adm1027_alarm_mask(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static void adt7463_tmin_ctl(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void adt7463_therm_signal(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static void emc6d100_in(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static struct i2c_driver lm85_driver = { ++ .owner = THIS_MODULE, ++ .name = "LM85 compatible sensor driver", ++ .id = I2C_DRIVERID_LM85, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = &lm85_attach_adapter, ++ .detach_client = &lm85_detach_client, ++}; ++ ++/* Unique ID assigned to each LM85 detected */ ++static int lm85_id = 0; ++ ++/* -- SENSORS SYSCTL START -- */ ++/* Common parameters */ ++#define LM85_SYSCTL_IN0 1000 ++#define LM85_SYSCTL_IN1 1001 ++#define LM85_SYSCTL_IN2 1002 ++#define LM85_SYSCTL_IN3 1003 ++#define LM85_SYSCTL_IN4 1004 ++#define LM85_SYSCTL_FAN1 1005 ++#define LM85_SYSCTL_FAN2 1006 ++#define LM85_SYSCTL_FAN3 1007 ++#define LM85_SYSCTL_FAN4 1008 ++#define LM85_SYSCTL_TEMP1 1009 ++#define LM85_SYSCTL_TEMP2 1010 ++#define LM85_SYSCTL_TEMP3 1011 ++#define LM85_SYSCTL_VID 1012 ++#define LM85_SYSCTL_ALARMS 1013 ++#define LM85_SYSCTL_PWM1 1014 ++#define LM85_SYSCTL_PWM2 1015 ++#define LM85_SYSCTL_PWM3 1016 ++#define LM85_SYSCTL_VRM 1017 ++#define LM85_SYSCTL_PWM_CFG1 1019 ++#define LM85_SYSCTL_PWM_CFG2 1020 ++#define LM85_SYSCTL_PWM_CFG3 1021 ++#define LM85_SYSCTL_PWM_ZONE1 1022 ++#define LM85_SYSCTL_PWM_ZONE2 1023 ++#define LM85_SYSCTL_PWM_ZONE3 1024 ++#define LM85_SYSCTL_ZONE1 1025 ++#define LM85_SYSCTL_ZONE2 1026 ++#define LM85_SYSCTL_ZONE3 1027 ++#define LM85_SYSCTL_SMOOTH1 1028 ++#define LM85_SYSCTL_SMOOTH2 1029 ++#define LM85_SYSCTL_SMOOTH3 1030 ++ ++/* Vendor specific values */ ++#define LM85_SYSCTL_SPINUP_CTL 1100 ++#define LM85_SYSCTL_TACH_MODE 1101 ++ ++/* Analog Devices variant of the LM85 */ ++#define ADM1027_SYSCTL_TACH_MODE 1200 ++#define ADM1027_SYSCTL_TEMP_OFFSET1 1201 ++#define ADM1027_SYSCTL_TEMP_OFFSET2 1202 ++#define ADM1027_SYSCTL_TEMP_OFFSET3 1203 ++#define ADM1027_SYSCTL_FAN_PPR 1204 ++#define ADM1027_SYSCTL_ALARM_MASK 1205 ++ ++/* Analog Devices variant of the LM85/ADM1027 */ ++#define ADT7463_SYSCTL_TMIN_CTL1 1300 ++#define ADT7463_SYSCTL_TMIN_CTL2 1301 ++#define ADT7463_SYSCTL_TMIN_CTL3 1302 ++#define ADT7463_SYSCTL_THERM_SIGNAL 1303 ++ ++/* SMSC variant of the LM85 */ ++#define EMC6D100_SYSCTL_IN5 1400 ++#define EMC6D100_SYSCTL_IN6 1401 ++#define EMC6D100_SYSCTL_IN7 1402 ++ ++#define LM85_ALARM_IN0 0x0001 ++#define LM85_ALARM_IN1 0x0002 ++#define LM85_ALARM_IN2 0x0004 ++#define LM85_ALARM_IN3 0x0008 ++#define LM85_ALARM_TEMP1 0x0010 ++#define LM85_ALARM_TEMP2 0x0020 ++#define LM85_ALARM_TEMP3 0x0040 ++#define LM85_ALARM_ALARM2 0x0080 ++#define LM85_ALARM_IN4 0x0100 ++#define LM85_ALARM_RESERVED 0x0200 ++#define LM85_ALARM_FAN1 0x0400 ++#define LM85_ALARM_FAN2 0x0800 ++#define LM85_ALARM_FAN3 0x1000 ++#define LM85_ALARM_FAN4 0x2000 ++#define LM85_ALARM_TEMP1_FAULT 0x4000 ++#define LM85_ALARM_TEMP3_FAULT 0x08000 ++#define LM85_ALARM_IN6 0x10000 ++#define LM85_ALARM_IN7 0x20000 ++#define LM85_ALARM_IN5 0x40000 ++/* -- SENSORS SYSCTL END -- */ ++ ++/* The /proc/sys entries */ ++/* These files are created for each detected LM85. This is just a template; ++ * The actual list is built from this and additional per-chip ++ * custom lists below. Note the XXX_LEN macros. These must be ++ * compile time constants because they will be used to allocate ++ * space for the final template passed to i2c_register_entry. ++ * We depend on the ability of GCC to evaluate expressions at ++ * compile time to turn these expressions into compile time ++ * constants, but this can generate a warning. ++ */ ++static ctl_table lm85_common[] = { ++ {LM85_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_in}, ++ {LM85_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_in}, ++ {LM85_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_in}, ++ {LM85_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_in}, ++ {LM85_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_in}, ++ {LM85_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_fan}, ++ {LM85_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_fan}, ++ {LM85_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_fan}, ++ {LM85_SYSCTL_FAN4, "fan4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_fan}, ++ {LM85_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_temp}, ++ {LM85_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_temp}, ++ {LM85_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_temp}, ++ {LM85_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_vid}, ++ {LM85_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_vrm}, ++ {LM85_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_alarms}, ++ {LM85_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_pwm}, ++ {LM85_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_pwm}, ++ {LM85_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_pwm}, ++ {LM85_SYSCTL_PWM_CFG1, "pwm1_cfg", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_pwm_config}, ++ {LM85_SYSCTL_PWM_CFG2, "pwm2_cfg", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_pwm_config}, ++ {LM85_SYSCTL_PWM_CFG3, "pwm3_cfg", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_pwm_config}, ++ {LM85_SYSCTL_PWM_ZONE1, "pwm1_zone", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm85_pwm_zone}, ++ {LM85_SYSCTL_PWM_ZONE2, "pwm2_zone", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm85_pwm_zone}, ++ {LM85_SYSCTL_PWM_ZONE3, "pwm3_zone", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm85_pwm_zone}, ++ {LM85_SYSCTL_ZONE1, "zone1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_zone}, ++ {LM85_SYSCTL_ZONE2, "zone2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_zone}, ++ {LM85_SYSCTL_ZONE3, "zone3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_zone}, ++ {LM85_SYSCTL_SMOOTH1, "smooth1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_smooth}, ++ {LM85_SYSCTL_SMOOTH2, "smooth2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_smooth}, ++ {LM85_SYSCTL_SMOOTH3, "smooth3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm85_smooth}, ++ {0} ++}; ++#define CTLTBL_COMMON (sizeof(lm85_common)/sizeof(lm85_common[0])) ++ ++/* NOTE: tach_mode is a shared name, but implemented with ++ * different functions ++ */ ++static ctl_table lm85_specific[] = { ++ {LM85_SYSCTL_SPINUP_CTL, "spinup_ctl", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm85_spinup_ctl}, ++ {LM85_SYSCTL_TACH_MODE, "tach_mode", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm85_tach_mode}, ++/* {0} The doc generator needs this. */ ++}; ++#define CTLTBL_LM85 (sizeof(lm85_specific)/sizeof(lm85_specific[0])) ++ ++static ctl_table adm1027_specific[] = { ++ {ADM1027_SYSCTL_TACH_MODE, "tach_mode", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1027_tach_mode}, ++ {ADM1027_SYSCTL_TEMP_OFFSET1, "temp1_offset", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1027_temp_offset}, ++ {ADM1027_SYSCTL_TEMP_OFFSET2, "temp2_offset", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1027_temp_offset}, ++ {ADM1027_SYSCTL_TEMP_OFFSET3, "temp3_offset", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1027_temp_offset}, ++ {ADM1027_SYSCTL_FAN_PPR, "fan_ppr", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1027_fan_ppr}, ++ {ADM1027_SYSCTL_ALARM_MASK, "alarm_mask", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adm1027_alarm_mask}, ++/* {0} The doc generator needs this. */ ++}; ++#define CTLTBL_ADM1027 (sizeof(adm1027_specific)/sizeof(adm1027_specific[0])) ++ ++static ctl_table adt7463_specific[] = { ++ {ADT7463_SYSCTL_TMIN_CTL1, "tmin_ctl1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adt7463_tmin_ctl}, ++ {ADT7463_SYSCTL_TMIN_CTL2, "tmin_ctl2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adt7463_tmin_ctl}, ++ {ADT7463_SYSCTL_TMIN_CTL3, "tmin_ctl3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adt7463_tmin_ctl}, ++ {ADT7463_SYSCTL_THERM_SIGNAL, "therm_signal", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &adt7463_therm_signal}, ++/* {0} The doc generator needs this. */ ++}; ++#define CTLTBL_ADT7463 (sizeof(adt7463_specific)/sizeof(adt7463_specific[0])) ++ ++static ctl_table emc6d100_specific[] = { ++ {EMC6D100_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &emc6d100_in}, ++ {EMC6D100_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &emc6d100_in}, ++ {EMC6D100_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &emc6d100_in}, ++/* {0} The doc generator needs this. */ ++}; ++#define CTLTBL_EMC6D100 (sizeof(emc6d100_specific)/sizeof(emc6d100_specific[0])) ++ ++ ++#define MAX2(a,b) ((a)>(b)?(a):(b)) ++#define MAX3(a,b,c) ((a)>(b)?MAX2((a),(c)):MAX2((b),(c))) ++#define MAX4(a,b,c,d) ((a)>(b)?MAX3((a),(c),(d)):MAX3((b),(c),(d))) ++ ++#define CTLTBL_MAX (CTLTBL_COMMON + MAX3(CTLTBL_LM85, CTLTBL_ADM1027+CTLTBL_ADT7463, CTLTBL_EMC6D100)) ++ ++/* This function is called when: ++ * lm85_driver is inserted (when this module is loaded), for each ++ available adapter ++ * when a new adapter is inserted (and lm85_driver is still present) */ ++int lm85_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, lm85_detect); ++} ++ ++/* This function is called by i2c_detect */ ++int lm85_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ int company, verstep ; ++ struct i2c_client *new_client; ++ struct lm85_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ struct ctl_table template[CTLTBL_MAX] ; ++ int template_used ; ++ ++ if (i2c_is_isa_adapter(adapter)) { ++ /* This chip has no ISA interface */ ++ goto ERROR0 ; ++ }; ++ ++ if (!i2c_check_functionality(adapter, ++ I2C_FUNC_SMBUS_BYTE_DATA)) { ++ /* We need to be able to do byte I/O */ ++ goto ERROR0 ; ++ }; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access lm85_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct lm85_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &lm85_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ ++ company = lm85_read_value(new_client, LM85_REG_COMPANY); ++ verstep = lm85_read_value(new_client, LM85_REG_VERSTEP); ++ ++#ifdef DEBUG ++ printk("lm85: Detecting device at %d,0x%02x with" ++ " COMPANY: 0x%02x and VERSTEP: 0x%02x\n", ++ i2c_adapter_id(new_client->adapter), new_client->addr, ++ company, verstep ++ ); ++#endif ++ ++ /* If auto-detecting, Determine the chip type. */ ++ if (kind <= 0) { ++#ifdef DEBUG ++ printk("lm85: Autodetecting device at %d,0x%02x ...\n", ++ i2c_adapter_id(adapter), address ); ++#endif ++ if( company == LM85_COMPANY_NATIONAL ++ && verstep == LM85_VERSTEP_LM85C ) { ++ kind = lm85c ; ++ } else if( company == LM85_COMPANY_NATIONAL ++ && verstep == LM85_VERSTEP_LM85B ) { ++ kind = lm85b ; ++ } else if( company == LM85_COMPANY_NATIONAL ++ && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) { ++ printk("lm85: Detected National Semiconductor chip\n"); ++ printk("lm85: Unrecgonized version/stepping 0x%02x" ++ " Defaulting to Generic LM85.\n", verstep ); ++ kind = any_chip ; ++ } else if( company == LM85_COMPANY_ANALOG_DEV ++ && verstep == LM85_VERSTEP_ADM1027 ) { ++ kind = adm1027 ; ++ } else if( company == LM85_COMPANY_ANALOG_DEV ++ && verstep == LM85_VERSTEP_ADT7463 ) { ++ kind = adt7463 ; ++ } else if( company == LM85_COMPANY_ANALOG_DEV ++ && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) { ++ printk("lm85: Detected Analog Devices chip\n"); ++ printk("lm85: Unrecgonized version/stepping 0x%02x" ++ " Defaulting to Generic LM85.\n", verstep ); ++ kind = any_chip ; ++ } else if( company == LM85_COMPANY_SMSC ++ && (verstep == LM85_VERSTEP_EMC6D100_A0 ++ || verstep == LM85_VERSTEP_EMC6D100_A1) ) { ++ /* Unfortunately, we can't tell a '100 from a '101 ++ * from the registers. Since a '101 is a '100 ++ * in a package with fewer pins and therefore no ++ * 3.3V, 1.5V or 1.8V inputs, perhaps if those ++ * inputs read 0, then it's a '101. ++ */ ++ kind = emc6d100 ; ++ } else if( company == LM85_COMPANY_SMSC ++ && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) { ++ printk("lm85: Detected SMSC chip\n"); ++ printk("lm85: Unrecognized version/stepping 0x%02x" ++ " Defaulting to Generic LM85.\n", verstep ); ++ kind = any_chip ; ++ } else if( kind == any_chip ++ && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) { ++ printk("lm85: Generic LM85 Version 6 detected\n"); ++ /* Leave kind as "any_chip" */ ++ } else { ++#ifdef DEBUG ++ printk("lm85: Autodetection failed\n"); ++#endif ++ /* Not an LM85 ... */ ++ if( kind == any_chip ) { /* User used force=x,y */ ++ printk("lm85: Generic LM85 Version 6 not" ++ " found at %d,0x%02x. Try force_lm85c.\n", ++ i2c_adapter_id(adapter), address ); ++ } ++ err = 0 ; ++ goto ERROR1; ++ } ++ } ++ ++ /* Fill in the chip specific driver values */ ++ switch (kind) { ++ case any_chip : ++ type_name = "lm85"; ++ strcpy(new_client->name, "Generic LM85"); ++ template_used = 0 ; ++ break ; ++ case lm85b : ++ type_name = "lm85b"; ++ strcpy(new_client->name, "National LM85-B"); ++ memcpy( template, lm85_specific, sizeof(lm85_specific) ); ++ template_used = CTLTBL_LM85 ; ++ break ; ++ case lm85c : ++ type_name = "lm85c"; ++ strcpy(new_client->name, "National LM85-C"); ++ memcpy( template, lm85_specific, sizeof(lm85_specific) ); ++ template_used = CTLTBL_LM85 ; ++ break ; ++ case adm1027 : ++ type_name = "adm1027"; ++ strcpy(new_client->name, "Analog Devices ADM1027"); ++ memcpy( template, adm1027_specific, sizeof(adm1027_specific) ); ++ template_used = CTLTBL_ADM1027 ; ++ break ; ++ case adt7463 : ++ type_name = "adt7463"; ++ strcpy(new_client->name, "Analog Devices ADT7463"); ++ memcpy( template, adt7463_specific, sizeof(adt7463_specific) ); ++ template_used = CTLTBL_ADT7463 ; ++ memcpy( template+template_used, adm1027_specific, sizeof(adm1027_specific) ); ++ template_used += CTLTBL_ADM1027 ; ++ break ; ++ case emc6d100 : ++ type_name = "emc6d100"; ++ strcpy(new_client->name, "SMSC EMC6D100"); ++ memcpy(template, emc6d100_specific, sizeof(emc6d100_specific)); ++ template_used = CTLTBL_EMC6D100 ; ++ break ; ++ default : ++ printk("lm85: Internal error, invalid kind (%d)!", kind); ++ err = -EFAULT ; ++ goto ERROR1; ++ } ++ ++ /* Fill in the remaining client fields */ ++ new_client->id = lm85_id++; ++ printk("lm85: Assigning ID %d to %s at %d,0x%02x\n", ++ new_client->id, new_client->name, ++ i2c_adapter_id(new_client->adapter), ++ new_client->addr ++ ); ++ ++ /* Housekeeping values */ ++ data->type = kind; ++ data->valid = 0; ++ ++ /* Set the VRM version */ ++ data->vrm = LM85_INIT_VRM ; ++ ++ /* Zero the accumulators */ ++ data->therm_total = 0; ++ data->therm_ovfl = 0; ++ ++ init_MUTEX(&data->update_lock); ++ ++ /* Initialize the LM85 chip */ ++ lm85_init_client(new_client); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR1; ++ ++ /* Finish out the template */ ++ memcpy( template + template_used, lm85_common, sizeof(lm85_common) ); ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, ++ type_name, ++ template)) < 0) { ++ err = i; ++ goto ERROR2; ++ } ++ data->sysctl_id = i; ++ ++ return 0; ++ ++ /* Error out and cleanup code */ ++ ERROR2: ++ i2c_detach_client(new_client); ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++int lm85_detach_client(struct i2c_client *client) ++{ ++ int err; ++ int id ; ++ ++ id = client->id; ++ i2c_deregister_entry(((struct lm85_data *)(client->data))->sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk("lm85(%d): Client deregistration failed," ++ " client not detached.\n", id ); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++int lm85_read_value(struct i2c_client *client, u16 reg) ++{ ++ int res; ++ ++ /* What size location is it? */ ++ switch( reg ) { ++ case LM85_REG_FAN(0) : /* Read WORD data */ ++ case LM85_REG_FAN(1) : ++ case LM85_REG_FAN(2) : ++ case LM85_REG_FAN(3) : ++ case LM85_REG_FAN_MIN(0) : ++ case LM85_REG_FAN_MIN(1) : ++ case LM85_REG_FAN_MIN(2) : ++ case LM85_REG_FAN_MIN(3) : ++ case LM85_REG_ALARM : /* Read ALARM1 and ALARM2 */ ++ case ADM1027_REG_INTMASK : /* Read MASK1 and MASK2 */ ++ case ADM1027_REG_EXTEND_ADC : /* Read ADC1 and ADC2 */ ++ reg &= 0xff ; /* Pseudo words have address + 0x0100 */ ++ res = i2c_smbus_read_byte_data(client, reg) & 0xff ; ++ res |= (i2c_smbus_read_byte_data(client, reg+1) & 0xff) << 8 ; ++ break ; ++ case ADT7463_REG_TMIN_CTL : /* Read WORD MSB, LSB */ ++ reg &= 0xff ; /* Pseudo words have address + 0x0100 */ ++ res = (i2c_smbus_read_byte_data(client, reg) & 0xff) << 8 ; ++ res |= i2c_smbus_read_byte_data(client, reg+1) & 0xff ; ++ break ; ++ default: /* Read BYTE data */ ++ res = i2c_smbus_read_byte_data(client, reg & 0xff) & 0xff ; ++ break ; ++ } ++ ++ return res ; ++} ++ ++int lm85_write_value(struct i2c_client *client, u16 reg, int value) ++{ ++ int res ; ++ ++ switch( reg ) { ++ case LM85_REG_FAN(0) : /* Write WORD data */ ++ case LM85_REG_FAN(1) : ++ case LM85_REG_FAN(2) : ++ case LM85_REG_FAN(3) : ++ case LM85_REG_FAN_MIN(0) : ++ case LM85_REG_FAN_MIN(1) : ++ case LM85_REG_FAN_MIN(2) : ++ case LM85_REG_FAN_MIN(3) : ++ case ADM1027_REG_INTMASK : ++ /* NOTE: ALARM and ADC are read only, so not included here */ ++ reg &= 0xff ; /* Pseudo words have address + 0x0100 */ ++ res = i2c_smbus_write_byte_data(client, reg, value & 0xff) ; ++ res |= i2c_smbus_write_byte_data(client, reg+1, (value>>8) & 0xff) ; ++ break ; ++ case ADT7463_REG_TMIN_CTL : /* Write WORD MSB, LSB */ ++ reg &= 0xff ; /* Pseudo words have address + 0x0100 */ ++ res = i2c_smbus_write_byte_data(client, reg, (value>>8) & 0xff); ++ res |= i2c_smbus_write_byte_data(client, reg+1, value & 0xff) ; ++ break ; ++ default: /* Write BYTE data */ ++ res = i2c_smbus_write_byte_data(client, reg & 0xff, value); ++ break ; ++ } ++ ++ return res ; ++} ++ ++/* Called when we have found a new LM85. It should set limits, etc. */ ++void lm85_init_client(struct i2c_client *client) ++{ ++ int value; ++ struct lm85_data *data = client->data; ++ ++#ifdef DEBUG ++ printk("lm85(%d): Initializing device\n", client->id); ++#endif ++ ++ /* Warn if part was not "READY" */ ++ value = lm85_read_value(client, LM85_REG_CONFIG); ++#ifdef DEBUG ++ printk("lm85(%d): LM85_REG_CONFIG is: 0x%02x\n", client->id, value ); ++#endif ++ if( value & 0x02 ) { ++ printk("lm85(%d): Client (%d,0x%02x) config is locked.\n", ++ client->id, ++ i2c_adapter_id(client->adapter), client->addr ); ++ }; ++ if( ! (value & 0x04) ) { ++ printk("lm85(%d): Client (%d,0x%02x) is not ready.\n", ++ client->id, ++ i2c_adapter_id(client->adapter), client->addr ); ++ }; ++ if( (data->type == adm1027 || data->type == adt7463) ++ && (value & 0x10) ++ ) { ++ printk("lm85(%d): Client (%d,0x%02x) VxI mode is set. " ++ "Please report this to the lm85 maintainer.\n", ++ client->id, ++ i2c_adapter_id(client->adapter), client->addr ); ++ }; ++ ++ /* See if SYNC to PWM3 is set */ ++ if( data->type == adt7463 ++ && (lm85_read_value(client, LM85_REG_AFAN_SPIKE1) & 0x10) ++ ) { ++ printk("lm85(%d): Sync to PWM3 is set. Expect PWM3 " ++ "to control fans 2, 3, and 4\n", ++ client->id ); ++ }; ++ ++ /* See if PWM2 is #SMBALERT */ ++ if( (data->type == adm1027 || data->type == adt7463) ++ && (lm85_read_value(client, ADM1027_REG_CONFIG3) & 0x01) ++ ) { ++ printk("lm85(%d): PWM2 is SMBALERT. PWM2 not available.\n", ++ client->id ); ++ }; ++ ++ /* Check if 2.5V and 5V inputs are reconfigured */ ++ if( data->type == adt7463 ) { ++ value = lm85_read_value(client, ADT7463_REG_CONFIG4); ++ if( value & 0x01 ) { ++ printk("lm85(%d): 2.5V input (in0) is SMBALERT. " ++ "in0 not available.\n", client->id ); ++ }; ++ if( value & 0x02 ) { ++ printk("lm85(%d): 5V input (in3) is THERM. " ++ "in3 not available.\n", client->id ); ++ } ++ }; ++ ++ /* FIXME? Display EMC6D100 config info? */ ++ ++ /* WE INTENTIONALLY make no changes to the limits, ++ * offsets, pwms, fans and zones. If they were ++ * configured, we don't want to mess with them. ++ * If they weren't, the default is 100% PWM, no ++ * control and will suffice until 'sensors -s' ++ * can be run by the user. ++ */ ++ ++ /* Start monitoring */ ++ value = lm85_read_value(client, LM85_REG_CONFIG); ++ /* Try to clear LOCK, Set START, save everything else */ ++ value = ((value & ~ 0x02) | 0x01) & 0xff ; ++#ifdef DEBUG ++ printk("lm85(%d): Setting CONFIG to: 0x%02x\n", client->id, value ); ++#endif ++ lm85_write_value(client, LM85_REG_CONFIG, value); ++ ++} ++ ++void lm85_update_client(struct i2c_client *client) ++{ ++ struct lm85_data *data = client->data; ++ int i; ++ ++ down(&data->update_lock); ++ ++ if (!data->valid ++ || (jiffies - data->last_reading > LM85_DATA_INTERVAL )) { ++ /* Things that change quickly */ ++ ++#ifdef DEBUG ++ printk("lm85(%d): Reading sensor values\n", client->id); ++#endif ++ /* Have to read extended bits first to "freeze" the ++ * more significant bits that are read later. ++ */ ++ switch( data->type ) { ++ case adm1027 : ++ case adt7463 : ++ data->extend_adc = ++ lm85_read_value(client, ADM1027_REG_EXTEND_ADC); ++ break ; ++ default : ++ data->extend_adc = 0 ; ++ break ; ++ } ++ ++ for (i = 0; i <= 4; ++i) { ++ data->in[i] = ++ lm85_read_value(client, LM85_REG_IN(i)); ++ } ++ ++ for (i = 0; i <= 3; ++i) { ++ data->fan[i] = ++ lm85_read_value(client, LM85_REG_FAN(i)); ++ } ++ ++ for (i = 0; i <= 2; ++i) { ++ data->temp[i] = ++ lm85_read_value(client, LM85_REG_TEMP(i)); ++ } ++ ++ for (i = 0; i <= 2; ++i) { ++ data->pwm[i] = ++ lm85_read_value(client, LM85_REG_PWM(i)); ++ } ++ ++ data->alarms = lm85_read_value(client, LM85_REG_ALARM); ++ ++ switch( ((struct lm85_data *)(client->data))->type ) { ++ case adt7463 : ++ /* REG_THERM code duplicated in therm_signal() */ ++ i = lm85_read_value(client, ADT7463_REG_THERM); ++ if( data->therm_total < LONG_MAX - 256 ) { ++ data->therm_total += i ; ++ } ++ if( i >= 255 ) { ++ ++data->therm_ovfl ; ++ } ++ break ; ++ case emc6d100 : ++ /* Three more voltage sensors */ ++ for (i = 5; i <= 7; ++i) { ++ data->in[i] = ++ lm85_read_value(client, EMC6D100_REG_IN(i)); ++ } ++ /* More alarm bits */ ++ data->alarms |= ++ lm85_read_value(client, EMC6D100_REG_ALARM3) << 16; ++ ++ break ; ++ default : break ; /* no warnings */ ++ } ++ ++ data->last_reading = jiffies ; ++ }; /* last_reading */ ++ ++ if (!data->valid ++ || (jiffies - data->last_config > LM85_CONFIG_INTERVAL) ) { ++ /* Things that don't change often */ ++ ++#ifdef DEBUG ++ printk("lm85(%d): Reading config values\n", client->id); ++#endif ++ for (i = 0; i <= 4; ++i) { ++ data->in_min[i] = ++ lm85_read_value(client, LM85_REG_IN_MIN(i)); ++ data->in_max[i] = ++ lm85_read_value(client, LM85_REG_IN_MAX(i)); ++ } ++ ++ for (i = 0; i <= 3; ++i) { ++ data->fan_min[i] = ++ lm85_read_value(client, LM85_REG_FAN_MIN(i)); ++ } ++ ++ for (i = 0; i <= 2; ++i) { ++ data->temp_min[i] = ++ lm85_read_value(client, LM85_REG_TEMP_MIN(i)); ++ data->temp_max[i] = ++ lm85_read_value(client, LM85_REG_TEMP_MAX(i)); ++ } ++ ++ data->vid = lm85_read_value(client, LM85_REG_VID); ++ ++ for (i = 0; i <= 2; ++i) { ++ int val ; ++ data->autofan[i].config = ++ lm85_read_value(client, LM85_REG_AFAN_CONFIG(i)); ++ val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i)); ++ data->autofan[i].freq = val & 0x07 ; ++ data->zone[i].range = (val >> 4) & 0x0f ; ++ data->autofan[i].min_pwm = ++ lm85_read_value(client, LM85_REG_AFAN_MINPWM(i)); ++ data->zone[i].limit = ++ lm85_read_value(client, LM85_REG_AFAN_LIMIT(i)); ++ data->zone[i].critical = ++ lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i)); ++ } ++ ++ i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); ++ data->smooth[0] = i & 0x0f ; ++ data->syncpwm3 = i & 0x10 ; /* Save PWM3 config */ ++ data->autofan[0].min_off = i & 0x20 ; ++ data->autofan[1].min_off = i & 0x40 ; ++ data->autofan[2].min_off = i & 0x80 ; ++ i = lm85_read_value(client, LM85_REG_AFAN_SPIKE2); ++ data->smooth[1] = (i>>4) & 0x0f ; ++ data->smooth[2] = i & 0x0f ; ++ ++ i = lm85_read_value(client, LM85_REG_AFAN_HYST1); ++ data->zone[0].hyst = (i>>4) & 0x0f ; ++ data->zone[1].hyst = i & 0x0f ; ++ ++ i = lm85_read_value(client, LM85_REG_AFAN_HYST2); ++ data->zone[2].hyst = (i>>4) & 0x0f ; ++ ++ switch( ((struct lm85_data *)(client->data))->type ) { ++ case lm85b : ++ case lm85c : ++ data->tach_mode = lm85_read_value(client, ++ LM85_REG_TACH_MODE ); ++ data->spinup_ctl = lm85_read_value(client, ++ LM85_REG_SPINUP_CTL ); ++ break ; ++ case adt7463 : ++ for (i = 0; i <= 2; ++i) { ++ data->oppoint[i] = lm85_read_value(client, ++ ADT7463_REG_OPPOINT(i) ); ++ } ++ data->tmin_ctl = lm85_read_value(client, ++ ADT7463_REG_TMIN_CTL ); ++ data->therm_limit = lm85_read_value(client, ++ ADT7463_REG_THERM_LIMIT ); ++ /* FALL THROUGH */ ++ case adm1027 : ++ for (i = 0; i <= 2; ++i) { ++ data->temp_offset[i] = lm85_read_value(client, ++ ADM1027_REG_TEMP_OFFSET(i) ); ++ } ++ data->tach_mode = lm85_read_value(client, ++ ADM1027_REG_CONFIG3 ); ++ data->fan_ppr = lm85_read_value(client, ++ ADM1027_REG_FAN_PPR ); ++ data->alarm_mask = lm85_read_value(client, ++ ADM1027_REG_INTMASK ); ++ break ; ++ case emc6d100 : ++ for (i = 5; i <= 7; ++i) { ++ data->in_min[i] = ++ lm85_read_value(client, EMC6D100_REG_IN_MIN(i)); ++ data->in_max[i] = ++ lm85_read_value(client, EMC6D100_REG_IN_MAX(i)); ++ } ++ break ; ++ default : break ; /* no warnings */ ++ } ++ ++ data->last_config = jiffies; ++ }; /* last_config */ ++ ++ data->valid = 1; ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The next functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the data ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ */ ++void lm85_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int nr = ctl_name - LM85_SYSCTL_IN0; ++ ++ if (nr < 0 || nr > 4) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; /* 1.000 */ ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ int ext = 0 ; ++ lm85_update_client(client); ++ ext = EXT_FROM_REG(data->extend_adc, nr); ++ results[0] = INS_FROM_REG(nr,data->in_min[nr]); ++ results[1] = INS_FROM_REG(nr,data->in_max[nr]); ++ results[2] = INSEXT_FROM_REG(nr,data->in[nr],ext); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 1) { ++ data->in_max[nr] = INS_TO_REG(nr,results[1]); ++ lm85_write_value(client, LM85_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ if (*nrels_mag > 0) { ++ data->in_min[nr] = INS_TO_REG(nr,results[0]); ++ lm85_write_value(client, LM85_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void lm85_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int nr = ctl_name - LM85_SYSCTL_FAN1 ; ++ ++ if (nr < 0 || nr > 3) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr]); ++ results[1] = FAN_FROM_REG(data->fan[nr]); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 0) { ++ data->fan_min[nr] = FAN_TO_REG(results[0]); ++ lm85_write_value(client, LM85_REG_FAN_MIN(nr), ++ data->fan_min[nr]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++ ++void lm85_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int nr = ctl_name - LM85_SYSCTL_TEMP1 ; ++ ++ if (nr < 0 || nr > 2) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ int ext = 0 ; ++ lm85_update_client(client); ++ ++ /* +5 for offset of temp data in ext reg */ ++ ext = EXT_FROM_REG(data->extend_adc, nr+5); ++ ++ results[0] = TEMP_FROM_REG(data->temp_min[nr]); ++ results[1] = TEMP_FROM_REG(data->temp_max[nr]); ++ results[2] = TEMPEXT_FROM_REG(data->temp[nr],ext); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 1) { ++ data->temp_max[nr] = TEMP_TO_REG(results[1]); ++ lm85_write_value(client, LM85_REG_TEMP_MAX(nr), ++ data->temp_max[nr]); ++ } ++ if (*nrels_mag > 0) { ++ data->temp_min[nr] = TEMP_TO_REG(results[0]); ++ lm85_write_value(client, LM85_REG_TEMP_MIN(nr), ++ data->temp_min[nr]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void lm85_pwm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int nr = ctl_name - LM85_SYSCTL_PWM1 ; ++ int pwm_zone ; ++ ++ if (nr < 0 || nr > 2) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ results[0] = PWM_FROM_REG(data->pwm[nr]); ++ pwm_zone = ZONE_FROM_REG(data->autofan[nr].config); ++ /* PWM "enabled" if not off (0) nor on (-1) */ ++ results[1] = pwm_zone != 0 && pwm_zone != -1 ; ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ /* PWM enable is read-only */ ++ if (*nrels_mag > 0) { ++ data->pwm[nr] = PWM_TO_REG(results[0]); ++ lm85_write_value(client, LM85_REG_PWM(nr), ++ data->pwm[nr]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void lm85_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ ++ if( ctl_name != LM85_SYSCTL_VID ) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ results[0] = VID_FROM_REG((data->vid)&0x3f,data->vrm); ++ *nrels_mag = 1; ++ } ++} ++ ++void lm85_vrm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ ++ if( ctl_name != LM85_SYSCTL_VRM ) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->vrm ; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 0) { ++ data->vrm = results[0] ; ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void lm85_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ ++ if( ctl_name != LM85_SYSCTL_ALARMS ) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++void lm85_spinup_ctl(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int old; ++ ++ if( ctl_name != LM85_SYSCTL_SPINUP_CTL ) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ results[0] = (data->spinup_ctl & 1) != 0 ; ++ results[1] = (data->spinup_ctl & 2) != 0 ; ++ results[2] = (data->spinup_ctl & 4) != 0 ; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ old = data->spinup_ctl ; ++ if (*nrels_mag > 2) { ++ old = (old & (~4)) | (results[2]?4:0) ; ++ } ++ if (*nrels_mag > 1) { ++ old = (old & (~2)) | (results[1]?2:0) ; ++ } ++ if (*nrels_mag > 0) { ++ old = (old & (~1)) | (results[0]?1:0) ; ++ lm85_write_value(client, LM85_REG_SPINUP_CTL, old); ++ data->spinup_ctl = old ; ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void lm85_tach_mode(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int old; ++ ++ /* Tach Mode 1, Tach Mode 2, Tach Mode 3 & 4 */ ++ ++ if( ctl_name != LM85_SYSCTL_TACH_MODE ) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ results[0] = (data->tach_mode & 0x03) ; ++ results[1] = (data->tach_mode & 0x0c) >> 2 ; ++ results[2] = (data->tach_mode & 0x30) >> 4 ; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ old = data->tach_mode ; ++ if (*nrels_mag > 2) { ++ old = (old & (~0x30)) | ((results[2]&3) << 4) ; ++ } ++ if (*nrels_mag > 1) { ++ old = (old & (~0x0c)) | ((results[1]&3) << 2) ; ++ } ++ if (*nrels_mag > 0) { ++ old = (old & (~0x03)) | (results[0]&3) ; ++ lm85_write_value(client, LM85_REG_TACH_MODE, old); ++ data->tach_mode = old ; ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1027_tach_mode(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int old; ++ ++ /* Tach/DC 1, Tach/DC 2, Tach/DC 3, Tach/DC 4 */ ++ ++ if( ctl_name != ADM1027_SYSCTL_TACH_MODE ) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ results[0] = (data->tach_mode & 0x10) != 0 ; ++ results[1] = (data->tach_mode & 0x20) != 0 ; ++ results[2] = (data->tach_mode & 0x40) != 0 ; ++ results[3] = (data->tach_mode & 0x80) != 0 ; ++ *nrels_mag = 4; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ old = data->tach_mode ; ++ if (*nrels_mag > 3) { ++ old = (old & (~0x80)) | (results[3] ? 0x80 : 0) ; ++ } ++ if (*nrels_mag > 2) { ++ old = (old & (~0x40)) | (results[2] ? 0x40 : 0) ; ++ } ++ if (*nrels_mag > 1) { ++ old = (old & (~0x20)) | (results[1] ? 0x20 : 0) ; ++ } ++ if (*nrels_mag > 0) { ++ old = (old & (~0x10)) | (results[0] ? 0x10 : 0) ; ++ ++ /* Enable fast measurements if any TACH's are DC */ ++ old = (old & (~0x08)) | ((old&0xf0) ? 0x08 : 0) ; ++ ++ lm85_write_value(client, ADM1027_REG_CONFIG3, old); ++ data->tach_mode = old ; ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void lm85_pwm_config(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int nr = ctl_name - LM85_SYSCTL_PWM_CFG1 ; ++ ++ /* Spinup, min PWM, PWM Frequency, min below limit, Invert */ ++ ++ if (nr < 0 || nr > 2) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ ++ results[0] = SPINUP_FROM_REG(data->autofan[nr].config); ++ results[1] = PWM_FROM_REG(data->autofan[nr].min_pwm)*10; ++ results[2] = FREQ_FROM_REG(data->autofan[nr].freq); ++ results[3] = data->autofan[nr].min_off ? 10 : 0 ; ++ results[4] = (data->autofan[nr].config & 0x10) ? 10 : 0 ; ++ *nrels_mag = 5; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ int old_config ; ++ ++ down(&data->update_lock); ++ old_config = data->autofan[nr].config ; ++ if (*nrels_mag > 4) { ++ old_config = (old_config & (~0x10)) | (results[4]?0x10:0) ; ++ } ++ if (*nrels_mag > 3) { ++ data->autofan[nr].min_off = results[3] != 0 ; ++ lm85_write_value(client, LM85_REG_AFAN_SPIKE1, ++ data->smooth[0] ++ | data->syncpwm3 ++ | (data->autofan[0].min_off ? 0x20 : 0) ++ | (data->autofan[1].min_off ? 0x40 : 0) ++ | (data->autofan[2].min_off ? 0x80 : 0) ++ ); ++ } ++ if (*nrels_mag > 2) { ++ data->autofan[nr].freq = FREQ_TO_REG(results[2]) ; ++ lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), ++ (data->zone[nr].range << 4) ++ | data->autofan[nr].freq ++ ); ++ } ++ if (*nrels_mag > 1) { ++ data->autofan[nr].min_pwm = PWM_TO_REG((results[1]+5)/10); ++ lm85_write_value(client, LM85_REG_AFAN_MINPWM(nr), ++ data->autofan[nr].min_pwm ++ ); ++ } ++ if (*nrels_mag > 0) { ++ old_config = (old_config & (~0x07)) | SPINUP_TO_REG(results[0]) ; ++ lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr), old_config); ++ data->autofan[nr].config = old_config ; ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void lm85_smooth(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int nr = ctl_name - LM85_SYSCTL_SMOOTH1 ; ++ ++ if (nr < 0 || nr > 2) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ results[0] = SMOOTH_FROM_REG(data->smooth[nr]); ++ *nrels_mag = 1; ++ ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if( *nrels_mag > 0 ) { ++ data->smooth[nr] = SMOOTH_TO_REG(results[0]); ++ } ++ if( nr == 0 ) { ++ lm85_write_value(client, LM85_REG_AFAN_SPIKE1, ++ data->smooth[0] ++ | data->syncpwm3 ++ | (data->autofan[0].min_off ? 0x20 : 0) ++ | (data->autofan[1].min_off ? 0x40 : 0) ++ | (data->autofan[2].min_off ? 0x80 : 0) ++ ); ++ } else { ++ lm85_write_value(client, LM85_REG_AFAN_SPIKE2, ++ (data->smooth[1] << 4) | data->smooth[2]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void lm85_zone(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int nr = ctl_name - LM85_SYSCTL_ZONE1 ; ++ ++ /* Limit, Hysteresis (neg), Range, Critical */ ++ ++ if (nr < 0 || nr > 2) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ ++ results[0] = TEMP_FROM_REG(data->zone[nr].limit) / 10; ++ results[1] = HYST_FROM_REG(data->zone[nr].hyst); ++ results[2] = RANGE_FROM_REG(data->zone[nr].range); ++ results[3] = TEMP_FROM_REG(data->zone[nr].critical) / 10; ++ *nrels_mag = 4; ++ ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 3) { ++ data->zone[nr].critical = TEMP_TO_REG(results[3]*10); ++ lm85_write_value(client, LM85_REG_AFAN_CRITICAL(nr), ++ data->zone[nr].critical ); ++ } ++ if (*nrels_mag > 2) { ++ data->zone[nr].range = RANGE_TO_REG(results[2]); ++ lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), ++ (data->zone[nr].range << 4) ++ | data->autofan[nr].freq ++ ); ++ } ++ if (*nrels_mag > 1) { ++ data->zone[nr].hyst = HYST_TO_REG(results[1]); ++ if( nr == 0 || nr == 1 ) { ++ lm85_write_value(client, LM85_REG_AFAN_HYST1, ++ (data->zone[0].hyst << 4) ++ | data->zone[1].hyst ++ ); ++ } else { ++ lm85_write_value(client, LM85_REG_AFAN_HYST2, ++ (data->zone[2].hyst << 4) ++ ); ++ } ++ } ++ if (*nrels_mag > 0) { ++ data->zone[nr].limit = TEMP_TO_REG(results[0]*10); ++ lm85_write_value(client, LM85_REG_AFAN_LIMIT(nr), ++ data->zone[nr].limit ++ ); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void lm85_pwm_zone(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int nr = ctl_name - LM85_SYSCTL_PWM_ZONE1 ; ++ ++ if (nr < 0 || nr > 2) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ results[0] = ZONE_FROM_REG(data->autofan[nr].config); ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 0) { ++ data->autofan[nr].config = ++ (data->autofan[nr].config & (~0xe0)) ++ | ZONE_TO_REG(results[0]) ; ++ lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr), ++ data->autofan[nr].config); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1027_temp_offset(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int nr = ctl_name - ADM1027_SYSCTL_TEMP_OFFSET1 ; ++ ++ if (nr < 0 || nr > 2) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ switch( data->type ) { ++ case adm1027 : ++ default : ++ results[0] = TEMP_FROM_REG(data->temp_offset[nr]); ++ break ; ++ case adt7463 : ++ results[0] = TEMPEXT_FROM_REG(0,data->temp_offset[nr]); ++ break ; ++ } ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 0) { ++ switch( data->type ) { ++ case adm1027 : ++ default : ++ data->temp_offset[nr] = TEMP_TO_REG(results[0]); ++ break ; ++ case adt7463 : ++ data->temp_offset[nr] = EXTTEMP_TO_REG(results[0]); ++ break ; ++ }; ++ lm85_write_value(client, ADM1027_REG_TEMP_OFFSET(nr), ++ data->temp_offset[nr]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1027_fan_ppr(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int old ; ++ ++ if (ctl_name != ADM1027_SYSCTL_FAN_PPR) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ results[0] = PPR_FROM_REG(data->fan_ppr,0); ++ results[1] = PPR_FROM_REG(data->fan_ppr,1); ++ results[2] = PPR_FROM_REG(data->fan_ppr,2); ++ results[3] = PPR_FROM_REG(data->fan_ppr,3); ++ *nrels_mag = 4; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ old = data->fan_ppr ; ++ if (*nrels_mag > 3) { ++ old = (old & ~PPR_MASK(3)) | PPR_TO_REG(results[3],3); ++ }; ++ if (*nrels_mag > 2) { ++ old = (old & ~PPR_MASK(2)) | PPR_TO_REG(results[2],2); ++ }; ++ if (*nrels_mag > 1) { ++ old = (old & ~PPR_MASK(1)) | PPR_TO_REG(results[1],1); ++ }; ++ if (*nrels_mag > 0) { ++ old = (old & ~PPR_MASK(0)) | PPR_TO_REG(results[0],0); ++ lm85_write_value(client, ADM1027_REG_FAN_PPR, old); ++ data->fan_ppr = old ; ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adm1027_alarm_mask(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ ++ if( ctl_name != ADM1027_SYSCTL_ALARM_MASK ) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ results[0] = INTMASK_FROM_REG(data->alarm_mask); ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 0) { ++ data->alarm_mask = INTMASK_TO_REG(results[0]); ++ lm85_write_value(client, ADM1027_REG_INTMASK, ++ data->alarm_mask); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adt7463_tmin_ctl(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int nr = ctl_name - ADT7463_SYSCTL_TMIN_CTL1 ; ++ u16 old ; ++ ++ if (nr < 0 || nr > 2) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ old = data->tmin_ctl ; ++ results[0] = (old & ( 0x2000 << nr )) != 0 ; ++ results[1] = (old >> (nr*3)) & 0x07 ; ++ results[2] = (old & ( 0x0400 << nr )) != 0 ; ++ results[3] = OPPOINT_FROM_REG(data->oppoint[nr]); ++ *nrels_mag = 4; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ old = data->tmin_ctl ; ++ if (*nrels_mag > 3) { ++ data->oppoint[nr] = OPPOINT_TO_REG(results[3]); ++ lm85_write_value(client, ADT7463_REG_OPPOINT(nr), ++ data->oppoint[nr]); ++ }; ++ if (*nrels_mag > 2) { ++ if( results[2] ) { ++ old |= (0x0400 << nr) ; ++ } else { ++ old &= ~(0x0400 << nr) ; ++ } ++ }; ++ if (*nrels_mag > 1) { ++ old &= ~(0x07 << (nr*3)) ; ++ old |= (results[1] & 0x07) << (nr*3) ; ++ }; ++ if (*nrels_mag > 0) { ++ if( results[0] ) { ++ old |= 0x2000 << nr ; ++ } else { ++ old &= ~(0x2000 << nr) ; ++ } ++ lm85_write_value(client, ADT7463_REG_TMIN_CTL, old); ++ data->tmin_ctl = old ; ++ } ++ up(&data->update_lock); ++ } ++} ++ ++void adt7463_therm_signal(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int counts ; ++ ++ if (ctl_name != ADT7463_SYSCTL_THERM_SIGNAL) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ /* Don't call update_client here because ++ * ADT7463_REG_THERM has to be read every ++ * 5 seconds to prevent lost counts ++ */ ++ down(&data->update_lock); ++ counts = lm85_read_value(client, ADT7463_REG_THERM) & 0xff; ++ if( data->therm_total < LONG_MAX - 256 ) { ++ data->therm_total += counts ; ++ } ++ if( counts >= 255 ) { ++ ++data->therm_ovfl ; ++ } ++ up(&data->update_lock); ++ ++ results[0] = data->therm_limit ; ++ results[1] = data->therm_total ; ++ results[2] = data->therm_ovfl ; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ /* therm_total and therm_ovfl are read only */ ++ if (*nrels_mag > 0) { ++ data->therm_limit = SENSORS_LIMIT(results[0],0,255); ++ lm85_write_value(client, ADT7463_REG_THERM_LIMIT, ++ data->therm_limit); ++ }; ++ up(&data->update_lock); ++ } ++} ++ ++ ++void emc6d100_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm85_data *data = client->data; ++ int nr = ctl_name - EMC6D100_SYSCTL_IN5 +5; ++ ++ if (nr < 5 || nr > 7) ++ return ; /* ERROR */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; /* 1.000 */ ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm85_update_client(client); ++ results[0] = INS_FROM_REG(nr,data->in_min[nr]); ++ results[1] = INS_FROM_REG(nr,data->in_max[nr]); ++ results[2] = INS_FROM_REG(nr,data->in[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ down(&data->update_lock); ++ if (*nrels_mag > 1) { ++ data->in_max[nr] = INS_TO_REG(nr,results[1]); ++ lm85_write_value(client, EMC6D100_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ if (*nrels_mag > 0) { ++ data->in_min[nr] = INS_TO_REG(nr,results[0]); ++ lm85_write_value(client, EMC6D100_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ up(&data->update_lock); ++ } ++} ++ ++ ++static int __init sm_lm85_init(void) ++{ ++ printk("lm85: Version %s (%s)\n", LM_VERSION, LM_DATE); ++ printk("lm85: See http://www.penguincomputing.com/lm_sensors for more info.\n" ); ++ return i2c_add_driver(&lm85_driver); ++} ++ ++static void __exit sm_lm85_exit(void) ++{ ++ i2c_del_driver(&lm85_driver); ++} ++ ++/* Thanks to Richard Barrington for adding the LM85 to sensors-detect. ++ * Thanks to Margit Schubert-While for help with ++ * post 2.7.0 CVS changes ++ */ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Philip Pokorny ++ Philip Edelbrock ++ Stephen Rousset ++ Dan Eaton ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++ ++/* Chip configuration settings. These should be set to reflect the ++HARDWARE configuration of your chip. By default (read: when all of ++these are left commented out), this driver assumes that the ++configuration is the same as National's defaults for the Channel Mode ++register. ++ ++Set to '1' the appropriate defines, as nessesary: ++ ++ - External temp sensors 2 (possible second CPU temp) ++ This will disable the 2.5V and Vccp2 readings. ++ Ironically, National decided that you can read the ++ temperature of a second CPU or it's core voltage, ++ but not both! Comment out if FAULT is reported. */ ++ ++/* #define LM87_EXT2 1 */ ++ ++/* Aux analog input. When enabled, the Fan 1 reading ++ will be disabled */ ++ ++/* #define LM87_AIN1 1 */ ++ ++/* Aux analog input 2. When enabled, the Fan 2 reading ++ will be disabled */ ++ ++/* #define LM87_AIN2 1 */ ++ ++/* Internal Vcc is 5V instead of 3.3V */ ++ ++/* #define LM87_5V_VCC 1 */ ++ ++/* That's the end of the hardware config defines. I would have made ++ them insmod params, but it would be too much work. ;') */ ++ ++ ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x2c, 0x2e, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(lm87); ++ ++/* The following is the calculation for the register offset ++ * for the monitored items minimum and maximum locations. ++ */ ++#define LM87_REG_IN_MAX(nr) (0x2b + ((nr) * 2)) ++#define LM87_REG_IN_MIN(nr) (0x2c + ((nr) * 2)) ++#define LM87_REG_IN(nr) (0x20 + (nr)) ++ ++/* Initial limits */ ++ ++/* ++ * LM87 register definition ++ * ++ */ ++ ++ /* The LM87 registers */ ++#define LM87_INT_TEMP_HI_LIMIT_LOCKABLE 0x13 ++#define LM87_EXT_TEMP_HI_LIMIT_LOCKABLE 0x14 ++#define LM87_REG_TEST 0x15 ++#define LM87_REG_CHANNEL_MODE 0x16 ++#define LM87_REG_INT_TEMP_HI_LIMIT 0x17 ++#define LM87_REG_EXT_TEMP_HI_LIMIT 0x18 ++#define LM87_REG_ANALOG_OUT 0x19 ++ ++ /* These are all read-only */ ++#define LM87_REG_2_5V_EXT_TEMP_2 0x20 ++#define LM87_REG_VCCP1 0x21 ++#define LM87_REG_3_3V 0x22 ++#define LM87_REG_5V 0x23 ++#define LM87_REG_12V 0x24 ++#define LM87_REG_VCCP2 0x25 ++#define LM87_REG_EXT_TEMP_1 0x26 ++#define LM87_REG_INT_TEMP 0x27 /* LM87 temp. */ ++#define LM87_REG_FAN1_AIN1 0x28 ++#define LM87_REG_FAN2_AIN2 0x29 ++ ++/* These are read/write */ ++#define LM87_REG_AIN1_LOW 0x1A ++#define LM87_REG_AIN2_LOW 0x1B ++#define LM87_REG_2_5V_EXT_TEMP_2_HIGH 0x2B ++#define LM87_REG_2_5V_EXT_TEMP_2_LOW 0x2C ++#define LM87_REG_VCCP1_HIGH 0x2D ++#define LM87_REG_VCCP1_LOW 0x2E ++#define LM87_REG_3_3V_HIGH 0x2F ++#define LM87_REG_3_3V_LOW 0x30 ++#define LM87_REG_5V_HIGH 0x31 ++#define LM87_REG_5V_LOW 0x32 ++#define LM87_REG_12V_HIGH 0x33 ++#define LM87_REG_12V_LOW 0x34 ++#define LM87_REG_VCCP2_HIGH 0x35 ++#define LM87_REG_VCCP2_LOW 0x36 ++#define LM87_REG_EXT_TEMP_1_HIGH 0x37 ++#define LM87_REG_EXT_TEMP_1_LOW 0x38 ++#define LM87_REG_INT_TEMP_HIGH 0x39 ++#define LM87_REG_INT_TEMP_LOW 0x3A ++#define LM87_REG_FAN1_AIN1_LIMIT 0x3B ++#define LM87_REG_FAN2_AIN2_LIMIT 0x3C ++#define LM87_REG_COMPANY_ID 0x3E ++#define LM87_REG_DIE_REV 0x3F ++ ++#define LM87_REG_CONFIG 0x40 ++#define LM87_REG_INT1_STAT 0x41 ++#define LM87_REG_INT2_STAT 0x42 ++#define LM87_REG_INT1_MASK 0x43 ++#define LM87_REG_INT2_MASK 0x44 ++#define LM87_REG_CHASSIS_CLEAR 0x46 ++#define LM87_REG_VID_FAN_DIV 0x47 ++#define LM87_REG_VID4 0x49 ++#define LM87_REG_CONFIG_2 0x4A ++#define LM87_REG_INTRPT_STATUS_1_MIRROR 0x4C ++#define LM87_REG_INTRPT_STATUS_2_MIRROR 0x4D ++#define LM87_REG_SMBALERT_NUM_ENABLE 0x80 ++ ++ ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++ ++#define IN_TO_REG(val,nr) (SENSORS_LIMIT(((val) & 0xff),0,255)) ++#define IN_FROM_REG(val,nr) (val) ++ ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 255; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, ++ 254); ++} ++ ++#define FAN_FROM_REG(val,div) ((val)==0?-1:\ ++ (val)==255?0:1350000/((div)*(val))) ++ ++#define TEMP_FROM_REG(temp) (temp * 10) ++ ++#define TEMP_LIMIT_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10) ++ ++#define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT(((val)<0?(((val)-5)/10):\ ++ ((val)+5)/10),0,255) ++#if 0 ++#define TEMP_FROM_REG(temp) \ ++ ((temp)<256?((((temp)&0x1fe) >> 1) * 10) + ((temp) & 1) * 5: \ ++ ((((temp)&0x1fe) >> 1) -255) * 10 - ((temp) & 1) * 5) \ ++ ++#define TEMP_LIMIT_FROM_REG(val) (val) ++ ++#define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val),0,255) ++#endif ++ ++ ++#define ALARMS_FROM_REG(val) (val) ++ ++#define DIV_FROM_REG(val) (1 << (val)) ++#define DIV_TO_REG(val) ((val)==1?0:((val)==8?3:((val)==4?2:1))) ++ ++/* For each registered LM87, we need to keep some data in memory. That ++ data is pointed to by LM87_list[NR]->data. The structure itself is ++ dynamically allocated, at the same time when a new LM87 client is ++ allocated. */ ++struct lm87_data { ++ struct i2c_client client; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 in[6]; /* Scaled Register value */ ++ u8 in_max[6]; /* Scaled Register value */ ++ u8 in_min[6]; /* Scaled Register value */ ++ u8 ain1; /* Register value */ ++ u8 ain1_min; /* Register value */ ++ u8 ain1_max; /* Register value */ ++ u8 ain2; /* Register value */ ++ u8 ain2_min; /* Register value */ ++ u8 ain2_max; /* Register value */ ++ u8 fan; /* Register value */ ++ u8 fan_min; /* Register value */ ++ u8 fan_div; /* Register encoding, shifted right */ ++ u8 fan2; /* Register value */ ++ u8 fan2_min; /* Register value */ ++ u8 fan2_div; /* Register encoding, shifted right */ ++ int ext2_temp; /* Temp, shifted right */ ++ int ext_temp; /* Temp, shifted right */ ++ int int_temp; /* Temp, shifted right */ ++ u8 ext_temp_max; /* Register value */ ++ u8 ext_temp_min; /* Register value */ ++ u8 ext2_temp_max; /* Register value */ ++ u8 ext2_temp_min; /* Register value */ ++ u8 int_temp_max; /* Register value */ ++ u8 int_temp_min; /* Register value */ ++ u16 alarms; /* Register encoding, combined */ ++ u8 analog_out; /* Register value */ ++ u8 vid; /* Register value combined */ ++ u8 vrm; /* VRM version * 10 */ ++}; ++ ++static int lm87_attach_adapter(struct i2c_adapter *adapter); ++static int lm87_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int lm87_detach_client(struct i2c_client *client); ++ ++static int lm87_read_value(struct i2c_client *client, u8 register); ++static int lm87_write_value(struct i2c_client *client, u8 register, ++ u8 value); ++static void lm87_update_client(struct i2c_client *client); ++static void lm87_init_client(struct i2c_client *client); ++ ++ ++static void lm87_in(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++#if defined (LM87_AIN1) || defined (LM87_AIN2) ++static void lm87_ain(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++#endif ++static void lm87_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm87_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm87_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm87_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm87_analog_out(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, ++ long *results); ++static void lm87_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm87_vrm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static int lm87_id = 0; ++ ++static struct i2c_driver LM87_driver = { ++ .owner = THIS_MODULE, ++ .name = "LM87 sensor driver", ++ .id = I2C_DRIVERID_LM87, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = lm87_attach_adapter, ++ .detach_client = lm87_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++#define LM87_SYSCTL_IN0 1000 /* Volts * 100 */ ++#define LM87_SYSCTL_IN1 1001 ++#define LM87_SYSCTL_IN2 1002 ++#define LM87_SYSCTL_IN3 1003 ++#define LM87_SYSCTL_IN4 1004 ++#define LM87_SYSCTL_IN5 1005 ++#define LM87_SYSCTL_AIN1 1006 ++#define LM87_SYSCTL_AIN2 1007 ++#define LM87_SYSCTL_FAN1 1102 ++#define LM87_SYSCTL_FAN2 1103 ++#define LM87_SYSCTL_TEMP1 1250 /* Degrees Celcius * 100 */ ++#define LM87_SYSCTL_TEMP2 1251 /* Degrees Celcius * 100 */ ++#define LM87_SYSCTL_TEMP3 1252 /* Degrees Celcius * 100 */ ++#define LM87_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define LM87_SYSCTL_ALARMS 2001 /* bitvector */ ++#define LM87_SYSCTL_ANALOG_OUT 2002 ++#define LM87_SYSCTL_VID 2003 ++#define LM87_SYSCTL_VRM 2004 ++ ++#define LM87_ALARM_IN0 0x0001 ++#define LM87_ALARM_IN1 0x0002 ++#define LM87_ALARM_IN2 0x0004 ++#define LM87_ALARM_IN3 0x0008 ++#define LM87_ALARM_TEMP1 0x0010 ++#define LM87_ALARM_TEMP2 0x0020 ++#define LM87_ALARM_TEMP3 0x0020 /* same?? */ ++#define LM87_ALARM_FAN1 0x0040 ++#define LM87_ALARM_FAN2 0x0080 ++#define LM87_ALARM_IN4 0x0100 ++#define LM87_ALARM_IN5 0x0200 ++#define LM87_ALARM_RESERVED1 0x0400 ++#define LM87_ALARM_RESERVED2 0x0800 ++#define LM87_ALARM_CHAS 0x1000 ++#define LM87_ALARM_THERM_SIG 0x2000 ++#define LM87_ALARM_TEMP2_FAULT 0x4000 ++#define LM87_ALARM_TEMP3_FAULT 0x08000 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* The /proc/sys entries */ ++/* These files are created for each detected LM87. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++ ++static ctl_table LM87_dir_table_template[] = { ++#ifdef LM87_AIN1 ++ {LM87_SYSCTL_AIN1, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_ain}, ++#endif ++#ifdef LM87_AIN2 ++ {LM87_SYSCTL_AIN2, "in7", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_ain}, ++#endif ++#ifndef LM87_EXT2 ++ {LM87_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_in}, ++ {LM87_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_in}, ++#endif ++ {LM87_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_in}, ++ {LM87_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_in}, ++ {LM87_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_in}, ++ {LM87_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_in}, ++#ifndef LM87_AIN1 ++ {LM87_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_fan}, ++ {LM87_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_fan_div}, ++#define LM87_FANDIV_FLAG ++#endif ++#ifndef LM87_AIN2 ++ {LM87_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_fan}, ++#ifndef LM87_FANDIV_FLAG ++ {LM87_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_fan_div}, ++#endif /* LM87_FANDIV_FLAG */ ++#endif /* LM87_AIN2 */ ++#ifdef LM87_EXT2 ++ {LM87_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_temp}, ++#endif ++ {LM87_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_temp}, ++ {LM87_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_temp}, ++ {LM87_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_alarms}, ++ {LM87_SYSCTL_ANALOG_OUT, "analog_out", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_analog_out}, ++ {LM87_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_vid}, ++ {LM87_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm87_vrm}, ++ {0} ++}; ++ ++static int lm87_attach_adapter(struct i2c_adapter *adapter) ++{ ++ int error; ++ struct i2c_client_address_data lm87_client_data; ++ ++ lm87_client_data.normal_i2c = addr_data.normal_i2c; ++ lm87_client_data.normal_i2c_range = addr_data.normal_i2c_range; ++ lm87_client_data.probe = addr_data.probe; ++ lm87_client_data.probe_range = addr_data.probe_range; ++ lm87_client_data.ignore = addr_data.ignore; ++ lm87_client_data.ignore_range = addr_data.ignore_range; ++ lm87_client_data.force = addr_data.forces->force; ++ ++ error = i2c_probe(adapter, &lm87_client_data, lm87_detect); ++ i2c_detect(adapter, &addr_data, lm87_detect); ++ ++ return error; ++} ++ ++static int lm87_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct lm87_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access LM87_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct lm87_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &LM87_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ ++ if (kind < 0) { ++ if (((lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80) ++ != 0x00) || ++ (lm87_read_value(new_client, LM87_REG_COMPANY_ID) != 0x02)) ++ goto ERROR1; ++ } ++ ++ /* Fill in the remaining client fields and put into the global list */ ++ type_name = "lm87"; ++ client_name = "LM87 chip"; ++ strcpy(new_client->name, client_name); ++ data->type = kind; ++ ++ new_client->id = lm87_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, ++ type_name, ++ LM87_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the LM87 chip */ ++ lm87_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int lm87_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct lm87_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("lm87.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++static int lm87_read_value(struct i2c_client *client, u8 reg) ++{ ++ return 0xFF & i2c_smbus_read_byte_data(client, reg); ++} ++ ++static int lm87_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++/* Called when we have found a new LM87. It should set limits, etc. */ ++static void lm87_init_client(struct i2c_client *client) ++{ ++ struct lm87_data *data = client->data; ++ ++ /* Reset all except Watchdog values and last conversion values ++ This sets fan-divs to 2, among others. This makes most other ++ initializations unnecessary */ ++ lm87_write_value(client, LM87_REG_CONFIG, 0x80); ++ ++ /* Setup Channel Mode register for configuration of monitoring ++ * Default is 00000000b ++ * bit 0 - Configures Fan 1/AIN 1 input (1 = AIN) ++ * bit 1 - Configures Fan 2/AIN 2 input (1 = AIN) ++ * bit 2 - Configures 2.5V&Vccp2/D2 input (1 = 2nd Therm.) ++ * bit 3 - Configures Vcc for 5V/3.3V reading (0 = 3.3V) ++ * bit 4 - Configures IRQ0 Enable if = 1 ++ * bit 5 - Configures IRQ1 Enable if = 1 ++ * bit 6 - Configures IRQ2 Enable if = 1 ++ * bit 7 - Configures VID/IRQ input as interrupts if = 1 ++ */ ++ ++/* I know, not clean, but it works. :'p */ ++ lm87_write_value(client, LM87_REG_CHANNEL_MODE, ++#ifdef LM87_AIN1 ++ 0x01 ++#else ++0 ++#endif ++ | ++#ifdef LM87_AIN2 ++ 0x02 ++#else ++0 ++#endif ++ | ++#ifdef LM87_EXT2 ++ 0x04 ++#else ++0 ++#endif ++ | ++#ifdef LM87_5V_VCC ++0x08 ++#else ++0 ++#endif ++ ); ++ ++ data->vrm = DEFAULT_VRM; ++ ++ /* Start monitoring */ ++ lm87_write_value(client, LM87_REG_CONFIG, 0x01); ++} ++ ++static void lm87_update_client(struct i2c_client *client) ++{ ++ struct lm87_data *data = client->data; ++ int i; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ) || /* 1 sec cache */ ++ (jiffies < data->last_updated) || ++ !data->valid) { ++ for (i = 0; i <= 5; i++) { ++ data->in[i] = ++ lm87_read_value(client,LM87_REG_IN(i)); ++ data->in_min[i] = ++ lm87_read_value(client,LM87_REG_IN_MIN(i)); ++ data->in_max[i] = ++ lm87_read_value(client,LM87_REG_IN_MAX(i)); ++ } ++ data->ain1 = ++ lm87_read_value(client,LM87_REG_FAN1_AIN1); ++ data->ain1_min = ++ lm87_read_value(client,LM87_REG_AIN1_LOW); ++ data->ain1_max = ++ lm87_read_value(client,LM87_REG_FAN1_AIN1_LIMIT); ++ data->ain2 = ++ lm87_read_value(client,LM87_REG_FAN2_AIN2); ++ data->ain2_min = ++ lm87_read_value(client,LM87_REG_AIN2_LOW); ++ data->ain2_max = ++ lm87_read_value(client,LM87_REG_FAN2_AIN2_LIMIT); ++ ++ data->fan = ++ lm87_read_value(client, LM87_REG_FAN1_AIN1); ++ data->fan_min = ++ lm87_read_value(client, LM87_REG_FAN1_AIN1_LIMIT); ++ data->fan2 = ++ lm87_read_value(client, LM87_REG_FAN2_AIN2); ++ data->fan2_min = ++ lm87_read_value(client, LM87_REG_FAN2_AIN2_LIMIT); ++ ++ data->ext2_temp = ++ lm87_read_value(client, LM87_REG_2_5V_EXT_TEMP_2); ++ data->ext_temp = ++ lm87_read_value(client, LM87_REG_EXT_TEMP_1); ++ data->int_temp = ++ lm87_read_value(client, LM87_REG_INT_TEMP); ++ ++ data->ext2_temp_max = ++ lm87_read_value(client, LM87_REG_2_5V_EXT_TEMP_2_HIGH); ++ data->ext2_temp_min = ++ lm87_read_value(client, LM87_REG_2_5V_EXT_TEMP_2_LOW); ++ ++ data->ext_temp_max = ++ lm87_read_value(client, LM87_REG_EXT_TEMP_1_HIGH); ++ data->ext_temp_min = ++ lm87_read_value(client, LM87_REG_EXT_TEMP_1_LOW); ++ ++ data->int_temp_max = ++ lm87_read_value(client, LM87_REG_INT_TEMP_HIGH); ++ data->int_temp_min = ++ lm87_read_value(client, LM87_REG_INT_TEMP_LOW); ++ ++ i = lm87_read_value(client, LM87_REG_VID_FAN_DIV); ++ data->fan_div = (i >> 4) & 0x03; ++ data->fan2_div = (i >> 6) & 0x03; ++ data->vid = i & 0x0f; ++ data->vid |= ++ (lm87_read_value(client, LM87_REG_VID4) & 0x01) ++ << 4; ++ data->alarms = ++ lm87_read_value(client, LM87_REG_INT1_STAT) + ++ (lm87_read_value(client, LM87_REG_INT2_STAT) << 8); ++ data->analog_out = ++ lm87_read_value(client, LM87_REG_ANALOG_OUT); ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ up(&data->update_lock); ++} ++ ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the date ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++void lm87_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ long scales[6] = { 250, 270, ++#ifdef LM87_5V_VCC ++500, ++#else ++330, ++#endif ++ 500, 1200, 270 }; ++ ++ struct lm87_data *data = client->data; ++ int nr = ctl_name - LM87_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm87_update_client(client); ++ results[0] = ++ ((long)data->in_min[nr] * scales[nr]) / 192; ++ results[1] = ++ ((long)data->in_max[nr] * scales[nr]) / 192; ++ results[2] = ++ ((long)data->in[nr] * scales[nr]) / 192; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = ++ (results[0] * 192) / scales[nr]; ++ lm87_write_value(client, LM87_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = ++ (results[1] * 192) / scales[nr]; ++ lm87_write_value(client, LM87_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++} ++ ++#if defined (LM87_AIN1) || defined (LM87_AIN2) ++void lm87_ain(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm87_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm87_update_client(client); ++ if (ctl_name == LM87_SYSCTL_AIN1) { ++ results[0] = data->ain1_min; ++ results[1] = data->ain1_max; ++ results[2] = data->ain1; ++ } else { ++ results[0] = data->ain2_min; ++ results[1] = data->ain2_max; ++ results[2] = data->ain2; ++ } ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ if (ctl_name == LM87_SYSCTL_AIN1) { ++ data->ain1_min = results[0]; ++ lm87_write_value(client, LM87_REG_AIN1_LOW, ++ data->ain1_min); ++ } else { ++ data->ain2_min = results[0]; ++ lm87_write_value(client, LM87_REG_AIN2_LOW, ++ data->ain2_min); ++ } ++ } ++ if (*nrels_mag >= 2) { ++ if (ctl_name == LM87_SYSCTL_AIN1) { ++ data->ain1_max = results[1]; ++ lm87_write_value(client, LM87_REG_FAN1_AIN1_LIMIT, ++ data->ain1_max); ++ } else { ++ data->ain2_max = results[1]; ++ lm87_write_value(client, LM87_REG_FAN2_AIN2_LIMIT, ++ data->ain2_max); ++ } ++ } ++ } ++} ++#endif ++ ++void lm87_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm87_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm87_update_client(client); ++ if (ctl_name == LM87_SYSCTL_FAN1) { ++ results[0] = FAN_FROM_REG(data->fan_min, ++ DIV_FROM_REG(data->fan_div)); ++ results[1] = FAN_FROM_REG(data->fan, ++ DIV_FROM_REG(data->fan_div)); ++ } else { ++ results[0] = FAN_FROM_REG(data->fan2_min, ++ DIV_FROM_REG(data->fan2_div)); ++ results[1] = FAN_FROM_REG(data->fan2, ++ DIV_FROM_REG(data->fan2_div)); ++ } ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 0) { ++ if (ctl_name == LM87_SYSCTL_FAN1) { ++ data->fan_min = FAN_TO_REG(results[0], ++ DIV_FROM_REG ++ (data->fan_div)); ++ lm87_write_value(client, LM87_REG_FAN1_AIN1_LIMIT, ++ data->fan_min); ++ } else { ++ data->fan2_min = FAN_TO_REG(results[0], ++ DIV_FROM_REG ++ (data->fan2_div)); ++ lm87_write_value(client, LM87_REG_FAN2_AIN2_LIMIT, ++ data->fan2_min); ++ } ++ } ++ } ++} ++ ++ ++void lm87_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm87_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) ++ { ++ lm87_update_client(client); ++ ++ /* find out which temp. is being requested */ ++ if (ctl_name == LM87_SYSCTL_TEMP3) ++ { ++ results[0] = TEMP_LIMIT_FROM_REG(data->ext2_temp_max); ++ results[1] = TEMP_LIMIT_FROM_REG(data->ext2_temp_min); ++ results[2] = TEMP_FROM_REG(data->ext2_temp); ++ } ++ else if(ctl_name == LM87_SYSCTL_TEMP2) ++ { ++ results[0] = TEMP_LIMIT_FROM_REG(data->ext_temp_max); ++ results[1] = TEMP_LIMIT_FROM_REG(data->ext_temp_min); ++ results[2] = TEMP_FROM_REG(data->ext_temp); ++ } ++ else if(ctl_name == LM87_SYSCTL_TEMP1) ++ { ++ results[0] = TEMP_LIMIT_FROM_REG(data->int_temp_max); ++ results[1] = TEMP_LIMIT_FROM_REG(data->int_temp_min); ++ results[2] = TEMP_FROM_REG(data->int_temp); ++ } ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ if (ctl_name == LM87_SYSCTL_TEMP3) { ++ data->ext2_temp_max = TEMP_LIMIT_TO_REG(results[0]); ++ lm87_write_value(client, LM87_REG_2_5V_EXT_TEMP_2_HIGH, ++ data->ext2_temp_max); ++ } ++ if (ctl_name == LM87_SYSCTL_TEMP2) { ++ data->ext_temp_max = TEMP_LIMIT_TO_REG(results[0]); ++ lm87_write_value(client, LM87_REG_EXT_TEMP_1_HIGH, ++ data->ext_temp_max); ++ } ++ if (ctl_name == LM87_SYSCTL_TEMP1) { ++ data->int_temp_max = TEMP_LIMIT_TO_REG(results[0]); ++ lm87_write_value(client, LM87_REG_INT_TEMP_HIGH, ++ data->int_temp_max); ++ } ++ } ++ if (*nrels_mag >= 2) { ++ if (ctl_name == LM87_SYSCTL_TEMP3) { ++ data->ext2_temp_min = TEMP_LIMIT_TO_REG(results[1]); ++ lm87_write_value(client, LM87_REG_2_5V_EXT_TEMP_2_LOW, ++ data->ext2_temp_min); ++ } ++ if (ctl_name == LM87_SYSCTL_TEMP2) { ++ data->ext_temp_min = TEMP_LIMIT_TO_REG(results[1]); ++ lm87_write_value(client, LM87_REG_EXT_TEMP_1_LOW, ++ data->ext_temp_min); ++ } ++ if (ctl_name == LM87_SYSCTL_TEMP1) { ++ data->int_temp_min = TEMP_LIMIT_TO_REG(results[1]); ++ lm87_write_value(client, LM87_REG_INT_TEMP_LOW, ++ data->int_temp_min); ++ } ++ } ++ } ++} ++ ++void lm87_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm87_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm87_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++void lm87_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++/* This gets a little hairy depending on the hardware config */ ++ ++ struct lm87_data *data = client->data; ++ int old; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm87_update_client(client); ++#ifndef LM87_AIN1 ++ results[0] = DIV_FROM_REG(data->fan_div); ++# ifndef LM87_AIN2 ++ results[1] = DIV_FROM_REG(data->fan2_div); ++ *nrels_mag = 2; ++# else ++ *nrels_mag = 1; ++# endif ++#else /* Must be referring to fan 2 */ ++ results[0] = DIV_FROM_REG(data->fan2_div); ++ *nrels_mag = 1; ++#endif ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = lm87_read_value(client, LM87_REG_VID_FAN_DIV); ++/* Note: it's OK to change fan2 div even if fan2 isn't enabled */ ++#ifndef LM87_AIN1 ++ if (*nrels_mag >= 2) { ++ data->fan2_div = DIV_TO_REG(results[1]); ++ old = (old & 0x3f) | (data->fan2_div << 6); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div = DIV_TO_REG(results[0]); ++ old = (old & 0xcf) | (data->fan_div << 4); ++ lm87_write_value(client, LM87_REG_VID_FAN_DIV, old); ++ } ++#else /* Must be referring to fan 2 */ ++ if (*nrels_mag >= 1) { ++ data->fan2_div = DIV_TO_REG(results[0]); ++ old = (old & 0xcf) | (data->fan2_div << 6); ++ lm87_write_value(client, LM87_REG_VID_FAN_DIV, old); ++ } ++#endif ++ } ++} ++ ++void lm87_analog_out(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct lm87_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm87_update_client(client); ++ results[0] = data->analog_out; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->analog_out = results[0]; ++ lm87_write_value(client, LM87_REG_ANALOG_OUT, ++ data->analog_out); ++ } ++ } ++} ++ ++void lm87_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm87_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ lm87_update_client(client); ++ results[0] = vid_from_reg(data->vid, data->vrm); ++ *nrels_mag = 1; ++ } ++} ++ ++void lm87_vrm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct lm87_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->vrm; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) ++ data->vrm = results[0]; ++ } ++} ++ ++static int __init sm_lm87_init(void) ++{ ++ printk("lm87.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&LM87_driver); ++} ++ ++static void __exit sm_lm87_exit(void) ++{ ++ i2c_del_driver(&LM87_driver); ++} ++ ++ ++ ++MODULE_LICENSE("GPL"); ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard , Philip Edelbrock , " ++ "Mark Studebaker , and Stephen Rousset "); ++ ++MODULE_DESCRIPTION("LM87 driver"); ++ ++module_init(sm_lm87_init); ++module_exit(sm_lm87_exit); +--- linux-old/drivers/sensors/lm90.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/lm90.c Mon Dec 13 20:18:49 2004 +@@ -0,0 +1,782 @@ ++/* ++ * lm90.c - Part of lm_sensors, Linux kernel modules for hardware ++ * monitoring ++ * Copyright (C) 2003-2004 Jean Delvare ++ * ++ * Based on the lm83 driver. The LM90 is a sensor chip made by National ++ * Semiconductor. It reports up to two temperatures (its own plus up to ++ * one external one) with a 0.125 deg resolution (1 deg for local ++ * temperature) and a 3-4 deg accuracy. Complete datasheet can be ++ * obtained from National's website at: ++ * http://www.national.com/pf/LM/LM90.html ++ * ++ * This driver also supports the LM89 and LM99, two other sensor chips ++ * made by National Semiconductor. Both have an increased remote ++ * temperature measurement accuracy (1 degree), and the LM99 ++ * additionally shifts remote temperatures (measured and limits) by 16 ++ * degrees, which allows for higher temperatures measurement. The ++ * driver doesn't handle it since it can be done easily in user-space. ++ * Complete datasheets can be obtained from National's website at: ++ * http://www.national.com/pf/LM/LM89.html ++ * http://www.national.com/pf/LM/LM99.html ++ * Note that there is no way to differenciate between both chips. ++ * ++ * This driver also supports the LM86, another sensor chip made by ++ * National Semiconductor. It is exactly similar to the LM90 except it ++ * has a higher accuracy. ++ * Complete datasheet can be obtained from National's website at: ++ * http://www.national.com/pf/LM/LM86.html ++ * ++ * This driver also supports the ADM1032, a sensor chip made by Analog ++ * Devices. That chip is similar to the LM90, with a few differences ++ * that are not handled by this driver. Complete datasheet can be ++ * obtained from Analog's website at: ++ * http://products.analog.com/products/info.asp?product=ADM1032 ++ * Among others, it has a higher accuracy than the LM90, much like the ++ * LM86 does. ++ * ++ * This driver also supports the MAX6657 and MAX6658, sensor chips made ++ * by Maxim. These chips are similar to the LM86. Complete datasheet ++ * can be obtained at Maxim's website at: ++ * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578 ++ * Note that there is no way to differenciate between both chips (but ++ * no need either). ++ * ++ * Since the LM90 was the first chipset supported by this driver, most ++ * comments will refer to this chipset, but are actually general and ++ * concern all supported chipsets, unless mentioned otherwise. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++#ifndef I2C_DRIVERID_LM90 ++#define I2C_DRIVERID_LM90 1042 ++#endif ++ ++/* ++ * Addresses to scan ++ * Address is fully defined internally and cannot be changed. ++ * LM86, LM89, LM90, LM99, ADM1032, MAX6657 and MAX6658 have address 0x4c. ++ * LM89-1, and LM99-1 have address 0x4d. ++ */ ++ ++static unsigned short normal_i2c[] = { 0x4c, 0x4d, SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* ++ * Insmod parameters ++ */ ++ ++SENSORS_INSMOD_5(lm90, adm1032, lm99, lm86, max6657); ++ ++/* ++ * The LM90 registers ++ */ ++ ++#define LM90_REG_R_MAN_ID 0xFE ++#define LM90_REG_R_CHIP_ID 0xFF ++#define LM90_REG_R_CONFIG1 0x03 ++#define LM90_REG_W_CONFIG1 0x09 ++#define LM90_REG_R_CONFIG2 0xBF ++#define LM90_REG_W_CONFIG2 0xBF ++#define LM90_REG_R_CONVRATE 0x04 ++#define LM90_REG_W_CONVRATE 0x0A ++#define LM90_REG_R_STATUS 0x02 ++#define LM90_REG_R_LOCAL_TEMP 0x00 ++#define LM90_REG_R_LOCAL_HIGH 0x05 ++#define LM90_REG_W_LOCAL_HIGH 0x0B ++#define LM90_REG_R_LOCAL_LOW 0x06 ++#define LM90_REG_W_LOCAL_LOW 0x0C ++#define LM90_REG_R_LOCAL_CRIT 0x20 ++#define LM90_REG_W_LOCAL_CRIT 0x20 ++#define LM90_REG_R_REMOTE_TEMPH 0x01 ++#define LM90_REG_R_REMOTE_TEMPL 0x10 ++#define LM90_REG_R_REMOTE_OFFSH 0x11 ++#define LM90_REG_W_REMOTE_OFFSH 0x11 ++#define LM90_REG_R_REMOTE_OFFSL 0x12 ++#define LM90_REG_W_REMOTE_OFFSL 0x12 ++#define LM90_REG_R_REMOTE_HIGHH 0x07 ++#define LM90_REG_W_REMOTE_HIGHH 0x0D ++#define LM90_REG_R_REMOTE_HIGHL 0x13 ++#define LM90_REG_W_REMOTE_HIGHL 0x13 ++#define LM90_REG_R_REMOTE_LOWH 0x08 ++#define LM90_REG_W_REMOTE_LOWH 0x0E ++#define LM90_REG_R_REMOTE_LOWL 0x14 ++#define LM90_REG_W_REMOTE_LOWL 0x14 ++#define LM90_REG_R_REMOTE_CRIT 0x19 ++#define LM90_REG_W_REMOTE_CRIT 0x19 ++#define LM90_REG_R_TCRIT_HYST 0x21 ++#define LM90_REG_W_TCRIT_HYST 0x21 ++ ++/* ++ * Conversions and various macros ++ * The LM90 uses signed 8-bit values for the local temperatures, ++ * and signed 11-bit values for the remote temperatures (except ++ * T_CRIT). The 11-bit conversion formulas may not round negative ++ * numbers perfectly, but who cares? ++ */ ++ ++#define TEMP1_FROM_REG(val) (val & 0x80 ? val-0x100 : val) ++#define TEMP1_TO_REG(val) (val < 0 ? val+0x100 : val) ++#define TEMP2_FROM_REG(val) (((val & 0x8000 ? val-0x10000 : val) \ ++ * 10 + 128) >> 8) ++#define TEMP2_TO_REG(val) (((val << 8) / 10 + (val < 0 ? \ ++ 0x10000 : 0)) & 0xFFE0) ++#define HYST_TO_REG(val) (val < 0 ? 0 : val > 31 ? 31 : val) ++ ++/* ++ * Functions declaration ++ */ ++ ++static int lm90_attach_adapter(struct i2c_adapter *adapter); ++static int lm90_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static void lm90_init_client(struct i2c_client *client); ++static int lm90_detach_client(struct i2c_client *client); ++static void lm90_local_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm90_remote_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm90_local_tcrit(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm90_remote_tcrit(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm90_local_hyst(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm90_remote_hyst(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void lm90_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++/* ++ * Driver data (common to all clients) ++ */ ++ ++static struct i2c_driver lm90_driver = { ++ .owner = THIS_MODULE, ++ .name = "LM90/ADM1032 sensor driver", ++ .id = I2C_DRIVERID_LM90, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = lm90_attach_adapter, ++ .detach_client = lm90_detach_client ++}; ++ ++/* ++ * Client data (each client gets its own) ++ */ ++ ++struct lm90_data ++{ ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* zero until following fields are valid */ ++ unsigned long last_updated; /* in jiffies */ ++ ++ /* registers values */ ++ u8 local_temp, local_high, local_low; ++ u16 remote_temp, remote_high, remote_low; /* combined */ ++ u8 local_crit, remote_crit; ++ u8 hyst; /* linked to two sysctl files (hyst1 RW, hyst2 RO) */ ++ u16 alarms; /* bitvector, combined */ ++}; ++ ++/* ++ * Proc entries ++ * These files are created for each detected LM90. ++ */ ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define LM90_SYSCTL_LOCAL_TEMP 1200 ++#define LM90_SYSCTL_REMOTE_TEMP 1201 ++#define LM90_SYSCTL_LOCAL_TCRIT 1204 ++#define LM90_SYSCTL_REMOTE_TCRIT 1205 ++#define LM90_SYSCTL_LOCAL_HYST 1207 ++#define LM90_SYSCTL_REMOTE_HYST 1208 ++#define LM90_SYSCTL_ALARMS 1210 ++ ++#define LM90_ALARM_LOCAL_HIGH 0x40 ++#define LM90_ALARM_LOCAL_LOW 0x20 ++#define LM90_ALARM_LOCAL_CRIT 0x01 ++#define LM90_ALARM_REMOTE_HIGH 0x10 ++#define LM90_ALARM_REMOTE_LOW 0x08 ++#define LM90_ALARM_REMOTE_CRIT 0x02 ++#define LM90_ALARM_REMOTE_OPEN 0x04 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++ ++static ctl_table lm90_dir_table_template[] = ++{ ++ {LM90_SYSCTL_LOCAL_TEMP, "temp1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm90_local_temp}, ++ {LM90_SYSCTL_REMOTE_TEMP, "temp2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm90_remote_temp}, ++ {LM90_SYSCTL_LOCAL_TCRIT, "tcrit1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm90_local_tcrit}, ++ {LM90_SYSCTL_REMOTE_TCRIT, "tcrit2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm90_remote_tcrit}, ++ {LM90_SYSCTL_LOCAL_HYST, "hyst1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm90_local_hyst}, ++ {LM90_SYSCTL_REMOTE_HYST, "hyst2", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm90_remote_hyst}, ++ {LM90_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &lm90_alarms}, ++ {0} ++}; ++ ++/* ++ * Internal variables ++ */ ++ ++static int lm90_id = 0; ++ ++/* ++ * Real code ++ */ ++ ++static int lm90_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, lm90_detect); ++} ++ ++/* ++ * The following function does more than just detection. If detection ++ * succeeds, it also registers the new chip. ++ */ ++static int lm90_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ struct i2c_client *new_client; ++ struct lm90_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) ++ { ++ printk("lm90.o: Called for an ISA bus adapter, aborting.\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ { ++#ifdef DEBUG ++ printk("lm90.o: I2C bus doesn't support byte read mode, " ++ "skipping.\n"); ++#endif ++ return 0; ++ } ++ ++ if (!(data = kmalloc(sizeof(struct lm90_data), GFP_KERNEL))) ++ { ++ printk("lm90.o: Out of memory in lm90_detect (new_client).\n"); ++ return -ENOMEM; ++ } ++ ++ /* ++ * The common I2C client data is placed right before the ++ * LM90-specific data. The LM90-specific data is pointed to by the ++ * data field from the I2C client data. ++ */ ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &lm90_driver; ++ new_client->flags = 0; ++ ++ /* ++ * Now we do the remaining detection. A negative kind means that ++ * the driver was loaded with no force parameter (default), so we ++ * must both detect and identify the chip. A zero kind means that ++ * the driver was loaded with the force parameter, the detection ++ * step shall be skipped. A positive kind means that the driver ++ * was loaded with the force parameter and a given kind of chip is ++ * requested, so both the detection and the identification steps ++ * are skipped. ++ */ ++ ++ /* Default to an LM90 if forced */ ++ if (kind == 0) ++ kind = lm90; ++ ++ if (kind < 0) /* detection and identification */ ++ { ++ u8 man_id, chip_id, reg_config1, reg_convrate; ++ ++ man_id = i2c_smbus_read_byte_data(new_client, ++ LM90_REG_R_MAN_ID); ++ chip_id = i2c_smbus_read_byte_data(new_client, ++ LM90_REG_R_CHIP_ID); ++ reg_config1 = i2c_smbus_read_byte_data(new_client, ++ LM90_REG_R_CONFIG1); ++ reg_convrate = i2c_smbus_read_byte_data(new_client, ++ LM90_REG_R_CONVRATE); ++ ++ if (man_id == 0x01) /* National Semiconductor */ ++ { ++ u8 reg_config2; ++ ++ reg_config2 = i2c_smbus_read_byte_data(new_client, ++ LM90_REG_R_CONFIG2); ++ ++ if ((reg_config1 & 0x2A) == 0x00 ++ && (reg_config2 & 0xF8) == 0x00 ++ && reg_convrate <= 0x09) ++ { ++ if (address == 0x4C ++ && (chip_id & 0xF0) == 0x20) /* LM90 */ ++ kind = lm90; ++ else if ((chip_id & 0xF0) == 0x30) /* LM89/LM99 */ ++ kind = lm99; ++ else if (address == 0x4C ++ && (chip_id & 0xF0) == 0x10) /* LM86 */ ++ kind = lm99; ++ } ++ } ++ else if (man_id == 0x41) /* Analog Devices */ ++ { ++ if (address == 0x4C ++ && (chip_id & 0xF0) == 0x40 /* ADM1032 */ ++ && (reg_config1 & 0x3F) == 0x00 ++ && reg_convrate <= 0x0A) ++ kind = adm1032; ++ } ++ else if (man_id == 0x4D) /* Maxim */ ++ { ++ if (address == 0x4C ++ && (reg_config1 & 0x1F) == 0 ++ && reg_convrate <= 0x09) ++ kind = max6657; ++ } ++ } ++ ++ if (kind <= 0) /* identification failed */ ++ { ++ printk("lm90.o: Unsupported chip.\n"); ++ goto ERROR1; ++ } ++ ++ if (kind == lm90) ++ { ++ type_name = "lm90"; ++ client_name = "LM90 chip"; ++ } ++ else if (kind == adm1032) ++ { ++ type_name = "adm1032"; ++ client_name = "ADM1032 chip"; ++ } ++ else if (kind == lm99) ++ { ++ type_name = "lm99"; ++ client_name = "LM99 chip"; ++ } ++ else if (kind == lm86) ++ { ++ type_name = "lm86"; ++ client_name = "LM86 chip"; ++ } ++ else if (kind == max6657) ++ { ++ type_name = "max6657"; ++ client_name = "MAX6657 chip"; ++ } ++ else ++ { ++ printk("lm90.o: Unknown kind %d.\n", kind); ++ goto ERROR1; ++ } ++ ++ /* ++ * OK, we got a valid chip so we can fill in the remaining client ++ * fields. ++ */ ++ ++ strcpy(new_client->name, client_name); ++ new_client->id = lm90_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* ++ * Tell the I2C layer a new client has arrived. ++ */ ++ ++ if ((err = i2c_attach_client(new_client))) ++ { ++#ifdef DEBUG ++ printk("lm90.o: Failed attaching client.\n"); ++#endif ++ goto ERROR1; ++ } ++ ++ /* ++ * Register a new directory entry. ++ */ ++ ++ if ((err = i2c_register_entry(new_client, type_name, ++ lm90_dir_table_template)) < 0) ++ { ++#ifdef DEBUG ++ printk("lm90.o: Failed registering directory entry.\n"); ++#endif ++ goto ERROR2; ++ } ++ data->sysctl_id = err; ++ ++ /* ++ * Initialize the LM90 chip. ++ */ ++ ++ lm90_init_client(new_client); ++ return 0; ++ ++ ERROR2: ++ i2c_detach_client(new_client); ++ ERROR1: ++ kfree(data); ++ return err; ++} ++ ++static void lm90_init_client(struct i2c_client *client) ++{ ++ u8 config; ++ ++ /* ++ * Start the conversions. ++ */ ++ ++ i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, ++ 5); /* 2 Hz */ ++ config = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG1); ++ if (config & 0x40) ++ i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, ++ config & 0xBF); /* run */ ++} ++ ++ ++static int lm90_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct lm90_data *) (client->data))->sysctl_id); ++ if ((err = i2c_detach_client(client))) ++ { ++ printk("lm90.o: Client deregistration failed, client not " ++ "detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ return 0; ++} ++ ++static void lm90_update_client(struct i2c_client *client) ++{ ++ struct lm90_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ * 2) || ++ (jiffies < data->last_updated) || !data->valid) ++ { ++ u8 oldh, newh; ++#ifdef DEBUG ++ printk("lm90.o: Updating data.\n"); ++#endif ++ ++ data->local_temp = ++ i2c_smbus_read_byte_data(client, LM90_REG_R_LOCAL_TEMP); ++ data->local_high = ++ i2c_smbus_read_byte_data(client, LM90_REG_R_LOCAL_HIGH); ++ data->local_low = ++ i2c_smbus_read_byte_data(client, LM90_REG_R_LOCAL_LOW); ++ data->local_crit = ++ i2c_smbus_read_byte_data(client, LM90_REG_R_LOCAL_CRIT); ++ ++ /* ++ * There is a trick here. We have to read two registers to ++ * have the remote sensor temperature, but we have to beware ++ * a conversion could occur inbetween the readings. The ++ * datasheet says we should either use the one-shot ++ * conversion register, which we don't want to do (disables ++ * hardware monitoring) or monitor the busy bit, which is ++ * impossible (we can't read the values and monitor that bit ++ * at the exact same time). So the solution used here is to ++ * read the high byte once, then the low byte, then the high ++ * byte again. If the new high byte matches the old one, ++ * then we have a valid reading. Else we have to read the low ++ * byte again, and now we believe we have a correct reading. ++ */ ++ ++ oldh = ++ i2c_smbus_read_byte_data(client, LM90_REG_R_REMOTE_TEMPH); ++ data->remote_temp = ++ i2c_smbus_read_byte_data(client, LM90_REG_R_REMOTE_TEMPL); ++ newh = ++ i2c_smbus_read_byte_data(client, LM90_REG_R_REMOTE_TEMPH); ++ if (newh != oldh) ++ { ++ data->remote_temp = ++ i2c_smbus_read_byte_data(client, LM90_REG_R_REMOTE_TEMPL); ++#ifdef DEBUG ++ oldh = /* actually newer */ ++ i2c_smbus_read_byte_data(client, LM90_REG_R_REMOTE_TEMPH); ++ if (newh != oldh) ++ printk("lm90.o: Remote temperature may be wrong.\n"); ++#endif ++ } ++ data->remote_temp |= (newh << 8); ++ data->remote_high = ++ (i2c_smbus_read_byte_data(client, LM90_REG_R_REMOTE_HIGHH) << 8) ++ + i2c_smbus_read_byte_data(client, LM90_REG_R_REMOTE_HIGHL); ++ data->remote_low = ++ (i2c_smbus_read_byte_data(client, LM90_REG_R_REMOTE_LOWH) << 8) ++ + i2c_smbus_read_byte_data(client, LM90_REG_R_REMOTE_LOWL); ++ data->remote_crit = ++ i2c_smbus_read_byte_data(client, LM90_REG_R_REMOTE_CRIT); ++ ++ data->hyst = ++ i2c_smbus_read_byte_data(client, LM90_REG_R_TCRIT_HYST); ++ data->alarms = ++ i2c_smbus_read_byte_data(client, LM90_REG_R_STATUS); ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++static void lm90_local_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct lm90_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; /* magnitude */ ++ else if (operation == SENSORS_PROC_REAL_READ) ++ { ++ lm90_update_client(client); ++ results[0] = TEMP1_FROM_REG(data->local_high); ++ results[1] = TEMP1_FROM_REG(data->local_low); ++ results[2] = TEMP1_FROM_REG(data->local_temp); ++ *nrels_mag = 3; ++ } ++ else if (operation == SENSORS_PROC_REAL_WRITE) ++ { ++ if (*nrels_mag >= 1) ++ { ++ data->local_high = TEMP1_TO_REG(results[0]); ++ i2c_smbus_write_byte_data(client, LM90_REG_W_LOCAL_HIGH, ++ data->local_high); ++ } ++ if (*nrels_mag >= 2) ++ { ++ data->local_low = TEMP1_TO_REG(results[1]); ++ i2c_smbus_write_byte_data(client, LM90_REG_W_LOCAL_LOW, ++ data->local_low); ++ } ++ } ++} ++ ++static void lm90_remote_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct lm90_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; /* magnitude */ ++ else if (operation == SENSORS_PROC_REAL_READ) ++ { ++ lm90_update_client(client); ++ results[0] = TEMP2_FROM_REG(data->remote_high); ++ results[1] = TEMP2_FROM_REG(data->remote_low); ++ results[2] = TEMP2_FROM_REG(data->remote_temp); ++ *nrels_mag = 3; ++ } ++ else if (operation == SENSORS_PROC_REAL_WRITE) ++ { ++ if (*nrels_mag >= 1) ++ { ++ data->remote_high = TEMP2_TO_REG(results[0]); ++ i2c_smbus_write_byte_data(client, LM90_REG_W_REMOTE_HIGHH, ++ data->remote_high >> 8); ++ i2c_smbus_write_byte_data(client, LM90_REG_W_REMOTE_HIGHL, ++ data->remote_high & 0xFF); ++ } ++ if (*nrels_mag >= 2) ++ { ++ data->remote_low = TEMP2_TO_REG(results[1]); ++ i2c_smbus_write_byte_data(client, LM90_REG_W_REMOTE_LOWH, ++ data->remote_low >> 8); ++ i2c_smbus_write_byte_data(client, LM90_REG_W_REMOTE_LOWL, ++ data->remote_low & 0xFF); ++ } ++ } ++} ++ ++static void lm90_local_tcrit(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct lm90_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; /* magnitude */ ++ else if (operation == SENSORS_PROC_REAL_READ) ++ { ++ lm90_update_client(client); ++ results[0] = TEMP1_FROM_REG(data->local_crit); ++ *nrels_mag = 1; ++ } ++ else if (operation == SENSORS_PROC_REAL_WRITE) ++ { ++ if (*nrels_mag >= 1) ++ { ++ data->local_crit = TEMP1_TO_REG(results[0]); ++ i2c_smbus_write_byte_data(client, LM90_REG_W_LOCAL_CRIT, ++ data->local_crit); ++ } ++ } ++} ++ ++static void lm90_remote_tcrit(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct lm90_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; /* magnitude */ ++ else if (operation == SENSORS_PROC_REAL_READ) ++ { ++ lm90_update_client(client); ++ results[0] = TEMP1_FROM_REG(data->remote_crit); ++ *nrels_mag = 1; ++ } ++ else if (operation == SENSORS_PROC_REAL_WRITE) ++ { ++ if (*nrels_mag >= 1) ++ { ++ data->remote_crit = TEMP1_TO_REG(results[0]); ++ i2c_smbus_write_byte_data(client, LM90_REG_W_REMOTE_CRIT, ++ data->remote_crit); ++ } ++ } ++} ++ ++/* ++ * One quick note about hysteresis. Internally, the hysteresis value ++ * is held in a single register by the LM90, as a relative value. ++ * This relative value applies to both the local critical temperature ++ * and the remote critical temperature. Since all temperatures exported ++ * through procfs have to be absolute, we have to do some conversions. ++ * The solution retained here is to export two absolute values, one for ++ * each critical temperature. In order not to confuse the users too ++ * much, only one file is writable. Would we fail to do so, users ++ * would probably attempt to write to both files, as if they were ++ * independant, and since they aren't, they wouldn't understand why ++ * setting one affects the other one (and would probably claim there's ++ * a bug in the driver). ++ */ ++ ++static void lm90_local_hyst(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct lm90_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; /* magnitude */ ++ else if (operation == SENSORS_PROC_REAL_READ) ++ { ++ lm90_update_client(client); ++ results[0] = TEMP1_FROM_REG(data->local_crit) - ++ TEMP1_FROM_REG(data->hyst); ++ *nrels_mag = 1; ++ } ++ else if (operation == SENSORS_PROC_REAL_WRITE) ++ { ++ if (*nrels_mag >= 1) ++ { ++ data->hyst = HYST_TO_REG(data->local_crit - results[0]); ++ i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, ++ data->hyst); ++ } ++ } ++} ++ ++static void lm90_remote_hyst(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct lm90_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; /* magnitude */ ++ else if (operation == SENSORS_PROC_REAL_READ) ++ { ++ lm90_update_client(client); ++ results[0] = TEMP1_FROM_REG(data->remote_crit) - ++ TEMP1_FROM_REG(data->hyst); ++ *nrels_mag = 1; ++ } ++} ++ ++static void lm90_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct lm90_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; /* magnitude */ ++ else if (operation == SENSORS_PROC_REAL_READ) ++ { ++ lm90_update_client(client); ++ results[0] = data->alarms; ++ *nrels_mag = 1; ++ } ++} ++ ++static int __init sm_lm90_init(void) ++{ ++ printk(KERN_INFO "lm90.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&lm90_driver); ++} ++ ++static void __exit sm_lm90_exit(void) ++{ ++ i2c_del_driver(&lm90_driver); ++} ++ ++MODULE_AUTHOR("Jean Delvare "); ++MODULE_DESCRIPTION("LM90/ADM1032 sensor driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_lm90_init); ++module_exit(sm_lm90_exit); +--- linux-old/drivers/sensors/lm92.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/lm92.c Mon Dec 13 20:18:49 2004 +@@ -0,0 +1,421 @@ ++ ++/* ++ * LM92 - Part of lm_sensors, Linux kernel modules for hardware ++ * monitoring ++ * ++ * Author: Abraham van der Merwe ++ * ++ * Linux support for the National Semiconductor LM92 Temperature ++ * Sensor. ++ * ++ * Based on code from the lm-sensors project which is available ++ * at http://www.lm-sensors.nu/. lm87.c have been particularly ++ * helpful (: ++ * ++ * This source code 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. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++/* if defined, 4 faults must occur consecutively to set alarm flags */ ++/* #define ENABLE_FAULT_QUEUE */ ++ ++#define LM92_REG_TEMPERATURE 0x00 /* ro, 16-bit */ ++#define LM92_REG_CONFIGURATION 0x01 /* rw, 8-bit */ ++#define LM92_REG_TRIP_HYSTERESIS 0x02 /* rw, 16-bit */ ++#define LM92_REG_TRIP_CRITICAL 0x03 /* rw, 16-bit */ ++#define LM92_REG_TRIP_LOW 0x04 /* rw, 16-bit */ ++#define LM92_REG_TRIP_HIGH 0x05 /* rw, 16-bit */ ++#define LM92_REG_MANUFACTURER 0x07 /* ro, 16-bit */ ++ ++#define LM92_MANUFACTURER_ID 0x8001 ++ ++#define TEMP_MIN (-4096) ++#define TEMP_MAX 4095 ++ ++#define LIMIT(x) do { \ ++ if ((x) < TEMP_MIN) (x) = TEMP_MIN; \ ++ if ((x) > TEMP_MAX) (x) = TEMP_MAX; \ ++ } while (0) ++ ++#define PROC_TO_NATIVE(x) ((x) / 625) ++#define NATIVE_TO_PROC(x) ((x) * 625) ++#define CELSIUS(x) ((x) * 16) ++ ++static void lm92_temp (struct i2c_client *client,int operation,int ctl_name,int *nrels_mag,long *results); ++static void lm92_alarms (struct i2c_client *client,int operation,int ctl_name,int *nrels_mag,long *results); ++ ++/* -- SENSORS SYSCTL START -- */ ++#define LM92_SYSCTL_ALARMS 2001 /* high, low, critical */ ++#define LM92_SYSCTL_TEMP 1200 /* high, low, critical, hysteresis, input */ ++ ++#define LM92_ALARM_TEMP_HIGH 0x01 ++#define LM92_ALARM_TEMP_LOW 0x02 ++#define LM92_ALARM_TEMP_CRIT 0x04 ++#define LM92_TEMP_HIGH 0x08 ++#define LM92_TEMP_LOW 0x10 ++#define LM92_TEMP_CRIT 0x20 ++#define LM92_TEMP_HYST 0x40 ++#define LM92_TEMP_INPUT 0x80 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++static ctl_table lm92_dir_table[] = { ++ {LM92_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm92_temp, NULL}, ++ {LM92_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &lm92_alarms, NULL}, ++ {0} ++}; ++ ++/* NOTE: all temperatures are degrees centigrade * 16 */ ++typedef struct { ++ struct i2c_client client; ++ int sysctl_id; ++ unsigned long timestamp; ++ struct { ++ long high; ++ long low; ++ long crit; ++ long hyst; ++ long input; ++ } temp; ++ struct { ++ long low; ++ long high; ++ long crit; ++ } alarms; ++} lm92_t; ++ ++/* this is needed for each client driver method */ ++static struct i2c_driver lm92_driver; ++ ++/* ensure exclusive access to chip and static variables */ ++static DECLARE_MUTEX (mutex); ++ ++/* addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x48, 0x4f, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* insmod parameters */ ++SENSORS_INSMOD_1 (lm92); ++ ++static inline int lm92_write8 (struct i2c_client *client,u8 reg,u8 value) ++{ ++ return (i2c_smbus_write_byte_data (client,reg,value) < 0 ? -EIO : 0); ++} ++ ++static inline int lm92_read16 (struct i2c_client *client,u8 reg,u16 *value) ++{ ++ s32 tmp = i2c_smbus_read_word_data (client,reg); ++ ++ if (tmp < 0) return (-EIO); ++ ++ /* convert the data to little endian format */ ++ *value = swab16((u16) tmp); ++ ++ return (0); ++} ++ ++static inline int lm92_write16 (struct i2c_client *client,u8 reg,u16 value) ++{ ++ /* convert the data to big endian format */ ++ if (i2c_smbus_write_word_data(client, reg, swab16(value)) < 0) ++ return -EIO; ++ ++ return 0; ++} ++ ++static int lm92_read (struct i2c_client *client) ++{ ++ lm92_t *data = (lm92_t *) client->data; ++ u16 value[5]; ++ ++ if ((jiffies - data->timestamp) > HZ) { ++ if (lm92_read16 (client,LM92_REG_TEMPERATURE,value) < 0 || ++ lm92_read16 (client,LM92_REG_TRIP_HYSTERESIS,value + 1) < 0 || ++ lm92_read16 (client,LM92_REG_TRIP_CRITICAL,value + 2) < 0 || ++ lm92_read16 (client,LM92_REG_TRIP_LOW,value + 3) < 0 || ++ lm92_read16 (client,LM92_REG_TRIP_HIGH,value + 4) < 0) ++ return (-EIO); ++ ++ data->temp.input = (s16) value[0] >> 3; ++ data->temp.hyst = (s16) value[1] >> 3; ++ data->temp.crit = (s16) value[2] >> 3; ++ data->temp.low = (s16) value[3] >> 3; ++ data->temp.high = (s16) value[4] >> 3; ++ ++ data->alarms.low = value[0] & 1; ++ data->alarms.high = (value[0] & 2) >> 1; ++ data->alarms.crit = (value[0] & 4) >> 2; ++ ++ data->timestamp = jiffies; ++ } ++ ++ return (0); ++} ++ ++static int lm92_write (struct i2c_client *client) ++{ ++ lm92_t *data = (lm92_t *) client->data; ++ ++ LIMIT (data->temp.hyst); ++ LIMIT (data->temp.crit); ++ LIMIT (data->temp.low); ++ LIMIT (data->temp.high); ++ ++ if (lm92_write16 (client,LM92_REG_TRIP_HYSTERESIS,((s16) data->temp.hyst << 3)) < 0 || ++ lm92_write16 (client,LM92_REG_TRIP_CRITICAL,((s16) data->temp.crit << 3)) < 0 || ++ lm92_write16 (client,LM92_REG_TRIP_LOW,((s16) data->temp.low << 3)) < 0 || ++ lm92_write16 (client,LM92_REG_TRIP_HIGH,((s16) data->temp.high << 3)) < 0) ++ return (-EIO); ++ ++ return (0); ++} ++ ++static void lm92_temp (struct i2c_client *client,int operation,int ctl_name,int *nrels_mag,long *results) ++{ ++ if (!down_interruptible (&mutex)) { ++ lm92_t *data = (lm92_t *) client->data; ++ ++ if (operation == SENSORS_PROC_REAL_READ) { ++ lm92_read (client); ++ results[0] = NATIVE_TO_PROC (data->temp.input); ++ results[1] = NATIVE_TO_PROC (data->temp.high); ++ results[2] = NATIVE_TO_PROC (data->temp.low); ++ results[3] = NATIVE_TO_PROC (data->temp.crit); ++ results[4] = NATIVE_TO_PROC (data->temp.hyst); ++ *nrels_mag = 5; ++ } else if (operation == SENSORS_PROC_REAL_WRITE && *nrels_mag == 4) { ++ data->temp.high = PROC_TO_NATIVE (results[0]); ++ data->temp.low = PROC_TO_NATIVE (results[1]); ++ data->temp.crit = PROC_TO_NATIVE (results[2]); ++ data->temp.hyst = PROC_TO_NATIVE (results[3]); ++ lm92_write (client); ++ } else if (operation == SENSORS_PROC_REAL_INFO) { ++ *nrels_mag = 4; ++ } ++ ++ up (&mutex); ++ } ++} ++ ++static void lm92_alarms (struct i2c_client *client,int operation,int ctl_name,int *nrels_mag,long *results) ++{ ++ if (!down_interruptible (&mutex)) { ++ lm92_t *data = (lm92_t *) client->data; ++ ++ if (operation == SENSORS_PROC_REAL_READ) { ++ lm92_read (client); ++ results[0] = data->alarms.high || (data->alarms.low << 1) || (data->alarms.crit << 2); ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_INFO) { ++ *nrels_mag = 0; ++ } ++ ++ up (&mutex); ++ } ++} ++ ++static int max6635_check(struct i2c_client *client) ++{ ++ int i; ++ u16 temp_low, temp_high, temp_hyst, temp_crit; ++ u8 conf; ++ ++ temp_low = i2c_smbus_read_word_data(client, LM92_REG_TRIP_LOW); ++ temp_high = i2c_smbus_read_word_data(client, LM92_REG_TRIP_HIGH); ++ temp_hyst = i2c_smbus_read_word_data(client, LM92_REG_TRIP_HYSTERESIS); ++ temp_crit = i2c_smbus_read_word_data(client, LM92_REG_TRIP_CRITICAL); ++ ++ if ((temp_low & 0x7f00) || (temp_high & 0x7f00) ++ || (temp_hyst & 0x7f00) || (temp_crit & 0x7f00)) ++ return 0; ++ ++ conf = i2c_smbus_read_byte_data(client, LM92_REG_CONFIGURATION); ++ ++ for (i=0; i<128; i+=16) { ++ if (temp_low != i2c_smbus_read_word_data(client, LM92_REG_TRIP_LOW + i) ++ || temp_high != i2c_smbus_read_word_data(client, LM92_REG_TRIP_HIGH + i) ++ || temp_hyst != i2c_smbus_read_word_data(client, LM92_REG_TRIP_HYSTERESIS + i) ++ || temp_crit != i2c_smbus_read_word_data(client, LM92_REG_TRIP_CRITICAL + i) ++ || conf != i2c_smbus_read_byte_data(client, LM92_REG_CONFIGURATION + i)) ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static int lm92_init_client (struct i2c_client *client) ++{ ++ lm92_t *data = (lm92_t *) client->data; ++ u8 value = 0; ++ int result; ++ ++ /* force reads to query the chip */ ++ data->timestamp = 0; ++ ++ /* setup the configuration register */ ++ ++#ifdef ENABLE_FAULT_QUEUE ++ value |= 0x10; ++#endif /* #ifdef ENABLE_FAULT_QUEUE */ ++ ++ if (lm92_write8 (client,LM92_REG_CONFIGURATION,value) < 0) ++ return (-ENODEV); ++ ++ /* set default alarm trigger values */ ++ ++ data->temp.high = CELSIUS (64); ++ data->temp.low = CELSIUS (10); ++ data->temp.crit = CELSIUS (80); ++ data->temp.hyst = CELSIUS (2); ++ ++ if ((result = lm92_write (client)) < 0) ++ return (result); ++ ++ /* read everything once so that our cached data is updated */ ++ ++ if ((result = lm92_read (client)) < 0) ++ return (result); ++ ++ return (0); ++} ++ ++static int lm92_detect (struct i2c_adapter *adapter,int address,unsigned short flags,int kind) ++{ ++ static int id = 0; ++ struct i2c_client *client; ++ lm92_t *data; ++ int result; ++ u16 manufacturer; ++ ++ if (!i2c_check_functionality (adapter,I2C_FUNC_SMBUS_BYTE_DATA)) ++ return (-ENODEV); ++ ++ if (!(data = kmalloc(sizeof(lm92_t), GFP_KERNEL))) ++ return (-ENOMEM); ++ ++ client = &data->client; ++ client->addr = address; ++ client->data = data; ++ client->adapter = adapter; ++ client->driver = &lm92_driver; ++ client->flags = 0; ++ strcpy (client->name,lm92_driver.name); ++ ++ if (down_interruptible (&mutex)) { ++ result = -ERESTARTSYS; ++ goto ERROR1; ++ } ++ ++ if (kind < 0) { ++ /* Is it an lm92? */ ++ if (address < 0x4c ++ && (lm92_read16(client,LM92_REG_MANUFACTURER,&manufacturer) < 0 ++ || manufacturer != LM92_MANUFACTURER_ID)) { ++ /* Is it a MAX6635/MAX6635/MAX6635? */ ++ if (!max6635_check(client)) { ++ result = -ENODEV; ++ goto ERROR2; ++ } ++ } ++ } ++ ++ if ((result = i2c_attach_client (client))) { ++ goto ERROR2; ++ } ++ ++ if ((result = i2c_register_entry (client,client->name,lm92_dir_table)) < 0) { ++ goto ERROR3; ++ } ++ data->sysctl_id = result; ++ ++ if ((result = lm92_init_client (client)) < 0) { ++ goto ERROR4; ++ } ++ ++ client->id = id++; ++ ++ up (&mutex); ++ ++ return (0); ++ ++ERROR4: ++ i2c_deregister_entry(data->sysctl_id); ++ERROR3: ++ i2c_detach_client(client); ++ERROR2: ++ up(&mutex); ++ERROR1: ++ kfree(data); ++ return result; ++} ++ ++static int lm92_attach_adapter (struct i2c_adapter *adapter) ++{ ++ return i2c_detect (adapter,&addr_data,lm92_detect); ++} ++ ++static int lm92_detach_client (struct i2c_client *client) ++{ ++ int result; ++ ++ i2c_deregister_entry (((lm92_t *) (client->data))->sysctl_id); ++ ++ if ((result = i2c_detach_client (client))) ++ return (result); ++ ++ kfree(client->data); ++ ++ return (0); ++} ++ ++ ++static struct i2c_driver lm92_driver = { ++ .owner = THIS_MODULE, ++ .name = "lm92", ++ .id = I2C_DRIVERID_LM92, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = lm92_attach_adapter, ++ .detach_client = lm92_detach_client, ++}; ++ ++static int __init sm_lm92_init(void) ++{ ++ printk ("lm92.o version %s (%s)\n",LM_VERSION,LM_DATE); ++ return i2c_add_driver(&lm92_driver); ++} ++ ++ ++static void __exit sm_lm92_exit(void) ++{ ++ i2c_del_driver(&lm92_driver); ++} ++ ++ ++ ++MODULE_AUTHOR ("Abraham van der Merwe "); ++MODULE_DESCRIPTION ("Linux support for LM92 Temperature Sensor"); ++ ++MODULE_LICENSE ("GPL"); ++ ++module_init(sm_lm92_init); ++module_exit(sm_lm92_exit); ++ +--- linux-old/drivers/sensors/matorb.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/matorb.c Mon Dec 13 20:18:49 2004 +@@ -0,0 +1,286 @@ ++/* ++ matorb.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard ++ and Philip Edelbrock ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++ ++#define DEBUG 1 ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { 0x2E, SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(matorb); ++ ++/* Many MATORB constants specified below */ ++ ++ ++/* Each client has this additional data */ ++struct matorb_data { ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++}; ++ ++static int matorb_attach_adapter(struct i2c_adapter *adapter); ++static int matorb_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static void matorb_init_client(struct i2c_client *client); ++static int matorb_detach_client(struct i2c_client *client); ++ ++static int matorb_write_value(struct i2c_client *client, u8 reg, ++ u16 value); ++static void matorb_disp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void matorb_update_client(struct i2c_client *client); ++ ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver matorb_driver = { ++ .owner = THIS_MODULE, ++ .name = "Matrix Orbital LCD driver", ++ .id = I2C_DRIVERID_MATORB, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = matorb_attach_adapter, ++ .detach_client = matorb_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++#define MATORB_SYSCTL_DISP 1000 ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected MATORB. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table matorb_dir_table_template[] = { ++ {MATORB_SYSCTL_DISP, "disp", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &matorb_disp}, ++ {0} ++}; ++ ++static int matorb_id = 0; ++ ++static int matorb_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, matorb_detect); ++} ++ ++/* This function is called by i2c_detect */ ++int matorb_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i, cur; ++ struct i2c_client *new_client; ++ struct matorb_data *data; ++ int err = 0; ++ const char *type_name = "matorb"; ++ const char *client_name = "matorb"; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("matorb.o: matorb_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE | ++ I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) ++ goto ERROR0; ++ ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access matorb_{read,write}_value. */ ++ if (!(data = kmalloc(sizeof(struct matorb_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &matorb_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. It is lousy. */ ++ cur = i2c_smbus_write_byte_data(new_client, 0x0FE, 0x58); /* clear screen */ ++ ++ printk("matorb.o: debug detect 0x%X\n", cur); ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = matorb_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, type_name, ++ matorb_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ matorb_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int matorb_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct matorb_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("matorb.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++ ++#if 0 ++/* All registers are word-sized, except for the configuration register. ++ MATORB uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int matorb_read_value(struct i2c_client *client, u8 reg) ++{ ++ return -1; /* Doesn't support reads */ ++} ++#endif ++ ++/* All registers are word-sized, except for the configuration register. ++ MATORB uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int matorb_write_value(struct i2c_client *client, u8 reg, u16 value) ++{ ++ if (reg == 0) { ++ return i2c_smbus_write_byte(client, value); ++ } else { ++ return i2c_smbus_write_byte_data(client, reg, value); ++ } ++} ++ ++static void matorb_init_client(struct i2c_client *client) ++{ ++ /* Initialize the MATORB chip */ ++} ++ ++static void matorb_update_client(struct i2c_client *client) ++{ ++ struct matorb_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("Starting matorb update\n"); ++#endif ++ ++/* nothing yet */ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++void matorb_disp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ int i; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ matorb_update_client(client); ++ results[0] = 0; ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ for (i = 1; i <= *nrels_mag; i++) { ++ matorb_write_value(client, 0, results[i - 1]); ++ } ++ } ++} ++ ++static int __init sm_matorb_init(void) ++{ ++ printk("matorb.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&matorb_driver); ++} ++ ++static void __exit sm_matorb_exit(void) ++{ ++ i2c_del_driver(&matorb_driver); ++} ++ ++ ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard and Philip Edelbrock "); ++MODULE_DESCRIPTION("MATORB driver"); ++ ++module_init(sm_matorb_init); ++module_exit(sm_matorb_exit); +--- linux-old/drivers/sensors/max6650.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/max6650.c Mon Dec 13 20:18:50 2004 +@@ -0,0 +1,545 @@ ++/* ++ * max6650.c - Part of lm_sensors, Linux kernel modules for hardware ++ * monitoring. ++ * ++ * Author: John Morris ++ * ++ * Copyright (c) 2003 Spirent Communications ++ * ++ * This module has only been tested with the MAX6651 chip. It should ++ * work with the MAX6650 also, though with reduced functionality. It ++ * does not yet distinguish max6650 and max6651 chips. ++ * ++ * Tha datasheet was last seen at: ++ * ++ * http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++#ifndef I2C_DRIVERID_MAX6650 ++#define I2C_DRIVERID_MAX6650 1044 ++#endif ++ ++/* ++ * Addresses to scan. There are four disjoint possibilities, by pin config. ++ */ ++ ++static unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b, SENSORS_I2C_END}; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* ++ * Insmod parameters ++ */ ++ ++SENSORS_INSMOD_1(max6650); ++ ++/* ++ * MAX 6650/6651 registers ++ */ ++ ++#define MAX6650_REG_SPEED 0x00 ++#define MAX6650_REG_CONFIG 0x02 ++#define MAX6650_REG_GPIO_DEF 0x04 ++#define MAX6650_REG_DAC 0x06 ++#define MAX6650_REG_ALARM_EN 0x08 ++#define MAX6650_REG_ALARM 0x0A ++#define MAX6650_REG_TACH0 0x0C ++#define MAX6650_REG_TACH1 0x0E ++#define MAX6650_REG_TACH2 0x10 ++#define MAX6650_REG_TACH3 0x12 ++#define MAX6650_REG_GPIO_STAT 0x14 ++#define MAX6650_REG_COUNT 0x16 ++ ++/* ++ * Config register bits ++ */ ++ ++#define MAX6650_CFG_MODE_MASK 0x30 ++#define MAX6650_CFG_MODE_ON 0x00 ++#define MAX6650_CFG_MODE_OFF 0x10 ++#define MAX6650_CFG_MODE_CLOSED_LOOP 0x20 ++#define MAX6650_CFG_MODE_OPEN_LOOP 0x30 ++ ++static const u8 tach_reg[] = ++{ ++ MAX6650_REG_TACH0, MAX6650_REG_TACH1, ++ MAX6650_REG_TACH2, MAX6650_REG_TACH3 ++}; ++ ++#define MAX6650_INT_CLK 254000 /* Default clock speed - 254 kHz */ ++ ++/* ++ * Functions declaration ++ */ ++ ++static void max6650_fan (struct i2c_client *client, int operation, int ++ ctl_name, int *nrels_mag, long *results); ++static void max6650_speed (struct i2c_client *client, int operation, int ++ ctl_name, int *nrels_mag, long *results); ++static void max6650_xdump (struct i2c_client *client, int operation, int ++ ctl_name, int *nrels_mag, long *results); ++static int max6650_detect(struct i2c_adapter *adapter, int address, unsigned ++ short flags, int kind); ++static int max6650_attach_adapter(struct i2c_adapter *adapter); ++static int max6650_detach_client(struct i2c_client *client); ++static void max6650_init_client(struct i2c_client *client); ++static int max6650_read(struct i2c_client *client, u8 reg); ++ ++/* ++ * Driver data (common to all clients) ++ */ ++ ++ ++static struct i2c_driver max6650_driver = { ++ .owner = THIS_MODULE, ++ .name = "MAX6650/1 sensor driver", ++ .id = I2C_DRIVERID_MAX6650, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = max6650_attach_adapter, ++ .detach_client = max6650_detach_client ++}; ++ ++/* ++ * Client data (each client gets its own) ++ */ ++ ++struct max6650_data ++{ ++ struct i2c_client client; ++ int sysctl_id; ++ struct semaphore update_lock; ++ char valid; /* zero until following fields are valid */ ++ unsigned long last_updated; /* in jiffies */ ++ ++ /* register values */ ++ ++ u8 speed; ++ u8 config; ++ u8 tach[4]; ++ u8 count; ++}; ++ ++/* ++ * Proc entries ++ * These files are created for each detected max6650. ++ */ ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define MAX6650_SYSCTL_FAN1 1101 ++#define MAX6650_SYSCTL_FAN2 1102 ++#define MAX6650_SYSCTL_FAN3 1103 ++#define MAX6650_SYSCTL_FAN4 1104 ++#define MAX6650_SYSCTL_SPEED 1105 ++#define MAX6650_SYSCTL_XDUMP 1106 ++ ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++ ++static ctl_table max6650_dir_table_template[] = ++{ ++ {MAX6650_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &max6650_fan}, ++ {MAX6650_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &max6650_fan}, ++ {MAX6650_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &max6650_fan}, ++ {MAX6650_SYSCTL_FAN4, "fan4", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &max6650_fan}, ++ {MAX6650_SYSCTL_SPEED, "speed", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &max6650_speed}, ++ {MAX6650_SYSCTL_XDUMP, "xdump", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &max6650_xdump}, ++ {0} ++}; ++ ++/* ++ * Internal variables ++ */ ++ ++static int max6650_id = 0; ++ ++/* ++ * Real code ++ */ ++ ++static int max6650_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, max6650_detect); ++} ++ ++/* ++ * The following function does more than just detection. If detection ++ * succeeds, it also registers the new chip. ++ */ ++ ++static int max6650_detect(struct i2c_adapter *adapter, int address, unsigned ++ short flags, int kind) ++{ ++ struct i2c_client *new_client; ++ struct max6650_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk("max6650.o: Called for an ISA bus adapter, aborting.\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { ++#ifdef DEBUG ++ printk("max6650.o: I2C bus doesn't support byte read mode, skipping.\n"); ++#endif ++ return 0; ++ } ++ ++ if (!(data = kmalloc(sizeof(struct max6650_data), GFP_KERNEL))) { ++ printk("max6650.o: Out of memory in max6650_detect (new_client).\n"); ++ return -ENOMEM; ++ } ++ ++ /* ++ * The common I2C client data is placed right before the ++ * max6650-specific data. The max6650-specific data is pointed to by the ++ * data field from the I2C client data. ++ */ ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &max6650_driver; ++ new_client->flags = 0; ++ ++ /* ++ * Now we do the remaining detection. A negative kind means that ++ * the driver was loaded with no force parameter (default), so we ++ * must both detect and identify the chip (actually there is only ++ * one possible kind of chip for now, max6650). A zero kind means that ++ * the driver was loaded with the force parameter, the detection ++ * step shall be skipped. A positive kind means that the driver ++ * was loaded with the force parameter and a given kind of chip is ++ * requested, so both the detection and the identification steps ++ * are skipped. ++ * ++ * Currently I can find no way to distinguish between a MAX6650 and ++ * a MAX6651. This driver has only been tried on the latter. ++ */ ++ ++ if (kind < 0) { /* detection */ ++ if ( ++ (max6650_read(new_client, MAX6650_REG_CONFIG) & 0xC0) || ++ (max6650_read(new_client, MAX6650_REG_GPIO_STAT) & 0xE0) || ++ (max6650_read(new_client, MAX6650_REG_ALARM_EN) & 0xE0) || ++ (max6650_read(new_client, MAX6650_REG_ALARM) & 0xE0) || ++ (max6650_read(new_client, MAX6650_REG_COUNT) & 0xFC) ++ ) ++ { ++#ifdef DEBUG ++ printk("max6650.o: max6650 detection failed at 0x%02x.\n", ++ address); ++#endif ++ goto ERROR1; ++ } ++ } ++ ++ if (kind <= 0) { /* identification */ ++ kind = max6650; ++ } ++ ++ if (kind <= 0) { /* identification failed */ ++ printk("max6650.o: Unsupported chip.\n"); ++ goto ERROR1; ++ } ++ ++ if (kind == max6650) { ++ type_name = "max6650"; ++ client_name = "max6650 chip"; ++ } else { ++ printk("max6650.o: Unknown kind %d.\n", kind); ++ goto ERROR1; ++ } ++ ++ /* ++ * OK, we got a valid chip so we can fill in the remaining client ++ * fields. ++ */ ++ ++ strcpy(new_client->name, client_name); ++ new_client->id = max6650_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* ++ * Tell the I2C layer a new client has arrived. ++ */ ++ ++ if ((err = i2c_attach_client(new_client))) { ++#ifdef DEBUG ++ printk("max6650.o: Failed attaching client.\n"); ++#endif ++ goto ERROR1; ++ } ++ ++ /* ++ * Register a new directory entry. ++ */ ++ if ((err = i2c_register_entry(new_client, type_name, ++ max6650_dir_table_template)) < 0) { ++#ifdef DEBUG ++ printk("max6650.o: Failed registering directory entry.\n"); ++#endif ++ goto ERROR2; ++ } ++ data->sysctl_id = err; ++ ++ /* ++ * Initialize the max6650 chip ++ */ ++ max6650_init_client(new_client); ++ return 0; ++ ++ERROR2: ++ i2c_detach_client(new_client); ++ERROR1: ++ kfree(data); ++ return err; ++} ++ ++static void max6650_init_client(struct i2c_client *client) ++{ ++ /* Nothing to do here - assume the BIOS has initialized the chip */ ++} ++ ++static int max6650_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct max6650_data *) (client->data))->sysctl_id); ++ if ((err = i2c_detach_client(client))) { ++ printk("max6650.o: Client deregistration failed, " ++ "client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ return 0; ++} ++ ++static int max6650_read(struct i2c_client *client, u8 reg) ++{ ++ return i2c_smbus_read_byte_data(client, reg); ++} ++ ++static int max6650_write(struct i2c_client *client, u8 reg, u8 value) ++{ ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++static void max6650_update_client(struct i2c_client *client) ++{ ++ int i; ++ struct max6650_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ) || ++ (jiffies < data->last_updated) || !data->valid) { ++#ifdef DEBUG ++ printk("max6650.o: Updating max6650 data.\n"); ++#endif ++ data->speed = max6650_read (client, MAX6650_REG_SPEED); ++ data->config = max6650_read (client, MAX6650_REG_CONFIG); ++ for (i = 0; i < 4; i++) { ++ data->tach[i] = max6650_read(client, tach_reg[i]); ++ } ++ data->count = max6650_read (client, MAX6650_REG_COUNT); ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ up(&data->update_lock); ++} ++ ++static void max6650_fan (struct i2c_client *client, int operation, int ++ ctl_name, int *nrels_mag, long *results) ++{ ++ int index = ctl_name - MAX6650_SYSCTL_FAN1; ++ struct max6650_data *data = client->data; ++ int tcount; /* Tachometer count time, 0.25 second units */ ++ ++ if (operation == SENSORS_PROC_REAL_INFO) { ++ *nrels_mag = 0; ++ } else if (operation == SENSORS_PROC_REAL_READ) { ++ max6650_update_client(client); ++ ++ /* ++ * Calculation details: ++ * ++ * Each tachometer counts over an interval given by the "count" ++ * register (0.25, 0.5, 1 or 2 seconds). This module assumes ++ * that the fans produce two pulses per revolution (this seems ++ * to be the most common). ++ */ ++ ++ tcount = 1 << data->count; /* 0.25 second units */ ++ results[0] = (data->tach[index] * 240) / tcount; /* counts per min */ ++ results[0] /= 2; /* Assume two counts per rev */ ++ *nrels_mag = 1; ++ } ++} ++ ++/* ++ * Set the fan speed to the specified RPM (or read back the RPM setting). ++ * ++ * The MAX6650/1 will automatically control fan speed when in closed loop ++ * mode. ++ * ++ * Assumptions: ++ * ++ * 1) The MAX6650/1 is running from its internal 254kHz clock (perhaps ++ * this should be made a module parameter). ++ * ++ * 2) The prescaler (low three bits of the config register) has already ++ * been set to an appropriate value. ++ * ++ * The relevant equations are given on pages 21 and 22 of the datasheet. ++ * ++ * From the datasheet, the relevant equation when in regulation is: ++ * ++ * [fCLK / (128 x (KTACH + 1))] = 2 x FanSpeed / KSCALE ++ * ++ * where: ++ * ++ * fCLK is the oscillator frequency (either the 254kHz internal ++ * oscillator or the externally applied clock) ++ * ++ * KTACH is the value in the speed register ++ * ++ * FanSpeed is the speed of the fan in rps ++ * ++ * KSCALE is the prescaler value (1, 2, 4, 8, or 16) ++ * ++ * When reading, we need to solve for FanSpeed. When writing, we need to ++ * solve for KTACH. ++ * ++ * Note: this tachometer is completely separate from the tachometers ++ * used to measure the fan speeds. Only one fan's speed (fan1) is ++ * controlled. ++ */ ++ ++static void max6650_speed (struct i2c_client *client, int operation, int ++ ctl_name, int *nrels_mag, long *results) ++{ ++ struct max6650_data *data = client->data; ++ int kscale, ktach, fclk, rpm; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) { ++ *nrels_mag = 0; ++ } else if (operation == SENSORS_PROC_REAL_READ) { ++ /* ++ * Use the datasheet equation: ++ * ++ * FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)] ++ * ++ * then multiply by 60 to give rpm. ++ */ ++ ++ max6650_update_client(client); ++ ++ kscale = 1 << (data->config & 7); ++ ktach = data->speed; ++ fclk = MAX6650_INT_CLK; ++ rpm = 60 * kscale * fclk / (256 * (ktach + 1)); ++ ++ results[0] = rpm; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE && *nrels_mag >= 1) { ++ /* ++ * Divide the required speed by 60 to get from rpm to rps, then ++ * use the datasheet equation: ++ * ++ * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1 ++ */ ++ ++ max6650_update_client(client); ++ ++ rpm = results[0]; ++ kscale = 1 << (data->config & 7); ++ fclk = MAX6650_INT_CLK; ++ ktach = ((fclk * kscale) / (256 * rpm / 60)) - 1; ++ ++ data->speed = ktach; ++ data->config = (data->config & ~MAX6650_CFG_MODE_MASK) | ++ MAX6650_CFG_MODE_CLOSED_LOOP; ++ max6650_write (client, MAX6650_REG_CONFIG, data->config); ++ max6650_write (client, MAX6650_REG_SPEED, data->speed); ++ } ++} ++ ++/* ++ * Debug - dump all registers except the tach counts. ++ */ ++ ++static void max6650_xdump (struct i2c_client *client, int operation, int ++ ctl_name, int *nrels_mag, long *results) ++{ ++ if (operation == SENSORS_PROC_REAL_INFO) { ++ *nrels_mag = 0; ++ } else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = max6650_read (client, MAX6650_REG_SPEED); ++ results[1] = max6650_read (client, MAX6650_REG_CONFIG); ++ results[2] = max6650_read (client, MAX6650_REG_GPIO_DEF); ++ results[3] = max6650_read (client, MAX6650_REG_DAC); ++ results[4] = max6650_read (client, MAX6650_REG_ALARM_EN); ++ results[5] = max6650_read (client, MAX6650_REG_ALARM); ++ results[6] = max6650_read (client, MAX6650_REG_GPIO_STAT); ++ results[7] = max6650_read (client, MAX6650_REG_COUNT); ++ *nrels_mag = 8; ++ } ++} ++ ++static int __init sm_max6650_init(void) ++{ ++ printk(KERN_INFO "max6650.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&max6650_driver); ++} ++ ++static void __exit sm_max6650_exit(void) ++{ ++ i2c_del_driver(&max6650_driver); ++} ++ ++MODULE_AUTHOR("john.morris@spirentcom.com"); ++MODULE_DESCRIPTION("max6650 sensor driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_max6650_init); ++module_exit(sm_max6650_exit); +--- linux-old/drivers/sensors/maxilife.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/maxilife.c Mon Dec 13 20:18:50 2004 +@@ -0,0 +1,1387 @@ ++/* ++ maxilife.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1999-2000 Fons Rademakers ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* The is the driver for the HP MaxiLife Health monitoring system ++ as used in the line of HP Kayak Workstation PC's. ++ ++ The driver supports the following MaxiLife firmware versions: ++ ++ 0) HP KAYAK XU/XAs (Dual Pentium II Slot 1, Deschutes/Klamath) ++ 1) HP KAYAK XU (Dual Xeon [Slot 2] 400/450 Mhz) ++ 2) HP KAYAK XA (Pentium II Slot 1, monoprocessor) ++ ++ Currently firmware auto detection is not implemented. To use the ++ driver load it with the correct option for you Kayak. For example: ++ ++ insmod maxilife.o maxi_version=0 | 1 | 2 ++ ++ maxi_version=0 is the default ++ ++ This version of MaxiLife is called MaxiLife'98 and has been ++ succeeded by MaxiLife'99, see below. ++ ++ The new version of the driver also supports MaxiLife NBA (New BIOS ++ Architecture). This new MaxiLife controller provides a much cleaner ++ machine independent abstraction layer to the MaxiLife controller. ++ Instead of accessing directly registers (different for each revision) ++ one now accesses the sensors via unique mailbox tokens that do not ++ change between revisions. Also the quantities are already in physical ++ units (degrees, rpms, voltages, etc.) and don't need special conversion ++ formulas. This new MaxiLife is available on the new 2000 machines, ++ like the Kayak XU800 and XM600. This hardware is also autodetected. ++*/ ++ ++static const char *version_str = "2.00 29/2/2000 Fons Rademakers"; ++ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++#undef AUTODETECT /* try to autodetect MaxiLife version */ ++/*#define AUTODETECT*/ ++#define NOWRITE /* don't allow writing to MaxiLife registers */ ++ ++#ifdef AUTODETECT ++#include ++#include ++#endif ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x10, 0x14, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(maxilife); ++ ++/* Macro definitions */ ++#define LOW(MyWord) ((u8) (MyWord)) ++#define HIGH(MyWord) ((u8) (((u16)(MyWord) >> 8) & 0xFF)) ++ ++/*----------------- MaxiLife'98 registers and conversion formulas ------------*/ ++#define MAXI_REG_TEMP(nr) (0x60 + (nr)) ++ ++#define MAXI_REG_FAN(nr) (0x65 + (nr)) ++#define MAXI_REG_FAN_MIN(nr) ((nr)==0 ? 0xb3 : (nr)==1 ? 0xb3 : 0xab) ++#define MAXI_REG_FAN_MINAS(nr) ((nr)==0 ? 0xb3 : (nr)==1 ? 0xab : 0xb3) ++#define MAXI_REG_FAN_SPEED(nr) ((nr)==0 ? 0xe4 : (nr)==1 ? 0xe5 : 0xe9) ++ ++#define MAXI_REG_PLL 0xb9 ++#define MAXI_REG_PLL_MIN 0xba ++#define MAXI_REG_PLL_MAX 0xbb ++ ++#define MAXI_REG_VID(nr) ((nr)==0 ? 0xd1 : (nr)==1 ? 0xd9 : \ ++ (nr)==2 ? 0xd4 : 0xc5) ++#define MAXI_REG_VID_MIN(nr) MAXI_REG_VID(nr)+1 ++#define MAXI_REG_VID_MAX(nr) MAXI_REG_VID(nr)+2 ++ ++#define MAXI_REG_DIAG_RT1 0x2c ++#define MAXI_REG_DIAG_RT2 0x2d ++ ++#define MAXI_REG_BIOS_CTRL 0x2a ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++ ++ /* 0xfe: fan off, 0xff: stopped (alarm) */ ++ /* 19531 / val * 60 == 1171860 / val */ ++#define FAN_FROM_REG(val) ((val)==0xfe ? 0 : (val)==0xff ? -1 : \ ++ (val)==0x00 ? -1 : (1171860 / (val))) ++ ++static inline u8 FAN_TO_REG(long rpm) ++{ ++ if (rpm == 0) ++ return 255; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1171860 + rpm / 2) / (rpm), 1, 254); ++} ++ ++#define TEMP_FROM_REG(val) ((val) * 5) ++#define TEMP_TO_REG(val) (SENSORS_LIMIT((val+2) / 5),0,0xff) ++#define PLL_FROM_REG(val) (((val) * 1000) / 32) ++#define PLL_TO_REG(val) (SENSORS_LIMIT((((val) * 32 + 500) / 1000),\ ++ 0,0xff)) ++#define VID_FROM_REG(val) ((val) ? (((val) * 27390) / 256) + 3208 : 0) ++#define VID_TO_REG(val) (SENSORS_LIMIT((((val) - 3208) * 256) / 27390, \ ++ 0,255)) ++#define ALARMS_FROM_REG(val) (val) ++ ++/*----------------- MaxiLife'99 mailbox and token definitions ----------------*/ ++/* MaxiLife mailbox data register map */ ++#define MAXI_REG_MBX_STATUS 0x5a ++#define MAXI_REG_MBX_CMD 0x5b ++#define MAXI_REG_MBX_TOKEN_H 0x5c ++#define MAXI_REG_MBX_TOKEN_L 0x5d ++#define MAXI_REG_MBX_DATA 0x60 ++ ++/* Mailbox status register definition */ ++#define MAXI_STAT_IDLE 0xff ++#define MAXI_STAT_OK 0x00 ++#define MAXI_STAT_BUSY 0x0b ++/* other values not used */ ++ ++/* Mailbox command register opcodes */ ++#define MAXI_CMD_READ 0x02 ++#define MAXI_CMD_WRITE 0x03 ++/* other values not used */ ++ ++/* MaxiLife NBA Hardware monitoring tokens */ ++ ++/* Alarm tokens (0x1xxx) */ ++#define MAXI_TOK_ALARM(nr) (0x1000 + (nr)) ++#define MAXI_TOK_ALARM_EVENT 0x1000 ++#define MAXI_TOK_ALARM_FAN 0x1001 ++#define MAXI_TOK_ALARM_TEMP 0x1002 ++#define MAXI_TOK_ALARM_VID 0x1003 /* voltages */ ++#define MAXI_TOK_ALARM_AVID 0x1004 /* additional voltages */ ++#define MAXI_TOK_ALARM_PWR 0x1101 /* power supply glitch */ ++ ++/* Fan status tokens (0x20xx) */ ++#define MAXI_TOK_FAN(nr) (0x2000 + (nr)) ++#define MAXI_TOK_FAN_CPU 0x2000 ++#define MAXI_TOK_FAN_PCI 0x2001 ++#define MAXI_TOK_FAN_HDD 0x2002 /* hard disk bay fan */ ++#define MAXI_TOK_FAN_SINK 0x2003 /* heatsink */ ++ ++/* Temperature status tokens (0x21xx) */ ++#define MAXI_TOK_TEMP(nr) (0x2100 + (nr)) ++#define MAXI_TOK_TEMP_CPU1 0x2100 ++#define MAXI_TOK_TEMP_CPU2 0x2101 ++#define MAXI_TOK_TEMP_PCI 0x2102 /* PCI/ambient temp */ ++#define MAXI_TOK_TEMP_HDD 0x2103 /* hard disk bay temp */ ++#define MAXI_TOK_TEMP_MEM 0x2104 /* mother board temp */ ++#define MAXI_TOK_TEMP_CPU 0x2105 /* CPU reference temp */ ++ ++/* Voltage status tokens (0x22xx) */ ++#define MAXI_TOK_VID(nr) (0x2200 + (nr)) ++#define MAXI_TOK_VID_12 0x2200 /* +12 volt */ ++#define MAXI_TOK_VID_CPU1 0x2201 /* cpu 1 voltage */ ++#define MAXI_TOK_VID_CPU2 0x2202 /* cpu 2 voltage */ ++#define MAXI_TOK_VID_L2 0x2203 /* level 2 cache voltage */ ++#define MAXI_TOK_VID_M12 0x2204 /* -12 volt */ ++ ++/* Additive voltage status tokens (0x23xx) */ ++#define MAXI_TOK_AVID(nr) (0x2300 + (nr)) ++#define MAXI_TOK_AVID_15 0x2300 /* 1.5 volt */ ++#define MAXI_TOK_AVID_18 0x2301 /* 1.8 volt */ ++#define MAXI_TOK_AVID_25 0x2302 /* 2.5 volt */ ++#define MAXI_TOK_AVID_33 0x2303 /* 3.3 volt */ ++#define MAXI_TOK_AVID_5 0x2304 /* 5 volt */ ++#define MAXI_TOK_AVID_M5 0x2305 /* -5 volt */ ++#define MAXI_TOK_AVID_BAT 0x2306 /* battery voltage */ ++ ++/* Threshold tokens (0x3xxx) */ ++#define MAXI_TOK_MIN(token) ((token) + 0x1000) ++#define MAXI_TOK_MAX(token) ((token) + 0x1800) ++ ++/* LCD Panel (0x4xxx) */ ++#define MAXI_TOK_LCD(nr) (0x4000 + (nr)) ++#define MAXI_TOK_LCD_LINE1 0x4000 ++#define MAXI_TOK_LCD_LINE2 0x4001 ++#define MAXI_TOK_LCD_LINE3 0x4002 ++#define MAXI_TOK_LCD_LINE4 0x4003 ++ ++ /* 0xfe: fan off, 0xff: stopped (alarm) */ ++ /* or not available */ ++#define FAN99_FROM_REG(val) ((val)==0xfe ? 0 : (val)==0xff ? -1 : ((val)*39)) ++ ++ /* when no CPU2 temp is 127 (0x7f) */ ++#define TEMP99_FROM_REG(val) ((val)==0x7f ? -1 : (val)==0xff ? -1 : (val)) ++ ++#define VID99_FROM_REG(nr,val) ((val)==0xff ? 0 : \ ++ (nr)==1 ? ((val) * 608) : \ ++ (nr)==2 ? ((val) * 160) : \ ++ (nr)==3 ? ((val) * 160) : \ ++ (nr)==4 ? (val) /* no formula spcified */ : \ ++ (nr)==5 ? ((val) * 823 - 149140) : 0) ++ ++ ++/* The following product codenames apply: ++ Cristal/Geronimo: HP KAYAK XU/XAs ++ (Dual Pentium II Slot 1, Deschutes/Klamath) ++ Cognac: HP KAYAK XU (Dual Xeon [Slot 2] 400/450 Mhz) ++ Ashaki: HP KAYAK XA (Pentium II Slot 1, monoprocessor) ++ NBA: New BIOS Architecture, Kayak XU800, XM600, ... */ ++ ++enum maxi_type { cristal, cognac, ashaki, nba }; ++enum sensor_type { fan, temp, vid, pll, lcd, alarm }; ++ ++/* For each registered MaxiLife controller, we need to keep some data in ++ memory. That data is pointed to by maxi_list[NR]->data. The structure ++ itself is dynamically allocated, at the same time when a new MaxiLife ++ client is allocated. We assume MaxiLife will only be present on the ++ SMBus and not on the ISA bus. */ ++struct maxi_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ enum maxi_type type; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 fan[4]; /* Register value */ ++ u8 fan_min[4]; /* Register value */ ++ u8 fan_speed[4]; /* Register value */ ++ u8 fan_div[4]; /* Static value */ ++ u8 temp[6]; /* Register value */ ++ u8 temp_max[6]; /* Static value */ ++ u8 temp_hyst[6]; /* Static value */ ++ u8 pll; /* Register value */ ++ u8 pll_min; /* Register value */ ++ u8 pll_max; /* register value */ ++ u8 vid[5]; /* Register value */ ++ u8 vid_min[5]; /* Register value */ ++ u8 vid_max[5]; /* Register value */ ++ u8 lcd[4][17]; /* Four LCD lines */ ++ u16 alarms; /* Register encoding, combined */ ++}; ++ ++ ++static int maxi_attach_adapter(struct i2c_adapter *adapter); ++static int maxi_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int maxi_detach_client(struct i2c_client *client); ++ ++static int maxi_read_value(struct i2c_client *client, u8 register); ++static int maxi_read_token(struct i2c_client *client, u16 token); ++#ifndef NOWRITE ++static int maxi_write_value(struct i2c_client *client, u8 register, ++ u8 value); ++#endif ++static int maxi_write_token_loop(struct i2c_client *client, u16 token, ++ u8 len, u8 * values); ++ ++static void maxi_update_client(struct i2c_client *client); ++static void maxi99_update_client(struct i2c_client *client, ++ enum sensor_type sensor, int which); ++static void maxi_init_client(struct i2c_client *client); ++ ++static void maxi_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void maxi99_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void maxi_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void maxi99_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void maxi_pll(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void maxi_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void maxi99_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void maxi_lcd(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void maxi_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++/* The driver. I choose to use type i2c_driver, as at is identical to ++ the smbus_driver. */ ++static struct i2c_driver maxi_driver = { ++ .owner = THIS_MODULE, ++ .name = "HP MaxiLife driver", ++ .id = I2C_DRIVERID_MAXILIFE, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = maxi_attach_adapter, ++ .detach_client = maxi_detach_client, ++}; ++ ++static int maxi_id = 0; ++ ++/* Default firmware version. Use module option "maxi_version" ++ to set desired version. Auto detect is not yet working */ ++static int maxi_version = cristal; ++ ++/* The /proc/sys entries */ ++ ++/* -- SENSORS SYSCTL START -- */ ++#define MAXI_SYSCTL_FAN1 1101 /* Rotations/min */ ++#define MAXI_SYSCTL_FAN2 1102 /* Rotations/min */ ++#define MAXI_SYSCTL_FAN3 1103 /* Rotations/min */ ++#define MAXI_SYSCTL_FAN4 1104 /* Rotations/min */ ++#define MAXI_SYSCTL_TEMP1 1201 /* Degrees Celcius */ ++#define MAXI_SYSCTL_TEMP2 1202 /* Degrees Celcius */ ++#define MAXI_SYSCTL_TEMP3 1203 /* Degrees Celcius */ ++#define MAXI_SYSCTL_TEMP4 1204 /* Degrees Celcius */ ++#define MAXI_SYSCTL_TEMP5 1205 /* Degrees Celcius */ ++#define MAXI_SYSCTL_TEMP6 1206 /* Degrees Celcius */ ++#define MAXI_SYSCTL_PLL 1301 /* MHz */ ++#define MAXI_SYSCTL_VID1 1401 /* Volts / 6.337, for nba just Volts */ ++#define MAXI_SYSCTL_VID2 1402 /* Volts */ ++#define MAXI_SYSCTL_VID3 1403 /* Volts */ ++#define MAXI_SYSCTL_VID4 1404 /* Volts */ ++#define MAXI_SYSCTL_VID5 1405 /* Volts */ ++#define MAXI_SYSCTL_LCD1 1501 /* Line 1 of LCD */ ++#define MAXI_SYSCTL_LCD2 1502 /* Line 2 of LCD */ ++#define MAXI_SYSCTL_LCD3 1503 /* Line 3 of LCD */ ++#define MAXI_SYSCTL_LCD4 1504 /* Line 4 of LCD */ ++#define MAXI_SYSCTL_ALARMS 2001 /* Bitvector (see below) */ ++ ++#define MAXI_ALARM_VID4 0x0001 ++#define MAXI_ALARM_TEMP2 0x0002 ++#define MAXI_ALARM_VID1 0x0004 ++#define MAXI_ALARM_VID2 0x0008 ++#define MAXI_ALARM_VID3 0x0010 ++#define MAXI_ALARM_PLL 0x0080 ++#define MAXI_ALARM_TEMP4 0x0100 ++#define MAXI_ALARM_TEMP5 0x0200 ++#define MAXI_ALARM_FAN1 0x1000 ++#define MAXI_ALARM_FAN2 0x2000 ++#define MAXI_ALARM_FAN3 0x4000 ++ ++#define MAXI_ALARM_FAN 0x0100 /* To be used with MaxiLife'99 */ ++#define MAXI_ALARM_VID 0x0200 /* The MSB specifies which sensor */ ++#define MAXI_ALARM_TEMP 0x0400 /* in the alarm group failed, i.e.: */ ++#define MAXI_ALARM_VADD 0x0800 /* 0x0402 = TEMP2 failed = CPU2 temp */ ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected MaxiLife processor. ++ This is just a template; though at first sight, you might think we ++ could use a statically allocated list, we need some way to get back ++ to the parent - which is done through one of the 'extra' fields ++ which are initialized when a new copy is allocated. */ ++static ctl_table maxi_dir_table_template[] = { ++ {MAXI_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_fan}, ++ {MAXI_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_fan}, ++ {MAXI_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_fan}, ++ {MAXI_SYSCTL_FAN4, "fan4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_fan}, ++ {MAXI_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_temp}, ++ {MAXI_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_temp}, ++ {MAXI_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_temp}, ++ {MAXI_SYSCTL_TEMP4, "temp4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_temp}, ++ {MAXI_SYSCTL_TEMP5, "temp5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_temp}, ++ {MAXI_SYSCTL_TEMP6, "temp6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_temp}, ++ {MAXI_SYSCTL_PLL, "pll", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_pll}, ++ {MAXI_SYSCTL_VID1, "vid1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_vid}, ++ {MAXI_SYSCTL_VID2, "vid2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_vid}, ++ {MAXI_SYSCTL_VID3, "vid3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_vid}, ++ {MAXI_SYSCTL_VID4, "vid4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_vid}, ++ {MAXI_SYSCTL_VID5, "vid5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_vid}, ++ {MAXI_SYSCTL_LCD1, "lcd1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_lcd}, ++ {MAXI_SYSCTL_LCD2, "lcd2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_lcd}, ++ {MAXI_SYSCTL_LCD3, "lcd3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_lcd}, ++ {MAXI_SYSCTL_LCD4, "lcd4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_lcd}, ++ {MAXI_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &maxi_alarms}, ++ {0} ++}; ++ ++/* This function is called when: ++ - maxi_driver is inserted (when this module is loaded), for each ++ available adapter ++ - when a new adapter is inserted (and maxi_driver is still present) */ ++static int maxi_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, maxi_detect); ++} ++ ++/* This function is called by i2c_detect */ ++int maxi_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ struct i2c_client *new_client; ++ struct maxi_data *data; ++ enum maxi_type type = 0; ++ int i, j, err = 0; ++ const char *type_name = NULL, *client_name = NULL; ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access maxi_{read,write}_value. */ ++ if (!(data = kmalloc(sizeof(struct maxi_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ /* Fill the new client structure with data */ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &maxi_driver; ++ new_client->flags = 0; ++ ++ /* Now we do the remaining detection. */ ++ if (kind < 0) { ++ if (i2c_smbus_read_byte_data ++ (new_client, MAXI_REG_MBX_STATUS) < 0) ++ goto ERROR2; ++ } ++ ++ /* Determine the chip type - only one kind supported */ ++ if (kind <= 0) ++ kind = maxilife; ++ ++ if (kind == maxilife) { ++ /* Detect if the machine has a MaxiLife NBA controller. ++ The right way to perform this check is to do a read/modify/write ++ on register MbxStatus (5A): ++ - Read 5A (value 0 for non-NBA firmware, FF (MbxIdle on NBA-firmware) ++ - Write 55 on 5A, then read back 5A ++ Non-NBA firmware: value is 55 (reg 5A is a standard writable reg) ++ NBA firmaware: value is FF (write-protect on MbxStatus active) */ ++ int stat; ++ i2c_smbus_write_byte_data(new_client, MAXI_REG_MBX_STATUS, ++ 0x55); ++ stat = ++ i2c_smbus_read_byte_data(new_client, ++ MAXI_REG_MBX_STATUS); ++ ++ /*if (stat == MAXI_STAT_IDLE || stat == MAXI_STAT_OK) */ ++ if (stat != 0x55) ++ maxi_version = nba; ++#ifdef AUTODETECT ++ else { ++ /* The right way to get the platform info is to read the firmware ++ revision from serial EEPROM (addr=0x54), at offset 0x0045. ++ This is a string as: ++ "CG 00.04" -> Cristal [XU] / Geronimo [XAs] ++ "CO 00.03" -> Cognac [XU] ++ "AS 00.01" -> Ashaki [XA] */ ++#if 0 ++ int biosctl; ++ biosctl = ++ i2c_smbus_read_byte_data(new_client, ++ MAXI_REG_BIOS_CTRL); ++ i2c_smbus_write_byte_data(new_client, ++ MAXI_REG_BIOS_CTRL, ++ biosctl | 4); ++ err = eeprom_read_byte_data(adapter, 0x54, 0x45); ++ i2c_smbus_write_byte_data(new_client, ++ MAXI_REG_BIOS_CTRL, ++ biosctl); ++#endif ++ int i; ++ char *biosmem, *bm; ++ bm = biosmem = ioremap(0xe0000, 0x20000); ++ if (biosmem) { ++ printk("begin of bios search\n"); ++ for (i = 0; i < 0x20000; i++) { ++ if (*bm == 'C') { ++ char *s = bm; ++ while (s && isprint(*s)) { ++ printk("%c", *s); ++ s++; ++ } ++ printk("\n"); ++ if (!strncmp ++ (bm, "CG 00.04", 8)) { ++ maxi_version = ++ cristal; ++ printk ++ ("maxilife: found MaxiLife Rev CG 00.04\n"); ++ break; ++ } ++ if (!strncmp ++ (bm, "CO 00.03", 8)) { ++ maxi_version = ++ cognac; ++ printk ++ ("maxilife: found MaxiLife Rev CO 00.03\n"); ++ break; ++ } ++ } ++ if (*bm == 'A' && *(bm + 1) == 'S') { ++ char *s = bm; ++ while (s && isprint(*s)) { ++ printk("%c", *s); ++ s++; ++ } ++ printk("\n"); ++ if (!strncmp ++ (bm, "AS 00.01", 8)) { ++ maxi_version = ++ ashaki; ++ printk ++ ("maxilife: found MaxiLife Rev AS 00.01\n"); ++ break; ++ } ++ } ++ bm++; ++ } ++ printk("end of bios search\n"); ++ } else ++ printk("could not map bios memory\n"); ++ } ++#endif ++ ++ if (maxi_version == cristal) { ++ type = cristal; ++ type_name = "maxilife-cg"; ++ client_name = "HP MaxiLife Rev CG 00.04"; ++ printk ++ ("maxilife: HP KAYAK XU/XAs (Dual Pentium II Slot 1)\n"); ++ } else if (maxi_version == cognac) { ++ type = cognac; ++ type_name = "maxilife-co"; ++ client_name = "HP MaxiLife Rev CO 00.03"; ++ printk ++ ("maxilife: HP KAYAK XU (Dual Xeon Slot 2 400/450 Mhz)\n"); ++ } else if (maxi_version == ashaki) { ++ type = ashaki; ++ type_name = "maxilife-as"; ++ client_name = "HP MaxiLife Rev AS 00.01"; ++ printk ++ ("maxilife: HP KAYAK XA (Pentium II Slot 1, monoprocessor)\n"); ++ } else if (maxi_version == nba) { ++ type = nba; ++ type_name = "maxilife-nba"; ++ client_name = "HP MaxiLife NBA"; ++ printk("maxilife: HP KAYAK XU800/XM600\n"); ++ } else { ++#ifdef AUTODETECT ++ printk ++ ("maxilife: Warning: probed non-maxilife chip?!? (%x)\n", ++ err); ++#else ++ printk ++ ("maxilife: Error: specified wrong maxi_version (%d)\n", ++ maxi_version); ++#endif ++ goto ERROR2; ++ } ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ ((struct maxi_data *) (new_client->data))->type = type; ++ ++ for (i = 0; i < 4; i++) ++ for (j = 0; j < 17; j++) ++ ((struct maxi_data *) (new_client->data))-> ++ lcd[i][j] = (u8) 0; ++ ++ new_client->id = maxi_id++; ++ ++ data->valid = 0; ++ init_MUTEX(&data->lock); ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell i2c-core that a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR2; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((err = i2c_register_entry(new_client, type_name, ++ maxi_dir_table_template)) < 0) ++ goto ERROR4; ++ data->sysctl_id = err; ++ ++ /* Initialize the MaxiLife chip */ ++ maxi_init_client(new_client); ++ return 0; ++ ++ /* OK, this is not exactly good programming practice, usually. ++ But it is very code-efficient in this case. */ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR2: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++/* This function is called whenever a client should be removed: ++ - maxi_driver is removed (when this module is unloaded) ++ - when an adapter is removed which has a maxi client (and maxi_driver ++ is still present). */ ++static int maxi_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct maxi_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("maxilife: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ kfree(client->data); ++ return 0; ++} ++ ++/* Read byte from specified register (-1 in case of error, value otherwise). */ ++static int maxi_read_value(struct i2c_client *client, u8 reg) ++{ ++ return i2c_smbus_read_byte_data(client, reg); ++} ++ ++/* Read the byte value for a MaxiLife token (-1 in case of error, value otherwise */ ++static int maxi_read_token(struct i2c_client *client, u16 token) ++{ ++ u8 lowToken, highToken; ++ int error, value; ++ ++ lowToken = LOW(token); ++ highToken = HIGH(token); ++ ++ /* Set mailbox status register to idle state. */ ++ error = ++ i2c_smbus_write_byte_data(client, MAXI_REG_MBX_STATUS, ++ MAXI_STAT_IDLE); ++ if (error < 0) ++ return error; ++ ++ /* Check for mailbox idle state. */ ++ error = i2c_smbus_read_byte_data(client, MAXI_REG_MBX_STATUS); ++ if (error != MAXI_STAT_IDLE) ++ return -1; ++ ++ /* Write the most significant byte of the token we want to read. */ ++ error = ++ i2c_smbus_write_byte_data(client, MAXI_REG_MBX_TOKEN_H, ++ highToken); ++ if (error < 0) ++ return error; ++ ++ /* Write the least significant byte of the token we want to read. */ ++ error = ++ i2c_smbus_write_byte_data(client, MAXI_REG_MBX_TOKEN_L, ++ lowToken); ++ if (error < 0) ++ return error; ++ ++ /* Write the read token opcode to the mailbox. */ ++ error = ++ i2c_smbus_write_byte_data(client, MAXI_REG_MBX_CMD, ++ MAXI_CMD_READ); ++ if (error < 0) ++ return error; ++ ++ /* Check for transaction completion */ ++ do { ++ error = ++ i2c_smbus_read_byte_data(client, MAXI_REG_MBX_STATUS); ++ } while (error == MAXI_STAT_BUSY); ++ if (error != MAXI_STAT_OK) ++ return -1; ++ ++ /* Read the value of the token. */ ++ value = i2c_smbus_read_byte_data(client, MAXI_REG_MBX_DATA); ++ if (value == -1) ++ return -1; ++ ++ /* set mailbox status to idle to complete transaction. */ ++ error = ++ i2c_smbus_write_byte_data(client, MAXI_REG_MBX_STATUS, ++ MAXI_STAT_IDLE); ++ if (error < 0) ++ return error; ++ ++ return value; ++} ++ ++#ifndef NOWRITE ++/* Write byte to specified register (-1 in case of error, 0 otherwise). */ ++static int maxi_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++#endif ++ ++/* Write a set of len byte values to MaxiLife token (-1 in case of error, 0 otherwise). */ ++int maxi_write_token_loop(struct i2c_client *client, u16 token, u8 len, ++ u8 * values) ++{ ++ u8 lowToken, highToken, bCounter; ++ int error; ++ ++ lowToken = LOW(token); ++ highToken = HIGH(token); ++ ++ /* Set mailbox status register to idle state. */ ++ error = ++ i2c_smbus_write_byte_data(client, MAXI_REG_MBX_STATUS, ++ MAXI_STAT_IDLE); ++ if (error < 0) ++ return error; ++ ++ /* Check for mailbox idle state. */ ++ error = i2c_smbus_read_byte_data(client, MAXI_REG_MBX_STATUS); ++ if (error != MAXI_STAT_IDLE) ++ return -1; ++ ++ for (bCounter = 0; (bCounter < len && bCounter < 32); bCounter++) { ++ error = ++ i2c_smbus_write_byte_data(client, ++ (u8) (MAXI_REG_MBX_DATA + ++ bCounter), ++ values[bCounter]); ++ if (error < 0) ++ return error; ++ } ++ ++ /* Write the most significant byte of the token we want to read. */ ++ error = ++ i2c_smbus_write_byte_data(client, MAXI_REG_MBX_TOKEN_H, ++ highToken); ++ if (error < 0) ++ return error; ++ ++ /* Write the least significant byte of the token we want to read. */ ++ error = ++ i2c_smbus_write_byte_data(client, MAXI_REG_MBX_TOKEN_L, ++ lowToken); ++ if (error < 0) ++ return error; ++ ++ /* Write the write token opcode to the mailbox. */ ++ error = ++ i2c_smbus_write_byte_data(client, MAXI_REG_MBX_CMD, ++ MAXI_CMD_WRITE); ++ if (error < 0) ++ return error; ++ ++ /* Check for transaction completion */ ++ do { ++ error = ++ i2c_smbus_read_byte_data(client, MAXI_REG_MBX_STATUS); ++ } while (error == MAXI_STAT_BUSY); ++ if (error != MAXI_STAT_OK) ++ return -1; ++ ++ /* set mailbox status to idle to complete transaction. */ ++ return i2c_smbus_write_byte_data(client, MAXI_REG_MBX_STATUS, ++ MAXI_STAT_IDLE); ++} ++ ++/* Called when we have found a new MaxiLife. It should set limits, etc. */ ++static void maxi_init_client(struct i2c_client *client) ++{ ++ struct maxi_data *data = client->data; ++ ++ if (data->type == nba) { ++ strcpy(data->lcd[2], " Linux MaxiLife"); ++ maxi_write_token_loop(client, MAXI_TOK_LCD(2), ++ strlen(data->lcd[2]) + 1, ++ data->lcd[2]); ++ } ++} ++ ++static void maxi_update_client(struct i2c_client *client) ++{ ++ struct maxi_data *data = client->data; ++ int i; ++ ++ if (data->type == nba) { ++ printk ++ ("maxi_update_client should never be called by nba\n"); ++ return; ++ } ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("maxilife: Starting MaxiLife update\n"); ++#endif ++ for (i = 0; i < 5; i++) ++ data->temp[i] = ++ maxi_read_value(client, MAXI_REG_TEMP(i)); ++ switch (data->type) { ++ case cristal: ++ data->temp[0] = 0; /* not valid */ ++ data->temp_max[0] = 0; ++ data->temp_hyst[0] = 0; ++ data->temp_max[1] = 110; /* max PCI slot temp */ ++ data->temp_hyst[1] = 100; ++ data->temp_max[2] = 120; /* max BX chipset temp */ ++ data->temp_hyst[2] = 110; ++ data->temp_max[3] = 100; /* max HDD temp */ ++ data->temp_hyst[3] = 90; ++ data->temp_max[4] = 120; /* max CPU temp */ ++ data->temp_hyst[4] = 110; ++ break; ++ ++ case cognac: ++ data->temp_max[0] = 120; /* max CPU1 temp */ ++ data->temp_hyst[0] = 110; ++ data->temp_max[1] = 110; /* max PCI slot temp */ ++ data->temp_hyst[1] = 100; ++ data->temp_max[2] = 120; /* max CPU2 temp */ ++ data->temp_hyst[2] = 110; ++ data->temp_max[3] = 100; /* max HDD temp */ ++ data->temp_hyst[3] = 90; ++ data->temp_max[4] = 120; /* max reference CPU temp */ ++ data->temp_hyst[4] = 110; ++ break; ++ ++ case ashaki: ++ data->temp[0] = 0; /* not valid */ ++ data->temp_max[0] = 0; ++ data->temp_hyst[0] = 0; ++ data->temp_max[1] = 110; /* max PCI slot temp */ ++ data->temp_hyst[1] = 100; ++ data->temp[2] = 0; /* not valid */ ++ data->temp_max[2] = 0; ++ data->temp_hyst[2] = 0; ++ data->temp_max[3] = 100; /* max HDD temp */ ++ data->temp_hyst[3] = 90; ++ data->temp_max[4] = 120; /* max CPU temp */ ++ data->temp_hyst[4] = 110; ++ break; ++ ++ default: ++ printk("maxilife: Unknown MaxiLife chip\n"); ++ } ++ data->temp[5] = 0; /* only used by MaxiLife'99 */ ++ data->temp_max[5] = 0; ++ data->temp_hyst[5] = 0; ++ ++ for (i = 0; i < 3; i++) { ++ data->fan[i] = ++ maxi_read_value(client, MAXI_REG_FAN(i)); ++ data->fan_speed[i] = ++ maxi_read_value(client, MAXI_REG_FAN_SPEED(i)); ++ data->fan_div[i] = 4; ++ if (data->type == ashaki) ++ data->fan_min[i] = ++ maxi_read_value(client, ++ MAXI_REG_FAN_MINAS(i)); ++ else ++ data->fan_min[i] = ++ maxi_read_value(client, ++ MAXI_REG_FAN_MIN(i)); ++ } ++ data->fan[3] = 0xff; /* only used by MaxiLife'99 */ ++ data->fan_speed[3] = 0; ++ data->fan_div[3] = 4; /* avoid possible /0 */ ++ data->fan_min[3] = 0; ++ ++ data->pll = maxi_read_value(client, MAXI_REG_PLL); ++ data->pll_min = maxi_read_value(client, MAXI_REG_PLL_MIN); ++ data->pll_max = maxi_read_value(client, MAXI_REG_PLL_MAX); ++ ++ for (i = 0; i < 4; i++) { ++ data->vid[i] = ++ maxi_read_value(client, MAXI_REG_VID(i)); ++ data->vid_min[i] = ++ maxi_read_value(client, MAXI_REG_VID_MIN(i)); ++ data->vid_max[i] = ++ maxi_read_value(client, MAXI_REG_VID_MAX(i)); ++ } ++ switch (data->type) { ++ case cristal: ++ data->vid[3] = 0; /* no voltage cache L2 */ ++ data->vid_min[3] = 0; ++ data->vid_max[3] = 0; ++ break; ++ ++ case cognac: ++ break; ++ ++ case ashaki: ++ data->vid[1] = 0; /* no voltage CPU 2 */ ++ data->vid_min[1] = 0; ++ data->vid_max[1] = 0; ++ data->vid[3] = 0; /* no voltage cache L2 */ ++ data->vid_min[3] = 0; ++ data->vid_max[3] = 0; ++ break; ++ ++ default: ++ printk("maxilife: Unknown MaxiLife chip\n"); ++ } ++ data->vid[4] = 0; /* only used by MaxliLife'99 */ ++ data->vid_min[4] = 0; ++ data->vid_max[4] = 0; ++ ++ data->alarms = maxi_read_value(client, MAXI_REG_DIAG_RT1) + ++ (maxi_read_value(client, MAXI_REG_DIAG_RT2) << 8); ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++void maxi99_update_client(struct i2c_client *client, ++ enum sensor_type sensor, int which) ++{ ++ static unsigned long last_updated[6][6]; /* sensor, which */ ++ struct maxi_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ /*maxi_write_token_loop(client, MAXI_TOK_LCD_LINE3, 13, "Linux 2.2.13"); */ ++ ++ if ((jiffies - last_updated[sensor][which] > 2 * HZ) || ++ (jiffies < last_updated[sensor][which] ++ || !last_updated[sensor][which])) { ++ ++ int tmp, i; ++ ++ switch (sensor) { ++ case fan: ++ for (i = 0; i < 4; i++) { ++ if (i == which) { ++ tmp = ++ maxi_read_token(client, ++ MAXI_TOK_FAN ++ (i)); ++ data->fan[i] = ++ maxi_read_token(client, ++ MAXI_TOK_FAN ++ (i)); ++ data->fan_speed[i] = ++ maxi_read_token(client, ++ MAXI_TOK_MAX ++ (MAXI_TOK_FAN ++ (i))); ++ data->fan_div[i] = 1; ++ data->fan_min[i] = 0; ++ } ++ } ++ break; ++ ++ case temp: ++ for (i = 0; i < 6; i++) { ++ if (i == which) { ++ data->temp[i] = ++ maxi_read_token(client, ++ MAXI_TOK_TEMP ++ (i)); ++ data->temp_max[i] = ++ maxi_read_token(client, ++ MAXI_TOK_MAX ++ (MAXI_TOK_TEMP ++ (i))); ++ data->temp_hyst[i] = ++ data->temp_max[i] - 5; ++ } ++ } ++ break; ++ ++ case vid: ++ for (i = 0; i < 5; i++) { ++ if (i == which) { ++ data->vid[i] = ++ maxi_read_token(client, ++ MAXI_TOK_VID ++ (i)); ++ data->vid_min[i] = ++ maxi_read_token(client, ++ MAXI_TOK_MIN ++ (MAXI_TOK_VID ++ (i))); ++ data->vid_max[i] = ++ maxi_read_token(client, ++ MAXI_TOK_MAX ++ (MAXI_TOK_VID ++ (i))); ++ } ++ } ++ break; ++ ++ case pll: ++ data->pll = 0; ++ data->pll_min = 0; ++ data->pll_max = 0; ++ break; ++ ++ case alarm: ++ data->alarms = ++ (maxi_read_token(client, MAXI_TOK_ALARM_EVENT) ++ << 8); ++ if (data->alarms) ++ data->alarms += ++ data->alarms == ++ (1 << 8) ? maxi_read_token(client, ++ MAXI_TOK_ALARM_FAN) ++ : data->alarms == ++ (2 << 8) ? maxi_read_token(client, ++ MAXI_TOK_ALARM_VID) ++ : data->alarms == ++ (4 << 8) ? maxi_read_token(client, ++ MAXI_TOK_ALARM_TEMP) ++ : data->alarms == ++ (8 << 8) ? maxi_read_token(client, ++ MAXI_TOK_ALARM_FAN) ++ : 0; ++ break; ++ ++ default: ++ printk("maxilife: Unknown sensor type\n"); ++ } ++ ++ last_updated[sensor][which] = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the data ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++void maxi_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct maxi_data *data = client->data; ++ int nr; ++ ++ if (data->type == nba) { ++ maxi99_fan(client, operation, ctl_name, nrels_mag, ++ results); ++ return; ++ } ++ ++ nr = ctl_name - MAXI_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ maxi_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr - 1]); ++ results[1] = data->fan_div[nr - 1]; ++ results[2] = FAN_FROM_REG(data->fan[nr - 1]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++#ifndef NOWRITE ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = FAN_TO_REG(results[0]); ++ maxi_write_value(client, MAXI_REG_FAN_MIN(nr), ++ data->fan_min[nr - 1]); ++ } ++#endif ++ } ++} ++ ++void maxi99_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct maxi_data *data = client->data; ++ int nr; ++ ++ nr = ctl_name - MAXI_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ maxi99_update_client(client, fan, nr - 1); ++ results[0] = FAN99_FROM_REG(data->fan_min[nr - 1]); /* min rpm */ ++ results[1] = data->fan_div[nr - 1]; /* divisor */ ++ results[2] = FAN99_FROM_REG(data->fan[nr - 1]); /* rpm */ ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++#ifndef NOWRITE ++ /* still to do */ ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = FAN_TO_REG(results[0]); ++ maxi_write_value(client, MAXI_REG_FAN_MIN(nr), ++ data->fan_min[nr - 1]); ++ } ++#endif ++ } ++} ++ ++void maxi_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct maxi_data *data = client->data; ++ int nr; ++ ++ if (data->type == nba) { ++ maxi99_temp(client, operation, ctl_name, nrels_mag, ++ results); ++ return; ++ } ++ ++ nr = ctl_name - MAXI_SYSCTL_TEMP1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ maxi_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_max[nr - 1]); ++ results[1] = TEMP_FROM_REG(data->temp_hyst[nr - 1]); ++ results[2] = TEMP_FROM_REG(data->temp[nr - 1]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ /* temperature range can not be changed */ ++ } ++} ++ ++void maxi99_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct maxi_data *data = client->data; ++ int nr; ++ ++ nr = ctl_name - MAXI_SYSCTL_TEMP1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ maxi99_update_client(client, temp, nr - 1); ++ results[0] = TEMP99_FROM_REG(data->temp_max[nr - 1]); ++ results[1] = TEMP99_FROM_REG(data->temp_hyst[nr - 1]); ++ results[2] = TEMP99_FROM_REG(data->temp[nr - 1]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ /* temperature range can not be changed */ ++ } ++} ++ ++void maxi_pll(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct maxi_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ if (data->type == nba) ++ maxi99_update_client(client, pll, 0); ++ else ++ maxi_update_client(client); ++ results[0] = PLL_FROM_REG(data->pll_min); ++ results[1] = PLL_FROM_REG(data->pll_max); ++ results[2] = PLL_FROM_REG(data->pll); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++#ifndef NOWRITE ++ if (*nrels_mag >= 1) { ++ data->pll_min = PLL_TO_REG(results[0]); ++ maxi_write_value(client, MAXI_REG_PLL_MIN, ++ data->pll_min); ++ } ++ if (*nrels_mag >= 2) { ++ data->pll_max = PLL_TO_REG(results[1]); ++ maxi_write_value(client, MAXI_REG_PLL_MAX, ++ data->pll_max); ++ } ++#endif ++ } ++} ++ ++void maxi_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct maxi_data *data = client->data; ++ int nr; ++ ++ if (data->type == nba) { ++ maxi99_vid(client, operation, ctl_name, nrels_mag, ++ results); ++ return; ++ } ++ ++ nr = ctl_name - MAXI_SYSCTL_VID1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 4; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ maxi_update_client(client); ++ results[0] = VID_FROM_REG(data->vid_min[nr - 1]); ++ results[1] = VID_FROM_REG(data->vid_max[nr - 1]); ++ results[2] = VID_FROM_REG(data->vid[nr - 1]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++#ifndef NOWRITE ++ if (*nrels_mag >= 1) { ++ data->vid_min[nr - 1] = VID_TO_REG(results[0]); ++ maxi_write_value(client, MAXI_REG_VID_MIN(nr), ++ data->vid_min[nr - 1]); ++ } ++ if (*nrels_mag >= 2) { ++ data->vid_max[nr - 1] = VID_TO_REG(results[1]); ++ maxi_write_value(client, MAXI_REG_VID_MAX(nr), ++ data->vid_max[nr - 1]); ++ } ++#endif ++ } ++} ++ ++void maxi99_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct maxi_data *data = client->data; ++ int nr = ctl_name - MAXI_SYSCTL_VID1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 4; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ maxi99_update_client(client, vid, nr - 1); ++ results[0] = VID99_FROM_REG(nr, data->vid_min[nr - 1]); ++ results[1] = VID99_FROM_REG(nr, data->vid_max[nr - 1]); ++ results[2] = VID99_FROM_REG(nr, data->vid[nr - 1]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++#ifndef NOWRITE ++ /* still to do */ ++ if (*nrels_mag >= 1) { ++ data->vid_min[nr - 1] = VID_TO_REG(results[0]); ++ maxi_write_value(client, MAXI_REG_VID_MIN(nr), ++ data->vid_min[nr - 1]); ++ } ++ if (*nrels_mag >= 2) { ++ data->vid_max[nr - 1] = VID_TO_REG(results[1]); ++ maxi_write_value(client, MAXI_REG_VID_MAX(nr), ++ data->vid_max[nr - 1]); ++ } ++#endif ++ } ++} ++ ++void maxi_lcd(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ /* Allows writing and reading from LCD display */ ++ ++ struct maxi_data *data = client->data; ++ int nr; ++ ++ if (data->type != nba) ++ return; ++ ++ nr = ctl_name - MAXI_SYSCTL_LCD1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = *((long *) &data->lcd[nr - 1][0]); ++ results[1] = *((long *) &data->lcd[nr - 1][4]); ++ results[2] = *((long *) &data->lcd[nr - 1][8]); ++ results[3] = *((long *) &data->lcd[nr - 1][12]); ++ *nrels_mag = 4; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ /* ++ Writing a string to line 3 of the LCD can be done like: ++ echo -n "Linux MaxiLife" | od -A n -l > \ ++ /proc/sys/dev/sensors/maxilife-nba-i2c-0-14/lcd3 ++ */ ++ if (*nrels_mag >= 1) ++ *((long *) &data->lcd[nr - 1][0]) = results[0]; ++ if (*nrels_mag >= 2) ++ *((long *) &data->lcd[nr - 1][4]) = results[1]; ++ if (*nrels_mag >= 3) ++ *((long *) &data->lcd[nr - 1][8]) = results[2]; ++ if (*nrels_mag >= 4) ++ *((long *) &data->lcd[nr - 1][12]) = results[3]; ++ maxi_write_token_loop(client, MAXI_TOK_LCD(nr - 1), ++ strlen(data->lcd[nr - 1]) + 1, ++ data->lcd[nr - 1]); ++#if 0 ++ if (*nrels_mag >= 1) ++ printk("nr=%d, result[0] = %.4s\n", nr, ++ (char *) &results[0]); ++ if (*nrels_mag >= 2) ++ printk("nr=%d, result[1] = %.4s\n", nr, ++ (char *) &results[1]); ++ if (*nrels_mag >= 3) ++ printk("nr=%d, result[2] = %.4s\n", nr, ++ (char *) &results[2]); ++ if (*nrels_mag >= 4) ++ printk("nr=%d, result[3] = %.4s\n", nr, ++ (char *) &results[3]); ++#endif ++ } ++ ++} ++ ++void maxi_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct maxi_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ if (data->type == nba) ++ maxi99_update_client(client, alarm, 0); ++ else ++ maxi_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++static int __init sm_maxilife_init(void) ++{ ++ printk("maxilife: Version %s (lm_sensors %s (%s))\n", version_str, ++ LM_VERSION, LM_DATE); ++ return i2c_add_driver(&maxi_driver); ++} ++ ++static void __exit sm_maxilife_exit(void) ++{ ++ i2c_del_driver(&maxi_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Fons Rademakers "); ++MODULE_DESCRIPTION("HP MaxiLife driver"); ++MODULE_PARM(maxi_version, "i"); ++MODULE_PARM_DESC(maxi_version, "MaxiLife firmware version"); ++ ++module_init(sm_maxilife_init); ++module_exit(sm_maxilife_exit); +--- linux-old/drivers/sensors/mtp008.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/mtp008.c Mon Dec 13 20:18:51 2004 +@@ -0,0 +1,1103 @@ ++/* ++ mtp008.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (C) 2001, 2004 Kris Van Hees ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = {SENSORS_I2C_END}; ++static unsigned short normal_i2c_range[] = {0x2c, 0x2e, SENSORS_I2C_END}; ++static unsigned int normal_isa[] = {SENSORS_ISA_END}; ++static unsigned int normal_isa_range[] = {SENSORS_ISA_END}; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(mtp008); ++ ++/* The MTP008 registers */ ++/* in0 .. in6 */ ++#define MTP008_REG_IN(nr) (0x20 + (nr)) ++#define MTP008_REG_IN_MAX(nr) (0x2b + (nr) * 2) ++#define MTP008_REG_IN_MIN(nr) (0x2c + (nr) * 2) ++ ++/* temp1 */ ++#define MTP008_REG_TEMP 0x27 ++#define MTP008_REG_TEMP_MAX 0x39 ++#define MTP008_REG_TEMP_MIN 0x3a ++ ++/* fan1 .. fan3 */ ++#define MTP008_REG_FAN(nr) (0x27 + (nr)) ++#define MTP008_REG_FAN_MIN(nr) (0x3a + (nr)) ++ ++#define MTP008_REG_CONFIG 0x40 ++#define MTP008_REG_INT_STAT1 0x41 ++#define MTP008_REG_INT_STAT2 0x42 ++ ++#define MTP008_REG_SMI_MASK1 0x43 ++#define MTP008_REG_SMI_MASK2 0x44 ++ ++#define MTP008_REG_NMI_MASK1 0x45 ++#define MTP008_REG_NMI_MASK2 0x46 ++ ++#define MTP008_REG_VID_FANDIV 0x47 ++ ++#define MTP008_REG_I2C_ADDR 0x48 ++ ++#define MTP008_REG_RESET_VID4 0x49 ++ ++#define MTP008_REG_OVT_PROP 0x50 ++ ++#define MTP008_REG_BEEP_CTRL1 0x51 ++#define MTP008_REG_BEEP_CTRL2 0x52 ++ ++/* pwm1 .. pwm3 nr range 1-3 */ ++#define MTP008_REG_PWM_CTRL(nr) (0x52 + (nr)) ++ ++#define MTP008_REG_PIN_CTRL1 0x56 ++#define MTP008_REG_PIN_CTRL2 0x57 ++ ++#define MTP008_REG_CHIPID 0x58 ++ ++/* ++ * Pin control register configuration constants. ++ */ ++#define MTP008_CFG_VT1_PII 0x08 ++#define MTP008_CFG_VT2_AIN 0x00 ++#define MTP008_CFG_VT2_VT 0x03 ++#define MTP008_CFG_VT2_PII 0x04 ++#define MTP008_CFG_VT2_MASK 0x06 ++#define MTP008_CFG_VT3_VT 0x01 ++ ++/* sensor pin types */ ++#define VOLTAGE 1 ++#define THERMISTOR 2 ++#define PIIDIODE 3 ++ ++/* ++ * Conversion routines and macros. Limit checking is only done on ++ * the TO_REG variants. ++ * ++ * Note that IN values are expressed as 100 times the actual voltage to avoid ++ * having to use floating point values. As such, IN values are between 0 and ++ * 409 (0V to 4.096V). ++ */ ++#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8) / 16), 0, 255)) ++#define IN_FROM_REG(val) (((val) * 16 + 5) / 10) ++ ++/* ++ * The fan cotation count (as stored in the register) is calculated using the ++ * following formula: ++ * count = (22.5K * 60) / (rpm * div) = 1350000 / (rpm * div) ++ * and the rpm is therefore: ++ * rpm = 1350000 / (count * div) ++ */ ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 255; ++ ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ ++ return SENSORS_LIMIT( ++ (1350000 + rpm * div / 2) / (rpm * div), ++ 1, 254 ++ ); ++} ++ ++#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 \ ++ : (val) == 255 ? 0 \ ++ : 1350000 / \ ++ ((val) * (div)) \ ++ ) ++ ++/* ++ * Temperatures are stored as two's complement values of the Celsius value. It ++ * actually uses 10 times the Celsius value to avoid using floating point ++ * values. ++ */ ++#define TEMP_TO_REG(val) ( \ ++ (val) < 0 \ ++ ? SENSORS_LIMIT(((val) - 5) / 10, 0, 255) \ ++ : SENSORS_LIMIT(((val) + 5) / 10, 0, 255) \ ++ ) ++#define TEMP_FROM_REG(val) ( \ ++ ( \ ++ (val) > 0x80 ? (val) - 0x100 \ ++ : (val) \ ++ ) * 10 \ ++ ) ++ ++/* ++ * VCORE voltage: ++ * 0x00 to 0x0f = 2.05 to 1.30 (0.05 per unit) ++ * 0x10 to 0x1e = 3.50 to 2.10 (0.10 per unit) ++ * 0x1f = No CPU ++ */ ++#define VID_FROM_REG(val) ((val) == 0x1f \ ++ ? 0 \ ++ : (val) < 0x10 ? 205 - (val) * 5 \ ++ : 510 - (val) * 10) ++ ++/* ++ * Fan divider. ++ */ ++#define DIV_FROM_REG(val) (1 << (val)) ++#define DIV_TO_REG(val) ((val) == 8 ? 3 \ ++ : (val) == 4 ? 2 \ ++ : (val) == 2 ? 1 \ ++ : 0) ++ ++/* ++ * Alarms (interrupt status). ++ */ ++#define ALARMS_FROM_REG(val) (val) ++ ++/* ++ * Beep controls. ++ */ ++#define BEEPS_FROM_REG(val) (val) ++#define BEEPS_TO_REG(val) (val) ++ ++/* ++ * PWM control. nr range 1 to 3 ++ */ ++#define PWM_FROM_REG(val) (val) ++#define PWM_TO_REG(val) (val) ++#define PWMENABLE_FROM_REG(nr, val) (((val) >> ((nr) + 3)) & 1) ++ ++/* ++ * For each registered MTP008, we need to keep some data in memory. The ++ * structure itself is dynamically allocated, at the same time when a new ++ * mtp008 client is allocated. ++ */ ++struct mtp008_data { ++ struct i2c_client client; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 in[7]; /* Register value */ ++ u8 in_max[7]; /* Register value */ ++ u8 in_min[7]; /* Register value */ ++ u8 temp; /* Register value */ ++ u8 temp_max; /* Register value */ ++ u8 temp_min; /* Register value */ ++ u8 fan[3]; /* Register value */ ++ u8 fan_min[3]; /* Register value */ ++ u8 vid; /* Register encoding */ ++ u8 fan_div[3]; /* Register encoding */ ++ u16 alarms; /* Register encoding */ ++ u16 beeps; /* Register encoding */ ++ u8 pwm[4]; /* Register value */ ++ u8 sens[3]; /* 1 = Analog input, ++ 2 = Thermistor, ++ 3 = PII/Celeron diode */ ++ u8 pwmenable; /* Register 0x57 value */ ++}; ++ ++static int mtp008_attach_adapter(struct i2c_adapter *adapter); ++static int mtp008_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int mtp008_detach_client(struct i2c_client *client); ++ ++static int mtp008_read_value(struct i2c_client *client, u8 register); ++static int mtp008_write_value(struct i2c_client *client, u8 register, u8 value); ++static void mtp008_update_client(struct i2c_client *client); ++static void mtp008_init_client(struct i2c_client *client); ++ ++static void mtp008_in(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void mtp008_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void mtp008_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void mtp008_temp_add(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void mtp008_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void mtp008_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void mtp008_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void mtp008_beep(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void mtp008_pwm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void mtp008_sens(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void mtp008_getsensortype(struct mtp008_data *data, u8 inp); ++ ++static int mtp008_id = 0; ++ ++static struct i2c_driver mtp008_driver = ++{ ++ .owner = THIS_MODULE, ++ .name = "MTP008 sensor driver", ++ .id = I2C_DRIVERID_MTP008, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = mtp008_attach_adapter, ++ .detach_client = mtp008_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++#define MTP008_SYSCTL_IN0 1000 /* Volts * 100 */ ++#define MTP008_SYSCTL_IN1 1001 ++#define MTP008_SYSCTL_IN2 1002 ++#define MTP008_SYSCTL_IN3 1003 ++#define MTP008_SYSCTL_IN4 1004 ++#define MTP008_SYSCTL_IN5 1005 ++#define MTP008_SYSCTL_IN6 1006 ++#define MTP008_SYSCTL_FAN1 1101 /* Rotations/min */ ++#define MTP008_SYSCTL_FAN2 1102 ++#define MTP008_SYSCTL_FAN3 1103 ++#define MTP008_SYSCTL_TEMP1 1200 /* Degrees Celcius * 10 */ ++#define MTP008_SYSCTL_TEMP2 1201 /* Degrees Celcius * 10 */ ++#define MTP008_SYSCTL_TEMP3 1202 /* Degrees Celcius * 10 */ ++#define MTP008_SYSCTL_VID 1300 /* Volts * 100 */ ++#define MTP008_SYSCTL_PWM1 1401 ++#define MTP008_SYSCTL_PWM2 1402 ++#define MTP008_SYSCTL_PWM3 1403 ++#define MTP008_SYSCTL_SENS1 1501 /* 1, 2, or Beta (3000-5000) */ ++#define MTP008_SYSCTL_SENS2 1502 ++#define MTP008_SYSCTL_SENS3 1503 ++#define MTP008_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define MTP008_SYSCTL_ALARMS 2001 /* bitvector */ ++#define MTP008_SYSCTL_BEEP 2002 /* bitvector */ ++ ++#define MTP008_ALARM_IN0 0x0001 ++#define MTP008_ALARM_IN1 0x0002 ++#define MTP008_ALARM_IN2 0x0004 ++#define MTP008_ALARM_IN3 0x0008 ++#define MTP008_ALARM_IN4 0x0100 ++#define MTP008_ALARM_IN5 0x0200 ++#define MTP008_ALARM_IN6 0x0400 ++#define MTP008_ALARM_FAN1 0x0040 ++#define MTP008_ALARM_FAN2 0x0080 ++#define MTP008_ALARM_FAN3 0x0800 ++#define MTP008_ALARM_TEMP1 0x0010 ++#define MTP008_ALARM_TEMP2 0x0100 ++#define MTP008_ALARM_TEMP3 0x0200 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* The /proc/sys entries */ ++/* These files are created for each detected chip. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++ ++static ctl_table mtp008_dir_table_template[] = ++{ ++ {MTP008_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_in}, ++ {MTP008_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_in}, ++ {MTP008_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_in}, ++ {MTP008_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_in}, ++ {MTP008_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_in}, ++ {MTP008_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_in}, ++ {MTP008_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_in}, ++ {MTP008_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_fan}, ++ {MTP008_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_fan}, ++ {MTP008_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_fan}, ++ {MTP008_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_temp}, ++ {MTP008_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_temp_add}, ++ {MTP008_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_temp_add}, ++ {MTP008_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_vid}, ++ {MTP008_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_fan_div}, ++ {MTP008_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_alarms}, ++ {MTP008_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_beep}, ++ {MTP008_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_pwm}, ++ {MTP008_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_pwm}, ++ {MTP008_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_pwm}, ++ {MTP008_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_sens}, ++ {MTP008_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_sens}, ++ {MTP008_SYSCTL_SENS3, "sensor3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &mtp008_sens}, ++ {0} ++}; ++ ++/* This function is called when: ++ * mtp008_driver is inserted (when this module is loaded), for each available ++ * adapter when a new adapter is inserted (and mtp008_driver is still present) ++ */ ++static int mtp008_attach_adapter(struct i2c_adapter *adapter) ++{ ++ struct i2c_client_address_data mtp008_addr_data; ++ ++ mtp008_addr_data.normal_i2c = addr_data.normal_i2c; ++ mtp008_addr_data.normal_i2c_range = addr_data.normal_i2c_range; ++ mtp008_addr_data.probe = addr_data.probe; ++ mtp008_addr_data.probe_range = addr_data.probe_range; ++ mtp008_addr_data.ignore = addr_data.ignore; ++ mtp008_addr_data.ignore_range = addr_data.ignore_range; ++ mtp008_addr_data.force = addr_data.forces->force; ++ ++ return i2c_probe(adapter, &mtp008_addr_data, mtp008_detect); ++} ++ ++int mtp008_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ const char *type_name = ""; ++ const char *client_name = ""; ++ int is_isa, err, sysid; ++ struct i2c_client *new_client; ++ struct mtp008_data *data; ++ ++ err = 0; ++ ++ is_isa = i2c_is_isa_adapter(adapter); ++ if (is_isa || ++ !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* ++ * We presume we have a valid client. We now create the client ++ * structure, even though we cannot fill it completely yet. But it ++ * allows us to use mtp008_(read|write)_value(). ++ */ ++ if (!(data = kmalloc(sizeof(struct mtp008_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &mtp008_driver; ++ new_client->flags = 0; ++ ++ /* ++ * Remaining detection. ++ */ ++ if (kind < 0) { ++ if (mtp008_read_value(new_client, MTP008_REG_CHIPID) != 0xac) ++ goto ERROR1; ++ } ++ /* ++ * Fill in the remaining client fields and put it into the global list. ++ */ ++ type_name = "mtp008"; ++ client_name = "MTP008 chip"; ++ strcpy(new_client->name, client_name); ++ data->type = kind; ++ ++ new_client->id = mtp008_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* ++ * Tell the I2C layer that a new client has arrived. ++ */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR1; ++ ++ /* ++ * Register a new directory entry with the sensors module. ++ */ ++ if ((sysid = i2c_register_entry(new_client, type_name, ++ mtp008_dir_table_template)) < 0) { ++ err = sysid; ++ goto ERROR2; ++ } ++ data->sysctl_id = sysid; ++ ++ /* ++ * Initialize the MTP008 chip. ++ */ ++ mtp008_init_client(new_client); ++ ++ return 0; ++ ++ /* ++ * Error handling. Bad programming practise but very code efficient. ++ */ ++ ERROR2: ++ i2c_detach_client(new_client); ++ ERROR1: ++ kfree(data); ++ ++ ERROR0: ++ return err; ++} ++ ++static int mtp008_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry( ++ ((struct mtp008_data *) (client->data))->sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk("mtp008.o: Deregistration failed, " ++ "client not detached.\n"); ++ return err; ++ } ++ kfree(client->data); ++ ++ return 0; ++} ++ ++ ++static int mtp008_read_value(struct i2c_client *client, u8 reg) ++{ ++ return i2c_smbus_read_byte_data(client, reg) & 0xff; ++} ++ ++static int mtp008_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++/* Called when we have found a new MTP008. It should set limits, etc. */ ++static void mtp008_init_client(struct i2c_client *client) ++{ ++ u8 save1, save2; ++ struct mtp008_data *data; ++ ++ data = client->data; ++ ++ /* ++ * Initialize the Myson MTP008 hardware monitoring chip. ++ * Save the pin settings that the BIOS hopefully set. ++ */ ++ save1 = mtp008_read_value(client, MTP008_REG_PIN_CTRL1); ++ save2 = mtp008_read_value(client, MTP008_REG_PIN_CTRL2); ++ mtp008_write_value(client, MTP008_REG_CONFIG, ++ (mtp008_read_value(client, MTP008_REG_CONFIG) & 0x7f) | 0x80); ++ mtp008_write_value(client, MTP008_REG_PIN_CTRL1, save1); ++ mtp008_write_value(client, MTP008_REG_PIN_CTRL2, save2); ++ ++ mtp008_getsensortype(data, save2); ++ ++ ++ /* ++ * Start monitoring. ++ */ ++ mtp008_write_value( ++ client, MTP008_REG_CONFIG, ++ (mtp008_read_value(client, MTP008_REG_CONFIG) & 0xf7) | 0x01 ++ ); ++} ++ ++static void mtp008_update_client(struct i2c_client *client) ++{ ++ int i; ++ u8 inp; ++ struct mtp008_data *data; ++ ++ data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++#ifdef DEBUG ++ printk("Starting MTP008 update\n"); ++#endif ++ ++ /* ++ * Read in the analog inputs. We're reading AIN4 and AIN5 as ++ * regular analog inputs, even though they may have been ++ * configured as temperature readings instead. Interpretation ++ * of these values is done elsewhere. ++ */ ++ for (i = 0; i < 7; i++) { ++ data->in[i] = ++ mtp008_read_value(client, MTP008_REG_IN(i)); ++ data->in_max[i] = ++ mtp008_read_value(client, MTP008_REG_IN_MAX(i)); ++ data->in_min[i] = ++ mtp008_read_value(client, MTP008_REG_IN_MIN(i)); ++ } ++ ++ /* ++ * Read the temperature sensor. ++ */ ++ data->temp = mtp008_read_value(client, MTP008_REG_TEMP); ++ data->temp_max = mtp008_read_value(client, MTP008_REG_TEMP_MAX); ++ data->temp_min = mtp008_read_value(client, MTP008_REG_TEMP_MIN); ++ ++ /* ++ * Read the first 2 fan dividers and the VID setting. Read the ++ * third fan divider from a different register. ++ */ ++ inp = mtp008_read_value(client, MTP008_REG_VID_FANDIV); ++ data->vid = inp & 0x0f; ++ data->vid |= (mtp008_read_value(client, ++ MTP008_REG_RESET_VID4) & 0x01) << 4; ++ ++ data->fan_div[0] = (inp >> 4) & 0x03; ++ data->fan_div[1] = inp >> 6; ++ data->fan_div[2] = ++ mtp008_read_value(client, MTP008_REG_PIN_CTRL1) >> 6; ++ ++ /* ++ * Read the interrupt status registers. ++ */ ++ data->alarms = ++ (mtp008_read_value(client, ++ MTP008_REG_INT_STAT1) & 0xdf) | ++ (mtp008_read_value(client, ++ MTP008_REG_INT_STAT2) & 0x0f) << 8; ++ ++ /* ++ * Read the beep control registers. ++ */ ++ data->beeps = ++ (mtp008_read_value(client, ++ MTP008_REG_BEEP_CTRL1) & 0xdf) | ++ (mtp008_read_value(client, ++ MTP008_REG_BEEP_CTRL2) & 0x8f) << 8; ++ ++ /* ++ * Read the sensor configuration. ++ */ ++ inp = mtp008_read_value(client, MTP008_REG_PIN_CTRL2); ++ mtp008_getsensortype(data, inp); ++ data->pwmenable = inp; ++ ++ /* ++ * Read the PWM registers if enabled. ++ */ ++ for (i = 1; i <= 3; i++) ++ { ++ if(PWMENABLE_FROM_REG(i, inp)) ++ data->pwm[i-1] = mtp008_read_value(client, ++ MTP008_REG_PWM_CTRL(i)); ++ else ++ data->pwm[i-1] = 255; ++ } ++ ++ /* ++ * Read the fan sensors. Skip 3 if PWM1 enabled. ++ */ ++ for (i = 1; i <= 3; i++) { ++ if(i == 3 && PWMENABLE_FROM_REG(1, inp)) { ++ data->fan[2] = 0; ++ data->fan_min[2] = 0; ++ } else { ++ data->fan[i-1] = mtp008_read_value(client, ++ MTP008_REG_FAN(i)); ++ data->fan_min[i-1] = mtp008_read_value(client, ++ MTP008_REG_FAN_MIN(i)); ++ } ++ } ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ up(&data->update_lock); ++} ++ ++static void mtp008_getsensortype(struct mtp008_data *data, u8 inp) ++{ ++ inp &= 0x0f; ++ data->sens[0] = (inp >> 3) + 2; /* 2 or 3 */ ++ data->sens[1] = ((inp >> 1) & 0x03) + 1; /* 1, 2 or 3 */ ++ data->sens[2] = (inp & 0x01) + 1; /* 1 or 2 */ ++} ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the date ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++void mtp008_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ int nr; ++ struct mtp008_data *data; ++ ++ nr = ctl_name - MTP008_SYSCTL_IN0; ++ data = client->data; ++ ++ switch (operation) { ++ case SENSORS_PROC_REAL_INFO: ++ *nrels_mag = 2; ++ ++ break; ++ case SENSORS_PROC_REAL_READ: ++ mtp008_update_client(client); ++ ++ if((nr != 4 && nr != 5) || data->sens[nr - 3] == VOLTAGE) { ++ results[0] = IN_FROM_REG(data->in_min[nr]); ++ results[1] = IN_FROM_REG(data->in_max[nr]); ++ results[2] = IN_FROM_REG(data->in[nr]); ++ } else { ++ results[0] = 0; ++ results[1] = 0; ++ results[2] = 0; ++ } ++ ++ *nrels_mag = 3; ++ ++ break; ++ case SENSORS_PROC_REAL_WRITE: ++ if((nr != 4 && nr != 5) || data->sens[nr - 3] == VOLTAGE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = IN_TO_REG(results[0]); ++ mtp008_write_value(client, MTP008_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = IN_TO_REG(results[1]); ++ mtp008_write_value(client, MTP008_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++ } ++} ++ ++void mtp008_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ int nr; ++ struct mtp008_data *data; ++ ++ nr = ctl_name - MTP008_SYSCTL_FAN1; ++ data = client->data; ++ ++ switch (operation) { ++ case SENSORS_PROC_REAL_INFO: ++ *nrels_mag = 0; ++ ++ break; ++ case SENSORS_PROC_REAL_READ: ++ mtp008_update_client(client); ++ ++ results[0] = FAN_FROM_REG(data->fan_min[nr], ++ DIV_FROM_REG(data->fan_div[nr])); ++ results[1] = FAN_FROM_REG(data->fan[nr], ++ DIV_FROM_REG(data->fan_div[nr])); ++ ++ *nrels_mag = 2; ++ ++ break; ++ case SENSORS_PROC_REAL_WRITE: ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr] = ++ FAN_TO_REG(results[0], ++ DIV_FROM_REG(data->fan_div[nr])); ++ mtp008_write_value(client, MTP008_REG_FAN_MIN(nr + 1), ++ data->fan_min[nr]); ++ } ++ } ++} ++ ++void mtp008_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct mtp008_data *data; ++ ++ data = client->data; ++ ++ switch (operation) { ++ case SENSORS_PROC_REAL_INFO: ++ *nrels_mag = 1; ++ ++ break; ++ case SENSORS_PROC_REAL_READ: ++ mtp008_update_client(client); ++ ++ results[0] = TEMP_FROM_REG(data->temp_max); ++ results[1] = TEMP_FROM_REG(data->temp_min); ++ results[2] = TEMP_FROM_REG(data->temp); ++ *nrels_mag = 3; ++ ++ break; ++ case SENSORS_PROC_REAL_WRITE: ++ if (*nrels_mag >= 1) { ++ data->temp_max = TEMP_TO_REG(results[0]); ++ mtp008_write_value(client, MTP008_REG_TEMP_MAX, ++ data->temp_max); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_min = TEMP_TO_REG(results[1]); ++ mtp008_write_value(client, MTP008_REG_TEMP_MIN, ++ data->temp_min); ++ } ++ } ++} ++ ++void mtp008_temp_add(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ int nr; ++ struct mtp008_data *data; ++ ++ nr = 3 + ctl_name - MTP008_SYSCTL_TEMP1; /* AIN4 or AIN5 */ ++ data = client->data; ++ ++ switch (operation) { ++ case SENSORS_PROC_REAL_INFO: ++ *nrels_mag = 1; ++ ++ break; ++ case SENSORS_PROC_REAL_READ: ++ mtp008_update_client(client); ++ ++ if(data->sens[nr - 3] != VOLTAGE) { ++ results[0] = TEMP_FROM_REG(data->in_max[nr]); ++ results[1] = TEMP_FROM_REG(data->in_min[nr]); ++ results[2] = TEMP_FROM_REG(data->in[nr]); ++ } else { ++ results[0] = 0; ++ results[1] = 0; ++ results[2] = 0; ++ } ++ *nrels_mag = 3; ++ ++ break; ++ case SENSORS_PROC_REAL_WRITE: ++ if(data->sens[nr - 3] != VOLTAGE) { ++ if (*nrels_mag >= 1) { ++ data->in_max[nr] = TEMP_TO_REG(results[0]); ++ mtp008_write_value(client, ++ MTP008_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_min[nr] = TEMP_TO_REG(results[1]); ++ mtp008_write_value(client, ++ MTP008_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ } ++ } ++} ++ ++void mtp008_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct mtp008_data *data; ++ ++ data = client->data; ++ ++ switch (operation) { ++ case SENSORS_PROC_REAL_INFO: ++ *nrels_mag = 2; ++ ++ break; ++ case SENSORS_PROC_REAL_READ: ++ mtp008_update_client(client); ++ ++ results[0] = VID_FROM_REG(data->vid); ++ ++ *nrels_mag = 1; ++ } ++} ++ ++void mtp008_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct mtp008_data *data; ++ u8 val; ++ ++ data = client->data; ++ ++ switch (operation) { ++ case SENSORS_PROC_REAL_INFO: ++ *nrels_mag = 0; ++ ++ break; ++ case SENSORS_PROC_REAL_READ: ++ mtp008_update_client(client); ++ ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ results[2] = DIV_FROM_REG(data->fan_div[2]); ++ ++ *nrels_mag = 3; ++ ++ break; ++ case SENSORS_PROC_REAL_WRITE: ++ if (*nrels_mag >= 3) { ++ data->fan_div[2] = DIV_TO_REG(results[2]); ++ val = mtp008_read_value(client, MTP008_REG_PIN_CTRL1); ++ val = (val & 0x3f) | (data->fan_div[2] & 0x03) << 6; ++ mtp008_write_value(client, MTP008_REG_PIN_CTRL1, val); ++ } ++ if (*nrels_mag >= 1) { ++ val = mtp008_read_value(client, MTP008_REG_VID_FANDIV); ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ val = (val & 0x3f) | ++ (data->fan_div[1] & 0x03) << 6; ++ } ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ val = (val & 0xcf) | (data->fan_div[0] & 0x03) << 4; ++ mtp008_write_value(client, MTP008_REG_VID_FANDIV, val); ++ } ++ } ++} ++ ++void mtp008_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct mtp008_data *data; ++ ++ data = client->data; ++ ++ switch (operation) { ++ case SENSORS_PROC_REAL_INFO: ++ *nrels_mag = 0; ++ ++ break; ++ case SENSORS_PROC_REAL_READ: ++ mtp008_update_client(client); ++ ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ ++ *nrels_mag = 1; ++ } ++} ++ ++void mtp008_beep(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct mtp008_data *data; ++ ++ data = client->data; ++ ++ switch (operation) { ++ case SENSORS_PROC_REAL_INFO: ++ *nrels_mag = 0; ++ ++ break; ++ case SENSORS_PROC_REAL_READ: ++ mtp008_update_client(client); ++ ++ results[0] = BEEPS_FROM_REG(data->beeps); ++ ++ *nrels_mag = 1; ++ ++ break; ++ case SENSORS_PROC_REAL_WRITE: ++ if (*nrels_mag >= 1) { ++ data->beeps = BEEPS_TO_REG(results[0]) & 0xdf8f; ++ ++ mtp008_write_value(client, MTP008_REG_BEEP_CTRL1, ++ data->beeps & 0xff); ++ mtp008_write_value(client, MTP008_REG_BEEP_CTRL2, ++ data->beeps >> 8); ++ } ++ } ++} ++ ++void mtp008_pwm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ int nr; ++ struct mtp008_data *data; ++ ++ nr = ctl_name - MTP008_SYSCTL_PWM1; ++ data = client->data; ++ ++ switch (operation) { ++ case SENSORS_PROC_REAL_INFO: ++ *nrels_mag = 0; ++ ++ break; ++ case SENSORS_PROC_REAL_READ: ++ mtp008_update_client(client); ++ ++ results[0] = PWM_FROM_REG(data->pwm[nr]); ++ results[1] = PWMENABLE_FROM_REG(nr + 1, data->pwmenable); ++ *nrels_mag = 2; ++ ++ break; ++ case SENSORS_PROC_REAL_WRITE: ++ if (*nrels_mag >= 1) { ++ if (*nrels_mag >= 2) { ++ if(results[1]) ++ data->pwmenable |= 0x10 << nr; ++ else ++ data->pwmenable &= ~(0x10 << nr); ++ mtp008_write_value(client, MTP008_REG_PIN_CTRL2, ++ data->pwmenable); ++ } ++ data->pwm[nr] = PWM_TO_REG(results[0]); ++ mtp008_write_value(client, MTP008_REG_PWM_CTRL(nr), ++ data->pwm[nr]); ++ } ++ } ++} ++ ++void mtp008_sens(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ const char *opts = ""; ++ int nr; ++ u8 tmp; ++ struct mtp008_data *data; ++ ++ nr = 1 + ctl_name - MTP008_SYSCTL_SENS1; ++ data = client->data; ++ ++ switch (operation) { ++ case SENSORS_PROC_REAL_INFO: ++ *nrels_mag = 0; ++ ++ break; ++ case SENSORS_PROC_REAL_READ: ++ results[0] = data->sens[nr - 1]; ++ ++ *nrels_mag = 1; ++ ++ break; ++ case SENSORS_PROC_REAL_WRITE: ++ if (*nrels_mag >= 1) { ++ tmp = mtp008_read_value(client, MTP008_REG_PIN_CTRL2); ++ ++ switch (nr) { ++ case 1: /* VT or PII */ ++ opts = "2 or 3"; ++ ++ switch (results[0]) { ++ case THERMISTOR: ++ mtp008_write_value( ++ client, MTP008_REG_PIN_CTRL2, ++ tmp & ~MTP008_CFG_VT1_PII); ++ data->sens[0] = 2; ++ return; ++ case PIIDIODE: ++ mtp008_write_value( ++ client, MTP008_REG_PIN_CTRL2, ++ tmp | MTP008_CFG_VT1_PII); ++ data->sens[0] = 3; ++ return; ++ } ++ ++ break; ++ case 2: /* AIN, VT or PII */ ++ tmp &= ~MTP008_CFG_VT2_MASK; ++ opts = "1, 2 or 3"; ++ ++ switch (results[0]) { ++ case VOLTAGE: ++ mtp008_write_value( ++ client, MTP008_REG_PIN_CTRL2, ++ tmp | MTP008_CFG_VT2_AIN); ++ data->sens[1] = 1; ++ return; ++ case THERMISTOR: ++ mtp008_write_value( ++ client, MTP008_REG_PIN_CTRL2, ++ tmp | MTP008_CFG_VT2_VT); ++ data->sens[1] = 2; ++ return; ++ case PIIDIODE: ++ mtp008_write_value( ++ client, MTP008_REG_PIN_CTRL2, ++ tmp | MTP008_CFG_VT2_PII); ++ data->sens[1] = 3; ++ return; ++ } ++ ++ break; ++ case 3: /* AIN or VT */ ++ opts = "1 or 2"; ++ ++ switch (results[0]) { ++ case VOLTAGE: ++ mtp008_write_value( ++ client, MTP008_REG_PIN_CTRL2, ++ tmp & ~MTP008_CFG_VT3_VT); ++ data->sens[2] = 1; ++ return; ++ case THERMISTOR: ++ mtp008_write_value( ++ client, MTP008_REG_PIN_CTRL2, ++ tmp | MTP008_CFG_VT3_VT); ++ data->sens[2] = 2; ++ return; ++ } ++ ++ break; ++ } ++ ++ printk("mtp008.o: Invalid sensor type %ld " ++ "for sensor %d; must be %s.\n", ++ results[0], nr, opts); ++ } ++ } ++} ++ ++static int __init sm_mtp008_init(void) ++{ ++ printk("mtp008.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&mtp008_driver); ++} ++ ++static void __exit sm_mtp008_exit(void) ++{ ++ i2c_del_driver(&mtp008_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Frodo Looijaard , " ++ "Philip Edelbrock , " ++ "and Kris Van Hees "); ++MODULE_DESCRIPTION("MTP008 driver"); ++ ++module_init(sm_mtp008_init); ++module_exit(sm_mtp008_exit); +--- linux-old/drivers/sensors/pc87360.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/pc87360.c Mon Dec 13 20:18:51 2004 +@@ -0,0 +1,1357 @@ ++/* ++ * pc87360.c - Part of lm_sensors, Linux kernel modules ++ * for hardware monitoring ++ * Copyright (C) 2004 Jean Delvare ++ * ++ * Copied from smsc47m1.c: ++ * Copyright (C) 2002 Mark D. Studebaker ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ * Supports the following chips: ++ * ++ * Chip #vin #fan #pwm #temp devid ++ * PC87360 - 2 2 - 0xE1 ++ * PC87363 - 2 2 - 0xE8 ++ * PC87364 - 3 3 - 0xE4 ++ * PC87365 11 3 3 2 0xE5 ++ * PC87366 11 3 3 3-4 0xE9 ++ * ++ * This driver assumes that no more than one chip is present, and the ++ * standard Super-I/O address is used (0x2E/0x2F). ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { 0x0000, SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++static struct i2c_force_data forces[] = {{NULL}}; ++static u8 devid; ++static unsigned int extra_isa[] = { 0x0000, 0x0000, 0x0000 }; ++static u8 confreg[4]; ++ ++enum chips { any_chip, pc87360, pc87363, pc87364, pc87365, pc87366 }; ++static struct i2c_address_data addr_data = { ++ .normal_i2c = normal_i2c, ++ .normal_i2c_range = normal_i2c_range, ++ .normal_isa = normal_isa, ++ .normal_isa_range = normal_isa_range, ++ .probe = normal_i2c, /* cheat */ ++ .probe_range = normal_i2c_range, /* cheat */ ++ .ignore = normal_i2c, /* cheat */ ++ .ignore_range = normal_i2c_range, /* cheat */ ++ .forces = forces, ++}; ++ ++static int init = 1; ++MODULE_PARM(init, "i"); ++MODULE_PARM_DESC(init, ++ "Chip initialization level:\n" ++ " 0: None\n" ++ "*1: Forcibly enable internal voltage and temperature channels, except in9\n" ++ " 2: Forcibly enable all voltage and temperature channels, except in9\n" ++ " 3: Forcibly enable all voltage and temperature channels, including in9"); ++ ++/* ++ * Super-I/O registers and operations ++ */ ++ ++#define REG 0x2e /* The register to read/write */ ++#define VAL 0x2f /* The value to read/write */ ++ ++#define DEV 0x07 /* Register: Logical device select */ ++#define DEVID 0x20 /* Register: Device ID */ ++#define ACT 0x30 /* Register: Device activation */ ++#define BASE 0x60 /* Register: Base address */ ++ ++#define FSCM 0x09 /* Logical device: fans */ ++#define VLM 0x0d /* Logical device: voltages */ ++#define TMS 0x0e /* Logical device: temperatures */ ++static const u8 logdev[3] = { FSCM, VLM, TMS }; ++ ++#define LD_FAN 0 ++#define LD_IN 1 ++#define LD_TEMP 2 ++ ++static inline void superio_outb(int reg, int val) ++{ ++ outb(reg, REG); ++ outb(val, VAL); ++} ++ ++static inline int superio_inb(int reg) ++{ ++ outb(reg, REG); ++ return inb(VAL); ++} ++ ++static inline void superio_exit(void) ++{ ++ outb(0x02, REG); ++ outb(0x02, VAL); ++} ++ ++/* ++ * Logical devices ++ */ ++ ++#define PC87360_EXTENT 0x10 ++#define PC87365_REG_BANK 0x09 ++#define NO_BANK 0xff ++ ++/* ++ * Fan registers and conversions ++ */ ++ ++/* nr has to be 0 or 1 (PC87360/87363) or 2 (PC87364/87365/87366) */ ++#define PC87360_REG_PRESCALE(nr) (0x00 + 2 * (nr)) ++#define PC87360_REG_PWM(nr) (0x01 + 2 * (nr)) ++#define PC87360_REG_FAN_MIN(nr) (0x06 + 3 * (nr)) ++#define PC87360_REG_FAN(nr) (0x07 + 3 * (nr)) ++#define PC87360_REG_FAN_STATUS(nr) (0x08 + 3 * (nr)) ++ ++#define FAN_FROM_REG(val,div) ((val)==0?0: \ ++ 480000/((val)*(div))) ++#define FAN_TO_REG(val,div) ((val)<=100?0: \ ++ 480000/((val)*(div))) ++#define FAN_DIV_FROM_REG(val) (1 << ((val >> 5) & 0x03)) ++#define FAN_DIV_TO_REG(val) ((val)==8?0x60:(val)==4?0x40: \ ++ (val)==1?0x00:0x20) ++#define FAN_STATUS_FROM_REG(val) ((val) & 0x07) ++ ++#define FAN_CONFIG_MONITOR(val,nr) (((val) >> (2 + nr * 3)) & 1) ++#define FAN_CONFIG_CONTROL(val,nr) (((val) >> (3 + nr * 3)) & 1) ++#define FAN_CONFIG_INVERT(val,nr) (((val) >> (4 + nr * 3)) & 1) ++ ++#define PWM_FROM_REG(val,inv) ((inv) ? 255 - (val) : (val)) ++static inline u8 PWM_TO_REG(int val, int inv) ++{ ++ if (inv) ++ val = 255 - val; ++ if (val < 0) ++ return 0; ++ if (val > 255) ++ return 255; ++ return val; ++} ++ ++/* ++ * Voltage registers and conversions ++ */ ++ ++#define PC87365_REG_IN_CONVRATE 0x07 ++#define PC87365_REG_IN_CONFIG 0x08 ++#define PC87365_REG_IN 0x0B ++#define PC87365_REG_IN_MIN 0x0D ++#define PC87365_REG_IN_MAX 0x0C ++#define PC87365_REG_IN_STATUS 0x0A ++#define PC87365_REG_IN_ALARMS1 0x00 ++#define PC87365_REG_IN_ALARMS2 0x01 ++#define PC87365_REG_VID 0x06 ++ ++#define IN_FROM_REG(val,ref) (((val) * (ref) + 128) / 256) ++#define IN_TO_REG(val,ref) ((val)<0 ? 0 : \ ++ (val)*256>=(ref)*255 ? 255: \ ++ ((val) * 256 + (ref) / 2) / (ref)) ++ ++/* ++ * Temperature registers and conversions ++ */ ++ ++#define PC87365_REG_TEMP_CONFIG 0x08 ++#define PC87365_REG_TEMP 0x0B ++#define PC87365_REG_TEMP_MIN 0x0D ++#define PC87365_REG_TEMP_MAX 0x0C ++#define PC87365_REG_TEMP_CRIT 0x0E ++#define PC87365_REG_TEMP_STATUS 0x0A ++#define PC87365_REG_TEMP_ALARMS 0x00 ++ ++#define TEMP_FROM_REG(val) ((val)&0x80 ? (val) - 0x100 : (val)) ++#define TEMP_TO_REG(val) ((val)<-55 ? 201 : (val)>127 ? 0x7F : \ ++ (val)<0 ? (val) + 0x100 : (val)) ++ ++struct pc87360_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ int address[3]; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 fannr, innr, tempnr; ++ ++ u8 fan[3]; /* Register value */ ++ u8 fan_min[3]; /* Register value */ ++ u8 fan_status[3]; /* Register value */ ++ u8 pwm[3]; /* Register value */ ++ u16 fan_conf; /* Configuration register values, combined */ ++ ++ u16 in_vref; /* 10mV/bit */ ++ u8 in[14]; /* Register value */ ++ u8 in_min[14]; /* Register value */ ++ u8 in_max[14]; /* Register value */ ++ u8 in_crit[3]; /* Register value */ ++ u8 in_status[14]; /* Register value */ ++ u16 in_alarms; /* Register values, combined, masked */ ++ u8 vid_conf; /* Configuration register value */ ++ u8 vrm; ++ u8 vid; /* Register value */ ++ ++ u8 temp[3]; /* Register value */ ++ u8 temp_min[3]; /* Register value */ ++ u8 temp_max[3]; /* Register value */ ++ u8 temp_crit[3]; /* Register value */ ++ u8 temp_status[3]; /* Register value */ ++ u8 temp_alarms; /* Register value, masked */ ++}; ++ ++ ++static int pc87360_attach_adapter(struct i2c_adapter *adapter); ++static int pc87360_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int pc87360_detach_client(struct i2c_client *client); ++ ++static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank, ++ u8 reg); ++static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, ++ u8 reg, u8 value); ++static void pc87360_init_client(struct i2c_client *client, int use_thermistors); ++static void pc87360_update_client(struct i2c_client *client); ++static int pc87360_find(u8 *devid, int *address); ++ ++ ++void pc87365_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++ ++static void pc87360_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void pc87360_fan_status(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void pc87360_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void pc87360_pwm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++void pc87365_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++void pc87365_in_status(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++void pc87365_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++void pc87365_vrm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++ ++void pc87365_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++void pc87365_temp_status(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results); ++ ++static int pc87360_id = 0; ++ ++static struct i2c_driver pc87360_driver = { ++ .owner = THIS_MODULE, ++ .name = "PC8736x hardware monitor", ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = pc87360_attach_adapter, ++ .detach_client = pc87360_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define PC87365_SYSCTL_ALARMS 100 /* bit field */ ++ ++#define PC87360_SYSCTL_FAN1 1101 /* Rotations/min */ ++#define PC87360_SYSCTL_FAN2 1102 ++#define PC87360_SYSCTL_FAN3 1103 /* not for PC87360/PC87363 */ ++#define PC87360_SYSCTL_FAN_DIV 1201 /* 1, 2, 4 or 8 */ ++#define PC87360_SYSCTL_FAN1_STATUS 1301 /* bit field */ ++#define PC87360_SYSCTL_FAN2_STATUS 1302 ++#define PC87360_SYSCTL_FAN3_STATUS 1303 /* not for PC87360/PC87363 */ ++#define PC87360_SYSCTL_PWM1 1401 /* 0-255 */ ++#define PC87360_SYSCTL_PWM2 1402 ++#define PC87360_SYSCTL_PWM3 1403 /* not for PC87360/PC87363 */ ++ ++#define PC87360_STATUS_FAN_READY 0x01 ++#define PC87360_STATUS_FAN_LOW 0x02 ++#define PC87360_STATUS_FAN_OVERFLOW 0x04 ++ ++#define PC87365_SYSCTL_IN0 2100 /* mV */ ++#define PC87365_SYSCTL_IN1 2101 ++#define PC87365_SYSCTL_IN2 2102 ++#define PC87365_SYSCTL_IN3 2103 ++#define PC87365_SYSCTL_IN4 2104 ++#define PC87365_SYSCTL_IN5 2105 ++#define PC87365_SYSCTL_IN6 2106 ++#define PC87365_SYSCTL_IN7 2107 ++#define PC87365_SYSCTL_IN8 2108 ++#define PC87365_SYSCTL_IN9 2109 ++#define PC87365_SYSCTL_IN10 2110 ++#define PC87365_SYSCTL_TEMP4 2111 /* not for PC87365 */ ++#define PC87365_SYSCTL_TEMP5 2112 /* not for PC87365 */ ++#define PC87365_SYSCTL_TEMP6 2113 /* not for PC87365 */ ++#define PC87365_SYSCTL_IN0_STATUS 2300 /* bit field */ ++#define PC87365_SYSCTL_IN1_STATUS 2301 ++#define PC87365_SYSCTL_IN2_STATUS 2302 ++#define PC87365_SYSCTL_IN3_STATUS 2303 ++#define PC87365_SYSCTL_IN4_STATUS 2304 ++#define PC87365_SYSCTL_IN5_STATUS 2305 ++#define PC87365_SYSCTL_IN6_STATUS 2306 ++#define PC87365_SYSCTL_IN7_STATUS 2307 ++#define PC87365_SYSCTL_IN8_STATUS 2308 ++#define PC87365_SYSCTL_IN9_STATUS 2309 ++#define PC87365_SYSCTL_IN10_STATUS 2310 ++#define PC87365_SYSCTL_TEMP4_STATUS 2311 /* not for PC87365 */ ++#define PC87365_SYSCTL_TEMP5_STATUS 2312 /* not for PC87365 */ ++#define PC87365_SYSCTL_TEMP6_STATUS 2313 /* not for PC87365 */ ++ ++#define PC87365_SYSCTL_VID 2400 ++#define PC87365_SYSCTL_VRM 2401 ++ ++#define PC87365_STATUS_IN_MIN 0x02 ++#define PC87365_STATUS_IN_MAX 0x04 ++ ++#define PC87365_SYSCTL_TEMP1 3101 /* degrees Celcius */ ++#define PC87365_SYSCTL_TEMP2 3102 ++#define PC87365_SYSCTL_TEMP3 3103 /* not for PC87365 */ ++#define PC87365_SYSCTL_TEMP1_STATUS 3301 /* bit field */ ++#define PC87365_SYSCTL_TEMP2_STATUS 3302 ++#define PC87365_SYSCTL_TEMP3_STATUS 3303 /* not for PC87365 */ ++ ++#define PC87365_STATUS_TEMP_MIN 0x02 ++#define PC87365_STATUS_TEMP_MAX 0x04 ++#define PC87365_STATUS_TEMP_CRIT 0x08 ++#define PC87365_STATUS_TEMP_OPEN 0x40 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++static ctl_table pc87360_dir_table_template[] = { /* PC87363 and PC87364 too */ ++ {PC87360_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan}, ++ {PC87360_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan}, ++ {PC87360_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan}, ++ {PC87360_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_div}, ++ {PC87360_SYSCTL_FAN1_STATUS, "fan1_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_status}, ++ {PC87360_SYSCTL_FAN2_STATUS, "fan2_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_status}, ++ {PC87360_SYSCTL_FAN3_STATUS, "fan3_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_status}, ++ {PC87360_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_pwm}, ++ {PC87360_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_pwm}, ++ {PC87360_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_pwm}, ++ {0} ++}; ++ ++static ctl_table pc87365_dir_table_template[] = { /* PC87366 too */ ++ {PC87365_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_alarms}, ++ {PC87360_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan}, ++ {PC87360_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan}, ++ {PC87360_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan}, ++ {PC87360_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_div}, ++ {PC87360_SYSCTL_FAN1_STATUS, "fan1_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_status}, ++ {PC87360_SYSCTL_FAN2_STATUS, "fan2_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_status}, ++ {PC87360_SYSCTL_FAN3_STATUS, "fan3_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_status}, ++ {PC87360_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_pwm}, ++ {PC87360_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_pwm}, ++ {PC87360_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_pwm}, ++ {PC87365_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_IN9, "in9", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_IN10, "in10", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_IN0_STATUS, "in0_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_IN1_STATUS, "in1_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_IN2_STATUS, "in2_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_IN3_STATUS, "in3_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_IN4_STATUS, "in4_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_IN5_STATUS, "in5_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_IN6_STATUS, "in6_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_IN7_STATUS, "in7_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_IN8_STATUS, "in8_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_IN9_STATUS, "in9_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_IN10_STATUS, "in10_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_temp}, ++ {PC87365_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_temp}, ++ {PC87365_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_temp}, ++ {PC87365_SYSCTL_TEMP4, "temp4", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_TEMP5, "temp5", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_TEMP6, "temp6", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in}, ++ {PC87365_SYSCTL_TEMP1_STATUS, "temp1_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_temp_status}, ++ {PC87365_SYSCTL_TEMP2_STATUS, "temp2_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_temp_status}, ++ {PC87365_SYSCTL_TEMP3_STATUS, "temp3_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_temp_status}, ++ {PC87365_SYSCTL_TEMP4_STATUS, "temp4_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_TEMP5_STATUS, "temp5_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_TEMP6_STATUS, "temp6_status", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status}, ++ {PC87365_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_vid}, ++ {PC87365_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_vrm}, ++ {0} ++}; ++ ++static int pc87360_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, pc87360_detect); ++} ++ ++static int pc87360_find(u8 *devid, int *address) ++{ ++ u16 val; ++ int i; ++ int nrdev; /* logical device count */ ++ ++ /* No superio_enter */ ++ ++ /* Identify device */ ++ val = superio_inb(DEVID); ++ switch (val) { ++ case 0xE1: /* PC87360 */ ++ case 0xE8: /* PC87363 */ ++ case 0xE4: /* PC87364 */ ++ nrdev = 1; ++ break; ++ case 0xE5: /* PC87365 */ ++ case 0xE9: /* PC87366 */ ++ nrdev = 3; ++ break; ++ default: ++ superio_exit(); ++ return -ENODEV; ++ } ++ /* Remember the device id */ ++ *devid = val; ++ ++ for (i = 0; i < nrdev; i++) { ++ /* select logical device */ ++ superio_outb(DEV, logdev[i]); ++ ++ val = superio_inb(ACT); ++ if (!(val & 0x01)) { ++ printk(KERN_INFO "pc87360.o: Device 0x%02x not " ++ "activated\n", logdev[i]); ++ continue; ++ } ++ ++ val = (superio_inb(BASE) << 8) ++ | superio_inb(BASE + 1); ++ if (!val) { ++ printk(KERN_INFO "pc87360.o: Base address not set for " ++ "device 0x%02x\n", logdev[i]); ++ continue; ++ } ++ ++ address[i] = val; ++ ++ if (i==0) { /* Fans */ ++ confreg[0] = superio_inb(0xF0); ++ confreg[1] = superio_inb(0xF1); ++ ++#ifdef DEBUG ++ printk(KERN_DEBUG "pc87360.o: Fan 1: mon=%d " ++ "ctrl=%d inv=%d\n", (confreg[0]>>2)&1, ++ (confreg[0]>>3)&1, (confreg[0]>>4)&1); ++ printk(KERN_DEBUG "pc87360.o: Fan 2: mon=%d " ++ "ctrl=%d inv=%d\n", (confreg[0]>>5)&1, ++ (confreg[0]>>6)&1, (confreg[0]>>7)&1); ++ printk(KERN_DEBUG "pc87360.o: Fan 3: mon=%d " ++ "ctrl=%d inv=%d\n", confreg[1]&1, ++ (confreg[1]>>1)&1, (confreg[1]>>2)&1); ++#endif ++ } else if (i==1) { /* Voltages */ ++ /* Are we using thermistors? */ ++ if (*devid == 0xE9) { /* PC87366 */ ++ /* These registers are not logical-device ++ specific, just that we won't need them if ++ we don't use the VLM device */ ++ confreg[2] = superio_inb(0x2B); ++ confreg[3] = superio_inb(0x25); ++ ++ if (confreg[2] & 0x40) { ++ printk(KERN_INFO "pc87360.o: Using " ++ "thermistors for temperature " ++ "monitoring\n"); ++ } ++ if (confreg[3] & 0xE0) { ++ printk(KERN_INFO "pc87360.o: VID " ++ "inputs routed (mode %u)\n", ++ confreg[3] >> 5); ++ } ++ } ++ } ++ } ++ ++ superio_exit(); ++ return 0; ++} ++ ++/* We don't really care about the address. ++ Read from extra_isa instead. */ ++int pc87360_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct pc87360_data *data; ++ int err = 0; ++ const char *type_name = "pc87360"; ++ const char *client_name = "PC8736x chip"; ++ ctl_table *template = pc87360_dir_table_template; ++ int use_thermistors = 0; ++ ++ if (!i2c_is_isa_adapter(adapter)) { ++ return 0; ++ } ++ ++ for (i = 0; i < 3; i++) { ++ if (extra_isa[i] ++ && check_region(extra_isa[i], PC87360_EXTENT)) { ++ printk(KERN_ERR "pc87360.o: Region 0x%x-0x%x already " ++ "in use!\n", extra_isa[i], ++ extra_isa[i]+PC87360_EXTENT-1); ++ return -ENODEV; ++ } ++ } ++ ++ if (!(data = kmalloc(sizeof(struct pc87360_data), GFP_KERNEL))) { ++ return -ENOMEM; ++ } ++ memset(data, 0x00, sizeof(struct pc87360_data)); ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ init_MUTEX(&data->lock); ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &pc87360_driver; ++ new_client->flags = 0; ++ ++ data->fannr = 2; ++ data->innr = 0; ++ data->tempnr = 0; ++ ++ switch (devid) { ++ case 0xe8: ++ type_name = "pc87363"; ++ break; ++ case 0xe4: ++ type_name = "pc87364"; ++ data->fannr = 3; ++ break; ++ case 0xe5: ++ type_name = "pc87365"; ++ template = pc87365_dir_table_template; ++ data->fannr = extra_isa[0] ? 3 : 0; ++ data->innr = extra_isa[1] ? 11 : 0; ++ data->tempnr = extra_isa[2] ? 2 : 0; ++ break; ++ case 0xe9: ++ type_name = "pc87366"; ++ template = pc87365_dir_table_template; ++ data->fannr = extra_isa[0] ? 3 : 0; ++ data->innr = extra_isa[1] ? 14 : 0; ++ data->tempnr = extra_isa[2] ? 3 : 0; ++ break; ++ } ++ ++ /* Retrieve the fans configuration from Super-I/O space */ ++ if (data->fannr) ++ data->fan_conf = confreg[0] | (confreg[1] << 8); ++ ++ for (i = 0; i < 3; i++) { ++ if ((data->address[i] = extra_isa[i])) { ++ request_region(extra_isa[i], PC87360_EXTENT, "pc87360"); ++ } ++ } ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = pc87360_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR1; ++ ++ /* Use the correct reference voltage ++ Unless both the VLM and the TMS logical devices agree to ++ use an external Vref, the internal one is used. */ ++ if (data->innr) { ++ i = pc87360_read_value(data, LD_IN, NO_BANK, ++ PC87365_REG_IN_CONFIG); ++ if (data->tempnr) { ++ i &= pc87360_read_value(data, LD_TEMP, NO_BANK, ++ PC87365_REG_TEMP_CONFIG); ++ } ++ data->in_vref = (i&0x02) ? 3025 : 2966; ++#ifdef DEBUG ++ printk(KERN_DEBUG "pc87360.o: Using %s reference voltage\n", ++ (i&0x02) ? "external" : "internal"); ++#endif ++ ++ data->vid_conf = confreg[3]; ++ data->vrm = 90; ++ } ++ ++ /* Fan clock dividers may be needed before any data is read */ ++ for (i = 0; i < data->fannr; i++) { ++ data->fan_status[i] = pc87360_read_value(data, LD_FAN, ++ NO_BANK, PC87360_REG_FAN_STATUS(i)); ++ } ++ ++ if (init > 0) { ++ if (devid == 0xe9 && data->address[1]) /* PC87366 */ ++ use_thermistors = confreg[2] & 0x40; ++ ++ pc87360_init_client(new_client, use_thermistors); ++ } ++ ++ if ((i = i2c_register_entry((struct i2c_client *) new_client, ++ type_name, template)) < 0) { ++ err = i; ++ goto ERROR2; ++ } ++ data->sysctl_id = i; ++ ++ return 0; ++ ++ERROR2: ++ i2c_detach_client(new_client); ++ERROR1: ++ for (i = 0; i < 3; i++) { ++ if (data->address[i]) { ++ release_region(data->address[i], PC87360_EXTENT); ++ } ++ } ++ kfree(data); ++ return err; ++} ++ ++static int pc87360_detach_client(struct i2c_client *client) ++{ ++ struct pc87360_data *data = client->data; ++ int i, err; ++ ++ i2c_deregister_entry(data->sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk(KERN_ERR "pc87360.o: Client deregistration failed, " ++ "client not detached.\n"); ++ return err; ++ } ++ ++ for (i = 0; i < 3; i++) { ++ if (data->address[i]) { ++ release_region(data->address[i], PC87360_EXTENT); ++ } ++ } ++ kfree(client->data); ++ ++ return 0; ++} ++ ++/* ldi is the logical device index ++ bank is for voltages and temperatures only */ ++static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank, ++ u8 reg) ++{ ++ int res; ++ ++ down(&(data->lock)); ++ if (bank != NO_BANK) { ++ outb_p(bank, data->address[ldi] + PC87365_REG_BANK); ++ } ++ res = inb_p(data->address[ldi] + reg); ++ up(&(data->lock)); ++ return res; ++} ++ ++static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, ++ u8 reg, u8 value) ++{ ++ down(&(data->lock)); ++ if (bank != NO_BANK) { ++ outb_p(bank, data->address[ldi] + PC87365_REG_BANK); ++ } ++ outb_p(value, data->address[ldi] + reg); ++ up(&(data->lock)); ++} ++ ++static void pc87360_init_client(struct i2c_client *client, int use_thermistors) ++{ ++ struct pc87360_data *data = client->data; ++ int i, nr; ++ const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 }; ++ const u8 init_temp[3] = { 2, 2, 1 }; ++ u8 reg; ++ ++ if (init >= 2 && data->innr) { ++ reg = pc87360_read_value(data, LD_IN, NO_BANK, ++ PC87365_REG_IN_CONVRATE); ++ printk(KERN_INFO "pc87360.o: VLM conversion set to" ++ "1s period, 160us delay\n"); ++ pc87360_write_value(data, LD_IN, NO_BANK, ++ PC87365_REG_IN_CONVRATE, ++ (reg & 0xC0) | 0x11); ++ } ++ ++ nr = data->innr < 11 ? data->innr : 11; ++ for (i=0; i= init_in[i]) { ++ /* Forcibly enable voltage channel */ ++ reg = pc87360_read_value(data, LD_IN, i, ++ PC87365_REG_IN_STATUS); ++ if (!(reg & 0x01)) { ++#ifdef DEBUG ++ printk(KERN_DEBUG "pc87360.o: Forcibly " ++ "enabling in%d\n", i); ++#endif ++ pc87360_write_value(data, LD_IN, i, ++ PC87365_REG_IN_STATUS, ++ (reg & 0x68) | 0x87); ++ } ++ } ++ } ++ ++ /* We can't blindly trust the Super-I/O space configuration bit, ++ most BIOS won't set it properly */ ++ for (i=11; iinnr; i++) { ++ reg = pc87360_read_value(data, LD_IN, i, ++ PC87365_REG_TEMP_STATUS); ++ use_thermistors = use_thermistors || (reg & 0x01); ++ } ++ ++ i = use_thermistors ? 2 : 0; ++ for (; itempnr; i++) { ++ if (init >= init_temp[i]) { ++ /* Forcibly enable temperature channel */ ++ reg = pc87360_read_value(data, LD_TEMP, i, ++ PC87365_REG_TEMP_STATUS); ++ if (!(reg & 0x01)) { ++#ifdef DEBUG ++ printk(KERN_DEBUG "pc87360.o: Forcibly " ++ "enabling temp%d\n", i+1); ++#endif ++ pc87360_write_value(data, LD_TEMP, i, ++ PC87365_REG_TEMP_STATUS, ++ 0xCF); ++ } ++ } ++ } ++ ++ if (use_thermistors) { ++ for (i=11; iinnr; i++) { ++ if (init >= init_in[i]) { ++ /* The pin may already be used by thermal ++ diodes */ ++ reg = pc87360_read_value(data, LD_TEMP, (i-11)/2, ++ PC87365_REG_TEMP_STATUS); ++ if (reg & 0x01) { ++#ifdef DEBUG ++ printk(KERN_DEBUG "pc87360.o: Skipping " ++ "temp%d, pin already in use by ", ++ "temp%d\n", i-7, (i-11)/2); ++#endif ++ continue; ++ } ++ ++ /* Forcibly enable thermistor channel */ ++ reg = pc87360_read_value(data, LD_IN, i, ++ PC87365_REG_IN_STATUS); ++ if (!(reg & 0x01)) { ++#ifdef DEBUG ++ printk(KERN_DEBUG "pc87360.o: Forcibly " ++ "enabling temp%d\n", i-7); ++#endif ++ pc87360_write_value(data, LD_IN, i, ++ PC87365_REG_TEMP_STATUS, ++ (reg & 0x60) | 0x8F); ++ } ++ } ++ } ++ } ++ ++ if (data->innr) { ++ reg = pc87360_read_value(data, LD_IN, NO_BANK, ++ PC87365_REG_IN_CONFIG); ++ if (reg & 0x01) { ++#ifdef DEBUG ++ printk(KERN_DEBUG "pc87360.o: Forcibly " ++ "enabling monitoring (VLM)\n"); ++#endif ++ pc87360_write_value(data, LD_IN, NO_BANK, ++ PC87365_REG_IN_CONFIG, ++ reg & 0xFE); ++ } ++ } ++ ++ if (data->tempnr) { ++ reg = pc87360_read_value(data, LD_TEMP, NO_BANK, ++ PC87365_REG_TEMP_CONFIG); ++ if (reg & 0x01) { ++#ifdef DEBUG ++ printk(KERN_DEBUG "pc87360.o: Forcibly " ++ "enabling monitoring (TMS)\n"); ++#endif ++ pc87360_write_value(data, LD_TEMP, NO_BANK, ++ PC87365_REG_TEMP_CONFIG, ++ reg & 0xFE); ++ } ++ ++ if (init >= 2) { ++ /* Chip config as documented by National Semi. */ ++ pc87360_write_value(data, LD_TEMP, 0xF, 0xA, 0x08); ++ /* We voluntarily omit the bank here, in case the ++ sequence itself matters. It shouldn't be a problem, ++ since nobody else is supposed to access the ++ device at that point. */ ++ pc87360_write_value(data, LD_TEMP, NO_BANK, 0xB, 0x04); ++ pc87360_write_value(data, LD_TEMP, NO_BANK, 0xC, 0x35); ++ pc87360_write_value(data, LD_TEMP, NO_BANK, 0xD, 0x05); ++ pc87360_write_value(data, LD_TEMP, NO_BANK, 0xE, 0x05); ++ } ++ } ++} ++ ++static void pc87360_autodiv(struct pc87360_data *data, int nr) ++{ ++ u8 old_min = data->fan_min[nr]; ++ ++ /* Increase clock divider if needed and possible */ ++ if ((data->fan_status[nr] & 0x04) /* overflow flag */ ++ || (data->fan[nr] >= 224)) { /* next to overflow */ ++ if ((data->fan_status[nr] & 0x60) != 0x60) { ++ data->fan_status[nr] += 0x20; ++ data->fan_min[nr] >>= 1; ++ data->fan[nr] >>= 1; ++#ifdef DEBUG ++ printk(KERN_DEBUG "pc87360.o: Increasing " ++ "clock divider to %d for fan %d\n", ++ FAN_DIV_FROM_REG(data->fan_status[nr]), ++ nr+1); ++#endif ++ } ++ } else { ++ /* Decrease clock divider if possible */ ++ while (!(data->fan_min[nr] & 0x80) /* fan min "nails" divider */ ++ && data->fan[nr] < 85 /* bad accuracy */ ++ && (data->fan_status[nr] & 0x60) != 0x00) { ++ data->fan_status[nr] -= 0x20; ++ data->fan_min[nr] <<= 1; ++ data->fan[nr] <<= 1; ++#ifdef DEBUG ++ printk(KERN_DEBUG "pc87360.o: Decreasing " ++ "clock divider to %d for fan %d\n", ++ FAN_DIV_FROM_REG(data->fan_status[nr]), ++ nr+1); ++#endif ++ } ++ } ++ ++ /* Write new fan min if it changed */ ++ if (old_min != data->fan_min[nr]) { ++ pc87360_write_value(data, LD_FAN, NO_BANK, ++ PC87360_REG_FAN_MIN(nr), ++ data->fan_min[nr]); ++ } ++} ++ ++static void pc87360_update_client(struct i2c_client *client) ++{ ++ struct pc87360_data *data = client->data; ++ u8 i; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ * 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++#ifdef DEBUG ++ printk(KERN_DEBUG "pc87360.o: Data update\n"); ++#endif ++ ++ /* Fans */ ++ for (i = 0; i < data->fannr; i++) { ++ if (FAN_CONFIG_MONITOR(data->fan_conf, i)) { ++ data->fan_status[i] = pc87360_read_value(data, ++ LD_FAN, NO_BANK, ++ PC87360_REG_FAN_STATUS(i)); ++ data->fan[i] = pc87360_read_value(data, LD_FAN, ++ NO_BANK, PC87360_REG_FAN(i)); ++ data->fan_min[i] = pc87360_read_value(data, ++ LD_FAN, NO_BANK, ++ PC87360_REG_FAN_MIN(i)); ++ /* Change clock divider if needed */ ++ pc87360_autodiv(data, i); ++ /* Clear bits and write new divider */ ++ pc87360_write_value(data, LD_FAN, NO_BANK, ++ PC87360_REG_FAN_STATUS(i), ++ data->fan_status[i]); ++ } ++ data->pwm[i] = pc87360_read_value(data, LD_FAN, ++ NO_BANK, PC87360_REG_PWM(i)); ++ } ++ ++ /* Voltages */ ++ for (i = 0; i < data->innr; i++) { ++ data->in_status[i] = pc87360_read_value(data, LD_IN, i, ++ PC87365_REG_IN_STATUS); ++ /* Clear bits */ ++ pc87360_write_value(data, LD_IN, i, ++ PC87365_REG_IN_STATUS, ++ data->in_status[i]); ++ if ((data->in_status[i] & 0x81) == 0x81) { ++ data->in[i] = pc87360_read_value(data, LD_IN, ++ i, PC87365_REG_IN); ++ } ++ if (data->in_status[i] & 0x01) { ++ data->in_min[i] = pc87360_read_value(data, ++ LD_IN, i, ++ PC87365_REG_IN_MIN); ++ data->in_max[i] = pc87360_read_value(data, ++ LD_IN, i, ++ PC87365_REG_IN_MAX); ++ if (i >= 11) ++ data->in_crit[i-11] = ++ pc87360_read_value(data, LD_IN, ++ i, PC87365_REG_TEMP_CRIT); ++ } ++ } ++ if (data->innr) { ++ data->in_alarms = pc87360_read_value(data, LD_IN, ++ NO_BANK, PC87365_REG_IN_ALARMS1) ++ | ((pc87360_read_value(data, LD_IN, ++ NO_BANK, PC87365_REG_IN_ALARMS2) ++ & 0x07) << 8); ++ data->vid = (data->vid_conf & 0xE0) ? ++ pc87360_read_value(data, LD_IN, ++ NO_BANK, PC87365_REG_VID) : 0x1F; ++ } ++ ++ /* Temperatures */ ++ for (i = 0; i < data->tempnr; i++) { ++ data->temp_status[i] = pc87360_read_value(data, ++ LD_TEMP, i, ++ PC87365_REG_TEMP_STATUS); ++ /* Clear bits */ ++ pc87360_write_value(data, LD_TEMP, i, ++ PC87365_REG_TEMP_STATUS, ++ data->temp_status[i]); ++ if ((data->temp_status[i] & 0x81) == 0x81) { ++ data->temp[i] = pc87360_read_value(data, ++ LD_TEMP, i, ++ PC87365_REG_TEMP); ++ } ++ if (data->temp_status[i] & 0x01) { ++ data->temp_min[i] = pc87360_read_value(data, ++ LD_TEMP, i, ++ PC87365_REG_TEMP_MIN); ++ data->temp_max[i] = pc87360_read_value(data, ++ LD_TEMP, i, ++ PC87365_REG_TEMP_MAX); ++ data->temp_crit[i] = pc87360_read_value(data, ++ LD_TEMP, i, ++ PC87365_REG_TEMP_CRIT); ++ } ++ } ++ if (data->tempnr) { ++ data->temp_alarms = pc87360_read_value(data, LD_TEMP, ++ NO_BANK, PC87365_REG_TEMP_ALARMS) ++ & 0x3F; ++ } ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++void pc87365_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pc87360_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ pc87360_update_client(client); ++ results[0] = data->in_alarms; ++ results[1] = data->temp_alarms; ++ *nrels_mag = 2; ++ } ++} ++ ++void pc87360_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pc87360_data *data = client->data; ++ int nr = ctl_name - PC87360_SYSCTL_FAN1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ pc87360_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr], ++ FAN_DIV_FROM_REG(data->fan_status[nr])); ++ results[1] = FAN_FROM_REG(data->fan[nr], ++ FAN_DIV_FROM_REG(data->fan_status[nr])); ++ *nrels_mag = 2; ++ } ++ /* We ignore National's recommendation */ ++ else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (nr >= data->fannr) ++ return; ++ if (*nrels_mag >= 1) { ++ int fan_min = FAN_TO_REG(results[0], ++ FAN_DIV_FROM_REG(data->fan_status[nr])); ++ /* If it wouldn't fit, change clock divisor */ ++ while (fan_min > 255 ++ && (data->fan_status[nr] & 0x60) != 0x60) { ++ fan_min >>= 1; ++ data->fan[nr] >>= 1; ++ data->fan_status[nr] += 0x20; ++ } ++ data->fan_min[nr] = fan_min > 255 ? 255 : fan_min; ++ pc87360_write_value(data, LD_FAN, NO_BANK, ++ PC87360_REG_FAN_MIN(nr), ++ data->fan_min[nr]); ++ /* Write new divider, preserve alarm bits */ ++ pc87360_write_value(data, LD_FAN, NO_BANK, ++ PC87360_REG_FAN_STATUS(nr), ++ data->fan_status[nr] & 0xF9); ++ } ++ } ++} ++ ++void pc87360_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct pc87360_data *data = client->data; ++ int i; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ pc87360_update_client(client); ++ for (i = 0; i < data->fannr; i++) { ++ results[i] = FAN_DIV_FROM_REG(data->fan_status[i]); ++ } ++ for (; i < 3; i++) { ++ results[i] = 0; ++ } ++ *nrels_mag = 3; ++ } ++} ++ ++void pc87360_pwm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pc87360_data *data = client->data; ++ int nr = ctl_name - PC87360_SYSCTL_PWM1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ pc87360_update_client(client); ++ results[0] = PWM_FROM_REG(data->pwm[nr], ++ FAN_CONFIG_INVERT(data->fan_conf, nr)); ++ results[1] = FAN_CONFIG_CONTROL(data->fan_conf, nr); ++ *nrels_mag = 2; ++ } ++ else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (nr >= data->fannr) ++ return; ++ if (*nrels_mag >= 1) { ++ data->pwm[nr] = PWM_TO_REG(results[0], ++ FAN_CONFIG_INVERT(data->fan_conf, nr)); ++ pc87360_write_value(data, LD_FAN, NO_BANK, ++ PC87360_REG_PWM(nr), ++ data->pwm[nr]); ++ } ++ } ++} ++ ++void pc87360_fan_status(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pc87360_data *data = client->data; ++ int nr = ctl_name - PC87360_SYSCTL_FAN1_STATUS; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ pc87360_update_client(client); ++ results[0] = FAN_STATUS_FROM_REG(data->fan_status[nr]); ++ *nrels_mag = 1; ++ } ++} ++ ++void pc87365_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pc87360_data *data = client->data; ++ int nr = ctl_name - PC87365_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ pc87360_update_client(client); ++ results[0] = IN_FROM_REG(data->in_min[nr], data->in_vref); ++ results[1] = IN_FROM_REG(data->in_max[nr], data->in_vref); ++ if (nr < 11) { ++ *nrels_mag = 3; ++ } else { ++ results[2] = IN_FROM_REG(data->in_crit[nr-11], ++ data->in_vref); ++ *nrels_mag = 4; ++ } ++ results[(*nrels_mag)-1] = IN_FROM_REG(data->in[nr], ++ data->in_vref); ++ } ++ else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = IN_TO_REG(results[0], ++ data->in_vref); ++ pc87360_write_value(data, LD_IN, nr, ++ PC87365_REG_IN_MIN, ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = IN_TO_REG(results[1], ++ data->in_vref); ++ pc87360_write_value(data, LD_IN, nr, ++ PC87365_REG_IN_MAX, ++ data->in_max[nr]); ++ } ++ if (*nrels_mag >= 3 && nr >= 11) { ++ data->in_crit[nr-11] = IN_TO_REG(results[2], ++ data->in_vref); ++ pc87360_write_value(data, LD_IN, nr, ++ PC87365_REG_TEMP_CRIT, ++ data->in_crit[nr-11]); ++ } ++ } ++} ++ ++void pc87365_in_status(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pc87360_data *data = client->data; ++ int nr = ctl_name - PC87365_SYSCTL_IN0_STATUS; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ pc87360_update_client(client); ++ results[0] = data->in_status[nr]; ++ *nrels_mag = 1; ++ } ++} ++ ++void pc87365_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pc87360_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ pc87360_update_client(client); ++ results[0] = vid_from_reg(data->vid & 0x1f, data->vrm); ++ *nrels_mag = 1; ++ } ++} ++ ++void pc87365_vrm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pc87360_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->vrm; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) ++ data->vrm = results[0]; ++ } ++} ++ ++void pc87365_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pc87360_data *data = client->data; ++ int nr = ctl_name - PC87365_SYSCTL_TEMP1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ pc87360_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_max[nr]); ++ results[1] = TEMP_FROM_REG(data->temp_min[nr]); ++ results[2] = TEMP_FROM_REG(data->temp_crit[nr]); ++ results[3] = TEMP_FROM_REG(data->temp[nr]); ++ *nrels_mag = 4; ++ } ++ else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (nr >= data->tempnr) ++ return; ++ if (*nrels_mag >= 1) { ++ data->temp_max[nr] = TEMP_TO_REG(results[0]); ++ pc87360_write_value(data, LD_TEMP, nr, ++ PC87365_REG_TEMP_MAX, ++ data->temp_max[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_min[nr] = TEMP_TO_REG(results[1]); ++ pc87360_write_value(data, LD_TEMP, nr, ++ PC87365_REG_TEMP_MIN, ++ data->temp_min[nr]); ++ } ++ if (*nrels_mag >= 3) { ++ data->temp_crit[nr] = TEMP_TO_REG(results[2]); ++ pc87360_write_value(data, LD_TEMP, nr, ++ PC87365_REG_TEMP_CRIT, ++ data->temp_crit[nr]); ++ } ++ } ++} ++ ++void pc87365_temp_status(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pc87360_data *data = client->data; ++ int nr = ctl_name - PC87365_SYSCTL_TEMP1_STATUS; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ pc87360_update_client(client); ++ results[0] = data->temp_status[nr]; ++ *nrels_mag = 1; ++ } ++} ++ ++ ++static int __init pc87360_init(void) ++{ ++ int i; ++ ++ printk(KERN_INFO "pc87360.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ ++ if (pc87360_find(&devid, extra_isa)) { ++ printk(KERN_WARNING "pc87360.o: PC8736x not detected, " ++ "module not inserted.\n"); ++ return -ENODEV; ++ } ++ ++ /* Arbitrarily pick one of the addresses */ ++ for (i = 0; i < 3; i++) { ++ if (extra_isa[i] != 0x0000) { ++ normal_isa[0] = extra_isa[i]; ++ break; ++ } ++ } ++ ++ if (normal_isa[0] == 0x0000) { ++ printk(KERN_WARNING "pc87360.o: No active logical device, " ++ "module not inserted.\n"); ++ return -ENODEV; ++ ++ } ++ ++ return i2c_add_driver(&pc87360_driver); ++} ++ ++static void __exit pc87360_exit(void) ++{ ++ i2c_del_driver(&pc87360_driver); ++} ++ ++ ++MODULE_AUTHOR("Jean Delvare "); ++MODULE_DESCRIPTION("PC8736x hardware monitor"); ++MODULE_LICENSE("GPL"); ++ ++module_init(pc87360_init); ++module_exit(pc87360_exit); +--- linux-old/drivers/sensors/pcf8574.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/pcf8574.c Mon Dec 13 20:18:51 2004 +@@ -0,0 +1,309 @@ ++/* ++ pcf8574.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 2000 Frodo Looijaard , ++ Philip Edelbrock , ++ Dan Eaton ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* A few notes about the PCF8574: ++ ++* The PCF8574 is an 8-bit I/O expander for the I2C bus produced by ++ Philips Semiconductors. It is designed to provide a byte I2C ++ interface to up to 8 separate devices. ++ ++* The PCF8574 appears as a very simple SMBus device which can be ++ read from or written to with SMBUS byte read/write accesses. ++ ++* Because of the general purpose nature of this device, it will most ++ likely be necessary to customize the /proc interface to suit the ++ specific application. ++ ++ --Dan ++ ++*/ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x20, 0x27, 0x38, 0x3f, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_2(pcf8574, pcf8574a); ++ ++/* The PCF8574 registers */ ++ ++/* (No registers. [Wow! This thing is SIMPLE!] ) */ ++ ++/* Initial values */ ++#define PCF8574_INIT 255 /* All outputs on (input mode) */ ++ ++/* Each client has this additional data */ ++struct pcf8574_data { ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ ++ u8 read, write; /* Register values */ ++}; ++ ++static int pcf8574_attach_adapter(struct i2c_adapter *adapter); ++static int pcf8574_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int pcf8574_detach_client(struct i2c_client *client); ++ ++static void pcf8574_read(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void pcf8574_write(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void pcf8574_update_client(struct i2c_client *client); ++static void pcf8574_init_client(struct i2c_client *client); ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver pcf8574_driver = { ++ .owner = THIS_MODULE, ++ .name = "PCF8574 sensor chip driver", ++ .id = I2C_DRIVERID_PCF8574, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = pcf8574_attach_adapter, ++ .detach_client = pcf8574_detach_client, ++}; ++ ++ ++/* -- SENSORS SYSCTL START -- */ ++#define PCF8574_SYSCTL_READ 1000 ++#define PCF8574_SYSCTL_WRITE 1001 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected PCF8574. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table pcf8574_dir_table_template[] = { ++ {PCF8574_SYSCTL_READ, "read", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &pcf8574_read}, ++ {PCF8574_SYSCTL_WRITE, "write", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &pcf8574_write}, ++ {0} ++}; ++ ++static int pcf8574_id = 0; ++ ++static int pcf8574_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, pcf8574_detect); ++} ++ ++/* This function is called by i2c_detect */ ++int pcf8574_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct pcf8574_data *data; ++ int err = 0; ++ const char *type_name, *client_name; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("pcf8574.o: pcf8574_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. */ ++ if (!(data = kmalloc(sizeof(struct pcf8574_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &pcf8574_driver; ++ new_client->flags = 0; ++ ++ /* Now, we would do the remaining detection. But the PCF8574 is plainly ++ impossible to detect! Stupid chip. */ ++ ++ /* Determine the chip type */ ++ if (kind <= 0) { ++ if (address >= 0x38 && address <= 0x3f) ++ kind = pcf8574a; ++ else ++ kind = pcf8574; ++ } ++ ++ if (kind == pcf8574a) { ++ type_name = "pcf8574a"; ++ client_name = "PCF8574A chip"; ++ } else { ++ type_name = "pcf8574a"; ++ client_name = "PCF8574A chip"; ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = pcf8574_id++; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR1; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, type_name, ++ pcf8574_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR2; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the PCF8574 chip */ ++ pcf8574_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR2: ++ i2c_detach_client(new_client); ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int pcf8574_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct pcf8574_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk("pcf8574.o: Client deregistration failed, " ++ "client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++/* Called when we have found a new PCF8574. */ ++static void pcf8574_init_client(struct i2c_client *client) ++{ ++ struct pcf8574_data *data = client->data; ++ data->write = PCF8574_INIT; ++ i2c_smbus_write_byte(client, data->write); ++} ++ ++ ++static void pcf8574_update_client(struct i2c_client *client) ++{ ++ struct pcf8574_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++#ifdef DEBUG ++ printk("Starting pcf8574 update\n"); ++#endif ++ ++ data->read = i2c_smbus_read_byte(client); ++ ++ up(&data->update_lock); ++} ++ ++ ++void pcf8574_read(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct pcf8574_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ pcf8574_update_client(client); ++ results[0] = data->read; ++ *nrels_mag = 1; ++ } ++} ++void pcf8574_write(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct pcf8574_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->write; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->write = results[0]; ++ i2c_smbus_write_byte(client, data->write); ++ } ++ } ++} ++ ++ ++static int __init sm_pcf8574_init(void) ++{ ++ printk("pcf8574.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&pcf8574_driver); ++} ++ ++static void __exit sm_pcf8574_exit(void) ++{ ++ i2c_del_driver(&pcf8574_driver); ++} ++ ++ ++MODULE_AUTHOR("Frodo Looijaard , " ++ "Philip Edelbrock , " ++ "Dan Eaton and " ++ "Aurelien Jarno "); ++MODULE_DESCRIPTION("PCF8574 driver"); ++ ++module_init(sm_pcf8574_init); ++module_exit(sm_pcf8574_exit); +--- linux-old/drivers/sensors/pcf8591.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/pcf8591.c Mon Dec 13 20:18:51 2004 +@@ -0,0 +1,448 @@ ++/* ++ pcf8591.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 2001 Aurelien Jarno ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x48, 0x4f, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(pcf8591); ++ ++/* The PCF8591 control byte */ ++/* 7 6 5 4 3 2 1 0 */ ++/* | 0 |AOEF| AIP | 0 |AINC| AICH | */ ++ ++#define PCF8591_CONTROL_BYTE_AOEF 0x40 /* Analog Output Enable Flag */ ++ /* (analog output active if 1) */ ++ ++#define PCF8591_CONTROL_BYTE_AIP 0x30 /* Analog Input Programming */ ++ /* 0x00 = four single ended inputs */ ++ /* 0x10 = three differential inputs */ ++ /* 0x20 = single ended and differential mixed */ ++ /* 0x30 = two differential inputs */ ++ ++#define PCF8591_CONTROL_BYTE_AINC 0x04 /* Autoincrement Flag */ ++ /* (switch on if 1) */ ++ ++#define PCF8591_CONTROL_BYTE_AICH 0x03 /* Analog Output Enable Flag */ ++ /* 0x00 = channel 0 */ ++ /* 0x01 = channel 1 */ ++ /* 0x02 = channel 2 */ ++ /* 0x03 = channel 3 */ ++ ++ ++/* Initial values */ ++#define PCF8591_INIT_CONTROL_BYTE (PCF8591_CONTROL_BYTE_AOEF | PCF8591_CONTROL_BYTE_AINC) ++ /* DAC out enabled, four single ended inputs, autoincrement */ ++ ++#define PCF8591_INIT_AOUT 0 /* DAC out = 0 */ ++ ++ ++/* Conversions. */ ++#define REG_TO_SIGNED(reg) (reg & 0x80)?(reg - 256):(reg) ++ /* Convert signed 8 bit value to signed value */ ++ ++ ++struct pcf8591_data { ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 control_byte; ++ u8 ch[4]; ++ u8 aout; ++}; ++ ++static int pcf8591_attach_adapter(struct i2c_adapter *adapter); ++static int pcf8591_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int pcf8591_detach_client(struct i2c_client *client); ++ ++static void pcf8591_update_client(struct i2c_client *client); ++static void pcf8591_init_client(struct i2c_client *client); ++ ++static void pcf8591_ain_conf(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void pcf8591_ain(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void pcf8591_aout_enable(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void pcf8591_aout(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver pcf8591_driver = { ++ .owner = THIS_MODULE, ++ .name = "PCF8591 sensor chip driver", ++ .id = I2C_DRIVERID_PCF8591, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = pcf8591_attach_adapter, ++ .detach_client = pcf8591_detach_client, ++}; ++ ++static int pcf8591_id = 0; ++ ++/* The /proc/sys entries */ ++ ++/* -- SENSORS SYSCTL START -- */ ++#define PCF8591_SYSCTL_AIN_CONF 1000 /* Analog input configuration */ ++#define PCF8591_SYSCTL_CH0 1001 /* Input channel 1 */ ++#define PCF8591_SYSCTL_CH1 1002 /* Input channel 2 */ ++#define PCF8591_SYSCTL_CH2 1003 /* Input channel 3 */ ++#define PCF8591_SYSCTL_CH3 1004 /* Input channel 4 */ ++#define PCF8591_SYSCTL_AOUT_ENABLE 1005 /* Analog output enable flag */ ++#define PCF8591_SYSCTL_AOUT 1006 /* Analog output */ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected PCF8591. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table pcf8591_dir_table_template[] = { ++ {PCF8591_SYSCTL_AIN_CONF, "ain_conf", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &pcf8591_ain_conf}, ++ {PCF8591_SYSCTL_CH0, "ch0", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &pcf8591_ain}, ++ {PCF8591_SYSCTL_CH1, "ch1", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &pcf8591_ain}, ++ {PCF8591_SYSCTL_CH2, "ch2", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &pcf8591_ain}, ++ {PCF8591_SYSCTL_CH3, "ch3", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &pcf8591_ain}, ++ {PCF8591_SYSCTL_AOUT_ENABLE, "aout_enable", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &pcf8591_aout_enable}, ++ {PCF8591_SYSCTL_AOUT, "aout", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &pcf8591_aout}, ++ {0} ++}; ++ ++ ++/* This function is called when: ++ * pcf8591_driver is inserted (when this module is loaded), for each ++ available adapter ++ * when a new adapter is inserted (and pcf8591_driver is still present) */ ++static int pcf8591_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, pcf8591_detect); ++} ++ ++/* This function is called by i2c_detect */ ++int pcf8591_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct pcf8591_data *data; ++ int err = 0; ++ ++ const char *type_name = ""; ++ const char *client_name = ""; ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ (KERN_ERR "pcf8591.o: pcf8591_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE ++ | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. */ ++ if (!(data = kmalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &pcf8591_driver; ++ new_client->flags = 0; ++ ++ /* Now, we would do the remaining detection. But the PCF8591 is plainly ++ impossible to detect! Stupid chip. */ ++ ++ /* Determine the chip type - only one kind supported! */ ++ if (kind <= 0) ++ kind = pcf8591; ++ ++ type_name = "pcf8591"; ++ client_name = "PCF8591 chip"; ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = pcf8591_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, ++ type_name, ++ pcf8591_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the PCF8591 chip */ ++ pcf8591_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int pcf8591_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct pcf8591_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ (KERN_ERR "pcf8591.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++/* Called when we have found a new PCF8591. */ ++static void pcf8591_init_client(struct i2c_client *client) ++{ ++ struct pcf8591_data *data = client->data; ++ data->control_byte = PCF8591_INIT_CONTROL_BYTE; ++ data->aout = PCF8591_INIT_AOUT; ++ ++ i2c_smbus_write_byte_data(client, data->control_byte, data->aout); ++} ++ ++static void pcf8591_update_client(struct i2c_client *client) ++{ ++ struct pcf8591_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk(KERN_DEBUG "Starting pcf8591 update\n"); ++#endif ++ ++ i2c_smbus_write_byte(client, data->control_byte); ++ i2c_smbus_read_byte(client); /* The first byte transmitted contains the */ ++ /* conversion code of the previous read cycled */ ++ /* FLUSH IT ! */ ++ ++ ++ /* Number of byte to read to signed depend on the analog input mode */ ++ data->ch[0] = i2c_smbus_read_byte(client); ++ data->ch[1] = i2c_smbus_read_byte(client); ++ /* In all case, read at least two values */ ++ ++ if ((data->control_byte & PCF8591_CONTROL_BYTE_AIP) != 0x30) ++ data->ch[2] = i2c_smbus_read_byte(client); ++ /* Read the third value if not in "two differential inputs" mode */ ++ ++ if ((data->control_byte & PCF8591_CONTROL_BYTE_AIP) == 0x00) ++ data->ch[3] = i2c_smbus_read_byte(client); ++ /* Read the fourth value only in "four single ended inputs" mode */ ++ ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. */ ++void pcf8591_ain_conf(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pcf8591_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = (data->control_byte & PCF8591_CONTROL_BYTE_AIP) >> 4; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ if (results[0] >= 0 && results[0] <= 3) ++ { ++ data->control_byte &= ~PCF8591_CONTROL_BYTE_AIP; ++ data->control_byte |= (results[0] << 4); ++ i2c_smbus_write_byte(client, data->control_byte); ++ data->valid = 0; ++ } ++ } ++ } ++} ++ ++void pcf8591_ain(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pcf8591_data *data = client->data; ++ int nr = ctl_name - PCF8591_SYSCTL_CH0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ pcf8591_update_client(client); ++ ++ /* Number of data to show and conversion to signed depend on */ ++ /* the analog input mode */ ++ ++ switch(nr) { ++ case 0: ++ if (((data->control_byte & PCF8591_CONTROL_BYTE_AIP) == 0) ++ | ((data->control_byte & PCF8591_CONTROL_BYTE_AIP) == 2)) ++ results[0] = data->ch[0]; /* single ended */ ++ else ++ results[0] = REG_TO_SIGNED(data->ch[0]);/* differential */ ++ break; ++ case 1: ++ if (((data->control_byte & PCF8591_CONTROL_BYTE_AIP) == 0) ++ | ((data->control_byte & PCF8591_CONTROL_BYTE_AIP) == 2)) ++ results[0] = data->ch[1]; /* single ended */ ++ else ++ results[0] = REG_TO_SIGNED(data->ch[1]);/* differential */ ++ break; ++ case 2: ++ if ((data->control_byte & PCF8591_CONTROL_BYTE_AIP) == 3) ++ results[0] = 0; /* channel not used */ ++ else if ((data->control_byte & PCF8591_CONTROL_BYTE_AIP) == 0) ++ results[0] = data->ch[2]; /* single ended */ ++ else ++ results[0] = REG_TO_SIGNED(data->ch[2]);/* differential */ ++ break; ++ case 3: ++ if (((data->control_byte & PCF8591_CONTROL_BYTE_AIP) == 0) ++ | ((data->control_byte & PCF8591_CONTROL_BYTE_AIP) == 2)) ++ results[0] = data->ch[3]; /* single ended */ ++ else ++ results[0] = 0; /* channel not used */ ++ break; ++ } ++ *nrels_mag = 1; ++ } ++} ++ ++void pcf8591_aout_enable(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pcf8591_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = !(!(data->control_byte & PCF8591_CONTROL_BYTE_AOEF)); ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ if (results[0]) ++ data->control_byte |= PCF8591_CONTROL_BYTE_AOEF; ++ else ++ data->control_byte &= ~PCF8591_CONTROL_BYTE_AOEF; ++ ++ i2c_smbus_write_byte(client, data->control_byte); ++ } ++ } ++} ++ ++void pcf8591_aout(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct pcf8591_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->aout; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ if (results[0] >= 0 && results[0] <= 255) /* ignore values outside DAC range */ ++ { ++ data->aout = results[0]; ++ i2c_smbus_write_byte_data(client, data->control_byte, data->aout); ++ } ++ } ++ } ++} ++ ++static int __init sm_pcf8591_init(void) ++{ ++ printk(KERN_INFO "pcf8591.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&pcf8591_driver); ++} ++ ++static void __exit sm_pcf8591_exit(void) ++{ ++ i2c_del_driver(&pcf8591_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Aurelien Jarno "); ++MODULE_DESCRIPTION("PCF8591 driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_pcf8591_init); ++module_exit(sm_pcf8591_exit); +--- linux-old/drivers/sensors/sis5595.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/sis5595.c Mon Dec 13 20:18:52 2004 +@@ -0,0 +1,735 @@ ++/* ++ sis5595.c - Part of lm_sensors, Linux kernel modules ++ for hardware monitoring ++ ++ Copyright (c) 1998 - 2001 Frodo Looijaard , ++ Kyösti Mälkki , and ++ Mark D. Studebaker ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ Supports following revisions: ++ Version PCI ID PCI Revision ++ 1 1039/0008 AF or less ++ 2 1039/0008 B0 or greater ++ ++ Note: these chips contain a 0008 device which is incompatible with the ++ 5595. We recognize these by the presence of the listed ++ "blacklist" PCI ID and refuse to load. ++ ++ NOT SUPPORTED PCI ID BLACKLIST PCI ID ++ 540 0008 0540 ++ 550 0008 0550 ++ 5513 0008 5511 ++ 5581 0008 5597 ++ 5582 0008 5597 ++ 5597 0008 5597 ++ 5598 0008 5597/5598 ++ 630 0008 0630 ++ 645 0008 0645 ++ 730 0008 0730 ++ 735 0008 0735 ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* If force_addr is set to anything different from 0, we forcibly enable ++ the device at the given address. */ ++static int force_addr = 0; ++MODULE_PARM(force_addr, "i"); ++MODULE_PARM_DESC(force_addr, ++ "Initialize the base address of the sensors"); ++ ++/* Addresses to scan. ++ Note that we can't determine the ISA address until we have initialized ++ our module */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { 0x0000, SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(sis5595); ++ ++static int blacklist[] = { ++ PCI_DEVICE_ID_SI_540, ++ PCI_DEVICE_ID_SI_550, ++ PCI_DEVICE_ID_SI_630, ++ PCI_DEVICE_ID_SI_730, ++ PCI_DEVICE_ID_SI_5511, /* 5513 chip has the 0008 device but ++ that ID shows up in other chips so we ++ use the 5511 ID for recognition */ ++ PCI_DEVICE_ID_SI_5597, ++ PCI_DEVICE_ID_SI_5598, ++ 0x645, ++ 0x735, ++ 0 }; ++/* ++ SiS southbridge has a LM78-like chip integrated on the same IC. ++ This driver is a customized copy of lm78.c ++*/ ++ ++/* Many SIS5595 constants specified below */ ++ ++/* Length of ISA address segment */ ++#define SIS5595_EXTENT 8 ++/* PCI Config Registers */ ++#define SIS5595_REVISION_REG 0x08 ++#define SIS5595_BASE_REG 0x68 ++#define SIS5595_PIN_REG 0x7A ++#define SIS5595_ENABLE_REG 0x7B ++ ++/* Where are the ISA address/data registers relative to the base address */ ++#define SIS5595_ADDR_REG_OFFSET 5 ++#define SIS5595_DATA_REG_OFFSET 6 ++ ++/* The SIS5595 registers */ ++#define SIS5595_REG_IN_MAX(nr) (0x2b + (nr) * 2) ++#define SIS5595_REG_IN_MIN(nr) (0x2c + (nr) * 2) ++#define SIS5595_REG_IN(nr) (0x20 + (nr)) ++ ++#define SIS5595_REG_FAN_MIN(nr) (0x3a + (nr)) ++#define SIS5595_REG_FAN(nr) (0x27 + (nr)) ++ ++/* On the first version of the chip, the temp registers are separate. ++ On the second version, ++ TEMP pin is shared with IN4, configured in PCI register 0x7A. ++ The registers are the same as well. ++ OVER and HYST are really MAX and MIN. */ ++ ++#define REV2MIN 0xb0 ++#define SIS5595_REG_TEMP (( data->revision) >= REV2MIN) ? \ ++ SIS5595_REG_IN(4) : 0x27 ++#define SIS5595_REG_TEMP_OVER (( data->revision) >= REV2MIN) ? \ ++ SIS5595_REG_IN_MAX(4) : 0x39 ++#define SIS5595_REG_TEMP_HYST (( data->revision) >= REV2MIN) ? \ ++ SIS5595_REG_IN_MIN(4) : 0x3a ++ ++#define SIS5595_REG_CONFIG 0x40 ++#define SIS5595_REG_ALARM1 0x41 ++#define SIS5595_REG_ALARM2 0x42 ++#define SIS5595_REG_FANDIV 0x47 ++ ++/* Conversions. Limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++ ++#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255)) ++#define IN_FROM_REG(val) (((val) * 16 + 5) / 10) ++ ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 255; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, ++ 254); ++} ++ ++#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div))) ++ ++/* Version 1 datasheet temp=.83*reg + 52.12 */ ++#define TEMP_FROM_REG(val) (((((val)>=0x80?(val)-0x100:(val))*83)+5212)/10) ++/* inverse 1.20*val - 62.77 */ ++#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?\ ++ ((((val)*12)-6327)/100):\ ++ ((((val)*12)-6227)/100)),0,255)) ++ ++#define ALARMS_FROM_REG(val) (val) ++ ++#define DIV_FROM_REG(val) (1 << (val)) ++#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) ++ ++/* For the SIS5595, we need to keep some data in memory. That ++ data is pointed to by sis5595_list[NR]->data. The structure itself is ++ dynamically allocated, at the time when the new sis5595 client is ++ allocated. */ ++struct sis5595_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ char maxins; /* == 3 if temp enabled, otherwise == 4 */ ++ u8 revision; /* Reg. value */ ++ ++ u8 in[5]; /* Register value */ ++ u8 in_max[5]; /* Register value */ ++ u8 in_min[5]; /* Register value */ ++ u8 fan[2]; /* Register value */ ++ u8 fan_min[2]; /* Register value */ ++ u8 temp; /* Register value */ ++ u8 temp_over; /* Register value - really max */ ++ u8 temp_hyst; /* Register value - really min */ ++ u8 fan_div[2]; /* Register encoding, shifted right */ ++ u16 alarms; /* Register encoding, combined */ ++}; ++ ++static struct pci_dev *s_bridge; /* pointer to the (only) sis5595 */ ++ ++static int sis5595_attach_adapter(struct i2c_adapter *adapter); ++static int sis5595_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int sis5595_detach_client(struct i2c_client *client); ++ ++static int sis5595_read_value(struct i2c_client *client, u8 register); ++static int sis5595_write_value(struct i2c_client *client, u8 register, ++ u8 value); ++static void sis5595_update_client(struct i2c_client *client); ++static void sis5595_init_client(struct i2c_client *client); ++static int sis5595_find_sis(int *address); ++ ++ ++static void sis5595_in(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void sis5595_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void sis5595_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void sis5595_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void sis5595_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static int sis5595_id = 0; ++ ++/* The driver. I choose to use type i2c_driver, as at is identical to both ++ smbus_driver and isa_driver, and clients could be of either kind */ ++static struct i2c_driver sis5595_driver = { ++ .owner = THIS_MODULE, ++ .name = "SiS 5595", ++ .id = I2C_DRIVERID_SIS5595, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = sis5595_attach_adapter, ++ .detach_client = sis5595_detach_client, ++}; ++ ++/* The /proc/sys entries */ ++ ++/* -- SENSORS SYSCTL START -- */ ++#define SIS5595_SYSCTL_IN0 1000 /* Volts * 100 */ ++#define SIS5595_SYSCTL_IN1 1001 ++#define SIS5595_SYSCTL_IN2 1002 ++#define SIS5595_SYSCTL_IN3 1003 ++#define SIS5595_SYSCTL_IN4 1004 ++#define SIS5595_SYSCTL_FAN1 1101 /* Rotations/min */ ++#define SIS5595_SYSCTL_FAN2 1102 ++#define SIS5595_SYSCTL_TEMP 1200 /* Degrees Celcius * 10 */ ++#define SIS5595_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define SIS5595_SYSCTL_ALARMS 2001 /* bitvector */ ++ ++#define SIS5595_ALARM_IN0 0x01 ++#define SIS5595_ALARM_IN1 0x02 ++#define SIS5595_ALARM_IN2 0x04 ++#define SIS5595_ALARM_IN3 0x08 ++#define SIS5595_ALARM_BTI 0x20 ++#define SIS5595_ALARM_FAN1 0x40 ++#define SIS5595_ALARM_FAN2 0x80 ++#define SIS5595_ALARM_IN4 0x8000 ++#define SIS5595_ALARM_TEMP 0x8000 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected SIS5595. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table sis5595_dir_table_template[] = { ++ {SIS5595_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &sis5595_in}, ++ {SIS5595_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &sis5595_in}, ++ {SIS5595_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &sis5595_in}, ++ {SIS5595_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &sis5595_in}, ++ {SIS5595_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &sis5595_in}, ++ {SIS5595_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &sis5595_fan}, ++ {SIS5595_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &sis5595_fan}, ++ {SIS5595_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &sis5595_temp}, ++ {SIS5595_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &sis5595_fan_div}, ++ {SIS5595_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &sis5595_alarms}, ++ {0} ++}; ++ ++/* This is called when the module is loaded */ ++static int sis5595_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, sis5595_detect); ++} ++ ++/* Locate SiS bridge and correct base address for SIS5595 */ ++static int sis5595_find_sis(int *address) ++{ ++ u16 val; ++ int *i; ++ ++ if (!pci_present()) ++ return -ENODEV; ++ ++ if (!(s_bridge = ++ pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, ++ NULL))) ++ return -ENODEV; ++ ++ /* Look for imposters */ ++ for(i = blacklist; *i != 0; i++) { ++ if (pci_find_device(PCI_VENDOR_ID_SI, *i, NULL)) { ++ printk("sis5595.o: Error: Looked for SIS5595 but found unsupported device %.4X\n", *i); ++ return -ENODEV; ++ } ++ } ++ ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_word(s_bridge, SIS5595_BASE_REG, &val)) ++ return -ENODEV; ++ ++ *address = val & ~(SIS5595_EXTENT - 1); ++ if (*address == 0 && force_addr == 0) { ++ printk("sis5595.o: base address not set - upgrade BIOS or use force_addr=0xaddr\n"); ++ return -ENODEV; ++ } ++ if (force_addr) ++ *address = force_addr; /* so detect will get called */ ++ ++ return 0; ++} ++ ++int sis5595_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct sis5595_data *data; ++ int err = 0; ++ const char *type_name = "sis5595"; ++ const char *client_name = "SIS5595 chip"; ++ char val; ++ u16 a; ++ ++ /* Make sure we are probing the ISA bus!! */ ++ if (!i2c_is_isa_adapter(adapter)) { ++ printk ++ ("sis5595.o: sis5595_detect called for an I2C bus adapter?!?\n"); ++ return 0; ++ } ++ ++ if(force_addr) ++ address = force_addr & ~(SIS5595_EXTENT - 1); ++ if (check_region(address, SIS5595_EXTENT)) { ++ printk("sis5595.o: region 0x%x already in use!\n", address); ++ return -ENODEV; ++ } ++ if(force_addr) { ++ printk("sis5595.o: forcing ISA address 0x%04X\n", address); ++ if (PCIBIOS_SUCCESSFUL != ++ pci_write_config_word(s_bridge, SIS5595_BASE_REG, address)) ++ return -ENODEV; ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_word(s_bridge, SIS5595_BASE_REG, &a)) ++ return -ENODEV; ++ if ((a & ~(SIS5595_EXTENT - 1)) != address) { ++ /* doesn't work for some chips? */ ++ printk("sis5595.o: force address failed\n"); ++ return -ENODEV; ++ } ++ } ++ ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val)) ++ return -ENODEV; ++ if((val & 0x80) == 0) { ++ printk("sis5595.o: enabling sensors\n"); ++ if (PCIBIOS_SUCCESSFUL != ++ pci_write_config_byte(s_bridge, SIS5595_ENABLE_REG, ++ val | 0x80)) ++ return -ENODEV; ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val)) ++ return -ENODEV; ++ if((val & 0x80) == 0) { /* doesn't work for some chips! */ ++ printk("sis5595.o: sensors enable failed - not supported?\n"); ++ return -ENODEV; ++ } ++ } ++ ++ if (!(data = kmalloc(sizeof(struct sis5595_data), GFP_KERNEL))) { ++ return -ENOMEM; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ init_MUTEX(&data->lock); ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &sis5595_driver; ++ new_client->flags = 0; ++ ++ /* Reserve the ISA region */ ++ request_region(address, SIS5595_EXTENT, type_name); ++ ++ /* Check revision and pin registers to determine whether 3 or 4 voltages */ ++ pci_read_config_byte(s_bridge, SIS5595_REVISION_REG, &(data->revision)); ++ if(data->revision < REV2MIN) { ++ data->maxins = 3; ++ } else { ++ pci_read_config_byte(s_bridge, SIS5595_PIN_REG, &val); ++ if(val & 0x80) ++ /* 3 voltages, 1 temp */ ++ data->maxins = 3; ++ else ++ /* 4 voltages, no temps */ ++ data->maxins = 4; ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = sis5595_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry((struct i2c_client *) new_client, ++ type_name, ++ sis5595_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the SIS5595 chip */ ++ sis5595_init_client(new_client); ++ return 0; ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ release_region(address, SIS5595_EXTENT); ++ kfree(data); ++ return err; ++} ++ ++static int sis5595_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct sis5595_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("sis5595.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ release_region(client->addr, SIS5595_EXTENT); ++ kfree(client->data); ++ ++ return 0; ++} ++ ++ ++/* ISA access must be locked explicitly. ++ There are some ugly typecasts here, but the good news is - they should ++ nowhere else be necessary! */ ++static int sis5595_read_value(struct i2c_client *client, u8 reg) ++{ ++ int res; ++ ++ down(&(((struct sis5595_data *) (client->data))->lock)); ++ outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET); ++ res = inb_p(client->addr + SIS5595_DATA_REG_OFFSET); ++ up(&(((struct sis5595_data *) (client->data))->lock)); ++ return res; ++} ++ ++static int sis5595_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++ down(&(((struct sis5595_data *) (client->data))->lock)); ++ outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET); ++ outb_p(value, client->addr + SIS5595_DATA_REG_OFFSET); ++ up(&(((struct sis5595_data *) (client->data))->lock)); ++ return 0; ++} ++ ++/* Called when we have found a new SIS5595. */ ++static void sis5595_init_client(struct i2c_client *client) ++{ ++ u8 reg; ++ ++ /* Start monitoring */ ++ reg = i2c_smbus_read_byte_data(client, SIS5595_REG_CONFIG); ++ sis5595_write_value(client, SIS5595_REG_CONFIG, (reg|0x01)&0x7F); ++} ++ ++static void sis5595_update_client(struct i2c_client *client) ++{ ++ struct sis5595_data *data = client->data; ++ int i; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++ for (i = 0; i <= data->maxins; i++) { ++ data->in[i] = ++ sis5595_read_value(client, SIS5595_REG_IN(i)); ++ data->in_min[i] = ++ sis5595_read_value(client, ++ SIS5595_REG_IN_MIN(i)); ++ data->in_max[i] = ++ sis5595_read_value(client, ++ SIS5595_REG_IN_MAX(i)); ++ } ++ for (i = 1; i <= 2; i++) { ++ data->fan[i - 1] = ++ sis5595_read_value(client, SIS5595_REG_FAN(i)); ++ data->fan_min[i - 1] = ++ sis5595_read_value(client, ++ SIS5595_REG_FAN_MIN(i)); ++ } ++ if(data->maxins == 3) { ++ data->temp = ++ sis5595_read_value(client, SIS5595_REG_TEMP); ++ data->temp_over = ++ sis5595_read_value(client, SIS5595_REG_TEMP_OVER); ++ data->temp_hyst = ++ sis5595_read_value(client, SIS5595_REG_TEMP_HYST); ++ } ++ i = sis5595_read_value(client, SIS5595_REG_FANDIV); ++ data->fan_div[0] = (i >> 4) & 0x03; ++ data->fan_div[1] = i >> 6; ++ data->alarms = ++ sis5595_read_value(client, SIS5595_REG_ALARM1) | ++ (sis5595_read_value(client, SIS5595_REG_ALARM2) << 8); ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the date ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++ ++/* Return 0 for in4 and disallow writes if pin used for temp */ ++void sis5595_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct sis5595_data *data = client->data; ++ int nr = ctl_name - SIS5595_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ if(nr <= 3 || data->maxins == 4) { ++ sis5595_update_client(client); ++ results[0] = IN_FROM_REG(data->in_min[nr]); ++ results[1] = IN_FROM_REG(data->in_max[nr]); ++ results[2] = IN_FROM_REG(data->in[nr]); ++ } else { ++ results[0] = 0; ++ results[1] = 0; ++ results[2] = 0; ++ } ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if(nr <= 3 || data->maxins == 4) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = IN_TO_REG(results[0]); ++ sis5595_write_value(client, ++ SIS5595_REG_IN_MIN(nr), data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = IN_TO_REG(results[1]); ++ sis5595_write_value(client, ++ SIS5595_REG_IN_MAX(nr), data->in_max[nr]); ++ } ++ } ++ } ++} ++ ++void sis5595_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct sis5595_data *data = client->data; ++ int nr = ctl_name - SIS5595_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ sis5595_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ results[1] = FAN_FROM_REG(data->fan[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = FAN_TO_REG(results[0], ++ DIV_FROM_REG ++ (data-> ++ fan_div[nr-1])); ++ sis5595_write_value(client, ++ SIS5595_REG_FAN_MIN(nr), ++ data->fan_min[nr - 1]); ++ } ++ } ++} ++ ++ ++/* Return 0 for temp and disallow writes if pin used for in4 */ ++void sis5595_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct sis5595_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ if(data->maxins == 3) { ++ sis5595_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_over); ++ results[1] = TEMP_FROM_REG(data->temp_hyst); ++ results[2] = TEMP_FROM_REG(data->temp); ++ } else { ++ results[0] = 0; ++ results[1] = 0; ++ results[2] = 0; ++ } ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if(data->maxins == 3) { ++ if (*nrels_mag >= 1) { ++ data->temp_over = TEMP_TO_REG(results[0]); ++ sis5595_write_value(client, ++ SIS5595_REG_TEMP_OVER, data->temp_over); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst = TEMP_TO_REG(results[1]); ++ sis5595_write_value(client, ++ SIS5595_REG_TEMP_HYST, data->temp_hyst); ++ } ++ } ++ } ++} ++ ++void sis5595_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct sis5595_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ sis5595_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++void sis5595_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct sis5595_data *data = client->data; ++ int old; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ sis5595_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = sis5595_read_value(client, SIS5595_REG_FANDIV); ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ old = (old & 0x3f) | (data->fan_div[1] << 6); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ old = (old & 0xcf) | (data->fan_div[0] << 4); ++ sis5595_write_value(client, SIS5595_REG_FANDIV, old); ++ } ++ } ++} ++ ++static int __init sm_sis5595_init(void) ++{ ++ int addr; ++ ++ printk("sis5595.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ ++ if (sis5595_find_sis(&addr)) { ++ printk("sis5595.o: SIS5595 not detected, module not inserted.\n"); ++ return -ENODEV; ++ } ++ normal_isa[0] = addr; ++ ++ return i2c_add_driver(&sis5595_driver); ++} ++ ++static void __exit sm_sis5595_exit(void) ++{ ++ i2c_del_driver(&sis5595_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Kyösti Mälkki "); ++MODULE_DESCRIPTION("SiS 5595 Sensor device"); ++ ++module_init(sm_sis5595_init); ++module_exit(sm_sis5595_exit); +--- linux-old/drivers/sensors/smsc47m1.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/smsc47m1.c Mon Dec 13 20:18:52 2004 +@@ -0,0 +1,515 @@ ++/* ++ smsc47m1.c - Part of lm_sensors, Linux kernel modules ++ for hardware monitoring ++ ++ Copyright (c) 2002 Mark D. Studebaker ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++static int force_addr = 0; ++MODULE_PARM(force_addr, "i"); ++MODULE_PARM_DESC(force_addr, ++ "Initialize the base address of the sensors"); ++ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { 0x0000, SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++SENSORS_INSMOD_1(smsc47m1); ++ ++/* modified from kernel/include/traps.c */ ++#define REG 0x2e /* The register to read/write */ ++#define DEV 0x07 /* Register: Logical device select */ ++#define VAL 0x2f /* The value to read/write */ ++#define PME 0x0a /* The device with the fan registers in it */ ++#define DEVID 0x20 /* Register: Device ID */ ++ ++static inline void ++superio_outb(int reg, int val) ++{ ++ outb(reg, REG); ++ outb(val, VAL); ++} ++ ++static inline int ++superio_inb(int reg) ++{ ++ outb(reg, REG); ++ return inb(VAL); ++} ++ ++static inline void ++superio_select(void) ++{ ++ outb(DEV, REG); ++ outb(PME, VAL); ++} ++ ++static inline void ++superio_enter(void) ++{ ++ outb(0x55, REG); ++} ++ ++static inline void ++superio_exit(void) ++{ ++ outb(0xAA, REG); ++} ++ ++/* ++ * SMSC LPC47M10x (device id 0x59), LPC47M14x (device id 0x5F) and ++ * LPC47B27x (device id 0x51) have fan control. ++ * The 47M15x and 47M192 chips "with hardware monitoring block" ++ * can do much more besides (device id 0x60). ++ */ ++#define SMSC_DEVID_MATCH(id) ((id) == 0x51 || (id) == 0x59 || (id) == 0x5F) ++ ++#define SMSC_ACT_REG 0x30 ++#define SMSC_BASE_REG 0x60 ++ ++#define SMSC_EXTENT 0x80 ++ ++#define SMSC47M1_REG_ALARM1 0x04 ++#define SMSC47M1_REG_TPIN2 0x33 ++#define SMSC47M1_REG_TPIN1 0x34 ++#define SMSC47M1_REG_PPIN(nr) (0x37 - (nr)) ++#define SMSC47M1_REG_PWM(nr) (0x55 + (nr)) ++#define SMSC47M1_REG_FANDIV 0x58 ++#define SMSC47M1_REG_FAN(nr) (0x58 + (nr)) ++#define SMSC47M1_REG_FAN_MIN(nr) (0x5a + (nr)) ++ ++static inline u8 MIN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 0; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT(192 - ((983040 + rpm * div / 2) / (rpm * div)), ++ 0, 191); ++} ++ ++#define MIN_FROM_REG(val,div) ((val)>=192?0: \ ++ 983040/((192-(val))*(div))) ++#define FAN_FROM_REG(val,div,preload) ((val)==0?-1:(val)==255?0: \ ++ 983040/(((val)-preload)*(div))) ++#define DIV_FROM_REG(val) (1 << (val)) ++#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) ++/* reg is 6 middle bits; /proc is 8 bits */ ++#define PWM_FROM_REG(val) (((val) << 1) & 0xfc) ++#define PWM_TO_REG(val) (((SENSORS_LIMIT((val), 0, 255)) >> 1) & 0x7e) ++ ++struct smsc47m1_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 fan[2]; /* Register value */ ++ u8 fan_min[2]; /* Register value */ ++ u8 fan_div[2]; /* Register encoding, shifted right */ ++ u8 alarms; /* Register encoding */ ++ u8 pwm[2]; /* Register value (bit 7 is enable) */ ++}; ++ ++ ++static int smsc47m1_attach_adapter(struct i2c_adapter *adapter); ++static int smsc47m1_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int smsc47m1_detach_client(struct i2c_client *client); ++ ++static int smsc47m1_read_value(struct i2c_client *client, u8 register); ++static int smsc47m1_write_value(struct i2c_client *client, u8 register, ++ u8 value); ++static void smsc47m1_update_client(struct i2c_client *client); ++static void smsc47m1_init_client(struct i2c_client *client); ++static int smsc47m1_find(int *address); ++ ++ ++static void smsc47m1_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void smsc47m1_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void smsc47m1_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void smsc47m1_pwm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static int smsc47m1_id = 0; ++ ++static struct i2c_driver smsc47m1_driver = { ++ .owner = THIS_MODULE, ++ .name = "SMSC 47M1xx fan monitor", ++ .id = I2C_DRIVERID_SMSC47M1, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = smsc47m1_attach_adapter, ++ .detach_client = smsc47m1_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++#define SMSC47M1_SYSCTL_FAN1 1101 /* Rotations/min */ ++#define SMSC47M1_SYSCTL_FAN2 1102 ++#define SMSC47M1_SYSCTL_PWM1 1401 ++#define SMSC47M1_SYSCTL_PWM2 1402 ++#define SMSC47M1_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define SMSC47M1_SYSCTL_ALARMS 2004 /* bitvector */ ++ ++#define SMSC47M1_ALARM_FAN1 0x0001 ++#define SMSC47M1_ALARM_FAN2 0x0002 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++static ctl_table smsc47m1_dir_table_template[] = { ++ {SMSC47M1_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &smsc47m1_fan}, ++ {SMSC47M1_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &smsc47m1_fan}, ++ {SMSC47M1_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &smsc47m1_fan_div}, ++ {SMSC47M1_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &smsc47m1_alarms}, ++ {SMSC47M1_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &smsc47m1_pwm}, ++ {SMSC47M1_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &smsc47m1_pwm}, ++ {0} ++}; ++ ++static int smsc47m1_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, smsc47m1_detect); ++} ++ ++static int smsc47m1_find(int *address) ++{ ++ u16 val; ++ ++ superio_enter(); ++ val= superio_inb(DEVID); ++ if (!SMSC_DEVID_MATCH(val)) { ++ superio_exit(); ++ return -ENODEV; ++ } ++ ++ superio_select(); ++ val = (superio_inb(SMSC_BASE_REG) << 8) | ++ superio_inb(SMSC_BASE_REG + 1); ++ *address = val & ~(SMSC_EXTENT - 1); ++ if (*address == 0 && force_addr == 0) { ++ printk("smsc47m1.o: base address not set - use force_addr=0xaddr\n"); ++ superio_exit(); ++ return -ENODEV; ++ } ++ if (force_addr) ++ *address = force_addr; /* so detect will get called */ ++ ++ superio_exit(); ++ return 0; ++} ++ ++int smsc47m1_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct smsc47m1_data *data; ++ int err = 0; ++ const char *type_name = "smsc47m1"; ++ const char *client_name = "47M1xx chip"; ++ ++ if (!i2c_is_isa_adapter(adapter)) { ++ return 0; ++ } ++ ++ if(force_addr) ++ address = force_addr & ~(SMSC_EXTENT - 1); ++ if (check_region(address, SMSC_EXTENT)) { ++ printk("smsc47m1.o: region 0x%x already in use!\n", address); ++ return -ENODEV; ++ } ++ if(force_addr) { ++ printk("smsc47m1.o: forcing ISA address 0x%04X\n", address); ++ superio_enter(); ++ superio_select(); ++ superio_outb(SMSC_BASE_REG, address >> 8); ++ superio_outb(SMSC_BASE_REG+1, address & 0xff); ++ superio_exit(); ++ } ++ ++ if (!(data = kmalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) { ++ return -ENOMEM; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ init_MUTEX(&data->lock); ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &smsc47m1_driver; ++ new_client->flags = 0; ++ ++ request_region(address, SMSC_EXTENT, "smsc47m1-fans"); ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = smsc47m1_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ if ((i = i2c_register_entry((struct i2c_client *) new_client, ++ type_name, ++ smsc47m1_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ smsc47m1_init_client(new_client); ++ return 0; ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ release_region(address, SMSC_EXTENT); ++ kfree(data); ++ return err; ++} ++ ++static int smsc47m1_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct smsc47m1_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("smsc47m1.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ release_region(client->addr, SMSC_EXTENT); ++ kfree(client->data); ++ ++ return 0; ++} ++ ++static int smsc47m1_read_value(struct i2c_client *client, u8 reg) ++{ ++ int res; ++ ++ down(&(((struct smsc47m1_data *) (client->data))->lock)); ++ res = inb_p(client->addr + reg); ++ up(&(((struct smsc47m1_data *) (client->data))->lock)); ++ return res; ++} ++ ++static int smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++ down(&(((struct smsc47m1_data *) (client->data))->lock)); ++ outb_p(value, client->addr + reg); ++ up(&(((struct smsc47m1_data *) (client->data))->lock)); ++ return 0; ++} ++ ++static void smsc47m1_init_client(struct i2c_client *client) ++{ ++ /* configure pins for tach function */ ++ smsc47m1_write_value(client, SMSC47M1_REG_TPIN1, 0x05); ++ smsc47m1_write_value(client, SMSC47M1_REG_TPIN2, 0x05); ++} ++ ++static void smsc47m1_update_client(struct i2c_client *client) ++{ ++ struct smsc47m1_data *data = client->data; ++ int i; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ for (i = 1; i <= 2; i++) { ++ data->fan[i - 1] = ++ smsc47m1_read_value(client, SMSC47M1_REG_FAN(i)); ++ data->fan_min[i - 1] = ++ smsc47m1_read_value(client, SMSC47M1_REG_FAN_MIN(i)); ++ data->pwm[i - 1] = ++ smsc47m1_read_value(client, SMSC47M1_REG_PWM(i)); ++ } ++ ++ i = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV); ++ data->fan_div[0] = (i >> 4) & 0x03; ++ data->fan_div[1] = i >> 6; ++ data->alarms = ++ smsc47m1_read_value(client, SMSC47M1_REG_ALARM1) >> 6; ++ if(data->alarms) ++ smsc47m1_write_value(client, SMSC47M1_REG_ALARM1, 0xc0); ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++void smsc47m1_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct smsc47m1_data *data = client->data; ++ int nr = ctl_name - SMSC47M1_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ smsc47m1_update_client(client); ++ results[0] = MIN_FROM_REG(data->fan_min[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ results[1] = FAN_FROM_REG(data->fan[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1]), ++ data->fan_min[nr - 1]); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = MIN_TO_REG(results[0], ++ DIV_FROM_REG ++ (data-> ++ fan_div[nr-1])); ++ smsc47m1_write_value(client, SMSC47M1_REG_FAN_MIN(nr), ++ data->fan_min[nr - 1]); ++ } ++ } ++} ++ ++ ++void smsc47m1_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct smsc47m1_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ smsc47m1_update_client(client); ++ results[0] = data->alarms; ++ *nrels_mag = 1; ++ } ++} ++ ++void smsc47m1_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct smsc47m1_data *data = client->data; ++ int old; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ smsc47m1_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV); ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ old = (old & 0x3f) | (data->fan_div[1] << 6); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ old = (old & 0xcf) | (data->fan_div[0] << 4); ++ smsc47m1_write_value(client, SMSC47M1_REG_FANDIV, old); ++ } ++ } ++} ++ ++void smsc47m1_pwm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct smsc47m1_data *data = client->data; ++ int nr = 1 + ctl_name - SMSC47M1_SYSCTL_PWM1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ smsc47m1_update_client(client); ++ results[0] = PWM_FROM_REG(data->pwm[nr - 1]); ++ results[1] = data->pwm[nr - 1] & 0x01; ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->pwm[nr - 1] &= 0x81; ++ data->pwm[nr - 1] |= PWM_TO_REG(results[0]); ++ if (*nrels_mag >= 2) { ++ if(results[1] && (data->pwm[nr-1] & 0x01)) { ++ /* enable PWM */ ++/* hope BIOS did it already ++ smsc47m1_write_value(client, ++ SMSC47M1_REG_PPIN(nr), 0x04); ++*/ ++ data->pwm[nr - 1] &= 0xfe; ++ } else if((!results[1]) && (!(data->pwm[nr-1] & 0x01))) { ++ /* disable PWM */ ++ data->pwm[nr - 1] |= 0x01; ++ } ++ } ++ smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr), ++ data->pwm[nr - 1]); ++ } ++ } ++} ++ ++static int __init sm_smsc47m1_init(void) ++{ ++ int addr; ++ ++ printk("smsc47m1.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ ++ if (smsc47m1_find(&addr)) { ++ printk("smsc47m1.o: SMSC 47M1xx not detected, module not inserted.\n"); ++ return -ENODEV; ++ } ++ normal_isa[0] = addr; ++ ++ return i2c_add_driver(&smsc47m1_driver); ++} ++ ++static void __exit sm_smsc47m1_exit(void) ++{ ++ i2c_del_driver(&smsc47m1_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Mark D. Studebaker "); ++MODULE_DESCRIPTION("SMSC 47M1xx Fan sensors"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_smsc47m1_init); ++module_exit(sm_smsc47m1_exit); +--- linux-old/drivers/sensors/thmc50.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/thmc50.c Mon Dec 13 20:18:52 2004 +@@ -0,0 +1,496 @@ ++/* ++ thmc50.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999 Frodo Looijaard and ++ Philip Edelbrock ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#define DEBUG 1 ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++MODULE_LICENSE("GPL"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x2D, 0x2E, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(thmc50); ++ ++/* Many THMC50 constants specified below */ ++ ++/* The THMC50 registers */ ++#define THMC50_REG_TEMP 0x27 ++#define THMC50_REG_CONF 0x40 ++#define THMC50_REG_TEMP_HYST 0x3A ++#define THMC50_REG_TEMP_OS 0x39 ++ ++#define THMC50_REG_TEMP_TRIP 0x13 ++#define THMC50_REG_TEMP_REMOTE_TRIP 0x14 ++#define THMC50_REG_TEMP_DEFAULT_TRIP 0x17 ++#define THMC50_REG_TEMP_REMOTE_DEFAULT_TRIP 0x18 ++#define THMC50_REG_ANALOG_OUT 0x19 ++#define THMC50_REG_REMOTE_TEMP 0x26 ++#define THMC50_REG_REMOTE_TEMP_HYST 0x38 ++#define THMC50_REG_REMOTE_TEMP_OS 0x37 ++ ++#define THMC50_REG_INTER 0x41 ++#define THMC50_REG_INTER_MIRROR 0x4C ++#define THMC50_REG_INTER_MASK 0x43 ++ ++#define THMC50_REG_COMPANY_ID 0x3E ++#define THMC50_REG_DIE_CODE 0x3F ++ ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++#define TEMP_FROM_REG(val) ((val>127)?val - 0x0100:val) ++#define TEMP_TO_REG(val) ((val<0)?0x0100+val:val) ++ ++/* Each client has this additional data */ ++struct thmc50_data { ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u16 temp, temp_os, temp_hyst, ++ remote_temp, remote_temp_os, remote_temp_hyst, ++ inter, inter_mask, die_code, analog_out; /* Register values */ ++}; ++ ++static int thmc50_attach_adapter(struct i2c_adapter *adapter); ++static int thmc50_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static void thmc50_init_client(struct i2c_client *client); ++static int thmc50_detach_client(struct i2c_client *client); ++ ++static int thmc50_read_value(struct i2c_client *client, u8 reg); ++static int thmc50_write_value(struct i2c_client *client, u8 reg, ++ u16 value); ++static void thmc50_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void thmc50_remote_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, ++ long *results); ++static void thmc50_inter(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void thmc50_inter_mask(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void thmc50_die_code(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void thmc50_analog_out(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void thmc50_update_client(struct i2c_client *client); ++ ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver thmc50_driver = { ++ .owner = THIS_MODULE, ++ .name = "THMC50 sensor chip driver", ++ .id = I2C_DRIVERID_THMC50, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = thmc50_attach_adapter, ++ .detach_client = thmc50_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define THMC50_SYSCTL_TEMP 1200 /* Degrees Celcius */ ++#define THMC50_SYSCTL_REMOTE_TEMP 1201 /* Degrees Celcius */ ++#define THMC50_SYSCTL_INTER 1202 ++#define THMC50_SYSCTL_INTER_MASK 1203 ++#define THMC50_SYSCTL_DIE_CODE 1204 ++#define THMC50_SYSCTL_ANALOG_OUT 1205 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected THMC50. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table thmc50_dir_table_template[] = { ++ {THMC50_SYSCTL_TEMP, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &thmc50_temp}, ++ {THMC50_SYSCTL_REMOTE_TEMP, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &thmc50_remote_temp}, ++ {THMC50_SYSCTL_INTER, "inter", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &thmc50_inter}, ++ {THMC50_SYSCTL_INTER_MASK, "inter_mask", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &thmc50_inter_mask}, ++ {THMC50_SYSCTL_DIE_CODE, "die_code", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &thmc50_die_code}, ++ {THMC50_SYSCTL_ANALOG_OUT, "analog_out", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &thmc50_analog_out}, ++ {0} ++}; ++ ++ ++static int thmc50_id = 0; ++ ++static int thmc50_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, thmc50_detect); ++} ++ ++/* This function is called by i2c_detect */ ++int thmc50_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int company, i; ++ struct i2c_client *new_client; ++ struct thmc50_data *data; ++ int err = 0; ++ const char *type_name, *client_name; ++ ++#ifdef DEBUG ++ printk("thmc50.o: Probing for THMC50 at 0x%2X on bus %d\n", ++ address, adapter->id); ++#endif ++ ++ /* Make sure we aren't probing the ISA bus!! This is just a safety check ++ at this moment; i2c_detect really won't call us. */ ++#ifdef DEBUG ++ if (i2c_is_isa_adapter(adapter)) { ++ printk ++ ("thmc50.o: thmc50_detect called for an ISA bus adapter?!?\n"); ++ return 0; ++ } ++#endif ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto ERROR0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access thmc50_{read,write}_value. */ ++ if (!(data = kmalloc(sizeof(struct thmc50_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &thmc50_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ company = ++ i2c_smbus_read_byte_data(new_client, THMC50_REG_COMPANY_ID); ++ ++ if (company != 0x49) { ++#ifdef DEBUG ++ printk ++ ("thmc50.o: Detect of THMC50 failed (reg 3E: 0x%X)\n", ++ company); ++#endif ++ goto ERROR1; ++ } ++ ++ /* Determine the chip type - only one kind supported! */ ++ kind = thmc50; ++ ++ if (kind == thmc50) { ++ type_name = "thmc50"; ++ client_name = "THMC50 chip"; ++ } else { ++#ifdef DEBUG ++ printk("thmc50.o: Internal error: unknown kind (%d)?!?", ++ kind); ++#endif ++ goto ERROR1; ++ } ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = thmc50_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, type_name, ++ thmc50_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ thmc50_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int thmc50_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct thmc50_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("thmc50.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++} ++ ++ ++/* All registers are word-sized, except for the configuration register. ++ THMC50 uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int thmc50_read_value(struct i2c_client *client, u8 reg) ++{ ++ return i2c_smbus_read_byte_data(client, reg); ++} ++ ++/* All registers are word-sized, except for the configuration register. ++ THMC50 uses a high-byte first convention, which is exactly opposite to ++ the usual practice. */ ++static int thmc50_write_value(struct i2c_client *client, u8 reg, u16 value) ++{ ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++static void thmc50_init_client(struct i2c_client *client) ++{ ++ thmc50_write_value(client, THMC50_REG_CONF, 1); ++} ++ ++static void thmc50_update_client(struct i2c_client *client) ++{ ++ struct thmc50_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("Starting thmc50 update\n"); ++#endif ++ ++ data->temp = thmc50_read_value(client, THMC50_REG_TEMP); ++ data->temp_os = ++ thmc50_read_value(client, THMC50_REG_TEMP_OS); ++ data->temp_hyst = ++ thmc50_read_value(client, THMC50_REG_TEMP_HYST); ++ data->remote_temp = ++ thmc50_read_value(client, THMC50_REG_REMOTE_TEMP); ++ data->remote_temp_os = ++ thmc50_read_value(client, THMC50_REG_REMOTE_TEMP_OS); ++ data->remote_temp_hyst = ++ thmc50_read_value(client, THMC50_REG_REMOTE_TEMP_HYST); ++ data->inter = thmc50_read_value(client, THMC50_REG_INTER); ++ data->inter_mask = ++ thmc50_read_value(client, THMC50_REG_INTER_MASK); ++ data->die_code = ++ thmc50_read_value(client, THMC50_REG_DIE_CODE); ++ data->analog_out = ++ thmc50_read_value(client, THMC50_REG_ANALOG_OUT); ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++void thmc50_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct thmc50_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ thmc50_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_os); ++ results[1] = TEMP_FROM_REG(data->temp_hyst); ++ results[2] = TEMP_FROM_REG(data->temp); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_os = TEMP_TO_REG(results[0]); ++ thmc50_write_value(client, THMC50_REG_TEMP_OS, ++ data->temp_os); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst = TEMP_TO_REG(results[1]); ++ thmc50_write_value(client, THMC50_REG_TEMP_HYST, ++ data->temp_hyst); ++ } ++ } ++} ++ ++ ++void thmc50_remote_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct thmc50_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ thmc50_update_client(client); ++ results[0] = TEMP_FROM_REG(data->remote_temp_os); ++ results[1] = TEMP_FROM_REG(data->remote_temp_hyst); ++ results[2] = TEMP_FROM_REG(data->remote_temp); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->remote_temp_os = TEMP_TO_REG(results[0]); ++ thmc50_write_value(client, ++ THMC50_REG_REMOTE_TEMP_OS, ++ data->remote_temp_os); ++ } ++ if (*nrels_mag >= 2) { ++ data->remote_temp_hyst = TEMP_TO_REG(results[1]); ++ thmc50_write_value(client, ++ THMC50_REG_REMOTE_TEMP_HYST, ++ data->remote_temp_hyst); ++ } ++ } ++} ++ ++ ++void thmc50_inter(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct thmc50_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ thmc50_update_client(client); ++ results[0] = data->inter; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ printk("thmc50.o: No writes to Interrupt register!\n"); ++ } ++} ++ ++ ++void thmc50_inter_mask(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct thmc50_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ thmc50_update_client(client); ++ results[0] = data->inter_mask; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->inter_mask = results[0]; ++ thmc50_write_value(client, THMC50_REG_INTER_MASK, ++ data->inter_mask); ++ } ++ } ++} ++ ++ ++void thmc50_die_code(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct thmc50_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ thmc50_update_client(client); ++ results[0] = data->die_code; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ printk("thmc50.o: No writes to Die-Code register!\n"); ++ } ++} ++ ++ ++void thmc50_analog_out(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct thmc50_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ thmc50_update_client(client); ++ results[0] = data->analog_out; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->analog_out = results[0]; ++ thmc50_write_value(client, THMC50_REG_ANALOG_OUT, ++ data->analog_out); ++ } ++ } ++} ++ ++ ++ ++ ++static int __init sm_thmc50_init(void) ++{ ++ printk("thmc50.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ ++ return i2c_add_driver(&thmc50_driver); ++} ++ ++static void __exit sm_thmc50_exit(void) ++{ ++ i2c_del_driver(&thmc50_driver); ++} ++ ++ ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard and Philip Edelbrock "); ++MODULE_DESCRIPTION("THMC50 driver"); ++ ++module_init(sm_thmc50_init); ++module_exit(sm_thmc50_exit); +--- linux-old/drivers/sensors/via686a.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/via686a.c Mon Dec 13 20:18:52 2004 +@@ -0,0 +1,849 @@ ++/* ++ via686a.c - Part of lm_sensors, Linux kernel modules ++ for hardware monitoring ++ ++ Copyright (c) 1998 - 2002 Frodo Looijaard , ++ Kyösti Mälkki , ++ Mark Studebaker , ++ and Bob Dougherty ++ (Some conversion-factor data were contributed by Jonathan Teh Soon Yew ++ and Alex van Kaam .) ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ Supports the Via VT82C686A, VT82C686B south bridges. ++ Reports all as a 686A. ++ See doc/chips/via686a for details. ++ Warning - only supports a single device. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++ ++/* If force_addr is set to anything different from 0, we forcibly enable ++ the device at the given address. */ ++static int force_addr = 0; ++MODULE_PARM(force_addr, "i"); ++MODULE_PARM_DESC(force_addr, ++ "Initialize the base address of the sensors"); ++ ++/* Addresses to scan. ++ Note that we can't determine the ISA address until we have initialized ++ our module */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { 0x0000, SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(via686a); ++ ++/* ++ The Via 686a southbridge has a LM78-like chip integrated on the same IC. ++ This driver is a customized copy of lm78.c ++*/ ++ ++/* Many VIA686A constants specified below */ ++ ++/* Length of ISA address segment */ ++#define VIA686A_EXTENT 0x80 ++#define VIA686A_BASE_REG 0x70 ++#define VIA686A_ENABLE_REG 0x74 ++ ++/* The VIA686A registers */ ++/* ins numbered 0-4 */ ++#define VIA686A_REG_IN_MAX(nr) (0x2b + ((nr) * 2)) ++#define VIA686A_REG_IN_MIN(nr) (0x2c + ((nr) * 2)) ++#define VIA686A_REG_IN(nr) (0x22 + (nr)) ++ ++/* fans numbered 1-2 */ ++#define VIA686A_REG_FAN_MIN(nr) (0x3a + (nr)) ++#define VIA686A_REG_FAN(nr) (0x28 + (nr)) ++ ++// the following values are as speced by VIA: ++static const u8 regtemp[] = { 0x20, 0x21, 0x1f }; ++static const u8 regover[] = { 0x39, 0x3d, 0x1d }; ++static const u8 reghyst[] = { 0x3a, 0x3e, 0x1e }; ++ ++/* temps numbered 1-3 */ ++#define VIA686A_REG_TEMP(nr) (regtemp[(nr) - 1]) ++#define VIA686A_REG_TEMP_OVER(nr) (regover[(nr) - 1]) ++#define VIA686A_REG_TEMP_HYST(nr) (reghyst[(nr) - 1]) ++#define VIA686A_REG_TEMP_LOW1 0x4b // bits 7-6 ++#define VIA686A_REG_TEMP_LOW23 0x49 // 2 = bits 5-4, 3 = bits 7-6 ++ ++#define VIA686A_REG_ALARM1 0x41 ++#define VIA686A_REG_ALARM2 0x42 ++#define VIA686A_REG_FANDIV 0x47 ++#define VIA686A_REG_CONFIG 0x40 ++// The following register sets temp interrupt mode (bits 1-0 for temp1, ++// 3-2 for temp2, 5-4 for temp3). Modes are: ++// 00 interrupt stays as long as value is out-of-range ++// 01 interrupt is cleared once register is read (default) ++// 10 comparator mode- like 00, but ignores hysteresis ++// 11 same as 00 ++#define VIA686A_REG_TEMP_MODE 0x4b ++// We'll just assume that you want to set all 3 simultaneously: ++#define VIA686A_TEMP_MODE_MASK 0x3F ++#define VIA686A_TEMP_MODE_CONTINUOUS (0x00) ++ ++/* Conversions. Limit checking is only done on the TO_REG ++ variants. */ ++ ++/********* VOLTAGE CONVERSIONS (Bob Dougherty) ********/ ++// From HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew): ++// voltagefactor[0]=1.25/2628; (2628/1.25=2102.4) // Vccp ++// voltagefactor[1]=1.25/2628; (2628/1.25=2102.4) // +2.5V ++// voltagefactor[2]=1.67/2628; (2628/1.67=1573.7) // +3.3V ++// voltagefactor[3]=2.6/2628; (2628/2.60=1010.8) // +5V ++// voltagefactor[4]=6.3/2628; (2628/6.30=417.14) // +12V ++// in[i]=(data[i+2]*25.0+133)*voltagefactor[i]; ++// That is: ++// volts = (25*regVal+133)*factor ++// regVal = (volts/factor-133)/25 ++// (These conversions were contributed by Jonathan Teh Soon Yew ++// ) ++static inline u8 IN_TO_REG(long val, int inNum) ++{ ++ /* To avoid floating point, we multiply constants by 10 (100 for +12V). ++ Rounding is done (120500 is actually 133000 - 12500). ++ Remember that val is expressed in 0.01V/bit, which is why we divide ++ by an additional 1000 (10000 for +12V): 100 for val and 10 (100) ++ for the constants. */ ++ if (inNum <= 1) ++ return (u8) ++ SENSORS_LIMIT((val * 21024 - 120500) / 25000, 0, 255); ++ else if (inNum == 2) ++ return (u8) ++ SENSORS_LIMIT((val * 15737 - 120500) / 25000, 0, 255); ++ else if (inNum == 3) ++ return (u8) ++ SENSORS_LIMIT((val * 10108 - 120500) / 25000, 0, 255); ++ else ++ return (u8) ++ SENSORS_LIMIT((val * 41714 - 1205000) / 250000, 0, 255); ++} ++ ++static inline long IN_FROM_REG(u8 val, int inNum) ++{ ++ /* To avoid floating point, we multiply constants by 10 (100 for +12V). ++ We also multiply them by 100 because we want 0.01V/bit for the ++ output value. Rounding is done. */ ++ if (inNum <= 1) ++ return (long) ((25000 * val + 133000 + 21024 / 2) / 21024); ++ else if (inNum == 2) ++ return (long) ((25000 * val + 133000 + 15737 / 2) / 15737); ++ else if (inNum == 3) ++ return (long) ((25000 * val + 133000 + 10108 / 2) / 10108); ++ else ++ return (long) ((250000 * val + 1330000 + 41714 / 2) / 41714); ++} ++ ++/********* FAN RPM CONVERSIONS ********/ ++// Higher register values = slower fans (the fan's strobe gates a counter). ++// But this chip saturates back at 0, not at 255 like all the other chips. ++// So, 0 means 0 RPM ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 0; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 255); ++} ++ ++#define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:1350000/((val)*(div))) ++ ++/******** TEMP CONVERSIONS (Bob Dougherty) *********/ ++// linear fits from HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew) ++// if(temp<169) ++// return double(temp)*0.427-32.08; ++// else if(temp>=169 && temp<=202) ++// return double(temp)*0.582-58.16; ++// else ++// return double(temp)*0.924-127.33; ++// ++// A fifth-order polynomial fits the unofficial data (provided by Alex van ++// Kaam ) a bit better. It also give more reasonable ++// numbers on my machine (ie. they agree with what my BIOS tells me). ++// Here's the fifth-order fit to the 8-bit data: ++// temp = 1.625093e-10*val^5 - 1.001632e-07*val^4 + 2.457653e-05*val^3 - ++// 2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0. ++// ++// (2000-10-25- RFD: thanks to Uwe Andersen for ++// finding my typos in this formula!) ++// ++// Alas, none of the elegant function-fit solutions will work because we ++// aren't allowed to use floating point in the kernel and doing it with ++// integers doesn't rpovide enough precision. So we'll do boring old ++// look-up table stuff. The unofficial data (see below) have effectively ++// 7-bit resolution (they are rounded to the nearest degree). I'm assuming ++// that the transfer function of the device is monotonic and smooth, so a ++// smooth function fit to the data will allow us to get better precision. ++// I used the 5th-order poly fit described above and solved for ++// VIA register values 0-255. I *10 before rounding, so we get tenth-degree ++// precision. (I could have done all 1024 values for our 10-bit readings, ++// but the function is very linear in the useful range (0-80 deg C), so ++// we'll just use linear interpolation for 10-bit readings.) So, tempLUT ++// is the temp at via register values 0-255: ++static const long tempLUT[] = ++ { -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519, ++ -503, -487, -471, -456, -442, -428, -414, -400, -387, -375, ++ -362, -350, -339, -327, -316, -305, -295, -285, -275, -265, ++ -255, -246, -237, -229, -220, -212, -204, -196, -188, -180, ++ -173, -166, -159, -152, -145, -139, -132, -126, -120, -114, ++ -108, -102, -96, -91, -85, -80, -74, -69, -64, -59, -54, -49, ++ -44, -39, -34, -29, -25, -20, -15, -11, -6, -2, 3, 7, 12, 16, ++ 20, 25, 29, 33, 37, 42, 46, 50, 54, 59, 63, 67, 71, 75, 79, 84, ++ 88, 92, 96, 100, 104, 109, 113, 117, 121, 125, 130, 134, 138, ++ 142, 146, 151, 155, 159, 163, 168, 172, 176, 181, 185, 189, ++ 193, 198, 202, 206, 211, 215, 219, 224, 228, 232, 237, 241, ++ 245, 250, 254, 259, 263, 267, 272, 276, 281, 285, 290, 294, ++ 299, 303, 307, 312, 316, 321, 325, 330, 334, 339, 344, 348, ++ 353, 357, 362, 366, 371, 376, 380, 385, 390, 395, 399, 404, ++ 409, 414, 419, 423, 428, 433, 438, 443, 449, 454, 459, 464, ++ 469, 475, 480, 486, 491, 497, 502, 508, 514, 520, 526, 532, ++ 538, 544, 551, 557, 564, 571, 578, 584, 592, 599, 606, 614, ++ 621, 629, 637, 645, 654, 662, 671, 680, 689, 698, 708, 718, ++ 728, 738, 749, 759, 770, 782, 793, 805, 818, 830, 843, 856, ++ 870, 883, 898, 912, 927, 943, 958, 975, 991, 1008, 1026, 1044, ++ 1062, 1081, 1101, 1121, 1141, 1162, 1184, 1206, 1229, 1252, ++ 1276, 1301, 1326, 1352, 1378, 1406, 1434, 1462 ++}; ++ ++/* the original LUT values from Alex van Kaam ++ (for via register values 12-240): ++{-50,-49,-47,-45,-43,-41,-39,-38,-37,-35,-34,-33,-32,-31, ++-30,-29,-28,-27,-26,-25,-24,-24,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15, ++-15,-14,-14,-13,-12,-12,-11,-11,-10,-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3, ++-3,-2,-2,-1,-1,0,0,1,1,1,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,9,10,10,11,11,12, ++12,12,13,13,13,14,14,15,15,16,16,16,17,17,18,18,19,19,20,20,21,21,21,22,22, ++22,23,23,24,24,25,25,26,26,26,27,27,27,28,28,29,29,30,30,30,31,31,32,32,33, ++33,34,34,35,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45, ++45,46,46,47,48,48,49,49,50,51,51,52,52,53,53,54,55,55,56,57,57,58,59,59,60, ++61,62,62,63,64,65,66,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,83,84, ++85,86,88,89,91,92,94,96,97,99,101,103,105,107,109,110}; ++*/ ++ ++// Here's the reverse LUT. I got it by doing a 6-th order poly fit (needed ++// an extra term for a good fit to these inverse data!) and then ++// solving for each temp value from -50 to 110 (the useable range for ++// this chip). Here's the fit: ++// viaRegVal = -1.160370e-10*val^6 +3.193693e-08*val^5 - 1.464447e-06*val^4 ++// - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01) ++// Note that n=161: ++static const u8 viaLUT[] = ++ { 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23, ++ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40, ++ 41, 43, 45, 46, 48, 49, 51, 53, 55, 57, 59, 60, 62, 64, 66, ++ 69, 71, 73, 75, 77, 79, 82, 84, 86, 88, 91, 93, 95, 98, 100, ++ 103, 105, 107, 110, 112, 115, 117, 119, 122, 124, 126, 129, ++ 131, 134, 136, 138, 140, 143, 145, 147, 150, 152, 154, 156, ++ 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, ++ 182, 183, 185, 187, 188, 190, 192, 193, 195, 196, 198, 199, ++ 200, 202, 203, 205, 206, 207, 208, 209, 210, 211, 212, 213, ++ 214, 215, 216, 217, 218, 219, 220, 221, 222, 222, 223, 224, ++ 225, 226, 226, 227, 228, 228, 229, 230, 230, 231, 232, 232, ++ 233, 233, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, ++ 239, 240 ++}; ++ ++/* Converting temps to (8-bit) hyst and over registers ++ No interpolation here. ++ The +50 is because the temps start at -50 */ ++static inline u8 TEMP_TO_REG(long val) ++{ ++ return viaLUT[val <= -500 ? 0 : val >= 1100 ? 160 : ++ (val < 0 ? val - 5 : val + 5) / 10 + 50]; ++} ++ ++/* for 8-bit temperature hyst and over registers */ ++#define TEMP_FROM_REG(val) (tempLUT[(val)]) ++ ++/* for 10-bit temperature readings */ ++// You might _think_ this is too long to inline, but's it's really only ++// called once... ++static inline long TEMP_FROM_REG10(u16 val) ++{ ++ // the temp values are already *10, so we don't need to do that. ++ long temp; ++ u16 eightBits = val >> 2; ++ u16 twoBits = val & 3; ++ ++ /* no interpolation for these */ ++ if (twoBits == 0 || eightBits == 255) ++ return (long) tempLUT[eightBits]; ++ ++ /* do some linear interpolation */ ++ temp = (4 - twoBits) * tempLUT[eightBits] ++ + twoBits * tempLUT[eightBits + 1]; ++ /* achieve rounding */ ++ return (temp < 0 ? temp - 2 : temp + 2) / 4; ++} ++ ++#define ALARMS_FROM_REG(val) (val) ++ ++#define DIV_FROM_REG(val) (1 << (val)) ++#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) ++ ++/* For the VIA686A, we need to keep some data in memory. ++ The structure is dynamically allocated, at the same time when a new ++ via686a client is allocated. */ ++struct via686a_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 in[5]; /* Register value */ ++ u8 in_max[5]; /* Register value */ ++ u8 in_min[5]; /* Register value */ ++ u8 fan[2]; /* Register value */ ++ u8 fan_min[2]; /* Register value */ ++ u16 temp[3]; /* Register value 10 bit */ ++ u8 temp_over[3]; /* Register value */ ++ u8 temp_hyst[3]; /* Register value */ ++ u8 fan_div[2]; /* Register encoding, shifted right */ ++ u16 alarms; /* Register encoding, combined */ ++}; ++ ++static struct pci_dev *s_bridge; /* pointer to the (only) via686a */ ++ ++static int via686a_attach_adapter(struct i2c_adapter *adapter); ++static int via686a_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int via686a_detach_client(struct i2c_client *client); ++ ++static int via686a_read_value(struct i2c_client *client, u8 register); ++static void via686a_write_value(struct i2c_client *client, u8 register, ++ u8 value); ++static void via686a_update_client(struct i2c_client *client); ++static void via686a_init_client(struct i2c_client *client); ++ ++ ++static void via686a_in(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void via686a_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void via686a_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void via686a_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void via686a_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static int via686a_id = 0; ++ ++/* The driver. I choose to use type i2c_driver, as at is identical to both ++ smbus_driver and isa_driver, and clients could be of either kind */ ++static struct i2c_driver via686a_driver = { ++ .owner = THIS_MODULE, ++ .name = "VIA 686A", ++ .id = I2C_DRIVERID_VIA686A, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = via686a_attach_adapter, ++ .detach_client = via686a_detach_client, ++}; ++ ++ ++ ++/* The /proc/sys entries */ ++ ++/* -- SENSORS SYSCTL START -- */ ++#define VIA686A_SYSCTL_IN0 1000 ++#define VIA686A_SYSCTL_IN1 1001 ++#define VIA686A_SYSCTL_IN2 1002 ++#define VIA686A_SYSCTL_IN3 1003 ++#define VIA686A_SYSCTL_IN4 1004 ++#define VIA686A_SYSCTL_FAN1 1101 ++#define VIA686A_SYSCTL_FAN2 1102 ++#define VIA686A_SYSCTL_TEMP 1200 ++#define VIA686A_SYSCTL_TEMP2 1201 ++#define VIA686A_SYSCTL_TEMP3 1202 ++#define VIA686A_SYSCTL_FAN_DIV 2000 ++#define VIA686A_SYSCTL_ALARMS 2001 ++ ++#define VIA686A_ALARM_IN0 0x01 ++#define VIA686A_ALARM_IN1 0x02 ++#define VIA686A_ALARM_IN2 0x04 ++#define VIA686A_ALARM_IN3 0x08 ++#define VIA686A_ALARM_TEMP 0x10 ++#define VIA686A_ALARM_FAN1 0x40 ++#define VIA686A_ALARM_FAN2 0x80 ++#define VIA686A_ALARM_IN4 0x100 ++#define VIA686A_ALARM_TEMP2 0x800 ++#define VIA686A_ALARM_CHAS 0x1000 ++#define VIA686A_ALARM_TEMP3 0x8000 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected VIA686A. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table via686a_dir_table_template[] = { ++ {VIA686A_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &via686a_in}, ++ {VIA686A_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &via686a_in}, ++ {VIA686A_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &via686a_in}, ++ {VIA686A_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &via686a_in}, ++ {VIA686A_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &via686a_in}, ++ {VIA686A_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &via686a_fan}, ++ {VIA686A_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &via686a_fan}, ++ {VIA686A_SYSCTL_TEMP, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &via686a_temp}, ++ {VIA686A_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &via686a_temp}, ++ {VIA686A_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &via686a_temp}, ++ {VIA686A_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &via686a_fan_div}, ++ {VIA686A_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &via686a_alarms}, ++ {0} ++}; ++ ++static inline int via686a_read_value(struct i2c_client *client, u8 reg) ++{ ++ return (inb_p(client->addr + reg)); ++} ++ ++static inline void via686a_write_value(struct i2c_client *client, u8 reg, ++ u8 value) ++{ ++ outb_p(value, client->addr + reg); ++} ++ ++/* This is called when the module is loaded */ ++static int via686a_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, via686a_detect); ++} ++ ++int via686a_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct via686a_data *data; ++ int err = 0; ++ const char *type_name = "via686a"; ++ u16 val; ++ ++ /* Make sure we are probing the ISA bus!! */ ++ if (!i2c_is_isa_adapter(adapter)) { ++ printk ++ ("via686a.o: via686a_detect called for an I2C bus adapter?!?\n"); ++ return 0; ++ } ++ ++ /* 8231 requires multiple of 256, we enforce that on 686 as well */ ++ if(force_addr) ++ address = force_addr & 0xFF00; ++ if (check_region(address, VIA686A_EXTENT)) { ++ printk("via686a.o: region 0x%x already in use!\n", ++ address); ++ return -ENODEV; ++ } ++ ++ if(force_addr) { ++ printk("via686a.o: forcing ISA address 0x%04X\n", address); ++ if (PCIBIOS_SUCCESSFUL != ++ pci_write_config_word(s_bridge, VIA686A_BASE_REG, address)) ++ return -ENODEV; ++ } ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_word(s_bridge, VIA686A_ENABLE_REG, &val)) ++ return -ENODEV; ++ if (!(val & 0x0001)) { ++ printk("via686a.o: enabling sensors\n"); ++ if (PCIBIOS_SUCCESSFUL != ++ pci_write_config_word(s_bridge, VIA686A_ENABLE_REG, ++ val | 0x0001)) ++ return -ENODEV; ++ } ++ ++ if (!(data = kmalloc(sizeof(struct via686a_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ init_MUTEX(&data->lock); ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &via686a_driver; ++ new_client->flags = 0; ++ ++ /* Reserve the ISA region */ ++ request_region(address, VIA686A_EXTENT, "via686a-sensors"); ++ ++ /* Fill in the remaining client fields and put into the global list */ ++ strcpy(new_client->name, "Via 686A Integrated Sensors"); ++ ++ new_client->id = via686a_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry((struct i2c_client *) new_client, ++ type_name, ++ via686a_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the VIA686A chip */ ++ via686a_init_client(new_client); ++ return 0; ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ release_region(address, VIA686A_EXTENT); ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int via686a_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct via686a_data *) ++ (client->data))->sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("via686a.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ release_region(client->addr, VIA686A_EXTENT); ++ kfree(client->data); ++ ++ return 0; ++} ++ ++/* Called when we have found a new VIA686A. */ ++static void via686a_init_client(struct i2c_client *client) ++{ ++ u8 reg; ++ ++ /* Start monitoring */ ++ reg = via686a_read_value(client, VIA686A_REG_CONFIG); ++ via686a_write_value(client, VIA686A_REG_CONFIG, (reg|0x01)&0x7F); ++ ++ /* Configure temp interrupt mode for continuous-interrupt operation */ ++ via686a_write_value(client, VIA686A_REG_TEMP_MODE, ++ via686a_read_value(client, VIA686A_REG_TEMP_MODE) & ++ !(VIA686A_TEMP_MODE_MASK | VIA686A_TEMP_MODE_CONTINUOUS)); ++} ++ ++static void via686a_update_client(struct i2c_client *client) ++{ ++ struct via686a_data *data = client->data; ++ int i; ++ ++ down(&data->update_lock); ++ ++ if (time_after(jiffies - data->last_updated, HZ + HZ / 2) || ++ time_before(jiffies, data->last_updated) || !data->valid) { ++ ++ for (i = 0; i <= 4; i++) { ++ data->in[i] = ++ via686a_read_value(client, VIA686A_REG_IN(i)); ++ data->in_min[i] = via686a_read_value(client, ++ VIA686A_REG_IN_MIN ++ (i)); ++ data->in_max[i] = ++ via686a_read_value(client, VIA686A_REG_IN_MAX(i)); ++ } ++ for (i = 1; i <= 2; i++) { ++ data->fan[i - 1] = ++ via686a_read_value(client, VIA686A_REG_FAN(i)); ++ data->fan_min[i - 1] = via686a_read_value(client, ++ VIA686A_REG_FAN_MIN(i)); ++ } ++ for (i = 1; i <= 3; i++) { ++ data->temp[i - 1] = via686a_read_value(client, ++ VIA686A_REG_TEMP(i)) << 2; ++ data->temp_over[i - 1] = ++ via686a_read_value(client, ++ VIA686A_REG_TEMP_OVER(i)); ++ data->temp_hyst[i - 1] = ++ via686a_read_value(client, ++ VIA686A_REG_TEMP_HYST(i)); ++ } ++ /* add in lower 2 bits ++ temp1 uses bits 7-6 of VIA686A_REG_TEMP_LOW1 ++ temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23 ++ temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23 ++ */ ++ data->temp[0] |= (via686a_read_value(client, ++ VIA686A_REG_TEMP_LOW1) ++ & 0xc0) >> 6; ++ data->temp[1] |= ++ (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) & ++ 0x30) >> 4; ++ data->temp[2] |= ++ (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) & ++ 0xc0) >> 6; ++ ++ i = via686a_read_value(client, VIA686A_REG_FANDIV); ++ data->fan_div[0] = (i >> 4) & 0x03; ++ data->fan_div[1] = i >> 6; ++ data->alarms = ++ via686a_read_value(client, ++ VIA686A_REG_ALARM1) | ++ (via686a_read_value(client, VIA686A_REG_ALARM2) << 8); ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the date ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++static void via686a_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct via686a_data *data = client->data; ++ int nr = ctl_name - VIA686A_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ via686a_update_client(client); ++ results[0] = IN_FROM_REG(data->in_min[nr], nr); ++ results[1] = IN_FROM_REG(data->in_max[nr], nr); ++ results[2] = IN_FROM_REG(data->in[nr], nr); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = IN_TO_REG(results[0], nr); ++ via686a_write_value(client, VIA686A_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = IN_TO_REG(results[1], nr); ++ via686a_write_value(client, VIA686A_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++} ++ ++void via686a_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct via686a_data *data = client->data; ++ int nr = ctl_name - VIA686A_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ via686a_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr - 1], ++ DIV_FROM_REG(data->fan_div ++ [nr - 1])); ++ results[1] = FAN_FROM_REG(data->fan[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = FAN_TO_REG(results[0], ++ DIV_FROM_REG(data-> ++ fan_div[nr -1])); ++ via686a_write_value(client, ++ VIA686A_REG_FAN_MIN(nr), ++ data->fan_min[nr - 1]); ++ } ++ } ++} ++ ++void via686a_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct via686a_data *data = client->data; ++ int nr = ctl_name - VIA686A_SYSCTL_TEMP; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ via686a_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_over[nr]); ++ results[1] = TEMP_FROM_REG(data->temp_hyst[nr]); ++ results[2] = TEMP_FROM_REG10(data->temp[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_over[nr] = TEMP_TO_REG(results[0]); ++ via686a_write_value(client, ++ VIA686A_REG_TEMP_OVER(nr + 1), ++ data->temp_over[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst[nr] = TEMP_TO_REG(results[1]); ++ via686a_write_value(client, ++ VIA686A_REG_TEMP_HYST(nr + 1), ++ data->temp_hyst[nr]); ++ } ++ } ++} ++ ++void via686a_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct via686a_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ via686a_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++void via686a_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct via686a_data *data = client->data; ++ int old; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ via686a_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = via686a_read_value(client, VIA686A_REG_FANDIV); ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ old = (old & 0x3f) | (data->fan_div[1] << 6); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ old = (old & 0xcf) | (data->fan_div[0] << 4); ++ via686a_write_value(client, VIA686A_REG_FANDIV, ++ old); ++ } ++ } ++} ++ ++ ++static struct pci_device_id via686a_pci_ids[] __devinitdata = { ++ {PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, ++ { 0, } ++}; ++ ++static int __devinit via686a_pci_probe(struct pci_dev *dev, ++ const struct pci_device_id *id) ++{ ++ u16 val; ++ int addr = 0; ++ ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_word(dev, VIA686A_BASE_REG, &val)) ++ return -ENODEV; ++ ++ addr = val & ~(VIA686A_EXTENT - 1); ++ if (addr == 0 && force_addr == 0) { ++ printk("via686a.o: base address not set - upgrade BIOS or use force_addr=0xaddr\n"); ++ return -ENODEV; ++ } ++ if (force_addr) ++ addr = force_addr; /* so detect will get called */ ++ ++ if (!addr) { ++ printk("via686a.o: No Via 686A sensors found.\n"); ++ return -ENODEV; ++ } ++ normal_isa[0] = addr; ++ s_bridge = dev; ++ return i2c_add_driver(&via686a_driver); ++} ++ ++static void __devexit via686a_pci_remove(struct pci_dev *dev) ++{ ++ i2c_del_driver(&via686a_driver); ++} ++ ++static struct pci_driver via686a_pci_driver = { ++ .name = "via686a", ++ .id_table = via686a_pci_ids, ++ .probe = via686a_pci_probe, ++ .remove = __devexit_p(via686a_pci_remove), ++}; ++ ++static int __init sm_via686a_init(void) ++{ ++ printk("via686a.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return pci_module_init(&via686a_pci_driver); ++} ++ ++static void __exit sm_via686a_exit(void) ++{ ++ pci_unregister_driver(&via686a_pci_driver); ++} ++ ++MODULE_AUTHOR("Kyösti Mälkki , " ++ "Mark Studebaker " ++ "and Bob Dougherty "); ++MODULE_DESCRIPTION("VIA 686A Sensor device"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_via686a_init); ++module_exit(sm_via686a_exit); +--- linux-old/drivers/sensors/vt1211.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/vt1211.c Mon Dec 13 20:18:53 2004 +@@ -0,0 +1,823 @@ ++/* ++ vt1211.c - Part of lm_sensors, Linux kernel modules ++ for hardware monitoring ++ ++ Copyright (c) 2002 Mark D. Studebaker ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* Supports VIA VT1211 Super I/O sensors via ISA (LPC) accesses only. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++ ++static int force_addr = 0; ++MODULE_PARM(force_addr, "i"); ++MODULE_PARM_DESC(force_addr, ++ "Initialize the base address of the sensors"); ++ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { 0x0000, SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++SENSORS_INSMOD_1(vt1211); ++ ++/* modified from kernel/include/traps.c */ ++#define REG 0x2e /* The register to read/write */ ++#define DEV 0x07 /* Register: Logical device select */ ++#define VAL 0x2f /* The value to read/write */ ++#define PME 0x0b /* The device with the hardware monitor */ ++#define DEVID 0x20 /* Register: Device ID */ ++ ++static inline void ++superio_outb(int reg, int val) ++{ ++ outb(reg, REG); ++ outb(val, VAL); ++} ++ ++static inline int ++superio_inb(int reg) ++{ ++ outb(reg, REG); ++ return inb(VAL); ++} ++ ++static inline void ++superio_select(void) ++{ ++ outb(DEV, REG); ++ outb(PME, VAL); ++} ++ ++static inline void ++superio_enter(void) ++{ ++ outb(0x87, REG); ++ outb(0x87, REG); ++} ++ ++static inline void ++superio_exit(void) ++{ ++ outb(0xAA, REG); ++} ++ ++#define VT1211_DEVID 0x3c ++#define VT1211_ACT_REG 0x30 ++#define VT1211_BASE_REG 0x60 ++ ++#define VT1211_EXTENT 0x80 ++ ++/* pwm numbered 1-2 */ ++#define VT1211_REG_PWM(nr) (0x5f + (nr)) ++#define VT1211_REG_PWM_CTL 0x51 ++ ++/* The VT1211 registers */ ++/* We define the sensors as follows. Somewhat convoluted to minimize ++ changes from via686a. ++ Sensor Voltage Mode Temp Mode ++ -------- ------------ --------- ++ Reading 1 temp3 ++ Reading 3 temp1 not in vt1211 ++ UCH1/Reading2 in0 temp2 ++ UCH2 in1 temp4 ++ UCH3 in2 temp5 ++ UCH4 in3 temp6 ++ UCH5 in4 temp7 ++ 3.3V in5 ++ -12V in6 not in vt1211 ++*/ ++ ++/* ins numbered 0-6 */ ++#define VT1211_REG_IN_MAX(nr) ((nr)==0 ? 0x3d : 0x29 + ((nr) * 2)) ++#define VT1211_REG_IN_MIN(nr) ((nr)==0 ? 0x3e : 0x2a + ((nr) * 2)) ++#define VT1211_REG_IN(nr) (0x21 + (nr)) ++ ++/* fans numbered 1-2 */ ++#define VT1211_REG_FAN_MIN(nr) (0x3a + (nr)) ++#define VT1211_REG_FAN(nr) (0x28 + (nr)) ++ ++static const u8 regtemp[] = { 0x20, 0x21, 0x1f, 0x22, 0x23, 0x24, 0x25 }; ++static const u8 regover[] = { 0x39, 0x3d, 0x1d, 0x2b, 0x2d, 0x2f, 0x31 }; ++static const u8 reghyst[] = { 0x3a, 0x3e, 0x1e, 0x2c, 0x2e, 0x30, 0x32 }; ++ ++/* temps numbered 1-7 */ ++#define VT1211_REG_TEMP(nr) (regtemp[(nr) - 1]) ++#define VT1211_REG_TEMP_OVER(nr) (regover[(nr) - 1]) ++#define VT1211_REG_TEMP_HYST(nr) (reghyst[(nr) - 1]) ++#define VT1211_REG_TEMP_LOW3 0x4b /* bits 7-6 */ ++#define VT1211_REG_TEMP_LOW2 0x49 /* bits 5-4 */ ++#define VT1211_REG_TEMP_LOW47 0x4d ++ ++#define VT1211_REG_CONFIG 0x40 ++#define VT1211_REG_ALARM1 0x41 ++#define VT1211_REG_ALARM2 0x42 ++#define VT1211_REG_VID 0x45 ++#define VT1211_REG_FANDIV 0x47 ++#define VT1211_REG_UCH_CONFIG 0x4a ++#define VT1211_REG_TEMP1_CONFIG 0x4b ++#define VT1211_REG_TEMP2_CONFIG 0x4c ++ ++/* temps 1-7; voltages 0-6 */ ++#define ISTEMP(i, ch_config) ((i) == 1 ? 1 : \ ++ (i) == 3 ? 1 : \ ++ (i) == 2 ? ((ch_config) >> 1) & 0x01 : \ ++ ((ch_config) >> ((i)-1)) & 0x01) ++#define ISVOLT(i, ch_config) ((i) > 4 ? 1 : !(((ch_config) >> ((i)+2)) & 0x01)) ++ ++#define DIV_FROM_REG(val) (1 << (val)) ++#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) ++#define PWM_FROM_REG(val) (val) ++#define PWM_TO_REG(val) SENSORS_LIMIT((val), 0, 255) ++ ++#define TEMP_FROM_REG(val) ((val)*10) ++#define TEMP_FROM_REG10(val) (((val)*10)/4) ++#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-5)/10):\ ++ ((val)+5)/10),0,255)) ++#define IN_FROM_REG(val) /*(((val)*10+5)/10)*/ (val) ++#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 5)/10),0,255)) ++ ++ ++/********* FAN RPM CONVERSIONS ********/ ++/* But this chip saturates back at 0, not at 255 like all the other chips. ++ So, 0 means 0 RPM */ ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 0; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1310720 + rpm * div / 2) / (rpm * div), 1, 255); ++} ++ ++#define MIN_TO_REG(a,b) FAN_TO_REG(a,b) ++#define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:1310720/((val)*(div))) ++ ++struct vt1211_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 in[7]; /* Register value */ ++ u8 in_max[7]; /* Register value */ ++ u8 in_min[7]; /* Register value */ ++ u16 temp[7]; /* Register value 10 bit */ ++ u8 temp_over[7]; /* Register value */ ++ u8 temp_hyst[7]; /* Register value */ ++ u8 fan[2]; /* Register value */ ++ u8 fan_min[2]; /* Register value */ ++ u8 fan_div[2]; /* Register encoding, shifted right */ ++ u16 alarms; /* Register encoding */ ++ u8 pwm[2]; /* Register value */ ++ u8 pwm_ctl; /* Register value */ ++ u8 vid; /* Register encoding */ ++ u8 vrm; ++ u8 uch_config; ++}; ++ ++static int vt1211_attach_adapter(struct i2c_adapter *adapter); ++static int vt1211_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int vt1211_detach_client(struct i2c_client *client); ++ ++static inline int vt_rdval(struct i2c_client *client, u8 register); ++static inline void vt1211_write_value(struct i2c_client *client, u8 register, ++ u8 value); ++static void vt1211_update_client(struct i2c_client *client); ++static void vt1211_init_client(struct i2c_client *client); ++static int vt1211_find(int *address); ++ ++ ++static void vt1211_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt1211_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt1211_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt1211_in(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt1211_pwm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt1211_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt1211_vrm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt1211_uch(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt1211_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static int vt1211_id = 0; ++ ++static struct i2c_driver vt1211_driver = { ++ .owner = THIS_MODULE, ++ .name = "VT1211 sensors driver", ++ .id = I2C_DRIVERID_VT1211, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = vt1211_attach_adapter, ++ .detach_client = vt1211_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++#define VT1211_SYSCTL_IN0 1000 ++#define VT1211_SYSCTL_IN1 1001 ++#define VT1211_SYSCTL_IN2 1002 ++#define VT1211_SYSCTL_IN3 1003 ++#define VT1211_SYSCTL_IN4 1004 ++#define VT1211_SYSCTL_IN5 1005 ++#define VT1211_SYSCTL_IN6 1006 ++#define VT1211_SYSCTL_FAN1 1101 ++#define VT1211_SYSCTL_FAN2 1102 ++#define VT1211_SYSCTL_TEMP 1200 ++#define VT1211_SYSCTL_TEMP2 1201 ++#define VT1211_SYSCTL_TEMP3 1202 ++#define VT1211_SYSCTL_TEMP4 1203 ++#define VT1211_SYSCTL_TEMP5 1204 ++#define VT1211_SYSCTL_TEMP6 1205 ++#define VT1211_SYSCTL_TEMP7 1206 ++#define VT1211_SYSCTL_VID 1300 ++#define VT1211_SYSCTL_PWM1 1401 ++#define VT1211_SYSCTL_PWM2 1402 ++#define VT1211_SYSCTL_VRM 1600 ++#define VT1211_SYSCTL_UCH 1700 ++#define VT1211_SYSCTL_FAN_DIV 2000 ++#define VT1211_SYSCTL_ALARMS 2001 ++ ++#define VT1211_ALARM_IN1 0x01 ++#define VT1211_ALARM_IN2 0x02 ++#define VT1211_ALARM_IN5 0x04 ++#define VT1211_ALARM_IN3 0x08 ++#define VT1211_ALARM_TEMP 0x10 ++#define VT1211_ALARM_FAN1 0x40 ++#define VT1211_ALARM_FAN2 0x80 ++#define VT1211_ALARM_IN4 0x100 ++#define VT1211_ALARM_IN6 0x200 ++#define VT1211_ALARM_TEMP2 0x800 ++#define VT1211_ALARM_CHAS 0x1000 ++#define VT1211_ALARM_TEMP3 0x8000 ++/* duplicates */ ++#define VT1211_ALARM_IN0 VT1211_ALARM_TEMP ++#define VT1211_ALARM_TEMP4 VT1211_ALARM_IN1 ++#define VT1211_ALARM_TEMP5 VT1211_ALARM_IN2 ++#define VT1211_ALARM_TEMP6 VT1211_ALARM_IN3 ++#define VT1211_ALARM_TEMP7 VT1211_ALARM_IN4 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++static ctl_table vt1211_dir_table_template[] = { ++ {VT1211_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_in}, ++ {VT1211_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_in}, ++ {VT1211_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_in}, ++ {VT1211_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_in}, ++ {VT1211_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_in}, ++ {VT1211_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_in}, ++/* ++ datasheet says these are reserved ++ {VT1211_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_in}, ++ {VT1211_SYSCTL_TEMP, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_temp}, ++*/ ++ {VT1211_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &vt1211_temp}, ++ {VT1211_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &vt1211_temp}, ++ {VT1211_SYSCTL_TEMP4, "temp4", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &vt1211_temp}, ++ {VT1211_SYSCTL_TEMP5, "temp5", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &vt1211_temp}, ++ {VT1211_SYSCTL_TEMP6, "temp6", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &vt1211_temp}, ++ {VT1211_SYSCTL_TEMP7, "temp7", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &vt1211_temp}, ++ {VT1211_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_fan}, ++ {VT1211_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_fan}, ++ {VT1211_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_fan_div}, ++ {VT1211_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_alarms}, ++ {VT1211_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_pwm}, ++ {VT1211_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_pwm}, ++ {VT1211_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_vid}, ++ {VT1211_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_vrm}, ++ {VT1211_SYSCTL_UCH, "uch_config", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt1211_uch}, ++ {0} ++}; ++ ++static int vt1211_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, vt1211_detect); ++} ++ ++static int vt1211_find(int *address) ++{ ++ u16 val; ++ ++ superio_enter(); ++ val= superio_inb(DEVID); ++ if(VT1211_DEVID != val) { ++ superio_exit(); ++ return -ENODEV; ++ } ++ ++ superio_select(); ++ val = (superio_inb(VT1211_BASE_REG) << 8) | ++ superio_inb(VT1211_BASE_REG + 1); ++ *address = val & ~(VT1211_EXTENT - 1); ++ if (*address == 0 && force_addr == 0) { ++ printk("vt1211.o: base address not set - use force_addr=0xaddr\n"); ++ superio_exit(); ++ return -ENODEV; ++ } ++ if (force_addr) ++ *address = force_addr; /* so detect will get called */ ++ ++ superio_exit(); ++ return 0; ++} ++ ++int vt1211_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct vt1211_data *data; ++ int err = 0; ++ u8 val; ++ const char *type_name = "vt1211"; ++ const char *client_name = "VT1211 chip"; ++ ++ if (!i2c_is_isa_adapter(adapter)) { ++ return 0; ++ } ++ ++ if(force_addr) ++ address = force_addr & ~(VT1211_EXTENT - 1); ++ if (check_region(address, VT1211_EXTENT)) { ++ printk("vt1211.o: region 0x%x already in use!\n", address); ++ return -ENODEV; ++ } ++ if(force_addr) { ++ printk("vt1211.o: forcing ISA address 0x%04X\n", address); ++ superio_enter(); ++ superio_select(); ++ superio_outb(VT1211_BASE_REG, address >> 8); ++ superio_outb(VT1211_BASE_REG+1, address & 0xff); ++ superio_exit(); ++ } ++ ++ superio_enter(); ++ superio_select(); ++ if((val = 0x01 & superio_inb(VT1211_ACT_REG)) == 0) ++ superio_outb(VT1211_ACT_REG, 1); ++ superio_exit(); ++ ++ if (!(data = kmalloc(sizeof(struct vt1211_data), GFP_KERNEL))) { ++ return -ENOMEM; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ init_MUTEX(&data->lock); ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &vt1211_driver; ++ new_client->flags = 0; ++ ++ request_region(address, VT1211_EXTENT, "vt1211-sensors"); ++ strcpy(new_client->name, client_name); ++ ++ new_client->id = vt1211_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ if ((i = i2c_register_entry((struct i2c_client *) new_client, ++ type_name, ++ vt1211_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ vt1211_init_client(new_client); ++ return 0; ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ release_region(address, VT1211_EXTENT); ++ kfree(data); ++ return err; ++} ++ ++static int vt1211_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct vt1211_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("vt1211.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ release_region(client->addr, VT1211_EXTENT); ++ kfree(client->data); ++ ++ return 0; ++} ++ ++static inline int vt_rdval(struct i2c_client *client, u8 reg) ++{ ++ return (inb_p(client->addr + reg)); ++} ++ ++static inline void vt1211_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++ outb_p(value, client->addr + reg); ++} ++ ++static void vt1211_init_client(struct i2c_client *client) ++{ ++ struct vt1211_data *data = client->data; ++ ++ data->vrm = DEFAULT_VRM; ++ /* set "default" interrupt mode for alarms, which isn't the default */ ++ vt1211_write_value(client, VT1211_REG_TEMP1_CONFIG, 0); ++ vt1211_write_value(client, VT1211_REG_TEMP2_CONFIG, 0); ++} ++ ++static void vt1211_update_client(struct i2c_client *client) ++{ ++ struct vt1211_data *data = client->data; ++ int i, j; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ data->uch_config = vt_rdval(client, VT1211_REG_UCH_CONFIG); ++ for (i = 0; i <= 5; i++) { ++ if(ISVOLT(i, data->uch_config)) { ++ data->in[i] = vt_rdval(client, VT1211_REG_IN(i)); ++ data->in_min[i] = vt_rdval(client, ++ VT1211_REG_IN_MIN(i)); ++ data->in_max[i] = vt_rdval(client, ++ VT1211_REG_IN_MAX(i)); ++ } else { ++ data->in[i] = 0; ++ data->in_min[i] = 0; ++ data->in_max[i] = 0; ++ } ++ } ++ for (i = 1; i <= 2; i++) { ++ data->fan[i - 1] = vt_rdval(client, VT1211_REG_FAN(i)); ++ data->fan_min[i - 1] = vt_rdval(client, ++ VT1211_REG_FAN_MIN(i)); ++ } ++ for (i = 2; i <= 7; i++) { ++ if(ISTEMP(i, data->uch_config)) { ++ data->temp[i - 1] = vt_rdval(client, ++ VT1211_REG_TEMP(i)) << 2; ++ switch(i) { ++ case 1: ++ /* ? */ ++ j = 0; ++ break; ++ case 2: ++ j = (vt_rdval(client, ++ VT1211_REG_TEMP_LOW2) & ++ 0x30) >> 4; ++ break; ++ case 3: ++ j = (vt_rdval(client, ++ VT1211_REG_TEMP_LOW3) & ++ 0xc0) >> 6; ++ break; ++ case 4: ++ case 5: ++ case 6: ++ case 7: ++ default: ++ j = (vt_rdval(client, ++ VT1211_REG_TEMP_LOW47) >> ++ ((i-4)*2)) & 0x03; ++ break; ++ ++ } ++ data->temp[i - 1] |= j; ++ data->temp_over[i - 1] = vt_rdval(client, ++ VT1211_REG_TEMP_OVER(i)); ++ data->temp_hyst[i - 1] = vt_rdval(client, ++ VT1211_REG_TEMP_HYST(i)); ++ } else { ++ data->temp[i - 1] = 0; ++ data->temp_over[i - 1] = 0; ++ data->temp_hyst[i - 1] = 0; ++ } ++ } ++ ++ for (i = 1; i <= 2; i++) { ++ data->fan[i - 1] = vt_rdval(client, VT1211_REG_FAN(i)); ++ data->fan_min[i - 1] = vt_rdval(client, ++ VT1211_REG_FAN_MIN(i)); ++ data->pwm[i - 1] = vt_rdval(client, VT1211_REG_PWM(i)); ++ } ++ ++ data->pwm_ctl = vt_rdval(client, VT1211_REG_PWM_CTL); ++ i = vt_rdval(client, VT1211_REG_FANDIV); ++ data->fan_div[0] = (i >> 4) & 0x03; ++ data->fan_div[1] = i >> 6; ++ data->alarms = vt_rdval(client, VT1211_REG_ALARM1) | ++ (vt_rdval(client, VT1211_REG_ALARM2) << 8); ++ data->vid= vt_rdval(client, VT1211_REG_VID) & 0x1f; ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++void vt1211_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt1211_data *data = client->data; ++ int nr = ctl_name - VT1211_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt1211_update_client(client); ++ results[0] = IN_FROM_REG(data->in_min[nr]); ++ results[1] = IN_FROM_REG(data->in_max[nr]); ++ results[2] = IN_FROM_REG(data->in[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = IN_TO_REG(results[0]); ++ vt1211_write_value(client, VT1211_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = IN_TO_REG(results[1]); ++ vt1211_write_value(client, VT1211_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++} ++ ++void vt1211_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt1211_data *data = client->data; ++ int nr = ctl_name - VT1211_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt1211_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr - 1], ++ DIV_FROM_REG(data->fan_div ++ [nr - 1])); ++ results[1] = FAN_FROM_REG(data->fan[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = MIN_TO_REG(results[0], ++ DIV_FROM_REG ++ (data-> ++ fan_div[nr-1])); ++ vt1211_write_value(client, VT1211_REG_FAN_MIN(nr), ++ data->fan_min[nr - 1]); ++ } ++ } ++} ++ ++ ++void vt1211_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt1211_data *data = client->data; ++ int nr = ctl_name - VT1211_SYSCTL_TEMP; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt1211_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_over[nr]); ++ results[1] = TEMP_FROM_REG(data->temp_hyst[nr]); ++ results[2] = TEMP_FROM_REG10(data->temp[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_over[nr] = TEMP_TO_REG(results[0]); ++ vt1211_write_value(client, ++ VT1211_REG_TEMP_OVER(nr + 1), ++ data->temp_over[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst[nr] = TEMP_TO_REG(results[1]); ++ vt1211_write_value(client, ++ VT1211_REG_TEMP_HYST(nr + 1), ++ data->temp_hyst[nr]); ++ } ++ } ++} ++ ++void vt1211_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt1211_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt1211_update_client(client); ++ results[0] = data->alarms; ++ *nrels_mag = 1; ++ } ++} ++ ++void vt1211_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct vt1211_data *data = client->data; ++ int old; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt1211_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = vt_rdval(client, VT1211_REG_FANDIV); ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ old = (old & 0x3f) | (data->fan_div[1] << 6); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ old = (old & 0xcf) | (data->fan_div[0] << 4); ++ vt1211_write_value(client, VT1211_REG_FANDIV, old); ++ } ++ } ++} ++ ++void vt1211_pwm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt1211_data *data = client->data; ++ int nr = 1 + ctl_name - VT1211_SYSCTL_PWM1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt1211_update_client(client); ++ results[0] = PWM_FROM_REG(data->pwm[nr - 1]); ++ results[1] = (data->pwm_ctl >> (3 + (4 * (nr - 1)))) & 1; ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->pwm[nr - 1] = PWM_TO_REG(results[0]); ++ if (*nrels_mag >= 2) { ++ if(results[1]) { ++ data->pwm_ctl |= ++ (0x08 << (4 * (nr - 1))); ++ vt1211_write_value(client, ++ VT1211_REG_PWM_CTL, ++ data->pwm_ctl); ++ } else { ++ data->pwm_ctl &= ++ ~ (0x08 << (4 * (nr - 1))); ++ vt1211_write_value(client, ++ VT1211_REG_PWM_CTL, ++ data->pwm_ctl); ++ } ++ } ++ vt1211_write_value(client, VT1211_REG_PWM(nr), ++ data->pwm[nr - 1]); ++ } ++ } ++} ++ ++void vt1211_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt1211_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt1211_update_client(client); ++ results[0] = vid_from_reg(data->vid, data->vrm); ++ *nrels_mag = 1; ++ } ++} ++ ++void vt1211_vrm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt1211_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->vrm; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) ++ data->vrm = results[0]; ++ } ++} ++ ++void vt1211_uch(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt1211_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->uch_config & 0x7c; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->uch_config = (data->uch_config & 0x83)|(results[0] & 0x7c); ++ vt1211_write_value(client, VT1211_REG_UCH_CONFIG, ++ data->uch_config); ++ } ++ } ++} ++ ++static int __init sm_vt1211_init(void) ++{ ++ int addr; ++ ++ printk("vt1211.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ ++ if (vt1211_find(&addr)) { ++ printk("vt1211.o: VT1211 not detected, module not inserted.\n"); ++ return -ENODEV; ++ } ++ normal_isa[0] = addr; ++ ++ return i2c_add_driver(&vt1211_driver); ++} ++ ++static void __exit sm_vt1211_exit(void) ++{ ++ i2c_del_driver(&vt1211_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Mark D. Studebaker "); ++MODULE_DESCRIPTION("VT1211 sensors"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_vt1211_init); ++module_exit(sm_vt1211_exit); +--- linux-old/drivers/sensors/vt8231.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/vt8231.c Mon Dec 13 20:18:53 2004 +@@ -0,0 +1,794 @@ ++/* ++ vt8231.c - Part of lm_sensors, Linux kernel modules ++ for hardware monitoring ++ ++ Copyright (c) 2002 Mark D. Studebaker ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* Supports VIA VT8231 South Bridge embedded sensors */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++ ++ ++static int force_addr = 0; ++MODULE_PARM(force_addr, "i"); ++MODULE_PARM_DESC(force_addr, ++ "Initialize the base address of the sensors"); ++ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { 0x0000, SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++SENSORS_INSMOD_1(vt8231); ++ ++#define VIA686A_EXTENT 0x80 ++#define VIA686A_BASE_REG 0x70 ++#define VIA686A_ENABLE_REG 0x74 ++ ++/* pwm numbered 1-2 */ ++#define VT8231_REG_PWM(nr) (0x5f + (nr)) ++#define VT8231_REG_PWM_CTL 0x51 ++ ++/* The VT8231 registers */ ++/* We define the sensors as follows. Somewhat convoluted to minimize ++ changes from via686a. ++ Sensor Voltage Mode Temp Mode ++ -------- ------------ --------- ++ Reading 1 temp3 ++ Reading 3 temp1 not in vt8231 ++ UCH1/Reading2 in0 temp2 ++ UCH2 in1 temp4 ++ UCH3 in2 temp5 ++ UCH4 in3 temp6 ++ UCH5 in4 temp7 ++ 3.3V in5 ++ -12V in6 not in vt8231 ++*/ ++ ++/* ins numbered 0-6 */ ++#define VT8231_REG_IN_MAX(nr) ((nr)==0 ? 0x3d : 0x29 + ((nr) * 2)) ++#define VT8231_REG_IN_MIN(nr) ((nr)==0 ? 0x3e : 0x2a + ((nr) * 2)) ++#define VT8231_REG_IN(nr) (0x21 + (nr)) ++ ++/* fans numbered 1-2 */ ++#define VT8231_REG_FAN_MIN(nr) (0x3a + (nr)) ++#define VT8231_REG_FAN(nr) (0x28 + (nr)) ++ ++static const u8 regtemp[] = { 0x20, 0x21, 0x1f, 0x22, 0x23, 0x24, 0x25 }; ++static const u8 regover[] = { 0x39, 0x3d, 0x1d, 0x2b, 0x2d, 0x2f, 0x31 }; ++static const u8 reghyst[] = { 0x3a, 0x3e, 0x1e, 0x2c, 0x2e, 0x30, 0x32 }; ++ ++/* temps numbered 1-7 */ ++#define VT8231_REG_TEMP(nr) (regtemp[(nr) - 1]) ++#define VT8231_REG_TEMP_OVER(nr) (regover[(nr) - 1]) ++#define VT8231_REG_TEMP_HYST(nr) (reghyst[(nr) - 1]) ++#define VT8231_REG_TEMP_LOW3 0x4b /* bits 7-6 */ ++#define VT8231_REG_TEMP_LOW2 0x49 /* bits 5-4 */ ++#define VT8231_REG_TEMP_LOW47 0x4d ++ ++#define VT8231_REG_CONFIG 0x40 ++#define VT8231_REG_ALARM1 0x41 ++#define VT8231_REG_ALARM2 0x42 ++#define VT8231_REG_VID 0x45 ++#define VT8231_REG_FANDIV 0x47 ++#define VT8231_REG_UCH_CONFIG 0x4a ++#define VT8231_REG_TEMP1_CONFIG 0x4b ++#define VT8231_REG_TEMP2_CONFIG 0x4c ++ ++/* temps 1-7; voltages 0-6 */ ++#define ISTEMP(i, ch_config) ((i) == 1 ? 1 : \ ++ (i) == 3 ? 1 : \ ++ (i) == 2 ? ((ch_config) >> 1) & 0x01 : \ ++ ((ch_config) >> ((i)-1)) & 0x01) ++#define ISVOLT(i, ch_config) ((i) > 4 ? 1 : !(((ch_config) >> ((i)+2)) & 0x01)) ++ ++#define DIV_FROM_REG(val) (1 << (val)) ++#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) ++#define PWM_FROM_REG(val) (val) ++#define PWM_TO_REG(val) SENSORS_LIMIT((val), 0, 255) ++ ++#define TEMP_FROM_REG(val) ((val)*10) ++#define TEMP_FROM_REG10(val) (((val)*10)/4) ++#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-5)/10):\ ++ ((val)+5)/10),0,255)) ++#define IN_FROM_REG(val) /*(((val)*10+5)/10)*/ (val) ++#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 5)/10),0,255)) ++ ++ ++/********* FAN RPM CONVERSIONS ********/ ++/* But this chip saturates back at 0, not at 255 like all the other chips. ++ So, 0 means 0 RPM */ ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 0; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1310720 + rpm * div / 2) / (rpm * div), 1, 255); ++} ++ ++#define MIN_TO_REG(a,b) FAN_TO_REG(a,b) ++#define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:1310720/((val)*(div))) ++ ++struct vt8231_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 in[7]; /* Register value */ ++ u8 in_max[7]; /* Register value */ ++ u8 in_min[7]; /* Register value */ ++ u16 temp[7]; /* Register value 10 bit */ ++ u8 temp_over[7]; /* Register value */ ++ u8 temp_hyst[7]; /* Register value */ ++ u8 fan[2]; /* Register value */ ++ u8 fan_min[2]; /* Register value */ ++ u8 fan_div[2]; /* Register encoding, shifted right */ ++ u16 alarms; /* Register encoding */ ++ u8 pwm[2]; /* Register value */ ++ u8 pwm_ctl; /* Register value */ ++ u8 vid; /* Register encoding */ ++ u8 vrm; ++ u8 uch_config; ++}; ++ ++static int vt8231_attach_adapter(struct i2c_adapter *adapter); ++static int vt8231_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int vt8231_detach_client(struct i2c_client *client); ++ ++static inline int vt_rdval(struct i2c_client *client, u8 register); ++static inline void vt8231_write_value(struct i2c_client *client, u8 register, ++ u8 value); ++static void vt8231_update_client(struct i2c_client *client); ++static void vt8231_init_client(struct i2c_client *client); ++static int vt8231_find(int *address); ++ ++ ++static void vt8231_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt8231_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt8231_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt8231_in(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt8231_pwm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt8231_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt8231_vrm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt8231_uch(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void vt8231_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static int vt8231_id = 0; ++ ++static struct i2c_driver vt8231_driver = { ++ .owner = THIS_MODULE, ++ .name = "VT8231 sensors driver", ++ .id = I2C_DRIVERID_VT8231, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = vt8231_attach_adapter, ++ .detach_client = vt8231_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++#define VT8231_SYSCTL_IN0 1000 ++#define VT8231_SYSCTL_IN1 1001 ++#define VT8231_SYSCTL_IN2 1002 ++#define VT8231_SYSCTL_IN3 1003 ++#define VT8231_SYSCTL_IN4 1004 ++#define VT8231_SYSCTL_IN5 1005 ++#define VT8231_SYSCTL_IN6 1006 ++#define VT8231_SYSCTL_FAN1 1101 ++#define VT8231_SYSCTL_FAN2 1102 ++#define VT8231_SYSCTL_TEMP 1200 ++#define VT8231_SYSCTL_TEMP2 1201 ++#define VT8231_SYSCTL_TEMP3 1202 ++#define VT8231_SYSCTL_TEMP4 1203 ++#define VT8231_SYSCTL_TEMP5 1204 ++#define VT8231_SYSCTL_TEMP6 1205 ++#define VT8231_SYSCTL_TEMP7 1206 ++#define VT8231_SYSCTL_VID 1300 ++#define VT8231_SYSCTL_PWM1 1401 ++#define VT8231_SYSCTL_PWM2 1402 ++#define VT8231_SYSCTL_VRM 1600 ++#define VT8231_SYSCTL_UCH 1700 ++#define VT8231_SYSCTL_FAN_DIV 2000 ++#define VT8231_SYSCTL_ALARMS 2001 ++ ++#define VT8231_ALARM_IN1 0x01 ++#define VT8231_ALARM_IN2 0x02 ++#define VT8231_ALARM_IN5 0x04 ++#define VT8231_ALARM_IN3 0x08 ++#define VT8231_ALARM_TEMP 0x10 ++#define VT8231_ALARM_FAN1 0x40 ++#define VT8231_ALARM_FAN2 0x80 ++#define VT8231_ALARM_IN4 0x100 ++#define VT8231_ALARM_IN6 0x200 ++#define VT8231_ALARM_TEMP2 0x800 ++#define VT8231_ALARM_CHAS 0x1000 ++#define VT8231_ALARM_TEMP3 0x8000 ++/* duplicates */ ++#define VT8231_ALARM_IN0 VT8231_ALARM_TEMP ++#define VT8231_ALARM_TEMP4 VT8231_ALARM_IN1 ++#define VT8231_ALARM_TEMP5 VT8231_ALARM_IN2 ++#define VT8231_ALARM_TEMP6 VT8231_ALARM_IN3 ++#define VT8231_ALARM_TEMP7 VT8231_ALARM_IN4 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++static ctl_table vt8231_dir_table_template[] = { ++ {VT8231_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_in}, ++ {VT8231_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_in}, ++ {VT8231_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_in}, ++ {VT8231_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_in}, ++ {VT8231_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_in}, ++ {VT8231_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_in}, ++/* ++ not in 8231 ++ {VT8231_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_in}, ++ {VT8231_SYSCTL_TEMP, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_temp}, ++*/ ++ {VT8231_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &vt8231_temp}, ++ {VT8231_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &vt8231_temp}, ++ {VT8231_SYSCTL_TEMP4, "temp4", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &vt8231_temp}, ++ {VT8231_SYSCTL_TEMP5, "temp5", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &vt8231_temp}, ++ {VT8231_SYSCTL_TEMP6, "temp6", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &vt8231_temp}, ++ {VT8231_SYSCTL_TEMP7, "temp7", NULL, 0, 0644, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &vt8231_temp}, ++ {VT8231_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_fan}, ++ {VT8231_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_fan}, ++ {VT8231_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_fan_div}, ++ {VT8231_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_alarms}, ++ {VT8231_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_pwm}, ++ {VT8231_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_pwm}, ++ {VT8231_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_vid}, ++ {VT8231_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_vrm}, ++ {VT8231_SYSCTL_UCH, "uch_config", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &vt8231_uch}, ++ {0} ++}; ++ ++static struct pci_dev *s_bridge; ++ ++static int vt8231_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, vt8231_detect); ++} ++ ++/* Locate chip and get correct base address */ ++static int vt8231_find(int *address) ++{ ++ u16 val; ++ ++ if (!pci_present()) ++ return -ENODEV; ++ ++ if (!(s_bridge = pci_find_device(PCI_VENDOR_ID_VIA, ++ 0x8235, NULL))) ++ return -ENODEV; ++ ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_word(s_bridge, VIA686A_BASE_REG, &val)) ++ return -ENODEV; ++ *address = val & ~(VIA686A_EXTENT - 1); ++ if (*address == 0 && force_addr == 0) { ++ printk("vt8231.o: base address not set - upgrade BIOS or use force_addr=0xaddr\n"); ++ return -ENODEV; ++ } ++ if (force_addr) ++ *address = force_addr; /* so detect will get called */ ++ ++ return 0; ++} ++ ++int vt8231_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct vt8231_data *data; ++ int err = 0; ++ const char *type_name = "vt8231"; ++ u16 val; ++ ++ if (!i2c_is_isa_adapter(adapter)) { ++ return 0; ++ } ++ ++ /* 8231 requires multiple of 256 */ ++ if(force_addr) ++ address = force_addr & 0xFF00; ++ if (check_region(address, VIA686A_EXTENT)) { ++ printk("vt8231.o: region 0x%x already in use!\n", ++ address); ++ return -ENODEV; ++ } ++ ++ if(force_addr) { ++ printk("vt8231.o: forcing ISA address 0x%04X\n", address); ++ if (PCIBIOS_SUCCESSFUL != ++ pci_write_config_word(s_bridge, VIA686A_BASE_REG, address)) ++ return -ENODEV; ++ } ++ if (PCIBIOS_SUCCESSFUL != ++ pci_read_config_word(s_bridge, VIA686A_ENABLE_REG, &val)) ++ return -ENODEV; ++ if (!(val & 0x0001)) { ++ printk("vt8231.o: enabling sensors\n"); ++ if (PCIBIOS_SUCCESSFUL != ++ pci_write_config_word(s_bridge, VIA686A_ENABLE_REG, ++ val | 0x0001)) ++ return -ENODEV; ++ } ++ ++ if (!(data = kmalloc(sizeof(struct vt8231_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ init_MUTEX(&data->lock); ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &vt8231_driver; ++ new_client->flags = 0; ++ ++ /* Reserve the ISA region */ ++ request_region(address, VIA686A_EXTENT, "vt8231-sensors"); ++ ++ /* Fill in the remaining client fields and put into the global list */ ++ strcpy(new_client->name, "Via 8231 Integrated Sensors"); ++ ++ new_client->id = vt8231_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry((struct i2c_client *) new_client, ++ type_name, ++ vt8231_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR4; ++ } ++ data->sysctl_id = i; ++ ++ vt8231_init_client(new_client); ++ return 0; ++ ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ release_region(address, VIA686A_EXTENT); ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int vt8231_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct vt8231_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("vt8231.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ release_region(client->addr, VIA686A_EXTENT); ++ kfree(client->data); ++ ++ return 0; ++} ++ ++ ++static inline int vt_rdval(struct i2c_client *client, u8 reg) ++{ ++ return (inb_p(client->addr + reg)); ++} ++ ++static inline void vt8231_write_value(struct i2c_client *client, u8 reg, u8 value) ++{ ++ outb_p(value, client->addr + reg); ++} ++ ++static void vt8231_init_client(struct i2c_client *client) ++{ ++ struct vt8231_data *data = client->data; ++ ++ data->vrm = DEFAULT_VRM; ++ /* set "default" interrupt mode for alarms, which isn't the default */ ++ vt8231_write_value(client, VT8231_REG_TEMP1_CONFIG, 0); ++ vt8231_write_value(client, VT8231_REG_TEMP2_CONFIG, 0); ++} ++ ++static void vt8231_update_client(struct i2c_client *client) ++{ ++ struct vt8231_data *data = client->data; ++ int i, j; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ data->uch_config = vt_rdval(client, VT8231_REG_UCH_CONFIG); ++ for (i = 0; i <= 5; i++) { ++ if(ISVOLT(i, data->uch_config)) { ++ data->in[i] = vt_rdval(client, VT8231_REG_IN(i)); ++ data->in_min[i] = vt_rdval(client, ++ VT8231_REG_IN_MIN(i)); ++ data->in_max[i] = vt_rdval(client, ++ VT8231_REG_IN_MAX(i)); ++ } else { ++ data->in[i] = 0; ++ data->in_min[i] = 0; ++ data->in_max[i] = 0; ++ } ++ } ++ for (i = 1; i <= 2; i++) { ++ data->fan[i - 1] = vt_rdval(client, VT8231_REG_FAN(i)); ++ data->fan_min[i - 1] = vt_rdval(client, ++ VT8231_REG_FAN_MIN(i)); ++ } ++ for (i = 2; i <= 7; i++) { ++ if(ISTEMP(i, data->uch_config)) { ++ data->temp[i - 1] = vt_rdval(client, ++ VT8231_REG_TEMP(i)) << 2; ++ switch(i) { ++ case 1: ++ /* ? */ ++ j = 0; ++ break; ++ case 2: ++ j = (vt_rdval(client, ++ VT8231_REG_TEMP_LOW2) & ++ 0x30) >> 4; ++ break; ++ case 3: ++ j = (vt_rdval(client, ++ VT8231_REG_TEMP_LOW3) & ++ 0xc0) >> 6; ++ break; ++ case 4: ++ case 5: ++ case 6: ++ case 7: ++ default: ++ j = (vt_rdval(client, ++ VT8231_REG_TEMP_LOW47) >> ++ ((i-4)*2)) & 0x03; ++ break; ++ ++ } ++ data->temp[i - 1] |= j; ++ data->temp_over[i - 1] = vt_rdval(client, ++ VT8231_REG_TEMP_OVER(i)); ++ data->temp_hyst[i - 1] = vt_rdval(client, ++ VT8231_REG_TEMP_HYST(i)); ++ } else { ++ data->temp[i - 1] = 0; ++ data->temp_over[i - 1] = 0; ++ data->temp_hyst[i - 1] = 0; ++ } ++ } ++ ++ for (i = 1; i <= 2; i++) { ++ data->fan[i - 1] = vt_rdval(client, VT8231_REG_FAN(i)); ++ data->fan_min[i - 1] = vt_rdval(client, ++ VT8231_REG_FAN_MIN(i)); ++ data->pwm[i - 1] = vt_rdval(client, VT8231_REG_PWM(i)); ++ } ++ ++ data->pwm_ctl = vt_rdval(client, VT8231_REG_PWM_CTL); ++ i = vt_rdval(client, VT8231_REG_FANDIV); ++ data->fan_div[0] = (i >> 4) & 0x03; ++ data->fan_div[1] = i >> 6; ++ data->alarms = vt_rdval(client, VT8231_REG_ALARM1) | ++ (vt_rdval(client, VT8231_REG_ALARM2) << 8); ++ data->vid= vt_rdval(client, VT8231_REG_VID) & 0x1f; ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++void vt8231_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt8231_data *data = client->data; ++ int nr = ctl_name - VT8231_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt8231_update_client(client); ++ results[0] = IN_FROM_REG(data->in_min[nr]); ++ results[1] = IN_FROM_REG(data->in_max[nr]); ++ results[2] = IN_FROM_REG(data->in[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = IN_TO_REG(results[0]); ++ vt8231_write_value(client, VT8231_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = IN_TO_REG(results[1]); ++ vt8231_write_value(client, VT8231_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++} ++ ++void vt8231_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt8231_data *data = client->data; ++ int nr = ctl_name - VT8231_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt8231_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr - 1], ++ DIV_FROM_REG(data->fan_div ++ [nr - 1])); ++ results[1] = FAN_FROM_REG(data->fan[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = MIN_TO_REG(results[0], ++ DIV_FROM_REG ++ (data-> ++ fan_div[nr-1])); ++ vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), ++ data->fan_min[nr - 1]); ++ } ++ } ++} ++ ++ ++void vt8231_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt8231_data *data = client->data; ++ int nr = ctl_name - VT8231_SYSCTL_TEMP; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt8231_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_over[nr]); ++ results[1] = TEMP_FROM_REG(data->temp_hyst[nr]); ++ results[2] = TEMP_FROM_REG10(data->temp[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_over[nr] = TEMP_TO_REG(results[0]); ++ vt8231_write_value(client, ++ VT8231_REG_TEMP_OVER(nr + 1), ++ data->temp_over[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst[nr] = TEMP_TO_REG(results[1]); ++ vt8231_write_value(client, ++ VT8231_REG_TEMP_HYST(nr + 1), ++ data->temp_hyst[nr]); ++ } ++ } ++} ++ ++void vt8231_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt8231_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt8231_update_client(client); ++ results[0] = data->alarms; ++ *nrels_mag = 1; ++ } ++} ++ ++void vt8231_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct vt8231_data *data = client->data; ++ int old; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt8231_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = vt_rdval(client, VT8231_REG_FANDIV); ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = DIV_TO_REG(results[1]); ++ old = (old & 0x3f) | (data->fan_div[1] << 6); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = DIV_TO_REG(results[0]); ++ old = (old & 0xcf) | (data->fan_div[0] << 4); ++ vt8231_write_value(client, VT8231_REG_FANDIV, old); ++ } ++ } ++} ++ ++void vt8231_pwm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt8231_data *data = client->data; ++ int nr = 1 + ctl_name - VT8231_SYSCTL_PWM1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt8231_update_client(client); ++ results[0] = PWM_FROM_REG(data->pwm[nr - 1]); ++ results[1] = (data->pwm_ctl >> (3 + (4 * (nr - 1)))) & 1; ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->pwm[nr - 1] = PWM_TO_REG(results[0]); ++ if (*nrels_mag >= 2) { ++ if(results[1]) { ++ data->pwm_ctl |= ++ (0x08 << (4 * (nr - 1))); ++ vt8231_write_value(client, ++ VT8231_REG_PWM_CTL, ++ data->pwm_ctl); ++ } else { ++ data->pwm_ctl &= ++ ~ (0x08 << (4 * (nr - 1))); ++ vt8231_write_value(client, ++ VT8231_REG_PWM_CTL, ++ data->pwm_ctl); ++ } ++ } ++ vt8231_write_value(client, VT8231_REG_PWM(nr), ++ data->pwm[nr - 1]); ++ } ++ } ++} ++ ++void vt8231_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt8231_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ vt8231_update_client(client); ++ results[0] = vid_from_reg(data->vid, data->vrm); ++ *nrels_mag = 1; ++ } ++} ++ ++void vt8231_vrm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt8231_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->vrm; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) ++ data->vrm = results[0]; ++ } ++} ++ ++void vt8231_uch(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct vt8231_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->uch_config & 0x7c; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->uch_config = (data->uch_config & 0x83)|(results[0] & 0x7c); ++ vt8231_write_value(client, VT8231_REG_UCH_CONFIG, ++ data->uch_config); ++ } ++ } ++} ++ ++static int __init sm_vt8231_init(void) ++{ ++ int addr; ++ ++ printk("vt8231.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ ++ if (vt8231_find(&addr)) { ++ printk("vt8231.o: VT8231 not detected, module not inserted.\n"); ++ return -ENODEV; ++ } ++ normal_isa[0] = addr; ++ ++ return i2c_add_driver(&vt8231_driver);} ++ ++static void __exit sm_vt8231_exit(void) ++{ ++ i2c_del_driver(&vt8231_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Mark D. Studebaker "); ++MODULE_DESCRIPTION("VT8231 sensors"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_vt8231_init); ++module_exit(sm_vt8231_exit); +--- linux-old/drivers/sensors/w83627hf.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/w83627hf.c Mon Dec 13 20:18:53 2004 +@@ -0,0 +1,1422 @@ ++/* ++ w83627hf.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998 - 2003 Frodo Looijaard , ++ Philip Edelbrock , ++ and Mark Studebaker ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ Supports following chips: ++ ++ Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA ++ w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) ++ w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) ++ w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) ++ w83697hf 8 2 2 2 0x60 0x5ca3 no yes(LPC) ++ ++ For other winbond chips, and for i2c support in the above chips, ++ use w83781d.c. ++ ++ Note: automatic ("cruise") fan control for 697, 637 & 627thf not ++ supported yet. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++#include "lm75.h" ++ ++static int force_addr; ++MODULE_PARM(force_addr, "i"); ++MODULE_PARM_DESC(force_addr, ++ "Initialize the base address of the sensors"); ++static int force_i2c = 0x1f; ++MODULE_PARM(force_i2c, "i"); ++MODULE_PARM_DESC(force_i2c, ++ "Initialize the i2c address of the sensors"); ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { 0, SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_4(w83627hf, w83627thf, w83697hf, w83637hf); ++ ++static int init = 1; ++MODULE_PARM(init, "i"); ++MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); ++ ++/* modified from kernel/include/traps.c */ ++#define REG 0x2e /* The register to read/write */ ++#define DEV 0x07 /* Register: Logical device select */ ++#define VAL 0x2f /* The value to read/write */ ++ ++/* logical device numbers for superio_select (below) */ ++#define W83627HF_LD_FDC 0x00 ++#define W83627HF_LD_PRT 0x01 ++#define W83627HF_LD_UART1 0x02 ++#define W83627HF_LD_UART2 0x03 ++#define W83627HF_LD_KBC 0x05 ++#define W83627HF_LD_CIR 0x06 /* w83627hf only */ ++#define W83627HF_LD_GAME 0x07 ++#define W83627HF_LD_MIDI 0x07 ++#define W83627HF_LD_GPIO1 0x07 ++#define W83627HF_LD_GPIO5 0x07 /* w83627thf only */ ++#define W83627HF_LD_GPIO2 0x08 ++#define W83627HF_LD_GPIO3 0x09 ++#define W83627HF_LD_GPIO4 0x09 /* w83627thf only */ ++#define W83627HF_LD_ACPI 0x0a ++#define W83627HF_LD_HWM 0x0b ++ ++#define DEVID 0x20 /* Register: Device ID */ ++ ++#define W83627THF_GPIO5_IOSR 0xf3 /* w83627thf only */ ++#define W83627THF_GPIO5_DR 0xf4 /* w83627thf only */ ++#define W83627THF_GPIO5_INVR 0xf5 /* w83627thf only */ ++ ++static inline void ++superio_outb(int reg, int val) ++{ ++ outb(reg, REG); ++ outb(val, VAL); ++} ++ ++static inline int ++superio_inb(int reg) ++{ ++ outb(reg, REG); ++ return inb(VAL); ++} ++ ++static inline void ++superio_select(int ld) ++{ ++ outb(DEV, REG); ++ outb(ld, VAL); ++} ++ ++static inline void ++superio_enter(void) ++{ ++ outb(0x87, REG); ++ outb(0x87, REG); ++} ++ ++static inline void ++superio_exit(void) ++{ ++ outb(0xAA, REG); ++} ++ ++#define W627_DEVID 0x52 ++#define W627THF_DEVID 0x82 ++#define W697_DEVID 0x60 ++#define W637_DEVID 0x70 ++#define WINB_ACT_REG 0x30 ++#define WINB_BASE_REG 0x60 ++/* Constants specified below */ ++ ++/* Length of ISA address segment */ ++#define WINB_EXTENT 8 ++ ++/* Where are the ISA address/data registers relative to the base address */ ++#define W83781D_ADDR_REG_OFFSET 5 ++#define W83781D_DATA_REG_OFFSET 6 ++ ++/* The W83781D registers */ ++/* The W83782D registers for nr=7,8 are in bank 5 */ ++#define W83781D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \ ++ (0x554 + (((nr) - 7) * 2))) ++#define W83781D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \ ++ (0x555 + (((nr) - 7) * 2))) ++#define W83781D_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ ++ (0x550 + (nr) - 7)) ++ ++#define W83781D_REG_FAN_MIN(nr) (0x3a + (nr)) ++#define W83781D_REG_FAN(nr) (0x27 + (nr)) ++ ++#define W83781D_REG_TEMP2 0x0150 ++#define W83781D_REG_TEMP3 0x0250 ++#define W83781D_REG_TEMP2_HYST 0x153 ++#define W83781D_REG_TEMP3_HYST 0x253 ++#define W83781D_REG_TEMP2_CONFIG 0x152 ++#define W83781D_REG_TEMP3_CONFIG 0x252 ++#define W83781D_REG_TEMP2_OVER 0x155 ++#define W83781D_REG_TEMP3_OVER 0x255 ++ ++#define W83781D_REG_TEMP 0x27 ++#define W83781D_REG_TEMP_OVER 0x39 ++#define W83781D_REG_TEMP_HYST 0x3A ++#define W83781D_REG_BANK 0x4E ++ ++#define W83781D_REG_CONFIG 0x40 ++#define W83781D_REG_ALARM1 0x41 ++#define W83781D_REG_ALARM2 0x42 ++#define W83781D_REG_ALARM3 0x450 ++ ++#define W83781D_REG_IRQ 0x4C ++#define W83781D_REG_BEEP_CONFIG 0x4D ++#define W83781D_REG_BEEP_INTS1 0x56 ++#define W83781D_REG_BEEP_INTS2 0x57 ++#define W83781D_REG_BEEP_INTS3 0x453 ++ ++#define W83781D_REG_VID_FANDIV 0x47 ++ ++#define W83781D_REG_CHIPID 0x49 ++#define W83781D_REG_WCHIPID 0x58 ++#define W83781D_REG_CHIPMAN 0x4F ++#define W83781D_REG_PIN 0x4B ++ ++#define W83781D_REG_VBAT 0x5D ++ ++#define W83627HF_REG_PWM1 0x5A ++#define W83627HF_REG_PWM2 0x5B ++#define W83627HF_REG_PWMCLK12 0x5C ++ ++#define W83627THF_REG_PWM1 0x01 /* 697HF and 637HF too */ ++#define W83627THF_REG_PWM2 0x03 /* 697HF and 637HF too */ ++#define W83627THF_REG_PWM3 0x11 /* 637HF too */ ++ ++#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF too */ ++ ++static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 }; ++static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2, ++ W83627THF_REG_PWM3 }; ++#define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \ ++ regpwm_627hf[(nr) - 1] : regpwm[(nr) - 1]) ++ ++#define W83781D_REG_I2C_ADDR 0x48 ++#define W83781D_REG_I2C_SUBADDR 0x4A ++ ++/* Sensor selection */ ++#define W83781D_REG_SCFG1 0x5D ++static const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 }; ++#define W83781D_REG_SCFG2 0x59 ++static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 }; ++#define W83781D_DEFAULT_BETA 3435 ++ ++/* Conversions. Limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255)) ++#define IN_FROM_REG(val) (((val) * 16 + 5) / 10) ++ ++#define IN_TO_REG_VRM9(val) \ ++ (SENSORS_LIMIT((((val) * 1000 - 70000 + 244) / 488), 0, 255)) ++#define IN_FROM_REG_VRM9(reg) (((reg) * 488 + 70000 + 500) / 1000) ++ ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 255; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, ++ 254); ++} ++ ++#define TEMP_MIN (-1280) ++#define TEMP_MAX ( 1270) ++ ++/* TEMP: 1/10 degrees C (-128C to +127C) ++ REG: 1C/bit, two's complement */ ++static u8 TEMP_TO_REG(int temp) ++{ ++ int ntemp = SENSORS_LIMIT(temp, TEMP_MIN, TEMP_MAX); ++ ntemp += (ntemp<0 ? -5 : 5); ++ return (u8)(ntemp / 10); ++} ++ ++static int TEMP_FROM_REG(u8 reg) ++{ ++ return (s8)reg * 10; ++} ++ ++#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div))) ++ ++#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) ++#define BEEPS_TO_REG(val) ((val) & 0xffffff) ++ ++#define BEEP_ENABLE_TO_REG(val) ((val)?1:0) ++#define BEEP_ENABLE_FROM_REG(val) ((val)?1:0) ++ ++#define DIV_FROM_REG(val) (1 << (val)) ++ ++static inline u8 DIV_TO_REG(long val) ++{ ++ int i; ++ val = SENSORS_LIMIT(val, 1, 128) >> 1; ++ for (i = 0; i < 6; i++) { ++ if (val == 0) ++ break; ++ val >>= 1; ++ } ++ return ((u8) i); ++} ++ ++/* For each registered chip, we need to keep some data in memory. That ++ data is pointed to by w83627hf_list[NR]->data. The structure itself is ++ dynamically allocated, at the same time when a new client is allocated. */ ++struct w83627hf_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ struct i2c_client *lm75; /* for secondary I2C addresses */ ++ /* pointer to array of 2 subclients */ ++ ++ u8 in[9]; /* Register value */ ++ u8 in_max[9]; /* Register value */ ++ u8 in_min[9]; /* Register value */ ++ u8 fan[3]; /* Register value */ ++ u8 fan_min[3]; /* Register value */ ++ u8 temp; ++ u8 temp_over; /* Register value */ ++ u8 temp_hyst; /* Register value */ ++ u16 temp_add[2]; /* Register value */ ++ u16 temp_add_over[2]; /* Register value */ ++ u16 temp_add_hyst[2]; /* Register value */ ++ u8 fan_div[3]; /* Register encoding, shifted right */ ++ u8 vid; /* Register encoding, combined */ ++ u32 alarms; /* Register encoding, combined */ ++ u32 beeps; /* Register encoding, combined */ ++ u8 beep_enable; /* Boolean */ ++ u8 pwm[3]; /* Register value */ ++ u8 pwmenable[3]; /* bool */ ++ u16 sens[3]; /* 782D/783S only. ++ 1 = pentium diode; 2 = 3904 diode; ++ 3000-5000 = thermistor beta. ++ Default = 3435. ++ Other Betas unimplemented */ ++ u8 vrm; ++ u8 vrm_ovt; /* Register value, 627thf & 637hf only */ ++}; ++ ++ ++static int w83627hf_attach_adapter(struct i2c_adapter *adapter); ++static int w83627hf_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int w83627hf_detach_client(struct i2c_client *client); ++ ++static int w83627hf_read_value(struct i2c_client *client, u16 register); ++static int w83627hf_write_value(struct i2c_client *client, u16 register, ++ u16 value); ++static void w83627hf_update_client(struct i2c_client *client); ++static void w83627hf_init_client(struct i2c_client *client); ++ ++ ++static void w83627hf_in(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83627hf_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83627hf_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83627hf_temp_add(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83627hf_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83627hf_vrm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83627hf_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83627hf_beep(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83627hf_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83627hf_pwm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83627hf_sens(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++ ++static int w83627hf_id = 0; ++ ++static struct i2c_driver w83627hf_driver = { ++ .owner = THIS_MODULE, ++ .name = "W83627HF sensor driver", ++ .id = I2C_DRIVERID_W83627HF, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = w83627hf_attach_adapter, ++ .detach_client = w83627hf_detach_client, ++}; ++ ++/* The /proc/sys entries */ ++/* WARNING these are copied from w83781d.c and have not been renamed. ++ Note that the 627hf and 697hf are supported by both drivers. ++ Do not make incompatible changes here or we will have errors ++ in the generated file ../include/sensors.h !!! ++*/ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define W83781D_SYSCTL_IN0 1000 /* Volts * 100 */ ++#define W83781D_SYSCTL_IN1 1001 ++#define W83781D_SYSCTL_IN2 1002 ++#define W83781D_SYSCTL_IN3 1003 ++#define W83781D_SYSCTL_IN4 1004 ++#define W83781D_SYSCTL_IN5 1005 ++#define W83781D_SYSCTL_IN6 1006 ++#define W83781D_SYSCTL_IN7 1007 ++#define W83781D_SYSCTL_IN8 1008 ++#define W83781D_SYSCTL_FAN1 1101 /* Rotations/min */ ++#define W83781D_SYSCTL_FAN2 1102 ++#define W83781D_SYSCTL_FAN3 1103 ++#define W83781D_SYSCTL_TEMP1 1200 /* Degrees Celcius * 10 */ ++#define W83781D_SYSCTL_TEMP2 1201 /* Degrees Celcius * 10 */ ++#define W83781D_SYSCTL_TEMP3 1202 /* Degrees Celcius * 10 */ ++#define W83781D_SYSCTL_VID 1300 /* Volts * 1000 */ ++#define W83781D_SYSCTL_VRM 1301 ++#define W83781D_SYSCTL_PWM1 1401 ++#define W83781D_SYSCTL_PWM2 1402 ++#define W83781D_SYSCTL_PWM3 1403 ++#define W83781D_SYSCTL_SENS1 1501 /* 1, 2, or Beta (3000-5000) */ ++#define W83781D_SYSCTL_SENS2 1502 ++#define W83781D_SYSCTL_SENS3 1503 ++#define W83781D_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define W83781D_SYSCTL_ALARMS 2001 /* bitvector */ ++#define W83781D_SYSCTL_BEEP 2002 /* bitvector */ ++ ++#define W83781D_ALARM_IN0 0x0001 ++#define W83781D_ALARM_IN1 0x0002 ++#define W83781D_ALARM_IN2 0x0004 ++#define W83781D_ALARM_IN3 0x0008 ++#define W83781D_ALARM_IN4 0x0100 ++#define W83781D_ALARM_IN5 0x0200 ++#define W83781D_ALARM_IN6 0x0400 ++#define W83782D_ALARM_IN7 0x10000 ++#define W83782D_ALARM_IN8 0x20000 ++#define W83781D_ALARM_FAN1 0x0040 ++#define W83781D_ALARM_FAN2 0x0080 ++#define W83781D_ALARM_FAN3 0x0800 ++#define W83781D_ALARM_TEMP1 0x0010 ++#define W83781D_ALARM_TEMP23 0x0020 /* 781D only */ ++#define W83781D_ALARM_TEMP2 0x0020 /* 782D/783S */ ++#define W83781D_ALARM_TEMP3 0x2000 /* 782D only */ ++#define W83781D_ALARM_CHAS 0x1000 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected chip. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++ ++/* without pwm3-4 */ ++static ctl_table w83627hf_dir_table_template[] = { ++ {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_fan}, ++ {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_fan}, ++ {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_fan}, ++ {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_temp}, ++ {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_temp_add}, ++ {W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_temp_add}, ++ {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_vid}, ++ {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_vrm}, ++ {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_fan_div}, ++ {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_alarms}, ++ {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_beep}, ++ {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_pwm}, ++ {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_pwm}, ++ {W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_sens}, ++ {W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_sens}, ++ {W83781D_SYSCTL_SENS3, "sensor3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_sens}, ++ {0} ++}; ++ ++/* similar to w83782d but no fan3, no vid */ ++static ctl_table w83697hf_dir_table_template[] = { ++ {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ /* no in1 to maintain compatibility with 781d and 782d. */ ++ {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_fan}, ++ {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_fan}, ++ {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_temp}, ++ {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_temp_add}, ++ {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_fan_div}, ++ {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_alarms}, ++ {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_beep}, ++ {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_pwm}, ++ {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_pwm}, ++ {W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_sens}, ++ {W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_sens}, ++ {0} ++}; ++ ++/* no in5 and in6 */ ++/* We use this one for W83637HF too */ ++static ctl_table w83627thf_dir_table_template[] = { ++ {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_in}, ++ {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_fan}, ++ {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_fan}, ++ {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_fan}, ++ {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_temp}, ++ {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_temp_add}, ++ {W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_temp_add}, ++ {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_vid}, ++ {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_vrm}, ++ {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_fan_div}, ++ {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_alarms}, ++ {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_beep}, ++ {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_pwm}, ++ {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_pwm}, ++ {W83781D_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_pwm}, ++ {W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_sens}, ++ {W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_sens}, ++ {W83781D_SYSCTL_SENS3, "sensor3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83627hf_sens}, ++ {0} ++}; ++ ++ ++/* This function is called when: ++ * w83627hf_driver is inserted (when this module is loaded), for each ++ available adapter ++ * when a new adapter is inserted (and w83627hf_driver is still present) */ ++static int w83627hf_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, w83627hf_detect); ++} ++ ++static int w83627hf_find(int *address) ++{ ++ u16 val; ++ ++ superio_enter(); ++ val= superio_inb(DEVID); ++ if(val != W627_DEVID && val !=W627THF_DEVID && val != W697_DEVID && val != W637_DEVID) { ++ superio_exit(); ++ return -ENODEV; ++ } ++ ++ superio_select(W83627HF_LD_HWM); ++ val = (superio_inb(WINB_BASE_REG) << 8) | ++ superio_inb(WINB_BASE_REG + 1); ++ *address = val & ~(WINB_EXTENT - 1); ++ if (*address == 0 && force_addr == 0) { ++ printk("w83627hf.o: base address not set - use force_addr=0xaddr\n"); ++ superio_exit(); ++ return -ENODEV; ++ } ++ if (force_addr) ++ *address = force_addr; /* so detect will get called */ ++ ++ superio_exit(); ++ return 0; ++} ++ ++int w83627hf_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i, val; ++ struct i2c_client *new_client; ++ struct w83627hf_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ ++ if (!i2c_is_isa_adapter(adapter)) ++ return 0; ++ ++ if(force_addr) ++ address = force_addr & ~(WINB_EXTENT - 1); ++ if (check_region(address, WINB_EXTENT)) { ++ printk("w83627hf.o: region 0x%x already in use!\n", address); ++ return -ENODEV; ++ } ++ if(force_addr) { ++ printk("w83627hf.o: forcing ISA address 0x%04X\n", address); ++ superio_enter(); ++ superio_select(W83627HF_LD_HWM); ++ superio_outb(WINB_BASE_REG, address >> 8); ++ superio_outb(WINB_BASE_REG+1, address & 0xff); ++ superio_exit(); ++ } ++ ++ superio_enter(); ++ val= superio_inb(DEVID); ++ if(val == W627_DEVID) ++ kind = w83627hf; ++ else if(val == W697_DEVID) ++ kind = w83697hf; ++ else if(val == W627THF_DEVID) ++ kind = w83627thf; ++ else if(val == W637_DEVID) ++ kind = w83637hf; ++ ++ superio_select(W83627HF_LD_HWM); ++ if((val = 0x01 & superio_inb(WINB_ACT_REG)) == 0) ++ superio_outb(WINB_ACT_REG, 1); ++ superio_exit(); ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access w83627hf_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ init_MUTEX(&data->lock); ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &w83627hf_driver; ++ new_client->flags = 0; ++ ++ ++ if (kind == w83627hf) { ++ type_name = "w83627hf"; ++ client_name = "W83627HF chip"; ++ } else if (kind == w83627thf) { ++ type_name = "w83627thf"; ++ client_name = "W83627THF chip"; ++ } else if (kind == w83697hf) { ++ type_name = "w83697hf"; ++ client_name = "W83697HF chip"; ++ } else if (kind == w83637hf) { ++ type_name = "w83637hf"; ++ client_name = "W83637HF chip"; ++ } else { ++ goto ERROR1; ++ } ++ ++ request_region(address, WINB_EXTENT, type_name); ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ data->type = kind; ++ new_client->id = w83627hf_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ data->lm75 = NULL; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, ++ type_name, ++ (kind == w83697hf) ? ++ w83697hf_dir_table_template : ++ (kind == w83627hf) ? ++ w83627hf_dir_table_template : ++ /* w83627thf table also used for 637 */ ++ w83627thf_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR7; ++ } ++ data->sysctl_id = i; ++ ++ /* Initialize the chip */ ++ w83627hf_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR7: ++ i2c_detach_client(new_client); ++ ERROR3: ++ release_region(address, WINB_EXTENT); ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int w83627hf_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct w83627hf_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ (KERN_ERR "w83627hf.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ release_region(client->addr, WINB_EXTENT); ++ kfree(client->data); ++ ++ return 0; ++} ++ ++ ++/* ++ ISA access must always be locked explicitly! ++ We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, ++ would slow down the W83781D access and should not be necessary. ++ There are some ugly typecasts here, but the good news is - they should ++ nowhere else be necessary! */ ++static int w83627hf_read_value(struct i2c_client *client, u16 reg) ++{ ++ int res, word_sized; ++ ++ down(&(((struct w83627hf_data *) (client->data))->lock)); ++ word_sized = (((reg & 0xff00) == 0x100) ++ || ((reg & 0xff00) == 0x200)) ++ && (((reg & 0x00ff) == 0x50) ++ || ((reg & 0x00ff) == 0x53) ++ || ((reg & 0x00ff) == 0x55)); ++ if (reg & 0xff00) { ++ outb_p(W83781D_REG_BANK, ++ client->addr + W83781D_ADDR_REG_OFFSET); ++ outb_p(reg >> 8, ++ client->addr + W83781D_DATA_REG_OFFSET); ++ } ++ outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET); ++ res = inb_p(client->addr + W83781D_DATA_REG_OFFSET); ++ if (word_sized) { ++ outb_p((reg & 0xff) + 1, ++ client->addr + W83781D_ADDR_REG_OFFSET); ++ res = ++ (res << 8) + inb_p(client->addr + ++ W83781D_DATA_REG_OFFSET); ++ } ++ if (reg & 0xff00) { ++ outb_p(W83781D_REG_BANK, ++ client->addr + W83781D_ADDR_REG_OFFSET); ++ outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); ++ } ++ up(&(((struct w83627hf_data *) (client->data))->lock)); ++ return res; ++} ++ ++static int w83627thf_read_gpio5(struct i2c_client *client) ++{ ++ int res, inv; ++ ++ down(&(((struct w83627hf_data *) (client->data))->lock)); ++ superio_enter(); ++ superio_select(W83627HF_LD_GPIO5); ++ res = superio_inb(W83627THF_GPIO5_DR); ++ inv = superio_inb(W83627THF_GPIO5_INVR); ++ superio_exit(); ++ up(&(((struct w83627hf_data *) (client->data))->lock)); ++ return res; ++} ++ ++static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value) ++{ ++ int word_sized; ++ ++ down(&(((struct w83627hf_data *) (client->data))->lock)); ++ word_sized = (((reg & 0xff00) == 0x100) ++ || ((reg & 0xff00) == 0x200)) ++ && (((reg & 0x00ff) == 0x53) ++ || ((reg & 0x00ff) == 0x55)); ++ if (reg & 0xff00) { ++ outb_p(W83781D_REG_BANK, ++ client->addr + W83781D_ADDR_REG_OFFSET); ++ outb_p(reg >> 8, ++ client->addr + W83781D_DATA_REG_OFFSET); ++ } ++ outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET); ++ if (word_sized) { ++ outb_p(value >> 8, ++ client->addr + W83781D_DATA_REG_OFFSET); ++ outb_p((reg & 0xff) + 1, ++ client->addr + W83781D_ADDR_REG_OFFSET); ++ } ++ outb_p(value & 0xff, ++ client->addr + W83781D_DATA_REG_OFFSET); ++ if (reg & 0xff00) { ++ outb_p(W83781D_REG_BANK, ++ client->addr + W83781D_ADDR_REG_OFFSET); ++ outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); ++ } ++ up(&(((struct w83627hf_data *) (client->data))->lock)); ++ return 0; ++} ++ ++/* Called when we have found a new W83781D. It should set limits, etc. */ ++static void w83627hf_init_client(struct i2c_client *client) ++{ ++ struct w83627hf_data *data = client->data; ++ int i; ++ int type = data->type; ++ u8 tmp; ++ ++ /* Minimize conflicts with other winbond i2c-only clients... */ ++ /* disable i2c subclients... how to disable main i2c client?? */ ++ /* force i2c address to relatively uncommon address */ ++ w83627hf_write_value(client, W83781D_REG_I2C_SUBADDR, 0x89); ++ w83627hf_write_value(client, W83781D_REG_I2C_ADDR, force_i2c); ++ ++ /* Read VID only once */ ++ if (w83627hf == data->type || w83637hf == data->type) { ++ int lo = w83627hf_read_value(client, W83781D_REG_VID_FANDIV); ++ int hi = w83627hf_read_value(client, W83781D_REG_CHIPID); ++ data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); ++ } else if (w83627thf == data->type) { ++ data->vid = w83627thf_read_gpio5(client) & 0x1f; ++ } ++ ++ /* Read VRM & OVT Config only once */ ++ if (w83627thf == data->type || w83637hf == data->type) ++ data->vrm_ovt = ++ w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG); ++ else ++ data->vrm_ovt = 0; ++ ++ /* Choose VRM based on "VRM & OVT" register */ ++ data->vrm = (data->vrm_ovt & 0x01) ? 90 : 82; ++ ++ tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); ++ for (i = 1; i <= 3; i++) { ++ if (!(tmp & BIT_SCFG1[i - 1])) { ++ data->sens[i - 1] = W83781D_DEFAULT_BETA; ++ } else { ++ if (w83627hf_read_value ++ (client, ++ W83781D_REG_SCFG2) & BIT_SCFG2[i - 1]) ++ data->sens[i - 1] = 1; ++ else ++ data->sens[i - 1] = 2; ++ } ++ if ((type == w83697hf) && (i == 2)) ++ break; ++ } ++ ++ data->pwmenable[0] = 1; ++ data->pwmenable[1] = 1; ++ data->pwmenable[2] = 1; ++ ++ if(init) { ++ if (type == w83627hf) { ++ /* enable PWM2 control (can't hurt since PWM reg ++ should have been reset to 0xff) */ ++ w83627hf_write_value(client, W83627HF_REG_PWMCLK12, 0x19); ++ } ++ /* enable comparator mode for temp2 and temp3 so ++ alarm indication will work correctly */ ++ i = w83627hf_read_value(client, W83781D_REG_IRQ); ++ if (!(i & 0x40)) ++ w83627hf_write_value(client, W83781D_REG_IRQ, ++ i | 0x40); ++ } ++ ++ /* Start monitoring */ ++ w83627hf_write_value(client, W83781D_REG_CONFIG, ++ (w83627hf_read_value(client, ++ W83781D_REG_CONFIG) & 0xf7) ++ | 0x01); ++} ++ ++static void w83627hf_update_client(struct i2c_client *client) ++{ ++ struct w83627hf_data *data = client->data; ++ int i; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ for (i = 0; i <= 8; i++) { ++ /* skip missing sensors */ ++ if (((data->type == w83697hf) && (i == 1)) || ++ ((data->type == w83627thf || data->type == w83637hf) && ++ (i == 4 || i == 5))) ++ continue; ++ data->in[i] = ++ w83627hf_read_value(client, W83781D_REG_IN(i)); ++ data->in_min[i] = ++ w83627hf_read_value(client, ++ W83781D_REG_IN_MIN(i)); ++ data->in_max[i] = ++ w83627hf_read_value(client, ++ W83781D_REG_IN_MAX(i)); ++ } ++ for (i = 1; i <= 3; i++) { ++ data->fan[i - 1] = ++ w83627hf_read_value(client, W83781D_REG_FAN(i)); ++ data->fan_min[i - 1] = ++ w83627hf_read_value(client, ++ W83781D_REG_FAN_MIN(i)); ++ } ++ for (i = 1; i <= 3; i++) { ++ u8 tmp = w83627hf_read_value(client, ++ W836X7HF_REG_PWM(data->type, i)); ++ if (data->type == w83627thf) ++ tmp &= 0xf0; /* bits 0-3 are reserved in 627THF */ ++ data->pwm[i - 1] = tmp; ++ if(i == 2 && (data->type == w83627hf || data->type == w83697hf)) ++ break; ++ } ++ ++ data->temp = w83627hf_read_value(client, W83781D_REG_TEMP); ++ data->temp_over = ++ w83627hf_read_value(client, W83781D_REG_TEMP_OVER); ++ data->temp_hyst = ++ w83627hf_read_value(client, W83781D_REG_TEMP_HYST); ++ data->temp_add[0] = ++ w83627hf_read_value(client, W83781D_REG_TEMP2); ++ data->temp_add_over[0] = ++ w83627hf_read_value(client, W83781D_REG_TEMP2_OVER); ++ data->temp_add_hyst[0] = ++ w83627hf_read_value(client, W83781D_REG_TEMP2_HYST); ++ if (data->type != w83697hf) { ++ data->temp_add[1] = ++ w83627hf_read_value(client, W83781D_REG_TEMP3); ++ data->temp_add_over[1] = ++ w83627hf_read_value(client, W83781D_REG_TEMP3_OVER); ++ data->temp_add_hyst[1] = ++ w83627hf_read_value(client, W83781D_REG_TEMP3_HYST); ++ } ++ ++ i = w83627hf_read_value(client, W83781D_REG_VID_FANDIV); ++ data->fan_div[0] = (i >> 4) & 0x03; ++ data->fan_div[1] = (i >> 6) & 0x03; ++ if (data->type != w83697hf) { ++ data->fan_div[2] = (w83627hf_read_value(client, ++ W83781D_REG_PIN) >> 6) & 0x03; ++ } ++ i = w83627hf_read_value(client, W83781D_REG_VBAT); ++ data->fan_div[0] |= (i >> 3) & 0x04; ++ data->fan_div[1] |= (i >> 4) & 0x04; ++ if (data->type != w83697hf) ++ data->fan_div[2] |= (i >> 5) & 0x04; ++ data->alarms = ++ w83627hf_read_value(client, W83781D_REG_ALARM1) | ++ (w83627hf_read_value(client, W83781D_REG_ALARM2) << 8) | ++ (w83627hf_read_value(client, W83781D_REG_ALARM3) << 16); ++ i = w83627hf_read_value(client, W83781D_REG_BEEP_INTS2); ++ data->beep_enable = i >> 7; ++ data->beeps = ((i & 0x7f) << 8) | ++ w83627hf_read_value(client, W83781D_REG_BEEP_INTS1) | ++ w83627hf_read_value(client, W83781D_REG_BEEP_INTS3) << 16; ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++void w83627hf_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83627hf_data *data = client->data; ++ int nr = ctl_name - W83781D_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83627hf_update_client(client); ++ ++ if (nr == 0 && (data->vrm_ovt & 0x01)) { ++ /* use VRM9 calculation */ ++ results[0] = IN_FROM_REG_VRM9(data->in_min[0]); ++ results[1] = IN_FROM_REG_VRM9(data->in_max[0]); ++ results[2] = IN_FROM_REG_VRM9(data->in[0]); ++ ++ } else { ++ /* use VRM8 (standard) calculation */ ++ results[0] = IN_FROM_REG(data->in_min[nr]); ++ results[1] = IN_FROM_REG(data->in_max[nr]); ++ results[2] = IN_FROM_REG(data->in[nr]); ++ } ++ ++ *nrels_mag = 3; ++ ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ if (nr == 0 && (data->vrm_ovt & 0x01)) ++ /* use VRM9 calculation */ ++ data->in_min[0] = IN_TO_REG_VRM9(results[0]); ++ else ++ /* use VRM8 (standard) calculation */ ++ data->in_min[nr] = IN_TO_REG(results[0]); ++ ++ w83627hf_write_value(client, W83781D_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ if (nr == 0 && (data->vrm_ovt & 0x01)) ++ /* use VRM9 calculation */ ++ data->in_min[0] = IN_TO_REG_VRM9(results[1]); ++ else ++ /* use VRM8 (standard) calculation */ ++ data->in_max[nr] = IN_TO_REG(results[1]); ++ ++ w83627hf_write_value(client, W83781D_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++} ++ ++void w83627hf_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83627hf_data *data = client->data; ++ int nr = ctl_name - W83781D_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83627hf_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ results[1] = FAN_FROM_REG(data->fan[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = ++ FAN_TO_REG(results[0], ++ DIV_FROM_REG(data->fan_div[nr-1])); ++ w83627hf_write_value(client, ++ W83781D_REG_FAN_MIN(nr), ++ data->fan_min[nr - 1]); ++ } ++ } ++} ++ ++void w83627hf_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83627hf_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83627hf_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_over); ++ results[1] = TEMP_FROM_REG(data->temp_hyst); ++ results[2] = TEMP_FROM_REG(data->temp); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_over = TEMP_TO_REG(results[0]); ++ w83627hf_write_value(client, W83781D_REG_TEMP_OVER, ++ data->temp_over); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst = TEMP_TO_REG(results[1]); ++ w83627hf_write_value(client, W83781D_REG_TEMP_HYST, ++ data->temp_hyst); ++ } ++ } ++} ++ ++void w83627hf_temp_add(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct w83627hf_data *data = client->data; ++ int nr = ctl_name - W83781D_SYSCTL_TEMP2; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83627hf_update_client(client); ++ results[0] = ++ LM75_TEMP_FROM_REG(data->temp_add_over[nr]); ++ results[1] = ++ LM75_TEMP_FROM_REG(data->temp_add_hyst[nr]); ++ results[2] = LM75_TEMP_FROM_REG(data->temp_add[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_add_over[nr] = ++ LM75_TEMP_TO_REG(results[0]); ++ w83627hf_write_value(client, ++ nr ? W83781D_REG_TEMP3_OVER : ++ W83781D_REG_TEMP2_OVER, ++ data->temp_add_over[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_add_hyst[nr] = ++ LM75_TEMP_TO_REG(results[1]); ++ w83627hf_write_value(client, ++ nr ? W83781D_REG_TEMP3_HYST : ++ W83781D_REG_TEMP2_HYST, ++ data->temp_add_hyst[nr]); ++ } ++ } ++} ++ ++void w83627hf_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83627hf_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83627hf_update_client(client); ++ results[0] = vid_from_reg(data->vid, data->vrm); ++ *nrels_mag = 1; ++ } ++} ++ ++void w83627hf_vrm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83627hf_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->vrm; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) ++ data->vrm = results[0]; ++ } ++} ++ ++void w83627hf_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83627hf_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83627hf_update_client(client); ++ results[0] = data->alarms; ++ *nrels_mag = 1; ++ } ++} ++ ++void w83627hf_beep(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83627hf_data *data = client->data; ++ int val; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83627hf_update_client(client); ++ results[0] = BEEP_ENABLE_FROM_REG(data->beep_enable); ++ results[1] = data->beeps; ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 2) { ++ data->beeps = BEEPS_TO_REG(results[1]); ++ w83627hf_write_value(client, W83781D_REG_BEEP_INTS1, ++ data->beeps & 0xff); ++ w83627hf_write_value(client, ++ W83781D_REG_BEEP_INTS3, ++ ((data-> beeps) >> 16) & ++ 0xff); ++ val = (data->beeps >> 8) & 0x7f; ++ } else if (*nrels_mag >= 1) ++ val = ++ w83627hf_read_value(client, ++ W83781D_REG_BEEP_INTS2) & ++ 0x7f; ++ if (*nrels_mag >= 1) { ++ data->beep_enable = BEEP_ENABLE_TO_REG(results[0]); ++ w83627hf_write_value(client, W83781D_REG_BEEP_INTS2, ++ val | data->beep_enable << 7); ++ } ++ } ++} ++ ++/* w83697hf only has two fans */ ++void w83627hf_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct w83627hf_data *data = client->data; ++ int old, old2, old3 = 0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83627hf_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ if (data->type == w83697hf) { ++ *nrels_mag = 2; ++ } else { ++ results[2] = DIV_FROM_REG(data->fan_div[2]); ++ *nrels_mag = 3; ++ } ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = w83627hf_read_value(client, W83781D_REG_VID_FANDIV); ++ /* w83627hf doesn't have extended divisor bits */ ++ old3 = ++ w83627hf_read_value(client, W83781D_REG_VBAT); ++ if (*nrels_mag >= 3 && data->type != w83697hf) { ++ data->fan_div[2] = ++ DIV_TO_REG(results[2]); ++ old2 = w83627hf_read_value(client, W83781D_REG_PIN); ++ old2 = ++ (old2 & 0x3f) | ((data->fan_div[2] & 0x03) << 6); ++ w83627hf_write_value(client, W83781D_REG_PIN, old2); ++ old3 = ++ (old3 & 0x7f) | ++ ((data->fan_div[2] & 0x04) << 5); ++ } ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = ++ DIV_TO_REG(results[1]); ++ old = ++ (old & 0x3f) | ((data->fan_div[1] & 0x03) << 6); ++ old3 = ++ (old3 & 0xbf) | ++ ((data->fan_div[1] & 0x04) << 4); ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = ++ DIV_TO_REG(results[0]); ++ old = ++ (old & 0xcf) | ((data->fan_div[0] & 0x03) << 4); ++ w83627hf_write_value(client, W83781D_REG_VID_FANDIV, ++ old); ++ old3 = ++ (old3 & 0xdf) | ++ ((data->fan_div[0] & 0x04) << 3); ++ w83627hf_write_value(client, ++ W83781D_REG_VBAT, ++ old3); ++ } ++ } ++} ++ ++/* we do not currently support disabling PWM with 2nd argument; ++ set first argument to 255 to disable */ ++void w83627hf_pwm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83627hf_data *data = client->data; ++ int nr = 1 + ctl_name - W83781D_SYSCTL_PWM1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83627hf_update_client(client); ++ results[0] = data->pwm[nr - 1]; ++ results[1] = data->pwmenable[nr - 1]; ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ if (data->type == w83627thf) { ++ /* bits 0-3 are reserved in 627THF */ ++ data->pwm[nr - 1] = PWM_TO_REG(results[0]) & 0xf0; ++ w83627hf_write_value(client, ++ W836X7HF_REG_PWM(data->type, nr), ++ data->pwm[nr - 1] | ++ (w83627hf_read_value(client, ++ W836X7HF_REG_PWM(data->type, nr)) & 0x0f)); ++ } else { ++ data->pwm[nr - 1] = PWM_TO_REG(results[0]); ++ w83627hf_write_value(client, ++ W836X7HF_REG_PWM(data->type, nr), ++ data->pwm[nr - 1]); ++ } ++ } ++ } ++} ++ ++void w83627hf_sens(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83627hf_data *data = client->data; ++ int nr = 1 + ctl_name - W83781D_SYSCTL_SENS1; ++ u8 tmp; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->sens[nr - 1]; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ switch (results[0]) { ++ case 1: /* PII/Celeron diode */ ++ tmp = w83627hf_read_value(client, ++ W83781D_REG_SCFG1); ++ w83627hf_write_value(client, ++ W83781D_REG_SCFG1, ++ tmp | BIT_SCFG1[nr - ++ 1]); ++ tmp = w83627hf_read_value(client, ++ W83781D_REG_SCFG2); ++ w83627hf_write_value(client, ++ W83781D_REG_SCFG2, ++ tmp | BIT_SCFG2[nr - ++ 1]); ++ data->sens[nr - 1] = results[0]; ++ break; ++ case 2: /* 3904 */ ++ tmp = w83627hf_read_value(client, ++ W83781D_REG_SCFG1); ++ w83627hf_write_value(client, ++ W83781D_REG_SCFG1, ++ tmp | BIT_SCFG1[nr - ++ 1]); ++ tmp = w83627hf_read_value(client, ++ W83781D_REG_SCFG2); ++ w83627hf_write_value(client, ++ W83781D_REG_SCFG2, ++ tmp & ~BIT_SCFG2[nr - ++ 1]); ++ data->sens[nr - 1] = results[0]; ++ break; ++ case W83781D_DEFAULT_BETA: /* thermistor */ ++ tmp = w83627hf_read_value(client, ++ W83781D_REG_SCFG1); ++ w83627hf_write_value(client, ++ W83781D_REG_SCFG1, ++ tmp & ~BIT_SCFG1[nr - ++ 1]); ++ data->sens[nr - 1] = results[0]; ++ break; ++ default: ++ printk ++ (KERN_ERR "w83627hf.o: Invalid sensor type %ld; must be 1, 2, or %d\n", ++ results[0], W83781D_DEFAULT_BETA); ++ break; ++ } ++ } ++ } ++} ++ ++static int __init sm_w83627hf_init(void) ++{ ++ int addr; ++ ++ printk(KERN_INFO "w83627hf.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ if (w83627hf_find(&addr)) { ++ printk("w83627hf.o: W83627/697 not detected, module not inserted.\n"); ++ return -ENODEV; ++ } ++ normal_isa[0] = addr; ++ ++ return i2c_add_driver(&w83627hf_driver); ++} ++ ++static void __exit sm_w83627hf_exit(void) ++{ ++ i2c_del_driver(&w83627hf_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Frodo Looijaard , " ++ "Philip Edelbrock , " ++ "and Mark Studebaker "); ++MODULE_DESCRIPTION("W83627HF driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_w83627hf_init); ++module_exit(sm_w83627hf_exit); +--- linux-old/drivers/sensors/w83781d.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/w83781d.c Mon Dec 13 20:18:54 2004 +@@ -0,0 +1,1957 @@ ++/* ++ w83781d.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998 - 2003 Frodo Looijaard , ++ Philip Edelbrock , ++ and Mark Studebaker ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ Supports following chips: ++ ++ Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA ++ as99127f 7 3 0 3 0x31 0x12c3 yes no ++ as99127f rev.2 (type name = as99127f) 0x31 0x5ca3 yes no ++ w83627hf 9 3 2 3 0x21 0x5ca3 yes yes(LPC) ++ w83697hf 8 2 2 2 0x60 0x5ca3 no yes(LPC) ++ w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes ++ w83782d 9 3 2-4 3 0x30 0x5ca3 yes yes ++ w83783s 5-6 3 2 1-2 0x40 0x5ca3 yes no ++ w83791d 10 5 5 3 0x71 0x5ca3 yes no ++ ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++#include ++#include "lm75.h" ++ ++/* RT Table support #defined so we can take it out if it gets bothersome */ ++#define W83781D_RT 1 ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { 0x20, 0x2f, SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { 0x0290, SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_7(w83781d, w83782d, w83783s, w83627hf, as99127f, w83697hf, w83791d); ++SENSORS_MODULE_PARM(force_subclients, "List of subclient addresses: " \ ++ "{bus, clientaddr, subclientaddr1, subclientaddr2}"); ++ ++static int init = 1; ++MODULE_PARM(init, "i"); ++MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); ++ ++/* Constants specified below */ ++ ++/* Length of ISA address segment */ ++#define W83781D_EXTENT 8 ++ ++/* Where are the ISA address/data registers relative to the base address */ ++#define W83781D_ADDR_REG_OFFSET 5 ++#define W83781D_DATA_REG_OFFSET 6 ++ ++/* The W83781D registers */ ++/* The W83782D registers for nr=7,8 are in bank 5 */ ++#define W83781D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \ ++ (0x554 + (((nr) - 7) * 2))) ++#define W83781D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \ ++ (0x555 + (((nr) - 7) * 2))) ++#define W83781D_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ ++ (0x550 + (nr) - 7)) ++ ++#define W83791D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \ ++ (0xb4 + (((nr) - 7) * 2))) ++#define W83791D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \ ++ (0xb5 + (((nr) - 7) * 2))) ++#define W83791D_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ ++ (0xb0 + (nr) - 7)) ++ ++#define W83781D_REG_FAN_MIN(nr) ((nr < 4) ? (0x3a + (nr)) : \ ++ (0xba + (nr) - 4)) ++#define W83781D_REG_FAN(nr) ((nr < 4) ? (0x27 + (nr)) : \ ++ (0xbc + (nr) - 4)) ++ ++#define W83781D_REG_TEMP2 0x0150 ++#define W83781D_REG_TEMP3 0x0250 ++#define W83781D_REG_TEMP2_HYST 0x153 ++#define W83781D_REG_TEMP3_HYST 0x253 ++#define W83781D_REG_TEMP2_CONFIG 0x152 ++#define W83781D_REG_TEMP3_CONFIG 0x252 ++#define W83781D_REG_TEMP2_OVER 0x155 ++#define W83781D_REG_TEMP3_OVER 0x255 ++ ++#define W83781D_REG_TEMP 0x27 ++#define W83781D_REG_TEMP_OVER 0x39 ++#define W83781D_REG_TEMP_HYST 0x3A ++#define W83781D_REG_BANK 0x4E ++ ++#define W83781D_REG_CONFIG 0x40 ++#define W83781D_REG_ALARM1 0x41 ++#define W83781D_REG_ALARM2 0x42 ++#define W83781D_REG_ALARM3 0x450 /* not on W83781D */ ++ ++#define W83781D_REG_IRQ 0x4C ++#define W83781D_REG_BEEP_CONFIG 0x4D ++#define W83781D_REG_BEEP_INTS1 0x56 ++#define W83781D_REG_BEEP_INTS2 0x57 ++#define W83781D_REG_BEEP_INTS3 0x453 /* not on W83781D */ ++ ++#define W83781D_REG_VID_FANDIV 0x47 ++ ++#define W83781D_REG_CHIPID 0x49 ++#define W83781D_REG_WCHIPID 0x58 ++#define W83781D_REG_CHIPMAN 0x4F ++#define W83781D_REG_PIN 0x4B ++ ++/* 782D/783S only */ ++#define W83781D_REG_VBAT 0x5D ++ ++/* PWM 782D (1-4) and 783S (1-2) only */ ++#define W83781D_REG_PWM1 0x5B /* 782d and 783s/627hf datasheets disagree */ ++ /* on which is which; */ ++#define W83781D_REG_PWM2 0x5A /* We follow the 782d convention here, */ ++ /* However 782d is probably wrong. */ ++#define W83781D_REG_PWM3 0x5E ++#define W83781D_REG_PWM4 0x5F ++#define W83781D_REG_PWMCLK12 0x5C ++#define W83781D_REG_PWMCLK34 0x45C ++ ++#define W83791D_REG_PWM1 0x81 ++#define W83791D_REG_PWM2 0x83 ++#define W83791D_REG_PWM3 0x94 ++ ++#define W83627HF_REG_PWM1 0x01 ++#define W83627HF_REG_PWM2 0x03 ++#define W83627HF_REG_PWMCLK1 0x00 ++#define W83627HF_REG_PWMCLK2 0x02 ++ ++static const u8 regpwm[] = { W83781D_REG_PWM1, W83781D_REG_PWM2, ++ W83781D_REG_PWM3, W83781D_REG_PWM4 ++}; ++ ++static const u8 regpwm_w83791d[] = { W83791D_REG_PWM1, W83791D_REG_PWM2, ++ W83791D_REG_PWM3 ++}; ++ ++#define W83781D_REG_PWM(type, nr) (((type) == w83791d) ? \ ++ regpwm_w83791d[(nr) - 1] : \ ++ ((type) == w83697hf) ? \ ++ (((nr) * 2) - 1) : \ ++ regpwm[(nr) - 1]) ++ ++#define W83781D_REG_I2C_ADDR 0x48 ++#define W83781D_REG_I2C_SUBADDR 0x4A ++ ++/* The following are undocumented in the data sheets however we ++ received the information in an email from Winbond tech support */ ++/* Sensor selection - not on 781d */ ++#define W83781D_REG_SCFG1 0x5D ++static const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 }; ++#define W83781D_REG_SCFG2 0x59 ++static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 }; ++#define W83781D_DEFAULT_BETA 3435 ++ ++/* RT Table registers */ ++#define W83781D_REG_RT_IDX 0x50 ++#define W83781D_REG_RT_VAL 0x51 ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255)) ++#define IN_FROM_REG(val) (((val) * 16 + 5) / 10) ++ ++static inline u8 FAN_TO_REG(long rpm, int div) ++{ ++ if (rpm == 0) ++ return 255; ++ rpm = SENSORS_LIMIT(rpm, 1, 1000000); ++ return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, ++ 254); ++} ++ ++#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div))) ++ ++#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-5)/10):\ ++ ((val)+5)/10),0,255)) ++#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10) ++ ++#define AS99127_TEMP_ADD_TO_REG(val) (SENSORS_LIMIT((((((val) + 2)*4)/10) \ ++ << 7),0,0xffff)) ++#define AS99127_TEMP_ADD_FROM_REG(val) ((((val) >> 7) * 10) / 4) ++ ++#define ALARMS_FROM_REG(val) (val) ++#define PWM_FROM_REG(val) (val) ++#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) ++#define BEEPS_FROM_REG(val,type) ((type)==as99127f?(val)^0x7FFF:(val)) ++#define BEEPS_TO_REG(val,type) ((type)==as99127f?(~(val))&0x7FFF:(val)&0xffffff) ++ ++#define BEEP_ENABLE_TO_REG(val) ((val)?1:0) ++#define BEEP_ENABLE_FROM_REG(val) ((val)?1:0) ++ ++#define DIV_FROM_REG(val) (1 << (val)) ++ ++static inline u8 DIV_TO_REG(long val, enum chips type) ++{ ++ int i; ++ val = SENSORS_LIMIT(val, 1, ++ ((type == w83781d || type == as99127f) ? 8 : 128)) >> 1; ++ for (i = 0; i < 6; i++) { ++ if (val == 0) ++ break; ++ val >>= 1; ++ } ++ return ((u8) i); ++} ++ ++/* There are some complications in a module like this. First off, W83781D chips ++ may be both present on the SMBus and the ISA bus, and we have to handle ++ those cases separately at some places. Second, there might be several ++ W83781D chips available (well, actually, that is probably never done; but ++ it is a clean illustration of how to handle a case like that). Finally, ++ a specific chip may be attached to *both* ISA and SMBus, and we would ++ not like to detect it double. Fortunately, in the case of the W83781D at ++ least, a register tells us what SMBus address we are on, so that helps ++ a bit - except if there could be more than one SMBus. Groan. No solution ++ for this yet. */ ++ ++/* This module may seem overly long and complicated. In fact, it is not so ++ bad. Quite a lot of bookkeeping is done. A real driver can often cut ++ some corners. */ ++ ++/* For each registered W83781D, we need to keep some data in memory. That ++ data is pointed to by w83781d_list[NR]->data. The structure itself is ++ dynamically allocated, at the same time when a new w83781d client is ++ allocated. */ ++struct w83781d_data { ++ struct i2c_client client; ++ struct semaphore lock; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ struct i2c_client *lm75; /* for secondary I2C addresses */ ++ /* pointer to array of 2 subclients */ ++ ++ u8 in[10]; /* Register value - 8 & 9 for 782D and 791D only 10 for 791D */ ++ u8 in_max[10]; /* Register value - 8 & 9 for 782D and 791D only 10 for 791D */ ++ u8 in_min[10]; /* Register value - 8 & 9 for 782D and 791D only 10 for 791D */ ++ u8 fan[5]; /* Register value - 4 & 5 for 791D only */ ++ u8 fan_min[5]; /* Register value - 4 & 5 for 791D only */ ++ u8 temp; ++ u8 temp_over; /* Register value */ ++ u8 temp_hyst; /* Register value */ ++ u16 temp_add[2]; /* Register value */ ++ u16 temp_add_over[2]; /* Register value */ ++ u16 temp_add_hyst[2]; /* Register value */ ++ u8 fan_div[3]; /* Register encoding, shifted right */ ++ u8 vid; /* Register encoding, combined */ ++ u32 alarms; /* Register encoding, combined */ ++ u32 beeps; /* Register encoding, combined */ ++ u8 beep_enable; /* Boolean */ ++ u8 pwm[4]; /* Register value */ ++ u8 pwmenable[4]; /* bool */ ++ u16 sens[3]; /* 782D/783S only. ++ 1 = pentium diode; 2 = 3904 diode; ++ 3000-5000 = thermistor beta. ++ Default = 3435. ++ Other Betas unimplemented */ ++#ifdef W83781D_RT ++ u8 rt[3][32]; /* Register value */ ++#endif ++ u8 vrm; ++}; ++ ++ ++static int w83781d_attach_adapter(struct i2c_adapter *adapter); ++static int w83781d_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static int w83781d_detach_client(struct i2c_client *client); ++ ++static int w83781d_read_value(struct i2c_client *client, u16 register); ++static int w83781d_write_value(struct i2c_client *client, u16 register, ++ u16 value); ++static void w83781d_update_client(struct i2c_client *client); ++static void w83781d_init_client(struct i2c_client *client); ++ ++ ++static void w83781d_in(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83781d_fan(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83781d_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83781d_temp_add(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83781d_vid(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83781d_vrm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83781d_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83781d_beep(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83781d_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83781d_pwm(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void w83781d_sens(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++#ifdef W83781D_RT ++static void w83781d_rt(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++#endif ++ ++static int w83781d_id = 0; ++ ++static struct i2c_driver w83781d_driver = { ++ .owner = THIS_MODULE, ++ .name = "W83781D sensor driver", ++ .id = I2C_DRIVERID_W83781D, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = w83781d_attach_adapter, ++ .detach_client = w83781d_detach_client, ++}; ++ ++/* The /proc/sys entries */ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define W83781D_SYSCTL_IN0 1000 /* Volts * 100 */ ++#define W83781D_SYSCTL_IN1 1001 ++#define W83781D_SYSCTL_IN2 1002 ++#define W83781D_SYSCTL_IN3 1003 ++#define W83781D_SYSCTL_IN4 1004 ++#define W83781D_SYSCTL_IN5 1005 ++#define W83781D_SYSCTL_IN6 1006 ++#define W83781D_SYSCTL_IN7 1007 ++#define W83781D_SYSCTL_IN8 1008 ++#define W83781D_SYSCTL_IN9 1009 ++#define W83781D_SYSCTL_FAN1 1101 /* Rotations/min */ ++#define W83781D_SYSCTL_FAN2 1102 ++#define W83781D_SYSCTL_FAN3 1103 ++#define W83781D_SYSCTL_FAN4 1104 ++#define W83781D_SYSCTL_FAN5 1105 ++ ++#define W83781D_SYSCTL_TEMP1 1200 /* Degrees Celcius * 10 */ ++#define W83781D_SYSCTL_TEMP2 1201 /* Degrees Celcius * 10 */ ++#define W83781D_SYSCTL_TEMP3 1202 /* Degrees Celcius * 10 */ ++#define W83781D_SYSCTL_VID 1300 /* Volts * 1000 */ ++#define W83781D_SYSCTL_VRM 1301 ++#define W83781D_SYSCTL_PWM1 1401 ++#define W83781D_SYSCTL_PWM2 1402 ++#define W83781D_SYSCTL_PWM3 1403 ++#define W83781D_SYSCTL_PWM4 1404 ++#define W83781D_SYSCTL_SENS1 1501 /* 1, 2, or Beta (3000-5000) */ ++#define W83781D_SYSCTL_SENS2 1502 ++#define W83781D_SYSCTL_SENS3 1503 ++#define W83781D_SYSCTL_RT1 1601 /* 32-entry table */ ++#define W83781D_SYSCTL_RT2 1602 /* 32-entry table */ ++#define W83781D_SYSCTL_RT3 1603 /* 32-entry table */ ++#define W83781D_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ ++#define W83781D_SYSCTL_ALARMS 2001 /* bitvector */ ++#define W83781D_SYSCTL_BEEP 2002 /* bitvector */ ++ ++#define W83781D_ALARM_IN0 0x0001 ++#define W83781D_ALARM_IN1 0x0002 ++#define W83781D_ALARM_IN2 0x0004 ++#define W83781D_ALARM_IN3 0x0008 ++#define W83781D_ALARM_IN4 0x0100 ++#define W83781D_ALARM_IN5 0x0200 ++#define W83781D_ALARM_IN6 0x0400 ++#define W83782D_ALARM_IN7 0x10000 ++#define W83782D_ALARM_IN8 0x20000 ++#define W83781D_ALARM_FAN1 0x0040 ++#define W83781D_ALARM_FAN2 0x0080 ++#define W83781D_ALARM_FAN3 0x0800 ++#define W83781D_ALARM_TEMP1 0x0010 ++#define W83781D_ALARM_TEMP23 0x0020 /* 781D only */ ++#define W83781D_ALARM_TEMP2 0x0020 /* 782D/783S */ ++#define W83781D_ALARM_TEMP3 0x2000 /* 782D only */ ++#define W83781D_ALARM_CHAS 0x1000 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected chip. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++ ++/* just a guess - no datasheet */ ++static ctl_table as99127f_dir_table_template[] = { ++ {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp}, ++ {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp_add}, ++ {W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp_add}, ++ {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_vid}, ++ {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_vrm}, ++ {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan_div}, ++ {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_alarms}, ++ {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_beep}, ++ {0} ++}; ++ ++static ctl_table w83781d_dir_table_template[] = { ++ {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp}, ++ {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp_add}, ++ {W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp_add}, ++ {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_vid}, ++ {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_vrm}, ++ {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan_div}, ++ {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_alarms}, ++ {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_beep}, ++#ifdef W83781D_RT ++ {W83781D_SYSCTL_RT1, "rt1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_rt}, ++ {W83781D_SYSCTL_RT2, "rt2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_rt}, ++ {W83781D_SYSCTL_RT3, "rt3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_rt}, ++#endif ++ {0} ++}; ++ ++/* without pwm3-4 */ ++static ctl_table w83782d_isa_dir_table_template[] = { ++ {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp}, ++ {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp_add}, ++ {W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp_add}, ++ {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_vid}, ++ {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_vrm}, ++ {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan_div}, ++ {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_alarms}, ++ {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_beep}, ++ {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_sens}, ++ {W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_sens}, ++ {W83781D_SYSCTL_SENS3, "sensor3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_sens}, ++ {0} ++}; ++ ++/* with pwm3-4 */ ++static ctl_table w83782d_i2c_dir_table_template[] = { ++ {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp}, ++ {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp_add}, ++ {W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp_add}, ++ {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_vid}, ++ {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_vrm}, ++ {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan_div}, ++ {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_alarms}, ++ {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_beep}, ++ {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_PWM4, "pwm4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_sens}, ++ {W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_sens}, ++ {W83781D_SYSCTL_SENS3, "sensor3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_sens}, ++ {0} ++}; ++ ++/* w83791D has 10 voltages 5 fans and 3 temps. 2 of the temps are on other ++ devices. */ ++static ctl_table w83791d_dir_table_template[] = { ++ {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN9, "in9", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN4, "fan4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN5, "fan5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp}, ++ {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp_add}, ++ {W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp_add}, ++ {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_vid}, ++ {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan_div}, ++ {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_alarms}, ++ {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_beep}, ++ {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_PWM4, "pwm4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_vrm}, ++ {0} ++}; ++ ++static ctl_table w83783s_dir_table_template[] = { ++ {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ /* no in1 to maintain compatibility with 781d and 782d. */ ++ {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp}, ++ {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp_add}, ++ {W83781D_SYSCTL_VID, "vid", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_vid}, ++ {W83781D_SYSCTL_VRM, "vrm", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_vrm}, ++ {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan_div}, ++ {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_alarms}, ++ {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_beep}, ++ {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_sens}, ++ {W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_sens}, ++ {0} ++}; ++ ++/* similar to w83782d but no fan3, no vid */ ++static ctl_table w83697hf_dir_table_template[] = { ++ {W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ /* no in1 to maintain compatibility with 781d and 782d. */ ++ {W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_in}, ++ {W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan}, ++ {W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp}, ++ {W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_temp_add}, ++ {W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_fan_div}, ++ {W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_alarms}, ++ {W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_beep}, ++ {W83781D_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_pwm}, ++ {W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_sens}, ++ {W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &w83781d_sens}, ++ {0} ++}; ++ ++ ++/* This function is called when: ++ * w83781d_driver is inserted (when this module is loaded), for each ++ available adapter ++ * when a new adapter is inserted (and w83781d_driver is still present) */ ++static int w83781d_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, w83781d_detect); ++} ++ ++static int w83781d_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i, val1 = 0, val2, id; ++ struct i2c_client *new_client; ++ struct w83781d_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ int is_isa = i2c_is_isa_adapter(adapter); ++ enum vendor { winbond, asus } vendid; ++ ++ if (!is_isa ++ && !i2c_check_functionality(adapter, ++ I2C_FUNC_SMBUS_BYTE_DATA)) goto ++ ERROR0; ++ ++ if (is_isa) { ++ if (!request_region(address, W83781D_EXTENT, "w83781d")) ++ goto ERROR0; ++ release_region(address, W83781D_EXTENT); ++ } ++ ++ /* Probe whether there is anything available on this address. Already ++ done for SMBus clients */ ++ if (kind < 0) { ++ if (is_isa) { ++ ++#define REALLY_SLOW_IO ++ /* We need the timeouts for at least some LM78-like chips. But only ++ if we read 'undefined' registers. */ ++ i = inb_p(address + 1); ++ if (inb_p(address + 2) != i) ++ goto ERROR0; ++ if (inb_p(address + 3) != i) ++ goto ERROR0; ++ if (inb_p(address + 7) != i) ++ goto ERROR0; ++#undef REALLY_SLOW_IO ++ ++ /* Let's just hope nothing breaks here */ ++ i = inb_p(address + 5) & 0x7f; ++ outb_p(~i & 0x7f, address + 5); ++ if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) { ++ outb_p(i, address + 5); ++ return 0; ++ } ++ } ++ } ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access w83781d_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct w83781d_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ init_MUTEX(&data->lock); ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &w83781d_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ ++ /* The w8378?d may be stuck in some other bank than bank 0. This may ++ make reading other information impossible. Specify a force=... or ++ force_*=... parameter, and the Winbond will be reset to the right ++ bank. */ ++ if (kind < 0) { ++ if (w83781d_read_value(new_client, W83781D_REG_CONFIG) & ++ 0x80) { ++ err = -ENODEV; ++ goto ERROR1; ++ } ++ val1 = w83781d_read_value(new_client, W83781D_REG_BANK); ++ val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN); ++ /* Check for Winbond or Asus ID if in bank 0 */ ++ if ((!(val1 & 0x07)) && ++ (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3)) ++ || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) { ++ err = -ENODEV; ++ goto ERROR1; ++ } ++ /* If Winbond SMBus, check address at 0x48. ++ Asus doesn't support, except for the as99127f rev.2 */ ++ if ((!is_isa) && (((!(val1 & 0x80)) && (val2 == 0xa3)) || ++ ((val1 & 0x80) && (val2 == 0x5c)))) { ++ if (w83781d_read_value ++ (new_client, W83781D_REG_I2C_ADDR) != address) { ++ err = -ENODEV; ++ goto ERROR1; ++ } ++ } ++ } ++ ++ /* We have either had a force parameter, or we have already detected the ++ Winbond. Put it now into bank 0 and Vendor ID High Byte */ ++ w83781d_write_value(new_client, W83781D_REG_BANK, ++ (w83781d_read_value(new_client, ++ W83781D_REG_BANK) & 0x78) | ++ 0x80); ++ ++ /* Determine the chip type. */ ++ if (kind <= 0) { ++ /* get vendor ID */ ++ val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN); ++ if (val2 == 0x5c) ++ vendid = winbond; ++ else if (val2 == 0x12) ++ vendid = asus; ++ else { ++ err = -ENODEV; ++ goto ERROR1; ++ } ++ val1 = ++ w83781d_read_value(new_client, W83781D_REG_WCHIPID); ++ if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond) ++ kind = w83781d; ++ else if (val1 == 0x30 && vendid == winbond) ++ kind = w83782d; ++ else if (val1 == 0x40 && vendid == winbond && !is_isa && address == 0x2d) ++ kind = w83783s; ++ else if (val1 == 0x21 && vendid == winbond) ++ kind = w83627hf; ++ else if (val1 == 0x71 && vendid == winbond && address >= 0x2c) ++ kind = w83791d; ++ else if (val1 == 0x31 && !is_isa && address >= 0x28) ++ kind = as99127f; ++ else if (val1 == 0x60 && vendid == winbond && is_isa) ++ kind = w83697hf; ++ else { ++ if (kind == 0) ++ printk ++ (KERN_WARNING "w83781d.o: Ignoring 'force' parameter for unknown chip at" ++ "adapter %d, address 0x%02x\n", ++ i2c_adapter_id(adapter), address); ++ err = -EINVAL; ++ goto ERROR1; ++ } ++ } ++ ++ if (kind == w83781d) { ++ type_name = "w83781d"; ++ client_name = "W83781D chip"; ++ } else if (kind == w83782d) { ++ type_name = "w83782d"; ++ client_name = "W83782D chip"; ++ } else if (kind == w83783s) { ++ type_name = "w83783s"; ++ client_name = "W83783S chip"; ++ } else if (kind == w83627hf) { ++ type_name = "w83627hf"; ++ client_name = "W83627HF chip"; ++ } else if (kind == as99127f) { ++ type_name = "as99127f"; ++ client_name = "AS99127F chip"; ++ } else if (kind == w83697hf) { ++ type_name = "w83697hf"; ++ client_name = "W83697HF chip"; ++ } else if (kind == w83791d) { ++ type_name = "w83791d"; ++ client_name = "W83791D chip"; ++ } else { ++#ifdef DEBUG ++ printk(KERN_ERR "w83781d.o: Internal error: unknown kind (%d)?!?", ++ kind); ++#endif ++ err = -ENODEV; ++ goto ERROR1; ++ } ++ ++ /* Reserve the ISA region */ ++ if (is_isa) ++ request_region(address, W83781D_EXTENT, type_name); ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ data->type = kind; ++ ++ new_client->id = w83781d_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto ERROR3; ++ ++ /* attach secondary i2c lm75-like clients */ ++ if (!is_isa) { ++ if (!(data->lm75 = kmalloc(2 * sizeof(struct i2c_client), ++ GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto ERROR4; ++ } ++ id = i2c_adapter_id(adapter); ++ if(force_subclients[0] == id && force_subclients[1] == address) { ++ for(i = 2; i <= 3; i++) { ++ if(force_subclients[i] < 0x48 || ++ force_subclients[i] > 0x4f) { ++ printk(KERN_ERR "w83781d.o: Invalid subclient address %d; must be 0x48-0x4f\n", ++ force_subclients[i]); ++ err = -EINVAL; ++ goto ERROR5; ++ } ++ } ++ w83781d_write_value(new_client, ++ W83781D_REG_I2C_SUBADDR, ++ (force_subclients[2] & 0x07) | ++ ((force_subclients[3] & 0x07) <<4)); ++ data->lm75[0].addr = force_subclients[2]; ++ } else { ++ val1 = w83781d_read_value(new_client, ++ W83781D_REG_I2C_SUBADDR); ++ data->lm75[0].addr = 0x48 + (val1 & 0x07); ++ } ++ if (kind != w83783s) { ++ if(force_subclients[0] == id && ++ force_subclients[1] == address) { ++ data->lm75[1].addr = force_subclients[3]; ++ } else { ++ data->lm75[1].addr = 0x48 + ((val1 >> 4) & 0x07); ++ } ++ if(data->lm75[0].addr == data->lm75[1].addr) { ++ printk(KERN_ERR "w83781d.o: Duplicate addresses 0x%x for subclients.\n", ++ data->lm75[0].addr); ++ err = -EBUSY; ++ goto ERROR5; ++ } ++ } ++ if (kind == w83781d) ++ client_name = "W83781D subclient"; ++ else if (kind == w83782d) ++ client_name = "W83782D subclient"; ++ else if (kind == w83783s) ++ client_name = "W83783S subclient"; ++ else if (kind == w83627hf) ++ client_name = "W83627HF subclient"; ++ else if (kind == as99127f) ++ client_name = "AS99127F subclient"; ++ else if (kind == w83791d) ++ client_name = "W83791D subclient"; ++ ++ ++ for (i = 0; i <= 1; i++) { ++ data->lm75[i].data = NULL; /* store all data in w83781d */ ++ data->lm75[i].adapter = adapter; ++ data->lm75[i].driver = &w83781d_driver; ++ data->lm75[i].flags = 0; ++ strcpy(data->lm75[i].name, client_name); ++ data->lm75[i].id = w83781d_id++; ++ if ((err = i2c_attach_client(&(data->lm75[i])))) { ++ printk(KERN_ERR "w83781d.o: Subclient %d registration at address 0x%x failed.\n", ++ i, data->lm75[i].addr); ++ if (i == 1) ++ goto ERROR6; ++ goto ERROR5; ++ } ++ if (kind == w83783s) ++ break; ++ } ++ } else { ++ data->lm75 = NULL; ++ } ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, ++ type_name, ++ (kind == as99127f) ? ++ as99127f_dir_table_template : ++ (kind == w83781d) ? ++ w83781d_dir_table_template : ++ (kind == w83783s) ? ++ w83783s_dir_table_template : ++ (kind == w83697hf) ? ++ w83697hf_dir_table_template : ++ (kind == w83791d ) ? ++ w83791d_dir_table_template : ++ (is_isa || kind == w83627hf) ? ++ w83782d_isa_dir_table_template : ++ w83782d_i2c_dir_table_template)) < 0) { ++ err = i; ++ goto ERROR7; ++ } ++ data->sysctl_id = i; ++ ++ /* Only PWM2 can be disabled */ ++ for(i = 0; i < 4; i++) ++ data->pwmenable[i] = 1; ++ ++ /* Initialize the chip */ ++ w83781d_init_client(new_client); ++ return 0; ++ ++/* OK, this is not exactly good programming practice, usually. But it is ++ very code-efficient in this case. */ ++ ++ ERROR7: ++ if (!is_isa) ++ i2c_detach_client(& ++ (((struct ++ w83781d_data *) (new_client->data))-> ++ lm75[1])); ++ ERROR6: ++ if (!is_isa) ++ i2c_detach_client(& ++ (((struct ++ w83781d_data *) (new_client->data))-> ++ lm75[0])); ++ ERROR5: ++ if (!is_isa) ++ kfree(((struct w83781d_data *) (new_client->data))->lm75); ++ ERROR4: ++ i2c_detach_client(new_client); ++ ERROR3: ++ if (is_isa) ++ release_region(address, W83781D_EXTENT); ++ ERROR1: ++ kfree(data); ++ ERROR0: ++ return err; ++} ++ ++static int w83781d_detach_client(struct i2c_client *client) ++{ ++ int err; ++ struct w83781d_data *data = client->data; ++ ++ i2c_deregister_entry(data->sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ (KERN_ERR "w83781d.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ if(i2c_is_isa_client(client)) { ++ release_region(client->addr, W83781D_EXTENT); ++ } else { ++ i2c_detach_client(&(data->lm75[0])); ++ if (data->type != w83783s) ++ i2c_detach_client(&(data->lm75[1])); ++ kfree(data->lm75); ++ } ++ kfree(data); ++ ++ return 0; ++} ++ ++/* The SMBus locks itself, usually, but nothing may access the Winbond between ++ bank switches. ISA access must always be locked explicitly! ++ We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, ++ would slow down the W83781D access and should not be necessary. ++ There are some ugly typecasts here, but the good news is - they should ++ nowhere else be necessary! */ ++static int w83781d_read_value(struct i2c_client *client, u16 reg) ++{ ++ int res, word_sized, bank; ++ struct i2c_client *cl; ++ ++ down(&(((struct w83781d_data *) (client->data))->lock)); ++ if (i2c_is_isa_client(client)) { ++ word_sized = (((reg & 0xff00) == 0x100) ++ || ((reg & 0xff00) == 0x200)) ++ && (((reg & 0x00ff) == 0x50) ++ || ((reg & 0x00ff) == 0x53) ++ || ((reg & 0x00ff) == 0x55)); ++ if (reg & 0xff00) { ++ outb_p(W83781D_REG_BANK, ++ client->addr + W83781D_ADDR_REG_OFFSET); ++ outb_p(reg >> 8, ++ client->addr + W83781D_DATA_REG_OFFSET); ++ } ++ outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET); ++ res = inb_p(client->addr + W83781D_DATA_REG_OFFSET); ++ if (word_sized) { ++ outb_p((reg & 0xff) + 1, ++ client->addr + W83781D_ADDR_REG_OFFSET); ++ res = ++ (res << 8) + inb_p(client->addr + ++ W83781D_DATA_REG_OFFSET); ++ } ++ if (reg & 0xff00) { ++ outb_p(W83781D_REG_BANK, ++ client->addr + W83781D_ADDR_REG_OFFSET); ++ outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); ++ } ++ } else { ++ bank = (reg >> 8) & 0x0f; ++ if (bank > 2) ++ /* switch banks */ ++ i2c_smbus_write_byte_data(client, W83781D_REG_BANK, ++ bank); ++ if (bank == 0 || bank > 2) { ++ res = i2c_smbus_read_byte_data(client, reg & 0xff); ++ } else { ++ /* switch to subclient */ ++ cl = ++ &(((struct w83781d_data *) (client->data))-> ++ lm75[bank - 1]); ++ /* convert from ISA to LM75 I2C addresses */ ++ switch (reg & 0xff) { ++ case 0x50: /* TEMP */ ++ res = swab16(i2c_smbus_read_word_data(cl, 0)); ++ break; ++ case 0x52: /* CONFIG */ ++ res = i2c_smbus_read_byte_data(cl, 1); ++ break; ++ case 0x53: /* HYST */ ++ res = swab16(i2c_smbus_read_word_data(cl, 2)); ++ break; ++ case 0x55: /* OVER */ ++ default: ++ res = swab16(i2c_smbus_read_word_data(cl, 3)); ++ break; ++ } ++ } ++ if (bank > 2) ++ i2c_smbus_write_byte_data(client, W83781D_REG_BANK, ++ 0); ++ } ++ up(&(((struct w83781d_data *) (client->data))->lock)); ++ return res; ++} ++ ++static int w83781d_write_value(struct i2c_client *client, u16 reg, u16 value) ++{ ++ int word_sized, bank; ++ struct i2c_client *cl; ++ ++ down(&(((struct w83781d_data *) (client->data))->lock)); ++ if (i2c_is_isa_client(client)) { ++ word_sized = (((reg & 0xff00) == 0x100) ++ || ((reg & 0xff00) == 0x200)) ++ && (((reg & 0x00ff) == 0x53) ++ || ((reg & 0x00ff) == 0x55)); ++ if (reg & 0xff00) { ++ outb_p(W83781D_REG_BANK, ++ client->addr + W83781D_ADDR_REG_OFFSET); ++ outb_p(reg >> 8, ++ client->addr + W83781D_DATA_REG_OFFSET); ++ } ++ outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET); ++ if (word_sized) { ++ outb_p(value >> 8, ++ client->addr + W83781D_DATA_REG_OFFSET); ++ outb_p((reg & 0xff) + 1, ++ client->addr + W83781D_ADDR_REG_OFFSET); ++ } ++ outb_p(value & 0xff, ++ client->addr + W83781D_DATA_REG_OFFSET); ++ if (reg & 0xff00) { ++ outb_p(W83781D_REG_BANK, ++ client->addr + W83781D_ADDR_REG_OFFSET); ++ outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); ++ } ++ } else { ++ bank = (reg >> 8) & 0x0f; ++ if (bank > 2) ++ /* switch banks */ ++ i2c_smbus_write_byte_data(client, W83781D_REG_BANK, ++ bank); ++ if (bank == 0 || bank > 2) { ++ i2c_smbus_write_byte_data(client, reg & 0xff, ++ value & 0xff); ++ } else { ++ /* switch to subclient */ ++ cl = &(((struct w83781d_data *) (client->data))-> ++ lm75[bank - 1]); ++ /* convert from ISA to LM75 I2C addresses */ ++ switch (reg & 0xff) { ++ case 0x52: /* CONFIG */ ++ i2c_smbus_write_byte_data(cl, 1, value & 0xff); ++ break; ++ case 0x53: /* HYST */ ++ i2c_smbus_write_word_data(cl, 2, swab16(value)); ++ break; ++ case 0x55: /* OVER */ ++ i2c_smbus_write_word_data(cl, 3, swab16(value)); ++ break; ++ } ++ } ++ if (bank > 2) ++ i2c_smbus_write_byte_data(client, W83781D_REG_BANK, ++ 0); ++ } ++ up(&(((struct w83781d_data *) (client->data))->lock)); ++ return 0; ++} ++ ++/* Called when we have found a new W83781D. It should set limits, etc. */ ++static void w83781d_init_client(struct i2c_client *client) ++{ ++ struct w83781d_data *data = client->data; ++ int i, p; ++ int type = data->type; ++ u8 tmp; ++ ++ if(init && type != as99127f) { /* this resets registers we don't have ++ documentation for on the as99127f */ ++ /* save these registers */ ++ i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); ++ p = w83781d_read_value(client, W83781D_REG_PWMCLK12); ++ /* Reset all except Watchdog values and last conversion values ++ This sets fan-divs to 2, among others */ ++ w83781d_write_value(client, W83781D_REG_CONFIG, 0x80); ++ /* Restore the registers and disable power-on abnormal beep. ++ This saves FAN 1/2/3 input/output values set by BIOS. */ ++ w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80); ++ w83781d_write_value(client, W83781D_REG_PWMCLK12, p); ++ /* Disable master beep-enable (reset turns it on). ++ Individual beeps should be reset to off but for some reason ++ disabling this bit helps some people not get beeped */ ++ w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0); ++ } ++ ++ data->vrm = (type == w83791d) ? 90 : 82; ++ ++ if ((type != w83781d) && (type != as99127f)) { ++ tmp = w83781d_read_value(client, W83781D_REG_SCFG1); ++ for (i = 1; i <= 3; i++) { ++ if (!(tmp & BIT_SCFG1[i - 1])) { ++ data->sens[i - 1] = W83781D_DEFAULT_BETA; ++ } else { ++ if (w83781d_read_value ++ (client, ++ W83781D_REG_SCFG2) & BIT_SCFG2[i - 1]) ++ data->sens[i - 1] = 1; ++ else ++ data->sens[i - 1] = 2; ++ } ++ if ((type == w83783s || type == w83697hf) && (i == 2)) ++ break; ++ } ++ } ++#ifdef W83781D_RT ++/* ++ Fill up the RT Tables. ++ We assume that they are 32 bytes long, in order for temp 1-3. ++ Data sheet documentation is sparse. ++ We also assume that it is only for the 781D although I suspect ++ that the others support it as well.... ++*/ ++ ++ if (init && type == w83781d) { ++ u16 k = 0; ++/* ++ Auto-indexing doesn't seem to work... ++ w83781d_write_value(client,W83781D_REG_RT_IDX,0); ++*/ ++ for (i = 0; i < 3; i++) { ++ int j; ++ for (j = 0; j < 32; j++) { ++ w83781d_write_value(client, ++ W83781D_REG_RT_IDX, ++ k++); ++ data->rt[i][j] = ++ w83781d_read_value(client, ++ W83781D_REG_RT_VAL); ++ } ++ } ++ } ++#endif /* W83781D_RT */ ++ ++ if(init) { ++ w83781d_write_value(client, W83781D_REG_TEMP2_CONFIG, 0x00); ++ if (type != w83783s && type != w83697hf) { ++ w83781d_write_value(client, W83781D_REG_TEMP3_CONFIG, ++ 0x00); ++ } ++ if (type != w83781d) { ++ /* enable comparator mode for temp2 and temp3 so ++ alarm indication will work correctly */ ++ i = w83781d_read_value(client, W83781D_REG_IRQ); ++ if (!(i & 0x40)) ++ w83781d_write_value(client, W83781D_REG_IRQ, ++ i | 0x40); ++ } ++ } ++ ++ /* Start monitoring */ ++ w83781d_write_value(client, W83781D_REG_CONFIG, ++ (w83781d_read_value(client, ++ W83781D_REG_CONFIG) & 0xf7) ++ | 0x01); ++} ++ ++static void w83781d_update_client(struct i2c_client *client) ++{ ++ struct w83781d_data *data = client->data; ++ int i; ++ ++ down(&data->update_lock); ++ ++ if (time_after(jiffies - data->last_updated, HZ + HZ / 2) || ++ time_before(jiffies, data->last_updated) || !data->valid) { ++ pr_debug(KERN_DEBUG "Starting device update\n"); ++ ++ for (i = 0; i <= 9; i++) { ++ if ((data->type == w83783s || data->type == w83697hf) ++ && (i == 1)) ++ continue; /* 783S has no in1 */ ++ if (data->type == w83791d) { ++ data->in[i] = ++ w83781d_read_value(client, W83791D_REG_IN(i)); ++ data->in_min[i] = ++ w83781d_read_value(client, ++ W83791D_REG_IN_MIN(i)); ++ data->in_max[i] = ++ w83781d_read_value(client, ++ W83791D_REG_IN_MAX(i)); ++ } else { ++ data->in[i] = ++ w83781d_read_value(client, W83781D_REG_IN(i)); ++ data->in_min[i] = ++ w83781d_read_value(client, ++ W83781D_REG_IN_MIN(i)); ++ data->in_max[i] = ++ w83781d_read_value(client, ++ W83781D_REG_IN_MAX(i)); ++ } ++ if ((data->type != w83782d) && (data->type != w83697hf) ++ && (data->type != w83627hf) && (i == 6) ++ && (data->type != w83791d)) ++ break; ++ ++ if (data->type != w83791d && i == 8) ++ break; ++ } ++ for (i = 1; i <= 5; i++) { ++ data->fan[i - 1] = ++ w83781d_read_value(client, W83781D_REG_FAN(i)); ++ data->fan_min[i - 1] = ++ w83781d_read_value(client, ++ W83781D_REG_FAN_MIN(i)); ++ if (data->type != w83791d && i == 3) break; ++ } ++ if (data->type != w83781d && data->type != as99127f) { ++ for (i = 1; i <= 4; i++) { ++ data->pwm[i - 1] = ++ w83781d_read_value(client, ++ W83781D_REG_PWM(data->type, i)); ++ if (((data->type == w83783s) ++ || (data->type == w83627hf) ++ || (data->type == w83697hf) ++ || ((data->type == w83782d) ++ && i2c_is_isa_client(client))) ++ && i == 2) ++ break; ++ } ++ /* Only PWM2 can be disabled */ ++ data->pwmenable[1] = (w83781d_read_value(client, ++ W83781D_REG_PWMCLK12) & 0x08) >> 3; ++ } ++ ++ data->temp = w83781d_read_value(client, W83781D_REG_TEMP); ++ data->temp_over = ++ w83781d_read_value(client, W83781D_REG_TEMP_OVER); ++ data->temp_hyst = ++ w83781d_read_value(client, W83781D_REG_TEMP_HYST); ++ data->temp_add[0] = ++ w83781d_read_value(client, W83781D_REG_TEMP2); ++ data->temp_add_over[0] = ++ w83781d_read_value(client, W83781D_REG_TEMP2_OVER); ++ data->temp_add_hyst[0] = ++ w83781d_read_value(client, W83781D_REG_TEMP2_HYST); ++ if (data->type != w83783s && data->type != w83697hf) { ++ data->temp_add[1] = ++ w83781d_read_value(client, W83781D_REG_TEMP3); ++ data->temp_add_over[1] = ++ w83781d_read_value(client, W83781D_REG_TEMP3_OVER); ++ data->temp_add_hyst[1] = ++ w83781d_read_value(client, W83781D_REG_TEMP3_HYST); ++ } ++ i = w83781d_read_value(client, W83781D_REG_VID_FANDIV); ++ if (data->type != w83697hf) { ++ data->vid = i & 0x0f; ++ data->vid |= ++ (w83781d_read_value(client, W83781D_REG_CHIPID) & 0x01) ++ << 4; ++ } ++ data->fan_div[0] = (i >> 4) & 0x03; ++ data->fan_div[1] = (i >> 6) & 0x03; ++ if (data->type != w83697hf) { ++ data->fan_div[2] = (w83781d_read_value(client, ++ W83781D_REG_PIN) >> 6) & 0x03; ++ } ++ if ((data->type != w83781d) && (data->type != as99127f)) { ++ i = w83781d_read_value(client, W83781D_REG_VBAT); ++ data->fan_div[0] |= (i >> 3) & 0x04; ++ data->fan_div[1] |= (i >> 4) & 0x04; ++ if (data->type != w83697hf) ++ data->fan_div[2] |= (i >> 5) & 0x04; ++ } ++ data->alarms = ++ w83781d_read_value(client, ++ W83781D_REG_ALARM1) + ++ (w83781d_read_value(client, W83781D_REG_ALARM2) << 8); ++ if ((data->type == w83782d) || (data->type == w83627hf) || ++ (data->type == w83697hf)) { ++ data->alarms |= ++ w83781d_read_value(client, ++ W83781D_REG_ALARM3) << 16; ++ } ++ i = w83781d_read_value(client, W83781D_REG_BEEP_INTS2); ++ data->beep_enable = i >> 7; ++ data->beeps = ((i & 0x7f) << 8) + ++ w83781d_read_value(client, W83781D_REG_BEEP_INTS1); ++ if ((data->type != w83781d) && (data->type != as99127f) ++ && (data->type != w83791d)) { ++ data->beeps |= ++ w83781d_read_value(client, ++ W83781D_REG_BEEP_INTS3) << 16; ++ } ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++ ++/* The next few functions are the call-back functions of the /proc/sys and ++ sysctl files. Which function is used is defined in the ctl_table in ++ the extra1 field. ++ Each function must return the magnitude (power of 10 to divide the date ++ with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must ++ put a maximum of *nrels elements in results reflecting the data of this ++ file, and set *nrels to the number it actually put in it, if operation== ++ SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from ++ results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE. ++ Note that on SENSORS_PROC_REAL_READ, I do not check whether results is ++ large enough (by checking the incoming value of *nrels). This is not very ++ good practice, but as long as you put less than about 5 values in results, ++ you can assume it is large enough. */ ++static void w83781d_in(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83781d_data *data = client->data; ++ int nr = ctl_name - W83781D_SYSCTL_IN0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 2; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83781d_update_client(client); ++ results[0] = IN_FROM_REG(data->in_min[nr]); ++ results[1] = IN_FROM_REG(data->in_max[nr]); ++ results[2] = IN_FROM_REG(data->in[nr]); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->in_min[nr] = IN_TO_REG(results[0]); ++ w83781d_write_value(client, W83781D_REG_IN_MIN(nr), ++ data->in_min[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ data->in_max[nr] = IN_TO_REG(results[1]); ++ w83781d_write_value(client, W83781D_REG_IN_MAX(nr), ++ data->in_max[nr]); ++ } ++ } ++} ++ ++void w83781d_fan(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83781d_data *data = client->data; ++ int nr = ctl_name - W83781D_SYSCTL_FAN1 + 1; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83781d_update_client(client); ++ results[0] = FAN_FROM_REG(data->fan_min[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ results[1] = FAN_FROM_REG(data->fan[nr - 1], ++ DIV_FROM_REG(data->fan_div[nr - 1])); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->fan_min[nr - 1] = ++ FAN_TO_REG(results[0], ++ DIV_FROM_REG(data->fan_div[nr-1])); ++ w83781d_write_value(client, ++ W83781D_REG_FAN_MIN(nr), ++ data->fan_min[nr - 1]); ++ } ++ } ++} ++ ++void w83781d_temp(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83781d_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83781d_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_over); ++ results[1] = TEMP_FROM_REG(data->temp_hyst); ++ results[2] = TEMP_FROM_REG(data->temp); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->temp_over = TEMP_TO_REG(results[0]); ++ w83781d_write_value(client, W83781D_REG_TEMP_OVER, ++ data->temp_over); ++ } ++ if (*nrels_mag >= 2) { ++ data->temp_hyst = TEMP_TO_REG(results[1]); ++ w83781d_write_value(client, W83781D_REG_TEMP_HYST, ++ data->temp_hyst); ++ } ++ } ++} ++ ++void w83781d_temp_add(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct w83781d_data *data = client->data; ++ int nr = ctl_name - W83781D_SYSCTL_TEMP2; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83781d_update_client(client); ++ if (data->type == as99127f) { ++ results[0] = ++ AS99127_TEMP_ADD_FROM_REG(data-> ++ temp_add_over[nr]); ++ results[1] = ++ AS99127_TEMP_ADD_FROM_REG(data-> ++ temp_add_hyst[nr]); ++ results[2] = ++ AS99127_TEMP_ADD_FROM_REG(data->temp_add[nr]); ++ } else { ++ results[0] = ++ LM75_TEMP_FROM_REG(data->temp_add_over[nr]); ++ results[1] = ++ LM75_TEMP_FROM_REG(data->temp_add_hyst[nr]); ++ results[2] = LM75_TEMP_FROM_REG(data->temp_add[nr]); ++ } ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ if (data->type == as99127f) ++ data->temp_add_over[nr] = ++ AS99127_TEMP_ADD_TO_REG(results[0]); ++ else ++ data->temp_add_over[nr] = ++ LM75_TEMP_TO_REG(results[0]); ++ w83781d_write_value(client, ++ nr ? W83781D_REG_TEMP3_OVER : ++ W83781D_REG_TEMP2_OVER, ++ data->temp_add_over[nr]); ++ } ++ if (*nrels_mag >= 2) { ++ if (data->type == as99127f) ++ data->temp_add_hyst[nr] = ++ AS99127_TEMP_ADD_TO_REG(results[1]); ++ else ++ data->temp_add_hyst[nr] = ++ LM75_TEMP_TO_REG(results[1]); ++ w83781d_write_value(client, ++ nr ? W83781D_REG_TEMP3_HYST : ++ W83781D_REG_TEMP2_HYST, ++ data->temp_add_hyst[nr]); ++ } ++ } ++} ++ ++ ++void w83781d_vid(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83781d_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 3; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83781d_update_client(client); ++ results[0] = vid_from_reg(data->vid, data->vrm); ++ *nrels_mag = 1; ++ } ++} ++ ++void w83781d_vrm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83781d_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 1; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->vrm; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) ++ data->vrm = results[0]; ++ } ++} ++ ++void w83781d_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83781d_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83781d_update_client(client); ++ results[0] = ALARMS_FROM_REG(data->alarms); ++ *nrels_mag = 1; ++ } ++} ++ ++void w83781d_beep(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83781d_data *data = client->data; ++ int val; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83781d_update_client(client); ++ results[0] = BEEP_ENABLE_FROM_REG(data->beep_enable); ++ results[1] = BEEPS_FROM_REG(data->beeps, data->type); ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 2) { ++ data->beeps = BEEPS_TO_REG(results[1], data->type); ++ w83781d_write_value(client, W83781D_REG_BEEP_INTS1, ++ data->beeps & 0xff); ++ if ((data->type != w83781d) && ++ (data->type != as99127f)) { ++ w83781d_write_value(client, ++ W83781D_REG_BEEP_INTS3, ++ ((data-> beeps) >> 16) & ++ 0xff); ++ } ++ val = (data->beeps >> 8) & 0x7f; ++ } else if (*nrels_mag >= 1) ++ val = ++ w83781d_read_value(client, ++ W83781D_REG_BEEP_INTS2) & ++ 0x7f; ++ if (*nrels_mag >= 1) { ++ data->beep_enable = BEEP_ENABLE_TO_REG(results[0]); ++ w83781d_write_value(client, W83781D_REG_BEEP_INTS2, ++ val | data->beep_enable << 7); ++ } ++ } ++} ++ ++/* w83697hf only has two fans */ ++void w83781d_fan_div(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct w83781d_data *data = client->data; ++ int old, old2, old3 = 0; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83781d_update_client(client); ++ results[0] = DIV_FROM_REG(data->fan_div[0]); ++ results[1] = DIV_FROM_REG(data->fan_div[1]); ++ if (data->type == w83697hf) { ++ *nrels_mag = 2; ++ } else { ++ results[2] = DIV_FROM_REG(data->fan_div[2]); ++ *nrels_mag = 3; ++ } ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ old = w83781d_read_value(client, W83781D_REG_VID_FANDIV); ++ /* w83781d and as99127f don't have extended divisor bits */ ++ if ((data->type != w83781d) && data->type != as99127f) { ++ old3 = ++ w83781d_read_value(client, W83781D_REG_VBAT); ++ } ++ if (*nrels_mag >= 3 && data->type != w83697hf) { ++ data->fan_div[2] = ++ DIV_TO_REG(results[2], data->type); ++ old2 = w83781d_read_value(client, W83781D_REG_PIN); ++ old2 = ++ (old2 & 0x3f) | ((data->fan_div[2] & 0x03) << 6); ++ w83781d_write_value(client, W83781D_REG_PIN, old2); ++ if ((data->type != w83781d) && ++ (data->type != as99127f)) { ++ old3 = ++ (old3 & 0x7f) | ++ ((data->fan_div[2] & 0x04) << 5); ++ } ++ } ++ if (*nrels_mag >= 2) { ++ data->fan_div[1] = ++ DIV_TO_REG(results[1], data->type); ++ old = ++ (old & 0x3f) | ((data->fan_div[1] & 0x03) << 6); ++ if ((data->type != w83781d) && ++ (data->type != as99127f)) { ++ old3 = ++ (old3 & 0xbf) | ++ ((data->fan_div[1] & 0x04) << 4); ++ } ++ } ++ if (*nrels_mag >= 1) { ++ data->fan_div[0] = ++ DIV_TO_REG(results[0], data->type); ++ old = ++ (old & 0xcf) | ((data->fan_div[0] & 0x03) << 4); ++ w83781d_write_value(client, W83781D_REG_VID_FANDIV, ++ old); ++ if ((data->type != w83781d) && ++ (data->type != as99127f)) { ++ old3 = ++ (old3 & 0xdf) | ++ ((data->fan_div[0] & 0x04) << 3); ++ w83781d_write_value(client, ++ W83781D_REG_VBAT, ++ old3); ++ } ++ } ++ } ++} ++ ++void w83781d_pwm(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83781d_data *data = client->data; ++ int nr = 1 + ctl_name - W83781D_SYSCTL_PWM1; ++ int j, k; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ w83781d_update_client(client); ++ results[0] = PWM_FROM_REG(data->pwm[nr - 1]); ++ results[1] = data->pwmenable[nr - 1]; ++ *nrels_mag = 2; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->pwm[nr - 1] = PWM_TO_REG(results[0]); ++ w83781d_write_value(client, ++ W83781D_REG_PWM(data->type, nr), ++ data->pwm[nr - 1]); ++ } ++ /* only PWM2 can be enabled/disabled */ ++ if (*nrels_mag >= 2 && nr == 2) { ++ j = w83781d_read_value(client, W83781D_REG_PWMCLK12); ++ k = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); ++ if(results[1]) { ++ if(!(j & 0x08)) ++ w83781d_write_value(client, ++ W83781D_REG_PWMCLK12, j | 0x08); ++ if(k & 0x10) ++ w83781d_write_value(client, ++ W83781D_REG_BEEP_CONFIG, k & 0xef); ++ data->pwmenable[1] = 1; ++ } else { ++ if(j & 0x08) ++ w83781d_write_value(client, ++ W83781D_REG_PWMCLK12, j & 0xf7); ++ if(!(k & 0x10)) ++ w83781d_write_value(client, ++ W83781D_REG_BEEP_CONFIG, j | 0x10); ++ data->pwmenable[1] = 0; ++ } ++ } ++ } ++} ++ ++void w83781d_sens(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83781d_data *data = client->data; ++ int nr = 1 + ctl_name - W83781D_SYSCTL_SENS1; ++ u8 tmp; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ results[0] = data->sens[nr - 1]; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ switch (results[0]) { ++ case 1: /* PII/Celeron diode */ ++ tmp = w83781d_read_value(client, ++ W83781D_REG_SCFG1); ++ w83781d_write_value(client, ++ W83781D_REG_SCFG1, ++ tmp | BIT_SCFG1[nr - ++ 1]); ++ tmp = w83781d_read_value(client, ++ W83781D_REG_SCFG2); ++ w83781d_write_value(client, ++ W83781D_REG_SCFG2, ++ tmp | BIT_SCFG2[nr - ++ 1]); ++ data->sens[nr - 1] = results[0]; ++ break; ++ case 2: /* 3904 */ ++ tmp = w83781d_read_value(client, ++ W83781D_REG_SCFG1); ++ w83781d_write_value(client, ++ W83781D_REG_SCFG1, ++ tmp | BIT_SCFG1[nr - ++ 1]); ++ tmp = w83781d_read_value(client, ++ W83781D_REG_SCFG2); ++ w83781d_write_value(client, ++ W83781D_REG_SCFG2, ++ tmp & ~BIT_SCFG2[nr - ++ 1]); ++ data->sens[nr - 1] = results[0]; ++ break; ++ case W83781D_DEFAULT_BETA: /* thermistor */ ++ tmp = w83781d_read_value(client, ++ W83781D_REG_SCFG1); ++ w83781d_write_value(client, ++ W83781D_REG_SCFG1, ++ tmp & ~BIT_SCFG1[nr - ++ 1]); ++ data->sens[nr - 1] = results[0]; ++ break; ++ default: ++ printk ++ (KERN_ERR "w83781d.o: Invalid sensor type %ld; must be 1, 2, or %d\n", ++ results[0], W83781D_DEFAULT_BETA); ++ break; ++ } ++ } ++ } ++} ++ ++#ifdef W83781D_RT ++static void w83781d_rt(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct w83781d_data *data = client->data; ++ int nr = 1 + ctl_name - W83781D_SYSCTL_RT1; ++ int i; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ for (i = 0; i < 32; i++) { ++ results[i] = data->rt[nr - 1][i]; ++ } ++ *nrels_mag = 32; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag > 32) ++ *nrels_mag = 32; ++ for (i = 0; i < *nrels_mag; i++) { ++ /* fixme: no bounds checking 0-255 */ ++ data->rt[nr - 1][i] = results[i]; ++ w83781d_write_value(client, W83781D_REG_RT_IDX, i); ++ w83781d_write_value(client, W83781D_REG_RT_VAL, ++ data->rt[nr - 1][i]); ++ } ++ } ++} ++#endif ++ ++static int __init sm_w83781d_init(void) ++{ ++ printk(KERN_INFO "w83781d.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&w83781d_driver); ++} ++ ++static void __exit sm_w83781d_exit(void) ++{ ++ i2c_del_driver(&w83781d_driver); ++} ++ ++ ++ ++MODULE_AUTHOR("Frodo Looijaard , " ++ "Philip Edelbrock , " ++ "and Mark Studebaker "); ++MODULE_DESCRIPTION("W83781D driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_w83781d_init); ++module_exit(sm_w83781d_exit); +--- linux-old/drivers/sensors/w83l785ts.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/w83l785ts.c Mon Dec 13 20:18:54 2004 +@@ -0,0 +1,388 @@ ++/* ++ * w83l785ts.c - Part of lm_sensors, Linux kernel modules for hardware ++ * monitoring ++ * Copyright (C) 2003-2004 Jean Delvare ++ * ++ * Inspired from the lm83 driver. The W83L785TS-S is a sensor chip made ++ * by Winbond. It reports a single external temperature with a 1 deg ++ * resolution and a 3 deg accuracy. Data sheet can be obtained from ++ * Winbond's website at: ++ * http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83L785TS-S.pdf ++ * ++ * Thanks to James Bolt for benchmarking the read ++ * error handling mechanism. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++#ifndef I2C_DRIVERID_W83L785TS ++#define I2C_DRIVERID_W83L785TS 1047 ++#endif ++ ++/* How many retries on register read error */ ++#define MAX_RETRIES 5 ++ ++/* ++ * Address to scan ++ * Address is fully defined internally and cannot be changed. ++ */ ++ ++static unsigned short normal_i2c[] = { 0x2e, SENSORS_I2C_END }; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* ++ * Insmod parameters ++ */ ++ ++SENSORS_INSMOD_1(w83l785ts); ++ ++/* ++ * The W83L785TS-S registers ++ * Manufacturer ID is 0x5CA3 for Winbond. ++ */ ++ ++#define W83L785TS_REG_MAN_ID1 0x4D ++#define W83L785TS_REG_MAN_ID2 0x4C ++#define W83L785TS_REG_CHIP_ID 0x4E ++#define W83L785TS_REG_CONFIG 0x40 ++#define W83L785TS_REG_TYPE 0x52 ++#define W83L785TS_REG_TEMP 0x27 ++#define W83L785TS_REG_TEMP_OVER 0x53 /* not sure about this one */ ++ ++/* ++ * Conversions ++ * The W83L785TS-S uses signed 8-bit values. ++ */ ++ ++#define TEMP_FROM_REG(val) (val & 0x80 ? val-0x100 : val) ++ ++/* ++ * Functions declaration ++ */ ++ ++static int w83l785ts_attach_adapter(struct i2c_adapter *adapter); ++static int w83l785ts_detect(struct i2c_adapter *adapter, int address, unsigned ++ short flags, int kind); ++static int w83l785ts_detach_client(struct i2c_client *client); ++static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval); ++static void w83l785ts_update_client(struct i2c_client *client); ++static void w83l785ts_temp(struct i2c_client *client, int operation, int ++ ctl_name, int *nrels_mag, long *results); ++ ++/* ++ * Driver data (common to all clients) ++ */ ++ ++static struct i2c_driver w83l785ts_driver = { ++ .owner = THIS_MODULE, ++ .name = "W83L785S-S sensor driver", ++ .id = I2C_DRIVERID_W83L785TS, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = w83l785ts_attach_adapter, ++ .detach_client = w83l785ts_detach_client, ++}; ++ ++/* ++ * Client data (each client gets its own) ++ */ ++ ++struct w83l785ts_data { ++ struct i2c_client client; ++ int sysctl_id; ++ ++ struct semaphore update_lock; ++ char valid; /* zero until following fields are valid */ ++ unsigned long last_updated; /* in jiffies */ ++ ++ /* registers values */ ++ u8 temp, temp_over; ++}; ++ ++/* ++ * Proc entries ++ * These files are created for each detected W83L785TS-S. ++ */ ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define W83L785TS_SYSCTL_TEMP 1200 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++ ++static ctl_table w83l785ts_dir_table_template[] = ++{ ++ {W83L785TS_SYSCTL_TEMP, "temp", NULL, 0, 0444, NULL, ++ &i2c_proc_real, &i2c_sysctl_real, NULL, &w83l785ts_temp}, ++ {0} ++}; ++ ++/* ++ * Internal variables ++ */ ++ ++static int w83l785ts_id = 0; ++ ++/* ++ * Real code ++ */ ++ ++static int w83l785ts_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, w83l785ts_detect); ++} ++ ++/* ++ * The following function does more than just detection. If detection ++ * succeeds, it also registers the new chip. ++ */ ++static int w83l785ts_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ struct i2c_client *new_client; ++ struct w83l785ts_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { ++#ifdef DEBUG ++ printk(KERN_DEBUG "w83l785ts.o: I2C bus doesn't support " ++ "byte read mode, skipping.\n"); ++#endif ++ return 0; ++ } ++ ++ if (!(data = kmalloc(sizeof(struct w83l785ts_data), GFP_KERNEL))) { ++ printk(KERN_ERR "w83l785ts.o: Out of memory in w83l785ts_detect " ++ "(new_client).\n"); ++ return -ENOMEM; ++ } ++ ++ /* ++ * The common I2C client data is placed right after the ++ * W83L785TS-specific. The W83L785TS-specific data is pointed to by the ++ * data field from the I2C client data. ++ */ ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &w83l785ts_driver; ++ new_client->flags = 0; ++ ++ /* ++ * Now we do the remaining detection. A negative kind means that ++ * the driver was loaded with no force parameter (default), so we ++ * must both detect and identify the chip (actually there is only ++ * one possible kind of chip for now, W83L785TS-S). A zero kind means ++ * that the driver was loaded with the force parameter, the detection ++ * step shall be skipped. A positive kind means that the driver ++ * was loaded with the force parameter and a given kind of chip is ++ * requested, so both the detection and the identification steps ++ * are skipped. ++ */ ++ ++ if (kind < 0) { /* detection */ ++ if (((w83l785ts_read_value(new_client, W83L785TS_REG_CONFIG, 0) ++ & 0x80) != 0x00) ++ || ((w83l785ts_read_value(new_client, W83L785TS_REG_TYPE, 0) ++ & 0xFC) != 0x00)) { ++#ifdef DEBUG ++ printk(KERN_DEBUG "w83l785ts.o: Detection failed at " ++ "0x%02x.\n", address); ++#endif ++ goto ERROR1; ++ } ++ } ++ ++ if (kind <= 0) { /* identification */ ++ u16 man_id; ++ u8 chip_id; ++ ++ man_id = (w83l785ts_read_value(new_client, W83L785TS_REG_MAN_ID1, 0) << 8) ++ + w83l785ts_read_value(new_client, W83L785TS_REG_MAN_ID2, 0); ++ chip_id = w83l785ts_read_value(new_client, W83L785TS_REG_CHIP_ID, 0); ++ if (man_id == 0x5CA3) { /* Winbond */ ++ if (chip_id == 0x70) ++ kind = w83l785ts; ++ } ++ } ++ ++ if (kind <= 0) { /* identification failed */ ++ printk(KERN_INFO "w83l785ts.o: Unsupported chip.\n"); ++ goto ERROR1; ++ } ++ ++ if (kind == w83l785ts) { ++ type_name = "w83l785ts"; ++ client_name = "W83L785TS-S chip"; ++ } else { ++ printk(KERN_ERR "w83l785ts.o: Unknown kind %d.\n", kind); ++ goto ERROR1; ++ } ++ ++ /* ++ * OK, we got a valid chip so we can fill in the remaining client ++ * fields. ++ */ ++ ++ strcpy(new_client->name, client_name); ++ new_client->id = w83l785ts_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* ++ * Tell the I2C layer a new client has arrived. ++ */ ++ ++ if ((err = i2c_attach_client(new_client))) { ++#ifdef DEBUG ++ printk(KERN_ERR "w83l785ts.o: Failed attaching client.\n"); ++#endif ++ goto ERROR1; ++ } ++ ++ /* ++ * Register a new directory entry. ++ */ ++ ++ if ((err = i2c_register_entry(new_client, type_name, ++ w83l785ts_dir_table_template)) < 0) { ++#ifdef DEBUG ++ printk(KERN_ERR "w83l785ts.o: Failed registering directory " ++ "entry.\n"); ++#endif ++ goto ERROR2; ++ } ++ data->sysctl_id = err; ++ ++ /* ++ * Initialize the W83L785TS chip ++ * Nothing yet, assume it is already started. ++ */ ++ ++ return 0; ++ ++ ERROR2: ++ i2c_detach_client(new_client); ++ ERROR1: ++ kfree(data); ++ return err; ++} ++ ++static int w83l785ts_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ i2c_deregister_entry(((struct w83l785ts_data *) (client->data))->sysctl_id); ++ if ((err = i2c_detach_client(client))) { ++ printk(KERN_ERR "w83l785ts.o: Client deregistration failed, " ++ "client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ return 0; ++} ++ ++static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval) ++{ ++ int value, i; ++ ++ /* Frequent read errors have been reported on Asus boards, so we ++ * retry on read errors. If it still fails (unlikely), return the ++ * default value requested by the caller. */ ++ for (i = 1; i <= MAX_RETRIES; i++) { ++ value = i2c_smbus_read_byte_data(client, reg); ++ if (value >= 0) ++ return value; ++ printk(KERN_WARNING "w83l785ts.o: Read failed, will retry " ++ "in %d.\n", i); ++ mdelay(i); ++ } ++ ++ printk(KERN_ERR "w83l785ts.o: Couldn't read value from register. " ++ "Please report.\n"); ++ return defval; ++} ++ ++static void w83l785ts_update_client(struct i2c_client *client) ++{ ++ struct w83l785ts_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ * 2) ++ || (jiffies < data->last_updated) ++ || !data->valid) { ++#ifdef DEBUG ++ printk(KERN_DEBUG "w83l785ts.o: Updating data.\n"); ++#endif ++ data->temp = w83l785ts_read_value(client, W83L785TS_REG_TEMP, ++ data->temp); ++ data->temp_over = w83l785ts_read_value(client, ++ W83L785TS_REG_TEMP_OVER, data->temp_over); ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++static void w83l785ts_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct w83l785ts_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) { ++ *nrels_mag = 0; /* magnitude */ ++ } else if (operation == SENSORS_PROC_REAL_READ) { ++ w83l785ts_update_client(client); ++ results[0] = TEMP_FROM_REG(data->temp_over); ++ results[1] = TEMP_FROM_REG(data->temp); ++ *nrels_mag = 2; ++ } ++} ++ ++static int __init sm_w83l785ts_init(void) ++{ ++ printk(KERN_INFO "w83l785ts.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&w83l785ts_driver); ++} ++ ++static void __exit sm_w83l785ts_exit(void) ++{ ++ i2c_del_driver(&w83l785ts_driver); ++} ++ ++MODULE_AUTHOR("Jean Delvare "); ++MODULE_DESCRIPTION("W83L785TS-S sensor driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(sm_w83l785ts_init); ++module_exit(sm_w83l785ts_exit); +--- linux-old/drivers/sensors/xeontemp.c Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/xeontemp.c Mon Dec 13 20:18:54 2004 +@@ -0,0 +1,388 @@ ++/* ++ xeontemp.c - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 1998, 1999,2003 Frodo Looijaard , ++ Philip Edelbrock , and ++ Mark D. Studebaker ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* The Xeon temperature sensor looks just like an ADM1021 with the remote ++ sensor only. There is are no ID registers so detection is difficult. */ ++ ++#include ++#include ++#include ++#include ++#include ++#define LM_DATE "20041007" ++#define LM_VERSION "2.8.8" ++ ++#ifndef I2C_DRIVERID_XEONTEMP ++#define I2C_DRIVERID_XEONTEMP 1045 ++#endif ++ ++/* Addresses to scan */ ++static unsigned short normal_i2c[] = { 0x18, 0x1a, 0x29, 0x2b, ++ 0x4c, 0x4e, SENSORS_I2C_END ++}; ++static unsigned short normal_i2c_range[] = { SENSORS_I2C_END }; ++static unsigned int normal_isa[] = { SENSORS_ISA_END }; ++static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; ++ ++/* Insmod parameters */ ++SENSORS_INSMOD_1(xeontemp); ++ ++/* xeontemp constants specified below */ ++ ++/* The registers */ ++/* Read-only */ ++#define XEONTEMP_REG_REMOTE_TEMP 0x01 ++#define XEONTEMP_REG_STATUS 0x02 ++/* These use different addresses for reading/writing */ ++#define XEONTEMP_REG_CONFIG_R 0x03 ++#define XEONTEMP_REG_CONFIG_W 0x09 ++#define XEONTEMP_REG_CONV_RATE_R 0x04 ++#define XEONTEMP_REG_CONV_RATE_W 0x0A ++/* limits */ ++#define XEONTEMP_REG_REMOTE_TOS_R 0x07 ++#define XEONTEMP_REG_REMOTE_TOS_W 0x0D ++#define XEONTEMP_REG_REMOTE_THYST_R 0x08 ++#define XEONTEMP_REG_REMOTE_THYST_W 0x0E ++/* write-only */ ++#define XEONTEMP_REG_ONESHOT 0x0F ++ ++#define XEONTEMP_ALARM_RTEMP (XEONTEMP_ALARM_RTEMP_HIGH | XEONTEMP_ALARM_RTEMP_LOW\ ++ | XEONTEMP_ALARM_RTEMP_NA) ++#define XEONTEMP_ALARM_ALL XEONTEMP_ALARM_RTEMP ++ ++/* Conversions. Rounding and limit checking is only done on the TO_REG ++ variants. Note that you should be a bit careful with which arguments ++ these macros are called: arguments may be evaluated more than once. ++ Fixing this is just not worth it. */ ++/* Conversions note: 1021 uses normal integer signed-byte format*/ ++#define TEMP_FROM_REG(val) (val > 127 ? val-256 : val) ++#define TEMP_TO_REG(val) (SENSORS_LIMIT((val < 0 ? val+256 : val),0,255)) ++ ++/* Each client has this additional data */ ++struct xeontemp_data { ++ struct i2c_client client; ++ int sysctl_id; ++ enum chips type; ++ ++ struct semaphore update_lock; ++ char valid; /* !=0 if following fields are valid */ ++ unsigned long last_updated; /* In jiffies */ ++ ++ u8 remote_temp, remote_temp_os, remote_temp_hyst, alarms; ++ u8 fail; ++}; ++ ++static int xeontemp_attach_adapter(struct i2c_adapter *adapter); ++static int xeontemp_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind); ++static void xeontemp_init_client(struct i2c_client *client); ++static int xeontemp_detach_client(struct i2c_client *client); ++static int xeontemp_read_value(struct i2c_client *client, u8 reg); ++static int xeontemp_rd_good(u8 *val, struct i2c_client *client, u8 reg, u8 mask); ++static int xeontemp_write_value(struct i2c_client *client, u8 reg, ++ u16 value); ++static void xeontemp_remote_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, ++ long *results); ++static void xeontemp_alarms(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results); ++static void xeontemp_update_client(struct i2c_client *client); ++ ++/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */ ++static int read_only = 0; ++ ++ ++/* This is the driver that will be inserted */ ++static struct i2c_driver xeontemp_driver = { ++ .owner = THIS_MODULE, ++ .name = "Xeon temp sensor driver", ++ .id = I2C_DRIVERID_XEONTEMP, ++ .flags = I2C_DF_NOTIFY, ++ .attach_adapter = xeontemp_attach_adapter, ++ .detach_client = xeontemp_detach_client, ++}; ++ ++/* -- SENSORS SYSCTL START -- */ ++ ++#define XEONTEMP_SYSCTL_REMOTE_TEMP 1201 ++#define XEONTEMP_SYSCTL_ALARMS 1203 ++ ++#define XEONTEMP_ALARM_RTEMP_HIGH 0x10 ++#define XEONTEMP_ALARM_RTEMP_LOW 0x08 ++#define XEONTEMP_ALARM_RTEMP_NA 0x04 ++ ++/* -- SENSORS SYSCTL END -- */ ++ ++/* These files are created for each detected xeontemp. This is just a template; ++ though at first sight, you might think we could use a statically ++ allocated list, we need some way to get back to the parent - which ++ is done through one of the 'extra' fields which are initialized ++ when a new copy is allocated. */ ++static ctl_table xeontemp_dir_table_template[] = { ++ {XEONTEMP_SYSCTL_REMOTE_TEMP, "temp", NULL, 0, 0644, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &xeontemp_remote_temp}, ++ {XEONTEMP_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, ++ &i2c_sysctl_real, NULL, &xeontemp_alarms}, ++ {0} ++}; ++ ++static int xeontemp_id = 0; ++ ++static int xeontemp_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_detect(adapter, &addr_data, xeontemp_detect); ++} ++ ++static int xeontemp_detect(struct i2c_adapter *adapter, int address, ++ unsigned short flags, int kind) ++{ ++ int i; ++ struct i2c_client *new_client; ++ struct xeontemp_data *data; ++ int err = 0; ++ const char *type_name = ""; ++ const char *client_name = ""; ++ ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ++ goto error0; ++ ++ /* OK. For now, we presume we have a valid client. We now create the ++ client structure, even though we cannot fill it completely yet. ++ But it allows us to access xeontemp_{read,write}_value. */ ++ ++ if (!(data = kmalloc(sizeof(struct xeontemp_data), GFP_KERNEL))) { ++ err = -ENOMEM; ++ goto error0; ++ } ++ ++ new_client = &data->client; ++ new_client->addr = address; ++ new_client->data = data; ++ new_client->adapter = adapter; ++ new_client->driver = &xeontemp_driver; ++ new_client->flags = 0; ++ ++ /* Now, we do the remaining detection. */ ++ ++ if (kind < 0) { ++ if ( ++ (xeontemp_read_value(new_client, XEONTEMP_REG_STATUS) & ++ 0x03) != 0x00) ++ goto error1; ++ } ++ ++ /* Determine the chip type. */ ++ ++ if (kind <= 0) { ++ kind = xeontemp; ++ } ++ ++ type_name = "xeontemp"; ++ client_name = "xeon sensors"; ++ ++ /* Fill in the remaining client fields and put it into the global list */ ++ strcpy(new_client->name, client_name); ++ data->type = kind; ++ ++ new_client->id = xeontemp_id++; ++ data->valid = 0; ++ init_MUTEX(&data->update_lock); ++ ++ /* Tell the I2C layer a new client has arrived */ ++ if ((err = i2c_attach_client(new_client))) ++ goto error3; ++ ++ /* Register a new directory entry with module sensors */ ++ if ((i = i2c_register_entry(new_client, type_name, ++ xeontemp_dir_table_template)) < 0) { ++ err = i; ++ goto error4; ++ } ++ data->sysctl_id = i; ++ ++ xeontemp_init_client(new_client); ++ return 0; ++ ++ error4: ++ i2c_detach_client(new_client); ++ error3: ++ error1: ++ kfree(data); ++ error0: ++ return err; ++} ++ ++static void xeontemp_init_client(struct i2c_client *client) ++{ ++ /* Enable ADC and disable suspend mode */ ++ xeontemp_write_value(client, XEONTEMP_REG_CONFIG_W, 0); ++ /* Set Conversion rate to 1/sec (this can be tinkered with) */ ++ xeontemp_write_value(client, XEONTEMP_REG_CONV_RATE_W, 0x04); ++} ++ ++static int xeontemp_detach_client(struct i2c_client *client) ++{ ++ ++ int err; ++ ++ i2c_deregister_entry(((struct xeontemp_data *) (client->data))-> ++ sysctl_id); ++ ++ if ((err = i2c_detach_client(client))) { ++ printk ++ ("xeontemp.o: Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ ++ kfree(client->data); ++ ++ return 0; ++ ++} ++ ++ ++/* All registers are byte-sized */ ++static int xeontemp_read_value(struct i2c_client *client, u8 reg) ++{ ++ return i2c_smbus_read_byte_data(client, reg); ++} ++ ++/* only update value if read succeeded; set fail bit if failed */ ++static int xeontemp_rd_good(u8 *val, struct i2c_client *client, u8 reg, u8 mask) ++{ ++ int i; ++ struct xeontemp_data *data = client->data; ++ ++ i = i2c_smbus_read_byte_data(client, reg); ++ if (i < 0) { ++ data->fail |= mask; ++ return i; ++ } ++ *val = i; ++ return 0; ++} ++ ++static int xeontemp_write_value(struct i2c_client *client, u8 reg, u16 value) ++{ ++ if (read_only > 0) ++ return 0; ++ ++ return i2c_smbus_write_byte_data(client, reg, value); ++} ++ ++static void xeontemp_update_client(struct i2c_client *client) ++{ ++ struct xeontemp_data *data = client->data; ++ ++ down(&data->update_lock); ++ ++ if ((jiffies - data->last_updated > HZ + HZ / 2) || ++ (jiffies < data->last_updated) || !data->valid) { ++ ++#ifdef DEBUG ++ printk("Starting xeontemp update\n"); ++#endif ++ ++ data->fail = 0; ++ xeontemp_rd_good(&(data->remote_temp), client, ++ XEONTEMP_REG_REMOTE_TEMP, XEONTEMP_ALARM_RTEMP); ++ xeontemp_rd_good(&(data->remote_temp_os), client, ++ XEONTEMP_REG_REMOTE_TOS_R, XEONTEMP_ALARM_RTEMP); ++ xeontemp_rd_good(&(data->remote_temp_hyst), client, ++ XEONTEMP_REG_REMOTE_THYST_R, ++ XEONTEMP_ALARM_RTEMP); ++ data->alarms = XEONTEMP_ALARM_ALL; ++ if (!xeontemp_rd_good(&(data->alarms), client, ++ XEONTEMP_REG_STATUS, 0)) ++ data->alarms &= XEONTEMP_ALARM_ALL; ++ data->last_updated = jiffies; ++ data->valid = 1; ++ } ++ ++ up(&data->update_lock); ++} ++ ++void xeontemp_remote_temp(struct i2c_client *client, int operation, ++ int ctl_name, int *nrels_mag, long *results) ++{ ++ struct xeontemp_data *data = client->data; ++ ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ xeontemp_update_client(client); ++ results[0] = TEMP_FROM_REG(data->remote_temp_os); ++ results[1] = TEMP_FROM_REG(data->remote_temp_hyst); ++ results[2] = TEMP_FROM_REG(data->remote_temp); ++ *nrels_mag = 3; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ if (*nrels_mag >= 1) { ++ data->remote_temp_os = TEMP_TO_REG(results[0]); ++ xeontemp_write_value(client, ++ XEONTEMP_REG_REMOTE_TOS_W, ++ data->remote_temp_os); ++ } ++ if (*nrels_mag >= 2) { ++ data->remote_temp_hyst = TEMP_TO_REG(results[1]); ++ xeontemp_write_value(client, ++ XEONTEMP_REG_REMOTE_THYST_W, ++ data->remote_temp_hyst); ++ } ++ } ++} ++ ++void xeontemp_alarms(struct i2c_client *client, int operation, int ctl_name, ++ int *nrels_mag, long *results) ++{ ++ struct xeontemp_data *data = client->data; ++ if (operation == SENSORS_PROC_REAL_INFO) ++ *nrels_mag = 0; ++ else if (operation == SENSORS_PROC_REAL_READ) { ++ xeontemp_update_client(client); ++ results[0] = data->alarms | data->fail; ++ *nrels_mag = 1; ++ } else if (operation == SENSORS_PROC_REAL_WRITE) { ++ /* Can't write to it */ ++ } ++} ++ ++static int __init sm_xeontemp_init(void) ++{ ++ printk(KERN_INFO "xeontemp.o version %s (%s)\n", LM_VERSION, LM_DATE); ++ return i2c_add_driver(&xeontemp_driver); ++} ++ ++static void __exit sm_xeontemp_exit(void) ++{ ++ i2c_del_driver(&xeontemp_driver); ++} ++ ++MODULE_AUTHOR ++ ("Frodo Looijaard and Philip Edelbrock "); ++MODULE_DESCRIPTION("xeontemp driver"); ++MODULE_LICENSE("GPL"); ++ ++MODULE_PARM(read_only, "i"); ++MODULE_PARM_DESC(read_only, "Don't set any values, read only mode"); ++ ++module_init(sm_xeontemp_init) ++module_exit(sm_xeontemp_exit) +--- linux-old/include/linux/sensors_compat.h Thu Jan 1 00:00:00 1970 ++++ linux/include/linux/sensors_compat.h Mon Dec 13 20:18:54 2004 +@@ -0,0 +1,31 @@ ++/* ++ * Stolen from kernel 2.5.69 ++ * device.h - generic, centralized driver model ++ * To make it easier to backport from 2.5 ++ * ++ * Copyright (c) 2001-2003 Patrick Mochel ++ * ++ */ ++ ++#ifndef _SENSORS_COMPAT_H_ ++#define _SENSORS_COMPAT_H_ ++ ++/* debugging and troubleshooting/diagnostic helpers. */ ++#define dev_printk(level, dev, format, arg...) \ ++ printk(level "%s: " format , (dev)->name , ## arg) ++ ++#ifdef DEBUG ++#define dev_dbg(dev, format, arg...) \ ++ dev_printk(KERN_DEBUG , dev , format , ## arg) ++#else ++#define dev_dbg(dev, format, arg...) do {} while (0) ++#endif ++ ++#define dev_err(dev, format, arg...) \ ++ dev_printk(KERN_ERR , dev , format , ## arg) ++#define dev_info(dev, format, arg...) \ ++ dev_printk(KERN_INFO , dev , format , ## arg) ++#define dev_warn(dev, format, arg...) \ ++ dev_printk(KERN_WARNING , dev , format , ## arg) ++ ++#endif /* _SENSORS_COMPAT_H_ */ +--- linux-old/include/linux/sensors_vid.h Thu Jan 1 00:00:00 1970 ++++ linux/include/linux/sensors_vid.h Mon Dec 13 20:18:54 2004 +@@ -0,0 +1,95 @@ ++/* ++ sensors_vid.h - Part of lm_sensors, Linux kernel modules for hardware ++ monitoring ++ Copyright (c) 2002-2004 Mark D. Studebaker ++ With assistance from Trent Piepho ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* ++ This file contains common code for decoding VID pins. ++ This file is #included in various sensor chip drivers. ++ As the user is unlikely to load more than one driver which ++ includes this code we don't worry about the wasted space. ++ References: VRM x.y DC-DC Converter Design Guidelines, ++ VRD 10.0 Design Guide, ++ available at http://developer.intel.com ++*/ ++ ++/* ++ AMD Opteron processors don't follow the Intel VRM spec. ++ I'm going to "make up" 2.4 as the VRM spec for the Opterons. ++ No good reason just a mnemonic for the 24x Opteron processor ++ series ++ ++ Opteron VID encoding is: ++ ++ 00000 = 1.550 V ++ 00001 = 1.525 V ++ . . . . ++ 11110 = 0.800 V ++ 11111 = 0.000 V (off) ++ */ ++ ++/* ++ Legal val values 00 - 1F except for VRD 10.0, 0x00-0x3f. ++ vrm is the Intel VRM document version. ++ Note: vrm version is scaled by 10 and the return value is scaled by 1000 ++ to avoid floating point in the kernel. ++*/ ++ ++#define DEFAULT_VRM 82 ++ ++static inline int vid_from_reg(int val, int vrm) ++{ ++ int vid; ++ ++ switch(vrm) { ++ ++ case 100: /* VRD 10.0 */ ++ if((val & 0x1f) == 0x1f) ++ return 0; ++ if((val & 0x1f) <= 0x09 || val == 0x0a) ++ vid = 10875 - (val & 0x1f) * 250; ++ else ++ vid = 18625 - (val & 0x1f) * 250; ++ if(val & 0x20) ++ vid -= 125; ++ vid /= 10; /* only return 3 dec. places for now */ ++ return vid; ++ ++ case 24: /* Opteron processor */ ++ return(val == 0x1f ? 0 : 1550 - val * 25); ++ ++ case 91: /* VRM 9.1 */ ++ case 90: /* VRM 9.0 */ ++ return(val == 0x1f ? 0 : ++ 1850 - val * 25); ++ ++ case 85: /* VRM 8.5 */ ++ return((val & 0x10 ? 25 : 0) + ++ ((val & 0x0f) > 0x04 ? 2050 : 1250) - ++ ((val & 0x0f) * 50)); ++ ++ case 84: /* VRM 8.4 */ ++ val &= 0x0f; ++ /* fall through */ ++ default: /* VRM 8.2 */ ++ return(val == 0x1f ? 0 : ++ val & 0x10 ? 5100 - (val) * 100 : ++ 2050 - (val) * 50); ++ } ++} +--- linux-old/drivers/sensors/Config.in Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/Config.in Mon Dec 13 20:18:54 2004 +@@ -0,0 +1,62 @@ ++# ++# Sensor device configuration ++# All depend on CONFIG_I2C_PROC. ++# ISA-only devices depend on CONFIG_I2C_ISA also. ++# ++ ++if [ "$CONFIG_I2C" = "m" -o "$CONFIG_I2C" = "y" ] ; then ++if [ "$CONFIG_I2C_PROC" = "m" -o "$CONFIG_I2C_PROC" = "y" ] ; then ++ mainmenu_option next_comment ++ comment 'Hardware sensors support' ++ ++ dep_mbool 'Hardware sensors support' CONFIG_SENSORS $CONFIG_I2C $CONFIG_I2C_PROC ++ ++ if [ "$CONFIG_SENSORS" != "n" ]; then ++ dep_tristate ' Analog Devices ADM1021 and compatibles' CONFIG_SENSORS_ADM1021 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Analog Devices ADM1024' CONFIG_SENSORS_ADM1024 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Analog Devices ADM1025' CONFIG_SENSORS_ADM1025 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Analog Devices ADM1026' CONFIG_SENSORS_ADM1026 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Analog Devices ADM9240 and compatibles' CONFIG_SENSORS_ADM9240 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Asus ASB100' CONFIG_SENSORS_ASB100 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Dallas DS1621 and DS1625' CONFIG_SENSORS_DS1621 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Fujitsu-Siemens Poseidon' CONFIG_SENSORS_FSCPOS $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Fujitsu-Siemens Scylla' CONFIG_SENSORS_FSCSCY $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Genesys Logic GL518SM' CONFIG_SENSORS_GL518SM $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Genesys Logic GL520SM' CONFIG_SENSORS_GL520SM $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' HP Maxilife' CONFIG_SENSORS_MAXILIFE $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Intel Xeon Thermal Sensor' CONFIG_SENSORS_XEONTEMP $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' ITE 8705/8712, SiS950' CONFIG_SENSORS_IT87 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Maxim MAX6650, MAX6651' CONFIG_SENSORS_MAX6650 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Myson MTP008' CONFIG_SENSORS_MTP008 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' National Semiconductor LM75 and compatibles' CONFIG_SENSORS_LM75 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' National Semiconductor LM78' CONFIG_SENSORS_LM78 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' National Semiconductor LM80' CONFIG_SENSORS_LM80 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' National Semiconductor LM83' CONFIG_SENSORS_LM83 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' National Semiconductor LM85, Analog Devices ADM1027' CONFIG_SENSORS_LM85 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' National Semiconductor LM87' CONFIG_SENSORS_LM87 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' National Semiconductor LM90 and compatibles' CONFIG_SENSORS_LM90 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' National Semiconductor LM92' CONFIG_SENSORS_LM92 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' National Semiconductor PC8736x Sensors' CONFIG_SENSORS_PC87360 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Silicon Integrated Systems Corp. SiS5595' CONFIG_SENSORS_SIS5595 $CONFIG_I2C $CONFIG_I2C_PROC $CONFIG_I2C_ISA ++ dep_tristate ' SMSC47M1xx Integrated Sensors' CONFIG_SENSORS_SMSC47M1 $CONFIG_I2C $CONFIG_I2C_PROC $CONFIG_I2C_ISA ++ dep_tristate ' Texas Instruments THMC50 and compatibles' CONFIG_SENSORS_THMC50 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' VIA 686a Integrated Hardware Monitor' CONFIG_SENSORS_VIA686A $CONFIG_I2C $CONFIG_I2C_PROC $CONFIG_I2C_ISA ++ dep_tristate ' VIA VT1211 Integrated Sensors' CONFIG_SENSORS_VT1211 $CONFIG_I2C $CONFIG_I2C_PROC $CONFIG_I2C_ISA ++ dep_tristate ' VIA VT8231 Integrated Sensors' CONFIG_SENSORS_VT8231 $CONFIG_I2C $CONFIG_I2C_PROC $CONFIG_I2C_ISA ++ dep_tristate ' Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F' CONFIG_SENSORS_W83781D $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Winbond W83627HF, W83627THF, W83697HF' CONFIG_SENSORS_W83627HF $CONFIG_I2C $CONFIG_I2C_PROC $CONFIG_I2C_ISA ++ dep_tristate ' Winbond W83L785TS-S' CONFIG_SENSORS_W83L785TS $CONFIG_I2C $CONFIG_I2C_PROC ++ bool 'Other I2C devices' CONFIG_SENSORS_OTHER ++ if [ "$CONFIG_SENSORS_OTHER" = "y" ] ; then ++ dep_tristate ' Brooktree BT869 Video Modulator' CONFIG_SENSORS_BT869 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' DDC Monitor EDID EEPROM' CONFIG_SENSORS_DDCMON $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' EEprom (DIMM) reader ' CONFIG_SENSORS_EEPROM $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Matrix-Orbital LCD Displays' CONFIG_SENSORS_MATORB $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Philips PCF8574 Parallel I/O' CONFIG_SENSORS_PCF8574 $CONFIG_I2C $CONFIG_I2C_PROC ++ dep_tristate ' Philips PCF8591 D/A and A/D' CONFIG_SENSORS_PCF8591 $CONFIG_I2C $CONFIG_I2C_PROC ++ fi ++ fi ++ endmenu ++fi ++fi ++ +--- linux-old/Makefile Sat Aug 14 18:38:44 2004 ++++ linux/Makefile Mon Dec 13 20:18:54 2004 +@@ -195,6 +195,7 @@ + DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o + DRIVERS-$(CONFIG_CRYPTO) += crypto/crypto.o + ++DRIVERS-$(CONFIG_SENSORS) += drivers/sensors/sensor.o + DRIVERS := $(DRIVERS-y) + + +--- linux-old/drivers/Makefile Mon Nov 17 01:07:35 2003 ++++ linux/drivers/Makefile Mon Dec 13 20:18:54 2004 +@@ -8,7 +8,7 @@ + + mod-subdirs := dio hil mtd sbus video macintosh usb input telephony ide \ + message/i2o message/fusion scsi md ieee1394 pnp isdn atm \ +- fc4 net/hamradio i2c acpi bluetooth usb/gadget ++ fc4 net/hamradio i2c acpi bluetooth usb/gadget sensors + + subdir-y := parport char block net sound misc media cdrom hotplug + subdir-m := $(subdir-y) +@@ -45,6 +45,7 @@ + # CONFIG_HAMRADIO can be set without CONFIG_NETDEVICE being set -- ch + subdir-$(CONFIG_HAMRADIO) += net/hamradio + subdir-$(CONFIG_I2C) += i2c ++subdir-$(CONFIG_SENSORS) += sensors + subdir-$(CONFIG_ACPI_BOOT) += acpi + + subdir-$(CONFIG_BLUEZ) += bluetooth +--- linux-old/drivers/sensors/Makefile Thu Jan 1 00:00:00 1970 ++++ linux/drivers/sensors/Makefile Mon Dec 13 20:18:54 2004 +@@ -0,0 +1,49 @@ ++# ++# Makefile for the kernel hardware sensors drivers. ++# ++ ++MOD_LIST_NAME := SENSORS_MODULES ++O_TARGET := sensor.o ++ ++obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o ++obj-$(CONFIG_SENSORS_ADM1024) += adm1024.o ++obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o ++obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o ++obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o ++obj-$(CONFIG_SENSORS_ASB100) += asb100.o ++obj-$(CONFIG_SENSORS_BT869) += bt869.o ++obj-$(CONFIG_SENSORS_DDCMON) += ddcmon.o ++obj-$(CONFIG_SENSORS_DS1621) += ds1621.o ++obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o ++obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o ++obj-$(CONFIG_SENSORS_FSCSCY) += fscscy.o ++obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o ++obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o ++obj-$(CONFIG_SENSORS_IT87) += it87.o ++obj-$(CONFIG_SENSORS_LM75) += lm75.o ++obj-$(CONFIG_SENSORS_LM78) += lm78.o ++obj-$(CONFIG_SENSORS_LM80) += lm80.o ++obj-$(CONFIG_SENSORS_LM83) += lm83.o ++obj-$(CONFIG_SENSORS_LM85) += lm85.o ++obj-$(CONFIG_SENSORS_LM87) += lm87.o ++obj-$(CONFIG_SENSORS_LM90) += lm90.o ++obj-$(CONFIG_SENSORS_LM92) += lm92.o ++obj-$(CONFIG_SENSORS_MAX6650) += max6650.o ++obj-$(CONFIG_SENSORS_MAXILIFE) += maxilife.o ++obj-$(CONFIG_SENSORS_MTP008) += mtp008.o ++obj-$(CONFIG_SENSORS_PC87360) += pc87360.o ++obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o ++obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o ++obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o ++obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o ++obj-$(CONFIG_SENSORS_THMC50) += thmc50.o ++obj-$(CONFIG_SENSORS_VIA686A) += via686a.o ++obj-$(CONFIG_SENSORS_VT1211) += vt1211.o ++obj-$(CONFIG_SENSORS_VT8231) += vt8231.o ++obj-$(CONFIG_SENSORS_W83781D) += w83781d.o ++obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o ++obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o ++obj-$(CONFIG_SENSORS_XEONTEMP) += xeontemp.o ++ ++include $(TOPDIR)/Rules.make ++ +--- linux-old/drivers/char/Config.in Sat Aug 14 18:38:49 2004 ++++ linux/drivers/char/Config.in Mon Dec 13 20:18:54 2004 +@@ -191,6 +191,8 @@ + + source drivers/i2c/Config.in + ++source drivers/sensors/Config.in ++ + mainmenu_option next_comment + comment 'Mice' + tristate 'Bus Mouse Support' CONFIG_BUSMOUSE +--- linux-old/drivers/i2c/Config.in Wed Jul 7 00:38:02 2004 ++++ linux/drivers/i2c/Config.in Mon Dec 13 20:18:54 2004 +@@ -63,6 +63,30 @@ + fi + + # This is needed for automatic patch generation: sensors code starts here ++ bool 'I2C mainboard interfaces' CONFIG_I2C_MAINBOARD ++ if [ "$CONFIG_I2C_MAINBOARD" = "y" ]; then ++ dep_tristate ' Acer Labs ALI 1535' CONFIG_I2C_ALI1535 $CONFIG_I2C ++ dep_tristate ' Acer Labs ALI 1533 and 1543C' CONFIG_I2C_ALI15X3 $CONFIG_I2C ++ dep_tristate ' Apple Hydra Mac I/O' CONFIG_I2C_HYDRA $CONFIG_I2C_ALGOBIT ++ dep_tristate ' AMD 756/766/768/8111' CONFIG_I2C_AMD756 $CONFIG_I2C ++ dep_tristate ' AMD 8111 SMBus 2.0' CONFIG_I2C_AMD8111 $CONFIG_I2C ++ if [ "$CONFIG_ALPHA" = "y" ]; then ++ dep_tristate ' DEC Tsunami I2C interface' CONFIG_I2C_TSUNAMI $CONFIG_I2C_ALGOBIT ++ fi ++ dep_tristate ' Intel 82801AA, AB, BA, DB' CONFIG_I2C_I801 $CONFIG_I2C ++ dep_tristate ' Intel i810AA/AB/E and i815' CONFIG_I2C_I810 $CONFIG_I2C_ALGOBIT ++ dep_tristate ' Intel 82371AB PIIX4(E), 443MX, ServerWorks OSB4/CSB5, SMSC Victory66' CONFIG_I2C_PIIX4 $CONFIG_I2C ++ dep_tristate ' Nvidia Nforce2' CONFIG_I2C_NFORCE2 $CONFIG_I2C ++ dep_tristate ' SiS 5595' CONFIG_I2C_SIS5595 $CONFIG_I2C ++ dep_tristate ' SiS 630/730' CONFIG_I2C_SIS630 $CONFIG_I2C ++ dep_tristate ' SiS 645/961,645DX/961,735' CONFIG_I2C_SIS645 $CONFIG_I2C $CONFIG_HOTPLUG ++ dep_tristate ' Savage 4' CONFIG_I2C_SAVAGE4 $CONFIG_I2C_ALGOBIT ++ dep_tristate ' VIA Technologies, Inc. VT82C586B' CONFIG_I2C_VIA $CONFIG_I2C_ALGOBIT ++ dep_tristate ' VIA Technologies, Inc. VT596A/B, 686A/B, 8231, 8233, 8233A, 8235' CONFIG_I2C_VIAPRO $CONFIG_I2C ++ dep_tristate ' Voodoo3 I2C interface' CONFIG_I2C_VOODOO3 $CONFIG_I2C_ALGOBIT ++ dep_tristate ' Pseudo ISA adapter (for some hardware sensors)' CONFIG_I2C_ISA $CONFIG_I2C ++ fi ++ + # This is needed for automatic patch generation: sensors code ends here + + dep_tristate 'I2C device interface' CONFIG_I2C_CHARDEV $CONFIG_I2C +--- linux-old/drivers/i2c/Makefile Wed Jul 7 00:38:02 2004 ++++ linux/drivers/i2c/Makefile Mon Dec 13 20:18:54 2004 +@@ -28,6 +28,24 @@ + obj-$(CONFIG_I2C_ALGO_AU1550) += i2c-algo-au1550.o i2c-au1550.o i2c-au1550.o + + # This is needed for automatic patch generation: sensors code starts here ++obj-$(CONFIG_I2C_ALI1535) += i2c-ali1535.o ++obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o ++obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o ++obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o ++obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o ++obj-$(CONFIG_I2C_I801) += i2c-i801.o ++obj-$(CONFIG_I2C_I810) += i2c-i810.o ++obj-$(CONFIG_I2C_ISA) += i2c-isa.o ++obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o ++obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o ++obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o ++obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o ++obj-$(CONFIG_I2C_SIS645) += i2c-sis645.o ++obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o ++obj-$(CONFIG_I2C_TSUNAMI) += i2c-tsunami.o ++obj-$(CONFIG_I2C_VIA) += i2c-via.o ++obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o ++obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o + # This is needed for automatic patch generation: sensors code ends here + + include $(TOPDIR)/Rules.make +--- linux-old/Documentation/Configure.help Mon Dec 13 20:09:52 2004 ++++ linux/Documentation/Configure.help Mon Dec 13 20:18:56 2004 +@@ -29449,4 +29449,527 @@ + # fill-prefix:" " + # adaptive-fill:nil + # fill-column:70 ++I2C mainboard interfaces ++CONFIG_I2C_MAINBOARD ++ Many modern mainboards have some kind of I2C interface integrated. This ++ is often in the form of a SMBus, or System Management Bus, which is ++ basically the same as I2C but which uses only a subset of the I2C ++ protocol. ++ ++ You will also want the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Acer Labs ALI 1535 ++CONFIG_I2C_ALI1535 ++ If you say yes to this option, support will be included for the Acer ++ Labs ALI 1535 mainboard I2C interface. This can also be ++ built as a module. ++ ++Acer Labs ALI 1533 and 1543C ++CONFIG_I2C_ALI15X3 ++ If you say yes to this option, support will be included for the Acer ++ Labs ALI 1533 and 1543C mainboard I2C interfaces. This can also be ++ built as a module which can be inserted and removed while the kernel ++ is running. ++ ++AMD 756/766/768/8111 ++CONFIG_I2C_AMD756 ++ If you say yes to this option, support will be included for the AMD ++ 756/766/768/8111 mainboard I2C interfaces. This can also be ++ built as a module which can be inserted and removed while the kernel ++ is running. ++ ++AMD 8111 SMBus 2.0 ++CONFIG_I2C_AMD8111 ++ If you say yes to this option, support will be included for the AMD ++ 8111 mainboard SMBus 2.0 interface. This can also be ++ built as a module which can be inserted and removed while the kernel ++ is running. ++ ++Apple Hydra Mac I/O ++CONFIG_I2C_HYDRA ++ If you say yes to this option, support will be included for the ++ Hydra mainboard I2C interface. This can also be built as a module ++ which can be inserted and removed while the kernel is running. ++ ++Intel I801 ++CONFIG_I2C_I801 ++ If you say yes to this option, support will be included for the ++ Intel I801 mainboard I2C interfaces. "I810" mainboard sensor chips are ++ generally located on the I801's I2C bus. This can also be ++ built as a module which can be inserted and removed while the kernel ++ is running. ++ ++Intel I810/I815 based Mainboard ++CONFIG_I2C_I810 ++ If you say yes to this option, support will be included for the ++ Intel I810/I815 mainboard I2C interfaces. The I2C busses these chips ++ are generally used only for video devices. For "810" mainboard sensor ++ chips, use the I801 I2C driver instead. This can also be ++ built as a module which can be inserted and removed while the kernel ++ is running. ++ ++Intel 82371AB PIIX4(E) / ServerWorks OSB4 and CSB5 ++CONFIG_I2C_PIIX4 ++ If you say yes to this option, support will be included for the ++ Intel PIIX4, PIIX4E, and 443MX, Serverworks OSB4/CSB5, ++ and SMSC Victory66 mainboard ++ I2C interfaces. This can also be ++ built as a module which can be inserted and removed while the kernel ++ is running. ++ ++Nvidia Nforce2 based Mainboard ++CONFIG_I2C_NFORCE2 ++ If you say yes to this option, support will be included for the ++ Nvidia Nforce2 family of mainboard I2C interfaces. This can also be ++ built as a module which can be inserted and removed while the kernel ++ is running. ++ ++Silicon Integrated Systems Corp. SiS5595 based Mainboard ++CONFIG_I2C_SIS5595 ++ If you say yes to this option, support will be included for the ++ SiS5595 mainboard I2C interfaces. For integrated sensors on the ++ Sis5595, use CONFIG_SENSORS_SIS5595. This can also be ++ built as a module which can be inserted and removed while the kernel ++ is running. ++ ++Silicon Integrated Systems Corp. SiS630/730 based Mainboard ++CONFIG_I2C_SIS630 ++ If you say yes to this option, support will be included for the SiS 630 ++ and 730 mainboard I2C interfaces. This can also be built as a module ++ which can be inserted and removed while the kernel is running. ++ ++Silicon Integrated Systems Corp. SiS645/961,645DX/961,735 based Mainboard ++CONFIG_I2C_SIS645 ++ If you say yes to this option, support will be included for the SiS 645/961, ++ 645DX/961 and 735 mainboard I2C interfaces. This can also be built as a module ++ which can be inserted and removed while the kernel is running. ++ ++VIA Technologies, Inc. VT82C586B ++CONFIG_I2C_VIA ++ If you say yes to this option, support will be included for the VIA ++ Technologies I2C adapter found on some motherboards. This can also ++ be built as a module which can be inserted and removed while the ++ kernel is running. ++ ++VIA Technologies, Inc. VT82C596, 596B, 686A/B, 8233, 8235 ++CONFIG_I2C_VIAPRO ++ If you say yes to this option, support will be included for the VIA ++ Technologies I2C adapter on these chips. For integrated sensors on the ++ Via 686A/B, use CONFIG_SENSORS_VIA686A. This can also be ++ be built as a module which can be inserted and removed while the ++ kernel is running. ++ ++3DFX Banshee / Voodoo3 ++CONFIG_I2C_VOODOO3 ++ If you say yes to this option, support will be included for the ++ 3DFX Banshee and Voodoo3 I2C interfaces. The I2C busses on the these ++ chips are generally used only for video devices. ++ This can also be ++ built as a module which can be inserted and removed while the kernel ++ is running. ++ ++DEC Tsunami 21272 ++CONFIG_I2C_TSUNAMI ++ If you say yes to this option, support will be included for the DEC ++ Tsunami chipset I2C adapter. Requires the Alpha architecture; ++ do not enable otherwise. This can also be built as a module which ++ can be inserted and removed while the kernel is running. ++ ++Pseudo ISA adapter (for hardware sensors modules) ++CONFIG_I2C_ISA ++ This provides support for accessing some hardware sensor chips over ++ the ISA bus rather than the I2C or SMBus. If you want to do this, ++ say yes here. This feature can also be built as a module which can ++ be inserted and removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Analog Devices ADM1021 and compatibles ++CONFIG_SENSORS_ADM1021 ++ If you say yes here you get support for Analog Devices ADM1021 ++ and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A, ++ Genesys Logic GL523SM, National Semi LM84, TI THMC10 and Onsemi ++ MC1066. This can also be built as a module which can be inserted ++ and removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Analog Devices ADM1024 ++CONFIG_SENSORS_ADM1024 ++ If you say yes here you get support for Analog Devices ADM1024 sensor ++ chips. This can also be built as a module. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Analog Devices ADM1025 ++CONFIG_SENSORS_ADM1025 ++ If you say yes here you get support for Analog Devices ADM1025 sensor ++ chips. This can also be built as a module which can be inserted and ++ removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Analog Devices ADM1026 ++CONFIG_SENSORS_ADM1026 ++ If you say yes here you get support for Analog Devices ADM1026 sensor ++ chips. This can also be built as a module which can be inserted and ++ removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Analog Devices ADM9240 and compatibles ++CONFIG_SENSORS_ADM9240 ++ If you say yes here you get support for Analog Devices ADM9240 ++ sensor chips and clones: the Dallas Semiconductor DS1780 and ++ the National Semiconductor LM81. This can also be built as a ++ module which can be inserted and removed while the kernel is ++ running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Asus ASB100 ++CONFIG_SENSORS_ASB100 ++ If you say yes here you get support for the Asus ASB100 (aka ++ "Bach") sensor chip. This can also be built as a module. ++ ++ You will also need the latest user-space utilities: you can find ++ them in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu/ ++ ++Dallas DS1621 and DS1625 ++CONFIG_SENSORS_DS1621 ++ If you say yes here you get support for the Dallas DS1621 and DS1625x ++ sensor chips. This can also be built as a module. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Fujitsu-Siemens Poseidon ++CONFIG_SENSORS_FSCPOS ++ If you say yes here you get support for the Fujitsu-Siemens Poseidon ++ sensor chip. This can also be built as a module. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Fujitsu-Siemens Scylla ++CONFIG_SENSORS_FSCSCY ++ If you say yes here you get support for the Fujitsu-Siemens Scylla ++ sensor chip. This can also be built as a module. This driver may/should ++ also work with the following Fujitsu-Siemens chips: "Poseidon", ++ "Poseidon II" and "Hydra". You may have to force loading of the module ++ for motherboards in these cases. Be careful - those motherboards have ++ not been tested with this driver. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Genesys Logic GL518SM ++CONFIG_SENSORS_GL518SM ++ If you say yes here you get support for Genesys Logic GL518SM sensor ++ chips. This can also be built as a module which can be inserted and ++ removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Genesys Logic GL520SM ++CONFIG_SENSORS_GL520SM ++ If you say yes here you get support for Genesys Logic GL518SM sensor ++ chips. This can also be built as a module which can be inserted and ++ removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++HP Maxilife ++CONFIG_SENSORS_MAXILIFE ++ If you say yes here you get support for the HP Maxilife ++ sensor chip. This can also be built as a module. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Intel Xeon Thermal Sensor ++CONFIG_SENSORS_XEONTEMP ++ If you say yes here you get support for the Intel Xeon processor ++ built-in thermal sensor. This can also be built as a module which ++ can be inserted and removed while the kernel is running. ++ ++ You will also need the latest user-space utilities: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu/ ++ ++ITE 8705, 8712, Sis950 ++CONFIG_SENSORS_IT87 ++ If you say yes here you get support for the ITE 8705 and 8712 and ++ SiS950 sensor chips. This can also be built as a module. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Maxim MAX6650, MAX6651 ++CONFIG_SENSORS_MAX6650 ++ If you say yes here you get support for the Maxim MAX6650 and ++ MAX6651 sensor chips. This can also be built as a module. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Myson MTP008 ++CONFIG_SENSORS_MTP008 ++ If you say yes here you get support for the Myson MTP008 ++ sensor chip. This can also be built as a module. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++National Semiconductor LM75 and compatibles ++CONFIG_SENSORS_LM75 ++ If you say yes here you get support for National Semiconductor LM75 ++ sensor chips and clones: Dallas Semiconductor DS75 and DS1775 (in ++ 9-bit precision mode), and TelCom (now Microchip) TCN75. This can ++ also be built as a module which can be inserted and removed while ++ the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++National Semiconductor LM78 ++CONFIG_SENSORS_LM78 ++ If you say yes here you get support for National Semiconductor LM78 ++ sensor chips family: the LM78-J and LM79. Many clone chips will ++ also work at least somewhat with this driver. This can also be built ++ as a module which can be inserted and removed while the kernel is ++ running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++National Semiconductor LM80 ++CONFIG_SENSORS_LM80 ++ If you say yes here you get support for National Semiconductor LM80 ++ sensor chips. This can also be built as a module which can be ++ inserted and removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++National Semiconductor LM83 ++CONFIG_SENSORS_LM83 ++ If you say yes here you get support for the National Semiconductor ++ LM83 sensor chip. This can also be built as a module. ++ ++ You will also need the latest user-space utilities: you can find ++ them in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu/ ++ ++National Semiconductor LM85 ++CONFIG_SENSORS_LM85 ++ If you say yes here you get support for National Semiconductor LM85 ++ sensor chips and compatibles. Compatible chips include the Analog ++ Devices ADM1027 and ADT7463 and SMSC EMC6D100 and EMC6D101. This ++ can also be built as a module which can be inserted and removed ++ while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++National Semiconductor LM87 ++CONFIG_SENSORS_LM87 ++ If you say yes here you get support for National Semiconductor LM87 ++ sensor chips. This can also be built as a module which can be ++ inserted and removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++National Semiconductor LM90 ++CONFIG_SENSORS_LM90 ++ If you say yes here you get support for the National Semiconductor ++ LM90, LM89 and LM99, and Analog Devices ADM1032 sensor chips. This ++ can also be built as a module. ++ ++ You will also need the latest user-space utilities: you can find ++ them in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu/ ++ ++National Semiconductor LM92 ++CONFIG_SENSORS_LM92 ++ If you say yes here you get support for National Semiconductor LM92 ++ sensor chips. This can also be built as a module which can be ++ inserted and removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++National Semiconductor PC8736x Sensors ++CONFIG_SENSORS_PC87360 ++ If you say yes here you get support for the integrated hardware ++ monitoring in the National Semicoductor PC87360, PC87363, PC87364, ++ PC87365 and PC87366 Super I/O chips. This can also be built as a ++ module which can be inserted and removed while the kernel is ++ running. ++ ++ You will also need the latest user-space utilities: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu/ ++ ++Philips PCF8574 ++CONFIG_SENSORS_PCF8574 ++ If you say yes here you get support for the Philips PCF8574 ++ I2C 8-bit Parallel I/O device. ++ This can also be built as a module which can be ++ inserted and removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Philips PCF8591 ++CONFIG_SENSORS_PCF8591 ++ If you say yes here you get support for the Philips PCF8591 ++ I2C Quad D/A + Single A/D I/O device. ++ This can also be built as a module which can be ++ inserted and removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Silicon Integrated Systems Corp. SiS5595 Sensor ++CONFIG_SENSORS_SIS5595 ++ If you say yes here you get support for the integrated sensors in ++ SiS5595 South Bridges. This can also be built as a module ++ which can be inserted and removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++SMSC47M1xx Super I/O Fan Support ++CONFIG_SENSORS_SMSC47M1 ++ If you say yes here you get support for the integrated fan ++ monitoring and control in the SMSC 47M1xx Super I/O chips. ++ This can also be built as a module ++ which can be inserted and removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Texas Instruments THMC50 / Analog Devices ADM1022 ++CONFIG_SENSORS_THMC50 ++ If you say yes here you get support for Texas Instruments THMC50 ++ sensor chips and clones: the Analog Devices ADM1022. ++ This can also be built as a module which ++ can be inserted and removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Via VT82C686A/B ++CONFIG_SENSORS_VIA686A ++ If you say yes here you get support for the integrated sensors in ++ Via 686A/B South Bridges. This can also be built as a module ++ which can be inserted and removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Via VT1211 Sensors ++CONFIG_SENSORS_VT1211 ++ If you say yes here you get support for the integrated sensors in ++ the Via VT1211 Super I/O device. This can also be built as a module ++ which can be inserted and removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Via VT8231 Sensors ++CONFIG_SENSORS_VT8231 ++ If you say yes here you get support for the integrated sensors in ++ the Via VT8231 device. This can also be built as a module ++ which can be inserted and removed while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Winbond W83781D, W83782D, W83783S, W83627HF, AS99127F ++CONFIG_SENSORS_W83781D ++ If you say yes here you get support for the Winbond W8378x series ++ of sensor chips: the W83781D, W83782D, W83783S and W83682HF, ++ and the similar Asus AS99127F. This ++ can also be built as a module which can be inserted and removed ++ while the kernel is running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ ++Winbond W83627HF, W83627THF, W83697HF ++CONFIG_SENSORS_W83627HF ++ If you say yes here you get support for the Winbond W836x7 series ++ of sensor chips: the Winbond W83627HF, W83627THF and W83697HF. This ++ can also be built as a module which can be inserted and removed ++ while the kernel is running. ++ ++ You will also need the latest user-space utilities: you can find ++ them in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu/ ++ ++Winbond W83L785TS-S ++CONFIG_SENSORS_W83L785TS ++ If you say yes here you get support for the Winbond W83L785TS-S ++ sensor chip. This can also be built as a module. ++ ++ You will also need the latest user-space utilities: you can find ++ them in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu/ ++ ++EEprom (DIMM) reader ++CONFIG_SENSORS_EEPROM ++ If you say yes here you get read-only access to the EEPROM data ++ available on modern memory DIMMs, and which could theoretically ++ also be available on other devices. This can also be built as a ++ module which can be inserted and removed while the kernel is ++ running. ++ ++ You will also need the latest user-space utilties: you can find them ++ in the lm_sensors package, which you can download at ++ http://www.lm-sensors.nu ++ + # End: +--- linux-old/MAINTAINERS Sun Oct 3 01:33:28 2004 ++++ linux/MAINTAINERS Mon Dec 13 20:18:56 2004 +@@ -1659,6 +1659,15 @@ + L: linux-ide@vger.kernel.org + S: Supported + ++SENSORS DRIVERS ++P: Frodo Looijaard ++M: frodol@dds.nl ++P: Philip Edelbrock ++M: phil@netroedge.com ++L: sensors@stimpy.netroedge.com ++W: http://www.lm-sensors.nu/ ++S: Maintained ++ + SGI VISUAL WORKSTATION 320 AND 540 + P: Bent Hagemark + M: bh@sgi.com +--- linux-old/arch/i386/kernel/dmi_scan.c Fri Apr 16 03:14:11 2004 ++++ linux/arch/i386/kernel/dmi_scan.c Mon Dec 13 20:18:56 2004 +@@ -15,6 +15,7 @@ + #include "pci-i386.h" + + unsigned long dmi_broken; ++int is_unsafe_smbus; + int is_sony_vaio_laptop; + + struct dmi_header +@@ -371,6 +372,19 @@ + } + + /* ++ * Don't access SMBus on IBM systems which get corrupted eeproms ++ */ ++ ++static __init int disable_smbus(struct dmi_blacklist *d) ++{ ++ if (is_unsafe_smbus == 0) { ++ is_unsafe_smbus = 1; ++ printk(KERN_INFO "%s machine detected. Disabling SMBus accesses.\n", d->ident); ++ } ++ return 0; ++} ++ ++/* + * Check for a Sony Vaio system + * + * On a Sony system we want to enable the use of the sonypi +@@ -675,6 +689,10 @@ + NO_MATCH, NO_MATCH, + } }, + ++ { disable_smbus, "IBM", { ++ MATCH(DMI_SYS_VENDOR, "IBM"), ++ NO_MATCH, NO_MATCH, NO_MATCH ++ } }, + { sony_vaio_laptop, "Sony Vaio", { /* This is a Sony Vaio laptop */ + MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + MATCH(DMI_PRODUCT_NAME, "PCG-"), +--- linux-old/arch/i386/kernel/i386_ksyms.c Fri Apr 16 03:14:11 2004 ++++ linux/arch/i386/kernel/i386_ksyms.c Mon Dec 13 20:18:56 2004 +@@ -179,6 +179,9 @@ + EXPORT_SYMBOL(atomic_dec_and_lock); + #endif + ++extern int is_unsafe_smbus; ++EXPORT_SYMBOL(is_unsafe_smbus); ++ + extern int is_sony_vaio_laptop; + EXPORT_SYMBOL(is_sony_vaio_laptop); + diff --git a/packages/linux/linux-mtx-2-2.4.27/18-i2c-au1x00gpio.patch b/packages/linux/linux-mtx-2-2.4.27/18-i2c-au1x00gpio.patch new file mode 100644 index 0000000000..38a88e754a --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/18-i2c-au1x00gpio.patch @@ -0,0 +1,466 @@ +diff -urN linux-2.4.27-mtx2-lm_sensors-2.8.8/drivers/i2c/Config.in linux-2.4.27-mtx2-lm_sensors-2.8.8-i2cau1x00gpio/drivers/i2c/Config.in +--- linux-old/drivers/i2c/Config.in 2004-12-13 18:03:18.000000000 +0100 ++++ linux/drivers/i2c/Config.in 2004-12-13 18:11:02.000000000 +0100 +@@ -17,6 +17,11 @@ + int ' GPIO pin used for SCL' CONFIG_SCx200_I2C_SCL 12 + int ' GPIO pin used for SDA' CONFIG_SCx200_I2C_SDA 13 + fi ++ dep_tristate ' I2C using Au1x00 GPIO pins' CONFIG_I2C_AU1X00GPIO $CONFIG_I2C_ALGOBIT ++ if [ "$CONFIG_I2C_AU1X00GPIO" != "n" ]; then ++ int ' GPIO pin used for SCL' CONFIG_I2C_AU1X00GPIO_SCL 206 ++ int ' GPIO pin used for SDA' CONFIG_I2C_AU1X00GPIO_SDA 207 ++ fi + fi + + dep_tristate 'NatSemi SCx200 ACCESS.bus' CONFIG_SCx200_ACB $CONFIG_I2C +diff -urN linux-2.4.27-mtx2-lm_sensors-2.8.8/drivers/i2c/i2c-au1x00gpio.c linux-2.4.27-mtx2-lm_sensors-2.8.8-i2cau1x00gpio/drivers/i2c/i2c-au1x00gpio.c +--- linux-old/drivers/i2c/i2c-au1x00gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/i2c/i2c-au1x00gpio.c 2004-12-13 18:12:50.000000000 +0100 +@@ -0,0 +1,426 @@ ++/* ------------------------------------------------------------------------- */ ++/* i2c-au1x00gpio.c i2c-hw access for Au1x00 GPIO pins. */ ++/* ------------------------------------------------------------------------- */ ++/* Copyright (C) 1995-2000 Michael Stickel ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ ++/* ------------------------------------------------------------------------- */ ++ ++/* With some changes from Kyösti Mälkki and even ++ Frodo Looijaard ++ Simon G. Vogl ++*/ ++ ++/* $Id: i2c-au1x00gpio.c,v 1.1.1.2 2004/01/22 15:35:47 br1 Exp $ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++#ifndef __exit ++#define __exit __init ++#endif ++ ++ ++struct i2c_au1x00gpio ++{ ++ struct i2c_au1x00gpio *next; ++ ++ short scl_gpio; ++ short sda_gpio; ++ ++ unsigned long scl_mask; ++ unsigned long sda_mask; ++ ++ struct i2c_adapter adapter; ++ struct i2c_algo_bit_data bit_au1x00gpio_data; ++}; ++ ++static struct i2c_au1x00gpio *adapter_list; ++ ++ ++ ++/* ----- global defines ----------------------------------------------- */ ++#define DEB(x) /* should be reasonable open, close &c. */ ++#define DEB2(x) /* low level debugging - very slow */ ++#define DEBE(x) x /* error messages */ ++ ++/* ----- printer port defines ------------------------------------------*/ ++ ++/* ----- local functions ---------------------------------------------- */ ++ ++ ++//-- Primary GPIO ++static void bit_au1x00gpio_setscl(void *data, int state) ++{ ++ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; ++ if (state) ++ au_writel(adapter->scl_mask, SYS_TRIOUTCLR); // Disable Driver: Switch off Transistor => 1 ++ else ++ au_writel(adapter->scl_mask, SYS_OUTPUTCLR); // Clear Output and switch on Transistor => 0 ++} ++ ++ ++static void bit_au1x00gpio_setsda(void *data, int state) ++{ ++ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; ++ if (state) ++ au_writel(adapter->sda_mask, SYS_TRIOUTCLR); ++ else ++ au_writel(adapter->sda_mask, SYS_OUTPUTCLR); ++} ++ ++ ++static int bit_au1x00gpio_getscl(void *data) ++{ ++ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; ++ return (au_readl(SYS_PINSTATERD) & adapter->scl_mask) ? 1 : 0; ++} ++ ++ ++static int bit_au1x00gpio_getsda(void *data) ++{ ++ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; ++ return (au_readl(SYS_PINSTATERD) & adapter->sda_mask) ? 1 : 0; ++} ++ ++ ++ ++ ++/*-- ++ *-- Functions for accessing GPIO-2 ++ *-- ++ */ ++static void bit_au1x00gpio2_setscl(void *data, int state) ++{ ++ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; ++ if (state) ++ { ++ au_writel(au_readl(GPIO2_DIR) & ~adapter->scl_mask, GPIO2_DIR); ++ } ++ else ++ { ++ au_writel(au_readl(GPIO2_OUTPUT) & ~adapter->scl_mask, GPIO2_OUTPUT); ++ au_writel(au_readl(GPIO2_DIR) | adapter->scl_mask, GPIO2_DIR); ++ } ++} ++ ++static void bit_au1x00gpio2_setsda(void *data, int state) ++{ ++ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; ++ if (state) ++ { ++ au_writel(au_readl(GPIO2_DIR) & ~adapter->sda_mask, GPIO2_DIR); ++ } ++ else ++ { ++ au_writel(au_readl(GPIO2_OUTPUT) & ~adapter->sda_mask, GPIO2_OUTPUT); ++ au_writel(au_readl(GPIO2_DIR) | adapter->sda_mask, GPIO2_DIR); ++ } ++} ++ ++static int bit_au1x00gpio2_getscl(void *data) ++{ ++ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; ++ return (au_readl(GPIO2_PINSTATE) & adapter->scl_mask) ? 1 : 0; ++} ++ ++static int bit_au1x00gpio2_getsda(void *data) ++{ ++ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; ++ return (au_readl(GPIO2_PINSTATE) & adapter->sda_mask) ? 1 : 0; ++} ++ ++ ++ ++static int check_i2c_au1x00gpio_adapter(struct i2c_au1x00gpio *adapter) ++{ ++ int state = 0; ++ ++ adapter->bit_au1x00gpio_data.setsda (adapter, 1); ++ adapter->bit_au1x00gpio_data.setscl (adapter, 1); ++ ++ if (adapter->bit_au1x00gpio_data.getsda(adapter)==0) ++ { ++ printk ("i2c-au1x00gpio: sda line should read 1 but reads 0\n"); ++ state = -1; ++ } ++ if (adapter->bit_au1x00gpio_data.getscl(adapter)==0) ++ { ++ printk ("i2c-au1x00gpio: scl line should read 1 but reads 0\n"); ++ state = -1; ++ } ++ ++ ++ adapter->bit_au1x00gpio_data.setsda (adapter, 0); ++ adapter->bit_au1x00gpio_data.setscl (adapter, 0); ++ ++ if (adapter->bit_au1x00gpio_data.getsda(adapter)==1) ++ { ++ printk ("i2c-au1x00gpio: sda line should read 0 but reads 1\n"); ++ state = -1; ++ } ++ if (adapter->bit_au1x00gpio_data.getscl(adapter)==1) ++ { ++ printk ("i2c-au1x00gpio: scl line should read 0 but reads 1\n"); ++ state = -1; ++ } ++ ++ if (state==0) ++ printk ("i2c-au1x00gpio: adapter with scl=GPIO%d,sda=GPIO%d is working\n", ++ adapter->scl_gpio, adapter->sda_gpio ++ ); ++ return state; ++} ++ ++ ++ ++#if 0 ++static int bit_au1x00gpio_reg(struct i2c_client *client) ++{ ++ return 0; ++} ++ ++static int bit_au1x00gpio_unreg(struct i2c_client *client) ++{ ++ return 0; ++} ++ ++static void bit_au1x00gpio_inc_use(struct i2c_adapter *adap) ++{ ++ MOD_INC_USE_COUNT; ++} ++ ++static void bit_au1x00gpio_dec_use(struct i2c_adapter *adap) ++{ ++ MOD_DEC_USE_COUNT; ++} ++#endif ++ ++ ++ ++static struct i2c_algo_bit_data bit_au1x00gpio_data = { ++ .setsda = bit_au1x00gpio_setsda, ++ .setscl = bit_au1x00gpio_setscl, ++ .getsda = bit_au1x00gpio_getsda, ++ .getscl = bit_au1x00gpio_getscl, ++ .udelay = 80, ++ .mdelay = 80, ++ .timeout = HZ ++}; ++ ++ ++static struct i2c_adapter bit_au1x00gpio_ops = { ++ .owner = THIS_MODULE, ++ .name = "Au1x00 GPIO I2C adapter", ++ .id = I2C_HW_B_AU1x00GPIO, ++}; ++ ++ ++ ++/* ++ * scl_gpio: ++ * 0..31 for primary GPIO's ++ * 200..215 for secondary GPIO's ++ * ++ * sda_gpio: ++ * 0..31 for primary GPIO's ++ * 200..215 for secondary GPIO's ++ * ++ * You can even mix primary and secondary GPIO's. ++ * E.g.: i2c_au1x00gpio_create(4,206); ++ */ ++ ++static int i2c_au1x00gpio_create (int scl_gpio, int sda_gpio) ++{ ++ if ((scl_gpio < 32 || (scl_gpio >= 200 && scl_gpio <= 215)) && ++ (scl_gpio < 32 || (scl_gpio >= 200 && scl_gpio <= 215))) ++ { ++ struct i2c_au1x00gpio *adapter = kmalloc(sizeof(struct i2c_au1x00gpio), ++ GFP_KERNEL); ++ if (!adapter) { ++ printk(KERN_ERR "i2c-au1x00-gpio: Unable to malloc.\n"); ++ return -1; ++ } ++ ++ printk(KERN_DEBUG "i2c-au1x00-gpio.o: attaching to SCL=GPIO%d, SDA=GPIO%d\n", ++ scl_gpio, sda_gpio); ++ ++ memset (adapter, 0, sizeof(struct i2c_au1x00gpio)); ++ ++ adapter->adapter = bit_au1x00gpio_ops; ++ ++ adapter->adapter.algo_data = &adapter->bit_au1x00gpio_data; ++ adapter->bit_au1x00gpio_data = bit_au1x00gpio_data; ++ adapter->bit_au1x00gpio_data.data = adapter; ++ ++ adapter->bit_au1x00gpio_data.data = adapter; ++ ++ adapter->scl_gpio = scl_gpio; ++ adapter->sda_gpio = sda_gpio; ++ ++ if (sda_gpio < 32) ++ { ++ adapter->bit_au1x00gpio_data.setsda = bit_au1x00gpio_setsda; ++ adapter->bit_au1x00gpio_data.getsda = bit_au1x00gpio_getsda; ++ adapter->sda_mask = 1<= 200 && sda_gpio <= 215) ++ { ++ adapter->bit_au1x00gpio_data.setsda = bit_au1x00gpio2_setsda; ++ adapter->bit_au1x00gpio_data.getsda = bit_au1x00gpio2_getsda; ++ adapter->sda_mask = 1<<(sda_gpio-200); ++ } ++ ++ ++ if (scl_gpio < 32) ++ { ++ adapter->bit_au1x00gpio_data.setscl = bit_au1x00gpio_setscl; ++ adapter->bit_au1x00gpio_data.getscl = bit_au1x00gpio_getscl; ++ adapter->scl_mask = 1<= 200 && scl_gpio <= 215) ++ { ++ adapter->bit_au1x00gpio_data.setscl = bit_au1x00gpio2_setscl; ++ adapter->bit_au1x00gpio_data.getscl = bit_au1x00gpio2_getscl; ++ adapter->scl_mask = 1<<(scl_gpio-200); ++ } ++ ++ au_writel(0L, SYS_PININPUTEN); ++ if (check_i2c_au1x00gpio_adapter(adapter)==0) ++ { ++ adapter->bit_au1x00gpio_data.setsda (adapter, 1); ++ adapter->bit_au1x00gpio_data.setscl (adapter, 1); ++ ++ if (i2c_bit_add_bus(&adapter->adapter) < 0) ++ { ++ printk(KERN_ERR "i2c-au1x00-gpio: Unable to register with I2C.\n"); ++ kfree(adapter); ++ return -1; /* No good */ ++ } ++ ++ adapter->next = adapter_list; ++ adapter_list = adapter; ++ return 0; ++ } ++ } ++ else ++ printk(KERN_ERR "i2c-au1x00-gpio: Invalid argument scl_gpio=%d, sda_gpio=%d.\n", scl_gpio, sda_gpio); ++ return -1; ++} ++ ++ ++ ++static void i2c_au1x00gpio_delete (int scl_gpio, int sda_gpio) ++{ ++ struct i2c_au1x00gpio *adapter, *prev = NULL; ++ ++ for (adapter = adapter_list; adapter; adapter = adapter->next) ++ { ++ if (adapter->scl_gpio == scl_gpio && ++ adapter->sda_gpio == sda_gpio) ++ { ++ i2c_bit_del_bus(&adapter->adapter); ++ if (prev) ++ prev->next = adapter->next; ++ else ++ adapter_list = adapter->next; ++ kfree(adapter); ++ return; ++ } ++ prev = adapter; ++ } ++} ++ ++ ++ ++ ++ ++#ifndef CONFIG_I2C_AU1X00GPIO_SCL ++#define CONFIG_I2C_AU1X00GPIO_SCL (216) ++#endif ++ ++#ifndef CONFIG_I2C_AU1X00GPIO_SDA ++#define CONFIG_I2C_AU1X00GPIO_SDA (217) ++#endif ++ ++static int au1x00gpiopin_scl = CONFIG_I2C_AU1X00GPIO_SCL; ++static int au1x00gpiopin_sda = CONFIG_I2C_AU1X00GPIO_SDA; ++ ++ ++ ++int __init i2c_bit_au1x00gpio_init(void) ++{ ++ printk(KERN_INFO "i2c-au1x00gpio.o: i2c Au1x00 GPIO adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE); ++ ++ if (i2c_au1x00gpio_create (au1x00gpiopin_scl, au1x00gpiopin_sda) == 0) ++ { ++ printk(KERN_INFO "i2c-au1x00gpio.o: registered I2C-Bus for GPIO%d,GPIO%d\n", ++ au1x00gpiopin_scl, au1x00gpiopin_sda ++ ); ++ return 0; ++ } ++ printk(KERN_INFO "i2c-au1x00gpio.o: failed to register I2C-Bus for GPIO%d,GPIO%d\n", ++ au1x00gpiopin_scl, au1x00gpiopin_sda ++ ); ++ return -1; ++} ++ ++ ++void __exit i2c_bit_au1x00gpio_exit(void) ++{ ++ i2c_au1x00gpio_delete (au1x00gpiopin_scl, au1x00gpiopin_sda); ++} ++ ++ ++ ++EXPORT_NO_SYMBOLS; ++ ++MODULE_PARM(au1x00gpiopin_scl, "i"); ++MODULE_PARM_DESC(au1x00gpiopin_scl, "GPIO pin number used for SCL pin."); ++ ++MODULE_PARM(au1x00gpiopin_sda, "i"); ++MODULE_PARM_DESC(au1x00gpiopin_sda, "GPIO pin number used for SDA pin."); ++ ++MODULE_AUTHOR("Michael Stickel "); ++MODULE_DESCRIPTION("I2C-Bus adapter routines for Au1x00 GPIO adapter."); ++MODULE_LICENSE("GPL"); ++ ++ ++#ifdef MODULE ++int init_module(void) ++{ ++ return i2c_bit_au1x00gpio_init(); ++} ++ ++void cleanup_module(void) ++{ ++ i2c_bit_au1x00gpio_exit(); ++} ++#endif +diff -urN linux-2.4.27-mtx2-lm_sensors-2.8.8/drivers/i2c/Makefile linux-2.4.27-mtx2-lm_sensors-2.8.8-i2cau1x00gpio/drivers/i2c/Makefile +--- linux-old/drivers/i2c/Makefile 2004-12-13 18:03:18.000000000 +0100 ++++ linux/drivers/i2c/Makefile 2004-12-13 18:11:59.000000000 +0100 +@@ -25,6 +25,7 @@ + obj-$(CONFIG_I2C_ALGO_SIBYTE) += i2c-algo-sibyte.o i2c-sibyte.o + obj-$(CONFIG_I2C_MAX1617) += i2c-max1617.o + obj-$(CONFIG_I2C_ALGO_SGI) += i2c-algo-sgi.o ++obj-$(CONFIG_I2C_AU1X00GPIO) += i2c-au1x00gpio.o + obj-$(CONFIG_I2C_ALGO_AU1550) += i2c-algo-au1550.o i2c-au1550.o + + # This is needed for automatic patch generation: sensors code starts here +--- linux-old/include/linux/i2c-id.h 2004-12-13 21:09:52.000000000 +0100 ++++ linux/include/linux/i2c-id.h 2004-12-13 21:36:14.000000000 +0100 +@@ -242,6 +242,7 @@ + #define I2C_HW_B_S3VIA 0x18 /* S3Via ProSavage adapter */ + #define I2C_HW_B_ZR36067 0x19 /* Zoran-36057/36067 based boards */ + #define I2C_HW_B_PCILYNX 0x1a /* TI PCILynx I2C adapter */ ++#define I2C_HW_B_AU1x00GPIO 0x1b /* Au1x00 GPIO adapter */ + + /* --- PCF 8584 based algorithms */ + #define I2C_HW_P_LP 0x00 /* Parallel port interface */ diff --git a/packages/linux/linux-mtx-2-2.4.27/19-kernel-make-depend.diff b/packages/linux/linux-mtx-2-2.4.27/19-kernel-make-depend.diff new file mode 100644 index 0000000000..3b28135561 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/19-kernel-make-depend.diff @@ -0,0 +1,11 @@ +--- linux-orig/Makefile 2004-11-24 12:11:29.000000000 +0100 ++++ linux/Makefile 2006-05-01 13:11:35.043371250 +0200 +@@ -501,7 +502,7 @@ + ifdef CONFIG_MODVERSIONS + $(MAKE) update-modverfile + endif +- scripts/mkdep -- `find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend ++ (find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print | xargs -r scripts/mkdep -- ) > .hdepend + scripts/mkdep -- init/*.c > .depend + + ifdef CONFIG_MODVERSIONS diff --git a/packages/linux/linux-mtx-2-2.4.27/22-umts.diff b/packages/linux/linux-mtx-2-2.4.27/22-umts.diff new file mode 100644 index 0000000000..e142082f41 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/22-umts.diff @@ -0,0 +1,28 @@ +diff -Nurb linux-2.4.27-mtx2/drivers/usb/serial/usbserial.c linux-2.4.27-mtx2-umts/drivers/usb/serial/usbserial.c +--- linux-old/drivers/usb/serial/usbserial.c 2004-08-14 20:38:57.000000000 +0200 ++++ linux/drivers/usb/serial/usbserial.c 2005-06-07 10:53:03.000000000 +0200 +@@ -332,7 +332,7 @@ + static __u16 vendor = 0x05f9; + static __u16 product = 0xffff; + +-static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ ++static struct usb_device_id generic_device_ids[5]; /* Initially all zeroes. */ + + /* All of the device info needed for the Generic Serial Converter */ + static struct usb_serial_device_type generic_device = { +@@ -1773,6 +1773,15 @@ + generic_device_ids[0].idVendor = vendor; + generic_device_ids[0].idProduct = product; + generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; ++ generic_device_ids[1].idVendor = 0xaf0; ++ generic_device_ids[1].idProduct = 0x5000; ++ generic_device_ids[1].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; ++ generic_device_ids[2].idVendor = 0xaf0; ++ generic_device_ids[2].idProduct = 0x6000; ++ generic_device_ids[2].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; ++ generic_device_ids[3].idVendor = 0xaf0; ++ generic_device_ids[3].idProduct = 0x6300; ++ generic_device_ids[3].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; + /* register our generic driver with ourselves */ + usb_serial_register (&generic_device); + #endif diff --git a/packages/linux/linux-mtx-2-2.4.27/27-idsel-cardbus.diff b/packages/linux/linux-mtx-2-2.4.27/27-idsel-cardbus.diff new file mode 100644 index 0000000000..0ec19ccee3 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/27-idsel-cardbus.diff @@ -0,0 +1,115 @@ +--- linux-org/arch/mips/au1000/mtx-2/board_setup.c 2006-05-01 13:23:16.491209000 +0200 ++++ linux/arch/mips/au1000/mtx-2/board_setup.c 2006-04-30 20:35:58.000000000 +0200 +@@ -48,14 +48,45 @@ + + extern struct rtc_ops no_rtc_ops; + ++void board_reset (void) ++{ ++ /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ ++ au_writel(0x00000000, 0xAE00001C); ++} ++ ++ ++#if 0 ++static void au1x00_setpinfunc (u32 mask, char setbit) ++{ ++ u32 pin_func = au_readl(SYS_PINFUNC); ++ au_sync(); ++ ++ if (setbit) ++ pin_func |= mask; ++ else ++ pin_func &= (u32)(~mask); ++ ++ au_writel(pin_func, SYS_PINFUNC); ++} ++#endif ++ ++ + void __init board_setup(void) + { + rtc_ops = &no_rtc_ops; + ++#if 0 ++ ++ /* Enable PSC1 SYNC for AC97. Normaly done in audio driver, ++ * but it is board specific code, so put it here. ++ */ ++ au1x00_pinfunc (SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1, 1); ++ ++ + #if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + #ifdef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB device +- au_writel(au_readl(SYS_PINFUNC) & (u32)(~0x8000), SYS_PINFUNC); ++ au1x00_setpinfunc (0x8000, 0); // USB On + #endif + // enable USB power switch + au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR ); +@@ -72,8 +103,7 @@ + + // initialize sys_pinfunc: + // disable second ethernet port (SYS_PF_NI2) +- // set U3/GPIO23 to GPIO23 (SYS_PF_U3) +- au_writel( SYS_PF_NI2 | SYS_PF_U3, SYS_PINFUNC ); ++ au1x00_setpinfunc (SYS_PF_NI2, 0); + + // initialize GPIO + au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR ); +@@ -84,6 +114,6 @@ + // enable LED and set it to green + au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR ); + au_writel( 0x18000800, GPIO2_OUTPUT ); +- ++#endif + printk("4G Systems MTX-2 Board\n"); + } +--- linux-org/arch/mips/au1000/mtx-2/irqmap.c 2006-05-01 13:23:27.219879500 +0200 ++++ linux/arch/mips/au1000/mtx-2/irqmap.c 2006-04-30 20:35:58.000000000 +0200 +@@ -50,17 +50,24 @@ + /* Need to define this. + */ + au1xxx_irq_map_t au1xxx_irq_map[] = { ++ ++ // SLIC DET pin ++ { AU1000_GPIO_9, INTC_INT_RISE_AND_FALL_EDGE, 0 }, ++ ++ // Push-Buttons at GPIO 211-215 ++ { AU1500_GPIO_208_218, INTC_INT_RISE_AND_FALL_EDGE, 0 }, ++ + { 0, 0, 0} + }; + +-int au1xxx_nr_irqs = 0; ++int au1xxx_nr_irqs = 2; + + #ifdef CONFIG_PCI + +-#define INTA AU1000_PCI_INTA +-#define INTB AU1000_PCI_INTB +-#define INTC AU1000_PCI_INTC +-#define INTD AU1000_PCI_INTD ++#define INTA AU1550_PCI_INTA ++#define INTB AU1550_PCI_INTB ++#define INTC AU1550_PCI_INTC ++#define INTD AU1550_PCI_INTD + #define INTX 0xFF /* not valid */ + + int __init +@@ -72,12 +79,10 @@ + * A B C D + */ + { +- {INTA, INTB, INTX, INTX}, /* IDSEL 0 */ +- {INTB, INTA, INTX, INTX}, /* IDSEL 1 */ +- {INTC, INTD, INTX, INTX}, /* IDSEL 2 */ +- {INTD, INTC, INTX, INTX}, /* IDSEL 3 */ ++ {INTA, INTX, INTX, INTX}, /* IDSEL 0 */ ++ {INTB, INTC, INTX, INTX}, /* IDSEL 1 */ + }; +- const long min_idsel = 0, max_idsel = 3, irqs_per_slot = 4; ++ const long min_idsel = 0, max_idsel = 1, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; + }; + #endif diff --git a/packages/linux/linux-mtx-2-2.4.27/28-surfbox2-idsel.diff b/packages/linux/linux-mtx-2-2.4.27/28-surfbox2-idsel.diff new file mode 100644 index 0000000000..94f1c0e664 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/28-surfbox2-idsel.diff @@ -0,0 +1,47 @@ +diff -Nur linux-orig/arch/mips/au1000/mtx-2/board_setup.c linux-mtx-2-2.4.27-idsel-fix/linux/arch/mips/au1000/mtx-2/board_setup.c +--- linux-orig/arch/mips/au1000/mtx-2/board_setup.c 2006-05-26 12:39:00.000000000 +0200 ++++ linux/arch/mips/au1000/mtx-2/board_setup.c 2006-06-02 17:50:09.000000000 +0200 +@@ -46,8 +46,11 @@ + #include + #include + ++static int mtx2_pci_idsel(unsigned int devsel, int assert); ++extern int (*board_pci_idsel)(unsigned int devsel, int assert); ++ + extern struct rtc_ops no_rtc_ops; + + void board_reset (void) + { + /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ +@@ -115,5 +118,31 @@ + au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR ); + au_writel( 0x18000800, GPIO2_OUTPUT ); + #endif ++ ++ ++ board_pci_idsel = mtx2_pci_idsel; ++ + printk("4G Systems MTX-2 Board\n"); + } ++ ++ ++static int mtx2_pci_idsel(unsigned int devsel, int assert) ++{ ++#define MTX_IDSEL_ONLY_0_AND_3 0 ++#if MTX_IDSEL_ONLY_0_AND_3 ++ if (devsel != 0 && devsel != 3) { ++ printk("*** not 0 or 3\n"); ++ return 0; ++ } ++#endif ++ ++ if (assert && devsel != 0) { ++ // supress signal to cardbus ++ au_writel( (1<<(16+5)) | (0<<5), GPIO2_OUTPUT); // set EXT_IO3 OFF ++ } ++ else { ++ au_writel( (1<<(16+5)) | (1<<5), GPIO2_OUTPUT); // set EXT_IO3 ON ++ } ++ au_sync_udelay(1); ++ return 1; ++} diff --git a/packages/linux/linux-mtx-2-2.4.27/29-au1000-pci-config-clear-errors.diff b/packages/linux/linux-mtx-2-2.4.27/29-au1000-pci-config-clear-errors.diff new file mode 100644 index 0000000000..5da1cd61f8 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/29-au1000-pci-config-clear-errors.diff @@ -0,0 +1,15 @@ +--- linux/arch/mips/au1000/common/pci_ops.c.orig 2005-08-24 17:36:25.000000000 +0200 ++++ linux/arch/mips/au1000/common/pci_ops.c 2005-08-24 17:37:38.000000000 +0200 +@@ -259,7 +259,11 @@ + *data = 0xffffffff; + error = -1; + } else if ((status >> 28) & 0xf) { +- DBG("PCI ERR detected: status %x\n", status); ++ DBG("PCI ERR detected: device %d, status %x\n", device, ((status >> 28) & 0xf)); ++ ++ /* clear errors */ ++ au_writel(status & 0xf000ffff, Au1500_PCI_STATCMD); ++ + *data = 0xffffffff; + error = -1; + } diff --git a/packages/linux/linux-mtx-2-2.4.27/32-usbserial-stalled-hack.diff b/packages/linux/linux-mtx-2-2.4.27/32-usbserial-stalled-hack.diff new file mode 100644 index 0000000000..1651bd5678 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/32-usbserial-stalled-hack.diff @@ -0,0 +1,22 @@ +--- linux-old/drivers/usb/serial/usbserial.c 2005-08-28 20:23:40.000000000 +0200 ++++ linux/drivers/usb/serial/usbserial.c 2005-08-28 20:23:12.000000000 +0200 +@@ -499,6 +499,19 @@ + /* get_usb_serial checks port->tty, so cannot be used */ + serial = port->serial; + if (port->write_busy) { ++ ++ /*-- how is the status of the outgoing urb? --*/ ++ /*-- did we miss a callback? --*/ ++ /*-- problem with the hack below is that we may */ ++ /* corrup structures we currently walk thru */ ++ if (port->write_urb && port->write_urb->status != -EINPROGRESS) { ++ if (port->write_urb->complete) ++ port->write_urb->complete(port->write_urb); ++ else ++ dbg("%s: URB %p has no complete function\n", __FUNCTION__, port->write_urb); ++ } ++ ++ + dbg("%s - port %d busy", __FUNCTION__, port->number); + pos = pos->next; + continue; diff --git a/packages/linux/linux-mtx-2-2.4.27/33-usbserial-bulk_in_size-4096.diff b/packages/linux/linux-mtx-2-2.4.27/33-usbserial-bulk_in_size-4096.diff new file mode 100644 index 0000000000..e615a92fa4 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/33-usbserial-bulk_in_size-4096.diff @@ -0,0 +1,140 @@ +--- linux/drivers/usb/serial/usbserial.c~33-usbserial-bulk_in_size-4096.diff 2006-03-31 15:05:46.674445000 +0200 ++++ linux/drivers/usb/serial/usbserial.c 2006-04-07 12:23:56.970400500 +0200 +@@ -332,6 +332,9 @@ + static __u16 vendor = 0x05f9; + static __u16 product = 0xffff; + ++static int count_smaller64 = 0; ++static int count_bigger64 = 0; ++ + static struct usb_device_id generic_device_ids[5]; /* Initially all zeroes. */ + + /* All of the device info needed for the Generic Serial Converter */ +@@ -396,6 +399,10 @@ + drivers depend on it. + */ + ++/* global params controlling max sizes for read, write, control */ ++static int maxszr = 0; ++static int maxszw = 0; ++static int maxszc = 0; + + static int serial_refcount; + static struct tty_driver serial_tty_driver; +@@ -1272,6 +1279,14 @@ + tty_flip_buffer_push(tty); + } + ++ if (urb->actual_length>64) { ++ count_bigger64++; ++ } else { ++ count_smaller64++; ++ } ++ ++ /*printk("*** %d\n", urb->actual_length);*/ ++ + /* Continue trying to always read */ + usb_fill_bulk_urb (port->read_urb, serial->dev, + usb_rcvbulkpipe (serial->dev, +@@ -1505,7 +1520,8 @@ + err("No free urbs available"); + goto probe_error; + } +- buffer_size = endpoint->wMaxPacketSize; ++ buffer_size = (endpoint->wMaxPacketSize > maxszr)? ++ endpoint->wMaxPacketSize: maxszr; + port->bulk_in_endpointAddress = endpoint->bEndpointAddress; + port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); + if (!port->bulk_in_buffer) { +@@ -1530,7 +1546,8 @@ + err("No free urbs available"); + goto probe_error; + } +- buffer_size = endpoint->wMaxPacketSize; ++ buffer_size = (endpoint->wMaxPacketSize > maxszw)? ++ endpoint->wMaxPacketSize: maxszw; + port->bulk_out_size = buffer_size; + port->bulk_out_endpointAddress = endpoint->bEndpointAddress; + port->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL); +@@ -1556,7 +1573,8 @@ + err("No free urbs available"); + goto probe_error; + } +- buffer_size = endpoint->wMaxPacketSize; ++ buffer_size = (endpoint->wMaxPacketSize > maxszc)? ++ endpoint->wMaxPacketSize: maxszc; + port->interrupt_in_endpointAddress = endpoint->bEndpointAddress; + port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL); + if (!port->interrupt_in_buffer) { +@@ -1807,6 +1825,7 @@ + + static void __exit usb_serial_exit(void) + { ++ printk("*** received packets\n< 64: %d\n> 64: %d\n", count_smaller64, count_bigger64); + + #ifdef CONFIG_USB_SERIAL_GENERIC + /* remove our generic driver */ +@@ -1874,6 +1893,15 @@ + MODULE_PARM(debug, "i"); + MODULE_PARM_DESC(debug, "Debug enabled or not"); + ++MODULE_PARM(maxszr, "i"); ++MODULE_PARM_DESC(maxszr, "User specified USB endpoint read size"); ++ ++MODULE_PARM(maxszw, "i"); ++MODULE_PARM_DESC(maxszw, "User specified USB endpoint write size"); ++ ++MODULE_PARM(maxszc, "i"); ++MODULE_PARM_DESC(maxszc, "User specified USB endpoint control size"); ++ + #ifdef CONFIG_USB_SERIAL_GENERIC + MODULE_PARM(vendor, "h"); + MODULE_PARM_DESC(vendor, "User specified USB idVendor"); +--- linux/drivers/usb/acm.c.orig 2006-04-07 13:56:33.837683000 +0200 ++++ linux/drivers/usb/acm.c 2006-04-07 12:14:37.995466750 +0200 +@@ -155,6 +155,11 @@ + unsigned char clocal; /* termios CLOCAL */ + }; + ++/* global params controlling max sizes for read, write, control */ ++static int maxszr = 0; ++static int maxszw = 0; ++static int maxszc = 0; ++ + static struct usb_driver acm_driver; + static struct tty_driver acm_tty_driver; + static struct acm *acm_table[ACM_TTY_MINORS]; +@@ -573,9 +578,13 @@ + } + memset(acm, 0, sizeof(struct acm)); + +- ctrlsize = epctrl->wMaxPacketSize; +- readsize = epread->wMaxPacketSize; +- acm->writesize = epwrite->wMaxPacketSize; ++ ctrlsize = (epctrl->wMaxPacketSize > maxszc)? ++ epctrl->wMaxPacketSize: maxszc; ++ readsize = (epread->wMaxPacketSize > maxszr)? ++ epread->wMaxPacketSize: maxszr; ++ acm->writesize = (epwrite->wMaxPacketSize > maxszw)? ++ epwrite->wMaxPacketSize: maxszw; ++ + acm->iface = cfacm->interface + j; + acm->minor = minor; + acm->dev = dev; +@@ -740,6 +749,16 @@ + module_init(acm_init); + module_exit(acm_exit); + ++ ++MODULE_PARM(maxszr, "i"); ++MODULE_PARM_DESC(maxszr, "User specified USB endpoint read size"); ++ ++MODULE_PARM(maxszw, "i"); ++MODULE_PARM_DESC(maxszw, "User specified USB endpoint write size"); ++ ++MODULE_PARM(maxszc, "i"); ++MODULE_PARM_DESC(maxszc, "User specified USB endpoint control size"); ++ + MODULE_AUTHOR( DRIVER_AUTHOR ); + MODULE_DESCRIPTION( DRIVER_DESC ); + MODULE_LICENSE("GPL"); diff --git a/packages/linux/linux-mtx-2-2.4.27/35-sb2-slic.patch b/packages/linux/linux-mtx-2-2.4.27/35-sb2-slic.patch new file mode 100644 index 0000000000..9d985da878 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/35-sb2-slic.patch @@ -0,0 +1,761 @@ +--- linux-org/arch/mips/au1000/mtx-2/Makefile 2006-05-01 13:34:12.664217250 +0200 ++++ linux/arch/mips/au1000/mtx-2/Makefile 2006-05-01 13:33:35.609901500 +0200 +@@ -15,6 +15,6 @@ + + O_TARGET := mtx-2.o + +-obj-y := init.o board_setup.o irqmap.o ++obj-y := init.o board_setup.o irqmap.o slic.o + + include $(TOPDIR)/Rules.make +--- linux-org/arch/mips/au1000/mtx-2/slic.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/arch/mips/au1000/mtx-2/slic.c 2006-06-20 13:46:05.321244750 +0200 +@@ -0,0 +1,704 @@ ++/* ++ * Driver for the SLIC ++ * ++ * After the module is loaded there is a device /dev/misc/slic ++ * that can be read. A read returns if the DETECT-line has been toggled, ++ * indicating an offhook-event. ++ * ++ * Commands to be written to the device: ++ * P1 - Power on ++ * P0 - Power off ++ * ID - Idle state ++ * AC - Active state ++ * AR - Active state with reverse polarity ++ * R1 - Ringing on ++ * R0 - Ringing off ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* #define DEBUG */ ++#ifdef DEBUG ++#define debug(args...) printk(args) ++#else /* DEBUG */ ++#define debug(args...) ++#endif /* DEBUG */ ++ ++/*---------[ declarations ]-----------------*/ ++ ++#ifdef CONFIG_MIPS_MTX1 ++ ++//#define SLIC_D0 (AU1500_GPIO_205) /* D0 - D3 */ ++//#define SLIC_D1 (AU1500_GPIO_206) ++//#define SLIC_D2 (AU1500_GPIO_208) ++//#define SLIC_PD (AU1500_GPIO_209) /* Power down */ ++#define SLIC_D0_GPIO (5) ++#define SLIC_D1_GPIO (6) ++#define SLIC_D2_GPIO (8) ++#define SLIC_PD_GPIO (9) ++#define SLIC_OH (AU1000_GPIO_8) /* Off hook */ ++#define SLIC_OH_GPIO (8) /* GPIO-pin */ ++#define SLIC_D0 (AU1500_GPIO_205) /* D0 - D3 */ ++#define SLIC_D1 (AU1500_GPIO_206) ++#define SLIC_D2 (AU1500_GPIO_208) ++#define SLIC_PD (AU1500_GPIO_209) /* Power down */ ++#define SLIC_DP_DIR (GPIO2_DIR) /* Direction-register */ ++#define SLIC_DP_OUT (GPIO2_OUTPUT) /* Output-register */ ++#define SLIC_DP_PINSTATE (GPIO2_PINSTATE) /* Input-register */ ++ ++inline void gpio_init(void) { ++ au_writel(au_readl(SYS_TRIOUTCLR) & ~SLIC_OH_GPIO, SYS_TRIOUTCLR); // SLIC_OH_GPIO as tristate ++ au_writel((au_readl(SLIC_DP_DIR) | ((1 << SLIC_PD_GPIO)|(1 << SLIC_D0_GPIO)|(1 << SLIC_D1_GPIO)|(1 << SLIC_D2_GPIO))), SLIC_DP_DIR); ++} ++ ++inline void gpio_write(unsigned short bitmask, unsigned short value) { ++ au_writel((bitmask << 16) | value, SLIC_DP_OUT); ++} ++inline short gpio_read(unsigned short pin) { ++ return (au_readl(SLIC_DP_PINSTATE) >> pin) & 1; ++} ++ ++inline short gpio2_read(unsigned short pin) { ++ return (au_readl(SYS_PINSTATERD) >> pin) & 1; ++} ++#elif defined CONFIG_MIPS_MTX2 ++ ++//#define SLIC_D0 (AU1000_GPIO_10) /* D0 - D3 */ ++//#define SLIC_D1 (AU1000_GPIO_11) ++//#define SLIC_D2 (AU1000_GPIO_12) ++//#define SLIC_PD (AU1000_GPIO_13) /* Power down */ ++#define SLIC_D0_GPIO (10) /* GPIO-pins */ ++#define SLIC_D1_GPIO (11) ++#define SLIC_D2_GPIO (12) ++#define SLIC_PD_GPIO (13) ++ ++#define SLIC_OH (AU1000_GPIO_9) /* Off hook */ ++#define SLIC_OH_GPIO (9) /* GPIO-pin */ ++ ++inline void gpio_init(void) { ++ au_writel(au_readl(SYS_PINFUNC) & ~SYS_PF_U3, SYS_PINFUNC); // configure GPIO9-14 as GPIO ++ au_writel(1<>pin) & 1; ++} ++ ++inline short gpio2_read(unsigned short pin) { ++ return (au_readl(SYS_PINSTATERD)>>pin) & 1; ++} ++#else ++#error Cannot find hardware platform ++#endif ++ ++ ++/* States of SLIC-device, set via PD- and Dx-Pins */ ++/* ---------------------------------------------- */ ++#define SLIC_BITMASK ((1 << SLIC_PD_GPIO)|(1 << SLIC_D0_GPIO)|(1 << SLIC_D1_GPIO)|(1 << SLIC_D2_GPIO)) ++/* Hi-Z-state, for onhook-condition, only detects offhook-event, minimum power-usage */ ++#define SLIC_STATE_IDLE (1 << SLIC_PD_GPIO) ++/* Active-state, for offhook-condition and other states where phone needs to be powered */ ++#define SLIC_STATE_ACTIVE ((1 << SLIC_PD_GPIO)|(1 << SLIC_D1_GPIO)) ++/* Active-state with reverse polarity */ ++#define SLIC_STATE_REVERSE ((1 << SLIC_PD_GPIO)|(1 << SLIC_D1_GPIO)|(1 << SLIC_D2_GPIO)) ++/* Ringing-state */ ++#define SLIC_STATE_RINGING ((1 << SLIC_PD_GPIO)|(1 << SLIC_D0_GPIO)) ++/* Powerdown-state */ ++#define SLIC_STATE_POWERDOWN (0) ++ ++#define SLIC_SET_STATE(x) do { \ ++ current_state = x; \ ++ gpio_write(SLIC_BITMASK, x); \ ++ } while (0) ++ ++enum Slic_State { ONHOOK, OFFHOOK }; ++ ++enum Event { evONHOOK, evOFFHOOK, evFLASH }; ++ ++static DECLARE_WAIT_QUEUE_HEAD(slic_wait_queue); ++static int slic_minor = -1; ++static char is_inuse = 0; ++static char state_changed = 0; ++static enum Event last_value = 0; ++static unsigned long event_time = 0; ++static enum Slic_State event_value = 0; ++static u32 current_state = 0; ++static char active_reverse = 0; ++ ++/* Timer-stuff */ ++static char restart_timer = 1; /* Bool, if true, timer will be restarted by timer-function. */ ++static char timer_started = 0; /* Bool, if true, timer was added. */ ++static struct timer_list slic_ring_timer; ++static struct timer_list slic_timer; ++ ++#define RING_TIMER_INTERVALL (HZ/50) /* 25 Hz */ ++#define RINGOFF_TIME (4*HZ) ++#define RINGON_TIME (1*HZ) ++ ++static void irq_taskletFunc(unsigned long dummy); ++DECLARE_TASKLET(irq_tasklet, irq_taskletFunc, (unsigned long)&state_changed); ++ ++enum Timer_Task { DEBOUNCE_ONHOOK, DETECT_FLASH_MIN, DETECT_FLASH_MAX, POWERON }; ++ ++inline enum Slic_State get_current_slic_state(void) { ++ return gpio2_read(SLIC_OH_GPIO) ? ONHOOK : OFFHOOK; ++} ++ ++#define DEBOUNCE_TIME 200 ++#define FLASH_MIN_TIME 170 ++#define FLASH_MAX_TIME 310 ++#define POWERON_TIME 200 ++ ++unsigned int flash_min_t = FLASH_MIN_TIME; ++unsigned int flash_max_t = FLASH_MAX_TIME; ++ ++ ++static void slic_start_timer (unsigned long time_base, unsigned int timeout, enum Timer_Task timer_task ); ++ ++/*---------[ Timer functions ]--------------------*/ ++ ++/* The timer is used to toggle the d2-pin with 25 Hz. This generates the ++ ring-tone in the phone. */ ++ ++static unsigned long ringtone = 0; ++static unsigned long ringpause = RINGOFF_TIME; ++static unsigned long ringsignal = RINGON_TIME; ++ ++static void slic_do_ring (unsigned long data) ++{ ++ /* Debug-output */ ++ /* ++ static int count = 0; ++ if (((++count) % 50) == 0) ++ debug("."); ++ */ ++ ++ /* Toggle d2-pin */ ++ u32 tmp = gpio_read(SLIC_D2_GPIO); ++ gpio_write((1 << SLIC_D2_GPIO), (tmp ? 0 : 1) << SLIC_D2_GPIO); ++ ++ if (restart_timer) { ++ if ( jiffies use an event queue to deliver ++ // events in sequence !! ++ debug("event: %i\n", ev); ++ last_value = ev; ++ state_changed = 1; ++ wake_up (&slic_wait_queue); ++} ++ ++// timeout in ms ; if timebase is 0 timeout is increased, otherwise absolute time_base+timeout is used ++static void slic_start_timer (unsigned long time_base, unsigned int timeout, enum Timer_Task timer_task ) ++{ ++ if ( time_base == 0 ) ++ slic_timer.expires += (timeout * HZ)/ 1000; ++ else ++ slic_timer.expires = time_base + (timeout * HZ)/ 1000; ++ slic_timer.data = (unsigned long) timer_task; ++ add_timer(&slic_timer); ++} ++ ++// timer used for - debouncing offhook (setting slic active, results in a onhook offhook irq) ++// - distinguish between onhook and flash ++static void slic_do_timer (unsigned long timer_task) { ++ enum Slic_State current = get_current_slic_state(); ++ int done = 0; ++ ++ switch ( timer_task ) { ++ case DEBOUNCE_ONHOOK: ++ if ( current == OFFHOOK ) { ++ // done, stable onhook state reached ++ done = 1; ++ } else { // current == ONHOOK ++ slic_start_timer(0, flash_min_t, DETECT_FLASH_MIN); ++ } ++ break; ++ case DETECT_FLASH_MIN: ++ if ( current == ONHOOK ) { ++ slic_start_timer(0, flash_max_t - flash_min_t, DETECT_FLASH_MAX); ++ } else { // current == OFFHOOK ++ // offhook too short for flash, ignore ++ done = 1; ++ } ++ break; ++ case DETECT_FLASH_MAX: ++ if ( current == ONHOOK ) { ++ // off-hook state reached ++ slic_idle(); ++ generate_event(evONHOOK); ++ done = 1; ++ } else { // current == OFFHOOK ++ // flash signal detected ++ generate_event(evFLASH); ++ done = 1; ++ } ++ break; ++ case POWERON: ++ if ( current == ONHOOK ) { ++ done = 1; // power on event 'debounced' ++ } else if ( current == OFFHOOK ) { ++ // probably we were off-hook when activating the slic; go off-hook now ++ slic_active(); ++ generate_event(evOFFHOOK); ++ slic_start_timer(event_time, DEBOUNCE_TIME, DEBOUNCE_ONHOOK); ++ } ++ } ++ ++ if ( done ) { ++ //re-enable irq and be careful to not loose a state change ++ event_time = 0; ++ if ( current != get_current_slic_state() && event_time==0 ) { ++ event_time = jiffies; ++ event_value = get_current_slic_state(); ++ tasklet_schedule(&irq_tasklet); ++ } ++ } ++} ++ ++static void irq_taskletFunc(unsigned long dummy) ++{ ++ if ( (current_state == SLIC_STATE_IDLE || current_state == SLIC_STATE_RINGING) && ++ event_value == OFFHOOK ) { ++ slic_active(); ++ generate_event(evOFFHOOK); ++ slic_start_timer(event_time, DEBOUNCE_TIME, DEBOUNCE_ONHOOK); ++ } else if ( ( current_state == SLIC_STATE_ACTIVE || current_state == SLIC_STATE_REVERSE ) && ++ event_value == ONHOOK ) { ++ slic_start_timer(event_time, flash_min_t, DETECT_FLASH_MIN); ++ } else { ++ // ignore event ++ event_time = 0; ++ } ++} ++ ++/* The interrupt is raised by a state-change on the DET-pin. This signals an ++ offhook-condition on the phone. */ ++static void slic_irq (int irq, void *private, struct pt_regs *regs) ++{ ++ if ( !event_time ) { ++ event_time = jiffies; ++ event_value = get_current_slic_state(); ++ tasklet_schedule(&irq_tasklet); ++ } ++} ++ ++static int slic_startirq (void) ++{ ++ if (request_irq(SLIC_OH, slic_irq, SA_INTERRUPT, "slic", (void *) &state_changed) < 0) { ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int slic_stopirq (void) ++{ ++ free_irq (SLIC_OH, (void *) &state_changed); ++ return 0; ++} ++ ++/*---------[ File Functions ]-----------------*/ ++ ++static int slic_open (struct inode *inode, struct file *file) ++{ ++ if (MINOR(inode->i_rdev) != slic_minor) ++ return -ENODEV; ++ if (is_inuse) ++ return -EBUSY; ++ is_inuse = 1; ++ state_changed = 0; ++ MOD_INC_USE_COUNT; ++ return 0; ++} ++ ++static int slic_release (struct inode *inode, struct file *file) ++{ ++ if (MINOR(inode->i_rdev) == slic_minor) { ++ is_inuse = 0; ++ } ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++static ssize_t slic_read (struct file *file, char *buf, size_t count, loff_t *ppos) ++{ ++ if (count < 1) ++ return -EINVAL; ++ if (!state_changed) ++ interruptible_sleep_on (&slic_wait_queue); ++ ++ state_changed = 0; ++ if (copy_to_user(buf, &last_value, 1)) { ++ return -EFAULT; ++ } ++ return 1; ++} ++ ++/* The SLIC is controlled with 2-byte commands. The first byte selects the type ++ of the command, the second is an additional parameter or ignored. */ ++static ssize_t slic_write (struct file *file, const char *buf, size_t count, loff_t *ppos) ++{ ++ char localbuff[2]; ++ size_t bytes_read = 0; ++ if (count < 2 || (count % 2)) ++ return -EINVAL; ++ while (bytes_read < count) { ++ if (copy_from_user(localbuff, buf + bytes_read, 2)) ++ return -EFAULT; ++ bytes_read += 2; ++ debug("SLIC: "); ++ switch (localbuff[0]) { ++ case 'P': ++ /* Power-command */ ++ if (localbuff[1] == '0') { ++ debug("Power off\n"); ++ slic_power_off(); ++ } else { ++ debug("Power on\n"); ++ slic_power_on(); ++ } ++ break; ++ case 'R': ++ /* Ring-command */ ++ if (localbuff[1] == '0') { ++ debug("Ring off\n"); ++ slic_ring_off(); ++ } else { ++ debug("Ring on\n"); ++ slic_ring_on(); ++ } ++ break; ++ case 'M': ++ /* Mode-command: 0 - active standard mode, 1 - active reverse mode */ ++ if (localbuff[1] == '0') { ++ debug("Active default\n"); ++ active_reverse = 0; ++ if ( current_state == SLIC_STATE_REVERSE ) ++ slic_active(); ++ } else { ++ debug("Active reverse default\n"); ++ active_reverse = 1; ++ if ( current_state == SLIC_STATE_ACTIVE ) ++ slic_active(); ++ } ++ break; ++ ++#ifdef DEBUG ++ case 'A': ++ /* Active-command */ ++ debug("Active\n"); ++ slic_active(); ++ break; ++ case 'I': ++ /* Idle-command */ ++ debug("Idle\n"); ++ slic_idle(); ++ break; ++ case 'T': ++ /* Test-command */ ++ debug("Test %c\n", localbuff[1]); ++ slic_test(localbuff[1]); ++ break; ++#endif ++ default: ++ return -EFAULT; ++ } ++ } ++ return count; /* Everything read */ ++} ++ ++static int ++slic_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ // don't using file information for now; only one slic supported ++ int ret = 0; ++ ++ /* ++ * extract the type and number bitfields, and don't decode ++ * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok() ++ */ ++ if (_IOC_TYPE(cmd) != SLIC_IOC_MAGIC) return -ENOTTY; ++ if (_IOC_NR(cmd) > SLIC_IOC_MAXNR) return -ENOTTY; ++ ++ switch (cmd) { ++ case IOC_SLIC_POWER: ++ /* Power-command */ ++ if ( arg ) { ++ debug("Power on\n"); ++ slic_power_on(); ++ } else { ++ debug("Power off\n"); ++ slic_power_off(); ++ } ++ break; ++ case IOC_SLIC_RING: ++ /* Ring-command */ ++ if ( arg ) { ++ debug("Ring on\n"); ++ slic_ring_on(); ++ } else { ++ debug("Ring off\n"); ++ slic_ring_off(); ++ } ++ break; ++ case IOC_SLIC_MODE: ++ /* Mode-command: 0 - active standard mode, 1 - active reverse mode */ ++ if ( arg ) { ++ debug("Active reverse default\n"); ++ active_reverse = 1; ++ if ( current_state == SLIC_STATE_ACTIVE ) ++ slic_active(); ++ } else { ++ debug("Active default\n"); ++ active_reverse = 0; ++ if ( current_state == SLIC_STATE_REVERSE ) ++ slic_active(); ++ } ++ break; ++ case IOC_SLIC_HOOKFLASH: ++ /* set hook-flash time */ ++ { ++ int min = arg & 0xffff; ++ int max = arg>>16; ++ if ( min= 20 && max <= 1000 ) { ++ flash_min_t = min; ++ flash_max_t = max; ++ } else { ++ ret = -EINVAL; ++ } ++ } ++ break; ++ ++#ifdef DEBUG ++ case IOC_SLIC_TEST: ++ /* Test-command */ ++ debug("Test %li\n", arg & SLIC_BITMASK); ++ SLIC_SET_STATE(arg); ++ break; ++#endif ++ default: ++ ret = -ENOTTY; ++ } ++ ++ return ret; ++} ++ ++static unsigned int slic_poll (struct file *file, poll_table * wait) ++{ ++ unsigned int mask = 0; ++ ++ poll_wait (file, &slic_wait_queue, wait); ++ if (state_changed) /* state changed since last time. */ ++ mask |= POLLIN | POLLRDNORM; ++ return mask; ++} ++ ++/*---------[ Module stuff ]-----------------*/ ++ ++static struct file_operations slic_fops = { ++ .owner = THIS_MODULE, ++ .llseek = NULL, ++ .read = slic_read, ++ .write = slic_write, ++ .readdir = NULL, ++ .poll = slic_poll, ++ .ioctl = slic_ioctl, ++ .mmap = NULL, ++ .open = slic_open, ++ .flush = NULL, ++ .release = slic_release ++}; ++ ++static struct miscdevice slic_miscdev = { ++ MISC_DYNAMIC_MINOR, ++ "slic", ++ &slic_fops ++}; ++ ++void __exit slic_cleanup (void) ++{ ++ is_inuse = 1; ++ slic_stop_ring_timer(); ++ slic_stopirq(); ++ misc_deregister(&slic_miscdev); ++} ++ ++int __init slic_init (void) ++{ ++ printk("Surfbox2 SLIC driver\n"); ++ debug(" with debug\n"); ++ ++ is_inuse = 1; ++ ++ // prepare time for handling RING ++ init_timer(&slic_ring_timer); ++ slic_ring_timer.function = slic_do_ring; ++ slic_ring_timer.data = 0; ++ ++ // prepare time for onhook/offhook debounce and flash detection ++ init_timer(&slic_timer); ++ slic_timer.function = slic_do_timer; ++ slic_timer.data = 0; ++ ++ /* Set GPIOs for Dx- and PD-pins as output */ ++ gpio_init(); ++ ++ /* Set initial state */ ++ slic_power_off(); ++ ++ /* Register device */ ++ if (misc_register(&slic_miscdev) >= 0) { ++ slic_minor = slic_miscdev.minor; ++ if (slic_startirq () == 0) { ++ /* Everything fine */ ++ is_inuse = 0; ++ return 0; ++ } ++ /* Error */ ++ misc_deregister(&slic_miscdev); ++ } ++ return 1; ++} ++ ++module_init(slic_init); ++module_exit(slic_cleanup); ++ ++MODULE_AUTHOR("Ingo Salzmann"); ++MODULE_DESCRIPTION("Driver for MTX SLIC"); ++MODULE_LICENSE("GPL"); ++EXPORT_NO_SYMBOLS; +--- linux-org/include/linux/slic.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux/include/linux/slic.h 2006-06-20 13:46:05.321244750 +0200 +@@ -0,0 +1,41 @@ ++/** ++ * @file slic.h ++ * @author Thomas Geffert ++ * @date Tue Jun 20 13:22:01 2006 ++ * ++ * @brief Some ioctl declarations for the mtx slic driver ++ * ++ * ++ */ ++ ++/* ++ * (c) COPYRIGHT 2006 by 4G Systems GmbH Germany ++ * All rights reserved. ++ */ ++ ++ ++#ifndef SLIC__H__ ++#define SLIC__H__ ++ ++#define SLIC_IOC_MAGIC 0xC1 /// an arbitrary number for identifying slic ioctls ++ ++// ioctl argument: arg == 0 -> power off, arg == 1 -> power on ++#define IOC_SLIC_POWER _IOW(SLIC_IOC_MAGIC, 0x00, unsigned int) ++ ++// ioctl argument: arg == 0 -> ring off, arg == 1 -> ring on ++#define IOC_SLIC_RING _IOW(SLIC_IOC_MAGIC, 0x01, unsigned int) ++ ++// ioctl argument: arg == 0 -> active, arg == 1 -> active reverse ++#define IOC_SLIC_MODE _IOW(SLIC_IOC_MAGIC, 0x02, unsigned int) ++ ++// ioctl argument: set hook-flash time; arg&0xffff is min time in ms, arg>>16 is max time in ms ++// 20 <= min < max <= 1000 ++#define IOC_SLIC_HOOKFLASH _IOW(SLIC_IOC_MAGIC, 0x04, unsigned int) ++ ++// ioctl argument: write arg to slic register ; only available if slic driver compiled with DEBUG ++#define IOC_SLIC_TEST _IOW(SLIC_IOC_MAGIC, 0x03, unsigned int) ++ ++#define SLIC_IOC_MAXNR 0x04 /// max number of supported ioctl calls ++ ++ ++#endif /* SLIC__H__ */ diff --git a/packages/linux/linux-mtx-2-2.4.27/36-sb2-lcd.patch b/packages/linux/linux-mtx-2-2.4.27/36-sb2-lcd.patch new file mode 100644 index 0000000000..cd56e5837f --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/36-sb2-lcd.patch @@ -0,0 +1,465 @@ +--- linux-old/arch/mips/au1000/mtx-2/lcd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/arch/mips/au1000/mtx-2/lcd.c 2006-04-30 19:43:48.070431000 +0200 +@@ -0,0 +1,423 @@ ++/* ++ * Driver for the KS0713 LCD controller ++ * ++ * Loading the module will cause DEVFS to create the device file /dev/misc/lcd, ++ * which can be written to to control the display. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++/*---------[ declarations ]-----------------*/ ++ ++#if !defined(LCD_PLATFORM) ++# define LCD_PLATFORM SURFBOX2 ++#endif ++ ++#define BLA(X) #X ++#define BLA2(X) BLA(X) ++ ++static enum lcd_platform lcd_platform = LCD_PLATFORM; ++MODULE_PARM(lcd_platform, "i"); ++MODULE_PARM_DESC(lcd_platform, "The platform we are on (default " BLA2(LCD_PLATFORM) ")"); ++ ++static enum lcd_mode lcd_mode = COMMAND; ++MODULE_PARM(lcd_mode, "i"); ++MODULE_PARM_DESC(lcd_mode, "The intial mode (default COMMAND)"); ++ ++static char lcd_use_dle = 0; ++MODULE_PARM(lcd_use_dle, "b"); ++MODULE_PARM_DESC(lcd_use_dle, "Use DLE escapes (default no)"); ++ ++#define DLE 0x10 ++ ++static int lcd_minor = -1; ++static char is_inuse = 0; ++ ++#define SBOX1_LCD_BACKLIGHT (1<<27) // GPIO27 ++#define SBOX2_LCD_BACKLIGHT (1<<14) // GPIO14 ++ ++#define KS0713_BITMASK (0x1F << 10) /* GPIOs start at GPIO_10 */ ++#define SBOX1_BITMASK ((0x1F << 10) | (3 << 25)) /* two GPIO blocks */ ++#define SBOX2_BITMASK1 (1) /* GPIO 1 */ ++#define SBOX2_BITMASK2 ((1 << 3) | (0x1F << 6)) /* GPIO 2 */ ++ ++/*---------[ Internal Functions ]-------------*/ ++ ++/* Layer 0 */ ++ ++static void set_backlight(const char on) ++{ ++ if (lcd_platform == SURFBOX1) ++ au_writel(SBOX1_LCD_BACKLIGHT, on ? SYS_OUTPUTSET : SYS_OUTPUTCLR); ++ else if (lcd_platform == SURFBOX2) ++ au_writel(SBOX2_LCD_BACKLIGHT, on ? SYS_OUTPUTSET : SYS_OUTPUTCLR); ++} ++ ++static inline void write_gpio1(const unsigned int line, ++ const unsigned int mask) ++{ ++ const u32 reg = line & mask; ++ const u32 neg = (~reg) & mask; ++ au_writel(neg, SYS_OUTPUTCLR); ++ au_writel(reg, SYS_OUTPUTSET); ++} ++ ++static inline void write_gpio2(const unsigned int line, ++ const unsigned int mask) ++{ ++ au_writel((mask&0xffff) << 16 | (line&0xffff), GPIO2_OUTPUT); ++} ++ ++static inline void write_flags(const int reset, const int cs, const int rs, ++ const int clock, const int data) ++{ ++ switch (lcd_platform) { ++ case KS0713: ++ write_gpio1((!reset) << 14 | cs << 13 | rs << 12 | ++ clock << 11 | data << 10, KS0713_BITMASK); ++ break; ++ case SURFBOX1: ++ write_gpio1(rs << 25 | cs << 14 | !cs << 13 | 1 << 12 | ++ data << 11 | clock << 10, SBOX1_BITMASK); ++ break; ++ case SURFBOX2: ++ write_gpio1(0, SBOX2_BITMASK1); ++ write_gpio2(rs << 3 | cs << 7 | !cs << 6 | 0 << 8 | ++ data << 9 | clock << 10, SBOX2_BITMASK2); ++ break; ++ } ++} ++ ++/* Layer 1 */ ++ ++static inline void write_line(unsigned int line) ++{ ++ if (lcd_platform == KS0713) { ++ write_gpio1(line << 10, KS0713_BITMASK); ++ } else if (lcd_platform == SURFBOX1) { ++ const int hi = line >> 5; ++ line &= 0x1f; ++ write_gpio1(line << 10 | hi << 25, SBOX1_BITMASK | SBOX1_LCD_BACKLIGHT); ++ } else if (lcd_platform == SURFBOX2) { ++ int bm0 = line&1; ++ int bl = (line>>1)&1; ++ int cd = (line>>2)&1; ++ int rest = (line>>3)&0x1f; ++ write_gpio1(bm0 | bl<<14, SBOX2_BITMASK1 | SBOX2_LCD_BACKLIGHT); ++ write_gpio2(rest<<6 | cd<<3, SBOX2_BITMASK2); ++ } ++} ++ ++static inline void release(void) ++{ ++ return write_flags(0, 0, 0, 0, 0); ++} ++ ++static inline void reset(void) ++{ ++ return write_flags(1, 0, 0, 0, 0); ++} ++ ++static void init_gpios(void) ++{ ++ switch (lcd_platform) { ++ case KS0713: ++ // TODO: init lines? ++ release(); ++ break; ++ case SURFBOX1: ++ if (lcd_mode == I2C) ++ write_gpio1(1 << 26 | 1 << 12 | 1 << 11 | 1 << 10, SBOX1_BITMASK); ++ else ++ release(); ++ break; ++ case SURFBOX2: ++ au_writel(au_readl(GPIO2_DIR) | SBOX2_BITMASK2, GPIO2_DIR); ++ // au_writel(PSC_SEL_PS_DISABLED, PSC2_BASE_ADDR + PSC_CTRL_OFFSET); ++ au_writel(au_readl(SYS_PINFUNC) | SYS_PF_PSC2_GPIO, SYS_PINFUNC); ++ release(); ++ break; ++ } ++} ++ ++static inline void write_bit(const int rs, const int bit) ++{ ++ /* Data is read on the rising edge */ ++ write_flags(0, 1, rs, 0, bit); ++ write_flags(0, 1, rs, 1, bit); ++ if (lcd_platform != KS0713 && rs == LCD_RS_DATA) { ++ write_flags(0, 1, rs, 0, bit); ++ write_flags(0, 1, rs, 1, bit); ++ } ++} ++ ++/* Layer 2 */ ++ ++static inline void write_byte(const int rs, const int byte) ++{ ++ int i; ++ for (i = 7; i >= 0; i--) ++ write_bit(rs, (byte >> i) & 1); ++} ++ ++DECLARE_WAIT_QUEUE_HEAD(lcd_sleep_q); ++ ++static inline void sleep (long jiff) ++{ ++ const long j = jiffies + jiff; ++ while (jiffies < j) ++ interruptible_sleep_on_timeout(&lcd_sleep_q, j - jiffies); ++} ++ ++static inline void ctrl_init(void) ++{ ++ switch (lcd_platform) { ++ case KS0713: ++ reset(); ++ sleep(1L); ++ release(); ++ sleep(1L); ++ // TODO: write_byte (LCD_RS_COMMAND, cmd|arg) ++/* do_command(fd, LCD_CMD_DISPSTART, 0, 0); */ ++/* do_command(fd, LCD_CMD_DISPONOFF, 1, 0); */ ++/* do_command(fd, LCD_CMD_ENTIREDISP, 0, 0); */ ++/* do_command(fd, LCD_CMD_SHLSELECT, 0, 0); */ ++/* do_command(fd, LCD_CMD_ADCSELECT, 1, 0); */ ++/* do_command(fd, LCD_CMD_REFVOLTMODE, 0, 0); */ ++/* do_command(fd, 0, 40, 0); */ ++/* do_command(fd, LCD_CMD_LCDBIAS, 1, 0); */ ++/* do_command(fd, LCD_CMD_POWERCTRL, 7, 0); */ ++/* do_command(fd, LCD_CMD_REGRESISTOR, 6, 1); */ ++ release(); ++ sleep(1L); ++ break; ++ case SURFBOX1: ++ case SURFBOX2: ++ write_byte (LCD_RS_COMMAND, 0xe2); // RESET ++ release(); ++ sleep(1L); ++ write_byte (LCD_RS_COMMAND, 0x81); // Vbias potentiometer ++ write_byte (LCD_RS_COMMAND, 0x1c); // set to 28 (conf?) ++ write_byte (LCD_RS_COMMAND, 0xad); // ON, b/w ++ release(); ++ set_backlight(1); ++ break; ++ } ++} ++ ++/* Layer i */ ++ ++static int dle = 0; ++ ++static inline void handle_input (const unsigned char byte) ++{ ++ if (dle) { ++ switch (byte) { ++ case DLE: ++ write_line (DLE); ++ break; ++ case 'B': /* backlight on */ ++ set_backlight(1); ++ break; ++ case 'b': /* backlight off */ ++ set_backlight(0); ++ break; ++ case 'r': /* reset */ ++ reset(); ++ break; ++ case 'l': /* release */ ++ release(); ++ break; ++ case 'i': /* init */ ++ ctrl_init(); ++ break; ++ case 's': /* serial mode */ ++ lcd_mode = SERIAL; ++ break; ++ case 'c': /* command mode */ ++ lcd_mode = COMMAND; ++ break; ++ case 'd': /* data mode */ ++ lcd_mode = DATA; ++ break; ++ case '3': /* select mode by number */ ++ case '2': ++ case '1': ++ case '0': ++ lcd_mode = (enum lcd_mode) (byte - '0'); ++ break; ++ case 'e': /* stop dle mode, reversable by ioctl only */ ++ lcd_use_dle = 0; ++ break; ++ } ++ dle = 0; ++ } else if (lcd_use_dle && byte == DLE) { ++ dle = 1; ++ } else switch (lcd_mode) { ++ case COMMAND: ++ write_byte (LCD_RS_COMMAND, byte); ++ break; ++ case DATA: ++ write_byte (LCD_RS_DATA, byte); ++ break; ++ case SERIAL: ++ case I2C: ++ write_line (byte); ++ break; ++ } ++} ++ ++/*---------[ File Functions ]-----------------*/ ++ ++static int lcd_open (struct inode *inode, struct file *file) ++{ ++ if (MINOR(inode->i_rdev) != lcd_minor) ++ return -ENODEV; ++ if (is_inuse) ++ return -EBUSY; ++ is_inuse = 1; ++ MOD_INC_USE_COUNT; ++ return 0; ++} ++ ++static int lcd_release (struct inode *inode, struct file *file) ++{ ++ if (MINOR(inode->i_rdev) == lcd_minor) { ++ is_inuse = 0; ++ } ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++static ssize_t lcd_write (struct file *file, const char *buf, ++ size_t count, loff_t *ppos) ++{ ++ unsigned char localbuf; ++ ssize_t bytes_read = 0; ++ while (bytes_read < count) { ++ if (copy_from_user(&localbuf, buf + bytes_read, 1)) ++ return -EFAULT; ++ ++bytes_read; ++ handle_input(localbuf); ++ } ++ return bytes_read; /* Everything read */ ++} ++ ++static int lcd_ioctl (struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ switch (cmd) { ++ case LCD_IOCRESET: ++ reset(); ++ break; ++ case LCD_IOCRELEASE: ++ release (); ++ break; ++ case LCD_IOCSMODE: ++ lcd_mode = (enum lcd_mode) arg; ++ break; ++ case LCD_IOCGMODE: ++ return __put_user(lcd_mode, (enum lcd_mode *) arg); ++ case LCD_IOCSUSEDLE: ++ lcd_use_dle = (char) arg; ++ break; ++ case LCD_IOCGUSEDLE: ++ return __put_user(lcd_use_dle, (char *) arg); ++ case LCD_IOCCOMMAND: ++ write_byte (LCD_RS_COMMAND, arg); ++ break; ++ case LCD_IOCINIT: ++ ctrl_init(); ++ break; ++ case LCD_IOCSBACKLIGHT: ++ set_backlight((char) arg); ++ break; ++ case LCD_IOCGPLATFORM: ++ return __put_user(lcd_platform, (enum lcd_platform *) arg); ++ break; ++ ++ default: ++ return -ENOTTY; /* sic! "inappropiate ioctl for device" */ ++ } ++ return 0; ++} ++ ++/*---------[ Module stuff ]-----------------*/ ++ ++static struct file_operations lcd_fops = { ++ .owner = THIS_MODULE, ++ .llseek = NULL, ++ .read = NULL, ++ .write = lcd_write, ++ .readdir = NULL, ++ .poll = NULL, ++ .ioctl = lcd_ioctl, ++ .mmap = NULL, ++ .open = lcd_open, ++ .flush = NULL, ++ .release = lcd_release ++}; ++ ++static struct miscdevice lcd_miscdev = { ++ MISC_DYNAMIC_MINOR, ++ "lcd", ++ &lcd_fops ++}; ++ ++int __init lcd_init (void) ++{ ++ is_inuse = 1; ++ printk(KERN_INFO "Surfbox2 LCD driver ..."); ++ ++ init_gpios(); ++ //au_writel( 0x12000000 & LCD_BITMASK, SYS_OUTPUTCLR ); ++ //au_writel( 0x0c000000, SYS_OUTPUTSET ); /* Magic GPIO to activate LED-driver */ ++ ++ /* Register device */ ++ if (misc_register(&lcd_miscdev) >= 0) { ++ lcd_minor = lcd_miscdev.minor; ++ printk(" successfully loaded (platform=%d,mode=%d,dle=%d).\n", ++ lcd_platform, lcd_mode, lcd_use_dle); ++ is_inuse = 0; ++ return 0; ++ } else { ++ printk("failed.\n"); ++ is_inuse = 0; ++ return 1; ++ } ++} ++ ++void __exit lcd_cleanup (void) ++{ ++ is_inuse = 1; ++ misc_deregister(&lcd_miscdev); ++ printk(KERN_INFO "Surfbox (%d) LCD driver unloaded (mode=%d,dle=%d).\n", ++ lcd_platform, lcd_mode, lcd_use_dle); ++ is_inuse = 0; ++} ++ ++module_init(lcd_init); ++module_exit(lcd_cleanup); ++ ++MODULE_AUTHOR("Simon Krahnke"); ++MODULE_DESCRIPTION("Driver for MTX LCD"); ++MODULE_LICENSE("GPL"); ++EXPORT_NO_SYMBOLS; +--- linux-old/include/linux/lcd-driver.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux/include/linux/lcd-driver.h 2006-04-30 19:44:02.035303750 +0200 +@@ -0,0 +1,26 @@ ++#if !defined(LCD_DRIVER_H) ++#define LCD_DRIVER_H ++ ++enum lcd_platform { KS0713 = 0, SURFBOX1, SURFBOX2 }; ++ ++enum lcd_mode { SERIAL = 0, COMMAND, DATA, I2C }; ++ ++#define LCD_RS_COMMAND 0 ++#define LCD_RS_DATA 1 ++ ++/* We use the available magic L with number 0x40-0x4f */ ++ ++#define LCD_IOC_MAGIC 'L' ++ ++#define LCD_IOCRESET _IO(LCD_IOC_MAGIC, 0x40) ++#define LCD_IOCRELEASE _IO(LCD_IOC_MAGIC, 0x41) ++#define LCD_IOCSMODE _IOW(LCD_IOC_MAGIC, 0x42, enum lcd_mode) ++#define LCD_IOCGMODE _IOR(LCD_IOC_MAGIC, 0x43, enum lcd_mode*) ++#define LCD_IOCSUSEDLE _IOW(LCD_IOC_MAGIC, 0x44, char) ++#define LCD_IOCGUSEDLE _IOR(LCD_IOC_MAGIC, 0x45, char*) ++#define LCD_IOCCOMMAND _IOW(LCD_IOC_MAGIC, 0x46, unsigned char) ++#define LCD_IOCINIT _IO(LCD_IOC_MAGIC, 0x47) ++#define LCD_IOCSBACKLIGHT _IOW(LCD_IOC_MAGIC, 0x48, char) ++#define LCD_IOCGPLATFORM _IOR(LCD_IOC_MAGIC, 0x49, enum lcd_platform*) ++ ++#endif /* LCD_DRIVER_H */ +--- linux/arch/mips/au1000/mtx-2/Makefile.org 2006-05-01 13:36:01.675030000 +0200 ++++ linux/arch/mips/au1000/mtx-2/Makefile 2006-05-01 13:36:11.175623750 +0200 +@@ -15,6 +15,6 @@ + + O_TARGET := mtx-2.o + +-obj-y := init.o board_setup.o irqmap.o slic.o ++obj-y := init.o board_setup.o irqmap.o slic.o lcd.o + + include $(TOPDIR)/Rules.make diff --git a/packages/linux/linux-mtx-2-2.4.27/37-sb2-sysbtn.patch b/packages/linux/linux-mtx-2-2.4.27/37-sb2-sysbtn.patch new file mode 100644 index 0000000000..9936721672 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/37-sb2-sysbtn.patch @@ -0,0 +1,246 @@ +--- linux/arch/mips/au1000/mtx-2/Makefile.org 2006-05-29 10:45:47.702096500 +0200 ++++ linux/arch/mips/au1000/mtx-2/Makefile 2006-05-29 10:46:05.643217750 +0200 +@@ -15,6 +15,6 @@ + + O_TARGET := mtx-2.o + +-obj-y := init.o board_setup.o irqmap.o slic.o lcd.o ++obj-y := init.o board_setup.o irqmap.o slic.o lcd.o pollbtn.o + + include $(TOPDIR)/Rules.make +--- linux/arch/mips/au1000/mtx-2/pollbtn.c.org 1970-01-01 01:00:00.000000000 +0100 ++++ linux/arch/mips/au1000/mtx-2/pollbtn.c 2006-05-29 10:42:53.071182750 +0200 +@@ -0,0 +1,233 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int mtx_btn_ms = 100; ++MODULE_PARM(mtx_btn_ms, "i"); ++MODULE_PARM_DESC(mtx_btn_ms, "The time in ms to wait between polls (default 100)"); ++ ++/* Bitposition of button in GPIO-byte */ ++#define SB2_BTNPOWER_GPIO (11) ++#define SB2_BTNRESET_GPIO (12) /* The MTX-1 Button is attached to GPIO207. */ ++#define SB2_BTNCONNECT_GPIO (13) ++#define SB2_BTNDISPLAY_GPIO (14) ++#define SB2_BTN_4_GPIO (15) ++ ++/* IRQs for buttons */ ++#define SB2_BTN_IRQ (AU1500_GPIO_208_218) ++ ++/* Pinstate of GPIO-port */ ++#define SB2_BTN_PINSTATE (GPIO2_PINSTATE) ++ ++/* Direction of GPIO-register */ ++#define SB2_BTN_DIR (GPIO2_DIR) ++ ++static struct timer_list check_button_timer; ++static int restart_timer = 1; ++ ++#define MAX_ACCESS 4 ++struct priv_data { ++ char in_use; ++ char state_changed; ++ char last_state; ++ char current_state; ++ wait_queue_head_t btn_wait_queue; ++}; ++static struct priv_data priv_data[MAX_ACCESS]; ++ ++/*---------[ Hardware Functions ]-----------------*/ ++ ++static void mtx_initbuttons (void) ++{ ++ int i; ++ for (i = 11; i <= 15; ++i) { ++ /* Clear dir-bit to configure GPIO as input */ ++ au_writel (au_readl(SB2_BTN_DIR) & ~(1 << i), SB2_BTN_DIR); ++ } ++} ++ ++static unsigned char lval=0, cval = 0; ++ ++static void check_buttons (unsigned long timer_task) { ++ int i; ++ cval = (au_readl(GPIO2_PINSTATE) >> 11) & 0x1f; ++ if (lval != cval) { ++ for (i=0; ii_rdev) != mtxsysbtn_minor) ++ return -ENODEV; ++ ++ MOD_INC_USE_COUNT; ++ ++ // search an unused priv_data ++ for (i=0; iprivate_data = &priv_data[i]; ++ init_waitqueue_head(&pd->btn_wait_queue); ++ priv_data[i].in_use = 1; ++ break; ++ } ++ } ++ ++ if (file->private_data==NULL) { ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static int mtxsysbtn_release (struct inode *inode, struct file *file) ++{ ++ struct priv_data *pd = (struct priv_data*)file->private_data; ++ if ( pd ) { ++ pd->in_use = 0; ++ file->private_data=NULL; ++ } ++ ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++static ssize_t mtxsysbtn_read (struct file *file, char *buf, size_t count, loff_t *ppos) ++{ ++ struct priv_data *pd = (struct priv_data*)file->private_data; ++ if (count < 1 || !pd ) ++ return -EINVAL; ++ if (!pd->state_changed) { ++ interruptible_sleep_on(&pd->btn_wait_queue); ++ } ++ char chg = pd->current_state ^ pd->last_state; ++ char chgack=0; ++ ++ int r[5],i,c=0; ++ for (i = 0; i<5; i++) { ++ if ( chg & (1 << i)) { ++ r[c] = i+1; ++ if ((pd->current_state & (1 << i)) == 0) ++ r[c] |= 0x80; ++ chgack |= (1< count ) { ++ break; ++ } ++ } ++ } ++ pd->last_state ^= chgack; ++ ++ if ( pd->last_state == pd->current_state ) { ++ pd->state_changed = 0; ++ } ++ ++ if (copy_to_user(buf, r, c)) { ++ return -EFAULT; ++ } ++ ++ return c; ++} ++ ++static unsigned int mtxsysbtn_poll (struct file *file, poll_table * wait) ++{ ++ unsigned int mask = 0; ++ struct priv_data *pd = (struct priv_data*)file->private_data; ++ if (!pd) ++ return -EINVAL; ++ ++ poll_wait(file, &pd->btn_wait_queue, wait); ++ if (pd->state_changed) /* state changed since last time. */ ++ mask |= POLLIN | POLLRDNORM; ++ return mask; ++} ++ ++/*---------[ Module stuff ]-----------------*/ ++ ++static struct file_operations mtxsysbtn_fops = { ++ .owner = THIS_MODULE, ++ .read = mtxsysbtn_read, ++ .poll = mtxsysbtn_poll, ++ .open = mtxsysbtn_open, ++ .release = mtxsysbtn_release ++}; ++ ++static struct miscdevice mtxsysbtn_miscdev = { ++ MISC_DYNAMIC_MINOR /* SYSBTN_MINOR */ , ++ "btn", ++ &mtxsysbtn_fops ++}; ++ ++void __exit cleanup_mtx_sysbtn (void) ++{ ++ restart_timer = 0; ++ del_timer_sync(&check_button_timer); ++ is_inuse = 1; ++ misc_deregister(&mtxsysbtn_miscdev); ++ is_inuse = 0; ++} ++ ++int __init init_mtx_sysbtn (void) ++{ ++ memset(priv_data, 0, sizeof(struct priv_data)*MAX_ACCESS); ++ init_timer(&check_button_timer); ++ check_button_timer.function = check_buttons; ++ check_button_timer.data = 0; ++ check_button_timer.expires = jiffies+100; ++ add_timer(&check_button_timer); ++ ++ is_inuse = 1; ++ mtx_initbuttons(); ++ if (misc_register(&mtxsysbtn_miscdev) >= 0) { ++ mtxsysbtn_minor = mtxsysbtn_miscdev.minor; ++ printk(KERN_INFO "MTX-1 System Button minor: %d\n", ++ mtxsysbtn_miscdev.minor); ++ if (1) { ++ is_inuse = 0; ++ return 0; ++ } ++ ++ misc_deregister(&mtxsysbtn_miscdev); ++ } ++ is_inuse = 0; ++ return 1; ++} ++ ++module_init(init_mtx_sysbtn); ++module_exit(cleanup_mtx_sysbtn); ++ ++MODULE_AUTHOR("Simon Krahnke"); ++MODULE_DESCRIPTION("Driver for MTX buttons"); ++MODULE_LICENSE("GPL"); ++EXPORT_NO_SYMBOLS; diff --git a/packages/linux/linux-mtx-2-2.4.27/39-mppe-mpc.patch b/packages/linux/linux-mtx-2-2.4.27/39-mppe-mpc.patch new file mode 100644 index 0000000000..28ce19d467 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/39-mppe-mpc.patch @@ -0,0 +1,1665 @@ +diff -ruN linux.orig/Documentation/Configure.help linux/Documentation/Configure.help +--- linux.orig/Documentation/Configure.help 2004-08-08 12:14:49.000000000 +0200 ++++ linux/Documentation/Configure.help 2004-08-15 09:22:18.000000000 +0200 +@@ -9905,6 +9905,28 @@ + module; it is called bsd_comp.o and will show up in the directory + modules once you have said "make modules". If unsure, say N. + ++Microsoft PPP compression/encryption (MPPC/MPPE) ++CONFIG_PPP_MPPE_MPPC ++ Support for the Microsoft Point-To-Point Compression (RFC2118) and ++ Microsoft Point-To-Point Encryption (RFC3078). These protocols are ++ supported by Microsoft Windows and wide range of "hardware" access ++ servers. MPPE is common protocol in Virtual Private Networks. According ++ to RFC3078, MPPE supports 40, 56 and 128-bit key lengths. Depending on ++ PPP daemon configuration on both ends of the link, following scenarios ++ are possible: ++ - only compression (MPPC) is used, ++ - only encryption (MPPE) is used, ++ - compression and encryption (MPPC+MPPE) are used. ++ ++ Please note that Hi/Fn (http://www.hifn.com) holds patent on MPPC so ++ you should check if this patent is valid in your country in order to ++ avoid legal problems. ++ ++ For more information please visit http://free.polbox.pl/h/hs001 ++ ++ To compile this driver as a module, choose M here. The module will ++ be called ppp_mppe_mppc.o. ++ + PPP over Ethernet + CONFIG_PPPOE + Support for PPP over Ethernet. +diff -ruN linux.orig/crypto/Config.in linux/crypto/Config.in +--- linux.orig/crypto/Config.in 2004-08-08 12:14:50.000000000 +0200 ++++ linux/crypto/Config.in 2004-08-15 11:36:18.000000000 +0200 +@@ -11,7 +11,9 @@ + "$CONFIG_INET6_AH" = "y" -o \ + "$CONFIG_INET6_AH" = "m" -o \ + "$CONFIG_INET6_ESP" = "y" -o \ +- "$CONFIG_INET6_ESP" = "m" ]; then ++ "$CONFIG_INET6_ESP" = "m" -o \ ++ "$CONFIG_PPP_MPPE_MPPC" = "y" -o \ ++ "$CONFIG_PPP_MPPE_MPPC" = "m" ]; then + define_bool CONFIG_CRYPTO y + else + bool 'Cryptographic API' CONFIG_CRYPTO +@@ -44,6 +46,7 @@ + else + tristate ' MD5 digest algorithm' CONFIG_CRYPTO_MD5 + fi ++ + if [ "$CONFIG_INET_AH" = "y" -o \ + "$CONFIG_INET_AH" = "m" -o \ + "$CONFIG_INET_ESP" = "y" -o \ +@@ -51,11 +54,24 @@ + "$CONFIG_INET6_AH" = "y" -o \ + "$CONFIG_INET6_AH" = "m" -o \ + "$CONFIG_INET6_ESP" = "y" -o \ +- "$CONFIG_INET6_ESP" = "m" ]; then +- define_bool CONFIG_CRYPTO_SHA1 y +- else +- tristate ' SHA1 digest algorithm' CONFIG_CRYPTO_SHA1 ++ "$CONFIG_INET6_ESP" = "m" -o \ ++ "$CONFIG_PPP_MPPE_MPPC" = "y" -o \ ++ "$CONFIG_PPP_MPPE_MPPC" = "m" ]; then ++ if [ "$CONFIG_INET_AH" = "y" -o \ ++ "$CONFIG_INET_ESP" = "y" -o \ ++ "$CONFIG_INET6_AH" = "y" -o \ ++ "$CONFIG_INET6_ESP" = "y" -o \ ++ "$CONFIG_PPP_MPPE_MPPC" = "y" ]; then ++ define_tristate CONFIG_CRYPTO_SHA1 y ++ else ++ if [ "$CONFIG_CRYPTO_SHA1" != "y" -a \ ++ "$CONFIG_CRYPTO_SHA1" != "m" ]; then ++ define_tristate CONFIG_CRYPTO_SHA1 m ++ fi ++ fi + fi ++ tristate ' SHA1 digest algorithm' CONFIG_CRYPTO_SHA1 ++ + tristate ' SHA256 digest algorithm' CONFIG_CRYPTO_SHA256 + tristate ' SHA384 and SHA512 digest algorithms' CONFIG_CRYPTO_SHA512 + if [ "$CONFIG_INET_ESP" = "y" -o \ +@@ -73,7 +89,20 @@ + tristate ' CAST5 (CAST-128) cipher algorithm' CONFIG_CRYPTO_CAST5 + tristate ' CAST6 (CAST-256) cipher algorithm' CONFIG_CRYPTO_CAST6 + tristate ' TEA and XTEA cipher algorithms' CONFIG_CRYPTO_TEA ++ ++ if [ "$CONFIG_PPP_MPPE_MPPC" = "y" -o \ ++ "$CONFIG_PPP_MPPE_MPPC" = "m" ]; then ++ if [ "$CONFIG_PPP_MPPE_MPPC" = "y" ]; then ++ define_tristate CONFIG_CRYPTO_ARC4 y ++ else ++ if [ "$CONFIG_CRYPTO_ARC4" != "y" -a \ ++ "$CONFIG_CRYPTO_ARC4" != "m" ]; then ++ define_tristate CONFIG_CRYPTO_ARC4 m ++ fi ++ fi ++ fi + tristate ' ARC4 cipher algorithm' CONFIG_CRYPTO_ARC4 ++ + if [ "$CONFIG_INET_IPCOMP" = "y" -o \ + "$CONFIG_INET_IPCOMP" = "m" -o \ + "$CONFIG_INET6_IPCOMP" = "y" -o \ +diff -ruN linux.orig/drivers/net/Config.in linux/drivers/net/Config.in +--- linux.orig/drivers/net/Config.in 2004-08-08 12:14:52.000000000 +0200 ++++ linux/drivers/net/Config.in 2004-08-08 12:17:43.000000000 +0200 +@@ -325,6 +325,7 @@ + dep_tristate ' PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP + dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP + dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP ++ dep_tristate ' Microsoft PPP compression/encryption (MPPC/MPPE)' CONFIG_PPP_MPPE_MPPC $CONFIG_PPP + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP + fi +diff -ruN linux.orig/drivers/net/Makefile linux/drivers/net/Makefile +--- linux.orig/drivers/net/Makefile 2004-08-08 12:14:52.000000000 +0200 ++++ linux/drivers/net/Makefile 2004-08-08 12:17:43.000000000 +0200 +@@ -161,6 +161,7 @@ + obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o + obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o + obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o ++obj-$(CONFIG_PPP_MPPE_MPPC) += ppp_mppe_mppc.o + obj-$(CONFIG_PPPOE) += pppox.o pppoe.o + + obj-$(CONFIG_SLIP) += slip.o +diff -ruN linux.orig/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c +--- linux.orig/drivers/net/ppp_generic.c 2003-08-25 13:44:42.000000000 +0200 ++++ linux/drivers/net/ppp_generic.c 2004-08-08 12:17:43.000000000 +0200 +@@ -19,7 +19,7 @@ + * PPP driver, written by Michael Callahan and Al Longyear, and + * subsequently hacked by Paul Mackerras. + * +- * ==FILEVERSION 20020217== ++ * ==FILEVERSION 20040509== + */ + + #include +@@ -102,6 +102,7 @@ + spinlock_t rlock; /* lock for receive side 58 */ + spinlock_t wlock; /* lock for transmit side 5c */ + int mru; /* max receive unit 60 */ ++ int mru_alloc; /* MAX(1500,MRU) for dev_alloc_skb() */ + unsigned int flags; /* control bits 64 */ + unsigned int xstate; /* transmit state bits 68 */ + unsigned int rstate; /* receive state bits 6c */ +@@ -552,7 +553,9 @@ + case PPPIOCSMRU: + if (get_user(val, (int *) arg)) + break; +- ppp->mru = val; ++ ppp->mru_alloc = ppp->mru = val; ++ if (ppp->mru_alloc < PPP_MRU) ++ ppp->mru_alloc = PPP_MRU; /* increase for broken peers */ + err = 0; + break; + +@@ -1025,14 +1028,37 @@ + case PPP_CCP: + /* peek at outbound CCP frames */ + ppp_ccp_peek(ppp, skb, 0); ++ /* ++ * When LZS or MPPE/MPPC has been negotiated we don't send ++ * CCP_RESETACK after receiving CCP_RESETREQ; in fact pppd ++ * sends such a packet but we silently discard it here ++ */ ++ if (CCP_CODE(skb->data+2) == CCP_RESETACK ++ && (ppp->xcomp->compress_proto == CI_MPPE ++ || ppp->xcomp->compress_proto == CI_LZS)) { ++ --ppp->stats.tx_packets; ++ ppp->stats.tx_bytes -= skb->len - 2; ++ kfree_skb(skb); ++ return; ++ } + break; + } + + /* try to do packet compression */ + if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0 + && proto != PPP_LCP && proto != PPP_CCP) { +- new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len, +- GFP_ATOMIC); ++ int comp_ovhd = 0; ++ /* ++ * because of possible data expansion when MPPC or LZS ++ * is used, allocate compressor's buffer 12.5% bigger ++ * than MTU ++ */ ++ if (ppp->xcomp->compress_proto == CI_MPPE) ++ comp_ovhd = ((ppp->dev->mtu * 9) / 8) + 1 + MPPE_OVHD; ++ else if (ppp->xcomp->compress_proto == CI_LZS) ++ comp_ovhd = ((ppp->dev->mtu * 9) / 8) + 1 + LZS_OVHD; ++ new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len ++ + comp_ovhd, GFP_ATOMIC); + if (new_skb == 0) { + printk(KERN_ERR "PPP: no memory (comp pkt)\n"); + goto drop; +@@ -1050,9 +1076,21 @@ + skb = new_skb; + skb_put(skb, len); + skb_pull(skb, 2); /* pull off A/C bytes */ +- } else { ++ } else if (len == 0) { + /* didn't compress, or CCP not up yet */ + kfree_skb(new_skb); ++ } else { ++ /* ++ * (len < 0) ++ * MPPE requires that we do not send unencrypted ++ * frames. The compressor will return -1 if we ++ * should drop the frame. We cannot simply test ++ * the compress_proto because MPPE and MPPC share ++ * the same number. ++ */ ++ printk(KERN_ERR "ppp: compressor dropped pkt\n"); ++ kfree_skb(new_skb); ++ goto drop; + } + } + +@@ -1540,14 +1578,15 @@ + int len; + + if (proto == PPP_COMP) { +- ns = dev_alloc_skb(ppp->mru + PPP_HDRLEN); ++ ns = dev_alloc_skb(ppp->mru_alloc + PPP_HDRLEN); + if (ns == 0) { + printk(KERN_ERR "ppp_decompress_frame: no memory\n"); + goto err; + } + /* the decompressor still expects the A/C bytes in the hdr */ + len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2, +- skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN); ++ skb->len + 2, ns->data, ++ ppp->mru_alloc + PPP_HDRLEN); + if (len < 0) { + /* Pass the compressed frame to pppd as an + error indication. */ +@@ -1573,7 +1612,14 @@ + return skb; + + err: +- ppp->rstate |= SC_DC_ERROR; ++ if (ppp->rcomp->compress_proto != CI_MPPE ++ && ppp->rcomp->compress_proto != CI_LZS) { ++ /* ++ * If decompression protocol isn't MPPE/MPPC or LZS, we set ++ * SC_DC_ERROR flag and wait for CCP_RESETACK ++ */ ++ ppp->rstate |= SC_DC_ERROR; ++ } + ppp_receive_error(ppp); + return skb; + } +@@ -2253,6 +2299,7 @@ + /* Initialize the new ppp unit */ + ppp->file.index = unit; + ppp->mru = PPP_MRU; ++ ppp->mru_alloc = PPP_MRU; + init_ppp_file(&ppp->file, INTERFACE); + ppp->file.hdrlen = PPP_HDRLEN - 2; /* don't count proto bytes */ + for (i = 0; i < NUM_NP; ++i) +diff -ruN linux.orig/drivers/net/ppp_mppe_mppc.c linux/drivers/net/ppp_mppe_mppc.c +--- linux.orig/drivers/net/ppp_mppe_mppc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/net/ppp_mppe_mppc.c 2004-08-15 10:12:23.000000000 +0200 +@@ -0,0 +1,1269 @@ ++/* ++ * ppp_mppe_mppc.c - MPPC/MPPE "compressor/decompressor" module. ++ * ++ * Copyright (c) 1994 Árpád Magosányi ++ * Copyright (c) 1999 Tim Hockin, Cobalt Networks Inc. ++ * Copyright (c) 2002-2004 Jan Dubiec ++ * ++ * Permission to use, copy, modify, and distribute this software and its ++ * documentation is hereby granted, provided that the above copyright ++ * notice appears in all copies. This software is provided without any ++ * warranty, express or implied. ++ * ++ * The code is based on MPPE kernel module written by Árpád Magosányi and ++ * Tim Hockin which can be found on http://planetmirror.com/pub/mppe/. ++ * I have added MPPC and 56 bit session keys support in MPPE. ++ * ++ * WARNING! Although this is open source code, its usage in some countries ++ * (in particular in the USA) may violate Stac Inc. patent for MPPC. ++ * ++ * ==FILEVERSION 20040815== ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* ++ * In 2.4.x kernels macro offset_in_page() is not defined in linux/mm.h so ++ * we define it here; PAGE_MASK is defined in asm/page.h which is included ++ * by linux/mm.h. ++ */ ++#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) ++ ++/* ++ * State for a mppc/mppe "(de)compressor". ++ */ ++struct ppp_mppe_state { ++ struct crypto_tfm *arc4_tfm; ++ struct crypto_tfm *sha1_tfm; ++ u8 master_key[MPPE_MAX_KEY_LEN]; ++ u8 session_key[MPPE_MAX_KEY_LEN]; ++ u8 mppc; /* do we use compression (MPPC)? */ ++ u8 mppe; /* do we use encryption (MPPE)? */ ++ u8 keylen; /* key length in bytes */ ++ u8 bitkeylen; /* key length in bits */ ++ u16 ccount; /* coherency counter */ ++ u16 bits; /* MPPC/MPPE control bits */ ++ u8 stateless; /* do we use stateless mode? */ ++ u8 nextflushed; /* set A bit in the next outgoing packet; ++ used only by compressor*/ ++ u8 flushexpected; /* drop packets until A bit is received; ++ used only by decompressor*/ ++ u8 *hist; /* MPPC history */ ++ u16 *hash; /* Hash table; used only by compressor */ ++ u16 histptr; /* history "cursor" */ ++ int unit; ++ int debug; ++ int mru; ++ struct compstat stats; ++}; ++ ++#define MPPE_HIST_LEN 8192 /* MPPC history size */ ++#define MPPE_MAX_CCOUNT 0x0FFF /* max. coherency counter value */ ++ ++#define MPPE_BIT_FLUSHED 0x80 /* bit A */ ++#define MPPE_BIT_RESET 0x40 /* bit B */ ++#define MPPE_BIT_COMP 0x20 /* bit C */ ++#define MPPE_BIT_ENCRYPTED 0x10 /* bit D */ ++ ++#define MPPE_SALT0 0xD1 /* values used in MPPE key derivation */ ++#define MPPE_SALT1 0x26 /* according to RFC3079 */ ++#define MPPE_SALT2 0x9E ++ ++#define MPPE_CCOUNT(x) ((((x)[4] & 0x0f) << 8) + (x)[5]) ++#define MPPE_BITS(x) ((x)[4] & 0xf0) ++#define MPPE_CTRLHI(x) ((((x)->ccount & 0xf00)>>8)|((x)->bits)) ++#define MPPE_CTRLLO(x) ((x)->ccount & 0xff) ++ ++static inline void ++setup_sg(struct scatterlist *sg, const void *address, unsigned int length) ++{ ++ sg[0].page = virt_to_page(address); ++ sg[0].offset = offset_in_page(address); ++ sg[0].length = length; ++} ++ ++static inline void ++arc4_setkey(struct ppp_mppe_state *state, const unsigned char *key, ++ const unsigned int keylen) ++{ ++ crypto_cipher_setkey(state->arc4_tfm, key, keylen); ++} ++ ++static inline void ++arc4_encrypt(struct ppp_mppe_state *state, const unsigned char *in, ++ const unsigned int len, unsigned char *out) ++{ ++ struct scatterlist sgin[4], sgout[4]; ++ ++ setup_sg(sgin, in, len); ++ setup_sg(sgout, out, len); ++ crypto_cipher_encrypt(state->arc4_tfm, sgout, sgin, len); ++} ++ ++#define arc4_decrypt arc4_encrypt ++ ++/* ++ * Key Derivation, from RFC 3078, RFC 3079. ++ * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079. ++ */ ++static void ++GetNewKeyFromSHA(struct ppp_mppe_state *state, unsigned char *MasterKey, ++ unsigned char *SessionKey, unsigned long SessionKeyLength, ++ unsigned char *InterimKey) ++{ ++ /*Pads used in key derivation */ ++ static const unsigned char SHAPad1[40] = { ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ }; ++ ++ static const unsigned char SHAPad2[40] = { ++ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, ++ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, ++ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, ++ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 ++ }; ++ ++ unsigned char Digest[20]; /* SHA1_DIGEST_SIZE = 20 */ ++ struct scatterlist sg[2]; ++ ++ crypto_digest_init(state->sha1_tfm); ++ ++ setup_sg(sg, MasterKey, SessionKeyLength); ++ crypto_digest_update(state->sha1_tfm, sg, 1); ++ ++ setup_sg(sg, SHAPad1, sizeof(SHAPad1)); ++ crypto_digest_update(state->sha1_tfm, sg, 1); ++ ++ setup_sg(sg, SessionKey, SessionKeyLength); ++ crypto_digest_update(state->sha1_tfm, sg, 1); ++ ++ setup_sg(sg, SHAPad2, sizeof(SHAPad2)); ++ crypto_digest_update(state->sha1_tfm, sg, 1); ++ ++ crypto_digest_final(state->sha1_tfm, Digest); ++ ++ memcpy(InterimKey, Digest, SessionKeyLength); ++} ++ ++static void ++mppe_change_key(struct ppp_mppe_state *state, int initialize) ++{ ++ unsigned char InterimKey[MPPE_MAX_KEY_LEN]; ++ ++ GetNewKeyFromSHA(state, state->master_key, state->session_key, ++ state->keylen, InterimKey); ++ if (initialize) { ++ memcpy(state->session_key, InterimKey, state->keylen); ++ } else { ++ arc4_setkey(state, InterimKey, state->keylen); ++ arc4_encrypt(state, InterimKey, state->keylen, state->session_key); ++ } ++ if (state->keylen == 8) { ++ if (state->bitkeylen == 40) { ++ state->session_key[0] = MPPE_SALT0; ++ state->session_key[1] = MPPE_SALT1; ++ state->session_key[2] = MPPE_SALT2; ++ } else { ++ state->session_key[0] = MPPE_SALT0; ++ } ++ } ++ arc4_setkey(state, state->session_key, state->keylen); ++} ++ ++/* increase 12-bit coherency counter */ ++static inline void ++mppe_increase_ccount(struct ppp_mppe_state *state) ++{ ++ state->ccount = (state->ccount + 1) & MPPE_MAX_CCOUNT; ++ if (state->mppe) { ++ if (state->stateless) { ++ mppe_change_key(state, 0); ++ state->nextflushed = 1; ++ } else { ++ if ((state->ccount & 0xff) == 0xff) { ++ mppe_change_key(state, 0); ++ } ++ } ++ } ++} ++ ++/* allocate space for a MPPE/MPPC (de)compressor. */ ++/* comp != 0 -> init compressor */ ++/* comp = 0 -> init decompressor */ ++static void * ++mppe_alloc(unsigned char *options, int opt_len, int comp) ++{ ++ struct ppp_mppe_state *state; ++ u8* fname; ++ ++ fname = comp ? "mppe_comp_alloc" : "mppe_decomp_alloc"; ++ ++ /* ++ * Hack warning - additionally to the standard MPPC/MPPE configuration ++ * options, pppd passes to the (de)copressor 8 or 16 byte session key. ++ * Therefore options[1] contains MPPC/MPPE configuration option length ++ * (CILEN_MPPE = 6), but the real options length, depending on the key ++ * length, is 6+8 or 6+16. ++ */ ++ if (opt_len < CILEN_MPPE) { ++ printk(KERN_WARNING "%s: wrong options length: %u\n", fname, opt_len); ++ return NULL; ++ } ++ ++ if (options[0] != CI_MPPE || options[1] != CILEN_MPPE || ++ (options[2] & ~MPPE_STATELESS) != 0 || ++ options[3] != 0 || options[4] != 0 || ++ (options[5] & ~(MPPE_128BIT|MPPE_56BIT|MPPE_40BIT|MPPE_MPPC)) != 0 || ++ (options[5] & (MPPE_128BIT|MPPE_56BIT|MPPE_40BIT|MPPE_MPPC)) == 0) { ++ printk(KERN_WARNING "%s: options rejected: o[0]=%02x, o[1]=%02x, " ++ "o[2]=%02x, o[3]=%02x, o[4]=%02x, o[5]=%02x\n", fname, options[0], ++ options[1], options[2], options[3], options[4], options[5]); ++ return NULL; ++ } ++ ++ state = (struct ppp_mppe_state *)kmalloc(sizeof(*state), GFP_KERNEL); ++ if (state == NULL) { ++ printk(KERN_ERR "%s: cannot allocate space for %scompressor\n", fname, ++ comp ? "" : "de"); ++ return NULL; ++ } ++ memset(state, 0, sizeof(struct ppp_mppe_state)); ++ ++ state->mppc = options[5] & MPPE_MPPC; /* Do we use MPPC? */ ++ state->mppe = options[5] & (MPPE_128BIT | MPPE_56BIT | ++ MPPE_40BIT); /* Do we use MPPE? */ ++ ++ if (state->mppc) { ++ /* allocate MPPC history */ ++ state->hist = (u8*)vmalloc(2*MPPE_HIST_LEN*sizeof(u8)); ++ if (state->hist == NULL) { ++ kfree(state); ++ printk(KERN_ERR "%s: cannot allocate space for MPPC history\n", ++ fname); ++ return NULL; ++ } ++ ++ /* allocate hashtable for MPPC compressor */ ++ if (comp) { ++ state->hash = (u16*)vmalloc(MPPE_HIST_LEN*sizeof(u16)); ++ if (state->hash == NULL) { ++ vfree(state->hist); ++ kfree(state); ++ printk(KERN_ERR "%s: cannot allocate space for MPPC history\n", ++ fname); ++ return NULL; ++ } ++ } ++ } ++ ++ if (state->mppe) { /* specific for MPPE */ ++ /* Load SHA1 algorithm */ ++ state->sha1_tfm = crypto_alloc_tfm("sha1", 0); ++ if (state->sha1_tfm == NULL) { ++ vfree(state->hash); ++ vfree(state->hist); ++ kfree(state); ++ printk(KERN_ERR "%s: cannot load SHA1 module\n", fname); ++ return NULL; ++ } ++ ++ /* Load ARC4 algorithm */ ++ state->arc4_tfm = crypto_alloc_tfm("arc4", 0); ++ if (state->arc4_tfm == NULL) { ++ crypto_free_tfm(state->sha1_tfm); ++ vfree(state->hash); ++ vfree(state->hist); ++ kfree(state); ++ printk(KERN_ERR "%s: cannot load ARC4 module\n", fname); ++ return NULL; ++ } ++ ++ memcpy(state->master_key, options+CILEN_MPPE, MPPE_MAX_KEY_LEN); ++ memcpy(state->session_key, state->master_key, MPPE_MAX_KEY_LEN); ++ /* initial key generation is done in mppe_init() */ ++ } ++ ++ MOD_INC_USE_COUNT; ++ ++ return (void *) state; ++} ++ ++static void * ++mppe_comp_alloc(unsigned char *options, int opt_len) ++{ ++ return mppe_alloc(options, opt_len, 1); ++} ++ ++static void * ++mppe_decomp_alloc(unsigned char *options, int opt_len) ++{ ++ return mppe_alloc(options, opt_len, 0); ++} ++ ++/* cleanup the (de)compressor */ ++static void ++mppe_comp_free(void *arg) ++{ ++ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; ++ ++ if (state != NULL) { ++ if (state->mppe) { ++ if (state->sha1_tfm != NULL) ++ crypto_free_tfm(state->sha1_tfm); ++ if (state->arc4_tfm != NULL) ++ crypto_free_tfm(state->arc4_tfm); ++ } ++ if (state->hist != NULL) ++ vfree(state->hist); ++ if (state->hash != NULL) ++ vfree(state->hash); ++ kfree(state); ++ } ++ ++ MOD_DEC_USE_COUNT; ++} ++ ++/* init MPPC/MPPE (de)compresor */ ++/* comp != 0 -> init compressor */ ++/* comp = 0 -> init decompressor */ ++static int ++mppe_init(void *arg, unsigned char *options, int opt_len, int unit, ++ int hdrlen, int mru, int debug, int comp) ++{ ++ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; ++ u8* fname; ++ ++ fname = comp ? "mppe_comp_init" : "mppe_decomp_init"; ++ ++ if (opt_len < CILEN_MPPE) { ++ if (debug) ++ printk(KERN_WARNING "%s: wrong options length: %u\n", ++ fname, opt_len); ++ return 0; ++ } ++ ++ if (options[0] != CI_MPPE || options[1] != CILEN_MPPE || ++ (options[2] & ~MPPE_STATELESS) != 0 || ++ options[3] != 0 || options[4] != 0 || ++ (options[5] & ~(MPPE_56BIT|MPPE_128BIT|MPPE_40BIT|MPPE_MPPC)) != 0 || ++ (options[5] & (MPPE_56BIT|MPPE_128BIT|MPPE_40BIT|MPPE_MPPC)) == 0) { ++ if (debug) ++ printk(KERN_WARNING "%s: options rejected: o[0]=%02x, o[1]=%02x, " ++ "o[2]=%02x, o[3]=%02x, o[4]=%02x, o[5]=%02x\n", fname, ++ options[0], options[1], options[2], options[3], options[4], ++ options[5]); ++ return 0; ++ } ++ ++ if ((options[5] & ~MPPE_MPPC) != MPPE_128BIT && ++ (options[5] & ~MPPE_MPPC) != MPPE_56BIT && ++ (options[5] & ~MPPE_MPPC) != MPPE_40BIT && ++ (options[5] & MPPE_MPPC) != MPPE_MPPC) { ++ if (debug) ++ printk(KERN_WARNING "%s: don't know what to do: o[5]=%02x\n", ++ fname, options[5]); ++ return 0; ++ } ++ ++ state->mppc = options[5] & MPPE_MPPC; /* Do we use MPPC? */ ++ state->mppe = options[5] & (MPPE_128BIT | MPPE_56BIT | ++ MPPE_40BIT); /* Do we use MPPE? */ ++ state->stateless = options[2] & MPPE_STATELESS; /* Do we use stateless mode? */ ++ ++ switch (state->mppe) { ++ case MPPE_40BIT: /* 40 bit key */ ++ state->keylen = 8; ++ state->bitkeylen = 40; ++ break; ++ case MPPE_56BIT: /* 56 bit key */ ++ state->keylen = 8; ++ state->bitkeylen = 56; ++ break; ++ case MPPE_128BIT: /* 128 bit key */ ++ state->keylen = 16; ++ state->bitkeylen = 128; ++ break; ++ default: ++ state->keylen = 0; ++ state->bitkeylen = 0; ++ } ++ ++ state->ccount = MPPE_MAX_CCOUNT; ++ state->bits = 0; ++ state->unit = unit; ++ state->debug = debug; ++ state->histptr = MPPE_HIST_LEN; ++ if (state->mppc) { /* reset history if MPPC was negotiated */ ++ memset(state->hist, 0, 2*MPPE_HIST_LEN*sizeof(u8)); ++ } ++ ++ if (state->mppe) { /* generate initial session keys */ ++ mppe_change_key(state, 1); ++ } ++ ++ if (comp) { /* specific for compressor */ ++ state->nextflushed = 1; ++ } else { /* specific for decompressor */ ++ state->mru = mru; ++ state->flushexpected = 1; ++ } ++ ++ return 1; ++} ++ ++static int ++mppe_comp_init(void *arg, unsigned char *options, int opt_len, int unit, ++ int hdrlen, int debug) ++{ ++ return mppe_init(arg, options, opt_len, unit, hdrlen, 0, debug, 1); ++} ++ ++ ++static int ++mppe_decomp_init(void *arg, unsigned char *options, int opt_len, int unit, ++ int hdrlen, int mru, int debug) ++{ ++ return mppe_init(arg, options, opt_len, unit, hdrlen, mru, debug, 0); ++} ++ ++static void ++mppe_comp_reset(void *arg) ++{ ++ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg; ++ ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: resetting MPPC/MPPE compressor\n", ++ __FUNCTION__, state->unit); ++ ++ state->nextflushed = 1; ++ if (state->mppe) ++ arc4_setkey(state, state->session_key, state->keylen); ++} ++ ++static void ++mppe_decomp_reset(void *arg) ++{ ++ /* When MPPC/MPPE is in use, we shouldn't receive any CCP Reset-Ack. ++ But when we receive such a packet, we just ignore it. */ ++ return; ++} ++ ++static void ++mppe_stats(void *arg, struct compstat *stats) ++{ ++ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg; ++ ++ *stats = state->stats; ++} ++ ++/***************************/ ++/**** Compression stuff ****/ ++/***************************/ ++/* inserts 1 to 8 bits into the output buffer */ ++static inline void putbits8(u8 *buf, u32 val, const u32 n, u32 *i, u32 *l) ++{ ++ buf += *i; ++ if (*l >= n) { ++ *l = (*l) - n; ++ val <<= *l; ++ *buf = *buf | (val & 0xff); ++ if (*l == 0) { ++ *l = 8; ++ (*i)++; ++ *(++buf) = 0; ++ } ++ } else { ++ (*i)++; ++ *l = 8 - n + (*l); ++ val <<= *l; ++ *buf = *buf | ((val >> 8) & 0xff); ++ *(++buf) = val & 0xff; ++ } ++} ++ ++/* inserts 9 to 16 bits into the output buffer */ ++static inline void putbits16(u8 *buf, u32 val, const u32 n, u32 *i, u32 *l) ++{ ++ buf += *i; ++ if (*l >= n - 8) { ++ (*i)++; ++ *l = 8 - n + (*l); ++ val <<= *l; ++ *buf = *buf | ((val >> 8) & 0xff); ++ *(++buf) = val & 0xff; ++ if (*l == 0) { ++ *l = 8; ++ (*i)++; ++ *(++buf) = 0; ++ } ++ } else { ++ (*i)++; (*i)++; ++ *l = 16 - n + (*l); ++ val <<= *l; ++ *buf = *buf | ((val >> 16) & 0xff); ++ *(++buf) = (val >> 8) & 0xff; ++ *(++buf) = val & 0xff; ++ } ++} ++ ++/* inserts 17 to 24 bits into the output buffer */ ++static inline void putbits24(u8 *buf, u32 val, const u32 n, u32 *i, u32 *l) ++{ ++ buf += *i; ++ if (*l >= n - 16) { ++ (*i)++; (*i)++; ++ *l = 16 - n + (*l); ++ val <<= *l; ++ *buf = *buf | ((val >> 16) & 0xff); ++ *(++buf) = (val >> 8) & 0xff; ++ *(++buf) = val & 0xff; ++ if (*l == 0) { ++ *l = 8; ++ (*i)++; ++ *(++buf) = 0; ++ } ++ } else { ++ (*i)++; (*i)++; (*i)++; ++ *l = 24 - n + (*l); ++ val <<= *l; ++ *buf = *buf | ((val >> 24) & 0xff); ++ *(++buf) = (val >> 16) & 0xff; ++ *(++buf) = (val >> 8) & 0xff; ++ *(++buf) = val & 0xff; ++ } ++} ++ ++static int ++mppc_compress(struct ppp_mppe_state *state, unsigned char *ibuf, ++ unsigned char *obuf, int isize, int osize) ++{ ++ u32 olen, off, len, idx, i, l; ++ u8 *hist, *sbuf, *p, *q, *r, *s; ++ ++ /* ++ At this point, to avoid possible buffer overflow caused by packet ++ expansion during/after compression, we should make sure that ++ osize >= (((isize*9)/8)+1)+2, but we don't do that because in ++ ppp_generic.c we simply allocate bigger obuf. ++ ++ Maximum MPPC packet expansion is 12.5%. This is the worst case when ++ all octets in the input buffer are >= 0x80 and we cannot find any ++ repeated tokens. Additionally we have to reserve 2 bytes for MPPE/MPPC ++ status bits and coherency counter. ++ */ ++ ++ hist = state->hist + MPPE_HIST_LEN; ++ /* check if there is enough room at the end of the history */ ++ if (state->histptr + isize >= 2*MPPE_HIST_LEN) { ++ state->bits |= MPPE_BIT_RESET; ++ state->histptr = MPPE_HIST_LEN; ++ memcpy(state->hist, hist, MPPE_HIST_LEN); ++ } ++ /* add packet to the history; isize must be <= MPPE_HIST_LEN */ ++ sbuf = state->hist + state->histptr; ++ memcpy(sbuf, ibuf, isize); ++ state->histptr += isize; ++ ++ /* compress data */ ++ r = sbuf + isize; ++ *obuf = olen = i = 0; ++ l = 8; ++ while (i < isize - 2) { ++ s = q = sbuf + i; ++ idx = ((40543*((((s[0]<<4)^s[1])<<4)^s[2]))>>4) & 0x1fff; ++ p = hist + state->hash[idx]; ++ state->hash[idx] = (u16) (s - hist); ++ off = s - p; ++ if (off > MPPE_HIST_LEN - 1 || off < 1 || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++) { ++ /* no match found; encode literal byte */ ++ if (ibuf[i] < 0x80) { /* literal byte < 0x80 */ ++ putbits8(obuf, (u32) ibuf[i], 8, &olen, &l); ++ } else { /* literal byte >= 0x80 */ ++ putbits16(obuf, (u32) (0x100|(ibuf[i]&0x7f)), 9, &olen, &l); ++ } ++ ++i; ++ continue; ++ } ++ if (r - q >= 64) { ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || ++ *p++ != *s++; ++ if (s - q == 64) { ++ p--; s--; ++ while((*p++ == *s++) && (s < r) && (p < q)); ++ } ++ } else { ++ while((*p++ == *s++) && (s < r) && (p < q)); ++ } ++ len = s - q - 1; ++ i += len; ++ ++ /* at least 3 character match found; code data */ ++ /* encode offset */ ++ if (off < 64) { /* 10-bit offset; 0 <= offset < 64 */ ++ putbits16(obuf, 0x3c0|off, 10, &olen, &l); ++ } else if (off < 320) { /* 12-bit offset; 64 <= offset < 320 */ ++ putbits16(obuf, 0xe00|(off-64), 12, &olen, &l); ++ } else if (off < 8192) { /* 16-bit offset; 320 <= offset < 8192 */ ++ putbits16(obuf, 0xc000|(off-320), 16, &olen, &l); ++ } else { ++ /* This shouldn't happen; we return 0 what means "packet expands", ++ and we send packet uncompressed. */ ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: wrong offset value: %d\n", ++ __FUNCTION__, state->unit, off); ++ return 0; ++ } ++ /* encode length of match */ ++ if (len < 4) { /* length = 3 */ ++ putbits8(obuf, 0, 1, &olen, &l); ++ } else if (len < 8) { /* 4 <= length < 8 */ ++ putbits8(obuf, 0x08|(len&0x03), 4, &olen, &l); ++ } else if (len < 16) { /* 8 <= length < 16 */ ++ putbits8(obuf, 0x30|(len&0x07), 6, &olen, &l); ++ } else if (len < 32) { /* 16 <= length < 32 */ ++ putbits8(obuf, 0xe0|(len&0x0f), 8, &olen, &l); ++ } else if (len < 64) { /* 32 <= length < 64 */ ++ putbits16(obuf, 0x3c0|(len&0x1f), 10, &olen, &l); ++ } else if (len < 128) { /* 64 <= length < 128 */ ++ putbits16(obuf, 0xf80|(len&0x3f), 12, &olen, &l); ++ } else if (len < 256) { /* 128 <= length < 256 */ ++ putbits16(obuf, 0x3f00|(len&0x7f), 14, &olen, &l); ++ } else if (len < 512) { /* 256 <= length < 512 */ ++ putbits16(obuf, 0xfe00|(len&0xff), 16, &olen, &l); ++ } else if (len < 1024) { /* 512 <= length < 1024 */ ++ putbits24(obuf, 0x3fc00|(len&0x1ff), 18, &olen, &l); ++ } else if (len < 2048) { /* 1024 <= length < 2048 */ ++ putbits24(obuf, 0xff800|(len&0x3ff), 20, &olen, &l); ++ } else if (len < 4096) { /* 2048 <= length < 4096 */ ++ putbits24(obuf, 0x3ff000|(len&0x7ff), 22, &olen, &l); ++ } else if (len < 8192) { /* 4096 <= length < 8192 */ ++ putbits24(obuf, 0xffe000|(len&0xfff), 24, &olen, &l); ++ } else { ++ /* This shouldn't happen; we return 0 what means "packet expands", ++ and send packet uncompressed. */ ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: wrong length of match value: %d\n", ++ __FUNCTION__, state->unit, len); ++ return 0; ++ } ++ } ++ ++ /* Add remaining octets to the output */ ++ while(isize - i > 0) { ++ if (ibuf[i] < 0x80) { /* literal byte < 0x80 */ ++ putbits8(obuf, (u32) ibuf[i++], 8, &olen, &l); ++ } else { /* literal byte >= 0x80 */ ++ putbits16(obuf, (u32) (0x100|(ibuf[i++]&0x7f)), 9, &olen, &l); ++ } ++ } ++ /* Reset unused bits of the last output octet */ ++ if ((l != 0) && (l != 8)) { ++ putbits8(obuf, 0, l, &olen, &l); ++ } ++ ++ return (int) olen; ++} ++ ++int ++mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf, ++ int isize, int osize) ++{ ++ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; ++ int proto, olen, complen, off; ++ unsigned char *wptr; ++ ++ /* Check that the protocol is in the range we handle. */ ++ proto = PPP_PROTOCOL(ibuf); ++ if (proto < 0x0021 || proto > 0x00fa) ++ return 0; ++ ++ wptr = obuf; ++ /* Copy over the PPP header */ ++ wptr[0] = PPP_ADDRESS(ibuf); ++ wptr[1] = PPP_CONTROL(ibuf); ++ wptr[2] = PPP_COMP >> 8; ++ wptr[3] = PPP_COMP; ++ wptr += PPP_HDRLEN + (MPPE_OVHD / 2); /* Leave two octets for MPPE/MPPC bits */ ++ ++ /* ++ * In ver. 0.99 protocol field was compressed. Deflate and BSD compress ++ * do PFC before actual compression, RCF2118 and RFC3078 are not precise ++ * on this topic so I decided to do PFC. Unfortunately this change caused ++ * incompatibility with older/other MPPE/MPPC modules. I have received ++ * a lot of complaints from unexperienced users so I have decided to revert ++ * to previous state, i.e. the protocol field is sent uncompressed now. ++ * Although this may be changed in the future. ++ * ++ * Receiving side (mppe_decompress()) still accepts packets with compressed ++ * and uncompressed protocol field so you shouldn't get "Unsupported protocol ++ * 0x2145 received" messages anymore. ++ */ ++ //off = (proto > 0xff) ? 2 : 3; /* PFC - skip first protocol byte if 0 */ ++ off = 2; ++ ++ ibuf += off; ++ ++ mppe_increase_ccount(state); ++ ++ if (state->nextflushed) { ++ state->bits |= MPPE_BIT_FLUSHED; ++ state->nextflushed = 0; ++ if (state->mppe && !state->stateless) { ++ /* ++ * If this is the flag packet, the key has been already changed in ++ * mppe_increase_ccount() so we dont't do it once again. ++ */ ++ if ((state->ccount & 0xff) != 0xff) { ++ arc4_setkey(state, state->session_key, state->keylen); ++ } ++ } ++ if (state->mppc) { /* reset history */ ++ state->bits |= MPPE_BIT_RESET; ++ state->histptr = MPPE_HIST_LEN; ++ memset(state->hist + MPPE_HIST_LEN, 0, MPPE_HIST_LEN*sizeof(u8)); ++ } ++ } ++ ++ if (state->mppc && !state->mppe) { /* Do only compression */ ++ complen = mppc_compress(state, ibuf, wptr, isize - off, ++ osize - PPP_HDRLEN - (MPPE_OVHD / 2)); ++ /* ++ * TODO: Implement an heuristics to handle packet expansion in a smart ++ * way. Now, when a packet expands, we send it as uncompressed and ++ * when next packet is sent we have to reset compressor's history. ++ * Maybe it would be better to send such packet as compressed in order ++ * to keep history's continuity. ++ */ ++ if ((complen > isize) || (complen > osize - PPP_HDRLEN) || ++ (complen == 0)) { ++ /* packet expands */ ++ state->nextflushed = 1; ++ memcpy(wptr, ibuf, isize - off); ++ olen = isize - (off - 2) + MPPE_OVHD; ++ (state->stats).inc_bytes += olen; ++ (state->stats).inc_packets++; ++ } else { ++ state->bits |= MPPE_BIT_COMP; ++ olen = complen + PPP_HDRLEN + (MPPE_OVHD / 2); ++ (state->stats).comp_bytes += olen; ++ (state->stats).comp_packets++; ++ } ++ } else { /* Do encryption with or without compression */ ++ state->bits |= MPPE_BIT_ENCRYPTED; ++ if (!state->mppc && state->mppe) { /* Do only encryption */ ++ /* read from ibuf, write to wptr, adjust for PPP_HDRLEN */ ++ arc4_encrypt(state, ibuf, isize - off, wptr); ++ olen = isize - (off - 2) + MPPE_OVHD; ++ (state->stats).inc_bytes += olen; ++ (state->stats).inc_packets++; ++ } else { /* Do compression and then encryption - RFC3078 */ ++ complen = mppc_compress(state, ibuf, wptr, isize - off, ++ osize - PPP_HDRLEN - (MPPE_OVHD / 2)); ++ /* ++ * TODO: Implement an heuristics to handle packet expansion in a smart ++ * way. Now, when a packet expands, we send it as uncompressed and ++ * when next packet is sent we have to reset compressor's history. ++ * Maybe it would be good to send such packet as compressed in order ++ * to keep history's continuity. ++ */ ++ if ((complen > isize) || (complen > osize - PPP_HDRLEN) || ++ (complen == 0)) { ++ /* packet expands */ ++ state->nextflushed = 1; ++ arc4_encrypt(state, ibuf, isize - off, wptr); ++ olen = isize - (off - 2) + MPPE_OVHD; ++ (state->stats).inc_bytes += olen; ++ (state->stats).inc_packets++; ++ } else { ++ state->bits |= MPPE_BIT_COMP; ++ /* Hack warning !!! RC4 implementation which we use does ++ encryption "in place" - it means that input and output ++ buffers can be *the same* memory area. Therefore we don't ++ need to use a temporary buffer. But be careful - other ++ implementations don't have to be so nice. ++ I used to use ibuf as temporary buffer here, but it led ++ packet sniffers into error. Thanks to Wilfried Weissmann ++ for pointing that. */ ++ arc4_encrypt(state, wptr, complen, wptr); ++ olen = complen + PPP_HDRLEN + (MPPE_OVHD / 2); ++ (state->stats).comp_bytes += olen; ++ (state->stats).comp_packets++; ++ } ++ } ++ } ++ ++ /* write status bits and coherency counter into the output buffer */ ++ wptr = obuf + PPP_HDRLEN; ++ wptr[0] = MPPE_CTRLHI(state); ++ wptr[1] = MPPE_CTRLLO(state); ++ ++ state->bits = 0; ++ ++ (state->stats).unc_bytes += isize; ++ (state->stats).unc_packets++; ++ ++ return olen; ++} ++ ++/***************************/ ++/*** Decompression stuff ***/ ++/***************************/ ++static inline u32 getbits(const u8 *buf, const u32 n, u32 *i, u32 *l) ++{ ++ static const u32 m[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; ++ u32 res, ol; ++ ++ ol = *l; ++ if (*l >= n) { ++ *l = (*l) - n; ++ res = (buf[*i] & m[ol]) >> (*l); ++ if (*l == 0) { ++ *l = 8; ++ (*i)++; ++ } ++ } else { ++ *l = 8 - n + (*l); ++ res = (buf[(*i)++] & m[ol]) << 8; ++ res = (res | buf[*i]) >> (*l); ++ } ++ ++ return res; ++} ++ ++static inline u32 getbyte(const u8 *buf, const u32 i, const u32 l) ++{ ++ if (l == 8) { ++ return buf[i]; ++ } else { ++ return (((buf[i] << 8) | buf[i+1]) >> l) & 0xff; ++ } ++} ++ ++static inline void lamecopy(u8 *dst, u8 *src, u32 len) ++{ ++ while (len--) ++ *dst++ = *src++; ++} ++ ++static int ++mppc_decompress(struct ppp_mppe_state *state, unsigned char *ibuf, ++ unsigned char *obuf, int isize, int osize) ++{ ++ u32 olen, off, len, bits, val, sig, i, l; ++ u8 *history, *s; ++ ++ history = state->hist + state->histptr; ++ olen = len = i = 0; ++ l = 8; ++ bits = isize * 8; ++ while (bits >= 8) { ++ val = getbyte(ibuf, i++, l); ++ if (val < 0x80) { /* literal byte < 0x80 */ ++ if (state->histptr < 2*MPPE_HIST_LEN) { ++ /* copy uncompressed byte to the history */ ++ (state->hist)[(state->histptr)++] = (u8) val; ++ } else { ++ /* buffer overflow; drop packet */ ++ if (state->debug) ++ printk(KERN_ERR "%s%d: trying to write outside history " ++ "buffer\n", __FUNCTION__, state->unit); ++ return DECOMP_ERROR; ++ } ++ olen++; ++ bits -= 8; ++ continue; ++ } ++ ++ sig = val & 0xc0; ++ if (sig == 0x80) { /* literal byte >= 0x80 */ ++ if (state->histptr < 2*MPPE_HIST_LEN) { ++ /* copy uncompressed byte to the history */ ++ (state->hist)[(state->histptr)++] = ++ (u8) (0x80|((val&0x3f)<<1)|getbits(ibuf, 1 , &i ,&l)); ++ } else { ++ /* buffer overflow; drop packet */ ++ if (state->debug) ++ printk(KERN_ERR "%s%d: trying to write outside history " ++ "buffer\n", __FUNCTION__, state->unit); ++ return DECOMP_ERROR; ++ } ++ olen++; ++ bits -= 9; ++ continue; ++ } ++ ++ /* Not a literal byte so it must be an (offset,length) pair */ ++ /* decode offset */ ++ sig = val & 0xf0; ++ if (sig == 0xf0) { /* 10-bit offset; 0 <= offset < 64 */ ++ off = (((val&0x0f)<<2)|getbits(ibuf, 2 , &i ,&l)); ++ bits -= 10; ++ } else { ++ if (sig == 0xe0) { /* 12-bit offset; 64 <= offset < 320 */ ++ off = ((((val&0x0f)<<4)|getbits(ibuf, 4 , &i ,&l))+64); ++ bits -= 12; ++ } else { ++ if ((sig&0xe0) == 0xc0) {/* 16-bit offset; 320 <= offset < 8192 */ ++ off = ((((val&0x1f)<<8)|getbyte(ibuf, i++, l))+320); ++ bits -= 16; ++ if (off > MPPE_HIST_LEN - 1) { ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: too big offset value: %d\n", ++ __FUNCTION__, state->unit, off); ++ return DECOMP_ERROR; ++ } ++ } else { /* this shouldn't happen */ ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: cannot decode offset value\n", ++ __FUNCTION__, state->unit); ++ return DECOMP_ERROR; ++ } ++ } ++ } ++ /* decode length of match */ ++ val = getbyte(ibuf, i, l); ++ if ((val & 0x80) == 0x00) { /* len = 3 */ ++ len = 3; ++ bits--; ++ getbits(ibuf, 1 , &i ,&l); ++ } else if ((val & 0xc0) == 0x80) { /* 4 <= len < 8 */ ++ len = 0x04 | ((val>>4) & 0x03); ++ bits -= 4; ++ getbits(ibuf, 4 , &i ,&l); ++ } else if ((val & 0xe0) == 0xc0) { /* 8 <= len < 16 */ ++ len = 0x08 | ((val>>2) & 0x07); ++ bits -= 6; ++ getbits(ibuf, 6 , &i ,&l); ++ } else if ((val & 0xf0) == 0xe0) { /* 16 <= len < 32 */ ++ len = 0x10 | (val & 0x0f); ++ bits -= 8; ++ i++; ++ } else { ++ bits -= 8; ++ val = (val << 8) | getbyte(ibuf, ++i, l); ++ if ((val & 0xf800) == 0xf000) { /* 32 <= len < 64 */ ++ len = 0x0020 | ((val >> 6) & 0x001f); ++ bits -= 2; ++ getbits(ibuf, 2 , &i ,&l); ++ } else if ((val & 0xfc00) == 0xf800) { /* 64 <= len < 128 */ ++ len = 0x0040 | ((val >> 4) & 0x003f); ++ bits -= 4; ++ getbits(ibuf, 4 , &i ,&l); ++ } else if ((val & 0xfe00) == 0xfc00) { /* 128 <= len < 256 */ ++ len = 0x0080 | ((val >> 2) & 0x007f); ++ bits -= 6; ++ getbits(ibuf, 6 , &i ,&l); ++ } else if ((val & 0xff00) == 0xfe00) { /* 256 <= len < 512 */ ++ len = 0x0100 | (val & 0x00ff); ++ bits -= 8; ++ i++; ++ } else { ++ bits -= 8; ++ val = (val << 8) | getbyte(ibuf, ++i, l); ++ if ((val & 0xff8000) == 0xff0000) { /* 512 <= len < 1024 */ ++ len = 0x000200 | ((val >> 6) & 0x0001ff); ++ bits -= 2; ++ getbits(ibuf, 2 , &i ,&l); ++ } else if ((val & 0xffc000) == 0xff8000) {/* 1024 <= len < 2048 */ ++ len = 0x000400 | ((val >> 4) & 0x0003ff); ++ bits -= 4; ++ getbits(ibuf, 4 , &i ,&l); ++ } else if ((val & 0xffe000) == 0xffc000) {/* 2048 <= len < 4096 */ ++ len = 0x000800 | ((val >> 2) & 0x0007ff); ++ bits -= 6; ++ getbits(ibuf, 6 , &i ,&l); ++ } else if ((val & 0xfff000) == 0xffe000) {/* 4096 <= len < 8192 */ ++ len = 0x001000 | (val & 0x000fff); ++ bits -= 8; ++ i++; ++ } else { /* this shouldn't happen */ ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: wrong length code: 0x%X\n", ++ __FUNCTION__, state->unit, val); ++ return DECOMP_ERROR; ++ } ++ } ++ } ++ s = state->hist + state->histptr; ++ state->histptr += len; ++ olen += len; ++ if (state->histptr < 2*MPPE_HIST_LEN) { ++ /* copy uncompressed bytes to the history */ ++ ++ /* In some cases len may be greater than off. It means that memory ++ * areas pointed by s and s-off overlap. I had used memmove() here ++ * because I thought that it acts as libc's version. Unfortunately, ++ * I was wrong. :-) I got strange errors sometimes. Wilfried suggested ++ * using of byte by byte copying here and strange errors disappeared. ++ */ ++ lamecopy(s, s - off, len); ++ } else { ++ /* buffer overflow; drop packet */ ++ if (state->debug) ++ printk(KERN_ERR "%s%d: trying to write outside history " ++ "buffer\n", __FUNCTION__, state->unit); ++ return DECOMP_ERROR; ++ } ++ } ++ ++ /* Do PFC decompression */ ++ len = olen; ++ if ((history[0] & 0x01) != 0) { ++ obuf[0] = 0; ++ obuf++; ++ len++; ++ } ++ ++ if (len <= osize) { ++ /* copy uncompressed packet to the output buffer */ ++ memcpy(obuf, history, olen); ++ } else { ++ /* buffer overflow; drop packet */ ++ if (state->debug) ++ printk(KERN_ERR "%s%d: too big uncompressed packet: %d\n", ++ __FUNCTION__, state->unit, len + (PPP_HDRLEN / 2)); ++ return DECOMP_ERROR; ++ } ++ ++ return (int) len; ++} ++ ++int ++mppe_decompress(void *arg, unsigned char *ibuf, int isize, ++ unsigned char *obuf, int osize) ++{ ++ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg; ++ int seq, bits, uncomplen; ++ ++ if (isize <= PPP_HDRLEN + MPPE_OVHD) { ++ if (state->debug) { ++ printk(KERN_DEBUG "%s%d: short packet (len=%d)\n", __FUNCTION__, ++ state->unit, isize); ++ } ++ return DECOMP_ERROR; ++ } ++ ++ /* Get coherency counter and control bits from input buffer */ ++ seq = MPPE_CCOUNT(ibuf); ++ bits = MPPE_BITS(ibuf); ++ ++ if (state->stateless) { ++ /* RFC 3078, sec 8.1. */ ++ mppe_increase_ccount(state); ++ if ((seq != state->ccount) && state->debug) ++ printk(KERN_DEBUG "%s%d: bad sequence number: %d, expected: %d\n", ++ __FUNCTION__, state->unit, seq, state->ccount); ++ while (seq != state->ccount) ++ mppe_increase_ccount(state); ++ } else { ++ /* RFC 3078, sec 8.2. */ ++ if (state->flushexpected) { /* discard state */ ++ if ((bits & MPPE_BIT_FLUSHED)) { /* we received expected FLUSH bit */ ++ while (seq != state->ccount) ++ mppe_increase_ccount(state); ++ state->flushexpected = 0; ++ } else /* drop packet*/ ++ return DECOMP_ERROR; ++ } else { /* normal state */ ++ mppe_increase_ccount(state); ++ if (seq != state->ccount) { ++ /* Packet loss detected, enter the discard state. */ ++ if (state->debug) ++ printk(KERN_DEBUG "%s%d: bad sequence number: %d, expected: %d\n", ++ __FUNCTION__, state->unit, seq, state->ccount); ++ state->flushexpected = 1; ++ return DECOMP_ERROR; ++ } ++ } ++ if (state->mppe && (bits & MPPE_BIT_FLUSHED)) { ++ arc4_setkey(state, state->session_key, state->keylen); ++ } ++ } ++ ++ if (state->mppc && (bits & (MPPE_BIT_FLUSHED | MPPE_BIT_RESET))) { ++ state->histptr = MPPE_HIST_LEN; ++ if ((bits & MPPE_BIT_FLUSHED)) { ++ memset(state->hist + MPPE_HIST_LEN, 0, MPPE_HIST_LEN*sizeof(u8)); ++ } else ++ if ((bits & MPPE_BIT_RESET)) { ++ memcpy(state->hist, state->hist + MPPE_HIST_LEN, MPPE_HIST_LEN); ++ } ++ } ++ ++ /* Fill in the first part of the PPP header. The protocol field ++ comes from the decompressed data. */ ++ obuf[0] = PPP_ADDRESS(ibuf); ++ obuf[1] = PPP_CONTROL(ibuf); ++ obuf += PPP_HDRLEN / 2; ++ ++ if (state->mppe) { /* process encrypted packet */ ++ if ((bits & MPPE_BIT_ENCRYPTED)) { ++ /* OK, packet encrypted, so decrypt it */ ++ if (state->mppc && (bits & MPPE_BIT_COMP)) { ++ /* Hack warning !!! RC4 implementation which we use does ++ decryption "in place" - it means that input and output ++ buffers can be *the same* memory area. Therefore we don't ++ need to use a temporary buffer. But be careful - other ++ implementations don't have to be so nice. */ ++ arc4_decrypt(state, ibuf + PPP_HDRLEN + (MPPE_OVHD / 2), isize - ++ PPP_HDRLEN - (MPPE_OVHD / 2), ibuf + PPP_HDRLEN + ++ (MPPE_OVHD / 2)); ++ uncomplen = mppc_decompress(state, ibuf + PPP_HDRLEN + ++ (MPPE_OVHD / 2), obuf, isize - ++ PPP_HDRLEN - (MPPE_OVHD / 2), ++ osize - (PPP_HDRLEN / 2)); ++ if (uncomplen == DECOMP_ERROR) { ++ state->flushexpected = 1; ++ return DECOMP_ERROR; ++ } ++ uncomplen += PPP_HDRLEN / 2; ++ (state->stats).comp_bytes += isize; ++ (state->stats).comp_packets++; ++ } else { ++ uncomplen = isize - MPPE_OVHD; ++ /* Decrypt the first byte in order to check if it is ++ compressed or uncompressed protocol field */ ++ arc4_decrypt(state, ibuf + PPP_HDRLEN + (MPPE_OVHD / 2), 1, obuf); ++ /* Do PFC decompression */ ++ if ((obuf[0] & 0x01) != 0) { ++ obuf[1] = obuf[0]; ++ obuf[0] = 0; ++ obuf++; ++ uncomplen++; ++ } ++ /* And finally, decrypt the rest of the frame. */ ++ arc4_decrypt(state, ibuf + PPP_HDRLEN + (MPPE_OVHD / 2) + 1, ++ isize - PPP_HDRLEN - (MPPE_OVHD / 2) - 1, obuf + 1); ++ (state->stats).inc_bytes += isize; ++ (state->stats).inc_packets++; ++ } ++ } else { /* this shouldn't happen */ ++ if (state->debug) ++ printk(KERN_ERR "%s%d: encryption negotiated but not an " ++ "encrypted packet received\n", __FUNCTION__, state->unit); ++ mppe_change_key(state, 0); ++ state->flushexpected = 1; ++ return DECOMP_ERROR; ++ } ++ } else { ++ if (state->mppc) { /* no MPPE, only MPPC */ ++ if ((bits & MPPE_BIT_COMP)) { ++ uncomplen = mppc_decompress(state, ibuf + PPP_HDRLEN + ++ (MPPE_OVHD / 2), obuf, isize - ++ PPP_HDRLEN - (MPPE_OVHD / 2), ++ osize - (PPP_HDRLEN / 2)); ++ if (uncomplen == DECOMP_ERROR) { ++ state->flushexpected = 1; ++ return DECOMP_ERROR; ++ } ++ uncomplen += PPP_HDRLEN / 2; ++ (state->stats).comp_bytes += isize; ++ (state->stats).comp_packets++; ++ } else { ++ memcpy(obuf, ibuf + PPP_HDRLEN + (MPPE_OVHD / 2), isize - ++ PPP_HDRLEN - (MPPE_OVHD / 2)); ++ uncomplen = isize - MPPE_OVHD; ++ (state->stats).inc_bytes += isize; ++ (state->stats).inc_packets++; ++ } ++ } else { /* this shouldn't happen */ ++ if (state->debug) ++ printk(KERN_ERR "%s%d: error - not an MPPC or MPPE frame " ++ "received\n", __FUNCTION__, state->unit); ++ state->flushexpected = 1; ++ return DECOMP_ERROR; ++ } ++ } ++ ++ (state->stats).unc_bytes += uncomplen; ++ (state->stats).unc_packets++; ++ ++ return uncomplen; ++} ++ ++ ++/************************************************************ ++ * Module interface table ++ ************************************************************/ ++ ++/* These are in ppp_generic.c */ ++extern int ppp_register_compressor (struct compressor *cp); ++extern void ppp_unregister_compressor (struct compressor *cp); ++ ++/* ++ * Functions exported to ppp_generic.c. ++ * ++ * In case of MPPC/MPPE there is no need to process incompressible data ++ * because such a data is sent in MPPC/MPPE frame. Therefore the (*incomp) ++ * callback function isn't needed. ++ */ ++struct compressor ppp_mppe = { ++ CI_MPPE, /* compress_proto */ ++ mppe_comp_alloc, /* comp_alloc */ ++ mppe_comp_free, /* comp_free */ ++ mppe_comp_init, /* comp_init */ ++ mppe_comp_reset, /* comp_reset */ ++ mppe_compress, /* compress */ ++ mppe_stats, /* comp_stat */ ++ mppe_decomp_alloc, /* decomp_alloc */ ++ mppe_comp_free, /* decomp_free */ ++ mppe_decomp_init, /* decomp_init */ ++ mppe_decomp_reset, /* decomp_reset */ ++ mppe_decompress, /* decompress */ ++ NULL, /* incomp */ ++ mppe_stats, /* decomp_stat */ ++}; ++ ++/************************************************************ ++ * Module support routines ++ ************************************************************/ ++ ++int __init mppe_module_init(void) ++{ ++ int answer = ppp_register_compressor(&ppp_mppe); ++ if (answer == 0) { ++ printk(KERN_INFO "MPPE/MPPC encryption/compression module registered\n"); ++ } ++ return answer; ++} ++ ++void __exit mppe_module_cleanup(void) ++{ ++ ppp_unregister_compressor(&ppp_mppe); ++ printk(KERN_INFO "MPPE/MPPC encryption/compression module unregistered\n"); ++} ++ ++module_init(mppe_module_init); ++module_exit(mppe_module_cleanup); ++ ++MODULE_AUTHOR("Jan Dubiec "); ++MODULE_DESCRIPTION("MPPE/MPPC encryption/compression module for Linux"); ++MODULE_LICENSE("Dual BSD/GPL"); +diff -ruN linux.orig/include/linux/ppp-comp.h linux/include/linux/ppp-comp.h +--- linux.orig/include/linux/ppp-comp.h 1999-08-06 19:44:11.000000000 +0200 ++++ linux/include/linux/ppp-comp.h 2004-08-08 12:17:43.000000000 +0200 +@@ -1,34 +1,42 @@ + /* + * ppp-comp.h - Definitions for doing PPP packet compression. + * +- * Copyright (c) 1994 The Australian National University. +- * All rights reserved. ++ * Copyright (c) 1984 Paul Mackerras. All rights reserved. + * +- * Permission to use, copy, modify, and distribute this software and its +- * documentation is hereby granted, provided that the above copyright +- * notice appears in all copies. This software is provided without any +- * warranty, express or implied. The Australian National University +- * makes no representations about the suitability of this software for +- * any purpose. +- * +- * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY +- * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF +- * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY +- * OF SUCH DAMAGE. +- * +- * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, +- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +- * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO +- * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, +- * OR MODIFICATIONS. ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: + * +- * $Id: ppp-comp.h,v 1.6 1997/11/27 06:04:44 paulus Exp $ ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. The name(s) of the authors of this software must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. ++ * ++ * 4. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by Paul Mackerras ++ * ". ++ * ++ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO ++ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ++ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY ++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN ++ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING ++ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * $Id: ppp-comp.h,v 1.10 2002/12/06 09:49:15 paulus Exp $ + */ + + /* +- * ==FILEVERSION 980319== ++ * ==FILEVERSION 20040509== + * + * NOTE TO MAINTAINERS: + * If you modify this file at all, please set the above date. +@@ -78,7 +86,7 @@ + + /* Compress a packet */ + int (*compress) (void *state, unsigned char *rptr, +- unsigned char *obuf, int isize, int osize); ++ unsigned char *obuf, int isize, int osize); + + /* Return compression statistics */ + void (*comp_stat) (void *state, struct compstat *stats); +@@ -99,7 +107,7 @@ + + /* Decompress a packet. */ + int (*decompress) (void *state, unsigned char *ibuf, int isize, +- unsigned char *obuf, int osize); ++ unsigned char *obuf, int osize); + + /* Update state for an incompressible packet received */ + void (*incomp) (void *state, unsigned char *ibuf, int icnt); +@@ -187,6 +195,42 @@ + #define DEFLATE_CHK_SEQUENCE 0 + + /* ++ * Definitions for MPPE/MPPC. ++ */ ++ ++#define CI_MPPE 18 /* config option for MPPE */ ++#define CILEN_MPPE 6 /* length of config option */ ++ ++#define MPPE_OVHD 4 /* MPPE overhead */ ++#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */ ++ ++#define MPPE_STATELESS 0x01 /* configuration bit H */ ++#define MPPE_40BIT 0x20 /* configuration bit L */ ++#define MPPE_56BIT 0x80 /* configuration bit M */ ++#define MPPE_128BIT 0x40 /* configuration bit S */ ++#define MPPE_MPPC 0x01 /* configuration bit C */ ++ ++/* ++ * Definitions for Stac LZS. ++ */ ++ ++#define CI_LZS 17 /* config option for Stac LZS */ ++#define CILEN_LZS 5 /* length of config option */ ++ ++#define LZS_OVHD 4 /* max. LZS overhead */ ++#define LZS_HIST_LEN 2048 /* LZS history size */ ++#define LZS_MAX_CCOUNT 0x0FFF /* max. coherency counter value */ ++ ++#define LZS_MODE_NONE 0 ++#define LZS_MODE_LCB 1 ++#define LZS_MODE_CRC 2 ++#define LZS_MODE_SEQ 3 ++#define LZS_MODE_EXT 4 ++ ++#define LZS_EXT_BIT_FLUSHED 0x80 /* bit A */ ++#define LZS_EXT_BIT_COMP 0x20 /* bit C */ ++ ++/* + * Definitions for other, as yet unsupported, compression methods. + */ + diff --git a/packages/linux/linux-mtx-2-2.4.27/40-option-hsdpa.patch b/packages/linux/linux-mtx-2-2.4.27/40-option-hsdpa.patch new file mode 100644 index 0000000000..2055f72312 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/40-option-hsdpa.patch @@ -0,0 +1,2961 @@ +diff -uNr linux-org/Documentation/Configure.help linux/Documentation/Configure.help +--- linux-org/Documentation/Configure.help 2006-02-06 14:01:32.375955928 +0100 ++++ linux/Documentation/Configure.help 2006-02-06 15:51:13.332498464 +0100 +@@ -4057,6 +4057,9 @@ + The module will be called synclinkmp.o. If you want to do that, say M + here. + ++Option HSDPA card support ++CONFIG_NOZOMI ++ + ACP Modem (Mwave) support + CONFIG_MWAVE + The ACP modem (Mwave) for Linux is a WinModem. It is composed of a +diff -uNr linux-org/drivers/char/Config.in linux/drivers/char/Config.in +--- linux-org/drivers/char/Config.in 2006-02-06 14:01:55.767399888 +0100 ++++ linux/drivers/char/Config.in 2006-02-06 15:51:07.574373832 +0100 +@@ -388,6 +388,8 @@ + + endmenu + ++tristate ' Option HSDPA card support' CONFIG_NOZOMI ++ + if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then + source drivers/char/pcmcia/Config.in + fi +diff -uNr linux-org/drivers/char/Makefile linux/drivers/char/Makefile +--- linux-org/drivers/char/Makefile 2006-02-06 14:01:55.782397608 +0100 ++++ linux/drivers/char/Makefile 2006-02-06 15:30:37.949305256 +0100 +@@ -331,6 +331,11 @@ + obj-$(CONFIG_INDYDOG) += indydog.o + obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o + ++subdir-$(CONFIG_NOZOMI) += nozomi ++ifeq ($(CONFIG_NOZOMI),y) ++ obj-y += nozomi/noz.o ++endif ++ + subdir-$(CONFIG_MWAVE) += mwave + ifeq ($(CONFIG_MWAVE),y) + obj-y += mwave/mwave.o +diff -uNr linux-org/drivers/char/nozomi/CHANGELOG linux/drivers/char/nozomi/CHANGELOG +--- linux-org/drivers/char/nozomi/CHANGELOG 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/CHANGELOG 2006-02-06 15:30:07.370953872 +0100 +@@ -0,0 +1,7 @@ ++/* ++ * Version 1.0 ++ * ++ * First version of driver, only tested with card of type F32_2. ++ * Works fine with 2.4 and 2.6 kernels. ++ * Driver also support big endian architecture. ++ */ +diff -uNr linux-org/drivers/char/nozomi/COPYING linux/drivers/char/nozomi/COPYING +--- linux-org/drivers/char/nozomi/COPYING 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/COPYING 2006-02-06 15:30:07.371953720 +0100 +@@ -0,0 +1,340 @@ ++ GNU GENERAL PUBLIC LICENSE ++ Version 2, June 1991 ++ ++ Copyright (C) 1989, 1991 Free Software Foundation, Inc. ++ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ Everyone is permitted to copy and distribute verbatim copies ++ of this license document, but changing it is not allowed. ++ ++ Preamble ++ ++ The licenses for most software are designed to take away your ++freedom to share and change it. By contrast, the GNU General Public ++License is intended to guarantee your freedom to share and change free ++software--to make sure the software is free for all its users. This ++General Public License applies to most of the Free Software ++Foundation's software and to any other program whose authors commit to ++using it. (Some other Free Software Foundation software is covered by ++the GNU Library General Public License instead.) You can apply it to ++your programs, too. ++ ++ When we speak of free software, we are referring to freedom, not ++price. Our General Public Licenses are designed to make sure that you ++have the freedom to distribute copies of free software (and charge for ++this service if you wish), that you receive source code or can get it ++if you want it, that you can change the software or use pieces of it ++in new free programs; and that you know you can do these things. ++ ++ To protect your rights, we need to make restrictions that forbid ++anyone to deny you these rights or to ask you to surrender the rights. ++These restrictions translate to certain responsibilities for you if you ++distribute copies of the software, or if you modify it. ++ ++ For example, if you distribute copies of such a program, whether ++gratis or for a fee, you must give the recipients all the rights that ++you have. You must make sure that they, too, receive or can get the ++source code. And you must show them these terms so they know their ++rights. ++ ++ We protect your rights with two steps: (1) copyright the software, and ++(2) offer you this license which gives you legal permission to copy, ++distribute and/or modify the software. ++ ++ Also, for each author's protection and ours, we want to make certain ++that everyone understands that there is no warranty for this free ++software. If the software is modified by someone else and passed on, we ++want its recipients to know that what they have is not the original, so ++that any problems introduced by others will not reflect on the original ++authors' reputations. ++ ++ Finally, any free program is threatened constantly by software ++patents. We wish to avoid the danger that redistributors of a free ++program will individually obtain patent licenses, in effect making the ++program proprietary. To prevent this, we have made it clear that any ++patent must be licensed for everyone's free use or not licensed at all. ++ ++ The precise terms and conditions for copying, distribution and ++modification follow. ++ ++ GNU GENERAL PUBLIC LICENSE ++ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION ++ ++ 0. This License applies to any program or other work which contains ++a notice placed by the copyright holder saying it may be distributed ++under the terms of this General Public License. The "Program", below, ++refers to any such program or work, and a "work based on the Program" ++means either the Program or any derivative work under copyright law: ++that is to say, a work containing the Program or a portion of it, ++either verbatim or with modifications and/or translated into another ++language. (Hereinafter, translation is included without limitation in ++the term "modification".) Each licensee is addressed as "you". ++ ++Activities other than copying, distribution and modification are not ++covered by this License; they are outside its scope. The act of ++running the Program is not restricted, and the output from the Program ++is covered only if its contents constitute a work based on the ++Program (independent of having been made by running the Program). ++Whether that is true depends on what the Program does. ++ ++ 1. You may copy and distribute verbatim copies of the Program's ++source code as you receive it, in any medium, provided that you ++conspicuously and appropriately publish on each copy an appropriate ++copyright notice and disclaimer of warranty; keep intact all the ++notices that refer to this License and to the absence of any warranty; ++and give any other recipients of the Program a copy of this License ++along with the Program. ++ ++You may charge a fee for the physical act of transferring a copy, and ++you may at your option offer warranty protection in exchange for a fee. ++ ++ 2. You may modify your copy or copies of the Program or any portion ++of it, thus forming a work based on the Program, and copy and ++distribute such modifications or work under the terms of Section 1 ++above, provided that you also meet all of these conditions: ++ ++ a) You must cause the modified files to carry prominent notices ++ stating that you changed the files and the date of any change. ++ ++ b) You must cause any work that you distribute or publish, that in ++ whole or in part contains or is derived from the Program or any ++ part thereof, to be licensed as a whole at no charge to all third ++ parties under the terms of this License. ++ ++ c) If the modified program normally reads commands interactively ++ when run, you must cause it, when started running for such ++ interactive use in the most ordinary way, to print or display an ++ announcement including an appropriate copyright notice and a ++ notice that there is no warranty (or else, saying that you provide ++ a warranty) and that users may redistribute the program under ++ these conditions, and telling the user how to view a copy of this ++ License. (Exception: if the Program itself is interactive but ++ does not normally print such an announcement, your work based on ++ the Program is not required to print an announcement.) ++ ++These requirements apply to the modified work as a whole. If ++identifiable sections of that work are not derived from the Program, ++and can be reasonably considered independent and separate works in ++themselves, then this License, and its terms, do not apply to those ++sections when you distribute them as separate works. But when you ++distribute the same sections as part of a whole which is a work based ++on the Program, the distribution of the whole must be on the terms of ++this License, whose permissions for other licensees extend to the ++entire whole, and thus to each and every part regardless of who wrote it. ++ ++Thus, it is not the intent of this section to claim rights or contest ++your rights to work written entirely by you; rather, the intent is to ++exercise the right to control the distribution of derivative or ++collective works based on the Program. ++ ++In addition, mere aggregation of another work not based on the Program ++with the Program (or with a work based on the Program) on a volume of ++a storage or distribution medium does not bring the other work under ++the scope of this License. ++ ++ 3. You may copy and distribute the Program (or a work based on it, ++under Section 2) in object code or executable form under the terms of ++Sections 1 and 2 above provided that you also do one of the following: ++ ++ a) Accompany it with the complete corresponding machine-readable ++ source code, which must be distributed under the terms of Sections ++ 1 and 2 above on a medium customarily used for software interchange; or, ++ ++ b) Accompany it with a written offer, valid for at least three ++ years, to give any third party, for a charge no more than your ++ cost of physically performing source distribution, a complete ++ machine-readable copy of the corresponding source code, to be ++ distributed under the terms of Sections 1 and 2 above on a medium ++ customarily used for software interchange; or, ++ ++ c) Accompany it with the information you received as to the offer ++ to distribute corresponding source code. (This alternative is ++ allowed only for noncommercial distribution and only if you ++ received the program in object code or executable form with such ++ an offer, in accord with Subsection b above.) ++ ++The source code for a work means the preferred form of the work for ++making modifications to it. For an executable work, complete source ++code means all the source code for all modules it contains, plus any ++associated interface definition files, plus the scripts used to ++control compilation and installation of the executable. However, as a ++special exception, the source code distributed need not include ++anything that is normally distributed (in either source or binary ++form) with the major components (compiler, kernel, and so on) of the ++operating system on which the executable runs, unless that component ++itself accompanies the executable. ++ ++If distribution of executable or object code is made by offering ++access to copy from a designated place, then offering equivalent ++access to copy the source code from the same place counts as ++distribution of the source code, even though third parties are not ++compelled to copy the source along with the object code. ++ ++ 4. You may not copy, modify, sublicense, or distribute the Program ++except as expressly provided under this License. Any attempt ++otherwise to copy, modify, sublicense or distribute the Program is ++void, and will automatically terminate your rights under this License. ++However, parties who have received copies, or rights, from you under ++this License will not have their licenses terminated so long as such ++parties remain in full compliance. ++ ++ 5. You are not required to accept this License, since you have not ++signed it. However, nothing else grants you permission to modify or ++distribute the Program or its derivative works. These actions are ++prohibited by law if you do not accept this License. Therefore, by ++modifying or distributing the Program (or any work based on the ++Program), you indicate your acceptance of this License to do so, and ++all its terms and conditions for copying, distributing or modifying ++the Program or works based on it. ++ ++ 6. Each time you redistribute the Program (or any work based on the ++Program), the recipient automatically receives a license from the ++original licensor to copy, distribute or modify the Program subject to ++these terms and conditions. You may not impose any further ++restrictions on the recipients' exercise of the rights granted herein. ++You are not responsible for enforcing compliance by third parties to ++this License. ++ ++ 7. If, as a consequence of a court judgment or allegation of patent ++infringement or for any other reason (not limited to patent issues), ++conditions are imposed on you (whether by court order, agreement or ++otherwise) that contradict the conditions of this License, they do not ++excuse you from the conditions of this License. If you cannot ++distribute so as to satisfy simultaneously your obligations under this ++License and any other pertinent obligations, then as a consequence you ++may not distribute the Program at all. For example, if a patent ++license would not permit royalty-free redistribution of the Program by ++all those who receive copies directly or indirectly through you, then ++the only way you could satisfy both it and this License would be to ++refrain entirely from distribution of the Program. ++ ++If any portion of this section is held invalid or unenforceable under ++any particular circumstance, the balance of the section is intended to ++apply and the section as a whole is intended to apply in other ++circumstances. ++ ++It is not the purpose of this section to induce you to infringe any ++patents or other property right claims or to contest validity of any ++such claims; this section has the sole purpose of protecting the ++integrity of the free software distribution system, which is ++implemented by public license practices. Many people have made ++generous contributions to the wide range of software distributed ++through that system in reliance on consistent application of that ++system; it is up to the author/donor to decide if he or she is willing ++to distribute software through any other system and a licensee cannot ++impose that choice. ++ ++This section is intended to make thoroughly clear what is believed to ++be a consequence of the rest of this License. ++ ++ 8. If the distribution and/or use of the Program is restricted in ++certain countries either by patents or by copyrighted interfaces, the ++original copyright holder who places the Program under this License ++may add an explicit geographical distribution limitation excluding ++those countries, so that distribution is permitted only in or among ++countries not thus excluded. In such case, this License incorporates ++the limitation as if written in the body of this License. ++ ++ 9. The Free Software Foundation may publish revised and/or new versions ++of the General Public License from time to time. Such new versions will ++be similar in spirit to the present version, but may differ in detail to ++address new problems or concerns. ++ ++Each version is given a distinguishing version number. If the Program ++specifies a version number of this License which applies to it and "any ++later version", you have the option of following the terms and conditions ++either of that version or of any later version published by the Free ++Software Foundation. If the Program does not specify a version number of ++this License, you may choose any version ever published by the Free Software ++Foundation. ++ ++ 10. If you wish to incorporate parts of the Program into other free ++programs whose distribution conditions are different, write to the author ++to ask for permission. For software which is copyrighted by the Free ++Software Foundation, write to the Free Software Foundation; we sometimes ++make exceptions for this. Our decision will be guided by the two goals ++of preserving the free status of all derivatives of our free software and ++of promoting the sharing and reuse of software generally. ++ ++ NO WARRANTY ++ ++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY ++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN ++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES ++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED ++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS ++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE ++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, ++REPAIR OR CORRECTION. ++ ++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING ++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR ++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, ++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING ++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED ++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY ++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER ++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE ++POSSIBILITY OF SUCH DAMAGES. ++ ++ END OF TERMS AND CONDITIONS ++ ++ How to Apply These Terms to Your New Programs ++ ++ If you develop a new program, and you want it to be of the greatest ++possible use to the public, the best way to achieve this is to make it ++free software which everyone can redistribute and change under these terms. ++ ++ To do so, attach the following notices to the program. It is safest ++to attach them to the start of each source file to most effectively ++convey the exclusion of warranty; and each file should have at least ++the "copyright" line and a pointer to where the full notice is found. ++ ++ ++ Copyright (C) ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ ++ ++Also add information on how to contact you by electronic and paper mail. ++ ++If the program is interactive, make it output a short notice like this ++when it starts in an interactive mode: ++ ++ Gnomovision version 69, Copyright (C) year name of author ++ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. ++ This is free software, and you are welcome to redistribute it ++ under certain conditions; type `show c' for details. ++ ++The hypothetical commands `show w' and `show c' should show the appropriate ++parts of the General Public License. Of course, the commands you use may ++be called something other than `show w' and `show c'; they could even be ++mouse-clicks or menu items--whatever suits your program. ++ ++You should also get your employer (if you work as a programmer) or your ++school, if any, to sign a "copyright disclaimer" for the program, if ++necessary. Here is a sample; alter the names: ++ ++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program ++ `Gnomovision' (which makes passes at compilers) written by James Hacker. ++ ++ , 1 April 1989 ++ Ty Coon, President of Vice ++ ++This General Public License does not permit incorporating your program into ++proprietary programs. If your program is a subroutine library, you may ++consider it more useful to permit linking proprietary applications with the ++library. If this is what you want to do, use the GNU Library General ++Public License instead of this License. +diff -uNr linux-org/drivers/char/nozomi/Makefile linux/drivers/char/nozomi/Makefile +--- linux-org/drivers/char/nozomi/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/Makefile 2006-02-06 15:30:07.379952504 +0100 +@@ -0,0 +1,25 @@ ++# ++# Makefile for ACP Modem (Mwave). ++# ++# See the README file in this directory for more info. ++# ++# Note! Dependencies are done automagically by 'make dep', which also ++# removes any old dependencies. DON'T put your own dependencies here ++# unless it's something special (ie not a .c file). ++# ++# Note 2! The CFLAGS definitions are now inherited from the ++# parent makes.. ++# ++ ++# To compile in lots (~20 KiB) of run-time enablable printk()s for debugging: ++#EXTRA_CFLAGS += -DMW_TRACE ++ ++# To have the mwave driver disable other uarts if necessary ++# EXTRA_CFLAGS += -DMWAVE_FUTZ_WITH_OTHER_DEVICES ++ ++O_TARGET := noz.o ++ ++obj-y := nozomi.o kfifo.o ++obj-m := $(O_TARGET) ++ ++include $(TOPDIR)/Rules.make +diff -uNr linux-org/drivers/char/nozomi/README linux/drivers/char/nozomi/README +--- linux-org/drivers/char/nozomi/README 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/README 2006-02-06 15:30:07.380952352 +0100 +@@ -0,0 +1,17 @@ ++To build this driver for your kernel, please check: ++ ++For kernel 2.6 ++--------------- ++Check the Makefile and run 'make'. ++ ++For kernel 2.4 ++---------- ++make HW=PC_24 ++ ++If you have troubles: ++1) Have proper kernel headers/source as your running kernel. ++2) Make sure this variable in Makefile is correct KERNELDIR = -I/path/to/kernel ++3) If the /dev/noz[0-3] will not be created automatically, do: ++mknod /dev/noz0 c 241 0; mknod /dev/noz1 c 241 1; ++mknod /dev/noz2 c 241 2; mknod /dev/noz3 c 241 3 ++ +diff -uNr linux-org/drivers/char/nozomi/TODO linux/drivers/char/nozomi/TODO +--- linux-org/drivers/char/nozomi/TODO 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/TODO 2006-02-06 15:30:07.361955240 +0100 +@@ -0,0 +1,6 @@ ++* When having a noz* open and rmmod module or removing card, ++ the driver core dumps. ++ ++* Does not yet support multiple cards. ++ ++* Add a helpful description. +diff -uNr linux-org/drivers/char/nozomi/kfifo.c linux/drivers/char/nozomi/kfifo.c +--- linux-org/drivers/char/nozomi/kfifo.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/kfifo.c 2006-02-06 15:30:07.361955240 +0100 +@@ -0,0 +1,189 @@ ++/* ++ * A simple kernel FIFO implementation. ++ * ++ * Copyright (C) 2004 Stelian Pop ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include "kfifo.h" ++ ++ ++/** ++ * kfifo_init - allocates a new FIFO using a preallocated buffer ++ * @buffer: the preallocated buffer to be used. ++ * @size: the size of the internal buffer, this have to be a power of 2. ++ * @gfp_mask: get_free_pages mask, passed to kmalloc() ++ * @lock: the lock to be used to protect the fifo buffer ++ * ++ * Do NOT pass the kfifo to kfifo_free() after use ! Simply free the ++ * struct kfifo with kfree(). ++ */ ++struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size, ++ unsigned int gfp_mask, void *lock) ++{ ++ struct kfifo *fifo; ++ ++ /* size must be a power of 2 */ ++ BUG_ON(size & (size - 1)); ++ ++ fifo = kmalloc(sizeof(struct kfifo), gfp_mask); ++ if (!fifo) ++ return ERR_PTR(-ENOMEM); ++ ++ fifo->buffer = buffer; ++ fifo->size = size; ++ fifo->in = fifo->out = 0; ++ ++ return fifo; ++} ++ ++/** ++ * kfifo_alloc - allocates a new FIFO and its internal buffer ++ * @size: the size of the internal buffer to be allocated. ++ * @gfp_mask: get_free_pages mask, passed to kmalloc() ++ * @lock: the lock to be used to protect the fifo buffer ++ * ++ * The size will be rounded-up to a power of 2. ++ */ ++struct kfifo *kfifo_alloc(unsigned int size, unsigned int gfp_mask, void *lock) ++{ ++ unsigned char *buffer; ++ struct kfifo *ret; ++ ++ /* ++ * round up to the next power of 2, since our 'let the indices ++ * wrap' tachnique works only in this case. ++ */ ++ if (size & (size - 1)) { ++ BUG_ON(size > 0x80000000); ++ printk("Do not support no power of two!\n"); ++ //size = roundup_pow_of_two(size); ++ } ++ ++ buffer = kmalloc(size, gfp_mask); ++ if (!buffer) ++ return ERR_PTR(-ENOMEM); ++ ++ ret = kfifo_init(buffer, size, gfp_mask, lock); ++ ++ if (IS_ERR(ret)) ++ kfree(buffer); ++ ++ return ret; ++} ++ ++/** ++ * kfifo_free - frees the FIFO ++ * @fifo: the fifo to be freed. ++ */ ++void kfifo_free(struct kfifo *fifo) ++{ ++ kfree(fifo->buffer); ++ kfree(fifo); ++} ++ ++/** ++ * __kfifo_put - puts some data into the FIFO, no locking version ++ * @fifo: the fifo to be used. ++ * @buffer: the data to be added. ++ * @len: the length of the data to be added. ++ * ++ * This function copies at most 'len' bytes from the 'buffer' into ++ * the FIFO depending on the free space, and returns the number of ++ * bytes copied. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these functions. ++ */ ++unsigned int __kfifo_put(struct kfifo *fifo, ++ unsigned char *buffer, unsigned int len) ++{ ++ unsigned int l; ++ ++ len = min(len, fifo->size - fifo->in + fifo->out); ++ ++ /* first put the data starting from fifo->in to buffer end */ ++ l = min(len, fifo->size - (fifo->in & (fifo->size - 1))); ++ memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l); ++ ++ /* then put the rest (if any) at the beginning of the buffer */ ++ memcpy(fifo->buffer, buffer + l, len - l); ++ ++ fifo->in += len; ++ ++ return len; ++} ++ ++/** __kfifio_put_user works like __kfifo_put, but copies data from ++ * user space. ++ */ ++ ++unsigned int __kfifo_put_user(struct kfifo *fifo, ++ unsigned char *buffer, unsigned int len) ++{ ++ unsigned int l; ++ ++ len = min(len, fifo->size - fifo->in + fifo->out); ++ ++ /* first put the data starting from fifo->in to buffer end */ ++ l = min(len, fifo->size - (fifo->in & (fifo->size - 1))); ++ copy_from_user(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l); ++ ++ /* then put the rest (if any) at the beginning of the buffer */ ++ copy_from_user(fifo->buffer, buffer + l, len - l); ++ ++ fifo->in += len; ++ ++ return len; ++} ++ ++ ++ ++/** ++ * __kfifo_get - gets some data from the FIFO, no locking version ++ * @fifo: the fifo to be used. ++ * @buffer: where the data must be copied. ++ * @len: the size of the destination buffer. ++ * ++ * This function copies at most 'len' bytes from the FIFO into the ++ * 'buffer' and returns the number of copied bytes. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these functions. ++ */ ++unsigned int __kfifo_get(struct kfifo *fifo, ++ unsigned char *buffer, unsigned int len) ++{ ++ unsigned int l; ++ ++ len = min(len, fifo->in - fifo->out); ++ ++ /* first get the data from fifo->out until the end of the buffer */ ++ l = min(len, fifo->size - (fifo->out & (fifo->size - 1))); ++ memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l); ++ ++ /* then get the rest (if any) from the beginning of the buffer */ ++ memcpy(buffer + l, fifo->buffer, len - l); ++ ++ fifo->out += len; ++ ++ return len; ++} +diff -uNr linux-org/drivers/char/nozomi/kfifo.h linux/drivers/char/nozomi/kfifo.h +--- linux-org/drivers/char/nozomi/kfifo.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/kfifo.h 2006-02-06 15:30:07.361955240 +0100 +@@ -0,0 +1,67 @@ ++/* ++ * A simple kernel FIFO implementation. ++ * ++ * Copyright (C) 2004 Stelian Pop ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++#ifndef _LINUX_KFIFO_H ++#define _LINUX_KFIFO_H ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++#warning "Don't include this header in 2.6, use header supplied with kernel" ++#endif ++ ++struct kfifo { ++ unsigned char *buffer; /* the buffer holding the data */ ++ unsigned int size; /* the size of the allocated buffer */ ++ unsigned int in; /* data is added at offset (in % size) */ ++ unsigned int out; /* data is extracted from off. (out % size) */ ++}; ++ ++extern struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size, unsigned int gfp_mask, void *lock); ++extern struct kfifo *kfifo_alloc(unsigned int size, unsigned int gfp_mask, void *lock); ++extern void kfifo_free(struct kfifo *fifo); ++extern unsigned int __kfifo_put(struct kfifo *fifo, unsigned char *buffer, unsigned int len); ++extern unsigned int __kfifo_put_user(struct kfifo *fifo, unsigned char *buffer, unsigned int len); ++extern unsigned int __kfifo_get(struct kfifo *fifo, unsigned char *buffer, unsigned int len); ++ ++/** ++ * __kfifo_reset - removes the entire FIFO contents, no locking version ++ * @fifo: the fifo to be emptied. ++ */ ++static inline void __kfifo_reset(struct kfifo *fifo) ++{ ++ fifo->in = fifo->out = 0; ++} ++ ++/** ++ * __kfifo_len - returns the number of bytes available in the FIFO, no locking version ++ * @fifo: the fifo to be used. ++ */ ++static inline unsigned int __kfifo_len(struct kfifo *fifo) ++{ ++ return fifo->in - fifo->out; ++} ++ ++#else ++#warning "don't include kernel headers in userspace" ++#endif /* __KERNEL__ */ ++#endif +diff -uNr linux-org/drivers/char/nozomi/nozomi.c linux/drivers/char/nozomi/nozomi.c +--- linux-org/drivers/char/nozomi/nozomi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux/drivers/char/nozomi/nozomi.c 2006-02-06 15:30:07.379952504 +0100 +@@ -0,0 +1,2238 @@ ++ ++/* nozomi.c -- HSDPA driver Broadband Wireless Data Card - Globe Trotter ++ * ++ * Written by: Ulf Jakobsson, ++ * Jan Åkerfeldt, ++ * Stefan Thomasson, ++ * ++ * Maintained by: Paul Hardwick, p.hardwick@option.com ++ * ++ * Source has been ported from an implementation made by Filip Aben, f.aben@option.com ++ * ++ * -------------------------------------------------------------------------- ++ ++ Copyright (c) 2005 Option Wireless Sweden AB ++ All rights Reserved. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ ++ * -------------------------------------------------------------------------- ++ */ ++ ++/* CHANGELOG ++ * ++ * See CHANGELOG in this package ++ */ ++ ++/* TODO ++ * ++ * See TODO file in this package ++ */ ++ ++ ++/* ++ * TODO2 fix the send_reset_token() routine not to use the fixed start address ++ */ ++ ++ ++ ++#include ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++#define KERNEL_2_6 ++#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0) ++#define KERNEL_2_4 ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define VERSION_STRING DRIVER_DESC " (build date: " __DATE__ " " __TIME__ ")" ++ ++#ifdef KERNEL_2_6 ++#include ++#else ++#include "kfifo.h" ++#endif ++ ++#ifdef KERNEL_2_4 ++#ifndef IRQ_NONE ++#define IRQ_NONE ++#endif ++#ifndef IRQ_HANDLED ++#define IRQ_HANDLED ++typedef void irqreturn_t; ++#endif ++#endif ++ ++#ifndef CONFIG_PCI ++#error "This driver needs PCI support to be available" ++#endif ++ ++/* Macros definitions */ ++ ++/* Enable this to have a lot of debug printouts */ ++/*#define NOZOMI_DEBUG */ ++ ++/* Default debug printout level */ ++#define NOZOMI_DEBUG_LEVEL 0xffff ++ ++#define P_BUF_SIZE 128 ++#define NFO( _err_flag_, args...) \ ++ do{ \ ++ char t_m_p_[P_BUF_SIZE]; \ ++ snprintf(t_m_p_, sizeof(t_m_p_), ##args); \ ++ printk( _err_flag_ "[%d] %s(): %s\n", __LINE__, __FUNCTION__, t_m_p_); \ ++} while(0) ++ ++#define INFO(args...) NFO(KERN_INFO, ##args) ++#define ERR(args...) NFO( KERN_ERR, ##args) ++ ++#define D1(args...) D_(0x01, ##args) ++#define D2(args...) D_(0x02, ##args) ++#define D3(args...) D_(0x04, ##args) ++#define D4(args...) D_(0x08, ##args) ++#define D5(args...) D_(0x10, ##args) ++#define D6(args...) D_(0x20, ##args) ++#define D7(args...) D_(0x40, ##args) ++#define D8(args...) D_(0x80, ##args) ++ ++ ++#ifdef NOZOMI_DEBUG ++#define D_(lvl, args...) D(lvl, ##args) ++ /* Do we need this settable at runtime? */ ++static int nzdebug = NOZOMI_DEBUG_LEVEL; ++ ++#define D(lvl, args...) do{if(lvl & nzdebug) NFO(KERN_INFO, ##args );}while(0) ++#define D_(lvl, args...) D(lvl, ##args) ++ ++/* These printouts are always printed */ ++ ++#else ++ static const int nzdebug = 0; ++#define D_(lvl, args...) ++#endif ++ ++/* TODO: rewrite to optimize macros... */ ++#define SET_FCR(value__) \ ++ do { \ ++ writew((value__), (void*) (dc->REG_FCR )); \ ++} while(0) ++ ++#define SET_IER(value__, mask__) \ ++ do { \ ++ dc->ier_last_written = (dc->ier_last_written & ~mask__) | (value__ & mask__ );\ ++ writew( dc->ier_last_written, (void*) (dc->REG_IER));\ ++} while(0) ++ ++#define GET_IER(read_val__) \ ++ do { \ ++ (read_val__) = readw((void*) (dc->REG_IER));\ ++} while(0) ++ ++#define GET_IIR(read_val__) \ ++ do { \ ++ (read_val__) = readw((void*) (dc->REG_IIR));\ ++} while(0) ++ ++#define GET_MEM(value__, addr__, length__) \ ++ do { \ ++ read_mem32( (u32*) (value__), (u32) (addr__), (length__));\ ++} while(0) ++ ++#define GET_MEM_BUF(value__, addr__, length__) \ ++ do { \ ++ read_mem32_buf( (u32*) (value__), (u32) (addr__), (length__));\ ++} while(0) ++ ++#define SET_MEM(addr__, value__, length__) \ ++ do { \ ++ write_mem32( (addr__), (u32*) (value__), (length__));\ ++} while(0) ++ ++#define SET_MEM_BUF(addr__, value__, length__) \ ++ do { \ ++ write_mem32_buf( (addr__), (u32*) (value__), (length__));\ ++} while(0) ++ ++ ++#define TMP_BUF_MAX 256 ++ ++#define DUMP(buf__,len__) \ ++ do { \ ++ char tbuf[TMP_BUF_MAX]={0};\ ++ if (len__>1) {\ ++ snprintf(tbuf, len__ > TMP_BUF_MAX ? TMP_BUF_MAX : len__, "%s",buf__);\ ++ if(tbuf[len__-2] == '\r') {\ ++ tbuf[len__-2] = 'r';\ ++ }\ ++ D1( "SENDING: '%s' (%d+n)", tbuf, len__);\ ++ } else {\ ++ D1( "SENDING: '%s' (%d)", tbuf, len__);\ ++ }\ ++} while(0) ++ ++#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) ++ ++ ++/* Defines */ ++#define NOZOMI_NAME "nozomi" ++#define NOZOMI_NAME_TTY "nozomi_tty" ++#define DRIVER_DESC "Nozomi driver" ++ ++#define NTTY_TTY_MAJOR 241 ++#define NTTY_TTY_MINORS MAX_PORT ++#define NTTY_FIFO_BUFFER_SIZE 8192 ++ ++/* Must be power of 2 */ ++#define FIFO_BUFFER_SIZE_UL 8192 ++ ++/* Size of tmp send buffer to card */ ++#define SEND_BUF_MAX 1024 ++#define RECEIVE_BUF_MAX 4 ++ ++/* Our fake UART values */ ++#define MCR_DTR 0x01 ++#define MCR_RTS 0x02 ++#define MCR_LOOP 0x04 ++#define MSR_CTS 0x08 ++#define MSR_CD 0x10 ++#define MSR_RI 0x20 ++#define MSR_DSR 0x40 ++ ++/* Define all types of vendors and devices to support */ ++#define VENDOR1 0x1931 /* Vendor Option */ ++#define DEVICE1 0x000c /* HSDPA card */ ++ ++#define R_IIR 0x0000 /* Interrupt Identity Register */ ++#define R_FCR 0x0000 /* Flow Control Register */ ++#define R_IER 0x0004 /* Interrupt Enable Register */ ++ ++#define CONFIG_MAGIC 0xEFEFFEFE ++#define TOGGLE_VALID 0x0000 ++ ++/* Definition of interrupt tokens */ ++#define MDM_DL1 0x0001 ++#define MDM_UL1 0x0002 ++#define MDM_DL2 0x0004 ++#define MDM_UL2 0x0008 ++#define DIAG_DL1 0x0010 ++#define DIAG_DL2 0x0020 ++#define DIAG_UL 0x0040 ++#define APP1_DL 0x0080 ++#define APP1_UL 0x0100 ++#define APP2_DL 0x0200 ++#define APP2_UL 0x0400 ++#define CTRL_DL 0x0800 ++#define CTRL_UL 0x1000 ++#define RESET 0x8000 ++ ++#define MDM_DL (MDM_DL1 | MDM_DL2) ++#define MDM_UL (MDM_UL1 | MDM_UL2) ++#define DIAG_DL (DIAG_DL1 | DIAG_DL2) ++ ++/* modem signal definition */ ++#define CTRL_DSR 0x0001 ++#define CTRL_DCD 0x0002 ++#define CTRL_RI 0x0004 ++#define CTRL_CTS 0x0008 ++ ++#define CTRL_DTR 0x0001 ++#define CTRL_RTS 0x0002 ++ ++#define MAX_PORT 4 ++#define NOZOMI_MAX_PORTS 5 ++ ++/* Type definitions */ ++ ++/* There are two types of nozomi cards, one with 2048 memory and with 8192 memory */ ++typedef enum { ++ F32_2 = 2048, /* Has 512 bytes downlink and uplink * 2 -> 2048 */ ++ F32_8 = 9192, /* Has 3072 bytes downlink and 1024 bytes uplink * 2 -> 8192 */ ++} card_type_t; ++ ++/* Two different toggle channels exist */ ++typedef enum { ++ CH_A=0, ++ CH_B=1, ++} channel_t; ++ ++/* Port definition for the card regarding flow control */ ++typedef enum { ++ CTRL_CMD = 0x00, ++ CTRL_MDM = 0x01, ++ CTRL_DIAG = 0x02, ++ CTRL_APP1 = 0x03, ++ CTRL_APP2 = 0x04, ++ CTRL_ERROR = -1, ++} ctrl_port_t; ++ ++/* Ports that the nozomi has */ ++typedef enum { ++ PORT_MDM = 0, ++ PORT_DIAG= 1, ++ PORT_APP1= 2, ++ PORT_APP2= 3, ++ PORT_CTRL= 4, ++ PORT_ERROR=-1, ++} port_type_t; ++ ++#ifdef __ARMEB__ ++/* Big endian */ ++ ++typedef struct { ++ unsigned enabled : 5; /* Toggle fields are valid if enabled is 0, else A-channels ++ must always be used. */ ++ unsigned diag_dl : 1; ++ unsigned mdm_dl : 1; ++ unsigned mdm_ul : 1; ++} __attribute__ ((packed)) toggles_t; ++ ++/* Configuration table to read at startup of card */ ++/* Is for now only needed during initialization phase */ ++typedef struct { ++ u32 signature; ++ u16 product_information; ++ u16 version; ++ u8 pad3[3]; ++ toggles_t toggle; ++ u8 pad1[4]; ++ u16 dl_mdm_len1; /* If this is 64, it can hold 60 bytes + 4 that is length field */ ++ u16 dl_start; ++ ++ u16 dl_diag_len1; ++ u16 dl_mdm_len2; /* If this is 64, it can hold 60 bytes + 4 that is length field */ ++ u16 dl_app1_len; ++ ++ u16 dl_diag_len2; ++ u16 dl_ctrl_len; ++ u16 dl_app2_len; ++ u8 pad2[16]; ++ u16 ul_mdm_len1; ++ u16 ul_start; ++ u16 ul_diag_len; ++ u16 ul_mdm_len2; ++ u16 ul_app1_len; ++ u16 ul_app2_len; ++ u16 ul_ctrl_len; ++} __attribute__((packed)) config_table_t; ++ ++/* This stores all control downlink flags */ ++typedef struct { ++ u8 port; ++ unsigned reserved : 4; ++ unsigned CTS : 1; ++ unsigned RI : 1; ++ unsigned DCD : 1; ++ unsigned DSR : 1; ++} __attribute__ ((packed)) ctrl_dl_t; ++ ++/* This stores all control uplink flags */ ++typedef struct { ++ u8 port; ++ unsigned reserved : 6; ++ unsigned RTS : 1; ++ unsigned DTR : 1; ++} __attribute__ ((packed)) ctrl_ul_t; ++ ++#else ++/* Little endian */ ++ ++/* This represents the toggle information */ ++typedef struct { ++ unsigned mdm_ul : 1; ++ unsigned mdm_dl : 1; ++ unsigned diag_dl : 1; ++ unsigned enabled : 5; /* Toggle fields are valid if enabled is 0, else A-channels ++ must always be used. */ ++} __attribute__ ((packed)) toggles_t; ++ ++/* Configuration table to read at startup of card */ ++typedef struct { ++ u32 signature; ++ u16 version; ++ u16 product_information; ++ toggles_t toggle; ++ u8 pad1[7]; ++ u16 dl_start; ++ u16 dl_mdm_len1; /* If this is 64, it can hold 60 bytes + 4 that is length field */ ++ u16 dl_mdm_len2; ++ u16 dl_diag_len1; ++ u16 dl_diag_len2; ++ u16 dl_app1_len; ++ u16 dl_app2_len; ++ u16 dl_ctrl_len; ++ u8 pad2[16]; ++ u16 ul_start; ++ u16 ul_mdm_len2; ++ u16 ul_mdm_len1; ++ u16 ul_diag_len; ++ u16 ul_app1_len; ++ u16 ul_app2_len; ++ u16 ul_ctrl_len; ++} __attribute__((packed)) config_table_t; ++ ++/* This stores all control downlink flags */ ++typedef struct { ++ unsigned DSR : 1; ++ unsigned DCD : 1; ++ unsigned RI : 1; ++ unsigned CTS : 1; ++ unsigned reserverd : 4; ++ u8 port; ++} __attribute__ ((packed)) ctrl_dl_t; ++ ++/* This stores all control uplink flags */ ++typedef struct { ++ unsigned DTR : 1; ++ unsigned RTS : 1; ++ unsigned reserved : 6; ++ u8 port; ++} __attribute__ ((packed)) ctrl_ul_t; ++#endif ++ ++/* This holds all information that is needed regarding a port */ ++typedef struct { ++ u8 update_flow_control; ++ ctrl_ul_t ctrl_ul; ++ ctrl_dl_t ctrl_dl; ++ struct kfifo *fifo_ul; ++ u32 dl_addr[2]; ++ u32 dl_size[2]; ++ u8 toggle_dl; ++ u32 ul_addr[2]; ++ u32 ul_size[2]; ++ u8 toggle_ul; ++ u16 token_dl; ++ ++ struct tty_struct *tty; ++ int tty_open_count; ++ struct semaphore tty_sem; ++ wait_queue_head_t tty_wait; ++ struct async_icount tty_icount; ++ int tty_index; ++ u32 rx_data, tx_data; ++ u8 tty_dont_flip; ++ ++} port_t; ++ ++/* Private data one for each card in the system */ ++typedef struct { ++ u32 base_addr; ++ u8 closing; ++ ++ /* Register addresses */ ++ u32 REG_IIR; ++ u32 REG_FCR; ++ u32 REG_IER; ++ ++ volatile u16 ier_last_written; ++ card_type_t card_type; ++ config_table_t config_table; /* Configuration table */ ++ struct pci_dev *pdev; ++ port_t port[NOZOMI_MAX_PORTS]; ++ u8 *send_buf; ++ ++ struct tty_driver tty_driver; ++ ++#ifdef KERNEL_2_4 ++ struct tty_struct *tty_table[NTTY_TTY_MINORS]; ++ struct tq_struct tty_flip_queue; ++ s32 tty_refcount; ++#endif ++#ifdef KERNEL_2_6 ++ struct workqueue_struct *tty_flip_wq; ++ struct work_struct tty_flip_wq_struct; ++#endif ++ ++ struct termios *tty_termios[NTTY_TTY_MINORS]; ++ struct termios *tty_termios_locked[NTTY_TTY_MINORS]; ++ spinlock_t spin_mutex; ++ ++ u32 open_ttys; ++ struct proc_dir_entry *proc_entry; ++ ++} dc_t; ++ ++/* This is a data packet that is read or written to/from card */ ++typedef struct { ++ u32 size; /* size is the length of the data buffer */ ++ u8 *data; ++} __attribute__ ((packed)) buf_t; ++ ++/* Function declarations */ ++static int ntty_tty_init(dc_t *dc); ++ ++static void tty_flip_queue_function(void *tmp_dc); ++ ++/* Global variables */ ++static struct pci_device_id nozomi_pci_tbl[] __devinitdata = { ++ {VENDOR1, DEVICE1}, ++ {0, } ++}; ++ ++/* Used to store interrupt variables */ ++typedef struct { ++ volatile u16 read_iir; /* Holds current interrupt tokens */ ++} irq_t; ++ ++MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl); ++ ++/* Representing the pci device of interest */ ++static int cards_found = 0; ++static int cards_initialized = 0; ++dc_t* my_dev = NULL; ++struct pci_dev *my_pdev = NULL; ++irq_t my_irq; ++ ++#define CARD_CHECK(rval) { \ ++ if (cards_found == 0 || cards_found != cards_initialized) { \ ++ ERR("Operation requested on uninitialized nozomi card."); \ ++ return rval; \ ++ } } ++ ++ ++static inline dc_t* get_dc_by_pdev(struct pci_dev* pdev) { ++ return my_dev; ++} ++ ++static inline dc_t* get_dc_by_index(s32 index ) { ++ return my_dev; ++} ++ ++static inline s32 get_index(struct tty_struct *tty) { ++#ifdef KERNEL_2_6 ++ return tty->index; ++#else ++ return MINOR(tty->device) - tty->driver.minor_start; ++#endif ++} ++ ++static inline port_t* get_port_by_tty(struct tty_struct *tty) { ++ return &my_dev->port[ get_index(tty) ]; ++} ++ ++static inline dc_t* get_dc_by_tty(struct tty_struct *tty ) { ++ return my_dev; ++} ++ ++ ++/* TODO: */ ++/* -Optimize */ ++/* -Rewrite cleaner */ ++static void read_mem32(u32 *buf, u32 mem_addr_start, u32 size_bytes) { ++ u32 i = 0; ++ u32* ptr = (u32*) mem_addr_start; ++ u16* buf16; ++ ++ /* 2 bytes */ ++ if (size_bytes == 2) { ++ buf16 = (u16*) buf; ++ *buf16 = readw( ptr ); ++ return; ++ } ++ ++ while (i < size_bytes) { ++ if ( size_bytes - i == 2) { ++ /* Handle 2 bytes in the end */ ++ buf16 = (u16*) buf; ++ *(buf16) = readw( ptr ); ++ i+=2; ++ } else { ++ /* Read 4 bytes */ ++ *(buf) = readl( ptr ); ++ i+=4; ++ } ++ buf++; ptr++; ++ } ++} ++ ++/* TODO: */ ++/* - Rewrite cleaner */ ++/* - merge with read_mem32() */ ++static void read_mem32_buf(u32 *buf, u32 mem_addr_start, u32 size_bytes) { ++#ifdef __ARMEB__ ++ u32 i = 0; ++ u32* ptr = (u32*) mem_addr_start; ++ u16* buf16; ++ ++ /* 2 bytes */ ++ if (size_bytes == 2) { ++ buf16 = (u16*) buf; ++ *buf16 = __le16_to_cpu( readw( ptr )); ++ return; ++ } ++ ++ while (i < size_bytes) { ++ if ( size_bytes - i == 2) { ++ /* Handle 2 bytes in the end */ ++ buf16 = (u16*) buf; ++ *(buf16) = __le16_to_cpu( readw( ptr )); ++ i+=2; ++ } else { ++ /* Read 4 bytes */ ++ *(buf) = __le32_to_cpu( readl( ptr )); ++ i+=4; ++ } ++ buf++; ptr++; ++ } ++#else ++ read_mem32(buf, mem_addr_start, size_bytes); ++#endif ++} ++ ++/* TODO: */ ++/* -Optimize */ ++/* -Rewrite cleaner */ ++static u32 write_mem32(u32 mem_addr_start, u32 *buf, u32 size_bytes) { ++ u32 i = 0; ++ u32* ptr = (u32*) mem_addr_start; ++ u16* buf16; ++ ++ /* 2 bytes */ ++ if (size_bytes == 2) { ++ buf16 = (u16*) buf; ++ writew( *buf16, ptr); ++ return 2; ++ } ++ ++ while (i < size_bytes) { ++ if ( size_bytes - i == 2) { ++ /* 2 bytes */ ++ buf16 = (u16*) buf; ++ writew( *buf16, ptr); ++ i+=2; ++ } else { ++ /* 4 bytes */ ++ writel( *buf, ptr ); ++ i += 4; ++ } ++ buf++; ptr++; ++ } ++ return size_bytes; ++} ++ ++/* Todo: */ ++/* - Merge with write_mem32() */ ++static u32 write_mem32_buf(u32 mem_addr_start, u32 *buf, u32 size_bytes) { ++#ifdef __ARMEB__ ++ u32 i = 0; ++ u32* ptr = (u32*) mem_addr_start; ++ u16* buf16; ++ ++ /* 2 bytes */ ++ if (size_bytes == 2) { ++ buf16 = (u16*) buf; ++ writew( __le16_to_cpu(*buf16), ptr); ++ return 2; ++ } ++ ++ while (i < size_bytes) { ++ if ( size_bytes - i == 2) { ++ /* 2 bytes */ ++ buf16 = (u16*) buf; ++ writew( __le16_to_cpu(*buf16), ptr); ++ i+=2; ++ } else { ++ /* 4 bytes */ ++ writel( __cpu_to_le32( *buf ), ptr ); ++ i += 4; ++ } ++ buf++; ptr++; ++ } ++ return size_bytes; ++#else ++ return write_mem32(mem_addr_start, buf, size_bytes); ++#endif ++} ++ ++/* Setup pointers to different channels and also setup buffer sizes. */ ++static void setup_memory(dc_t *dc) { ++ ++ u32 offset = dc->base_addr + dc->config_table.dl_start; ++ /* The length reported is including the length field of 4 bytes, hence subtract with 4. */ ++ u16 buff_offset = 4; ++ ++ /* Modem port dl configuration */ ++ dc->port[PORT_MDM].dl_addr[CH_A] = offset; ++ dc->port[PORT_MDM].dl_addr[CH_B] = (offset += dc->config_table.dl_mdm_len1); ++ dc->port[PORT_MDM].dl_size[CH_A] = dc->config_table.dl_mdm_len1 - buff_offset; ++ dc->port[PORT_MDM].dl_size[CH_B] = dc->config_table.dl_mdm_len2 - buff_offset; ++ ++ /* Diag port dl configuration */ ++ dc->port[PORT_DIAG].dl_addr[CH_A] = (offset += dc->config_table.dl_mdm_len2); ++ dc->port[PORT_DIAG].dl_size[CH_A] = dc->config_table.dl_diag_len1 - buff_offset; ++ dc->port[PORT_DIAG].dl_addr[CH_B] = (offset += dc->config_table.dl_diag_len1); ++ dc->port[PORT_DIAG].dl_size[CH_B] = dc->config_table.dl_diag_len2 - buff_offset; ++ ++ /* App1 port dl configuration */ ++ dc->port[PORT_APP1].dl_addr[CH_A] = (offset += dc->config_table.dl_diag_len2); ++ dc->port[PORT_APP1].dl_size[CH_A] = dc->config_table.dl_app1_len - buff_offset; ++ ++ /* App2 port dl configuration */ ++ dc->port[PORT_APP2].dl_addr[CH_A] = (offset += dc->config_table.dl_app1_len); ++ dc->port[PORT_APP2].dl_size[CH_A] = dc->config_table.dl_app2_len - buff_offset; ++ ++ /* Ctrl dl configuration */ ++ dc->port[PORT_CTRL].dl_addr[CH_A] = (offset += dc->config_table.dl_app2_len); ++ dc->port[PORT_CTRL].dl_size[CH_A] = dc->config_table.dl_ctrl_len - buff_offset; ++ ++ ++ /* Modem Port ul configuration */ ++ dc->port[PORT_MDM].ul_addr[CH_A] = (offset = dc->base_addr + dc->config_table.ul_start); ++ dc->port[PORT_MDM].ul_size[CH_A] = dc->config_table.ul_mdm_len1 - buff_offset; ++ dc->port[PORT_MDM].ul_addr[CH_B] = (offset += dc->config_table.ul_mdm_len1); ++ dc->port[PORT_MDM].ul_size[CH_B] = dc->config_table.ul_mdm_len2 - buff_offset; ++ ++ /* Diag port ul configuration */ ++ dc->port[PORT_DIAG].ul_addr[CH_A] = (offset += dc->config_table.ul_mdm_len2); ++ dc->port[PORT_DIAG].ul_size[CH_A] = dc->config_table.ul_diag_len - buff_offset; ++ ++ /* App1 port ul configuration */ ++ dc->port[PORT_APP1].ul_addr[CH_A] = (offset += dc->config_table.ul_diag_len); ++ dc->port[PORT_APP1].ul_size[CH_A] = dc->config_table.ul_app1_len - buff_offset; ++ ++ /* App2 port ul configuration */ ++ dc->port[PORT_APP2].ul_addr[CH_A] = (offset += dc->config_table.ul_app1_len); ++ dc->port[PORT_APP2].ul_size[CH_A] = dc->config_table.ul_app2_len - buff_offset; ++ ++ /* Ctrl ul configuration */ ++ dc->port[PORT_CTRL].ul_addr[CH_A] = (offset += dc->config_table.ul_app2_len); ++ dc->port[PORT_CTRL].ul_size[CH_A] = dc->config_table.ul_ctrl_len - buff_offset; ++ offset = dc->config_table.ul_start; ++} ++ ++/* Dump config table under initalization phase */ ++#ifdef NOZOMI_DEBUG ++static void dump_table(dc_t *dc) { ++ D3("signature: 0x%08X", dc->config_table.signature); ++ D3("version: 0x%04X", dc->config_table.version); ++ D3("product_information: 0x%04X", dc->config_table.product_information); ++ D3("toggle enabled: %d", dc->config_table.toggle.enabled); ++ D3("toggle up_mdm: %d", dc->config_table.toggle.mdm_ul); ++ D3("toggle dl_mdm: %d", dc->config_table.toggle.mdm_dl); ++ D3("toggle dl_dbg: %d", dc->config_table.toggle.diag_dl); ++ ++ D3("dl_start: 0x%04X", dc->config_table.dl_start); ++ D3("dl_mdm_len0: 0x%04X, %d", dc->config_table.dl_mdm_len1, dc->config_table.dl_mdm_len1); ++ D3("dl_mdm_len1: 0x%04X, %d", dc->config_table.dl_mdm_len2, dc->config_table.dl_mdm_len2); ++ D3("dl_diag_len0: 0x%04X, %d", dc->config_table.dl_diag_len1, dc->config_table.dl_diag_len1); ++ D3("dl_diag_len1: 0x%04X, %d", dc->config_table.dl_diag_len2, dc->config_table.dl_diag_len2); ++ D3("dl_app1_len: 0x%04X, %d", dc->config_table.dl_app1_len, dc->config_table.dl_app1_len); ++ D3("dl_app2_len: 0x%04X, %d", dc->config_table.dl_app2_len, dc->config_table.dl_app2_len); ++ D3("dl_ctrl_len: 0x%04X, %d", dc->config_table.dl_ctrl_len, dc->config_table.dl_ctrl_len); ++ D3("ul_start: 0x%04X, %d", dc->config_table.ul_start, dc->config_table.ul_start); ++ D3("ul_mdm_len[0]: 0x%04X, %d", dc->config_table.ul_mdm_len1, dc->config_table.ul_mdm_len1); ++ D3("ul_mdm_len[1]: 0x%04X, %d", dc->config_table.ul_mdm_len2, dc->config_table.ul_mdm_len2); ++ D3("ul_diag_len: 0x%04X, %d", dc->config_table.ul_diag_len, dc->config_table.ul_diag_len); ++ D3("ul_app1_len: 0x%04X, %d", dc->config_table.ul_app1_len, dc->config_table.ul_app1_len); ++ D3("ul_app2_len: 0x%04X, %d", dc->config_table.ul_app2_len, dc->config_table.ul_app2_len); ++ D3("ul_ctrl_len: 0x%04X, %d", dc->config_table.ul_ctrl_len, dc->config_table.ul_ctrl_len); ++} ++#endif ++ ++/* Read configuration table from card under intalization phase */ ++/* Returns 1 if ok, else 0 */ ++static int nozomi_read_config_table(dc_t *dc) { ++ ++ if (cards_found > 0 && cards_found == cards_initialized) { ++ return 1; ++ } ++ ++ GET_MEM( &dc->config_table, dc->base_addr + 0, sizeof(config_table_t)); ++ ++ /* D1( "0x%08X == 0x%08X ", dc->config_table.signature, CONFIG_MAGIC); */ ++ ++ if( dc->config_table.signature != CONFIG_MAGIC ) { ++ ERR("ConfigTable Bad! 0x%08X != 0x%08X", dc->config_table.signature, CONFIG_MAGIC); ++ return 0; ++ } ++ ++ if( (dc->config_table.version == 0) || (dc->config_table.toggle.enabled == TOGGLE_VALID) ) { ++ int i; ++ INFO( "Second phase, configuring card"); ++ ++ setup_memory(dc); ++ ++ dc->port[PORT_MDM].toggle_ul = dc->config_table.toggle.mdm_ul; ++ dc->port[PORT_MDM].toggle_dl = dc->config_table.toggle.mdm_dl; ++ dc->port[PORT_DIAG].toggle_dl = dc->config_table.toggle.diag_dl; ++ D1( "toggle ports: MDM UL:%d MDM DL:%d, DIAG DL:%d", ++ dc->port[PORT_MDM].toggle_ul, ++ dc->port[PORT_MDM].toggle_dl, ++ dc->port[PORT_DIAG].toggle_dl); ++ ++#ifdef NOZOMI_DEBUG ++ dump_table(dc); ++#endif ++ for (i=PORT_MDM; i< MAX_PORT;i++) { ++ dc->port[i].fifo_ul = kfifo_alloc( FIFO_BUFFER_SIZE_UL, GFP_ATOMIC , NULL); ++ memset( &dc->port[i].ctrl_dl, 0, sizeof (ctrl_dl_t)); ++ memset( &dc->port[i].ctrl_ul, 0, sizeof (ctrl_ul_t)); ++ } ++ ++ /* Enable control channel */ ++ SET_IER( CTRL_DL, CTRL_DL ); ++ ++ INFO("Initialization OK!"); ++ cards_initialized++; ++ return 1; ++ } ++ ++ if( (dc->config_table.version > 0) && (dc->config_table.toggle.enabled != TOGGLE_VALID ) ) { ++ u32 offset = 0; ++ INFO( "First phase: pushing upload buffers, clearing download"); ++ ++ INFO("Version of card: %d", dc->config_table.version); ++ ++ /* Here we should disable all I/O over F32. */ ++ setup_memory(dc); ++ ++ /* We should send ALL channel pair tokens back along with reset token */ ++ ++ /* push upload modem buffers */ ++ SET_MEM( dc->port[PORT_MDM].ul_addr[CH_A], &offset, 4); ++ SET_MEM( dc->port[PORT_MDM].ul_addr[CH_B], &offset, 4); ++ ++ SET_FCR( MDM_UL | DIAG_DL | MDM_DL ); ++ ++ D1( "First phase done"); ++ } ++ ++ return 1; ++} ++ ++/* Enable uplink interrupts */ ++static void enable_transmit_ul( port_type_t port , dc_t *dc ) { ++ ++ switch( port ) { ++ case PORT_MDM: SET_IER( MDM_UL , MDM_UL ); break; ++ case PORT_DIAG: SET_IER( DIAG_UL, DIAG_UL ); break; ++ case PORT_APP1: SET_IER( APP1_UL, APP1_UL ); break; ++ case PORT_APP2: SET_IER( APP2_UL, APP2_UL ); break; ++ case PORT_CTRL: SET_IER( CTRL_UL, CTRL_UL ); break; ++ default: ++ ERR("Called with wrong port?"); ++ break; ++ }; ++} ++ ++/* Disable uplink interrupts */ ++static void disable_transmit_ul( port_type_t port , dc_t *dc ) { ++ ++ switch( port ) { ++ case PORT_MDM: SET_IER( 0 ,MDM_UL ); break; ++ case PORT_DIAG: SET_IER( 0, DIAG_UL ); break; ++ case PORT_APP1: SET_IER( 0, APP1_UL ); break; ++ case PORT_APP2: SET_IER( 0, APP2_UL ); break; ++ case PORT_CTRL: SET_IER( 0, CTRL_UL ); break; ++ default: ++ ERR("Called with wrong port?"); ++ break; ++ }; ++} ++ ++/* Enable downlink interrupts */ ++static void enable_transmit_dl( port_type_t port , dc_t *dc ) { ++ ++ switch( port ) { ++ case PORT_MDM: SET_IER( MDM_DL , MDM_DL ); break; ++ case PORT_DIAG: SET_IER( DIAG_DL, DIAG_DL ); break; ++ case PORT_APP1: SET_IER( APP1_DL, APP1_DL ); break; ++ case PORT_APP2: SET_IER( APP2_DL, APP2_DL ); break; ++ case PORT_CTRL: SET_IER( CTRL_DL, CTRL_DL ); break; ++ default: ++ ERR("Called with wrong port?"); ++ break; ++ }; ++} ++ ++/* Disable downlink interrupts */ ++static void disable_transmit_dl( port_type_t port , dc_t *dc ) { ++ ++ switch( port ) { ++ case PORT_MDM: SET_IER( 0 ,MDM_DL ); break; ++ case PORT_DIAG: SET_IER( 0, DIAG_DL ); break; ++ case PORT_APP1: SET_IER( 0, APP1_DL ); break; ++ case PORT_APP2: SET_IER( 0, APP2_DL ); break; ++ case PORT_CTRL: SET_IER( 0, CTRL_DL ); break; ++ default: ++ ERR("Called with wrong port?"); ++ break; ++ }; ++} ++ ++/* Return 1 - send buffer to card and ack. */ ++/* Return 0 - don't ack, don't send buffer to card. */ ++int send_data( port_type_t index, dc_t *dc ) { ++ u32 size = 0; ++ port_t *port = &dc->port[index]; ++ u8 toggle = port->toggle_ul; ++ u32 addr = port->ul_addr[toggle]; ++ u32 ul_size = port->ul_size[toggle]; ++ struct tty_struct *tty = port->tty; ++ ++ if (index >= NTTY_TTY_MINORS) { ++ ERR("Called with wrong index?"); ++ return 0; ++ } ++ ++ /* Get data from tty and place in buf for now */ ++ size = __kfifo_get( port->fifo_ul, dc->send_buf, ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX ); ++ ++ if (size == 0) { ++ D4("No more data to send, disable link:"); ++ return 0; ++ } ++ ++ port->tx_data += size; ++ ++ /* DUMP(buf, size); */ ++ ++ /* Write length + data */ ++ SET_MEM( addr, &size, 4 ); ++ SET_MEM_BUF( addr + 4, dc->send_buf, size); ++ ++ if (port->tty) { ++ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { ++ tty->ldisc.write_wakeup(tty); ++ } ++ wake_up_interruptible(&tty->write_wait); ++ } ++ ++ return 1; ++} ++ ++/* If all data has been read, return 1, else 0 */ ++static int receive_data( port_type_t index, dc_t* dc ) { ++ u8 buf[RECEIVE_BUF_MAX] = {0}; ++ int size; ++ u32 offset = 4; ++ port_t *port = &dc->port[index]; ++ u8 toggle = port->toggle_dl; ++ u32 addr = port->dl_addr[toggle]; ++ struct tty_struct *tty = port->tty; ++ int i; ++ ++ if ( !tty ) { ++ D1("tty not open for port: %d?", index); ++ return 1; ++ } ++ ++ if (test_bit(TTY_DONT_FLIP, &tty->flags)) { ++ D6("TTY_DONT_FLIP set!! %d", index); ++ /* Here we disable interrupt for that port and schedule */ ++/* task. Task wakes up a little bit later and enables interrupt.. */ ++ port->tty_dont_flip = 1; ++ disable_transmit_dl(index, dc); ++#ifdef KERNEL_2_4 ++ schedule_task(&dc->tty_flip_queue); ++#endif ++#ifdef KERNEL_2_6 ++ if (!queue_work(dc->tty_flip_wq, &dc->tty_flip_wq_struct)) { ++ ERR("Call to queue_work() failed."); ++ } ++#endif ++ return 0; ++ } ++ ++ GET_MEM( &size, addr, 4 ); ++ /* D1( "%d bytes port: %d", size, index); */ ++ ++ if ( test_bit( TTY_THROTTLED, & tty->flags) ) { ++ D1("No room in tty, don't read data, don't ack interrupt, disable interrupt"); ++ ++ /* disable interrupt in downlink... */ ++ disable_transmit_dl(index, dc); ++ return 0; ++ } ++ ++ if (size == 0) { ++ ERR("size == 0?"); ++ return 1; ++ } ++ ++ while( size > 0 ) { ++ GET_MEM_BUF(buf, addr + offset, 4); ++ ++ i = 0; ++ while (i < 4 && size > 0) { ++ if (tty->flip.count >= TTY_FLIPBUF_SIZE) { ++ tty_flip_buffer_push(tty); ++ } ++ tty_insert_flip_char(tty, buf[i], TTY_NORMAL); ++ port->rx_data++; ++ i++; ++ size--; ++ } ++ ++ offset += 4; ++ } ++ ++ tty_flip_buffer_push(tty); ++ ++ return 1; ++} ++ ++/* Debug for interrupts */ ++#ifdef NOZOMI_DEBUG ++static char* interrupt2str( u16 interrupt) { ++ static char buf[TMP_BUF_MAX]; ++ char *p = buf; ++ ++ interrupt & MDM_DL1 ? p += snprintf(p, TMP_BUF_MAX, "MDM_DL1 "):0; ++ interrupt & MDM_DL2 ? p += snprintf(p, TMP_BUF_MAX, "MDM_DL2 "):0; ++ ++ interrupt & MDM_UL1 ? p += snprintf(p, TMP_BUF_MAX, "MDM_UL1 "):0; ++ interrupt & MDM_UL2 ? p += snprintf(p, TMP_BUF_MAX, "MDM_UL2 "):0; ++ ++ interrupt & DIAG_DL1 ? p += snprintf(p, TMP_BUF_MAX, "DIAG_DL1 "):0; ++ interrupt & DIAG_DL2 ? p += snprintf(p, TMP_BUF_MAX, "DIAG_DL2 "):0; ++ ++ interrupt & DIAG_UL ? p += snprintf(p, TMP_BUF_MAX, "DIAG_UL "):0; ++ ++ interrupt & APP1_DL ? p += snprintf(p, TMP_BUF_MAX, "APP1_DL "):0; ++ interrupt & APP2_DL ? p += snprintf(p, TMP_BUF_MAX, "APP2_DL "):0; ++ ++ interrupt & APP1_UL ? p += snprintf(p, TMP_BUF_MAX, "APP1_UL "):0; ++ interrupt & APP2_UL ? p += snprintf(p, TMP_BUF_MAX, "APP2_UL "):0; ++ ++ interrupt & CTRL_DL ? p += snprintf(p, TMP_BUF_MAX, "CTRL_DL "):0; ++ interrupt & CTRL_UL ? p += snprintf(p, TMP_BUF_MAX, "CTRL_UL "):0; ++ ++ interrupt & RESET ? p += snprintf(p, TMP_BUF_MAX, "RESET "):0; ++ ++ return buf; ++} ++#endif ++ ++/* Receive flow control */ ++/* Return 1 - If ok, else 0 */ ++static int receive_flow_control( dc_t *dc, irq_t *m) { ++ port_type_t port = PORT_MDM; ++ ctrl_dl_t ctrl_dl; ++ ctrl_dl_t old_ctrl; ++ u16 enable_ier = 0; ++ ++ GET_MEM( &ctrl_dl, dc->port[PORT_CTRL].dl_addr[CH_A], 2); ++ ++ switch( ctrl_dl.port ) { ++ case CTRL_CMD: ++ D1( "The Base Band sends this value as a response to a request for IMSI detach sent" ++ " over the control channel uplink (see section 7.6.1)."); ++ break; ++ case CTRL_MDM: port = PORT_MDM; enable_ier = MDM_DL; break; ++ case CTRL_DIAG: port = PORT_DIAG; enable_ier = DIAG_DL; break; ++ case CTRL_APP1: port = PORT_APP1; enable_ier = APP1_DL; break; ++ case CTRL_APP2: port = PORT_APP2; enable_ier = APP2_DL; break; ++ default: ++ ERR("ERROR: flow control received for non-existing port"); ++ return 0; ++ }; ++ ++ D1( "0x%04X->0x%04X", *((u16*) &dc->port[port].ctrl_dl), *((u16*)&ctrl_dl)); ++ ++ old_ctrl = dc->port[port].ctrl_dl; ++ dc->port[port].ctrl_dl = ctrl_dl; ++ ++ if ( old_ctrl.CTS == 1 && ctrl_dl.CTS == 0 ) { ++ D1( "Disable interrupt (0x%04X) on port: %d", enable_ier, port); ++ disable_transmit_ul(port, dc); ++ ++ } else if ( old_ctrl.CTS == 0 && ctrl_dl.CTS == 1 ) { ++ ++ if ( __kfifo_len(dc->port[port].fifo_ul) ) { ++ D1( "Enable interrupt (0x%04X) on port: %d", enable_ier, port); ++ D1( "Data in buffer [%d], enable transmit! ", __kfifo_len(dc->port[port].fifo_ul) ); ++ enable_transmit_ul( port, dc ); ++ } else { ++ D1( "No data in buffer..."); ++ } ++ } ++ ++ if(*(u16*)&old_ctrl == *(u16*)&ctrl_dl) ++ { ++ D1( " No change in mctrl"); ++ return 1; ++ } ++ /* Update statistics */ ++ if(old_ctrl.CTS != ctrl_dl.CTS) { ++ dc->port[port].tty_icount.cts++; ++ } ++ if(old_ctrl.DSR != ctrl_dl.DSR) { ++ dc->port[port].tty_icount.dsr++; ++ } ++ if(old_ctrl.RI != ctrl_dl.RI) { ++ dc->port[port].tty_icount.rng++; ++ } ++ if(old_ctrl.DCD != ctrl_dl.DCD) { ++ dc->port[port].tty_icount.dcd++; ++ } ++ D1("port: %d DCD(%d), CTS(%d), RI(%d), DSR(%d)", ++ port, ++ dc->port[port].tty_icount.dcd, dc->port[port].tty_icount.cts, ++ dc->port[port].tty_icount.rng, dc->port[port].tty_icount.dsr); ++ ++ return 1; ++} ++ ++/* TODO: */ ++/* - return ctrl_port_t */ ++static u8 port2ctrl(port_type_t port) { ++ switch( port ) { ++ case PORT_MDM: ++ return CTRL_MDM; ++ case PORT_DIAG: ++ return CTRL_DIAG; ++ case PORT_APP1: ++ return CTRL_APP1; ++ case PORT_APP2: ++ return CTRL_APP2; ++ default: ++ ERR("ERROR: send flow control received for non-existing port"); ++ return -1; ++ }; ++ return -1; ++} ++ ++/* Send flow control, can only update one channel at a time */ ++/* Return 0 - If we have updated all flow control */ ++/* Return 1 - If we need to update more flow control, ack current enable more */ ++static int send_flow_control( dc_t *dc ) { ++ u32 i, more_flow_control_to_be_updated = 0; ++ u16* ctrl; ++ ++ for( i=PORT_MDM; iport[i].update_flow_control ) { ++ if ( more_flow_control_to_be_updated ) { ++ /* We have more flow control to be updated */ ++ return 1; ++ } ++ dc->port[i].ctrl_ul.port = port2ctrl(i); ++ ctrl = (u16*) &dc->port[i].ctrl_ul; ++ /* D1( "sending flow control 0x%04X for port %d, %d", (u16) *ctrl, i, dc->port[i].ctrl_ul.port ); */ ++ SET_MEM( dc->port[PORT_CTRL].ul_addr[0], (u32*) ctrl, 2 ); ++ dc->port[i].update_flow_control = 0; ++ more_flow_control_to_be_updated = 1; ++ } ++ } ++ return 0; ++} ++ ++/* Handle donlink data, ports that are handled are modem and diagnostics */ ++/* Return 1 - ok */ ++/* Return 0 - toggle fields are out of sync */ ++static int handle_data_dl(dc_t *dc, irq_t *m, port_type_t port, u8 *toggle, u16 mask1, u16 mask2) { ++ ++ if ( *toggle == 0 && m->read_iir & mask1 ) { ++ if (receive_data( port, dc )) { ++ SET_FCR( mask1 ); ++ *toggle = !(*toggle); ++ } ++ ++ if ( m->read_iir & mask2 ) { ++ if (receive_data( port, dc )) { ++ SET_FCR( mask2 ); ++ *toggle = !(*toggle); ++ } ++ } ++ } else if ( *toggle == 1 && m->read_iir & mask2 ) { ++ if (receive_data( port, dc )) { ++ SET_FCR( mask2 ); ++ *toggle = !(*toggle); ++ } ++ ++ if ( m->read_iir & mask1 ) { ++ if (receive_data( port, dc )) { ++ SET_FCR( mask1 ); ++ *toggle = !(*toggle); ++ } ++ } ++ } else { ++ ERR("port out of sync!, toggle:%d", *toggle); ++ return 0; ++ } ++ return 1; ++} ++ ++/* Handle uplink data, this is currently for the modem port */ ++/* Return 1 - ok */ ++/* Return 0 - toggle field are out of sync */ ++static int handle_data_ul(dc_t *dc, irq_t *m, port_type_t port) { ++ ++ u8 *toggle = &(dc->port[port].toggle_ul); ++ ++ if ( *toggle==0 && m->read_iir & MDM_UL1 ) { ++ SET_IER( 0, MDM_UL ); ++ if (send_data(port, dc)) { ++ SET_FCR( MDM_UL1 ); ++ SET_IER( MDM_UL, MDM_UL); ++ *toggle = !*toggle; ++ } ++ ++ if ( m->read_iir & MDM_UL2 ) { ++ SET_IER( 0, MDM_UL ); ++ if (send_data(port, dc)) { ++ SET_FCR( MDM_UL2 ); ++ SET_IER( MDM_UL, MDM_UL); ++ *toggle = !*toggle; ++ } ++ } ++ ++ } else if ( *toggle==1 && m->read_iir & MDM_UL2 ) { ++ SET_IER( 0, MDM_UL ); ++ if (send_data(port, dc)) { ++ SET_FCR( MDM_UL2 ); ++ SET_IER( MDM_UL, MDM_UL); ++ *toggle = !*toggle; ++ } ++ ++ if ( m->read_iir & MDM_UL1 ) { ++ SET_IER( 0, MDM_UL ); ++ if (send_data(port, dc)) { ++ SET_FCR( MDM_UL1 ); ++ SET_IER( MDM_UL, MDM_UL); ++ *toggle = !*toggle; ++ } ++ } ++ } else { ++ SET_FCR( m->read_iir & MDM_UL ); ++ ERR("port out of sync!"); ++ return 0; ++ } ++ return 1; ++} ++ ++static irqreturn_t interrupt_handler(int irq, void *dev_id, struct pt_regs *regs) { ++ dc_t *dc = NULL; ++ irq_t* m = &my_irq; ++ ++ if (my_dev && my_dev->pdev != dev_id) { ++ return IRQ_NONE; ++ } ++ ++ if ( !(dc = get_dc_by_pdev(dev_id)) ) { ++ ERR("Could not find device context from pci_dev: %d", (u32) dev_id); ++ return IRQ_NONE; ++ } ++ ++ GET_IIR( m->read_iir ); ++ ++ /* Just handle interrupt enabled in IER (by masking with dc->ier_last_written) */ ++ m->read_iir &= dc->ier_last_written; ++ ++ if (m->read_iir == 0) { ++ return IRQ_NONE; ++ } ++ ++ if (dc == NULL ) { ++ ERR("ERROR!!"); ++ return IRQ_NONE; ++ } ++ ++ spin_lock(&dc->spin_mutex); ++ ++ D4( "%s irq:0x%04X, prev:0x%04X", interrupt2str(m->read_iir), m->read_iir, dc->ier_last_written); ++ ++ if ( m->read_iir & RESET) { ++ if( !nozomi_read_config_table(dc) ) { ++ SET_IER( 0, 0xFFFF); ++ ERR("ERR: Could not read status from card, we should disable interface"); ++ } else { ++ SET_FCR( RESET ); ++ } ++ goto exit_handler; /* No more useful info if this was the reset interrupt. */ ++ } ++ if ( m->read_iir & CTRL_UL ) { ++ D1( "CTRL_UL"); ++ SET_IER( 0, CTRL_UL ); ++ if ( send_flow_control(dc) ) { ++ SET_FCR( CTRL_UL ); ++ SET_IER( CTRL_UL, CTRL_UL ); ++ } ++ } ++ if ( m->read_iir & CTRL_DL ) { ++ receive_flow_control(dc, m); ++ SET_FCR( CTRL_DL ); ++ } ++ if ( m->read_iir & MDM_DL ) { ++ if ( !(handle_data_dl(dc, m, PORT_MDM, &(dc->port[PORT_MDM].toggle_dl), MDM_DL1, MDM_DL2)) ) { ++ ERR("MDM_DL out of sync!"); ++ goto exit_handler; ++ } ++ } ++ if ( m->read_iir & MDM_UL ) { ++ if ( !handle_data_ul(dc, m, PORT_MDM ) ) { ++ ERR("MDM_UL out of sync!"); ++ goto exit_handler; ++ } ++ } ++ if ( m->read_iir & DIAG_DL ) { ++ if ( !(handle_data_dl(dc, m, PORT_DIAG, &(dc->port[PORT_DIAG].toggle_dl), DIAG_DL1, DIAG_DL2)) ) { ++ ERR("DIAG_DL out of sync!"); ++ goto exit_handler; ++ } ++ } ++ if ( m->read_iir & DIAG_UL ) { ++ SET_IER( 0, DIAG_UL ); ++ if( send_data( PORT_DIAG, dc ) ) { ++ SET_FCR( DIAG_UL ); ++ SET_IER( DIAG_UL, DIAG_UL ); ++ } ++ } ++ if ( m->read_iir & APP1_DL ) { ++ if (receive_data( PORT_APP1, dc ) ) { ++ SET_FCR( APP1_DL ); ++ } ++ } ++ if ( m->read_iir & APP1_UL ) { ++ SET_IER( 0, APP1_UL ); ++ if(send_data( PORT_APP1, dc )) { ++ SET_FCR( APP1_UL ); ++ SET_IER( APP1_UL, APP1_UL ); ++ } ++ } ++ if ( m->read_iir & APP2_DL ) { ++ if (receive_data( PORT_APP2, dc )) { ++ SET_FCR( APP2_DL ); ++ } ++ } ++ if ( m->read_iir & APP2_UL ) { ++ SET_IER( 0, APP2_UL ); ++ if(send_data( PORT_APP2, dc )) { ++ SET_FCR( APP2_UL ); ++ SET_IER( APP2_UL, APP2_UL ); ++ } ++ } ++ ++ exit_handler: ++ spin_unlock(&dc->spin_mutex); ++ return IRQ_HANDLED; ++} ++ ++/* Request a shared IRQ from system */ ++static int nozomi_setup_interrupt(struct pci_dev *pdev) { ++ ++ int rval = 0; ++ ++ if ( (rval = request_irq( pdev->irq, &interrupt_handler, SA_SHIRQ, NOZOMI_NAME, pdev )) ) { ++ ERR("Cannot open because IRQ %d is already in use.", pdev->irq ); ++ return rval; ++ } ++ ++ return rval; ++} ++ ++static void nozomi_get_card_type(dc_t *dc) { ++ u32 i, size=0; ++ for(i=0;i<6;i++) { ++ size += pci_resource_len(dc->pdev, i); ++ } ++ ++ /* Assume card type F32_8 if no match */ ++ dc->card_type = size == 2048 ? F32_2 : F32_8; ++ ++ INFO("Card type is: %d", dc->card_type ); ++} ++ ++void nozomi_setup_private_data(dc_t *dc) { ++ u32 offset = dc->base_addr + dc->card_type/2; ++ int i; ++ ++ dc->REG_FCR = offset + R_FCR; ++ dc->REG_IIR = offset + R_IIR; ++ dc->REG_IER = offset + R_IER; ++ dc->ier_last_written = 0; ++ dc->closing = 0; ++ ++ dc->port[PORT_MDM ].token_dl = MDM_DL; ++ dc->port[PORT_DIAG].token_dl = DIAG_DL; ++ dc->port[PORT_APP1].token_dl = APP1_DL; ++ dc->port[PORT_APP2].token_dl = APP2_DL; ++ ++ for(i=PORT_MDM;iport[i].rx_data = dc->port[i].tx_data = 0; ++ dc->port[i].tty_dont_flip = 0; ++ } ++} ++ ++ ++static void tty_flip_queue_function(void *tmp_dc) { ++ dc_t *dc = (dc_t*) tmp_dc; ++ int i; ++ ++ /* Enable interrupt for that port */ ++ for(i=0;iport[i].tty_dont_flip) { ++ D6("Enable for port: %d", i); ++ dc->port[i].tty_dont_flip = 0; ++ enable_transmit_dl(dc->port[i].tty_index, dc); ++ } ++ } ++} ++ ++static int read_proc_card_type(char *buf, char **start, off_t offset, int len) { ++ dc_t *dc = get_dc_by_index(0); ++ len = 0; ++ ++ len += sprintf(buf+len,"%d\n", dc->card_type); ++ return len; ++} ++ ++static int read_proc_open_ttys(char *buf, char **start, off_t offset, int len) { ++ dc_t *dc = get_dc_by_index(0); ++ len = 0; ++ ++ len += sprintf(buf+len,"%d\n", dc->open_ttys); ++ return len; ++} ++ ++static int read_proc_version(char *buf, char **start, off_t offset, int len) { ++ len = 0; ++ ++ len += sprintf(buf+len, "%s\n", VERSION_STRING); ++ return len; ++} ++ ++static int read_proc_rtx(char *buf, char **start, off_t offset, int len) { ++ dc_t *dc = get_dc_by_index(0); ++ int i; ++ ++ len = 0; ++ ++ ++ for(i=PORT_MDM;iport[i].rx_data, dc->port[i].tx_data); ++ } ++ return len; ++} ++ ++static void make_proc_dirs(void) { ++ dc_t *dc = get_dc_by_index(0); ++ ++ dc->proc_entry = proc_mkdir("nozomi", &proc_root); ++ ++ /* Register the read_proc */ ++ if ( !create_proc_info_entry("card_type",0,dc->proc_entry,read_proc_card_type) ) { ++ ERR("ERROR: failed to register read_procmem"); ++ } ++ if ( !create_proc_info_entry("open_ttys",0,dc->proc_entry,read_proc_open_ttys) ) { ++ ERR("ERROR: failed to register read_procmem"); ++ } ++ if ( !create_proc_info_entry("rtx",0,dc->proc_entry,read_proc_rtx) ) { ++ ERR("ERROR: failed to register read_procmem"); ++ } ++ if ( !create_proc_info_entry("version",0,dc->proc_entry,read_proc_version) ) { ++ ERR("ERROR: failed to register read_procmem"); ++ } ++} ++ ++static void remove_proc_dirs(void) { ++ dc_t *dc = get_dc_by_index(0); ++ ++ remove_proc_entry("card_type", dc->proc_entry); ++ remove_proc_entry("open_ttys", dc->proc_entry); ++ remove_proc_entry("rtx", dc->proc_entry); ++ remove_proc_entry("version", dc->proc_entry); ++ remove_proc_entry("nozomi", &proc_root); ++} ++ ++static void send_reset_token(dc_t *dc) { ++ ++ ctrl_ul_t ctrl; ++ ++ /* Send 0x0001, command card to resend the reset token. */ ++ /* This is to get the reset when the module is reloaded. */ ++ ctrl.port = 0x00; ctrl.reserved = 0; ctrl.RTS=0; ctrl.DTR=1; ++ D1( "sending flow control 0x%04X", * ((u16*) &ctrl) ); ++ ++ ++ /*SET_MEM( dc->port[PORT_CTRL].ul_addr[0], (u32*) &ctrl, 2 );*/ ++ /* hack alert :D (fixed address determined experimentally) */ ++ SET_MEM( dc->base_addr + 0x000002FC, (u32*) &ctrl, 2 ); ++ SET_FCR( CTRL_UL ); /* push the token to the card. */ ++ D1( "sent flow control 0x%04X", * ((u16*) &ctrl) ); ++} ++ ++/* Allocate memory for one device */ ++static int __devinit nozomi_card_init(struct pci_dev *pdev, const struct pci_device_id *ent) { ++ int ret = -EIO; ++ dc_t *dc=NULL; ++ ++ cards_found++; ++ INFO("Init, cards_found: %d", cards_found); ++ ++ if (!(my_dev = kmalloc(sizeof(dc_t), GFP_KERNEL))) { ++ D1( "Could not allocate memory"); ++ return -EIO; ++ } ++ ++ memset(my_dev, 0, sizeof( dc_t )); ++ ++ if (cards_found > 1) { ++ ERR("This driver only supports 1 device"); ++ return -ENODEV; ++ } ++ ++ my_dev->pdev = pdev; ++ dc = my_dev; ++ ++ /* Find out what card type it is */ ++ nozomi_get_card_type(dc); ++ ++ if (pci_enable_device(dc->pdev)) { ++ ERR("Not possible to enable PCI Device"); ++ return -ENODEV; ++ } ++ ++ if ( (dc->base_addr = pci_resource_start(dc->pdev, 0)) == 0x0000) { ++ ERR("No I/O-Address for card detected"); ++ ret = -ENODEV; ++ goto err_disable_device; ++ } ++ ++ if (!(dc->base_addr = (u32) ioremap(dc->base_addr, dc->card_type))) { ++ ERR("No I/O-Address for card detected"); ++ ret = -ENODEV; ++ goto err_disable_device; ++ } ++ ++ dc->open_ttys=0; ++ ++ nozomi_setup_private_data(dc); ++ ++ if (pci_request_regions(dc->pdev, NOZOMI_NAME)) { ++ ERR("I/O address 0x%04x already in use", ++ (int) /* nozomi_private.io_addr */ 0); ++ ret = -EIO; ++ goto err_disable_regions; ++ } ++ ++ if ( !(dc->send_buf = kmalloc(SEND_BUF_MAX, GFP_KERNEL))) { ++ ERR("Could not allocate send buffer?"); ++ goto err_disable_regions; ++ } ++ ++ /* Disable all interrupts */ ++ SET_IER( 0 , 0xFFFF ); ++ ++ /* Setup interrupt handler */ ++ if (nozomi_setup_interrupt(dc->pdev)) { ++ ret = -EIO; ++ goto err_disable_regions; ++ } ++ ++ D1( "base_addr: 0x%08X", dc->base_addr); ++ ++#ifdef KERNEL_2_4 ++ dc->tty_flip_queue.list.next = NULL; ++ dc->tty_flip_queue.list.prev = NULL; ++ dc->tty_flip_queue.sync = 0; ++ dc->tty_flip_queue.data = dc; ++ dc->tty_flip_queue.routine = tty_flip_queue_function; ++#endif ++#ifdef KERNEL_2_6 ++ if ( !(dc->tty_flip_wq = create_singlethread_workqueue(NOZOMI_NAME )) ) { ++ ERR("Could not create workqueue?"); ++ BUG_ON(!dc->tty_flip_wq); ++ return -ENOMEM; ++ } ++ INIT_WORK( &dc->tty_flip_wq_struct, tty_flip_queue_function, (void*) dc); ++#endif ++ ++ spin_lock_init(&dc->spin_mutex); ++ ++ make_proc_dirs(); ++ ++ ntty_tty_init(dc); ++#if 0 ++ if (!nozomi_read_config_table(dc)) { ++ ERR("Could not read config table (pass 1)"); ++ return -ENODEV; ++ } ++ if (!nozomi_read_config_table(dc)) { ++ ERR("Could not read config table (pass 2)"); ++ return -ENODEV; ++ } ++#endif ++ send_reset_token(dc); ++ ++ /* Enable RESET interrupt. */ ++ SET_IER( RESET, 0xFFFF ); ++ ++ return 0; ++ ++err_disable_regions: ++ pci_release_regions(pdev); ++ iounmap((void *)dc->base_addr ); ++ dc->base_addr = 0; ++ ++err_disable_device: ++ pci_disable_device(pdev); ++ if(my_dev) { ++ kfree( my_dev ); ++ } ++ return ret; ++} ++ ++static void tty_do_close(dc_t *dc, port_t *port) { ++ ++ down(&port->tty_sem); ++ ++ if ( !port->tty_open_count ) { ++ goto exit; ++ } ++ ++ dc->open_ttys--; ++ port->tty_open_count--; ++#ifdef KERNEL_2_4 ++ MOD_DEC_USE_COUNT; ++#endif ++ ++ if ( port->tty_open_count == 0) { ++ D1("close: %d", port->token_dl ); ++ SET_IER( 0, port->token_dl ); ++ } ++ ++exit: ++ up(&port->tty_sem); ++} ++ ++static void __exit tty_exit(void) { ++ int i; ++ dc_t *dc = my_dev; ++ ++ D1( " "); ++ ++#ifdef KERNEL_2_6 ++ for (i = 0; i < NTTY_TTY_MINORS; ++i) ++ tty_unregister_device(&dc->tty_driver, i); ++#endif ++ ++ tty_unregister_driver(&dc->tty_driver); ++ ++ for (i = 0; i < NTTY_TTY_MINORS; i++) { ++ while (dc->port[i].tty_open_count) { ++ tty_do_close(dc, &dc->port[i]); ++ } ++ ++ dc->port[i].tty = NULL; ++ } ++} ++ ++/* Deallocate memory for one device */ ++static void __devexit nozomi_card_exit(struct pci_dev *pdev) { ++ int i; ++ dc_t *dc = get_dc_by_pdev(pdev); ++ ++ /* Disable all interrupts */ ++ SET_IER( 0, 0xFFFF); ++ ++ /* Setup dc->reg addresses to we can use defines here */ ++ nozomi_setup_private_data(dc); ++ send_reset_token(dc); ++ ++ D1( "pci_release_regions"); ++ pci_release_regions(pdev); ++ ++ if(dc->base_addr) ++ iounmap((void *)dc->base_addr); ++ ++ D1( "pci_disable_device"); ++ pci_disable_device(pdev); ++ ++ free_irq( pdev->irq, pdev ); ++ ++ for (i=PORT_MDM; i< MAX_PORT;i++) { ++ kfree ( dc->port[i].fifo_ul ); ++ } ++ ++ kfree( dc->send_buf ); ++ ++ tty_exit(); ++ ++ remove_proc_dirs(); ++ ++#ifdef KERNEL_2_6 ++ destroy_workqueue(dc->tty_flip_wq); ++#endif ++ ++ if (my_dev) { ++ kfree( my_dev ); ++ } ++ ++ cards_found--; ++ cards_initialized--; ++} ++ ++static void set_rts(int index, int rts) { ++ dc_t *dc = get_dc_by_index(index); ++ ++ dc->port[index].ctrl_ul.RTS = rts; ++ dc->port[index].update_flow_control = 1; ++ enable_transmit_ul(PORT_CTRL, dc); ++} ++ ++static void set_dtr(int index, int dtr) { ++ dc_t *dc = get_dc_by_index(index); ++ ++ D1("SETTING DTR index: %d, dtr: %d", index, dtr); ++ ++ dc->port[index].ctrl_ul.DTR = dtr; ++ dc->port[index].update_flow_control = 1; ++ enable_transmit_ul(PORT_CTRL, dc); ++} ++ ++ ++/* --------------------------------------------------------------------------------------------------- ++ TTY code ++ ---------------------------------------------------------------------------------------------------*/ ++ ++ ++/* Called when the userspace process opens the tty, /dev/noz*. */ ++static int ntty_open(struct tty_struct *tty, struct file *file) { ++ ++ s32 index = get_index(tty); ++ port_t *port = get_port_by_tty(tty); ++ dc_t *dc = get_dc_by_tty(tty); ++ ++ CARD_CHECK(-ENODEV); ++ ++ down(&port->tty_sem); ++ ++ tty->low_latency = 1; ++ tty->driver_data = port; ++ port->tty = tty; ++ port->tty_index = index; ++ ++ port->tty_open_count++; ++ dc->open_ttys++; ++ ++#ifdef KERNEL_2_4 ++ MOD_INC_USE_COUNT; ++#endif ++ ++ /* Enable interrupt downlink for channel */ ++ if ( port->tty_open_count == 1) { ++ port->rx_data = port->tx_data = 0; ++ D1("open: %d", port->token_dl ); ++ SET_IER( port->token_dl, port->token_dl ); ++ } ++ ++ up(&port->tty_sem); ++ ++ return 0; ++} ++ ++/* Called when the userspace process close the tty, /dev/noz*. */ ++static void ntty_close(struct tty_struct *tty, struct file *file) { ++ dc_t *dc; ++ CARD_CHECK(); ++ dc = get_dc_by_tty(tty); ++ tty_do_close(dc, (port_t *) tty->driver_data); ++} ++ ++/* called when the userspace process writes to the tty (/dev/noz*). */ ++/* Data is inserted into a fifo, which is then read and transfered to the modem. */ ++#ifdef KERNEL_2_6 ++static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, int count) { ++#else ++static s32 ntty_write(struct tty_struct *tty, s32 from_user, const u8 *buffer, s32 count) { ++#endif ++ int rval = -EINVAL; ++ dc_t *dc = get_dc_by_tty(tty); ++ port_t *port = (port_t *) tty->driver_data; ++ ++ CARD_CHECK(rval); ++ ++ /* D1( "WRITEx: %d, index = %d", count, index); */ ++ ++ if (! port) { ++ return -ENODEV; ++ } ++ ++ down(&port->tty_sem); ++ ++ if (! port->tty_open_count) { ++ D1( " "); ++ goto exit; ++ } ++ ++#ifdef KERNEL_2_4 ++ if (from_user) { ++ rval = __kfifo_put_user(port->fifo_ul, (unsigned char *) buffer, count); ++ } else { ++ rval = __kfifo_put(port->fifo_ul, (unsigned char *) buffer, count); ++ } ++#else ++ rval = __kfifo_put(port->fifo_ul, (unsigned char *) buffer, count); ++#endif ++ ++ /* notify card */ ++ if ( dc == NULL) { ++ D1( "No device context?"); ++ goto exit; ++ } ++ ++ // CTS is only valid on the modem channel ++ if ( port == &(dc->port[PORT_MDM]) ) { ++ if ( port->ctrl_dl.CTS ) { ++ D4( "Enable interrupt"); ++ enable_transmit_ul(port->tty_index, dc ); ++ } else { ++ ERR("CTS not active on modem port?"); ++ } ++ } else { ++ enable_transmit_ul(port->tty_index, dc ); ++ } ++ ++exit: ++ up(&port->tty_sem); ++ return rval; ++} ++ ++/* Calculate how much is left in device */ ++/* This method is called by the upper tty layer. */ ++/* #according to sources N_TTY.c it expects a value >= 0 and does not check for negative values. */ ++static int ntty_write_room(struct tty_struct *tty) { ++ port_t *port = (port_t *) tty->driver_data; ++ int room = 0; ++/* u32 flags = 0; */ ++/* dc_t *dc = get_dc_by_tty(tty); */ ++ ++ CARD_CHECK(-ENODEV); ++ ++ if (! port) { ++ return 0; ++ } ++ ++ down(&port->tty_sem); ++ ++ if (! port->tty_open_count) { ++ goto exit; ++ } ++ ++ room = port->fifo_ul->size - __kfifo_len(port->fifo_ul); ++ ++exit: ++ up(&port->tty_sem); ++ return room; ++} ++ ++/* Sets termios flags, called by the tty layer. */ ++static void ntty_set_termios(struct tty_struct *tty, struct termios *old_termios) { ++ unsigned int cflag; ++ ++ CARD_CHECK(); ++ ++ cflag = tty->termios->c_cflag; ++ ++ if (old_termios) { ++ if ((cflag == old_termios->c_cflag) && ++ (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) { ++ D1( " - nothing to change..."); ++ goto exit_termios; ++ } ++ } ++ ++ /* get the byte size */ ++ switch (cflag & CSIZE) { ++ case CS5: ++ D1( " - data bits = 5"); ++ break; ++ case CS6: ++ D1( " - data bits = 6"); ++ break; ++ case CS7: ++ D1( " - data bits = 7"); ++ break; ++ default: ++ case CS8: ++ D1( " - data bits = 8"); ++ break; ++ } ++ ++ /* determine the parity */ ++ if (cflag & PARENB) { ++ if (cflag & PARODD) { ++ D1( " - parity = odd"); ++ } else { ++ D1( " - parity = even"); ++ } ++ } else { ++ D1( " - parity = none"); ++ } ++ ++ /* figure out the stop bits requested */ ++ if (cflag & CSTOPB) { ++ D1( " - stop bits = 2"); ++ } else { ++ D1( " - stop bits = 1"); ++ } ++ ++ /* figure out the hardware flow control settings */ ++ if (cflag & CRTSCTS) { ++ D1( " - RTS/CTS is enabled"); ++ } else { ++ D1( " - RTS/CTS is disabled"); ++ } ++ ++ /* determine software flow control */ ++ /* if we are implementing XON/XOFF, set the start and ++ * stop character in the device */ ++ if (I_IXOFF(tty) || I_IXON(tty)) { ++#ifdef NOZOMI_DEBUG ++ unsigned char stop_char = STOP_CHAR(tty); ++ unsigned char start_char = START_CHAR(tty); ++#endif ++ /* if we are implementing INBOUND XON/XOFF */ ++ if (I_IXOFF(tty)) { ++ D1( " - INBOUND XON/XOFF is enabled, " ++ "XON = %2x, XOFF = %2x", start_char, stop_char); ++ } else { ++ D1( " - INBOUND XON/XOFF is disabled"); ++ } ++ ++ /* if we are implementing OUTBOUND XON/XOFF */ ++ if (I_IXON(tty)) { ++ D1( " - OUTBOUND XON/XOFF is enabled, " ++ "XON = %2x, XOFF = %2x", start_char, stop_char); ++ } else { ++ D1( " - OUTBOUND XON/XOFF is disabled"); ++ } ++ } ++ ++ exit_termios: ++ return; ++} ++ ++/* Gets io control parameters */ ++static int ntty_tiocmget(struct tty_struct *tty, struct file *file) { ++ port_t *port = (port_t *) tty->driver_data; ++ ctrl_dl_t *ctrl_dl = &port->ctrl_dl; ++ ctrl_ul_t *ctrl_ul = &port->ctrl_ul; ++ ++ return 0 ++ | (ctrl_ul->RTS ? TIOCM_RTS : 0) ++ | (ctrl_ul->DTR ? TIOCM_DTR : 0) ++ | (ctrl_dl->DCD ? TIOCM_CAR : 0) ++ | (ctrl_dl->RI ? TIOCM_RNG : 0) ++ | (ctrl_dl->DSR ? TIOCM_DSR : 0) ++ | (ctrl_dl->CTS ? TIOCM_CTS : 0); ++} ++ ++/* Sets io controls parameters */ ++static int ntty_tiocmset(struct tty_struct *tty, struct file *file, u32 arg) { ++ port_t *port = (port_t *) tty->driver_data; ++ ++ set_rts(port->tty_index, (arg & TIOCM_RTS) ? 1 : 0); ++ set_dtr(port->tty_index, (arg & TIOCM_DTR) ? 1 : 0); ++ ++ return 0; ++} ++ ++static int ntty_ioctl_tiocmiwait(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { ++ port_t *port = (port_t *) tty->driver_data; ++ ++ if (cmd == TIOCMIWAIT) { ++ DECLARE_WAITQUEUE(wait, current); ++ struct async_icount cnow; ++ struct async_icount cprev; ++ ++ cprev = port->tty_icount; ++ while (1) { ++ add_wait_queue(&port->tty_wait, &wait); ++ set_current_state(TASK_INTERRUPTIBLE); ++ schedule(); ++ remove_wait_queue(&port->tty_wait, &wait); ++ ++ /* see if a signal woke us up */ ++ if (signal_pending(current)) ++ return -ERESTARTSYS; ++ ++ cnow = port->tty_icount; ++ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && ++ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) ++ return -EIO; /* no change => error */ ++ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ++ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || ++ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || ++ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { ++ return 0; ++ } ++ cprev = cnow; ++ } ++ ++ } ++ return -ENOIOCTLCMD; ++} ++ ++static int ntty_ioctl_tiocgicount(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { ++ port_t *port = (port_t *) tty->driver_data; ++ ++ if (cmd == TIOCGICOUNT) { ++ struct async_icount cnow = port->tty_icount; ++ struct serial_icounter_struct icount; ++ ++ icount.cts = cnow.cts; ++ icount.dsr = cnow.dsr; ++ icount.rng = cnow.rng; ++ icount.dcd = cnow.dcd; ++ icount.rx = cnow.rx; ++ icount.tx = cnow.tx; ++ icount.frame = cnow.frame; ++ icount.overrun = cnow.overrun; ++ icount.parity = cnow.parity; ++ icount.brk = cnow.brk; ++ icount.buf_overrun = cnow.buf_overrun; ++ ++ if (copy_to_user((void *)arg, &icount, sizeof(icount))) ++ return -EFAULT; ++ return 0; ++ } ++ return -ENOIOCTLCMD; ++} ++ ++static int ntty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { ++ port_t *port = (port_t *) tty->driver_data; ++ int mask; ++ int rval = -ENOIOCTLCMD; ++ ++ CARD_CHECK(rval); ++ ++ D1("******** IOCTL, cmd: %d", cmd); ++ ++ ++ switch (cmd) { ++ case TCGETS: ++ D1( "IOCTL TCGETS ..."); ++ rval = -ENOIOCTLCMD; ++ break; ++ case TCSETS: ++ D1( "IOCTL TCSETS ..."); ++ rval = -ENOIOCTLCMD; ++ break; ++ case TIOCMIWAIT: ++ rval = ntty_ioctl_tiocmiwait(tty, file, cmd, arg); ++ break; ++ case TIOCGICOUNT: ++ rval = ntty_ioctl_tiocgicount(tty, file, cmd, arg); ++ break; ++ case TIOCMGET: ++ rval = ntty_tiocmget(tty, file); ++ break; ++ case TIOCMSET: ++ rval = ntty_tiocmset(tty, file, arg); ++ break; ++ case TIOCMBIC: ++ if (get_user(mask, (unsigned long *) arg)) ++ return -EFAULT; ++ ++ if (mask & TIOCM_RTS) ++ set_rts(port->tty_index, 0); ++ if (mask & TIOCM_DTR) ++ set_dtr(port->tty_index, 0); ++ rval = 0; ++ break; ++ case TIOCMBIS: ++ if (get_user(mask, (unsigned long *) arg)) ++ return -EFAULT; ++ ++ if (mask & TIOCM_RTS) ++ set_rts(port->tty_index, 1); ++ if (mask & TIOCM_DTR) ++ set_dtr(port->tty_index, 1); ++ rval = 0; ++ break; ++ case TCFLSH: ++ D1( "IOCTL TCFLSH ..."); ++ rval = -ENOIOCTLCMD; ++ break; ++ ++ default: ++ D1( "ERR: 0x%08X, %d", cmd, cmd); ++ break; ++ }; ++ ++ return rval; ++} ++ ++/* Called by the upper tty layer when tty buffers are ready */ ++/* to receive data again after a call to throttle. */ ++static void ntty_unthrottle(struct tty_struct *tty) { ++ port_t *port = (port_t *) tty->driver_data; ++ dc_t *dc = get_dc_by_tty(tty); ++ u32 flags; ++ ++ CARD_CHECK(); ++ ++ D1( "UNTHROTTLE"); ++ spin_lock_irqsave(&dc->spin_mutex, flags); ++ enable_transmit_dl(port->tty_index, dc); ++ set_rts(port->tty_index, 1); ++ ++ spin_unlock_irqrestore(&dc->spin_mutex, flags); ++} ++ ++/* Called by the upper tty layer when the tty buffers are almost full. */ ++/* The driver should stop send more data. */ ++static void ntty_throttle(struct tty_struct *tty) { ++ port_t *port = (port_t *) tty->driver_data; ++ dc_t *dc = get_dc_by_tty(tty); ++ u32 flags; ++ ++ CARD_CHECK(); ++ ++ D1( "THROTTLE"); ++ spin_lock_irqsave(&dc->spin_mutex, flags); ++ set_rts(port->tty_index, 0); ++ spin_unlock_irqrestore(&dc->spin_mutex, flags); ++} ++ ++static void ntty_put_char(struct tty_struct *tty, unsigned char c) { ++ CARD_CHECK(); ++ D2("PUT CHAR Function: %c", c); ++} ++ ++/* Returns number of chars in buffer, called by tty layer */ ++static s32 ntty_chars_in_buffer(struct tty_struct *tty) { ++ port_t *port = (port_t *) tty->driver_data; ++ s32 rval; ++ ++ CARD_CHECK(-ENODEV); ++ ++ if (! port) { ++ rval = -ENODEV; ++ goto exit_in_buffer; ++ } ++ ++ if (! port->tty_open_count) { ++ ERR("No tty open?"); ++ rval = -ENODEV; ++ goto exit_in_buffer; ++ } ++ ++ rval = __kfifo_len(port->fifo_ul); ++ ++ exit_in_buffer: ++ return rval; ++} ++ ++/* Initializes the tty */ ++static int ntty_tty_init(dc_t *dc) { ++ struct tty_driver *td = &dc->tty_driver; ++ int rval; ++ int i; ++ ++ memset(td, 0, sizeof(struct tty_driver)); ++ ++ td->magic = TTY_DRIVER_MAGIC; ++ td->driver_name = NOZOMI_NAME_TTY; ++ td->name = "noz"; ++ td->major = NTTY_TTY_MAJOR, ++ td->type = TTY_DRIVER_TYPE_SERIAL, ++ td->subtype = SERIAL_TYPE_NORMAL, ++ td->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, ++ td->init_termios = tty_std_termios; ++ td->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL; ++ ++ td->num = MAX_PORT; ++ td->name_base = 0; ++ td->minor_start = 0; ++ ++#ifdef KERNEL_2_4 ++ td->table = dc->tty_table; ++ td->refcount = &dc->tty_refcount; ++#endif ++ ++ td->termios = dc->tty_termios; ++ td->termios_locked = dc->tty_termios_locked; ++ ++ td->ioctl = ntty_ioctl; ++ td->open = ntty_open; ++ td->close = ntty_close; ++ td->write = ntty_write; ++ td->write_room = ntty_write_room; ++ td->unthrottle = ntty_unthrottle; ++ td->throttle = ntty_throttle; ++ td->set_termios = ntty_set_termios; ++ td->chars_in_buffer = ntty_chars_in_buffer; ++ td->put_char = ntty_put_char; ++ ++ rval = tty_register_driver(td); ++ ++ if (rval) { ++ printk(KERN_ERR "failed to register ntty tty driver"); ++ D1( "failed to register ntty tty driver"); ++ return rval; ++ } ++ ++ for (i = 0; i < NTTY_TTY_MINORS; i++) { ++ init_MUTEX(&dc->port[i].tty_sem); ++ dc->port[i].tty_open_count = 0; ++ dc->port[i].tty = NULL; ++ ++#ifdef KERNEL_2_6 ++ tty_register_device(td, i, NULL); ++#endif ++ } ++ ++ printk(KERN_INFO DRIVER_DESC " " NOZOMI_NAME_TTY); ++ D1( " "); ++ return rval; ++} ++ ++/* Module initialization */ ++static struct pci_driver nozomi_driver = { ++ .name = NOZOMI_NAME, ++ .id_table = nozomi_pci_tbl, ++ .probe = nozomi_card_init, ++ .remove = __devexit_p(nozomi_card_exit), ++}; ++ ++static int __init nozomi_init(void) { ++ int rval = 0; ++ ++ rval = pci_module_init(&nozomi_driver); ++ printk(KERN_INFO "Initializing %s\n", VERSION_STRING); ++ return rval; ++} ++ ++static void nozomi_exit(void) { ++ printk(KERN_INFO "Unloading %s", DRIVER_DESC); ++ ++ pci_unregister_driver(&nozomi_driver); ++} ++ ++module_init(nozomi_init); ++module_exit(nozomi_exit); ++ ++#ifdef NOZOMI_DEBUG ++ MODULE_PARM(nzdebug, "i"); ++#endif ++ ++MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_DESCRIPTION( DRIVER_DESC ); diff --git a/packages/linux/linux-mtx-2-2.4.27/42-usb-ohci-fixes.patch b/packages/linux/linux-mtx-2-2.4.27/42-usb-ohci-fixes.patch new file mode 100644 index 0000000000..4c3058ce00 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/42-usb-ohci-fixes.patch @@ -0,0 +1,42 @@ +--- linux/drivers/usb/host/usb-ohci.c.orig 2006-03-30 11:38:08.972225500 +0200 ++++ linux/drivers/usb/host/usb-ohci.c 2006-03-30 11:39:46.858343000 +0200 +@@ -104,6 +104,10 @@ + + #define OHCI_UNLINK_TIMEOUT (HZ / 10) + ++static int ohci_delay = 3000; ++MODULE_PARM(ohci_delay, "i"); ++MODULE_PARM_DESC(ohci_delay, "Wait time [ms] for OHCI to come up"); ++ + /*-------------------------------------------------------------------------*/ + + /* AMD-756 (D2 rev) reports corrupt register contents in some cases. +@@ -2587,12 +2591,12 @@ + hc_release_ohci (ohci); + return -ENODEV; + } +- ++#if 0 + /* FIXME this is a second HC reset; why?? */ + writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control); + (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */ + wait_ms (10); +- ++#endif + usb_register_bus (ohci->bus); + + if (request_irq (irq, hc_interrupt, SA_SHIRQ, +@@ -2668,6 +2672,13 @@ + void *mem_base; + int status; + ++ printk ("waiting for ohci to come up\n"); ++ mdelay(ohci_delay); ++ /* We have to wait for about four seconds for some devices to be available. ++ * This may only be a matter of the Option Globetrotter Fusion, ++ * that may need to much time to start up correctly. */ ++ printk ("ohci should be up\n"); ++ + if (pci_enable_device(dev) < 0) + return -ENODEV; + diff --git a/packages/linux/linux-mtx-2-2.4.27/43-usbserial-27-32-backport.diff b/packages/linux/linux-mtx-2-2.4.27/43-usbserial-27-32-backport.diff new file mode 100644 index 0000000000..6a98f76c7a --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/43-usbserial-27-32-backport.diff @@ -0,0 +1,33 @@ +--- linux/drivers/usb/serial/usbserial.c-27 2006-06-27 10:26:06.294476250 +0200 ++++ linux/drivers/usb/serial/usbserial.c 2006-06-27 10:30:31.011020000 +0200 +@@ -528,8 +528,18 @@ + down(&port->sem); + dbg("%s - port %d len %d backlog %d", __FUNCTION__, + port->number, job->len, port->write_backlog); +- if (port->tty != NULL) +- __serial_write(port, 0, job->buff, job->len); ++ if (port->tty != NULL) { ++ int rc; ++ int sent = 0; ++ while (sent < job->len) { ++ rc = __serial_write(port, 0, job->buff + sent, job->len - sent); ++ if ((rc < 0) || signal_pending(current)) ++ break; ++ sent += rc; ++ if ((sent < job->len) && current->need_resched) ++ schedule(); ++ } ++ } + up(&port->sem); + + spin_lock_irqsave(&post_lock, flags); +@@ -725,6 +735,9 @@ + struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; + int rc; + ++ if (!port) ++ return -ENODEV; ++ + if (!in_interrupt()) { + /* + * Run post_list to reduce a possiblity of reordered writes. diff --git a/packages/linux/linux-mtx-2-2.4.27/44-dbdma-and-au1550_psc.diff b/packages/linux/linux-mtx-2-2.4.27/44-dbdma-and-au1550_psc.diff new file mode 100644 index 0000000000..af249dbe58 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/44-dbdma-and-au1550_psc.diff @@ -0,0 +1,1491 @@ +--- linux-old/include/asm-mips/au1xxx_dbdma.h 2006-05-09 18:24:17.000000000 +0200 ++++ linux/include/asm-mips/au1xxx_dbdma.h 2006-05-09 14:05:48.000000000 +0200 +@@ -34,6 +34,8 @@ + #ifndef _AU1000_DBDMA_H_ + #define _AU1000_DBDMA_H_ + ++#include ++ + #ifndef _LANGUAGE_ASSEMBLY + + /* The DMA base addresses. +@@ -43,7 +45,7 @@ + #define DDMA_GLOBAL_BASE 0xb4003000 + #define DDMA_CHANNEL_BASE 0xb4002000 + +-typedef struct dbdma_global { ++typedef volatile struct dbdma_global { + u32 ddma_config; + u32 ddma_intstat; + u32 ddma_throttle; +@@ -60,7 +62,7 @@ + + /* The structure of a DMA Channel. + */ +-typedef struct au1xxx_dma_channel { ++typedef volatile struct au1xxx_dma_channel { + u32 ddma_cfg; /* See below */ + u32 ddma_desptr; /* 32-byte aligned pointer to descriptor */ + u32 ddma_statptr; /* word aligned pointer to status word */ +@@ -96,7 +98,7 @@ + /* "Standard" DDMA Descriptor. + * Must be 32-byte aligned. + */ +-typedef struct au1xxx_ddma_desc { ++typedef volatile struct au1xxx_ddma_desc { + u32 dscr_cmd0; /* See below */ + u32 dscr_cmd1; /* See below */ + u32 dscr_source0; /* source phys address */ +@@ -105,6 +107,12 @@ + u32 dscr_dest1; /* See below */ + u32 dscr_stat; /* completion status */ + u32 dscr_nxtptr; /* Next descriptor pointer (mostly) */ ++ /* First 32bytes are HW specific!!! ++ Lets have some SW data following.. make sure its 32bytes ++ */ ++ u32 sw_status; ++ u32 sw_context; ++ u32 sw_reserved[6]; + } au1x_ddma_desc_t; + + #define DSCR_CMD0_V (1 << 31) /* Descriptor valid */ +@@ -123,6 +131,8 @@ + #define DSCR_CMD0_CV (0x1 << 2) /* Clear Valid when done */ + #define DSCR_CMD0_ST_MASK (0x3 << 0) /* Status instruction */ + ++#define SW_STATUS_INUSE (1<<0) ++ + /* Command 0 device IDs. + */ + #ifdef CONFIG_SOC_AU1550 +@@ -169,8 +179,8 @@ + #define DSCR_CMD0_SDMS_RX0 9 + #define DSCR_CMD0_SDMS_TX1 10 + #define DSCR_CMD0_SDMS_RX1 11 +-#define DSCR_CMD0_AES_TX 12 +-#define DSCR_CMD0_AES_RX 13 ++#define DSCR_CMD0_AES_TX 13 ++#define DSCR_CMD0_AES_RX 12 + #define DSCR_CMD0_PSC0_TX 14 + #define DSCR_CMD0_PSC0_RX 15 + #define DSCR_CMD0_PSC1_TX 16 +@@ -189,6 +199,10 @@ + #define DSCR_CMD0_THROTTLE 30 + #define DSCR_CMD0_ALWAYS 31 + #define DSCR_NDEV_IDS 32 ++/* THis macro is used to find/create custom device types */ ++#define DSCR_DEV2CUSTOM_ID(x,d) (((((x)&0xFFFF)<<8)|0x32000000)|((d)&0xFF)) ++#define DSCR_CUSTOM2DEV_ID(x) ((x)&0xFF) ++ + + #define DSCR_CMD0_SID(x) (((x) & 0x1f) << 25) + #define DSCR_CMD0_DID(x) (((x) & 0x1f) << 20) +@@ -277,6 +291,43 @@ + */ + #define NUM_DBDMA_CHANS 16 + ++/* ++ * Ddma API definitions ++ * FIXME: may not fit to this header file ++ */ ++typedef struct dbdma_device_table { ++ u32 dev_id; ++ u32 dev_flags; ++ u32 dev_tsize; ++ u32 dev_devwidth; ++ u32 dev_physaddr; /* If FIFO */ ++ u32 dev_intlevel; ++ u32 dev_intpolarity; ++} dbdev_tab_t; ++ ++ ++typedef struct dbdma_chan_config { ++ spinlock_t lock; ++ ++ u32 chan_flags; ++ u32 chan_index; ++ dbdev_tab_t *chan_src; ++ dbdev_tab_t *chan_dest; ++ au1x_dma_chan_t *chan_ptr; ++ au1x_ddma_desc_t *chan_desc_base; ++ au1x_ddma_desc_t *get_ptr, *put_ptr, *cur_ptr; ++ void *chan_callparam; ++ void (*chan_callback)(int, void *, struct pt_regs *); ++} chan_tab_t; ++ ++#define DEV_FLAGS_INUSE (1 << 0) ++#define DEV_FLAGS_ANYUSE (1 << 1) ++#define DEV_FLAGS_OUT (1 << 2) ++#define DEV_FLAGS_IN (1 << 3) ++#define DEV_FLAGS_BURSTABLE (1 << 4) ++#define DEV_FLAGS_SYNC (1 << 5) ++/* end Ddma API definitions */ ++ + /* External functions for drivers to use. + */ + /* Use this to allocate a dbdma channel. The device ids are one of the +@@ -299,8 +350,8 @@ + + /* Put buffers on source/destination descriptors. + */ +-u32 au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes); +-u32 au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes); ++u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags); ++u32 _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags); + + /* Get a buffer from the destination descriptor. + */ +@@ -314,5 +365,29 @@ + void au1xxx_dbdma_chan_free(u32 chanid); + void au1xxx_dbdma_dump(u32 chanid); + ++u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr ); ++ ++u32 au1xxx_ddma_add_device( dbdev_tab_t *dev ); ++void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp); ++ ++/* ++ Some compatibilty macros -- ++ Needed to make changes to API without breaking existing drivers ++*/ ++#define au1xxx_dbdma_put_source(chanid,buf,nbytes)_au1xxx_dbdma_put_source(chanid, buf, nbytes, DDMA_FLAGS_IE) ++#define au1xxx_dbdma_put_source_flags(chanid,buf,nbytes,flags) _au1xxx_dbdma_put_source(chanid, buf, nbytes, flags) ++#define put_source_flags(chanid,buf,nbytes,flags) au1xxx_dbdma_put_source_flags(chanid,buf,nbytes,flags) ++ ++ ++#define au1xxx_dbdma_put_dest(chanid,buf,nbytes) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, DDMA_FLAGS_IE) ++#define au1xxx_dbdma_put_dest_flags(chanid,buf,nbytes,flags) _au1xxx_dbdma_put_dest(chanid, buf, nbytes, flags) ++#define put_dest_flags(chanid,buf,nbytes,flags) au1xxx_dbdma_put_dest_flags(chanid,buf,nbytes,flags) ++ ++/* ++ * Flags for the put_source/put_dest functions. ++ */ ++#define DDMA_FLAGS_IE (1<<0) ++#define DDMA_FLAGS_NOIE (1<<1) ++ + #endif /* _LANGUAGE_ASSEMBLY */ + #endif /* _AU1000_DBDMA_H_ */ +--- linux-old/arch/mips/au1000/common/dbdma.c 2006-05-09 18:23:18.000000000 +0200 ++++ linux/arch/mips/au1000/common/dbdma.c 2006-05-09 14:04:44.000000000 +0200 +@@ -30,6 +30,7 @@ + * + */ + ++#include + #include + #include + #include +@@ -37,13 +38,14 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include + +-#include + +-#if 1 // defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) ++#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) + + /* + * The Descriptor Based DMA supports up to 16 channels. +@@ -62,37 +64,10 @@ + */ + #define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1)) + +-static volatile dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE; +-static int dbdma_initialized; ++static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE; ++static int dbdma_initialized=0; + static void au1xxx_dbdma_init(void); + +-typedef struct dbdma_device_table { +- u32 dev_id; +- u32 dev_flags; +- u32 dev_tsize; +- u32 dev_devwidth; +- u32 dev_physaddr; /* If FIFO */ +- u32 dev_intlevel; +- u32 dev_intpolarity; +-} dbdev_tab_t; +- +-typedef struct dbdma_chan_config { +- u32 chan_flags; +- u32 chan_index; +- dbdev_tab_t *chan_src; +- dbdev_tab_t *chan_dest; +- au1x_dma_chan_t *chan_ptr; +- au1x_ddma_desc_t *chan_desc_base; +- au1x_ddma_desc_t *get_ptr, *put_ptr, *cur_ptr; +- void *chan_callparam; +- void (*chan_callback)(int, void *, struct pt_regs *); +-} chan_tab_t; +- +-#define DEV_FLAGS_INUSE (1 << 0) +-#define DEV_FLAGS_ANYUSE (1 << 1) +-#define DEV_FLAGS_OUT (1 << 2) +-#define DEV_FLAGS_IN (1 << 3) +- + static dbdev_tab_t dbdev_tab[] = { + #ifdef CONFIG_SOC_AU1550 + /* UARTS */ +@@ -158,25 +133,25 @@ + { DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, + { DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, + +- { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, +- { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, +- { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, +- { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, ++ { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 }, ++ { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 }, ++ { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 }, ++ { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 }, + +- { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, +- { DSCR_CMD0_AES_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, ++ { DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 }, ++ { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 }, + +- { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 }, +- { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 }, ++ { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 }, ++ { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 }, + { DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, + +- { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 }, +- { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 }, ++ { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x11b0001c, 0, 0 }, ++ { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x11b0001c, 0, 0 }, + { DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, + +- { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, +- { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, +- { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, ++ { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 }, ++ { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 }, ++ { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 }, + { DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, + + { DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, +@@ -185,6 +160,24 @@ + + { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, + { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, ++ ++ /* Provide 16 user definable device types */ ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, ++ { 0, 0, 0, 0, 0, 0, 0 }, + }; + + #define DBDEV_TAB_SIZE (sizeof(dbdev_tab) / sizeof(dbdev_tab_t)) +@@ -204,6 +197,36 @@ + return NULL; + } + ++void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp) ++{ ++ return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); ++} ++EXPORT_SYMBOL(au1xxx_ddma_get_nextptr_virt); ++ ++u32 ++au1xxx_ddma_add_device(dbdev_tab_t *dev) ++{ ++ u32 ret = 0; ++ dbdev_tab_t *p=NULL; ++ static u16 new_id=0x1000; ++ ++ p = find_dbdev_id(0); ++ if ( NULL != p ) ++ { ++ memcpy(p, dev, sizeof(dbdev_tab_t)); ++ p->dev_id = DSCR_DEV2CUSTOM_ID(new_id,dev->dev_id); ++ ret = p->dev_id; ++ new_id++; ++#if 0 ++ printk("add_device: id:%x flags:%x padd:%x\n", ++ p->dev_id, p->dev_flags, p->dev_physaddr ); ++#endif ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL(au1xxx_ddma_add_device); ++ + /* Allocate a channel and return a non-zero descriptor if successful. + */ + u32 +@@ -216,7 +239,7 @@ + int i; + dbdev_tab_t *stp, *dtp; + chan_tab_t *ctp; +- volatile au1x_dma_chan_t *cp; ++ au1x_dma_chan_t *cp; + + /* We do the intialization on the first channel allocation. + * We have to wait because of the interrupt handler initialization +@@ -226,9 +249,6 @@ + au1xxx_dbdma_init(); + dbdma_initialized = 1; + +- if ((srcid > DSCR_NDEV_IDS) || (destid > DSCR_NDEV_IDS)) +- return 0; +- + if ((stp = find_dbdev_id(srcid)) == NULL) return 0; + if ((dtp = find_dbdev_id(destid)) == NULL) return 0; + +@@ -240,7 +260,7 @@ + spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags); + if (!(stp->dev_flags & DEV_FLAGS_INUSE) || + (stp->dev_flags & DEV_FLAGS_ANYUSE)) { +- /* Got source */ ++ /* Got source */ + stp->dev_flags |= DEV_FLAGS_INUSE; + if (!(dtp->dev_flags & DEV_FLAGS_INUSE) || + (dtp->dev_flags & DEV_FLAGS_ANYUSE)) { +@@ -270,9 +290,8 @@ + /* If kmalloc fails, it is caught below same + * as a channel not available. + */ +- ctp = (chan_tab_t *)kmalloc(sizeof(chan_tab_t), GFP_KERNEL); ++ ctp = kmalloc(sizeof(chan_tab_t), GFP_KERNEL); + chan_tab_ptr[i] = ctp; +- ctp->chan_index = chan = i; + break; + } + } +@@ -280,10 +299,11 @@ + + if (ctp != NULL) { + memset(ctp, 0, sizeof(chan_tab_t)); ++ ctp->chan_index = chan = i; + dcp = DDMA_CHANNEL_BASE; + dcp += (0x0100 * chan); + ctp->chan_ptr = (au1x_dma_chan_t *)dcp; +- cp = (volatile au1x_dma_chan_t *)dcp; ++ cp = (au1x_dma_chan_t *)dcp; + ctp->chan_src = stp; + ctp->chan_dest = dtp; + ctp->chan_callback = callback; +@@ -300,6 +320,9 @@ + i |= DDMA_CFG_DED; + if (dtp->dev_intpolarity) + i |= DDMA_CFG_DP; ++ if ((stp->dev_flags & DEV_FLAGS_SYNC) || ++ (dtp->dev_flags & DEV_FLAGS_SYNC)) ++ i |= DDMA_CFG_SYNC; + cp->ddma_cfg = i; + au_sync(); + +@@ -310,14 +333,14 @@ + rv = (u32)(&chan_tab_ptr[chan]); + } + else { +- /* Release devices. +- */ ++ /* Release devices */ + stp->dev_flags &= ~DEV_FLAGS_INUSE; + dtp->dev_flags &= ~DEV_FLAGS_INUSE; + } + } + return rv; + } ++EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc); + + /* Set the device width if source or destination is a FIFO. + * Should be 8, 16, or 32 bits. +@@ -345,6 +368,7 @@ + + return rv; + } ++EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth); + + /* Allocate a descriptor ring, initializing as much as possible. + */ +@@ -371,10 +395,11 @@ + * and if we try that first we are likely to not waste larger + * slabs of memory. + */ +- desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL); ++ desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), ++ GFP_KERNEL|GFP_DMA); + if (desc_base == 0) + return 0; +- ++ + if (desc_base & 0x1f) { + /* Lost....do it again, allocate extra, and round + * the address base. +@@ -382,7 +407,7 @@ + kfree((const void *)desc_base); + i = entries * sizeof(au1x_ddma_desc_t); + i += (sizeof(au1x_ddma_desc_t) - 1); +- if ((desc_base = (u32)kmalloc(i, GFP_KERNEL)) == 0) ++ if ((desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA)) == 0) + return 0; + + desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t)); +@@ -404,7 +429,13 @@ + cmd0 |= DSCR_CMD0_SID(srcid); + cmd0 |= DSCR_CMD0_DID(destid); + cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV; +- cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_CURRENT); ++ cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_NOCHANGE); ++ ++ /* is it mem to mem transfer? */ ++ if(((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) && ++ ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS))) { ++ cmd0 |= DSCR_CMD0_MEM; ++ } + + switch (stp->dev_devwidth) { + case 8: +@@ -462,9 +493,14 @@ + /* If source input is fifo, set static address. + */ + if (stp->dev_flags & DEV_FLAGS_IN) { +- src0 = stp->dev_physaddr; ++ if ( stp->dev_flags & DEV_FLAGS_BURSTABLE ) ++ src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST); ++ else + src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC); ++ + } ++ if (stp->dev_physaddr) ++ src0 = stp->dev_physaddr; + + /* Set up dest1. For now, assume no stride and increment. + * A channel attribute update can change this later. +@@ -488,10 +524,18 @@ + /* If destination output is fifo, set static address. + */ + if (dtp->dev_flags & DEV_FLAGS_OUT) { +- dest0 = dtp->dev_physaddr; ++ if ( dtp->dev_flags & DEV_FLAGS_BURSTABLE ) ++ dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST); ++ else + dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC); + } +- ++ if (dtp->dev_physaddr) ++ dest0 = dtp->dev_physaddr; ++ ++#if 0 ++ printk("did:%x sid:%x cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n", ++ dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, src1, dest0, dest1 ); ++#endif + for (i=0; idscr_cmd0 = cmd0; + dp->dscr_cmd1 = cmd1; +@@ -500,10 +544,12 @@ + dp->dscr_dest0 = dest0; + dp->dscr_dest1 = dest1; + dp->dscr_stat = 0; ++ dp->sw_context = 0; ++ dp->sw_status = 0; + dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(dp + 1)); + dp++; + } +- ++ + /* Make last descrptor point to the first. + */ + dp--; +@@ -512,13 +558,14 @@ + + return (u32)(ctp->chan_desc_base); + } ++EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc); + + /* Put a source buffer into the DMA ring. + * This updates the source pointer and byte count. Normally used + * for memory to fifo transfers. + */ + u32 +-au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes) ++_au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags) + { + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; +@@ -540,14 +587,30 @@ + if (dp->dscr_cmd0 & DSCR_CMD0_V) { + return 0; + } +- ++ + /* Load up buffer address and byte count. + */ + dp->dscr_source0 = virt_to_phys(buf); + dp->dscr_cmd1 = nbytes; +- dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ +- ctp->chan_ptr->ddma_dbell = 0xffffffff; /* Make it go */ +- ++ /* Check flags */ ++ if (flags & DDMA_FLAGS_IE) ++ dp->dscr_cmd0 |= DSCR_CMD0_IE; ++ if (flags & DDMA_FLAGS_NOIE) ++ dp->dscr_cmd0 &= ~DSCR_CMD0_IE; ++ ++ /* ++ * There is an errata on the Au1200/Au1550 parts that could result ++ * in "stale" data being DMA'd. It has to do with the snoop logic on ++ * the dache eviction buffer. NONCOHERENT_IO is on by default for ++ * these parts. If it is fixedin the future, these dma_cache_inv will ++ * just be nothing more than empty macros. See io.h. ++ * */ ++ dma_cache_wback_inv((unsigned long)buf, nbytes); ++ dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ ++ au_sync(); ++ dma_cache_wback_inv((unsigned long)dp, sizeof(dp)); ++ ctp->chan_ptr->ddma_dbell = 0; ++ + /* Get next descriptor pointer. + */ + ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); +@@ -556,13 +619,14 @@ + */ + return nbytes; + } ++EXPORT_SYMBOL(_au1xxx_dbdma_put_source); + + /* Put a destination buffer into the DMA ring. + * This updates the destination pointer and byte count. Normally used + * to place an empty buffer into the ring for fifo to memory transfers. + */ + u32 +-au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes) ++_au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags) + { + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; +@@ -581,15 +645,38 @@ + /* If the descriptor is valid, we are way ahead of the DMA + * engine, so just return an error condition. + */ +- if (dp->dscr_cmd0 & DSCR_CMD0_V) ++ if (dp->dscr_cmd0 & DSCR_CMD0_V) { + return 0; +- +- /* Load up buffer address and byte count. +- */ ++ } ++ ++ /* Load up buffer address and byte count */ ++ ++ /* Check flags */ ++ if (flags & DDMA_FLAGS_IE) ++ dp->dscr_cmd0 |= DSCR_CMD0_IE; ++ if (flags & DDMA_FLAGS_NOIE) ++ dp->dscr_cmd0 &= ~DSCR_CMD0_IE; ++ + dp->dscr_dest0 = virt_to_phys(buf); + dp->dscr_cmd1 = nbytes; ++#if 0 ++ printk("cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n", ++ dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0, ++ dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1 ); ++#endif ++ /* ++ * There is an errata on the Au1200/Au1550 parts that could result in ++ * "stale" data being DMA'd. It has to do with the snoop logic on the ++ * dache eviction buffer. NONCOHERENT_IO is on by default for these ++ * parts. If it is fixedin the future, these dma_cache_inv will just ++ * be nothing more than empty macros. See io.h. ++ * */ ++ dma_cache_inv((unsigned long)buf,nbytes); + dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ +- ++ au_sync(); ++ dma_cache_wback_inv((unsigned long)dp, sizeof(dp)); ++ ctp->chan_ptr->ddma_dbell = 0; ++ + /* Get next descriptor pointer. + */ + ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); +@@ -598,6 +685,7 @@ + */ + return nbytes; + } ++EXPORT_SYMBOL(_au1xxx_dbdma_put_dest); + + /* Get a destination buffer into the DMA ring. + * Normally used to get a full buffer from the ring during fifo +@@ -625,29 +713,31 @@ + /* If the descriptor is valid, we are way ahead of the DMA + * engine, so just return an error condition. + */ +- if (dp->dscr_cmd0 & DSCR_CMD0_V) ++ if (dp->dscr_cmd0 & DSCR_CMD0_V) { + return 0; +- ++ } ++ + /* Return buffer address and byte count. + */ + *buf = (void *)(phys_to_virt(dp->dscr_dest0)); + *nbytes = dp->dscr_cmd1; + rv = dp->dscr_stat; +- ++ + /* Get next descriptor pointer. + */ + ctp->get_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); + + /* return something not zero. + */ +- return rv; ++ return *nbytes; + } ++EXPORT_SYMBOL(au1xxx_dbdma_get_dest); + + void + au1xxx_dbdma_stop(u32 chanid) + { + chan_tab_t *ctp; +- volatile au1x_dma_chan_t *cp; ++ au1x_dma_chan_t *cp; + int halt_timeout = 0; + + ctp = *((chan_tab_t **)chanid); +@@ -667,6 +757,7 @@ + cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V); + au_sync(); + } ++EXPORT_SYMBOL(au1xxx_dbdma_stop); + + /* Start using the current descriptor pointer. If the dbdma encounters + * a not valid descriptor, it will stop. In this case, we can just +@@ -676,17 +767,17 @@ + au1xxx_dbdma_start(u32 chanid) + { + chan_tab_t *ctp; +- volatile au1x_dma_chan_t *cp; ++ au1x_dma_chan_t *cp; + + ctp = *((chan_tab_t **)chanid); +- + cp = ctp->chan_ptr; + cp->ddma_desptr = virt_to_phys(ctp->cur_ptr); + cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */ + au_sync(); +- cp->ddma_dbell = 0xffffffff; /* Make it go */ ++ cp->ddma_dbell = 0; + au_sync(); + } ++EXPORT_SYMBOL(au1xxx_dbdma_start); + + void + au1xxx_dbdma_reset(u32 chanid) +@@ -705,15 +796,21 @@ + + do { + dp->dscr_cmd0 &= ~DSCR_CMD0_V; ++ /* reset our SW status -- this is used to determine ++ * if a descriptor is in use by upper level SW. Since ++ * posting can reset 'V' bit. ++ */ ++ dp->sw_status = 0; + dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); + } while (dp != ctp->chan_desc_base); + } ++EXPORT_SYMBOL(au1xxx_dbdma_reset); + + u32 + au1xxx_get_dma_residue(u32 chanid) + { + chan_tab_t *ctp; +- volatile au1x_dma_chan_t *cp; ++ au1x_dma_chan_t *cp; + u32 rv; + + ctp = *((chan_tab_t **)chanid); +@@ -726,6 +823,7 @@ + + return rv; + } ++EXPORT_SYMBOL(au1xxx_get_dma_residue); + + void + au1xxx_dbdma_chan_free(u32 chanid) +@@ -739,35 +837,35 @@ + + au1xxx_dbdma_stop(chanid); + +- if (ctp->chan_desc_base != NULL) +- kfree(ctp->chan_desc_base); +- ++ kfree((void *)ctp->chan_desc_base); ++ + stp->dev_flags &= ~DEV_FLAGS_INUSE; + dtp->dev_flags &= ~DEV_FLAGS_INUSE; + chan_tab_ptr[ctp->chan_index] = NULL; + + kfree(ctp); + } ++EXPORT_SYMBOL(au1xxx_dbdma_chan_free); + +-static void ++static irqreturn_t + dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs) + { +- u32 intstat; +- u32 chan_index; ++ u32 intstat; ++ u32 chan_index; + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; +- volatile au1x_dma_chan_t *cp; ++ au1x_dma_chan_t *cp; + + intstat = dbdma_gptr->ddma_intstat; + au_sync(); + chan_index = au_ffs(intstat) - 1; + + ctp = chan_tab_ptr[chan_index]; + cp = ctp->chan_ptr; + dp = ctp->cur_ptr; + + /* Reset interrupt. +- */ ++ */ + cp->ddma_irq = 0; + au_sync(); + +@@ -775,18 +875,28 @@ + (ctp->chan_callback)(irq, ctp->chan_callparam, regs); + + ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); +- ++ ++ return IRQ_RETVAL(1); + } + +-static void +-au1xxx_dbdma_init(void) ++static void au1xxx_dbdma_init(void) + { ++ int irq_nr; ++ + dbdma_gptr->ddma_config = 0; + dbdma_gptr->ddma_throttle = 0; + dbdma_gptr->ddma_inten = 0xffff; + au_sync(); + +- if (request_irq(AU1550_DDMA_INT, dbdma_interrupt, SA_INTERRUPT, ++#if defined(CONFIG_SOC_AU1550) ++ irq_nr = AU1550_DDMA_INT; ++#elif defined(CONFIG_SOC_AU1200) ++ irq_nr = AU1200_DDMA_INT; ++#else ++ #error Unknown Au1x00 SOC ++#endif ++ ++ if (request_irq(irq_nr, dbdma_interrupt, SA_INTERRUPT, + "Au1xxx dbdma", (void *)dbdma_gptr)) + printk("Can't get 1550 dbdma irq"); + } +@@ -797,7 +907,8 @@ + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; + dbdev_tab_t *stp, *dtp; +- volatile au1x_dma_chan_t *cp; ++ au1x_dma_chan_t *cp; ++ u32 i = 0; + + ctp = *((chan_tab_t **)chanid); + stp = ctp->chan_src; +@@ -809,7 +920,7 @@ + printk("desc base %x, get %x, put %x, cur %x\n", + (u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr), + (u32)(ctp->put_ptr), (u32)(ctp->cur_ptr)); +- ++ + printk("dbdma chan %x\n", (u32)cp); + printk("cfg %08x, desptr %08x, statptr %08x\n", + cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr); +@@ -822,28 +933,65 @@ + dp = ctp->chan_desc_base; + + do { +- printk("dp %08x, cmd0 %08x, cmd1 %08x\n", +- (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1); +- printk("src0 %08x, src1 %08x, dest0 %08x\n", +- dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0); +- printk("dest1 %08x, stat %08x, nxtptr %08x\n", +- dp->dscr_dest1, dp->dscr_stat, dp->dscr_nxtptr); ++ printk("Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n", ++ i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1); ++ printk("src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n", ++ dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1); ++ printk("stat %08x, nxtptr %08x\n", ++ dp->dscr_stat, dp->dscr_nxtptr); + dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); + } while (dp != ctp->chan_desc_base); + } ++EXPORT_SYMBOL(au1xxx_dbdma_dump); + ++/* Put a descriptor into the DMA ring. ++ * This updates the source/destination pointers and byte count. ++ */ ++u32 ++au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr ) ++{ ++ chan_tab_t *ctp; ++ au1x_ddma_desc_t *dp; ++ u32 nbytes=0; + +-EXPORT_SYMBOL(au1xxx_dbdma_dump); +-EXPORT_SYMBOL(au1xxx_dbdma_put_source); +-EXPORT_SYMBOL(au1xxx_dbdma_put_dest); +-EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc); +-EXPORT_SYMBOL(au1xxx_dbdma_start); +-EXPORT_SYMBOL(au1xxx_dbdma_get_dest); +-EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc); +-EXPORT_SYMBOL(au1xxx_get_dma_residue); +-EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth); +-EXPORT_SYMBOL(au1xxx_dbdma_chan_free); +-EXPORT_SYMBOL(au1xxx_dbdma_reset); ++ /* I guess we could check this to be within the ++ * range of the table...... ++ */ ++ ctp = *((chan_tab_t **)chanid); + +-#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ ++ /* We should have multiple callers for a particular channel, ++ * an interrupt doesn't affect this pointer nor the descriptor, ++ * so no locking should be needed. ++ */ ++ dp = ctp->put_ptr; ++ ++ /* If the descriptor is valid, we are way ahead of the DMA ++ * engine, so just return an error condition. ++ */ ++ if (dp->dscr_cmd0 & DSCR_CMD0_V) ++ return 0; + ++ /* Load up buffer addresses and byte count. ++ */ ++ dp->dscr_dest0 = dscr->dscr_dest0; ++ dp->dscr_source0 = dscr->dscr_source0; ++ dp->dscr_dest1 = dscr->dscr_dest1; ++ dp->dscr_source1 = dscr->dscr_source1; ++ dp->dscr_cmd1 = dscr->dscr_cmd1; ++ nbytes = dscr->dscr_cmd1; ++ /* Allow the caller to specifiy if an interrupt is generated */ ++ dp->dscr_cmd0 &= ~DSCR_CMD0_IE; ++ dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V; ++ ctp->chan_ptr->ddma_dbell = 0; ++ ++ /* Get next descriptor pointer. ++ */ ++ ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); ++ ++ /* return something not zero. ++ */ ++ return nbytes; ++} ++EXPORT_SYMBOL(au1xxx_dbdma_put_dscr); ++ ++#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ +--- linux-old/drivers/sound/au1550_psc.c 2006-05-09 14:49:35.000000000 +0200 ++++ linux/drivers/sound/au1550_psc.c 2006-05-09 18:19:01.000000000 +0200 +@@ -82,6 +83,11 @@ + + #define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg) + #define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg) ++#ifdef AU1000_VERBOSE_DEBUG ++#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg) ++#else ++#define dbg(format, arg...) ++#endif /* AU1000_VERBOSE_DEBUG */ + + /* Boot options + * 0 = no VRA, 1 = use VRA if codec supports it +@@ -127,7 +129,7 @@ + unsigned fragshift; + void *nextIn; + void *nextOut; +- int count; ++ volatile int count; + unsigned total_bytes; + unsigned error; + wait_queue_head_t wait; +@@ -198,7 +200,7 @@ + struct au1550_state *s = (struct au1550_state *)codec->private_data; + unsigned long flags; + u32 cmd, val; +- u16 data; ++ u16 data=0; + int i; + + spin_lock_irqsave(&s->lock, flags); +@@ -210,26 +212,21 @@ + break; + } + if (i == POLL_COUNT) +- err("rdcodec: codec cmd pending expired!"); ++ err("rdcodec: codec cmd pending expired! %i %i", val, addr); ++ ++ val = au_readl(PSC_AC97EVNT); ++ if (val & PSC_AC97EVNT_CD) { ++ err("rdcodec: command done is set! %i %i", val, addr); ++ au_readl(PSC_AC97CDC); // manual says: you must read CDC[DATA] before resetting EVNT[CD], if command was read; and we don't know here what the last command was ++ au_sync(); ++ au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT); ++ } + + cmd = (u32)PSC_AC97CDC_INDX(addr); + cmd |= PSC_AC97CDC_RD; /* read command */ + au_writel(cmd, PSC_AC97CDC); + au_sync(); + +- /* now wait for the data +- */ +- for (i = 0; i < POLL_COUNT; i++) { +- val = au_readl(PSC_AC97STAT); +- au_sync(); +- if (!(val & PSC_AC97STAT_CP)) +- break; +- } +- if (i == POLL_COUNT) { +- err("rdcodec: read poll expired!"); +- return 0; +- } +- + /* wait for command done? + */ + for (i = 0; i < POLL_COUNT; i++) { +@@ -239,8 +236,8 @@ + break; + } + if (i == POLL_COUNT) { +- err("rdcodec: read cmdwait expired!"); +- return 0; ++ err("rdcodec: read cmdwait expired! %i %i", val, addr); ++ goto rcodec_out; + } + + data = au_readl(PSC_AC97CDC) & 0xffff; +@@ -251,8 +248,11 @@ + au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT); + au_sync(); + ++ rcodec_out: + spin_unlock_irqrestore(&s->lock, flags); + ++ dbg("rdcodec %x -> %x", addr, data); ++ + return data; + } + +@@ -274,7 +274,15 @@ + break; + } + if (i == POLL_COUNT) +- err("wrcodec: codec cmd pending expired!"); ++ err("wrcodec: codec cmd pending expired! %i %i", val, addr); ++ ++ val = au_readl(PSC_AC97EVNT); ++ if (val & PSC_AC97EVNT_CD) { ++ err("wrcodec: command done is set! %i %i", val, addr); ++ au_readl(PSC_AC97CDC); // manual says: you must read CDC[DATA] before resetting EVNT[CD], if command was read; and we don't know here what the last command was ++ au_sync(); ++ au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT); ++ } + + cmd = (u32)PSC_AC97CDC_INDX(addr); + cmd |= (u32)data; +@@ -282,22 +290,13 @@ + au_sync(); + + for (i = 0; i < POLL_COUNT; i++) { +- val = au_readl(PSC_AC97STAT); +- au_sync(); +- if (!(val & PSC_AC97STAT_CP)) +- break; +- } +- if (i == POLL_COUNT) +- err("wrcodec: codec cmd pending expired!"); +- +- for (i = 0; i < POLL_COUNT; i++) { + val = au_readl(PSC_AC97EVNT); + au_sync(); + if (val & PSC_AC97EVNT_CD) + break; + } + if (i == POLL_COUNT) +- err("wrcodec: read cmdwait expired!"); ++ err("wrcodec: read cmdwait expired! %i %i", val, addr); + + /* Clear command done event. + */ +@@ -305,6 +304,8 @@ + au_sync(); + + spin_unlock_irqrestore(&s->lock, flags); ++ ++ dbg("wrcodec %x -> %x done", data, addr); + } + + static void +@@ -392,7 +393,7 @@ + adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE); + + #ifdef AU1000_VERBOSE_DEBUG +- dbg(__FUNCTION__ ": set to %d Hz", adc_rate); ++ dbg("%s : set to %d Hz", __FUNCTION__, adc_rate); + #endif + + /* some codec's don't allow unequal DAC and ADC rates, in which case +@@ -452,7 +453,7 @@ + dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE); + + #ifdef AU1000_VERBOSE_DEBUG +- dbg(__FUNCTION__ ": set to %d Hz", dac_rate); ++ dbg("%s : set to %d Hz", __FUNCTION__, dac_rate); + #endif + + /* some codec's don't allow unequal DAC and ADC rates, in which case +@@ -489,6 +490,9 @@ + au1xxx_dbdma_reset(db->dmanr); + + db->stopped = 1; ++ db->count = 0; ++ db->dma_qcount = 0; ++ db->nextIn = db->nextOut = db->rawbuf; + + spin_unlock_irqrestore(&s->lock, flags); + } +@@ -518,6 +522,9 @@ + au1xxx_dbdma_reset(db->dmanr); + + db->stopped = 1; ++ db->count = 0; ++ db->dma_qcount = 0; ++ db->nextIn = db->nextOut = db->rawbuf; + + spin_unlock_irqrestore(&s->lock, flags); + } +@@ -609,7 +616,8 @@ + + spin_lock_irqsave(&s->lock, flags); + +- set_xmit_slots(db->num_channels); ++ au1xxx_dbdma_reset(db->dmanr); ++ + au_writel(PSC_AC97PCR_TC, PSC_AC97PCR); + au_sync(); + au_writel(PSC_AC97PCR_TS, PSC_AC97PCR); +@@ -634,17 +642,20 @@ + + spin_lock_irqsave(&s->lock, flags); + ++ au1xxx_dbdma_reset(db->dmanr); ++ + /* Put two buffers on the ring to get things started. + */ +- for (i=0; i<2; i++) { +- au1xxx_dbdma_put_dest(db->dmanr, db->nextIn, db->dma_fragsize); ++ for (i=0; idmanr, db->nextIn, db->dma_fragsize) ) { + +- db->nextIn += db->dma_fragsize; +- if (db->nextIn >= db->rawbuf + db->dmasize) +- db->nextIn -= db->dmasize; ++ db->nextIn += db->dma_fragsize; ++ if (db->nextIn >= db->rawbuf + db->dmasize) ++ db->nextIn -= db->dmasize; ++ } else ++ info("Cannot put dest %i", i); + } + +- set_recv_slots(db->num_channels); + au1xxx_dbdma_start(db->dmanr); + au_writel(PSC_AC97PCR_RC, PSC_AC97PCR); + au_sync(); +@@ -665,9 +676,12 @@ + if (!db->rawbuf) { + db->ready = db->mapped = 0; + db->buforder = 5; /* 32 * PAGE_SIZE */ ++ bufs = PAGE_SIZE << db->buforder; + db->rawbuf = kmalloc((PAGE_SIZE << db->buforder), GFP_KERNEL); + if (!db->rawbuf) + return -ENOMEM; ++ } else { ++ bufs = PAGE_SIZE << db->buforder; + } + + db->cnt_factor = 1; +@@ -686,7 +700,6 @@ + 2 : db->num_channels); + + user_bytes_per_sec = rate * db->user_bytes_per_sample; +- bufs = PAGE_SIZE << db->buforder; + if (db->ossfragshift) { + if ((1000 << db->ossfragshift) < user_bytes_per_sec) + db->fragshift = ld2(user_bytes_per_sec/1000); +@@ -731,6 +744,7 @@ + static int + prog_dmabuf_adc(struct au1550_state *s) + { ++ dbg("prog_dmabuf_adc s%i c%i", s->dma_adc.sample_size, s->dma_adc.num_channels); + stop_adc(s); + return prog_dmabuf(s, &s->dma_adc); + +@@ -739,6 +753,8 @@ + static int + prog_dmabuf_dac(struct au1550_state *s) + { ++ dbg("prog_dmabuf_dac s%i c%i", s->dma_dac.sample_size, s->dma_dac.num_channels); ++ + stop_dac(s); + return prog_dmabuf(s, &s->dma_dac); + } +@@ -752,20 +768,20 @@ + { + struct au1550_state *s = (struct au1550_state *) dev_id; + struct dmabuf *db = &s->dma_dac; ++#ifdef AU1000_VERBOSE_DEBUG + u32 ac97c_stat; ++#endif + +- ac97c_stat = au_readl(PSC_AC97STAT); + #ifdef AU1000_VERBOSE_DEBUG +- if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE)) +- dbg("AC97C status = 0x%08x", ac97c_stat); ++// if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE)) ++// dbg("AC97C status = 0x%08x", ac97c_stat); + #endif + db->dma_qcount--; + +- if (db->count >= db->fragsize) { +- if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, +- db->fragsize) == 0) { +- err("qcount < 2 and no ring room!"); +- } ++ // put source buffers as long as we have data and free dma descr ++ while ( (db->count >= db->fragsize) && ++ (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, ++ db->fragsize) ) ) { + db->nextOut += db->fragsize; + if (db->nextOut >= db->rawbuf + db->dmasize) + db->nextOut -= db->dmasize; +@@ -785,30 +799,44 @@ + struct dmabuf *dp = &s->dma_adc; + u32 obytes; + char *obuf; ++#ifdef AU1000_VERBOSE_DEBUG ++ u32 ac97c_stat; ++#endif + +- /* Pull the buffer from the dma queue. +- */ +- au1xxx_dbdma_get_dest(dp->dmanr, (void *)(&obuf), &obytes); +- +- if ((dp->count + obytes) > dp->dmasize) { +- /* Overrun. Stop ADC and log the error +- */ +- stop_adc(s); +- dp->error++; +- err("adc overrun"); +- return; +- } ++#ifdef AU1000_VERBOSE_DEBUG ++// if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE)) ++// dbg("AC97C status = 0x%08x", ac97c_stat); ++#endif + +- /* Put a new empty buffer on the destination DMA. ++ /* Pull completed buffer(s) from the dma queue. + */ +- au1xxx_dbdma_put_dest(dp->dmanr, dp->nextIn, dp->dma_fragsize); ++ int cnt=0; ++ while ( au1xxx_dbdma_get_dest(dp->dmanr, (void *)(&obuf), &obytes) ) { ++ if ((dp->count + obytes) > dp->dmasize) { ++ /* Overrun. Stop ADC and log the error ++ */ ++ stop_adc(s); ++ dp->error++; ++ err("adc overrun"); ++ break; ++ } + +- dp->nextIn += dp->dma_fragsize; +- if (dp->nextIn >= dp->rawbuf + dp->dmasize) +- dp->nextIn -= dp->dmasize; ++ dp->count += obytes; ++ dp->total_bytes += obytes; + +- dp->count += obytes; +- dp->total_bytes += obytes; ++ /* Put new empty buffer(s) on the destination DMA. ++ */ ++ while ( au1xxx_dbdma_put_dest(dp->dmanr, dp->nextIn, dp->dma_fragsize) ) { ++ dp->nextIn += dp->dma_fragsize; ++ if (dp->nextIn >= dp->rawbuf + dp->dmasize) ++ dp->nextIn -= dp->dmasize; ++ } ++ ++ if ( ++cnt>3 ) { ++ // get max 4 buffers at once here ++ break; ++ } ++ } + + /* wake up anybody listening + */ +@@ -1078,13 +1104,10 @@ + /* wait for samples in ADC dma buffer + */ + do { +- if (db->stopped) ++ if (db->stopped) + start_adc(s); +- spin_lock_irqsave(&s->lock, flags); ++ set_current_state(TASK_INTERRUPTIBLE); + avail = db->count; +- if (avail <= 0) +- __set_current_state(TASK_INTERRUPTIBLE); +- spin_unlock_irqrestore(&s->lock, flags); + if (avail <= 0) { + if (file->f_flags & O_NONBLOCK) { + if (!ret) +@@ -1163,11 +1189,8 @@ + /* wait for space in playback buffer + */ + do { +- spin_lock_irqsave(&s->lock, flags); ++ set_current_state(TASK_INTERRUPTIBLE); + avail = (int) db->dmasize - db->count; +- if (avail <= 0) +- __set_current_state(TASK_INTERRUPTIBLE); +- spin_unlock_irqrestore(&s->lock, flags); + if (avail <= 0) { + if (file->f_flags & O_NONBLOCK) { + if (!ret) +@@ -1190,6 +1214,7 @@ + if ((cnt = copy_dmabuf_user(db, (char *) buffer, + count > avail ? + avail : count, 0)) < 0) { ++ err("copy_dmabuf_user error %i", cnt); + if (!ret) + ret = -EFAULT; + goto out; +@@ -1213,6 +1228,7 @@ + err("qcount < 2 and no ring room!"); + } + db->nextOut += db->fragsize; ++ db->count -= db->fragsize; + if (db->nextOut >= db->rawbuf + db->dmasize) + db->nextOut -= db->dmasize; + db->total_bytes += db->dma_fragsize; +@@ -1244,13 +1269,20 @@ + unsigned int mask = 0; + + if (file->f_mode & FMODE_WRITE) { +- if (!s->dma_dac.ready) ++ if (!s->dma_dac.ready) { ++ err("poll: dma_dac not ready"); + return 0; ++ } + poll_wait(file, &s->dma_dac.wait, wait); + } + if (file->f_mode & FMODE_READ) { +- if (!s->dma_adc.ready) ++ if (!s->dma_adc.ready) { ++ err("poll: dma_adc not ready"); + return 0; ++ } ++ if ( s->dma_adc.stopped ) { ++ start_adc(s); ++ } + poll_wait(file, &s->dma_adc.wait, wait); + } + +@@ -1388,7 +1420,7 @@ + break; + } + if (count < sizeof(ioctl_str) / sizeof(ioctl_str[0])) +- dbg("ioctl %s, arg=0x%lx", ioctl_str[count].str, arg); ++ dbg("ioctl %s(%x), arg=0x%lx", ioctl_str[count].str, cmd, arg); + else + dbg("ioctl 0x%x unknown, arg=0x%lx", cmd, arg); + #endif +@@ -1456,12 +1488,14 @@ + if (file->f_mode & FMODE_READ) { + stop_adc(s); + s->dma_adc.num_channels = val ? 2 : 1; ++ set_recv_slots(s->dma_adc.num_channels); + if ((ret = prog_dmabuf_adc(s))) + return ret; + } + if (file->f_mode & FMODE_WRITE) { + stop_dac(s); + s->dma_dac.num_channels = val ? 2 : 1; ++ set_xmit_slots(s->dma_dac.num_channels); + if (s->codec_ext_caps & AC97_EXT_DACS) { + /* disable surround and center/lfe in AC'97 + */ +@@ -1486,6 +1520,7 @@ + return -EINVAL; + stop_adc(s); + s->dma_adc.num_channels = val; ++ set_recv_slots(s->dma_adc.num_channels); + if ((ret = prog_dmabuf_adc(s))) + return ret; + } +@@ -1543,6 +1578,7 @@ + } + + s->dma_dac.num_channels = val; ++ set_xmit_slots(s->dma_dac.num_channels); + if ((ret = prog_dmabuf_dac(s))) + return ret; + } +@@ -1799,6 +1835,7 @@ + return -EINVAL; + } + ++ info("mixdev_ioctl(%i)", cmd); + return mixdev_ioctl(s->codec, cmd, arg); + } + +@@ -1813,9 +1850,9 @@ + + #ifdef AU1000_VERBOSE_DEBUG + if (file->f_flags & O_NONBLOCK) +- dbg(__FUNCTION__ ": non-blocking"); ++ info("%s : non-blocking", __FUNCTION__); + else +- dbg(__FUNCTION__ ": blocking"); ++ info("%s : blocking", __FUNCTION__); + #endif + + file->private_data = s; +@@ -1846,6 +1883,7 @@ + s->dma_adc.num_channels = 1; + s->dma_adc.sample_size = 8; + set_adc_rate(s, 8000); ++ set_recv_slots(s->dma_adc.num_channels); + if ((minor & 0xf) == SND_DEV_DSP16) + s->dma_adc.sample_size = 16; + } +@@ -1856,22 +1894,31 @@ + s->dma_dac.num_channels = 1; + s->dma_dac.sample_size = 8; + set_dac_rate(s, 8000); ++ set_xmit_slots(s->dma_dac.num_channels); + if ((minor & 0xf) == SND_DEV_DSP16) + s->dma_dac.sample_size = 16; + } + + if (file->f_mode & FMODE_READ) { +- if ((ret = prog_dmabuf_adc(s))) ++ if ((ret = prog_dmabuf_adc(s))) { ++ err("prog_dmabuf_adc failed"); ++ up(&s->open_sem); + return ret; ++ } ++ + } + if (file->f_mode & FMODE_WRITE) { +- if ((ret = prog_dmabuf_dac(s))) ++ if ((ret = prog_dmabuf_dac(s))) { ++ err("prog_dmabuf_dac failed"); ++ up(&s->open_sem); + return ret; ++ } + } + + s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); + up(&s->open_sem); + init_MUTEX(&s->sem); ++ + return 0; + } + +@@ -1954,12 +2001,13 @@ + err("AC'97 ports in use"); + } + ++ + /* Allocate the DMA Channels + */ + if ((s->dma_dac.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_MEM_CHAN, + DBDMA_AC97_TX_CHAN, dac_dma_interrupt, (void *)s)) == 0) { + err("Can't get DAC DMA"); +- goto err_dma1; ++ goto err_dev1; + } + au1xxx_dbdma_set_devwidth(s->dma_dac.dmanr, 16); + if (au1xxx_dbdma_ring_alloc(s->dma_dac.dmanr, +@@ -1968,10 +2016,11 @@ + goto err_dma1; + } + ++ + if ((s->dma_adc.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_AC97_RX_CHAN, +- DBDMA_MEM_CHAN, adc_dma_interrupt, (void *)s)) == 0) { ++ DBDMA_MEM_CHAN, adc_dma_interrupt, (void *)s)) == 0) { + err("Can't get ADC DMA"); +- goto err_dma2; ++ goto err_dma1; + } + au1xxx_dbdma_set_devwidth(s->dma_adc.dmanr, 16); + if (au1xxx_dbdma_ring_alloc(s->dma_adc.dmanr, +@@ -1980,7 +2029,7 @@ + + #ifdef AU1550_DEBUG + /* intialize the debug proc device */ +- s->ps = create_proc_read_entry(AU1000_MODULE_NAME, 0, NULL, ++ s->ps = create_proc_read_entry(AU1550_MODULE_NAME, 0, NULL, + proc_au1550_dump, NULL); + #endif /* AU1550_DEBUG */ + +@@ -2102,11 +2150,11 @@ + unregister_sound_mixer(s->codec->dev_mixer); + err_dev2: + unregister_sound_dsp(s->dev_audio); +- err_dev1: +- au1xxx_dbdma_chan_free(s->dma_adc.dmanr); + err_dma2: +- au1xxx_dbdma_chan_free(s->dma_dac.dmanr); ++ au1xxx_dbdma_chan_free(s->dma_adc.dmanr); + err_dma1: ++ au1xxx_dbdma_chan_free(s->dma_dac.dmanr); ++ err_dev1: + release_region(PHYSADDR(AC97_PSC_SEL), 0x30); + + ac97_release_codec(s->codec); +@@ -2125,11 +2173,11 @@ + remove_proc_entry(AU1000_MODULE_NAME, NULL); + #endif /* AU1000_DEBUG */ + synchronize_irq(); ++ unregister_sound_dsp(s->dev_audio); ++ unregister_sound_mixer(s->codec->dev_mixer); + au1xxx_dbdma_chan_free(s->dma_adc.dmanr); + au1xxx_dbdma_chan_free(s->dma_dac.dmanr); + release_region(PHYSADDR(AC97_PSC_SEL), 0x30); +- unregister_sound_dsp(s->dev_audio); +- unregister_sound_mixer(s->codec->dev_mixer); + ac97_release_codec(s->codec); + } + diff --git a/packages/linux/linux-mtx-2-2.4.27/45-acm-tty.patch b/packages/linux/linux-mtx-2-2.4.27/45-acm-tty.patch new file mode 100644 index 0000000000..028d10ad9a --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/45-acm-tty.patch @@ -0,0 +1,252 @@ +--- linux/drivers/usb/acm.c~45-acm-tty.patch 2006-06-07 11:21:21.648422000 +0200 ++++ linux/drivers/usb/acm.c 2006-06-09 17:20:51.735793750 +0200 +@@ -139,6 +139,8 @@ + * Internal driver structures. + */ + ++#define TD_SIZE 16384 ++ + struct acm { + struct usb_device *dev; /* the coresponding usb device */ + struct usb_interface *iface; /* the interfaces - +0 control +1 data */ +@@ -153,6 +155,11 @@ + unsigned int minor; /* acm minor number */ + unsigned char throttle; /* throttled by tty layer */ + unsigned char clocal; /* termios CLOCAL */ ++ unsigned long throttle_start; ++ unsigned char resubmit_to_unthrottle; /* Leftover data from last operation */ ++ unsigned char *throttle_data; ++ int td_len; ++ int td_busy; + }; + + /* global params controlling max sizes for read, write, control */ +@@ -166,6 +173,96 @@ + + #define ACM_READY(acm) (acm && acm->dev && acm->used) + ++ ++/* ++ * Helper functions to optimize throttleing ++ */ ++static int ++acm_fill_tty(struct urb *urb, struct tty_struct *tty, unsigned char *data, int length) ++{ ++ struct acm *acm = urb->context; ++ int n = 0; ++ /*printk("acm_fill_tty: %d bytes\n", length);*/ ++ if (!urb->status && !acm->throttle) { ++ for (n = 0; n < length && !acm->throttle; n++) { ++ /* if we insert more than TTY_FLIPBUF_SIZE characters, ++ * we drop them. */ ++ if (tty->flip.count >= TTY_FLIPBUF_SIZE) { ++ tty_flip_buffer_push(tty); ++ } ++ tty_insert_flip_char(tty, data[n], 0); ++ } ++ tty_flip_buffer_push(tty); ++ } ++ /*printk("copied %d bytes.\n", n);*/ ++ return n; ++} ++ ++static int ++acm_shift_if_throttle(unsigned char *data, int *length, int shift_by) ++{ ++ if (shift_by < *length) { ++ dbg("need to shift uncopied %d bytes to front.", *length - shift_by); ++ memmove(data, data + shift_by, *length - shift_by); ++ *length -= shift_by; ++ return 1; ++ } ++ return 0; ++} ++ ++static int ++acm_buffer_if_thottle(struct acm *acm, unsigned char *data, int start, int *length) ++{ ++ int copied = *length; ++ if (start < *length) { ++ int space = TD_SIZE - acm->td_len; ++ int needed = *length - start; ++ copied = (space < needed)? space: needed; ++ dbg("need to push %d to throttle buffer, can copy %d.", ++ needed, copied); ++ memcpy(acm->throttle_data + acm->td_len, data, copied); ++ acm->td_len += copied; ++ *length -= copied; ++ } ++ return copied; ++} ++ ++static int ++acm_empty_throttle(struct urb *urb, struct tty_struct *tty) ++{ ++ unsigned long flags; ++ struct acm *acm = urb->context; ++ ++ save_flags(flags); ++ cli(); ++ ++ if (acm->td_busy) { ++ restore_flags(flags); ++ return 0; ++ } ++ acm->td_busy = 1; ++ restore_flags(flags); ++ ++ if (acm->td_len > 0) { ++ ++ dbg("acm_empty_throttle: trying to empty throttle buffer: %d bytes.", ++ acm->td_len); ++ ++ /* if there has been something left from previous operations ++ * we try to complete this before looking at the urb */ ++ int copied = acm_fill_tty(urb, tty, acm->throttle_data, acm->td_len); ++ if (acm_shift_if_throttle(acm->throttle_data, &acm->td_len, copied)) { ++ /* we were unable to empty the throttle data, so we can't ++ * copy anything more now */ ++ acm->td_busy = 0; ++ return 0; ++ } ++ acm->td_len = 0; ++ } ++ acm->td_busy = 0; ++ return 1; ++} ++ + /* + * Functions for ACM control messages. + */ +@@ -238,36 +335,40 @@ + struct acm *acm = urb->context; + struct tty_struct *tty = acm->tty; + unsigned char *data = urb->transfer_buffer; +- int i = 0; ++ int copied = 0; ++ int buffered = 0; + + if (!ACM_READY(acm)) return; + +- if (urb->status) ++ if (urb->status) { + dbg("nonzero read bulk status received: %d", urb->status); ++ } + +- if (!urb->status && !acm->throttle) { +- for (i = 0; i < urb->actual_length && !acm->throttle; i++) { +- /* if we insert more than TTY_FLIPBUF_SIZE characters, +- * we drop them. */ +- if (tty->flip.count >= TTY_FLIPBUF_SIZE) { +- tty_flip_buffer_push(tty); +- } +- tty_insert_flip_char(tty, data[i], 0); +- } +- tty_flip_buffer_push(tty); ++ dbg("acm_read_bulk, calling acm_empty_throttle()"); ++ if (!acm_empty_throttle(urb, tty)) { ++ dbg("could not empty throttle buffer, entering throttle state, acm->td_busy: %d.", acm->td_busy); + } + ++ /* got here, either there was nothing in the throttle data or it could ++ * all be copied without throttleing again */ ++ copied = acm_fill_tty(urb, tty, data, urb->actual_length); + if (acm->throttle) { +- memmove(data, data + i, urb->actual_length - i); +- urb->actual_length -= i; +- return; ++ int length = urb->actual_length; ++ buffered = acm_buffer_if_thottle(acm, data, copied, &urb->actual_length); ++ if (buffered < length - copied ++ && acm_shift_if_throttle(data, &urb->actual_length, copied + buffered)) { ++ printk("need to resubmit to unthrottle\n"); ++ acm->resubmit_to_unthrottle = 1; ++ return; ++ } + } + + urb->actual_length = 0; + urb->dev = acm->dev; + +- if (usb_submit_urb(urb)) ++ if (usb_submit_urb(urb)) { + dbg("failed resubmitting read urb"); ++ } + } + + static void acm_write_bulk(struct urb *urb) +@@ -330,7 +431,12 @@ + + acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS); + +- /* force low_latency on so that our tty_push actually forces the data through, ++ acm->resubmit_to_unthrottle = 0; ++ acm->td_len = 0; ++ acm->td_busy = 0; ++ acm->throttle_data = kmalloc(TD_SIZE * sizeof (*acm->throttle_data), GFP_KERNEL); ++ ++ /* force low_latency on so that our tty_push actually forces the data through, + otherwise it is scheduled, and with high data rates data can get lost. */ + tty->low_latency = 1; + +@@ -352,6 +458,7 @@ + } else { + tty_unregister_devfs(&acm_tty_driver, acm->minor); + acm_table[acm->minor] = NULL; ++ kfree(acm->throttle_data); + kfree(acm); + } + } +@@ -363,8 +470,16 @@ + struct acm *acm = tty->driver_data; + + if (!ACM_READY(acm)) return -EINVAL; +- if (acm->writeurb.status == -EINPROGRESS) return 0; +- if (!count) return 0; ++ ++ if (acm->writeurb.status == -EINPROGRESS) { ++ dbg("tty_write in progress"); ++ return 0; ++ } ++ ++ if (!count) { ++ dbg("tty_write: nothing to write"); ++ return 0; ++ } + + count = (count > acm->writesize) ? acm->writesize : count; + +@@ -401,16 +516,32 @@ + { + struct acm *acm = tty->driver_data; + if (!ACM_READY(acm)) return; ++ dbg("acm_tty_throttle ON %ld ---> %ld", jiffies-acm->throttle_start, jiffies); + acm->throttle = 1; ++ acm->throttle_start = jiffies; + } + + static void acm_tty_unthrottle(struct tty_struct *tty) + { + struct acm *acm = tty->driver_data; + if (!ACM_READY(acm)) return; ++ dbg("acm_tty_throttle OFF %ld ---> %ld", jiffies, jiffies-acm->throttle_start); + acm->throttle = 0; +- if (acm->readurb.status != -EINPROGRESS) ++ ++ dbg("acm_tty_unthrottle, calling acm_empty_throttle()"); ++ if (!acm_empty_throttle(&acm->readurb, tty)) { ++ if (acm->td_busy) { ++ printk("***** pending acm_empty_throttle!\n"); ++ } else { ++ dbg("throttle not emptied.\n"); ++ } ++ } ++ ++ if (acm->resubmit_to_unthrottle != 0) { ++ dbg("resubmit_to_unthrottle: acm_read_bulk"); ++ acm->resubmit_to_unthrottle = 0; + acm_read_bulk(&acm->readurb); ++ } + } + + static void acm_tty_break_ctl(struct tty_struct *tty, int state) diff --git a/packages/linux/linux-mtx-2-2.4.27/defconfig-mtx-2 b/packages/linux/linux-mtx-2-2.4.27/defconfig-mtx-2 new file mode 100644 index 0000000000..fb8c033e09 --- /dev/null +++ b/packages/linux/linux-mtx-2-2.4.27/defconfig-mtx-2 @@ -0,0 +1,1347 @@ +# +# Automatically generated by make menuconfig: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_DB1550 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_HYDROGEN3 is not set +# CONFIG_MIPS_PB1550 is not set +# CONFIG_MIPS_XXS1500 is not set +CONFIG_MIPS_MTX2=y +# CONFIG_COGENT_CSB250 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_PMC_BIG_SUR is not set +# CONFIG_PMC_STRETCH is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_BUILD_ELF64 is not set +CONFIG_NET=y +CONFIG_PCI=y +CONFIG_PCI_NEW=y +CONFIG_PCI_AUTO=y +CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +CONFIG_CARDBUS=y +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_PCMCIA_AU1X00 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set +# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set +# CONFIG_HOTPLUG_PCI_PCIE is not set +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +CONFIG_BINFMT_MISC=m +# CONFIG_OOM_KILLER is not set +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_CONCAT=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_AMDSTD_RETRY=y +CONFIG_MTD_CFI_AMDSTD_RETRY_MAX=5 +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_DB1X00 is not set +CONFIG_MTD_MTX2=y +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +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=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP 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_INET_ECN is not set +CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=y +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_LIMIT=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=y +CONFIG_IP_NF_MATCH_CONNTRACK=y +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_NAT_AMANDA=m +# CONFIG_IP_NF_NAT_LOCAL is not set +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_MANGLE=y +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=y +CONFIG_IP_NF_TARGET_LOG=y +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 + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +CONFIG_IPV6=m + +# +# IPv6: Netfilter Configuration +# +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_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_KHTTPD is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +CONFIG_VLAN_8021Q=m +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +CONFIG_BRIDGE=m +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL 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_HFSC is not set +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_NETEM is not set +CONFIG_NET_SCH_DSMARK=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 + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +CONFIG_IPSEC_NAT_TRAVERSAL=y +CONFIG_IPSEC=m +CONFIG_IPSEC_IPIP=y +CONFIG_IPSEC_AH=y +CONFIG_IPSEC_AUTH_HMAC_MD5=y +CONFIG_IPSEC_AUTH_HMAC_SHA1=y +CONFIG_IPSEC_ESP=y +CONFIG_IPSEC_ENC_3DES=y +CONFIG_IPSEC_ENC_AES=y +CONFIG_IPSEC_ALG=y +CONFIG_IPSEC_ALG_AES=m +CONFIG_IPSEC_ALG_CRYPTOAPI=m +CONFIG_IPSEC_ALG_NON_LIBRE=y +CONFIG_IPSEC_IPCOMP=y +CONFIG_IPSEC_DEBUG=y + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=m +CONFIG_BLK_DEV_SD=m +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +# CONFIG_CHR_DEV_SG is not set +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_MEGARAID2 is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_SATA_SVW is not set +# CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_SX4 is not set +# CONFIG_SCSI_SATA_SIL is not set +# CONFIG_SCSI_SATA_SIS is not set +# CONFIG_SCSI_SATA_VIA is not set +# CONFIG_SCSI_SATA_VITESSE is not set +# CONFIG_SCSI_BUSLOGIC 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_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_NCR53C8XX is not set +# CONFIG_SCSI_SYM53C8XX is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# PCMCIA SCSI adapter support +# +# CONFIG_SCSI_PCMCIA is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +CONFIG_DUMMY=m +CONFIG_BONDING=m +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE_MPPC=y +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +CONFIG_AIRONET4500=m +CONFIG_AIRONET4500_NONCS=m +# CONFIG_AIRONET4500_PNP is not set +CONFIG_AIRONET4500_PCI=y +# CONFIG_AIRONET4500_ISA is not set +# CONFIG_AIRONET4500_I365 is not set +CONFIG_AIRONET4500_PROC=m +CONFIG_AIRO=m +# CONFIG_HERMES is not set +# CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set +# CONFIG_PCI_HERMES is not set +# CONFIG_PCMCIA_HERMES is not set +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_ATMEL is not set +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +CONFIG_SHAPER=m + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT 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_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# 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 +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 +CONFIG_NOZOMI=m + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_ALGOBIT=m +# CONFIG_I2C_PHILIPSPAR is not set +# CONFIG_I2C_ELV is not set +# CONFIG_I2C_VELLEMAN is not set +# CONFIG_SCx200_I2C is not set +CONFIG_I2C_AU1X00GPIO=m +CONFIG_I2C_AU1X00GPIO_SCL=206 +CONFIG_I2C_AU1X00GPIO_SDA=207 +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_MAINBOARD is not set +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_PROC=m + +# +# Hardware sensors support +# +CONFIG_SENSORS=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1024 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_FSCSCY is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_MAXILIFE is not set +# CONFIG_SENSORS_XEONTEMP is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MTP008 is not set +CONFIG_SENSORS_LM75=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_PC87360=m +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83L785TS is not set +CONFIG_SENSORS_OTHER=y +CONFIG_SENSORS_BT869=m +CONFIG_SENSORS_DDCMON=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_MATORB=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200 is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +CONFIG_AU1X00_GPIO=m +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=m +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=m +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=m +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_SMB_UNIX is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +CONFIG_ZISOFS_FS=m + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-15" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=m +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=m + +# +# Video For Linux +# +CONFIG_VIDEO_PROC_FS=y +# CONFIG_I2C_PARPORT is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set +CONFIG_VIDEO_CPIA=m +# CONFIG_VIDEO_CPIA_PP is not set +CONFIG_VIDEO_CPIA_USB=m +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +# CONFIG_VIDEO_ZORAN_BUZ is not set +# CONFIG_VIDEO_ZORAN_DC10 is not set +# CONFIG_VIDEO_ZORAN_LML33 is not set +# CONFIG_VIDEO_ZR36120 is not set +# CONFIG_VIDEO_MEYE is not set + +# +# Radio Adapters +# +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set +# CONFIG_RADIO_MIROPCM20 is not set + +# +# Sound +# +CONFIG_SOUND=m +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_AU1X00 ist not set +CONFIG_SOUND_AU1550_PSC=m +# CONFIG_SOUND_AU1550_I2S is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_TRACEINIT is not set +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_AD1889 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_PAS_JOYSTICK is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_KAHLUA is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_YMFPCI_LEGACY is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_AD1980 is not set +# CONFIG_SOUND_WM97XX is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=m +CONFIG_USB_AUDIO=m +CONFIG_USB_EMI26=m +CONFIG_USB_MIDI=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_DEBUG=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +# CONFIG_USB_STORAGE_ISD200 is not set +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_ACM=m +CONFIG_USB_PRINTER=m +# CONFIG_USB_HID is not set +# CONFIG_USB_HIDINPUT is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +CONFIG_USB_DC2XX=m +CONFIG_USB_MDC800=m +CONFIG_USB_SCANNER=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_HPUSBSCSI=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_W9968CF is not set +CONFIG_USB_VICAM=m +CONFIG_USB_DSBR=m +CONFIG_USB_DABUSB=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_KAWETH=m +CONFIG_USB_CATC=m +CONFIG_USB_CDCETHER=m +CONFIG_USB_USBNET=m +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_DEBUG is not set +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=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_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_RIO500=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_TIGL=m +CONFIG_USB_BRLVGER=m +CONFIG_USB_LCD=m + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# +# USB clients (devices, not hosts) +# +CONFIG_USBD=m +# CONFIG_USBD_HIGH_SPEED is not set +# CONFIG_USBD_NO_SERIAL_NUMBER is not set +CONFIG_USBD_SERIAL_NUMBER_STR="" +CONFIG_USBD_MAXPOWER=0 +CONFIG_USBD_PROCFS=y +CONFIG_USBD_PROCFSM=m + +# +# Network Function +# +CONFIG_USBD_NETWORK=m +CONFIG_USBD_NETWORK_VENDORID=12b9 +CONFIG_USBD_NETWORK_PRODUCTID=f001 +CONFIG_USBD_NETWORK_BCDDEVICE=0100 +CONFIG_USBD_NETWORK_MANUFACTURER="Belcarra" +## CONFIG_USBD_NETWORK_PRODUCT_NAME="Belcarra BLAN Device" +## CONFIG_USBD_NETWORK_BLAN=y +## CONFIG_USBD_NETWORK_BLAN_DESC="BLAN Net Cfg" +## CONFIG_USBD_NETWORK_BLAN_INTF="Comm/Data Intf" +# CONFIG_USBD_NETWORK_BLAN_CRC is not set +# CONFIG_USBD_NETWORK_BLAN_DO_NOT_SETTIME is not set +# CONFIG_USBD_NETWORK_BLAN_HOSTNAME is not set +# CONFIG_USBD_NETWORK_BLAN_NOBRIDGE is not set +CONFIG_USBD_NETWORK_SAFE=y +CONFIG_USBD_NETWORK_SAFE_NOBRIDGE=y +# CONFIG_USBD_NETWORK_CDC is not set +# CONFIG_USBD_NETWORK_BASIC is not set +# CONFIG_USBD_NETWORK_BASIC2 is not set +# CONFIG_USBD_NETWORK_START_SINGLE is not set +# CONFIG_USBD_NETWORK_EP0TEST is not set + +# +# CDC ACM Function +# +CONFIG_USBD_ACM=m +CONFIG_USBD_ACM_VENDORID=12b9 +CONFIG_USBD_ACM_PRODUCTID=f002 +CONFIG_USBD_ACM_BCDDEVICE=0100 +CONFIG_USBD_ACM_MANUFACTURER="Belcarra" +CONFIG_USBD_ACM_PRODUCT_NAME="Belcarra ACM Device" +CONFIG_USBD_ACM_DESC="Acm Cfg" +CONFIG_USBD_ACM_COMM_INTF="Comm Intf" +CONFIG_USBD_ACM_DATA_INTF="Data Intf" +# CONFIG_USBD_ACM_TRACE is not set + +# +# Random Mouse Function +# +# CONFIG_USBD_MOUSE is not set + +# +# AMD AU1X000 Bus Interface +# +CONFIG_USBD_AU1X00_BUS=m +CONFIG_USBD_AU1X00_SCLOCK=400 +CONFIG_AU1000_USB_DEVICE=y +CONFIG_AU1X00_USB_DEVICE=y +# CONFIG_USBD_BI_REGISTER_TRACE is not set + +# +# Bluetooth support +# +CONFIG_BLUEZ=m +CONFIG_BLUEZ_L2CAP=m +CONFIG_BLUEZ_SCO=m +CONFIG_BLUEZ_RFCOMM=m +CONFIG_BLUEZ_RFCOMM_TTY=y +CONFIG_BLUEZ_BNEP=m +CONFIG_BLUEZ_BNEP_MC_FILTER=y +CONFIG_BLUEZ_BNEP_PROTO_FILTER=y + +# +# Bluetooth device drivers +# +CONFIG_BLUEZ_HCIUSB=m +CONFIG_BLUEZ_HCIUSB_SCO=y +CONFIG_BLUEZ_HCIUART=m +CONFIG_BLUEZ_HCIUART_H4=y +CONFIG_BLUEZ_HCIUART_BCSP=y +CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y +CONFIG_BLUEZ_HCIBFUSB=m +# CONFIG_BLUEZ_HCIDTL1 is not set +# CONFIG_BLUEZ_HCIBT3C is not set +# CONFIG_BLUEZ_HCIBLUECARD is not set +# CONFIG_BLUEZ_HCIBTUART is not set +CONFIG_BLUEZ_HCIVHCI=m + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_TEST=m + +# +# Library routines +# +CONFIG_CRC32=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_FW_LOADER=m diff --git a/packages/linux/linux-mtx-2_2.4.27.bb b/packages/linux/linux-mtx-2_2.4.27.bb new file mode 100644 index 0000000000..b08b3dcaeb --- /dev/null +++ b/packages/linux/linux-mtx-2_2.4.27.bb @@ -0,0 +1,94 @@ +DESCRIPTION = "Linux kernel for MTX-2 (Surfbox2)" +MAINTAINER = "Bruno Randolf " +HOMEPAGE = "http://meshcube.org/meshwiki/" +LICENSE = "GPL" +KV = "${PV}" +PR = "r11" +inherit module-base kernel + +PROVIDES = "virtual/kernel" +RDEPENDS = "mtd-utils" + +SRC_URI += "cvs://cvs:cvs@ftp.linux-mips.org/home/cvs;module=linux;tag=linux_2_4_27 \ + file://00-mtx-2.diff;patch=1 \ + file://01-mtd-mtx-2.diff;patch=1 \ + file://03-mtd-erase-compiler-bug.diff;patch=1 \ + file://04-mtd-yamonenv-readwrite.diff;patch=1 \ + file://05-mtx-2-pci-irq.diff;patch=1 \ + file://06-zboot-2.4.26.patch;patch=1 \ + file://07-zboot-zimage-flash-bin.diff;patch=1 \ + file://08-usb-nonpci-2.4.24.patch;patch=1 \ + file://10-iw-max-spy-32.diff;patch=1 \ + file://11-mtd-proc-partition-rw.diff;patch=1 \ + file://12-openswan-2.2.0-nat-t.diff;patch=1 \ + file://13-openswan-2.2.0.patch;patch=1 \ + file://16-i2c.patch;patch=1 \ + file://17-lmsensors.2.8.8.patch;patch=1 \ + file://18-i2c-au1x00gpio.patch;patch=1 \ + file://19-kernel-make-depend.diff;patch=1 \ + file://22-umts.diff;patch=1 \ + file://27-idsel-cardbus.diff;patch=1 \ + file://28-surfbox2-idsel.diff;patch=1 \ + file://29-au1000-pci-config-clear-errors.diff;patch=1 \ + file://32-usbserial-stalled-hack.diff;patch=1 \ + file://33-usbserial-bulk_in_size-4096.diff;patch=1 \ + file://35-sb2-slic.patch;patch=1 \ + file://36-sb2-lcd.patch;patch=1 \ + file://37-sb2-sysbtn.patch;patch=1 \ + file://39-mppe-mpc.patch;patch=1 \ + file://40-option-hsdpa.patch;patch=1 \ + file://42-usb-ohci-fixes.patch;patch=1 \ + file://43-usbserial-27-32-backport.diff;patch=1 \ + file://44-dbdma-and-au1550_psc.diff;patch=1 \ + file://45-acm-tty.patch;patch=1 \ + file://defconfig-mtx-2" + +FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/linux-mtx-2-${PV}" + +S = "${WORKDIR}/linux" + +inherit kernel + +COMPATIBLE_HOST = "mipsel.*-linux" +ARCH = "mips" +KERNEL_OUTPUT = "arch/mips/zboot/images/mtx-2.flash.bin" +KERNEL_IMAGETYPE = "zImage.flash" +KERNEL_IMAGEDEST = "tmp" + +KERNEL_IMAGE_NAME = "kernel-${KV}-${MACHINE}_${BUILDNAME}" + +MTX_KERNEL_NON_PCI_OHCI = "no" + +PACKAGE_ARCH = "mtx-2" + +do_configure_prepend() { + install -m 0644 ${WORKDIR}/defconfig-mtx-2 ${S}/.config + if [ "x${MTX_KERNEL_NON_PCI_OHCI}" == "xyes" ]; then + echo "CONFIG_USB_NON_PCI_OHCI=y" >> ${S}/.config + fi +} + +pkg_postinst_kernel() { +if test "x$D" != "x"; then + exit 1 +else + if test -e /tmp/zImage.flash-${KV}; then + echo "*** flashing kernel ***" + flashcp -v /tmp/zImage.flash-${KV} /dev/mtd/2 + echo "*** done. please reboot ***" + fi +fi +} + +FILES_kernel += " /tmp" + +do_deploy() { + install -d ${DEPLOY_DIR}/images + install -m 0644 arch/mips/zboot/images/mtx-2.flash.bin ${DEPLOY_DIR}/images/${KERNEL_IMAGE_NAME}.flash.bin + install -m 0644 arch/mips/zboot/images/mtx-2.flash.srec ${DEPLOY_DIR}/images/${KERNEL_IMAGE_NAME}.flash.srec + install -m 0644 arch/mips/zboot/images/mtx-2.srec ${DEPLOY_DIR}/images/${KERNEL_IMAGE_NAME}.ram.srec +} + +do_deploy[dirs] = "${S}" + +addtask deploy before do_build after do_compile -- cgit v1.2.3 From 624a8d827f1da93d61e853152294f2fbfcd93ff7 Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 12:44:24 +0000 Subject: libccaudio2: added new port. --- packages/libccaudio2/.mtn2git_empty | 0 .../libccaudio2/libccaudio2-0.9.0/.mtn2git_empty | 0 .../libccaudio2-0.9.0/01-ccaudio-fixed-point.diff | 677 +++++++++++++++++++++ .../libccaudio2-0.9.0/02-ccaudio-stereo.diff | 54 ++ .../libccaudio2-0.9.0/03-ccaudio-dtmf-reset.diff | 36 ++ packages/libccaudio2/libccaudio2_0.9.0.bb | 24 + 6 files changed, 791 insertions(+) create mode 100644 packages/libccaudio2/.mtn2git_empty create mode 100644 packages/libccaudio2/libccaudio2-0.9.0/.mtn2git_empty create mode 100644 packages/libccaudio2/libccaudio2-0.9.0/01-ccaudio-fixed-point.diff create mode 100644 packages/libccaudio2/libccaudio2-0.9.0/02-ccaudio-stereo.diff create mode 100644 packages/libccaudio2/libccaudio2-0.9.0/03-ccaudio-dtmf-reset.diff create mode 100644 packages/libccaudio2/libccaudio2_0.9.0.bb diff --git a/packages/libccaudio2/.mtn2git_empty b/packages/libccaudio2/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/libccaudio2/libccaudio2-0.9.0/.mtn2git_empty b/packages/libccaudio2/libccaudio2-0.9.0/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/libccaudio2/libccaudio2-0.9.0/01-ccaudio-fixed-point.diff b/packages/libccaudio2/libccaudio2-0.9.0/01-ccaudio-fixed-point.diff new file mode 100644 index 0000000000..226a4203cc --- /dev/null +++ b/packages/libccaudio2/libccaudio2-0.9.0/01-ccaudio-fixed-point.diff @@ -0,0 +1,677 @@ +diff -NurBb src/audio2.h patched_src/audio2.h +--- ccaudio2-0.9.0/src/audio2.h 2006-04-06 10:25:17.000000000 +0200 ++++ ccaudio2-0.9.0/patched_src/audio2.h 2006-04-22 14:13:25.000000000 +0200 +@@ -82,6 +82,7 @@ + #endif + + #include ++#include "fixedPoint.H" + + namespace ost { + +@@ -760,7 +761,7 @@ + Rate rate; + unsigned samples; + Linear frame; +- double df1, df2, p1, p2; ++ FixedPoint df1, df2, p1, p2; + Level m1, m2; + bool silencer; + +diff -NurBb src/detect.cpp patched_src/detect.cpp +--- ccaudio2-0.9.0/src/detect.cpp 2005-07-29 22:16:35.000000000 +0200 ++++ ccaudio2-0.9.0/patched_src/detect.cpp 2006-04-22 14:13:26.000000000 +0200 +@@ -78,6 +78,13 @@ + static float dtmf_col[] = { 1209.0, 1336.0, 1477.0, 1633.0 }; + static float fax_freq = 1100.0; + ++ // fixed value for dtmf_detect_(row|col)[].fac for SAMPLE_RATE = 8000 ++ static float init[4][4]={ {1.70774,1.1641,0.916368,-0.644862}, ++ {1.64528,0.99637,0.70695,-1.00725}, ++ {1.56869,0.798618,0.460779,-1.36221}, ++ {1.4782,0.568533,0.185089,-1.67677} ++ }; ++ + state = (dtmf_detect_state_t *)malloc(sizeof(dtmf_detect_state_t)); + memset(state, 0, sizeof(state)); + +@@ -85,15 +92,19 @@ + { + theta = (float)(2.0 * M_PI * (dtmf_row[i] / SAMPLE_RATE)); + dtmf_detect_row[i].fac = (float)(2.0 * cos(theta)); ++ dtmf_detect_row[i].fac = init[i][0]; + + theta = (float)(2.0 * M_PI * (dtmf_col[i] / SAMPLE_RATE)); + dtmf_detect_col[i].fac = (float)(2.0 * cos(theta)); ++ dtmf_detect_col[i].fac = init[i][1]; + + theta = (float)(2.0 * M_PI * (dtmf_row[i] * 2.0 / SAMPLE_RATE)); + dtmf_detect_row_2nd[i].fac = (float)(2.0 * cos(theta)); ++ dtmf_detect_row_2nd[i].fac = init[i][2]; + + theta = (float)(2.0 * M_PI * (dtmf_col[i] * 2.0 / SAMPLE_RATE)); + dtmf_detect_col_2nd[i].fac = (float)(2.0 * cos(theta)); ++ dtmf_detect_col_2nd[i].fac = init[i][3]; + + goertzelInit(&state->row_out[i], &dtmf_detect_row[i]); + goertzelInit(&state->col_out[i], &dtmf_detect_col[i]); +@@ -196,30 +207,30 @@ + state->row_out[0].v2 = state->row_out[0].v3; + state->row_out[0].v3 = state->row_out[0].fac*state->row_out[0].v2 - v1 + famp; + +- v1 = state->col_out[0].v2; +- state->col_out[0].v2 = state->col_out[0].v3; +- state->col_out[0].v3 = state->col_out[0].fac*state->col_out[0].v2 - v1 + famp; +- + v1 = state->row_out[1].v2; + state->row_out[1].v2 = state->row_out[1].v3; + state->row_out[1].v3 = state->row_out[1].fac*state->row_out[1].v2 - v1 + famp; + +- v1 = state->col_out[1].v2; +- state->col_out[1].v2 = state->col_out[1].v3; +- state->col_out[1].v3 = state->col_out[1].fac*state->col_out[1].v2 - v1 + famp; +- + v1 = state->row_out[2].v2; + state->row_out[2].v2 = state->row_out[2].v3; + state->row_out[2].v3 = state->row_out[2].fac*state->row_out[2].v2 - v1 + famp; + +- v1 = state->col_out[2].v2; +- state->col_out[2].v2 = state->col_out[2].v3; +- state->col_out[2].v3 = state->col_out[2].fac*state->col_out[2].v2 - v1 + famp; +- + v1 = state->row_out[3].v2; + state->row_out[3].v2 = state->row_out[3].v3; + state->row_out[3].v3 = state->row_out[3].fac*state->row_out[3].v2 - v1 + famp; + ++ v1 = state->col_out[0].v2; ++ state->col_out[0].v2 = state->col_out[0].v3; ++ state->col_out[0].v3 = state->col_out[0].fac*state->col_out[0].v2 - v1 + famp; ++ ++ v1 = state->col_out[1].v2; ++ state->col_out[1].v2 = state->col_out[1].v3; ++ state->col_out[1].v3 = state->col_out[1].fac*state->col_out[1].v2 - v1 + famp; ++ ++ v1 = state->col_out[2].v2; ++ state->col_out[2].v2 = state->col_out[2].v3; ++ state->col_out[2].v3 = state->col_out[2].fac*state->col_out[2].v2 - v1 + famp; ++ + v1 = state->col_out[3].v2; + state->col_out[3].v2 = state->col_out[3].v3; + state->col_out[3].v3 = state->col_out[3].fac*state->col_out[3].v2 - v1 + famp; +@@ -228,34 +239,34 @@ + state->col_out2nd[0].v2 = state->col_out2nd[0].v3; + state->col_out2nd[0].v3 = state->col_out2nd[0].fac*state->col_out2nd[0].v2 - v1 + famp; + +- v1 = state->row_out2nd[0].v2; +- state->row_out2nd[0].v2 = state->row_out2nd[0].v3; +- state->row_out2nd[0].v3 = state->row_out2nd[0].fac*state->row_out2nd[0].v2 - v1 + famp; +- + v1 = state->col_out2nd[1].v2; + state->col_out2nd[1].v2 = state->col_out2nd[1].v3; + state->col_out2nd[1].v3 = state->col_out2nd[1].fac*state->col_out2nd[1].v2 - v1 + famp; + +- v1 = state->row_out2nd[1].v2; +- state->row_out2nd[1].v2 = state->row_out2nd[1].v3; +- state->row_out2nd[1].v3 = state->row_out2nd[1].fac*state->row_out2nd[1].v2 - v1 + famp; +- + v1 = state->col_out2nd[2].v2; + state->col_out2nd[2].v2 = state->col_out2nd[2].v3; + state->col_out2nd[2].v3 = state->col_out2nd[2].fac*state->col_out2nd[2].v2 - v1 + famp; + +- v1 = state->row_out2nd[2].v2; +- state->row_out2nd[2].v2 = state->row_out2nd[2].v3; +- state->row_out2nd[2].v3 = state->row_out2nd[2].fac*state->row_out2nd[2].v2 - v1 + famp; +- + v1 = state->col_out2nd[3].v2; + state->col_out2nd[3].v2 = state->col_out2nd[3].v3; + state->col_out2nd[3].v3 = state->col_out2nd[3].fac*state->col_out2nd[3].v2 - v1 + famp; + ++ v1 = state->row_out2nd[0].v2; ++ state->row_out2nd[0].v2 = state->row_out2nd[0].v3; ++ state->row_out2nd[0].v3 = state->row_out2nd[0].fac*state->row_out2nd[0].v2 - v1 + famp; ++ ++ v1 = state->row_out2nd[1].v2; ++ state->row_out2nd[1].v2 = state->row_out2nd[1].v3; ++ state->row_out2nd[1].v3 = state->row_out2nd[1].fac*state->row_out2nd[1].v2 - v1 + famp; ++ ++ v1 = state->row_out2nd[2].v2; ++ state->row_out2nd[2].v2 = state->row_out2nd[2].v3; ++ state->row_out2nd[2].v3 = state->row_out2nd[2].fac*state->row_out2nd[2].v2 - v1 + famp; ++ + v1 = state->row_out2nd[3].v2; + state->row_out2nd[3].v2 = state->row_out2nd[3].v3; + state->row_out2nd[3].v3 = state->row_out2nd[3].fac*state->row_out2nd[3].v2 - v1 + famp; +- ++#ifdef FAXDETECT + v1 = state->fax_tone.v2; + state->fax_tone.v2 = state->fax_tone.v3; + state->fax_tone.v3 = state->fax_tone.fac*state->fax_tone.v2 - v1 + famp; +@@ -263,13 +274,15 @@ + v1 = state->fax_tone.v2; + state->fax_tone2nd.v2 = state->fax_tone2nd.v3; + state->fax_tone2nd.v3 = state->fax_tone2nd.fac*state->fax_tone2nd.v2 - v1 + famp; ++#endif + } + state->current_sample += (limit - sample); + if(state->current_sample < 102) + continue; + ++#ifdef FAXDETECT + fax_energy = goertzelResult(&state->fax_tone); +- ++#endif + // We are at the end of a DTMF detection block + // Find the peak row and the peak column + row_energy[0] = goertzelResult (&state->row_out[0]); +@@ -332,6 +345,7 @@ + } + } + ++#ifdef FAXDETECT + if (!hit && (fax_energy >= FAX_THRESHOLD) && (fax_energy > state->energy * 21.0)) + { + fax_energy_2nd = goertzelResult(&state->fax_tone2nd); +@@ -356,6 +370,7 @@ + } + state->fax_hits = 0; + } ++#endif + state->hit1 = state->hit2; + state->hit2 = state->hit3; + state->hit3 = hit; +diff -NurBb src/fixedPoint.C patched_src/fixedPoint.C +--- ccaudio2-0.9.0/src/fixedPoint.C 1970-01-01 01:00:00.000000000 +0100 ++++ ccaudio2-0.9.0/patched_src/fixedPoint.C 2006-04-22 14:13:26.000000000 +0200 +@@ -0,0 +1,145 @@ ++#include "fixedPoint.H" ++ ++#include ++ ++#define TABLESIZE (1<(q))); ++} ++ ++static FixedPoint cosGenerator(int x) { ++ FixedPoint q(2 * x * 3.14156); ++ q /= NUMPOINTS; ++ return FixedPoint(cos(static_cast(q))); ++} ++ ++static FixedPoint sinGeneratorSmall(int x) { ++ FixedPoint q(2 * x * 3.14156); ++ q /= NUMPOINTS * NUMPOINTS; ++ return FixedPoint(sin(static_cast(q))); ++} ++ ++void FixedPoint::generateTables() { ++ int i; ++ std::cout << "unsigned short sinL[] = { 0"; ++ for (i=1; i(v) >> RES_BITS) & 3; ++ ++ // handle sin(alpha) as sin(large+small) with large+small=alpha ++ // large is here 0-NUMPOINTS, small is (alpha-large) scaled to NUMPOINTS ++ int large = static_cast(v) & (TABLESIZE-1); ++ int small = v.getNKS()>>(FixedPoint::decimalPlaces - RES_BITS); ++ ++ // calculate sin for first quadrant ++ FixedPoint r; ++ // assuming coshelper2(small) == 1 ++ if ( q&1 ) { ++ r = coshelper(large)-sinhelper(large)*sinhelperSmall(small); ++ } else { ++ r = sinhelper(large)+sinhelperSmall(small)*coshelper(large); ++ } ++ ++ if ( q>1 ) ++ r.negate(); ++ ++ return r; ++} ++ ++FixedPoint ++cos(const FixedPoint& v) { ++ // scaled to use NUMPOINTS==(1<(v) >> RES_BITS) & 3; ++ ++ // handle sin(alpha) as sin(large+small) with large+small=alpha ++ // large is here 0-NUMPOINTS, small is (alpha-large) scaled to NUMPOINTS ++ int large = static_cast(v) & (TABLESIZE-1); ++ int small = v.getNKS()>>(FixedPoint::decimalPlaces - RES_BITS); ++ ++ // calculate sin for first quadrant ++ FixedPoint r; ++ // assuming coshelper2(small) == 1 ++ if ( q&1 ) { ++ r = sinhelper(large)+sinhelperSmall(small)*coshelper(large); ++ } else { ++ r = coshelper(large)-sinhelper(large)*sinhelperSmall(small); ++ } ++ ++ if ( q==1 || q==2 ) ++ r.negate(); ++ ++ return r; ++} +diff -NurBb src/fixedPoint.H patched_src/fixedPoint.H +--- ccaudio2-0.9.0/src/fixedPoint.H 1970-01-01 01:00:00.000000000 +0100 ++++ ccaudio2-0.9.0/patched_src/fixedPoint.H 2006-04-22 14:13:26.000000000 +0200 +@@ -0,0 +1,239 @@ ++#ifndef FIXEDPOINT__H__ ++#define FIXEDPOINT__H__ ++ ++#include ++ ++#define longlong ++ ++const int RES_BITS = 7; ++const int NUMPOINTS = (1<<(RES_BITS+2)); ++ ++const int FP_PI_TRIG = (1<<(RES_BITS+1)); // use this as pi in trig functions ++ ++class FixedPoint; ++static inline int prepareMultiply(FixedPoint& r, FixedPoint&f); ++static inline void check_overflow(const FixedPoint&a, const FixedPoint&b); ++ ++class FixedPoint { ++public: ++#ifdef longlong ++ typedef long long _fp; ++#else ++ typedef long _fp; ++#endif ++ ++ FixedPoint() { value=0; } ++ FixedPoint(int v) { value = static_cast<_fp>(v) << decimalPlaces; } ++ FixedPoint(unsigned int v) { value = static_cast<_fp>(v) << decimalPlaces; } ++ FixedPoint(double v) { value = static_cast<_fp>(v * (1 << decimalPlaces)); } ++ FixedPoint(float v) { value = static_cast<_fp>(v * (1 << decimalPlaces)); } ++ FixedPoint(const FixedPoint& a) { value = a.value; } ++ FixedPoint(int ganz, int komma) { value = (static_cast<_fp>(ganz)<> decimalPlaces; } ++ operator int() const { return value >> decimalPlaces; } // this conversion can overflow!! ++ operator double() const { return (double)value / (1<>= shift; ++ ++ return r; ++ } ++ ++ void operator*=(const FixedPoint& b) ++ { ++ FixedPoint f(b); ++ ++ // shift r.value and f.value so, that no overrun occurs ++ int shift = prepareMultiply(*this, f); ++ check_overflow(*this, f); ++ ++ value *= f.value; ++ ++ // shift away nks ++ value >>= shift; ++ } ++ ++#endif ++ friend FixedPoint operator*(const FixedPoint& a, int v) ++ { FixedPoint r(a); r.value *= v; return r; } ++ friend FixedPoint operator*(int v, const FixedPoint& b) ++ { FixedPoint r(b); r.value *= v; return r; } ++ void operator*=(int v) ++ { value *= v; } ++ ++#ifdef longlong ++ friend FixedPoint operator/(const FixedPoint& a, const FixedPoint& b) ++ { FixedPoint r(a); r.value<<=decimalPlaces; r.value /= b.value; return r; } ++ void operator/=(const FixedPoint& a) ++ { value<<=decimalPlaces; value /= a.value; } ++#else ++ friend FixedPoint operator/(const FixedPoint& a, const FixedPoint& b) ++ { ++ FixedPoint r; ++ long long v = a.value; ++ v <<= decimalPlaces; ++ v /= b.value; ++ r.value = v; ++ return r; ++ } ++ void operator/=(const FixedPoint& a) ++ { ++ long long v = value; ++ v <<= decimalPlaces; ++ v /= a.value; ++ value = v; ++ } ++#endif ++ friend FixedPoint operator/(const FixedPoint& a, int v) ++ { FixedPoint r(a); r.value /= v; return r; } ++ void operator/=(int v) ++ { value /= v; } ++ ++ friend FixedPoint operator+(const FixedPoint& a, const FixedPoint& b) ++ { FixedPoint r(a); r.value += b.value; return r; } ++ friend FixedPoint operator+(const FixedPoint& a, int v) ++ { FixedPoint r(a); r.value += v<(const FixedPoint& a, const FixedPoint& b) ++ { return a.value > b.value; } ++ friend bool operator>(const FixedPoint& a, int v) ++ { return a.value > (v << decimalPlaces) ; } ++ friend bool operator>(int v, const FixedPoint& b) ++ { return (v << decimalPlaces )> b.value; } ++ ++ friend bool operator>=(const FixedPoint& a, const FixedPoint& b) ++ { return a.value >= b.value; } ++ friend bool operator<=(const FixedPoint& a, const FixedPoint& b) ++ { return a.value <= b.value; } ++ friend bool operator>=(const FixedPoint& a, int v) ++ { return a.value >= ( v << decimalPlaces ); } ++ friend bool operator>=(int v, const FixedPoint& b) ++ { return ( v << decimalPlaces ) >= b.value; } ++ friend bool operator<=(const FixedPoint& a, int v) ++ { return a.value <= ( v << decimalPlaces ); } ++ friend bool operator<=(int v, const FixedPoint& b) ++ { return ( v << decimalPlaces ) <= b.value; } ++ ++ friend std::ostream& operator<<(std::ostream& os, FixedPoint f) ++ { ++ return os << (double)f << " [" << std::hex << (_fp)f << "#" << f.getNKS() << std::dec << "]"; ++ } ++ ++ friend FixedPoint sin(const FixedPoint& v); ++ friend FixedPoint cos(const FixedPoint& v); ++ ++ unsigned int getNKS() const { return value & ((1<>=1; ++ } ++ } else { ++ first=0x4000000000000000LL; ++ while ( shift>=1; ++ } ++ } ++ if ( f.value < 0 ) { ++ first=0x4000000000000000LL; ++ while ( shift>=1; ++ } ++ } else { ++ first=0x4000000000000000LL; ++ while ( shift>=1; ++ } ++ } ++ ++ if ( shift>= donow/2; ++ f.value >>= donow-(donow/2); ++ } ++ return shift; ++} ++ ++void check_overflow(const FixedPoint&a, const FixedPoint&b) { ++ if ( a<0 && b<0 || (a>0 && b>0) ) { ++ if ( a.value * b.value < 0 ) ++ std::cerr << " overflow1: " << a << " * " << b << "=" << a.value*b.value << std::endl; ++ } else if ( a.value * b.value > 0 ) ++ std::cerr << " overflow2: " << a << " * " << b << "=" << a.value*b.value << std::endl; ++} ++ ++#endif /* FIXEDPOINT__H__ */ +diff -NurBb src/Makefile.am patched_src/Makefile.am +--- ccaudio2-0.9.0/src/Makefile.am 2006-03-01 17:43:29.000000000 +0100 ++++ ccaudio2-0.9.0/patched_src/Makefile.am 2006-04-22 14:13:25.000000000 +0200 +@@ -14,12 +14,13 @@ + RELEASE = -version-info @LT_VERSION@ -release @LT_RELEASE@ + ccxxincludedir=$(includedir)/cc++ + ccxxinclude_HEADERS = audio2.h ++AM_CXXFLAGS=-msoft-float + + lib_LTLIBRARIES = libccaudio2.la + + libccaudio2_la_SOURCES = audiofile.cpp friends.cpp codec.cpp tone.cpp \ + fileio.cpp buffer.cpp stream.cpp oss.cpp w32.cpp osx.cpp \ +- mapper.cpp dialers.cpp teltones.cpp detect.cpp audiobase.cpp ++ mapper.cpp dialers.cpp teltones.cpp detect.cpp audiobase.cpp fixedPoint.C + + libccaudio2_la_LDFLAGS = $(DYN_LOADER) $(AUDIO_LIBS) -lm $(RELEASE) + +diff -NurBb src/tone.cpp patched_src/tone.cpp +--- ccaudio2-0.9.0/src/tone.cpp 2006-03-01 16:51:13.000000000 +0100 ++++ ccaudio2-0.9.0/patched_src/tone.cpp 2006-04-22 14:13:25.000000000 +0200 +@@ -37,12 +37,15 @@ + + #include "private.h" + #include "audio2.h" +-#include ++#include "fixedPoint.H" + + #ifndef M_PI + #define M_PI 3.14159265358979323846 + #endif + ++#undef M_PI ++#define M_PI FP_PI_TRIG ++ + using namespace ost; + + AudioTone::AudioTone(timeout_t duration, Rate r) +@@ -59,8 +62,8 @@ + AudioTone::AudioTone(unsigned freq, Level l, timeout_t duration, Rate r) + { + rate = r; +- df1 = (freq * M_PI * 2) / (long)rate; +- df2 = (freq * M_PI * 2) / (long)rate; ++ df1 = FixedPoint(freq * M_PI * 2) / (int)rate; ++ df2 = FixedPoint(freq * M_PI * 2) / (int)rate; + p1 = 0, p2 = 0; + samples = (duration * (long)rate) / 1000; + m1 = l / 2; +@@ -73,8 +76,8 @@ + AudioTone::AudioTone(unsigned f1, unsigned f2, Level l1, Level l2, timeout_t duration, Rate r) + { + rate = r; +- df1 = (f1 * M_PI * 2) / (long)r; +- df2 = (f2 * M_PI * 2) / (long)r; ++ df1 = FixedPoint(f1 * M_PI * 2) / (int)r; ++ df2 = FixedPoint(f2 * M_PI * 2) / (int)r; + p1 = 0, p2 = 0; + samples = (duration * (long)r) / 1000; + m1 = l1 / 2; +@@ -124,8 +127,8 @@ + + void AudioTone::single(unsigned freq, Level l) + { +- df1 = (freq * M_PI * 2) / (long)rate; +- df2 = (freq * M_PI * 2) / (long)rate; ++ df1 = FixedPoint(freq * M_PI * 2) / (int)rate; ++ df2 = FixedPoint(freq * M_PI * 2) / (int)rate; + m1 = l / 2; + m2 = l / 2; + silencer = false; +@@ -133,8 +136,8 @@ + + void AudioTone::dual(unsigned f1, unsigned f2, Level l1, Level l2) + { +- df1 = (f1 * M_PI * 2) / (long)rate; +- df2 = (f2 * M_PI * 2) / (long)rate; ++ df1 = FixedPoint(f1 * M_PI * 2) / (int)rate; ++ df2 = FixedPoint(f2 * M_PI * 2) / (int)rate; + m1 = l1 / 2; + m2 = l2 / 2; + silencer = false; +@@ -188,8 +191,8 @@ + continue; + } + +- *(data++) = (Level)(sin(p1) * (double)m1) + +- (Level)(sin(p2) * (double)m2); ++ *(data++) = (Level)(int)(sin(p1) * m1) + ++ (Level)(int)(sin(p2) * m2); + + p1 += df1; + p2 += df2; +@@ -199,8 +202,8 @@ + { + while(count--) + { +- *(data++) = (Level)(sin(p1) * (double)m1) + +- (Level)(sin(p2) * (double)m2); ++ *(data++) = (Level)(int)(sin(p1) * m1) + ++ (Level)(int)(sin(p2) * m2); + + p1 += df1; + p2 += df2; diff --git a/packages/libccaudio2/libccaudio2-0.9.0/02-ccaudio-stereo.diff b/packages/libccaudio2/libccaudio2-0.9.0/02-ccaudio-stereo.diff new file mode 100644 index 0000000000..1643fd8d1c --- /dev/null +++ b/packages/libccaudio2/libccaudio2-0.9.0/02-ccaudio-stereo.diff @@ -0,0 +1,54 @@ +diff -NurBb ccaudio2-0.9.0/src/detect.cpp /tmp/ccaudiosrc/detect.cpp +--- ccaudio2-0.9.0/src/detect.cpp 2006-05-02 02:20:18.000000000 +0200 ++++ tmp/ccaudiosrc/detect.cpp 2006-05-02 02:17:27.000000000 +0200 +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + #ifdef HAVE_STDINT_H + #include +@@ -198,7 +199,7 @@ + // time of a rolled loop on the machine on which it was developed + for(j = sample; j < limit; j++) + { +- famp = amp[j]; ++ famp = amp[2*j+1]; + state->energy += famp*famp; + + // With GCC 2.95, the following unrolled code seems to take about 35% +diff -NurBb ccaudio2-0.9.0/src/oss.cpp /tmp/ccaudiosrc/oss.cpp +--- ccaudio2-0.9.0/src/oss.cpp 2006-03-30 00:17:28.000000000 +0200 ++++ tmp/ccaudiosrc/oss.cpp 2006-05-02 02:17:27.000000000 +0200 +@@ -39,7 +39,7 @@ + #include "audio2.h" + #include + #include +- ++#include + extern int _oss_ccaudio_dummy; + int _oss_ccaudio_dummy = 0; + +@@ -183,6 +183,10 @@ + + if(ioctl(dsp, SOUND_PCM_WRITE_RATE, &srate)) + return false; ++ if ( srate == 0 ) { ++ std::cerr << "ossSetAudio: invalid rate " << rate << std::endl; ++ return false; ++ } + + if(ioctl(dsp, SOUND_PCM_WRITE_CHANNELS, &channels)) + return false; +@@ -192,7 +196,10 @@ + ioctl(dsp, SNDCTL_DSP_GETBLKSIZE, &blksize); + info.framesize = blksize; + info.framecount = toSamples(info.encoding, blksize); ++ if ( srate ) + info.framing = (info.framecount * 1000l) / srate; ++ else ++ info.framing = (info.framecount * 500l); + + bufsize = info.framecount * channels; + diff --git a/packages/libccaudio2/libccaudio2-0.9.0/03-ccaudio-dtmf-reset.diff b/packages/libccaudio2/libccaudio2-0.9.0/03-ccaudio-dtmf-reset.diff new file mode 100644 index 0000000000..955de275a0 --- /dev/null +++ b/packages/libccaudio2/libccaudio2-0.9.0/03-ccaudio-dtmf-reset.diff @@ -0,0 +1,36 @@ +diff -NurbB ccaudio2-0.9.0/src/audio2.h ccaudio2-0.9.0.patched/src/audio2.h +--- ccaudio2-0.9.0/src/audio2.h 2006-05-03 14:44:12.000000000 +0200 ++++ ccaudio2-0.9.0.patched/src/audio2.h 2006-06-09 11:03:24.000000000 +0200 +@@ -1957,6 +1957,8 @@ + */ + inline bool isEnabled(void) + {return enabled;}; ++ ++ virtual void reset(void) {} + }; + + /** +diff -NurbB ccaudio2-0.9.0/src/detect.cpp ccaudio2-0.9.0.patched/src/detect.cpp +--- ccaudio2-0.9.0/src/detect.cpp 2006-05-03 14:44:12.000000000 +0200 ++++ ccaudio2-0.9.0.patched/src/detect.cpp 2006-06-09 12:36:30.000000000 +0200 +@@ -316,7 +316,7 @@ + } + // ... and second harmonic test + if(i >= 4 && +- (row_energy[best_row] + col_energy[best_col]) > 42.0*state->energy && ++ (row_energy[best_row] + col_energy[best_col]) > 37.0*state->energy && + goertzelResult (&state->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col] && + goertzelResult (&state->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row]) + { +diff -NurbB ccaudio2-0.9.0/src/oss.cpp ccaudio2-0.9.0.patched/src/oss.cpp +--- ccaudio2-0.9.0/src/oss.cpp 2006-06-08 14:53:27.000000000 +0200 ++++ ccaudio2-0.9.0.patched/src/oss.cpp 2006-06-08 20:07:30.000000000 +0200 +@@ -75,6 +75,8 @@ + void resetRecord(void); + void enableRecord(void); + void disableRecord(void); ++ void reset(void) { ioctl(dsp, SNDCTL_DSP_RESET, NULL); } ++ + }; + + OSSAudioDevice::OSSAudioDevice(int fdsp, int fmixer, DeviceMode mode) diff --git a/packages/libccaudio2/libccaudio2_0.9.0.bb b/packages/libccaudio2/libccaudio2_0.9.0.bb new file mode 100644 index 0000000000..1cfb715764 --- /dev/null +++ b/packages/libccaudio2/libccaudio2_0.9.0.bb @@ -0,0 +1,24 @@ +DESCRIPTION = "a C++ class library for generating and recognising sounds." +HOMEPAGE = "http://www.gnu.org/software/ccaudio/" +LICENSE = "GPL" +MAINTAINER = "Martin Dietze , Thomas Geffert " + +SRC_URI = "http://ftp.gnu.org/pub/gnu/ccaudio/ccaudio2-${PV}.tar.gz \ + file://01-ccaudio-fixed-point.diff;patch=1 \ + file://02-ccaudio-stereo.diff;patch=1 \ + file://03-ccaudio-dtmf-reset.diff;patch=1" + +FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/libccaudio2-${PV}" + +S = "${WORKDIR}/ccaudio2-${PV}" + +inherit autotools + +${EXTRA_OECONF}="-without-fp" + +do_stage () { + install -d ${STAGING_INCDIR}/cc++ + install -m 0644 src/audio2.h ${STAGING_INCDIR}/cc++ + install -m 0644 src/fixedPoint.H ${STAGING_INCDIR}/cc++ + oe_libinstall -C src libccaudio2 ${STAGING_LIBDIR} +} -- cgit v1.2.3 From ec33e91e3b1ec6a9845742879834893c4cda9764 Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 12:45:12 +0000 Subject: libpcre: added new port. --- packages/libpcre/.mtn2git_empty | 0 packages/libpcre/libpcre-native_4.4.bb | 4 ++++ packages/libpcre/libpcre_4.4.bb | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 packages/libpcre/.mtn2git_empty create mode 100644 packages/libpcre/libpcre-native_4.4.bb create mode 100644 packages/libpcre/libpcre_4.4.bb diff --git a/packages/libpcre/.mtn2git_empty b/packages/libpcre/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/libpcre/libpcre-native_4.4.bb b/packages/libpcre/libpcre-native_4.4.bb new file mode 100644 index 0000000000..7caddc321d --- /dev/null +++ b/packages/libpcre/libpcre-native_4.4.bb @@ -0,0 +1,4 @@ +SECTION = "unknown" +include libpcre_${PV}.bb +inherit native +FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/libpcre-${PV}" diff --git a/packages/libpcre/libpcre_4.4.bb b/packages/libpcre/libpcre_4.4.bb new file mode 100644 index 0000000000..9974e85806 --- /dev/null +++ b/packages/libpcre/libpcre_4.4.bb @@ -0,0 +1,33 @@ +DESCRIPTION = "Perl-compatible regular expression library. PCRE has its own native \ +API, but a set of 'wrapper' functions that are based on the POSIX API \ +are also supplied in the library libpcreposix. Note that this just \ +provides a POSIX calling interface to PCRE; the regular expressions \ +themselves still follow Perl syntax and semantics. The header file for \ +the POSIX-style functions is called pcreposix.h." +SECTION = "devel" +PR = "r1" + +SRC_URI = "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-${PV}.tar.bz2" +S = "${WORKDIR}/pcre-${PV}" + +inherit autotools binconfig + +LEAD_SONAME = "libpcre.so" +CFLAGS_append = " -D_REENTRANT" +EXTRA_OECONF = " --with-link-size=2 --enable-newline-is-lf --with-match-limit=10000000" + +do_compile () { + ${BUILD_CC} -DLINK_SIZE=2 -I${S}/include -c dftables.c + ${BUILD_CC} dftables.o -o dftables + oe_runmake +} + +do_stage () { + oe_libinstall -a -so libpcreposix ${STAGING_LIBDIR} + oe_libinstall -a -so libpcre ${STAGING_LIBDIR} + install -m 0644 pcre.h ${STAGING_INCDIR}/ + install -m 0644 pcreposix.h ${STAGING_INCDIR}/ +} + +FILES_${PN} = "${libdir}/lib*.so*" +FILES_${PN}-dev += "${bindir}" -- cgit v1.2.3 From abf168554971b3e714dd2ee2bbebf18ab91121e9 Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 12:48:50 +0000 Subject: pcre: removed accidentally added package --- packages/pcre/.mtn2git_empty | 0 packages/pcre/pcre-native_4.4.bb | 4 ---- packages/pcre/pcre_4.4.bb | 41 ---------------------------------------- 3 files changed, 45 deletions(-) delete mode 100644 packages/pcre/.mtn2git_empty delete mode 100644 packages/pcre/pcre-native_4.4.bb delete mode 100644 packages/pcre/pcre_4.4.bb diff --git a/packages/pcre/.mtn2git_empty b/packages/pcre/.mtn2git_empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/pcre/pcre-native_4.4.bb b/packages/pcre/pcre-native_4.4.bb deleted file mode 100644 index ba2645c5d3..0000000000 --- a/packages/pcre/pcre-native_4.4.bb +++ /dev/null @@ -1,4 +0,0 @@ -SECTION = "unknown" -require pcre_${PV}.bb -inherit native -FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/pcre-${PV}" diff --git a/packages/pcre/pcre_4.4.bb b/packages/pcre/pcre_4.4.bb deleted file mode 100644 index 7603e11537..0000000000 --- a/packages/pcre/pcre_4.4.bb +++ /dev/null @@ -1,41 +0,0 @@ -DESCRIPTION = "Perl-compatible regular expression library. PCRE has its own native \ -API, but a set of 'wrapper' functions that are based on the POSIX API \ -are also supplied in the library libpcreposix. Note that this just \ -provides a POSIX calling interface to PCRE; the regular expressions \ -themselves still follow Perl syntax and semantics. The header file for \ -the POSIX-style functions is called pcreposix.h." -SECTION = "devel" -PR = "r6" -LICENSE = "BSD" -SRC_URI = "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-${PV}.tar.bz2" -S = "${WORKDIR}/pcre-${PV}" - -inherit autotools binconfig - -PARALLEL_MAKE="" - -LEAD_SONAME = "libpcre.so" -CFLAGS_append = " -D_REENTRANT" -EXTRA_OECONF = " --with-link-size=2 --enable-newline-is-lf --with-match-limit=10000000" - -do_compile () { - # stop libtool from trying to link with host libraries - fix from #33 - # this resolve build problem on amd64 - #1015 - sed -i 's:-L\$:-L${STAGING_LIBDIR} -L\$:' ${S}/${TARGET_SYS}-libtool - - # The generation of dftables can lead to timestamp problems with ccache - # because the generated config.h seems newer. It is sufficient to ensure that the - # attempt to build dftables inside make will actually work (foo_FOR_BUILD is - # only used for this). - oe_runmake CC_FOR_BUILD="${BUILD_CC}" CFLAGS_FOR_BUILD="-DLINK_SIZE=2 -I${S}/include" LINK_FOR_BUILD="${BUILD_CC}" -} - -do_stage () { - oe_libinstall -a -so libpcre ${STAGING_LIBDIR} - oe_libinstall -a -so libpcreposix ${STAGING_LIBDIR} - install -m 0644 pcre.h ${STAGING_INCDIR}/ - install -m 0644 pcreposix.h ${STAGING_INCDIR}/ -} - -FILES_${PN} = "${libdir}/lib*.so*" -FILES_${PN}-dev += "${bindir}/*" -- cgit v1.2.3 From 30596c3e0a0216faaaa5b1ffaa4bd0e2c816eb21 Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 12:52:43 +0000 Subject: nylon: updated images and nylon specific packages from 4G trunk * updated list of supported packages in nylon-feed * new image nylon-image-extended aiming to put nylon-feed into one image (for debugging) * new versions of nylon-scripts, nylon-statistics, simple-firewall --- packages/images/nylon-image-base.bb | 8 +- packages/images/nylon-image-extended.bb | 85 +++++++++++++++++++++ packages/images/nylon-image-extra.bb | 4 +- packages/images/nylon-image-standard.bb | 2 +- packages/meta/nylon-feed.bb | 128 +++++++++----------------------- packages/meta/nylon-feed.inc | 68 +++++++++++++++++ packages/nylon/nylon-scripts_cvs.bb | 14 ++-- packages/nylon/nylon-statistics.bb | 7 +- packages/nylon/simple-firewall.bb | 5 +- packages/nylon/yamonenv.bb | 3 +- 10 files changed, 214 insertions(+), 110 deletions(-) create mode 100644 packages/images/nylon-image-extended.bb create mode 100644 packages/meta/nylon-feed.inc diff --git a/packages/images/nylon-image-base.bb b/packages/images/nylon-image-base.bb index a4f6d17dd8..4e7711e6c7 100644 --- a/packages/images/nylon-image-base.bb +++ b/packages/images/nylon-image-base.bb @@ -1,3 +1,6 @@ +inherit image_ipk nylon-image +LICENSE = MIT + export IMAGE_BASENAME = "nylon-base" NYLON_BASE = "base-files base-passwd bash busybox \ @@ -7,8 +10,8 @@ NYLON_BASE = "base-files base-passwd bash busybox \ openssh sysvinit \ timezones tinylogin" -DEPENDS = "virtual/kernel" -RDEPENDS = "kernel modutils-depmod modutils-modinfo \ +DEPENDS += "virtual/kernel less nano" +RDEPENDS = "kernel modutils-depmod modutils-modinfo less nano \ ${NYLON_BASE} ${BOOTSTRAP_EXTRA_RDEPENDS}" export IPKG_INSTALL = "${RDEPENDS}" @@ -19,4 +22,3 @@ IMAGE_LINGUAS = "" ROOTFS_POSTPROCESS_COMMAND = "rm -f ${IMAGE_ROOTFS}/tmp/zImage*" inherit image_ipk nylon-image -LICENSE = MIT diff --git a/packages/images/nylon-image-extended.bb b/packages/images/nylon-image-extended.bb new file mode 100644 index 0000000000..09ec4897f6 --- /dev/null +++ b/packages/images/nylon-image-extended.bb @@ -0,0 +1,85 @@ +LICENSE = MIT +require nylon-image-base.bb +require ../meta/nylon-feed.inc + +export IMAGE_BASENAME = "nylon-extended" + +NYLON_EXTENDED_DEPENDS = "${NYLON_FEED}" + +NYLON_EXTENDED_RDEPENDS = "\ + hostap-modules-cs \ + hostap-modules-pci \ + modutils-depmod \ + modutils-initscripts \ + modutils-modinfo \ + ntpdate \ + ntp-bin \ + ntp-tickadj \ + openssh-scp \ + openssh-ssh \ + openssh-sshd \ + perl-misc \ + perl-module-autoloader \ + perl-module-base \ + perl-module-bytes \ + perl-module-carp \ + perl-module-config \ + perl-module-constant \ + perl-module-data-dumper \ + perl-module-encode \ + perl-module-encode-alias \ + perl-module-encode-config \ + perl-module-encode-encoding \ + perl-module-encode-unicode \ + perl-module-errno \ + perl-module-exporter \ + perl-module-exporter-heavy \ + perl-module-fields \ + perl-module-getopt-long \ + perl-module-integer \ + perl-module-io \ + perl-module-io-handle \ + perl-module-io-socket \ + perl-module-io-socket-inet \ + perl-module-io-socket-unix \ + perl-module-locale \ + perl-module-overload \ + perl-module-posix \ + perl-module-selectsaver \ + perl-module-socket \ + perl-module-strict \ + perl-module-symbol \ + perl-module-sys-hostname \ + perl-module-vars \ + perl-module-warnings \ + perl-module-warnings-register \ + perl-module-xsloader \ +" + +KERNEL_MODULES = " \ + kernel-module-aes \ + kernel-module-bridge \ + kernel-module-ds \ + kernel-module-fat \ + kernel-module-mii \ + kernel-module-pcmcia-core \ + kernel-module-scsi-mod \ + kernel-module-sd-mod \ + kernel-module-usb-storage \ + kernel-module-usb-ohci \ + kernel-module-usbnet \ + kernel-module-usbserial \ + kernel-module-vfat \ + kernel-module-yenta-socket \ +" + + +DEPENDS += "${NYLON_EXTENDED_DEPENDS}" + +RDEPENDS += "${NYLON_EXTENDED_DEPENDS} ${KERNEL_MODULES} ${NYLON_EXTENDED_RDEPENDS}" + +RDEPENDS_append_mtx-1 = "\ + kernel-module-au1x00-bi \ + kernel-module-network-fd \ + kernel-module-usbdcore" + kernel-module-usbdprocfs \ diff --git a/packages/images/nylon-image-extra.bb b/packages/images/nylon-image-extra.bb index 194783af7e..e825b15e69 100644 --- a/packages/images/nylon-image-extra.bb +++ b/packages/images/nylon-image-extra.bb @@ -1,3 +1,5 @@ +LICENSE = MIT + require nylon-image-standard.bb export IMAGE_BASENAME = "nylon-extra" @@ -7,5 +9,3 @@ RDEPENDS = "\ netperf \ nylon-statistics \ openvpn" - -LICENSE = MIT diff --git a/packages/images/nylon-image-standard.bb b/packages/images/nylon-image-standard.bb index d7acf29142..c3c98ceca4 100644 --- a/packages/images/nylon-image-standard.bb +++ b/packages/images/nylon-image-standard.bb @@ -1,3 +1,4 @@ +LICENSE = MIT require nylon-image-base.bb export IMAGE_BASENAME = "nylon-standard" @@ -26,4 +27,3 @@ DEPENDS += "hostap-modules ntp \ RDEPENDS += "hostap-modules-pci ntpdate \ ${NYLON_STANDARD}" -LICENSE = MIT diff --git a/packages/meta/nylon-feed.bb b/packages/meta/nylon-feed.bb index f5b803f58e..40faab8056 100644 --- a/packages/meta/nylon-feed.bb +++ b/packages/meta/nylon-feed.bb @@ -1,99 +1,43 @@ -DEPENDS = " \ -base-files \ -bash \ -bridge-utils \ -busybox \ -chillispot \ -dash \ -db3 \ -ddclient \ -dhcp-forwarder \ -dhcp \ -dnsmasq \ -expat \ -gdb \ -glib-2.0 \ -glibc \ -gmp \ -gnupg \ -hostap-modules \ -hostap-utils \ -hostap-daemon \ -linux-hotplug \ -htb-init \ -ifplugd \ -initscripts \ -iperf \ -ipkg \ -iproute2 \ -iptables \ -virtual/kernel \ -kismet \ -less \ -libcgicc \ -libmail-sendmail-perl \ -libnetserver-generic-perl \ -libpcap \ -lsof \ -lzo \ -madwifi-modules \ -maradns \ -mc \ -mobilemesh \ -modutils \ -mtd-utils \ -mtr \ -nano \ -ncurses \ -netbase \ -netperf \ -net-snmp \ -ntp \ -nylon-scripts \ -nylon-statistics \ -olsrd \ -openssh \ -openssl \ -openvpn \ -openswan \ -pciutils \ -pcre \ -perl \ -pmacct \ -ppp \ -ppp-dsl \ -rp-pppoe \ -rrdtool \ -prism2-firmware-update \ -prism54-module \ -prism54-firmware \ -shorewall \ -stunnel \ -sysvinit \ -tcpdump \ -tinc \ -timezones \ -usbutils \ -vtun \ -wireless-tools \ -wlan-ng-modules \ -yamonenv \ -zlib \ -" +LICENSE = MIT -# TODO: -# ksymoops / binutils -# strace: SYS_read? -# gdb-cross: install paths, sdk? -# screen: sgttyb? -# nocat? -# pptp -# meshroaming +include nylon-feed.inc +DEPENDS = "${NYLON_FEED} \ + db3 \ + dhcp \ + dhcp-forwarder \ + expat \ + glib-2.0 \ + glibc \ + gmp \ + hotplug \ + iproute2 \ + libcgicc \ + libedit \ + libmail-sendmail-perl \ + libnetserver-generic-perl \ + lzo \ + make \ + mystun-server \ + mc \ + net-snmp \ + ntp \ + openssl \ + openswan \ + openvpn \ + pcre \ + ppp-dsl \ + rp-pppoe \ + simple-firewall \ + thttpd \ + vsftpd \ + wget \ + wlan-ng-modules \ + zlib \ +" do_index() { - ipkg-make-index -r ${DEPLOY_DIR_IPK}/Packages -p ${DEPLOY_DIR_IPK}/Packages -l ${DEPLOY_DIR_IPK}/Packages.filelist -m ${DEPLOY_DIR_IPK} + ipkg-make-index -r ${DEPLOY_DIR_IPK}/Packages -p ${DEPLOY_DIR_IPK}/Packages -l ${DEPLOY_DIR_IPK}/Packages.filelist -m ${DEPLOY_DIR_IPK} } addtask index before do_build after do_install -LICENSE = MIT diff --git a/packages/meta/nylon-feed.inc b/packages/meta/nylon-feed.inc new file mode 100644 index 0000000000..f2e55dc3a6 --- /dev/null +++ b/packages/meta/nylon-feed.inc @@ -0,0 +1,68 @@ +NYLON_FEED = " \ +base-files \ +bash \ +binutils \ +bridge-utils \ +busybox \ +chillispot \ +dash \ +ddclient \ +dnsmasq \ +gdb \ +gnupg \ +hostap-modules \ +hostap-utils \ +hostap-daemon \ +hotplug-ng \ +htb-init \ +ifplugd \ +initscripts \ +iperf \ +ipkg \ +iptables \ +kismet \ +ksymoops \ +less \ +lsof \ +madwifi-modules \ +maradns \ +minicom \ +mobilemesh \ +modutils \ +mtd-utils \ +mtr \ +nano \ +ncurses \ +netbase \ +netperf \ +nylon-scripts \ +nylon-statistics \ +olsrd \ +openssh \ +pciutils \ +pcmcia-cs \ +perl \ +pmacct \ +ppp \ +pptp-linux \ +rrdtool \ +ser \ +shorewall \ +stunnel \ +sysvinit \ +tcl \ +tcpdump \ +tinc \ +timezones \ +usbutils \ +vtun \ +wireless-tools \ +wpa-supplicant \ +yamonenv \ +" + +# TODO: +# strace: SYS_read? +# gdb-cross: install paths, sdk? +# screen: sgttyb? + diff --git a/packages/nylon/nylon-scripts_cvs.bb b/packages/nylon/nylon-scripts_cvs.bb index b7ce512e87..e4917d310f 100644 --- a/packages/nylon/nylon-scripts_cvs.bb +++ b/packages/nylon/nylon-scripts_cvs.bb @@ -5,14 +5,17 @@ SECTION = "base" PRIORITY = "optional" MAINTAINER = "Bruno Randolf " LICENSE = "GPLv2" -PV = "1:0.0+cvs${SRCDATE}" +SRCDATE = "20060114" +PV = "1.0.0+cvs${SRCDATE}" PR = "r2" +RDEPENDS = "bash" SRC_URI = "http://meshcube.org/download/${PN}_${SRCDATE}.tgz" S = "${WORKDIR}/${PN}" INHIBIT_PACKAGE_STRIP = "1" do_install() { + install -d -m 755 ${D} (cd ${S}; tar -c --exclude .svn -f - . ) | tar -C ${D} -xpf - } @@ -21,8 +24,8 @@ if test "x$D" != "x"; then exit 1 else update-rc.d -s hostap defaults 14 - update-rc.d -s firewall defaults 20 - update-rc.d -s routing defaults 20 + update-rc.d -s firewall defaults 16 + update-rc.d -s routing defaults 17 update-rc.d -s emergency-ip defaults 98 update-rc.d -s flash-backup start 38 S . stop 38 0 6 . update-rc.d -s dummydate start 50 S . stop 50 0 6 . @@ -46,8 +49,6 @@ fi pkg_postrm() { #!/bin/sh -e update-rc.d hostap remove -update-rc.d bridge remove -update-rc.d ipaliases remove update-rc.d firewall remove update-rc.d routing remove update-rc.d emergency-ip remove @@ -55,4 +56,5 @@ update-rc.d flash-backup remove update-rc.d dummydate remove } -CONFFILES_${PN} = "/etc/nylon/backup.list /etc/nylon/hostap.conf /etc/nylon/interfaces.conf /etc/nylon/route.list" +CONFFILES_${PN} = "/etc/nylon/backup.list /etc/nylon/hostap.conf /etc/nylon/check-process.list \ + /etc/nylon/interfaces.conf /etc/nylon/route.list /etc/nylon/wds-bridge.conf" diff --git a/packages/nylon/nylon-statistics.bb b/packages/nylon/nylon-statistics.bb index e24d9c93e8..21c588e78a 100644 --- a/packages/nylon/nylon-statistics.bb +++ b/packages/nylon/nylon-statistics.bb @@ -4,7 +4,8 @@ SECTION = "base" PRIORITY = "optional" MAINTAINER = "Bruno Randolf " LICENSE = "GPLv2" -PV = "1:0.0+cvs${SRCDATE}" +SRCDATE = "20050909" +PV = "1.0.0+cvs${SRCDATE}" PR = "r1" SRC_URI = "http://meshcube.org/download/${PN}_${SRCDATE}.tgz" @@ -13,11 +14,11 @@ INHIBIT_PACKAGE_STRIP = "1" do_install() { install -d ${D}/srv/www/cgi-bin - install -d ${D}${sbindir} + install -d ${D}/${sbindir} ln -s /var/tmp ${D}/srv/www/rrd-img install -m 755 ${S}/*.html ${D}/srv/www/cgi-bin ln -s /var/tmp/nav.inc.html ${D}/srv/www/cgi-bin - install -m 755 ${S}/collect.sh ${D}${sbindir} + install -m 755 ${S}/collect.sh ${D}/${sbindir} } pkg_postinst() { diff --git a/packages/nylon/simple-firewall.bb b/packages/nylon/simple-firewall.bb index 5698eb732a..35911dad2c 100644 --- a/packages/nylon/simple-firewall.bb +++ b/packages/nylon/simple-firewall.bb @@ -4,8 +4,9 @@ PRIORITY = "optional" MAINTAINER = "Bruno Randolf " LICENSE = "GPL" DEPENDS = "virtual/kernel" -SRCDATE = "20060114" -PV = "cvs${SRCDATE}" +SRCDATE = "20060810" +PV = "cvs${CVSDATE}" + INHIBIT_PACKAGE_STRIP = "1" diff --git a/packages/nylon/yamonenv.bb b/packages/nylon/yamonenv.bb index bf4c94200e..2c2fb3cbb7 100644 --- a/packages/nylon/yamonenv.bb +++ b/packages/nylon/yamonenv.bb @@ -3,7 +3,8 @@ SECTION = "base" PRIORITY = "optional" MAINTAINER = "Michael Stickel " LICENSE = "GPL" -PV = "1:0.0+cvs${SRCDATE}" +SRCDATE = "20050909" +PV = "1.0.0+cvs${SRCDATE}" SRC_URI = "http://meshcube.org/download/${PN}_${SRCDATE}.tgz" S = "${WORKDIR}/${PN}" -- cgit v1.2.3 From 7328a81a6b73ff6224184576d21c68af9bcad4b4 Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 12:56:35 +0000 Subject: initscripts: adaptions necessary for use with nylon on 4G access cube. * mtx-2 hardware added * the mount command for the local file systems did not work with tmpfs * checkroot did not remount / rw --- .../initscripts-1.0/mtx-1/.mtn2git_empty | 0 .../initscripts/initscripts-1.0/mtx-1/checkroot.sh | 167 +++++++++++++++++++++ .../initscripts/initscripts-1.0/mtx-1/mountall.sh | 46 ++++++ .../initscripts-1.0/mtx-2/.mtn2git_empty | 0 .../initscripts/initscripts-1.0/mtx-2/checkroot.sh | 167 +++++++++++++++++++++ .../initscripts/initscripts-1.0/mtx-2/mountall.sh | 46 ++++++ 6 files changed, 426 insertions(+) create mode 100644 packages/initscripts/initscripts-1.0/mtx-1/.mtn2git_empty create mode 100755 packages/initscripts/initscripts-1.0/mtx-1/checkroot.sh create mode 100755 packages/initscripts/initscripts-1.0/mtx-1/mountall.sh create mode 100644 packages/initscripts/initscripts-1.0/mtx-2/.mtn2git_empty create mode 100755 packages/initscripts/initscripts-1.0/mtx-2/checkroot.sh create mode 100755 packages/initscripts/initscripts-1.0/mtx-2/mountall.sh diff --git a/packages/initscripts/initscripts-1.0/mtx-1/.mtn2git_empty b/packages/initscripts/initscripts-1.0/mtx-1/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/initscripts/initscripts-1.0/mtx-1/checkroot.sh b/packages/initscripts/initscripts-1.0/mtx-1/checkroot.sh new file mode 100755 index 0000000000..e8ae039650 --- /dev/null +++ b/packages/initscripts/initscripts-1.0/mtx-1/checkroot.sh @@ -0,0 +1,167 @@ +# +# checkroot.sh Check to root filesystem. +# +# Version: @(#)checkroot.sh 2.84 25-Jan-2002 miquels@cistron.nl +# + +. /etc/default/rcS + +# +# Set SULOGIN in /etc/default/rcS to yes if you want a sulogin to be spawned +# from this script *before anything else* with a timeout, like SCO does. +# +test "$SULOGIN" = yes && sulogin -t 30 $CONSOLE + +# +# Ensure that bdflush (update) is running before any major I/O is +# performed (the following fsck is a good example of such activity :). +# +test -x /sbin/update && update + +# +# Read /etc/fstab. +# +exec 9>&0 &9 9>&- + +# +# Activate the swap device(s) in /etc/fstab. This needs to be done +# before fsck, since fsck can be quite memory-hungry. +# +doswap=no +test -d /proc/1 || mount -n /proc +case "`uname -r`" in + 2.[0123].*) + if test $swap_on_md = yes && grep -qs resync /proc/mdstat + then + test "$VERBOSE" != no && echo "Not activating swap - RAID array resyncing" + else + doswap=yes + fi + ;; + *) + doswap=yes + ;; +esac +if test $doswap = yes +then + test "$VERBOSE" != no && echo "Activating swap" + swapon -a 2> /dev/null +fi + +# +# Check the root filesystem. +# +if test -f /fastboot || test $rootcheck = no +then + test $rootcheck = yes && echo "Fast boot, no filesystem check" +else + # + # Ensure that root is quiescent and read-only before fsck'ing. + # + mount -n -o remount,ro / + if test $? = 0 + then + if test -f /forcefsck + then + force="-f" + else + force="" + fi + if test "$FSCKFIX" = yes + then + fix="-y" + else + fix="-a" + fi + spinner="-C" + case "$TERM" in + dumb|network|unknown|"") spinner="" ;; + esac + test `uname -m` = s390 && spinner="" # This should go away + test "$VERBOSE" != no && echo "Checking root filesystem..." + fsck $spinner $force $fix / + # + # If there was a failure, drop into single-user mode. + # + # NOTE: "failure" is defined as exiting with a return code of + # 2 or larger. A return code of 1 indicates that filesystem + # errors were corrected but that the boot may proceed. + # + if test "$?" -gt 1 + then + # Surprise! Re-directing from a HERE document (as in + # "cat << EOF") won't work, because the root is read-only. + echo + echo "fsck failed. Please repair manually and reboot. Please note" + echo "that the root filesystem is currently mounted read-only. To" + echo "remount it read-write:" + echo + echo " # mount -n -o remount,rw /" + echo + echo "CONTROL-D will exit from this shell and REBOOT the system." + echo + # Start a single user shell on the console + /sbin/sulogin $CONSOLE + reboot -f + fi + else + echo "*** ERROR! Cannot fsck root fs because it is not mounted read-only!" + echo + fi +fi + +# +# If the root filesystem was not marked as read-only in /etc/fstab, +# remount the rootfs rw but do not try to change mtab because it +# is on a ro fs until the remount succeeded. Then clean up old mtabs +# and finally write the new mtab. +# This part is only needed if the rootfs was mounted ro. +# +echo "Remounting root file system..." +mount -n -o remount,$rootmode / +if test "$rootmode" = rw +then + if test ! -L /etc/mtab + then + rm -f /etc/mtab~ /etc/nologin + : > /etc/mtab + fi + mount -f -o remount / + mount -f /proc + test "$devfs" && grep -q '^devfs /dev' /proc/mounts && mount -f "$devfs" +fi + +: exit 0 diff --git a/packages/initscripts/initscripts-1.0/mtx-1/mountall.sh b/packages/initscripts/initscripts-1.0/mtx-1/mountall.sh new file mode 100755 index 0000000000..4d12c06254 --- /dev/null +++ b/packages/initscripts/initscripts-1.0/mtx-1/mountall.sh @@ -0,0 +1,46 @@ +# +# mountall.sh Mount all filesystems. +# +# Version: @(#)mountall.sh 2.83-2 01-Nov-2001 miquels@cistron.nl +# +. /etc/default/rcS + +# +# Mount local filesystems in /etc/fstab. For some reason, people +# might want to mount "proc" several times, and mount -v complains +# about this. So we mount "proc" filesystems without -v. +# +test "$VERBOSE" != no && echo "Mounting local filesystems..." +mount -a 2>/dev/null +#t nonfs,nosmbfs,noncpfs 2>/dev/null + +# +# We might have mounted something over /dev, see if /dev/initctl is there. +# +if test ! -p /dev/initctl +then + rm -f /dev/initctl + mknod -m 600 /dev/initctl p +fi +kill -USR1 1 + +# +# Execute swapon command again, in case we want to swap to +# a file on a now mounted filesystem. +# +doswap=yes +case "`uname -r`" in + 2.[0123].*) + if grep -qs resync /proc/mdstat + then + doswap=no + fi + ;; +esac +if test $doswap = yes +then + swapon -a 2> /dev/null +fi + +: exit 0 + diff --git a/packages/initscripts/initscripts-1.0/mtx-2/.mtn2git_empty b/packages/initscripts/initscripts-1.0/mtx-2/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/initscripts/initscripts-1.0/mtx-2/checkroot.sh b/packages/initscripts/initscripts-1.0/mtx-2/checkroot.sh new file mode 100755 index 0000000000..e8ae039650 --- /dev/null +++ b/packages/initscripts/initscripts-1.0/mtx-2/checkroot.sh @@ -0,0 +1,167 @@ +# +# checkroot.sh Check to root filesystem. +# +# Version: @(#)checkroot.sh 2.84 25-Jan-2002 miquels@cistron.nl +# + +. /etc/default/rcS + +# +# Set SULOGIN in /etc/default/rcS to yes if you want a sulogin to be spawned +# from this script *before anything else* with a timeout, like SCO does. +# +test "$SULOGIN" = yes && sulogin -t 30 $CONSOLE + +# +# Ensure that bdflush (update) is running before any major I/O is +# performed (the following fsck is a good example of such activity :). +# +test -x /sbin/update && update + +# +# Read /etc/fstab. +# +exec 9>&0 &9 9>&- + +# +# Activate the swap device(s) in /etc/fstab. This needs to be done +# before fsck, since fsck can be quite memory-hungry. +# +doswap=no +test -d /proc/1 || mount -n /proc +case "`uname -r`" in + 2.[0123].*) + if test $swap_on_md = yes && grep -qs resync /proc/mdstat + then + test "$VERBOSE" != no && echo "Not activating swap - RAID array resyncing" + else + doswap=yes + fi + ;; + *) + doswap=yes + ;; +esac +if test $doswap = yes +then + test "$VERBOSE" != no && echo "Activating swap" + swapon -a 2> /dev/null +fi + +# +# Check the root filesystem. +# +if test -f /fastboot || test $rootcheck = no +then + test $rootcheck = yes && echo "Fast boot, no filesystem check" +else + # + # Ensure that root is quiescent and read-only before fsck'ing. + # + mount -n -o remount,ro / + if test $? = 0 + then + if test -f /forcefsck + then + force="-f" + else + force="" + fi + if test "$FSCKFIX" = yes + then + fix="-y" + else + fix="-a" + fi + spinner="-C" + case "$TERM" in + dumb|network|unknown|"") spinner="" ;; + esac + test `uname -m` = s390 && spinner="" # This should go away + test "$VERBOSE" != no && echo "Checking root filesystem..." + fsck $spinner $force $fix / + # + # If there was a failure, drop into single-user mode. + # + # NOTE: "failure" is defined as exiting with a return code of + # 2 or larger. A return code of 1 indicates that filesystem + # errors were corrected but that the boot may proceed. + # + if test "$?" -gt 1 + then + # Surprise! Re-directing from a HERE document (as in + # "cat << EOF") won't work, because the root is read-only. + echo + echo "fsck failed. Please repair manually and reboot. Please note" + echo "that the root filesystem is currently mounted read-only. To" + echo "remount it read-write:" + echo + echo " # mount -n -o remount,rw /" + echo + echo "CONTROL-D will exit from this shell and REBOOT the system." + echo + # Start a single user shell on the console + /sbin/sulogin $CONSOLE + reboot -f + fi + else + echo "*** ERROR! Cannot fsck root fs because it is not mounted read-only!" + echo + fi +fi + +# +# If the root filesystem was not marked as read-only in /etc/fstab, +# remount the rootfs rw but do not try to change mtab because it +# is on a ro fs until the remount succeeded. Then clean up old mtabs +# and finally write the new mtab. +# This part is only needed if the rootfs was mounted ro. +# +echo "Remounting root file system..." +mount -n -o remount,$rootmode / +if test "$rootmode" = rw +then + if test ! -L /etc/mtab + then + rm -f /etc/mtab~ /etc/nologin + : > /etc/mtab + fi + mount -f -o remount / + mount -f /proc + test "$devfs" && grep -q '^devfs /dev' /proc/mounts && mount -f "$devfs" +fi + +: exit 0 diff --git a/packages/initscripts/initscripts-1.0/mtx-2/mountall.sh b/packages/initscripts/initscripts-1.0/mtx-2/mountall.sh new file mode 100755 index 0000000000..4d12c06254 --- /dev/null +++ b/packages/initscripts/initscripts-1.0/mtx-2/mountall.sh @@ -0,0 +1,46 @@ +# +# mountall.sh Mount all filesystems. +# +# Version: @(#)mountall.sh 2.83-2 01-Nov-2001 miquels@cistron.nl +# +. /etc/default/rcS + +# +# Mount local filesystems in /etc/fstab. For some reason, people +# might want to mount "proc" several times, and mount -v complains +# about this. So we mount "proc" filesystems without -v. +# +test "$VERBOSE" != no && echo "Mounting local filesystems..." +mount -a 2>/dev/null +#t nonfs,nosmbfs,noncpfs 2>/dev/null + +# +# We might have mounted something over /dev, see if /dev/initctl is there. +# +if test ! -p /dev/initctl +then + rm -f /dev/initctl + mknod -m 600 /dev/initctl p +fi +kill -USR1 1 + +# +# Execute swapon command again, in case we want to swap to +# a file on a now mounted filesystem. +# +doswap=yes +case "`uname -r`" in + 2.[0123].*) + if grep -qs resync /proc/mdstat + then + doswap=no + fi + ;; +esac +if test $doswap = yes +then + swapon -a 2> /dev/null +fi + +: exit 0 + -- cgit v1.2.3 From 21d5affb846356fd486b06656835164f0b29324e Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 13:02:49 +0000 Subject: various packages: added mtx-2 configuration * where necessary, additional mtx-2 subdirs for files created * where necessary, additional entries in bitbake files created --- .../base-files/base-files/mtx-2/.mtn2git_empty | 0 packages/base-files/base-files/mtx-2/fstab | 8 + packages/base-files/base-files/mtx-2/profile | 25 ++ .../kismet/kismet-2004-04-R1/mtx-2/.mtn2git_empty | 0 .../kismet/kismet-2004-04-R1/mtx-2/kismet.conf | 328 ++++++++++++++++ packages/kismet/kismet_2004-04-R1.bb | 1 + packages/modutils/files/mtx-2/.mtn2git_empty | 0 packages/modutils/files/mtx-2/modules | 3 + packages/net-snmp/files/mtx-2/.mtn2git_empty | 0 packages/net-snmp/files/mtx-2/snmpd.conf | 434 +++++++++++++++++++++ packages/netbase/netbase/mtx-2/.mtn2git_empty | 0 packages/netbase/netbase/mtx-2/interfaces | 29 ++ packages/wpa-supplicant/files/mtx-2/.mtn2git_empty | 0 packages/wpa-supplicant/files/mtx-2/defconfig | 157 ++++++++ packages/wpa-supplicant/wpa-supplicant_0.3.8.bb | 1 + packages/wpa-supplicant/wpa-supplicant_0.4.7.bb | 1 + 16 files changed, 987 insertions(+) create mode 100644 packages/base-files/base-files/mtx-2/.mtn2git_empty create mode 100644 packages/base-files/base-files/mtx-2/fstab create mode 100644 packages/base-files/base-files/mtx-2/profile create mode 100644 packages/kismet/kismet-2004-04-R1/mtx-2/.mtn2git_empty create mode 100644 packages/kismet/kismet-2004-04-R1/mtx-2/kismet.conf create mode 100644 packages/modutils/files/mtx-2/.mtn2git_empty create mode 100644 packages/modutils/files/mtx-2/modules create mode 100644 packages/net-snmp/files/mtx-2/.mtn2git_empty create mode 100644 packages/net-snmp/files/mtx-2/snmpd.conf create mode 100644 packages/netbase/netbase/mtx-2/.mtn2git_empty create mode 100644 packages/netbase/netbase/mtx-2/interfaces create mode 100644 packages/wpa-supplicant/files/mtx-2/.mtn2git_empty create mode 100644 packages/wpa-supplicant/files/mtx-2/defconfig diff --git a/packages/base-files/base-files/mtx-2/.mtn2git_empty b/packages/base-files/base-files/mtx-2/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/base-files/base-files/mtx-2/fstab b/packages/base-files/base-files/mtx-2/fstab new file mode 100644 index 0000000000..f6f23ac2aa --- /dev/null +++ b/packages/base-files/base-files/mtx-2/fstab @@ -0,0 +1,8 @@ +# /etc/fstab: static file system information. mtx-2 +# +# +rootfs / auto defaults 1 1 +tmpfs /var tmpfs size=10m 0 0 +proc /proc proc defaults 0 0 +devpts /dev/pts devpts mode=0620,gid=5 0 0 +usbdevfs /proc/bus/usb usbdevfs noauto 0 0 diff --git a/packages/base-files/base-files/mtx-2/profile b/packages/base-files/base-files/mtx-2/profile new file mode 100644 index 0000000000..bedf2fc7d8 --- /dev/null +++ b/packages/base-files/base-files/mtx-2/profile @@ -0,0 +1,25 @@ +# /etc/profile: system-wide .profile file for the Bourne shell (sh(1)) +# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...). + +PATH="/usr/local/bin:/usr/bin:/bin" + +if [ "`id -u`" -eq 0 ]; then + PATH=$PATH:/usr/local/sbin:/usr/sbin:/sbin: +fi +if [ "$PS1" ]; then +# works for bash and ash (no other shells known to be in use here) + PS1='\u@\h:\w\$ ' +fi + +if [ -d /etc/profile.d ]; then + for i in `ls /etc/profile.d/`; do + . /etc/profile.d/$i + done + unset i +fi + +export PATH PS1 + +umask 022 + +alias ll="ls -lah" \ No newline at end of file diff --git a/packages/kismet/kismet-2004-04-R1/mtx-2/.mtn2git_empty b/packages/kismet/kismet-2004-04-R1/mtx-2/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/kismet/kismet-2004-04-R1/mtx-2/kismet.conf b/packages/kismet/kismet-2004-04-R1/mtx-2/kismet.conf new file mode 100644 index 0000000000..233aec378a --- /dev/null +++ b/packages/kismet/kismet-2004-04-R1/mtx-2/kismet.conf @@ -0,0 +1,328 @@ +# Kismet config file +# Most of the "static" configs have been moved to here -- the command line +# config was getting way too crowded and cryptic. We want functionality, +# not continually reading --help! + +# Version of Kismet config +version=2004.03.devel.a + +# Name of server (Purely for organiational purposes) +servername=Kismet + +# User to setid to (should be your normal user) +suiduser=your_user_here + +# Sources are defined as: +# source=cardtype,interface,name[,initialchannel] +# Card types and required drivers are listed in the README. +# The initial channel is optional, if hopping is not enabled it can be used +# to set the channel the interface listens on. +source=hostap,wlan0,wlan0 +source=hostap,wlan1,wlan1 +# Other common source configs: +# source=prism2,wlan0,prism2source +# source=prism2_avs,wlan0,newprism2source +# source=orinoco,eth0,orinocosource +# An example source line with an initial channel: +# source=orinoco,eth0,silver,11 + +# Comma-separated list of sources to enable. This is only needed if you defined +# multiple sources and only want to enable some of them. By default, all defined +# sources are enabled. +# For example: +# enablesources=prismsource,ciscosource + +# Do we channelhop? +channelhop=true + +# How many channels per second do we hop? (1-10) +channelvelocity=5 + +# By setting the dwell time for channel hopping we override the channelvelocity +# setting above and dwell on each channel for the given number of seconds. +#channeldwell=10 + +# Do we split channels between cards on the same spectrum? This means if +# multiple 802.11b capture sources are defined, they will be offset to cover +# the most possible spectrum at a given time. This also controls splitting +# fine-tuned sourcechannels lines which cover multiple interfaces (see below) +channelsplit=true + +# Basic channel hopping control: +# These define the channels the cards hop through for various frequency ranges +# supported by Kismet. More finegrain control is available via the +# "sourcechannels" configuration option. +# +# Don't change the IEEE80211 identifiers or channel hopping won't work. + +# Users outside the US might want to use this list: +# defaultchannels=IEEE80211b:1,7,13,2,8,3,14,9,4,10,5,11,6,12 +defaultchannels=IEEE80211b:1,6,11,2,7,3,8,4,9,5,10 + +# 802.11g uses the same channels as 802.11b... +defaultchannels=IEEE80211g:1,6,11,2,7,3,8,4,9,5,10 + +# 802.11a channels are non-overlapping so sequential is fine. You may want to +# adjust the list depending on the channels your card actually supports. +# defaultchannels=IEEE80211a:36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,184,188,192,196,200,204,208,212,216 +defaultchannels=IEEE80211a:36,40,44,48,52,56,60,64 + +# Combo cards like Atheros use both 'a' and 'b/g' channels. Of course, you +# can also explicitly override a given source. You can use the script +# extras/listchan.pl to extract all the channels your card supports. +defaultchannels=IEEE80211ab:1,6,11,2,7,3,8,4,9,5,10,36,40,44,48,52,56,60,64 + +# Fine-tuning channel hopping control: +# The sourcechannels option can be used to set the channel hopping for +# specific interfaces, and to control what interfaces share a list of +# channels for split hopping. This can also be used to easily lock +# one card on a single channel while hopping with other cards. +# Any card without a sourcechannel definition will use the standard hopping +# list. +# sourcechannels=sourcename[,sourcename]:ch1,ch2,ch3,...chN + +# ie, for us channels on the source 'prism2source' (same as normal channel +# hopping behavior): +# sourcechannels=prism2source:1,6,11,2,7,3,8,4,9,5,10 + +# Given two capture sources, "prism2a" and "prism2b", we want prism2a to stay +# on channel 6 and prism2b to hop normally. By not setting a sourcechannels +# line for prism2b, it will use the standard hopping. +# sourcechannels=prism2a:6 + +# To assign the same custom hop channel to multiple sources, or to split the +# same custom hop channel over two sources (if splitchannels is true), list +# them all on the same sourcechannels line: +# sourcechannels=prism2a,prism2b,prism2c:1,6,11 + +# Port to serve GUI data +tcpport=2501 +# People allowed to connect, comma seperated IP addresses or network/mask +# blocks. Netmasks can be expressed as dotted quad (/255.255.255.0) or as +# numbers (/24) +allowedhosts=127.0.0.1 +# Maximum number of concurrent GUI's +maxclients=5 + +# Do we have a GPS? +gps=true +# Host:port that GPSD is running on. This can be localhost OR remote! +gpshost=localhost:2947 +# Do we lock the mode? This overrides coordinates of lock "0", which will +# generate some bad information until you get a GPS lock, but it will +# fix problems with GPS units with broken NMEA that report lock 0 +gpsmodelock=false + +# Packet filtering options: +# filter_tracker - Packets filtered from the tracker are not processed or +# recorded in any way. +# filter_dump - Packets filtered at the dump level are tracked, displayed, +# and written to the csv/xml/network/etc files, but not +# recorded in the packet dump +# filter_export - Controls what packets influence the exported CSV, network, +# xml, gps, etc files. +# All filtering options take arguments containing the type of address and +# addresses to be filtered. Valid address types are 'ANY', 'BSSID', +# 'SOURCE', and 'DEST'. Filtering can be inverted by the use of '!' before +# the address. For example, +# filter_tracker=ANY(!00:00:DE:AD:BE:EF) +# has the same effect as the previous mac_filter config file option. +# filter_tracker=... +# filter_dump=... +# filter_export=... + +# Alerts to be reported and the throttling rates. +# alert=name,throttle/unit,burst +# The throttle/unit describes the number of alerts of this type that are +# sent per time unit. Valid time units are second, minute, hour, and day. +# Burst describes the number of alerts sent before throttling takes place. +# For example: +# alert=FOO,10/min,5 +# Would allow 5 alerts through before throttling is enabled, and will then +# limit the number of alerts to 10 per minute. +# A throttle rate of 0 disables throttling of the alert. +# See the README for a list of alert types. +alert=NETSTUMBLER,5/min,2 +alert=WELLENREITER,5/min,2 +alert=LUCENTTEST,5/min,2 +alert=DEAUTHFLOOD,5/min,4 +alert=BCASTDISCON,5/min,4 +alert=CHANCHANGE,5/min,4 +alert=AIRJACKSSID,5/min,2 +alert=PROBENOJOIN,5/min,2 +alert=DISASSOCTRAFFIC,5/min,2 +alert=NULLPROBERESP,5/min,5 + +# Known WEP keys to decrypt, bssid,hexkey. This is only for networks where +# the keys are already known, and it may impact throughput on slower hardware. +# Multiple wepkey lines may be used for multiple BSSIDs. +# wepkey=00:DE:AD:C0:DE:00,FEEDFACEDEADBEEF01020304050607080900 + +# Is transmission of the keys to the client allowed? This may be a security +# risk for some. If you disable this, you will not be able to query keys from +# a client. +allowkeytransmit=true + +# How often (in seconds) do we write all our data files (0 to disable) +writeinterval=300 + +# Do we use sound? +# Not to be confused with GUI sound parameter, this controls wether or not the +# server itself will play sound. Primarily for headless or automated systems. +sound=false +# Path to sound player +soundplay=/usr/bin/play +# Optional parameters to pass to the player +# soundopts=--volume=.3 +# New network found +sound_new=/usr/share/kismet/wav/new_network.wav +# Wepped new network +# sound_new_wep=/usr/com/kismet/wav/new_wep_network.wav +# Network traffic sound +sound_traffic=/usr/share/kismet/wav/traffic.wav +# Network junk traffic found +sound_junktraffic=/usr/share/kismet/wav/junk_traffic.wav +# GPS lock aquired sound +# sound_gpslock=/usr/share/kismet/wav/foo.wav +# GPS lock lost sound +# sound_gpslost=/usr/share/kismet/wav/bar.wav +# Alert sound +sound_alert=/usr/share/kismet/wav/alert.wav + +# Does the server have speech? (Again, not to be confused with the GUI's speech) +speech=false +# Server's path to Festival +festival=/usr/bin/festival +# How do we speak? Valid options: +# speech Normal speech +# nato NATO spellings (alpha, bravo, charlie) +# spell Spell the letters out (aye, bee, sea) +speech_type=nato +# speech_encrypted and speech_unencrypted - Speech templates +# Similar to the logtemplate option, this lets you customize the speech output. +# speech_encrypted is used for an encrypted network spoken string +# speech_unencrypted is used for an unencrypted network spoken string +# +# %b is replaced by the BSSID (MAC) of the network +# %s is replaced by the SSID (name) of the network +# %c is replaced by the CHANNEL of the network +# %r is replaced by the MAX RATE of the network +speech_encrypted=New network detected, s.s.i.d. %s, channel %c, network encrypted. +speech_unencrypted=New network detected, s.s.i.d. %s, channel %c, network open. + +# Where do we get our manufacturer fingerprints from? Assumed to be in the +# default config directory if an absolute path is not given. +ap_manuf=ap_manuf +client_manuf=client_manuf + +# Use metric measurements in the output? +metric=false + +# Do we write waypoints for gpsdrive to load? Note: This is NOT related to +# recent versions of GPSDrive's native support of Kismet. +waypoints=false +# GPSMap waypoint file. This WILL be truncated. +waypointdata=%h/.gpsdrive/way_kismet.txt + +# How many alerts do we backlog for new clients? Only change this if you have +# a -very- low memory system and need those extra bytes, or if you have a high +# memory system and a huge number of alert conditions. +alertbacklog=50 + +# File types to log, comma seperated +# dump - raw packet dump +# network - plaintext detected networks +# csv - plaintext detected networks in CSV format +# xml - XML formatted network and cisco log +# weak - weak packets (in airsnort format) +# cisco - cisco equipment CDP broadcasts +# gps - gps coordinates +logtypes=dump,network,csv,xml,weak,cisco,gps + +# Do we track probe responses and merge probe networks into their owners? +# This isn't always desireable, depending on the type of monitoring you're +# trying to do. +trackprobenets=true + +# Do we log "noise" packets that we can't decipher? I tend to not, since +# they don't have anything interesting at all in them. +noiselog=false + +# Do we log corrupt packets? Corrupt packets have enough header information +# to see what they are, but someting is wrong with them that prevents us from +# completely dissecting them. Logging these is usually not a bad idea. +corruptlog=true + +# Do we log beacon packets or do we filter them out of the dumpfile +beaconlog=true + +# Do we log PHY layer packets or do we filter them out of the dumpfile +phylog=true + +# Do we mangle packets if we can decrypt them or if they're fuzzy-detected +mangledatalog=true + +# Do we do "fuzzy" crypt detection? (byte-based detection instead of 802.11 +# frame headers) +# valid option: Comma seperated list of card types to perform fuzzy detection +# on, or 'all' +fuzzycrypt=wtapfile,wlanng,wlanng_legacy,wlanng_avs,hostap,wlanng_wext + +# What type of dump do we generate? +# valid option: "wiretap" +dumptype=wiretap +# Do we limit the size of dump logs? Sometimes ethereal can't handle big ones. +# 0 = No limit +# Anything else = Max number of packets to log to a single file before closing +# and opening a new one. +dumplimit=0 + +# Do we write data packets to a FIFO for an external data-IDS (such as Snort)? +# See the docs before enabling this. +#fifo=/tmp/kismet_dump + +# Default log title +logdefault=Kismet + +# logtemplate - Filename logging template. +# This is, at first glance, really nasty and ugly, but you'll hardly ever +# have to touch it so don't complain too much. +# +# %n is replaced by the logging instance name +# %d is replaced by the current date as Mon-DD-YYYY +# %D is replaced by the current date as YYYYMMDD +# %t is replaced by the starting log time +# %i is replaced by the increment log in the case of multiple logs +# %l is replaced by the log type (dump, status, crypt, etc) +# %h is replaced by the home directory +# ie, "netlogs/%n-%d-%i.dump" called with a logging name of "Pok" could expand +# to something like "netlogs/Pok-Dec-20-01-1.dump" for the first instance and +# "netlogs/Pok-Dec-20-01-2.%l" for the second logfile generated. +# %h/netlots/%n-%d-%i.dump could expand to +# /home/foo/netlogs/Pok-Dec-20-01-2.dump +# +# Other possibilities: Sorting by directory +# logtemplate=%l/%n-%d-%i +# Would expand to, for example, +# dump/Pok-Dec-20-01-1 +# crypt/Pok-Dec-20-01-1 +# and so on. The "dump", "crypt", etc, dirs must exist before kismet is run +# in this case. +logtemplate=/tmp/%n-%d-%i.%l + +# Where do we store the pid file of the server? +piddir=/var/run/ + +# Where state info, etc, is stored. You shouldnt ever need to change this. +# This is a directory. +configdir=%h/.kismet/ + +# cloaked SSID file. You shouldn't ever need to change this. +ssidmap=ssid_map + +# Group map file. You shouldn't ever need to change this. +groupmap=group_map + +# IP range map file. You shouldn't ever need to change this. +ipmap=ip_map + diff --git a/packages/kismet/kismet_2004-04-R1.bb b/packages/kismet/kismet_2004-04-R1.bb index f1510f9e87..9c864a3f86 100644 --- a/packages/kismet/kismet_2004-04-R1.bb +++ b/packages/kismet/kismet_2004-04-R1.bb @@ -13,6 +13,7 @@ SRC_URI = "http://www.kismetwireless.net/code/kismet-2004-04-R1.tar.gz \ file://glibc3.3.2-getopt-throw.diff;patch=1;pnum=0" SRC_URI_append_mtx-1 = " file://kismet.conf" +SRC_URI_append_mtx-2 = " file://kismet.conf" EXTRA_OECONF = "--with-pcap=linux --disable-setuid" diff --git a/packages/modutils/files/mtx-2/.mtn2git_empty b/packages/modutils/files/mtx-2/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/modutils/files/mtx-2/modules b/packages/modutils/files/mtx-2/modules new file mode 100644 index 0000000000..3eb719acf9 --- /dev/null +++ b/packages/modutils/files/mtx-2/modules @@ -0,0 +1,3 @@ +tun +ppp_async +hostap_pci \ No newline at end of file diff --git a/packages/net-snmp/files/mtx-2/.mtn2git_empty b/packages/net-snmp/files/mtx-2/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/net-snmp/files/mtx-2/snmpd.conf b/packages/net-snmp/files/mtx-2/snmpd.conf new file mode 100644 index 0000000000..9067f68d22 --- /dev/null +++ b/packages/net-snmp/files/mtx-2/snmpd.conf @@ -0,0 +1,434 @@ +############################################################################### +# +# EXAMPLE.conf: +# An example configuration file for configuring the ucd-snmp snmpd agent. +# +############################################################################### +# +# This file is intended to only be an example. If, however, you want +# to use it, it should be placed in /etc/snmp/snmpd.conf. +# When the snmpd agent starts up, this is where it will look for it. +# +# You might be interested in generating your own snmpd.conf file using +# the "snmpconf" program (perl script) instead. It's a nice menu +# based interface to writing well commented configuration files. Try it! +# +# Note: This file is automatically generated from EXAMPLE.conf.def. +# Do NOT read the EXAMPLE.conf.def file! Instead, after you have run +# configure & make, and then make sure you read the EXAMPLE.conf file +# instead, as it will tailor itself to your configuration. + +# All lines beginning with a '#' are comments and are intended for you +# to read. All other lines are configuration commands for the agent. + +# +# PLEASE: read the snmpd.conf(5) manual page as well! +# + + +############################################################################### +# Access Control +############################################################################### + +# YOU SHOULD CHANGE THE "COMMUNITY" TOKEN BELOW TO A NEW KEYWORD ONLY +# KNOWN AT YOUR SITE. YOU *MUST* CHANGE THE NETWORK TOKEN BELOW TO +# SOMETHING REFLECTING YOUR LOCAL NETWORK ADDRESS SPACE. + +# By far, the most common question I get about the agent is "why won't +# it work?", when really it should be "how do I configure the agent to +# allow me to access it?" +# +# By default, the agent responds to the "public" community for read +# only access, if run out of the box without any configuration file in +# place. The following examples show you other ways of configuring +# the agent so that you can change the community names, and give +# yourself write access as well. +# +# The following lines change the access permissions of the agent so +# that the COMMUNITY string provides read-only access to your entire +# NETWORK (EG: 10.10.10.0/24), and read/write access to only the +# localhost (127.0.0.1, not its real ipaddress). +# +# For more information, read the FAQ as well as the snmpd.conf(5) +# manual page. + +#### +# First, map the community name (COMMUNITY) into a security name +# (local and mynetwork, depending on where the request is coming +# from): + +# sec.name source community +#com2sec paranoid default public +com2sec readonly default public +#com2sec readwrite default private + +#### +# Second, map the security names into group names: + +# sec.model sec.name +group MyROSystem v1 paranoid +group MyROSystem v2c paranoid +group MyROSystem usm paranoid +group MyROGroup v1 readonly +group MyROGroup v2c readonly +group MyROGroup usm readonly +group MyRWGroup v1 readwrite +group MyRWGroup v2c readwrite +group MyRWGroup usm readwrite + +#### +# Third, create a view for us to let the groups have rights to: + +# incl/excl subtree mask +view all included .1 80 +view system included .iso.org.dod.internet.mgmt.mib-2.system + +#### +# Finally, grant the 2 groups access to the 1 view with different +# write permissions: + +# context sec.model sec.level match read write notif +access MyROSystem "" any noauth exact system none none +access MyROGroup "" any noauth exact all none none +access MyRWGroup "" any noauth exact all all none + +# ----------------------------------------------------------------------------- + + +############################################################################### +# System contact information +# + +# It is also possible to set the sysContact and sysLocation system +# variables through the snmpd.conf file. **PLEASE NOTE** that setting +# the value of these objects here makes these objects READ-ONLY +# (regardless of any access control settings). Any attempt to set the +# value of an object whose value is given here will fail with an error +# status of notWritable. + +syslocation Unknown (configure /etc/snmp/snmpd.local.conf) +syscontact Root (configure /etc/snmp/snmpd.local.conf) + +# Example output of snmpwalk: +# % snmpwalk -v 1 -c public localhost system +# system.sysDescr.0 = "SunOS name sun4c" +# system.sysObjectID.0 = OID: enterprises.ucdavis.ucdSnmpAgent.sunos4 +# system.sysUpTime.0 = Timeticks: (595637548) 68 days, 22:32:55 +# system.sysContact.0 = "Me " +# system.sysName.0 = "name" +# system.sysLocation.0 = "Right here, right now." +# system.sysServices.0 = 72 + + +# ----------------------------------------------------------------------------- + + +############################################################################### +# Process checks. +# +# The following are examples of how to use the agent to check for +# processes running on the host. The syntax looks something like: +# +# proc NAME [MAX=0] [MIN=0] +# +# NAME: the name of the process to check for. It must match +# exactly (ie, http will not find httpd processes). +# MAX: the maximum number allowed to be running. Defaults to 0. +# MIN: the minimum number to be running. Defaults to 0. + +# +# Examples: +# + +# Make sure mountd is running +#proc mountd + +# Make sure there are no more than 4 ntalkds running, but 0 is ok too. +#proc ntalkd 4 + +# Make sure at least one sendmail, but less than or equal to 10 are running. +#proc sendmail 10 1 + +# A snmpwalk of the prTable would look something like this: +# +# % snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.2021.2 +# enterprises.ucdavis.procTable.prEntry.prIndex.1 = 1 +# enterprises.ucdavis.procTable.prEntry.prIndex.2 = 2 +# enterprises.ucdavis.procTable.prEntry.prIndex.3 = 3 +# enterprises.ucdavis.procTable.prEntry.prNames.1 = "mountd" +# enterprises.ucdavis.procTable.prEntry.prNames.2 = "ntalkd" +# enterprises.ucdavis.procTable.prEntry.prNames.3 = "sendmail" +# enterprises.ucdavis.procTable.prEntry.prMin.1 = 0 +# enterprises.ucdavis.procTable.prEntry.prMin.2 = 0 +# enterprises.ucdavis.procTable.prEntry.prMin.3 = 1 +# enterprises.ucdavis.procTable.prEntry.prMax.1 = 0 +# enterprises.ucdavis.procTable.prEntry.prMax.2 = 4 +# enterprises.ucdavis.procTable.prEntry.prMax.3 = 10 +# enterprises.ucdavis.procTable.prEntry.prCount.1 = 0 +# enterprises.ucdavis.procTable.prEntry.prCount.2 = 0 +# enterprises.ucdavis.procTable.prEntry.prCount.3 = 1 +# enterprises.ucdavis.procTable.prEntry.prErrorFlag.1 = 1 +# enterprises.ucdavis.procTable.prEntry.prErrorFlag.2 = 0 +# enterprises.ucdavis.procTable.prEntry.prErrorFlag.3 = 0 +# enterprises.ucdavis.procTable.prEntry.prErrMessage.1 = "No mountd process running." +# enterprises.ucdavis.procTable.prEntry.prErrMessage.2 = "" +# enterprises.ucdavis.procTable.prEntry.prErrMessage.3 = "" +# enterprises.ucdavis.procTable.prEntry.prErrFix.1 = 0 +# enterprises.ucdavis.procTable.prEntry.prErrFix.2 = 0 +# enterprises.ucdavis.procTable.prEntry.prErrFix.3 = 0 +# +# Note that the errorFlag for mountd is set to 1 because one is not +# running (in this case an rpc.mountd is, but thats not good enough), +# and the ErrMessage tells you what's wrong. The configuration +# imposed in the snmpd.conf file is also shown. +# +# Special Case: When the min and max numbers are both 0, it assumes +# you want a max of infinity and a min of 1. +# + + +# ----------------------------------------------------------------------------- + + +############################################################################### +# Executables/scripts +# + +# +# You can also have programs run by the agent that return a single +# line of output and an exit code. Here are two examples. +# +# exec NAME PROGRAM [ARGS ...] +# +# NAME: A generic name. +# PROGRAM: The program to run. Include the path! +# ARGS: optional arguments to be passed to the program + +# a simple hello world +#exec echotest /bin/echo hello world + +# Run a shell script containing: +# +# #!/bin/sh +# echo hello world +# echo hi there +# exit 35 +# +# Note: this has been specifically commented out to prevent +# accidental security holes due to someone else on your system writing +# a /tmp/shtest before you do. Uncomment to use it. +# +#exec shelltest /bin/sh /tmp/shtest + +# Then, +# % snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.2021.8 +# enterprises.ucdavis.extTable.extEntry.extIndex.1 = 1 +# enterprises.ucdavis.extTable.extEntry.extIndex.2 = 2 +# enterprises.ucdavis.extTable.extEntry.extNames.1 = "echotest" +# enterprises.ucdavis.extTable.extEntry.extNames.2 = "shelltest" +# enterprises.ucdavis.extTable.extEntry.extCommand.1 = "/bin/echo hello world" +# enterprises.ucdavis.extTable.extEntry.extCommand.2 = "/bin/sh /tmp/shtest" +# enterprises.ucdavis.extTable.extEntry.extResult.1 = 0 +# enterprises.ucdavis.extTable.extEntry.extResult.2 = 35 +# enterprises.ucdavis.extTable.extEntry.extOutput.1 = "hello world." +# enterprises.ucdavis.extTable.extEntry.extOutput.2 = "hello world." +# enterprises.ucdavis.extTable.extEntry.extErrFix.1 = 0 +# enterprises.ucdavis.extTable.extEntry.extErrFix.2 = 0 + +# Note that the second line of the /tmp/shtest shell script is cut +# off. Also note that the exit status of 35 was returned. + +# ----------------------------------------------------------------------------- + + +############################################################################### +# disk checks +# + +# The agent can check the amount of available disk space, and make +# sure it is above a set limit. + +# disk PATH [MIN=DEFDISKMINIMUMSPACE] +# +# PATH: mount path to the disk in question. +# MIN: Disks with space below this value will have the Mib's errorFlag set. +# Default value = DEFDISKMINIMUMSPACE. + +# Check the / partition and make sure it contains at least 10 megs. + +#disk / 10000 + +# % snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.2021.9 +# enterprises.ucdavis.diskTable.dskEntry.diskIndex.1 = 0 +# enterprises.ucdavis.diskTable.dskEntry.diskPath.1 = "/" Hex: 2F +# enterprises.ucdavis.diskTable.dskEntry.diskDevice.1 = "/dev/dsk/c201d6s0" +# enterprises.ucdavis.diskTable.dskEntry.diskMinimum.1 = 10000 +# enterprises.ucdavis.diskTable.dskEntry.diskTotal.1 = 837130 +# enterprises.ucdavis.diskTable.dskEntry.diskAvail.1 = 316325 +# enterprises.ucdavis.diskTable.dskEntry.diskUsed.1 = 437092 +# enterprises.ucdavis.diskTable.dskEntry.diskPercent.1 = 58 +# enterprises.ucdavis.diskTable.dskEntry.diskErrorFlag.1 = 0 +# enterprises.ucdavis.diskTable.dskEntry.diskErrorMsg.1 = "" + +# ----------------------------------------------------------------------------- + + +############################################################################### +# load average checks +# + +# load [1MAX=DEFMAXLOADAVE] [5MAX=DEFMAXLOADAVE] [15MAX=DEFMAXLOADAVE] +# +# 1MAX: If the 1 minute load average is above this limit at query +# time, the errorFlag will be set. +# 5MAX: Similar, but for 5 min average. +# 15MAX: Similar, but for 15 min average. + +# Check for loads: +#load 12 14 14 + +# % snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.2021.10 +# enterprises.ucdavis.loadTable.laEntry.loadaveIndex.1 = 1 +# enterprises.ucdavis.loadTable.laEntry.loadaveIndex.2 = 2 +# enterprises.ucdavis.loadTable.laEntry.loadaveIndex.3 = 3 +# enterprises.ucdavis.loadTable.laEntry.loadaveNames.1 = "Load-1" +# enterprises.ucdavis.loadTable.laEntry.loadaveNames.2 = "Load-5" +# enterprises.ucdavis.loadTable.laEntry.loadaveNames.3 = "Load-15" +# enterprises.ucdavis.loadTable.laEntry.loadaveLoad.1 = "0.49" Hex: 30 2E 34 39 +# enterprises.ucdavis.loadTable.laEntry.loadaveLoad.2 = "0.31" Hex: 30 2E 33 31 +# enterprises.ucdavis.loadTable.laEntry.loadaveLoad.3 = "0.26" Hex: 30 2E 32 36 +# enterprises.ucdavis.loadTable.laEntry.loadaveConfig.1 = "12.00" +# enterprises.ucdavis.loadTable.laEntry.loadaveConfig.2 = "14.00" +# enterprises.ucdavis.loadTable.laEntry.loadaveConfig.3 = "14.00" +# enterprises.ucdavis.loadTable.laEntry.loadaveErrorFlag.1 = 0 +# enterprises.ucdavis.loadTable.laEntry.loadaveErrorFlag.2 = 0 +# enterprises.ucdavis.loadTable.laEntry.loadaveErrorFlag.3 = 0 +# enterprises.ucdavis.loadTable.laEntry.loadaveErrMessage.1 = "" +# enterprises.ucdavis.loadTable.laEntry.loadaveErrMessage.2 = "" +# enterprises.ucdavis.loadTable.laEntry.loadaveErrMessage.3 = "" + +# ----------------------------------------------------------------------------- + + +############################################################################### +# Extensible sections. +# + +# This alleviates the multiple line output problem found in the +# previous executable mib by placing each mib in its own mib table: + +# Run a shell script containing: +# +# #!/bin/sh +# echo hello world +# echo hi there +# exit 35 +# +# Note: this has been specifically commented out to prevent +# accidental security holes due to someone else on your system writing +# a /tmp/shtest before you do. Uncomment to use it. +# +# exec .1.3.6.1.4.1.2021.50 shelltest /bin/sh /tmp/shtest + +# % snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.2021.50 +# enterprises.ucdavis.50.1.1 = 1 +# enterprises.ucdavis.50.2.1 = "shelltest" +# enterprises.ucdavis.50.3.1 = "/bin/sh /tmp/shtest" +# enterprises.ucdavis.50.100.1 = 35 +# enterprises.ucdavis.50.101.1 = "hello world." +# enterprises.ucdavis.50.101.2 = "hi there." +# enterprises.ucdavis.50.102.1 = 0 + +# Now the Output has grown to two lines, and we can see the 'hi +# there.' output as the second line from our shell script. +# +# Note that you must alter the mib.txt file to be correct if you want +# the .50.* outputs above to change to reasonable text descriptions. + +# Other ideas: +# +# exec .1.3.6.1.4.1.2021.51 ps /bin/ps +# exec .1.3.6.1.4.1.2021.52 top /usr/local/bin/top +# exec .1.3.6.1.4.1.2021.53 mailq /usr/bin/mailq + +# ----------------------------------------------------------------------------- + + +############################################################################### +# Pass through control. +# + +# Usage: +# pass MIBOID EXEC-COMMAND +# +# This will pass total control of the mib underneath the MIBOID +# portion of the mib to the EXEC-COMMAND. +# +# Note: You'll have to change the path of the passtest script to your +# source directory or install it in the given location. +# +# Example: (see the script for details) +# (commented out here since it requires that you place the +# script in the right location. (its not installed by default)) + +# pass .1.3.6.1.4.1.2021.255 /bin/sh /usr/local/passtest + +# % snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.2021.255 +# enterprises.ucdavis.255.1 = "life the universe and everything" +# enterprises.ucdavis.255.2.1 = 42 +# enterprises.ucdavis.255.2.2 = OID: 42.42.42 +# enterprises.ucdavis.255.3 = Timeticks: (363136200) 42 days, 0:42:42 +# enterprises.ucdavis.255.4 = IpAddress: 127.0.0.1 +# enterprises.ucdavis.255.5 = 42 +# enterprises.ucdavis.255.6 = Gauge: 42 +# +# % snmpget -v 1 -c public localhost .1.3.6.1.4.1.2021.255.5 +# enterprises.ucdavis.255.5 = 42 +# +# % snmpset -v 1 -c public localhost .1.3.6.1.4.1.2021.255.1 s "New string" +# enterprises.ucdavis.255.1 = "New string" +# + +# For specific usage information, see the man/snmpd.conf.5 manual page +# as well as the local/passtest script used in the above example. + +############################################################################### +# Subagent control +# + +# The agent can support subagents using a number of extension mechanisms. +# From the 4.2.1 release, AgentX support is being compiled in by default. +# However, this is still experimental code, so should not be used on +# critical production systems. +# Please see the file README.agentx for more details. +# +# If having read, marked, learnt and inwardly digested this information, +# you decide that you do wish to make use of this mechanism, simply +# uncomment the following directive. +# +# master agentx +# +# I repeat - this is *NOT* regarded as suitable for front-line production +# systems, though it is probably stable enough for day-to-day use. +# Probably. +# +# No refunds will be given. + +############################################################################### +# Further Information +# +# See the snmpd.conf manual page, and the output of "snmpd -H". +# MUCH more can be done with the snmpd.conf than is shown as an +# example here. + +############################################################################### +# interfaces + +# types: +# ieee80211(71) +# ethernetCsmacd(6), + +# interface name type speed +interface eth0 6 100000000 +interface wlan0 71 5000000 +interface wlan1 71 5000000 diff --git a/packages/netbase/netbase/mtx-2/.mtn2git_empty b/packages/netbase/netbase/mtx-2/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/netbase/netbase/mtx-2/interfaces b/packages/netbase/netbase/mtx-2/interfaces new file mode 100644 index 0000000000..a7c6da5752 --- /dev/null +++ b/packages/netbase/netbase/mtx-2/interfaces @@ -0,0 +1,29 @@ +# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8) + +# The loopback interface +auto lo +iface lo inet loopback + +# Ethernet +auto eth0 +iface eth0 inet dhcp + +# wlan interface 1 for clients +auto wlan0 +iface wlan0 inet static + address 10.0.0.1 + netmask 255.0.0.0 + wireless_mode master + wireless_essid cube-ap + wireless_channel 1 + +# wlan interface 2 for mesh +auto wlan1 +iface wlan1 inet static + address 172.16.0.1 + netmask 255.240.0.0 + broadcast 172.31.255.255 + wireless_mode ad-hoc + wireless_essid cube-mesh + wireless_channel 11 + wireless_rts 250 diff --git a/packages/wpa-supplicant/files/mtx-2/.mtn2git_empty b/packages/wpa-supplicant/files/mtx-2/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/wpa-supplicant/files/mtx-2/defconfig b/packages/wpa-supplicant/files/mtx-2/defconfig new file mode 100644 index 0000000000..a0d9b73d3f --- /dev/null +++ b/packages/wpa-supplicant/files/mtx-2/defconfig @@ -0,0 +1,157 @@ +# This file lists the configuration options that are used when building the +# hostapd binary. All lines starting with # are ignored. Configuration option +# lines must be commented out complete, if they are not to be included, i.e., +# just setting VARIABLE=n is not disabling that variable. +# +# This file is included in Makefile, so variables like CFLAGS and LIBS can also +# be modified from here. In most cass, these lines should use += in order not +# to override previous values of the variables. + +CFLAGS = $(TARGET_CFLAGS) -I../hostapd -I../utils -I../driver/modules -Wall -MMD + +# for wpa_supplicant, wpa_cli +LIBS = $(TARGET_LDFLAGS) + +# for wpa_passphrase: +LIBS_p = $(TARGET_LDFLAGS) + + +# Uncomment following two lines and fix the paths if you have installed openssl +# in non-default location +#CFLAGS += -I/usr/local/openssl/include +#LIBS += -L/usr/local/openssl/lib + +# Example configuration for various cross-compilation platforms + +#### sveasoft (e.g., for Linksys WRT54G) ###################################### +#CC=mipsel-uclibc-gcc +#CC=/opt/brcm/hndtools-mipsel-uclibc/bin/mipsel-uclibc-gcc +#CFLAGS += -Os +#CPPFLAGS += -I../src/include -I../../src/router/openssl/include +#LIBS += -L/opt/brcm/hndtools-mipsel-uclibc-0.9.19/lib -lssl +############################################################################### + +#### openwrt (e.g., for Linksys WRT54G) ####################################### +#CC=mipsel-uclibc-gcc +#CC=/opt/brcm/hndtools-mipsel-uclibc/bin/mipsel-uclibc-gcc +#CFLAGS += -Os +#CPPFLAGS=-I../src/include -I../openssl-0.9.7d/include \ +# -I../WRT54GS/release/src/include +#LIBS = -lssl +############################################################################### + + +# Driver interface for Host AP driver +CONFIG_DRIVER_HOSTAP=y + +# Driver interface for Agere driver +#CONFIG_DRIVER_HERMES=y + +# Driver interface for madwifi driver +CONFIG_DRIVER_MADWIFI=y +# Change include directories to match with the local setup +#CFLAGS += -I../madwifi/wpa + +# Driver interface for Prism54 driver +CONFIG_DRIVER_PRISM54=y + +# Driver interface for ndiswrapper +#CONFIG_DRIVER_NDISWRAPPER=y + +# Driver interface for Atmel driver +#CONFIG_DRIVER_ATMEL=y + +# Driver interface for Broadcom driver +#CONFIG_DRIVER_BROADCOM=y +# Example path for wlioctl.h; change to match your configuration +#CFLAGS += -I/opt/WRT54GS/release/src/include + +# Driver interface for Intel ipw2100 driver +#CONFIG_DRIVER_IPW2100=y + +# Driver interface for generic Linux wireless extensions +CONFIG_DRIVER_WEXT=y + +# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) +#CONFIG_DRIVER_BSD=y +#CFLAGS += -I/usr/local/include +#LIBS += -L/usr/local/lib + +# Driver interface for Windows NDIS +#CONFIG_DRIVER_NDIS=y +#CFLAGS += -I/usr/include/w32api/ddk +#LIBS += -L/usr/local/lib +# For native build using mingw +#CONFIG_NATIVE_WINDOWS=y +# Additional directories for cross-compilation on Linux host for mingw target +#CFLAGS += -I/opt/mingw/mingw32/include/ddk +#LIBS += -L/opt/mingw/mingw32/lib +#CC=mingw32-gcc + +# Driver interface for development testing +#CONFIG_DRIVER_TEST=y + +# Enable IEEE 802.1X Supplicant (automatically included if any EAP method is +# included) +CONFIG_IEEE8021X_EAPOL=y + +# EAP-MD5 (automatically included if EAP-TTLS is enabled) +CONFIG_EAP_MD5=y + +# EAP-MSCHAPv2 (automatically included if EAP-PEAP is enabled) +CONFIG_EAP_MSCHAPV2=y + +# EAP-TLS +CONFIG_EAP_TLS=y + +# EAL-PEAP +CONFIG_EAP_PEAP=y + +# EAP-TTLS +CONFIG_EAP_TTLS=y + +# EAP-GTC +CONFIG_EAP_GTC=y + +# EAP-OTP +CONFIG_EAP_OTP=y + +# EAP-SIM (enable CONFIG_PCSC, if EAP-SIM is used) +#CONFIG_EAP_SIM=y + +# EAP-PSK (experimental; this is _not_ needed for WPA-PSK) +#CONFIG_EAP_PSK=y + +# LEAP +CONFIG_EAP_LEAP=y + +# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used) +#CONFIG_EAP_AKA=y + +# PKCS#12 (PFX) support (used to read private key and certificate file from +# a file that usually has extension .p12 or .pfx) +CONFIG_PKCS12=y + +# PC/SC interface for smartcards (USIM, GSM SIM) +# Enable this if EAP-SIM or EAP-AKA is included +#CONFIG_PCSC=y + +# Development testing +#CONFIG_EAPOL_TEST=y + +# Replace native Linux implementation of packet sockets with libdnet/libpcap. +# This will be automatically set for non-Linux OS. +#CONFIG_DNET_PCAP=y + +# Include control interface for external programs, e.g, wpa_cli +CONFIG_CTRL_IFACE=y + +# Include interface for using external supplicant (Xsupplicant) for EAP +# authentication +#CONFIG_XSUPPLICANT_IFACE=y + +# Include support for GNU Readline and History Libraries in wpa_cli. +# When building a wpa_cli binary for distribution, please note that these +# libraries are licensed under GPL and as such, BSD license may not apply for +# the resulting binary. +#CONFIG_READLINE=y diff --git a/packages/wpa-supplicant/wpa-supplicant_0.3.8.bb b/packages/wpa-supplicant/wpa-supplicant_0.3.8.bb index 684d7da8eb..d125fb4027 100644 --- a/packages/wpa-supplicant/wpa-supplicant_0.3.8.bb +++ b/packages/wpa-supplicant/wpa-supplicant_0.3.8.bb @@ -5,6 +5,7 @@ MAINTAINER = "Holger Schurig" HOMEPAGE = "http://hostap.epitest.fi/wpa_supplicant/" DEPENDS = "openssl" DEPENDS_mtx-1_append = "madwifi-modules" +DEPENDS_mtx-2_append = "madwifi-modules" PR = "r1" SRC_URI = "http://hostap.epitest.fi/releases/wpa_supplicant-${PV}.tar.gz \ diff --git a/packages/wpa-supplicant/wpa-supplicant_0.4.7.bb b/packages/wpa-supplicant/wpa-supplicant_0.4.7.bb index 03aa3f6d0d..bbb42879d9 100644 --- a/packages/wpa-supplicant/wpa-supplicant_0.4.7.bb +++ b/packages/wpa-supplicant/wpa-supplicant_0.4.7.bb @@ -5,6 +5,7 @@ MAINTAINER = "Holger Schurig" HOMEPAGE = "http://hostap.epitest.fi/wpa_supplicant/" DEPENDS = "openssl" DEPENDS_mtx-1_append = "madwifi-modules" +DEPENDS_mtx-2_append = "madwifi-modules" PR = "r1" SRC_URI = "http://hostap.epitest.fi/releases/wpa_supplicant-${PV}.tar.gz \ -- cgit v1.2.3 From 005ccbff6b2c8c9e36abb1802166befd8cc256e5 Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 13:06:05 +0000 Subject: chillispot: patch to fix compilation errors * remove the -ansi switch from the CFLAGS since some files are unix-style sources and do not compile in ansi mode --- packages/chillispot/chillispot-0.98/.mtn2git_empty | 0 packages/chillispot/chillispot-0.98/no-ansi.patch | 10 ++++++++++ packages/chillispot/chillispot-1.0RC3/.mtn2git_empty | 0 packages/chillispot/chillispot-1.0RC3/no-ansi.patch | 11 +++++++++++ 4 files changed, 21 insertions(+) create mode 100644 packages/chillispot/chillispot-0.98/.mtn2git_empty create mode 100644 packages/chillispot/chillispot-0.98/no-ansi.patch create mode 100644 packages/chillispot/chillispot-1.0RC3/.mtn2git_empty create mode 100644 packages/chillispot/chillispot-1.0RC3/no-ansi.patch diff --git a/packages/chillispot/chillispot-0.98/.mtn2git_empty b/packages/chillispot/chillispot-0.98/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/chillispot/chillispot-0.98/no-ansi.patch b/packages/chillispot/chillispot-0.98/no-ansi.patch new file mode 100644 index 0000000000..3a58433d87 --- /dev/null +++ b/packages/chillispot/chillispot-0.98/no-ansi.patch @@ -0,0 +1,10 @@ +--- chillispot-0.98/src/Makefile.am.org 2006-02-01 11:04:39.086469680 +0100 ++++ chillispot-0.98/src/Makefile.am 2006-02-01 11:04:46.451350048 +0100 +@@ -1,6 +1,6 @@ + sbin_PROGRAMS = chilli + +-AM_CFLAGS = -D_GNU_SOURCE -fno-builtin -ansi -DSBINDIR='"$(sbindir)"' ++AM_CFLAGS = -D_GNU_SOURCE -fno-builtin -DSBINDIR='"$(sbindir)"' + + chilli_SOURCES = chilli.c defs.h tun.c tun.h cmdline.c cmdline.h ippool.c ippool.h radius.h radius.c md5.c md5.h redir.h redir.c dhcp.c dhcp.h syserr.c syserr.h iphash.c iphash.h + diff --git a/packages/chillispot/chillispot-1.0RC3/.mtn2git_empty b/packages/chillispot/chillispot-1.0RC3/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/chillispot/chillispot-1.0RC3/no-ansi.patch b/packages/chillispot/chillispot-1.0RC3/no-ansi.patch new file mode 100644 index 0000000000..3a3ffab9a2 --- /dev/null +++ b/packages/chillispot/chillispot-1.0RC3/no-ansi.patch @@ -0,0 +1,11 @@ +--- chillispot-1.0RC3/src/Makefile.am.org 2006-02-01 10:43:45.628024328 +0100 ++++ chillispot-1.0RC3/src/Makefile.am 2006-02-01 10:43:50.922219488 +0100 +@@ -1,7 +1,7 @@ + sbin_PROGRAMS = chilli + + # add -pg to enable gprof +-AM_CFLAGS = -D_GNU_SOURCE -fno-builtin -ansi -DSBINDIR='"$(sbindir)"' ++AM_CFLAGS = -D_GNU_SOURCE -fno-builtin -DSBINDIR='"$(sbindir)"' + + chilli_SOURCES = chilli.c defs.h tun.c tun.h cmdline.c cmdline.h ippool.c ippool.h radius.h radius.c md5.c md5.h redir.h redir.c dhcp.c dhcp.h syserr.c syserr.h iphash.c iphash.h lookup.c lookup.h + -- cgit v1.2.3 From 9952fef5fb365afddfa9d6aeb940037c12019bdb Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 8 Sep 2006 13:08:41 +0000 Subject: speex: add 1.2beta which has reduced memory usage and lower cpu requirements --- packages/speex/speex_1.1.12+1.2beta1.bb | 38 +++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 packages/speex/speex_1.1.12+1.2beta1.bb diff --git a/packages/speex/speex_1.1.12+1.2beta1.bb b/packages/speex/speex_1.1.12+1.2beta1.bb new file mode 100644 index 0000000000..d0f33bf681 --- /dev/null +++ b/packages/speex/speex_1.1.12+1.2beta1.bb @@ -0,0 +1,38 @@ +DESCRIPTION = "Speex is an Open Source/Free Software patent-free audio compression format designed for speech." +SECTION = "libs" +LICENSE = "BSD" +HOMEPAGE = "http://www.speex.org" +DEPENDS = "libogg" +PR = "r0" + +SRC_URI = "http://downloads.us.xiph.org/releases/speex/speex-1.2beta1.tar.gz" +S = "${WORKDIR}/${PN}-1.2beta1" + +PARALLEL_MAKE = "" + +inherit autotools pkgconfig + +# Some interesting options are: +# +# --enable-arm4-asm +# --enable-arm5e-asm +# --enable-fixed-point +# + +EXTRA_OECONF_append_openmn = " --enable-arm5e-asm --enable-fixed-point" +EXTRA_OECONF_append_amsdelta = " --enable-arm4-asm --enable-fixed-point" +EXTRA_OECONF_append_arm = " --enable-fixed-point " + +do_configure_append() { + sed -i s/"^OGG_CFLAGS.*$"/"OGG_CFLAGS = "/g Makefile */Makefile */*/Makefile + sed -i s/"^OGG_LIBS.*$"/"OGG_LIBS = -logg"/g Makefile */Makefile */*/Makefile + perl -pi -e 's:^includedir.*$:includedir = ${STAGING_INCDIR}:g' Makefile */Makefile */*/Makefile + perl -pi -e 's:^oldincludedir.*$:includedir = ${STAGING_INCDIR}:g' Makefile */Makefile */*/Makefile + perl -pi -e 's:\s*-I/usr/include$::g' Makefile */Makefile */*/Makefile +} + +do_stage() { + oe_libinstall -C libspeex -so libspeex ${STAGING_LIBDIR} + install -d ${STAGING_INCDIR}/speex + install -m 0644 include/speex/*.h ${STAGING_INCDIR}/speex +} -- cgit v1.2.3 From 6f53e1d4b2c7aed88b3bf4c43ed3baa609654e5e Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 13:09:43 +0000 Subject: hostap-daemon and madwifi: fix compatibility problems on mtx platforms * added mtx-2 configuration to hostapd-daemon * made madwifi-modules_cvs the default choice (the bsd branch has been abandoned) * made sure that madwifi_modules stages the headers correctly so that hostap-daemon compiles on mtx/nylon --- packages/hostap/hostap-daemon.inc | 3 + packages/hostap/hostap-daemon/mtx-2/.mtn2git_empty | 0 packages/hostap/hostap-daemon/mtx-2/defconfig | 66 ++++++++++++++++++++++ packages/hostap/hostap-modules.inc | 2 + packages/madwifi/madwifi-modules_cvs-bsd.bb | 4 +- packages/madwifi/madwifi-modules_cvs.bb | 20 +++++-- 6 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 packages/hostap/hostap-daemon/mtx-2/.mtn2git_empty create mode 100644 packages/hostap/hostap-daemon/mtx-2/defconfig diff --git a/packages/hostap/hostap-daemon.inc b/packages/hostap/hostap-daemon.inc index 83491bfb14..a6e4a6246d 100644 --- a/packages/hostap/hostap-daemon.inc +++ b/packages/hostap/hostap-daemon.inc @@ -7,6 +7,9 @@ LICENSE = "GPL" RDEPENDS = "hostap-modules hostap-utils (${PV})" DEPENDS = "openssl" DEPENDS_mtx-1_append = "madwifi-modules" +DEPENDS_mtx-2_append = "madwifi-modules" +CPPFLAGS_append_mtx-1 = " -I${STAGING_INCDIR}/madwifi/" +CPPFLAGS_append_mtx-2 = " -I${STAGING_INCDIR}/madwifi/" SRC_URI = "http://hostap.epitest.fi/releases/hostapd-${PV}.tar.gz \ file://makefile-cross.diff;patch=1;pnum=0 \ diff --git a/packages/hostap/hostap-daemon/mtx-2/.mtn2git_empty b/packages/hostap/hostap-daemon/mtx-2/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/hostap/hostap-daemon/mtx-2/defconfig b/packages/hostap/hostap-daemon/mtx-2/defconfig new file mode 100644 index 0000000000..8c3065c3b9 --- /dev/null +++ b/packages/hostap/hostap-daemon/mtx-2/defconfig @@ -0,0 +1,66 @@ +# Example hostapd build time configuration +# +# This file lists the configuration options that are used when building the +# hostapd binary. All lines starting with # are ignored. Configuration option +# lines must be commented out complete, if they are not to be included, i.e., +# just setting VARIABLE=n is not disabling that variable. +# +# This file is included in Makefile, so variables like CFLAGS and LIBS can also +# be modified from here. In most cass, these lines should use += in order not +# to override previous values of the variables. + +# Driver interface for Host AP driver +CONFIG_DRIVER_HOSTAP=y + +# Driver interface for wired authenticator +CONFIG_DRIVER_WIRED=y + +# Driver interface for madwifi driver +CONFIG_DRIVER_MADWIFI=y +#CFLAGS += -I../head # change to reflect local setup; directory for madwifi src + +# Driver interface for Prism54 driver +CONFIG_DRIVER_PRISM54=y + +# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) +#CONFIG_DRIVER_BSD=y +#CFLAGS += -I/usr/local/include +#LIBS += -L/usr/local/lib + +# IEEE 802.11F/IAPP +CONFIG_IAPP=y + +# WPA2/IEEE 802.11i RSN pre-authentication +CONFIG_RSN_PREAUTH=y + +# Integrated EAP authenticator +CONFIG_EAP=y + +# EAP-MD5 for the integrated EAP authenticator +CONFIG_EAP_MD5=y + +# EAP-TLS for the integrated EAP authenticator +CONFIG_EAP_TLS=y + +# EAP-MSCHAPv2 for the integrated EAP authenticator +CONFIG_EAP_MSCHAPV2=y + +# EAP-PEAP for the integrated EAP authenticator +CONFIG_EAP_PEAP=y + +# EAP-GTC for the integrated EAP authenticator +CONFIG_EAP_GTC=y + +# EAP-TTLS for the integrated EAP authenticator +CONFIG_EAP_TTLS=y + +# EAP-SIM for the integrated EAP authenticator +#CONFIG_EAP_SIM=y + +# PKCS#12 (PFX) support (used to read private key and certificate file from +# a file that usually has extension .p12 or .pfx) +CONFIG_PKCS12=y + +# RADIUS authentication server. This provides access to the integrated EAP +# authenticator from external hosts using RADIUS. +CONFIG_RADIUS_SERVER=y diff --git a/packages/hostap/hostap-modules.inc b/packages/hostap/hostap-modules.inc index 5ce5e0db67..4d1cc76d32 100644 --- a/packages/hostap/hostap-modules.inc +++ b/packages/hostap/hostap-modules.inc @@ -8,6 +8,8 @@ SRC_URI = "http://hostap.epitest.fi/releases/hostap-driver-${PV}.tar.gz" SRC_URI_append_mtx-1 = " file://mtx_compat.diff;patch=1;pnum=0 \ file://mtx_hostap_deferred_irq.diff;patch=1;pnum=0" +SRC_URI_append_mtx-2 = " file://mtx_compat.diff;patch=1;pnum=0 \ + file://mtx_hostap_deferred_irq.diff;patch=1;pnum=0" SRC_URI_append_h3900 = " file://ipaq_compat.patch;patch=1 " diff --git a/packages/madwifi/madwifi-modules_cvs-bsd.bb b/packages/madwifi/madwifi-modules_cvs-bsd.bb index 6da2c34baf..be6de0663f 100644 --- a/packages/madwifi/madwifi-modules_cvs-bsd.bb +++ b/packages/madwifi/madwifi-modules_cvs-bsd.bb @@ -5,7 +5,8 @@ MAINTAINER = "Bruno Randolf " LICENSE = "GPL" RDEPENDS = "kernel (${KERNEL_VERSION})" DEPENDS = "virtual/kernel" -PV = "1:0.0+cvs${SRCDATE}-bsd" +PV = "1.0.0+cvs${SRCDATE}-bsd" +DEFAULT_PREFERENCE = "-1" SRC_URI = "cvs://anonymous@cvs.sourceforge.net/cvsroot/madwifi;module=madwifi;tag=BSD;date=${SRCDATE}" @@ -16,6 +17,7 @@ inherit module-base # Hack Alert :D ARCH_mipsel = "mips" EXTRA_OEMAKE_mtx-1 = "TARGET=mips-le-elf KERNELPATH=${STAGING_KERNEL_DIR} KERNELRELEASE=${KERNEL_VERSION} TOOLPREFIX=${TARGET_PREFIX} \ +EXTRA_OEMAKE_mtx-2 = "TARGET=mips-le-elf KERNELPATH=${STAGING_KERNEL_DIR} KERNELRELEASE=${KERNEL_VERSION} TOOLPREFIX=${TARGET_PREFIX} \ COPTS='-G 0 -mno-abicalls -fno-pic -Wa,--trap -fno-strict-aliasing -fno-common -fomit-frame-pointer -mlong-calls -DATH_PCI'" do_compile() { diff --git a/packages/madwifi/madwifi-modules_cvs.bb b/packages/madwifi/madwifi-modules_cvs.bb index 0bef3d506e..bc89d84a15 100644 --- a/packages/madwifi/madwifi-modules_cvs.bb +++ b/packages/madwifi/madwifi-modules_cvs.bb @@ -5,9 +5,10 @@ MAINTAINER = "Bruno Randolf " LICENSE = "GPL" RDEPENDS = "kernel (${KERNEL_VERSION})" DEPENDS = "virtual/kernel" -PV = "1:0.0+cvs${SRCDATE}" +SRCDATE = "20050803" +PV = "1.0.0+cvs${SRCDATE}" -SRC_URI = "cvs://anonymous@cvs.sourceforge.net/cvsroot/madwifi;module=madwifi" +SRC_URI = "cvs://anonymous@cvs.sourceforge.net/cvsroot/madwifi;module=madwifi;date=${SRCDATE}" S = "${WORKDIR}/madwifi" @@ -17,6 +18,8 @@ inherit module-base ARCH_mipsel = "mips" EXTRA_OEMAKE_mtx-1 = "TARGET=mips-le-elf KERNELPATH=${STAGING_KERNEL_DIR} KERNELRELEASE=${KERNEL_VERSION} TOOLPREFIX=${TARGET_PREFIX} \ COPTS='-G 0 -mno-abicalls -fno-pic -Wa,--trap -fno-strict-aliasing -fno-common -fomit-frame-pointer -mlong-calls -DATH_PCI'" +EXTRA_OEMAKE_mtx-2 = "TARGET=mips-le-elf KERNELPATH=${STAGING_KERNEL_DIR} KERNELRELEASE=${KERNEL_VERSION} TOOLPREFIX=${TARGET_PREFIX} \ +COPTS='-G 0 -mno-abicalls -fno-pic -Wa,--trap -fno-strict-aliasing -fno-common -fomit-frame-pointer -mlong-calls -DATH_PCI'" do_compile() { oe_runmake @@ -25,10 +28,19 @@ do_compile() { do_install() { oe_runmake DESTDIR=${D} install - install -d ${D}${sbindir} + install -d ${D}/${sbindir} cd tools; oe_runmake DESTDIR=${D} BINDIR=${sbindir} install - install -m 755 athchans athctrl athkey ${D}${sbindir} + install -m 755 athchans athctrl athkey ${D}/${sbindir} +} + +do_stage() { + # hostapd and wpa_supplicant need these files + install -d ${STAGING_INCDIR}/madwifi/net80211/ ${STAGING_INCDIR}/madwifi/include + install -m 0644 net80211/*.h ${STAGING_INCDIR}/madwifi/net80211/ + install -m 0644 include/compat.h ${STAGING_INCDIR}/madwifi/include/ + cd ${STAGING_INCDIR}/madwifi/net80211/ + ln -s ../include/compat.h . } pkg_postinst() { -- cgit v1.2.3 From 01ac74a79e791b4f2a1a3783ae827350fe7a8f92 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Fri, 8 Sep 2006 13:10:00 +0000 Subject: hh-pxa 2.6: update defconfigs --- packages/linux/handhelds-pxa-2.6/h5xxx/defconfig | 146 ++++++++++++++------- .../linux/handhelds-pxa-2.6/ipaq-pxa270/defconfig | 2 +- 2 files changed, 98 insertions(+), 50 deletions(-) diff --git a/packages/linux/handhelds-pxa-2.6/h5xxx/defconfig b/packages/linux/handhelds-pxa-2.6/h5xxx/defconfig index 82f309c895..b3f8f7c100 100644 --- a/packages/linux/handhelds-pxa-2.6/h5xxx/defconfig +++ b/packages/linux/handhelds-pxa-2.6/h5xxx/defconfig @@ -1,13 +1,15 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-hh5 -# Sat Aug 12 10:50:22 2006 +# Linux kernel version: 2.6.17-hh0 +# Sun Aug 27 16:30:03 2006 # CONFIG_ARM=y CONFIG_MMU=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_MTD_XIP=y +CONFIG_VECTORS_BASE=0xffff0000 # # Code maturity level options @@ -32,6 +34,7 @@ CONFIG_SYSCTL=y CONFIG_IKCONFIG=y # CONFIG_MINIMAL_OOPS is not set CONFIG_IKCONFIG_PROC=y +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_UID16=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -49,10 +52,6 @@ CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_USELIB=y CONFIG_CORE_DUMP=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -65,7 +64,6 @@ CONFIG_OBSOLETE_INTERMODULE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -73,6 +71,7 @@ CONFIG_KMOD=y # # Block layer # +# CONFIG_BLK_DEV_IO_TRACE is not set # # IO Schedulers @@ -94,11 +93,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set CONFIG_ARCH_PXA=y # CONFIG_ARCH_RPC is not set @@ -113,11 +114,13 @@ CONFIG_ARCH_PXA=y # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_AAEC2000 is not set # CONFIG_ARCH_AT91RM9200 is not set +CONFIG_DMABOUNCE=y # # Intel PXA2xx Implementations # # CONFIG_ARCH_LUBBOCK is not set +# CONFIG_MACH_LOGICPD_PXA270 is not set # CONFIG_MACH_MAINSTONE is not set # CONFIG_ARCH_PXA_IDP is not set # CONFIG_ARCH_ESERIES is not set @@ -130,7 +133,7 @@ CONFIG_ARCH_PXA=y # CONFIG_MACH_H4700 is not set # CONFIG_MACH_HX2750 is not set CONFIG_ARCH_H5400=y -# CONFIG_IPAQ_H5400_LCD is not set +CONFIG_IPAQ_H5400_LCD=m CONFIG_IPAQ_H5400_BATTERY=m # CONFIG_MACH_HIMALAYA is not set # CONFIG_MACH_HTCUNIVERSAL is not set @@ -190,7 +193,6 @@ CONFIG_IPAQ_HANDHELD=y # # Compaq/HP iPAQ Drivers # -CONFIG_IPAQ_CLOCKS=y CONFIG_IPAQ_SLEEVE=y CONFIG_IPAQ_SAMCOP=y # CONFIG_IPAQ_HAMCOP is not set @@ -198,7 +200,6 @@ CONFIG_IPAQ_SAMCOP_TOUCHSCREEN=y # CONFIG_IPAQ_SAMCOP_FSI is not set # CONFIG_IPAQ_SAMCOP_SLEEVE is not set CONFIG_IPAQ_SAMCOP_DMA=y -CONFIG_DMABOUNCE=y # # Bus support @@ -224,6 +225,7 @@ CONFIG_IPAQ_PCMCIA_SLEEVE=m # CONFIG_PREEMPT=y # CONFIG_NO_IDLE_HZ is not set +CONFIG_HZ=100 CONFIG_AEABI=y CONFIG_OABI_COMPAT=y # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set @@ -305,6 +307,7 @@ CONFIG_NET_IPGRE_BROADCAST=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=y CONFIG_INET_TCP_DIAG=y @@ -317,9 +320,11 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IP_VS is not set CONFIG_IPV6=m # CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set 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 @@ -346,6 +351,7 @@ CONFIG_IP_NF_IRC=m # CONFIG_IP_NF_TFTP is not set # CONFIG_IP_NF_AMANDA is not set # CONFIG_IP_NF_PPTP is not set +# CONFIG_IP_NF_H323 is not set # CONFIG_IP_NF_QUEUE is not set # @@ -376,6 +382,7 @@ CONFIG_IP_NF_IRC=m CONFIG_BRIDGE=m # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set +CONFIG_LLC=m # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -473,6 +480,8 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m +# CONFIG_IEEE80211_SOFTMAC is not set +CONFIG_WIRELESS_EXT=y # # Device Drivers @@ -561,7 +570,6 @@ CONFIG_MTD_IPAQ=y # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -740,6 +748,7 @@ CONFIG_TUN=m # Wireless LAN (non-hamradio) # CONFIG_NET_RADIO=y +# CONFIG_NET_WIRELESS_RTNETLINK is not set # # Obsolete Wireless cards support (pre-802.11) @@ -898,9 +907,7 @@ CONFIG_I2C_PXA=y # CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCA9535 is not set # CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -971,10 +978,19 @@ CONFIG_SA1100_RTC=y # Dallas's 1-wire bus # CONFIG_W1=y -# CONFIG_W1_DS9490 is not set -# CONFIG_W1_THERM is not set -# CONFIG_W1_SMEM is not set -# CONFIG_W1_DS2433 is not set + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS9490 is not set +# CONFIG_W1_MASTER_DS2482 is not set + +# +# 1-wire Slaves +# +# CONFIG_W1_SLAVE_THERM is not set +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2433 is not set CONFIG_W1_SAMCOP=y CONFIG_W1_DS2760=y @@ -1032,7 +1048,7 @@ CONFIG_SOC_MQ11XX=y # # Misc devices # -# CONFIG_BATTERY_MONITOR is not set +CONFIG_BATTERY_MONITOR=y # # Multimedia Capabilities Port drivers @@ -1040,31 +1056,76 @@ CONFIG_SOC_MQ11XX=y # CONFIG_MCP is not set # -# Multimedia Capabilities Port drivers +# LED devices +# +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers # +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_IDE_DISK=y + # # Multimedia devices # CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y # -# 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_CPIA=m # CONFIG_VIDEO_CPIA_USB is not set +# CONFIG_VIDEO_CPIA2 is not set # CONFIG_VIDEO_SAA5246A is not set # CONFIG_VIDEO_SAA5249 is not set # CONFIG_TUNER_3036 is not set -# CONFIG_VIDEO_EM28XX is not set # CONFIG_VIDEO_OVCAMCHIP is not set -# CONFIG_VIDEO_AUDIO_DECODER is not set -# CONFIG_VIDEO_DECODER is not set + +# +# Encoders and Decoders +# +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_CX25840 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set + +# +# V4L USB devices +# +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_USB_DSBR is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_W9968CF is not set +# CONFIG_USB_ZC0301 is not set +# CONFIG_USB_PWC is not set # # Radio Adapters @@ -1075,6 +1136,7 @@ CONFIG_VIDEO_CPIA=m # Digital Video Broadcasting Devices # # CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set # # Graphics support @@ -1084,12 +1146,12 @@ CONFIG_FB_CFB_FILLRECT=m CONFIG_FB_CFB_COPYAREA=m CONFIG_FB_CFB_IMAGEBLIT=m # CONFIG_FB_MACMODES is not set +CONFIG_FB_FIRMWARE_EDID=y # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_IMAGEON is not set # CONFIG_FB_S1D13XXX is not set -CONFIG_FB_PXA=m -# CONFIG_FB_PXA_PARAMETERS is not set +# CONFIG_FB_PXA is not set CONFIG_FB_MQ1100=m # CONFIG_FB_VIRTUAL is not set @@ -1117,9 +1179,9 @@ CONFIG_FONT_MINI_4x6=y # # CONFIG_LOGO is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_DEVICE=y -CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_DEVICE=y # @@ -1132,6 +1194,7 @@ CONFIG_LCD_DEVICE=y # CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set CONFIG_USB=m # CONFIG_USB_DEBUG is not set @@ -1182,9 +1245,7 @@ CONFIG_USB_SL811_CS=m # CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set -# CONFIG_USB_MTOUCH is not set -# CONFIG_USB_ITMTOUCH is not set -# CONFIG_USB_EGALAX is not set +# CONFIG_USB_TOUCHSCREEN is not set # CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -1198,21 +1259,6 @@ CONFIG_USB_SL811_CS=m # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set -# -# USB Multimedia devices -# -# CONFIG_USB_DABUSB is not set -# CONFIG_USB_VICAM is not set -# CONFIG_USB_DSBR is not set -# CONFIG_USB_ET61X251 is not set -# CONFIG_USB_IBMCAM is not set -# CONFIG_USB_KONICAWC is not set -# CONFIG_USB_OV511 is not set -# CONFIG_USB_SE401 is not set -# CONFIG_USB_SN9C102 is not set -# CONFIG_USB_STV680 is not set -# CONFIG_USB_PWC is not set - # # USB Network Adapters # @@ -1269,6 +1315,7 @@ CONFIG_USB_PXA2XX_SMALL=y # CONFIG_USB_GADGET_MQ11XX is not set # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_AT91 is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set # CONFIG_USB_GADGET_DUALSPEED is not set # CONFIG_USB_ZERO is not set @@ -1291,9 +1338,10 @@ CONFIG_MMC_SAMCOP=y # CONFIG_MMC_ASIC3 is not set # -# LED devices +# Real Time Clock # -CONFIG_CLASS_LEDS=y +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set # # File systems @@ -1351,7 +1399,6 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set # CONFIG_CONFIGFS_FS is not set # @@ -1483,6 +1530,7 @@ CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set diff --git a/packages/linux/handhelds-pxa-2.6/ipaq-pxa270/defconfig b/packages/linux/handhelds-pxa-2.6/ipaq-pxa270/defconfig index da28b781af..7fadc7ae3a 100644 --- a/packages/linux/handhelds-pxa-2.6/ipaq-pxa270/defconfig +++ b/packages/linux/handhelds-pxa-2.6/ipaq-pxa270/defconfig @@ -776,7 +776,7 @@ CONFIG_HOSTAP=m CONFIG_HOSTAP_FIRMWARE=y CONFIG_HOSTAP_FIRMWARE_NVRAM=y CONFIG_HOSTAP_CS=m -CONFIG_ACX=m +CONFIG_ACX=y # CONFIG_ACX_USB is not set CONFIG_ACX_MEM=y CONFIG_ACX_HX4700=m -- cgit v1.2.3 From ceb7923f061dc0ad4e2fa1d480e3e5f702ecd3ba Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 13:15:14 +0000 Subject: gcc: fix compilation problems * added patch to gcc 3.3.4, see http://mail-index.netbsd.org/netbsd-bugs/2004/06/15/0001.html --- packages/gcc/gcc-3.3.4/gcc-com.patch | 11 +++++++++++ packages/gcc/gcc_3.3.4.bb | 1 + 2 files changed, 12 insertions(+) create mode 100644 packages/gcc/gcc-3.3.4/gcc-com.patch diff --git a/packages/gcc/gcc-3.3.4/gcc-com.patch b/packages/gcc/gcc-3.3.4/gcc-com.patch new file mode 100644 index 0000000000..fb2ffdadf3 --- /dev/null +++ b/packages/gcc/gcc-3.3.4/gcc-com.patch @@ -0,0 +1,11 @@ +--- gcc-3.3.4/gcc/f/com.h 2005-08-16 10:06:34.370388888 +0200 ++++ gcc/gcc/f/com.h 2005-08-16 10:09:11.862446456 +0200 +@@ -233,7 +233,7 @@ + void ffecom_finish_progunit (void); + tree ffecom_get_invented_identifier (const char *pattern, ...) + ATTRIBUTE_PRINTF_1; +-ffeinfoKindtype ffecom_gfrt_basictype (ffecomGfrt ix); ++ffeinfoBasictype ffecom_gfrt_basictype (ffecomGfrt ix); + ffeinfoKindtype ffecom_gfrt_kindtype (ffecomGfrt ix); + void ffecom_init_0 (void); + void ffecom_init_2 (void); diff --git a/packages/gcc/gcc_3.3.4.bb b/packages/gcc/gcc_3.3.4.bb index 4a1d146dbb..c3df66d720 100644 --- a/packages/gcc/gcc_3.3.4.bb +++ b/packages/gcc/gcc_3.3.4.bb @@ -71,6 +71,7 @@ SRC_URI = "${GNU_MIRROR}/gcc/releases/gcc-${PV}/gcc-${PV}.tar.bz2 \ file://gcc-uclibc-3.3-120-softfloat.patch;patch=1 \ file://gcc-uclibc-3.3-200-code.patch;patch=1 \ file://zecke-xgcc-cpp.patch;patch=1 \ + file://gcc-com.patch;patch=1 \ file://bash3.patch;patch=1" PREMIRRORS_prepend () { -- cgit v1.2.3 From b4377c59723a3a4611f5b9ec1c3d1c708ef72a85 Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 13:16:30 +0000 Subject: libintl-perl: new package --- packages/perl/libintl-perl-native_1.11.bb | 5 +++++ packages/perl/libintl-perl_1.11.bb | 13 +++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 packages/perl/libintl-perl-native_1.11.bb create mode 100644 packages/perl/libintl-perl_1.11.bb diff --git a/packages/perl/libintl-perl-native_1.11.bb b/packages/perl/libintl-perl-native_1.11.bb new file mode 100644 index 0000000000..5499e713a5 --- /dev/null +++ b/packages/perl/libintl-perl-native_1.11.bb @@ -0,0 +1,5 @@ +SECTION = "libs" + +include libintl-perl_1.11.bb + +inherit native diff --git a/packages/perl/libintl-perl_1.11.bb b/packages/perl/libintl-perl_1.11.bb new file mode 100644 index 0000000000..833e9fbad8 --- /dev/null +++ b/packages/perl/libintl-perl_1.11.bb @@ -0,0 +1,13 @@ +SECTION = "libs" +LICENSE = "Artistic|GPL" +SRC_URI = "http://www.cpan.org/authors/id/G/GU/GUIDO/libintl-perl-${PV}.tar.gz" +DEPENDS = "perl" +RDEPENDS = "perl-module-vars perl-module-locale perl-module-io-handle perl-module-symbol perl-module-selectsaver perl-module-io perl-module-integer perl-module-exporter-heavy" + +S = "${WORKDIR}/libintl-perl-${PV}" + +inherit cpan + +do_compile() { + make CC="${CC}" LD="${LD}" +} \ No newline at end of file -- cgit v1.2.3 From 6c42bd48558d55307fc6abd10d724d8bbdaa6bbe Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 13:17:49 +0000 Subject: shorewall: added a version of the package for (more) monolithic kernels * dependency checking for some kernel modules is skipped assuming they are compiled in rather than installed as modules --- packages/shorewall/shorewall_2.0.9-monolithic.bb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/shorewall/shorewall_2.0.9-monolithic.bb diff --git a/packages/shorewall/shorewall_2.0.9-monolithic.bb b/packages/shorewall/shorewall_2.0.9-monolithic.bb new file mode 100644 index 0000000000..6521870444 --- /dev/null +++ b/packages/shorewall/shorewall_2.0.9-monolithic.bb @@ -0,0 +1,5 @@ +include shorewall_2.0.9.bb + +RDEPENDS = "iptables kernel-module-ipt-multiport kernel-module-ipt-mac kernel-module-ipt-mark kernel-module-ipt-pkttype kernel-module-ipt-tos" + +S = "${WORKDIR}/shorewall-2.0.9" -- cgit v1.2.3 From e536b4b111277baa303891dc1bf6c92e5b75a0ff Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 13:24:34 +0000 Subject: olsrd: made cvs version non-default choice --- packages/olsrd/olsrd_cvs.bb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/olsrd/olsrd_cvs.bb b/packages/olsrd/olsrd_cvs.bb index 6aca392434..697d279848 100644 --- a/packages/olsrd/olsrd_cvs.bb +++ b/packages/olsrd/olsrd_cvs.bb @@ -5,7 +5,10 @@ MAINTAINER = "Bruno Randolf " SECTION = "console/network" PRIORITY = "optional" LICENSE = "BSD" -PV = "1:0.0+cvs${SRCDATE}" +SRCDATE = "20051020" +PV = "0.4.9+cvs${SRCDATE}" + +DEFAULT_PREFERENCE = "-1" SRC_URI="cvs://anonymous@cvs.sourceforge.net/cvsroot/olsrd;module=olsrd-current \ file://init \ -- cgit v1.2.3 From 7bd38fb15b489b7a169879fc4811b55d14f3d35a Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 13:25:42 +0000 Subject: pmacct: duplicated mtx-1 specific configuration for mtx-2 --- packages/pmacct/pmacct_0.7.9.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pmacct/pmacct_0.7.9.bb b/packages/pmacct/pmacct_0.7.9.bb index 375eadce24..06cbd9296a 100644 --- a/packages/pmacct/pmacct_0.7.9.bb +++ b/packages/pmacct/pmacct_0.7.9.bb @@ -25,4 +25,4 @@ do_install() { install -m 644 ${WORKDIR}/pmacct.conf.eth0 ${D}${sysconfdir}/pmacct } -CONFFILES_nylon = "/etc/pmacct/pmacct.conf.eth0" +CONFFILES_${PN}_nylon = "${sysconfdir}/pmacct/pmacct.conf.eth0" -- cgit v1.2.3 From 7dc50cca89cd525310d665ab15098cfa99e18a07 Mon Sep 17 00:00:00 2001 From: Martin Dietze Date: Fri, 8 Sep 2006 13:26:35 +0000 Subject: openssl: duplicated mtx-1 specific configuration for mtx-2 --- packages/openssl/openssl.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/openssl/openssl.inc b/packages/openssl/openssl.inc index ab99495c54..176a71825c 100644 --- a/packages/openssl/openssl.inc +++ b/packages/openssl/openssl.inc @@ -11,6 +11,7 @@ export CFLAG = "-fPIC -DTHREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DTERMIO # -02 does not work on mipsel: ssh hangs when it tries to read /dev/urandom export CFLAG_mtx-1 := "${@'${CFLAG}'.replace('-O2', '')}" +export CFLAG_mtx-2 := "${@'${CFLAG}'.replace('-O2', '')}" export DIRS = "crypto ssl apps" export EX_LIBS = "-lgcc -ldl -L${STAGING_LIBDIR}" -- cgit v1.2.3 From 469b7173460c5b88fafdf75d41d8e10c3673e09b Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Fri, 8 Sep 2006 17:04:52 +0000 Subject: linux-openzaurus: autoload ohci-hcd on tosa --- packages/linux/linux-openzaurus.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/linux/linux-openzaurus.inc b/packages/linux/linux-openzaurus.inc index 2ff70f48e3..88ee712143 100644 --- a/packages/linux/linux-openzaurus.inc +++ b/packages/linux/linux-openzaurus.inc @@ -23,7 +23,7 @@ ALLOW_EMPTY = 1 EXTRA_OEMAKE = "OPENZAURUS_RELEASE=-${DISTRO_VERSION}" COMPATIBLE_HOST = "arm.*-linux" -COMPATIBLE_MACHINE = '(collie|poodle|c7x0|akita|spitz|tosa|ipoq-pxa270|qemuarm)' +COMPATIBLE_MACHINE = '(collie|poodle|c7x0|akita|spitz|tosa|ipaq-pxa270|qemuarm)' CMDLINE_CON = "console=ttyS0,115200n8 console=tty1 noinitrd" CMDLINE_ROOT = "root=/dev/mtdblock2 rootfstype=jffs2" @@ -52,6 +52,7 @@ ENABLE_ELPP = ${@bb.data.getVar("OZ_KERNEL_ENABLE_ELPP",d,1) or "no"} ############################################################### # module configs specific to this kernel # +module_autoload_ohci-hcd_tosa = "ohci-hcd" module_autoload_pxaficp_ir = "pxaficp_ir" module_autoload_snd-pcm-oss = "snd-pcm-oss" module_autoload_snd-soc-corgi_c7x0 = "snd-soc-corgi" -- cgit v1.2.3 From 8d43e979e77a19f312ef50f7c55ee34d4843c913 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Fri, 8 Sep 2006 17:09:02 +0000 Subject: linux-openzaurus 2.6.16: backport of USB MaxPower limit information Revision: 69f0a166098b754a6fa1cbb114317c805f34e399 from .oz354x --- .../linux-openzaurus-2.6.16/maxpower-message.patch | 55 ++++++++++++++++++++++ packages/linux/linux-openzaurus_2.6.16.bb | 3 +- 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 packages/linux/linux-openzaurus-2.6.16/maxpower-message.patch diff --git a/packages/linux/linux-openzaurus-2.6.16/maxpower-message.patch b/packages/linux/linux-openzaurus-2.6.16/maxpower-message.patch new file mode 100644 index 0000000000..6e76be4d1c --- /dev/null +++ b/packages/linux/linux-openzaurus-2.6.16/maxpower-message.patch @@ -0,0 +1,55 @@ +From: Daniel Drake +Date: Fri, 26 May 2006 20:36:28 +0000 (+0100) +Subject: [PATCH] USB: print message when device is rejected due to insufficient power +X-Git-Tag: v2.6.18-rc1 +X-Git-Url: http://kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=1fbe75e12f0dd567c86533e13ba2605f3ecad2e1 + +[PATCH] USB: print message when device is rejected due to insufficient power + +2.6.16 introduces USB power budgeting in the Linux kernel, and since then, a +fair number of users have observed that some of their devices no longer work in +unpowered hubs (this is not a bug, the devices claim that they need more than +100mA). + +The very least we can do is print an informational message to the kernel log +when this happens, otherwise it is not at all clear why the device was not +accepted. + +Signed-off-by: Daniel Drake +Signed-off-by: Greg Kroah-Hartman +--- + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1176,6 +1176,7 @@ static int choose_configuration(struct u + { + int i; + int num_configs; ++ int insufficient_power = 0; + struct usb_host_config *c, *best; + + best = NULL; +@@ -1228,8 +1229,10 @@ static int choose_configuration(struct u + */ + + /* Rule out configs that draw too much bus current */ +- if (c->desc.bMaxPower * 2 > udev->bus_mA) ++ if (c->desc.bMaxPower * 2 > udev->bus_mA) { ++ insufficient_power++; + continue; ++ } + + /* If the first config's first interface is COMM/2/0xff + * (MSFT RNDIS), rule it out unless Linux has host-side +@@ -1263,6 +1266,11 @@ static int choose_configuration(struct u + best = c; + } + ++ if (insufficient_power > 0) ++ dev_info(&udev->dev, "rejected %d configuration%s " ++ "due to insufficient available bus power\n", ++ insufficient_power, plural(insufficient_power)); ++ + if (best) { + i = best->desc.bConfigurationValue; + dev_info(&udev->dev, diff --git a/packages/linux/linux-openzaurus_2.6.16.bb b/packages/linux/linux-openzaurus_2.6.16.bb index 3aa85c1f98..cbb379d399 100644 --- a/packages/linux/linux-openzaurus_2.6.16.bb +++ b/packages/linux/linux-openzaurus_2.6.16.bb @@ -1,6 +1,6 @@ require linux-openzaurus.inc -PR = "r42" +PR = "r45" # Handy URLs # git://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git \ @@ -68,6 +68,7 @@ SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.16.tar.bz2 \ file://00-hostap.patch;patch=1;status=merged \ file://10-pcnet.patch;patch=1;status=merged \ ${RPSRC}/alsa/asoc-v0.10rc4.patch;patch=1 \ + file://maxpower-message.patch;patch=1;status=backported \ ${RPSRC}/asoc_fixups-r0.patch;patch=1 \ ${RPSRC}/hx2750_base-r24.patch;patch=1 \ ${RPSRC}/hx2750_bl-r5.patch;patch=1 \ -- cgit v1.2.3 From 8f9019eb06a381e31968b8ce7a0dcb68c3e7f7d0 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Fri, 8 Sep 2006 17:13:32 +0000 Subject: linux-openzaurus 2.6.17: added HACK which remove some IDs from orinoco_cs to not get it loaded for some cards Revision: c8c9e7a9b6add1a32094dbb3ed061b16831f61c5 from .oz354x --- .../hrw-pcmcia-ids-r3.patch | 31 ++++++++ ...inoco-remove-all-which-are-in-hostap-HACK.patch | 88 ++++++++++++++++++++++ packages/linux/linux-openzaurus_2.6.17.bb | 5 +- 3 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 packages/linux/linux-openzaurus-2.6.17/hrw-pcmcia-ids-r3.patch create mode 100644 packages/linux/linux-openzaurus-2.6.17/orinoco-remove-all-which-are-in-hostap-HACK.patch diff --git a/packages/linux/linux-openzaurus-2.6.17/hrw-pcmcia-ids-r3.patch b/packages/linux/linux-openzaurus-2.6.17/hrw-pcmcia-ids-r3.patch new file mode 100644 index 0000000000..b27fd09068 --- /dev/null +++ b/packages/linux/linux-openzaurus-2.6.17/hrw-pcmcia-ids-r3.patch @@ -0,0 +1,31 @@ + +The ident for Seagate 8GB microdrive is +"SEAGATE", "ST1" +hash 0x76dc4190, 0xcfba9599 +manfid 0x0111, 0x0000 + +CF card: + product info: "SAMSUNG", "04/05/06", "", "" + manfid : 0x0000, 0x0000 + function 4 (fixed disk) + + +Signed-off-by: Marcin Juszkiewicz + + drivers/ide/legacy/ide-cs.c | 1 + + 1 file changed, 1 insertion(+) + +Index: linux-2.6.17/drivers/ide/legacy/ide-cs.c +=================================================================== +--- linux-2.6.17.orig/drivers/ide/legacy/ide-cs.c 2006-06-18 03:49:35.000000000 +0200 ++++ linux-2.6.17/drivers/ide/legacy/ide-cs.c 2006-07-10 23:29:28.696446000 +0200 +@@ -402,6 +402,9 @@ + PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591), + PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), + PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), ++ PCMCIA_DEVICE_PROD_ID12("SEAGATE", "ST1", 0x87c1b330, 0xe1f30883), /* Seagate 8GB microdrive */ ++ PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "04/05/06", 0x43d74cb4, 0x6a22777d), ++ PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6), + PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), + PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), + PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), diff --git a/packages/linux/linux-openzaurus-2.6.17/orinoco-remove-all-which-are-in-hostap-HACK.patch b/packages/linux/linux-openzaurus-2.6.17/orinoco-remove-all-which-are-in-hostap-HACK.patch new file mode 100644 index 0000000000..380349f809 --- /dev/null +++ b/packages/linux/linux-openzaurus-2.6.17/orinoco-remove-all-which-are-in-hostap-HACK.patch @@ -0,0 +1,88 @@ +This patch should resolve problem when people get eth0 (orinoco_cs) instead of wlan0 (hostap_cs) +with their WiFi cards. + +Patch will NEVER been accepted upstream. + +Signed-off-by: Marcin Juszkiewicz + +Index: linux/drivers/net/wireless/orinoco_cs.c +=================================================================== +--- linux.orig/drivers/net/wireless/orinoco_cs.c 2006-08-23 16:04:10.000000000 +0200 ++++ linux/drivers/net/wireless/orinoco_cs.c 2006-08-23 16:17:43.000000000 +0200 +@@ -453,33 +453,21 @@ + "Pavel Roskin , et al)"; + + static struct pcmcia_device_id orinoco_cs_ids[] = { +- PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */ +- PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */ + PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */ +- PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */ +- PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */ + PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */ + PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */ + PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */ + PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */ + PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */ +- PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */ + PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */ + PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */ + PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */ +- PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */ +- PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */ +- PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */ + PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */ +- PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ + PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ + PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ +- PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ + PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ + PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */ + PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */ +- PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */ +- PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */ + PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9), + PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), + PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5), +@@ -487,31 +475,25 @@ + PCMCIA_DEVICE_PROD_ID123("AIRVAST", "IEEE 802.11b Wireless PCMCIA Card", "HFA3863", 0xea569531, 0x4bcb9645, 0x355cb092), + PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f), + PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842), +- PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e), + PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169), + PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb), + PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3), +- PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), + PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90), +- PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b), + PCMCIA_DEVICE_PROD_ID123("corega", "WL PCCL-11", "ISL37300P", 0x0a21501a, 0x59868926, 0xc9049a39), + PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584), + PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9), + PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae), + PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac), +- PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab), + PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916), + PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146), + PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3), + PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c), + PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), + PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077), +- PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), + PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77), + PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf), + PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2), + PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92), +- PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395), + PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a), + PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410), + PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3), +@@ -529,10 +511,8 @@ + PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26), + PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b), + PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), +- PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), + PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e), + PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39), +- PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), + PCMCIA_DEVICE_NULL, + }; + MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids); diff --git a/packages/linux/linux-openzaurus_2.6.17.bb b/packages/linux/linux-openzaurus_2.6.17.bb index a1bcec9b86..8a3e49eaee 100644 --- a/packages/linux/linux-openzaurus_2.6.17.bb +++ b/packages/linux/linux-openzaurus_2.6.17.bb @@ -1,6 +1,6 @@ require linux-openzaurus.inc -PR = "r22" +PR = "r23" # Handy URLs # git://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git \ @@ -29,7 +29,7 @@ SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.17.tar.bz2 \ file://00-hostap.patch;patch=1;status=merged \ file://10-pcnet.patch;patch=1;status=merged \ ${RPSRC}/alsa/asoc-v0.11.3.patch;patch=1 \ - ${RPSRC}/alsa/asoc_zaurus_fixups-r0.patch;patch=1 \ + ${RPSRC}/alsa/asoc_zaurus_fixups-r0.patch;patch=1 \ ${RPSRC}/asoc_makefile-r0.patch;patch=1 \ ${RPSRC}/hx2750_base-r27.patch;patch=1 \ ${RPSRC}/hx2750_bl-r7.patch;patch=1 \ @@ -62,6 +62,7 @@ SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.17.tar.bz2 \ ${RPSRC}/pxa_cf_initorder_hack-r1.patch;patch=1;status=hack \ file://pxa-serial-hack.patch;patch=1;status=hack \ file://connectplus-remove-ide-HACK.patch;patch=1;status=hack \ + file://orinoco-remove-all-which-are-in-hostap-HACK.patch;patch=1;status=unmergable-hack \ file://squashfs3.0-2.6.15.patch;patch=1;status=external \ file://defconfig-c7x0 \ file://defconfig-ipaq-pxa270 \ -- cgit v1.2.3 From bd6fa171e042c8a0011bcb32e6f5bb95ee32f75c Mon Sep 17 00:00:00 2001 From: Frans Meulenbroeks Date: Fri, 8 Sep 2006 20:56:53 +0000 Subject: slugos-packages: demoted ushare for ucslugc --- packages/meta/slugos-packages.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/meta/slugos-packages.bb b/packages/meta/slugos-packages.bb index 3b1ffb306c..888e9d5a0e 100644 --- a/packages/meta/slugos-packages.bb +++ b/packages/meta/slugos-packages.bb @@ -6,7 +6,7 @@ DESCRIPTION = "Packages that are compatible with the SlugOS firmware" MAINTAINER = "NSLU2 Linux " HOMEPAGE = "http://www.nslu2-linux.org" LICENSE = "MIT" -PR = "r12" +PR = "r13" CONFLICTS = "db3" PROVIDES += "${SLUGOS_IMAGENAME}-packages" @@ -164,7 +164,6 @@ SLUGOS_PACKAGES = "\ tiff \ unzip \ usbutils \ - ushare \ util-linux \ vim \ vlan \ @@ -186,6 +185,7 @@ SLUGOS_BROKEN_PACKAGES = "\ qc-usb-messenger \ unionfs-modules \ unionfs-utils \ + ushare \ " # These packages will never build because uclibc lacks (and always will lack) -- cgit v1.2.3 From 852cf86599c0e59c00e0fee8590f64dab31c077b Mon Sep 17 00:00:00 2001 From: Frans Meulenbroeks Date: Fri, 8 Sep 2006 20:57:50 +0000 Subject: ushare: added two missing DEPENDS --- packages/ushare/ushare_0.9.7.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ushare/ushare_0.9.7.bb b/packages/ushare/ushare_0.9.7.bb index a922fed2d0..539126c7a1 100644 --- a/packages/ushare/ushare_0.9.7.bb +++ b/packages/ushare/ushare_0.9.7.bb @@ -2,9 +2,9 @@ DESCRIPTION = "ushare is a UPnP media server" LICENSE = "GPL" HOMEPAGE = "http://ushare.geexbox.org/" MAINTAINER = "eFfeM " -DEPENDS = "libupnp" +DEPENDS = "libupnp virtual/libiconv virtual/libintl" SRC_URI = "http://ushare.geexbox.org/releases/ushare-0.9.7.tar.bz2" S = "${WORKDIR}/ushare-${PV}" -PR = "r0" +PR = "r1" inherit autotools -- cgit v1.2.3 From 80dc026cbf171b5eb9eab9c828861202e5106e2c Mon Sep 17 00:00:00 2001 From: Frans Meulenbroeks Date: Fri, 8 Sep 2006 21:02:58 +0000 Subject: slugos-packages: commented out icecast: for some reason it is moved to nonworking. --- packages/meta/slugos-packages.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/meta/slugos-packages.bb b/packages/meta/slugos-packages.bb index 888e9d5a0e..fe9cb506d5 100644 --- a/packages/meta/slugos-packages.bb +++ b/packages/meta/slugos-packages.bb @@ -6,7 +6,7 @@ DESCRIPTION = "Packages that are compatible with the SlugOS firmware" MAINTAINER = "NSLU2 Linux " HOMEPAGE = "http://www.nslu2-linux.org" LICENSE = "MIT" -PR = "r13" +PR = "r14" CONFLICTS = "db3" PROVIDES += "${SLUGOS_IMAGENAME}-packages" @@ -74,7 +74,7 @@ SLUGOS_PACKAGES = "\ gtk-doc \ gzip \ hdparm \ - icecast \ +# icecast \ ifupdown \ ipkg-utils \ iptables \ -- cgit v1.2.3 From aab6bff5f468bb98efdc737fba3726a3aaf00598 Mon Sep 17 00:00:00 2001 From: Holger Freyther Date: Fri, 8 Sep 2006 21:27:28 +0000 Subject: conf/bitbake.conf: Add FETCHCOMMAND and UPDATECOMMAND for subversion Adding these commands is needed to work with a future BitBake trunk version. SVN fetcher will behave more like the cvs fetcher and keep the co around. --- conf/bitbake.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conf/bitbake.conf b/conf/bitbake.conf index 2e3cb0f980..f02259ddc5 100644 --- a/conf/bitbake.conf +++ b/conf/bitbake.conf @@ -327,10 +327,12 @@ APACHE_MIRROR = "http://www.apache.org/dist" FETCHCOMMAND = "ERROR, this must be a BitBake bug" FETCHCOMMAND_wget = "/usr/bin/env wget -t 5 --passive-ftp -P ${DL_DIR} ${URI}" FETCHCOMMAND_cvs = "/usr/bin/env cvs -d${CVSROOT} co ${CVSCOOPTS} ${CVSMODULE}" +FETCHCOMMAND_svn = "/usr/bin/env svn co ${SVNCOOPTS} ${SVNROOT} ${SVNMODULE}" RESUMECOMMAND = "ERROR, this must be a BitBake bug" RESUMECOMMAND_wget = "/usr/bin/env wget -c -t 5 --passive-ftp -P ${DL_DIR} ${URI}" UPDATECOMMAND = "ERROR, this must be a BitBake bug" UPDATECOMMAND_cvs = "/usr/bin/env cvs -d${CVSROOT} update -d -P ${CVSCOOPTS}" +UPDATECOMMAND_svn = "/usr/bin/env svn update ${SVNCOOPTS}" SRCDATE = "${DATE}" SRC_URI = "file://${FILE}" -- cgit v1.2.3 From 7a5fda233c8cf37fc0338f13229703b0f837a1f0 Mon Sep 17 00:00:00 2001 From: Holger Freyther Date: Fri, 8 Sep 2006 21:35:51 +0000 Subject: conf/bitbake.conf: Add a SVNDIR similiar to GITDIR and CVSDIR as well --- conf/bitbake.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/bitbake.conf b/conf/bitbake.conf index f02259ddc5..fe0ff05e13 100644 --- a/conf/bitbake.conf +++ b/conf/bitbake.conf @@ -137,6 +137,7 @@ TMPDIR = "${TOPDIR}/tmp" CACHE = "${TMPDIR}/cache" DL_DIR = "${TMPDIR}/downloads" CVSDIR = "${DL_DIR}/cvs" +SVNDIR = "${DL_DIR}/svn" GITDIR = "${DL_DIR}/git" STAMP = "${TMPDIR}/stamps/${PF}" -- cgit v1.2.3 From e776e094a54c4141b4f1797cec5e1f1823687587 Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Sat, 9 Sep 2006 00:01:01 +0000 Subject: slugos-packages: Move ushare to uclibc broken packages, not generic --- packages/meta/slugos-packages.bb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/meta/slugos-packages.bb b/packages/meta/slugos-packages.bb index fe9cb506d5..12aaf89ca5 100644 --- a/packages/meta/slugos-packages.bb +++ b/packages/meta/slugos-packages.bb @@ -185,7 +185,6 @@ SLUGOS_BROKEN_PACKAGES = "\ qc-usb-messenger \ unionfs-modules \ unionfs-utils \ - ushare \ " # These packages will never build because uclibc lacks (and always will lack) @@ -207,6 +206,7 @@ UCLIBC_BROKEN_PACKAGES = "\ boost \ linphone \ sudo \ + ushare \ " # Packages which build only with glibc (some of these use internal -- cgit v1.2.3 From e22c47b69764b6a41b86aa256e9d84265c7986de Mon Sep 17 00:00:00 2001 From: Oyvind Repvik Date: Sat, 9 Sep 2006 00:03:10 +0000 Subject: slugos-packages: Remove icecast, add note about commenting --- packages/meta/slugos-packages.bb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/meta/slugos-packages.bb b/packages/meta/slugos-packages.bb index 12aaf89ca5..b35b50c83f 100644 --- a/packages/meta/slugos-packages.bb +++ b/packages/meta/slugos-packages.bb @@ -16,6 +16,9 @@ ALLOW_EMPTY = 1 # The list of packages to build for the slugos DISTRO. # KEEP IN ALPHABETICAL ORDER +# Do *not* simply comment out a line. That will break. Instead +# remove the package and place it in the corresponding "broken" list + SLUGOS_PACKAGES = "\ alsa-lib \ alsa-utils \ @@ -74,7 +77,6 @@ SLUGOS_PACKAGES = "\ gtk-doc \ gzip \ hdparm \ -# icecast \ ifupdown \ ipkg-utils \ iptables \ @@ -185,6 +187,7 @@ SLUGOS_BROKEN_PACKAGES = "\ qc-usb-messenger \ unionfs-modules \ unionfs-utils \ + icecast \ " # These packages will never build because uclibc lacks (and always will lack) -- cgit v1.2.3 From 7dda5b6d608fcb6f3d2264ae0038050b8f209231 Mon Sep 17 00:00:00 2001 From: Cyril Romain Date: Sat, 9 Sep 2006 00:13:06 +0000 Subject: sanitize.py: Revision 0.4 * formatting changes * functions with better names * useless or unused variables removed * comments added --- contrib/sanitize.py | 143 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 84 insertions(+), 59 deletions(-) diff --git a/contrib/sanitize.py b/contrib/sanitize.py index e38c28c13f..5239b09186 100755 --- a/contrib/sanitize.py +++ b/contrib/sanitize.py @@ -1,20 +1,29 @@ #!/usr/bin/env python -# sanitize a bitbake file following the OpenEmbedded style guidelines -# see http://openembedded.org/wiki/StyleGuide -# (C) 2006 Cyril Romain -# MIT license +""" sanitize a bitbake file following the OpenEmbedded style guidelines -# TODO: -# - add the others OpenEmbedded variables commonly used -# ./ handle comments in .bb files -# - parse command arguments and print usage on misuse -# . prevent giving more than one .bb file in arguments -# - write result to a file -# - backup the original .bb file -# - make a diff and ask confirmation for patching ? -# - /!\ startswith('SOMETHING') is not taken into account due to the previous startswith('S'). -# - count rule breaks and displays them in the order frequence +see http://openembedded.org/wiki/StyleGuide +(C) 2006 Cyril Romain +MIT license + +This script requires the odict module written by Nicola Larosa and Michael +Foord. +To get the odict module is available on: + Debian: apt-get install rest2web + Gentoo: emerge pythonutils + or can be download here: http://www.voidspace.org.uk/python/odict.html + +TODO: + - add the others OpenEmbedded variables commonly used: + - parse command arguments and print usage on misuse + . prevent giving more than one .bb file in arguments + - write result to a file + - backup the original .bb file + - make a diff and ask confirmation for patching ? + - do not use startswith only: + /!\ startswith('SOMETHING') is not taken into account due to the previous startswith('S'). + - count rule breaks and displays them in the order frequence +""" from odict import OrderedDict import fileinput @@ -22,9 +31,9 @@ import string import re __author__ = "Cyril Romain " -__version__ = "$Revision: 0.3 $" +__version__ = "$Revision: 0.4 $" -# The ordered list of OpenEmbedded variables +# The standard set of variables often found in .bb files in the preferred order OE_vars = OrderedDict([ ('DESCRIPTION', []), ('AUTHOR', []), @@ -45,6 +54,7 @@ OE_vars = OrderedDict([ ('PR', []), ('SRC_URI', []), ('S', []), + ('GPE_TARBALL_SUFFIX', []), ('inherit', []), ('EXTRA_', []), ('do_fetch', []), @@ -128,7 +138,6 @@ OE_vars = OrderedDict([ ('GLIBC_ADDONS', []), ('GLIBC_EXTRA_OECONF', []), ('GNOME_VFS_HEADERS', []), - ('GPE_TARBALL_SUFFIX', []), ('HEADERS', []), ('INHIBIT_DEFAULT_DEPS', []), ('INITSCRIPT_NAME', []), @@ -201,90 +210,108 @@ OE_vars = OrderedDict([ varRegexp = r'^([A-Z_0-9]*)([ \t]*?)([+.:]?=[+.]?)([ \t]*?)("[^"]*["\\]?)' routineRegexp = r'^([a-zA-Z0-9_ -]+?)\(' -# Style guideline #0: No spaces are allowed at the beginning of lines that define a variable or a do_ routine -def check_rule0(line): +# _Format guideline #0_: +# No spaces are allowed at the beginning of lines that define a variable or +# a do_ routine +def respect_rule0(line): return line.lstrip()==line -def follow_rule0(line): +def conformTo_rule0(line): return line.lstrip() -# Style guideline #1: No spaces are allowed behind the line continuation symbol '\' -def check_rule1(line): +# _Format guideline #1_: +# No spaces are allowed behind the line continuation symbol '\' +def respect_rule1(line): if line.rstrip().endswith('\\'): return line.endswith('\\') else: return True -def follow_rule1(line): +def conformTo_rule1(line): return line.rstrip() -# Style guideline #2: Tabs should not be used (use spaces instead). -def check_rule2(line): +# _Format guideline #2_: +# Tabs should not be used (use spaces instead). +def respect_rule2(line): return line.count('\t')==0 -def follow_rule2(line): +def conformTo_rule2(line): return line.expandtabs() -# Style guideline #3: Comments inside bb files are allowed using the '#' character at the beginning of a line. -def check_rule3(line): +# _Format guideline #3_: +# Comments inside bb files are allowed using the '#' character at the +# beginning of a line. +def respect_rule3(line): if line.lstrip().startswith('#'): return line.startswith('#') else: return True -def follow_rule3(line): +def conformTo_rule3(line): return line.lstrip() -# Style guideline #4: Use quotes on the right hand side of assignments: FOO = "BAR" -def check_rule4(line): +# _Format guideline #4_: +# Use quotes on the right hand side of assignments: FOO = "BAR" +def respect_rule4(line): return re.match(varRegexp, line) is not None -def follow_rule4(line): - return follow_rule5(line) +def conformTo_rule4(line): + return conformTo_rule5_(line) -# Style guideline #5: The correct spacing for a variable is FOO = "BAR". -def check_rule5(line): +# _Format guideline #5_: +# The correct spacing for a variable is FOO = "BAR". +def respect_rule5(line): r = re.search(varRegexp, line) return r is not None and r.group(2)==" " and r.group(4)==" " -def follow_rule5(line): +def conformTo_rule5(line): r = re.search(varRegexp, line) return ''.join([r.group(1), ' ', r.group(3), ' ', r.group(5)]) -# Style guideline #6: Don't use spaces or tabs on empty lines -def check_rule6(line): +# _Format guideline #6_: +# Don't use spaces or tabs on empty lines +def respect_rule6(line): return not line.isspace() or line=="\n" -def follow_rule6(line): +def conformTo_rule6(line): return "" -# Style guideline #7: Indentation of multiline variables such as SRC_URI is desireable. -def check_rule7(line): +# _Format guideline #7_: +# Indentation of multiline variables such as SRC_URI is desireable. +def respect_rule7(line): return True -def follow_rule7(line): +def conformTo_rule7(line): return line rules = ( - (check_rule0, follow_rule0, "No spaces are allowed at the beginning of lines that define a variable or a do_ routine"), - (check_rule1, follow_rule1, "No spaces are allowed behind the line continuation symbol '\\'"), - (check_rule2, follow_rule2, "Tabs should not be used (use spaces instead)"), - (check_rule3, follow_rule3, "Comments inside bb files are allowed using the '#' character at the beginning of a line"), - (check_rule4, follow_rule4, "Use quotes on the right hand side of assignments: FOO = \"BAR\""), - (check_rule5, follow_rule5, "The correct spacing for a variable is FOO = \"BAR\""), - (check_rule6, follow_rule6, "Don't use spaces or tabs on empty lines"), - (check_rule7, follow_rule7, "Indentation of multiline variables such as SRC_URI is desireable"), + (respect_rule0, conformTo_rule0, "No spaces are allowed at the beginning of lines that define a variable or a do_ routine"), + (respect_rule1, conformTo_rule1, "No spaces are allowed behind the line continuation symbol '\\'"), + (respect_rule2, conformTo_rule2, "Tabs should not be used (use spaces instead)"), + (respect_rule3, conformTo_rule3, "Comments inside bb files are allowed using the '#' character at the beginning of a line"), + (respect_rule4, conformTo_rule4, "Use quotes on the right hand side of assignments: FOO = \"BAR\""), + (respect_rule5, conformTo_rule5, "The correct spacing for a variable is FOO = \"BAR\""), + (respect_rule6, conformTo_rule6, "Don't use spaces or tabs on empty lines"), + (respect_rule7, conformTo_rule7, "Indentation of multiline variables such as SRC_URI is desireable"), ) +# Function to check that a line respects a rule. If not, it tries to conform +# the line to the rule. Reminder or Disgression message are dump accordingly. def follow_rule(i, line): oldline = line + # if the line does not respect the rule if not rules[i][0](line): + # try to conform it to the rule line = rules[i][1](line) + # if the line still does not respect the rule if not rules[i][0](line): - print "## Rule %d disgression: on this line: " % i, line - print "## Warning: ", rules[i][2] + # this is a rule disgression + print "## Disgression: ", rules[i][2], " in:", line else: + # just remind user about his/her errors print "## Reminder: ", rules[i][2], " in :", oldline return line if __name__ == "__main__": - # -- retrieves lines of the .bb file -- + # -- retrieves the lines of the .bb file -- lines = [] for line in fileinput.input(): + # use 'if True' to warn user about all the rule he/she breaks + # use 'if False' to conform to rules{2,1,6} without warnings if True: lines.append(line) else: @@ -301,12 +328,13 @@ if __name__ == "__main__": in_routine = False commentBloc = [] olines = [] - unknownVar = [] for line in lines: + # rstrip line to remove line breaks characters line = line.rstrip() line = follow_rule(2, line) line = follow_rule(1, line) line = follow_rule(6, line) + # ignore empty lines if line.isspace() or line is '': # flush comments into the olines @@ -348,15 +376,12 @@ if __name__ == "__main__": var = (keep==True or in_routine==True) and k or "" break if not varexist: - s = string.split(line)[0].rstrip().lstrip() - if s not in unknownVar: - unknownVar.append(s) if not in_routine: print "## Warning: unknown variable/routine \"%s\"" % line OE_vars['others'].append(line) if not keep and not in_routine: var = "" - # -- prepare the sanitized .bb file -- + # -- dump the sanitized .bb file -- #for k in OE_vars: print k, OE_vars[k] addEmptyLine = False for k in OE_vars: @@ -366,4 +391,4 @@ if __name__ == "__main__": for l in OE_vars[k]: olines.append(l) for line in olines: print line - #for i in unknownVar: print i, '\n' + -- cgit v1.2.3 From 0e3eb51fbcc63f041b10ae1ffda4b066bb9ad7b7 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 9 Sep 2006 00:50:37 +0000 Subject: sanitize.py: Drop odict dependency. --- contrib/sanitize.py | 378 ++++++++++++++++++++++++++-------------------------- 1 file changed, 188 insertions(+), 190 deletions(-) diff --git a/contrib/sanitize.py b/contrib/sanitize.py index 5239b09186..27ca6e3d8d 100755 --- a/contrib/sanitize.py +++ b/contrib/sanitize.py @@ -1,18 +1,12 @@ #!/usr/bin/env python -""" sanitize a bitbake file following the OpenEmbedded style guidelines - +"""\ +Sanitize a bitbake file following the OpenEmbedded style guidelines, see http://openembedded.org/wiki/StyleGuide + (C) 2006 Cyril Romain MIT license -This script requires the odict module written by Nicola Larosa and Michael -Foord. -To get the odict module is available on: - Debian: apt-get install rest2web - Gentoo: emerge pythonutils - or can be download here: http://www.voidspace.org.uk/python/odict.html - TODO: - add the others OpenEmbedded variables commonly used: - parse command arguments and print usage on misuse @@ -25,7 +19,6 @@ TODO: - count rule breaks and displays them in the order frequence """ -from odict import OrderedDict import fileinput import string import re @@ -34,182 +27,187 @@ __author__ = "Cyril Romain " __version__ = "$Revision: 0.4 $" # The standard set of variables often found in .bb files in the preferred order -OE_vars = OrderedDict([ - ('DESCRIPTION', []), - ('AUTHOR', []), - ('HOMEPAGE', []), - ('SECTION', []), - ('PRIORITY', []), - ('MAINTAINER', []), - ('LICENSE', []), - ('DEPENDS', []), - ('RDEPENDS', []), - ('RRECOMMENDS', []), - ('RSUGGESTS', []), - ('PROVIDES', []), - ('RPROVIDES', []), - ('RCONFLICTS', []), - ('SRCDATE', []), - ('PV', []), - ('PR', []), - ('SRC_URI', []), - ('S', []), - ('GPE_TARBALL_SUFFIX', []), - ('inherit', []), - ('EXTRA_', []), - ('do_fetch', []), - ('do_unpack', []), - ('do_patch', []), - ('do_configure', []), - ('do_compile', []), - ('do_install', []), - ('do_package', []), - ('do_stage', []), - ('PACKAGE_ARCH', []), - ('PACKAGES', []), - ('FILES', []), - ('WORKDIR', []), - ('acpaths', []), - ('addhandler', []), - ('addtask', []), - ('bindir', []), - ('export', []), - ('headers', []), - ('include', []), - ('includedir', []), - ('python', []), - ('qtopiadir', []), - ('pkg_postins', []), - ('pkg_postrm', []), - ('require', []), - ('sbindir', []), - ('basesysconfdir', []), - ('sysconfdir', []), - ('ALLOW_EMPTY', []), - ('ALTERNATIVE_LINK', []), - ('ALTERNATIVE_NAME', []), - ('ALTERNATIVE_PATH', []), - ('ALTERNATIVE_PRIORITY', []), - ('ALTNAME', []), - ('AMD_DRIVER_LABEL', []), - ('AMD_DRIVER_VERSION', []), - ('ANGSTROM_EXTRA_INSTALL', []), - ('APPDESKTOP', []), - ('APPIMAGE', []), - ('APPNAME', []), - ('APPTYPE', []), - ('APPWEB_BUILD', []), - ('APPWEB_HOST', []), - ('AR', []), - ('ARCH', []), - ('ARM_INSTRUCTION_SET', []), - ('ARM_MUTEX', []), - ('ART_CONFIG', []), - ('B', []), - ('BJAM_OPTS', []), - ('BJAM_TOOLS', []), - ('BONOBO_HEADERS', []), - ('BOOTSCRIPTS', []), - ('BROKEN', []), - ('BUILD_ALL_DEPS', []), - ('BUILD_CPPFLAGS', []), - ('CFLAGS', []), - ('CCFLAGS', []), - ('CMDLINE', []), - ('COLLIE_MEMORY_SIZE', []), - ('COMPATIBLE_HOST', []), - ('COMPATIBLE_MACHINE', []), - ('COMPILE_HERMES', []), - ('CONFFILES', []), - ('CONFLICTS', []), - ('CORE_EXTRA_D', []), - ('CORE_PACKAGES_D', []), - ('CORE_PACKAGES_RD', []), - ('CPPFLAGS', []), - ('CVSDATE', []), - ('CXXFLAGS', []), - ('DEBIAN_NOAUTONAME', []), - ('DEBUG_APPS', []), - ('DEFAULT_PREFERENCE', []), - ('DB4_CONFIG', []), - ('EXCLUDE_FROM_SHLIBS', []), - ('EXCLUDE_FROM_WORLD', []), - ('FIXEDSRCDATE', []), - ('GLIBC_ADDONS', []), - ('GLIBC_EXTRA_OECONF', []), - ('GNOME_VFS_HEADERS', []), - ('HEADERS', []), - ('INHIBIT_DEFAULT_DEPS', []), - ('INITSCRIPT_NAME', []), - ('INITSCRIPT_PACKAGES', []), - ('INITSCRIPT_PARAMS', []), - ('IPKG_INSTALL', []), - ('KERNEL_IMAGETYPE', []), - ('KERNEL_IMAGEDEST', []), - ('KERNEL_OUTPUT', []), - ('KERNEL_RELEASE', []), - ('KERNEL_PRIORITY', []), - ('KERNEL_SOURCE', []), - ('KERNEL_SUFFIX', []), - ('KERNEL_VERSION', []), - ('K_MAJOR', []), - ('K_MICRO', []), - ('K_MINOR', []), - ('HHV', []), - ('KV', []), - ('LDFLAGS', []), - ('LD', []), - ('LD_SO', []), - ('LDLIBS', []), - ('LEAD_SONAME', []), - ('LIBTOOL', []), - ('LIBBDB_EXTRA', []), - ('LIBV', []), - ('MACHINE', []), - ('MACHINE_ESSENTIAL_EXTRA_RDEPENDS', []), - ('MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS', []), - ('MACHINE_EXTRA_RDEPENDS', []), - ('MACHINE_EXTRA_RRECOMMENDS', []), - ('MACHINE_FEATURES', []), - ('MACHINE_TASKS', []), - ('MACHTYPE', []), - ('MAKE_TARGETS', []), - ('MESSAGEUSER', []), - ('MESSAGEHOME', []), - ('MIRRORS', []), - ('MUTEX', []), - ('OE_QMAKE_INCDIR_QT', []), - ('OE_QMAKE_CXXFLAGS', []), - ('ORBIT_IDL_SRC', []), - ('PARALLEL_MAKE', []), - ('PAKCAGE_ARCH', []), - ('PCMCIA_MANAGER', []), - ('PKG_BASENAME', []), - ('QEMU', []), - ('QMAKE_PROFILES', []), - ('QPEDIR', []), - ('QPF_DESCRIPTION', []), - ('QPF_PKGPATTERN', []), - ('QT_CONFIG_FLAGS', []), - ('QT_LIBRARY', []), - ('ROOTFS_POSTPROCESS_COMMAND', []), - ('RREPLACES', []), - ('TARGET_CFLAGS', []), - ('TARGET_CPPFLAGS', []), - ('TARGET_LDFLAGS', []), - ('UBOOT_MACHINE', []), - ('UCLIBC_BASE', []), - ('UCLIBC_PATCHES', []), - ('UNSLUNG_PACKAGES', []), - ('VIRTUAL_NAME', []), - ('XORG_PN', []), - ('XSERVER', []), - ('others', []) -]) +OE_vars = [ + 'DESCRIPTION', + 'AUTHOR', + 'HOMEPAGE', + 'SECTION', + 'PRIORITY', + 'MAINTAINER', + 'LICENSE', + 'DEPENDS', + 'RDEPENDS', + 'RRECOMMENDS', + 'RSUGGESTS', + 'PROVIDES', + 'RPROVIDES', + 'RCONFLICTS', + 'SRCDATE', + 'PV', + 'PR', + 'SRC_URI', + 'S', + 'GPE_TARBALL_SUFFIX', + 'inherit', + 'EXTRA_', + 'do_fetch', + 'do_unpack', + 'do_patch', + 'do_configure', + 'do_compile', + 'do_install', + 'do_package', + 'do_stage', + 'PACKAGE_ARCH', + 'PACKAGES', + 'FILES', + 'WORKDIR', + 'acpaths', + 'addhandler', + 'addtask', + 'bindir', + 'export', + 'headers', + 'include', + 'includedir', + 'python', + 'qtopiadir', + 'pkg_postins', + 'pkg_postrm', + 'require', + 'sbindir', + 'basesysconfdir', + 'sysconfdir', + 'ALLOW_EMPTY', + 'ALTERNATIVE_LINK', + 'ALTERNATIVE_NAME', + 'ALTERNATIVE_PATH', + 'ALTERNATIVE_PRIORITY', + 'ALTNAME', + 'AMD_DRIVER_LABEL', + 'AMD_DRIVER_VERSION', + 'ANGSTROM_EXTRA_INSTALL', + 'APPDESKTOP', + 'APPIMAGE', + 'APPNAME', + 'APPTYPE', + 'APPWEB_BUILD', + 'APPWEB_HOST', + 'AR', + 'ARCH', + 'ARM_INSTRUCTION_SET', + 'ARM_MUTEX', + 'ART_CONFIG', + 'B', + 'BJAM_OPTS', + 'BJAM_TOOLS', + 'BONOBO_HEADERS', + 'BOOTSCRIPTS', + 'BROKEN', + 'BUILD_ALL_DEPS', + 'BUILD_CPPFLAGS', + 'CFLAGS', + 'CCFLAGS', + 'CMDLINE', + 'COLLIE_MEMORY_SIZE', + 'COMPATIBLE_HOST', + 'COMPATIBLE_MACHINE', + 'COMPILE_HERMES', + 'CONFFILES', + 'CONFLICTS', + 'CORE_EXTRA_D', + 'CORE_PACKAGES_D', + 'CORE_PACKAGES_RD', + 'CPPFLAGS', + 'CVSDATE', + 'CXXFLAGS', + 'DEBIAN_NOAUTONAME', + 'DEBUG_APPS', + 'DEFAULT_PREFERENCE', + 'DB4_CONFIG', + 'EXCLUDE_FROM_SHLIBS', + 'EXCLUDE_FROM_WORLD', + 'FIXEDSRCDATE', + 'GLIBC_ADDONS', + 'GLIBC_EXTRA_OECONF', + 'GNOME_VFS_HEADERS', + 'HEADERS', + 'INHIBIT_DEFAULT_DEPS', + 'INITSCRIPT_NAME', + 'INITSCRIPT_PACKAGES', + 'INITSCRIPT_PARAMS', + 'IPKG_INSTALL', + 'KERNEL_IMAGETYPE', + 'KERNEL_IMAGEDEST', + 'KERNEL_OUTPUT', + 'KERNEL_RELEASE', + 'KERNEL_PRIORITY', + 'KERNEL_SOURCE', + 'KERNEL_SUFFIX', + 'KERNEL_VERSION', + 'K_MAJOR', + 'K_MICRO', + 'K_MINOR', + 'HHV', + 'KV', + 'LDFLAGS', + 'LD', + 'LD_SO', + 'LDLIBS', + 'LEAD_SONAME', + 'LIBTOOL', + 'LIBBDB_EXTRA', + 'LIBV', + 'MACHINE', + 'MACHINE_ESSENTIAL_EXTRA_RDEPENDS', + 'MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS', + 'MACHINE_EXTRA_RDEPENDS', + 'MACHINE_EXTRA_RRECOMMENDS', + 'MACHINE_FEATURES', + 'MACHINE_TASKS', + 'MACHTYPE', + 'MAKE_TARGETS', + 'MESSAGEUSER', + 'MESSAGEHOME', + 'MIRRORS', + 'MUTEX', + 'OE_QMAKE_INCDIR_QT', + 'OE_QMAKE_CXXFLAGS', + 'ORBIT_IDL_SRC', + 'PARALLEL_MAKE', + 'PAKCAGE_ARCH', + 'PCMCIA_MANAGER', + 'PKG_BASENAME', + 'QEMU', + 'QMAKE_PROFILES', + 'QPEDIR', + 'QPF_DESCRIPTION', + 'QPF_PKGPATTERN', + 'QT_CONFIG_FLAGS', + 'QT_LIBRARY', + 'ROOTFS_POSTPROCESS_COMMAND', + 'RREPLACES', + 'TARGET_CFLAGS', + 'TARGET_CPPFLAGS', + 'TARGET_LDFLAGS', + 'UBOOT_MACHINE', + 'UCLIBC_BASE', + 'UCLIBC_PATCHES', + 'UNSLUNG_PACKAGES', + 'VIRTUAL_NAME', + 'XORG_PN', + 'XSERVER', + 'others' +] varRegexp = r'^([A-Z_0-9]*)([ \t]*?)([+.:]?=[+.]?)([ \t]*?)("[^"]*["\\]?)' routineRegexp = r'^([a-zA-Z0-9_ -]+?)\(' +# Variables seen in the processed .bb +seen_vars = {} +for v in OE_vars: + seen_vars[v] = [] + # _Format guideline #0_: # No spaces are allowed at the beginning of lines that define a variable or # a do_ routine @@ -353,11 +351,11 @@ if __name__ == "__main__": commentBloc.append(line) continue - if OE_vars.has_key(var): + if seen_vars.has_key(var): for c in commentBloc: - OE_vars[var].append(c) + seen_vars[var].append(c) commentBloc = [] - OE_vars[var].append(line) + seen_vars[var].append(line) else: varexist = False for k in OE_vars: @@ -370,15 +368,15 @@ if __name__ == "__main__": line = follow_rule(4, line) line = follow_rule(5, line) for c in commentBloc: - OE_vars[k].append(c) + seen_vars[k].append(c) commentBloc = [] - OE_vars[k].append(line) + seen_vars[k].append(line) var = (keep==True or in_routine==True) and k or "" break if not varexist: if not in_routine: print "## Warning: unknown variable/routine \"%s\"" % line - OE_vars['others'].append(line) + seen_vars['others'].append(line) if not keep and not in_routine: var = "" # -- dump the sanitized .bb file -- @@ -386,9 +384,9 @@ if __name__ == "__main__": addEmptyLine = False for k in OE_vars: if k=='SRC_URI': addEmptyLine = True - if OE_vars[k] != []: + if seen_vars[k] != []: if addEmptyLine: olines.append("") - for l in OE_vars[k]: + for l in seen_vars[k]: olines.append(l) for line in olines: print line -- cgit v1.2.3 From 66dbbbfa587a752b6040e175a8fc3b18995e6bf9 Mon Sep 17 00:00:00 2001 From: Jamie Lenehan Date: Sat, 9 Sep 2006 04:50:21 +0000 Subject: gd 2.0.33: Don't search for the X11 headers. Without this hosts that have X11 headers in /usr/include/X11 and not in /usr/X11R6/include will get a cross-compile badness error from the compiler from tying to use the host includes. --- packages/gd/gd_2.0.33.bb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/gd/gd_2.0.33.bb b/packages/gd/gd_2.0.33.bb index 4415c81cc9..1d564fced9 100644 --- a/packages/gd/gd_2.0.33.bb +++ b/packages/gd/gd_2.0.33.bb @@ -13,7 +13,8 @@ inherit autotools binconfig gettext EXTRA_OECONF += " --with-zlib=${STAGING_LIBDIR}/.. \ --with-png=${STAGING_LIBDIR}/.. \ --with-jpeg=${STAGING_LIBDIR}/.. \ - --without-xpm" + --without-xpm \ + --without-x" EXTRA_OEMAKE = "LDFLAGS=-L${STAGING_LIBDIR}" -- cgit v1.2.3 From dea0a8631e64cef54a98708865ca016092479dbf Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sat, 9 Sep 2006 08:19:47 +0000 Subject: linux-oz-2.6: poodle compile fixes --- packages/linux/linux-openzaurus_2.6.17.bb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/linux/linux-openzaurus_2.6.17.bb b/packages/linux/linux-openzaurus_2.6.17.bb index 8a3e49eaee..46657f9837 100644 --- a/packages/linux/linux-openzaurus_2.6.17.bb +++ b/packages/linux/linux-openzaurus_2.6.17.bb @@ -1,6 +1,6 @@ require linux-openzaurus.inc -PR = "r23" +PR = "r24" # Handy URLs # git://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git \ @@ -46,10 +46,10 @@ SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.17.tar.bz2 \ ${RPSRC}/usb_add_epalloc-r1.patch;patch=1 \ ${DOSRC}/kexec-arm-r3.patch;patch=1 \ ${RPSRC}/locomo_kbd_tweak-r1.patch;patch=1 \ - ${RPSRC}/poodle_pm-r2.patch;patch=1 \ + ${RPSRC}/poodle_pm-r3.patch;patch=1 \ ${RPSRC}/pxafb_changeres-r0.patch;patch=1 \ - ${RPSRC}/poodle_audio-r2.patch;patch=1 \ - ${RPSRC}/pxa27x_overlay-r1.patch;patch=1 \ + ${RPSRC}/poodle_audio-r3.patch;patch=1 \ + ${RPSRC}/pxa27x_overlay-r2.patch;patch=1 \ file://serial-add-support-for-non-standard-xtals-to-16c950-driver.patch;patch=1 \ file://hrw-pcmcia-ids-r4.patch;patch=1 \ ${RPSRC}/logo_oh-r0.patch.bz2;patch=1;status=unmergable \ -- cgit v1.2.3 From 97b35308a73e4fe401592c7029f96eddf02d34d6 Mon Sep 17 00:00:00 2001 From: Marcin Juszkiewicz Date: Sat, 9 Sep 2006 08:40:36 +0000 Subject: linux-openzaurus 2.6.17: enable Multiple LUNs for tosa and collie --- packages/linux/linux-openzaurus-2.6.17/defconfig-collie | 2 +- packages/linux/linux-openzaurus-2.6.17/defconfig-tosa | 2 +- packages/linux/linux-openzaurus_2.6.17.bb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/linux/linux-openzaurus-2.6.17/defconfig-collie b/packages/linux/linux-openzaurus-2.6.17/defconfig-collie index 181eb228ed..7ae7c0ecfb 100644 --- a/packages/linux/linux-openzaurus-2.6.17/defconfig-collie +++ b/packages/linux/linux-openzaurus-2.6.17/defconfig-collie @@ -587,7 +587,7 @@ CONFIG_CHR_DEV_SG=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set diff --git a/packages/linux/linux-openzaurus-2.6.17/defconfig-tosa b/packages/linux/linux-openzaurus-2.6.17/defconfig-tosa index 4302f47e15..48501c8a76 100644 --- a/packages/linux/linux-openzaurus-2.6.17/defconfig-tosa +++ b/packages/linux/linux-openzaurus-2.6.17/defconfig-tosa @@ -591,7 +591,7 @@ CONFIG_CHR_DEV_SG=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set diff --git a/packages/linux/linux-openzaurus_2.6.17.bb b/packages/linux/linux-openzaurus_2.6.17.bb index 46657f9837..bed9923414 100644 --- a/packages/linux/linux-openzaurus_2.6.17.bb +++ b/packages/linux/linux-openzaurus_2.6.17.bb @@ -1,6 +1,6 @@ require linux-openzaurus.inc -PR = "r24" +PR = "r25" # Handy URLs # git://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git \ -- cgit v1.2.3 From 7ac8c483e8b8ae61b971000cf245bde7bf52275b Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Sat, 9 Sep 2006 09:44:28 +0000 Subject: linux-oz-2.6: poodle locomo oops fix --- packages/linux/linux-openzaurus_2.6.17.bb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/linux/linux-openzaurus_2.6.17.bb b/packages/linux/linux-openzaurus_2.6.17.bb index bed9923414..d9adf9ede4 100644 --- a/packages/linux/linux-openzaurus_2.6.17.bb +++ b/packages/linux/linux-openzaurus_2.6.17.bb @@ -1,6 +1,6 @@ require linux-openzaurus.inc -PR = "r25" +PR = "r26" # Handy URLs # git://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git \ @@ -48,7 +48,7 @@ SRC_URI = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.17.tar.bz2 \ ${RPSRC}/locomo_kbd_tweak-r1.patch;patch=1 \ ${RPSRC}/poodle_pm-r3.patch;patch=1 \ ${RPSRC}/pxafb_changeres-r0.patch;patch=1 \ - ${RPSRC}/poodle_audio-r3.patch;patch=1 \ + ${RPSRC}/poodle_audio-r4.patch;patch=1 \ ${RPSRC}/pxa27x_overlay-r2.patch;patch=1 \ file://serial-add-support-for-non-standard-xtals-to-16c950-driver.patch;patch=1 \ file://hrw-pcmcia-ids-r4.patch;patch=1 \ -- cgit v1.2.3 From b7b9e11f6f7dcee422e51654099340c67c002e33 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Sat, 9 Sep 2006 11:58:12 +0000 Subject: many recipes: change pcre to libpcre in DEPENDS --- packages/apache/apache_2.0.54.bb | 2 +- packages/balsa/balsa_2.0.17.bb | 2 +- packages/cherokee/cherokee-nossl_0.5.3.bb | 2 +- packages/cherokee/cherokee_0.4.29.bb | 2 +- packages/cherokee/cherokee_0.5.3.bb | 2 +- packages/ctrlproxy/ctrlproxy_2.6.2.bb | 2 +- packages/e17/evidence_20060128.bb | 2 +- packages/gpe-package/gpe-package_0.3.bb | 2 +- packages/gpsdrive/gpsdrive_2.10pre2.bb | 2 +- packages/gpsdrive/gpsdrive_2.10pre3.bb | 2 +- packages/gpsdrive/gpsdrive_cvs.bb | 2 +- packages/konqueror/konqueror-embedded_20030705.bb | 2 +- packages/konqueror/konqueror-embedded_20060404.bb | 2 +- packages/meta/nylon-feed.bb | 2 +- packages/meta/slugos-packages.bb | 2 +- packages/metalog/metalog_0.7.bb | 2 +- packages/ngrep/ngrep_1.42.bb | 2 +- packages/nmap/nmap_3.81.bb | 2 +- packages/pme/pme_1.0.3.bb | 2 +- packages/postfix/postfix-native_2.0.20.bb | 2 +- packages/postfix/postfix_2.0.20.bb | 2 +- packages/zsh/zsh_4.1.1.bb | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/apache/apache_2.0.54.bb b/packages/apache/apache_2.0.54.bb index 3ab58c590f..8afb375912 100644 --- a/packages/apache/apache_2.0.54.bb +++ b/packages/apache/apache_2.0.54.bb @@ -1,6 +1,6 @@ MAINTAINER="David Karlstrom " SECTION = "net" -DEPENDS = "openssl expat pcre" +DEPENDS = "openssl expat libpcre" PR = "r4" diff --git a/packages/balsa/balsa_2.0.17.bb b/packages/balsa/balsa_2.0.17.bb index 3d97a01fe9..7418f648e5 100644 --- a/packages/balsa/balsa_2.0.17.bb +++ b/packages/balsa/balsa_2.0.17.bb @@ -3,7 +3,7 @@ incorporating all the features you would expect in a robust mail client." HOMEPAGE = "http://balsa.gnome.org" SECTION = "x11/network" LICENSE = "GPL" -DEPENDS = "libesmtp glib-2.0 libgnome libgnomeui gtk+ gnome-vfs libbonobo aspell pcre libtool openssl gtkhtml-3.0" +DEPENDS = "libesmtp glib-2.0 libgnome libgnomeui gtk+ gnome-vfs libbonobo aspell libpcre libtool openssl gtkhtml-3.0" RDEPENDS = "gdk-pixbuf-loader-xpm" PR = "r3" diff --git a/packages/cherokee/cherokee-nossl_0.5.3.bb b/packages/cherokee/cherokee-nossl_0.5.3.bb index a7c08ce753..5487afcfde 100644 --- a/packages/cherokee/cherokee-nossl_0.5.3.bb +++ b/packages/cherokee/cherokee-nossl_0.5.3.bb @@ -1,6 +1,6 @@ require cherokee_${PV}.bb -DEPENDS = "pcre" +DEPENDS = "libpcre" FILESPATH = "${@base_set_filespath([ '${FILE_DIRNAME}/cherokee-${PV}', '${FILE_DIRNAME}/cherokee', '${FILE_DIRNAME}/files', '${FILE_DIRNAME}' ], d)}" diff --git a/packages/cherokee/cherokee_0.4.29.bb b/packages/cherokee/cherokee_0.4.29.bb index 0d2eb3dcfb..09a5934ba3 100644 --- a/packages/cherokee/cherokee_0.4.29.bb +++ b/packages/cherokee/cherokee_0.4.29.bb @@ -1,7 +1,7 @@ # Cherokee web server DESCRIPTION = "Cherokee Web Server fast and secure" LICENSE = "GPL" -DEPENDS = "openssl pcre" +DEPENDS = "openssl libpcre" SRC_URI = "http://www.0x50.org/download/0.4/${PV}/${P}.tar.gz \ file://configure.patch;patch=1 \ file://Makefile.in.patch;patch=1 \ diff --git a/packages/cherokee/cherokee_0.5.3.bb b/packages/cherokee/cherokee_0.5.3.bb index 9326619d2d..bb406792e6 100644 --- a/packages/cherokee/cherokee_0.5.3.bb +++ b/packages/cherokee/cherokee_0.5.3.bb @@ -1,7 +1,7 @@ DESCRIPTION = "Cherokee Web Server fast and secure" DESCRIPTION_cget = "Small downloader based in the Cherokee client library" LICENSE = "GPL" -DEPENDS = "pcre gnutls" +DEPENDS = "libpcre gnutls" HOMEPAGE = "http://www.0x50.org/" PR = "r1" diff --git a/packages/ctrlproxy/ctrlproxy_2.6.2.bb b/packages/ctrlproxy/ctrlproxy_2.6.2.bb index 6fdf0d8c2c..d426a351ca 100644 --- a/packages/ctrlproxy/ctrlproxy_2.6.2.bb +++ b/packages/ctrlproxy/ctrlproxy_2.6.2.bb @@ -2,7 +2,7 @@ DESCRIPTION = "ctrlproxy is an IRC server with multiserver support." SECTION = "console/network" PRIORITY = "optional" MAINTAINER = "NSLU2 Linux " -DEPENDS = "glib-2.0 libxml2 popt pcre openssl" +DEPENDS = "glib-2.0 libxml2 popt libpcre openssl" PR = "r1" LICENSE = "GPL" diff --git a/packages/e17/evidence_20060128.bb b/packages/e17/evidence_20060128.bb index 683ac8e536..30bc8792ac 100644 --- a/packages/e17/evidence_20060128.bb +++ b/packages/e17/evidence_20060128.bb @@ -1,7 +1,7 @@ DESCRIPTION = "evidence, an enlightenemt file manager" LICENSE = "GPL" # can support dbus, avifile, libmpeg3 -DEPENDS = "pkgconfig gtk+ glib-2.0 ecore-x11 evas-x11 edb eet edje imlib2-x11 libpng epeg jpeg pcre curl taglib libvorbis libogg libxine-x11 emotion freetype" +DEPENDS = "pkgconfig gtk+ glib-2.0 ecore-x11 evas-x11 edb eet edje imlib2-x11 libpng epeg jpeg libpcre curl taglib libvorbis libogg libxine-x11 emotion freetype" RDEPENDS += "examine" PR = "r0" diff --git a/packages/gpe-package/gpe-package_0.3.bb b/packages/gpe-package/gpe-package_0.3.bb index 4de6e056df..1ee7a9a2ff 100644 --- a/packages/gpe-package/gpe-package_0.3.bb +++ b/packages/gpe-package/gpe-package_0.3.bb @@ -3,7 +3,7 @@ PR = "r3" inherit gpe pkgconfig DESCRIPTION = "A package manager GUI for GPE" -DEPENDS = "ipkg pcre libgpewidget" +DEPENDS = "ipkg libpcre libgpewidget" RDEPENDS = "gpe-icons gpe-su" SECTION = "gpe" PRIORITY = "optional" diff --git a/packages/gpsdrive/gpsdrive_2.10pre2.bb b/packages/gpsdrive/gpsdrive_2.10pre2.bb index 4de819e5f6..98eee0c4fa 100644 --- a/packages/gpsdrive/gpsdrive_2.10pre2.bb +++ b/packages/gpsdrive/gpsdrive_2.10pre2.bb @@ -3,7 +3,7 @@ inherit autotools pkgconfig PR = "r1" PACKAGES += "gpsdrive-add" DESCRIPTION = "GPS navigation/map display software" -DEPENDS = "virtual/libc gtk+ pcre gpsd" +DEPENDS = "virtual/libc gtk+ libpcre gpsd" RDEPENDS_${PN} = "gdk-pixbuf-loader-gif gpsd" MAINTAINER = "Florian Boor " SECTION = "x11" diff --git a/packages/gpsdrive/gpsdrive_2.10pre3.bb b/packages/gpsdrive/gpsdrive_2.10pre3.bb index 7d0e32930c..6915bc0194 100644 --- a/packages/gpsdrive/gpsdrive_2.10pre3.bb +++ b/packages/gpsdrive/gpsdrive_2.10pre3.bb @@ -5,7 +5,7 @@ DEFAULT_PREFERENCE="-1" PACKAGES += "gpsdrive-add" DESCRIPTION = "GPS navigation/map display software" -DEPENDS = "virtual/libc gtk+ pcre gpsd" +DEPENDS = "virtual/libc gtk+ libpcre gpsd" RDEPENDS_${PN} = "gdk-pixbuf-loader-gif gpsd" MAINTAINER = "Florian Boor " SECTION = "x11" diff --git a/packages/gpsdrive/gpsdrive_cvs.bb b/packages/gpsdrive/gpsdrive_cvs.bb index e1ea27cac0..88c1fb411e 100644 --- a/packages/gpsdrive/gpsdrive_cvs.bb +++ b/packages/gpsdrive/gpsdrive_cvs.bb @@ -7,7 +7,7 @@ DEFAULT_PREFERENCE="-1" PACKAGES += "gpsdrive-add" DESCRIPTION = "GPS navigation/map display software" -DEPENDS = "virtual/libc libart-lgpl gtk+ pcre gpsd" +DEPENDS = "virtual/libc libart-lgpl gtk+ libpcre gpsd" RDEPENDS_${PN} = "gdk-pixbuf-loader-gif gpsd" MAINTAINER = "Koen Kooi " SECTION = "x11" diff --git a/packages/konqueror/konqueror-embedded_20030705.bb b/packages/konqueror/konqueror-embedded_20030705.bb index 5bdc4ed765..690df1acfa 100644 --- a/packages/konqueror/konqueror-embedded_20030705.bb +++ b/packages/konqueror/konqueror-embedded_20030705.bb @@ -2,7 +2,7 @@ DESCRIPTION = "KDE Web Browser Konqueror, QtE based Palmtop Environments Edition HOMEPAGE = "http://www.konqueror.org/embedded" SECTION = "opie/applications" PRIORITY = "optional" -DEPENDS = "libqpe-opie openssl pcre" +DEPENDS = "libqpe-opie openssl libpcre" LICENSE = "LGPL/GPL" PR = "r5" diff --git a/packages/konqueror/konqueror-embedded_20060404.bb b/packages/konqueror/konqueror-embedded_20060404.bb index 8ab25baf6e..02321bc1c1 100644 --- a/packages/konqueror/konqueror-embedded_20060404.bb +++ b/packages/konqueror/konqueror-embedded_20060404.bb @@ -2,7 +2,7 @@ DESCRIPTION = "KDE Web Browser Konqueror, QtE based Palmtop Environments Edition SECTION = "opie/applications" PRIORITY = "optional" HOMEPAGE = "http://www.konqueror.org/" -DEPENDS = "openssl pcre virtual/libqte2 dcopidl-native dcopidl2cpp-native" +DEPENDS = "openssl libpcre virtual/libqte2 dcopidl-native dcopidl2cpp-native" LICENSE = "LGPL/GPL" PR = "r3" diff --git a/packages/meta/nylon-feed.bb b/packages/meta/nylon-feed.bb index 40faab8056..21d53b9895 100644 --- a/packages/meta/nylon-feed.bb +++ b/packages/meta/nylon-feed.bb @@ -24,7 +24,7 @@ DEPENDS = "${NYLON_FEED} \ openssl \ openswan \ openvpn \ - pcre \ + libpcre \ ppp-dsl \ rp-pppoe \ simple-firewall \ diff --git a/packages/meta/slugos-packages.bb b/packages/meta/slugos-packages.bb index b35b50c83f..5ba21c80a6 100644 --- a/packages/meta/slugos-packages.bb +++ b/packages/meta/slugos-packages.bb @@ -138,7 +138,7 @@ SLUGOS_PACKAGES = "\ openvpn \ patch \ pciutils \ - pcre \ + libpcre \ perl \ pkgconfig \ ppp \ diff --git a/packages/metalog/metalog_0.7.bb b/packages/metalog/metalog_0.7.bb index fef8c315f1..ac24694001 100644 --- a/packages/metalog/metalog_0.7.bb +++ b/packages/metalog/metalog_0.7.bb @@ -1,5 +1,5 @@ DESCRIPTION = "Metalog is a replacement for syslogd." -DEPENDS = "pcre" +DEPENDS = "libpcre" LICENSE = "GPL" PR = "r0" diff --git a/packages/ngrep/ngrep_1.42.bb b/packages/ngrep/ngrep_1.42.bb index 64970ab994..7ff9aa1e6b 100644 --- a/packages/ngrep/ngrep_1.42.bb +++ b/packages/ngrep/ngrep_1.42.bb @@ -2,7 +2,7 @@ DESCRIPTION = "ngrep strives to provide most of GNU grep's \ common features, applying them to the network layer." SECTION = "console/network" PRIORITY = "optional" -DEPENDS = "libpcap pcre" +DEPENDS = "libpcap libpcre" LICENSE="ngrep" SRC_URI = "${SOURCEFORGE_MIRROR}/ngrep/ngrep-${PV}.tar.bz2 \ file://use-our-pcre.patch;patch=1" diff --git a/packages/nmap/nmap_3.81.bb b/packages/nmap/nmap_3.81.bb index a028d9d077..8d08fee21c 100644 --- a/packages/nmap/nmap_3.81.bb +++ b/packages/nmap/nmap_3.81.bb @@ -3,7 +3,7 @@ HOMEPAGE = "http://www.insecure.org/nmap/" MAINTAINER = "Chris Larson " SECTION = "console/network" LICENSE = "GPL" -DEPENDS = "libpcap pcre" +DEPENDS = "libpcap libpcre" PR = "r1" inherit autotools diff --git a/packages/pme/pme_1.0.3.bb b/packages/pme/pme_1.0.3.bb index 3992c44b61..9cfad5dfdd 100644 --- a/packages/pme/pme_1.0.3.bb +++ b/packages/pme/pme_1.0.3.bb @@ -1,5 +1,5 @@ SECTION = "unknown" -DEPENDS = "pcre" +DEPENDS = "libpcre" LICENSE = "BSD" DESCRIPTION = "PME is a C++ wrapper around the PCRE library." SRC_URI = "http://xaxxon.slackworks.com/pme/pme-${PV}.tar.gz" diff --git a/packages/postfix/postfix-native_2.0.20.bb b/packages/postfix/postfix-native_2.0.20.bb index dbbad9b450..0ba8c493ff 100644 --- a/packages/postfix/postfix-native_2.0.20.bb +++ b/packages/postfix/postfix-native_2.0.20.bb @@ -2,7 +2,7 @@ SECTION = "console/network" require postfix_${PV}.bb inherit native FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/postfix-${PV}" -DEPENDS = "virtual/db-native pcre-native" +DEPENDS = "virtual/db-native libpcre-native" export DIRS = "src/util src/global src/postconf" do_stage () { diff --git a/packages/postfix/postfix_2.0.20.bb b/packages/postfix/postfix_2.0.20.bb index 4a11a002e3..6ddc24477d 100644 --- a/packages/postfix/postfix_2.0.20.bb +++ b/packages/postfix/postfix_2.0.20.bb @@ -1,5 +1,5 @@ SECTION = "console/network" -DEPENDS = "virtual/db pcre postfix-native" +DEPENDS = "virtual/db libpcre postfix-native" LICENSE = "IPL" PR = "r8" diff --git a/packages/zsh/zsh_4.1.1.bb b/packages/zsh/zsh_4.1.1.bb index bb4cb1e27c..e59a42c174 100644 --- a/packages/zsh/zsh_4.1.1.bb +++ b/packages/zsh/zsh_4.1.1.bb @@ -2,7 +2,7 @@ DESCRIPTION = "The Zsh shell" SECTION = "base/shell" PRIORITY = "optional" MAINTAINER = "Chris Larson " -DEPENDS = "ncurses pcre" +DEPENDS = "ncurses libpcre" PR = "r2" LICENSE = "zsh" -- cgit v1.2.3 From b57419c6af9cfcb7c14c9e39e4670b871993e395 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 9 Sep 2006 15:04:48 +0000 Subject: bitbake.conf: update default maintainer --- conf/bitbake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/bitbake.conf b/conf/bitbake.conf index fe0ff05e13..e83f2b5667 100644 --- a/conf/bitbake.conf +++ b/conf/bitbake.conf @@ -91,7 +91,7 @@ SECTION = "base" PRIORITY = "optional" DESCRIPTION = "Version ${PV}-${PR} of package ${PN}" LICENSE = "unknown" -MAINTAINER = "OpenEmbedded Team " +MAINTAINER = "OpenEmbedded Team " HOMEPAGE = "unknown" # Package dependencies and provides. -- cgit v1.2.3 From bd246d9a4b143fa5766e9b2d86676d35971ecef6 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Sat, 9 Sep 2006 17:55:19 +0000 Subject: pcre: attempt to repair the damage introduced --- packages/libpcre/libpcre_4.4.bb | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/libpcre/libpcre_4.4.bb b/packages/libpcre/libpcre_4.4.bb index 9974e85806..f26b595894 100644 --- a/packages/libpcre/libpcre_4.4.bb +++ b/packages/libpcre/libpcre_4.4.bb @@ -10,12 +10,15 @@ PR = "r1" SRC_URI = "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-${PV}.tar.bz2" S = "${WORKDIR}/pcre-${PV}" +PARALLEL_MAKE = "" + inherit autotools binconfig LEAD_SONAME = "libpcre.so" CFLAGS_append = " -D_REENTRANT" EXTRA_OECONF = " --with-link-size=2 --enable-newline-is-lf --with-match-limit=10000000" + do_compile () { ${BUILD_CC} -DLINK_SIZE=2 -I${S}/include -c dftables.c ${BUILD_CC} dftables.o -o dftables @@ -23,11 +26,20 @@ do_compile () { } do_stage () { - oe_libinstall -a -so libpcreposix ${STAGING_LIBDIR} - oe_libinstall -a -so libpcre ${STAGING_LIBDIR} - install -m 0644 pcre.h ${STAGING_INCDIR}/ - install -m 0644 pcreposix.h ${STAGING_INCDIR}/ + # Force all -L(dir) output to be prepended with the staging libdir to stop libtool + # from trying to link to host libraries. + sed -i 's:-L\$:-L${STAGING_LIBDIR} -L\$:' ${S}/*libtool + + oe_libinstall -a -so libpcre ${STAGING_LIBDIR} + oe_libinstall -a -so libpcreposix ${STAGING_LIBDIR} + install -m 0644 pcre.h ${STAGING_INCDIR}/ + install -m 0644 pcreposix.h ${STAGING_INCDIR}/ + + # pcreposix linked originally to the libpcre in it's working directory. That messed + # the .la file up. I fix this manually here: + sed -i 's:${S}:${STAGING_LIBDIR}:' ${STAGING_LIBDIR}/libpcreposix.la } + FILES_${PN} = "${libdir}/lib*.so*" FILES_${PN}-dev += "${bindir}" -- cgit v1.2.3